From 7ba874332aa01d702943857bad3f7f3c5e49f144 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Tue, 1 Dec 2015 02:35:45 +1100 Subject: [PATCH] 20030512 release --- bin/a.sh | 1 - bin/appinst.bat | 2 + bin/appinst.sh | 17 + bin/appinst.ucp | 29 + bin/b.sh | 1 - bin/banked/cat | Bin 841 -> 841 bytes bin/banked/diff | Bin 26570 -> 27319 bytes bin/banked/ed | Bin 24122 -> 24122 bytes bin/banked/fsck | Bin 0 -> 19333 bytes bin/banked/grlogin | Bin 0 -> 20399 bytes bin/banked/init | Bin 21590 -> 21516 bytes bin/banked/ls | Bin 13581 -> 13633 bytes bin/banked/mkdir | Bin 1558 -> 1558 bytes bin/banked/mkfs | Bin 0 -> 15694 bytes bin/banked/msh | Bin 40306 -> 42333 bytes bin/banked/setclock | Bin 1537 -> 1537 bytes bin/banked/test | Bin 6867 -> 18569 bytes bin/banked/tr | Bin 12972 -> 13188 bytes bin/banked/wnd | Bin 0 -> 23128 bytes bin/boot.bin | Bin 1920 -> 1920 bytes bin/checksum | Bin 128 -> 128 bytes bin/checksum.dat | 2 + bin/data/0000.scr | Bin 0 -> 276 bytes bin/data/0001.scr | Bin 0 -> 518 bytes bin/data/0002.scr | Bin 0 -> 719 bytes bin/data/0003.scr | Bin 0 -> 460 bytes bin/data/0004.scr | Bin 0 -> 946 bytes bin/data/kass.scr | Bin 0 -> 464 bytes bin/data/logn.scr | Bin 0 -> 317 bytes bin/font/lcd0.cmd | Bin 0 -> 12700 bytes bin/font/lcd1.cmd | Bin 0 -> 11146 bytes bin/fstab.txt | 2 + bin/group.txt | 3 +- bin/inittab.txt | 6 +- bin/kernel.bin | Bin 81008 -> 81141 bytes bin/large/cat | Bin 732 -> 732 bytes bin/large/diff | Bin 24281 -> 24675 bytes bin/large/ed | Bin 22341 -> 22405 bytes bin/large/init | Bin 18309 -> 19748 bytes bin/large/ls | Bin 12670 -> 12717 bytes bin/large/mkdir | Bin 1437 -> 1437 bytes bin/large/mkfs | Bin 14660 -> 14685 bytes bin/large/setclock | Bin 1412 -> 1412 bytes bin/large/tr | Bin 12249 -> 12445 bytes bin/large/wnd | Bin 0 -> 16953 bytes bin/man/cat1/basename.0 | 2 +- bin/man/cat1/cal.0 | 2 +- bin/man/cat1/cat.0 | 2 +- bin/man/cat1/chmod.0 | 4 +- bin/man/cat1/chown.0 | 2 +- bin/man/cat1/cmp.0 | 2 +- bin/man/cat1/cp.0 | 2 +- bin/man/cat1/date.0 | 2 +- bin/man/cat1/dd.0 | 4 +- bin/man/cat1/diff.0 | 4 +- bin/man/cat1/du.0 | 2 +- bin/man/cat1/echo.0 | 2 +- bin/man/cat1/ed.0 | 16 +- bin/man/cat1/expr.0 | 4 +- bin/man/cat1/file.0 | 2 +- bin/man/cat1/find.0 | 4 +- bin/man/cat1/grep.0 | 6 +- bin/man/cat1/kill.0 | 2 +- bin/man/cat1/ln.0 | 2 +- bin/man/cat1/login.0 | 2 +- bin/man/cat1/ls.0 | 4 +- bin/man/cat1/man.0 | 4 +- bin/man/cat1/mkdir.0 | 2 +- bin/man/cat1/mv.0 | 2 +- bin/man/cat1/od.0 | 2 +- bin/man/cat1/passwd.0 | 2 +- bin/man/cat1/pr.0 | 2 +- bin/man/cat1/ps.0 | 4 +- bin/man/cat1/pwd.0 | 2 +- bin/man/cat1/rm.0 | 2 +- bin/man/cat1/roff.0 | 8 +- bin/man/cat1/sh.0 | 8 +- bin/man/cat1/sort.0 | 6 +- bin/man/cat1/split.0 | 2 +- bin/man/cat1/su.0 | 2 +- bin/man/cat1/sum.0 | 2 +- bin/man/cat1/tail.0 | 2 +- bin/man/cat1/tar.0 | 6 +- bin/man/cat1/tee.0 | 2 +- bin/man/cat1/test.0 | 4 +- bin/man/cat1/time.0 | 2 +- bin/man/cat1/touch.0 | 2 +- bin/man/cat1/tr.0 | 2 +- bin/man/cat1/troff.0 | 6 +- bin/man/cat1/true.0 | 2 +- bin/man/cat1/uniq.0 | 2 +- bin/man/cat1/wc.0 | 2 +- bin/mkboot.bat | 18 + bin/mkboot.ucp | 130 + bin/mkramfs.sh | 4 +- bin/mtab.txt | 1 - bin/n.bat | 24 +- bin/n.ucp | 97 +- bin/newkrnl.sh | 4 +- bin/padding.dat | 1 + bin/passwd.txt | 4 + bin/profile.sh | 6 + bin/runonce.rc | 6 + bin/runonce.sh | 13 + bin/sysinit.rc | 5 + bin/uzboot.bin | Bin 0 -> 108463 bytes bin/uzboot.gz | Bin 0 -> 106661 bytes bin/uzboot.ldr | Bin 0 -> 1802 bytes bin/uzidisk.dat | Bin 4194304 -> 4194304 bytes bin/x.sh | 1 - bin/xfstab.txt | 1 + bin/xinittab.txt | 4 + bin/xmtab.txt | 1 + doc/EXECPATH.TXT | 3 + doc/gui/Gui driver.doc | Bin 0 -> 47104 bytes doc/gui/Software design.doc | Bin 0 -> 19456 bytes doc/gui/scr file format.doc | Bin 0 -> 22016 bytes doc/rfc/rfc1700.txt | 12884 ++++++++++++++++ doc/rfc/rfc854.txt | 855 + doc/rfc/std5.txt | 7227 +++++++++ doc/rfc/std7.txt | 5248 +++++++ doc/rfc/std9.txt | 3934 +++++ include/syscalls.h | 3 + lib/libsysb.lib | 1 + lib/libsysl.lib | 1 + lib/relsysb/sysdebug.rel | 22 + lib/relsysl/sysdebug.rel | 19 + relnotes/20030512.txt | 667 + silly.bat | 3 - src/as-z80/as-z80.exe | Bin 110637 -> 0 bytes src/as-z80/as-z80.map | 533 - src/avr/2313def.inc | 232 + src/avr/4433def.inc | 296 + src/avr/4434def.inc | 364 + src/avr/7segv0.asm | 592 + src/avr/8535def.inc | 366 + src/avr/8x10.asm | 98 + src/avr/CFLASHV0.HEX | 76 + src/avr/CFLASHV1.HEX | 76 + src/avr/CFLASHV2.HEX | 76 + src/avr/CHSET00.WIN | Bin 0 -> 869 bytes src/avr/CS64V4.HEX | 385 + src/avr/CS64V5.ASM | 3077 ++++ src/avr/CS64V5.HEX | 385 + src/avr/ISPD.EXE | Bin 0 -> 69514 bytes src/avr/ISPD.INI | 16 + src/avr/MAKCHR.LOG | 96 + src/avr/MT102V0.HEX | 191 + src/avr/MT102V1.HEX | 191 + src/avr/MT102V2.HEX | 191 + src/avr/TAVRASM.EXE | Bin 0 -> 118606 bytes src/avr/TSV3.HEX | 504 + src/avr/TSV4.ASM | 3708 +++++ src/avr/TSV4.HEX | 504 + src/avr/WPO15V1.HEX | 132 + src/avr/WPOV0.HEX | 135 + src/avr/WPOV1.HEX | 135 + src/avr/WPOV2.HEX | 131 + src/avr/WPOV3.ASM | 2502 +++ src/avr/WPOV3.HEX | 146 + src/avr/a.bat | 1 + src/avr/a_avra.bat | 1 + src/avr/a_orig.bat | 1 + src/avr/aa.bat | 1 + src/avr/api.inc | 270 + src/avr/apicf.inc | 281 + src/avr/apics.inc | 271 + src/avr/apilc.inc | 295 + src/avr/apilc8.inc | 331 + src/avr/apits.inc | 296 + src/avr/avrasm.exe | Bin 0 -> 107092 bytes src/avr/cflashv0.asm | 826 + src/avr/cflashv1.asm | 826 + src/avr/cflashv2.asm | 827 + src/avr/charav0.asm | 2433 +++ src/avr/charav1.asm | 2479 +++ src/avr/chklin.asm | 85 + src/avr/chset00.inc | 58 + src/avr/chtest.asm | 2411 +++ src/avr/crcsubx.asm | 87 + src/avr/crcsubx.inc | 10 + src/avr/cs128v0.asm | 3076 ++++ src/avr/cs64v0.asm | 3076 ++++ src/avr/cs64v1.asm | 2912 ++++ src/avr/cs64v1a.asm | 2913 ++++ src/avr/cs64v2.asm | 2928 ++++ src/avr/cs64v4-cs64v5.diff | 625 + src/avr/cs64v4.asm | 3077 ++++ src/avr/dos.asm | 366 + src/avr/dos.inc | 20 + src/avr/file.asm | 3040 ++++ src/avr/file.inc | 58 + src/avr/iocall.asm | 1015 ++ src/avr/iocall.inc | 44 + src/avr/lcter.asm | 2398 +++ src/avr/lcv0.asm | 2398 +++ src/avr/lcv1.asm | 2476 +++ src/avr/m192rhs.asm | 1685 ++ src/avr/m192ter.asm | 1685 ++ src/avr/m192v0.asm | 1685 ++ src/avr/m192v1.asm | 1685 ++ src/avr/mac.inc | 195 + src/avr/maclc.inc | 242 + src/avr/makchr.bas | 650 + src/avr/makchr.exe | Bin 0 -> 53976 bytes src/avr/mega8def.inc | 380 + src/avr/mt102ter.asm | 1752 +++ src/avr/mt102v0.asm | 1831 +++ src/avr/mt102v1.asm | 1831 +++ src/avr/mt102v1.asm.orig | 1831 +++ src/avr/mt102v2.asm | 1831 +++ src/avr/mt102v2.asm.orig | 1831 +++ src/avr/prm.inc | 104 + src/avr/prm0.inc | 103 + src/avr/product/CFLASHV0.HEX | 76 + src/avr/product/CFLASHV1.HEX | 76 + src/avr/product/CFLASHV2.HEX | 76 + src/avr/product/CS64V4.HEX | 385 + src/avr/product/MT102V0.HEX | 191 + src/avr/product/MT102V1.HEX | 191 + src/avr/product/MT102V2.HEX | 191 + src/avr/product/TSV3.HEX | 504 + src/avr/product/WPO15V1.HEX | 132 + src/avr/product/WPOV0.HEX | 135 + src/avr/product/WPOV1.HEX | 135 + src/avr/product/WPOV2.HEX | 131 + src/avr/putpcx.asm | 79 + src/avr/set00.pcx | Bin 0 -> 3023 bytes src/avr/ter.inc | 211 + src/avr/terlc.inc | 196 + src/avr/terlc8.inc | 208 + src/avr/terts.inc | 215 + src/avr/tster.asm | 3507 +++++ src/avr/tsv0.asm | 3568 +++++ src/avr/tsv3-tsv4.diff | 666 + src/avr/tsv3.asm | 3708 +++++ src/avr/wpo15v1.asm | 2186 +++ src/avr/wpov0.asm | 2116 +++ src/avr/wpov1.asm | 2116 +++ src/avr/wpov2.asm | 2198 +++ src/bin/as-z80.exe | Bin 110637 -> 122932 bytes src/bin/bd.exe | Bin 57384 -> 69673 bytes src/bin/bin2avr.exe | Bin 0 -> 73774 bytes src/bin/bin2c.exe | Bin 57388 -> 69676 bytes src/bin/bmp2txt.exe | Bin 0 -> 98350 bytes src/bin/chs2cmd.exe | Bin 0 -> 73774 bytes src/bin/cr.exe | Bin 61481 -> 73769 bytes src/bin/diff.exe | Bin 200768 -> 0 bytes src/bin/fsck.exe | Bin 73770 -> 86059 bytes src/bin/ihex2bin.exe | Bin 57391 -> 73775 bytes src/bin/link-z80.exe | Bin 106545 -> 122936 bytes src/bin/mkfs.exe | Bin 65578 -> 81963 bytes src/bin/nroff.exe | Bin 143403 -> 155691 bytes src/bin/p.exe | Bin 0 -> 36052 bytes src/bin/patch.exe | Bin 172089 -> 0 bytes src/bin/pkzipc.exe | Bin 0 -> 258048 bytes src/bin/tavrasm.exe | Bin 0 -> 225342 bytes src/bin/touch.exe | Bin 61484 -> 73772 bytes src/bin/txt2chs.exe | Bin 0 -> 86062 bytes src/bin/ucp.exe | Bin 143402 -> 155690 bytes src/font/large.psd | Bin 0 -> 64357 bytes src/font/lcd0.cmd | Bin 0 -> 12700 bytes src/font/lcd1.cmd | Bin 0 -> 11146 bytes src/font/n.bat | 27 + src/font/set01.bmp | Bin 0 -> 26580 bytes src/font/set01.chs | Bin 0 -> 1592 bytes src/font/set01.cmd | Bin 0 -> 1597 bytes src/font/set01.txt | 1056 ++ src/font/set02.bmp | Bin 0 -> 29048 bytes src/font/set02.chs | Bin 0 -> 1602 bytes src/font/set02.cmd | Bin 0 -> 1607 bytes src/font/set02.txt | 1087 ++ src/font/set03.bmp | Bin 0 -> 41484 bytes src/font/set03.chs | Bin 0 -> 1826 bytes src/font/set03.cmd | Bin 0 -> 1831 bytes src/font/set03.txt | 1312 ++ src/font/set04.bmp | Bin 0 -> 68472 bytes src/font/set04.chs | Bin 0 -> 2578 bytes src/font/set04.cmd | Bin 0 -> 2583 bytes src/font/set04.txt | 1665 ++ src/font/set05.bmp | Bin 0 -> 124112 bytes src/font/set05.chs | Bin 0 -> 3523 bytes src/font/set05.cmd | Bin 0 -> 3528 bytes src/font/set05.txt | 2145 +++ src/font/set06.bmp | Bin 0 -> 20024 bytes src/font/set06.chs | Bin 0 -> 1549 bytes src/font/set06.cmd | Bin 0 -> 1554 bytes src/font/set06.txt | 1024 ++ src/font/small.psd | Bin 0 -> 39781 bytes src/fsutil/bd.exe | Bin 57384 -> 69673 bytes src/fsutil/boot.c | 6 +- src/fsutil/f.bat | 13 - src/fsutil/fsck.exe | Bin 73770 -> 86059 bytes src/fsutil/fsck.lnk | 10 +- src/fsutil/fsck.map | 239 +- src/fsutil/fsck.rel | 3776 +++-- src/fsutil/m.bat | 13 - src/fsutil/mkfs.c | 7 + src/fsutil/mkfs.exe | Bin 65578 -> 81963 bytes src/fsutil/mkfs.lnk | 10 +- src/fsutil/mkfs.map | 232 +- src/fsutil/mkfs.rel | 1708 +- src/fsutil/n.bat | 44 + src/fsutil/ucp.c | 20 +- src/fsutil/ucp.exe | Bin 143402 -> 155690 bytes src/fsutil/ucp.map | 1471 +- src/fsutil/ucpsub.c | 52 +- src/fsutil/utils.rel | 34 +- src/gboot/build.ban | 35 + src/gboot/gboot.asm$ | 793 - src/gboot/gboot.map | 39 - src/gboot/gboot.rel | 651 - src/gboot/n.bat | 31 +- src/gboot/uzboot.asm | 67 + src/gboot/uzboot.lnk | 12 + src/gboot/uzdata.asm | 22 + src/gboot/uzfile.asm | 1255 ++ src/gboot/uzmain.asm | 233 + src/gui/0000.scr | Bin 0 -> 262 bytes src/gui/0001.scr | Bin 0 -> 345 bytes src/gui/0001.tmp | 0 src/gui/0002.scr | Bin 0 -> 719 bytes src/gui/0003.scr | Bin 0 -> 760 bytes src/gui/0004.scr | Bin 0 -> 1596 bytes src/gui/Copy (2) of wnd.c | 1138 ++ src/gui/Copy of wnd.c | 941 ++ src/gui/Copy of wnd.h | 180 + src/gui/cl64180.r01 | Bin 0 -> 100922 bytes src/gui/grlogin.map | 272 + src/gui/hello.map | 1 + src/gui/login.c | 93 + src/gui/login.map | 283 + src/gui/login.rel | 231 + src/gui/m.bat | 27 + src/gui/p.bat | 2 + src/gui/t.bat | 33 + src/gui/test.c | 10 + src/gui/test.lnk | 15 + src/gui/test.map | 248 + src/gui/test.rel | 47 + src/gui/trans.c | 124 + src/gui/trans.h | 16 + src/gui/trans.rel | 638 + src/gui/wnd.c | 1141 ++ src/gui/wnd.cbackup | 658 + src/gui/wnd.h | 201 + src/gui/wnd.ihx | 1068 ++ src/gui/wnd.lnk | 14 + src/gui/wnd.map | 283 + src/gui/wnd.rel | 3437 +++++ src/gui/wnd.xcl | 13 + src/gui/wnd.xls | Bin 0 -> 15872 bytes src/gui/wnd.zip | Bin 0 -> 9882 bytes src/init/init.c | 293 +- src/kernel/build.ban | 72 +- src/kernel/cmx/apibus.asm | 2 + src/kernel/cmx/copyr.asm | 61 +- src/kernel/cmx/diag.asm | 4 + src/kernel/kernel.lnk | 1 + src/kernel/libc/{vendor.h => VENDOR.H} | 3 + src/kernel/libc/dprintf.c | 59 + src/kernel/libc/dprintf.h | 9 + src/kernel/uzi/config.h | 2 +- src/kernel/uzi/devhd.c | 20 +- src/kernel/uzi/devio.c | 107 +- src/kernel/uzi/devtty.c | 26 +- src/kernel/uzi/extern.h | 3 +- src/kernel/uzi/filesys.c | 285 +- src/kernel/uzi/hdconf.h | 2 +- src/kernel/uzi/machdep.c | 2 +- src/kernel/uzi/main.c | 18 +- src/kernel/uzi/process.c | 44 +- src/kernel/uzi/scall1.c | 70 +- src/kernel/uzi/scall2.c | 28 +- src/kernel/uzi/systrace.c | 6 + src/kernel/uzi/unix.h | 4 +- src/kernel/uzi/vendor.h | 2 + src/kernel/uzi/xip.c | 327 +- src/libiar/n.bat | 1 + src/libsys/build-b.ban | 7 + src/libsys/build-l.ban | 7 + src/libsys/libsysb.lib | 1 + src/libsys/libsysl.lib | 1 + src/libsys/syscalls.h | 1 + src/libsys/sysdebug.c | 32 + src/link-z80/link-z80.exe | Bin 106545 -> 0 bytes src/link-z80/link-z80.map | 520 - src/mkfont/bmp2txt.cpp | 313 + src/mkfont/bmp2txt.exe | Bin 0 -> 98350 bytes src/mkfont/chs2cmd.cpp | 109 + src/mkfont/chs2cmd.exe | Bin 0 -> 73774 bytes src/mkfont/hyfile.cpp | 307 + src/mkfont/hyfile.h | 125 + src/mkfont/hyfs.cpp | 137 + src/mkfont/hyfs.h | 121 + src/mkfont/hyimage.cpp | 1230 ++ src/mkfont/hyimage.h | 104 + src/mkfont/hymb.cpp | 117 + src/mkfont/hymb.h | 95 + src/mkfont/n.bat | 18 + src/mkfont/txt2chs.cpp | 431 + src/mkfont/txt2chs.exe | Bin 0 -> 86062 bytes src/mkutil/{cr.exe => CR.EXE} | Bin 61481 -> 73769 bytes src/mkutil/as-z80/as-z80.exe | Bin 0 -> 122932 bytes src/{ => mkutil}/as-z80/as-z80.lnk | 0 src/mkutil/as-z80/as-z80.map | 567 + src/{ => mkutil}/as-z80/asdata.c | 0 src/{ => mkutil}/as-z80/asexpr.c | 0 src/{ => mkutil}/as-z80/aslex.c | 0 src/{ => mkutil}/as-z80/aslist.c | 0 src/{ => mkutil}/as-z80/asmain.c | 0 src/{ => mkutil}/as-z80/asout.c | 0 src/{ => mkutil}/as-z80/assubr.c | 0 src/{ => mkutil}/as-z80/assym.c | 0 src/{ => mkutil}/as-z80/asxxxx.h | 0 src/{ => mkutil}/as-z80/n.bat | 2 +- src/{ => mkutil}/as-z80/tz80.asm | 0 src/{ => mkutil}/as-z80/tz80l.asm | 0 src/{ => mkutil}/as-z80/z80.h | 0 src/{ => mkutil}/as-z80/z80adr.c | 0 src/{ => mkutil}/as-z80/z80ext.c | 0 src/{ => mkutil}/as-z80/z80mch.c | 0 src/{ => mkutil}/as-z80/z80pst.c | 0 src/{ => mkutil}/as-z80/z80pst.c$ | 0 src/mkutil/avra-0.8/COPYING | 341 + src/mkutil/avra-0.8/ChangeLog | 47 + src/mkutil/avra-0.8/README | 274 + src/mkutil/avra-0.8/SOURCE/Makefile.amiga.gcc | 80 + src/mkutil/avra-0.8/SOURCE/Makefile.amiga.sas | 75 + src/mkutil/avra-0.8/SOURCE/Makefile.emx | 69 + src/mkutil/avra-0.8/SOURCE/Makefile.linux | 74 + src/mkutil/avra-0.8/SOURCE/Makefile.win | 58 + src/mkutil/avra-0.8/SOURCE/Makefile.win32.mvc | 47 + src/mkutil/avra-0.8/SOURCE/args.c | 240 + src/mkutil/avra-0.8/SOURCE/args.h | 65 + src/mkutil/avra-0.8/SOURCE/avra.c | 333 + src/mkutil/avra-0.8/SOURCE/avra.dev | 179 + src/mkutil/avra-0.8/SOURCE/avra.exe | Bin 0 -> 94208 bytes src/mkutil/avra-0.8/SOURCE/avra.h | 295 + src/mkutil/avra-0.8/SOURCE/coff.c | 2074 +++ src/mkutil/avra-0.8/SOURCE/coff.h | 403 + src/mkutil/avra-0.8/SOURCE/device.c | 206 + src/mkutil/avra-0.8/SOURCE/device.h | 32 + src/mkutil/avra-0.8/SOURCE/directiv.c | 824 + src/mkutil/avra-0.8/SOURCE/expr.c | 608 + src/mkutil/avra-0.8/SOURCE/file.c | 272 + src/mkutil/avra-0.8/SOURCE/macro.c | 427 + src/mkutil/avra-0.8/SOURCE/map.c | 70 + src/mkutil/avra-0.8/SOURCE/misc.h | 14 + src/mkutil/avra-0.8/SOURCE/mnemonic.c | 871 ++ src/mkutil/avra-0.8/SOURCE/n.bat | 2 + src/mkutil/avra-0.8/SOURCE/parser.c | 397 + src/mkutil/avra-0.8/SOURCE/stdextra.c | 197 + src/mkutil/avra-0.8/TODO | 10 + src/mkutil/avra-0.8/avra.dev | 179 + src/mkutil/bin2avr.c | 162 + src/mkutil/bin2avr.exe | Bin 0 -> 73774 bytes src/mkutil/bin2c.exe | Bin 57388 -> 69676 bytes src/mkutil/crc.exe | Bin 57386 -> 69674 bytes src/mkutil/ihex2bin.exe | Bin 57391 -> 73775 bytes src/{ => mkutil}/link-z80/aslink.h | 0 src/mkutil/link-z80/link-z80.exe | Bin 0 -> 122936 bytes src/{ => mkutil}/link-z80/link-z80.lnk | 0 src/mkutil/link-z80/link-z80.map | 550 + src/{ => mkutil}/link-z80/lkarea.c | 0 src/{ => mkutil}/link-z80/lkdata.c | 0 src/{ => mkutil}/link-z80/lkeval.c | 0 src/{ => mkutil}/link-z80/lkhead.c | 0 src/{ => mkutil}/link-z80/lklex.c | 0 src/{ => mkutil}/link-z80/lklibr.c | 0 src/{ => mkutil}/link-z80/lklist.c | 0 src/{ => mkutil}/link-z80/lkmain.c | 0 src/{ => mkutil}/link-z80/lkout.c | 0 src/{ => mkutil}/link-z80/lkrloc.c | 0 src/{ => mkutil}/link-z80/lksym.c | 0 src/{ => mkutil}/link-z80/n.bat | 2 +- src/{ => mkutil}/link-z80/x.bat | 0 src/mkutil/n.bat | 4 + src/mkutil/tavrasm.118/README | 320 + src/mkutil/tavrasm.118/gpl.txt | 285 + src/mkutil/tavrasm.118/src/8535def.inc | 366 + src/mkutil/tavrasm.118/src/TSV4.HEX | 464 + src/mkutil/tavrasm.118/src/a_tavr.bat | 1 + src/mkutil/tavrasm.118/src/apits.inc | 296 + src/mkutil/tavrasm.118/src/avrasm.cc | 1501 ++ src/mkutil/tavrasm.118/src/avrasm.hh | 300 + src/mkutil/tavrasm.118/src/avrlex.cc | 3202 ++++ src/mkutil/tavrasm.118/src/avrlex.l | 1428 ++ src/mkutil/tavrasm.118/src/avrlex0.inc | 495 + src/mkutil/tavrasm.118/src/avrlex1.inc | 495 + src/mkutil/tavrasm.118/src/avrparse.cc | 1753 +++ src/mkutil/tavrasm.118/src/avrparse.hh | 81 + src/mkutil/tavrasm.118/src/avrparse.y | 543 + src/mkutil/tavrasm.118/src/devices.hh | 110 + src/mkutil/tavrasm.118/src/mac.inc | 195 + src/mkutil/tavrasm.118/src/makefile | 117 + src/mkutil/tavrasm.118/src/messages.hh | 258 + src/mkutil/tavrasm.118/src/msg_de.hh | 243 + src/mkutil/tavrasm.118/src/msg_sp.hh | 245 + src/mkutil/tavrasm.118/src/msg_us.hh | 243 + src/mkutil/tavrasm.118/src/n.bat | 6 + src/mkutil/tavrasm.118/src/opcodes.hh | 227 + src/mkutil/tavrasm.118/src/semantic.cc | 1659 ++ src/mkutil/tavrasm.118/src/semantic.hh | 175 + src/mkutil/tavrasm.118/src/symbol.cc | 474 + src/mkutil/tavrasm.118/src/symbol.hh | 183 + src/mkutil/tavrasm.118/src/t.bat | 11 + src/mkutil/tavrasm.118/src/t.lnk | 4 + src/mkutil/tavrasm.118/src/tavrasm.exe | Bin 0 -> 225342 bytes src/mkutil/tavrasm.118/src/tsv4.asm | 3616 +++++ src/mkutil/tavrasm.118/src/utils.cc | 983 ++ src/mkutil/tavrasm.118/src/utils.hh | 87 + src/mkutil/touch.exe | Bin 61484 -> 73772 bytes src/sh/msh/closedir.c | 31 + src/sh/msh/closedir.rel | 49 + src/sh/msh/msh.lnk | 3 + src/sh/msh/msh.map | 169 +- src/sh/msh/n.bat | 18 + src/sh/msh/opendir.c | 44 + src/sh/msh/opendir.rel | 77 + src/sh/msh/readdir.c | 33 + src/sh/msh/readdir.rel | 95 + src/sh/msh/sh.h | 13 + src/sh/msh/sh1.c | 33 + src/sh/msh/sh1.rel | 677 +- src/sh/msh/sh2.c | 8 + src/sh/msh/sh2.rel | 9 +- src/sh/msh/sh3.c | 4 + src/sh/msh/sh3.rel | 350 +- src/sh/msh/sh4.c | 20 + src/sh/msh/sh4.rel | 912 +- src/sh/msh/sh5.c | 75 + src/sh/msh/sh5.rel | 1730 ++- src/simple/align.c | 10 + src/simple/build-b.ban | 188 +- src/simple/build-l.ban | 188 +- src/simple/cat.c | 2 +- src/simple/dosread.c | 12 +- src/simple/ls.c | 32 +- src/simple/m.bat | 4 +- src/simple/mkdir.c | 4 + src/simple/setclock.c | 2 +- src/troff/nroff.exe | Bin 143403 -> 155691 bytes uzi.bat | 5 +- 544 files changed, 193225 insertions(+), 8590 deletions(-) delete mode 100644 bin/a.sh create mode 100644 bin/appinst.bat create mode 100644 bin/appinst.sh create mode 100644 bin/appinst.ucp delete mode 100644 bin/b.sh create mode 100644 bin/banked/fsck create mode 100644 bin/banked/grlogin create mode 100644 bin/banked/mkfs create mode 100644 bin/banked/wnd create mode 100644 bin/checksum.dat create mode 100644 bin/data/0000.scr create mode 100644 bin/data/0001.scr create mode 100644 bin/data/0002.scr create mode 100644 bin/data/0003.scr create mode 100644 bin/data/0004.scr create mode 100644 bin/data/kass.scr create mode 100644 bin/data/logn.scr create mode 100644 bin/font/lcd0.cmd create mode 100644 bin/font/lcd1.cmd create mode 100644 bin/fstab.txt create mode 100644 bin/large/wnd create mode 100644 bin/mkboot.bat create mode 100644 bin/mkboot.ucp create mode 100644 bin/padding.dat create mode 100644 bin/profile.sh create mode 100644 bin/runonce.rc create mode 100644 bin/runonce.sh create mode 100644 bin/sysinit.rc create mode 100644 bin/uzboot.bin create mode 100644 bin/uzboot.gz create mode 100644 bin/uzboot.ldr delete mode 100644 bin/x.sh create mode 100644 bin/xfstab.txt create mode 100644 bin/xinittab.txt create mode 100644 bin/xmtab.txt create mode 100644 doc/EXECPATH.TXT create mode 100644 doc/gui/Gui driver.doc create mode 100644 doc/gui/Software design.doc create mode 100644 doc/gui/scr file format.doc create mode 100644 doc/rfc/rfc1700.txt create mode 100644 doc/rfc/rfc854.txt create mode 100644 doc/rfc/std5.txt create mode 100644 doc/rfc/std7.txt create mode 100644 doc/rfc/std9.txt create mode 100644 lib/relsysb/sysdebug.rel create mode 100644 lib/relsysl/sysdebug.rel create mode 100644 relnotes/20030512.txt delete mode 100644 silly.bat delete mode 100644 src/as-z80/as-z80.exe delete mode 100644 src/as-z80/as-z80.map create mode 100644 src/avr/2313def.inc create mode 100644 src/avr/4433def.inc create mode 100644 src/avr/4434def.inc create mode 100644 src/avr/7segv0.asm create mode 100644 src/avr/8535def.inc create mode 100644 src/avr/8x10.asm create mode 100644 src/avr/CFLASHV0.HEX create mode 100644 src/avr/CFLASHV1.HEX create mode 100644 src/avr/CFLASHV2.HEX create mode 100644 src/avr/CHSET00.WIN create mode 100644 src/avr/CS64V4.HEX create mode 100644 src/avr/CS64V5.ASM create mode 100644 src/avr/CS64V5.HEX create mode 100644 src/avr/ISPD.EXE create mode 100644 src/avr/ISPD.INI create mode 100644 src/avr/MAKCHR.LOG create mode 100644 src/avr/MT102V0.HEX create mode 100644 src/avr/MT102V1.HEX create mode 100644 src/avr/MT102V2.HEX create mode 100644 src/avr/TAVRASM.EXE create mode 100644 src/avr/TSV3.HEX create mode 100644 src/avr/TSV4.ASM create mode 100644 src/avr/TSV4.HEX create mode 100644 src/avr/WPO15V1.HEX create mode 100644 src/avr/WPOV0.HEX create mode 100644 src/avr/WPOV1.HEX create mode 100644 src/avr/WPOV2.HEX create mode 100644 src/avr/WPOV3.ASM create mode 100644 src/avr/WPOV3.HEX create mode 100644 src/avr/a.bat create mode 100644 src/avr/a_avra.bat create mode 100644 src/avr/a_orig.bat create mode 100644 src/avr/aa.bat create mode 100644 src/avr/api.inc create mode 100644 src/avr/apicf.inc create mode 100644 src/avr/apics.inc create mode 100644 src/avr/apilc.inc create mode 100644 src/avr/apilc8.inc create mode 100644 src/avr/apits.inc create mode 100644 src/avr/avrasm.exe create mode 100644 src/avr/cflashv0.asm create mode 100644 src/avr/cflashv1.asm create mode 100644 src/avr/cflashv2.asm create mode 100644 src/avr/charav0.asm create mode 100644 src/avr/charav1.asm create mode 100644 src/avr/chklin.asm create mode 100644 src/avr/chset00.inc create mode 100644 src/avr/chtest.asm create mode 100644 src/avr/crcsubx.asm create mode 100644 src/avr/crcsubx.inc create mode 100644 src/avr/cs128v0.asm create mode 100644 src/avr/cs64v0.asm create mode 100644 src/avr/cs64v1.asm create mode 100644 src/avr/cs64v1a.asm create mode 100644 src/avr/cs64v2.asm create mode 100644 src/avr/cs64v4-cs64v5.diff create mode 100644 src/avr/cs64v4.asm create mode 100644 src/avr/dos.asm create mode 100644 src/avr/dos.inc create mode 100644 src/avr/file.asm create mode 100644 src/avr/file.inc create mode 100644 src/avr/iocall.asm create mode 100644 src/avr/iocall.inc create mode 100644 src/avr/lcter.asm create mode 100644 src/avr/lcv0.asm create mode 100644 src/avr/lcv1.asm create mode 100644 src/avr/m192rhs.asm create mode 100644 src/avr/m192ter.asm create mode 100644 src/avr/m192v0.asm create mode 100644 src/avr/m192v1.asm create mode 100644 src/avr/mac.inc create mode 100644 src/avr/maclc.inc create mode 100644 src/avr/makchr.bas create mode 100644 src/avr/makchr.exe create mode 100644 src/avr/mega8def.inc create mode 100644 src/avr/mt102ter.asm create mode 100644 src/avr/mt102v0.asm create mode 100644 src/avr/mt102v1.asm create mode 100644 src/avr/mt102v1.asm.orig create mode 100644 src/avr/mt102v2.asm create mode 100644 src/avr/mt102v2.asm.orig create mode 100644 src/avr/prm.inc create mode 100644 src/avr/prm0.inc create mode 100644 src/avr/product/CFLASHV0.HEX create mode 100644 src/avr/product/CFLASHV1.HEX create mode 100644 src/avr/product/CFLASHV2.HEX create mode 100644 src/avr/product/CS64V4.HEX create mode 100644 src/avr/product/MT102V0.HEX create mode 100644 src/avr/product/MT102V1.HEX create mode 100644 src/avr/product/MT102V2.HEX create mode 100644 src/avr/product/TSV3.HEX create mode 100644 src/avr/product/WPO15V1.HEX create mode 100644 src/avr/product/WPOV0.HEX create mode 100644 src/avr/product/WPOV1.HEX create mode 100644 src/avr/product/WPOV2.HEX create mode 100644 src/avr/putpcx.asm create mode 100644 src/avr/set00.pcx create mode 100644 src/avr/ter.inc create mode 100644 src/avr/terlc.inc create mode 100644 src/avr/terlc8.inc create mode 100644 src/avr/terts.inc create mode 100644 src/avr/tster.asm create mode 100644 src/avr/tsv0.asm create mode 100644 src/avr/tsv3-tsv4.diff create mode 100644 src/avr/tsv3.asm create mode 100644 src/avr/wpo15v1.asm create mode 100644 src/avr/wpov0.asm create mode 100644 src/avr/wpov1.asm create mode 100644 src/avr/wpov2.asm create mode 100644 src/bin/bin2avr.exe create mode 100644 src/bin/bmp2txt.exe create mode 100644 src/bin/chs2cmd.exe delete mode 100644 src/bin/diff.exe create mode 100644 src/bin/p.exe delete mode 100644 src/bin/patch.exe create mode 100644 src/bin/pkzipc.exe create mode 100644 src/bin/tavrasm.exe create mode 100644 src/bin/txt2chs.exe create mode 100644 src/font/large.psd create mode 100644 src/font/lcd0.cmd create mode 100644 src/font/lcd1.cmd create mode 100644 src/font/n.bat create mode 100644 src/font/set01.bmp create mode 100644 src/font/set01.chs create mode 100644 src/font/set01.cmd create mode 100644 src/font/set01.txt create mode 100644 src/font/set02.bmp create mode 100644 src/font/set02.chs create mode 100644 src/font/set02.cmd create mode 100644 src/font/set02.txt create mode 100644 src/font/set03.bmp create mode 100644 src/font/set03.chs create mode 100644 src/font/set03.cmd create mode 100644 src/font/set03.txt create mode 100644 src/font/set04.bmp create mode 100644 src/font/set04.chs create mode 100644 src/font/set04.cmd create mode 100644 src/font/set04.txt create mode 100644 src/font/set05.bmp create mode 100644 src/font/set05.chs create mode 100644 src/font/set05.cmd create mode 100644 src/font/set05.txt create mode 100644 src/font/set06.bmp create mode 100644 src/font/set06.chs create mode 100644 src/font/set06.cmd create mode 100644 src/font/set06.txt create mode 100644 src/font/small.psd delete mode 100644 src/fsutil/f.bat delete mode 100644 src/fsutil/m.bat create mode 100644 src/gboot/build.ban delete mode 100644 src/gboot/gboot.asm$ delete mode 100644 src/gboot/gboot.map delete mode 100644 src/gboot/gboot.rel create mode 100644 src/gboot/uzboot.asm create mode 100644 src/gboot/uzboot.lnk create mode 100644 src/gboot/uzdata.asm create mode 100644 src/gboot/uzfile.asm create mode 100644 src/gboot/uzmain.asm create mode 100644 src/gui/0000.scr create mode 100644 src/gui/0001.scr create mode 100644 src/gui/0001.tmp create mode 100644 src/gui/0002.scr create mode 100644 src/gui/0003.scr create mode 100644 src/gui/0004.scr create mode 100644 src/gui/Copy (2) of wnd.c create mode 100644 src/gui/Copy of wnd.c create mode 100644 src/gui/Copy of wnd.h create mode 100644 src/gui/cl64180.r01 create mode 100644 src/gui/grlogin.map create mode 100644 src/gui/hello.map create mode 100644 src/gui/login.c create mode 100644 src/gui/login.map create mode 100644 src/gui/login.rel create mode 100644 src/gui/m.bat create mode 100644 src/gui/p.bat create mode 100644 src/gui/t.bat create mode 100644 src/gui/test.c create mode 100644 src/gui/test.lnk create mode 100644 src/gui/test.map create mode 100644 src/gui/test.rel create mode 100644 src/gui/trans.c create mode 100644 src/gui/trans.h create mode 100644 src/gui/trans.rel create mode 100644 src/gui/wnd.c create mode 100644 src/gui/wnd.cbackup create mode 100644 src/gui/wnd.h create mode 100644 src/gui/wnd.ihx create mode 100644 src/gui/wnd.lnk create mode 100644 src/gui/wnd.map create mode 100644 src/gui/wnd.rel create mode 100644 src/gui/wnd.xcl create mode 100644 src/gui/wnd.xls create mode 100644 src/gui/wnd.zip rename src/kernel/libc/{vendor.h => VENDOR.H} (79%) create mode 100644 src/kernel/libc/dprintf.c create mode 100644 src/kernel/libc/dprintf.h create mode 100644 src/libsys/sysdebug.c delete mode 100644 src/link-z80/link-z80.exe delete mode 100644 src/link-z80/link-z80.map create mode 100644 src/mkfont/bmp2txt.cpp create mode 100644 src/mkfont/bmp2txt.exe create mode 100644 src/mkfont/chs2cmd.cpp create mode 100644 src/mkfont/chs2cmd.exe create mode 100644 src/mkfont/hyfile.cpp create mode 100644 src/mkfont/hyfile.h create mode 100644 src/mkfont/hyfs.cpp create mode 100644 src/mkfont/hyfs.h create mode 100644 src/mkfont/hyimage.cpp create mode 100644 src/mkfont/hyimage.h create mode 100644 src/mkfont/hymb.cpp create mode 100644 src/mkfont/hymb.h create mode 100644 src/mkfont/n.bat create mode 100644 src/mkfont/txt2chs.cpp create mode 100644 src/mkfont/txt2chs.exe rename src/mkutil/{cr.exe => CR.EXE} (51%) create mode 100644 src/mkutil/as-z80/as-z80.exe rename src/{ => mkutil}/as-z80/as-z80.lnk (100%) create mode 100644 src/mkutil/as-z80/as-z80.map rename src/{ => mkutil}/as-z80/asdata.c (100%) rename src/{ => mkutil}/as-z80/asexpr.c (100%) rename src/{ => mkutil}/as-z80/aslex.c (100%) rename src/{ => mkutil}/as-z80/aslist.c (100%) rename src/{ => mkutil}/as-z80/asmain.c (100%) rename src/{ => mkutil}/as-z80/asout.c (100%) rename src/{ => mkutil}/as-z80/assubr.c (100%) rename src/{ => mkutil}/as-z80/assym.c (100%) rename src/{ => mkutil}/as-z80/asxxxx.h (100%) rename src/{ => mkutil}/as-z80/n.bat (93%) rename src/{ => mkutil}/as-z80/tz80.asm (100%) rename src/{ => mkutil}/as-z80/tz80l.asm (100%) rename src/{ => mkutil}/as-z80/z80.h (100%) rename src/{ => mkutil}/as-z80/z80adr.c (100%) rename src/{ => mkutil}/as-z80/z80ext.c (100%) rename src/{ => mkutil}/as-z80/z80mch.c (100%) rename src/{ => mkutil}/as-z80/z80pst.c (100%) rename src/{ => mkutil}/as-z80/z80pst.c$ (100%) create mode 100644 src/mkutil/avra-0.8/COPYING create mode 100644 src/mkutil/avra-0.8/ChangeLog create mode 100644 src/mkutil/avra-0.8/README create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.amiga.gcc create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.amiga.sas create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.emx create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.linux create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.win create mode 100644 src/mkutil/avra-0.8/SOURCE/Makefile.win32.mvc create mode 100644 src/mkutil/avra-0.8/SOURCE/args.c create mode 100644 src/mkutil/avra-0.8/SOURCE/args.h create mode 100644 src/mkutil/avra-0.8/SOURCE/avra.c create mode 100644 src/mkutil/avra-0.8/SOURCE/avra.dev create mode 100644 src/mkutil/avra-0.8/SOURCE/avra.exe create mode 100644 src/mkutil/avra-0.8/SOURCE/avra.h create mode 100644 src/mkutil/avra-0.8/SOURCE/coff.c create mode 100644 src/mkutil/avra-0.8/SOURCE/coff.h create mode 100644 src/mkutil/avra-0.8/SOURCE/device.c create mode 100644 src/mkutil/avra-0.8/SOURCE/device.h create mode 100644 src/mkutil/avra-0.8/SOURCE/directiv.c create mode 100644 src/mkutil/avra-0.8/SOURCE/expr.c create mode 100644 src/mkutil/avra-0.8/SOURCE/file.c create mode 100644 src/mkutil/avra-0.8/SOURCE/macro.c create mode 100644 src/mkutil/avra-0.8/SOURCE/map.c create mode 100644 src/mkutil/avra-0.8/SOURCE/misc.h create mode 100644 src/mkutil/avra-0.8/SOURCE/mnemonic.c create mode 100644 src/mkutil/avra-0.8/SOURCE/n.bat create mode 100644 src/mkutil/avra-0.8/SOURCE/parser.c create mode 100644 src/mkutil/avra-0.8/SOURCE/stdextra.c create mode 100644 src/mkutil/avra-0.8/TODO create mode 100644 src/mkutil/avra-0.8/avra.dev create mode 100644 src/mkutil/bin2avr.c create mode 100644 src/mkutil/bin2avr.exe rename src/{ => mkutil}/link-z80/aslink.h (100%) create mode 100644 src/mkutil/link-z80/link-z80.exe rename src/{ => mkutil}/link-z80/link-z80.lnk (100%) create mode 100644 src/mkutil/link-z80/link-z80.map rename src/{ => mkutil}/link-z80/lkarea.c (100%) rename src/{ => mkutil}/link-z80/lkdata.c (100%) rename src/{ => mkutil}/link-z80/lkeval.c (100%) rename src/{ => mkutil}/link-z80/lkhead.c (100%) rename src/{ => mkutil}/link-z80/lklex.c (100%) rename src/{ => mkutil}/link-z80/lklibr.c (100%) rename src/{ => mkutil}/link-z80/lklist.c (100%) rename src/{ => mkutil}/link-z80/lkmain.c (100%) rename src/{ => mkutil}/link-z80/lkout.c (100%) rename src/{ => mkutil}/link-z80/lkrloc.c (100%) rename src/{ => mkutil}/link-z80/lksym.c (100%) rename src/{ => mkutil}/link-z80/n.bat (93%) rename src/{ => mkutil}/link-z80/x.bat (100%) create mode 100644 src/mkutil/tavrasm.118/README create mode 100644 src/mkutil/tavrasm.118/gpl.txt create mode 100644 src/mkutil/tavrasm.118/src/8535def.inc create mode 100644 src/mkutil/tavrasm.118/src/TSV4.HEX create mode 100644 src/mkutil/tavrasm.118/src/a_tavr.bat create mode 100644 src/mkutil/tavrasm.118/src/apits.inc create mode 100644 src/mkutil/tavrasm.118/src/avrasm.cc create mode 100644 src/mkutil/tavrasm.118/src/avrasm.hh create mode 100644 src/mkutil/tavrasm.118/src/avrlex.cc create mode 100644 src/mkutil/tavrasm.118/src/avrlex.l create mode 100644 src/mkutil/tavrasm.118/src/avrlex0.inc create mode 100644 src/mkutil/tavrasm.118/src/avrlex1.inc create mode 100644 src/mkutil/tavrasm.118/src/avrparse.cc create mode 100644 src/mkutil/tavrasm.118/src/avrparse.hh create mode 100644 src/mkutil/tavrasm.118/src/avrparse.y create mode 100644 src/mkutil/tavrasm.118/src/devices.hh create mode 100644 src/mkutil/tavrasm.118/src/mac.inc create mode 100644 src/mkutil/tavrasm.118/src/makefile create mode 100644 src/mkutil/tavrasm.118/src/messages.hh create mode 100644 src/mkutil/tavrasm.118/src/msg_de.hh create mode 100644 src/mkutil/tavrasm.118/src/msg_sp.hh create mode 100644 src/mkutil/tavrasm.118/src/msg_us.hh create mode 100644 src/mkutil/tavrasm.118/src/n.bat create mode 100644 src/mkutil/tavrasm.118/src/opcodes.hh create mode 100644 src/mkutil/tavrasm.118/src/semantic.cc create mode 100644 src/mkutil/tavrasm.118/src/semantic.hh create mode 100644 src/mkutil/tavrasm.118/src/symbol.cc create mode 100644 src/mkutil/tavrasm.118/src/symbol.hh create mode 100644 src/mkutil/tavrasm.118/src/t.bat create mode 100644 src/mkutil/tavrasm.118/src/t.lnk create mode 100644 src/mkutil/tavrasm.118/src/tavrasm.exe create mode 100644 src/mkutil/tavrasm.118/src/tsv4.asm create mode 100644 src/mkutil/tavrasm.118/src/utils.cc create mode 100644 src/mkutil/tavrasm.118/src/utils.hh create mode 100644 src/sh/msh/closedir.c create mode 100644 src/sh/msh/closedir.rel create mode 100644 src/sh/msh/opendir.c create mode 100644 src/sh/msh/opendir.rel create mode 100644 src/sh/msh/readdir.c create mode 100644 src/sh/msh/readdir.rel diff --git a/bin/a.sh b/bin/a.sh deleted file mode 100644 index fac355b1..00000000 --- a/bin/a.sh +++ /dev/null @@ -1 +0,0 @@ -cp std-chs /dev/lcd0 diff --git a/bin/appinst.bat b/bin/appinst.bat new file mode 100644 index 00000000..09788264 --- /dev/null +++ b/bin/appinst.bat @@ -0,0 +1,2 @@ +ucp < appinst.ucp +copy uzidisk.dat e:\ diff --git a/bin/appinst.sh b/bin/appinst.sh new file mode 100644 index 00000000..4c6d489a --- /dev/null +++ b/bin/appinst.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +echo "" +echo "Installing application program" +echo "" + +rm -f /wnd/*.scr +cp -v /usr/boot/inst/wnd/*.scr /wnd + +rm -f /bin/grlogin /bin/test +cp -v /usr/boot/inst/bin/grlogin /usr/boot/inst/bin/test /bin +align -v /bin/grlogin /bin/test + +echo "" +echo "Finished installing application" +echo "" + diff --git a/bin/appinst.ucp b/bin/appinst.ucp new file mode 100644 index 00000000..d875517b --- /dev/null +++ b/bin/appinst.ucp @@ -0,0 +1,29 @@ +root b: +cd /boot +mkdir inst +get appinst.sh +chmod 755 appinst.sh +cd /boot/inst +mkdir bin +mkdir wnd +cd /boot/inst/bin +bget banked\grlogin grlogin +chmod 755 grlogin +bget banked\test test +chmod 755 test +cd /boot/inst/wnd +bget data\logn.scr logn.scr +chmod 644 logn.scr +bget data\0000.scr 0000.scr +chmod 644 0000.scr +bget data\0001.scr 0001.scr +chmod 644 0001.scr +bget data\0002.scr 0002.scr +chmod 644 0002.scr +bget data\0003.scr 0003.scr +chmod 644 0003.scr +bget data\0004.scr 0004.scr +chmod 644 0004.scr +bget data\kass.scr kass.scr +chmod 644 kass.scr +exit diff --git a/bin/b.sh b/bin/b.sh deleted file mode 100644 index 33ea9a3f..00000000 --- a/bin/b.sh +++ /dev/null @@ -1 +0,0 @@ -cp ned-chs /dev/lcd1 diff --git a/bin/banked/cat b/bin/banked/cat index 86a3fa225e70e8ae873f98aa5afbb984956fafe5..b94c628da711dba1e428b28eb09ef5edfce3477f 100644 GIT binary patch delta 12 TcmX@fc9LzvYetEUZ(^AMBY6cc delta 12 TcmX@fc9LzvYetccZ(^AMBV`3E diff --git a/bin/banked/diff b/bin/banked/diff index 11ee6f511cdd3054b53faa277e969911e8d2b291..acf0b6e5365cd0a512fedc645cfb9d507508a2ac 100644 GIT binary patch delta 11503 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 Xje|$#z&SyZ_NHx{l)j$KS?m5kyXrCo delta 11053 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 diff --git a/bin/banked/ed b/bin/banked/ed index 93cbad33431c21ce18f7e174c8205ab0f9b9c9d1..79387c496c24f277653c53dd773032a1324364fc 100644 GIT binary patch delta 8998 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 literal 0 HcmV?d00001 diff --git a/bin/banked/grlogin b/bin/banked/grlogin new file mode 100644 index 0000000000000000000000000000000000000000..b235271acc72c358ca7bdb0f85f09ca5238ba767 GIT binary patch literal 20399 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 K^U19xb^ix6Nr&_R delta 6383 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 delta 3106 zcmai0eNa<`Ft&A;8O<@5GrAQ!|R z>2s&|PPX=5dB{gH9{vfYsIrvQvBVNo%wSpY|zHdp8UcDP6yh<{KSVmr1%E$T9t)e-e zWr{qA37z0McmXBjKc`;IR+irE5ZZYLgnTelB>csxzFFuGo}PRvST3a7q`$=bONAReCcZ@)It zEvdUpEHmKa->YD27EBYQ?hdg`gQOZ?mUp0fT&zghEmlO#4e}u|bC4D&m=uLnM}Gpv zxFJB$byIF+q&(bsG!KE{pDdR^WEn^-gg?V9--L-Gjh(Y#S=f5IREOzym!QZV>XSvV zw-)!DY@R8}Q=wb^YB>Ym&siWI6#D-FY!7Ku5PMkQ_ll+Op)zPWVx?$7M644{sBiUy zwGm2siRqvFXn6xzF0up2%aJyg*n=J+h5I7jtmHXAML0@8j~@tn$MM_B6sW;D!Db@OgK)J%`TMVwJH-`4yc|%NAZLz{{=C+U1PeG0DG{FP%kXS4)Hy~`+V+? zt1>S3lP;EY1`#JqTtSAMrR(lj;|Jo(2#xyVDqhJDGfPZCa_3afrAWLZLW@-RP{h;d zPxx}g4S0VivLRXC4E{n>nU!+v^+8D__Vgn4xiT7j$7G3iaTQCv-+^c8!9lu7zg z0fqjPUUhmnfDfowKy+u+r?Pjo_;t^^7ig>U`os{tq|+A=uRm7&W>jpv7znQb$Gybl zlP_`^pNleXI!Ad2*--M|^gHKJx8R&(x>byN)dn!zN=;oo@6M(ET!(7V?%#O}Z|J)VsC0g4>Q=ICU~14p!;{k8_b6+MCq@amWZ<%breVAKcq z0%!;~#H@p~oruYM+@UXKWx0xGjwW-y=GlXLy@DZ@E;@sXE(${kUF5nTIOY%T)$iPg zo?X;U{U=>CHBf&Fz^})qMh*S9_@h|E06_K~*liT(a*mqApN6{kf* zxFYT>3dOIB0>63)% zNfSPrpr?S~Kmd?i9Cjk$9|<~S!oCC!o?K!IXR?yEU}Be1O;LeBbD{2il*i|(XG^>ToW7|*^+j34%& zCa$qddvG%Un!ibz&k&P~*ZBKzI_=F%T0Y{>A|39~XVa;7RG%IxW{DI8>w-vu%zbSW z{!DKGezU?#B*&`+4ZF~Yt%8;=JA`(09^VnHsC4wXC*MJ^xt*G^yqOmC(uq@EqCP?? zGVQ=QX-`*PqZe9Yk~AJY6W4)e0o_XK#09+|*DRCMuUdP5@GVuf37<-PlKp%e{xmH| zD~NrZ%k*nqymmhj%R{g(jOtcoBGiQ|3@@>>&3MGnjO3$H>3a}+y9Ezr+=Br2XX>D> zoyts5e&wJ&?+fbo5Wbd4dtPFeHu}&Ools#Yv@!4`ZuD+RUS=`39e zc91&i&E(xZ3=_hXIp($?htiSgFgWrZ#W+2?L+$T&_ekfz#U|K--_K60`D6UiofVxgjn{3iCB?YKQ( q18r=7erk+V1u4+z=xDJ2*>*gU{{lLJH3eF@va1TZVK|N!{Q5s?gSg-T diff --git a/bin/banked/mkdir b/bin/banked/mkdir index 070612392cd05a694bdde29fdeaaf1b0e874a95c..6e7b9cc8c6031e9904168f690449e8121bf24737 100644 GIT binary patch delta 14 VcmbQnGmU2hFB9Yc&3sH8EC3;)1JeKi delta 14 VcmbQnGmU2hFB9Xo&3sH8EC3(t1Bw6u diff --git a/bin/banked/mkfs b/bin/banked/mkfs new file mode 100644 index 0000000000000000000000000000000000000000..2deb3d6aa3aa24ae2e9c626a9ea3ab71cff933b8 GIT binary patch literal 15694 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 Wa>5y(NHysXe@okqMdq(v^nU>O`vD#R literal 0 HcmV?d00001 diff --git a/bin/banked/msh b/bin/banked/msh index 794803df181d0fe08e82bdbcd563d6b44ef18892..116e9021f895a847323f64a6e04a47d6676290cc 100644 GIT binary patch literal 42333 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 C=3!<4 diff --git a/bin/banked/tr b/bin/banked/tr index 08a15846deb468f7a18ed46cb8bbd11358a25e3b..b7215245c721e79de10c8ff155ad8e6a5ad40c9e 100644 GIT binary patch delta 3830 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 delta 3537 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 b_7Fb+l?=yS$q))xII+Z7q)L>tRLTDZKxFbN literal 0 HcmV?d00001 diff --git a/bin/boot.bin b/bin/boot.bin index 003e39766a13c597db04462790d70a5de38a9310..a38760367638bf02983db0866f709c20b9c01571 100644 GIT binary patch delta 25 gcmZqRZ{QbjHgk0|Fg7qXurx9-wlp-@C{Vx-085qy%K!iX delta 25 gcmZqRZ{QbjwlFp@Fg7qYG&C?VH8L^TC{Vx-07$U~pa1{> diff --git a/bin/checksum b/bin/checksum index e8bc3d32280587ac5715e8c167af852fa3a1922e..26858fb86afa13d0a7d42fa12a1aebb9e35a9529 100644 GIT binary patch literal 128 zcmcCCFtju@wDNWh@^kgkbMo|KU|=vZFfjv)Ir;mCKt&iBObuL3 HrKkh|h;b5} diff --git a/bin/checksum.dat b/bin/checksum.dat new file mode 100644 index 00000000..172cee84 --- /dev/null +++ b/bin/checksum.dat @@ -0,0 +1,2 @@ +C A:KERNEL.BIN +C A:BOOT.BIN diff --git a/bin/data/0000.scr b/bin/data/0000.scr new file mode 100644 index 0000000000000000000000000000000000000000..850c720851aa45376a7c7a1679b93f79b8654997 GIT binary patch literal 276 zcmYL?yAFat5Jm5}f|h&&iM>Je3(&%MG-9-L#TAXnCcDt<4LDQCv2h0RB;nAM>x0x8-AoT=M3i!K*Mex|``hSZsg3leC z_i6JcF0aR4N6^=?m$cUP_JczomnP}I=UU%yZ&lV9E1}0>JRI%$84x^Y&KE$j@Xk*c#YE?J7JI6 zOyhjV&e&5*e6=}X{cX8*>K_Iz#B}RLu(&X;!z|IbGA-}pGH_B$F%er4eRKogMemoi zt9(2#=?Hi9N#^CFerhT*)e807+|(5{W=_@O{goC}H$=;4WRdp~IFM%d n^8GLPxG?3z{{AeE2mUrW=*N_ntBPQ+Z>&WU=Lfu-lxcw7$I~?^e2|7U^o?|=i%$tLD5C#~B?E%6d8jiyG=6`7PPc{Gm literal 0 HcmV?d00001 diff --git a/bin/data/0003.scr b/bin/data/0003.scr new file mode 100644 index 0000000000000000000000000000000000000000..749c1d97adde7d86a3062d36c4a83bbb9d9bdd31 GIT binary patch literal 460 zcmZ9|OHKko5XSMZW(EXBY{wlZATz=!<8v{a77jo-g=_T`Ud{(TxDEegf>!87r}ImF zsj7aeHPYURGP9o@o@piv5wc%zNr(xy@s@@taP2K4i+y?Pkj1{eb;+h?@7@l`Vjtdm zWU)_ged;o^H*bg3VLfk0VJ@0*wda-Hq?l2+v>jrD5K}&({3BiH7-Qdww;{$Jg|`!o z!pd8~=+SsPWnXOSEf1?)<9}&ix4P54u5_&%T{2zGG!F|cUml-TYNA4w8l7tk6M`Jm literal 0 HcmV?d00001 diff --git a/bin/data/0004.scr b/bin/data/0004.scr new file mode 100644 index 0000000000000000000000000000000000000000..238ad7bfa5ab329b232738a5f10cbf1394e8cdb0 GIT binary patch literal 946 zcmZA0xidpi0EO}MLP)Ha*!P`6kw|Q%E4IiYVlQ<%Gw7-P(>^o88L#}kJDKy{d3l-C zl>R+YNs<)Wm{UPXh)}ZSmI^V272P^Q?7&KHogsE&+ivL))7Xw%SBPEMu3LAA-PoR6 zCd3T3@0JZQi{;&VLKFj=ZoPD1w{CrOU`KBKbYPcm19V_lZi94S_ilj>?AmRJ4(!Zr zm=3JrmZJl^a2uh6OFeKKr2}iZjnRRX-Nxy_j@>5cz)svI>A+6irs%*bZqsyN=Wa7} zU{$wSI9n=dry9FS$VAouCpikXrKGk_g^4pIk(WZ9OpJdYeT>5+HVS+E~=z$?Pynf+UI0b vw>r|Lu5_#KK;y+hC&j1U7a8ui%S%_Fgc{6r0_X z@666jrOa0D--`9CJI-kaTc7W<0=8-IGg)S}h}BYuGvsDA;!@QG{merF8>cMu(11-+ zmV3xEvwq47T-YFG4P4kTWe2!?+)ddbE-WroRh*@X3+tuq2$unGQ+A9Ciwjj1-IfP~ z{akv@UfK8LItVtmZBDRL4~%DDSL9afjc#zy_?KLB7mNMe@9XC_S3jOy|C8*}BaJmt eUjq%*#q1I3=<&T=EcNoX(EPJp>S3nm@jx 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 literal 0 HcmV?d00001 diff --git a/bin/fstab.txt b/bin/fstab.txt new file mode 100644 index 00000000..de99268e --- /dev/null +++ b/bin/fstab.txt @@ -0,0 +1,2 @@ +/dev/hd0 / rw +/dev/hd1 /usr rw diff --git a/bin/group.txt b/bin/group.txt index a0038f77..4c18bd12 100644 --- a/bin/group.txt +++ b/bin/group.txt @@ -1,4 +1,5 @@ root::0:root bin::1:bin tty::6:tty -users::100:users +operator::100:Operators +manager::101:Managers diff --git a/bin/inittab.txt b/bin/inittab.txt index b2991151..57df377c 100644 --- a/bin/inittab.txt +++ b/bin/inittab.txt @@ -1,4 +1,6 @@ -# Hytech initialisation table to format the RAM filesystem +# Hytech initialisation table for running system -/boot/mkramfs.sh +@/etc/rc.d/rc.sysinit +@/etc/rc.d/rc.runonce +/bin/grlogin diff --git a/bin/kernel.bin b/bin/kernel.bin index b670a1c0148c447b9f79184d6b5c22a24406e575..0b4c166f7ce3d5a30ba8c44a86e7196c5eea0a16 100644 GIT binary patch literal 81141 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 J&t5b7{vTx{ct`*M literal 81008 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 diff --git a/bin/large/cat b/bin/large/cat index e1f60193ed28ad427d23950cd0099fe74ccc151f..5eb63c1250dbac9f2798fb368c0bbf838bf31df3 100644 GIT binary patch delta 12 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 delta 9851 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 delta 9889 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 delta 6284 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 diff --git a/bin/large/mkdir b/bin/large/mkdir index f78e869fb25423f6252d25aea3dcf9e5671dbb9c..98bb0418fb13af827bb59fcb09902426ec94b960 100644 GIT binary patch delta 14 VcmbQsJ(qh!G9%;v%_)qQEC43-1iAnK delta 14 VcmbQsJ(qh!G9%-*%_)qQEC3}w1aSZW diff --git a/bin/large/mkfs b/bin/large/mkfs index dbe86c9515a9b1e654ab2cbf884eebbe8616ad9a..9c4ebdff2fde0252845168e7ee8e77668cfd0e69 100644 GIT binary patch delta 4099 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 delta 3882 zcmbVPeNa@_6@Pbk`B)*qis14g?0YM+tf-6PiUhZaWMd#~s3L=q(xfx4HnucT2u(s3 zNHk5fO{_O064N-SfH4X&8dw;^tl4$i#Jm`jG93elgk;vKr5n4gF$RI{x$i9>ZD;aF z*?I5Xd+zzV=l;$)7ue<5W%!_jaD{6*ZUM(NbIqpyPd%Uh`HF9|ssDm+!^-|qA-iAP zy>HC@<{88LicMuMZ*hUIDsMo{+~c<>PQ7c0g&GCem0mvmv{$@+(C-(&pnRFjoz*Pn zG+zudANg%)zyH#&4T=1N@|xzhQ@nmalh-e5TQr0d-)!SKg%@n$ zU{(8=#KZ{X8e?Wq+Q)(OkFa0A2r}aPn1NzxUY4hI$ejlgi~np&Wno=68TxRt#RYZ$fLgz?00;ks+J70XIJgP5-x`bPo1rpwQ|>)D#)Fgyc3$G0DgcI@y_&`9g3>a-L$1PGXeH8V+VvEaIKpVo>5*xF)Eaxuuoc=PHp!Um}2?FIh-;h)X;PDVjjY*ZEN8b zO2LYPA+ByF+8SIiP*MsyRC z)T23(NlxS9>YPXiaWN|=sl+Tol~8jV?B9D=fbAAozYA_@$KFw?YG0;O@wkftgTEP! zj)uefPIpF`2v1*+O2p#V8|m74Eo4yxgA|v#hn2p3t z*Jz$60(EH~B<*z3e0?M~piQs(p>7Il1GG9Nsc4W-;JhN&!A{ffUi1tW{;7a*#3{1` zAuag>jw$E~7*;~{6qEzFD3OvUNhCT*|tu5$vB(LgY zl|=8j#no$ys5sJog_$b;wXLL(O$J)T(w3Q3 z_1smQ476whoTz{K%7qA7X#`VBD`U;%J^K6Du1aisa`S%b9bGt>6+D=g*m9)S_Swst z^ltI9mwi>{elh+i)G44=Ifev{k&#i3kCT1;0Aur20KHgSQWz9|iMB3SR>Axa8rWJY zZtl=yUt<{`WO5%5F5(7bg4+#JFoa%$KyjXs2()=T&<*u>pnifWqA780D*&C|tN2z1Sdo>(2`mE`~R1MX*OUHm}r&K-VPnOwHk=L-9AZ z`VOmJi+ru=@E5Ivtq--j-|8nT7L$?myIFx$$t3!W0Bx}QNse;-N zxBoDhj}tJrb8i2u@{$!EJGT zezrQfjgYSorW7FmhLpQ8=NeO%Bv*K#ZUSm2F*7t^o+tzJq=zr_2<0B3f?i0;AVqX6 z#Y8G-a%uv;&8a_H*m*>54_3W>hn!Q<}vb)amsZVBn6Cv?J=naUt1 zi!rAkQ#Ts%DMJnC;yupc{>6;NekMJlEP7p^%HOFBG3%8a+$6X1ag^H z3hVB#^dvkA*%J&flkT^Ux*Ly@qHd-T?-7{zY_z$9RC?4i^`!m{KN@H8LzgZN;=Mp$ zQuv)IR4~)81%bgWOus1EbzF{(UT@P|5jZ zX^P2{R5a+A%)XW2Wgae+Nz-|XGPS(p&btA{_j5Ok=tr@Gy$MkZ> zV`yl-F&W?0()%gnFL8X`h*xxaV(AVXYcdxT(^+%oj}_55t4yX mvblvN)9Ll_2J diff --git a/bin/large/tr b/bin/large/tr index 35d2fdb6a37213650c0f2e65e46dce4135825662..b5e71100dc5771f7add6e4d02c41b3323090e017 100644 GIT binary patch delta 3176 zcmZWreNaa8(f{cpBc2U-GmAYlh7F(j-@>K~%cT145 z*4hrRZ~;Fmq9FLeNAe8Bo!xcDnqha;zMb(8?C5xR>#$+A%cO0rS^*(@?t7qgHW|ph z=bm%!Ip_B~=e>KsZ7Ve1>}F6~Dnc;`)uP&Cg6I-GcYMD-CVc73{#ec2c1U6dv9xkIL6^6r7W=qdAX-^)%|LQYGZ#w91abdVmH*gREjqlmUZAF<#xKg zs@%%38V6R+JFI-wDaO^|x_KLFRy)PY+O-M3oHb4k?yIa#O(MAy#4u$XE>;Re zay!R^X2IO}@Y9g3(OBRVh~z4WMX9pz)_wXG0q;_6Py7++-Q6I&Z0b(Nk1 z3N(;++cp8f7knGnh5<#uml7&OS&Q^1XVq$`6{QHMrOpZc3t^U7kb;u?t3zhHL@L<3 zX7=21sG{5@V_XMfTWlE+EFuW4vK!!`svFyd!u$b z04_-`ODsVu`{*H~iWIOUFG%#Cnk$d|6>lF6+L9G{$!QGc0s&8az1)*L4}B~z^LXp; zAi?{Ay4fQy7c9BPNnx4nrjz)su)V<<&UpK%0)HQ-owu?!4sjVyJQl{+WC(I2sCNl) zwYr4&EH^x44aNnG+2!u z@X#LtW*|{)tR66iafO2YDO1JUpQ0+YwO-6WbLVC#44h$z)+^q_#~0)=5Ab&jc-2tD zrws=i+8f+h8~zT1u{}IftpIk>AqKvK!LtYB+u@69Ha0_LNu`3=l;pP3ZcH&XKtdD5 zHaU|7lvSE1u}!3Of>WiYNQY|FXFFa(v-1MU6irO%phJCt6$+d3+Pc;Q9(51Z;@g&%)0aaml*aCQbOuMsrm0RdObB9HJk86So+Qn-qWdczJzTMa9wea2N_fTuLvXf zyZD5tk<%|zgV}N`>oiW#E@m@N;|%R8W)#1#eU08as6EQ=J%h6n@_|3663#9?DlC%; z1SQrVrH!I*6v*uzQ04j*%ZTMkSf_9jThdJ@l zMLJCV9zx$$hPnCD=*UPkvM|t!5_huNOZYE|YnfL3IPn~F8MiJz&OE^@lj0TrQ=Wh0 zoTSaVmM&7NAXcS)I{C(qt}K@HPZ9UD?!^Gc&ZHlHliO9)SXyKgUMz<>4F&5IfG6$c3F{pi<`&M#XHSOV5q~Fs zOoVWx7f{gWSd=~tZOw1n^iygG@C&apXes77hJ>UHCpSG+bkvv0&U6-P*{*%Lb*~Ob0FpU;9Un(t}AMiE0Qag>k5mD_f*<+$?q=L z6&F_6Y-O+vMcHM=#f9Y+MQHPZ^1{-0i}oX1*)Md-6`{zwzpO-F?J3u-lkAG*MJPh4 zdr&G$J%CboqkmqG?%CK=((`f8K#!+qq-VUx)SKV?$KIjduX~^MuIfuq?)zn5QD1dm zOJ85#P~SIw&-&u}U+K5@pXe9+5qu&H>x5l`>+_W?v$b8A`CdUNk{-@{+ON!fT@2FA U3gPz;g8Z!(SfrmLhekvH12PQ6$N&HU delta 2969 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 rS5)ic uzboot.gz + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/bin/mkboot.ucp b/bin/mkboot.ucp new file mode 100644 index 00000000..f8c52ec1 --- /dev/null +++ b/bin/mkboot.ucp @@ -0,0 +1,130 @@ +root b: +cd / +mkdir bin +mkdir boot +mkdir dev +mkdir etc +mkdir home +mkdir lib +mkdir mnt +mkdir root +mkdir tmp +mkdir usr +mkdir var +cd /bin +bget banked\align align +chmod 755 align +align align +bget banked\cat cat +chmod 755 cat +align cat +bget banked\chgrp chgrp +chmod 755 chgrp +align chgrp +bget banked\chmod chmod +chmod 755 chmod +align chmod +bget banked\chown chown +chmod 755 chown +align chown +bget banked\cp cp +chmod 755 cp +align cp +bget banked\echo echo +chmod 755 echo +align echo +bget banked\fsck fsck +chmod 755 fsck +align fsck +bget banked\init init +chmod 755 init +align init +sln cp ln +bget banked\login login +chmod 755 login +align login +bget banked\ls ls +chmod 755 ls +align ls +bget banked\mkdir mkdir +chmod 755 mkdir +align mkdir +bget banked\more more +chmod 755 more +align more +bget banked\mount mount +chmod 755 mount +align mount +bget banked\msh msh +chmod 755 msh +align msh +sln cp mv +bget banked\reboot reboot +chmod 755 reboot +align reboot +sln cp rm +bget banked\rmdir rmdir +chmod 755 rmdir +align rmdir +sln msh sh +bget banked\ualign ualign +chmod 755 ualign +align ualign +bget banked\umount umount +chmod 755 umount +align umount +cd /boot +bget kernel.bin +align kernel.bin +cd /dev +umask 000 +mknod hd0 60666 0 0 +mknod hd1 60666 0 1 +mknod null 20666 1 0 +mknod zero 20666 2 0 +mknod kmem 20666 3 0 +mknod tty 20666 4 0 +mknod tty0 20666 4 1 +mknod tty1 20666 4 2 +mknod tty2 20666 4 3 +mknod tty3 20666 4 4 +mknod scale 20666 4 5 +mknod lcd0 20666 4 6 +mknod lcd1 20666 4 7 +mknod lpr0 20666 4 9 +umask 022 +sln tty0 cognitive +sln tty1 barcode +sln tty1 console +sln tty2 atmodem +sln tty3 apilan +sln lpr0 printer +cd /etc +get group.txt group +get passwd.txt passwd +get mtab.txt mtab +get fstab.txt fstab +get inittab.txt inittab +get profile.sh profile +mkdir rc.d +cd /etc/rc.d +get sysinit.rc rc.sysinit +chmod 755 rc.sysinit +get runonce.rc rc.runonce +chmod 755 rc.runonce +cd /home +mkdir downingn +chown 60 downingn +chgrp 100 downingn +mkdir morsinkj +chown 70 morsinkj +chgrp 100 morsinkj +mkdir buijsr +chown 80 buijsr +chgrp 100 buijsr +mkdir 90 +chown 11 90 +chgrp 101 90 +cd /lib +get liberror.txt +exit diff --git a/bin/mkramfs.sh b/bin/mkramfs.sh index 6d037695..f8e4ce23 100644 --- a/bin/mkramfs.sh +++ b/bin/mkramfs.sh @@ -5,9 +5,7 @@ cd /boot/skel mkfs -l -q -v -y /dev/hd0 1536 30 mount /dev/hd0 /mnt cp -r -v * /mnt -align -s -v /mnt/bin/* -cp -v /boot/kernel.bin /mnt/boot -align -v /mnt/boot/kernel.bin +align -s -v /mnt/bin/* /mnt/boot/kernel.bin umount /dev/hd0 reboot diff --git a/bin/mtab.txt b/bin/mtab.txt index de99268e..070565f9 100644 --- a/bin/mtab.txt +++ b/bin/mtab.txt @@ -1,2 +1 @@ /dev/hd0 / rw -/dev/hd1 /usr rw diff --git a/bin/n.bat b/bin/n.bat index 3d1b1373..e49fa4f4 100644 --- a/bin/n.bat +++ b/bin/n.bat @@ -1,15 +1,33 @@ +@rem the following should not be done here - call it manually when necessary +@rem call mkboot.bat + +@rem the following should be uncommented to use the new style bootstrap 'bomb' +copy/b uzboot.ldr + uzboot.gz uzboot.bin + +@rem the following should be uncommented to use the old style bootstrap script +@rem copy kernel.bin uzboot.bin + +md \nlddl +copy checksum.dat \nlddl +copy checksum.dat \nlddl\crc.dat +copy boot.bin \nlddl +copy uzboot.bin \nlddl\kernel.bin +set country=NLD +del \nlddl\checksum +crc +copy \nlddl\checksum . + del uzidisk.dat touch uzidisk.dat @if errorlevel 1 goto failure -rem mkfs -b -f -q -v -y uzidisk.dat 8192 163 -rem mkfs -l -f -q -v -y uzidisk.dat 8192 163 mkfs -f -q -v -y uzidisk.dat 8192 163 @if errorlevel 1 goto failure ucp < n.ucp @if errorlevel 1 goto failure fsck -y uzidisk.dat @if errorlevel 1 goto failure -copy uzidisk.dat e:\ +call appinst.bat +@rem copy uzidisk.dat e:\ @echo SUCCESS @goto done diff --git a/bin/n.ucp b/bin/n.ucp index 64650e74..213a1d2c 100644 --- a/bin/n.ucp +++ b/bin/n.ucp @@ -215,7 +215,11 @@ chmod 755 yes cd /boot get mkramfs.sh chmod 755 mkramfs.sh -bget kernel.bin +get newkrnl.sh +chmod 755 newkrnl.sh +get runonce.sh +chmod 755 runonce.sh +bget uzboot.bin kernel.bin bget boot.bin bget checksum ln checksum crc @@ -245,6 +249,10 @@ bget banked\chown chown chmod 755 chown bget banked\cp cp chmod 755 cp +bget banked\echo echo +chmod 755 echo +bget banked\fsck fsck +chmod 755 fsck bget banked\init init chmod 755 init sln cp ln @@ -272,23 +280,24 @@ chmod 755 ualign bget banked\umount umount chmod 755 umount cd /boot/skel/boot -get newkrnl.sh -chmod 755 newkrnl.sh +bget kernel.bin cd /boot/skel/dev +umask 000 mknod hd0 60666 0 0 mknod hd1 60666 0 1 -mknod null 20644 1 0 -mknod zero 20644 2 0 -mknod kmem 20644 3 0 -mknod tty 20644 4 0 -mknod tty0 20644 4 1 -mknod tty1 20644 4 2 -mknod tty2 20644 4 3 -mknod tty3 20644 4 4 -mknod scale 20644 4 5 -mknod lcd0 20644 4 6 -mknod lcd1 20644 4 7 -mknod lpr0 20644 4 9 +mknod null 20666 1 0 +mknod zero 20666 2 0 +mknod kmem 20666 3 0 +mknod tty 20666 4 0 +mknod tty0 20666 4 1 +mknod tty1 20666 4 2 +mknod tty2 20666 4 3 +mknod tty3 20666 4 4 +mknod scale 20666 4 5 +mknod lcd0 20666 4 6 +mknod lcd1 20666 4 7 +mknod lpr0 20666 4 9 +umask 022 sln tty0 cognitive sln tty1 barcode sln tty1 console @@ -297,25 +306,49 @@ sln tty3 apilan sln lpr0 printer cd /boot/skel/etc get group.txt group -get mtab.txt mtab get passwd.txt passwd +get mtab.txt mtab +get fstab.txt fstab +get inittab.txt inittab +get profile.sh profile +mkdir rc.d +cd /boot/skel/etc/rc.d +get sysinit.rc rc.sysinit +chmod 755 rc.sysinit +get runonce.rc rc.runonce +chmod 755 rc.runonce +cd /boot/skel/home +mkdir downingn +chown 60 downingn +chgrp 100 downingn +mkdir morsinkj +chown 70 morsinkj +chgrp 100 morsinkj +mkdir buijsr +chown 80 buijsr +chgrp 100 buijsr +mkdir 90 +chown 11 90 +chgrp 101 90 cd /boot/skel/lib get liberror.txt cd /dev +umask 000 mknod hd0 60666 0 0 mknod hd1 60666 0 1 -mknod null 20644 1 0 -mknod zero 20644 2 0 -mknod kmem 20644 3 0 -mknod tty 20644 4 0 -mknod tty0 20644 4 1 -mknod tty1 20644 4 2 -mknod tty2 20644 4 3 -mknod tty3 20644 4 4 -mknod scale 20644 4 5 -mknod lcd0 20644 4 6 -mknod lcd1 20644 4 7 -mknod lpr0 20644 4 9 +mknod null 20666 1 0 +mknod zero 20666 2 0 +mknod kmem 20666 3 0 +mknod tty 20666 4 0 +mknod tty0 20666 4 1 +mknod tty1 20666 4 2 +mknod tty2 20666 4 3 +mknod tty3 20666 4 4 +mknod scale 20666 4 5 +mknod lcd0 20666 4 6 +mknod lcd1 20666 4 7 +mknod lpr0 20666 4 9 +umask 022 sln tty0 cognitive sln tty1 barcode sln tty1 console @@ -324,13 +357,19 @@ sln tty3 apilan sln lpr0 printer cd /etc get group.txt group -get inittab.txt inittab get passwd.txt passwd +get xmtab.txt mtab +get xfstab.txt fstab +get xinittab.txt inittab cd /lib get liberror.txt get fortune.dat +mkdir font mkdir term mkdir tmac +cd /lib/font +bget font\lcd0.cmd lcd0.cmd +bget font\lcd1.cmd lcd1.cmd cd /lib/term bget term\tab37 tab37 cd /lib/tmac diff --git a/bin/newkrnl.sh b/bin/newkrnl.sh index af07773c..03dd4cb8 100644 --- a/bin/newkrnl.sh +++ b/bin/newkrnl.sh @@ -1,10 +1,8 @@ #!/bin/sh -# fixme: must be <= 256 bytes cd /boot -cp -v /usr/boot/kernel.bin kernel.tmp +cp -v /usr/boot/skel/boot/kernel.bin kernel.tmp align -v kernel.tmp mv -v kernel.tmp kernel.bin -cp -v /usr/boot/boot.bin /dev/hd0 reboot diff --git a/bin/padding.dat b/bin/padding.dat new file mode 100644 index 00000000..73f6f6e4 --- /dev/null +++ b/bin/padding.dat @@ -0,0 +1 @@ +ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª \ No newline at end of file diff --git a/bin/passwd.txt b/bin/passwd.txt index 44938c47..fd1accf6 100644 --- a/bin/passwd.txt +++ b/bin/passwd.txt @@ -1,2 +1,6 @@ root::0:0::/root: bin:!:1:1::/bin: +downingn:LbnMHnQ.K1gpi:60:100:Downing, Nicholas:/home/downingn:/bin/test +morsinkj:TbKUmao1jtbos:70:100:Morsink, Joost:/home/morsinkj:/bin/test +buijsr:0bkPMVw/Z4/sh:80:100:Buijs, Rob:/home/buijsr:/bin/test +90:IccdKbe10jjDC:11:101:Surname Firstname:/home/90:/bin/test diff --git a/bin/profile.sh b/bin/profile.sh new file mode 100644 index 00000000..f6858681 --- /dev/null +++ b/bin/profile.sh @@ -0,0 +1,6 @@ +#! /bin/sh + +PS1='\u@\h:\w\# ' + +umask 022 + diff --git a/bin/runonce.rc b/bin/runonce.rc new file mode 100644 index 00000000..baa3cc1e --- /dev/null +++ b/bin/runonce.rc @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "/etc/rc.d/rc.runonce" +rm -v /etc/rc.d/rc.runonce +exec /usr/boot/runonce.sh + diff --git a/bin/runonce.sh b/bin/runonce.sh new file mode 100644 index 00000000..73906a5c --- /dev/null +++ b/bin/runonce.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +echo "" +echo "Installing LCD character sets" +echo "" + +cp -v /usr/lib/font/lcd0.cmd /dev/lcd0 +cp -v /usr/lib/font/lcd1.cmd /dev/lcd1 + +umask 022 +mkdir /wnd +exec /usr/boot/appinst.sh + diff --git a/bin/sysinit.rc b/bin/sysinit.rc new file mode 100644 index 00000000..06beea1c --- /dev/null +++ b/bin/sysinit.rc @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "/etc/rc.d/rc.sysinit" +fsck -y /dev/hd0 + diff --git a/bin/uzboot.bin b/bin/uzboot.bin new file mode 100644 index 0000000000000000000000000000000000000000..4a3da4bbabd9430bcfd0a76a6e9c9a32917e5008 GIT binary patch literal 108463 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 SyW0Oh_4^C^_kMx^o&^9%?F>Hv literal 0 HcmV?d00001 diff --git a/bin/uzboot.gz b/bin/uzboot.gz new file mode 100644 index 0000000000000000000000000000000000000000..d98900b2a72fe2ba1508e74c1223b20aea01eff8 GIT binary patch literal 106661 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 literal 0 HcmV?d00001 diff --git a/bin/uzboot.ldr b/bin/uzboot.ldr new file mode 100644 index 0000000000000000000000000000000000000000..0447abf4ef7d1012af65a47d8551b4022e38d073 GIT binary patch literal 1802 zcmZWpZD>HSMA`sY%rI zbLNCr#uP<1%Ki^wZm?Fyvaw%Tt$2-hP@!dPR>(^7!+3-uEjmfud(%3mOW<(t`#$%1 zpYwi6*VQPtzjbwiMR6225d9bWuNSG4&8h6q7pO}sc?>c_o^s2hLAe?YEgIn`Z$Jw< zrzin->+@D_@7L#@sP?n{Id1;`ix&I65%hgSFmLd5v(i`kNbv8fwkh+=++=C?I z9{h|_9yaYvTiy7%rD}@7h;sG+$5g~7@L!VRVj3*0hoP?eY#~b@?zZ9LWFlnM8G6m$j)U>)?XN=F4x$W zId67-+( z_eSIvw$k2Jh@gV_AHzp)8n(Y_Xek*A*$m&7fEdn+4RV^bd|NUQFx*Oms3uaT15qIT zu%m@Y1IfF`nS7CR3dI^HE2tPt)huf?=Cs}+cTT;e3B?*sg}l6;wThyc6)s)jACH2* z{7_NjTw}}`-QJ-bv!q&q=>P`R0Rd!;?%A~+F1hW%N~l|Il*%UQw)sM4;2}DYlHF(} zg-R+Wql`xdd2nNwaBqZ{N0_UqO-IL9^|oe}*n&9C)YA~KpnJ8d* zS3=NVl!w$%28V&r4kO{LHlF0OU`nmAV+5C&=kjj6Brr-x{y{ab*o8|82#{nDvKzCV3LUq*RosD@ z*322PS1bj4_&Rtddsy6`v>OD3yy>cRH9cv1mWPXn#px3KfnyzEkP5CK+N=ZwKn$xD zG&m}WbvSANxX3lvdO-(^DYNOR=LU6Ec+AvQZYgHv*?1wdR()jBjiB2Eq_PhB1C3WCc@sL@ukf{FG`R^e dYOS&Ey-#17_|-_K<;u$03XNWEP_1H&{{UG2rvLx| literal 0 HcmV?d00001 diff --git a/bin/uzidisk.dat b/bin/uzidisk.dat index 4f291729bc4751ca77fccd5dc326504aae8dde73..096a21928c3cc88185e1f93dd199b63ba866dc09 100644 GIT binary patch delta 305117 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%0A68}b^NOtGUJ|V(fBbtz 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 delta 118304 zcmeFadwfjC`#8R5v*+yDJtvaLZOO%+O+>6q;+DGAT~Nfe?hT=$RpJ&!RaV+6Rf=qz zQLU;=-HEs)^g>vIuq|3mii6PYTai{2bxnTH%$&W7_xJO8{r>sAUcYaUb7tn5XP$ZH znP;AP=9y#u{Q2tn@Gr1y>lTTLEfQNaYnIruRr8iD^8+7hwdu8OetkDgvIg)SnR@8# zU}pB7-^fH7a*$bU9r@sVpAr8R_qk)U2$lzcSYorF7-)= zhj_ye^+_Y2bg54|Jk+PYPa658OMTMeVLtVJ(#R)W>XQx+Zx--ds+V|LhlaNb^yKnE z^&vG3WvsO*T&(3;P^7k&g~vv!R2A8b3jZXx@xs*fn%ZhGcmnil;0>Vivko)FCb%(Z zL%jh){lfgh{S1C}{ObBe_(l3f`9=HHL(E++*xD(Guibs9H@M_yE%Rz{Nh5E76hEt> zPHcp`!B2o}&pwUE$QxMa*YWOZx}SAr9nYS0GkMp02U@OUipE@Ua^ub3-XKe$?Yf>g zDjItO>;Z0g0W|e#fyOA@6(@~%`g&JBs5zu5(i{dFqoP~5!JgFd2Kz(vAI%NT zpPHMRTbkRN3e8`dzcqI>m72TO{HSn4Rx@wte>C?r_cafIjZx82ZltGya!(Td*;-bq zo}!e4c*BoAV;R5(vO#QZ);cUY8ivT(h1IM#nue^IZKNR5;E84E<|8$Y*(PjLHi5O4 zMMuZD5zX^i*Y=3qDI}j+T=gCY4ka>1!Je$r=VBcV^E9*r< zzh69LvlMdq9HaNB&1UDY@33=OtHBsO)=g=YkAxz2CHpzMiv5E9l3mSy#jat$X4kUo z*!AoN_8WF1Fo^y*S$5B7fHtw4*)8l=Ak-KwxtrO>dH3fCYh#bH#|W_p6NGRdwidI; z*%RzZAXbWQ;>L2Vwl|jFSqJ+E`yciO`zL#oy~W;UD*$7tb-v`?_rKV`**k0{5G6&| zccVjkZ*)3N&k3B!`E#`pbH_g_$0XMG9E1QakPG5!bHQ8)7s`ck;hcf1!`0;?tj$aj zQJ#>ITof10)#Hqu#F@AlE*9epx6U_-eLcbIb8%b)E}m=1nYl(>W3CC;luO_exn^8* zt_9bUYXw}xKQEe}Nf>Q|oER~}6YEP{YpxB~mTSkg=U(PIV3;~Yco+Bc?r%q~6W5vR z!dZvKc*@>`*Sx{r;NIjWa&K|gl`)=^ScL^`E2 zCd?bxdG1%Plq=(Y<1TO)xl5ePUFNQESFH*4qr8mGa!T?1`rZ^@OJ*^R&y7lqc49oUW-ICU%jnT$x>uck*4YcvvhFY_> zk+!k6iMFXWK}*E~|919t85j$mLXfC!rfsfmp|!4z^VGh(+8hCQ}A0G}+*Ur#pYG-QS*3Qz-*3Qws zqn)dLS3A!-r9qSzx-6|lJ71d(^fmBQoFjY`=QrAo+D+Qc+AY@d1`Q0q`E+utcAIv) zb_dWDAN^l!7aL|X*e>zn5Kk5z)gIFpYmaMBXisWOw5PPEwRY`~+Ml#%v}ZjS>}GL$ zA0zE&?JwH%+F!M$T5DN+WUL!-Nxb)1+|d51y{WyWy$ysm^aSkJ(i^Z!Tdh^`46o*` z!@K}b`7~XZkKiNuC_b9EuJi)DX!gdKz$fy}_~v{I-dff$(qm>U_8GTiz6alv@5R5u z_vZWXefbo=AK#xJU`;SbdFjA`{2+cX|0+L(AIcBohw~%&k^CtBH9plk%^cx1heo3y zb08=uT_A|5C*Q}A0&AzX{IIF*8Ly%=ek?zZf1MxCr}Go|H~2UCiTqpqBz`iV!B63* z^3(X~{0tD04T@ns9|p=3HKSAO{B#-}nB~U08?s@-!Owj7=Ly8(;y7!k#@?nZN3wGQ zymPfR=JGY>>T1l@lU%$v^x7l{H3Ew@1N+yUU90BofSR)dYt9Z*vJ-svqfPGzMuXYu z{BbIpUVh%(lyoMH0CqvX2>Ra-G+AhMXXW8O)<#QRD_xTAC0%P>8(mvnJ6(I-%eoG_ zj=D~|&bltTt~%ewzc+d}-c8qCm#pid>#6Iddqvk<*GJb^m!j*Z>#rN28>kzk8$4P; z;Ur+r5N`yp>W1is>W1lt>qh8C>PG2a)1~T0>&EEPbYpenbg%2i>(X@-0Ee^wkip*d zt)mj7V^`>MbXMJ`0QRDVdMD*^Q8OPNhb0F`O9yp_bVa(u9K^JI=^pEz z=$?8s8Vr_^=QLsTYQ3L6mkTj^>@cRU_67>ohv~!h27MiUU44W;QXi#{*4NV;^^)GC zkI~2K>+9q64ZzHL5o5-qW?TrU<`$xt{gkespnpUErhcOSE&U|@WPJt(3%3@v@HQ-_ zklHydy(>@EPt#A=&(LS;XX@Y9&(hB(m2+bGAP`-zF3wR}Zz)jPu7S6yG=WM*ER|vHoNI68%#BC;Daj<@y!+9KBWl zss1y4t{&-E>Oa@7(tiPXob`9BRJFY5T0`hEY)GTqGTfdgeK6$lFD%6VoA^2#q?)U$ zaB+jWFD%9mjX1-LiqYEpkx}6368;N*ykmSZ0^?Qfi-}W{?dA({`~CM~&3`Xu|9dg_ z-;1^Xy;w(zeeK?_sd)NW!)t5IT~}l7`WkaL)R_AX$;HcR5SSHS0<+Ow1Pa)zXp_4L zwwzu?n_WfW&3u&47X4QJHvM)CAiYo$|F4(=L&=Zl9s>?^!GYs}57F?Uyu zx%oBb?k2f4is>F&RMgd5%kOp9@DX5iQUc>i6ppU;rs6MHc{;h|_J4hXW-y z4voWmhR)PTRKdepj-O8mX0Qgmjtic;+6(1j`|DZZnZ8P2jf-P&-;8Oni}fs435=i? z`~;1_3Y?%7U~(9&aF!703B(HvaX~CD@H%AB32(R#8H$p{+Mbp4f*^>vnh7@?(%PpZ z{z5H+Gbc?K>{ApV1S-w-@TMb3s7(t1q2VCd*q-eL3n4MNuO z{e=FwuF+aFOc&&XbpXL?EqX;Xc%mIB3=#$luL?tip%@^N2-1hOygNNi7%q$uMhc^Z z*MwAIGzK(~ejW2+_ZT4!7lJVL_8z3M!Z=z0qZ_uyM~q(=#tZ4V*p$;ptm{eL1mO+g zO<|(&mM}?}j3I#A{dM6!UC$7v2vdb=xE##VwtVfIK7F5#i(sJpcoQ{4$ixMhT3sl( zrafDpDZDMr!lfYLeZ8yA7Us}uxG&*8eR)TiE4-`JYs*Kz3?`Q++Id2jU=ijE*}{7m zC^9EStmRq$KF)=GB4F<5gZTqtf$$;4JU>P3<5_Ew@R6`s_*hsXEEPTxmI=#+6+(_+ z6+RW5s{wsFx3J4W33=8>S9^v<;sxCG;3HRg!Y*2;Q-3kilk$9Fx3EXpE9?^rghF9I z1~OQSx;`iU2VA%f1|RA9R`^c%Uibk67;^@A5A{LekkT$l)nuP87Ezq@2YBno!@?24 zhKq=9G=A>G!K1=4p;$OBoDfb5CBi8TNI974gZ?x{-)W#Xdb{wW@Do9wGvK*yo}qP$ z26}hntZ)t&#F9Cy^Wp8!!Y`ySr>8F1r|7)!E3G$wkhh8}70QI)gbTt&TufEmP@lS& z1X-!u`#HRqg)6kI(_n8xuL|W#0Zf3ee5T|z;kxiUE;d<<278NvL-<4Zk8nfyQ@API z5^iH4!qmt&VFq~0ONH>4@V9VBs1)vEpvas)&k^^JaF5b3|5b0|?h6lS0nE<8?!CMb zBf~G@arNEmd9BaHj}oKBdZJO3L=&v4QPxgFyjR;8G1j%(0{(iNeZ;1|7$-ImDv%k1bYrnuS#xEZ-Z42&DL5)P?7(Z4B96yFjjiIc?)af&!qoF+~eXNZ~NOz~}T zmN*-15&Gj)&#Pm->(3G25$B5UidMrb(Qw-C1bZjQ8*HigiMUK$F0K%BM639z_!$rs zPNZOukD-z)BBd`7X)@A#q*jWbyURd=7WmX%C4S*5FY>ATrMTKv1{^e;4ECn*D{+nZ zwYXNamc2rj^kC5k`DSs83&H$RVyGt zpLPz5M?BjJz3L<5Hu0!05fzs}y^dJXu%b zDxII|y$w0#Dk<_QIsL*CyQ`$r7;kJpx=UdGbn&6$Cs%3FXzzMwURZM0RpQ&$IcG`E z>)yzIb`_*~7yR;~g7Ysb_|;ipo$rII)K!8tMTJjK%e+d5`IP?VE*ndVl4tcke)t{zLMXwR5RWhKdDgqK)smB9l;na z`KmWwhlnuO&u&P=*|_Uxk1Av4q)D!%YOm^@@zbZc)B99!O&+f_hI0#4nVECk#i~M_ z_Gn-~PP-ehs1D$a=I$Eb;xq)wIe)%W%@~(9X}mM3`d&3@oF~OU;Itc|>Y!@U)af1# z9#V~)G9ly5%s1brIEqwb)25G`@;XgHLx%w%W5yI$6Gv2OnUkU1*(sYUZR(qo(g?dT z6-Uv4k<3r=$5a!hPnkK@MOU%vO=u-EZLE@WTs1Xq#*A67V_xrP3Q`%Py4eZUq<o zpFVxc^ro4!GgYdSs`M$-GiPRuZ~A%~BvmD<%<y>WC%=St*XEMCfEtqj{%ov~P z%4^90JEqKVrCTu><6lo~*2LL#l9E=2(V}`u$#9NiYbEV;=CmQ{<}L(nm9$e1+9_#g z{q{=QS^s4v4TrGTpRA+_{3xKJhmzr>xTlhKQrwHAlUxX2QPNI?y_K|+fIdpPW#OX<%!YeR$ilBi zso|er;a8(H=|9xR5!xXtRkkYo*p&|*AKpJ(G3eNp!xdeRUnw`8ykejI!7bbPqQZuC z*$h9+Pgmp=jhxKNscLzMpFMnmG+))mA*tb)Ir4HtTBwVONr_1&=~Rt8gsqbrGsGV9 zVR<=Z#h4;5n{UeqkKA@=e`xPISml1kO)wZZnfYYYKi8E-E%pSv<|Z#)Yv7(yy~ ztN)OZA(}Otf4bt323>GS11~%5rlQKq${@AMKE6nL_kzQVz^F}VQZ(Dba`sALypDPQ zLXb*jAN^4Wruo?`lAp@-mu%?MmX29s1Uaip zE~t)gKq-<_)N-<)oXX2XboLRJd?#1*@({s3BHuP+p;GTvAN1|LYvwb%fH;CBev1={ zPtuK(*>NFgH}0rH%wVN!7LXM}d^;cPPK*i)(inNijnN(`NkaoSa<9HU*EPc9qH2YU zIg8|(MSbMV!^8XA@%s@u(rWzc#$+j4D~8GwMZUvm`JQ;mt=C~ z9+8LGlw2f9Y?S)8j5@(nH+x-qxuHLZ3rd&RdX};}tnWpeygEhqhzz$Cy(5EZlc8!G1W_8NnzNGQr8ev2VMPN|ZUt6drR z#mOl1J=s|?UW7z)O!^z9d$OTZ5T~+#y`GlE#KbsgJ8W<;A$D>O zcln;|xOI41%v3tJ0TXH#%f6u&cA_t0*+?{?K3iY?$6_?QKARCb^<#I{iP?{Wx{ z`GxC1Ex|h$*iRa=QQ|w!3bqx?(QggeO%@ByVcLQodn%_ti=k?$QEHgVo}FhXk+La( z^nvnRPM-!7Z47f7I)X=7&d|u|tV41&q73ToCAK!p=ty0z_8QfbpIE3)ko06pIQfY( zx{jst%)4^tKT1AMK9n;b$r*R$^nYSvvI^t<<&1}N`Xl^)q^ngL;kV< zu^2ekT)}jEiGl-O=(^*DTQk`1Sc=|j#I}fYEOi06ntlESU2MeGVMd|*jaYNc>r3U7 zr*iT$1?=^u_{FurC0lL&D^OGu_GR^#D^PZ0wnZegO@>}k=0u?7)CcmAf9<2tnZ^pr z2XgYi3N0^2IV%T^Y64d&7Ot?BFGrs=0WFoBi*__&!!60V3jVCea={a$j_T)p%mdTQCS1ogj0Tp#zNoTrz)zHvc=X0eF zE=OIPvca*ta&5Oiqb(mf_$h61x=)KJFo6yC-<2z^R)p*FRrFO;whecCiQz{>LsD$m zl}jblA$_eh0*J9hiwSImuqzitH)tFdR@AX6!3M?7cF>RnHo*uDY@k(Z>XKm$X{U>u z3}>hQDq8v6sl!PUZApi^3qmH zqmmYxJb)#OziOHJ4>`sJ=FlgJ><54NFn zHA$s5>95}cO=r?v$B9}r!Cf~iim0A4W$9FQNZ(y_NLR1Y#R8U#D4*h!q}bvtXRcld zx_Z^F-yqLCBWIokogL#-;TNdjS~Z+jo8hVH@in{>VtsW+PCx5lRBDXqtsRx~_Lj8% z(u`GJN$ZtPofqz{^AwGRl^$54z<9l?V&v6p&Q%=pm@t*@mc7FkhqGUQIho~Aq zP#yNrRf8zjir!bRaw=)kWnI=E5?|8lOH3~qhreHwlkQxVlPa&u8F%FL$`k^Gb~R_s z4WalC7z}qd)aB##a?3kLKe=V4;dcXP{{0%jAioxD!(jC#4_;9N6LoCC)(HYUH@xt; z(BJgRt^xgxYo?pm(DyCaXiE*~<)r%tIqAVAIq4sG-n%4c-K|P91^`hpq+|a?ICEcz z+#8S!bR^x6#&s%s|0M$;NWSUzHS-_Wbf&+qG0c4P?Q0$8Z=X=nC6U-Vx33Yn8`m~j z0PxN=^GyJ}O91b90p0_-|j6XFicLpUNpugxUx!|{4w3ZN zImRBE-MdT0NX>QoZ+KEw^acSSc%Yru5pv3XIr)K^zm6g5+ycwnthycp1RDY@jC9Gf zKu&oiCqIUqm>3tZobj)mPMd|k$t|B?IeBV(cNO%*bnlw^uWK-IfE8X{yh*y)@Jl(B z^l)DdJ-m6%bk}mthGCxTqDZ<}OX*@QcNaO*MGm@%g%7hz>Eb_f@;$Q%UF4K5s-cT& z=pyc+N50ZSk@S%3Nr9bRgl1s`U0rE?PWH=w=;e2BI{7WpXUW8VW zF}&g=6px`Vp;calTA)6q^#3@1&y5NpR2dcLpin}cgQ5`Hc{N_XVlUY@{ZP>x1n(iH zvULEk)nSoZU80t!p*BuKnM3NLWL1LD!+`0bHkm1#e!%mUzi!rCPf}I%uDWJ^s$i;u zS_9pPAPGedX|xNG+KmY0ks=bWo4HAV2@gA1>Q}FMEg$hw<_EA;K2S{Iirx=on7y!b zx_Z^X8qNYGO1*2()q4o_9=hs1bk##m+pv-9M~6|LHf&sw9wut?x)S%oF`wHVg*0;?qC1BJp)Me>LxShDMDxz(vBS@GRTv(Dvm ziE{vOZp|d2kK3}Q7&jm^27vI}moRjuEo-zmo3$}tV^74!XYET$)?!0vV>Njrdwfa5 zU=l}QFNE?QzXg+ksV7BFr-bx@2PAz5NN61(T}fJ{;wz9vOLHZgr0U~@L*nqSFI`=Q zJXbs5nrcEV6x?v%Zb6r?09m*iyr*7uy(?tBz3|11B4alSPv`%^;Mp#$!I)rs(;7cr z_KTa(I9EF8B^~IM_H4``HwdtSg47@#^ER|Mp1?wjH=f!>N+(JVue4FRq!`HvLo?wsg!R}5|?Cvzh?oLzeN*Wct%tl!vWas`^F_WvD9uw6;szG5fFc1ev z7of~#s#5dIy{+$@ZC|lVo~f2I{r-Ce>}-9>Ne`d zMM&DD4)KG6+zxDee3o#Osgr@pF;&UtlUE$fV>xJ~Y;SX<(tdS20aioh37gcW(C%9+ zecAJ65&CMAI$XE(hf3N$${xywA>&1sZ?3)!URS-GECi`9+c)n6)r9qqS$#Q4<>uJL zY!|Czcc9K~wS&-@F0e&~QxPUEFiKr_6Ph+hQ%9}ZgruWfAN8OkXj-CXbSuSWYL324 zoW^O?T>!3RSbGxVJ-p6YG3isXs+t%>AP*&6z@tKhFczQammN)=DL?*qBLO!f{O&}bvy!_ zet=|9x=de`(a6rjnPkIPLo0q2U7@M0LN`6I2a3KdbyNXWlyl0mo>gUOd*tuUHQ>-; z*GE02KaHFocvnASOtr5Y-cX7u>+qW0@x?uuTXPRAuxG^zkdSA1wWbE4DGFgotbtH> zXDN_^0c0EM(fvGKh|h!Jb(Yx5boHURqP<_yE&Jv@WGoB0&Bn`g zn1Y~Gbu?%o{;lkvo6D(H@{nrCfDIyb9V&ANHB)QrHgB7K-aHWo)~Gg^Fj*5XL&&-P zE$ovQrR2+54;XNYJW$OFnz_Y3@%Y)3_K7HHtX~t9naqZ&Z`jbs$?U6Ym?uG7V3!@R z?c7$|)<3tZwxI!Igt2OQJ6iD*)2{ZPdt72fGyvo?2gHbw)E~&Yppi3K`4pQK-_U&O z3Tl=ngtlF~liH@HQ&+GekhjZOyj-9=vSK?G5qTyrXX@|{x1zW4GO;ztzTbEmrPbDj zso&a(7{oSI{|PrkrmDA~hP~Lp7IltPR@#Lluy}zxw0Mtw>`uT8)lNc#Utv=XH*A%_jqGd072CI);?S_{LP6s+Ms)KP z*2HGznVUP{f|q7bU~}A#bHMDUx1i1kn7X3sC|P@8M!pO69{Po;;hFt26YX8HwwYft z))|!tm~QAqA6CQ^{o03(6M#>ObL1c@-=Xdq(ytg)74~3K2@1ozbyObDMWC#{EU(6i zOmzgBw^Pjr!zR!BpU@kM8`+*TK&VDR8I-&%~Gjk~Z{X>*4fSwLV;$mG9Ck z3@DF7u*H;u+&BSjT0b_l?W}y}2AuH_p(ZdPo-oYokaCxWdX}N0er(+^XomQ#q;RjY zJN?)&bBM!k&6h$Ply~6Y4^%nqFwS&g=$s8x2+VAiedrmK*q;Tp4d0ZwsE=q8fSInG zIM_R9pO?avdUU`ala*H-s4Ng18rZcdrqqg7n zqMHNQZqnj!DL1mJ>L2OxZ3nfy^O;;w1x`$QLIA?B_Mv(@Iy{h_H@xe&BleHo|LcKP z`y1^qC_Gho82(ugNc;Qm-&WY9uytXd!tRAL540|fDx^3Y$usekv-S8^PTIi8N#Ce! zJql=1vOIMUP9*JR;DNFiFt3?#aw~vsBVb7z;dK*!g-&ghXKli8E3R|B{4ais4fK6- zW`XVT0hCt8Y-v<*+?gdO6&A`#`{g{jU~kFv1Gqyw<$^q;9t!s30(5o>7uEDT{Ay^> zA<(1v2a*@uApqxX%xiDtp-vI0)9k7~qV5P7(S34qfdobm7|viFyNDRDlq*obv=^OC z)|oMv&nEcA`h#w4slmHY)^=eZbWt0J=T@^5x&|nAD2z(_cWB;FHeSu0K$~#-&+k#t zVkW6DX&5_^!KMAaRmavRVu1|?Nu+~~4~eMv(E*YZLo(5=;cREzaN3=K2-Ir?Ym92{ zaBXXY@z??JS-t`MT$ zc?e=E*v=tcPPF!Ybrbg5 zVOZ5r5bHNx4bN#^HT7{({%&n}J$kHm9){aJIf)|I(uUJg*}CetkE401tO09jW%^Fc zeu(EGK77Xdm&xT~)eak)7OFAg@jrYIv@fLnN3;FZpunbe1G@~;b4J4<7o_taXj`fu zpGN~8XojLDW7se~>D$@Ecu8zFLK7Tk!pknKq#<+}hBrN3ik*GFdyMpHlV7NZdcS)N z<+tGK*1mfT1c@3e;KH0=()Soz@ir5!?hWN{GYRVZ$IzMVkoIUy8Y`$_nH(@ulZsBI z!5a6;ag@E;uP5p-mJJp>`ilQus#dos?7lm6IPrf55;yXFLPr`=>nXrdxGx{0a5n%XSO5 z$r9`X>9)E=mOfP8(Vf_U7I;y-x|eN&MvrF`abm@Iwo&A|pX?_upX~pm?d0l{yH0L8 zS$gus=>sQkonCtKv!77kJN(e*#0?%8AMHaDEQN%e)_ykQ8N)A>7R4i;mJU|a@e)*V zhd0Gnmvl&!cm69EJTy*vF^-m}(bNK1HlLhAJK{pfb6zFiE5XSDujX*a8XFRhXkUZXk1{AW!c;gwe!G;skmZ#;6M{@dOkPqwxLI=SGV5h4${DcnU#^3)DZTpA+ zFt*!|lqY!wM$95P^&ff2J$wH9DwUrq_DA)PpV^~+L|5Nrcc>@W(TYYwo!I{gr%~to zd@I~Rzqi;fYU3Hyq)|vch}PMN-h2y&6$%0$@MG#JsG2zW0&^`eKFY;@RCf~F0^4~5 znh15(txlk;5BSFFkYCZ~lh{UBHV(h49;_Z%iq_uIhoR<^!6gQ!SpUiFJ$2a6C~$p9 zf;#wT)OmeKq_Fy^-ph(;fO6LJWHEq^&622I%*G6zLZX9Ge%aG2k7*nfWC(Ys4f z236G=4pekT9TM%<0${X=Dy&d&Tm?NwgS}^>5T!o(E2@0PzlTC+fJ{Qqg6eY-_&M#g zo;-tIQk&3{)gi&?iy7=oxFq{~<_GoZU%~RzMWCITY@goOWqZfpTBjmq=wH36{*1!9v)N2_t@{^RU!*Z_ zugb$@bU9p%L>WW%eA|%g%Aem=sz3@seuw<7`~gGH=#f9>GW|35a^bF_`alNdak`gL z)mn`~b5Xt`7s3~88!#KQz-;(gox72ZEDXBKU1K(G23fqX&b`To7S_JY{mE>+&9?Om z_6sS5Z(=@U3gS6UWGw#VCXGdFR(7}iZY9K`H7kQyv=(LMrdDP4!q0Engu?i4Tod)H zqsu_In9|A=JHx*2eXzK&KgK+|3|1KyN)2ro-F$OenQ{PCA6^?W?aFix^3u0Vm$V`# z>3li)4Oua!G_*CDTg)6nt$J{hesme-xH%1t>A?-bX=2#|SWyqokciuXRl%c))?`b! zb%C=X*9w5QyrU7{lZ$OYYPsQ{(XvJj86d_D4E-972KD3`0VS56+)#5~Xf6WZojVC6A3koinf5h4H9XZ!Wyz?t|*K2@UtnS}uk8nsF#jH}0bg^;ADV1PdZ zQ-K^|Cr#O-AL@oZLPOx7ROvnqPeyF{0EC~y6a0&PJn`fzomrAL^R=N0bF z`wm)n;3XK`?8+iJ2%YM~z1pJLM=*rAcN4PB*)R;o+SEB=!l2eS3$nlMvQWnV6a*?~e+ zI5Sg@I;C)-k@=-rR&YVAnkAf?9nV5_s75?`jZArHS_&5u4eY8i8iO#~s&q!3!ZX8v z=nGn(!gaAc%E`=$$yvE#@QQWI8!o@KY}c|$%bG1a_{pMAI(|~RwDr=XOC~L8zGUSJ zZuzcduPrq#x&1NiF&up6mAZ(=(@TRz5jqa+Afv}vq5G!1Qp_sy?vPd~Vrr|(Aw=no z7T`_xB>(|F!I>}&Is?Hv*!Zm&Iq#Bv#{#FEFjhQk#{K513NBLujp?WunOEu|Q;fBu zHw*wq(0;KSffFyly6{?{z5myUYi0$^&N?-hP^OU1SaL}J!7g(5-#qR&s4D_b0mRu! zV3Icw8Ql0VI=G+*a9ZzViv8jm562SWlbzX1_xCvJ^-qWZ!tqn5EbqedN1~<(<8c68 z(6}=D(j&BW;C2o4{coE#e}q+4fHbbmA$_HYfI%eGSd`{m!)kn?K$z!UYJ>-~VkC$< zi$^!YJ&w;0qcM;$|HY#5`8R;gqDYamePcXNIqE%KvZ~TrCpjRDh6q%=fYM+a1qR&eFPTqm+<45gZ)7TpSgQh*IF%r<4# z(phiu5PPCYIZ$MvME*N7YY=ZL+Z7{051rm)2ZV9~NI+*dl$*F(IL;ki~ zn(cKS-nua=!Pw;JjcC085W~@*<`tBuSiJC8pajm%8iv84-~1d zJbA7HEC`ul4snDKg@8P4DdZKD4EfZx6{ZU~SY#zb&__eKC>^unT-DHbN>X0?660syX3|42lOBPYghOJ@`RKqF_`hM)12s{;Q181B3sW}hz9mX|}Rje6omT;6b>RW|{ zV2;9|9%%hAu6``BV*v&B%|qZKjCV!vxtGA;qW)^|n*aS7x;>1GYXi0f=oeyk(Nm9j zh|o35#OM4%B-%*U0h=I)SrN?IpPoj^s*0By(Pop+S|! z7y_9=sW^#WI+A=3KwMAtTur&98qa$_n;zn4HF5z9cRZkWtP>5m?DL9%>IkqFDRSkW zLzeoFdJj5{#?7O^5nRZt3on@#Tr$0X$-J)=*aUsUBkGWTR{AFWc3uhWhf`{@WBuxT ztUMmbng8OwhjdX<#h_ukucUniQ*h1*&ZrrG!M+o%9>E#E!|e_Htc+ z1v%;dtD70*3JPV$9XS)CM1dJSC|+75*TdT0Iai&hzp#6uCLJEqrA@;~v$3FT~r>b#A=0PW+q9GpJvP2QRMwVowp#vlDBth+hYZ;FF3_x+X#KtG> zjU28a{DesIpm}{TQu%RUKM~?9*IZ$8$R%UXlo2 z3=&3jO#+uI;zAUet?EnEb2QhycGZ{kfI+el6W?eqL`z0<2KN0+F{by?meE{X+Xe8t z;F7KQ3yPa=Q*@1zR2}rRGx5!&%@nzLA;2z#6-H@TH-_uYIMAzOxKaLRR_|W@)#~Ea zn^%9o`crgp441CWD}}QU*hDr;;`>|Z@#OL?LluGBecsq=Hyny%0*fC%$Ls?_Fa4$q%E%U#^bCI|N;AEbf zh(TCjKf1(>D+~Jg66`t*7N7?*NO4WJxSUk=v7A(m0rCpsn^QFLW(D3vp1SzD@Fd20 zGF{GMV1A-`cE#)Y*XQ+!CSF%go*?!W;%934$kFvok#lN#J5o-*` zw1B*J!Fyc1>&JEvwp+7dfU+t5jpOx%o_6tS1Ewges+|SSDJf`PsY0V6pHa_;YKmKm zg;&sSYTOXe$-$-?(7HFttvT8v7IYFG2ZkrXXz+uYPDMdltAT%Jy!X$lN^Ct4o*mj8 zZ2bxx4B*R$N;YOF&IX2}eXnyy3+1Dsn2M%t{yG4FqtL2hU|4BYu?@hoO6WLs-J`XS z)?QiLcwOUl9oF4m3ow}bKsv2J68ShmjA}f)aeMN?DwiV%luK2Dkp+!s@MG{f8VSk$ ztJ7-3VC5u*1$4j|0O;bxkGtaDm$CTtB~B@8L>y8lFQHGzb1{RuuB8h4)VoLOtq0Xt zZ#{0mss;v8{xniXt_h6X5GO{m(R(aUeS%d;SENtpIt>4O9bE*R&KqoZg1JLZyosFx zeX*Bsq{H$QOg?OXH0;|=fgem~5lyvDHcwZKHn7Up0($WKTutYC=rFBBeWJt(Tv!|P zRuBwgvA*QVi5K=}f>ES!$TER5Bsu+M45tD+H|UTI^A5aT_yt^Ehh$3Z!zvK=HuPE* za4Z+uCvYtcu)Q%H#RcG9Y;%aw;(HX|pO#yqYA7vK-{np-Efnodoj|$Y&?OM78(a?z zYi!uz(FMb9=@GI$?}1*K$eH_;?=?uA=+xH{m0iZ)!1lTMqRG)xRI(2N(p z02_z|PmDo*-r~lE{ibLM8159Oon+IZV{dVBb=xndn7|E3v@5V`8UFgSX&hoFaov~( z=#@!ay=K8%DHs+j(hj!zotfBbh4(CciT6nGRveb|Jz6!1YZ&&^=Dbb4H*eTfZ}a(0 zbW$cYwY5jTP2%b^?NRk4t`|IdP3DYZ184wqG06<&GbeN7LR(rDr???hx&h`>Xqm%) z8C6W?G8hJp%HT}eUkWfU8lVLkuu|}7YX+CYv_daW;hHI$pwSR{`eV=;59L{p@Enp4 zJ}zmz9lrs^jkhb7Ein-BilP+78SBzJ0-%WT^@~PH&UtE+aAl{i#@7g(AX8_96Iya% zv|yVPP*SIQf7)bP>rki-PMOyJ@We-nSF3fm;NA@E{J^Z90V+zbN>p`GrKkp~2B`+C zwA)j+nYZO^>$Yw7wr$(OxA{;t3dr%vGAiU*o-e}M9aH{%iPO?~z6ARjYOaHOfJ+Q- zgA>~i);SOh%#S1$DIm_=MCyck>0qMT(3loyEnK+pK4@#*G|tQt45;-qE{b^-4VlJu zk%sT2dyCc-1MIIs?SW^fA%0h!;8FOUBEZ8KqNqOVAtzH* z&a27Aht(B!lau{6PT=K(_<3;RsT`5{47(d#u4vHC*gI&sguUmHnOvj=D-MMam}9qs zC70)1p#l8FK&-(H)3=)+cmmpFt$9($|3npa%>Kmbr! zRR=5uaA7D44c|ObLV3&4nM^Lat2cSzSI;lifsO->;atrzVG2j_QG&uz>WKV)7xW%A zo5_XNwSX4_Glw!6XjFna%=6HgnOr?~%!XU`W$1&MoVkJJk`Am2=h+82q%bMF9|E-j z`U}2%bbcn6ARThXpTU|BQ!KV=pOLAD@}u%6=ReuiKL6GHTvY#U@Kqf`J>KS`;gS9} z*IRw>L$v2@t^s~tdYfxEoCMYpH9l8uA)*&2+tF0J$=&~IY8MFbax7~Wvq05w! ze_^W=V}eIkRc1V%+SmxF(TBcdkHLA!M8NdmFvHzJn?xG008xYMX=OILl)d) zhJa>#>7%0eVF*Z$Nyhg`0Ll;mrFba^6b8JPgT5X+57B-VBlncrcV@d@Tik~5yB4L& zR^2=o@4#7UIJT)ql{)BYqB|{h$B;-phiht~Ubps(A)*K3x2D3KP58%5y%;q0q8$q_ zGz#(x@`gixmS^9oa?2|{$Lm>ukJOwd04}Ap*`gRacsK4n^?%y+mqn9WFjhwI+F{bC42#C(DU7Am!jF)}R`FM;R&4>OaL*+!zl zbGdk?E}A!&i|O%JsY7}L{*8gYj>ETT$US+Ot60my?Rlj*!(ALyU5)pM_*@X$1M3OW z@1pQI$dIuWtE*BN&z*}P&yAZlbhBtjsXc@_aGa7J&8xNSTm!cpX@`M4M znKb0dc)&a4Y3_a+@-$~Z33*}~qGt2Bp6Zv%Xt2|7^SFlU^6zM{Q=cp@O5L=OhSA4; zOT*~JZ)q6)@iQch9u2f`!NRC>xW{B}pfRH~#wKIF3wo#2o_UViKtMCZ6INMZy9JIj zY|?^TttZ4GKDEILbs6m#rHND9Ags8ZzDKA{`8)t9N#z>~U>~ApuW2G)2kTO$3bI|c z^QQqNE7>j^B5am#Aye_nxbw0157Pt3s;%IxNW?5w_PRUH5K1Rxp9jP^AbjZ&I!=^+ z90INZf5dPk&*%DffA1IEwMtv#_dp=4s)5zCPjocsNGSdcXB;?qGQ8rzKlz@-fp_Tv zao|nx*}f77-lUAUU|?dx5uL8g9S5%a-v0J45C;wr3fL5HXhRS5});fIj$ zur`OO(QJAN$3WPU4k;1gHxJTL^Na|;UJ5gh`b2r@9B0sNKD(cS@j?PE~+0xrTskhdO2mAm+G<}i)fc1t)E z;FxWuDO&L%H-TMz#C)Qh#DN=6U_C+yAEJTV9P)|49*NE@C zf@dHx$Q=nJp1g<~s_uW31`_8Lkw9Wi(?Z)~^v*|Icd6Y;r$JQz$ioxZA>% z(-}wn@PsRl_~B7nMB<1cf#ZlD9z{X#@u?D|lrUmkpo9@WJPPXx2_ptD5=Ok_Bo+V? zM!f9=2_tT>737>|LFDgxi2Q{$AHs-ZNPk>m#2b)(2`4q(gv)(Gh_{eDpAh2hI1}Lz z;yN(PJVS`*edij5yZe=5<%Rw&~+m5@lhH<42*;bVl&$R2{%}M^CYUZ z44#uu(a7Od%eaY*a1%O4=gI^$EmIQ_=hjRUU@-%^ptA`J94G~nfRzR@IhxjLXqv_<1ns6 zLWy;DARC7gw-|mD1`a!ssK}e!;4meR5aKpv_72Vv;#I#;JyIU532Owi9F~v8&UjDv z)LMMTJ8&2j7!DkU73u7!TvPV#Gi1TRal_{8Os2KxGUQpV{Koo?^LrhK+C5@69)%dOIrzQ0w|b3VZU=1~cI1>X8#`(H=!*T0`HVT54Kpk~A-A zS{K59Uv&kSg%qUont^8gKQq&)zG)}^Df#CDMDepTy{Wu=-c%-PS|)%D*YH;f$2$)m?$XpS+})j{7Mwcq}% zvXaJ&&DmA5U;&!?j~HTMb{(0!02B$iGR;`XHEOUMb)VA%3n&BMbyihO$?OG;UWF4- zidH(+2tM>8z7$df0cz)FlNt``)KQ1MR}NgCYO_gMx8dw42qSPvSClf_RLcj{+Axm9 zC8oLfj;(3l3G>Vo4rcC&iji|q*gGtP2$B;W8p4;iOwzwcF$@NsM?fvUpxzB&i(~}8 z80x@r&eSYDys6SQ^#j~x;H95^+g5bz2fm5luHrfbfI+`u6RH|43ff}~^i#yN9}6XjX|NR2GVoCkS0 zACDg0;DJ7@FQ+_{ldC9s_AZ;?Tn5sZ@sSoc^T|bYh55=m6`;LXAv-X?@zC=i?5;F;uyNYH7=LEX!K^zLw3-eCPPIE0 zR7_K+=pY20F1AN4m%0$q?ny-3vStGn2v8;w^gtb(cU~}SHW)7A4456=wo+#pxV%<7 zq*6r|6ufw&hfOsS#>`BZuV}OxpGX(H+HU}z0gnVIRF%qNw`{G%YXhD8cx|{QXTpa@ z7~}JKcsha`TGh1dT-fT23$P5luo34 z0dqtz)x}jTP$yW)Z=d6k5-6TZsWW|{T?1XcSDv*GKD8ug?3L5^DW{5c6p2pVD-YRc z*Fb1D9Mj7!_ZfbL0fFP4cFV{>LDyW1hdi@D&Mc%@<U0@-if^c%kwcv>Kc3=)<6Xo8 zapxsTp^bJ68*HLj8!q2*`icd?DkfCkz+UKfx(KkJ_yY{dDeZ!96tw= zjny;k!tpEC4WJWqwb3ysailI(J!(7ZZ0F76)78!nrF;s>h1 zs`7H`6y(myotV2kcT+BP>U^-0I(2recC|~CKI9Xp4pzUg8hYIG2k|2J{Bg%{tSIIr z5cR=I#jDdA0=w|CE_P!C&%`k&)xqhmMt z+Q|5>7VbK2r;eVPKl39{^V9fd+E@N8?-XT}y+a6Ak6J|>Kw)HpDh?n5LB+YV!!Mfc z{e^i=3Gw8Ft|?L2h^IlMG7Zq3^L%|FtymGVBfIeZ`S!I`$LqMR&cpDMtMecK%0~u= z;R0-AkYGyi_dzMSI)C|BK2V+d1-&{CPob2TaGG45hi9)+z8+4KtMjQ4Q-g!(z{&yD zZO`+$IuBsv>U`=K?yK_z#^dTdl)0|XlQNI1^H9ICl&>2G&5)C7&#UuLCYAAFe0GWb zoiC*964bGbH>mG#qW-I&c6j)&M!=0On1jkic#zcqf6F|N8dVs_FX*zcam}k{>d5--xVaV@9N1KdIugS73URxRh(B( z)Dxcb3MHSKYf=o3!GPT!RJ&=oL6zALoVmlySRYffw$mS9|u-8 z$@6hweL(7vJMc$#c{#9>@)QRa5JB$1-&##QSioiC!HQb$@?d>}y9jsSft}ccrN`nN zO~e@`l=GqLWgAe`9lyHxc{V8^#GhDL@L8Lrs?Hgj+)KO(?}{%mD7#wSM-AWh`Kg>A ztUkJtdcH!SNt|F92X=x1q_-0+@c?y#Wvs$=uoFz(1=>By z2cxfpHMP{R2KGOo3mLk$#NO#ZxwN)~u9xOHCqT!0_`~L$u>YH_D390kD3B8T3mPfh ziv`3sz?bcTZ~p(`qZ`rHh~2K#cdz~IcCw7RF5AO0N_=J+XvKE6DOUwqL_TVCdIvp? z*}a3F#v~r3r!hxw@vGtn9rti}4LS}g)HLUWkHc$E3B8HFuLP~S%{R0RI_~s%4LVLO zJ?ily{RNL#+D?qa>G2wL96VloN<2JXBxfJaaeBN49gi`Q#wmvx*v*~TN#DmU_Tg^SX>?3HTJtX^y4mW{!dXp?gCHpaTl)=@^Kg7 z9r?J+(7*Uz@vi9t_=$Pqb4UOyIB5(qd)dh5O%5pIeR8|+op{)8KiUr}%KJ{d1@+s@ zb`M`ztl0QRb}^q6D_7!S!6H}UCm*L*;(z&@PgFw!uEf_x#yfmaRp1T$gS@c@G|2}*zeo&~hDO?BU1iojlAPhk(l^gMc_9{2xzuJdy#DB!hLq+?6 z>`{gEF1+)TEaWcyqy5TV_-t|){#n7rf{cO(1^6y}6qucl1ttukYxc_*X%!@SXUT5BW{(z;A6a-_kqr;KV0) z;y;Ebz7y{Or`(B;d(4kyKlsiD7|EUZ4UhRl7>wMBU-X1u)S$A&{CA0cJ-H5lk*e8? zM9q%y@bJUjBp?1ba)|o)VcwAse?U4dm+Oa(aPr{~NRKKK>f{_YlJ^3}o6(gsd z0E4d*)DONV|9446*UA#_d-4>3?iKJo`PUAkH>>&f%_uBoKj?M`)?lGW6deR-53mg( z8x=)0fU!l+9>A){7w0vYE|j(k{*xV`lzh^lgN=UDfUV}kYLnF+R`_bXJ)qqpUk3nS z@^t`s;;#dIR;+skBOu=e*bir9jBb%7VSMJe1n2+lGoAb|KW&ZUXOAB@GxN=i32;GQ zujGwO%V?0Pl#D0&3Glx(CBT2glb-hGr17si!KRN-BQ*))$?!i0wKb|-@2Xj)Tz`EiH3=Lgt&3$3qK%s(VJ}_~}OYuZBn_>ZQ>cc~@$hMi&#{OhE;J*P|U8T|Lx) zt)?#ObR$?qk6Q=^bfs^A@G7I)a5Vp@3VyOrD1T0RA8cfwRQ{AODkBC|e(o02Klh3u zR@#{fPZ)4iv{usr-R5)#lrcNRu<6b@9iv%OydKQR!OYx^ye`(ys`=D)E)l)4sjjE6 zUvoh7t>!z;_nIGEC1D$9>k|31nsb_;HNR+bH|vN=_bXGdRj26|o7K#DkTG$0WkF>z z9Ar$~4F?&Mc9)wncH0kqbj#MVF#a!Ho*%zpm(Er%+a8DR%noUcguA-v(OG#8DRZ~O z-t=Q^0vb%<%uu`!;7P&%@x%FJ(n2p70LMuB!BPs}(V_wj>+u=*&kyhpH7Hm`_EO|# z&?&U&t}aUb*orpYg;1|0fGEq^7`#EyPfi|1_Tw}BF)zI0xi(_M*H(52+_Cq_twlH+ zzDTGBw^|7Pf-CcBo^ti*6uA52;fvPTaKL5Y;d*Rka`Tk;Z(;rS;@8GyL21{XTpa?G^*hPKAddm=~WKm2r*51O$u@d;m zaokiaZrCBM%yZb~rQml2!vv$z@We)(Y^~Dl7YPaKg9icU{h842aM;YN!z4rXt_yQN^S}zgsl{)rDA0hl(LrH zIxNbL>>wb}P>YnsvfBf=vdF#^rcgjdFn|h1MTeO|jfzgI79%hyqd?o==Q-!zG%d`0 z-{1SsOKFpP?pdGnoM%7he6$qNF2DGO`n`(^xdBZ0LQHJHZ>Ik4eY`W*Xq!$m1e=NT-A#?5iqxODOF`~c7VIWmY931EqKt=<`90*P+#)VO!{;PC&4Ik%)pm9=m zjP8@=;?*VXRTR~%!hPc!c6Cv_%^V^9quA0#=dD=J`u=WuG#O7Wda^}OKhQ+PjFvMc zJ*!t7|l$myosOCiz)hgcAE}FvMK=ZCx59rsex8|kg zAI09Os{}%R$9**cWSqSfh!zKtGlmCcX%p-@!4}>&HB9}RI$GOP=o8HRJamgAm2d8M zzByNEZ=0H`T<3Y&hqvJsZ_n=DHnrDJTglqF<7Ear)SzU2F-IQJ8CbDBEmzr2c)r5@ zMHRkd*PL&2U~+gb>?XMMr)jx<+3J_C%2{mZ9aC(4 z>^81{s#L|>eT{c9OhnD1ovv|fgq?|#Ed*U{Ttl+|9c(k@0m4Mg^1O*#uX!J5jqaM7 z7|`v8?9scX-H-L(PIcb&+!mw?-B#%nADM-Zs*W{t>ME{=QOrF*^Q`?EZq0Nzfi*Mi zaE&!H>@Zm~OV(rjk;)InHP+07tG(T~L+wb0+Ci~bG%ob~vdeUse1@Wk?Zuw$~Dn($i3aJ8U z0C{7D8l`@Cy=2x|UM%rW*v_iEgf-E>Si_FiJN()s_73bbvW&htRbG6^-k z(KSrzzHBvty7}6S7fY&=ob~C$?u@1nvonl7OfYmdU#q-W;+TF^%20a~Fhxrgqv|Ho04v5;wl+reih~0dLV!#8I z$2;_WagJlRuU? zKbkcxHLekAWX(D#Lk>D46rZF&s0tc0s!9)2`pSvV;qo}CEoX7IZsGRIG$(&g)iITvl0u0&7?0PfKMBT`3l#-Rr z)SDgjNG3`=9@3lb`1nk3w&CMvy*UvdmOmq8d^8C$H^j%o_!wf{2=q~>qarCg+~O|;zBGkY*^+U^|s%r%oD&B!fn69Lby%eA%xpb26KY37emA^U;XZd zEU@}7yB^op(BpwM)LUCa{2fj#o^b?M@CovHlU7xoGFVlQ^VKHOP5vCz)nX^a5S@+| zRV@Q3coh%e>t!?#lj^bW++j=)enkg?#)3)ofd!m4MsQqVTbG1&vRA%VV-G#~+I{xW zsZ5#_GMlvuGcO)~>^1KzmtT3}wcW40{z{8iGGFO{-_X}KzT$Z$@s&5X?A!9*mg8G~ zdUfBHwXnaFiB${bJNa6`9C~tdkU10&WDY&aq;T^{2R*6QQ2MG`Lr-qjtf4123v1}M z*EQ3pXX91S`xI$7z$1kFoyPJOI{3XP78^j2f8N09Fd?>Sxn!( zY6MU;!ekN)?Dx8`i{g{)qU?tV%%hGy9BCdR<(ICDG;ft6bZ>ATL2QJF{7tIiM9F!m zhmLMrchtLd_f=&bN8IE**Q_I;`#~nbSx3AnT8P}X?E?2}n*@U^g_V%b#f)WVqRnyA zMs_*c+(eqgevdZ0B&^sNEJi2m6k~RoXB<&|jQ!cAlTyDnobKGKcJ(Nb2QIXCF2NZvqSBbnm*i*u>hJ{1>bBK}Bbxmb2R)|{XR8Q|(G zKDqiz&vdxm2kZ24Y=Oo6kkpSIwwU{~(UPfcRH!k`7;ZEf&Bh30?q>D#2{>hfqH_PU{ z-NY|19>oUtH|v8&USwzLLx2ajym1844PAHrU!_uHb7TF*qin!4rq*o*YizSK=`qg_3#>Vhw)-R6PWHssXF+?PZjQ?P#Cq^W4<|)Ewc#~{hY-B?A z^j#2o)O`f%j-d1%HyxL7;4qz~!ue^Noxyqdo>lX1t0>MIro zpXZDHITMd~o!c~nkN=pz`}JeB4L%}6jlpLG8`{|XNIQ{LECzxVEeMDu93FH~;^k3#O*z$*@@<2so#r7)StiBwmrP~SM{ev(%FM-43)*=r@FYV?E#Fgn4Q^b zc-T-~-K)6N5+9AD>AY(vu?oiw9E%E`~qe*QNY9a2uh=#YBys-we6 z@9dS=JbOx=qs{N@vj?9B74_$IKILt-^k$}h|52_+aV@I(0m#4$L`+`yUO^P&efLQZ4-flQNg$zIt8s zJ>$#crOpVXTdYeDc)xnx=2X5rUM9tB!JzFovL^4uHEPH!__{jdYh;gB3WD2W2gjO| zK?yI9H9MPhhL!Lg-?VRhSH7)bp&-IJ2TGf06FC>->(l=~}hI zH-an7_==4jXU>woW_!n(8;$pfcQ-|crOxk&>f(H}zxK`YHT3G2+79q)8vCYw?Hlg{ zyZYKU2N#!oT&tkk(&gZmq(m(wwkc~h-aMvJ=4sztI!ndX4PWS}I9E@6AtL7L&Gw8p zr`rddPVnV^T^`meQ}TYCcWj=o!`Bp3lw&+2yC)ssmR%xTg9c6Wlgf%5q2GE`9J z>Ve;Gr_1~~15SIpt+|SS8NTDC7xXJw@pyAPd-ngRv*&5F%DMy!6VEK;BQ?7oe zNvY%?dTjj6Jnibn7ELsF0wbhxv{w7?>VkGNX&n8uHl@r{iV@;Eoy>s=)-RQ=u*!+% zw$k&g^(36)FYx8pV4%|yiQY>lE|QwqxJl+I(inDWlDRQHu1_-eba!2qxT^iCR;w~r zH4FNN8>_!OZhHtHSB~3K@bT4gTMK-Aeca~2hwr!z0df>1Ql^9*EK_1nlzA6z#eyZ} zdCykc3!V)tB?C-66w$0&aN?8(K{-W6-!xV-*&I6>i+bzJihfC%()nbWw*w?MN5)Cm zRT?N+2RRwJfAOnoo)BAb12~zeKErufgg@##m}GTa+5e0+onme&eZ~e%F+ZF*{Jw6` z1SW<%GEe)vcVSOHYfdzZuOCk_ry9E9=e>f<~$l7Btz=#7*u-MbPX8Ax;$&HZxp3?n}G@*asvv=G%<1#V%5>_ zI_RzUB1{#b0(i<{kt5>@TEhv${186NN`X?R5gU!`|K4!)qy3#Y>A&i)pcV&h&(^#y zi^dL4AXmS&*t?A7)H_hdJwPjjqyAASz2-eHgq4Lte3X6tS+r^bMYE}75}NZ;NexG? z1c6+|k(zS6N-Qi?DfIlZwjypz9n!=XuX6hS=>|?#q6kNn-&E*Ou<0H)WturfQrN50 z%nd*sOQ)IJ89^NHzQe|xj!R;()6Fv0Nb~9DX3`+mce?qT|S53cYSkQ#PLx^HBrRzeN`upFKxYuy2lblZ@bE*^Kp@FFAYYcGBeD^fZ0}3{?svJ{ahy~?^AYombr=B zc>*I)cMm#G5PFPwnOm?7Cu%HMy*GHjc?;5dx@y6C3sy8RD`+iHhUk~hfVhoS?EPsg zVl?q^>SgbMmjiEMeXV(mhf^=pJuOKaFP(`Hm6F*17JG6wX!5&k-E8y0C&4iV=ZC=n zQT2MomlgsJ#kt}a8!gQbdB51`&q+J!m2uJ}ouzyY2^JS6qa04cLxtOKegyE;G1#nO zH_Z_WJ2}T3IfBNaHUneJpq+J$EuJ0fOAM6m6bZ_%Npr_{^DG-`*$4*h6gGli;-ZG> zpI{T2DTXf8$01V%OYApmcb(#z=7U71F9}ZTS0H4VvmZ&%Ahq{}scQ z$Sq4=`F8W=&7(KZ-8==qkGyhm^PSB@HvePO_nU5Sy1uE&E8lPW0Jex=E5S{~*{DHN zH(^4dSA4@C9>_{?lZl`ydQ{B>^i?$z++>=W0Qo3rD)PlwHJgBE2OIrQX>aq1yR{U= zOtpeye~4QN8u9T2tOTuDtUE?&lS1$7SO`*iS{(~PM@r-y{u*q3xt4{X0yk`O3&D<8 zM7-41mqol3V9n#Dey)j^T1ulsyc8hGZ3M*&q4)p5!WWr`=*PbyQ$^ubK!_QLG(s1C3xha+5K}%Ez1uY?C?VzQc zJ?#2=se@tVP87*oVoo;fdIM-g8~27}Gu3o2){ZOvWNoWN`bqC&npGl+77CVhZL0*w zal&c7cAzEQ;sldh4fb-Fn1# zd~_7G2qAE1|Pn#34|Li>*WdGqQ`zb}U|Fk)g zx@Ms?_DF$wi*dp(7jU0nzcu_U#zEzY$$7VK z5T^ASt~zeFFsJ*XZJI>B?Nwo%RKnSxHFPnc2?Hk>to z$($giu)Mp*M)`{Nt);0|!o)ACw6Qwg- z7(SPFzG`k`eA@Voajd50e=Y6&*gU|x%J`D8(74*T#<O(_94WY)+(9p2Z@KWhU)JgF}ae7VV8}TB^Shg-Z8F z4hUZux+rvUXl`iHy~tEbJ}(`sitPJnAikq?$Rknvl4A~q7Ka`VJrerY(2~%jp~pnM z?B-{qt%{GXh z712GcN7!RwJ;Qp1Jzi@0XY>u)FKXPmI=Z)IQrP6MDPhlsO%0nCHa%=c*i3qVy?^++ zu=QaZ!ZwB#Ib-Zp(LbeQt{6jV(<^N?1If8!(_c*<7)Z_)!$9&u@m0r1#ojxJ%6P2Q z`Bcm#{kV3AOcXlMTnNHASB9KkxPAfY@-Xo4gbZOgPPM>SsI+33(}OEDR)BR+1hW7Vazfr=C=OR!cx=dm?tIu+JkJ|n3w^S zP&y{2kEGvukQtwe$v4hEq>E%>kINVSNU^3E%yG9Pb8nrZLZ73xWncM?qIlr2u{-dP{Ef+ zs07Z%qx89l@ZFztsW^d7&&pr#N>D5F=kPuW0QIGM+4!+BkL#}#v*NKajayI+_WHal zyyBobY*E2IWVgr0^ojelnA~NYq;a0*xKzxBjEfo2IB$bv`XSrw%+|hxw|&R{V~q`$pm6(Im_SY{^2|Jr?Z9f1EvJBvqbS) ze5cw9_)8tL4?!Tu`SWxDvZY)UphH7Z;C4^}&bD}gxoUwszA-)TTK=RGif)FeS_eH1 z(D{JTX1AcUxgyQ=X>o4V$eKg9{oTJP2J(aPtSGAArpjcdGO6CXN5y;rrXGk_;9r(DOitJi|!1AZ&?{`?xWt2U~3 zHDL=o6l)rypIk)ycO2$HYveUyYg(`Au}19MQLy=o?&n;OsZl-QeBTbz`M#ac$o^St z-_FHizHcXC`#N>s&c$Lt)T69Zxqbs})!EPX zJ&UEaZXI`evn3_wNIkl{F3yx}T(aKv?GeGZzdb_LgBB6|yjiOS-*(duT7JGzuIduU zC+FKiZ@5cbagdS?V_*Djr8BW%07E1raATD zqxa0s8hxu8)B$x8(Z7O-enk1|h{Jcp@hvNU7bg*wZxkXry2?d#d~y-J`$loJ#*UZy z(He26iBk(YTI1UzB%goFK0AfW=TLyl=Trg7=g3%FKED7(FAgURY+r{WGv33g6R6v+ zn3UFC-^8@gj0rOB@&Y@8eTLp*?`zsNg2wEZnK6xAm?#{mah9pWuK^S!B*M7B=70q( zFEOG$_C>VYD77&bGhnT_hYz28Z@_kJ6~sM!;haMNgV~rvk&X38jq-=iq3Qi;cFbZu z=87V1rLjzT30s$tjUT2lmYtsyGeBC+X7n&Lh#I>^kS9#CcP<Vd3Py(sAhySQ6;X}v&?+8cKp!C zOj#Y?M7qGbu0}xgoLAW;Uq~-%i{Gs`|C^8&`rlt;hp$Ctv9)W$V{xE%j z0Y553vq@nVzROSVHEr0twmv8r7jm$eveJt3XXcu*FGrjqQ^O%zKR*gyFyB+tL6fm{?45617 z#Vj82^^RNH?rxjDh+TWgyX zzS|KnDSW4H(c&frJdjD@yElbNfgV+p0)16Y3g5k{nG}$Z@57oC2s7|(*dY!PYJ~Fu z0+9#J0yc#RKA?b2Az9cIT0Fp}(DFex1>E1M*%Yex)Uql3hE15d|mZ?S>-F@yC(b_qL! zFF$6o6!*Ez;1UTUX9)Kf~+EfkoFeb!CXukEumfhmnV*?qZ~dIT?bFkz&uKel+^lKio^69jcYE8Z)8_C*^O$ERO_+u}r5i59c9)7i zi#5c}=q%~_Hqhni^12p&e(m$S9^Dz%q^aDIwQ4Gdv%yW}c5WT>&2H?QmFUYgm51BI zGpkee%u}e#H2CJ3K$JT9=E%Oe^>4Y#i~fYWWN2Y(cHv!RNa4kPPRqsBzOu|b<+-8W z6ILYou3ntxj6u>8rRzj3DfeP8XZ`Yu+g;}Qlo5r#o`|!GKIgmY`BRsBae_0noEe(Q z4RQ*P+plGgIAJfZo#`!Ie_w6{I^=WcSZ?{-^L#_&eIw&8K4A~_4V8T(>)*;PcfdBY zLzk%&UCXF0Ds@I)9BB`~_)W&{6{%H4Y(X>mQ9C;9c3xD57Iw6sbNy8GXGV5msr~JY zA%*1+IZKr6LiW#QvOS&Ws-H0w?|6u>=@|v0U%`^QOO3*hiUB-m;KPv#sLVBCljv{Cf=kdCi8K z}vHu{WC!=^(=&U+TPbDAgZ-_0pMhmlu4|?ThYT zbo=>gyAbQox59r9zjE$!*_Ge%$5&Q~%O2Yp{Igy7O*Je`Z2|pJ3fEcE4gTVG$?+Mf zyj`VqT;>Y|)r?&R|3c*LlwNt&ceQ={Oa81B!~DbT+xxTH7}~dYMnB|ADg7l~?yi?w zvXqDAY-t_Ke^{O@#j;-?mOJX#+1N`{r3B+?nKQM#uHD=im%w5kksI5tCtSOF^CN@t!-Ck#kA6Q_cF5bf!SCMd3GB=!eY_r@?QTa| zS?0@e!)ZIUH-vrih`g>-p{&aotegIH3;auXYFwMHl}g?{cvihJA<(>g6+-iVqVTFC zt57*Vg-_r$MbF{LHf73vN~K5T-XUyGH~CS^*y-cuV{^*9>0kg{^D_qI7mv^1Jtn{HGx_EH@{0%LM-0q=cx=A&v3y-t{-%NXO1J!s zXY%)s%zx|g{F2f68BgR7Vyw4pZ~gh${QREzAN9^3+dsdB?%E3>`StSKqd$RGPe&3soANBjbZ2YL-_h;ir{eB=DKkD~`+4xbvAIip$_^w~w zYw3clrTAO=#L|i2SZ zEQYbmj7Fo*Fhx8~UxrsY!<=P$N?a%s^Om8s&aiBm0ks)kLIG605l_gnMHF~rnI26T zcDO|od&OfhstM5&o;T0osKMi;mZSS5z|0_vinVFB+{QUM>mtAK{qt{}A_z2MP;#|p9v`WFl- z$SHWHU{b-1f_VkG1uqu7RIssNOTpHHT?GdVjupIHaJJxL!RG~63a%FXSnzAX?*(@Y z^vlDSM=g(E-e`G?wK_;T-JTU9k^e0HG(GZ_i!dzruce)yoO+QB8f25Nxg zUXklwQA>Q_%41x?!c7d0J4NhXUpc{jrzovmQra4&-5Ml;03zF=)FFk3QU~LAP+_J$ zby%TNQRMiw2wGj%uSL*yUB4EU_3bff^cj3t{$1p_QAD19+8gB0x>008Dt+?fjKACH z_t5%Z@)QgqhMtB&8L)(f6Gz@W;q94XL|Vc2zaW1$>GNr$q?Ns+BMX(U9B#gBpPdsa+} zmg=Tx&xPGZ4(<7GgZZ-?m7K#=Qs|rZ>it1@1p#-(Bub$RJEA3?haUM6R4p;Q|Dpb>bs z>1{f%UXS_dpbQSo&)~w0L500C21A}Q(=>mJIkJU%4SG+{iS*a*ww}Ap=ij-|1#HgR z&%BWdDqbr_*0HC-Xz!S@a|Lh)W=D>5v~`J&r;7z{(rI;ssd#oqt9YOnctEv=JDVw0 zMZA(m>RW?&E1t^#;}(yX&UlgqGGZ<|ajz8ywxJ6K)~dDB(59M#LdhWvouQ2mh>KIY zM-;kr3=LnCn&`Yu6Q=MwXapDtYNPfaaz;R~d&F+^4#5?x5bHYP1^!nD{*~SxC>!Jd z`dxTesSQ>}b&(Jf)y{^C-l4=Hyuyd~fYsO2?CWSY7}-o?XdEjY6BSj@_IKVR)ZYQ; zRr#}YjEx>IH-h+hTM{)u1l~9qgAwCAV9nUN;_dWMc%Sul8eDrAO0d>24y?5ig{)+} zoE*nj#=UB)6{eyQFclTD_a?~BhFe$2IvO+2n{b80b)qJ86IE_S}yxWzT)`;BbX1UaE0?+u3}NWcRc>GVGuv7*OM1K*6eyuQJ2*+saO+vGo5xc$RIW37 zq6Y`8AoMiJCfY$M=9?@ip*m3Gg-0%Y*+Wary{*F?2)ASB)mb{ufjj{06sQ9&(Sg5oP!hBb z2pipkw*BX~?UlO~c=hHyZJ4|~23|uDIgipR;CXFRG$DnU zi7I8lG5~)Jn>0<{(hPK5vOBQzLYs--Gwxrd%sE|d+piYYxmTUBZN)HHKToDpufnpZ zSAx)napHM>HG~>+?qT7PFZ04DxX|ku;>*?kvA3qnkE9W%Upbv$xVCLYFO2FqAJy1C_l<}Q_%tHHn>mYg8ry_=#`fX!ONW&5xRasJ z!;pf-EzWU_00;~OSvGa1Y-@1B>d)eD1)3*7pg~VLeSc%7oLlb!GthRH+@@`<8K|nx zc#HZPc|4skdZ?IyNN~CcJ^}02u$N}Z=^Y+K<3&k~l1e^SGj)NIf6S6wHLueg#7wY8 zEsH9$q9&F#TW%PF>1WeV$X2#wwj6GtqU@#Fat7RO}yq~=cjzC94I=r7QUiR42NgnSCgo0ka$9HANYpVz`Ax;yY6t25ng{%4QiH8 z8D7v6l&2(UMQq=5asu(1^UukBhCtZW78$jrbyWDj1PFu#qk$nM4E4Z^qd^k_i|3VW zu}}g4nJ`aIYj!^xLxVwI1R0`^lk)cdJb5H$L76YNXeG2efGpD4I)ET>^l}ax9bOAa z?78`J;(beEhq`eW^jx4USelA!jnBr>s!XIpy?Sff{%ZiK3NBoqx9h#lW4vc?HQIUHxcCV`CPem zqyLl5J)vU1t(~?^YxrQ$N(WaAnkPJAuA`UKUNBC#taJ&U3g{*nKn=fp_{sYRKm)Ed zfE8}}u?KOe@7(g>R<&vehtj}9%W*)R%Gu~8az^d`@DersIgnGQ$b$g-0BA^_ z?0Qho9?g>{SZnnR5d~?L2cgX{_HLfca>bo?j;f;onmHBRUiHFRF`TpewT zg=Iq}1Ert5D2GYzx&p=lYa4{_!s_FjX7-JbAg9$oMxriqYx1GBk?<W5g&i~8JndB7;NKm`L>V&f_W$O>0EtPR64GJ)!7;gF4;j4e9h`7S%j3R0;kr{ zM~}G=a6v;?>b%yu>%hIv`v<_iP7Z90tUEJxa;V+I^kQCXzf&UH22^*b>Z#*EJcEr| z_iN^C)MUB-|EC%`fG$G_P;Cw*06b77Z%c{_#4iI>aVXiGsb@y`J4N|B#bh4$cZ&3P ziq5q7JH>+kkUNr{UnSc^>HGJL{etf;l3`W5TzU1DvO_p0@A5j-v~xjetm8{^3Kmsm zzt%7*%=eF7V*jpOe*tw}OzBA_6%Ma%xj>3QO&jLGy|-#<`?Y$p@?yxB%jh-Wet44apri{*%jy}@VT}kdfa0BzitKDhMcPrbyq*|dPbwv*)=u0R zNIZ8rQ@WKpq$G7{i9fx=ZN0x!2W=AWD#J@|<(4|b@8~A)E03{XpDo_7)IpTDywcyv z-NB!3E`QJ8$$VECRFeD1h0@87I8z^SX7Fzp-kto&1s{I%r=Y6bG+pWY2d5xknv^lP zBqlvHV@QeT;1q^mR1;Bp!8#>%SV@PBVI|&^Q+N(*cL+jy$1h#4|yxBaBs<1slf0gW#gLlSFIe02XnwMMdc0P9S&hL}aYzI&N6j8Z9 zJc7?iV&(WImAQ6I70Pt{cg&Q`kkltjGGkJ6NH27C0s3BRe8Y%#pD1pu%zw4|fmguiLA z%HWa?1VkmL)_8~>Mp`q0m=}6r-vdkv#B_y zc$D11{}e5i%7l*~?c>nNtUPbL!9pjM(OFhJ>MT1Y+%gKu?6Y;U?TMdkDM^WT@4rF> zlW8FgSA4f>yg}QwV*A+p?+}CzI>L^^xGh1}0f(btK~c#2lkIaHj=Wy3Z}2=1J-zpO z*hXX$h<$O6_FZmw zQa|71_)JX=-Rv-I7R53)JJRWEA5=VTv*TI%esN~%-#0t{wwc&`o-&L=Z@@4xa}e?t zVxv)1bQGeE@v6-BpXD$)hp>Xi=^C1qc4#aMbyYHeHqrw$VDq= z*$C`vrnh7u)_I`B(?}IM%fW zN4mMztvXur{_W|m)vJ3Rr-hF#qb2~Py z@^{DUU*aX5ZcJt*&*WmO03zfQnH+17XWgod<*TZ)?M;N$qztW6DFR$|Fp!S=3 zY{s`GRSm1j@-nh)pe*ZXrdB^}X*ONP zUrI`GvGyMdTa~F#S~d?brooffQp~2W!yle{GlI$i;2e*rBuE$HGbCWS-9}KDkVL%%AJZ^!p&6;aas4d6&-9kDwcI_1rB2_SY^V+?FRLQ z`%vn+6}ANcGN#OM+}>J%H!d?2=|CmN$Pye>;22$Evj925GQ%i)C@-Y5b>p9%mBLlI zz9Pds*T|A2P!x*?I7KV)y#J*{R3gUaI=>=WCp}$aqOuw1 zS5)cj3Jrz&e;)m}fCyvTbH=unt~XcGO4oTN%&wB`ag=GWnhCX@UtybFrB63kxx;Y5 z5|tcR6=omf&l+D6s=MgCnBW>$!c7M)S}Zs^YJSPE%l@3PC9*Cw!W(71c4^_!{?C{6 z@^{}_;m?|g60QlgbGs(tnO3KkaeD=CQ?;Sen*O7qFYV94K07A>usWmW5bMJ7Ccb%h z1W}+gBLb+7ZI&HU2)nXbPQpj!X1Q@2BFjLU2uo2Ouy@lumHd#K2ZTb0JrPyLl=?6g zVH&#@vd6c;#nH9U1df|X_M;9W-Gr-n`c?ZnR3lgE3e%YxwomXZ9@40%=Pvux(-Co| z+?dN{OfDwhx<)}~oznk2l>owI=3GZ&9bc7`Vp0sq$v4Gt6lD`$ zm4}fr-~fC7Rk%6`jIJ~THdT$Ahfl|e3T(^|;cDk71GyUjAb9G;J{x6XtBz@{A6h`VG>I${m$oYnOWTL8Yi26_ZVHejio-3>327ls2Chwl}yR zKflPvzApDqG~sMXva<6KiQW_2+Cdoj%`F7^rqKsx48n0$EV4v8ImC zSFrduWM|yu67owClJ4?ni`Wa+{|(uZIJqRKJ%lGvd-;LN*qS$F+5Ho>2W2+ZfCX?) zG97gdGX(X|pVb0x^mEeW5=D=EAlWsRXs*&b-hdQGWEhX#8S z=X*by4^X!x|1-_2WG&6>UjI*HtOm&y81fnAhchg8r`%hMMG|{ifYdsQKM@8}coX0y zA_ORtM&Cz-z>8H+_G%i0-X zE4Ot)_GMRg%8lT8OM>_W{~{fT(@)z!gJV`gSj;Zj3IlQTU2@B(qEx3<0zW)g)Xtq( zACR1PGlNx>I>oj#glEtWN5J78jR%|8^|ozV2ViN__@gu}A7iHOv4gwh#_b7zXuv`6 zmgZpSy=#Upa9>&+C|I>iwne=doQWmvmYW)`Lb704yXDS?i;z&+s@<|PJs1j3Y*wVB zGthy9)JY9+fz+pJrh<(;E;nZ3dt^)0akdoa14-lWGidlXZ)Qpdh;_!)?0XZJ z*wc)#xqD;8?@A-~ZI-5yrFj+jHML?q_+mpS~_mB6;9kCBuzgKRB zxoEprZt6%ect$>^Liq)yD=8t1%cWk6%5}w1(6B2oh0R4ieb`a<%3iRm6YRacazhsZ zfDUvO7`5pFG11yb^P@nC0%{VLq?!lN%+LkitQiZ=oMTJj<?L3Feg?T1_zGJ^*?1+d=VK?^6kEIp) z(*BcAqEI(<^54Gkw;Wvzl8B=0VeohFX#hv*ZSeK`#n;nMDoVc6oG@j|0XbFfW-#H5 zZ{T6NsL|kA+!IGj{q=x6GShgJ^nzb~S2=jykTtvf8&cl2Ay*$bUhZ0W6o z0iSNQquIc@H-CT^{dtsqcvzn52C#GcBAikj-zcb9Xozs|K!^jSQkU~mL0PeHimu8N z9qOxef!&t2405M(-yY{6nwE!+^5q)Kb;CkKAzzB49aSQChB}N>|M_L6oVJ;e!cXSN zW$zx5`?=}v*&D@nAeK$Su&Us*t;ChCM6G!fg37p$#;&{NB#*J}e%Tc5UHt9{uTK~tBRei-P%5tSYoJQw@b!hV$OgcX5fe6T>& zr9ia5W+_;K@i+b|+mZ>LtXwb9+m5-q5#r*6chZ}2>ZOUJFsf&5O5|yo^wt@rV1?y$ zqvhs31vNgXB|Kn_1h*$?OAl*;eOV$uO&JU?rz$Ph$RjYTg5cuF>&nxt`P=Xn z6SlDdZ_CZCDR4^*ctMBN-1eJKv(<0Q?I9{cXXNg`0Ahe{qndr}tGDG=Cav%R7WcjPn!6=MzGg}<18 z>+-IgI!aVUals$aP2V;wAtIlgX7eSat-Lge10oPWMB1DfL=fH))>8bpNh}{v7`ybY zJi_uvHj)Ekd5EVKd-xQ@A&HGRC9gElTlV8AxnoD^Nn%D&?0aHH=?Fov2`A5>xpnPD`G+e5!Ou!&R{j!|OSM>;%by|KR{wwWKm4Fe~w2$pR4YU?3 zCo_kP7>Vh^O?ytcolgf>z_pgsM-ziVQ=nI&6WmT?dF^xp#S)7V6Vs07%$!azp{GQ# zOv;qI53VU>sh}aPKp#}ig^FsU;}ntWC?Z;gVh>$?*^D!CYE+2za%iX^ZO~l~osnBV z-ItU)v6T`Wy(GbA2f0*P3svCH>d$lVjiyj}N^nSORe2aLeyJ|kO`t{(SS_b2G&O4h z;#_gnjaI`otg4-q1=ERiNQI<8?MXExbSxGr7w;+nIsd^2j$2FK>SvMLQyfZ;1kYcr4oPox9 zC`2ub1FPtufc9)XEBAO9D-fgV9T?Sag;jLK0@G6re+^LY0jQN{IFu+v2~fJQmD$hn zB{uk++|sQwc0|M0QBos`dhnxLz+|DD5d`lM1S>sNBWpKQRV{7SS(3>f#fgkm;C$P#IUAasUK z*ij5?1_@#iDA2uvK=+_SsIR${<1iitLPuEE2Qt8-;@EAVzr#3ixSVSlM8JeC1MF0> zz}BzJvkV{#W0*^AD7rjHxk1N60GaRvIt+ zA%=Hmm2U>sC@h~Ldx`2}`_=6hsOT z3o)14>${R!=11_b;SDyCsBiq;0kT+~h0)ydg%X%%EQj5sDn$Bob{habjs&pHiKJnH zB*MBBgCmU;6}2a6hMFaVj;a>N6u$Sd3$EJcDX=wDyy2UtO&uT{5T~rRUDAN4Q40-7 zkcBW!l_fMy$^}{O+L)FyL~lHwjrC_evl1Ba%t~z0UrfHjP?GkaSs6Ur zD=x@M`e#d92&n z3Vwo`LwkT3fi4ikWgsz#VfW{pt-wrNAeS}DVZ)aRmDo-a-b2R#D!Sf4OK((Q$m#8= zTlUs2GR&jhrWz@ByUJJl=5A(jYGdb#6nRqOo+D>VNvGB{cp0wv~<*oF?cr>ow0jV9C#hZ>B+ z07XZspIW=rU*4LN>p3B=Rt90HCkCaBmOxXFY}3c=5n4gdgb6?d1Q=B7q*w$kRQcTF ztHoJ4pO2d0>sf`v31C}Li!R*R>-nUe#gNnoPXMu1r5E9HK((m2jaIQh>@wvaK}7wg zD%ElO)tNEqf89#36h|cWyB4aWc{*I|Oja8XbYx-MQO~y>mb)EdTSw4AWqv_<22 z1z}hMLp8D$jOORPa;I(_V~9Cp#i$}jv6fkblprX$9#(Ighl}sjr3~jGhX(8ViJaXt zDoF3o{VV!&B;aqM>JVOV#3|R&5qR6S9ykvfD>#I&;47cV&D?6A^wcLkG4T-FS<$C^ zf!PaM_G0yc27i8h5~q1Qyje(y+%fR}?nxp~Ph;S#FgOXlz@G*71ak+dL98p?;I5I; z^tLx$8AR6-{8?aLq~wzgf}7X!loiC@R9e7oZ$bcpYw8VJ0=;Ohb0Lp+2(lT7v}JqX zl{PnG-fZ18y5$yf%Qq7Erp?7RvCa`KRN2#Vsm}FeZDq3RtAmI48qSm198x!4!u*>kfKj%UPL_A*cEddtP!PZ`q zt&KjZm_UHY>IM*Kok14f9vk(FY{!A4uz5@3~3vVdsSDF$0S z_bu^Uu&P)|6+*HqYYQ7cGyRAza;3rbqih%7`u!-|8fppyeEhr+s!vPMYJ5M+-Gn_`g$EDy&S33+lH*KRizd!YSl^%I#`R7Pp~7>kS~;UJ zz)(D~ML)@@roebv=}&TEWM{+T^6LJJ%42%D2C}O^$+EdKt!%=R&P@7QZkU7u`ARk! zCjcNaO>+QQAA>JMNF7jF9{pKP7{P6V0B%MGSa=xzKJth?3`-O`Vmv)*X|a^14_Iog zj|IP^7<6&ET#X%!9sXHv3pMNN&vIfTPFzel;2mA`pcnk;OpK75;2KuQEwT9zGh_l? z6FH#a537*pz{HS|!9J~!J2&CP05k*+dicdEQCOJfM7;fC=DH>~2!d1JYqG7CX7CL5 zIvG4ed(zPbFjVyIfr|z-Ok(R$B8*G+K+)oBa>rEQ%2Xg_O+F`CnSIlK@{RwQ%<{Np z^-q`r=(bjLhisS3`ipG0s@67ZG?3~i-_W1&lI+2(-!F2bwx~c$RE?PArxA3YA7lK7 zZ{DB2G*|-D?p9-ZH~#|Z48457bWZGr#X$2eoJI7ln*l2gIu!m2qOYQLo^pVe5@2l6 z*e0yxNyu;W9pXMFI=U2AYT;rMR$WRm(Y&(^Klji)>6aZ%2?FGy6J4&ThPowIZP2o0 zZ~En?gD}@K?(?kaYfr|E$F-T@IL;xAfs`qKLT?0!$w*$|8%i3g0PwGJdcvKhU@F{} zN+4F@&p|x#SGf^cm~(&e9rKd|RegCMsIg_Gg`vu-dP4f2Q#y06Iq^R}j(lYoxh&}% zJN39uE@KUIVeOSTTZqE-1Pe_JxCd;pNErqjRt+RE6Vg6|Nfq`tpT_p~9tKD}}6cpNqJ$YSj+8#*x1#xnyz_qFs1k#_AY4D!6>U1HxxZa1J zxcJ0(PbeAe@O8PNB|~dfuyXH4=DRLi!!itXKS^hH_qyEZA}feWg(-3WAe0J9|K1JLSi-QiNXhh0zsU!IsN z4nA51i?ZpqKOxf`v{Tc8Pr%Mc9*ozNDnx46&Eo2mo_isaAgOu;eq zmJGq^hMM;f(&OUdu3-rRtU|W!M<;!Tgivq^H*;!&?_)$WA$1CY9%3yQjcG7i4xWJw z5L5$YfWx#_70AFI`VGPawZw)8zAXrR+wvQB7Lo~xz5APNcMD^Zw$vc{avqhZ#F3cI zXD*e9PeXhC2h6VxwhB&1Yts)-x?BVd6_)wR2jpoJ6@g0D;Al%tz~LsE|6W@TYGVbz z!_hH*2)e%ice%OyU)Au*0cYQtY1x**bdK>%83Fwu+p>#NsW++s> zeN{MG`vJ2RE(T#68<-cB%-F+)&E3{J@TRteqY+qF5I1uZX%aqLLiwf2hh(oM7poD2 z37V_h0TLuur3lh7czz%B07MIlQuuukp;4T@jg~DSQgPXn{rf+19IWo4f5=K02-oMx z&f5IJ13$9=kdq-IF2Jjf9Fm#<`1v66yYV0c)xaDeJV7oaRP^Z|a-&#Ys}^ooaDja_0*?G;Fs7S_y%A1nZV0!aHSt8R-6xe^^Tkf3BnUG zG$0w(#vqdt#R~>97@~%iPoNbcjf$GNs=AIoS5Qa&L0k+?5;J|C?ARKnD+Oi+gehpwq~E zvQ4_h=G~J!cSTe;97cQz7<@yGoNO;uxFdmNWrTv@GWXzEkd0Q)jvT;Hj}ueZ=ODb~ zw|m&a(Zg`Y-_6yN{vzCp%h|}L^k8i(o*0eNH=f|lqSM)cgUpuBq2eB2G{ zoBf+_7AvU&zv2;Fm#bv^V;c2|tO;VV*}!8($dHQLOBKx#r)rz^V42K}hTWBWWl~s1 zwcOA^{bnPop;1$%Y;m>R(pFnV-I0^g8&=y0R~L4=T2@SO2dUn>ifV}V{IM~ZCE}bA z!^xLqO$;Xvxy`Xn(<(r0&k~r+Qktp==FjQ^`Gl_96$OJLLv0!oJ}{3U+eDEbdO(9N z)Y|V?U(f3%=v^Wl3;W$Ehzsx@F+hUFZR5-DSX-KVP_U7uTJnDR@=a@N*G4FUgp(jC z6bWi2wBh&kVn#Xg48Y$idv9RbjLH2uh-ow<;{9wM$CU zHA};qT&_J8TqJ4Xz^*B*>4<9>QM%gK%jj5zt+g;?kQCBOwN_thP$2;2_@V;&wXuCh z`Pus+*5sgwM+~@{TZ!+4Sd*k=mT0gh#*qaJfi`?z5Fx-tsWC!<)ZA+oP(3b=QuY-Yt&MR+(bbyl zcWY&@Y-Nw*h;|2vmR2p47MyCej}1ggQ1t0WYg0FI#yc|Y0pN1D#ux9_Bw=i}X7G_4 zoVfKXVDy2Q#S`wK`C3*W1P$G%zCFZ+tUP5FQ4LK?PB+BGWx4~2q-Uckm2J;PMgdfu zs2I=H2Xs*tz@4dZ^Fi%MHwagkD$^NsWu)oD2?gUfcYFneJ)xv><1S^<f97qp#+laM*p*$O#TtrMPS@eN7jrj3LI@xo|~ zLlaLC4@_XTBf)0{3S%*76zNg7jg)k`|E-Kg{+G|(K z+Bs%%Z$mEF50HRM_1gAV+ozh?2aj*taBGX9+l!{8Uo1_C>}XrIkor$bg|*`{MZl{55r~5Vjkp=aO#*0WwQt5f z-;7E`I|{eFa4K?~sSgCnG+`S+Bw-s+nUGPKpbZ{nEUXWi(m`_S!L8RIBi+!e#uW&+ zy6W<>xo8Ngo1H!b856CVudY9Qb-f4(e5r^{Oi!^`Ghl?JqdprFAcm8ohI}<93Z3HNM~YLE{gMdtv-*;{kJFl=B>* z?}S3s(OPM$5r}edpGQ1pR1*mVw16jY1Vo|=c)%4#BhTLPo;RozmCd5RT$2reQVk9a z@w_!&iUaZJY~WN{l|-SLOTV~<3mLwYw5nea@fICvZRc)@qxfmx)57xx1dfwt4<#1e zXwl*t>Y*2%frV;N(>&W#uKotwlhkXFQreBzPYfgyebNRHO+C&s&|hSB*&4&{C$=_I z4k63N;GX+|23u@@TaYD>9D)Ly{!R)N1@&u6E7!v{kJ3MVbFP5h@<7Pfrus(y(>L@A z)*GoxtW%V=DFvy$#KuHfAL>Tmrqa2EY91~=K{yum29imdw%&v>d)hyJTNu zTuS;9PUR@nGnSkUSj(QVEIiu!2$*EgXlr|W7xJmmK0Pr+^eY5eZKgox&C%B8k&q5e zN-MSa$I;e?IlRUik=-}XZ5UhRvK%K9S)8TF{s}+zMkKLqWebv-8b|fsG7?i3M{WR zZ@%#j{Z@M;k|Q8{eCHc_RZFd@$?+G~#A59i6Jk|5>$pDQnR^ECS!A&$VE&3M)(JxA zk?L7hBOkg%8@YXHUqhPpVgD_S>cX*S1u{EALv5>|I#<- ztN#luU;2iArNNS2s%LH87_21b*+3J*tdUke%9r+|L0ZEa##y@!S_1)1g$Ea(DC%Em zU--g#nXg}k51UeR{z9yCE$zChJM;9+CsJSnD~_{Togy3WleW=88!PXK5EG!&Uyrl4 zGEm#BNxZeWfxK9(cf9qXdXRf1oh=paDQsb}zvX#*D%%imb&8|4-ix>92%BnReQQr) zd!1O{+M*?&ZxQGr2*EuN0vtFU4qT*D&Gqz|TT0K&YXz_3#zc>IhAN970!Y<(K*B!% zfHu5x#sL8rMwxR^yKvTKB;T>Sew$kF+m=tE$@mKj#7hR|GDc!?}RKJr_~9C;}oWD$Y2dBBD4es5payAXW+@ z2&R%vx*J}D)w4PERnmKnN>-Xw+VFbyZb?P27mrsq*kJ1ayY@bJK<)SY{67Eu#64%9 zJ*>U<+H0@9*4k^g9#|)8!0nX8)02@m%DXBJ?Koe)B-Dc;6TClJI@x?p>pj8+jU6kS z86Anorm%INQSbi+ub0Z9f)Q}wAsJgrToG{cmvR?c#ePQK-pT!!Ox6rf0!c~2LFB6L zdO3<*Dz`r4#wOn!$#+p@wMT3#_&5Xue76UqHLPns*D!EnsSqEs&4%-0pYE8zV1y=y z%Dq6{7<05?#1bJRP`4x(ej*Sjf{z^e3Ds)7V?0DhvBu;f{%8u(f_n-jFG(}=J=EwM zk2?g`W77aW=Na~1oskevw~;%h5KrBR# zc>$i8_{{`2x;7w0yJAmpMZJ^aGdFqH>#Ft-dlw{nS4$H-yV5vdKnBa6Qfg)Y4Kp{K z*pOOD|GwLBrl0=JS^cgq+r#O{^kX zOP-vw3Eo6bZl-{v#NmP_e`+aB$~YlPe;zWNi_K=N1~DWB0wz-nU9V-Kdp2w77p zN-o#v*XwzkfYo5z74KJk2bivwMbo!c|8GsxB7~zdzg;r3$XG4xY9P}8uRvJ05*R?f z*%pT-#zk4g7=v-n&bvRbkis78jh4YKVi70+aN%S|?N-Wak^K$o!ek;2%RYuVr*%#7+KDeD89Pjy?h<| zKa-)R$$k;|D(#B?Jb+FzgfAUz0T(F!wR#2NO1W5!B1(C!eO` zAE7v(BH~aLi|nuUMgCF!ugIV1CzGL8K6^#}+WuPdSTb;-8bquzNDQhciZe#++h`G` zyEWv|iv(b41*LZN*ZM&s=ci<@waoC7n0=tC-X&v1hY!#O0L;|`Grbc;|`HBPofb2zG3Mc4Lf7lfrHKt^syunU|t%`d_kqo1)#Qb+5%8p@!8B#5Rk6 zBs3s>M*5CjpsyI=TO@4u6ifgxWv&CZXh9y4iwAcvvS(kj2oyPgP=tsSp|I@t>>~aA zy}N3IdL=G^|G1x@txpe3`zODluubVV?{Yl(js31&j>o^Tvt5p-zY%m}9Z1H#9)Yer zV|*#kC|~5c+HgloV5=SH6K>w6BYp%jPNaHbXC0&5PUUhynLU0GOinikVTgn47r(zFQL2w}g4L-oWhP@NH3%#AHLzNZV)@4$+H zH@t_VuJuhQ4&2^#e_Xp)ME?LcS)l}xA8ttzz)4nE2^8aQ(AL-_ts(&s54 zP#)kwP_;3?+!M|F!3Dta+%eGMg1W=_;d)V!5+$j&TPgvDds3W7dM3`!Mx;Y}vf12( zEAH?nqJ6j1L$t|mqBXvQVBhWh1A>i%?T&}FBx*%1wcW@SgD%65m>Wg8EV(O^c4mB_ z+eSs+nErO>AAeWyy{+?L`a7NC^c;dUHt0jhU)M?}bA}1eUD|&cH%eonHq~0E=xv=D zIma#JzfAUXqurXL&!+|)M1}g>of+L4eR>x*em?790+b)v#V1-z&S) z#4%mDZ8*vTzoNIr&pY&E0Oh9-Y{Znvz?A6O*pXf99fr%2<(?H@8$}Jkw@*ViARqPQ z?3#Nwx%L2%cf{olkM6=Q!A*36E^z)S{h3aFi0NSZsa@?yk9S<3{%q$Z-_+~cHstq^ zLTfLzmFI_E`ef~;t+s@$XFJ;_;gim%4J=^d6sN;y?n)PDmPg#HKOn*Sib)+q)u(=}$Z^ zlQp!zrzlk(2|~e7l)H_q>O*x{j-e_?;S^6{R{*&E-tf{HtwVGY%Kfo589qN4f_f&t>Cbc4K&4o+0Avkw(;nLP2t6~?p z#)1+8Q*rj>!t1GvU5OA^0&PLDmG1XU>_3BI%iQmM5$UQnD7M0#0E5N_Fk$_WclWH4 zHJ<8UkjUG$+st0=F1p|sn8C*VopivnIf7D8wNWvd{yQ zcMnuUQqrI82GJB(^7HOwRyqvZ0p6z7UFrq*XNXe>TS|gHdvX|etT;JLO9&8J>-Gig zUYuECA;UF4Pg3vUT8!sy^l;7AZyH>|zH?T>J_XYY!5f70e8Q^S+P=VTGh#c2YyISD zxb|5~Fx@blT^gZ92=m6d;adN`+-6N?Dl#n5;eJ)r;w<~zx%>;!LhC3tc7!(3cluh; z$sUxC9JK(3tf4ip+p1Gd@i++mIUR)lqP4D&eL4c++drM-)r>V;%QU?=hn*X(X>3Kd z78d7|zhr6tPY?7mUjZ2X)brHvhx9RmMK$lQco z1Qh2LTI^CJbYGN2u@c3se$|^?(EpmRok#wCGJuU3t>yWSE5S(IGFpp}d4iQ=%a^dl zJ{_$MAKMKzCR{n{8lj!@x&!Xa_>zXMqxIq(GWl=|oni7>I7XW#hWyAFZG10&S`fTQ z&~3n2PPcu>YAIGPTc;5PjoV;Hu(e~gxZd9_lx?V)qSlBbNE9dlbB=ozJ~CDtBiiU1 ztHoR9E+in%I}3jXKPC$#)5mFWztsfN$ zy7<=wD4v$H0TZ=&Q~OdjW1_Y(0ygdCOJx)MfzCUZ|7@ICAICnOs72spCIE4JDJ);= z%=twq>k(*Y|0J-1zLPX-s&O`NvS1N#dg3;7YZgRn@4!XpiIjhCeP{{$Y@(*dde_bS zSi0XR&~h*RR$2XTt~WRjK`U^KX$R|GxK6+rS`hjY>Q&cYu+s9g29cCt2J;l+H= zTd%`*?D%9&kIydQq(mw_F(}!&X>{XrwYBE@WyT(H3%e^Q1=4Im^CrF7Gr3OlSX@qD4;N{3}I#0ss2mnezh~3MgZT z4lM?kNb0)7X!tTmta5EokG;;6sam2?mhz#Q#U@PEvISqeX{r_v-7Ik44RrSMRBfHe zkv0vSFM>^+rrEpIQ8i5)B)H&{)3jv$>N?Q<@0cK7VZ%bsYN z?9mxoOlo|Y0TwaSYlCGRa^pRZXFtu*1`9DIr9jjDK$-t2Wityjhv`Hq+ghNhlTjsP zTI0A0cUJ*iqV)f@vCj&$M7x1PV#d&?diYA~?`v^WcDCFW!;)rdgTuXt5{m~HTS)Aw;I+I#SnL|jwD*U-7) z7iYz5{8!ga zbnQ(*AD6S8v$fK6Piwk0k~)3`y>L421_(R4&7>s@&%YJqRE(NQwJE^-ja<+!;5ZWQ zscX>bMi-5p&h(umf6dO#(R!P{wzB=7;I^AZ8(4d-|E^(%r?l9RJ%by}$?hm3l|M*T z9dcG57Bl?dk&}L~4$@?=xs-6My_)U+#Z+O!C9m>O-=(I78mk){7%|sb-BHz5wZ8h* zsv}jytMaQR;Qs;DPgZ?Wl~(mk<;#_4D&MLMseZZgp-NE~6lcE9O25|jYG>xdP~-hs zYHiyfK4BO8483GNE8~aNg()$tXq*2iJEc92yif4FnFsLr2t5Mc1J3G4DD(brl}TX@ zdQU4Z)CRI$IIBxDbalz^e75F@0|9WGv|mN z%{{>z^xvp;4@CLRJ>po+Ifa>mD%k0qz{oVji6bm8;tn8uWSkiYl;g}e?9A|`U%%E3 zK+z%R^21`#*?vXIprNfhqbjCbuV=;Q!ZJ<2S=s1=VS`QgSXuj?aNQJ(-(}&wWrf|k zSkp|SBH8JKVK>rMFMbYR2I7jEt7h8^XTxA2K*~ut-i%PaTwz zmN9m8R_^#2)5cFp88c~`BuVM18JS2Mlb1KsNRgz$spALVp5{NXW$U)Et+HIrwR0x(V6l{8GxpErAkt@l+rDsUMgO@YK5mO z4bswL?}oQaOINO_@U+y3_tJIC+;ukLeOD|*nt@HpTc(t&f-f%Rx-eUR%-k{*&aEG=H^LHonf+NItQ z|C!#s>N_Bm8PNSHYwmN4v)6?r679-Jws(&z9O&)^+Ng>swMj55K{ub|84lK$>0D zy$U|hvTP-rN|shtt}0t$OW0sG(v}vN^{X_#l<@R{U|$14*UO7ntu0yR%2rWQ%uDi$ z329k2$^8u0v2Kk-l_qSUe^TFpU`j?&QID;1osG{%v|(FU##<_2^4H-}?0KI+JFCy= zm1LioH+8%;uDG&fVCAaP610G-#+Ox=RM?goiENT@pe?}tR_+@ZAL4pL0pvHcr+fqB z*!2CrQEb%L;X&-TK|QVPv#B9H*)3m(n{(&wF#g>nNueGpmge1L{M#u@Hm~%PjpE;_ zMugPxO2?|iUfu7T&HmFP(8|g-Db`26I}<3URX5()*j80{13xL&A@6TEj-1D39N502 zAzRWPo{xb#2OTO8P;{!t}zkR8SU|RwEHQ5;9=I&WG>WwwKSm#*5*a7lhlB^!nKx06g7O z%8QY#xuq7$l?W=(p|^NvYu!nHe-xE-9euUW+yNNvg*zNmcXY@zcXZ94xdSz2&7?XV zc{{R`aFn;7{!RmBr2K_E|D0>)_ik>a0T$VyC6F=dLqi>UBl*eEQFlqtD5FLI5MhZ< zMM-*oIg(oA>e{NLjF0u73!?*4In_5Ivb1B417(SxC}1P%pPUdn}ZHphGqC>uK1y*sgb$edS#K zFN_hcV*eV(=<;uz>pLyKHq-*f*@W-wUr)t8P50T}LA@ek_|=OToK>_%gXwmlbJ|6? zdkdIR_6ZsxI(rT|^a4(U{tn+B9wfr(I_X&rwZQ@eONB zr8YYB6#8QYa4*8@F6s9X6>`~m^zMe|ELP=jp^IOae@n~|V0xl@S$k~QQ z1bG8__pm`C%{Y0;SyV*%G^UiH>X!7LMeM0_;Zdfui`j{D;d=I2LM^&VkPCGpvMV_PE#H5D}unvCxR-2|5UeYiSwh==Y_6GqSjn5AGlGVYi|jnD^q!FJ1RcM=@0&OX<>E7YU2n{2@F&{P1*;GM~uY zp%J*4%6k169%ni{ou&L3u3t05k{`p9C`0p);eGr%rvh>|^0k0ycKXNg=xY|Z{A2jg zYktW6Dg5|IK5jHv`ex2~+`~lLA2<5CSZs8PjOiVU+B0{N3x{-*dXQu-M`Y7M9-BRTq9=ac?1M|>Qd!JX@ zLtevWdAJe96J}BIF?_O3G$vcuYNQD*61byHbO}!p*UD%8kW%>sewU`6P_PhkZd;1i zj#~YoSEJ{=TXkQ4!@2T`t%eGDM1lSnuOi+h`T;RKXrGv3(M0U$Xi;@>G-FYv<8bh8 zvEf6l0bI8)#8*J8bUx09D&*kLnntyupCS4`z1p`f79GSTZX8RKjqE#VVL2^R+^_>O>F^7mn7_!h%akIj=I7Pd(D>&8xdu;+}O@KPSsr;+}Obf6mbE z;sk-%sz2*2d=7YiBo|dWGazd?GoC|~X@e$U+PQ9~jtyG}VW<0g?5sNCtZeaW%DL!> zv#ORnQ zug(~W=p3IW?g=6UA^8<0(w}2+O9^}BV)%ghvo~TO_!`^#BMAd=aNOBwxKDae?bTBu z@g)v7yeC~#nVzp>pxFApKBd&3PG->ds5m z2+{x9Y{1=TBfI-jcuee5LU5&}3JN4iH{OXSVhPyiADd;eZD5wm;R8kwo#(n6D~UQ> zLCc&=b5q6J9ki{BS#135! zkA~tBeF~kVq=~120kMhMAJT${z+fK|B`hR1Ed*@)hmFR=)E%vt<_Vw3lXws+U!yl{ zlz%T9dux)Sgc&e%d7H%fF>~3uNlJuhs^?^7Vj?w<6%tB*F17taZu@k#pBpn&7MNja z3j>qb&4IC+pKSw*u=0h0Y3z`!6#0@!%pNdBM6-b=CBVF4LFR&f3#Kkuwt(dq^;}|_ zw}_?rM2t|MBaSL)0At5vzTne{qe_fsEKLw0NRR7$%daLe1)@DGKdNXWjQ&$(PeM2# zorgO*$OrUTFs}F@K}6VjJbV z&#WZ$8rtX{fv##+XI4gre$*IAdjexzKv(aYl~LCJQYuMt`~!5PL~_);ZZh{_Q+g^E zxtM+TVL+s5Mlrj-CvLSZW~uQZ{I#X0V#DiclUbv$=Xxr!crDNKQ?q6i%U>HIz}imM z<&M!2aNKC24d0gGjbs|}P4)i976&QOYO$EHy4LN}o**S6Y2Hr2SVpUiK5wU>H#qk4 z%E6(9n=W!xl(Dyi6kFK6oHWGYjAi z4hmp9Xyk^7B5sRz8zN@X2VsbqO^;U?BIfe6D-00}co`TXV(eYiPB$}zq+dsD-Y`P| zB99s3;!-BZg!lJtLl&0Wce?vgV_g)qRFM)l+hBeDy4Fa zS0>tQx?5^ZpdJ0K_2F3p=67c)am=hKu{4Dpni505lZ@Y$nvxi^X{UQFuwa{935UU* zdgV_0#+`Od^}{dqNHi^3$K*QGKoj2E=lNObw>YY2w&|5Jwm+(;BHP&Lx&F$&+k2!a zsEw;oaK**^O*?T$iulFpmwUuhp|t3p3a@0oA5L!JiwJN=dVoBOgt#dBeh5D7esjci z0i0V>;qq5{B>28kM%3ODg8Y^eA``>R$Hf-lvjfidH|#|DBP2Mr>o@ROxuDLGzay() zM|VR=!49O-aJ%?WISoF|OK%BC^TH|CfAJZT5etq|dh~M17<@Lf_Hf^b!D0!0rNUh; zClr@}^GXGGN#mEOctn6Y)~*M}vprFY#gF%w?XNct@Oz?yq$G=#{KR}R(`#2 zq-kp<8yylc#b4H+;9IitRNuv{Z=7=Xz~m+v9%)^N5MWPkLR+xe6zs6)?{L0#p~hAK zH&n4OllZxNC!79ESd?rfOjtY zkabPc`RvBZp<4U%5t%yfG))PbkUhPJl#d+5ITV?Uy*2yp*|3=IGU?uGX8FY@!i3*q zXPE7(kNeYnvf0@SVaB{K-xxlTh1iuz1HGmu+Vu!$S6KIqRqkBN`myRQJ)Sumuvp&L zM@cd@Z(zxNly&;zM%pp(JrVDeyu6WAdY%OKU7wIa@_6=bA7zngd=tC1#4n1iN>CcY z$2UQG4o!@A(_-_6eYg#tG8HfPQ`ykI%22d}G==TxtK2T0BiNvRAS`5(pZBu`05g2I z#`0VIY;12oWs8*r2(ZbYot3|kb_;~}GlI<+1^jq{mb^q|u;~vVfa{|JUn>@|uN=xM z>S=zmGT2Wv6M81i%quA2^N@~K~Jc6$5 zqI3BrgEVlLmxnWQdZ}XigUTQ#4^aMQIyRYwKBNpZy)v1Nen{zU8qmbf4hyld{wc~M zes4}{y=xLHUgsBK@}0tt{t`UIB;$8jNQ`&BA?$&Zrbza;fy#Wp-zK-B#>2xyV%d;X z*MK4qMs0!4xjf=X1mIio~Gz>7BWbwGGqWbwP%be zd^$UKF<_gSGr0&pWT$(mvHlC{#7ldnDS8<`R$+;<)HZ^V+Vc5O8{U5Lx)1ai)s0>A zCy>rs$l5Y|n^GP2GdsJ+zQ5DDnzD!>L)~(TeFEY^qf&D|%N(qX943m0L884TYQopk z)T9`ty5C4t7weLH-1#hL`>R0Zb01aa()K1KQ;BCw?v~>)4N|MaXZu~AfjZd!@5~YG zXoeCI#!uQJ?Cxa|F@k8-lF%cXh`juing3d@Guhb#naX5Jtb0-J$KLf(Q`x}#l;twK z2hN1`Zh8GWf z9%wL}NTD|^Kt?P@35MGmGH^B$HwWqRgAG)ICnV+9A_WR&-V_v=6mT2>-W=Dl z$x^^^OfIg5ez}C8Fsw3Q(9pnvH$XLPv+5Bhs66OZta$;{UZ+(x(p?o7P{o}Ts$Z9& zOoq#LVhVxOp+C$Oent7b1!|e94WS27;g>V;rB$8y2N3V!1$8?+_d}psWa-{hlr(l< z&rIg6iDi^vAa`t5^8G?L?QnE;gvo2?(mbjB9pUQCXRXorzU+Fb8c4p zn$8z8zb&9`{N`^_Y_((L(5(a(-Og!fvV!F=w&Qpn=JokPbV?5R-!hPQFlmas%bVTh zF&uLD9Ju@wE$|!@coUW{wxhMjiP8mmpXD|due~8B2~e!nbzY+zCA6MkOKTL}Y7hqQ zABJ3D~fA6Ud*s8L3kzMR2+t5F8aJ6LM1vcA74;{}0^JEWIRvmR{ioZ_tc z#(AVO(b_e?ivWCqovKy(#fL5hobI)F644ZnveV4K?HOVov52k80MmtBHh!y;L%+>i zmFwgO*zv8(pj6&Zt{?Mso9o9exUt|86aO~dabmmBj~S(ee(Z14g?{XBq>lH}kA+Sb z`mx~YTt6ni#7@;IANmGkT98I;68my>`!;B)oLQv%#FU}Zy zx@-~MWqTSFHIny^i^N`9F`CV+__eTT_ECcpx$p&|MqnmL|8~2#8f@4MK(LzHL_o`d z1e!|&VssSne&A3W$@mA|lS;ZL&M0(gYllPQ`qG!#wC&gnfi_CFV}bp?fZe)Xd0ft5 z!yA>zpyvx^vt+sLCKP0>xKWwlM;NVRufzsNv)DJnda$<}m7dqkeYsH?lFM@wzJD&r zy6vV*@rf$^*b;;3$Ba{F_z8p->*oUfwwvsmcgk6=)~Hu*)e>c3TjPQ?c2|=U9LBEx z`0k}ZIGF>=t3RzC<8O<^r^n`@%5(Ou*q4z5CoXH})!sM8zqc>%-;^Cniy!CAT;CJS z*BeeF2WUJ6CPg#(%@J~O_iuBUM=qu>407>!mbFs}cDTq;kQ0}SIlWya z7ss=TotUt3?9rXdG&!FAyi=L!7f(biR6>=zlu%R79Ig|RbJzpBFoJj`oe*9>-KE&* z6*?g+v+l+Y2rr}&!nbL=m1z8|#?S1WIT&O^2XvbBL%7k`r60C+Q} z`?6P?72io;P`aTWBGR4dBHfwYNw-jtu2^sFJQprg+1%8jFXncRBG&6>C5nhT>1HKH zUdkri3{@V-G533A|D5hO+r)4X2YMx6;>0XJSc&%MBiQ-|JGn<0AN=Pf9&OT`C0v^% zKhDx_QGS>^bIF3DWkvrgzOHCM(KCzRT>LWrf4DflXhzYaiyeyxFP^k`%;Lu4!Hc67 zch@4#S>o0rjf0|-{5iQ62`{8Y8n?(xi$rOL7Kt7WEz-C}E-ex=b1l*$V#;nUQqLt^ zixea2!E3zIp+&j@il6OVi&W2IZdY!!3%=&dJ z$(2r}R%3hMmOhuUr|wqzn9f$P_wH6w;`sbLM;G67Ba+KHW*7@W8z|3G(k-w&;B27Bs$B{JmeQsTv*Q!j|i zv9jrkjs0}L(#PP*-~A;ZI{dD+Jfh|2JKfNU(m~#(S@{D>zS+&2SF%$NKuTE2Iv-GM zv9}`#DZ$$IpL$91mnM~-Un`del}42&mJTY-W=Z>%au)+O-2Hu8SFT~Vh6Y6zys;K5 z8JBuVf-!8#eDa^Of4xhXa5>*yxyCyq_imSTBjZ=yGBWFf%6Zez>%YCe<5}^Jfx9l>jo8=ZINZn;(PX?>QSx|^t)T@4X z%iitVWNAlp*1mzPIYf=Gwbb{N)%rj=s@^Qe)d$H5^}%vteTY1u-d9eo50wYi`^iJ< zd&nc|{pB(Bz2u4Y0dj7=k36m3B`T1X$>$u{ZpC*uhs zto^oqmd0)P#Pir+-%Hl~uH3&ik#aReKGB4$H}~T6*YlCzc;>ZOc6&;_d_}2Sw{^{b z*;A@kyzpXB-=X!@^9+DKF2n<@+qb(bBQSYmmc8yY`)gM;a2jB}=4n7Y3$X6?lzP)B zRqN`_eSqstcQMO@o~*B4(ZB)ZeAS&35U0%nppd?!<;S{xf_&eV`|4h(nl4sbp7d0B z%&Wo>!sHYycW?1n1; zMyT>}Defgxu<5vdQFFe0EVoi`UpqdE|!kGF!d(DYFChNBTR%@d7_nyJV` zvw0D?A-TT_3bSW63mLR)?2u-$@IZ%xNb1cx%ZXBF)pGuUh65c#nv?BAnytNXDED;} z;&Ri?z!$84HqzlM!|&V~(%fmK%Nd)|u@lCOKH;7V?inq56V;V_v`Np}htU`k?09uA zDJV?($CCg)isuxxm9VI2HQw}G6B`+=rVev6FU}Q6`F9vQMft65#+q%?@0o?N0Cyx| z#I>F0IDZ@!$wS%O(Q5P+m_=4m)%TYjZ#1E>8I7N(imcxXw%7@%Hs>RuYyNHf@Dchd z4&j33_(gI1)Momd$N#oA={uV3FOkK;-pEr%H&ZpA@1~Tq_**O4M>dlN%09lCs=kbl z)?N7y1{02^{!LBb+23(?H$WS46@)17OQ3O#+CoG&(!9So(*VxZu=NH40B?vZYoEj+ zBWO4Mb{q}OuH(Cj3Vp)6I4>>f zTWIqIMwR26#{uSJlz93m3@aZvMiONc$Oi~ySBJ!e<7gL7V!R#%Z)rx3uDR^- z7!`M}Hd{W~hIdXgdWowSyf%&i8riu-O}}w;xciBq$eE%;Zd^H9Y4AfhkgZKF81X9> z$gF+#SDNfcn_Of^(V}XP_$2m1<(yhD$ku5zEhYUyS|Z$=@W`tN&FHKCQj^#|%0c8F z%^f)GZ!|e3G}}Q&F1kc0vNxJs7S_aE$8o%nD~jc%VNHT_iQ+DInsOq~u3Ti}6~Zz{ zx!as|LtHmqn)FjMnO~eb&~$qt%ZyVCOdl7rU2*DAIgA~TQ#aSXwVN3J;+*a*Q6Tf$ z{DesS>~1lydpkZSVh#5i8`tPsRmTg2<}2t&)GQZo701unt2T9ma*-G#Xy0|*gs2J9Uq{5hXXjnT@rpdQ^V15rUSyZ|rYy#EF%X)!5b8#A!lYIJp%rR1{y= zt~6sON`@NoPUjMN&t9{ulLlD9k4c{ewn_sQys9XvD>t*52QjnyIR4sX4{O%Lnp->O zJ6_z&vf@>HSZNVQ69paTSN?X)XJzqfOz7K1f@UoKf+X2J@oI7`M~d6yJVf8V4K)HL zQ7QW}UM-7_Bc>zc+#j#d<^Ic40RdazN7eegxR;dexZWbuw`=T+dyTgFYy;tv&FsQ_ z_Cz1Gu-2azI_tZZb9|6!bXrd=bfG{vFKt{Xa3Pv9>3j^KDd$&j8LxmjuoE^Q_qZBv zWIm{kV0HO@aWDlq+!u;%O;Asorp#qi`l_=`7iY7F`l@#NeWR~Bz_f7=JCEOB7p-w$ zES;tGQ&Z?$aX&TA^!{A7t)DvBgbw|+pPE5szwM_w=zDac8nqa`=QB(=?wwp+1hj}z zMBw5BrjrFlVj_y$;Kg_w?ctkO=C4eNxPKAGtjk!@jJ^*pV0R>94aDzX6V>S6Zx>;; z#L`C8#+|UebAFeoDlvm;IXMTDi2(!Y=>>qTjf0L}7Kgf2 zcChGV^^j@S64sWi#w~n`xcnAeuF^|zbN+7q!s1JU2!F9hHg`-Nx2otUnd&2(qbGR;ib}wQA za5Oo@#{@?Vdpt#rwkMjC%noz1xxaaUImJBCoN7)pr<(_vGt7g{nda-vL(I2Z)BC1P zF;6v5Gv}G7oAb>x%mwC|=2_-K^KA1R^IY>h^L+CH^Fs3?^I~(6x!AnKywtp`C9Q|j zB(viwYJ%-2cv{hv6rd2jcIC!2({{>)7%I;!W#)lu;!utU<2XAH&jP+*Rsu2WL);qt z8=_x*D&Y*eBO09HH)qZT6vy&LIAD(rR0qhB?C%5BxLSPX+F2aq=h*^*J7G&jfz+`e z2Wp$H)!?!&CAu+bh`)}QW3Nt@tL(q0Hsk6C|x|kD<}81eR$;rMgRp8XJpT% zs(n>7$qAEc2Rq^%F@}AYs%mDy$0vy+l3CK!JG|cyrm216#PE#pMi?<}*VwV|)38;i z`nx04+KkqrX~OCg$3+^Q|7~n;o4wLLwi%28R-?81uz|8|&CR>1xc- zH`b9Vk*csZ7(LewXj^B9rl?xm3RgRc6`~oIFi5q9P`Y6$=XK8fXeN>3=~HmQbn9Q=`%Nr-M|jb~NE;Nw(_}g*m)Z0~(xXBaB;T z{9)a6$CsyWDkkX8aQNB1PV~5S@5(>u1EQCZKPOPmwq&R=wR{Mzd5#2-3{^*iD9IQ^ zJ)xP~OQ%tjUGu+aYWq*Qfpqda`l1Q!3Op1yz7t(`%}*dvu{{^O0`x(nFt_f5xzo`O zFmxIbc@hcLKoDNV7+s&K}XrfP12E7w3oTzj(Hdz_iFSrMeWB~&` zG9i!Q)!D^(n|0)b5-HVG2nveAx4_+@0R-+{4lK_9_=u+8{uI8pJ~2TgrPzL@mPZf3{Xml5m=(ZJ;q-T9L9vvV?R?@f7mM zbrtBJ7`=33lDbce5Q-o~7zkNa6d&KwHgKJgO$_pUGgFNj0D7PWmGhbo`ruzGGI4Z` zZUzu8q%K|0!md*X)y`fioB?nxSO?8r|5E-=ZSVz#@XQN(U=8$!6-rj4K^Ks57_~Sc znh%~VOO{ZgNQX%Fg0F2<+0=2hbi9;0ZswUpYu1S#CZ_*g@Z9Gw*Cf+hz=)Vbt5bjy*k8)e7D7I~Xkrc!*frk<&HONwmsz$A&@4S2Pev z#N$JVXVF>M%N$x|unI#YHYh(oOATMCH`CkU^0r;&F0ftWLt8pI)HObQr4{2d2z>;l zdgsfQ5rh!2%>_r|Q|K@*x-kl&a&{_9y)MMVU@lz-l3Ca=HOH?5o=;6|;V?DEbk8id zd6+uLbgr5m9;S}(ON=5hu`4%^8iSr7^LlVv(t?oa$^BG2+Fmbby@#v$v`nrWu8s+& zc4-$x=tH}&3|AvcrjnAu?*InIRr39I>bE@1?7<5rm^@aru~3 zBcRh@f$nTGE^RbfzY>fWl?|os4t}|2qctu-2m%hBeK$f?hhd$@noD6Y!Ed<)BNp4% zaJr(z9^Wi9NnkP_#0V)TfsM*mr>3mlu(PtL^3}>y__woiaMj?dBK(F|ezc*e^3zIl zrCd_)-WOq~|3bDp%JxN5>!k|EOYn+)2~N8?zd^1e<)^VokE=phO*J*_5~dxk`vAqr z%NCAQ6Kf+j@?jF9l6%V;zOi*iRqMDa!86@W{tubmdEONj3TXr9?F=*!NQ8zfuu?1J zyv-868Juq-Zg+7(8jk^sr*TP~3NS@sFkK7~!pEAh4~JX&^9zI&7lO>inVHk1;p9Ia+9 zy1kyrmsG7FHQ|HADPQj|TPF!D^&#pcZ)@BCfG>9&xcREJpPN_$#z3jmYdu>yMqM5; zrXoArsL2oBM{r6+Foy*8k1=Y$V902Fjmx_N9SJOWtZE&W&|GugCeEz6y5gQu-Bmx~ zmiyiP;M1(7c&vIqxk8VX_f1x#d)&4!9(FCJPgY-<0L`JH7H$0|2TY23ZPITb`B22e zg%aBbpNxwHO*+@Wi>nfiixMe~^~+WNk?&G&FQ7;Q-4)Y_V@6ji1iMlG1T`UW3LoT8 z>Fz>9J5K6fJ_wdYEPslc9&0F@FeXBwZ`cx0o)oZb{}eTRfG3ZAM6+nj7DFtU)Oun- zJMWQZam713I$cdnz6;*)UAdE*14+LCeKO(nf2iPIvnMNS%v0ZySF^(D z>SK#@o4Ho~8X9(I+1JkH|HkkM)M-NV917^TMwX8^A(nK{pE@f)1GsM8vw`F-bJ?PN zwVo^pU*xNcP4gGAaWmBWOi$#pFK4JJ^Efw1cVpYzK;lmH9s&e{KyF-$> zkb<4dLo(vwZ$Jq`vp$loEx=NV_VyR3(M#O~BFwIj86;wtNy)~elX26>aI)NVCmUx? zfb&RTVjr2J8U#3(2fB1*M&1BtVIVMq4#mw>b9<~IavaLm&s3i@LB|_AOO4k&^ul+8 zZu``nS?UmL7pZ7Oj8YQXdI~xMy*xTg9iFwT0d;c%buRkZS@;Vo=ZbW$v*()xd%kB@ zaj_15Unad^E{iQxHUFCloZn`$;e~3g|D6q(`S&)kV})v|398(**{a^-VFB=*+3GqI zOk*czs{{M~HIHBt@@(ese}mnyq4mLOV0;_f+WjQW~ae~fShfbP^Bb)atGle<)SCX!3*Yk9kY^`5IH zo8E0;ljf@ZqHKF^x3CXK)Hv*nCe2aT?X zJnwowV3WKRab+&zJ~^03KW<>HXvv(mgQRvOEMotiuZ~~)LX((p>08l&8 z{*Kr7vQHMM*O^{wV#-2wI{hwRs4fV3iEJ}x$d-GqYd+9*dZF4!>1=4dWv1@4o&IX{ z7wZxWTm%xpZ|WkDV)}Moj7?jFB{*xlHBleC-5ReKY{yN08NZYH`68mU|2zXDkZpqY z1W?e;IF;K437owQ4I-^24v41wnqIyK{}N%;9b=I~_vt#ug_f9YJ_0ioU4BcTUnXPwL2p*thC9NkrL+dk5{zg)uhE><%# zgnx%ySB0pKm+H~e?N;4A_iUtp#!^b(7=2?G7pqp~5yHR0N{p#DlqD6ZlWMuCBQ@0W zI5{(OfeBOHI!6fR!u-*(s)&5sxfYVPEg}`xYkf#_jdR~62n){pE>~Y+cz%H@bhBQ* zb^$@IDJ|&Qq4zPAEfl50Z60?a(#^cVl~ZT<8;qi7A>E)+3dw) zby$e7eVicAbzJ{7ne|wr7Mk#J(GqpDb!0Oq7>YjB&HBr}U!o?3jpxe?48>4gVJ1NX z&dQg;!ENGFRY~$pm6x{jsp3&Fi^&JikZJR14s2hlX3`vZX{kD6-b+oSKLaS+INvcC z502j1(O=AA!}ZLNeB90nnCjNJ*6O*&-pM7hyy6+J%k0&gRh88&Q>%Nt#go~EWooht z`zGgYLZUtP!h8~s*{~9|w<%^Gn_Hp|3x9JjU=q4(VH&|k<&hFKB@$&h9}&kEyoQne zw?rKpbb?#jUgJI~WNEXqJ;iDOD_E}Dhr%XDye!L2lUMRdLG4L0GI}{3fb~7S9MTfj zruOCPGOO`b(x-?;lC~LChAmuyl>omxSEx~;T<{iqeQrEt&#q9@R4!TMXCwS6-`_=Z zt10_!h01!I6$oN0)s(Tu+AMrEY{B{l!yf~t_{6@Rw@ld;+gkdmW3_5CeY}ueSgmGieHLT(LlUzY)=eHM3>LJBYt&&; zo9H9e3zNKyiefoD?A|qMk_jfwH`l0#GvJB<#n>ic&d0^7v&DG919GZ(s<~7Gzh%O) zEzmIgv!~XoeN^%$vPy1-{uuhYdRD4Q?V6o6T&Fjz%-QUf_x*>)g7i#oVmBQ5b)T68REn(kB?UO|Bqu zi+YC54ib*M$aUz-q>EHkNY!$C1wV|I52m_<#gz$_Om>+%)pFGu!~RsJ#>u|y#WHm$ zNxwgrsfl>Cty9Mip7rXSrMEgWeGucpSPr-) z-s*3tuLWp=_5FDHAZj)YfZQ1Q&Pu~~{x%|?LLoUEJF!BfI^N`4diua7m#e*Fm{%^_ zEZQ`?WfELfQeUp7)^Z5329q>S<}Tv9@2mvouepMQ#E-oQg9f+g3!{I>`0m~kV%>Hw zA_=|i47B|?b?JiuYJXXoHN3gy*k4?wNoR1|KHMX32uT2FM1`6S%x$hvhbDB#Z8NU; zbs4e51U-M5*!;&8>hLIV%xQ*+P$=-@))?D!mbyVzLItaJMHmC0ow-4^1s`pKdvsuq zpI>56fXudSP$wtegHhr4a!9(d)Yy6vDr(Me75j2my+3Y%hy{aqbfr2V=gRs8C%~b6 zt9%fKa9e-W?`kX0{hT;XzTdk!c5|f~)2n;Z^Ofq5zQ$y-5rzEjtiEW#043J>^{q*( zT_8nNsdleU&7n@^RDrwTx4a6h3ct4_Pdw07{)=<{uUjtNnCL>3(1`Ic-ja@feN?5! z7Pw|{6q+#fJE<;}4liJR9m*(7c$5A-DFksVmehJ|EgBZinnqXo73SYN*Z)8eP1>j? z)&5a+uTfFg4Iwrf7DAgd=X=Cp|LxM2M9uP`hl>wy#*OR0;kvKbbsqSJL|dNjmIbax zH6NNWc%Mqu$VO`HU)Z^gYFy}X1k$0{h3?hYR;^A?fCnHH*D$BU9iLA9*k5XLkoLeX z*4@FJ*xBA{_(6cXAFWo^3Ea2#*q$S9#xJxo{c3%;yM_t^HD`Qt%TZMU zmq)m?NxMe6*I6jDxTeVxd1ak7B!eU_1s%l;ClqlLk&m;Sy>q=9n#$Ei?$w{Gy~s1R zhLnH23r|kuU8tOBbRpyh_{VH$W+QKaBnMa5g*T|N^ty z4QD)VBJ_YJRvlx^XZ^P(!II!E2M2L8#_l!tgUoP}Fwu;MfbRqJn57Yu%Ghma9m^FvUw*)3xv$gUhU zU)73bAFNg0tU8u;TV_y>mcGpEkK)PR58_3?=Ci)46&*OK*LH&Kox z@)P5Hjy`fBnY7}VlV>szub!T<4eH1CY*wTDxj^U+WV|rGxiZi1$4+lnlg1`B<03r3 zX4C;VBH@w~>4kYOK$DtXJ#8(oa6`my-J(Wi^=l54eI+hJOFCb^U3slPgWpN&-I5+PG(VCA-ZiX zU_-Y;0r%VvQk!;A1IXPT=^8%iGi_ zKkli>_Vn{t*`Ru`mtQxrf_k{$;rFI`HCf(_qr(t1%S+gY_3Bdk9oB$%jO&61HDU4Q z8UTzddJL&bP$#E&A)z~KVArN2ap?n^?a5#fqSnQS3*%H4|NiZE)uHa$g5uUEg?%2QMbr3c zmeQzZrhQMJ+KG~CoQ>y6m2vaW)yZWmghzGjt2er;9ubt7pFp#9)Q z?)$mA^;Py(qdHA)V^K}2j-TO8s#X4k&1%B#=X-WzlNuX1>qgQf5d04|sY~RP7QY?p z1^M<-0YUqAs{Vdhe1$IK{ zhRh7~fU~&2_cp#`-U=axt~71IWkPgSI@r45gmnqGle)@$oIS=UBs3ai<|e(qkw`8F zwT8vEkmux8p8R$+nP-n97Zy0sHXgu8=#F(_wnF)ZYDSPA;=twMwq8_UPl*%-P!`mVh|ud-Lb?*oK@6*{x#WZUKE>A>9LA0}o--wS5EYqmF{e=v zd`YY;=nKkH(M)cUObl_CB8N2Vc%hDpq}1_rBEojXi3s|@m$=%d){xQeV=O~BHr-C_ zg0@|YERY=mJR1iKg@Vhysl+Z-hC1_TlclE=2}IC{@(~jYspUE^0%*=?T{sR|orOV8 z_SfB50n?m8sWXu#pf z9@v3b1B-r^S9V%`EPvfWej{GFe5G1LZ(|(Du@$=uB@X00Hk5kZ3K?ZwCW9>x?|)!; zVn4_6-SPJ0yGfAZ%I)L3y$ZpX1)lV~1>i&unLklWeqj>#`ljbVB+|&UFPot|!moC- zIw%DnFy5IaYar#JM~~w16~idvAdw2}-Z^PYkYw%}H^;hGtKxD^6AGQ{1cCdP^y`2CrYVE3YV z11YCwwv^n4xEoe(E|0zPGpaa#yV`GzxAx*{dioz}joSxs&fuxN*fPQ(^Zs6Sa2%IB zt$!DM^+PZMI<-KXYT}ROxh!#?Iy1Z{iDzQ}3|(aiWnz2wsiS)fxi#ZMl9>N)J?4DN zrv?U$S)6d$fA*=-5esPv7xN!D>uISF-(r~R$P}e{YqT61MjrtRoRb2)PI3tM1jJiN zn98;=HPM9MN0{0tJe5>XJ%uD?Pi?m5I#SuE4A#w5_Vk_VM4#8DwzK>1Rc$QtE;S-E zovcKT)Mk4+SMH{g^D6l9pMEAz&aKfoWY-|!%t)c#4=cF~4!$!935GC&#hwDE`?Ma( z)9rt#ph&d1t6f8dTOXlKH$=(f$vMf>Jj@b3H$-84h9oUG(G@oTK(~_w3%XmqlUC^i zcdKJmgPp9KrrU&s)W>p56T5gf+)5vCGZ3uq;)skPrMOVd4Tfi2p4~i-FD}}~)D<+) z0m$5%>NC#D_xL7=!p!CiYt+dL({(>@%*k7!nlcg!IL4e+?>j3$@D$YJ{}5j`M8Q1c zT>c)mK6LseabkCUPSujRMW={F6G>kJrI0cdF{3`%xHV<)TT*zT~s!NO#$pxO@J|u``Ul8#L9+ zS)Y5=5itS|?nhz^hiD<>4t|Wpp3Z9SRmYfa&1YNptEzwIr6-_JY-0H#J}Mh|pBfSe zK>4v;oW}jy2i)6{0l%7z=42io??fTf?^DxQ!UJkpk8|7%$KyNq|716uaD`(v{A?j9 zQinwb9+Ha^5#Wm_vef-*bgJ?kvM7l=77=#b>UM_UUJgg@9rOa{M2?rX)>&>}ypTHFs2cl>%07*MN zm;CS%V$1`!djKQ6Q`xzvRBf(nH{#Peey+3TOI&c_tm*h_)FJ5e70Ld|ZY0YA5`0%t z-8VGiE+G!r!6Go^C%dhi`Pd5APg!+mWyMdc5piNC~S6FxGm8j0B%fi zk%F~{AzlJ&6cv@mfEE2&jWXeP^PkluH@@7xqY!~S+sl7euj}jFo%Px7?(srD+wE}f zrY?xh2n{)lKA=X{x=`<$03Yaq-k9jDHBd6AvTF=McQerkdK53{o-#CJ_^AiJ z>aoZFW(tqFbD!IsOVL~JfV;&${f>S1ef#Vfcpkm=j`<>bE8cnZR{Zklt>@_J;CLh?Snf6s^@hxHd6sLS-rxvgLQO*P2 zIS)Ll^&iz{e%t(x`CapA^BMDd=J(AXm_IcC-TaaHALftEpP2t?cA7sme`Y>wZa05! z{=)pFxx@UG`CsO*&HpxkW9~Hn$9(&p8NFN5dm!ZVfe*C>@<}GATjS(YEqaFaGg*F1 zytcLInRq>Lw>3h3o5_c)akZy$+1G}Wvf|Q`lr)N8aR!&ntrd^-D!oUS&UwARFD{vL zr+gqTnRCB?C@n2r?|ze{zvI$5uUF|KiLQ%sr_@USkd`fTzoNm9rDdy@FZZN;A}y=( zyh+kOr4n3g=Sgu&CEdz@DwS+nU*Y-wnY0}DXnEex;=RmW0w5yfZPZdw60#a0nkWvB! zXrV12sFlNEL=HLZr-?U7CB_&7Wd|$Q6CjGsc zcg+0Wd)sZB?|q+|if2Wqa4Mb!c!1Mn@tm;252-16cFT`A^v(i3t?wsNZ{tBoeohZT z^EaI#;qwsk3u$QQ@GNOq5jJoRr{wv%+TOtw(}Y^4&Ga`)HPgW$xD3QiA)HBT^*BK* z$wG|d1TBtG&2*rjO_AvUk{oK7_9ZPOmmdMW!txqzg6k53Q&xMW#dR-Kb_d5Zp-3 zJVYzO$89gS04KY=-BA3 z(Q(n+qT{2tNAHMEh~62kj@}i$JF1`jbegsm^xV>N9!J833+n<7PYkEYMbcQmEL7^3 zNMpmI1%co)X>3=BzakFj*>9u?C)NcPe@7gu!xr)fX{rkqBKZ?>V_={BMfB9Uz`zyK zRNq`1#P~O93fUv%D&p{o{z2Rv(!WNUmn>N7+sh&3I$2RW$Q?V}`CGl!v*R7pM9{X7<@q*~-pD4l&}`5S6CS$gP1P!PM~7g``gLqK^`VL4 zc_r8?>vx^n$Zl=#w^VImb3!IwblD^ejfsd?@(NpR14*>L$#dNw6|45j-(ZI$?x@eZ z_sZ!RV=*3ccFegm?p3VM*iY5lY`5{0iuSl-=k0AJyqp7UVqnqR{0ZwAIQ5PmWr>JA zhBxLIn_zX5-iP0@mqM2D9%kzc%u=UWe&}rO@oDrS^)tIaq}qCkeGxK@sU)^4 zCi9PMxGC9gHG?0qfpl?4&gF&ff$vzZn>mAz_i7&EhitZW@o@Eoz4UL@e17Ub=ALZn zMNP%o4iu-@Lo6bsfSMj+CB12?hxmd*iao>!*Z}(=UK|qirKX429sLl8I${ecqPmCJ zb}9+JkHgy5*yrM%ka zb<&fo`5(6U(#f>Hg`c-uOfh+9Hu46`U&6&&iFhyUJUF>VPC2~=MyY6MNp)^;+ySFG^lU**-%N8oZ>+XO8foz9RJ{d zeyh|4e$bRgs=Rb=zodTU^MVWVc3t5g2Gyh6ka5%h;*7yuK7KE=oWIkUS?hI?TOOoeH1 zA54cDm;v`g>mF8Avlx~@Jv6{lSO$&I1kJDvs z0t9RT2~WaCcnUVbX4nE-;c3_g+hGUnglC`?TzFQyuEz(o-?UT6UP8u&ED*A{kcC3_ z5wfq4{e&zMvcHhULJknJM96_cmI_%W!W9}!6isP%`wNA44w0{9mwT(&u diff --git a/bin/x.sh b/bin/x.sh deleted file mode 100644 index 07748085..00000000 --- a/bin/x.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/sh diff --git a/bin/xfstab.txt b/bin/xfstab.txt new file mode 100644 index 00000000..21be366e --- /dev/null +++ b/bin/xfstab.txt @@ -0,0 +1 @@ +/dev/hd1 / rw diff --git a/bin/xinittab.txt b/bin/xinittab.txt new file mode 100644 index 00000000..b2991151 --- /dev/null +++ b/bin/xinittab.txt @@ -0,0 +1,4 @@ +# Hytech initialisation table to format the RAM filesystem + +/boot/mkramfs.sh + diff --git a/bin/xmtab.txt b/bin/xmtab.txt new file mode 100644 index 00000000..21be366e --- /dev/null +++ b/bin/xmtab.txt @@ -0,0 +1 @@ +/dev/hd1 / rw diff --git a/doc/EXECPATH.TXT b/doc/EXECPATH.TXT new file mode 100644 index 00000000..0815f68d --- /dev/null +++ b/doc/EXECPATH.TXT @@ -0,0 +1,3 @@ +General block diagram +Want a summary for the execution path from clear memory to running +With module names, function names, source file names, variable names diff --git a/doc/gui/Gui driver.doc b/doc/gui/Gui driver.doc new file mode 100644 index 0000000000000000000000000000000000000000..3e36ef1eccf58b219fb94210efc6f2711ec33068 GIT binary patch literal 47104 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:BgdJ_QnP`qMCUwm%c@iB|c{ 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 literal 0 HcmV?d00001 diff --git a/doc/gui/Software design.doc b/doc/gui/Software design.doc new file mode 100644 index 0000000000000000000000000000000000000000..1c86efa57ed7c677f37f1ceeb848540e265ba16a GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/doc/rfc/rfc1700.txt b/doc/rfc/rfc1700.txt new file mode 100644 index 00000000..1d1c0ab4 --- /dev/null +++ b/doc/rfc/rfc1700.txt @@ -0,0 +1,12884 @@ + + + + + +Network Working Group J. Reynolds +Request for Comments: 1700 J. Postel +STD: 2 ISI +Obsoletes RFCs: 1340, 1060, 1010, 990, 960, October 1994 +943, 923, 900, 870, 820, 790, 776, 770, +762, 758,755, 750, 739, 604, 503, 433, 349 +Obsoletes IENs: 127, 117, 93 +Category: Standards Track + + + ASSIGNED NUMBERS + +Status of this Memo + + This memo is a status report on the parameters (i.e., numbers and + keywords) used in protocols in the Internet community. Distribution + of this memo is unlimited. + +OVERVIEW + +This RFC is a snapshot of the ongoing process of the assignment of +protocol parameters for the Internet protocol suite. To make the +current information readily available the assignments are kept up-to- +date in a set of online text files. This RFC has been assembled by +catinating these files together with a minimum of formatting "glue". +The authors appologize for the somewhat rougher formatting and style +than is typical of most RFCs. + +We expect that various readers will notice specific items that should be +corrected. Please send any specific corrections via email to +. + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 1] + +RFC 1700 Assigned Numbers October 1994 + + +INTRODUCTION + +The files in this directory document the currently assigned values for +several series of numbers used in network protocol implementations. + + ftp://ftp.isi.edu/in-notes/iana/assignments + +The Internet Assigned Numbers Authority (IANA) is the central +coordinator for the assignment of unique parameter values for Internet +protocols. The IANA is chartered by the Internet Society (ISOC) and +the Federal Network Council (FNC) to act as the clearinghouse to +assign and coordinate the use of numerous Internet protocol +parameters. + +The Internet protocol suite, as defined by the Internet Engineering +Task Force (IETF) and its steering group (the IESG), contains numerous +parameters, such as internet addresses, domain names, autonomous +system numbers (used in some routing protocols), protocol numbers, +port numbers, management information base object identifiers, +including private enterprise numbers, and many others. + +The common use of the Internet protocols by the Internet community +requires that the particular values used in these parameter fields be +assigned uniquely. It is the task of the IANA to make those unique +assignments as requested and to maintain a registry of the currently +assigned values. + +Requests for parameter assignments (protocols, ports, etc.) should be +sent to . + +Requests for SNMP network management private enterprise number +assignments should be sent to . + +The IANA is located at and operated by the Information Sciences +Institute (ISI) of the University of Southern California (USC). + +If you are developing a protocol or application that will require the +use of a link, socket, port, protocol, etc., please contact the IANA +to receive a number assignment. + + Joyce K. Reynolds + Internet Assigned Numbers Authority + USC - Information Sciences Institute + 4676 Admiralty Way + Marina del Rey, California 90292-6695 + + Electronic mail: IANA@ISI.EDU + Phone: +1 310-822-1511 + + + +Reynolds & Postel [Page 2] + +RFC 1700 Assigned Numbers October 1994 + + +Most of the protocols are documented in the RFC series of notes. Some +of the items listed are undocumented. Further information on +protocols can be found in the memo, "Internet Official Protocol +Standards" (STD 1). + +Data Notations + +The convention in the documentation of Internet Protocols is to +express numbers in decimal and to picture data in "big-endian" order +[COHEN]. That is, fields are described left to right, with the most +significant octet on the left and the least significant octet on the +right. + +The order of transmission of the header and data described in this +document is resolved to the octet level. Whenever a diagram shows a +group of octets, the order of transmission of those octets is the +normal order in which they are read in English. For example, in the +following diagram the octets are transmitted in the order they are +numbered. + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 1 | 2 | 3 | 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 5 | 6 | 7 | 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 9 | 10 | 11 | 12 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Transmission Order of Bytes + +Whenever an octet represents a numeric quantity the left most bit in the +diagram is the high order or most significant bit. That is, the bit +labeled 0 is the most significant bit. For example, the following +diagram represents the value 170 (decimal). + + + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + |1 0 1 0 1 0 1 0| + +-+-+-+-+-+-+-+-+ + + Significance of Bits + +Similarly, whenever a multi-octet field represents a numeric quantity +the left most bit of the whole field is the most significant bit. When + + + +Reynolds & Postel [Page 3] + +RFC 1700 Assigned Numbers October 1994 + + +a multi-octet quantity is transmitted the most significant octet is +transmitted first. + +Special Addresses + +There are five classes of IP addresses: Class A through Class E. Of +these, Classes A, B, and C are used for unicast addresses, Class D is +used for multicast addresses, and Class E addresses are reserved for +future use. + +With the advent of classless addressing [CIDR1, CIDR2], the +network-number part of an address may be of any length, and the whole +notion of address classes becomes less important. + +There are certain special cases for IP addresses. These special cases +can be concisely summarized using the earlier notation for an IP +address: + + IP-address ::= { , } + + or + + IP-address ::= { , , + } + +if we also use the notation "-1" to mean the field contains all 1 +bits. Some common special cases are as follows: + + (a) {0, 0} + + This host on this network. Can only be used as a source + address (see note later). + + (b) {0, } + + Specified host on this network. Can only be used as a + source address. + + (c) { -1, -1} + + Limited broadcast. Can only be used as a destination + address, and a datagram with this address must never be + forwarded outside the (sub-)net of the source. + + (d) {, -1} + + Directed broadcast to specified network. Can only be used + as a destination address. + + + +Reynolds & Postel [Page 4] + +RFC 1700 Assigned Numbers October 1994 + + + (e) {, , -1} + + Directed broadcast to specified subnet. Can only be used as + a destination address. + + (f) {, -1, -1} + + Directed broadcast to all subnets of specified subnetted + network. Can only be used as a destination address. + + (g) {127, } + + Internal host loopback address. Should never appear outside + a host. + + +REFERENCES + +[COHEN] Cohen, D., "On Holy Wars and a Plea for Peace", IEEE Computer + Magazine, October 1981. + +[CIDR1] Fuller, V., T. Li, J. Yu, and K. Varadhan, "Classless + Inter-Domain Routing (CIDR): an Address Assignment and + Aggregation Strategy", RFC 1519, September 1993. + +[CIDR2] Rekhter, Y., and T. Li, "An Architecture for IP Address + Allocation with CIDR", RFC 1518, September 1993. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/introduction + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 5] + +RFC 1700 Assigned Numbers October 1994 + + +VERSION NUMBERS + +In the Internet Protocol (IP) [RFC791] there is a field to identify +the version of the internetwork general protocol. This field is 4 +bits in size. + +Assigned Internet Version Numbers + +Decimal Keyword Version References +------- ------- ------- ---------- + 0 Reserved [JBP] + 1-3 Unassigned [JBP] + 4 IP Internet Protocol [RFC791,JBP] + 5 ST ST Datagram Mode [RFC1190,JWF] + 6 SIP Simple Internet Protocol [RH6] + 7 TP/IX TP/IX: The Next Internet [RXU] + 8 PIP The P Internet Protocol [PXF] + 9 TUBA TUBA [RXC] +10-14 Unassigned [JBP] + 15 Reserved [JBP] + +REFERENCES + +[RFC791] Postel, J., ed., "Internet Protocol - DARPA Internet Program + Protocol Specification", STD 5, RFC 791, USC/Information + Sciences Institute, September 1981. + +[RFC1190] Topolcic, C., Editor, "Experimental Internet Stream + Protocol, Version 2 (ST-II)", RFC 1190, CIP Working Group, + October 1990. + +PEOPLE + +[JPB] Jon Postel + +[JWF] Jim Forgie + +[RH6] Robert Hinden + +[RXU] Robert Ullmann + +[PXF] Paul Francis + +[RXC] Ross Callon + +[] + + + + + +Reynolds & Postel [Page 6] + +RFC 1700 Assigned Numbers October 1994 + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/version-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 7] + +RFC 1700 Assigned Numbers October 1994 + + +PROTOCOL NUMBERS + + +In the Internet Protocol (IP) [DDN], [RFC791] there is a field, called +Protocol, to identify the next level protocol. This is an 8 bit +field. + + +Assigned Internet Protocol Numbers + +Decimal Keyword Protocol References +------- ------- -------- ---------- + 0 Reserved [JBP] + 1 ICMP Internet Control Message [RFC792,JBP] + 2 IGMP Internet Group Management [RFC1112,JBP] + 3 GGP Gateway-to-Gateway [RFC823,MB] + 4 IP IP in IP (encasulation) [JBP] + 5 ST Stream [RFC1190,IEN119,JWF] + 6 TCP Transmission Control [RFC793,JBP] + 7 UCL UCL [PK] + 8 EGP Exterior Gateway Protocol [RFC888,DLM1] + 9 IGP any private interior gateway [JBP] + 10 BBN-RCC-MON BBN RCC Monitoring [SGC] + 11 NVP-II Network Voice Protocol [RFC741,SC3] + 12 PUP PUP [PUP,XEROX] + 13 ARGUS ARGUS [RWS4] + 14 EMCON EMCON [BN7] + 15 XNET Cross Net Debugger [IEN158,JFH2] + 16 CHAOS Chaos [NC3] + 17 UDP User Datagram [RFC768,JBP] + 18 MUX Multiplexing [IEN90,JBP] + 19 DCN-MEAS DCN Measurement Subsystems [DLM1] + 20 HMP Host Monitoring [RFC869,RH6] + 21 PRM Packet Radio Measurement [ZSU] + 22 XNS-IDP XEROX NS IDP [ETHERNET,XEROX] + 23 TRUNK-1 Trunk-1 [BWB6] + 24 TRUNK-2 Trunk-2 [BWB6] + 25 LEAF-1 Leaf-1 [BWB6] + 26 LEAF-2 Leaf-2 [BWB6] + 27 RDP Reliable Data Protocol [RFC908,RH6] + 28 IRTP Internet Reliable Transaction [RFC938,TXM] + 29 ISO-TP4 ISO Transport Protocol Class 4 [RFC905,RC77] + 30 NETBLT Bulk Data Transfer Protocol [RFC969,DDC1] + 31 MFE-NSP MFE Network Services Protocol [MFENET,BCH2] + 32 MERIT-INP MERIT Internodal Protocol [HWB] + 33 SEP Sequential Exchange Protocol [JC120] + 34 3PC Third Party Connect Protocol [SAF3] + 35 IDPR Inter-Domain Policy Routing Protocol [MXS1] + + + +Reynolds & Postel [Page 8] + +RFC 1700 Assigned Numbers October 1994 + + + 36 XTP XTP [GXC] + 37 DDP Datagram Delivery Protocol [WXC] + 38 IDPR-CMTP IDPR Control Message Transport Proto [MXS1] + 39 TP++ TP++ Transport Protocol [DXF] + 40 IL IL Transport Protocol [DXP2] + 41 SIP Simple Internet Protocol [SXD] + 42 SDRP Source Demand Routing Protocol [DXE1] + 43 SIP-SR SIP Source Route [SXD] + 44 SIP-FRAG SIP Fragment [SXD] + 45 IDRP Inter-Domain Routing Protocol [Sue Hares] + 46 RSVP Reservation Protocol [Bob Braden] + 47 GRE General Routing Encapsulation [Tony Li] + 48 MHRP Mobile Host Routing Protocol[David Johnson] + 49 BNA BNA [Gary Salamon] + 50 SIPP-ESP SIPP Encap Security Payload [Steve Deering] + 51 SIPP-AH SIPP Authentication Header [Steve Deering] + 52 I-NLSP Integrated Net Layer Security TUBA [GLENN] + 53 SWIPE IP with Encryption [JI6] + 54 NHRP NBMA Next Hop Resolution Protocol + 55-60 Unassigned [JBP] + 61 any host internal protocol [JBP] + 62 CFTP CFTP [CFTP,HCF2] + 63 any local network [JBP] + 64 SAT-EXPAK SATNET and Backroom EXPAK [SHB] + 65 KRYPTOLAN Kryptolan [PXL1] + 66 RVD MIT Remote Virtual Disk Protocol [MBG] + 67 IPPC Internet Pluribus Packet Core [SHB] + 68 any distributed file system [JBP] + 69 SAT-MON SATNET Monitoring [SHB] + 70 VISA VISA Protocol [GXT1] + 71 IPCV Internet Packet Core Utility [SHB] + 72 CPNX Computer Protocol Network Executive [DXM2] + 73 CPHB Computer Protocol Heart Beat [DXM2] + 74 WSN Wang Span Network [VXD] + 75 PVP Packet Video Protocol [SC3] + 76 BR-SAT-MON Backroom SATNET Monitoring [SHB] + 77 SUN-ND SUN ND PROTOCOL-Temporary [WM3] + 78 WB-MON WIDEBAND Monitoring [SHB] + 79 WB-EXPAK WIDEBAND EXPAK [SHB] + 80 ISO-IP ISO Internet Protocol [MTR] + 81 VMTP VMTP [DRC3] + 82 SECURE-VMTP SECURE-VMTP [DRC3] + 83 VINES VINES [BXH] + 84 TTP TTP [JXS] + 85 NSFNET-IGP NSFNET-IGP [HWB] + 86 DGP Dissimilar Gateway Protocol [DGP,ML109] + 87 TCF TCF [GAL5] + 88 IGRP IGRP [CISCO,GXS] + + + +Reynolds & Postel [Page 9] + +RFC 1700 Assigned Numbers October 1994 + + + 89 OSPFIGP OSPFIGP [RFC1583,JTM4] + 90 Sprite-RPC Sprite RPC Protocol [SPRITE,BXW] + 91 LARP Locus Address Resolution Protocol [BXH] + 92 MTP Multicast Transport Protocol [SXA] + 93 AX.25 AX.25 Frames [BK29] + 94 IPIP IP-within-IP Encapsulation Protocol [JI6] + 95 MICP Mobile Internetworking Control Pro. [JI6] + 96 SCC-SP Semaphore Communications Sec. Pro. [HXH] + 97 ETHERIP Ethernet-within-IP Encapsulation [RXH1] + 98 ENCAP Encapsulation Header [RFC1241,RXB3] + 99 any private encryption scheme [JBP] + 100 GMTP GMTP [RXB5] +101-254 Unassigned [JBP] + 255 Reserved [JBP] + + +REFERENCES + +[CFTP] Forsdick, H., "CFTP", Network Message, Bolt Beranek and + Newman, January 1982. + +[CISCO] Cisco Systems, "Gateway Server Reference Manual", Manual + Revision B, January 10, 1988. + +[DDN] Feinler, E., Editor, "DDN Protocol Handbook", Network + Information Center, SRI International, December 1985. + +[DGP] M/A-COM Government Systems, "Dissimilar Gateway Protocol + Specification, Draft Version", Contract no. CS901145, + November 16, 1987. + +[ETHERNET] "The Ethernet, A Local Area Network: Data Link Layer and + Physical Layer Specification", AA-K759B-TK, Digital + Equipment Corporation, Maynard, MA. Also as: "The + Ethernet - A Local Area Network", Version 1.0, Digital + Equipment Corporation, Intel Corporation, Xerox + Corporation, September 1980. And: "The Ethernet, A Local + Area Network: Data Link Layer and Physical Layer + Specifications", Digital, Intel and Xerox, November 1982. + And: XEROX, "The Ethernet, A Local Area Network: Data Link + Layer and Physical Layer Specification", X3T51/80-50, + Xerox Corporation, Stamford, CT., October 1980. + +[IEN90] Cohen, D. and J. Postel, "Multiplexing Protocol", IEN 90, + USC/Information Sciences Institute, May 1979. + +[IEN119] Forgie, J., "ST - A Proposed Internet Stream Protocol", + IEN 119, MIT Lincoln Laboratory, September 1979. + + + +Reynolds & Postel [Page 10] + +RFC 1700 Assigned Numbers October 1994 + + +[IEN158] Haverty, J., "XNET Formats for Internet Protocol Version 4", + IEN 158, October 1980. + +[MFENET] Shuttleworth, B., "A Documentary of MFENet, a National + Computer Network", UCRL-52317, Lawrence Livermore Labs, + Livermore, California, June 1977. + +[PUP] Boggs, D., J. Shoch, E. Taft, and R. Metcalfe, "PUP: An + Internetwork Architecture", XEROX Palo Alto Research Center, + CSL-79-10, July 1979; also in IEEE Transactions on + Communication, Volume COM-28, Number 4, April 1980. + +[SPRITE] Welch, B., "The Sprite Remote Procedure Call System", + Technical Report, UCB/Computer Science Dept., 86/302, + University of California at Berkeley, June 1986. + +[RFC741] Cohen, D., "Specifications for the Network Voice Protocol", + RFC 741, ISI/RR 7539, USC/Information Sciences Institute, + March 1976. + +[RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + USC/Information Sciences Institute, August 1980. + +[RFC791] Postel, J., "Internet Protocol - DARPA Internet Program + Protocol Specification", STD 5, RFC 791, DARPA, September + 1981. + +[RFC792] Postel, J., "Internet Control Message Protocol - DARPA + Internet Program Protocol Specification", STD 5, RFC 792, + USC/Information Sciences Institute, September 1981. + +[RFC793] Postel, J., "Transmission Control Protocol - DARPA + Internet Program Protocol Specification", STD 7, RFC 793, + USC/Information Sciences Institute, September 1981. + +[RFC823] Hinden, R., and A. Sheltzer, "The DARPA Internet Gateway", + RFC 823, BBN, September 1982. + +[RFC869] Hinden, R., "A Host Monitoring Protocol", RFC 869, + Bolt Beranek and Newman, December 1983. + +[RFC888] Seamonson, L., and E. Rosen, "STUB" Exterior Gateway + Protocol", RFC 888, BBN Communications Corporation, + January 1984. + +[RFC905] International Standards Organization, "ISO Transport Protocol + Specification - ISO DP 8073", RFC 905, April 1984. + + + + +Reynolds & Postel [Page 11] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC908] Velten, D., R. Hinden, and J. Sax, "Reliable Data Protocol", + RFC 908, BBN Communications Corporation, July 1984. + +[RFC938] Miller, T., "Internet Reliable Transaction Protocol", RFC 938, + ACC, February 1985. + +[RFC969] Clark, D., M. Lambert, and L. Zhang, "NETBLT: A Bulk Data + Transfer Protocol", RFC 969, MIT Laboratory for Computer + Science, December 1985. + +[RFC1112] Deering, S., "Host Extensions for IP Multicasting", + STD 5, RFC 1112, Stanford University, August 1989. + +[RFC1190] Topolcic, C., Editor, "Experimental Internet Stream + Protocol, Version 2 (ST-II)", RFC 1190, CIP Working Group, + October 1990. + +[RFC1241] Woodburn, W., and D. Mills, " A Scheme for an Internet + Encapsulation Protocol: Version 1", RFC 1241, SAIC, + University of Delaware, July 1991. + +[RFC1583] Moy, J., "The OSPF Specification", RFC 1583, Proteon, + March 1994. + + +PEOPLE + +[BCH2] Barry Howard + +[BK29] Brian Kantor + +[BN7] + +[BWB6] Barry Boehm + +[BXH] Brian Horn <---none---> + +[BXW] Bruce Willins <---none---> + +[DDC1] David Clark + +[DLM1] David Mills + +[DRC3] Dave Cheriton + +[DXE1] Deborah Estrin + +[DXF] Dirk Fromhein + + + +Reynolds & Postel [Page 12] + +RFC 1700 Assigned Numbers October 1994 + + +[DXM2] David Mittnacht <---none---> + +[DXP2] Dave Presotto + +[GAL5] Guillermo A. Loyola + +[GLENN] K. Robert Glenn + +[GXC] Greg Chesson + +[GXS] Guenther Schreiner + +[GXT1] Gene Tsudik + +[HCF2] Harry Forsdick + +[HWB] Hans-Werner Braun + +[HXH] Howard Hart + +[JBP] Jon Postel + +[JC120] + +[JFH2] Jack Haverty + +[JI6] John Ioannidis + +[JTM4] John Moy + +[JWF] Jim Forgie + +[JXS] Jim Stevens + +[KATZ] Dave Katz + +[MB] Mike Brescia + +[MBG] Michael Greenwald + +[ML109] Mike Little + +[MTR] Marshall T. Rose + +[MXS1] Martha Steenstrup + + + + +Reynolds & Postel [Page 13] + +RFC 1700 Assigned Numbers October 1994 + + +[NC3] J. Noel Chiappa + +[PK] Peter Kirstein + +[PXL1] Paul Liu <---none---> + +[RH6] Robert Hinden + +[RTB3] Bob Braden + +[RC77] + +[RWS4] Robert W. Scheifler + +[RXB3] Robert Woodburn + +[RXH1] Russ Housley + +[SAF3] Stuart A. Friedberg + +[SC3] Steve Casner + +[SHB] Steven Blumenthal + +[Sue Hares] Sue Hares + +[SXA] Susie Armstrong + +[SXD] Steve Deering + +[Tony Li] Tony Li + +[TXM] Trudy Miller + +[VXD] Victor Dafoulas <---none---> + +[WM3] William Melohn + +[WXC] Wesley Craig + +[ZSU] Zaw-Sing Su + + +[] + + + + + +Reynolds & Postel [Page 14] + +RFC 1700 Assigned Numbers October 1994 + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/protocol-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 15] + +RFC 1700 Assigned Numbers October 1994 + + + +WELL KNOWN PORT NUMBERS + +The Well Known Ports are controlled and assigned by the IANA and on +most systems can only be used by system (or root) processes or by +programs executed by privileged users. + +Ports are used in the TCP [RFC793] to name the ends of logical +connections which carry long term conversations. For the purpose of +providing services to unknown callers, a service contact port is +defined. This list specifies the port used by the server process as +its contact port. The contact port is sometimes called the +"well-known port". + +To the extent possible, these same port assignments are used with the +UDP [RFC768]. + +The assigned ports use a small portion of the possible port numbers. +For many years the assigned ports were in the range 0-255. Recently, +the range for assigned ports managed by the IANA has been expanded to +the range 0-1023. + +Port Assignments: + +Keyword Decimal Description References +------- ------- ----------- ---------- + 0/tcp Reserved + 0/udp Reserved +# Jon Postel +tcpmux 1/tcp TCP Port Service Multiplexer +tcpmux 1/udp TCP Port Service Multiplexer +# Mark Lottor +compressnet 2/tcp Management Utility +compressnet 2/udp Management Utility +compressnet 3/tcp Compression Process +compressnet 3/udp Compression Process +# Bernie Volz +# 4/tcp Unassigned +# 4/udp Unassigned +rje 5/tcp Remote Job Entry +rje 5/udp Remote Job Entry +# Jon Postel +# 6/tcp Unassigned +# 6/udp Unassigned +echo 7/tcp Echo +echo 7/udp Echo +# Jon Postel +# 8/tcp Unassigned + + + +Reynolds & Postel [Page 16] + +RFC 1700 Assigned Numbers October 1994 + + +# 8/udp Unassigned +discard 9/tcp Discard +discard 9/udp Discard +# Jon Postel +# 10/tcp Unassigned +# 10/udp Unassigned +systat 11/tcp Active Users +systat 11/udp Active Users +# Jon Postel +# 12/tcp Unassigned +# 12/udp Unassigned +daytime 13/tcp Daytime +daytime 13/udp Daytime +# Jon Postel +# 14/tcp Unassigned +# 14/udp Unassigned +# 15/tcp Unassigned [was netstat] +# 15/udp Unassigned +# 16/tcp Unassigned +# 16/udp Unassigned +qotd 17/tcp Quote of the Day +qotd 17/udp Quote of the Day +# Jon Postel +msp 18/tcp Message Send Protocol +msp 18/udp Message Send Protocol +# Rina Nethaniel <---none---> +chargen 19/tcp Character Generator +chargen 19/udp Character Generator +ftp-data 20/tcp File Transfer [Default Data] +ftp-data 20/udp File Transfer [Default Data] +ftp 21/tcp File Transfer [Control] +ftp 21/udp File Transfer [Control] +# Jon Postel +# 22/tcp Unassigned +# 22/udp Unassigned +telnet 23/tcp Telnet +telnet 23/udp Telnet +# Jon Postel + 24/tcp any private mail system + 24/udp any private mail system +# Rick Adam +smtp 25/tcp Simple Mail Transfer +smtp 25/udp Simple Mail Transfer +# Jon Postel +# 26/tcp Unassigned +# 26/udp Unassigned +nsw-fe 27/tcp NSW User System FE +nsw-fe 27/udp NSW User System FE + + + +Reynolds & Postel [Page 17] + +RFC 1700 Assigned Numbers October 1994 + + +# Robert Thomas +# 28/tcp Unassigned +# 28/udp Unassigned +msg-icp 29/tcp MSG ICP +msg-icp 29/udp MSG ICP +# Robert Thomas +# 30/tcp Unassigned +# 30/udp Unassigned +msg-auth 31/tcp MSG Authentication +msg-auth 31/udp MSG Authentication +# Robert Thomas +# 32/tcp Unassigned +# 32/udp Unassigned +dsp 33/tcp Display Support Protocol +dsp 33/udp Display Support Protocol +# Ed Cain +# 34/tcp Unassigned +# 34/udp Unassigned + 35/tcp any private printer server + 35/udp any private printer server +# Jon Postel +# 36/tcp Unassigned +# 36/udp Unassigned +time 37/tcp Time +time 37/udp Time +# Jon Postel +rap 38/tcp Route Access Protocol +rap 38/udp Route Access Protocol +# Robert Ullmann +rlp 39/tcp Resource Location Protocol +rlp 39/udp Resource Location Protocol +# Mike Accetta +# 40/tcp Unassigned +# 40/udp Unassigned +graphics 41/tcp Graphics +graphics 41/udp Graphics +nameserver 42/tcp Host Name Server +nameserver 42/udp Host Name Server +nicname 43/tcp Who Is +nicname 43/udp Who Is +mpm-flags 44/tcp MPM FLAGS Protocol +mpm-flags 44/udp MPM FLAGS Protocol +mpm 45/tcp Message Processing Module [recv] +mpm 45/udp Message Processing Module [recv] +mpm-snd 46/tcp MPM [default send] +mpm-snd 46/udp MPM [default send] +# Jon Postel +ni-ftp 47/tcp NI FTP + + + +Reynolds & Postel [Page 18] + +RFC 1700 Assigned Numbers October 1994 + + +ni-ftp 47/udp NI FTP +# Steve Kille +auditd 48/tcp Digital Audit Daemon +auditd 48/udp Digital Audit Daemon +# Larry Scott +login 49/tcp Login Host Protocol +login 49/udp Login Host Protocol +# Pieter Ditmars +re-mail-ck 50/tcp Remote Mail Checking Protocol +re-mail-ck 50/udp Remote Mail Checking Protocol +# Steve Dorner +la-maint 51/tcp IMP Logical Address Maintenance +la-maint 51/udp IMP Logical Address Maintenance +# Andy Malis +xns-time 52/tcp XNS Time Protocol +xns-time 52/udp XNS Time Protocol +# Susie Armstrong +domain 53/tcp Domain Name Server +domain 53/udp Domain Name Server +# Paul Mockapetris +xns-ch 54/tcp XNS Clearinghouse +xns-ch 54/udp XNS Clearinghouse +# Susie Armstrong +isi-gl 55/tcp ISI Graphics Language +isi-gl 55/udp ISI Graphics Language +xns-auth 56/tcp XNS Authentication +xns-auth 56/udp XNS Authentication +# Susie Armstrong + 57/tcp any private terminal access + 57/udp any private terminal access +# Jon Postel +xns-mail 58/tcp XNS Mail +xns-mail 58/udp XNS Mail +# Susie Armstrong + 59/tcp any private file service + 59/udp any private file service +# Jon Postel + 60/tcp Unassigned + 60/udp Unassigned +ni-mail 61/tcp NI MAIL +ni-mail 61/udp NI MAIL +# Steve Kille +acas 62/tcp ACA Services +acas 62/udp ACA Services +# E. Wald +# 63/tcp Unassigned +# 63/udp Unassigned +covia 64/tcp Communications Integrator (CI) + + + +Reynolds & Postel [Page 19] + +RFC 1700 Assigned Numbers October 1994 + + +covia 64/udp Communications Integrator (CI) +# "Tundra" Tim Daneliuk +# +tacacs-ds 65/tcp TACACS-Database Service +tacacs-ds 65/udp TACACS-Database Service +# Kathy Huber +sql*net 66/tcp Oracle SQL*NET +sql*net 66/udp Oracle SQL*NET +# Jack Haverty +bootps 67/tcp Bootstrap Protocol Server +bootps 67/udp Bootstrap Protocol Server +bootpc 68/tcp Bootstrap Protocol Client +bootpc 68/udp Bootstrap Protocol Client +# Bill Croft +tftp 69/tcp Trivial File Transfer +tftp 69/udp Trivial File Transfer +# David Clark +gopher 70/tcp Gopher +gopher 70/udp Gopher +# Mark McCahill +netrjs-1 71/tcp Remote Job Service +netrjs-1 71/udp Remote Job Service +netrjs-2 72/tcp Remote Job Service +netrjs-2 72/udp Remote Job Service +netrjs-3 73/tcp Remote Job Service +netrjs-3 73/udp Remote Job Service +netrjs-4 74/tcp Remote Job Service +netrjs-4 74/udp Remote Job Service +# Bob Braden + 75/tcp any private dial out service + 75/udp any private dial out service +# Jon Postel +deos 76/tcp Distributed External Object Store +deos 76/udp Distributed External Object Store +# Robert Ullmann + 77/tcp any private RJE service + 77/udp any private RJE service +# Jon Postel +vettcp 78/tcp vettcp +vettcp 78/udp vettcp +# Christopher Leong +finger 79/tcp Finger +finger 79/udp Finger +# David Zimmerman +www-http 80/tcp World Wide Web HTTP +www-http 80/udp World Wide Web HTTP +# Tim Berners-Lee +hosts2-ns 81/tcp HOSTS2 Name Server + + + +Reynolds & Postel [Page 20] + +RFC 1700 Assigned Numbers October 1994 + + +hosts2-ns 81/udp HOSTS2 Name Server +# Earl Killian +xfer 82/tcp XFER Utility +xfer 82/udp XFER Utility +# Thomas M. Smith +mit-ml-dev 83/tcp MIT ML Device +mit-ml-dev 83/udp MIT ML Device +# David Reed <--none---> +ctf 84/tcp Common Trace Facility +ctf 84/udp Common Trace Facility +# Hugh Thomas +mit-ml-dev 85/tcp MIT ML Device +mit-ml-dev 85/udp MIT ML Device +# David Reed <--none---> +mfcobol 86/tcp Micro Focus Cobol +mfcobol 86/udp Micro Focus Cobol +# Simon Edwards <--none---> + 87/tcp any private terminal link + 87/udp any private terminal link +# Jon Postel +kerberos 88/tcp Kerberos +kerberos 88/udp Kerberos +# B. Clifford Neuman +su-mit-tg 89/tcp SU/MIT Telnet Gateway +su-mit-tg 89/udp SU/MIT Telnet Gateway +# Mark Crispin +dnsix 90/tcp DNSIX Securit Attribute Token Map +dnsix 90/udp DNSIX Securit Attribute Token Map +# Charles Watt +mit-dov 91/tcp MIT Dover Spooler +mit-dov 91/udp MIT Dover Spooler +# Eliot Moss +npp 92/tcp Network Printing Protocol +npp 92/udp Network Printing Protocol +# Louis Mamakos +dcp 93/tcp Device Control Protocol +dcp 93/udp Device Control Protocol +# Daniel Tappan +objcall 94/tcp Tivoli Object Dispatcher +objcall 94/udp Tivoli Object Dispatcher +# Tom Bereiter <--none---> +supdup 95/tcp SUPDUP +supdup 95/udp SUPDUP +# Mark Crispin +dixie 96/tcp DIXIE Protocol Specification +dixie 96/udp DIXIE Protocol Specification +# Tim Howes +swift-rvf 97/tcp Swift Remote Vitural File Protocol + + + +Reynolds & Postel [Page 21] + +RFC 1700 Assigned Numbers October 1994 + + +swift-rvf 97/udp Swift Remote Vitural File Protocol +# Maurice R. Turcotte +# +tacnews 98/tcp TAC News +tacnews 98/udp TAC News +# Jon Postel +metagram 99/tcp Metagram Relay +metagram 99/udp Metagram Relay +# Geoff Goodfellow +newacct 100/tcp [unauthorized use] +hostname 101/tcp NIC Host Name Server +hostname 101/udp NIC Host Name Server +# Jon Postel +iso-tsap 102/tcp ISO-TSAP +iso-tsap 102/udp ISO-TSAP +# Marshall Rose +gppitnp 103/tcp Genesis Point-to-Point Trans Net +gppitnp 103/udp Genesis Point-to-Point Trans Net +acr-nema 104/tcp ACR-NEMA Digital Imag. & Comm. 300 +acr-nema 104/udp ACR-NEMA Digital Imag. & Comm. 300 +# Patrick McNamee <--none---> +csnet-ns 105/tcp Mailbox Name Nameserver +csnet-ns 105/udp Mailbox Name Nameserver +# Marvin Solomon +3com-tsmux 106/tcp 3COM-TSMUX +3com-tsmux 106/udp 3COM-TSMUX +# Jeremy Siegel +rtelnet 107/tcp Remote Telnet Service +rtelnet 107/udp Remote Telnet Service +# Jon Postel +snagas 108/tcp SNA Gateway Access Server +snagas 108/udp SNA Gateway Access Server +# Kevin Murphy +pop2 109/tcp Post Office Protocol - Version 2 +pop2 109/udp Post Office Protocol - Version 2 +# Joyce K. Reynolds +pop3 110/tcp Post Office Protocol - Version 3 +pop3 110/udp Post Office Protocol - Version 3 +# Marshall Rose +sunrpc 111/tcp SUN Remote Procedure Call +sunrpc 111/udp SUN Remote Procedure Call +# Chuck McManis +mcidas 112/tcp McIDAS Data Transmission Protocol +mcidas 112/udp McIDAS Data Transmission Protocol +# Glenn Davis +auth 113/tcp Authentication Service +auth 113/udp Authentication Service +# Mike St. Johns + + + +Reynolds & Postel [Page 22] + +RFC 1700 Assigned Numbers October 1994 + + +audionews 114/tcp Audio News Multicast +audionews 114/udp Audio News Multicast +# Martin Forssen +sftp 115/tcp Simple File Transfer Protocol +sftp 115/udp Simple File Transfer Protocol +# Mark Lottor +ansanotify 116/tcp ANSA REX Notify +ansanotify 116/udp ANSA REX Notify +# Nicola J. Howarth +uucp-path 117/tcp UUCP Path Service +uucp-path 117/udp UUCP Path Service +sqlserv 118/tcp SQL Services +sqlserv 118/udp SQL Services +# Larry Barnes +nntp 119/tcp Network News Transfer Protocol +nntp 119/udp Network News Transfer Protocol +# Phil Lapsley +cfdptkt 120/tcp CFDPTKT +cfdptkt 120/udp CFDPTKT +# John Ioannidis +erpc 121/tcp Encore Expedited Remote Pro.Call +erpc 121/udp Encore Expedited Remote Pro.Call +# Jack O'Neil <---none---> +smakynet 122/tcp SMAKYNET +smakynet 122/udp SMAKYNET +# Mike O'Dowd +ntp 123/tcp Network Time Protocol +ntp 123/udp Network Time Protocol +# Dave Mills +ansatrader 124/tcp ANSA REX Trader +ansatrader 124/udp ANSA REX Trader +# Nicola J. Howarth +locus-map 125/tcp Locus PC-Interface Net Map Ser +locus-map 125/udp Locus PC-Interface Net Map Ser +# Eric Peterson +unitary 126/tcp Unisys Unitary Login +unitary 126/udp Unisys Unitary Login +# +locus-con 127/tcp Locus PC-Interface Conn Server +locus-con 127/udp Locus PC-Interface Conn Server +# Eric Peterson +gss-xlicen 128/tcp GSS X License Verification +gss-xlicen 128/udp GSS X License Verification +# John Light +pwdgen 129/tcp Password Generator Protocol +pwdgen 129/udp Password Generator Protocol +# Frank J. Wacho +cisco-fna 130/tcp cisco FNATIVE + + + +Reynolds & Postel [Page 23] + +RFC 1700 Assigned Numbers October 1994 + + +cisco-fna 130/udp cisco FNATIVE +cisco-tna 131/tcp cisco TNATIVE +cisco-tna 131/udp cisco TNATIVE +cisco-sys 132/tcp cisco SYSMAINT +cisco-sys 132/udp cisco SYSMAINT +statsrv 133/tcp Statistics Service +statsrv 133/udp Statistics Service +# Dave Mills +ingres-net 134/tcp INGRES-NET Service +ingres-net 134/udp INGRES-NET Service +# Mike Berrow <---none---> +loc-srv 135/tcp Location Service +loc-srv 135/udp Location Service +# Joe Pato +profile 136/tcp PROFILE Naming System +profile 136/udp PROFILE Naming System +# Larry Peterson +netbios-ns 137/tcp NETBIOS Name Service +netbios-ns 137/udp NETBIOS Name Service +netbios-dgm 138/tcp NETBIOS Datagram Service +netbios-dgm 138/udp NETBIOS Datagram Service +netbios-ssn 139/tcp NETBIOS Session Service +netbios-ssn 139/udp NETBIOS Session Service +# Jon Postel +emfis-data 140/tcp EMFIS Data Service +emfis-data 140/udp EMFIS Data Service +emfis-cntl 141/tcp EMFIS Control Service +emfis-cntl 141/udp EMFIS Control Service +# Gerd Beling +bl-idm 142/tcp Britton-Lee IDM +bl-idm 142/udp Britton-Lee IDM +# Susie Snitzer <---none---> +imap2 143/tcp Interim Mail Access Protocol v2 +imap2 143/udp Interim Mail Access Protocol v2 +# Mark Crispin +news 144/tcp NewS +news 144/udp NewS +# James Gosling +uaac 145/tcp UAAC Protocol +uaac 145/udp UAAC Protocol +# David A. Gomberg +iso-tp0 146/tcp ISO-IP0 +iso-tp0 146/udp ISO-IP0 +iso-ip 147/tcp ISO-IP +iso-ip 147/udp ISO-IP +# Marshall Rose +cronus 148/tcp CRONUS-SUPPORT +cronus 148/udp CRONUS-SUPPORT + + + +Reynolds & Postel [Page 24] + +RFC 1700 Assigned Numbers October 1994 + + +# Jeffrey Buffun +aed-512 149/tcp AED 512 Emulation Service +aed-512 149/udp AED 512 Emulation Service +# Albert G. Broscius +sql-net 150/tcp SQL-NET +sql-net 150/udp SQL-NET +# Martin Picard <<---none---> +hems 151/tcp HEMS +hems 151/udp HEMS +# Christopher Tengi +bftp 152/tcp Background File Transfer Program +bftp 152/udp Background File Transfer Program +# Annette DeSchon +sgmp 153/tcp SGMP +sgmp 153/udp SGMP +# Marty Schoffstahl +netsc-prod 154/tcp NETSC +netsc-prod 154/udp NETSC +netsc-dev 155/tcp NETSC +netsc-dev 155/udp NETSC +# Sergio Heker +sqlsrv 156/tcp SQL Service +sqlsrv 156/udp SQL Service +# Craig Rogers +knet-cmp 157/tcp KNET/VM Command/Message Protocol +knet-cmp 157/udp KNET/VM Command/Message Protocol +# Gary S. Malkin +pcmail-srv 158/tcp PCMail Server +pcmail-srv 158/udp PCMail Server +# Mark L. Lambert +nss-routing 159/tcp NSS-Routing +nss-routing 159/udp NSS-Routing +# Yakov Rekhter +sgmp-traps 160/tcp SGMP-TRAPS +sgmp-traps 160/udp SGMP-TRAPS +# Marty Schoffstahl +snmp 161/tcp SNMP +snmp 161/udp SNMP +snmptrap 162/tcp SNMPTRAP +snmptrap 162/udp SNMPTRAP +# Marshall Rose +cmip-man 163/tcp CMIP/TCP Manager +cmip-man 163/udp CMIP/TCP Manager +cmip-agent 164/tcp CMIP/TCP Agent +smip-agent 164/udp CMIP/TCP Agent +# Amatzia Ben-Artzi <---none---> +xns-courier 165/tcp Xerox +xns-courier 165/udp Xerox + + + +Reynolds & Postel [Page 25] + +RFC 1700 Assigned Numbers October 1994 + + +# Susie Armstrong +s-net 166/tcp Sirius Systems +s-net 166/udp Sirius Systems +# Brian Lloyd <---none---> +namp 167/tcp NAMP +namp 167/udp NAMP +# Marty Schoffstahl +rsvd 168/tcp RSVD +rsvd 168/udp RSVD +# Neil Todd +send 169/tcp SEND +send 169/udp SEND +# William D. Wisner +print-srv 170/tcp Network PostScript +print-srv 170/udp Network PostScript +# Brian Reid +multiplex 171/tcp Network Innovations Multiplex +multiplex 171/udp Network Innovations Multiplex +cl/1 172/tcp Network Innovations CL/1 +cl/1 172/udp Network Innovations CL/1 +# Kevin DeVault <<---none---> +xyplex-mux 173/tcp Xyplex +xyplex-mux 173/udp Xyplex +# Bob Stewart +mailq 174/tcp MAILQ +mailq 174/udp MAILQ +# Rayan Zachariassen +vmnet 175/tcp VMNET +vmnet 175/udp VMNET +# Christopher Tengi +genrad-mux 176/tcp GENRAD-MUX +genrad-mux 176/udp GENRAD-MUX +# Ron Thornton +xdmcp 177/tcp X Display Manager Control Protocol +xdmcp 177/udp X Display Manager Control Protocol +# Robert W. Scheifler +nextstep 178/tcp NextStep Window Server +NextStep 178/udp NextStep Window Server +# Leo Hourvitz +bgp 179/tcp Border Gateway Protocol +bgp 179/udp Border Gateway Protocol +# Kirk Lougheed +ris 180/tcp Intergraph +ris 180/udp Intergraph +# Dave Buehmann +unify 181/tcp Unify +unify 181/udp Unify +# Vinod Singh <--none---> + + + +Reynolds & Postel [Page 26] + +RFC 1700 Assigned Numbers October 1994 + + +audit 182/tcp Unisys Audit SITP +audit 182/udp Unisys Audit SITP +# Gil Greenbaum +ocbinder 183/tcp OCBinder +ocbinder 183/udp OCBinder +ocserver 184/tcp OCServer +ocserver 184/udp OCServer +# Jerrilynn Okamura <--none---> +remote-kis 185/tcp Remote-KIS +remote-kis 185/udp Remote-KIS +kis 186/tcp KIS Protocol +kis 186/udp KIS Protocol +# Ralph Droms +aci 187/tcp Application Communication Interface +aci 187/udp Application Communication Interface +# Rick Carlos +mumps 188/tcp Plus Five's MUMPS +mumps 188/udp Plus Five's MUMPS +# Hokey Stenn +qft 189/tcp Queued File Transport +qft 189/udp Queued File Transport +# Wayne Schroeder +gacp 190/tcp Gateway Access Control Protocol +cacp 190/udp Gateway Access Control Protocol +# C. Philip Wood +prospero 191/tcp Prospero Directory Service +prospero 191/udp Prospero Directory Service +# B. Clifford Neuman +osu-nms 192/tcp OSU Network Monitoring System +osu-nms 192/udp OSU Network Monitoring System +# Doug Karl +srmp 193/tcp Spider Remote Monitoring Protocol +srmp 193/udp Spider Remote Monitoring Protocol +# Ted J. Socolofsky +irc 194/tcp Internet Relay Chat Protocol +irc 194/udp Internet Relay Chat Protocol +# Jarkko Oikarinen +dn6-nlm-aud 195/tcp DNSIX Network Level Module Audit +dn6-nlm-aud 195/udp DNSIX Network Level Module Audit +dn6-smm-red 196/tcp DNSIX Session Mgt Module Audit Redir +dn6-smm-red 196/udp DNSIX Session Mgt Module Audit Redir +# Lawrence Lebahn +dls 197/tcp Directory Location Service +dls 197/udp Directory Location Service +dls-mon 198/tcp Directory Location Service Monitor +dls-mon 198/udp Directory Location Service Monitor +# Scott Bellew +smux 199/tcp SMUX + + + +Reynolds & Postel [Page 27] + +RFC 1700 Assigned Numbers October 1994 + + +smux 199/udp SMUX +# Marshall Rose +src 200/tcp IBM System Resource Controller +src 200/udp IBM System Resource Controller +# Gerald McBrearty <---none---> +at-rtmp 201/tcp AppleTalk Routing Maintenance +at-rtmp 201/udp AppleTalk Routing Maintenance +at-nbp 202/tcp AppleTalk Name Binding +at-nbp 202/udp AppleTalk Name Binding +at-3 203/tcp AppleTalk Unused +at-3 203/udp AppleTalk Unused +at-echo 204/tcp AppleTalk Echo +at-echo 204/udp AppleTalk Echo +at-5 205/tcp AppleTalk Unused +at-5 205/udp AppleTalk Unused +at-zis 206/tcp AppleTalk Zone Information +at-zis 206/udp AppleTalk Zone Information +at-7 207/tcp AppleTalk Unused +at-7 207/udp AppleTalk Unused +at-8 208/tcp AppleTalk Unused +at-8 208/udp AppleTalk Unused +# Rob Chandhok +tam 209/tcp Trivial Authenticated Mail Protocol +tam 209/udp Trivial Authenticated Mail Protocol +# Dan Bernstein +z39.50 210/tcp ANSI Z39.50 +z39.50 210/udp ANSI Z39.50 +# Mark Needleman +# +914c/g 211/tcp Texas Instruments 914C/G Terminal +914c/g 211/udp Texas Instruments 914C/G Terminal +# Bill Harrell <---none---> +anet 212/tcp ATEXSSTR +anet 212/udp ATEXSSTR +# Jim Taylor +ipx 213/tcp IPX +ipx 213/udp IPX +# Don Provan +vmpwscs 214/tcp VM PWSCS +vmpwscs 214/udp VM PWSCS +# Dan Shia +softpc 215/tcp Insignia Solutions +softpc 215/udp Insignia Solutions +# Martyn Thomas <---none---> +atls 216/tcp Access Technology License Server +atls 216/udp Access Technology License Server +# Larry DeLuca +dbase 217/tcp dBASE Unix + + + +Reynolds & Postel [Page 28] + +RFC 1700 Assigned Numbers October 1994 + + +dbase 217/udp dBASE Unix +# Don Gibson +# +mpp 218/tcp Netix Message Posting Protocol +mpp 218/udp Netix Message Posting Protocol +# Shannon Yeh +uarps 219/tcp Unisys ARPs +uarps 219/udp Unisys ARPs +# Ashok Marwaha <---none---> +imap3 220/tcp Interactive Mail Access Protocol v3 +imap3 220/udp Interactive Mail Access Protocol v3 +# James Rice +fln-spx 221/tcp Berkeley rlogind with SPX auth +fln-spx 221/udp Berkeley rlogind with SPX auth +rsh-spx 222/tcp Berkeley rshd with SPX auth +rsh-spx 222/udp Berkeley rshd with SPX auth +cdc 223/tcp Certificate Distribution Center +cdc 223/udp Certificate Distribution Center +# Kannan Alagappan +# 224-241 Reserved +# Jon Postel +# 242/tcp Unassigned +# 242/udp Unassigned +sur-meas 243/tcp Survey Measurement +sur-meas 243/udp Survey Measurement +# Dave Clark +# 244/tcp Unassigned +# 244/udp Unassigned +link 245/tcp LINK +link 245/udp LINK +dsp3270 246/tcp Display Systems Protocol +dsp3270 246/udp Display Systems Protocol +# Weldon J. Showalter +# 247-255 Reserved +# Jon Postel +# 256-343 Unassigned +pdap 344/tcp Prospero Data Access Protocol +pdap 344/udp Prospero Data Access Protocol +# B. Clifford Neuman +pawserv 345/tcp Perf Analysis Workbench +pawserv 345/udp Perf Analysis Workbench +zserv 346/tcp Zebra server +zserv 346/udp Zebra server +fatserv 347/tcp Fatmen Server +fatserv 347/udp Fatmen Server +csi-sgwp 348/tcp Cabletron Management Protocol +csi-sgwp 348/udp Cabletron Management Protocol +# 349-370 Unassigned + + + +Reynolds & Postel [Page 29] + +RFC 1700 Assigned Numbers October 1994 + + +clearcase 371/tcp Clearcase +clearcase 371/udp Clearcase +# Dave LeBlang +ulistserv 372/tcp Unix Listserv +ulistserv 372/udp Unix Listserv +# Anastasios Kotsikonas +legent-1 373/tcp Legent Corporation +legent-1 373/udp Legent Corporation +legent-2 374/tcp Legent Corporation +legent-2 374/udp Legent Corporation +# Keith Boyce <---none---> +hassle 375/tcp Hassle +hassle 375/udp Hassle +# Reinhard Doelz +nip 376/tcp Amiga Envoy Network Inquiry Proto +nip 376/udp Amiga Envoy Network Inquiry Proto +# Kenneth Dyke +tnETOS 377/tcp NEC Corporation +tnETOS 377/udp NEC Corporation +dsETOS 378/tcp NEC Corporation +dsETOS 378/udp NEC Corporation +# Tomoo Fujita +is99c 379/tcp TIA/EIA/IS-99 modem client +is99c 379/udp TIA/EIA/IS-99 modem client +is99s 380/tcp TIA/EIA/IS-99 modem server +is99s 380/udp TIA/EIA/IS-99 modem server +# Frank Quick +hp-collector 381/tcp hp performance data collector +hp-collector 381/udp hp performance data collector +hp-managed-node 382/tcp hp performance data managed node +hp-managed-node 382/udp hp performance data managed node +hp-alarm-mgr 383/tcp hp performance data alarm manager +hp-alarm-mgr 383/udp hp performance data alarm manager +# Frank Blakely +arns 384/tcp A Remote Network Server System +arns 384/udp A Remote Network Server System +# David Hornsby +ibm-app 385/tcp IBM Application +ibm-app 385/tcp IBM Application +# Lisa Tomita <---none---> +asa 386/tcp ASA Message Router Object Def. +asa 386/udp ASA Message Router Object Def. +# Steve Laitinen +aurp 387/tcp Appletalk Update-Based Routing Pro. +aurp 387/udp Appletalk Update-Based Routing Pro. +# Chris Ranch +unidata-ldm 388/tcp Unidata LDM Version 4 +unidata-ldm 388/udp Unidata LDM Version 4 + + + +Reynolds & Postel [Page 30] + +RFC 1700 Assigned Numbers October 1994 + + +# Glenn Davis +ldap 389/tcp Lightweight Directory Access Protocol +ldap 389/udp Lightweight Directory Access Protocol +# Tim Howes +uis 390/tcp UIS +uis 390/udp UIS +# Ed Barron <---none---> +synotics-relay 391/tcp SynOptics SNMP Relay Port +synotics-relay 391/udp SynOptics SNMP Relay Port +synotics-broker 392/tcp SynOptics Port Broker Port +synotics-broker 392/udp SynOptics Port Broker Port +# Illan Raab +dis 393/tcp Data Interpretation System +dis 393/udp Data Interpretation System +# Paul Stevens +embl-ndt 394/tcp EMBL Nucleic Data Transfer +embl-ndt 394/udp EMBL Nucleic Data Transfer +# Peter Gad +netcp 395/tcp NETscout Control Protocol +netcp 395/udp NETscout Control Protocol +# Anil Singhal <---none---> +netware-ip 396/tcp Novell Netware over IP +netware-ip 396/udp Novell Netware over IP +mptn 397/tcp Multi Protocol Trans. Net. +mptn 397/udp Multi Protocol Trans. Net. +# Soumitra Sarkar +kryptolan 398/tcp Kryptolan +kryptolan 398/udp Kryptolan +# Peter de Laval +# 399/tcp Unassigned +# 399/udp Unassigned +work-sol 400/tcp Workstation Solutions +work-sol 400/udp Workstation Solutions +# Jim Ward +ups 401/tcp Uninterruptible Power Supply +ups 401/udp Uninterruptible Power Supply +# Guenther Seybold +genie 402/tcp Genie Protocol +genie 402/udp Genie Protocol +# Mark Hankin <---none---> +decap 403/tcp decap +decap 403/udp decap +nced 404/tcp nced +nced 404/udp nced +ncld 405/tcp ncld +ncld 405/udp ncld +# Richard Jones <---none---> +imsp 406/tcp Interactive Mail Support Protocol + + + +Reynolds & Postel [Page 31] + +RFC 1700 Assigned Numbers October 1994 + + +imsp 406/udp Interactive Mail Support Protocol +# John Myers +timbuktu 407/tcp Timbuktu +timbuktu 407/udp Timbuktu +# Marc Epard +prm-sm 408/tcp Prospero Resource Manager Sys. Man. +prm-sm 408/udp Prospero Resource Manager Sys. Man. +prm-nm 409/tcp Prospero Resource Manager Node Man. +prm-nm 409/udp Prospero Resource Manager Node Man. +# B. Clifford Neuman +decladebug 410/tcp DECLadebug Remote Debug Protocol +decladebug 410/udp DECLadebug Remote Debug Protocol +# Anthony Berent +rmt 411/tcp Remote MT Protocol +rmt 411/udp Remote MT Protocol +# Peter Eriksson +synoptics-trap 412/tcp Trap Convention Port +synoptics-trap 412/udp Trap Convention Port +# Illan Raab +smsp 413/tcp SMSP +smsp 413/udp SMSP +infoseek 414/tcp InfoSeek +infoseek 414/udp InfoSeek +# Steve Kirsch +bnet 415/tcp BNet +bnet 415/udp BNet +# Jim Mertz +silverplatter 416/tcp Silverplatter +silverplatter 416/udp Silverplatter +# Peter Ciuffetti +onmux 417/tcp Onmux +onmux 417/udp Onmux +# Stephen Hanna +hyper-g 418/tcp Hyper-G +hyper-g 418/udp Hyper-G +# Frank Kappe +ariel1 419/tcp Ariel +ariel1 419/udp Ariel +# Jonathan Lavigne +smpte 420/tcp SMPTE +smpte 420/udp SMPTE +# Si Becker <71362.22@CompuServe.COM> +ariel2 421/tcp Ariel +ariel2 421/udp Ariel +ariel3 422/tcp Ariel +ariel3 422/udp Ariel +# Jonathan Lavigne +opc-job-start 423/tcp IBM Operations Planning and Control Start + + + +Reynolds & Postel [Page 32] + +RFC 1700 Assigned Numbers October 1994 + + +opc-job-start 423/udp IBM Operations Planning and Control Start +opc-job-track 424/tcp IBM Operations Planning and Control Track +opc-job-track 424/udp IBM Operations Planning and Control Track +# Conny Larsson +icad-el 425/tcp ICAD +icad-el 425/udp ICAD +# Larry Stone +smartsdp 426/tcp smartsdp +smartsdp 426/udp smartsdp +# Alexander Dupuy +svrloc 427/tcp Server Location +svrloc 427/udp Server Location +# +ocs_cmu 428/tcp OCS_CMU +ocs_cmu 428/udp OCS_CMU +ocs_amu 429/tcp OCS_AMU +ocs_amu 429/udp OCS_AMU +# Florence Wyman +utmpsd 430/tcp UTMPSD +utmpsd 430/udp UTMPSD +utmpcd 431/tcp UTMPCD +utmpcd 431/udp UTMPCD +iasd 432/tcp IASD +iasd 432/udp IASD +# Nir Baroz +nnsp 433/tcp NNSP +nnsp 433/udp NNSP +# Rob Robertson +mobileip-agent 434/tcp MobileIP-Agent +mobileip-agent 434/udp MobileIP-Agent +mobilip-mn 435/tcp MobilIP-MN +mobilip-mn 435/udp MobilIP-MN +# Kannan Alagappan +dna-cml 436/tcp DNA-CML +dna-cml 436/udp DNA-CML +# Dan Flowers +comscm 437/tcp comscm +comscm 437/udp comscm +# Jim Teague +dsfgw 438/tcp dsfgw +dsfgw 438/udp dsfgw +# Andy McKeen +dasp 439/tcp dasp Thomas Obermair +dasp 439/udp dasp tommy@inlab.m.eunet.de +# Thomas Obermair +sgcp 440/tcp sgcp +sgcp 440/udp sgcp +# Marshall Rose + + + +Reynolds & Postel [Page 33] + +RFC 1700 Assigned Numbers October 1994 + + +decvms-sysmgt 441/tcp decvms-sysmgt +decvms-sysmgt 441/udp decvms-sysmgt +# Lee Barton +cvc_hostd 442/tcp cvc_hostd +cvc_hostd 442/udp cvc_hostd +# Bill Davidson +https 443/tcp https MCom +https 443/udp https MCom +# Kipp E.B. Hickman +snpp 444/tcp Simple Network Paging Protocol +snpp 444/udp Simple Network Paging Protocol +# [RFC1568] +microsoft-ds 445/tcp Microsoft-DS +microsoft-ds 445/udp Microsoft-DS +# Arnold Miller +ddm-rdb 446/tcp DDM-RDB +ddm-rdb 446/udp DDM-RDB +ddm-dfm 447/tcp DDM-RFM +ddm-dfm 447/udp DDM-RFM +ddm-byte 448/tcp DDM-BYTE +ddm-byte 448/udp DDM-BYTE +# Jan David Fisher +as-servermap 449/tcp AS Server Mapper +as-servermap 449/udp AS Server Mapper +# Barbara Foss +tserver 450/tcp TServer +tserver 450/udp TServer +# Harvey S. Schultz +# 451-511 Unassigned +exec 512/tcp remote process execution; +# authentication performed using +# passwords and UNIX loppgin names +biff 512/udp used by mail system to notify users +# of new mail received; currently +# receives messages only from +# processes on the same machine +login 513/tcp remote login a la telnet; +# automatic authentication performed +# based on priviledged port numbers +# and distributed data bases which +# identify "authentication domains" +who 513/udp maintains data bases showing who's +# logged in to machines on a local +# net and the load average of the +# machine +cmd 514/tcp like exec, but automatic +# authentication is performed as for +# login server + + + +Reynolds & Postel [Page 34] + +RFC 1700 Assigned Numbers October 1994 + + +syslog 514/udp +printer 515/tcp spooler +printer 515/udp spooler +# 516/tcp Unassigned +# 516/udp Unassigned +talk 517/tcp like tenex link, but across +# machine - unfortunately, doesn't +# use link protocol (this is actually +# just a rendezvous port from which a +# tcp connection is established) +talk 517/udp like tenex link, but across +# machine - unfortunately, doesn't +# use link protocol (this is actually +# just a rendezvous port from which a + tcp connection is established) +ntalk 518/tcp +ntalk 518/udp +utime 519/tcp unixtime +utime 519/udp unixtime +efs 520/tcp extended file name server +router 520/udp local routing process (on site); +# uses variant of Xerox NS routing +# information protocol +# 521-524 Unassigned +timed 525/tcp timeserver +timed 525/udp timeserver +tempo 526/tcp newdate +tempo 526/udp newdate +# 527-529 Unassigned +courier 530/tcp rpc +courier 530/udp rpc +conference 531/tcp chat +conference 531/udp chat +netnews 532/tcp readnews +netnews 532/udp readnews +netwall 533/tcp for emergency broadcasts +netwall 533/udp for emergency broadcasts +# 534-538 Unassigned +apertus-ldp 539/tcp Apertus Technologies Load Determination +apertus-ldp 539/udp Apertus Technologies Load Determination +uucp 540/tcp uucpd +uucp 540/udp uucpd +uucp-rlogin 541/tcp uucp-rlogin Stuart Lynne +uucp-rlogin 541/udp uucp-rlogin sl@wimsey.com +# 542/tcp Unassigned +# 542/udp Unassigned +klogin 543/tcp +klogin 543/udp + + + +Reynolds & Postel [Page 35] + +RFC 1700 Assigned Numbers October 1994 + + +kshell 544/tcp krcmd +kshell 544/udp krcmd +# 545-549 Unassigned +new-rwho 550/tcp new-who +new-rwho 550/udp new-who +# 551-555 Unassigned +dsf 555/tcp +dsf 555/udp +remotefs 556/tcp rfs server +remotefs 556/udp rfs server +# 557-559 Unassigned +rmonitor 560/tcp rmonitord +rmonitor 560/udp rmonitord +monitor 561/tcp +monitor 561/udp +chshell 562/tcp chcmd +chshell 562/udp chcmd +# 563/tcp Unassigned +# 563/udp Unassigned +9pfs 564/tcp plan 9 file service +9pfs 564/udp plan 9 file service +whoami 565/tcp whoami +whoami 565/udp whoami +# 566-569 Unassigned +meter 570/tcp demon +meter 570/udp demon +meter 571/tcp udemon +meter 571/udp udemon +# 572-599 Unassigned +ipcserver 600/tcp Sun IPC server +ipcserver 600/udp Sun IPC server +nqs 607/tcp nqs +nqs 607/udp nqs +urm 606/tcp Cray Unified Resource Manager +urm 606/udp Cray Unified Resource Manager +# Bill Schiefelbein +sift-uft 608/tcp Sender-Initiated/Unsolicited File Transfer +sift-uft 608/udp Sender-Initiated/Unsolicited File Transfer +# Rick Troth +npmp-trap 609/tcp npmp-trap +npmp-trap 609/udp npmp-trap +npmp-local 610/tcp npmp-local +npmp-local 610/udp npmp-local +npmp-gui 611/tcp npmp-gui +npmp-gui 611/udp npmp-gui +# John Barnes +ginad 634/tcp ginad +ginad 634/udp ginad + + + +Reynolds & Postel [Page 36] + +RFC 1700 Assigned Numbers October 1994 + + +# Mark Crother +mdqs 666/tcp +mdqs 666/udp +doom 666/tcp doom Id Software +doom 666/tcp doom Id Software +# +elcsd 704/tcp errlog copy/server daemon +elcsd 704/udp errlog copy/server daemon + +entrustmanager 709/tcp EntrustManager +entrustmanager 709/udp EntrustManager +# Peter Whittaker +netviewdm1 729/tcp IBM NetView DM/6000 Server/Client +netviewdm1 729/udp IBM NetView DM/6000 Server/Client +netviewdm2 730/tcp IBM NetView DM/6000 send/tcp +netviewdm2 730/udp IBM NetView DM/6000 send/tcp +netviewdm3 731/tcp IBM NetView DM/6000 receive/tcp +netviewdm3 731/udp IBM NetView DM/6000 receive/tcp +# Philippe Binet (phbinet@vnet.IBM.COM) +netgw 741/tcp netGW +netgw 741/udp netGW +netrcs 742/tcp Network based Rev. Cont. Sys. +netrcs 742/udp Network based Rev. Cont. Sys. +# Gordon C. Galligher +flexlm 744/tcp Flexible License Manager +flexlm 744/udp Flexible License Manager +# Matt Christiano +# +fujitsu-dev 747/tcp Fujitsu Device Control +fujitsu-dev 747/udp Fujitsu Device Control +ris-cm 748/tcp Russell Info Sci Calendar Manager +ris-cm 748/udp Russell Info Sci Calendar Manager +kerberos-adm 749/tcp kerberos administration +kerberos-adm 749/udp kerberos administration +rfile 750/tcp +loadav 750/udp +pump 751/tcp +pump 751/udp +qrh 752/tcp +qrh 752/udp +rrh 753/tcp +rrh 753/udp +tell 754/tcp send +tell 754/udp send +nlogin 758/tcp +nlogin 758/udp +con 759/tcp +con 759/udp + + + +Reynolds & Postel [Page 37] + +RFC 1700 Assigned Numbers October 1994 + + +ns 760/tcp +ns 760/udp +rxe 761/tcp +rxe 761/udp +quotad 762/tcp +quotad 762/udp +cycleserv 763/tcp +cycleserv 763/udp +omserv 764/tcp +omserv 764/udp +webster 765/tcp +webster 765/udp +phonebook 767/tcp phone +phonebook 767/udp phone +vid 769/tcp +vid 769/udp +cadlock 770/tcp +cadlock 770/udp +rtip 771/tcp +rtip 771/udp +cycleserv2 772/tcp +cycleserv2 772/udp +submit 773/tcp +notify 773/udp +rpasswd 774/tcp +acmaint_dbd 774/udp +entomb 775/tcp +acmaint_transd 775/udp +wpages 776/tcp +wpages 776/udp +wpgs 780/tcp +wpgs 780/udp +concert 786/tcp Concert +concert 786/udp Concert +# Josyula R. Rao +mdbs_daemon 800/tcp +mdbs_daemon 800/udp +device 801/tcp +device 801/udp +xtreelic 996/tcp Central Point Software +xtreelic 996/udp Central Point Software +# Dale Cabell +maitrd 997/tcp +maitrd 997/udp +busboy 998/tcp +puparp 998/udp +garcon 999/tcp +applix 999/udp Applix ac + + + +Reynolds & Postel [Page 38] + +RFC 1700 Assigned Numbers October 1994 + + +puprouter 999/tcp +puprouter 999/udp +cadlock 1000/tcp +ock 1000/udp + 1023/tcp Reserved + 1024/udp Reserved +# IANA + + + +REGISTERED PORT NUMBERS + +The Registered Ports are not controlled by the IANA and on most +systems can be used by ordinary user processes or programs executed by +ordinary users. + +Ports are used in the TCP [RFC793] to name the ends of logical +connections which carry long term conversations. For the purpose of +providing services to unknown callers, a service contact port is +defined. This list specifies the port used by the server process as +its contact port. While the IANA can not control uses of these ports +it does register or list uses of these ports as a convienence to the +community. + +To the extent possible, these same port assignments are used with the +UDP [RFC768]. + +The Registered Ports are in the range 1024-65535. + +Port Assignments: + +Keyword Decimal Description References +------- ------- ----------- ---------- + 1024/tcp Reserved + 1024/udp Reserved +# IANA +blackjack 1025/tcp network blackjack +blackjack 1025/udp network blackjack +iad1 1030/tcp BBN IAD +iad1 1030/udp BBN IAD +iad2 1031/tcp BBN IAD +iad2 1031/udp BBN IAD +iad3 1032/tcp BBN IAD +iad3 1032/udp BBN IAD +# Andy Malis +instl_boots 1067/tcp Installation Bootstrap Proto. Serv. +instl_boots 1067/udp Installation Bootstrap Proto. Serv. +instl_bootc 1068/tcp Installation Bootstrap Proto. Cli. + + + +Reynolds & Postel [Page 39] + +RFC 1700 Assigned Numbers October 1994 + + +instl_bootc 1068/udp Installation Bootstrap Proto. Cli. +# David Arko < +socks 1080/tcp Socks +socks 1080/udp Socks +# Ying-Da Lee +nerv 1222/tcp SNI R&D network +nerv 1222/udp SNI R&D network +# Martin Freiss +hermes 1248/tcp +hermes 1248/udp +alta-ana-lm 1346/tcp Alta Analytics License Manager +alta-ana-lm 1346/udp Alta Analytics License Manager +bbn-mmc 1347/tcp multi media conferencing +bbn-mmc 1347/udp multi media conferencing +bbn-mmx 1348/tcp multi media conferencing +bbn-mmx 1348/udp multi media conferencing +sbook 1349/tcp Registration Network Protocol +sbook 1349/udp Registration Network Protocol +editbench 1350/tcp Registration Network Protocol +editbench 1350/udp Registration Network Protocol +# Simson L. Garfinkel +equationbuilder 1351/tcp Digital Tool Works (MIT) +equationbuilder 1351/udp Digital Tool Works (MIT) +# Terrence J. Talbot +lotusnote 1352/tcp Lotus Note +lotusnote 1352/udp Lotus Note +# Greg Pflaum +relief 1353/tcp Relief Consulting +relief 1353/udp Relief Consulting +# John Feiler +rightbrain 1354/tcp RightBrain Software +rightbrain 1354/udp RightBrain Software +# Glenn Reid +intuitive edge 1355/tcp Intuitive Edge +intuitive edge 1355/udp Intuitive Edge +# Montgomery Zukowski +# +cuillamartin 1356/tcp CuillaMartin Company +cuillamartin 1356/udp CuillaMartin Company +pegboard 1357/tcp Electronic PegBoard +pegboard 1357/udp Electronic PegBoard + + + +Reynolds & Postel [Page 40] + +RFC 1700 Assigned Numbers October 1994 + + +# Chris Cuilla +# +connlcli 1358/tcp CONNLCLI +connlcli 1358/udp CONNLCLI +ftsrv 1359/tcp FTSRV +ftsrv 1359/udp FTSRV +# Ines Homem de Melo +mimer 1360/tcp MIMER +mimer 1360/udp MIMER +# Per Schroeder +linx 1361/tcp LinX +linx 1361/udp LinX +# Steffen Schilke <---none---> +timeflies 1362/tcp TimeFlies +timeflies 1362/udp TimeFlies +# Doug Kent +ndm-requester 1363/tcp Network DataMover Requester +ndm-requester 1363/udp Network DataMover Requester +ndm-server 1364/tcp Network DataMover Server +ndm-server 1364/udp Network DataMover Server +# Toshio Watanabe +# +adapt-sna 1365/tcp Network Software Associates +adapt-sna 1365/udp Network Software Associates +# Jeffery Chiao <714-768-401> +netware-csp 1366/tcp Novell NetWare Comm Service Platform +netware-csp 1366/udp Novell NetWare Comm Service Platform +# Laurie Lindsey +dcs 1367/tcp DCS +dcs 1367/udp DCS +# Stefan Siebert +screencast 1368/tcp ScreenCast +screencast 1368/udp ScreenCast +# Bill Tschumy +gv-us 1369/tcp GlobalView to Unix Shell +gv-us 1369/udp GlobalView to Unix Shell +us-gv 1370/tcp Unix Shell to GlobalView +us-gv 1370/udp Unix Shell to GlobalView +# Makoto Mita +fc-cli 1371/tcp Fujitsu Config Protocol +fc-cli 1371/udp Fujitsu Config Protocol +fc-ser 1372/tcp Fujitsu Config Protocol +fc-ser 1372/udp Fujitsu Config Protocol +# Ryuichi Horie +chromagrafx 1373/tcp Chromagrafx +chromagrafx 1373/udp Chromagrafx +# Mike Barthelemy +molly 1374/tcp EPI Software Systems + + + +Reynolds & Postel [Page 41] + +RFC 1700 Assigned Numbers October 1994 + + +molly 1374/udp EPI Software Systems +# Jim Vlcek +bytex 1375/tcp Bytex +bytex 1375/udp Bytex +# Mary Ann Burt +ibm-pps 1376/tcp IBM Person to Person Software +ibm-pps 1376/udp IBM Person to Person Software +# Simon Phipps +cichlid 1377/tcp Cichlid License Manager +cichlid 1377/udp Cichlid License Manager +# Andy Burgess +elan 1378/tcp Elan License Manager +elan 1378/udp Elan License Manager +# Ken Greer +dbreporter 1379/tcp Integrity Solutions +dbreporter 1379/udp Integrity Solutions +# Tim Dawson +telesis-licman 1380/tcp Telesis Network License Manager +telesis-licman 1380/udp Telesis Network License Manager +# Karl Schendel, Jr. +apple-licman 1381/tcp Apple Network License Manager +apple-licman 1381/udp Apple Network License Manager +# Earl Wallace +udt_os 1382/tcp +udt_os 1382/udp +gwha 1383/tcp GW Hannaway Network License Manager +gwha 1383/udp GW Hannaway Network License Manager +# J. Gabriel Foster +os-licman 1384/tcp Objective Solutions License Manager +os-licman 1384/udp Objective Solutions License Manager +# Donald Cornwell +atex_elmd 1385/tcp Atex Publishing License Manager +atex_elmd 1385/udp Atex Publishing License Manager +# Brett Sorenson +checksum 1386/tcp CheckSum License Manager +checksum 1386/udp CheckSum License Manager +# Andreas Glocker +cadsi-lm 1387/tcp Computer Aided Design Software Inc LM +cadsi-lm 1387/udp Computer Aided Design Software Inc LM +# Sulistio Muljadi +objective-dbc 1388/tcp Objective Solutions DataBase Cache +objective-dbc 1388/udp Objective Solutions DataBase Cache +# Donald Cornwell +iclpv-dm 1389/tcp Document Manager +iclpv-dm 1389/udp Document Manager +iclpv-sc 1390/tcp Storage Controller +iclpv-sc 1390/udp Storage Controller +iclpv-sas 1391/tcp Storage Access Server + + + +Reynolds & Postel [Page 42] + +RFC 1700 Assigned Numbers October 1994 + + +iclpv-sas 1391/udp Storage Access Server +iclpv-pm 1392/tcp Print Manager +iclpv-pm 1392/udp Print Manager +iclpv-nls 1393/tcp Network Log Server +iclpv-nls 1393/udp Network Log Server +iclpv-nlc 1394/tcp Network Log Client +iclpv-nlc 1394/udp Network Log Client +iclpv-wsm 1395/tcp PC Workstation Manager software +iclpv-wsm 1395/udp PC Workstation Manager software +# A.P. Hobson +dvl-activemail 1396/tcp DVL Active Mail +dvl-activemail 1396/udp DVL Active Mail +audio-activmail 1397/tcp Audio Active Mail +audio-activmail 1397/udp Audio Active Mail +video-activmail 1398/tcp Video Active Mail +video-activmail 1398/udp Video Active Mail +# Ehud Shapiro +cadkey-licman 1399/tcp Cadkey License Manager +cadkey-licman 1399/udp Cadkey License Manager +cadkey-tablet 1400/tcp Cadkey Tablet Daemon +cadkey-tablet 1400/udp Cadkey Tablet Daemon +# Joe McCollough +goldleaf-licman 1401/tcp Goldleaf License Manager +goldleaf-licman 1401/udp Goldleaf License Manager +# John Fox <---none---> +prm-sm-np 1402/tcp Prospero Resource Manager +prm-sm-np 1402/udp Prospero Resource Manager +prm-nm-np 1403/tcp Prospero Resource Manager +prm-nm-np 1403/udp Prospero Resource Manager +# B. Clifford Neuman +igi-lm 1404/tcp Infinite Graphics License Manager +igi-lm 1404/udp Infinite Graphics License Manager +ibm-res 1405/tcp IBM Remote Execution Starter +ibm-res 1405/udp IBM Remote Execution Starter +netlabs-lm 1406/tcp NetLabs License Manager +netlabs-lm 1406/udp NetLabs License Manager +dbsa-lm 1407/tcp DBSA License Manager +dbsa-lm 1407/udp DBSA License Manager +# Scott Shattuck +sophia-lm 1408/tcp Sophia License Manager +sophia-lm 1408/udp Sophia License Manager +# Eric Brown +here-lm 1409/tcp Here License Manager +here-lm 1409/udp Here License Manager +# David Ison +hiq 1410/tcp HiQ License Manager +hiq 1410/udp HiQ License Manager +# Rick Pugh + + + +Reynolds & Postel [Page 43] + +RFC 1700 Assigned Numbers October 1994 + + +af 1411/tcp AudioFile +af 1411/udp AudioFile +# Jim Gettys +innosys 1412/tcp InnoSys +innosys 1412/udp InnoSys +innosys-acl 1413/tcp Innosys-ACL +innosys-acl 1413/udp Innosys-ACL +# Eric Welch <--none---> +ibm-mqseries 1414/tcp IBM MQSeries +ibm-mqseries 1414/udp IBM MQSeries +# Roger Meli +dbstar 1415/tcp DBStar +dbstar 1415/udp DBStar +# Jeffrey Millman +novell-lu6.2 1416/tcp Novell LU6.2 +novell-lu6.2 1416/udp Novell LU6.2 +# Peter Liu <--none---> +timbuktu-srv1 1417/tcp Timbuktu Service 1 Port +timbuktu-srv1 1417/tcp Timbuktu Service 1 Port +timbuktu-srv2 1418/tcp Timbuktu Service 2 Port +timbuktu-srv2 1418/udp Timbuktu Service 2 Port +timbuktu-srv3 1419/tcp Timbuktu Service 3 Port +timbuktu-srv3 1419/udp Timbuktu Service 3 Port +timbuktu-srv4 1420/tcp Timbuktu Service 4 Port +timbuktu-srv4 1420/udp Timbuktu Service 4 Port +# Marc Epard +gandalf-lm 1421/tcp Gandalf License Manager +gandalf-lm 1421/udp Gandalf License Manager +# gilmer@gandalf.ca +autodesk-lm 1422/tcp Autodesk License Manager +autodesk-lm 1422/udp Autodesk License Manager +# David Ko +essbase 1423/tcp Essbase Arbor Software +essbase 1423/udp Essbase Arbor Software +hybrid 1424/tcp Hybrid Encryption Protocol +hybrid 1424/udp Hybrid Encryption Protocol +# Howard Hart +zion-lm 1425/tcp Zion Software License Manager +zion-lm 1425/udp Zion Software License Manager +# David Ferrero +sas-1 1426/tcp Satellite-data Acquisition System 1 +sas-1 1426/udp Satellite-data Acquisition System 1 +# Bill Taylor +mloadd 1427/tcp mloadd monitoring tool +mloadd 1427/udp mloadd monitoring tool +# Bob Braden +informatik-lm 1428/tcp Informatik License Manager +informatik-lm 1428/udp Informatik License Manager + + + +Reynolds & Postel [Page 44] + +RFC 1700 Assigned Numbers October 1994 + + +# Harald Schlangmann +# +nms 1429/tcp Hypercom NMS +nms 1429/udp Hypercom NMS +tpdu 1430/tcp Hypercom TPDU +tpdu 1430/udp Hypercom TPDU +# Noor Chowdhury +rgtp 1431/tcp Reverse Gosip Transport +rgtp 1431/udp Reverse Gosip Transport +# +blueberry-lm 1432/tcp Blueberry Software License Manager +blueberry-lm 1432/udp Blueberry Software License Manager +# Steve Beigel +ms-sql-s 1433/tcp Microsoft-SQL-Server +ms-sql-s 1433/udp Microsoft-SQL-Server +ms-sql-m 1434/tcp Microsoft-SQL-Monitor +ms-sql-m 1434/udp Microsoft-SQL-Monitor +# Peter Hussey +ibm-cics 1435/tcp IBM CISC +ibm-cics 1435/udp IBM CISC +# Geoff Meacock +sas-2 1436/tcp Satellite-data Acquisition System 2 +sas-2 1436/udp Satellite-data Acquisition System 2 +# Bill Taylor +tabula 1437/tcp Tabula +tabula 1437/udp Tabula +# Marcelo Einhorn +# +eicon-server 1438/tcp Eicon Security Agent/Server +eicon-server 1438/udp Eicon Security Agent/Server +eicon-x25 1439/tcp Eicon X25/SNA Gateway +eicon-x25 1439/udp Eicon X25/SNA Gateway +eicon-slp 1440/tcp Eicon Service Location Protocol +eicon-slp 1440/udp Eicon Service Location Protocol +# Pat Calhoun +cadis-1 1441/tcp Cadis License Management +cadis-1 1441/udp Cadis License Management +cadis-2 1442/tcp Cadis License Management +cadis-2 1442/udp Cadis License Management +# Todd Wichers +ies-lm 1443/tcp Integrated Engineering Software +ies-lm 1443/udp Integrated Engineering Software +# David Tong +marcam-lm 1444/tcp Marcam License Management +marcam-lm 1444/udp Marcam License Management +# Therese Hunt +proxima-lm 1445/tcp Proxima License Manager +proxima-lm 1445/udp Proxima License Manager + + + +Reynolds & Postel [Page 45] + +RFC 1700 Assigned Numbers October 1994 + + +ora-lm 1446/tcp Optical Research Associates License Manager +ora-lm 1446/udp Optical Research Associates License Manager +apri-lm 1447/tcp Applied Parallel Research LM +apri-lm 1447/udp Applied Parallel Research LM +# Jim Dillon +oc-lm 1448/tcp OpenConnect License Manager +oc-lm 1448/udp OpenConnect License Manager +# Sue Barnhill +peport 1449/tcp PEport +peport 1449/udp PEport +# Qentin Neill +dwf 1450/tcp Tandem Distributed Workbench Facility +dwf 1450/udp Tandem Distributed Workbench Facility +# Mike Bert +infoman 1451/tcp IBM Information Management +infoman 1451/udp IBM Information Management +# Karen Burns <---none---> +gtegsc-lm 1452/tcp GTE Government Systems License Man +gtegsc-lm 1452/udp GTE Government Systems License Man +# Mike Gregory +genie-lm 1453/tcp Genie License Manager +genie-lm 1453/udp Genie License Manager +# Paul Applegate +interhdl_elmd 1454/tcp interHDL License Manager +interhdl_elmd 1454/tcp interHDL License Manager +# Eli Sternheim eli@interhdl.com +esl-lm 1455/tcp ESL License Manager +esl-lm 1455/udp ESL License Manager +# Abel Chou +dca 1456/tcp DCA +dca 1456/udp DCA +# Jeff Garbers +valisys-lm 1457/tcp Valisys License Manager +valisys-lm 1457/udp Valisys License Manager +# Leslie Lincoln +nrcabq-lm 1458/tcp Nichols Research Corp. +nrcabq-lm 1458/udp Nichols Research Corp. +# Howard Cole +proshare1 1459/tcp Proshare Notebook Application +proshare1 1459/udp Proshare Notebook Application +proshare2 1460/tcp Proshare Notebook Application +proshare2 1460/udp Proshare Notebook Application +# Robin Kar +ibm_wrless_lan 1461/tcp IBM Wireless LAN +ibm_wrless_lan 1461/udp IBM Wireless LAN +# +world-lm 1462/tcp World License Manager +world-lm 1462/udp World License Manager + + + +Reynolds & Postel [Page 46] + +RFC 1700 Assigned Numbers October 1994 + + +# Michael S Amirault +nucleus 1463/tcp Nucleus +nucleus 1463/udp Nucleus +# Venky Nagar +msl_lmd 1464/tcp MSL License Manager +msl_lmd 1464/udp MSL License Manager +# Matt Timmermans +pipes 1465/tcp Pipes Platform +pipes 1465/udp Pipes Platform mfarlin@peerlogic.com +# Mark Farlin +oceansoft-lm 1466/tcp Ocean Software License Manager +oceansoft-lm 1466/udp Ocean Software License Manager +# Randy Leonard +csdmbase 1467/tcp CSDMBASE +csdmbase 1467/udp CSDMBASE +csdm 1468/tcp CSDM +csdm 1468/udp CSDM +# Robert Stabl +aal-lm 1469/tcp Active Analysis Limited License Manager +aal-lm 1469/udp Active Analysis Limited License Manager +# David Snocken +44 (71)437-7009 +uaiact 1470/tcp Universal Analytics +uaiact 1470/udp Universal Analytics +# Mark R. Ludwig +csdmbase 1471/tcp csdmbase +csdmbase 1471/udp csdmbase +csdm 1472/tcp csdm +csdm 1472/udp csdm +# Robert Stabl +openmath 1473/tcp OpenMath +openmath 1473/udp OpenMath +# Garth Mayville +telefinder 1474/tcp Telefinder +telefinder 1474/udp Telefinder +# Jim White +taligent-lm 1475/tcp Taligent License Manager +taligent-lm 1475/udp Taligent License Manager +# Mark Sapsford +clvm-cfg 1476/tcp clvm-cfg +clvm-cfg 1476/udp clvm-cfg +# Eric Soderberg +ms-sna-server 1477/tcp ms-sna-server +ms-sna-server 1477/udp ms-sna-server +ms-sna-base 1478/tcp ms-sna-base +ms-sna-base 1478/udp ms-sna-base +# Gordon Mangione +dberegister 1479/tcp dberegister +dberegister 1479/udp dberegister + + + +Reynolds & Postel [Page 47] + +RFC 1700 Assigned Numbers October 1994 + + +# Brian Griswold +pacerforum 1480/tcp PacerForum +pacerforum 1480/udp PacerForum +# Peter Caswell +airs 1481/tcp AIRS +airs 1481/udp AIRS +# Bruce Wilson, 905-771-6161 +miteksys-lm 1482/tcp Miteksys License Manager +miteksys-lm 1482/udp Miteksys License Manager +# Shane McRoberts +afs 1483/tcp AFS License Manager +afs 1483/udp AFS License Manager +# Michael R. Pizolato +confluent 1484/tcp Confluent License Manager +confluent 1484/udp Confluent License Manager +# James Greenfiel +lansource 1485/tcp LANSource +lansource 1485/udp LANSource +# Doug Scott +nms_topo_serv 1486/tcp nms_topo_serv +nms_topo_serv 1486/udp nms_topo_serv +# Sylvia Siu +localinfosrvr 1487/tcp LocalInfoSrvr +localinfosrvr 1487/udp LocalInfoSrvr +# Brian Matthews +docstor 1488/tcp DocStor +docstor 1488/udp DocStor +# Brian Spears +dmdocbroker 1489/tcp dmdocbroker +dmdocbroker 1489/udp dmdocbroker +# Razmik Abnous +insitu-conf 1490/tcp insitu-conf +insitu-conf 1490/udp insitu-conf +# Paul Blacknell +anynetgateway 1491/tcp anynetgateway +anynetgateway 1491/udp anynetgateway +# Dan Poirier +stone-design-1 1492/tcp stone-design-1 +stone-design-1 1492/udp stone-design-1 +# Andrew Stone +netmap_lm 1493/tcp netmap_lm +netmap_lm 1493/udp netmap_lm +# Phillip Magson +ica 1494/tcp ica +ica 1494/udp ica +# John Richardson, Citrix Systems +cvc 1495/tcp cvc +cvc 1495/udp cvc + + + +Reynolds & Postel [Page 48] + +RFC 1700 Assigned Numbers October 1994 + + +# Bill Davidson +liberty-lm 1496/tcp liberty-lm +liberty-lm 1496/udp liberty-lm +# Jim Rogers +rfx-lm 1497/tcp rfx-lm +rfx-lm 1497/udp rfx-lm +# Bill Bishop +watcom-sql 1498/tcp Watcom-SQL +watcom-sql 1498/udp Watcom-SQL +# Rog Skubowius +fhc 1499/tcp Federico Heinz Consultora +fhc 1499/udp Federico Heinz Consultora +# Federico Heinz +vlsi-lm 1500/tcp VLSI License Manager +vlsi-lm 1500/udp VLSI License Manager +# Shue-Lin Kuo +sas-3 1501/tcp Satellite-data Acquisition System 3 +sas-3 1501/udp Satellite-data Acquisition System 3 +# Bill Taylor +shivadiscovery 1502/tcp Shiva +shivadiscovery 1502/udp Shiva +# Jonathan Wenocur +imtc-mcs 1503/tcp Databeam +imtc-mcs 1503/udp Databeam +# Jim Johnstone +evb-elm 1504/tcp EVB Software Engineering License Manager +evb-elm 1504/udp EVB Software Engineering License Manager +# B.G. Mahesh < mahesh@sett.com> +funkproxy 1505/tcp Funk Software, Inc. +funkproxy 1505/udp Funk Software, Inc. +# Robert D. Vincent +# 1506-1523 Unassigned +ingreslock 1524/tcp ingres +ingreslock 1524/udp ingres +orasrv 1525/tcp oracle +orasrv 1525/udp oracle +prospero-np 1525/tcp Prospero Directory Service non-priv +prospero-np 1525/udp Prospero Directory Service non-priv +pdap-np 1526/tcp Prospero Data Access Prot non-priv +pdap-np 1526/udp Prospero Data Access Prot non-priv +# B. Clifford Neuman +tlisrv 1527/tcp oracle +tlisrv 1527/udp oracle +coauthor 1529/tcp oracle +coauthor 1529/udp oracle +issd 1600/tcp +issd 1600/udp +nkd 1650/tcp + + + +Reynolds & Postel [Page 49] + +RFC 1700 Assigned Numbers October 1994 + + +nkd 1650/udp +proshareaudio 1651/tcp proshare conf audio +proshareaudio 1651/udp proshare conf audio +prosharevideo 1652/tcp proshare conf video +prosharevideo 1652/udp proshare conf video +prosharedata 1653/tcp proshare conf data +prosharedata 1653/udp proshare conf data +prosharerequest 1654/tcp proshare conf request +prosharerequest 1654/udp proshare conf request +prosharenotify 1655/tcp proshare conf notify +prosharenotify 1655/udp proshare conf notify +# +netview-aix-1 1661/tcp netview-aix-1 +netview-aix-1 1661/udp netview-aix-1 +netview-aix-2 1662/tcp netview-aix-2 +netview-aix-2 1662/udp netview-aix-2 +netview-aix-3 1663/tcp netview-aix-3 +netview-aix-3 1663/udp netview-aix-3 +netview-aix-4 1664/tcp netview-aix-4 +netview-aix-4 1664/udp netview-aix-4 +netview-aix-5 1665/tcp netview-aix-5 +netview-aix-5 1665/udp netview-aix-5 +netview-aix-6 1666/tcp netview-aix-6 +netview-aix-6 1666/udp netview-aix-6 +# Martha Crisson +licensedaemon 1986/tcp cisco license management +licensedaemon 1986/udp cisco license management +tr-rsrb-p1 1987/tcp cisco RSRB Priority 1 port +tr-rsrb-p1 1987/udp cisco RSRB Priority 1 port +tr-rsrb-p2 1988/tcp cisco RSRB Priority 2 port +tr-rsrb-p2 1988/udp cisco RSRB Priority 2 port +tr-rsrb-p3 1989/tcp cisco RSRB Priority 3 port +tr-rsrb-p3 1989/udp cisco RSRB Priority 3 port +#PROBLEMS!=================================================== +mshnet 1989/tcp MHSnet system +mshnet 1989/udp MHSnet system +# Bob Kummerfeld +#PROBLEMS!=================================================== +stun-p1 1990/tcp cisco STUN Priority 1 port +stun-p1 1990/udp cisco STUN Priority 1 port +stun-p2 1991/tcp cisco STUN Priority 2 port +stun-p2 1991/udp cisco STUN Priority 2 port +stun-p3 1992/tcp cisco STUN Priority 3 port +stun-p3 1992/udp cisco STUN Priority 3 port +#PROBLEMS!=================================================== +ipsendmsg 1992/tcp IPsendmsg +ipsendmsg 1992/udp IPsendmsg +# Bob Kummerfeld + + + +Reynolds & Postel [Page 50] + +RFC 1700 Assigned Numbers October 1994 + + +#PROBLEMS!=================================================== +snmp-tcp-port 1993/tcp cisco SNMP TCP port +snmp-tcp-port 1993/udp cisco SNMP TCP port +stun-port 1994/tcp cisco serial tunnel port +stun-port 1994/udp cisco serial tunnel port +perf-port 1995/tcp cisco perf port +perf-port 1995/udp cisco perf port +tr-rsrb-port 1996/tcp cisco Remote SRB port +tr-rsrb-port 1996/udp cisco Remote SRB port +gdp-port 1997/tcp cisco Gateway Discovery Protocol +gdp-port 1997/udp cisco Gateway Discovery Protocol +x25-svc-port 1998/tcp cisco X.25 service (XOT) +x25-svc-port 1998/udp cisco X.25 service (XOT) +tcp-id-port 1999/tcp cisco identification port +tcp-id-port 1999/udp cisco identification port +callbook 2000/tcp +callbook 2000/udp +dc 2001/tcp +wizard 2001/udp curry +globe 2002/tcp +globe 2002/udp +mailbox 2004/tcp +emce 2004/udp CCWS mm conf +berknet 2005/tcp +oracle 2005/udp +invokator 2006/tcp +raid-cc 2006/udp raid +dectalk 2007/tcp +raid-am 2007/udp +conf 2008/tcp +terminaldb 2008/udp +news 2009/tcp +whosockami 2009/udp +search 2010/tcp +pipe_server 2010/udp +raid-cc 2011/tcp raid +servserv 2011/udp +ttyinfo 2012/tcp +raid-ac 2012/udp +raid-am 2013/tcp +raid-cd 2013/udp +troff 2014/tcp +raid-sf 2014/udp +cypress 2015/tcp +raid-cs 2015/udp +bootserver 2016/tcp +bootserver 2016/udp +cypress-stat 2017/tcp + + + +Reynolds & Postel [Page 51] + +RFC 1700 Assigned Numbers October 1994 + + +bootclient 2017/udp +terminaldb 2018/tcp +rellpack 2018/udp +whosockami 2019/tcp +about 2019/udp +xinupageserver 2020/tcp +xinupageserver 2020/udp +servexec 2021/tcp +xinuexpansion1 2021/udp +down 2022/tcp +xinuexpansion2 2022/udp +xinuexpansion3 2023/tcp +xinuexpansion3 2023/udp +xinuexpansion4 2024/tcp +xinuexpansion4 2024/udp +ellpack 2025/tcp +xribs 2025/udp +scrabble 2026/tcp +scrabble 2026/udp +shadowserver 2027/tcp +shadowserver 2027/udp +submitserver 2028/tcp +submitserver 2028/udp +device2 2030/tcp +device2 2030/udp +blackboard 2032/tcp +blackboard 2032/udp +glogger 2033/tcp +glogger 2033/udp +scoremgr 2034/tcp +scoremgr 2034/udp +imsldoc 2035/tcp +imsldoc 2035/udp +objectmanager 2038/tcp +objectmanager 2038/udp +lam 2040/tcp +lam 2040/udp +interbase 2041/tcp +interbase 2041/udp +isis 2042/tcp +isis 2042/udp +isis-bcast 2043/tcp +isis-bcast 2043/udp +rimsl 2044/tcp +rimsl 2044/udp +cdfunc 2045/tcp +cdfunc 2045/udp +sdfunc 2046/tcp + + + +Reynolds & Postel [Page 52] + +RFC 1700 Assigned Numbers October 1994 + + +sdfunc 2046/udp +dls 2047/tcp +dls 2047/udp +dls-monitor 2048/tcp +dls-monitor 2048/udp +shilp 2049/tcp +shilp 2049/udp +dlsrpn 2065/tcp Data Link Switch Read Port Number +dlsrpn 2065/udp Data Link Switch Read Port Number +dlswpn 2067/tcp Data Link Switch Write Port Number +dlswpn 2067/udp Data Link Switch Write Port Number +ats 2201/tcp Advanced Training System Program +ats 2201/udp Advanced Training System Program +rtsserv 2500/tcp Resource Tracking system server +rtsserv 2500/udp Resource Tracking system server +rtsclient 2501/tcp Resource Tracking system client +rtsclient 2501/udp Resource Tracking system client +# Aubrey Turner +# +hp-3000-telnet 2564/tcp HP 3000 NS/VT block mode telnet +www-dev 2784/tcp world wide web - development +www-dev 2784/udp world wide web - development +NSWS 3049/tcp +NSWS 3049/udp +ccmail 3264/tcp cc:mail/lotus +ccmail 3264/udp cc:mail/lotus +dec-notes 3333/tcp DEC Notes +dec-notes 3333/udp DEC Notes +# Kim Moraros +mapper-nodemgr 3984/tcp MAPPER network node manager +mapper-nodemgr 3984/udp MAPPER network node manager +mapper-mapethd 3985/tcp MAPPER TCP/IP server +mapper-mapethd 3985/udp MAPPER TCP/IP server +mapper-ws_ethd 3986/tcp MAPPER workstation server +mapper-ws_ethd 3986/udp MAPPER workstation server +# John C. Horton +bmap 3421/tcp Bull Apprise portmapper +bmap 3421/udp Bull Apprise portmapper +# Jeremy Gilbert +udt_os 3900/tcp Unidata UDT OS +udt_os 3900/udp Unidata UDT OS +# James Powell +nuts_dem 4132/tcp NUTS Daemon +nuts_dem 4132/udp NUTS Daemon +nuts_bootp 4133/tcp NUTS Bootp Server +nuts_bootp 4133/udp NUTS Bootp Server +# Martin Freiss +unicall 4343/tcp UNICALL + + + +Reynolds & Postel [Page 53] + +RFC 1700 Assigned Numbers October 1994 + + +unicall 4343/udp UNICALL +# James Powell +krb524 4444/tcp KRB524 +krb524 4444/udp KRB524 +# B. Clifford Neuman +rfa 4672/tcp remote file access server +rfa 4672/udp remote file access server +commplex-main 5000/tcp +commplex-main 5000/udp +commplex-link 5001/tcp +commplex-link 5001/udp +rfe 5002/tcp radio free ethernet +rfe 5002/udp radio free ethernet +telelpathstart 5010/tcp TelepathStart +telelpathstart 5010/udp TelepathStart +telelpathattack 5011/tcp TelepathAttack +telelpathattack 5011/udp TelepathAttack +# Helmuth Breitenfellner +mmcc 5050/tcp multimedia conference control tool +mmcc 5050/udp multimedia conference control tool +rmonitor_secure 5145/tcp +rmonitor_secure 5145/udp +aol 5190/tcp America-Online +aol 5190/udp America-Online +# Marty Lyons +padl2sim 5236/tcp +padl2sim 5236/udp +hacl-hb 5300/tcp # HA cluster heartbeat +hacl-hb 5300/udp # HA cluster heartbeat +hacl-gs 5301/tcp # HA cluster general services +hacl-gs 5301/udp # HA cluster general services +hacl-cfg 5302/tcp # HA cluster configuration +hacl-cfg 5302/udp # HA cluster configuration +hacl-probe 5303/tcp # HA cluster probing +hacl-probe 5303/udp # HA cluster probing +hacl-local 5304/tcp +hacl-local 5304/udp +hacl-test 5305/tcp +hacl-test 5305/udp +# Eric Soderberg +x11 6000-6063/tcp X Window System +x11 6000-6063/udp X Window System +# Stephen Gildea +sub-process 6111/tcp HP SoftBench Sub-Process Control +sub-process 6111/udp HP SoftBench Sub-Process Control +meta-corp 6141/tcp Meta Corporation License Manager +meta-corp 6141/udp Meta Corporation License Manager +# Osamu Masuda <--none---> + + + +Reynolds & Postel [Page 54] + +RFC 1700 Assigned Numbers October 1994 + + +aspentec-lm 6142/tcp Aspen Technology License Manager +aspentec-lm 6142/udp Aspen Technology License Manager +# Kevin Massey +watershed-lm 6143/tcp Watershed License Manager +watershed-lm 6143/udp Watershed License Manager +# David Ferrero +statsci1-lm 6144/tcp StatSci License Manager - 1 +statsci1-lm 6144/udp StatSci License Manager - 1 +statsci2-lm 6145/tcp StatSci License Manager - 2 +statsci2-lm 6145/udp StatSci License Manager - 2 +# Scott Blachowicz +lonewolf-lm 6146/tcp Lone Wolf Systems License Manager +lonewolf-lm 6146/udp Lone Wolf Systems License Manager +# Dan Klein +montage-lm 6147/tcp Montage License Manager +montage-lm 6147/udp Montage License Manager +# Michael Ubell +xdsxdm 6558/udp +xdsxdm 6558/tcp +afs3-fileserver 7000/tcp file server itself +afs3-fileserver 7000/udp file server itself +afs3-callback 7001/tcp callbacks to cache managers +afs3-callback 7001/udp callbacks to cache managers +afs3-prserver 7002/tcp users & groups database +afs3-prserver 7002/udp users & groups database +afs3-vlserver 7003/tcp volume location database +afs3-vlserver 7003/udp volume location database +afs3-kaserver 7004/tcp AFS/Kerberos authentication service +afs3-kaserver 7004/udp AFS/Kerberos authentication service +afs3-volser 7005/tcp volume managment server +afs3-volser 7005/udp volume managment server +afs3-errors 7006/tcp error interpretation service +afs3-errors 7006/udp error interpretation service +afs3-bos 7007/tcp basic overseer process +afs3-bos 7007/udp basic overseer process +afs3-update 7008/tcp server-to-server updater +afs3-update 7008/udp server-to-server updater +afs3-rmtsys 7009/tcp remote cache manager service +afs3-rmtsys 7009/udp remote cache manager service +ups-onlinet 7010/tcp onlinet uninterruptable power supplies +ups-onlinet 7010/udp onlinet uninterruptable power supplies +# Brian Hammill +font-service 7100/tcp X Font Service +font-service 7100/udp X Font Service +# Stephen Gildea +fodms 7200/tcp FODMS FLIP +fodms 7200/udp FODMS FLIP +# David Anthony + + + +Reynolds & Postel [Page 55] + +RFC 1700 Assigned Numbers October 1994 + + +man 9535/tcp +man 9535/udp +isode-dua 17007/tcp +isode-dua 17007/udp + +REFERENCES + +[RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + USC/Information Sciences Institute, August 1980. + +[RFC793] Postel, J., ed., "Transmission Control Protocol - DARPA + Internet Program Protocol Specification", STD 7, RFC 793, + USC/Information Sciences Institute, September 1981. + + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 56] + +RFC 1700 Assigned Numbers October 1994 + + +INTERNET MULTICAST ADDRESSES + +Host Extensions for IP Multicasting [RFC1112] specifies the +extensions required of a host implementation of the Internet Protocol +(IP) to support multicasting. Current addresses are listed below. + +224.0.0.0 Base Address (Reserved) [RFC1112,JBP] +224.0.0.1 All Systems on this Subnet [RFC1112,JBP] +224.0.0.2 All Routers on this Subnet [JBP] +224.0.0.3 Unassigned [JBP] +224.0.0.4 DVMRP Routers [RFC1075,JBP] +224.0.0.5 OSPFIGP OSPFIGP All Routers [RFC1583,JXM1] +224.0.0.6 OSPFIGP OSPFIGP Designated Routers [RFC1583,JXM1] +224.0.0.7 ST Routers [RFC1190,KS14] +224.0.0.8 ST Hosts [RFC1190,KS14] +224.0.0.9 RIP2 Routers [GSM11] +224.0.0.10 IGRP Routers [Dino Farinacci] +224.0.0.11 Mobile-Agents [Bill Simpson] +224.0.0.12-224.0.0.255 Unassigned [JBP] + +224.0.1.0 VMTP Managers Group [RFC1045,DRC3] +224.0.1.1 NTP Network Time Protocol [RFC1119,DLM1] +224.0.1.2 SGI-Dogfight [AXC] +224.0.1.3 Rwhod [SXD] +224.0.1.4 VNP [DRC3] +224.0.1.5 Artificial Horizons - Aviator [BXF] +224.0.1.6 NSS - Name Service Server [BXS2] +224.0.1.7 AUDIONEWS - Audio News Multicast [MXF2] +224.0.1.8 SUN NIS+ Information Service [CXM3] +224.0.1.9 MTP Multicast Transport Protocol [SXA] +224.0.1.10 IETF-1-LOW-AUDIO [SC3] +224.0.1.11 IETF-1-AUDIO [SC3] +224.0.1.12 IETF-1-VIDEO [SC3] +224.0.1.13 IETF-2-LOW-AUDIO [SC3] +224.0.1.14 IETF-2-AUDIO [SC3] +224.0.1.15 IETF-2-VIDEO [SC3] +224.0.1.16 MUSIC-SERVICE [Guido van Rossum] +224.0.1.17 SEANET-TELEMETRY [Andrew Maffei] +224.0.1.18 SEANET-IMAGE [Andrew Maffei] +224.0.1.19 MLOADD [Braden] +224.0.1.20 any private experiment [JBP] +224.0.1.21 DVMRP on MOSPF [John Moy] +224.0.1.22 SVRLOC +224.0.1.23 XINGTV +224.0.1.24 microsoft-ds +224.0.1.25 nbc-pro +224.0.1.26 nbc-pfn +224.0.1.27-224.0.1.255 Unassigned [JBP] + + + +Reynolds & Postel [Page 57] + +RFC 1700 Assigned Numbers October 1994 + + +224.0.2.1 "rwho" Group (BSD) (unofficial) [JBP] +224.0.2.2 SUN RPC PMAPPROC_CALLIT [BXE1] + +224.0.3.000-224.0.3.255 RFE Generic Service [DXS3] +224.0.4.000-224.0.4.255 RFE Individual Conferences [DXS3] +224.0.5.000-224.0.5.127 CDPD Groups [Bob Brenner] +224.0.5.128-224.0.5.255 Unassigned [IANA] +224.0.6.000-224.0.6.127 Cornell ISIS Project [Tim Clark] +224.0.6.128-224.0.6.255 Unassigned [IANA] + +224.1.0.0-224.1.255.255 ST Multicast Groups [RFC1190,KS14] +224.2.0.0-224.2.255.255 Multimedia Conference Calls [SC3] + +224.252.0.0-224.255.255.255 DIS transient groups [Joel Snyder] + +232.0.0.0-232.255.255.255 VMTP transient groups [RFC1045,DRC3] + +These addresses are listed in the Domain Name Service under MCAST.NET +and 224.IN-ADDR.ARPA. + +Note that when used on an Ethernet or IEEE 802 network, the 23 +low-order bits of the IP Multicast address are placed in the low-order +23 bits of the Ethernet or IEEE 802 net multicast address +1.0.94.0.0.0. See the next section on "IANA ETHERNET ADDRESS BLOCK". + +REFERENCES + +[RFC1045] Cheriton, D., "VMTP: Versatile Message Transaction + Protocol Specification", RFC 1045, Stanford University, + February 1988. + +[RFC1075] Waitzman, D., C. Partridge, and S. Deering "Distance Vector + Multicast Routing Protocol", RFC-1075, BBN STC, Stanford + University, November 1988. + +[RFC1112] Deering, S., "Host Extensions for IP Multicasting", + STD 5, RFC 1112, Stanford University, August 1989. + +[RFC1119] Mills, D., "Network Time Protocol (Version 1), Specification + and Implementation", STD 12, RFC 1119, University of + Delaware, July 1988. + +[RFC1190] Topolcic, C., Editor, "Experimental Internet Stream + Protocol, Version 2 (ST-II)", RFC 1190, CIP Working Group, + October 1990. + +[RFC1583] Moy, J., "The OSPF Specification", RFC 1583, Proteon, + March 1994. + + + +Reynolds & Postel [Page 58] + +RFC 1700 Assigned Numbers October 1994 + + +PEOPLE + + + +[AXC] Andrew Cherenson + +[Bob Brenner] + + + +[Braden] Bob Braden + +[BXF] Bruce Factor + +[BXS2] Bill Schilit + +[CXM3] Chuck McManis + +[Tim Clark] + +[DLM1] David Mills + +[DRC3] Dave Cheriton + +[DXS3] Daniel Steinber + +[Dino Farinacci] + +[GSM11] Gary S. Malkin + + + +[IANA] IANA + +[JBP] Jon Postel + +[JXM1] Jim Miner + +[KS14] + +[Andrew Maffei] + +[John Moy] John Moy + +[MXF2] Martin Forssen + + + + +Reynolds & Postel [Page 59] + +RFC 1700 Assigned Numbers October 1994 + + +[Guido van Rossum] + +[SC3] Steve Casner + +[Joel Snyder] + +[SXA] Susie Armstrong + +[SXD] Steve Deering + + + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/multicast-addresses + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 60] + +RFC 1700 Assigned Numbers October 1994 + + +SUN RPC NUMBERS + + +To obtain SUN Remote Procedure Call (RPC) numbers send an e-mail +request to "rpc@sun.com". + +The RPC port management service ('portmap' in SunOS versions less than +5.0 and 'rpcbind' in SunOS versions greater than 5.0) "registers" the +IP port number that is allocated to a particular service when that +service is created. It does not allocate ports on behalf of those +services. + +For an exact specification of the semantics refer to the source code +of svcudp_create() and svctcp_create() in the archives. In short +however is that these interfaces, and svc_tli_create their Transport +Independent RPC equivalent, take either a user specified port number +or RPC_ANY (-1) which effectively means "I don't care." In the "I +don't care" case the create code simply calls socket(2) or t_open(3n) +which allocates an IP port based on the rules: + + if euid of the requesting process is 0 (i.e., root) + allocate the next available port number in the + reserved port range. + else + allocate the next available port in the non-reserved + range. + +Port numbers count up sequentially. + +Can a port that is "assigned" can be used when the assignee's service +is not present? Say port 501 is assigned to the "jeans" service. On +a machine that does not have the "jeans" service, nor has any clients +that might be expecting to use it, is port 501 available for other +uses? Any dynamic allocation process, like the portmapper, that +chooses the next unused port might allocate port 501 dynamically to a +process that asked for a "I don't care" port. So any dynamic +allocation scheme may pick an unused port that happened to correspond +to a port number that had been "assigned" but was currently unused. + +While it might be desirable, it is impossible to guarantee that any +unused port, even though officially assigned to a service, is not +picked by a dynamic allocator since such an assignment might occur +long after the delivery of the system into a site that doesn't watch +for the latest list. + +There is the restriction that only "superuser" on BSD derived systems +such as SunOS can bind to a port number that is less than 1024. So +programs have used this information in the past to identify whether or + + + +Reynolds & Postel [Page 61] + +RFC 1700 Assigned Numbers October 1994 + + +not the service they were talking to was started by the superuser on +the remote system. Making this assumption is dangerous because not +all system enforce this restriction. + +Sun RPC services use ports that are currently unused. If someone +noted that an RPC service was using port 781, it would be just as +happy using port 891, or 951. The service doesn't care what port it +gets, remote clients will query the portmapper to ask it what port +number was assigned to the service when it was started. The key is +that the port was not currently in use. The only port that ONC/RPC +must have is 111 its assigned port for the portmap service. + +The most common complaint comes when people put a new service on their +system. When they configure their systems they put the new service +configuration commands at the end of their system startup scripts. +During startup, several network services may be started. Those +services that are ONC/RPC based just pick the next available port, +those that have pre-assigned ports bind to their pre-assigned port. +Clearly the correct sequence is to have all services that need a +particular port to be started first (or if they are "latent" services +that are started by inetd, to have inetd started). Finally, the RPC +services should be started as they will be assigned unused ports. (In +the BSD networking code (which we use) the algorithm for picking +ports is in the file in_pcb.c, function in_pcbbind().) + +Services should be started in this order: + + a) Services that will "run" continuously and have an assigned + port. Note that this includes rpcbind (nee portmap) that has + port 111 assigned to it. + + b) inetd - which will automatically create sockets for those + services that have reserved ports but only run on demand + (like finger) + + c) RPC services - which will automatically pick unused ports and + maximize efficiency of the "IP Port" namespace. + +The include file /usr/include/netinet/in.h defines a constant +IPPORT_RESERVED to be 1024. The relevant text is: + + /* + * Ports < IPPORT_RESERVED are reserved for + * privileged processes (e.g. root). + * Ports > IPPORT_USERRESERVED are reserved + * for servers, not necessarily privileged. + */ + #define IPPORT_RESERVED 1024 + + + +Reynolds & Postel [Page 62] + +RFC 1700 Assigned Numbers October 1994 + + + #define IPPORT_USERRESERVED 5000 + +Portmap does not allocate ports, the kernel allocates ports. The code +that does this is part of nearly every UNIX system in the world (and +since the BSD code is 'free' it is often the same code). RPC services +ask the kernel to allocate them a port by calling the "bind()" system +call. The parameter they pass is "INADDR_ANY" which means "allocate +me any IP port you want". The kernel does that by looking at all of +the ports that are currently in use and picking one that is not +currently used. The number picked is either less that 1024 if the +process is privledged, or greater than 1024 if the process is not +privledged. After the kernel has allocated a port, the service +registers this allocation with portmap. The portmapper is merely a +registry of previously allocated ports. Note "allocated" here is +being used in the sense that they are used by an open socket, not +assigned a well known name. + +The role of /etc/services is to provide an idea to people who are +looking at network traffic as to where a packet may have originated +from or is headed to. For services like finger that have assigned +ports, they can just hard code the port they want into their +executable. (it isn't like it will change, and if they read it from +/etc/services and someone had mistyped the port number it won't +interoperate with clients anyway!) + +It is not practical to read the /etc/services file into the kernel to +prevent it from giving out port numbers that are "pre-assigned", nor +is it generally desirable since with the correct ordering of startup +it is completely unneccesary. + +Editors Note: This information was supplied by Chuck McManis of Sun. + +[] + + + + + + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/sun-rpc-numbers + + + + + + + + + + +Reynolds & Postel [Page 63] + +RFC 1700 Assigned Numbers October 1994 + + +IP OPTION NUMBERS + +The Internet Protocol (IP) has provision for optional header fields +identified by an option type field. Options 0 and 1 are exactly one +octet which is their type field. All other options have their one +octet type field, followed by a one octet length field, followed by +length-2 octets of option data. The option type field is sub-divided +into a one bit copied flag, a two bit class field, and a five bit +option number. These taken together form an eight bit value for the +option type field. IP options are commonly refered to by this value. + + +Copy Class Number Value Name Reference +---- ----- ------ ----- ------------------------------- --------- + 0 0 0 0 EOOL - End of Options List [RFC791,JBP] + 0 0 1 1 NOP - No Operation [RFC791,JBP] + 1 0 2 130 SEC - Security [RFC1108] + 1 0 3 131 LSR - Loose Source Route [RFC791,JBP] + 0 2 4 68 TS - Time Stamp [RFC791,JBP] + 1 0 5 133 E-SEC - Extended Security [RFC1108] + 1 0 6 134 CIPSO - Commercial Security [???] + 0 0 7 7 RR - Record Route [RFC791,JBP] + 1 0 8 136 SID - Stream ID [RFC791,JBP] + 1 0 9 137 SSR - Strict Source Route [RFC791,JBP] + 0 0 10 10 ZSU - Experimental Measurement [ZSu] + 0 0 11 11 MTUP - MTU Probe [RFC1191] + 0 0 12 12 MTUR - MTU Reply [RFC1191] + 1 2 13 205 FINN - Experimental Flow Control [Finn] + 1 0 14 142 VISA - Expermental Access Control [Estrin] + 0 0 15 15 ENCODE - ??? [VerSteeg] + 1 0 16 144 IMITD - IMI Traffic Descriptor [Lee] + 1 0 17 145 EIP - ??? [RFC1358] + 0 2 18 82 TR - Traceroute [RFC1393] + 1 0 19 147 ADDEXT - Address Extension [Ullmann IPv7] + + + +IP TIME TO LIVE PARAMETER + +The current recommended default time to live (TTL) for the +Internet Protocol (IP) [45,105] is 64. + + +IP TOS PARAMETERS + +This documents the default Type-of-Service values that are currently +recommended for the most important Internet protocols. + + + + +Reynolds & Postel [Page 64] + +RFC 1700 Assigned Numbers October 1994 + + +TOS Value Description Reference +--------- -------------------------- --------- + 0000 Default [RFC1349] + 0001 Minimize Monetary Cost [RFC1349] + 0010 Maximize Reliability [RFC1349] + 0100 Maximize Throughput [RFC1349] + 1000 Minimize Delay [RFC1349] + 1111 Maximize Security [RFC1455] + +The TOS value is used to indicate "better". Only one TOS value or +property can be requested in any one IP datagram. + +Generally, protocols which are involved in direct interaction with a +human should select low delay, while data transfers which may involve +large blocks of data are need high throughput. Finally, high reliability +is most important for datagram-based Internet management functions. + +Application protocols not included in these tables should be able to +make appropriate choice of low delay (8 decimal, 1000 binary) or high +throughput (4 decimal, 0100 binary). + +The following are recommended values for TOS: + + + ----- Type-of-Service Value ----- + +Protocol TOS Value + +TELNET (1) 1000 (minimize delay) + +FTP + Control 1000 (minimize delay) + Data (2) 0100 (maximize throughput) + +TFTP 1000 (minimize delay) + +SMTP (3) + Command phase 1000 (minimize delay) + DATA phase 0100 (maximize throughput) + +Domain Name Service + UDP Query 1000 (minimize delay) + TCP Query 0000 + Zone Transfer 0100 (maximize throughput) + +NNTP 0001 (minimize monetary cost) + +ICMP + + + +Reynolds & Postel [Page 65] + +RFC 1700 Assigned Numbers October 1994 + + + Errors 0000 + Requests 0000 (4) + Responses (4) + +Any IGP 0010 (maximize reliability) + +EGP 0000 + +SNMP 0010 (maximize reliability) + +BOOTP 0000 + +Notes: + +(1) Includes all interactive user protocols (e.g., rlogin). + +(2) Includes all bulk data transfer protocols (e.g., rcp). + +(3) If the implementation does not support changing the TOS +during the lifetime of the connection, then the +recommended TOS on opening the connection is the default +TOS (0000). + +(4) Although ICMP request messages are normally sent with +the default TOS, there are sometimes good reasons why they +would be sent with some other TOS value. An ICMP +response always uses the same TOS value as was used in the +corresponding ICMP request message. + +An application may (at the request of the user) substitute +0001 (minimize monetary cost) for any of the above values. + + +REFERENCES + +[RFC791] Postel, J., "Internet Protocol - DARPA Internet Program + Protocol Specification", STD 5, RFC 791, DARPA, September + 1981. + +[RFC1108] Kent, S., "U.S. Department of Defense Security Options for + the Internet Protocol", RFC 1108, BBN Communications, + November 1991. + +[RFC1191] Mogul, J., and S. Deering, "Path MTU Discovery", RFC 1191, + DECWRL, Stanford University, November 1990. + +[RFC1349] Almquist, P., "Type of Service in the Internet Protocol + Suite", RFC 1349, Consultant, July 1992. + + + +Reynolds & Postel [Page 66] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC1358] Chapin, L., Chair, "Charter of the Internet Architecture + Board (IAB)", RFC 1358, Internet Architecture Board, August + 1992. + +[RFC1393] Malkin, G., "Traceroute Using an IP Option", RFC 1393, + Xylogics, Inc., January 1993. + +[RFC1455] Eastlake, D., "Physical Link Security Type of Service", + RFC 1455, Digital Equipment Corporation, May 1993. + +[Ullmann IPv7] + + +PEOPLE + +[Estrin] Deborah Estrin + +[Finn] Greg Finn + +[JBP] Jon Postel + +[Ullmann] Robert Ullmann + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ip-parameters + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 67] + +RFC 1700 Assigned Numbers October 1994 + + +ICMP TYPE NUMBERS + +The Internet Control Message Protocol (ICMP) has many messages that +are identified by a "type" field. + +Type Name Reference +---- ------------------------- --------- + 0 Echo Reply [RFC792] + 1 Unassigned [JBP] + 2 Unassigned [JBP] + 3 Destination Unreachable [RFC792] + 4 Source Quench [RFC792] + 5 Redirect [RFC792] + 6 Alternate Host Address [JBP] + 7 Unassigned [JBP] + 8 Echo [RFC792] + 9 Router Advertisement [RFC1256] + 10 Router Selection [RFC1256] + 11 Time Exceeded [RFC792] + 12 Parameter Problem [RFC792] + 13 Timestamp [RFC792] + 14 Timestamp Reply [RFC792] + 15 Information Request [RFC792] + 16 Information Reply [RFC792] + 17 Address Mask Request [RFC950] + 18 Address Mask Reply [RFC950] + 19 Reserved (for Security) [Solo] + 20-29 Reserved (for Robustness Experiment) [ZSu] + 30 Traceroute [RFC1393] + 31 Datagram Conversion Error [RFC1475] + 32 Mobile Host Redirect [David Johnson] + 33 IPv6 Where-Are-You [Bill Simpson] + 34 IPv6 I-Am-Here [Bill Simpson] + 35 Mobile Registration Request [Bill Simpson] + 36 Mobile Registration Reply [Bill Simpson] + 37-255 Reserved [JBP] + +Many of these ICMP types have a "code" field. Here we list the types +again with their assigned code fields. + +Type Name Reference +---- ------------------------- --------- + 0 Echo Reply [RFC792] + + Codes + 0 No Code + + 1 Unassigned [JBP] + + + +Reynolds & Postel [Page 68] + +RFC 1700 Assigned Numbers October 1994 + + + 2 Unassigned [JBP] + + 3 Destination Unreachable [RFC792] + + Codes + 0 Net Unreachable + 1 Host Unreachable + 2 Protocol Unreachable + 3 Port Unreachable + 4 Fragmentation Needed and Don't Fragment was Set + 5 Source Route Failed + 6 Destination Network Unknown + 7 Destination Host Unknown + 8 Source Host Isolated + 9 Communication with Destination Network is + Administratively Prohibited + 10 Communication with Destination Host is + Administratively Prohibited + 11 Destination Network Unreachable for Type of Service + 12 Destination Host Unreachable for Type of Service + + 4 Source Quench [RFC792] + Codes + 0 No Code + + 5 Redirect [RFC792] + + Codes + 0 Redirect Datagram for the Network (or subnet) + 1 Redirect Datagram for the Host + 2 Redirect Datagram for the Type of Service and Network + 3 Redirect Datagram for the Type of Service and Host + + 6 Alternate Host Address [JBP] + + Codes + 0 Alternate Address for Host + + 7 Unassigned [JBP] + + 8 Echo [RFC792] + + Codes + 0 No Code + + 9 Router Advertisement [RFC1256] + + Codes + + + +Reynolds & Postel [Page 69] + +RFC 1700 Assigned Numbers October 1994 + + + 0 No Code + + 10 Router Selection [RFC1256] + + Codes + 0 No Code + + 11 Time Exceeded [RFC792] + + Codes + 0 Time to Live exceeded in Transit + 1 Fragment Reassembly Time Exceeded + + 12 Parameter Problem [RFC792] + + Codes + 0 Pointer indicates the error + 1 Missing a Required Option [RFC1108] + 2 Bad Length + + + 13 Timestamp [RFC792] + + Codes + 0 No Code + + 14 Timestamp Reply [RFC792] + + Codes + 0 No Code + + 15 Information Request [RFC792] + + Codes + 0 No Code + + 16 Information Reply [RFC792] + + Codes + 0 No Code + + 17 Address Mask Request [RFC950] + + Codes + 0 No Code + + 18 Address Mask Reply [RFC950] + + + + +Reynolds & Postel [Page 70] + +RFC 1700 Assigned Numbers October 1994 + + + Codes + 0 No Code + + 19 Reserved (for Security) [Solo] + + 20-29 Reserved (for Robustness Experiment) [ZSu] + + 30 Traceroute [RFC1393] + + 31 Datagram Conversion Error [RFC1475] + + 32 Mobile Host Redirect [David Johnson] + + 33 IPv6 Where-Are-You [Bill Simpson] + + 34 IPv6 I-Am-Here [Bill Simpson] + + 35 Mobile Registration Request [Bill Simpson] + + 36 Mobile Registration Reply [Bill Simpson] + +REFERENCES + +[RFC792] Postel, J., "Internet Control Message Protocol", STD 5, + RFC 792, USC/Information Sciences Institute, September 1981. + +[RFC950] Mogul, J., and J. Postel, "Internet Standard Subnetting + Procedure", STD 5, RFC 950, Stanford, USC/Information + Sciences Institute, August 1985. + +[RFC1108] Kent, S., "U.S. Department of Defense Security Options for + the Internet Protocol", RFC 1108, November 1991. + +[RFC1256] Deering, S., Editor, "ICMP Router Discovery Messages", RFC + 1256, Xerox PARC, September 1991. + +[RFC1393] Malkin, G., "Traceroute Using an IP Option", RFC 1393, + Xylogics, Inc., January 1993. + +[RFC1475] Ullmann, R., "TP/IX: The Next Internet", RFC 1475, Process + Software Corporation, June 1993. + + +PEOPLE + +[JBP] Jon Postel + +[David Johnson] + + + +Reynolds & Postel [Page 71] + +RFC 1700 Assigned Numbers October 1994 + + +[Bill Simpson] September, 1994. + +[Solo] + +[ZSu] Zaw-Sing Su + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/icmp-parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 72] + +RFC 1700 Assigned Numbers October 1994 + + +TCP OPTION NUMBERS + +The Transmission Control Protocol (TCP) has provision for optional +header fields identified by an option kind field. Options 0 and 1 are +exactly one octet which is their kind field. All other options have +their one octet kind field, followed by a one octet length field, +followed by length-2 octets of option data. + +Kind Length Meaning Reference +---- ------ ------------------------------- --------- + 0 - End of Option List [RFC793] + 1 - No-Operation [RFC793] + 2 4 Maximum Segment Lifetime [RFC793] + 3 3 WSOPT - Window Scale [RFC1323] + 4 2 SACK Permitted [RFC1072] + 5 N SACK [RFC1072] + 6 6 Echo (obsoleted by option 8) [RFC1072] + 7 6 Echo Reply (obsoleted by option 8)[RFC1072] + 8 10 TSOPT - Time Stamp Option [RFC1323] + 9 2 Partial Order Connection Permitted[RFC1693] + 10 5 Partial Order Service Profile [RFC1693] + 11 CC [Braden] + 12 CC.NEW [Braden] + 13 CC.ECHO [Braden] + 14 3 TCP Alternate Checksum Request [RFC1146] + 15 N TCP Alternate Checksum Data [RFC1146] + 16 Skeeter [Knowles] + 17 Bubba [Knowles] + 18 3 Trailer Checksum Option [Subbu & Monroe] + + +TCP ALTERNATE CHECKSUM NUMBERS + + +Number Description Reference +------- ------------------------------- ---------- + 0 TCP Checksum [RFC-1146] + 1 8-bit Fletchers's algorithm [RFC-1146] + 2 16-bit Fletchers's algorithm [RFC-1146] + 3 Redundant Checksum Avoidance [Kay] + + +REFERENCES + +[KAY] Kay, J. and Pasquale, J., "Measurement, Analysis, and + Improvement of UDP/IP Throughput for the DECstation 5000," + Proceedings of the Winter 1993 Usenix Conference, January 1993 + (available for anonymous FTP in + + + +Reynolds & Postel [Page 73] + +RFC 1700 Assigned Numbers October 1994 + + + ucsd.edu:/pub/csl/fastnet/fastnet.tar.Z). + +[RFC793] Postel, J., "Transmission Control Protocol - DARPA Internet + Program Protocol Specification", STD 7, RFC 793, DARPA, + September 1981. + +[RFC1323] Jacobson, V., Braden, R., and D. Borman, "TCP Extensions for + High Performance", RFC 1323, LBL, ISI, Cray Research, May + 1992. + +[RFC1072] Jacobson, V., and R. Braden, "TCP Extensions for Long-Delay + Paths", RFC 1072, LBL, ISI, October 1988. + +[RFC1693] ????? + +[RFC1146] Zweig, J., and C. Partridge, "TCP Alternate Checksum + Options", RFC 1146, UIUC, BBN, March 1990. + +PEOPLE + +[Braden] Bob Braden + +[Knowles] Stev Knowles + +[Kay] J. Kay + +[Subbu & Monroe] + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/tcp-parameters + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 74] + +RFC 1700 Assigned Numbers October 1994 + + +TELNET OPTIONS + +The Telnet Protocol has a number of options that may be negotiated. +These options are listed here. "Internet Official Protocol Standards" +(STD 1) provides more detailed information. + +Options Name References +------- ----------------------- ---------- + 0 Binary Transmission [RFC856,JBP] + 1 Echo [RFC857,JBP] + 2 Reconnection [NIC50005,JBP] + 3 Suppress Go Ahead [RFC858,JBP] + 4 Approx Message Size Negotiation [ETHERNET,JBP] + 5 Status [RFC859,JBP] + 6 Timing Mark [RFC860,JBP] + 7 Remote Controlled Trans and Echo [RFC726,JBP] + 8 Output Line Width [NIC50005,JBP] + 9 Output Page Size [NIC50005,JBP] + 10 Output Carriage-Return Disposition [RFC652,JBP] + 11 Output Horizontal Tab Stops [RFC653,JBP] + 12 Output Horizontal Tab Disposition [RFC654,JBP] + 13 Output Formfeed Disposition [RFC655,JBP] + 14 Output Vertical Tabstops [RFC656,JBP] + 15 Output Vertical Tab Disposition [RFC657,JBP] + 16 Output Linefeed Disposition [RFC657,JBP] + 17 Extended ASCII [RFC698,JBP] + 18 Logout [RFC727,MRC] + 19 Byte Macro [RFC735,JBP] + 20 Data Entry Terminal [RFC1043,RFC732,JBP] + 22 SUPDUP [RFC736,RFC734,MRC] + 22 SUPDUP Output [RFC749,MRC] + 23 Send Location [RFC779,EAK1] + 24 Terminal Type [RFC1091,MS56] + 25 End of Record [RFC885,JBP] + 26 TACACS User Identification [RFC927,BA4] + 27 Output Marking [RFC933,SXS] + 28 Terminal Location Number [RFC946,RN6] + 29 Telnet 3270 Regime [RFC1041,JXR] + 30 X.3 PAD [RFC1053,SL70] + 31 Negotiate About Window Size [RFC1073,DW183] + 32 Terminal Speed [RFC1079,CLH3] + 33 Remote Flow Control [RFC1372,CLH3] + 34 Linemode [RFC1184,DB14] + 35 X Display Location [RFC1096,GM23] + 36 Environment Option [RFC1408,DB14] + 37 Authentication Option [RFC1409,DB14] + 38 Encryption Option [DB14] + 39 New Environment Option [RFC1572,DB14] + + + +Reynolds & Postel [Page 75] + +RFC 1700 Assigned Numbers October 1994 + + + 40 TN3270E [RFC1647] + 255 Extended-Options-List [RFC861,JBP] + +Telnet Authentication Types + +In [RFC1409], a list of authentication types is introduced. Additions +to the list are registerd by the IANA and documented here. + +Type Description Reference + 0 NULL [RFC1409] + 1 KERBEROS_V4 [RFC1409] + 2 KERBEROS_V5 [RFC1409] + 3 SPX [RFC1409] + 4-5 Unassigned + 6 RSA [RFC1409] + 7-9 Unassigned + 10 LOKI [RFC1409] + 11 SSA [Schoch] + +REFERENCES + +[ETHERNET] "The Ethernet, A Local Area Network: Data Link Layer and + Physical Layer Specification", AA-K759B-TK, Digital + Equipment Corporation, Maynard, MA. Also as: "The + Ethernet - A Local Area Network", Version 1.0, Digital + Equipment Corporation, Intel Corporation, Xerox + Corporation, September 1980. And: "The Ethernet, A Local + Area Network: Data Link Layer and Physical Layer + Specifications", Digital, Intel and Xerox, November 1982. + And: XEROX, "The Ethernet, A Local Area Network: Data Link + Layer and Physical Layer Specification", X3T51/80-50, Xerox + Corporation, Stamford, CT., October 1980. + +[NIC50005] DDN Protocol Handbook, "Telnet Reconnection Option", + "Telnet Output Line Width Option", "Telnet Output Page Size + Option", NIC 50005, December 1985. + +[RFC652] Crocker, D., "Telnet Output Carriage-Return Disposition + Option", RFC 652, UCLA-NMC, October 1974. + +[RFC653] Crocker, D., "Telnet Output Horizontal Tabstops Option", + RFC 653, UCLA-NMC, October 1974. + +[RFC654] Crocker, D., "Telnet Output Horizontal Tab Disposition + Option", RFC 654, UCLA-NMC, October 1974. + +[RFC655] Crocker, D., "Telnet Output Formfeed Disposition Option", + RFC 655, UCLA-NMC, October 1974. + + + +Reynolds & Postel [Page 76] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC656] Crocker, D., "Telnet Output Vertical Tabstops Option", + RFC 656, UCLA-NMC, October 1974. + +[RFC657] Crocker, D., "Telnet Output Vertical Tab Disposition Option", + RFC 657, UCLA-NMC, October 1974. + +[RFC658] Crocker, D., "Telnet Output Linefeed Disposition", RFC 658, + UCLA-NMC, October 1974. + +[RFC698] Tovar, "Telnet Extended ASCII Option", RFC 698, Stanford + University-AI, July 1975. + +[RFC726] Postel, J. and D. Crocker, "Remote Controlled Transmission + and Echoing Telnet Option", RFC 726, SRI-ARC, UC Irvine, + March 1977. + +[RFC727] Crispin, M., "Telnet Logout Option", RFC 727, Stanford + University-AI, April 1977. + +[RFC734] Crispin, M., "SUPDUP Protocol", RFC 734, Stanford, + October 1977. + +[RFC735] Crocker, D. and R. Gumpertz, "Revised Telnet Byte Marco + Option", RFC 735, Rand, CMU, November 1977. + +[RFC736] Crispin, M., "Telnet SUPDUP Option", Stanford University-AI, + RFC 736, Stanford, October 1977. + +[RFC749] Greenberg, B., "Telnet SUPDUP-OUTPUT Option", RFC 749, + MIT-Multics, September 1978. + +[RFC779] Killian, E., "Telnet Send-Location Option", RFC 779, + LLL, April 1981. + +[RFC856] Postel, J. and J. Reynolds, "Telnet Binary Transmission", + STD 27, RFC 856, USC/Information Sciences Institute, May + 1983. + +[RFC857] Postel, J. and J. Reynolds, "Telnet Echo Option", STD 28, RFC + 857, USC/Information Sciences Institute, May 1983. + +[RFC858] Postel, J. and J. Reynolds, "Telnet Suppress Go Ahead + Option", STD 29, RFC 858, USC/Information Sciences Institute, + May 1983. + +[RFC859] Postel, J. and J. Reynolds, "Telnet Status Option", STD 30, + RFC 859, USC/Information Sciences Institute, May 1983. + + + + +Reynolds & Postel [Page 77] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC860] Postel, J. and J. Reynolds, "Telnet Timing Mark Option", + STD 31, RFC 860, USC/Information Sciences Institute, May + 1983. + +[RFC861] Postel, J. and J. Reynolds, "Telnet Extended Options - List + Option", STD 32, RFC 861, USC/Information Sciences Institute, + May 1983. + +[RFC885] Postel, J., "Telnet End of Record Option", RFC 885, + USC/Information Sciences Institute, December 1983. + +[RFC927] Anderson, B., "TACACS User Identification Telnet Option", + RFC 927, BBN, December 1984. + +[RFC933] Silverman, S., "Output Marking Telnet Option", RFC 933, + MITRE, January 1985. + +[RFC946] Nedved, R., "Telnet Terminal Location Number Option", + RFC 946, Carnegie-Mellon University, May 1985. + +[RDC1041] Rekhter, J., "Telnet 3270 Regime Option", RFC 1041, + IBM, January 1988. + +[RFC1043] Yasuda, A., and T. Thompson, "TELNET Data Entry Terminal + Option DODIIS Implementation", RFC 1043, DIA, February 1988. + +[RFC1053] Levy, S., and T. Jacobson, "Telnet X.3 PAD Option", + RFC 1053, Minnesota Supercomputer Center, April 1988. + +[RFC1073] Waitzman, D., "Telnet Window Size Option", RFC 1073, + BBN STC, October, 1988. + +[RFC1079] Hedrick, C., "Telnet Terminal Speed Option", RFC 1079, + Rutgers University, December 1988. + +[RFC1091] VanBokkelen, J., "Telnet Terminal Type Option", + RFC 1091, FTP Software, Inc., February 1989. + +[RFC1096] Marcy, G., "Telnet X Display Location Option", RFC 1096, + Carnegie Mellon University, March 1989. + +[RFC1184] Borman, D., Editor, "Telnet Linemode Option", + RFC 1184, Cray Research, Inc., October 1990. + +[RFC1372] Hedrick, C., and D. Borman, "Telnet Remote Flow Control + Option", RFC 1372, Rutgers University, Cray Research, Inc., + October 1992. + + + + +Reynolds & Postel [Page 78] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC1408] Borman, D., Editor, "Telnet Environment Option", RFC 1408, + Cray Research, Inc., January 1993. + +[RFC1409] Borman, D., Editor, "Telnet Authentication Option", RFC + 1409, Cray Research, Inc., January 1993. + +[RFC1572] Alexander, S., Editor, "Telnet Environment Option", RFC1572, + Lachman Technology, Inc., January 1994. + +[RFC1647] Kelly, B., "TN3270 Enhancements", RFC1647, Auburn + University, July 1994. + + +PEOPLE + +[BA4] Brian Anderson + +[CLH3] Charles Hedrick + +[DB14] Dave Borman + +[DW183] David Waitzman + +[EAK4] Earl Kill + +[GM23] Glenn Marcy + +[JBP] Jon Postel + +[MRC] Mark Crispin + +[MS56] Marvin Solomon + +[RN6] Rudy Nedved + +[Schoch] Steven Schoch + +[SL70] Stuart Levy + +[SXS] Steve Silverman + +[YXR] Yakov Rekhter + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/telnet-options + + + + +Reynolds & Postel [Page 79] + +RFC 1700 Assigned Numbers October 1994 + + +DOMAIN NAME SYSTEM PARAMETERS + +The Internet Domain Naming System (DOMAIN) includes several +parameters. These are documented in [RFC1034] and [RFC1035]. The +CLASS parameter is listed here. The per CLASS parameters are defined +in separate RFCs as indicated. + +Domain System Parameters: + +Decimal Name References +-------- ---- ---------- + 0 Reserved [PM1] + 1 Internet (IN) [RFC1034,PM1] + 2 Unassigned [PM1] + 3 Chaos (CH) [PM1] + 4 Hessoid (HS) [PM1] + 5-65534 Unassigned [PM1] + 65535 Reserved [PM1] + +In the Internet (IN) class the following TYPEs and QTYPEs are defined: + +TYPE value and meaning + +A 1 a host address [RFC1035] +NS 2 an authoritative name server [RFC1035] +MD 3 a mail destination (Obsolete - use MX) [RFC1035] +MF 4 a mail forwarder (Obsolete - use MX) [RFC1035] +CNAME 5 the canonical name for an alias [RFC1035] +SOA 6 marks the start of a zone of authority [RFC1035] +MB 7 a mailbox domain name (EXPERIMENTAL) [RFC1035] +MG 8 a mail group member (EXPERIMENTAL) [RFC1035] +MR 9 a mail rename domain name (EXPERIMENTAL)[RFC1035] +NULL 10 a null RR (EXPERIMENTAL) [RFC1035] +WKS 11 a well known service description [RFC1035] +PTR 12 a domain name pointer [RFC1035] +HINFO 13 host information [RFC1035] +MINFO 14 mailbox or mail list information [RFC1035] +MX 15 mail exchange [RFC1035] +TXT 16 text strings [RFC1035] + +RP 17 for Responsible Person [RFC1183] +AFSDB 18 for AFS Data Base location [RFC1183] +X25 19 for X.25 PSDN address [RFC1183] +ISDN 20 for ISDN address [RFC1183] +RT 21 for Route Through [RFC1183] + +NSAP 22 for NSAP address, NSAP style A record [RFC1348] +NSAP-PTR 23 for domain name pointer, NSAP style [RFC1348] + + + +Reynolds & Postel [Page 80] + +RFC 1700 Assigned Numbers October 1994 + + +SIG 24 for security signature [Donald Eastlake] +KEY 25 for security key [Donald Eastlake] + +PX 26 X.400 mail mapping information [RFC1664] + +GPOS 27 Geographical Position [Craig Farrell] + +AAAA 28 IP6 Address [Susan Thomson] + +AXFR 252 transfer of an entire zone [RFC1035] +MAILB 253 mailbox-related RRs (MB, MG or MR) [RFC1035] +MAILA 254 mail agent RRs (Obsolete - see MX) [RFC1035] +* 255 A request for all records [RFC1035] + + +REFERENCES + +[RFC1034] Mockapetris, P., "Domain Names - Concepts and + Facilities", STD 13, RFC 1034, USC/Information Sciences + Institute, November 1987. + +[RFC1035] Mockapetris, P., "Domain Names - Implementation and + Specification", STD 13, RFC 1035, USC/Information Sciences + Institute, November 1987. + +[RFC1183] Everhart, C., Mamakos, L., Ullmann, R., and P. Mockapetris, + Editors, "New DNS RR Definitions", RFC 1183, Transarc, + University of Maryland, Prime Computer, USC/Information + Sciences Institute, October 1990. + +[RFC1348] Manning, B., "DNS NSAP RRs", RFC 1348, Rice University, + July 1992. + +[RFC1664] Allocchio, C., Bonito, A., Cole, B., Giordano, S., and R. + Hagens, "Using the Internet DNS to Distribute RFC1327 Mail + Address Mapping Tables", GARR-Italy, Cisco Systems Inc., + Centro Svizzero Calcolo Scientifico, Advanced Network & + Services, August 1994. + + +PEOPLE + +[Susan Thomson] Susan Thomson + +[PM1] Paul Mockapetris + +[Donald Eastlake] Donald E. Eastlake, III + + + + +Reynolds & Postel [Page 81] + +RFC 1700 Assigned Numbers October 1994 + + +[Craig Farrell] + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 82] + +RFC 1700 Assigned Numbers October 1994 + + +MAIL ENCODING HEADER FIELD KEYWORDS + + +[RFC1505] specifies an initial list of keywords for the experimental +encoding header field (EHF-MAIL), and provides that additional +keywords may be registered with the IANA. + + +Keyword Description Reference +_______ ___________ ____________ + +EDIFACT EDIFACT format [RFC1505] +EDI-X12 EDI X12 format [ANSI-X12] +EVFU FORTRAN format [RFC1505] +FS File System format [RFC1505] +Hex Hex binary format [RFC1505] +LZJU90 LZJU90 format [RFC1505] +LZW LZW format [RFC1505] +Message Encapsulated Message [RFC822] +PEM, PEM-Clear Privacy Enhanced Mail [RFC1421] +PGP Pretty Good Privacy [RFC1505] +Postscript Postscript format [POSTSCRIPT] +Shar Shell Archive format [RFC1505] +Signature Signature [RFC1505] +Tar Tar format [RFC1505] +Text Text [IS-10646] +uuencode uuencode format [RFC1505] +URL external URL-reference [RFC1505] + + + +MAIL ENCRYPTION TYPES + + +[RFC822] specifies that Encryption Types for mail may be assigned. +There are currently no RFC 822 encryption types assigned. Please use +instead the Mail Privacy procedures defined in [RFC1421, RFC1422, +RFC1423]. + + +ESMTP MAIL KEYWORDS + + +[RFC1651] specifies that extension to SMTP can be identified with +keywords. + + +Keywords Description Reference + + + +Reynolds & Postel [Page 83] + +RFC 1700 Assigned Numbers October 1994 + + +------------ -------------------------------- --------- +SEND Send as mail [RFC821] +SOML Send as mail or terminal [RFC821] +SAML Send as mail and terminal [RFC821] +EXPN Expand the mailing list [RFC821] +HELP Supply helpful information [RFC821] +TURN Turn the operation around [RFC821] +8BITMIME Use 8-bit data [RFC1652] +SIZE Message size declaration [RFC1653] +VERB Verbose [Eric Allman] +ONEX One message transaction only [Eric Allman] + + + +MAIL EXTENSION TYPES + + +The Simple Mail Transfer Protocol [RFC821] specifies a set of +commands or services for mail transfer. A general procedure for +extending the set of services is defined in [RFC1651]. The set of +service extensions is listed here. + + +Service Ext EHLO Keyword Parameters Verb Reference +----------- ------------ ---------- ---------- --------- +Send SEND none SEND [RFC821] +Send or Mail SOML none SOML [RFC821] +Send and Mail SAML none SAML [RFC821] +Expand EXPN none EXPN [RFC821] +Help HELP none HELP [RFC821] +Turn TURN none TURN [RFC821] +8 Bit MIME 8BITMIME none none [RFC1652] +Size SIZE number none [RFC1653] + + + +MAIL SYSTEM NAMES + + +In some places, an identification of other mail systems is used. + +One of these is in "The COSINE and Internet X.500 Schema" (section +9.3.18) [RFC1274]. The mail system names listed here are used as the +legal values in that schema under the "otherMailbox" attribute +"mailboxType" type (which must be a PrintableString). + +Another place is in "Mapping between X.400(1988) / ISO 10021 and RFC +822" (section 4.2.2) [RFC1327]. The names listed here are used as + + + +Reynolds & Postel [Page 84] + +RFC 1700 Assigned Numbers October 1994 + + +the legal values in that schema under the "std-or-address" attribute +"registered-dd-type" type (which must be a "key-string"). + +Note that key-string = . + + +Mail System Name Description Reference +---------------- ------------------------------- --------- +mcimail MCI Mail + + + +MAIL TRANSMISSION TYPES + + +The Simple Mail Transfer Protocol [RFC821] and the Standard for the +Format of ARPA Internet Text Messages [RFC822] specify that a set of +"Received" lines will be prepended to the headers of electronic mail +messages as they are transported through the Internet. These received +line may optionally include either or both a "via" phrase and/or a +"with" phrase. The legal values for the phrases are listed here. The +via phrase is intended to indicate the link or physical medium over +which the message was transferred. The with phrase is intended to +indicate the protocol or logical process that was used to transfer the +message. + + +VIA link types Description Reference +-------------- ---------------------------- --------- +UUCP Unix-to-Unix Copy Program [???] + + +WITH protocol types Description Reference +------------------- ---------------------------- --------- +SMTP Simple Mail Transfer Protocol [RFC821] +ESMTP SMTP with Service Extensions [RFC1651] + + +REFERENCES + + +[ANSI-X12] + +[POSTSCRIPT] Adobe Systems Inc., "PostScript Langpuage Reference +Manual", 2nd Edition, 2nd Printing, January 1991. + +[IS-10646] + + + + +Reynolds & Postel [Page 85] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC821] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, + USC/Information Sciences Institute, August 1982. + +[RFC822] Crocker, D., "Standard for the Format of ARPA-Internet Text + Messages", STD 11, RFC 822, UDEL, August 1982. + +[RFC1274] Barker, P., and S. Kille, "The COSINE and Internet X.500 + Schema", RFC 1274, University College London, November 1991. + +[RFC1327] Hardcastle-Kille, S., "Mapping between X.400(1988) / ISO + 10021 and RFC 822", RFC 1327, University College London, + May 1992. + +[RFC1421] Linn, J., "Privacy Enhancement for Internet Electronic + Mail: Part I: Message Encipherment and Authentication + Procedures", RFC 1421, IAB IRTF PSRG, IETF PEM WG, + February 1993. + +[RFC1422] Kent, S., "Privacy Enhancement for Internet + Electronic Mail: Part II -- Certificate-Based Key + Management", BBN, IAB IRTF PSRG, IETF PEM, February 1993. + +[RFC1423] Balenson, D., "Privacy Enhancement for Internet Electronic + Mail: Part III -- Algorithms, Modes, and Identifiers", + RFC 1423, TIS, IAB IRTF PSRG, IETF PEM WG, February 1993. + +[RFC1505] Costanzo, A., Robinson, D., and R. Ullmann, "Encoding Header + Field for Internet Messages", RFC 1505, AKC Consulting, + Computervision Corporation, August 1993. + +[RFC1651] Klensin, J., Freed, N., Rose, M., Stefferud, E., and D. + Crocker, "SMTP Service Extensions", RFC 1651, MCI, Innosoft, + Dover Beach Consulting, Inc., Network Management Associates, + Inc., Silicon Graphics, Inc., July 1994. + +[RFC1652] Klensin, J., Freed, N., Rose, M., Stefferud, E., and D. + Crocker, "SMTP Service Extension for 8bit-MIMEtransport", + RFC 1652, MCI, Innosoft, Dover Beach Consulting, Inc., + Network Management Associates, Inc., Silicon Graphics, Inc., + July 1994. + +[RFC1653] Klensin, J., Freed, N., and K. Moore, "SMTP Service + Extension for Message Size Declaration", RFC 1653, + MCI, Innosoft, University of Tennessee, July 1994. + + +PEOPLE + + + + +Reynolds & Postel [Page 86] + +RFC 1700 Assigned Numbers October 1994 + + +[Eric Allman] + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/mail-parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 87] + +RFC 1700 Assigned Numbers October 1994 + + +BOOTP AND DHCP PARAMETERS + +The Bootstrap Protocol (BOOTP) [RFC951] describes an IP/UDP +bootstrap protocol (BOOTP) which allows a diskless client machine to +discover its own IP address, the address of a server host, and the +name of a file to be loaded into memory and executed. The Dynamic +Host Configuration Protocol (DHCP) [RFC1531] provides a framework for +automatic configuration of IP hosts. The "DHCP Options and BOOTP +Vendor Information Extensions" [RFC1533] describes the additions to the +Bootstrap Protocol (BOOTP) which can also be used as options with the +Dynamic Host Configuration Protocol (DHCP). + +BOOTP Vendor Extensions and DHCP Options are listed below: + + + Tag Name Data Length Meaning + --- ---- ----------- ------- + 0 Pad 0 None + 1 Subnet Mask 4 Subnet Mask Value + 2 Time Offset 4 Time Offset in + Seconds from UTC + 3 Gateways N N/4 Gateway addresses + 4 Time Server N N/4 Timeserver addresses + 5 Name Server N N/4 IEN-116 Server addresses + 6 Domain Server N N/4 DNS Server addresses + 7 Log Server N N/4 Logging Server addresses + 8 Quotes Server N N/4 Quotes Server addresses + 9 LPR Server N N/4 Printer Server addresses + 10 Impress Server N N/4 Impress Server addresses + 11 RLP Server N N/4 RLP Server addresses + 12 Hostname N Hostname string + 13 Boot File Size 2 Size of boot file in 512 byte + chunks + 14 Merit Dump File Client to dump and name + the file to dump it to + 15 Domain Name N The DNS domain name of the + client + 16 Swap Server N Swap Server addeess + 17 Root Path N Path name for root disk + 18 Extension File N Path name for more BOOTP info + + 19 Forward On/Off 1 Enable/Disable IP Forwarding + 20 SrcRte On/Off 1 Enable/Disable Source Routing + 21 Policy Filter N Routing Policy Filters + 22 Max DG Assembly 2 Max Datagram Reassembly Size + 23 Default IP TTL 1 Default IP Time to Live + 24 MTU Timeout 4 Path MTU Aging Timeout + 25 MTU Plateau N Path MTU Plateau Table + + + +Reynolds & Postel [Page 88] + +RFC 1700 Assigned Numbers October 1994 + + + 26 MTU Interface 2 Interface MTU Size + 27 MTU Subnet 1 All Subnets are Local + 28 Broadcast Address 4 Broadcast Address + 29 Mask Discovery 1 Perform Mask Discovery + 30 Mask Supplier 1 Provide Mask to Others + 31 Router Discovery 1 Perform Router Discovery + 32 Router Request 4 Router Solicitation Address + 33 Static Route N Static Routing Table + 34 Trailers 1 Trailer Encapsulation + 35 ARP Timeout 4 ARP Cache Timeout + 36 Ethernet 1 Ethernet Encapsulation + 37 Default TCP TTL 1 Default TCP Time to Live + 38 Keepalive Time 4 TCP Keepalive Interval + 39 Keepalive Data 1 TCP Keepalive Garbage + 40 NIS Domain N NIS Domain Name + 41 NIS Servers N NIS Server Addresses + 42 NTP Servers N NTP Server Addresses + 43 Vendor Specific N Vendor Specific Information + 44 NETBIOS Name Srv N NETBIOS Name Servers + 45 NETBIOS Dist Srv N NETBIOS Datagram Distribution + 46 NETBIOS Note Type 1 NETBIOS Note Type + 47 NETBIOS Scope N NETBIOS Scope + 48 X Window Font N X Window Font Server + 49 X Window Manmager N X Window Display Manager + 50 Address Request 4 Requested IP Address + 51 Address Time 4 IP Address Lease Time + 52 Overload 1 Overloaf "sname" or "file" + 53 DHCP Msg Type 1 DHCP Message Type + 54 DHCP Server Id 4 DHCP Server Identification + 55 Parameter List N Parameter Request List + 56 DHCP Message N DHCP Error Message + 57 DHCP Max Msg Size 2 DHCP Maximum Message Size + 58 Renewal Time 4 DHCP Renewal (T1) Time + 59 Rebinding Time 4 DHCP Rebinding (T2) Time + 60 Class Id N Class Identifier + 61 Client Id N Client Identifier + 62 Netware/IP Domain N Netware/IP Domain Name + 63 Netware/IP Option N Netware/IP sub Options + + + 64-127 Unassigned + 128-154 Reserved + + 255 End 0 None + + +REFERENCES + + + + +Reynolds & Postel [Page 89] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC951] Croft, B., and J. Gilmore, "BOOTSTRAP Protocol (BOOTP)", + RFC-951, Stanford and SUN Microsytems, September 1985. + +[RFC1531] Droms, R., "Dynamic Host Configuration Protocol", Bucknell + University, October 1993. + +[RFC1533] Alexander, S., and R. Droms, "DHCP Options and BOOTP Vendor + Extensions", Lachman Technology, Inc., Bucknell University, + October 1993. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/bootp-and-dhcp- +parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 90] + +RFC 1700 Assigned Numbers October 1994 + + +ADDRESS FAMILY NUMBERS + +Several protocols deal with multiple address families. The 16-bit +assignments are listed here. + + +Number Description Reference +------ ---------------------------------------------------- --------- + 0 Reserved + 1 IP (IP version 4) + 2 IP6 (IP version 6) + 3 NSAP + 4 HDLC (8-bit multidrop) + 5 BBN 1822 + 6 802 (includes all 802 media plus Ethernet "canonical format") + 7 E.163 + 8 E.164 (SMDS, Frame Relay, ATM) + 9 F.69 (Telex) + 10 X.121 (X.25, Frame Relay) + 11 IPX + 12 Appletalk + 13 Decnet IV + 14 Banyan Vines + 65535 Reserved + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/address-family-numbers + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 91] + +RFC 1700 Assigned Numbers October 1994 + + +FOOBAR AF NUMBERS + + +In the FTP Operation Over Big Address Records (FOOBAR) Protocol +[RFC1639] there is a field, called "address family" or "af", to +identify the lower level protocol addresses in use. This is an 8 bit +field. The first 16 assignments (0-15) of the af value are exactly +the same as the IP Version number. The assignment for values 16-255 +are listed here. + +Assigned FOOBAR Address Families + +Decimal Keyword Address Family References +------- ------- -------------- ---------- + 16 IPX Novell IPX +17-254 Unassigned + 255 Reserved + + +REFERENCES + +[RFC1639] Piscitello, D., "FTP Operation Over Big Address Records + (FOOBAR)", Core Competence, Inc., June 1994. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/foobar-af-numbers + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 92] + +RFC 1700 Assigned Numbers October 1994 + + +DIRECTORY SYSTEM NAMES + + +In the representation of distinquished names (and possibly other +contexts) of the X.500 Directory system, several unique keywords may +be necessary. For example, in the string representation of +distinguished names [RFC1485]. + +Keyword Attribute (X.520 keys) +------- --------------------------------- + CN CommonName + L LocalityName + ST StateOrProvinceName + O OrganizationName + OU OrganizationalUnitName + C CountryName + + +REFERENCES + +[RFC1485] Hardcastle-Kille, S., "A String Representation of + Distinguished Names (OSI-DS 23 (v5))", RFC1485, ISODE + Consortium, July 1993. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/directory-system-names + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 93] + +RFC 1700 Assigned Numbers October 1994 + + +PUBLISHER IDENTIFICATION CODE + +The RFC "A Format for E-Mailing Bibliographic Records" [RFC1357] +establishs a "publisher-ID" code. The IANA registry of these codes is +listed here. + + +Code Publisher Reference +------ ------------------------------------------------------- --------- +DUMMY for testing only [RFC1357] +TEST for testing only [RFC1357] +ISI Information Sciences Institute [JBP] + of the University of Southern California +UMCS University of Manchester Computer Science Department [TXC] + + +REFERENCES + +[RFC1357] Cohen, D., Editor, "A Format for E-mailing Bibliographic + Records", RFC 1357, USC/Information Sciences Institute, + July 1992. + +PEOPLE + +[JBP] Jon Postel + +[TXC] Tim Clement + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/publisher-id + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 94] + +RFC 1700 Assigned Numbers October 1994 + + +OSPF AUTHENTICATION CODES + + +The Open Shotrest Path First (OSPF) protocols has a provision for +authentication, and the type of authentication can me indicated by a +code number. The following are the registered authentication codes. + + +Code Authentication Method Reference +---- --------------------- --------- + 0 No Authentication [RFC1583] + 1 Simple Password Authentication [RFC1583] +2-65535 Reserved + + +REFERENCES + +[RFC1583] Moy, J., "OSPF Version 2", RFC 1583, Proteon, Inc., March + 1994. + +[RFC1584] Moy, J., "Multicast Extensions to OSPF", RFC 1584, Proteon, + Inc., March 1994. + +[RFC1585] Moy, J., "MOSPF: Analysis and Experience", RFC 1585, + Proteon, Inc., March 1994. + +[RFC1586] deSouza, O., and M. Rodrigues, "Guidelines for Running OSPF + Over Frame Relay Networks", RFC 1586, AT&T Bell + Laboratories, March 1994. + +[RFC1587] Coltun, R., and V. Fuller, "The OSPF NSSA Option", RFC 1587, + RainbowBridge Communications, BARRNet, March 1994. + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ospf-authentication- +codes + + + + + + + + + + + + +Reynolds & Postel [Page 95] + +RFC 1700 Assigned Numbers October 1994 + + +MEDIA TYPES + + +[RFC1521] specifies that Content Types, Content Subtypes, Character +Sets, Access Types, and Conversion values for MIME mail will be +assigned and listed by the IANA. + + +Content Types and Subtypes +-------------------------- + +Type Subtype Description Reference +---- ------- ----------- --------- +text plain [RFC1521,NSB] + richtext [RFC1521,NSB] + tab-separated-values [Paul Lindner] + +multipart mixed [RFC1521,NSB] + alternative [RFC1521,NSB] + digest [RFC1521,NSB] + parallel [RFC1521,NSB] + appledouble [MacMime,Patrik Faltstrom] + header-set [Dave Crocker] + +message rfc822 [RFC1521,NSB] + partial [RFC1521,NSB] + external-body [RFC1521,NSB] + news [RFC 1036, Henry Spencer] + +application octet-stream [RFC1521,NSB] + postscript [RFC1521,NSB] + oda [RFC1521,NSB] + atomicmail [atomicmail,NSB] + andrew-inset [andrew-inset,NSB] + slate [slate,terry crowley] + wita [Wang Info Transfer,Larry Campbell] + dec-dx [Digital Doc Trans, Larry Campbell] + dca-rft [IBM Doc Content Arch, Larry Campbell] + activemessage [Ehud Shapiro] + rtf [Paul Lindner] + applefile [MacMime,Patrik Faltstrom] + mac-binhex40 [MacMime,Patrik Faltstrom] + news-message-id [RFC1036, Henry Spencer] + news-transmission [RFC1036, Henry Spencer] + wordperfect5.1 [Paul Lindner] + pdf [Paul Lindner] + zip [Paul Lindner] + macwriteii [Paul Lindner] + + + +Reynolds & Postel [Page 96] + +RFC 1700 Assigned Numbers October 1994 + + + msword [Paul Lindner] + remote-printing [RFC1486,MTR] + +image jpeg [RFC1521,NSB] + gif [RFC1521,NSB] + ief Image Exchange Format [RFC1314] + tiff Tag Image File Format [MTR] + +audio basic [RFC1521,NSB] + +video mpeg [RFC1521,NSB] + quicktime [Paul Lindner] + +The "media-types" directory contains a subdirectory for each content +type and each of those directories contains a file for each content +subtype. + + |-application- + |-audio------- + |-image------- + |-media-types-|-message----- + |-multipart--- + |-text-------- + |-video------- + + URL = ftp://ftp.isi.edu/in-notes/iana/assignments/media-types + + +Character Sets +-------------- + +All of the character sets listed the section on Character Sets are +registered for use with MIME as MIME Character Sets. The +correspondance between the few character sets listed in the MIME +specification [RFC1521] and the list in that section are: + +Type Description Reference +---- ----------- --------- +US-ASCII see ANSI_X3.4-1968 below [RFC1521,NSB] +ISO-8859-1 see ISO_8859-1:1987 below [RFC1521,NSB] +ISO-8859-2 see ISO_8859-2:1987 below [RFC1521,NSB] +ISO-8859-3 see ISO_8859-3:1988 below [RFC1521,NSB] +ISO-8859-4 see ISO_8859-4:1988 below [RFC1521,NSB] +ISO-8859-5 see ISO_8859-5:1988 below [RFC1521,NSB] +ISO-8859-6 see ISO_8859-6:1987 below [RFC1521,NSB] +ISO-8859-7 see ISO_8859-7:1987 below [RFC1521,NSB] +ISO-8859-8 see ISO_8859-8:1988 below [RFC1521,NSB] +ISO-8859-9 see ISO_8859-9:1989 below [RFC1521,NSB] + + + +Reynolds & Postel [Page 97] + +RFC 1700 Assigned Numbers October 1994 + + +Access Types +------------ + +Type Description Reference +---- ----------- --------- +FTP [RFC1521,NSB] +ANON-FTP [RFC1521,NSB] +TFTP [RFC1521,NSB] +AFS [RFC1521,NSB] +LOCAL-FILE [RFC1521,NSB] +MAIL-SERVER [RFC1521,NSB] + + + +Conversion Values +----------------- + +Conversion values or Content Transfer Encodings. + +Type Description Reference +---- ----------- --------- +7BIT [RFC1521,NSB] +8BIT [RFC1521,NSB] +BASE64 [RFC1521,NSB] +BINARY [RFC1521,NSB] +QUOTED-PRINTABLE [RFC1521,NSB] + + +MIME / X.400 MAPPING TABLES + +MIME to X.400 Table + + MIME content-type X.400 Body Part Reference + ----------------- ------------------ --------- + text/plain + charset=us-ascii ia5-text [RFC1494] + charset=iso-8859-x EBP - GeneralText [RFC1494] + text/richtext no mapping defined [RFC1494] + application/oda EBP - ODA [RFC1494] + application/octet-stream bilaterally-defined [RFC1494] + application/postscript EBP - mime-postscript-body [RFC1494] + image/g3fax g3-facsimile [RFC1494] + image/jpeg EBP - mime-jpeg-body [RFC1494] + image/gif EBP - mime-gif-body [RFC1494] + audio/basic no mapping defined [RFC1494] + video/mpeg no mapping defined [RFC1494] + + Abbreviation: EBP - Extended Body Part + + + +Reynolds & Postel [Page 98] + +RFC 1700 Assigned Numbers October 1994 + + +X.400 to MIME Table + + + Basic Body Parts + + X.400 Basic Body Part MIME content-type Reference + --------------------- -------------------- --------- + ia5-text text/plain;charset=us-ascii [RFC1494] + voice No Mapping Defined [RFC1494] + g3-facsimile image/g3fax [RFC1494] + g4-class1 no mapping defined [RFC1494] + teletex no mapping defined [RFC1494] + videotex no mapping defined [RFC1494] + encrypted no mapping defined [RFC1494] + bilaterally-defined application/octet-stream [RFC1494] + nationally-defined no mapping defined [RFC1494] + externally-defined See Extended Body Parts [RFC1494] + + X.400 Extended Body Part MIME content-type Reference + ------------------------- -------------------- --------- + GeneralText text/plain;charset=iso-8859-x[RFC1494] + ODA application/oda [RFC1494] + mime-postscript-body application/postscript [RFC1494] + mime-jpeg-body image/jpeg [RFC1494] + mime-gif-body image/gif [RFC1494] + +REFERENCES + +[MacMime] Work in Progress. + +[RFC1036] Horton, M., and R. Adams, "Standard for Interchange of + USENET Messages", RFC 1036, AT&T Bell Laboratories, + Center for Seismic Studies, December 1987. + +[RFC1494] Alvestrand, H., and S. Thompson, "Equivalences between 1988 + X.400 and RFC-822 Message Bodies", RFC 1494, SINTEF DELAB, + Soft*Switch, Inc., August 1993. + +[RFC1521] Borenstien, N., and N. Freed, "MIME (Multipurpose Internet + Mail Extensions) Part One: Mechanisms for Specifying and + Describing the Format of Internet Message Bodies", RFC 1521, + Bellcore, Innosoft, September 1993. + +PEOPLE + +[Larry Campbell] + +[Dave Crocker] Dave Crocker + + + +Reynolds & Postel [Page 99] + +RFC 1700 Assigned Numbers October 1994 + + +[Terry Crowley] + +[NSB] Nathaniel Borenstein + +[MTR] Marshall Rose + +[Paul Lindner] + +[PXF] Patrik Faltstrom + +[Ehud Shapiro] + +[Henry Spencer] + +[] + + + + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/media- +types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 100] + +RFC 1700 Assigned Numbers October 1994 + + +CHARACTER SETS + +These are the official names for character sets that may be used in +the Internet and may be referred to in Internet documentation. These +names are expressed in ANSI_X3.4-1968 which is commonly called +US-ASCII or simply ASCII. The character set most commonly use in the +Internet and used especially in protocol standards is US-ASCII, this +is strongly encouraged. The use of the name US-ASCII is also +encouraged. + +The character set names may be up to 40 characters taken from the +printable characters of US-ASCII. However, no distinction is made +between use of upper and lower case letters. + + +Character Set Reference +------------- --------- + +Name: ANSI_X3.4-1968 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-6 +Alias: ANSI_X3.4-1986 +Alias: ISO_646.irv:1991 +Alias: ASCII +Alias: ISO646-US +Alias: US-ASCII +Alias: us +Alias: IBM367 +Alias: cp367 + +Name: ISO-10646-UCS-2 +Source: the 2-octet Basic Multilingual Plane, aka Unicode + this needs to specify network byte order: the standard + does not specify (it is a 16-bit integer space) + +Name: ISO-10646-UCS-4 +Source: the full code space. (same comment about byte order, + these are 31-bit numbers. + +Name: ISO-10646-UTF-1 +Source: Universal Transfer Format (1), this is the multibyte + encoding, that subsets ASCII-7. It does not have byte + ordering issues. + +Name: ISO_646.basic:1983 [RFC1345,KXS2] +Source: ECMA registry +Alias: ref + + + + +Reynolds & Postel [Page 101] + +RFC 1700 Assigned Numbers October 1994 + + +Name: INVARIANT [RFC1345,KXS2] + +Name: ISO_646.irv:1983 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-2 +Alias: irv + +Name: BS_4730 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-4 +Alias: ISO646-GB +Alias: gb +Alias: uk + +Name: NATS-SEFI [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-8-1 + +Name: NATS-SEFI-ADD [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-8-2 + +Name: NATS-DANO [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-9-1 + +Name: NATS-DANO-ADD [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-9-2 + +Name: SEN_850200_B [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-10 +Alias: FI +Alias: ISO646-FI +Alias: ISO646-SE +Alias: se + +Name: SEN_850200_C [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-11 +Alias: ISO646-SE2 +Alias: se2 + +Name: KS_C_5601-1987 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-149 +Alias: KS_C_5601-1989 + + + +Reynolds & Postel [Page 102] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: KSC_5601 +Alias: korean + +Name: ISO-2022-KR [RFC1557,Choi] +Source: RFC-1557 (see also KS_C_5601-1987) + +Name: EUC-KR [RFC1557,Choi] +Source: RFC-1557 (see also KS_C_5861-1992) + +Name: ISO-2022-JP [RFC1468,Murai] +Source: RFC-1468 + +Name: ISO-2022-JP-2 [RFC1554,Ohta] +Source: RFC-1554 + +Name: JIS_C6220-1969-jp [RFC1345,KXS2] +Source: ECMA registry +Alias: JIS_C6220-1969 +Alias: iso-ir-13 +Alias: katakana +Alias: x0201-7 + +Name: JIS_C6220-1969-ro [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-14 +Alias: jp +Alias: ISO646-JP + +Name: IT [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-15 +Alias: ISO646-IT + +Name: PT [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-16 +Alias: ISO646-PT + +Name: ES [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-17 +Alias: ISO646-ES + +Name: greek7-old [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-18 + +Name: latin-greek [RFC1345,KXS2] + + + +Reynolds & Postel [Page 103] + +RFC 1700 Assigned Numbers October 1994 + + +Source: ECMA registry +Alias: iso-ir-19 + +Name: DIN_66003 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-21 +Alias: de +Alias: ISO646-DE + +Name: NF_Z_62-010_(1973) [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-25 +Alias: ISO646-FR1 + +Name: Latin-greek-1 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-27 + +Name: ISO_5427 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-37 + +Name: JIS_C6226-1978 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-42 + +Name: BS_viewdata [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-47 + +Name: INIS [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-49 + +Name: INIS-8 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-50 + +Name: INIS-cyrillic [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-51 + +Name: ISO_5427:1981 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-54 + +Name: ISO_5428:1980 [RFC1345,KXS2] +Source: ECMA registry + + + +Reynolds & Postel [Page 104] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: iso-ir-55 + +Name: GB_1988-80 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-57 +Alias: cn +Alias: ISO646-CN + +Name: GB_2312-80 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-58 +Alias: chinese + +Name: NS_4551-1 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-60 +Alias: ISO646-NO +Alias: no + +Name: NS_4551-2 [RFC1345,KXS2] +Source: ECMA registry +Alias: ISO646-NO2 +Alias: iso-ir-61 +Alias: no2 + +Name: NF_Z_62-010 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-69 +Alias: ISO646-FR +Alias: fr + +Name: videotex-suppl [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-70 + +Name: PT2 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-84 +Alias: ISO646-PT2 + +Name: ES2 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-85 +Alias: ISO646-ES2 + +Name: MSZ_7795.3 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-86 + + + +Reynolds & Postel [Page 105] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: ISO646-HU +Alias: hu + +Name: JIS_C6226-1983 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-87 +Alias: x0208 +Alias: JIS_X0208-1983 + +Name: greek7 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-88 + +Name: ASMO_449 [RFC1345,KXS2] +Source: ECMA registry +Alias: ISO_9036 +Alias: arabic7 +Alias: iso-ir-89 + +Name: iso-ir-90 [RFC1345,KXS2] +Source: ECMA registry + +Name: JIS_C6229-1984-a [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-91 +Alias: jp-ocr-a + +Name: JIS_C6229-1984-b [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-92 +Alias: ISO646-JP-OCR-B +Alias: jp-ocr-b + +Name: JIS_C6229-1984-b-add [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-93 +Alias: jp-ocr-b-add + +Name: JIS_C6229-1984-hand [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-94 +Alias: jp-ocr-hand + +Name: JIS_C6229-1984-hand-add [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-95 +Alias: jp-ocr-hand-add + + + + +Reynolds & Postel [Page 106] + +RFC 1700 Assigned Numbers October 1994 + + +Name: JIS_C6229-1984-kana [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-96 + +Name: ISO_2033-1983 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-98 +Alias: e13b + +Name: ANSI_X3.110-1983 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-99 +Alias: CSA_T500-1983 +Alias: NAPLPS + +Name: ISO_8859-1:1987 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-100 +Alias: ISO_8859-1 +Alias: ISO-8859-1 +Alias: latin1 +Alias: l1 +Alias: IBM819 +Alias: CP819 + +Name: ISO_8859-2:1987 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-101 +Alias: ISO_8859-2 +Alias: ISO-8859-2 +Alias: latin2 +Alias: l2 + +Name: T.61-7bit [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-102 + +Name: T.61-8bit [RFC1345,KXS2] +Alias: T.61 +Source: ECMA registry +Alias: iso-ir-103 + +Name: ISO_8859-3:1988 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-109 +Alias: ISO_8859-3 +Alias: ISO-8859-3 +Alias: latin3 + + + +Reynolds & Postel [Page 107] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: l3 + +Name: ISO_8859-4:1988 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-110 +Alias: ISO_8859-4 +Alias: ISO-8859-4 +Alias: latin4 +Alias: l4 + +Name: ECMA-cyrillic [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-111 + +Name: CSA_Z243.4-1985-1 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-121 +Alias: ISO646-CA +Alias: csa7-1 +Alias: ca + +Name: CSA_Z243.4-1985-2 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-122 +Alias: ISO646-CA2 +Alias: csa7-2 + +Name: CSA_Z243.4-1985-gr [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-123 + +Name: ISO_8859-6:1987 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-127 +Alias: ISO_8859-6 +Alias: ISO-8859-6 +Alias: ECMA-114 +Alias: ASMO-708 +Alias: arabic + +Name: ISO_8859-6-E [RFC1556,IANA] +Source: RFC-1556 + +Name: ISO_8859-6-I [RFC1556,IANA] +Source: RFC-1556 + +Name: ISO_8859-7:1987 [RFC1345,KXS2] +Source: ECMA registry + + + +Reynolds & Postel [Page 108] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: iso-ir-126 +Alias: ISO_8859-7 +Alias: ISO-8859-7 +Alias: ELOT_928 +Alias: ECMA-118 +Alias: greek +Alias: greek8 + +Name: T.101-G2 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-128 + +Name: ISO_8859-8:1988 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-138 +Alias: ISO_8859-8 +Alias: ISO-8859-8 +Alias: hebrew + +Name: ISO_8859-8-E [RFC1556,Nussbacher] +Source: RFC-1556 + +Name: ISO_8859-8-I [RFC1556,Nussbacher] +Source: RFC-1556 + +Name: CSN_369103 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-139 + +Name: JUS_I.B1.002 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-141 +Alias: ISO646-YU +Alias: js +Alias: yu + +Name: ISO_6937-2-add [RFC1345,KXS2] +Source: ECMA registry and ISO 6937-2:1983 +Alias: iso-ir-142 + +Name: IEC_P27-1 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-143 + +Name: ISO_8859-5:1988 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-144 +Alias: ISO_8859-5 + + + +Reynolds & Postel [Page 109] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: ISO-8859-5 +Alias: cyrillic + +Name: JUS_I.B1.003-serb [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-146 +Alias: serbian + +Name: JUS_I.B1.003-mac [RFC1345,KXS2] +Source: ECMA registry +Alias: macedonian +Alias: iso-ir-147 + +Name: ISO_8859-9:1989 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-148 +Alias: ISO_8859-9 +Alias: ISO-8859-9 +Alias: latin5 +Alias: l5 + +Name: greek-ccitt [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-150 + +Name: NC_NC00-10:81 [RFC1345,KXS2] +Source: ECMA registry +Alias: cuba +Alias: iso-ir-151 +Alias: ISO646-CU + +Name: ISO_6937-2-25 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-152 + +Name: GOST_19768-74 [RFC1345,KXS2] +Source: ECMA registry +Alias: ST_SEV_358-88 +Alias: iso-ir-153 + +Name: ISO_8859-supp [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-154 +Alias: latin1-2-5 + +Name: ISO_10367-box [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-155 + + + +Reynolds & Postel [Page 110] + +RFC 1700 Assigned Numbers October 1994 + + +Name: latin6 [RFC1345,KXS2] +Source: ECMA registry +Alias: iso-ir-157 +Alias: l6 + +Name: latin-lap [RFC1345,KXS2] +Source: ECMA registry +Alias: lap +Alias: iso-ir-158 + +Name: JIS_X0212-1990 [RFC1345,KXS2] +Source: ECMA registry +Alias: x0212 +Alias: iso-ir-159 + +Name: DS_2089 [RFC1345,KXS2] +Source: Danish Standard, DS 2089, February 1974 +Alias: DS2089 +Alias: ISO646-DK +Alias: dk + +Name: us-dk [RFC1345,KXS2] + +Name: dk-us [RFC1345,KXS2] + +Name: JIS_X0201 [RFC1345,KXS2] +Alias: X0201 + +Name: KSC5636 [RFC1345,KXS2] +Alias: ISO646-KR + +Name: DEC-MCS [RFC1345,KXS2] +Source: VAX/VMS User's Manual, + Order Number: AI-Y517A-TE, April 1986. +Alias: dec + +Name: hp-roman8 [RFC1345,KXS2] +Source: LaserJet IIP Printer User's Manual, + HP part no 33471-90901, Hewlet-Packard, June 1989. +Alias: roman8 +Alias: r8 + +Name: macintosh [RFC1345,KXS2] +Source: The Unicode Standard ver1.0, ISBN 0-201-56788-1, Oct 1991 +Alias: mac + +Name: IBM037 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 + + + +Reynolds & Postel [Page 111] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: cp037 +Alias: ebcdic-cp-us +Alias: ebcdic-cp-ca +Alias: ebcdic-cp-wt +Alias: ebcdic-cp-nl + +Name: IBM038 [RFC1345,KXS2] +Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 +Alias: EBCDIC-INT +Alias: cp038 + +Name: IBM273 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP273 + +Name: IBM274 [RFC1345,KXS2] +Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 +Alias: EBCDIC-BE +Alias: CP274 + +Name: IBM275 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: EBCDIC-BR +Alias: cp275 + +Name: IBM277 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: EBCDIC-CP-DK +Alias: EBCDIC-CP-NO + +Name: IBM278 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP278 +Alias: ebcdic-cp-fi +Alias: ebcdic-cp-se + +Name: IBM280 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP280 +Alias: ebcdic-cp-it + +Name: IBM281 [RFC1345,KXS2] +Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 +Alias: EBCDIC-JP-E +Alias: cp281 + +Name: IBM284 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 + + + +Reynolds & Postel [Page 112] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: CP284 +Alias: ebcdic-cp-es + +Name: IBM285 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP285 +Alias: ebcdic-cp-gb + +Name: IBM290 [RFC1345,KXS2] +Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 +Alias: cp290 +Alias: EBCDIC-JP-kana + +Name: IBM297 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp297 +Alias: ebcdic-cp-fr + +Name: IBM420 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990, + IBM NLS RM p 11-11 +Alias: cp420 +Alias: ebcdic-cp-ar1 + +Name: IBM423 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp423 +Alias: ebcdic-cp-gr + +Name: IBM424 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp424 +Alias: ebcdic-cp-he + +Name: IBM437 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp437 +Alias: 437 + +Name: IBM500 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP500 +Alias: ebcdic-cp-be +Alias: ebcdic-cp-ch + +Name: IBM850 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp850 + + + +Reynolds & Postel [Page 113] + +RFC 1700 Assigned Numbers October 1994 + + +Alias: 850 + +Name: IBM851 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp851 +Alias: 851 + +Name: IBM852 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp852 +Alias: 852 + +Name: IBM855 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp855 +Alias: 855 + +Name: IBM857 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp857 +Alias: 857 + +Name: IBM860 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp860 +Alias: 860 + +Name: IBM861 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp861 +Alias: 861 +Alias: cp-is + +Name: IBM862 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp862 +Alias: 862 + +Name: IBM863 [RFC1345,KXS2] +Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 +Alias: cp863 +Alias: 863 + +Name: IBM864 [RFC1345,KXS2] +Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 +Alias: cp864 + +Name: IBM865 [RFC1345,KXS2] + + + +Reynolds & Postel [Page 114] + +RFC 1700 Assigned Numbers October 1994 + + +Source: IBM DOS 3.3 Ref (Abridged), 94X9575 (Feb 1987) +Alias: cp865 +Alias: 865 + +Name: IBM868 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP868 +Alias: cp-ar + +Name: IBM869 [RFC1345,KXS2] +Source: IBM Keyboard layouts and code pages, PN 07G4586 June 1991 +Alias: cp869 +Alias: 869 +Alias: cp-gr + +Name: IBM870 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP870 +Alias: ebcdic-cp-roece +Alias: ebcdic-cp-yu + +Name: IBM871 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP871 +Alias: ebcdic-cp-is + +Name: IBM880 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp880 +Alias: EBCDIC-Cyrillic + +Name: IBM891 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp891 + +Name: IBM903 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp903 + +Name: IBM904 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: cp904 +Alias: 904 + +Name: IBM905 [RFC1345,KXS2] +Source: IBM 3174 Character Set Ref, GA27-3831-02, March 1990 +Alias: CP905 +Alias: ebcdic-cp-tr + + + +Reynolds & Postel [Page 115] + +RFC 1700 Assigned Numbers October 1994 + + +Name: IBM918 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP918 +Alias: ebcdic-cp-ar2 + +Name: IBM1026 [RFC1345,KXS2] +Source: IBM NLS RM Vol2 SE09-8002-01, March 1990 +Alias: CP1026 + +Name: EBCDIC-AT-DE [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-AT-DE-A [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-CA-FR [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-DK-NO [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-DK-NO-A [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-FI-SE [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-FI-SE-A [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-FR [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-IT [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-PT [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-ES [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-ES-A [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-ES-S [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + + + + +Reynolds & Postel [Page 116] + +RFC 1700 Assigned Numbers October 1994 + + +Name: EBCDIC-UK [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: EBCDIC-US [RFC1345,KXS2] +Source: IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987 + +Name: UNKNOWN-8BIT [RFC1428] + +Name: MNEMONIC [RFC1345,KXS2] +Source: RFC 1345, also known as "mnemonic+ascii+38" + +Name: MNEM [RFC1345,KXS2] +Source: RFC 1345, also known as "mnemonic+ascii+8200" + +Name: VISCII [RFC1456] +Source: RFC 1456 + +Name: VIQR [RFC1456] +Source: RFC 1456 + +Name: KOI8-R [RFC1489] +Source: RFC 1489, based on GOST-19768-74, ISO-6937/8, + INIS-Cyrillic, ISO-5427. + +Name: UNICODE-1-1 [RFC1641] +Source: RFC 1641 + +Name: UNICODE-1-1-UTF-7 [RFC1642] +Source: RFC 1642 + +REFERENCES + +[RFC1345] Simonsen, K., "Character Mnemonics & Character Sets", + RFC 1345, Rationel Almen Planlaegning, Rationel Almen + Planlaegning, June 1992. + +[RFC1428] Vaudreuil, G., "Transition of Internet Mail from + Just-Send-8 to 8bit-SMTP/MIME", RFC1428, CNRI, February + 1993. + +[RFC1456] Vietnamese Standardization Working Group, "Conventions for + Encoding the Vietnamese Language VISCII: VIetnamese + Standard Code for Information Interchange VIQR: VIetnamese + Quoted-Readable Specification Revision 1.1", RFC 1456, May + 1993. + +[RFC1468] Murai, J., Crispin, M., and E. van der Poel, "Japanese + Character Encoding for Internet Messages", RFC 1468, + + + +Reynolds & Postel [Page 117] + +RFC 1700 Assigned Numbers October 1994 + + + Keio University, Panda Programming, June 1993. + +[RFC1489] Chernov, A., "Registration of a Cyrillic Character Set", + RFC1489, RELCOM Development Team, July 1993. + +[RFC1554] Ohta, M., and K. Handa, "ISO-2022-JP-2: Multilingual + Extension of ISO-2022-JP", RFC1554, Tokyo Institute of + Technology, ETL, December 1993. + +[RFC1556] Nussbacher, H., "Handling of Bi-directional Texts in MIME", + RFC1556, Israeli Inter-University, December 1993. + +[RFC1557] Choi, U., Chon, K., and H. Park, "Korean Character Encoding + for Internet Messages", KAIST, Solvit Chosun Media, + December 1993. + +[RFC1641] Goldsmith, D., and M. Davis, "Using Unicode with MIME", + RFC1641, Taligent, Inc., July 1994. + +[RFC1642] Goldsmith, D., and M. Davis, "UTF-7", RFC1642, Taligent, + Inc., July 1994. + +PEOPLE + +[KXS2] Keld Simonsen + +[Choi] Uhhyung Choi + +[Murai] Jun Murai + +[Ohta] Masataka Ohta + +[Nussbacher] Hank Nussbacher + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets + + + + + + + + + + + + +Reynolds & Postel [Page 118] + +RFC 1700 Assigned Numbers October 1994 + + +NETWORK MANAGEMENT PARAMETERS + +For the management of hosts and gateways on the Internet a data +structure for the information has been defined. This data structure +should be used with any of several possible management protocols, such +as the "Simple Network Management Protocol" (SNMP) [RFC1157], or the +"Common Management Information Protocol over TCP" (CMOT) [RFC1095]. + +The data structure is the "Structure and Indentification of Management +Information for TCP/IP-based Internets" (SMI) [RFC1155], and the +"Management Information Base for Network Management of TCP/IP-based +Internets" (MIB-II) [RFC1213]. + +The SMI includes the provision for panrameters or codes to indicate +experimental or private data structures. These parameter assignments +are listed here. + +The older "Simple Gateway Monitoring Protocol" (SGMP) [RFC1028] also +defined a data structure. The parameter assignments used with SGMP +are included here for historical completeness. + +The network management object identifiers are under the iso (1), org +(3), dod (6), internet (1), or 1.3.6.1, branch of the name space. + +The major branches are: + +1 iso +1.3 org +1.3.6 dod +1.3.6.1 internet +1.3.6.1.1 directory +1.3.6.1.2 mgmt +1.3.6.1.2.1 mib-2 +1.3.6.1.2.1.2.2.1.3 ifType +1.3.6.1.2.1.10 transmission +1.3.6.1.2.1.10.23 transmission.ppp +1.3.6.1.2.1.27 application +1.3.6.1.2.1.28 mta +1.3.6.1.3 experimental +1.3.6.1.4 private +1.3.6.1.4.1 enterprise +1.3.6.1.5 security +1.3.6.1.6 SNMPv2 +1.3.6.1.7 mail + +SMI Network Management Directory Codes: + +Prefix: iso.org.dod.internet.directory (1.3.6.1.1.) + + + +Reynolds & Postel [Page 119] + +RFC 1700 Assigned Numbers October 1994 + + +Decimal Name Description References +------- ---- ----------- ---------- + all Reserved Reserved for future use [IANA] + +SMI Network Management MGMT Codes: + +Prefix: iso.org.dod.internet.mgmt (1.3.6.1.2.) + +Decimal Name Description References +------- ---- ----------- ---------- + 0 Reserved [IANA] + 1 MIB [KZM] + +Prefix: iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1) + +Decimal Name Description References +------- ---- ----------- ---------- + 0 Reserved Reserved [IANA] + 1 system System [RFC1213,KZM] + 2 interfaces Interfaces [RFC1213,KZM] + 3 at Address Translation [RFC1213,KZM] + 4 ip Internet Protocol [RFC1213,KZM] + 5 icmp Internet Control Message [RFC1213,KZM] + 6 tcp Transmission Control Protocol[RFC1213,KZM] + 7 udp User Datagram Protocol [RFC1213,KZM] + 8 egp Exterior Gateway Protocol [RFC1213,KZM] + 9 cmot CMIP over TCP [RFC1213,KZM] + 10 transmission Transmission [RFC1213,KZM] + 11 snmp Simple Network Management [RFC1213,KZM] + 12 GenericIF Generic Interface Extensions +-- [RFC1229,RFC1239,KZM] + 13 Appletalk Appletalk Networking [RFC1243,SXW] + 14 ospf Open Shortest Path First [RFC1253,FB77] + 15 bgp Border Gateway Protocol [RFC1657] + 16 rmon Remote Network Monitoring [RFC1271,SXW] + 17 bridge Bridge Objects [RFC1286,EXD] + 18 DecnetP4 Decnet Phase 4 [RFC1559, Saperia] + 19 Character Character Streams [RFC1658] + 20 snmpParties SNMP Parties [RFC1353,KZM] + 21 snmpSecrets SNMP Secrets [RFC1353,KZM] + 22 snmpDot3RptrMgt [RFC1516] + 23 rip-2 Routing Information Protocol [RFC1389] + 24 ident Identification Protocol [RFC1414] + 25 host Host Resources [RFC1514] + 26 snmpDot3MauMgt 802.3 Medium Attachment Units [RFC1515] + 27 application Network Services Monitoring [RFC1565] + 28 mta Mail Monitoring [RFC1566] + 29 dsa X.500 Directory Monitoring [RFC1567] + + + +Reynolds & Postel [Page 120] + +RFC 1700 Assigned Numbers October 1994 + + + 30 IANAifType Interface Types [RFC1573] + 31 ifMIB Interface Types [RFC1573] + 32 dns Domain Name System [RFC1611] + 33 upsMIB Uninterruptible Power Supplies [RFC1628] + 34 sannauMIB SNA NAU MIB [RFC1665] + 35 etherMIB Ethernet-like generic objects [RFC1650] + 36 sipMIB SMDS inteface objects [RFC1694] + 37 atmMIB ATM objects [RFC1695] + 38 mdmMIB Dial-up modem objects [RFC1696] + 39 rdbmsMIB relational database objects [RFC1697] + +Prefix: iso.org.dod.internet.mgmt.mib-2.interface (1.3.6.1.2.1.2) + +(1.3.6.1.2.1.2.2.1.3) + +ifType definitions + +Decimal Name Description +------- ---- ----------- + 1 other none of the following [RFC1213] + 2 regular1822 BBN Report 1822 [RFC1213] + 3 hdh1822 BBN Report 1822 [RFC1213] + 4 ddn-x25 BBN Report 1822 [RFC1213] + 5 x25 X.25 [RFC1382] + 6 ethernet-csmacd [RFC1213] + 7 IEEE802.3 CSMACD--like Objects [RF1284,JXC] + 8 IEEE802.4 Token Bus-like Objects +-- [RFC1230,RFC1239,KZM] + 9 IEEE802.5 Token Ring-like Objects +-- [RFC1231,RFC1239,KZM] + 10 iso88026-man [RFC1213] + 11 starLan [RFC1213] + 12 proteon-10Mbit [RFC1213] + 13 proteon-80Mbit [RFC1213] + 14 hyperchannel [RFC1213] + 15 FDDI FDDI Objects [RFC1285,JDC20] + 16 lapb LAP B [RFC1381] + 17 sdlc [RFC1213] + 18 ds1 T1/E1 Carrier Objects [RFC1406] + 19 e1 obsolete + 20 basicISDN [RFC1213] + 21 primaryISDN [RFC1213] + 22 propPointToPointSerial [RFC1213] + 23 ppp Point-to-Point Protocol [RFC1471] + 24 softwareLoopback [RFC1213] + 25 eon [RFC1213] + 26 ethernet-3Mbit [RFC1213] + 27 nsip [RFC1213] + + + +Reynolds & Postel [Page 121] + +RFC 1700 Assigned Numbers October 1994 + + + 28 slip [RFC1213] + 29 ultra [RFC1213] + 30 ds3 DS3/E3 Interface Objects [RFC1407] + 31 sip SMDS Interface Objects [RFC1304,TXC] + 32 frame-relay Frame Relay Objects [RFC1315,CXB] + 33 RS-232 RS-232 Objects [RFC1659] + 34 Parallel Parallel Printer Objects [RFC1660] + 35 arcnet ARC network + 36 arcnet-plus ARC network plus + 37 atm ATM + 38 MIOX25 MIOX25 [RFC1461] + 39 SONET SONET or SDH + 40 x25ple X.25 packet level [RFC1382] + 41 iso88022llc 802.2 LLC + 42 localTalk + 43 smds-dxi SMDS DXI + 44 frameRelayService Frame Relay DCE + 45 v35 V.35 + 46 hssi HSSI + 47 hippi HIPPI + 48 modem generic modem + 49 aal5 AAL5 over ATM + 50 sonetPath + 51 sonetVT + 52 smds-icip SMDS Inter-Carrier Interface Protocol + 53 propVirtual proprietary vitural/internal interface + 54 propMultiLink proprietary multi-link multiplexing + 55 IEEE802.12 100BaseVG + 56 fibre-channel Fibre Channel + +Prefix: iso.org.dod.internet.mgmt.mib-2.transmission (1.3.6.1.2.1.10) + +Decimal Name Description +------- ---- ----------- + 5 x25 X.25 [RFC1382] + 7 IEEE802.3 CSMACD--like Objects [RFC1650] + 8 IEEE802.4 Token Bus-like Objects +-- [RFC1230,RFC1239,KZM] + 9 IEEE802.5 Token Ring-like Objects +-- [RFC1231,RFC1239,KZM] + 15 FDDI FDDI Objects [RFC1285,JDC20] + 16 lapb LAP B [RFC1381] + 18 ds1 T1 Carrier Objects [RFC1406] + 19 e1 E1 Carrier Objects [RFC1406] + 23 ppp Point-to-Point Protocol [RFC1471] + 30 ds3 DS3/E3 Interface Objects [RFC1407] + 31 sip SMDS Interface Objects [RFC1694] + 32 frame-relay Frame Relay Objects [RFC1315,CXB] + + + +Reynolds & Postel [Page 122] + +RFC 1700 Assigned Numbers October 1994 + + + 33 RS-232 RS-232 Objects [RFC1659] + 34 Parallel Parallel Printer Objects [RFC1660] + 35 arcnet ARC network + 36 arcnet-plus ARC network plus + 37 atm ATM + 38 MIOX25 MIOX25 [RFC1461] + 39 sonetMIB SONET MIB [RFC1595] + 44 frnetservMIB Frame Relay Service MIB for DCE [RFC1596] + +Prefix: iso.org.dod.internet.mgmt.mib-2.transmission (1.3.6.1.2.1.10) + +(1.3.6.1.2.1.10.23) + +Decimal Name Description References +------- ---- ----------- ---------- + 1 pppLcp ppp link control [RFC1471] + 2 pppSecurity ppp security [RFC1472] + 3 pppIp ppp IP network control [RFC1473] + 4 pppBridge ppp bridge networl control [RFC1474] + +Prefix: iso.org.dod.internet.mgmt.mib-2.application (1.3.6.1.2.1.27) + +(1.3.6.1.2.1.27.2.1.3) + + assocApplicationProtocol OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "An identification of the protocol being used for the + application. For an OSI Application, this will be the + Application Context. For Internet applications, the IANA + maintains a registry of the OIDs which correspond to + well-known applications. If the application protocol is + not listed in the registry, an OID value of the form + {applTCPProtoID port} or {applUDProtoID port} are used for + TCP-based and UDP-based protocols, respectively. In either + case 'port' corresponds to the primary port number being + used by the protocol." + ::= {assocEntry 3} + +Decimal Name Description +------- ---- ----------- + 0 Reserved + +(1.3.6.1.2.1.27.3) + +(1.3.6.1.2.1.27.4) + + + +Reynolds & Postel [Page 123] + +RFC 1700 Assigned Numbers October 1994 + + + -- OIDs of the form {applTCPProtoID port} are intended to be used + -- for TCP-based protocols that don't have OIDs assigned by other + -- means. {applUDPProtoID port} serves the same purpose for + -- UDP-based protocols. In either case 'port' corresponds to + -- the primary port number being used by the protocol. For example, + -- assuming no other OID is assigned for SMTP, an OID of + -- {applTCPProtoID 25} could be used, since SMTP is a TCP-based + -- protocol that uses port 25 as its primary port. + +Prefix: iso.org.dod.internet.mgmt.mib-2.mta (1.3.6.1.2.1.28) + +(1.3.6.1.2.1.28.2.1.24) + + mtaGroupMailProtocol OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "An identification of the protocol being used by this group. + For an group employing OSI protocols, this will be the + Application Context. For Internet applications, the IANA + maintains a registry of the OIDs which correspond to + well-known message transfer protocols. If the application + protocol is not listed in the registry, an OID value of the + form {applTCPProtoID port} or {applUDProtoID port} are used + for TCP-based and UDP-based protocols, respectively. In + either case 'port' corresponds to the primary port number + being used by the group. applTCPProtoID and applUDPProtoID + are defined in [5]." + ::= {mtaGroupEntry 24} + +Decimal Name Description +------- ---- ----------- + 0 Reserved + +SMI Network Management Experimental Codes: + +Prefix: iso.org.dod.internet.experimental (1.3.6.1.3.) + +Decimal Name Description References +------- ---- ----------- ---------- + 0 Reserved [JKR1] + 1 CLNS ISO CLNS Objects [GS2] + * 2 T1-Carrier T1 Carrier Objects [FB77] + * 3 IEEE802.3 Ethernet-like Objects [JXC] + * 4 IEEE802.5 Token Ring-like Objects [EXD] + * 5 DECNet-PHIV DECNet Phase IV [JXS2] + * 6 Interface Generic Interface Objects [KZM] + + + +Reynolds & Postel [Page 124] + +RFC 1700 Assigned Numbers October 1994 + + + * 7 IEEE802.4 Token Bus-like Objects [KZM] + * 8 FDDI FDDI Objects [JDC20] + 9 LANMGR-1 LAN Manager V1 Objects [JXG1] + 10 LANMGR-TRAPS LAN Manager Trap Objects [JXG1] + 11 Views SNMP View Objects [CXD] + 12 SNMP-AUTH SNMP Authentication Objects [KZM] + * 13 BGP Border Gateway Protocol [SW159] + * 14 Bridge Bridge MIB [FB77] + * 15 DS3 DS3 Interface Type [TXB] + * 16 SIP SMDS Interface Protocol [TXB] + * 17 Appletalk Appletalk Networking [SXW] + * 18 PPP PPP Objects [FJK2] + * 19 Character MIB Character MIB [BS221] + * 20 RS-232 MIB RS-232 MIB [BS221] + * 21 Parallel MIB Parallel MIB [BS221] + 22 atsign-proxy Proxy via Community [RXF] + * 23 OSPF OSPF MIB [FB77] + 24 Alert-Man Alert-Man [LS8] + 25 FDDI-Synoptics FDDI-Synoptics [DXP1] + * 26 Frame Relay Frame Relay MIB [CXB] + * 27 rmon Remote Network Management MIB [SXW] + 28 IDPR IDPR MIB [RAW44] + 29 HUBMIB IEEE 802.3 Hub MIB [DXM5] + 30 IPFWDTBLMIB IP Forwarding Table MIB [FB77] + 31 LATM MIB [TXB] + 32 SONET MIB [TXB] + 33 IDENT [MTR] + 34 MIME-MHS [MTR] + 35 MAUMIB IEEE 802.3 Mau MIB [DXM5] + 36 Host Resources Host Resources MIB [SXW] + 37 ISIS-MIB Integrated ISIS protocol MIB [CXG] + 38 Chassis Chassis MIB [JDC20] + 39 ups ups [JDC20] + 40 App-Mon Application Monitoring MIB [TXK] + 41 ATM UNI ATM [MXA1] + 42 FC Fibre Channel [JXC4] +* 43 DNS Domain Name Service [Rob Austein] + 44 X.25 X.25 MIB [Dean Throop] + 45 Frame Relay Serv. Frame Relay Service MIB [Tracy Cox] + 46 Madman-Applications [Ned Freed] + 47 Madman-MTA [Ned Freed] + 48 Madman-DSA [Ned Freed] + 49 Modem [Steve Waldbusser] + 50 SNA NAU [Deirdre Kostick] + 51 SDLC SDLC [Jeff Hilgeman] + 52 DNS Domain Name Service [Jon Saperia] + 53 network-objects IP info ix X.500 [Johannsen] + 54 printmib [Joel Gyllenskog] + + + +Reynolds & Postel [Page 125] + +RFC 1700 Assigned Numbers October 1994 + + + 55 rdbmsmib [Robert Purvey] + 56 sipMIB [Tracy Brown] + 57 stIImib ST-II protocol MIB [Hartmut Wittig] + 58 802.5 SSR MIB 802.5 Station Source Routing MIB [KZM] + + * = obsoleted + +SMI Private Codes: + +Prefix: iso.org.dod.internet.private (1.3.6.1.4) + +Decimal Name Description References +------- ---- ----------- ---------- + 0 Reserved [JKR1] + 1 enterprise private enterprises [JKR1] + +SMI Private Enterprise Codes: + +Prefix: iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) + +See the file "enterprise-numbers". + +SMI Security Codes: + +Prefix: iso.org.dod.internet.security (1.3.6.1.5) + +Decimal Name Description References +------- ---- ----------- ---------- + 0 Reserved [JKR1] + 1 kerberosV4 Kerberos version 4 objects [1,BCN] + 2 kerberosV5 Kerberos version 5 objects [2,BCN] + +SMI SNMPv2 Codes: + +Prefix: iso.org.dod.internet.snmpv2 (1.3.6.1.6) + +SMI mail Codes: + +Prefix: iso.org.dod.internet.mail (1.3.6.1.7) + + 1 mime-mhs + + +REFERENCES + +[1] Miller, S.P., B.C. Neuman, J.I. Schiller, and J.H. Saltzer, + "Project Athena Technical Plan Section E.2.1: Kerberos + Authentication and Authorization System", Project Athena, + + + +Reynolds & Postel [Page 126] + +RFC 1700 Assigned Numbers October 1994 + + + MIT, December 1987. + +[2] Kohl, J., and B.C. Neuman, "The Kerberos Network + Authentication Service (V5)" work in progress, September + 1992. + +[RFC1028] Davin, J., J. Case, M. Fedor, and M. Schoffstall, "A Simple + Gateway Monitoring Protocol", RFC 1028, Proteon, Inc., + University of Tennessee at Knoxville, Cornell University, + Rensselaer Polytechnic Institute, November 1987. + +[RFC1095] Warrier, U., and L. Besaw, "The Common Management + Information Services and Protocol over TCP/IP (CMOT)", + RFC 1095, Unisys Corp., Hewlett-Packard, April 1989. + +[RFC1155] Rose, M., and K. McCloghrie, "Structure and Identification + of Management Information for TCP/IP-based internets", + STD 16, RFC 1155, Performance Systems International, Hughes + LAN Systems, May 1990. + +[RFC1157] Case, J., M. Fedor, M. Schoffstall, and J. Davin, + "A Simple Network Management Protocol", STD 15, RFC 1157, + SNMP Research, Performance Systems International, + Performance Systems International, MIT Laboratory for + Computer Science, May 1990. + +[RFC1213] McCloghrie, K., and M. Rose, "Management Information Base + for Network Management of TCP/IP-based internets: MIB-II", + STD 17, RFC 1213, Hughes LAN Systems, Performance Systems + International, March 1991. + +[RFC1229] McCloghrie, K., Editor, "Extensions to the Generic-Interface + MIB", RFC 1229, Hughes LAN Systems, Inc., May 1991. + +[RFC1230] McCloghrie, K., and R. Fox, "IEEE 802.4 Token Bus MIB", + RFC 1230, Hughes LAN Systems, Inc., Synoptics, Inc., + May 1991. + +[RFC1231] McCloghrie, K., Fox, R., and E. Decker, "IEEE 802.5 Token + Ring MIB", RFC 1231, Hughes LAN Systems, Inc., Synoptics, + Inc., cisco Systems, Inc., May 1991. + +[RFC1239] Reynolds, J., "Reassignment of Experimental MIBs to + Standard MIBs", RFC 1239, USC/Information Sciences + Institute, ISI, June 1991. + +[RFC1243] Waldbusser, S., Editor, "AppleTalk Management Information + Base", RFC 1243, Carnegie Mellon University, July 1991. + + + +Reynolds & Postel [Page 127] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC1253] Baker, F., and R. Coltun, "OSPF Version 2 Management + Information Base", RFC 1253, ACC, Computer Science Center, + August 1991. + +[RFC1271] Waldbusser, S., "Remote Network Monitoring Management + Information Base", RFC 1271, Carnegie Mellon University, + November 1991. + +[RFC1284] Cook, J., Editor, "Definitions of Managed Objects + for the Ethernet-like Interface Types", RFC 1284, Chipcom + Corporation, December 1991. + +[RFC1285] Case, J., "FDDI Management Information Base", RFC 1285, + SNMP Research, Incorporated, January 1992. + +[RFC1286] Decker, E., Langille, P., Rijsinghani, A., and K. + McCloghrie, "Definitions of Managed Objects for Bridges", + RFC 1286, cisco Systems, Inc., DEC, Hughes LAN Systems, + Inc., December 1991. + +[RFC1304] Cox, T., and K. Tesnik, Editors, "Definitions of Managed + Objects for the SIP Interface Type", RFC 1304, Bell + Communications Research, February 1992. + +[RFC1315] Brown, C., Baker, F., and C. Carvalho, "Management + Information Base for Frame Relay DTEs", RFC 1315, Wellfleet + Communications, Inc., Advanced Computer Communications, + April 1992. + +[RFC1353] McCloghrie, K., Davin, J., and J. Galvin, "Definitions of + Managed Objects for Administration of SNMP Parties", + RFC 1353, Hughes LAN Systems, Inc., MIT Laboratory for + Computer Science, Trusted Information Systems, Inc., + July 1992. + +[RFC1381] Throop, D., and F. Baker, "SNMP MIB Extension for X.25 + LAPB", RFC 1381, Data General Corporation, Advanced Computer + Communications, November 1992. + +[RFC1382] Throop, D., Editor, "SNMP MIB Extension for the X.25 Packet + Layer", RFC 1382, Data General Corporation, November 1992. + +[RFC1389] Malkin, G., and F. Baker, "RIP Version 2 MIB Extension", RFC + 1389, Xylogics, Inc., Advanced Computer Communications, + January 1993. + +[RFC1406] Baker, F., and J. Watt, Editors, "Definitions of Managed + Objects for the DS1 and E1 Interface Types", RFC 1406, + + + +Reynolds & Postel [Page 128] + +RFC 1700 Assigned Numbers October 1994 + + + Advanced Computer Communications, Newbridge Networks + Corporation, January 1993. + +[RFC1407] Cox, T., and K. Tesink, "Definitions of Managed Objects + for the DS3/E3 Interface Type", RFC 1407, Bell + Communications Research, January 1993. + +[RFC1414] St. Johns, M., and M. Rose, "Identification MIB", RFC 1414, + US Department of Defense, Dover Beach Consulting, Inc., + February 1993. + +[RFC1461] Throop, D., "SNMP MIB extension for Multiprotocol + Interconnect over X.25", RFC 1461, Data General Corporation, + May 1993. + +[RFC1471] Kastenholz, F., "The Definitions of Managed Objects for + the Link Control Protocol of the Point-to-Point Protocol", + RFC 1471, FTP Software, Inc., June 1993. + +[RFC1472] Kastenholz, F., "The Definitions of Managed Objects for + the Security Protocols of the Point-to-Point Protocol", RFC + 1472, FTP Software, Inc., June 1993. + +[RFC1473] Kastenholz, F., "The Definitions of Managed Objects for + the IP Network Control Protocol of the Point-to-Point + Protocol", RFC 1473, FTP Software, Inc., June 1993. + +[RFC1474] Kastenholz, F., "The Definitions of Managed Objects for + the Bridge Network Control Protocol of the Point-to-Point + Protocol" RFC 1474, FTP Software, Inc., June 1993. + +[RFC1514] Grillo, P., and S. Waldbusser, "Host Resources MIB", RFC + 1514, Network Innovations, Intel Corporation, Carnegie + Mellon University, September 1993. + +[RFC1515] McMaster, D., McCloghrie, K., and S. Roberts, "Definitions + of Managed Objects for IEEE 802.3 Medium Attachment Units + (MAUs)", RFC 1515, SynOptics Communications, Inc., Hughes + LAN Systems, Inc., Farallon Computing, Inc., September 1993. + +[RFC1516] McMaster, D., and K. McCloghrie, "Definitions of Managed + Objects for IEEE 802.3 Repeater Devices", RFC 1516, + SynOptics Communications, Inc., Hughes LAN Systems, Inc., + September 1993. + +[RFC1559] Saperia, J., "DECnet Phase IV MIB Extensions", RFC 1559, + Digital Equipment Corporation, December 1993. + + + + +Reynolds & Postel [Page 129] + +RFC 1700 Assigned Numbers October 1994 + + +[RFC1565] Kille, S., WG Chair, and N. Freed, Editor, "Network Services + Monitoring MIB", RFC 1565, ISODE Consortium and Innosoft, + January 1994. + +[RFC1566] Kille, S., WG Chair, and N. Freed, Editor, "Mail Monitoring + MIB", RFC 1566, ISODE Consortium, Innosoft, January 1994. + +[RFC1567] Mansfield, G., and S. Kille, "X.500 Directory Monitoring + MIB", RFC 1567, AIC Systems Laboratory, ISODE Consortium, + January 1994. + +[RFC1573] McCloghrie, K., and F. Kastenholz, "Evolution of the + Interfaces Group of MIB-II", RFC 1573, Hughes LAN Systems, + FTP Software, January 1994. + +[RFC1595] Brown, T., and K. Tesink, Editors, "Definitions of Managed + Objects for the SONET/SDH Interface Type", RFC 1595, + Bell Communications Research, March 1994. + +[RFC1596] Brown, T., Editor, Definitions of Managed Objects for Frame + Relay Service", RFC 1596, Bell Communications Research, + March 1994. + +[RFC1611] Austein, R., and J. Saperia, "DNS Server MIB Extensions", + RFC 1611, Epilogue Technology Corporation, Digital Equipment + Corporation, May 1994. + +[RFC1628] Case, J., Editor, "UPS Management Information Base", RFC + 1628, SNMP Research, Incorporated, May 1994. + +[RFC1650] Kastenholz, F., "Definitions of Managed Objects for + the Ethernet-like Interface Types using SMIv2", RFC 1650, + FTP Software, Inc., August 1994. + +[RFC1657] Willis, S., Burruss, J., and J. Chu, Editor, "Definitions of + Managed Objects for the Fourth Version of the Border Gateway + Protocol (BGP-4) using SMIv2", RFC 1657, Wellfleet + Communications Inc., IBM Corp., July 1994. + +[RFC1658] Stewart, B., "Definitions of Managed Objects for Character + Stream Devices using SMIv2", RFC 1658, Xyplex, Inc., July + 1994. + +[RFC1659] Stewart, B., "Definitions of Managed Objects for RS-232-like + Hardware Devices using SMIv2", RFC 1659, Xyplex, Inc., July + 1994. + +[RFC1660] Stewart, B., "Definitions of Managed Objects for + + + +Reynolds & Postel [Page 130] + +RFC 1700 Assigned Numbers October 1994 + + + Parallel-printer-like Hardware Devices using SMIv2", RFC + 1660, Xyplex, Inc., July + 1994. + +[RFC1665] Kielczewski, Z., Kostick, D., and K. Shih, Editors, + "Definitions of Managed Objects for SNA NAUs using SMIv2", + RFC 1665, Eicon Technology Corporation, Bell Communications + Research, Novell, July 1994. + +[RFC1694] Brown, T., and K. Tesink, Editors, "Definitions of Managed + Objects for SMDS Interfaces using SMIv2", RFC 1694, Bell + Communications Research, August 1994. + +[RFC1695] Ahmed, M., and K. Tesink, Editors, "Definitions of Managed + Objects for ATM Management Version 8.0 using SMIv2", RFC + 1695, Bell Communications Research, August 1994. + +[RFC1696] Barnes, J., Brown, L., Royston, R., and S. Waldbusser, + "Modem Management Information Base (MIB) using SMIv2", RFC + 1696, Xylogics, Inc., Motorola, US Robotics, Inc., Carnegie + Mellon University, August 1994. + +[RFC1697] Brower, D., Editor, Purvy, B., RDBMSMIB Working Group Chair, + Daniel, A., Sinykin, M., and J. Smith, "Relational Database + Management System (RDBMS) Management Information Base (MIB) + using SMIv2", RFC 1697, The ASK Group, INGRES DBMS + Development, Oracle Corporation, Informix Software, Inc., + Oracle Corporation, August 1994. + +PEOPLE + +[Rob Austein] + +[BCN] B. Clifford Neuman + +[BS221] Bob Stewart + +[CXB] Caralyn Brown + +[CXD] Chuck Davin + +[CXG] Chris Gunner + +[Dean Throop] + +[DXM5] Donna McMaster + +[DXP1] David Perkins + + + +Reynolds & Postel [Page 131] + +RFC 1700 Assigned Numbers October 1994 + + +[EXD] Eric Decker + +[FB77] Fred Baker + +[FJK2] + +[GS2] Greg Satz + +[IANA] IANA + +[JDC20] Jeffrey Case + +[JKR1] Joyce K. Reynolds + +[JXC] John Cook + +[JXG1] Jim Greuel + +[JXS2] Jon Saperia + +[Jeff Hilgeman] + +[Johannsen] + +[KZM] Keith McCloghrie + +[LS8] Louis Steinberg + +[MXA1] Masuma Ahmed + +[MTR] Marshall Rose + +[RAW44] Robert A. Woodburn + +[JXC4] John Chu + +[Ned Freed] + +[Deirdre Kostick] + +[Joel Gyllenskog] Joel Gyllenskog + +[Robert Purvey] Robert Purvey + +[RXF] Richard Fox + +[Jon Saperia] Jon Saperia + + + + +Reynolds & Postel [Page 132] + +RFC 1700 Assigned Numbers October 1994 + + +[SW159] Steven Willis + +[SXW] Steve Waldbusser + +[TXB] Tracy Brown + +[TXK] Teemu Kurki + +[Hartmut Wittig] + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/smi-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 133] + +RFC 1700 Assigned Numbers October 1994 + + +PRIVATE ENTERPRISE NUMBERS + +SMI Network Management Private Enterprise Codes: + +Prefix: iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) + +This file is + + ftp://ftp.isi.edu/in-notes/iana/assignments/enterprise-numbers + +Decimal Name References +------- ---- ---------- + 0 Reserved Joyce K. Reynolds + 1 Proteon John A. Shriver + 2 IBM Vik Chandra + 3 CMU Steve Waldbusser + 4 Unix Keith Sklower + 5 ACC Art Berggreen + 6 TWG John Lunny (703) 847-4500 + 7 CAYMAN Beth Miaoulis beth@cayman.com + 8 PSI Marty Schoffstahl schoff@NISC.NYSER.NET + 9 cisco Greg Satz satz@CISCO.COM + 10 NSC Geof Stone geof@NETWORK.COM + 11 HP R. Dwight Schettler rds%hpcndm@HPLABS.HP.COM + 12 Epilogue Karl Auerbac karl@empirical.com + 13 U of Tennessee Jeffrey Case case@UTKUX1.UTK.EDU + 14 BBN Robert Hinden + 15 Xylogics, Inc. John R. LoVerso loverso@westford.ccur.com + 16 Timeplex Laura Bridge laura@uunet.UU.NET + 17 Canstar Sanand Patel sanand@HUB.TORONTO.EDU + 18 Wellfleet Caralyn Brown cbrown@wellfleet.com + 19 TRW Jay Frederking jayf@blackhole.ind.TRW.COM + 20 MIT Jon Rochlis jon@ATHENA.MIT.EDU + 21 EON Michael Waters ---none--- + 22 Spartacus Yoav Kluger ykluger@HAWK.ULOWELL.EDU + 23 Novell Steve Bostock steveb@novell.com + 24 Spider Systems Peter Reid peter@spider.co.uk + 25 NSFNET Hans-Werner Braun HWB@MCR.UMICH.EDU + 26 Hughes LAN Systems Keith McCloghrie KZM@HLS.COM + 27 Intergraph Guy Streeter guy@guy.bll.ingr.com + 28 Interlan Bruce Taber taber@europa.InterLan.COM + 29 Vitalink Communications + 30 Ulana Bill Anderson wda@MITRE-BEDFORD.ORG + 31 NSWC Stephen Northcutt SNORTHC@RELAY-NSWC.NAVY.MIL + 32 Santa Cruz Operation Keith Reynolds keithr@SCO.COM + 33 Xyplex Bob Stewart STEWART@XYPLEX.COM + 34 Cray Hunaid Engineer hunaid@OPUS.CRAY.COM + 35 Bell Northern Research Glenn Waters gwaters@BNR.CA + + + +Reynolds & Postel [Page 134] + +RFC 1700 Assigned Numbers October 1994 + + + 36 DEC Ron Bhanukitsiri rbhank@DECVAX.DEC.COM + 37 Touch Brad Benson ---none--- + 38 Network Research Corp. Bill Versteeg bvs@NCR.COM + 39 Baylor College of Medicine Stan Barber SOB@BCM.TMC.EDU + 40 NMFECC-LLNL Steven Hunter hunter@CCC.MFECC.LLNL.GOV + 41 SRI David Wolfe ctabka@TSCA.ISTC.SRI.COM + 42 Sun Microsystems Dennis Yaro yaro@SUN.COM + 43 3Com Jeremy Siegel jzs@NSD.3Com.COM + 44 CMC Dave Preston ---none--- + 45 SynOptics David Perkins dperkins@synoptics.com + 46 Cheyenne Software Reijane Huai sibal@CSD2.NYU.EDU + 47 Prime Computer Mike Spina WIZARD%enr.prime.com@RELAY.CS.NET + 48 MCNC/North Carolina Data Network Ken Whitfield ken@MCNC.ORG + 49 Chipcom John Cook cook@chipcom.com + 50 Optical Data Systems Josh Fielk ---none--- + 51 gated Jeffrey C. Honig jch@gated.cornell.edu + 52 Cabletron Systems Roger Dev ---none--- + 53 Apollo Computers Jeffrey Buffun jbuffum@APOLLO.COM + 54 DeskTalk Systems, Inc. David Kaufman ---none--- + 55 SSDS Ron Strich ---none--- + 56 Castle Rock Computing John Sancho ---none--- + 57 MIPS Computer Systems Charles Marker II marker@MIPS.COM + 58 TGV, Inc. Ken Adelman Adelman@TGV.COM + 59 Silicon Graphics, Inc. Ronald Jacoby rj@SGI.COM + 60 University of British Columbia Don McWilliam mcwillm@CC.UBC.CA + 61 Merit Bill Norton wbn@MERIT.EDU + 62 FiberCom Eric Rubin err@FIBERCOM.COM + 63 Apple Computer Inc Jim Hayes Hayes@APPLE.COM + 64 Gandalf Henry Kaijak ---none--- + 65 Dartmouth Philip Koch Philip.Koch@DARTMOUTH.EDU + 66 David Systems Kathryn de Graaf degraaf@davidsys.com + 67 Reuter Bob Zaniolo ---none--- + 68 Cornell Laurie Collinsworth ljc1@cornell.edu + 69 LMS L. Michael Sabo Sabo@DOCKMASTER.NCSC.MIL + 70 Locus Computing Corp. Arthur Salazar lcc.arthur@SEAS.UCLA.EDU + 71 NASA Steve Schoch SCHOCH@AMES.ARC.NASA.GOV + 72 Retix Alex Martin ---none--- + 73 Boeing Jerry Geisler ---none--- + 74 AT&T Rich Bantel rgb@mtung.att.com + 75 Ungermann-Bass Didier Moretti ---none--- + 76 Digital Analysis Corporation + Skip Koppenhaver stubby!skip@uunet.UU.NET + 77 LAN Manager Doug Karl KARL-D@OSU-20.IRCC.OHIO-STATE.EDU + 78 Netlabs Jonathan Biggar jon@netlabs.com + 79 ICL Jon Infante ---none--- + 80 Auspex Systems Brian A. Ehrmantraut bae@auspex.com + 81 Lannet Company Efrat Ramati ---none--- + 82 Network Computing Devices Dave Mackie lupine!djm@UUNET.UU.NET + + + +Reynolds & Postel [Page 135] + +RFC 1700 Assigned Numbers October 1994 + + + 83 Raycom Systems Bruce Willins ---none--- + 84 Pirelli Focom Ltd. Sam Lau ---none--- + 85 Datability Software Systems Larry Fischer lfischer@dss.com + 86 Network Application Technology Y.C. Wang ---none--- + 87 LINK (Lokales Informatik-Netz Karlsruhe) + Guenther Schreiner snmp-admin@ira.uka.de + 88 NYU Bill Russell russell@cmcl2.NYU.EDU + 89 RND Rina Nethaniel ---none--- + 90 InterCon Systems Corporation Amanda Walker AMANDA@INTERCON.COM + 91 Coral Network Corporation Jason Perreault jason@coral.com + 92 Webster Computer Corporation Robert R. Elz kre@munnari.oz.au + 93 Frontier Technologies Corporation + Prakash Ambegaonkar ---none--- + 94 Nokia Data Communications Douglas Egan ---none--- + 95 Allen-Bradely Company + Bill King abvax!calvin.icd.ab.com!wrk@uunet.UU.NET + 96 CERN + Jens T. Rasmussen jenst%cernvax.cern.ch@CUNYVM.CUNY.EDU + 97 Sigma Network Systems, Inc. + Ken Virgile signet!ken@xylogics.COM + 98 Emerging Technologies, Inc. + Dennis E. Baasch etinc!dennis@uu.psi.com + 99 SNMP Research Jeffrey Case case@UTKUX1.UTK.EDU + 100 Ohio State University + Shamim Ahmed ahmed@nisca.ircc.ohio-state.edu + 101 Ultra Network Technologies Julie Dmytryk + Julie_Dmytryk.MKT@usun.ultra.com + 102 Microcom Annmarie Freitas ---none--- + 103 Martin Marietta Astronautic Group David Rageth DAVE@MMC.COM + 104 Micro Technology Mike Erlinger mike@lexcel.com + 105 Process Software Corporation Bernie Volz VOLZ@PROCESS.COM + 106 Data General Corporation + Joanna Karwowska karwowska@dg-rtp.dg.com + 107 Bull Company Anthony Berent berent@rdgeng.enet.dec.com + 108 Emulex Corporation Jeff Freeman ---none--- + 109 Warwick University Computing Services + Israel Drori raanan@techunix.technion.ac.il + 110 Network General Corporation + James Davidson ngc!james@uunet.UU.NET + 111 Oracle John Hanley jhanley@oracle.com + 112 Control Data Corporation Nelluri L. Reddy reddy@uc.msc.umn.edu + 113 Hughes Aircraft Company Keith McCloghrie KZM@HLS.COM + 114 Synernetics, Inc. Jas Parmar jas@synnet.com + 115 Mitre Bede McCall bede@mitre.org + 116 Hitachi, Ltd. Hirotaka Usuda ---none--- + 117 Telebit Mark S. Lewis mlewis@telebit.com + 118 Salomon Technology Services Paul Maurer II ---none--- + 119 NEC Corporation Yoshiyuki Akiyama + + + +Reynolds & Postel [Page 136] + +RFC 1700 Assigned Numbers October 1994 + + + kddlab!ccs.mt.nec.co.jp!y-akiyam@uunet.uu.net + 120 Fibermux Michael Sung msung@ccrelay.fibermux.com + 121 FTP Software Inc. Stev Knowles stev@vax.ftp.com + 122 Sony Takashi Hagiwara Hagiwara@Sm.Sony.Co.Jp + 123 Newbridge Networks Corporation James Watt ---none--- + 124 Racal-Milgo Information Systems Maurice R. Turcotte + mailrus!uflorida!rm1!dnmrt%rmatl@uunet.UU.NET + 125 CR SYSTEMS Soren H. Sorensen ---none--- + 126 DSET Corporation Dan Shia dset!shia@uunet.UU.NET + 127 Computone Bill Versteeg bvs@NCR.COM + 128 Tektronix, Inc. Dennis Thomas dennist@tektronix.TEK.COM + 129 Interactive Systems Corporation + Steve Alexander stevea@i88.isc.com + 130 Banyan Systems Inc. + Deepak Taneja eepak=Taneja%Eng%Banyan@Thing.banyan.com + 131 Sintrom Datanet Limited + 132 Bell Canada Mark Fabbi markf@gpu.utcs.utoronto.ca + 133 Crosscomm Corporation Reuben Sivan crossc!rsivan@uunet.UU.NET + 134 Rice University Catherine Foulston cathyf@rice.edu + 135 T3Plus Networking, Inc. Harley Frazee harley@io.t3plus.com + 136 Concurrent Computer Corporation + John R. LoVerso loverso@westford.ccur.com + 137 Basser Paul O'Donnell paulod@cs.su.oz.au + 138 Luxcom + 139 Artel Jon Ziegler Ziegler@Artel.com + 140 Independence Technologies, Inc. (ITI) + Gerard Berthet gerard@indetech.com + 141 Frontier Software Development Narendra Popat ---none--- + 142 Digital Computer Limited Osamu Fujiki ---none--- + 143 Eyring, Inc. Ron Holt ron@Eyring.COM + 144 Case Communications Peter Kumik ---none--- + 145 Penril DataComm, Inc. Keith Hogan keith%penril@uunet.uu.net + 146 American Airlines Bill Keatley ---none--- + 147 Sequent Computer Systems Scott Hahn sdh@sequent.com + 148 Bellcore Kaj Tesink kaj@nvuxr.cc.bellcore.com + 149 Konkord Communications Ken Jones konkord!ksj@uunet.uu.net + 150 University of Washington + Christopher Wheeler cwheeler@cac.washignton.edu + 151 Develcon Sheri Mayhew zaphod!sherim@herald.usask.ca + 152 Solarix Systems Paul Afshar paul@solar1.portal.com + 153 Unifi Communications Corp. Yigal Hochberg yigal@unifi.com + 154 Roadnet Dale Shelton ---none--- + 155 Network Systems Corp. + Nadya K. El-Afandi nadya@khara.network.com + 156 ENE (European Network Engineering) Peter Cox ---none--- + 157 Dansk Data Elektronik A/S Per Bech Hansen pbh@dde.dk + 158 Morning Star Technologies Karl Fox karl@MorningStar.Com + 159 Dupont EOP Oscar Rodriguez ---none--- + + + +Reynolds & Postel [Page 137] + +RFC 1700 Assigned Numbers October 1994 + + + 160 Legato Systems, Inc. Jon Kepecs kepecs@Legato.COM + 161 Motorola SPS Vince Enriquez enriquez@sps.mot.com + 162 European Space Agency (ESA) + Eduardo EDUATO%ESOC.BITNET@CUNYVM.CUNY.EDU + 163 BIM Bernard Lemercier bl@sunbim.be + 164 Rad Data Communications Ltd. Oft Israel ---none--- + 165 Intellicom Paul Singh ---none--- + 166 Shiva Corporation Phil Budne phil@Shiva.COM + 167 Fujikura America Debbie Reed ---none--- + 168 Xlnt Designs INC (XDI) Mike Anello mike@xlnt.com + 169 Tandem Computers Rex Davis ---none--- + 170 BICC David A. Brown fzbicdb@uk.ac.ucl + 171 D-Link Systems, Inc. Henry P. Nagai ---none--- + 172 AMP, Inc. Rick Downs ---none--- + 173 Netlink Mauro Zallocco ---none--- + 174 C. Itoh Electronics Larry Davis ---none--- + 175 Sumitomo Electric Industries (SEI) + Kent Tsuno tsuno@sumitomo.com + 176 DHL Systems, Inc. + David B. Gurevich dgurevic@rhubarb.ssf-sys.dhl.com + 177 Network Equipment Technologies Mark Tom marktom@tom.net.com + 178 APTEC Computer Systems Larry Burton ssds!larryb@uunet.UU.NET + 179 Schneider & Koch & Co, Datensysteme GmbH Thomas Ruf tom@rsp.de + 180 Hill Air Force Base Russell G. Wilson rwilson@oodis01.af.mil + 181 ADC Kentrox Bruce Kropp ktxc8!bruce@uunet.UU.NET + 182 Japan Radio Co. Nagayuki Kojima nkojima@lab.nihonmusen.co.jp + 183 Versitron Matt Harris ---none--- + 184 Telecommunication Systems Hugh Lockhart ---none--- + 185 Interphase Gil Widdowson ---none--- + 186 Toshiba Corporation Mike Asagami toshiba@mothra.nts.uci.edu + 187 Clearpoint Research Corp. + 188 Ascom Andrew Smith andrew@hasler.ascom.ch + 189 Fujitsu America Chung Lam ---none--- + 190 NetCom Solutions, Inc. Dale Cabell---none--- + 191 NCR Cheryl Krupczak clefor@secola.columbia.ncr.com + 192 Dr. Materna GmbH Torsten Beyer tb@Materna.de + 193 Ericsson Business Communications Gunnar Nilsson ---none--- + 194 Metaphor Computer Systems Paul Rodwick ---none--- + 195 Patriot Partners Paul Rodwick ---none--- + 196 The Software Group Limited (TSG) + Ragnar Paulson tsgfred!ragnar@uunet.UU.NET + 197 Kalpana, Inc. Anil Bhavnani ---none--- + 198 University of Waterloo + R. J. White snmp-tech@watmath.waterloo.edu + 199 CCL/ITRI + Ming-Perng Chen N100CMP0%TWNITRI1.BITNET@CUNYVM.CUNY.EDU + 200 Coeur Postel Professor Kynikos Special Consultant + 201 Mitsubish Cable Industries, Ltd. Masahiko Hori ---none--- + + + +Reynolds & Postel [Page 138] + +RFC 1700 Assigned Numbers October 1994 + + + 202 SMC Lance Sprung ---none--- + 203 Crescendo Communication, Inc. Prem Jain prem@cres.com + 204 Goodall Software Engineering Doug Goodall goodall@crl.com + 205 Intecom Brad Parke ---none--- + 206 Victoria University of Wellington + Jonathan Stone jonathan@isor.vuw.ac.nz + 207 Allied Telesis, Inc. + Scott Holley SCOTT_CLINTON_HOLLEY@cup.portal.com + 208 Dowty Network Systems A/S Hartvig Ekner hj@dowtyns.dk + 209 Protools Glen Arp ---none--- + 210 Nippon Telegraph and Telephone Corp. + Toshiharu Sugawara sugawara%wink.ntt.jp@RELAY.CS.NET + 211 Fujitsu Limited Ippei Hayashi hayashi@sysrap.cs.fujitsu.co.jp + 212 Network Peripherals Inc. Creighton Chong cchong@fastnet.com + 213 Netronix, Inc. Jacques Roth ---none--- + 214 University of Wisconsin - Madison + Dave Windorski DAVID.WINDORSKI@MAIL.ADMIN.WISC.EDU + 215 NetWorth, Inc. Craig Scott ---none--- + 216 Tandberg Data A/S Harald Hoeg haho%huldra.uucp@nac.no + 217 Technically Elite Concepts, Inc. + Russell S. Dietz Russell_Dietz@Mcimail.com + 218 Labtam Australia Pty. Ltd. + Michael Podhorodecki michael@labtam.oz.au + 219 Republic Telcom Systems, Inc. + Steve Harris rtsc!harris@boulder.Colorado.edu + 220 ADI Systems, Inc. Paul Liu ---none--- + 221 Microwave Bypass Systems, Inc. Tad Artis ---none--- + 222 Pyramid Technology Corp. Richard Rein rein@pyramid.com + 223 Unisys_Corp Lawrence Brow ---none--- + 224 LANOPTICS LTD., Israel + Israel Drori raanan@techunix.technion.ac.il + 225 NKK Corporation J. Yoshida ---none--- + 226 MTrade UK Ltd. Peter Delchiappo ---none--- + 227 Acals Patrick Cheng pcheng@dill.ind.trw.com + 228 ASTEC, Inc. Hiroshi Fujii fujii@astec.co.jp + 229 Delmarva Power John K. Scoggin, Jr. scoggin@delmarva.com + 230 Telematics International, Inc. Kevin Smith ---none--- + 231 Siemens Nixdorf Informations Syteme AG + Gunther Kroenert ---none--- + 232 Compaq + 233 NetManage, Inc. William Dunn netmanage@cup.portal.com + 234 NCSU Computing Center David Joyner david@unity.ncsu.edu + 235 Empirical Tools and Technologies + Karl Auerbach karl@empirical.com + 236 Samsung Group Hong K. Paik paik@samsung.com + 237 Takaoka Electric Mfg. Co., Ltd. + Hidekazu Hagiwara hagiwara@takaoka.takaoka-electric.co.jp + 238 Netrix Systems Corporation Eldon S. Mast esm@netrix.com + + + +Reynolds & Postel [Page 139] + +RFC 1700 Assigned Numbers October 1994 + + + 239 WINDATA Bob Rosenbaum ---none--- + 240 RC International A/S Carl H. Dreyer chd@rci.dk + 241 Netexp Research Henk Boetzkes ---none--- + 242 Internode Systems Pty Ltd + Simon Hackett simon@ucs.adelaide.edu.au + 243 netCS Informationstechnik GmbH + Oliver Korfmacher okorf@bunt.netcs.com + 244 Lantronix Rich Lyman rich@alecto.gordian.com + 245 Avatar Consultants + Kory Hamzeh ames!avatar.com!kory@harvard.harvard.edu + 246 Furukawa Electoric Co. Ltd. + Shoji Fukutomi kddlab!polo.furukawa.co.jp!fuku@uunet.UU.NET + 247 AEG Electrcom R. Nurnberg ---none--- + 248 Richard Hirschmann GmbH & Co. + Heinz Nisi mia@intsun.rus.uni-stuttgart.de + 249 G2R Inc. Khalid Hireche ---none--- + 250 University of Michigan + Tim Howes Tim.Howes@terminator.cc.umich.edu + 251 Netcomm, Ltd. W.R. Maynard-Smith ---none--- + 252 Sable Technology Corporation Rodney Thayer ---none--- + 253 Xerox Edwards E. Reed ipcontact.cin_ops@xerox.com + 254 Conware Computer Consulting GmbH + Michael Sapich sapich@conware.de + 255 Compatible Systems Corp. John Gawf gawf@compatible.com + 256 Scitec Communications Systems Ltd. Stephen Lewis ---none--- + 257 Transarc Corporation Pat Barron Pat_Barron@TRANSARC.COM + 258 Matsushita Electric Industrial Co., Ltd. + Nob Mizuno mizuno@isl.mei.co.jp + 259 ACCTON Technology Don Rooney ---none--- + 260 Star-Tek, Inc. Carl Madison carl@startek.com + 261 Codenoll Tech. Corp. Dan Willie ---none--- + 262 Formation, Inc. Carl Marcinik ---none--- + 263 Seiko Instruments, Inc. (SII) Yasuyoshi Watanabe ---none--- + 264 RCE (Reseaux de Communication d'Entreprise S.A.) + Etienne Baudras-Chardigny ---none--- + 265 Xenocom, Inc. Sean Welch welch@raven.ulowell.edu + 266 KABELRHEYDT Hubert Theissen ---none--- + 267 Systech Computer Corporation + Brian Petry systech!bpetry@uunet.UU.NET + 268 Visual Brian O'Shea bos@visual.com + 269 SDD (Scandinavian Airlines Data Denmark A/S) + Per Futtrup ---none--- + 270 Zenith Electronics Corporation David Lin ---none--- + 271 TELECOM FINLAND Petri Jokela ---none--- + 272 BinTec Computersystems Marc Sheldon ms@BinTec.DE + 273 EUnet Germany Marc Sheldon ms@Germany.EU.net + 274 PictureTel Corporation Oliver Jones oj@pictel.com + 275 Michigan State University Lih-Er Wey WEYLE@msu.edu + + + +Reynolds & Postel [Page 140] + +RFC 1700 Assigned Numbers October 1994 + + + 276 GTE Telecom Incorporated Grant Gifford ---none--- + 277 Cascade Communications Corp. + Chikong Shue alpo!chi@uunet.uu.net + 278 Hitachi Cable, Ltd. Takahiro Asai ---none--- + 279 Olivetti Marco Framba framba@orc.olivetti.com + 280 Vitacom Corporation Parag Rastogi parag@cup.portal.com + 281 INMOS Graham Hudspith gwh@inmos.co.uk + 282 AIC Systems Laboratories Ltd. Glenn Mansfield glenn@aic.co.jp + 283 Cameo Communications, Inc. Alan Brind ---none--- + 284 Diab Data AB Mats Lindstrom mli@diab.se + 285 Olicom A/S Lars Povlsen krus@olicom.dk + 286 Digital-Kienzle Computersystems Hans Jurgen Dorr ---none--- + 287 CSELT(Centro Studi E Laboratori Telecomunicazioni) + Paolo Coppo coppo@cz8700.cselt.stet.it + 288 Electronic Data Systems Mark Holobach holobach@tis.eds.com + 289 McData Corporation Glenn Levitt gpl0363@mcmail.mcdata.com + 290 Harris Corporation David Rhein davidr@ssd.csd.harris.com + 291 Technology Dynamics, Inc. Chip Standifer TDYNAMICS@MCIMAIL.COM + 292 DATAHOUSE Information Systems Ltd. Kim Le ---none--- + 293 DSIR Network Group Tony van der Peet srghtvp@grv.dsir.govt.nz + 294 Texas Instruments Blair Sanders Blair_Sanders@mcimail.com + 295 PlainTree Systems Inc. Paul Chefurka chefurka@plntree.UUCP + 296 Hedemann Software Development + Stefan Hedemann 100015.2504@compuserve.com + 297 Fuji Xerox Co., Ltd. Hiroshi Kume + Kume%KSPB%Fuji_Xerox@tcpgw.netg.ksp.fujixerox.co.jp + 298 Asante Technology Hsiang Ming Ma ---none--- + 299 Stanford University + RL "Bob" Morgan morgan@jessica.stanford.edu + 300 Digital Link Jimmy Tu jimmy@dl.com + 301 Raylan Corporation Mark S. Lewis mlewis@telebit.com + 302 Datacraft Alan Lloyd alan@datacraft.oz + 303 Hughes Keith McCloghrie KZM@HLS.COM + 304 Farallon Computing, Inc. Steven Sweeney ---none--- + 305 GE Information Services Steve Bush sfb@ncoast.org + 306 Gambit Computer Communications Zohar Seigal ---none--- + 307 Livingston Enterprises, Inc. + Steve Willens steve@livingston.com + 308 Star Technologies Jim Miner miner@star.com + 309 Micronics Computers Inc. Darren Croke dc@micronics.com + 310 Basis, Inc. Heidi Stettner heidi@mtxinu.COM + 311 Microsoft John M. Ballard jballard@microsoft.com + 312 US West Advance Technologies + Donna Hopkins dmhopki@uswat.uswest.com + 313 University College London Shaw C. Chuang S.Chuang@cs.ucl.ac.uk + 314 Eastman Kodak Company W. James Colosky wjc@tornado.kodak.com + 315 Network Resources Corporation Kathy Weninger ---none--- + 316 Atlas Telecom Bruce Kropp ktxc8!bruce@uunet.UU.NET + + + +Reynolds & Postel [Page 141] + +RFC 1700 Assigned Numbers October 1994 + + + 317 Bridgeway Umberto Vizcaino ---none--- + 318 American Power Conversion Corp. + Peter C. Yoest apc!yoest@uunet.uu.net + 319 DOE Atmospheric Radiation Measurement Project + Paul Krystosek krystosk@eid.anl.gov + 320 VerSteeg CodeWorks Bill Versteeg bvs@NCR.COM + 321 Verilink Corp Bill Versteeg bvs@NCR.COM + 322 Sybus Corportation Mark T. Dauscher mdauscher@sybus.com + 323 Tekelec Bob Grady ---none--- + 324 NASA Ames Research Cente Nick Cuccia cuccia@nas.nasa.gov + 325 Simon Fraser University Robert Urquhart quipu@sfu.ca + 326 Fore Systems, Inc. Eric Cooper ecc@fore.com + 327 Centrum Communications, Inc. Vince Liu ---none--- + 328 NeXT Computer, Inc. + Lennart Lovstrand Lennart_Lovstrand@NeXT.COM + 329 Netcore, Inc. Skip Morton ---none--- + 330 Northwest Digital Systems Brian Dockter ---none--- + 331 Andrew Corporation Ted Tran ---none--- + 332 DigiBoard Dror Kessler dror@digibd.com + 333 Computer Network Technology Corp. Bob Meierhofer ---none--- + 334 Lotus Development Corp. Bill Flanagan bflanagan@lotus.com + 335 MICOM Communication Corporation + Donna Beatty SYSAD@prime.micom.com + 336 ASCII Corporation Toshiharu Ohno tony-o@ascii.co.jp + 337 PUREDATA Research Tony Baxter tony@puredata.com + 338 NTT DATA Yasuhiro Kohata kohata@rd.nttdata.jp + 339 Empros Systems International David Taylor dtaylor@ems.cdc.ca + 340 Kendall Square Research (KSR) Dave Hudson tdh@uunet.UU.NET + 341 Martin Marietta Energy Systems Gary Haney haneyg@ornl.gov + 342 Network Innovations Pete Grillo pl0143@mail.psi.net + 343 Intel Corporation Brady Orand borand@pcocd2.intel.com + 344 Proxar Ching-Fa Hwang cfh@proxar.com + 345 Epson Research Center Richard Schneider rschneid@epson.com + 346 Fibernet George Sandoval ---none--- + 347 Box Hill Systems Corporation Tim Jones tim@boxhill.com + 348 American Express Travel Related Services + Jeff Carton jcarton@amex-trs.com + 349 Compu-Shack Tomas Vocetka OPLER%CSEARN.bitnet@CUNYVM.CUNY.EDU + 350 Parallan Computer, Inc. Charles Dulin ---none--- + 351 Stratacom Clyde Iwamoto cki@strata.com + 352 Open Networks Engineering, Inc. Russ Blaesing rrb@one.com + 353 ATM Forum Keith McCloghrie KZM@HLS.COM + 354 SSD Management, Inc. Bill Rose ---none--- + 355 Automated Network Management, Inc. Carl Vanderbeek ---none-- + 356 Magnalink Communications Corporation + David E. Kaufman ---none--- + 357 TIL Systems, Ltd. Garry McCracken ---none--- + 358 Skyline Technology, Inc. Don Weir ---none--- + + + +Reynolds & Postel [Page 142] + +RFC 1700 Assigned Numbers October 1994 + + + 359 Nu-Mega Technologies, Inc. Dirk Smith ---none--- + 360 Morgan Stanley & Co. Inc. + Victor Kazdoba vsk@katana.is.morgan.com + 361 Integrated Business Network Michael Bell ---none--- + 362 L & N Technologies, Ltd. Steve Loring ---none--- + 363 Cincinnati Bell Information Systems, Inc. + Deron Meranda dmeranda@cbis.COM + 364 OSCOM International + Farhad Fozdar f_fozdar@fennel.cc.uwa.edu.au + 365 MICROGNOSIS Paul Andon pandon@micrognosis.co.uk + 366 Datapoint Corporation Lee Ziegenhals lcz@sat.datapoint.com + 367 RICOH Co. Ltd. + Toshio Watanabe watanabe@godzilla.rsc.spdd.ricoh.co.jp + 368 Axis Communications AB Martin Gren martin@axis.se + 369 Pacer Software Wayne Tackabury wft@pacersoft.com + 370 Axon Networks Inc. Robin Iddon axon@cix.clink.co.uk + 371 Brixton Systems, Inc. Peter S. Easton easton@brixton.com + 372 GSI Etienne Demailly etienne.demailly@gsi.fr + 373 Tatung Co., Ltd. + Chih-Yi Chen TCCISM1%TWNTTIT.BITNET@pucc.Princeton.EDU + 374 DIS Research LTD. Ray Compton rayc@command.com + 375 Quotron Systems, Inc. + Richard P. Stubbs richard@atd.quotron.com + 376 Dassault Electronique + Olivier J. Caleff caleff@dassault-elec.fr + 377 Corollary, Inc. James L. Gula gula@corollary.com + 378 SEEL, Ltd. Ken Ritchie ---none--- + 379 Lexcel Mike Erlinger mike@lexcel.com + 380 Sophisticated Technologies, Inc. + Bill Parducci 70262.1267@compuserve.com + 381 OST A. Pele ---none--- + 382 Megadata Pty Ltd. Andrew McRae andrew@megadata.mega.oz.au + 383 LLNL Livermore Computer Center + Dan Nessett nessett@ocfmail.ocf.llnl.gov + 384 Dynatech Communications Graham Welling s8000!gcw@uunet.uu.net + 385 Symplex Communications Corp. Cyrus Azar ---none--- + 386 Tribe Computer Works Ken Fujimoto fuji@tribe.com + 387 Taligent, Inc. Lorenzo Aguilar lorenzo@taligent.com + 388 Symbol Technologies, Inc. + John Kramer +1-408-369-2679 jkramer@psd.symbol.com + 389 Lancert Mark Hankin ---none--- + 390 Alantec Paul V. Fries pvf@alantec.com + 391 Ridgeback Solutions + Errol Ginsberg bacchus!zulu!errol@uu2.psi.com + 392 Metrix, Inc. D. Venkatrangan venkat@metrix.com + 393 Excutive Systems/XTree Company + Dale Cabell cabell@smtp.xtree.com + 394 NRL Communication Systems Branch + + + +Reynolds & Postel [Page 143] + +RFC 1700 Assigned Numbers October 1994 + + + R. K. Nair nair@itd.nrl.navy.mil + 395 I.D.E. Corporation Rob Spade ---none--- + 396 Matsushita Electric Works, Ltd. + Claude Huss claude@trc.mew.mei.co.jp + 397 MegaPAC Ian George ---none--- + 398 Pilkington Communication Systems Dave Atkinson ---none--- + 399 Hitachi Computer Products (America), Inc. + Masha Golosovker masha@hicomb.hi.com + 400 METEO FRANCE Remy Giraud Remy.Giraud@meteo.fr + 401 PRC Inc. Jim Noble noble_jim@prc.com + 402 Wal*Mart Stores, Inc. Mike Fitzgerel mlfitzg@wal-mart.com + 403 Nissin Electric Company, Ltd. Aki Komatsuzaki (408) 737-0274 + 404 Distributed Support Information Standard + Mike Migliano + 405 SMDS Interest Group (SIG) + Elysia C. Tan + 406 SolCom Systems Ltd. Hugh Evans 0506 873855 + 407 Bell Atlantic Colin deSa socrates!bm5ld15@bagout.BELL-ATL.COM + 408 Advanced Multiuser Technologies Corporation + 409 Mitsubishi Electric Corporation + Yoshitaka Ogawa + 410 C.O.L. Systems, Inc. Frank Castellucci (914) 277-4312 + 411 University of Auckland + Nevil Brownlee < n.brownlee@aukuni.ac.nz> + 412 Desktop Management Task Force (DMTF) + Dave Perkins + 413 Klever Computers, Inc. Tom Su 408-735-7723 kci@netcom.com + 414 Amdahl Corporation Steve Young sy@uts.admahl.com + 415 JTEC Pty, Ltd. Jan Bartel (02) 809 6933 + 416 Matra Communcation Hong-Loc Nguyen (33.1) 34.60.85.25 + 417 HAL Computer Systems Michael A. Petonic petonic@hal.com + 418 Lawrence Berkeley Laboratory Russ Wright wright@lbl.gov + 419 Dale Computer Corporation Dean Craven 1-800-336-7483 + 420 IPTC, Universitaet of Tuebingen + Andreas J. Haug + 421 Bytex Corporation + Mary Ann Burt + 422 Cogwheel, Inc. Brian Ellis bri@Cogwheel.COM + 423 Lanwan Technologies Thomas Liu (408) 986-8899 + 424 Thomas-Conrad Corporation Karen Boyd 512-836-1935 + 425 TxPort Bill VerSteeg bvs@ver.com + 426 Compex, Inc. Andrew Corlett BDA@ORION.OAC.UCI.EDU + 427 Evergreen Systems, Inc. Bill Grace (415) 897-8888 + 428 HNV, Inc. James R. Simons jrs@denver.ssds.COM + 429 U.S. Robotics, Inc. Chris Rozman chrisr@usr.com + 430 Canada Post Corporation Walter Brown +1 613 722-8843 + 431 Open Systems Solutions, Inc. David Ko davidk@ossi.com + 432 Toronto Stock Exchange Paul Kwan (416) 947-4284 + + + +Reynolds & Postel [Page 144] + +RFC 1700 Assigned Numbers October 1994 + + + 433 MamakosTransSys Consulting + Louis A. Mamakos louie@transsys.com + 434 EICON Vartan Narikian vartan@eicon.qc.ca + 435 Jupiter Systems Russell Leefer rml@jupiter.com + 436 SSTI Philip Calas (33) 61 44 19 51 + 437 Grand Junction Networks Randy Ryals randyr@grandjunction.com + 438 Anasazi, Inc. Chad Larson (chad@anasazi.com) + 439 Edward D. Jones and Company John Caruso (314) 851-3422 + 440 Amnet, Inc. Richard Mak mak@amnet.COM + 441 Chase Research Kevin Gage ---none--- + 442 PEER Networks Randy Presuhn randy@peer.com + 443 Gateway Communications, Inc. Ed Fudurich ---none--- + 444 Peregrine Systems Eric Olinger eric@peregrine.com + 445 Daewoo Telecom SeeYoung Oh oco@scorpio.dwt.co.kr + 446 Norwegian Telecom Research Paul Hoff paalh@brage.nta.no + 447 WilTel Anil Prasad anil_prasad@wiltel.com + 448 Ericsson-Camtec Satish Popat ---none--- + 449 Codex Thomas McGinty ---none--- + 450 Basis Heidi Stettner heidi@mtxinu.COM + 451 AGE Logic Syd Logan syd@age.com + 452 INDE Electronics Gordon Day gday@inde.ubc.ca + 453 ISODE Consortium Steve Kille S.Kille@isode.com + 454 J.I. Case Mike Oswald mike@helios.uwsp.edu + 455 Trillium Jeff Lawrence j_lawrence@trillium.com + 456 Bacchus Inc. Errol Ginsberg bacchus!zulu!errol@uu2.psi.com + 457 MCC Doug Rosenthal rosenthal@mcc.com + 458 Stratus Computer Dave Snay dks@sw.stratus.com + 459 Quotron Richard P. Stubbs richard@atd.quotron.com + 460 Beame & Whiteside Carl Beame beame@ns.bws.com + 461 Cellular Technical Services Greg Hummel ---none--- + 462 Shore Microsystems, Inc. Gordon Elam (309) 229-3009 + 463 Telecommunications Techniques Corp. Tom Nisbet nisbet@tt.com + 464 DNPAP (Technical University Delft) + Jan van Oorschot + 465 Plexcom, Inc. Bruce Miller (805) 522-3333 + 466 Tylink Stavros Mohlulis (508) 285-0033 + 467 Brookhaven National Laboratory + Dave Stampf drs@bach.ccd.bnl.gov + 468 Computer Communication Systems + Gerard Laborde + 469 Norand Corp. Rose Gorrell 319-269-3100 + 470 MUX-LAP Philippe Labrosse 514-735-2741 + 471 Premisys Communications, Inc + Mike MacFaden + 472 Bell South Telecommunications Johnny Walker 205-988-7105 + 473 J. Stainsbury PLC Steve Parker 44-71-921-7550 + 474 Ki Research Inc Toni Barckley 410-290-0355x220 + 475 Wandel and Goltermann Technologies + + + +Reynolds & Postel [Page 145] + +RFC 1700 Assigned Numbers October 1994 + + + David Walters 919-941-5730x4203 + 476 Emerson Computer Power + Roger Draper 714-457-3638 rdraper@cerf.net + 477 Network Software Associates Jeffery Chiao 714-768-4013 + 478 Procter and Gamble Peter Marshall 513-983-1100x5988 + 479 Meridian Technology Corporation + Kenneth B. Denson + 480 QMS, Inc. Bill Lott lott@imagen.com + 481 Network Express Tom Jarema 313-761-5051 ITOH@MSEN.COM + 482 LANcity Corporation Pam Yassini pam@lancity.com + 483 Dayna Communications, Inc. + Sanchaita Datta datta@signus.utah.edu + 484 kn-X Ltd. Sam Lau 44 943 467007 + 485 Sync Research, Inc. Alan Bartky (714) 588-2070 + 486 PremNet Ken Huang HuangK@rimail.interlan.com + 487 SIAC Peter Ripp (212) 383-9061 + 488 New York Stock Exchange Peter Ripp (212) 383-9061 + 489 American Stock Exchange Peter Ripp (212) 383-9061 + 490 FCR Software, Inc. Brad Parker brad@fcr.com + 491 National Medical Care, Inc. Robert Phelan (617) 466-9850 + 492 Dialogue Communication Systemes, S.A. + Klaus Handke +(49) 30 802 24 97 + 493 NorTele Bjorn Kvile +47 2 48 89 90 + 494 Madge Networks, Inc. + Duncan Greatwood dgreatwo@madge.mhs.compuserve.com + 495 Memotec Communications Graham Higgins ghiggins@teleglobe.com + 496 CTON Nick Hennenfent nicholas@cton.com + 497 Leap Technology, Inc. George Economou george@leap.com + 498 General DataComm, Inc. William Meltzer meltzer@gdc.com + 499 ACE Communications, Ltd. Danny On 972-3-570-1423 + 500 Automatic Data Processing (ADP) Alex Rosin (201) 714-3982 + 501 Programa SPRITEL Alberto Martinez + Martinez_Alberto_SPRITEL@euskom.spritel.es + 502 Adacom Aial Haorch 972-4-899-899 + 503 Metrodata Ltd Nick Brown 100022.767@compuserve.com + 504 Ellemtel Telecommunication Systems Laboratories + Richard G Bruvik Richard.Bruvik@eua.ericsson.se + 505 Arizona Public Service Duane Booher DBOOHER@APSC.COM + 506 NETWIZ, Ltd., Emanuel Wind eumzvir@techunix.technion.ac.il + 507 Science and Engineering Research Council (SERC) Paul Kummer + P.Kummer@daresbury.ac.uk + 508 The First Boston Corporation Kevin Chou + csfb1!dbadmin4!kchou@uunet.UU.NET + 509 Hadax Electronics Inc. Marian Kramarczyk + 73477.2731@compuserve.com + 510 VTKK Markku Lamminluoto lamminluoto@vtkes1.vtkk.fi + 511 North Hills Israel Ltd. Carmi Cohen carmi@north.hellnet.org + 512 TECSIEL R. Burlon sr@teculx.tecsiel.it + + + +Reynolds & Postel [Page 146] + +RFC 1700 Assigned Numbers October 1994 + + + 513 Bayerische Motoren Werke (BMW) AG Michael Connolly + mconnolly@net.bmw.de + 514 CNET Technologies Nelson Su 408-954-8000 + 515 MCI Kurt Robohm krobohm@mcimail.com + 516 Human Engineering AG (HEAG) Urs Brunner + ubrunner@clients.switch.ch + 517 FileNet Corporation Joe Raby raby@filenet.com + 518 NFT-Ericsson Kjetil Donasen +47 2 84 24 00 + 519 Dun & Bradstreet Vic Smagovic 908-464-2079 + 520 Intercomputer Communications Brian Kean 513-745-0500x244 + 521 Defense Intelligence Agency + Barry Atkinson DIA-DMS@DDN-CONUS.DDN.MIL + 522 Telesystems SLW Inc. Joe Magony 416-441-9966 + 523 APT Communications David Kloper 301-831-1182 + 524 Delta Airlines Jim Guy 404-715-2948 + 525 California Microwave Kevin Braun 408-720-6520 + 526 Avid Technology Inc Steve Olynyk 508-640-3328 + 527 Integro Advanced Computer Systems + Pascal Turbiez +33-20-08-00-40 + 528 RPTI Chris Shin 886-2-918-3006 + 529 Ascend Communications Inc. Marc Hyman 510-769-6001 + 530 Eden Computer Systems Inc. Louis Brando 305-591-7752 + 531 Kawasaki-Steel Corp + Tomoo Watanabe nrd@info.kawasaki-steel.co.jp + 532 Barclays Malcolm Houghton +44 202 671 212 + 533 B.U.G., Inc. Isao Tateishi tateishi@bug.co.jp + 534 Exide Electronics Brian Hammill hamill@dolphin.exide.com + 535 Superconducting Supercollider Lab. + Carl W. Kalbfleisch cwk@irrational.ssc.gov + 536 Triticom Jim Bales (612) 937-0772 + 537 Universal Instruments Corp. + Tom Dinnel BA06791%BINGVAXA.bitnet@CUNYVM.CUNY.EDU + 538 Information Resources, Inc. Jeff Gear jjg@infores.com + 539 Applied Innovation, Inc. Dean Dayton dean@aicorp.cmhnet.org + 540 Crypto AG Roland Luthi luthi@iis.ethz.ch + 541 Infinite Networks, Ltd. Sean Harding +44 923 710 277 + 542 Rabbit Software Bill Kwan kwan@rabbit.com + 543 Apertus Technologies Stuart Stanley stuarts@apertus.com + 544 Equinox Systems, Inc. Monty Norwood 1-800-275-3500 x293 + 545 Hayes Microcomputer Products + Chris Roussel hayes!hayes.com!croussel@uunet.UU.NET + 546 Empire Technologies Inc. Cheryl Krupczak cheryl@cc.gatech.edu + 547 Glaxochem, Ltd. Andy Wilson 0229 52261547 + 548 KPY Network Partners, Corp. + Gordon Vickers sccs@pizza.netcom.com + 549 Agent Technology, Inc. Ibi Dhilla idhilla@genesis.nred.ma.us + 550 Dornier GMBH Arens Heinrech 49-7545-8 ext 9337 + 551 Telxon Corporation Frank Ciotti frankc@teleng.telxon.com + + + +Reynolds & Postel [Page 147] + +RFC 1700 Assigned Numbers October 1994 + + + 552 Entergy Corporation Louis Cureau 504-364-7630 + 553 Garrett Communications Inc. Igor Khasin (408) 980-9752 + 554 Agile Networks, Inc. Dave Donegan ddonegan@agile.com + 555 Larscom Sameer Jayakar 415-969-7572 + 556 Stock Equipment Karl Klebenow 216-543-6000 + 557 ITT Corporation Kevin M. McCauley kmm@vaxf.acdnj.itt.com + 558 Universal Data Systems, Inc. + Howard Cunningham 70400.3671@compuserve.com + 559 Sonix Communications, Ltd. David Webster +44 285 641 651 + 560 Paul Freeman Associates, Inc. + Pete Wilson pwilson@world.std.com + 561 John S. Barnes, Corp. Michael Lynch 704-878-4107 + 562 Northern Telecom, Ltd. + Glenn Waters 613-763-3933 + 563 CAP Debris Patrick Preuss ppr@lfs.hamburg.cap-debris.de + 564 Telco Systems NAC Harry Hirani Harry@telco-nac.com + 565 Tosco Refining Co Fred Sanderson 510-602-4358 + 566 Russell Info Sys Atul Desai 714-362-4040 + 567 University of Salford Richard Letts R.J.Letts@salford.ac.uk + 568 NetQuest Corp. Jerry Jacobus netquest@tigger.jvnc.net + 569 Armon Networking Ltd. Yigal Jacoby yigal@armon.hellnet.org + 570 IA Corporation Didier Fort Didier.Fort@lia.com + 571 AU-System Communicaton AB Torbjorn Ryding 8-7267572 + 572 GoldStar Information & Communications, Ltd. + Soo N. Kim ksn@giconet.gsic.co.kr + 573 SECTRA AB Tommy Pedersen tcp@sectra.se + 574 ONEAC Corporation Bill Elliot ONEACWRE@AOL.COM + 575 Tree Technologies Michael Demjanenko (716) 688-4640 + 576 GTE Government Systems Henry Hernandez (617) 455-2942 + 577 Denmac Systems, Inc. Andy Denenberg (708) 291-7760 + 578 Interlink Computer Sciences, Inc. + Mike Mazurek mfm@interlink.com + 579 Bridge Information Systems, Inc. Stephen Harvey (314) 567-8482 + 580 Leeds and Northrup Australia (LNA) Nigel Cook nigelc@lna.oz.au + 581 BHA Computer David Hislop rob@bha.oz.au + 582 Newport Systems Solutions, Inc. + Pauline Chen paulinec@netcom.com + 583 Atrium Technologies Narender Reddy Vangati vnr@atrium.com + 584 ROBOTIKER Maribel Narganes maribel@teletek.es + 585 PeerLogic Inc. Ratinder Ahuja ratinder@peerlogic.com + 586 Digital Transmittion Systems Bill VerSteeg bvs@ver.com + 587 Far Point Communications Bill VerSteeg bvs@ver.com + 588 Xircom Bill VerSteeg bvs@ver.com + 589 Mead Data Central Stephanie Bowman steph@meaddata.com + 590 Royal Bank of Canada N. Lim (416) 348-5197 + 591 Advantis, Inc. Janet Brehm 813 878-4298 + 592 Chemical Banking Corp. Paul McDonnell pmcdonnl@world.std.com + 593 Eagle Technology Ted Haynes (408) 441-4043 + + + +Reynolds & Postel [Page 148] + +RFC 1700 Assigned Numbers October 1994 + + + 594 British Telecom Ray Smyth rsmyth@bfsec.bt.co.uk + 595 Radix BV P. Groenendaal project2@radix.nl + 596 TAINET Communication System Corp. + Joseph Chen +886-2-6583000 (R.O.C.) + 597 Comtek Services Inc. Steve Harris (703) 506-9556 + 598 Fair Issac Steve Pasadis apple.com!fico!sxp (415) 472-2211 + 599 AST Research Inc. Bob Beard bobb@ast.com + 600 Soft*Star s.r.l. Ing. Enrico Badella softstar@pol88a.polito.it + 601 Bancomm Joe Fontes jwf@bancomm.com + 602 Trusted Information Systems, Inc. + James M. Galvin galvin@tis.com + 603 Harris & Jeffries, Inc. Deepak Shahane hjinc@CERF.NET + 604 Axel Technology Corp. Henry Ngai (714) 455-1688 + 605 GN Navtel, Inc. Joe Magony 416-479-8090 + 606 CAP debis Patrick Preuss +49 40 527 28 366 + 607 Lachman Technology, Inc. Steve Alexander stevea@lachman.com + 608 Galcom Networking Ltd. + Zeev Greenblatt galnet@vax.trendline.co.il + 609 BAZIS M. van Luijt martin@bazis.nl + 610 SYNAPTEL Eric Remond remond@synaptel.fr + 611 Investment Management Services, Inc. + J. Laurens Troost rens@stimpys.imsi.com + 612 Taiwan Telecommunication Lab + Dennis Tseng LOUIS%TWNMOCTL.BITNET@pucc.Princeton.EDU + 613 Anagram Corporation Michael Demjanenko (716) 688-4640 + 614 Univel John Nunneley jnunnele@univel.com + 615 University of California, San Diego + Arthur Bierer abierer@ucsd.edu + 616 CompuServe Ed Isaacs, Brian Biggs SYSADM@csi.compuserve.com + 617 Telstra - OTC Australia + Peter Hanselmann peterhan@turin.research.otc.com.au + 618 Westinghouse Electric Corp. + Ananth Kupanna ananth@access.digex.com + 619 DGA Ltd. Tom L. Willis twillis@pintu.demon.co.uk + 620 Elegant Communications Inc. + Robert Story Robert.Story@Elegant.COM + 621 Experdata Claude Lubin clubin@expdat.gna.org + 622 Unisource Business Networks Sweden AB + Goran Sterner gsr@tip.net + 623 Molex, Inc. Steven Joffe molex@mcimail.com + 624 Quay Financial Software Mick Fleming mickf@quay.ie + 625 VMX Inc. Joga Ryali joga@vmxi.cerfnet.com + 626 Hypercom, Inc. Noor Chowdhury (602) 548-2113 + 627 University of Guelph Kent Percival Percival@CCS.UoGuelph.CA + 628 DIaLOGIKa Juergen Jungfleisch 0 68 97 9 35-0 + 629 NBASE Switch Communication + Sergiu Rotenstein 75250.1477@compuserve.com + 630 Anchor Datacomm B.V. Erik Snoek sdrierik@diamond.sara.nl + + + +Reynolds & Postel [Page 149] + +RFC 1700 Assigned Numbers October 1994 + + + 631 PACDATA John Reed johnr@hagar.pacdata.com + 632 University of Colorado Evi Nemeth evi@cs.colorado.edu + 633 Tricom Communications Limited + Robert Barrett 0005114429@mcimail.com + 634 Santix Software GmbH + Michael Santifaller santi%mozart@santix.guug.de + 635 FastComm Communications Corp. + Bill Flanagan 70632.1446@compuserve.com + 636 The Georgia Institute of Technology + Michael Mealling michael.mealling@oit.gatech.edu + 637 Alcatel Data Networks + Douglas E. Johnson doug.e.johnson@adn.sprint.com + 638 GTECH Brian Ruptash bar@gtech.com + 639 UNOCAL Corporation Peter Ho ho@unocal.com + 640 First Pacific Network Randy Hamilton 408-703-2763 + 641 Lexmark International Don Wright don@lexmark.com + 642 Qnix Computer Sang Weon, Yoo swyoo@qns.qnix.co.kr + 643 Jigsaw Software Concepts (Pty) Ltd. + Willem van Biljon wvb@itu2.sun.ac.za + 644 VIR, Inc. Mark Cotton (215) 364-7955 + 645 SFA Datacomm Inc. Don Lechthaler lech@world.std.com + 646 SEIKO Telecommunication Systems, Inc. + Lyn T. Robertson (503) 526-5638 + 647 Unified Management Andy Barnhouse (612) 561-4944 + 648 RADLINX Ltd. Ady Lifshes ady%rndi@uunet.uu.net + 649 Microplex Systems Ltd. Henry Lee hyl@microplex.com + 650 Objecta Elektronik & Data AB Johan Finnved jf@objecta.se + 651 Phoenix Microsystems Bill VerSteeg bvs@ver.com + 652 Distributed Systems International, Inc. + Ron Mackey rem@dsiinc.com + 653 Evolving Systems, Inc. Judith C. Bettinger judy@evolving.com + 654 SAT GmbH Walter Eichelburg 100063.74@compuserve.com + 655 CeLAN Technology, Inc. Mark Liu 886--35-772780 + 656 Landmark Systems Corp. + Steve Sonnenberg steves@socrates.umd.edu + 657 Netone Systems Co., Ltd. + YongKui Shao syk@new-news.netone.co.jp + 658 Loral Data Systems Jeff Price jprice@cps070.lds.loral.com + 659 Cellware Broadband Technology Michael Roth mike@cellware.de + 660 Mu-Systems Gaylord Miyata miyata@world.std.com + 661 IMC Networks Corp. Jerry Roby (714) 724-1070 + 662 Octel Communications Corp. Alan Newman (408) 321-5182 + 663 RIT Technologies LTD. Ghiora Drori drori@dcl.hellnet.org + 664 Adtran Jeff Wells 205-971-8000 + 665 PowerPlay Technologies, Inc. Ray Caruso rayman@csn.org + 666 Oki Electric Industry Co., Ltd. + Shigeru Urushibara uru@cs1.cs.oki.co.jp + 667 Specialix International Jeremy Rolls jeremyr@specialix.co.uk + + + +Reynolds & Postel [Page 150] + +RFC 1700 Assigned Numbers October 1994 + + + 668 INESC (Instituto de Engenharia de Sistemas e Computadores) + Pedro Ramalho Carlos prc@inesc.pt + 669 Globalnet Communications Real Barriere (514) 651-6164 + 670 Product Line Engineer SVEC Computer Corp. + Rich Huang msumgr@enya.cc.fcu.edu.tw + 671 Printer Systems Corp. Bill Babson bill@prsys.com + 672 Contec Micro Electronics USA David Sheih (408) 434-6767 + 673 Unix Integration Services Chris Howard chris@uis.com + 674 Dell Computer Corporation Steven Blair sblair@dell.com + 675 Whittaker Electronic Systems Michael McCune mccune@cerf.net + 676 QPSX Communications David Pascoe davidp@qpsx.oz.au + 677 Loral WDl Mike Aronson Mike_Aronson@msgate.wdl.loral.com + 678 Federal Express Corp. Randy Hale (901) 369-2152 + 679 E-COMMS Inc. Harvey Teale (206) 857-3399 + 680 Software Clearing House Tom Caris ca@sch.com + 681 Antlow Computers LTD. C. R. Bates 44-635-871829 + 682 Emcom Corp. Mike Swartz emcom@cerf.net + 683 Extended Systems, Inc. + Al Youngwerth alberty@tommy.extendsys.com + 684 Sola Electric Mike Paulsen (708) 439-2800 + 685 Esix Systems, Inc. Anthony Chung esix@esix.tony.com + 686 3M/MMM Chris Amley ccamley@mmm.com + 687 Cylink Corp. Ed Chou ed@cylink.com + 688 Znyx Advanced Systems Division, Inc. + Alan Deikman aland@netcom.com + 689 Texaco, Inc. Jeff Lin linj@Texaco.com + 690 McCaw Cellular Communication Corp. Tri Phan tri.phan@mccaw.com + 691 ASP Computer Product Inc. Elise Moss 71053.1066@compuserve.com + 692 HiPerformance Systems Mike Brien +27-11-806-1000 + 693 Regionales Rechenzentrum + Sibylle Schweizer unrz54@daphne.rrze.uni-erlangen.de + 694 SAP AG Dr. Uwe Hommel +49 62 27 34 0 + 695 ElectroSpace System Inc. + Dr. Joseph Cleveland e03353@esitx.esi.org + 696 ( Unassigned ) + 697 MultiPort Software Reuben Sivan 72302.3262@compuserve.com + 698 Combinet, Inc. Samir Sawhney samir@combinet.com + 699 TSCC Carl Wist carlw@tscc.com + 700 Teleos Communications Inc. Bill Nayavich wln@teleoscom.com + 701 Alta Research Amy Saperstein (305) 428-8535 + 702 Independence Blue Cross Bill Eshbach esh@ibx.com + 703 ADACOM Station Interconnectivity LTD. + Itay Kariv +9 72 48 99 89 9 + 704 MIROR Systems Frank Kloes +27 12 911 0003 + 705 Merlin Gerin Adam Stolinski (714) 557-1637 x249 + 706 Owen-Corning Fiberglas Tom Mann mann.td@ocf.compuserve.com + 707 Talking Networks Inc. Terry Braun tab@lwt.mtxinu.com + 708 Cubix Corporation Rebekah Marshall (702) 883-7611 + + + +Reynolds & Postel [Page 151] + +RFC 1700 Assigned Numbers October 1994 + + + 709 Formation Inc. Bob Millis bobm@formail.formation.com + 710 Lannair Ltd. Pablo Brenner pablo@lannet.com + 711 LightStream Corp. Chris Chiotasso chris@lightstream.com + 712 LANart Corp. Doron I. Gartner doron@lanart.com + 713 University of Stellenbosch Graham Phillips phil@cs.sun.ac.za + 714 Wyse Technology Bill Rainey bill@wyse.com + 715 DSC Communications Corp. Colm Bergin cbergin@cpdsc.com + 716 NetEc Thomas Krichel netec@uts.mcc.ac.uk + 717 Breltenbach Software Engineering Hilmar Tuneke +02 92 49 70 00 + 718 Victor Company of Japan,Limited + Atsushi Sakamoto 101176.2703@compuserve.com + 719 Japan Direx Corporation Teruo Tomiyama +81 3 3498 5050 + 720 NECSY Network Control Systems S.p.A. Piero Fiozzo fip@necsy.it + 721 ISDN Systems Corp. Jeff Milloy p00633@psilink.com + 722 Zero-One Technologies, LTD. Curt Chen + 88 62 56 52 32 33 + 723 Radix Technologies, Inc. Steve Giles giless@delphi.com + 724 National Institute of Standards and Technology + Jim West west@mgmt3.ncsl.nist.gov + 725 Digital Technology Inc. Chris Gianattasio gto@lanhawk.com + 726 Castelle Corp. Waiming Mok wmm@castelle.com + 727 Presticom Inc. Martin Dube 76270.2672@compuserve.com + 728 Showa Electric Wire & Cable Co., Ltd. + Robert O'Grady kfn@tanuki.twics.co.jp + 729 SpectraGraphics Jack Hinkle hinkle@spectra.com + 730 Connectware Inc. Rick Downs rxd4@acsysinc.com + 731 Wind River Systems Emily Hipp hipp@wrs.com + 732 RADWAY International Ltd. Doron Kolton 0005367977@mcimail.com + 733 System Management ARTS, Inc. Alexander Dupuy dupuy@smarts.com + 734 Persoft, Inc. Steven M. Entine entine@pervax.persoft.com + 735 Xnet Technology Inc. Esther Chung estchung@xnet-tech.com + 736 Unison-Tymlabs Dean Andrews ada@unison.com + 737 Micro-Matic Research Patrick Lemli 73677.2373@compuserve.com + 738 B.A.T.M. Advance Technologies + Nahum Killim bcrystal@actcom.co.il + 739 University of Copenhagen Kim H|glund shotokan@diku.dk + 740 Network Security Systems, Inc. + Carleton Smith rpitt@nic.cerf.net + 741 JNA Telecommunications Sean Cody seanc@jna.com.au + 742 Encore Computer Corporation Tony Shafer tshafer@encore.com + 743 Central Intelligent Agency Carol Jobusch 703 242-2485 + 744 ISC (GB) Limited Mike Townsend miket@cix.compulink.co.uk + 745 Digital Communication Associates Ravi Shankar shankarr@dca.com + 746 CyberMedia Inc. Unni Warrier unni@cs.ucla.edu + 747 Distributed Systems International, Inc. + Ron Mackey rem@dsiinc.com + 748 Peter Radig EDP-Consulting Peter Radig +49 69 9757 6100 + 749 Vicorp Interactive Systems Phil Romine phil@vis.com + 750 Inet Inc. Bennie Lopez brl@inetinc.com + + + +Reynolds & Postel [Page 152] + +RFC 1700 Assigned Numbers October 1994 + + + 751 Argonne National Laboratory Michael Shaffer mashaffer@anl.gov + 752 Tek Logix Peter Palsall 905 625-4121 + 753 North Western University Phil Draughon jpd@nwu.edu + 754 Astarte Fiber Networks James Garnett garnett@catbelly.com + 755 Diederich & Associates, Inc. + Douglas Capitano dlcapitano@delphi.com + 756 Florida Power Corporation Bob England rengland@fpc.com + 757 ASK/INGRES Howard Dernehl howard@ingres.com + 758 Open Network Enterprise Spada Stefano +39 39 245-8101 + 759 The Home Depot Keith Porter ktp01@homedepot.com + 760 Pan Dacom Telekommunikations Jens Andresen +49 40 644 09 71 + 761 NetTek Steve Kennedy steve@gbnet.com + 762 Karlnet Corp. Doug Kall kbridge@osu.edu + 763 Efficient Networks, Inc. Thirl Johnson (214) 991-3884 + 764 Fiberdata Jan Fernquist +46 828 8383 + 765 Lanser Emil Smilovici (514) 485-7104 + 766 Telebit Communications A/S Peder Chr. Norgaard pcn@tbit.dk + 767 HILAN GmbH Markus Pestinger markus@lahar.ka.sub.org + 768 Network Computing Inc. + Fredrik Noon fnoon@ncimail.mhs.compuserve.com + 769 Walgreens Company Denis Renaud (708) 818-4662 + 770 Internet Initiative Japan Inc. Toshiharu Ohno tony-o@iij.ad.jp + 771 GP van Niekerk Ondernemings + Gerrit van Niekerk gvanniek@dos-lan.cs.up.ac.za + 772 DSP & Telecoms Research Group + Patrick McGleenon p.mcgleenon@ee.queens-belfast.ac.uk + 773 Securities Industry Automation Corporation + Chiu Szeto cszeto@prism.poly.edu + 774 SYNaPTICS David Gray david@synaptics.ie + 775 Data Switch Corporation Joe Welfeld jwelfeld@dasw.com + 776 Telindus Distribution Karel Van den Bogaert kava@telindus.be + 777 MAXM Systems Corporation Gary Greathouse ggreathouse@maxm.com + 778 Fraunhofer Gesellschaft + Jan Gottschick jan.gottschick@isst.fhg.de + 779 EQS Business Services Ken Roberts kroberts@esq.com + 780 CNet Technology Inc. Repus Hsiung idps17@shts.seed.net.tw + 781 Datentechnik GmbH Thomas Pischinger +43 1 50100 266 + 782 Network Solutions Inc. Dave Putman davep@netsol.com + 783 Viaman Software Vikram Duvvoori info@viman.com + 784 Schweizerische Bankgesellschaft Zuerich + Roland Bernet Roland.Bernet@zh014.ubs.ubs.ch + 785 University of Twente - TIOS Aiko Pras pras@cs.utwente.nl + 786 Simplesoft Inc. Sudhir Pendse sudhir@netcom.com + 787 Stony Brook, Inc. Ken Packert p01006@psilink.com + 788 Unified Systems Solutions, Inc. + Steven Morgenthal smorgenthal@attmail.com + 789 Network Appliance Corporation + Varun Mehta varun@butch.netapp.com + + + +Reynolds & Postel [Page 153] + +RFC 1700 Assigned Numbers October 1994 + + + 790 Ornet Data Communication Technologies Ltd. + Haim Kurz haim@ornet.co.il + 791 Computer Associates International + Glenn Gianino giagl01@usildaca.cai.com + 792 Multipoint Network Inc. Michael Nguyen mike@multipoint.com + 793 NYNEX Science & Technology Lily Lau llau@nynexst.com + 794 Commercial Link Systems Wiljo Heinen wiljo@freeside.cls.de + 795 Adaptec Inc. Tom Battle tab@lwt.mtxinu.com + 796 Softswitch Charles Springer cjs@ssw.com + 797 Link Technologies, Inc. Roy Chu royc@wyse.com + 798 IIS Olry Rappaport iishaifa@attmail.com + 799 Mobile Solutions Inc. Dale Shelton dshelton@srg.srg.af.mil + 800 Xylan Corp. Burt Cyr burt@xylan.com + 801 Airtech Software Forge Limited + Callum Paterson tsf@cix.compulink.co.uk + 802 National Semiconductor Maurice Turcotte mturc@atlanta.nsc.com + 803 Video Lottery Technologies Angelo Lovisa ange@awd.cdc.com + 804 National Semiconductor Corp Waychi Doo wcd@berlioz.nsc.com + 805 Applications Management Corp + Terril (Terry) Steichen tjs@washington.ssds.com + 806 Travelers Insurance Company Eric Miner ustrv67v@ibmmail.com + 807 Taiwan International Standard Electronics Ltd. + B. J. Chen bjchen@taisel.com.tw + 808 US Patent and Trademark Office Rick Randall randall@uspto.gov + 809 Hynet, LTD. Amir Fuhrmann amf@teleop.co.il + 810 Aydin, Corp. Rick Veher (215) 657-8600 + 811 ADDTRON Technology Co., LTD. Tommy Tasi +8 86-2-4514507 + 812 Fannie Mae David King s4ujdk@fnma.com + 813 MultiNET Services Hubert Martens martens@multinet.de + 814 GECKO mbH Holger Dopp hdo@gecko.de + 815 Memorex Telex Mike Hill hill@raleng.mtc.com + 816 Advanced Communications Networks (ACN) SA + Antoine Boss +41 38 247434 + 817 Telekurs AG Jeremy Brookfield bkj@iris.F2.telekurs.ch + 818 Victron bv Jack Stiekema jack@victron.nl + 819 CF6 Company Francois Caron +331 4696 0060 + 820 Walker Richer and Quinn Inc. + Rebecca Higgins rebecca@elmer.wrq.com + 821 Saturn Systems Paul Parker paul_parker@parker.fac.cs.cmu.edu + 822 Mitsui Marine and Fire Insurance Co. LTD. + Kijuro Ikeda +813 5389 8111 + 823 Loop Telecommunication International, Inc. + Charng-Show Li +886 35 787 696 + 824 Telenex Corporation James Krug (609) 866-1100 + 825 Bus-Tech, Inc. Charlie Zhang chun@eecs.cory.berkley.edu + 826 ATRIE Fred B.R. Tuang cmp@fddi3.ccl.itri.org.tw + 827 Gallagher & Robertson A/S Arild Braathen arild@gar.no + 828 Networks Northwest, Inc. John J. Hansen jhansen@networksnw.com + + + +Reynolds & Postel [Page 154] + +RFC 1700 Assigned Numbers October 1994 + + + 829 Conner Peripherials Richard Boyd rboyd@mailserver.conner.com + 830 Elf Antar France P. Noblanc +33 1 47 44 45 46 + 831 Lloyd Internetworking Glenn McGregor glenn@lloyd.com + 832 Datatec Industries, Inc. Chris Wiener cwiener@datatec.com + 833 TAICOM Scott Tseng cmp@fddi3.ccl.itri.org.tw + 834 Brown's Operating System Services Ltd. + Alistair Bell alistair@ichthya.demon.co.uk + 835 MiLAN Technology Corp. Gopal Hegde gopal@milan.com + 836 NetEdge Systems, Inc. Dave Minnich Dave_Minnich@netedge.com + 837 NetFrame Systems George Mathew george_mathew@netframe.com + 838 Xedia Corporation Colin Kincaid colin%madway.uucp@dmc.com + 839 Pepsi Niraj Katwala niraj@netcom.com + 840 Tricord Systems, Inc. Mark Dillon mdillon@tricord.mn.org + 841 Proxim Inc. Russ Reynolds proxim@netcom.com + 842 Applications Plus, Inc. Joel Estes joele@hp827.applus.com + 843 Pacific Bell Aijaz Asif saasif@srv.PacBell.COM + 844 Supernet Sharon Barkai sharon@supernet.com + 845 TPS-Teleprocessing Systems Manfred Gorr gorr@tpscad.tps.de + 846 Technology Solutions Company Niraj Katwala niraj@netcom.com + 847 Computer Site Technologies Tim Hayes (805) 967-3494 + 848 NetPort Software John Bartas jbartas@sunlight.com + 849 Alon Systems Menachem Szus 70571.1350@compuserve.com + 850 Tripp Lite Lawren Markle 72170.460@compuserve.com + 851 NetComm Limited + Paul Ripamonti paulri@msmail.netcomm.pronet.com + 852 Precision Systems, Inc. (PSI) + Fred Griffin cheryl@empiretech.com + 853 Objective Systems Integrators Ed Reeder Ed.Reeder@osi.com + 854 Simpact Associates Inc. + Robert Patterson bpatterson@dcs.simpact.com + 855 Systems Enhancement Corporation + Steve Held 71165.2156@compuserve.com + 856 Information Integration, Inc. Gina Sun iiii@netcom.com + 857 CETREL S.C. Louis Reinard ssc-re@cetrel.lu + 858 ViaTech Development + Theodore J. Collins III ted.collins@vtdev.mn.org + 859 Olivetti North America Tom Purcell tomp@mail.spk.olivetti.com + 860 WILMA Nikolaus Schaller hns@ldv.e-technik.tu-muenchen.de + 861 ILX Systems Inc. Peter Mezey peterm@ilx.com + 862 Total Peripherals Inc. Mark Ustik (508) 393-1777 + 863 SunNetworks Consultant John Brady jbrady@fedeast.east.sun.com + 864 Arkhon Technologies, Inc. Joe Wang rkhon@nic.cerf.net + 865 Computer Sciences Corporation + George M. Dands dands@sed.csc.com + 866 Philips.TRT Thibault Muchery +33 14128 7000 + 867 Katron Technologies Inc. Robert Kao +88 627 991 064 + 868 Transition Engineering Inc. + Hemant Trivedi hemant@transition.com + + + +Reynolds & Postel [Page 155] + +RFC 1700 Assigned Numbers October 1994 + + + 869 Altos Engineering Applications, Inc. + Wes Weber or Dave Erhart altoseng@netcom.com + 870 Nicecom Ltd. Arik Ramon arik@nicecom.nice.com + 871 Fiskars/Deltec Carl Smith (619) 291-2973 + 872 AVM GmbH Andreas Stockmeier stocki@avm-berlin.de + 873 Comm Vision Richard Havens (408) 923 0301 x22 + 874 Institute for Information Industry + Peter Pan peterpan@pdd.iii.org.tw + 875 Legent Corporation Gary Strohm gstrohm@legent.com + 876 Network Automation Doug Jackson +64 6 285 1711 + 877 NetTech Marshall Sprague marshall@nettech.com + 878 Coman Data Communications Ltd. + Zvi Sasson coman@nms.cc.huji.ac.il + 879 Skattedirektoratet Karl Olav Wroldsen +47 2207 7162 + 880 Client-Server Technologies Timo Metsaportti timo@itf.fi + 881 Societe Internationale de Telecommunications Aeronautiques + Chuck Noren chuck.noren@es.atl.sita.int + 882 Maximum Strategy Inc. Paul Stolle pstolle@maxstrat.com + 883 Integrated Systems, Inc. Michael Zheng mz@isi.com + 884 E-Systems, Melpar Rick Silton rsilton@melpar.esys.com + 885 Reliance Comm/Tec Mark Scott 73422.1740@compuserve.com + 886 Summa Four Inc. Paul Nelson (603) 625-4050 + 887 J & L Information Systems Rex Jackson (818) 709-1778 + 888 Forest Computer Inc. Dave Black dave@forest.com + 889 Palindrome Corp. Jim Gast jgast@palindro.mhs.compuserve.com + 890 ZyXEL Communications Corp. Harry Chou howie@csie.nctu.edu.tw + 891 Network Managers (UK) Ltd, Mark D Dooley mark@netmgrs.co.uk + 892 Sensible Office Systems Inc. Pat Townsend (712) 276-0034 + 893 Informix Software Anthony Daniel anthony@informix.com + 894 Dynatek Communications Howard Linton (703) 490-7205 + 895 Versalynx Corp. Dave Fisler (619) 536-8023 + 896 Potomac Scheduling Communications Company + David Labovitz del@access.digex.net + 897 Sybase Inc. Dave Meldrum meldrum@sybase.com + 898 DiviCom Inc. Eyal Opher eyal@divi.com + 899 Datus elektronische Informationssysteme GmbH + Hubert Mertens marcus@datus.uucp + 900 Matrox Electronic Systems Limited + Marc-Andre Joyal marc-andre.joyal@matrox.com + 901 Digital Products, Inc. Ross Dreyer rdreyer@digprod.com + 902 Scitex Corp. Ltd. Yoav Chalfon yoav_h@ird.scitex.com + 903 RAD Vision Oleg Pogorelik radvis@vax.trendline.co.il + 904 Tran Network Systems Paul Winkeler paulw@revco.com + 905 Scorpion Logic Sean Harding +09 2324 5672 + 906 Inotech Inc. Eric Jacobs (703) 641-0469 + 907 Controlled Power Co. Yu Chin 76500,3160@compuserve.com + 908 Elsag Bailey Incorporate Derek McKearney mckearney@bailey.com + 909 J.P. Morgan Chung Szeto szeto_chung@jpmorgan.com + + + +Reynolds & Postel [Page 156] + +RFC 1700 Assigned Numbers October 1994 + + + 910 Clear Communications Corp. Kurt Hall khall@clear.com + 911 General Technology Inc. Perry Rockwell (407) 242-2733 + 912 Adax Inc. Jory Gessow jory@adax.com + 913 Mtel Technologies, Inc. Jon Robinson 552-3355@mcimail.com + 914 Underscore, Inc. Jeff Schnitzer jds@underscore.com + 915 SerComm Corp. Ben Lin +8 862-577-5400 + 916 Baxter Healthcare Corporation + Joseph Sturonas sturonaj@mpg.mcgawpark.baxter.com + 917 Tellus Technology Ron Cimorelli (510) 498-8500 + 918 Continuous Electron Beam Accelerator Facility + Paul Banta banta@cebaf.gov + 919 Canoga Perkins Margret Siska (818) 718-6300 + 920 R.I.S Technologies Fabrice Lacroix +33 7884 6400 + 921 INFONEX Corp. Kazuhiro Watanabe kazu@infonex.co.jp + 922 WordPerfect Corp. Douglas Eddy eddy@wordperfect.com + 923 NRaD Russ Carleton roccor@netcom.com + 924 Hong Kong Telecommunications Ltd. K. S. Luk +8 52 883 3183 + 925 Signature Systems Doug Goodall goodall@crl.com + 926 Alpha Technologies LTD. Guy Pothiboon (604) 430-8908 + 927 PairGain Technologies, Inc. Ken Huang kenh@pairgain.com + 928 Sonic Systems Sudhakar Ravi sudhakar@sonicsys.com + 929 Steinbrecher Corp. Kary Robertson krobertson@delphi.com + 930 Centillion Networks, Inc. Derek Pitcher derek@lanspd.com + 931 Network Communication Corp. + Tracy Clark ncc!central!tracyc@netcomm.attmail.com + 932 Sysnet A.S. Carstein Seeberg case@sysnet.no + 933 Telecommunication Systems Lab Gerald Maguire maguire@it.kth.se + 934 QMI Scott Brickner (410) 573-0013 + 935 Phoenixtec Power Co., LTD. An-Hsiang Tu +8 862 646 3311 + 936 Hirakawa Hewtech Corp. H. Ukaji lde02513@niftyserve.or.jp + 937 No Wires Needed B.V. Arnoud Zwemmer roana@cs.utwente.nl + 938 Primary Access Kerstin Lodman lodman@priacc.com + 939 Enterprises.FDSW Dag Framstad dag.framstad@fdsw.no + 940 Grabner & Kapfer GnbR Vinzenz Grabner zen@wsr.ac.att + 941 Nemesys Research Ltd. Michael Dixon mjd@nemesys.co.uk + 942 Pacific Communication Sciences, Inc. (PSCI) + Yvonne Kammer mib-contact@pcsi.com + 943 Level One Communications, Inc. + Moshe Kochinski moshek@level1.com + 944 Fast Track, Inc. Andrew H. Dimmick adimmick@world.std.com + 945 Andersen Consulting, OM/NI Practice + Greg Tilford p00919@psilink.com + 946 Bay Technologies Pty Ltd. Paul Simpson pauls@baytech.com.au + 947 Integrated Network Corp. Daniel Joffe wandan@integnet.com + 948 Epoch, Inc. David Haskell deh@epoch.com + 949 Wang Laboratories Inc. Pete Reilley pvr@wiis.wang.com + 950 Polaroid Corp. Sari Germanos sari@temerity.polaroid.com + 951 Sunrise Sierra Gerald Olson (510) 443-1133 + + + +Reynolds & Postel [Page 157] + +RFC 1700 Assigned Numbers October 1994 + + + 952 Silcon Group Bjarne Bonvang +45 75 54 22 55 + 953 Coastcom Donald Pickerel dpickere@netcom.com + 954 4th DIMENSION SOFTWARE LTD. + Thomas Segev/Ely Hofner autumn@zeus.datasrv.co.il + 955 SEIKO SYSTEMS Inc. Kiyoshi Ishida ishi@ssi.co.jp + 956 PERFORM Jean-Hugues Robert +33 42 27 29 32 + 957 TV/COM International Jean Tellier (619) 675-1376 + 958 Network Integration, Inc. + Scott C. Lemon slemon@nii.mhs.compuserve.com + 959 Sola Electric, A Unit of General Signal + Bruce Rhodes 72360,2436@compuserve.com + 960 Gradient Technologies, Inc. Geoff Charron geoff@gradient.com + 961 Tokyo Electric Co., Ltd. A. Akiyama +81 558 76 9606 + 962 Codonics, Inc. Joe Kulig jjk@codonics.com + 963 Delft Technical University Mark Schenk m.schenk@ced.tudelft.nl + 964 Carrier Access Corp. Roger Koenig tomquick@carrier.com + 965 eoncorp Barb Wilson wilsonb@eon.com + 966 Naval Undersea Warfare Center + Mark Lovelace lovelace@mp34.nl.nuwc.navy.mil + 967 AWA Limited Mike Williams +61 28 87 71 11 + 968 Distinct Corp. Tarcisio Pedrotti tarci@distinct.com + 969 National Technical University of Athens + Theodoros Karounos karounos@phgasos.ntua.gr + 970 BGS Systems, Inc. Amr Hafez amr@bgs.com + 971 McCaw Wireless Data Inc. Brian Bailey bbailey@airdata.com + 972 Bekaert Koen De Vleeschauwer kdv@bekaert.com + 973 Epic Data Inc. Vincent Lim vincent_lim@epic.wimsey.com + 974 Prodigy Services Co. Ed Ravin elr@wp.prodigy.com + 975 First Pacific Networks (FPN) Randy Hamilton randy@fpn.com + 976 Xylink Ltd. Bahman Rafatjoo 100117.665@compuserve.com + 977 Relia Technologies Corp. Fred Chen fredc@relia1.relia.com.tw + 978 Legacy Storage Systems Inc. + James Hayes james@lss-chq.mhs.compuserve.com + 979 Digicom, SPA Claudio Biotti +39 3312 0 0122 + 980 Ark Telecom Alan DeMars alan@arktel.com + 981 National Security Agency (NSA) + Cynthia Stewart maedeen@romulus.ncsc.mil + 982 Southwestern Bell Corporation + Brian Bearden bb8840@swuts.sbc.com + 983 Virtual Design Group, Inc. + Chip Standifer 70650.3316@compuserve.com + 984 Rhone Poulenc Olivier Pignault +33 1348 2 4053 + 985 Swiss Bank Corporation Neil Todd toddn@gb.swissbank.com + 986 ATEA N.V. Walter van Brussel p81710@banyan.atea.be + 987 Computer Communications Specialists, Inc. + Carolyn Zimmer cczimmer@crl.com + 988 Object Quest, Inc. Michael L. Kornegay mlk@bir.com + 989 DCL System International, Ltd. Gady Amit gady-a@dcl-see.co.il + + + +Reynolds & Postel [Page 158] + +RFC 1700 Assigned Numbers October 1994 + + + 990 SOLITON SYSTEMS K.K. Masayuki Yamai +81 33356 6091 + 991 U S Software Don Dunstan ussw@netcom.com + 992 Systems Research and Applications Corporation + Todd Herr herrt@smtplink.sra.com + 993 University of Florida Todd Hester todd@circa.ufl.edu + 994 Dantel, Inc. John Litster (209) 292-1111 + 995 Multi-Tech Systems, Inc. Dale Martenson (612) 785-3500 x519 + 996 Softlink Ltd. Moshe Leibovitch softlink@zeus.datasrv.co.il + 997 ProSum Christian Bucari +33.1.4590.6231 + 998 March Systems Consultancy, Ltd. + Ross Wakelin r.wakelin@march.co.uk + 999 Hong Technology, Inc. Walt Milnor brent@oceania.com + 1000 Internet Assigned Numbers Authority iana@isi.edu + 1001 PECO Energy Co. Rick Rioboli u002rdr@peco.com + 1002 United Parcel Service Steve Pollini nrd1sjp@nrd.ups.com + 1003 Storage Dimensions, Inc. Michael Torhan miketorh@xstor.com + 1004 ITV Technologies, Inc. Jacob Chen itv@netcom.com + 1005 TCPSI Victor San Jose Victor.Sanjose@sp1.y-net.es + 1006 Promptus Communications, Inc. Paul Fredette (401) 683-6100 + 1007 Norman Data Defense Systems + Kristian A. Bognaes norman@norman.no + 1008 Pilot Network Services, Inc. Rob Carrade carrade@pilot.net + 1009 Integrated Systems Solutions Corporation + Chris Cowan cc@austin.ibm.com + 1010 SISRO Kamp Alexandre 100074.344@compuserve.com + 1011 NetVantage Kevin Bailey speed@kaiwan.com + 1012 Marconi S.p.A. Giuseppe Grasso gg@relay.marconi.it + 1013 SURECOM Mike S. T. Hsieh +886.25.92232 + 1014 Royal Hong Kong Jockey Club + Edmond Lee 100267.3660@compuserve.com + 1015 Gupta Howard Cohen hcohen@gupta.com + 1016 Tone Software Corporation Neil P. Harkins (714) 991-9460 + 1017 Opus Telecom Pace Willisson pace@blitz.com + 1018 Cogsys Ltd. Niall Teasdale niall@hedgehog.demon.co.uk + 1019 Komatsu, Ltd. Akifumi Katsushima +81 463.22.84.30 + 1020 ROI Systems, Inc Michael Wong (801) 942-1752 + 1021 Lightning Instrumentation SA Mike O'Dowd odowd@lightning.ch + 1022 TimeStep Corp. Stephane Lacelle slacelle@newbridge.com + 1023 INTELSAT Ivan Giron i.giron@intelsat.int + 1024 Network Research Corporation Japan, Ltd. + Tsukasa Ueda 100156.2712@compuserve.com + 1025 Relational Development, Inc. Steven Smith rdi@ins.infonet.net + 1026 Emerald Systems, Corp. Robert A. Evans Jr. (619) 673-2161 x5120 + 1027 Mitel, Corp. Tom Quan tq@software.mitel.com + 1028 Software AG Peter Cohen sagpc@sagus.com + 1029 MillenNet, Inc. Manh Do (510) 770-9390 + 1030 NK-EXA Corp. Ken'ichi Hayami hayami@dst.nk-exa.co.jp + 1031 BMC Software Chris Sharp csharp@patrol.com + + + +Reynolds & Postel [Page 159] + +RFC 1700 Assigned Numbers October 1994 + + + 1032 StarFire Enterprises, Inc. Lew Gaiter lg@starfire.com + 1033 Hybrid Networks, Inc. Doug Muirhead dougm@hybrid.com + 1034 Quantum Software GmbH Thomas Omerzu omerzu@quantum.de + 1035 Openvision Technologies Limited + Andrew Lockhart alockhart@openvision.co.uk + 1036 Healthcare Communications, Inc. (HCI) + Larry Streepy streepy@healthcare.com + 1037 SAIT Systems Hai Dotu +3223.7053.11 + 1038 SAT Mleczko Alain +33.1.4077.1156 + 1039 CompuSci Inc., Bob Berry bberry@compusci.com + 1040 Aim Technology Ganesh Rajappan ganeshr@aim.com + 1041 CIESIN Kalpesh Unadkat kalpesh@ciesin.org + 1042 Systems & Technologies International + Howard Smith ghamex@aol.com + 1043 Israeli Electric Company (IEC) Yoram Harlev yoram@yor.iec.co.il + 1044 Phoenix Wireless Group, Inc. + Gregory M. Buchanan buchanan@pwgi.com + 1045 SWL Bill Kight wkightgrci.com (410) 290.7245 + 1046 nCUBE Greg Thompson gregt@ncube.com + 1047 Cerner, Corp. Dennis Avondet (816) 221.1024 X2432 + 1048 Andersen Consulting Mark Lindberg mlindber@andersen.com + 1049 Lincoln Telephone Company Bob Morrill root@si6000.ltec.com + 1050 Acer Jay Tao jtao@Altos.COM + 1051 Cedros Juergen Haakert +49.2241.9701.80 + 1052 AirAccess Ido Ophir 100274.365@compuserve.com + 1053 Expersoft Corporation David Curtis curtis@expersoft.com + 1054 Eskom Sanjay Lakhani h00161@duvi.eskom.co.za + 1055 SBE, Inc. Vimal Vaidya vimal@sbei.com + 1056 EBS, Inc. Emre Gundogan baroque@ebs.com + 1057 American Computer and Electronics, Corp. + Tom Abraham tha@acec.com + 1058 Syndesis Limited Wil Macaulay wil@syndesis.com + 1059 Isis Distributed Systems, Inc. Ken Chapman kchapman@isis.com + 1060 Priority Call Management Greg Schumacher gregs@world.std.com + 1061 Koelsch & Altmann GmbH + Christian Schreyer 100142.154@compuserve.com + 1062 WIPRO INFOTECH LTD. Chandrashekar Kapse kapse@wipinfo.soft.net + 1063 Controlware Uli Blatz ublatz@cware.de + 1064 Mosaic Software W.van Biljon willem@mosaic.co.za + 1065 Canon Information Systems + Victor Villalpando vvillalp@cisoc.canon.com + 1066 AmericaOnline Andrew R. Scholnick andrew@aol.net + 1067 Whitetree Network Technologies, Inc. + Carl Yang cyang@whitetree.com + 1068 Xetron Corp. Dave Alverson davea@xetron.com + 1069 Target Concepts, Inc. Bill Price bprice@tamu.edu + 1070 DMH Software Yigal Hochberg 72144.3704@compuserve.com + 1071 Innosoft International, Inc. Jeff Allison jeff@innosoft.com + + + +Reynolds & Postel [Page 160] + +RFC 1700 Assigned Numbers October 1994 + + + 1072 Controlware GmbH Uli Blatz ublatz@cware.de + 1073 Telecommunications Industry Association (TIA) + Mike Youngberg mikey@synacom.com + 1074 Boole & Babbage Rami Rubin rami@boole.com + 1075 System Engineering Support, Ltd. Vince Taylor +44 454.614.638 + 1076 SURFnet Ton Verschuren Ton.Verschuren@surfnet.nl + 1077 OpenConnect Systems, Inc. Mark Rensmeyer mrensme@oc.com + 1078 PDTS (Process Data Technology and Systems) + Martin Gutenbrunner GUT@pdts.mhs.compuserve.com + 1079 Cornet, Inc. Nat Kumar (703) 658-3400 + 1080 NetStar, Inc. John K. Renwick jkr@netstar.com + 1081 Semaphore Communications, Corp. Jimmy Soetarman (408) 980-7766 + 1082 Casio Computer Co., Ltd. Shouzo Ohdate ohdate@casio.co.jp + 1083 CSIR Frikkie Strecker fstreck@marge.mikom.csir.co.za + 1084 APOGEE Communications Olivier Caleff caleff@apogee-com.fr + 1085 Information Management Company Michael D. Liss mliss@imc.com + 1086 Wordlink, Inc. Mike Aleckson (314) 878-1422 + 1087 PEER Avinash S. Rao arao@cranel.com + 1088 Telstra Corp. Michael Scollay michaels@ind.tansu.com.au + 1089 Net X, Inc. Sridhar Kodela techsupp@netx.unicomp.net + 1090 PNC PLC Gordon Tees +44 716.061.200 + +To request an assignment of an Enterprise Number send the complete +company name, address, and phone number; and the contact's person +complete name, address, phone number, and email mailbox in an email +message to . + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/enterprise-numbers + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 161] + +RFC 1700 Assigned Numbers October 1994 + + +SGMP Vendor Specific Codes: [obsolete] + + +Prefix: 1,255, + +Decimal Name References +------- ---- ---------- + 0 Reserved [JKR1] + 1 Proteon [JS18] + 2 IBM [JXR] + 3 CMU [SXW] + 4 Unix [MS9] + 5 ACC [AB20] + 6 TWG [MTR] + 7 CAYMAN [BXM2] + 8 NYSERNET [MS9] + 9 cisco [GS2] + 10 BBN [RH6] + 11 Unassigned [JKR1] + 12 MIT [JR35] + 13-254 Unassigned [JKR1] + 255 Reserved [JKR1] + + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/sgmp-vendor-specific- +codes + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 162] + +RFC 1700 Assigned Numbers October 1994 + + +ADDRESS RESOLUTION PROTOCOL PARAMETERS + +The Address Resolution Protocol (ARP) specified in [RFC826] has +several parameters. The assigned values for these parameters are +listed here. + +REVERSE ADDRESS RESOLUTION PROTOCOL OPERATION CODES + +The Reverse Address Resolution Protocol (RARP) specified in [RFC903] +uses the "Reverse" codes below. + +DYNAMIC REVERSE ARP + +The Dynamic Reverse Address Resolution Protocol (DRARP) uses the +"DRARP" codes below. For further information, contact: David Brownell +(suneast!helium!db@Sun.COM). + +INVERSE ADDRESS RESOULUTION PROTOCOL + +The Inverse Address Resolution Protocol (IARP) specified in [RFC1293] +uses the "InARP" codes below. + +Assignments: + +Number Operation Code (op) Reference +------ -------------------------- --------- + 1 REQUEST [RFC826] + 2 REPLY [RFC826] + 3 request Reverse [RFC903] + 4 reply Reverse [RFC903] + 5 DRARP-Request [David Brownell] + 6 DRARP-Reply [David Brownell] + 7 DRARP-Error [David Brownell] + 8 InARP-Request [RFC1293] + 9 InARP-Reply [RFC1293] + 10 ARP-NAK [Mark Laubach] + +Number Hardware Type (hrd) References +------ ----------------------------------- ---------- + 1 Ethernet (10Mb) [JBP] + 2 Experimental Ethernet (3Mb) [JBP] + 3 Amateur Radio AX.25 [PXK] + 4 Proteon ProNET Token Ring [JBP] + 5 Chaos [GXP] + 6 IEEE 802 Networks [JBP] + 7 ARCNET [JBP] + 8 Hyperchannel [JBP] + 9 Lanstar [TU] + + + +Reynolds & Postel [Page 163] + +RFC 1700 Assigned Numbers October 1994 + + + 10 Autonet Short Address [MXB1] + 11 LocalTalk [JKR1] + 12 LocalNet (IBM PCNet or SYTEK LocalNET) [JXM] + 13 Ultra link [RXD2] + 14 SMDS [GXC1] + 15 Frame Relay [AGM] + 16 Asynchronous Transmission Mode (ATM) [JXB2] + 17 HDLC [JBP] + 18 Fibre Channel [Yakov Rekhter] + 19 Asynchronous Transmission Mode (ATM) [Mark Laubach] + 20 Serial Line [JBP] + 21 Asynchronous Transmission Mode (ATM) [MXB1] + +Protocol Type (pro) + +Use the same codes as listed in the section called "Ethernet Numbers +of Interest" (all hardware types use this code set for the protocol +type). + + +REFERENCES + +[RFC826] Plummer, D., "An Ethernet Address Resolution Protocol or + Converting Network Protocol Addresses to 48-bit Ethernet + Addresses for Transmission on Ethernet Hardware", STD 37, RFC + 826, MIT-LCS, November 1982. + +[RFC903] Finlayson, R., Mann, T., Mogul, J., and M. Theimer, "A + Reverse Address Resolution Protocol", STD 38, RFC 903, + Stanford University, June 1984. + +[RFC1293] Bradley, T., and C. Brown, "Inverse Address Resolution + Protocol", RFC 1293, Wellfleet Communications, Inc., + January 1992. + + +PEOPLE + +[AGM] Andy Malis + +[GXC1] George Clapp + +[GXP] Gill Pratt + +[JBP] Jon Postel + +[JKR1] Joyce K. Reynolds + + + + +Reynolds & Postel [Page 164] + +RFC 1700 Assigned Numbers October 1994 + + +[JXM] Joseph Murdock <---none---> + +[MXB1] Mike Burrows + +[PXK] Philip Koch + +[RXD2] Rajiv Dhingra + +[TU] Tom Unger + +[David Brownell] + +[Mark Laubach] + +[Yakov Rekhter] + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/arp-parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 165] + +RFC 1700 Assigned Numbers October 1994 + + +IEEE 802 NUMBERS OF INTEREST + +Some of the networks of all classes are IEEE 802 Networks. These +systems may use a Link Service Access Point (LSAP) field in much the +same way the MILNET uses the "link" field. Further, there is an +extension of the LSAP header called the Sub-Network Access Protocol +(SNAP). + +The IEEE likes to describe numbers in binary in bit transmission +order, which is the opposite of the big-endian order used throughout +the Internet protocol documentation. + + +Assignments: + + Link Service Access Point Description References + ------------------------- ----------- ---------- + IEEE Internet + binary binary decimal + 00000000 00000000 0 Null LSAP [IEEE] + 01000000 00000010 2 Indiv LLC Sublayer Mgt [IEEE] + 11000000 00000011 3 Group LLC Sublayer Mgt [IEEE] + 00100000 00000100 4 SNA Path Control [IEEE] + 01100000 00000110 6 Reserved (DOD IP) [RFC768,JBP] + 01110000 00001110 14 PROWAY-LAN [IEEE] + 01110010 01001110 78 EIA-RS 511 [IEEE] + 01111010 01011110 94 ISI IP [JBP] + 01110001 10001110 142 PROWAY-LAN [IEEE] + 01010101 10101010 170 SNAP [IEEE] + 01111111 11111110 254 ISO CLNS IS 8473 [RFC926,JXJ] + 11111111 11111111 255 Global DSAP [IEEE] + +These numbers (and others) are assigned by the IEEE Standards Office. +The address is: + +IEEE Registration Authority +c/o Iris Ringel +IEEE Standards Dept +445 Hoes Lane, P.O. Box 1331 +Piscataway, NJ 08855-1331 +Phone +1 908 562 3813 +Fax: +1 908 562 1571 + +The fee is $1000 and it takes 10 working days after receipt of the +request form and fee. They will not do anything via fax or phone. + +At an ad hoc special session on "IEEE 802 Networks and ARP", held +during the TCP Vendors Workshop (August 1986), an approach to a + + + +Reynolds & Postel [Page 166] + +RFC 1700 Assigned Numbers October 1994 + + +consistent way to send DoD-IP datagrams and other IP related protocols +(such as the Address Resolution Protocol (ARP)) on 802 networks was +developed, using the SNAP extension (see [RFC1042]). + +REFERENCES + +[RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + USC/Information Sciences Institute, August 1980. + +[RFC926] International Standards Organization, "Protocol for Providing + the Connectionless-Mode Network Services", RFC 926, ISO, + December 1984. + +[RFC1042] Postel, J., and J. Reynolds, "A Standard for the + Transmission of IP Datagrams over IEEE 802 Networks", STD + 43, RFC 1042, USC/Information Sciences Institute, February + 1988. + +PEOPLE + +[JBP] Jon Postel + +[JXJ] + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ieee-802-numbers + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 167] + +RFC 1700 Assigned Numbers October 1994 + + +ETHER TYPES + +Many of the networks of all classes are Ethernets (10Mb) or +Experimental Ethernets (3Mb). These systems use a message "type" +field in much the same way the ARPANET uses the "link" field. + +If you need an Ether Type, contact: + +Xerox Systems Institute +3400 Hillview Ave. +PO BOX 10034 +Palo Alto, CA 94303 + +Phone: 415-813-7164 +Contact: Fonda Lix Pallone + +The following list of EtherTypes is contributed unverified information +from various sources. + +Assignments: + +Ethernet Exp. Ethernet Description References +------------- ------------- ----------- ---------- +decimal Hex decimal octal + 000 0000-05DC - - IEEE802.3 Length Field [XEROX] + 257 0101-01FF - - Experimental [XEROX] + 512 0200 512 1000 XEROX PUP (see 0A00) [8,XEROX] + 513 0201 - - PUP Addr Trans (see 0A01)[XEROX] + 0400 Nixdorf [XEROX] + 1536 0600 1536 3000 XEROX NS IDP [133,XEROX] + 0660 DLOG [XEROX] + 0661 DLOG [XEROX] + 2048 0800 513 1001 Internet IP (IPv4) [105,JBP] + 2049 0801 - - X.75 Internet [XEROX] + 2050 0802 - - NBS Internet [XEROX] + 2051 0803 - - ECMA Internet [XEROX] + 2052 0804 - - Chaosnet [XEROX] + 2053 0805 - - X.25 Level 3 [XEROX] + 2054 0806 - - ARP [88,JBP] + 2055 0807 - - XNS Compatability [XEROX] + 2076 081C - - Symbolics Private [DCP1] + 2184 0888-088A - - Xyplex [XEROX] + 2304 0900 - - Ungermann-Bass net debugr[XEROX] + 2560 0A00 - - Xerox IEEE802.3 PUP [XEROX] + 2561 0A01 - - PUP Addr Trans [XEROX] + 2989 0BAD - - Banyan Systems [XEROX] + 4096 1000 - - Berkeley Trailer nego [XEROX] + 4097 1001-100F - - Berkeley Trailer encap/IP[XEROX] + + + +Reynolds & Postel [Page 168] + +RFC 1700 Assigned Numbers October 1994 + + + 5632 1600 - - Valid Systems [XEROX] + 16962 4242 - - PCS Basic Block Protocol [XEROX] + 21000 5208 - - BBN Simnet [XEROX] + 24576 6000 - - DEC Unassigned (Exp.) [XEROX] + 24577 6001 - - DEC MOP Dump/Load [XEROX] + 24578 6002 - - DEC MOP Remote Console [XEROX] + 24579 6003 - - DEC DECNET Phase IV Route[XEROX] + 24580 6004 - - DEC LAT [XEROX] + 24581 6005 - - DEC Diagnostic Protocol [XEROX] + 24582 6006 - - DEC Customer Protocol [XEROX] + 24583 6007 - - DEC LAVC, SCA [XEROX] + 24584 6008-6009 - - DEC Unassigned [XEROX] + 24586 6010-6014 - - 3Com Corporation [XEROX] + 28672 7000 - - Ungermann-Bass download [XEROX] + 28674 7002 - - Ungermann-Bass dia/loop [XEROX] + 28704 7020-7029 - - LRT [XEROX] + 28720 7030 - - Proteon [XEROX] + 28724 7034 - - Cabletron [XEROX] + 32771 8003 - - Cronus VLN [131,DT15] + 32772 8004 - - Cronus Direct [131,DT15] + 32773 8005 - - HP Probe [XEROX] + 32774 8006 - - Nestar [XEROX] + 32776 8008 - - AT&T [XEROX] + 32784 8010 - - Excelan [XEROX] + 32787 8013 - - SGI diagnostics [AXC] + 32788 8014 - - SGI network games [AXC] + 32789 8015 - - SGI reserved [AXC] + 32790 8016 - - SGI bounce server [AXC] + 32793 8019 - - Apollo Computers [XEROX] + 32815 802E - - Tymshare [XEROX] + 32816 802F - - Tigan, Inc. [XEROX] + 32821 8035 - - Reverse ARP [48,JXM] + 32822 8036 - - Aeonic Systems [XEROX] + 32824 8038 - - DEC LANBridge [XEROX] + 32825 8039-803C - - DEC Unassigned [XEROX] + 32829 803D - - DEC Ethernet Encryption [XEROX] + 32830 803E - - DEC Unassigned [XEROX] + 32831 803F - - DEC LAN Traffic Monitor [XEROX] + 32832 8040-8042 - - DEC Unassigned [XEROX] + 32836 8044 - - Planning Research Corp. [XEROX] + 32838 8046 - - AT&T [XEROX] + 32839 8047 - - AT&T [XEROX] + 32841 8049 - - ExperData [XEROX] + 32859 805B - - Stanford V Kernel exp. [XEROX] + 32860 805C - - Stanford V Kernel prod. [XEROX] + 32861 805D - - Evans & Sutherland [XEROX] + 32864 8060 - - Little Machines [XEROX] + 32866 8062 - - Counterpoint Computers [XEROX] + + + +Reynolds & Postel [Page 169] + +RFC 1700 Assigned Numbers October 1994 + + + 32869 8065 - - Univ. of Mass. @ Amherst [XEROX] + 32870 8066 - - Univ. of Mass. @ Amherst [XEROX] + 32871 8067 - - Veeco Integrated Auto. [XEROX] + 32872 8068 - - General Dynamics [XEROX] + 32873 8069 - - AT&T [XEROX] + 32874 806A - - Autophon [XEROX] + 32876 806C - - ComDesign [XEROX] + 32877 806D - - Computgraphic Corp. [XEROX] + 32878 806E-8077 - - Landmark Graphics Corp. [XEROX] + 32890 807A - - Matra [XEROX] + 32891 807B - - Dansk Data Elektronik [XEROX] + 32892 807C - - Merit Internodal [HWB] + 32893 807D-807F - - Vitalink Communications [XEROX] + 32896 8080 - - Vitalink TransLAN III [XEROX] + 32897 8081-8083 - - Counterpoint Computers [XEROX] + 32923 809B - - Appletalk [XEROX] + 32924 809C-809E - - Datability [XEROX] + 32927 809F - - Spider Systems Ltd. [XEROX] + 32931 80A3 - - Nixdorf Computers [XEROX] + 32932 80A4-80B3 - - Siemens Gammasonics Inc. [XEROX] + 32960 80C0-80C3 - - DCA Data Exchange Cluster[XEROX] + 80C4 Banyan Systems [XEROX] + 80C5 Banyan Systems [XEROX] + 32966 80C6 - - Pacer Software [XEROX] + 32967 80C7 - - Applitek Corporation [XEROX] + 32968 80C8-80CC - - Intergraph Corporation [XEROX] + 32973 80CD-80CE - - Harris Corporation [XEROX] + 32975 80CF-80D2 - - Taylor Instrument [XEROX] + 32979 80D3-80D4 - - Rosemount Corporation [XEROX] + 32981 80D5 - - IBM SNA Service on Ether [XEROX] + 32989 80DD - - Varian Associates [XEROX] + 32990 80DE-80DF - - Integrated Solutions TRFS[XEROX] + 32992 80E0-80E3 - - Allen-Bradley [XEROX] + 32996 80E4-80F0 - - Datability [XEROX] + 33010 80F2 - - Retix [XEROX] + 33011 80F3 - - AppleTalk AARP (Kinetics)[XEROX] + 33012 80F4-80F5 - - Kinetics [XEROX] + 33015 80F7 - - Apollo Computer [XEROX] + 33023 80FF-8103 - - Wellfleet Communications [XEROX] + 33031 8107-8109 - - Symbolics Private [XEROX] + 33072 8130 - - Hayes Microcomputers [XEROX] + 33073 8131 - - VG Laboratory Systems [XEROX] + 8132-8136 Bridge Communications [XEROX] + 33079 8137-8138 - - Novell, Inc. [XEROX] + 33081 8139-813D - - KTI [XEROX] + 8148 Logicraft [XEROX] + 8149 Network Computing Devices[XEROX] + 814A Alpha Micro [XEROX] + + + +Reynolds & Postel [Page 170] + +RFC 1700 Assigned Numbers October 1994 + + + 33100 814C - - SNMP [JKR1] + 814D BIIN [XEROX] + 814E BIIN [XEROX] + 814F Technically Elite Concept[XEROX] + 8150 Rational Corp [XEROX] + 8151-8153 Qualcomm [XEROX] + 815C-815E Computer Protocol Pty Ltd[XEROX] + 8164-8166 Charles River Data System[XEROX] + 817D-818C Protocol Engines [XEROX] + 818D Motorola Computer [XEROX] + 819A-81A3 Qualcomm [XEROX] + 81A4 ARAI Bunkichi [XEROX] + 81A5-81AE RAD Network Devices [XEROX] + 81B7-81B9 Xyplex [XEROX] + 81CC-81D5 Apricot Computers [XEROX] + 81D6-81DD Artisoft [XEROX] + 81E6-81EF Polygon [XEROX] + 81F0-81F2 Comsat Labs [XEROX] + 81F3-81F5 SAIC [XEROX] + 81F6-81F8 VG Analytical [XEROX] + 8203-8205 Quantum Software [XEROX] + 8221-8222 Ascom Banking Systems [XEROX] + 823E-8240 Advanced Encryption Syste[XEROX] + 827F-8282 Athena Programming [XEROX] + 8263-826A Charles River Data System[XEROX] + 829A-829B Inst Ind Info Tech [XEROX] + 829C-82AB Taurus Controls [XEROX] + 82AC-8693 Walker Richer & Quinn [XEROX] + 8694-869D Idea Courier [XEROX] + 869E-86A1 Computer Network Tech [XEROX] + 86A3-86AC Gateway Communications [XEROX] + 86DB SECTRA [XEROX] + 86DE Delta Controls [XEROX] + 34543 86DF - - ATOMIC [JBP] + 86E0-86EF Landis & Gyr Powers [XEROX] + 8700-8710 Motorola [XEROX] + 8A96-8A97 Invisible Software [XEROX] + 36864 9000 - - Loopback [XEROX] + 36865 9001 - - 3Com(Bridge) XNS Sys Mgmt[XEROX] + 36866 9002 - - 3Com(Bridge) TCP-IP Sys [XEROX] + 36867 9003 - - 3Com(Bridge) loop detect [XEROX] + 65280 FF00 - - BBN VITAL-LanBridge cache[XEROX] + FF00-FF0F ISC Bunker Ramo [XEROX] + +The standard for transmission of IP datagrams over Ethernets and +Experimental Ethernets is specified in [RFC894] and [RFC895] +respectively. + + + + +Reynolds & Postel [Page 171] + +RFC 1700 Assigned Numbers October 1994 + + +NOTE: Ethernet 48-bit address blocks are assigned by the IEEE. + +IEEE Registration Authority +c/o Iris Ringel +IEEE Standards Department +445 Hoes Lane, P.O. Box 1331 +Piscataway, NJ 08855-1331 +Phone +1 908 562 3813 +Fax: +1 908 562 1571 + + +IANA ETHERNET ADDRESS BLOCK + + +The IANA owns an Ethernet address block which may be used for +multicast address asignments or other special purposes. + +The address block in IEEE binary is: 0000 0000 0000 0000 0111 1010 + +In the normal Internet dotted decimal notation this is 0.0.94 since +the bytes are transmitted higher order first and bits within bytes are +transmitted lower order first (see "Data Notation" in the +Introduction). + +IEEE CSMA/CD and Token Bus bit transmission order: 00 00 5E + +IEEE Token Ring bit transmission order: 00 00 7A + +Appearance on the wire (bits transmitted from left to right): + + + 0 23 47 + | | | + 1000 0000 0000 0000 0111 1010 xxxx xxx0 xxxx xxxx xxxx xxxx + | | + Multicast Bit 0 = Internet Multicast + 1 = Assigned by IANA for + other uses + +Appearance in memory (bits transmitted right-to-left within octets, +octets transmitted left-to-right): + + + 0 23 47 + | | | + 0000 0001 0000 0000 0101 1110 0xxx xxxx xxxx xxxx xxxx xxxx + | | + Multicast Bit 0 = Internet Multicast + + + +Reynolds & Postel [Page 172] + +RFC 1700 Assigned Numbers October 1994 + + + 1 = Assigned by IANA for other uses + +The latter representation corresponds to the Internet standard +bit-order, and is the format that most programmers have to deal with. +Using this representation, the range of Internet Multicast addresses +is: + + + 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF in hex, or + + 1.0.94.0.0.0 to 1.0.94.127.255.255 in dotted decimal + + + +ETHERNET VENDOR ADDRESS COMPONENTS + +Ethernet hardware addresses are 48 bits, expressed as 12 hexadecimal +digits (0-9, plus A-F, capitalized). These 12 hex digits consist of +the first/left 6 digits (which should match the vendor of the Ethernet +interface within the station) and the last/right 6 digits which +specify the interface serial number for that interface vendor. + +Ethernet addresses might be written unhyphenated (e.g., 123456789ABC), +or with one hyphen (e.g., 123456-789ABC), but should be written +hyphenated by octets (e.g., 12-34-56-78-9A-BC). + +These addresses are physical station addresses, not multicast nor +broadcast, so the second hex digit (reading from the left) will be +even, not odd. + +At present, it is not clear how the IEEE assigns Ethernet block +addresses. Whether in blocks of 2**24 or 2**25, and whether +multicasts are assigned with that block or separately. A portion of +the vendor block address is reportedly assigned serially, with the +other portion intentionally assigned randomly. If there is a global +algorithm for which addresses are designated to be physical (in a +chipset) versus logical (assigned in software), or globally-assigned +versus locally-assigned addresses, some of the known addresses do not +follow the scheme (e.g., AA0003; 02xxxx). + +00000C Cisco +00000E Fujitsu +00000F NeXT +000010 Sytek +00001D Cabletron +000020 DIAB (Data Intdustrier AB) +000022 Visual Technology +00002A TRW + + + +Reynolds & Postel [Page 173] + +RFC 1700 Assigned Numbers October 1994 + + +000032 GPT Limited (reassigned from GEC Computers Ltd) +00005A S & Koch +00005E IANA +000065 Network General +00006B MIPS +000077 MIPS +00007A Ardent +000089 Cayman Systems Gatorbox +000093 Proteon +00009F Ameristar Technology +0000A2 Wellfleet +0000A3 Network Application Technology +0000A6 Network General (internal assignment, not for products) +0000A7 NCD X-terminals +0000A9 Network Systems +0000AA Xerox Xerox machines +0000B3 CIMLinc +0000B7 Dove Fastnet +0000BC Allen-Bradley +0000C0 Western Digital +0000C5 Farallon phone net card +0000C6 HP Intelligent Networks Operation (formerly Eon Systems) +0000C8 Altos +0000C9 Emulex Terminal Servers +0000D7 Dartmouth College (NED Router) +0000D8 3Com? Novell? PS/2 +0000DD Gould +0000DE Unigraph +0000E2 Acer Counterpoint +0000EF Alantec +0000FD High Level Hardvare (Orion, UK) +000102 BBN BBN internal usage (not registered) +0020AF 3COM ??? +001700 Kabel +008064 Wyse Technology / Link Technologies +00802B IMAC ??? +00802D Xylogics, Inc. Annex terminal servers +00808C Frontier Software Development +0080C2 IEEE 802.1 Committee +0080D3 Shiva +00AA00 Intel +00DD00 Ungermann-Bass +00DD01 Ungermann-Bass +020701 Racal InterLan +020406 BBN BBN internal usage (not registered) +026086 Satelcom MegaPac (UK) +02608C 3Com IBM PC; Imagen; Valid; Cisco +02CF1F CMC Masscomp; Silicon Graphics; Prime EXL + + + +Reynolds & Postel [Page 174] + +RFC 1700 Assigned Numbers October 1994 + + +080002 3Com (Formerly Bridge) +080003 ACC (Advanced Computer Communications) +080005 Symbolics Symbolics LISP machines +080008 BBN +080009 Hewlett-Packard +08000A Nestar Systems +08000B Unisys +080011 Tektronix, Inc. +080014 Excelan BBN Butterfly, Masscomp, Silicon Graphics +080017 NSC +08001A Data General +08001B Data General +08001E Apollo +080020 Sun Sun machines +080022 NBI +080025 CDC +080026 Norsk Data (Nord) +080027 PCS Computer Systems GmbH +080028 TI Explorer +08002B DEC +08002E Metaphor +08002F Prime Computer Prime 50-Series LHC300 +080036 Intergraph CAE stations +080037 Fujitsu-Xerox +080038 Bull +080039 Spider Systems +080041 DCA Digital Comm. Assoc. +080045 ???? (maybe Xylogics, but they claim not to know this number) +080046 Sony +080047 Sequent +080049 Univation +08004C Encore +08004E BICC +080056 Stanford University +080058 ??? DECsystem-20 +08005A IBM +080067 Comdesign +080068 Ridge +080069 Silicon Graphics +08006E Concurrent Masscomp +080075 DDE (Danish Data Elektronik A/S) +08007C Vitalink TransLAN III +080080 XIOS +080086 Imagen/QMS +080087 Xyplex terminal servers +080089 Kinetics AppleTalk-Ethernet interface +08008B Pyramid +08008D XyVision XyVision machines + + + +Reynolds & Postel [Page 175] + +RFC 1700 Assigned Numbers October 1994 + + +080090 Retix Inc Bridges +484453 HDS ??? +800010 AT&T +AA0000 DEC obsolete +AA0001 DEC obsolete +AA0002 DEC obsolete +AA0003 DEC Global physical address for some DEC machines +AA0004 DEC Local logical address for systems running + DECNET + + +ETHERNET MULTICAST ADDRESSES + +An Ethernet multicast address consists of the multicast bit, the +23-bit vendor component, and the 24-bit group identifier assigned by +the vendor. For example, DEC is assigned the vendor component +08-00-2B, so multicast addresses assigned by DEC have the first +24-bits 09-00-2B (since the multicast bit is the low-order bit of the +first byte, which is "the first bit on the wire"). + + +Ethernet Type +Address Field Usage + +Multicast Addresses: + +01-00-5E-00-00-00- 0800 Internet Multicast [RFC1112] +01-00-5E-7F-FF-FF +01-00-5E-80-00-00- ???? Internet reserved by IANA +01-00-5E-FF-FF-FF +01-80-C2-00-00-00 -802- Spanning tree (for bridges) +09-00-02-04-00-01? 8080? Vitalink printer +09-00-02-04-00-02? 8080? Vitalink management +09-00-09-00-00-01 8005 HP Probe +09-00-09-00-00-01 -802- HP Probe +09-00-09-00-00-04 8005? HP DTC +09-00-1E-00-00-00 8019? Apollo DOMAIN +09-00-2B-00-00-00 6009? DEC MUMPS? +09-00-2B-00-00-01 8039? DEC DSM/DTP? +09-00-2B-00-00-02 803B? DEC VAXELN? +09-00-2B-00-00-03 8038 DEC Lanbridge Traffic Monitor (LTM) +09-00-2B-00-00-04 ???? DEC MAP End System Hello +09-00-2B-00-00-05 ???? DEC MAP Intermediate System Hello +09-00-2B-00-00-06 803D? DEC CSMA/CD Encryption? +09-00-2B-00-00-07 8040? DEC NetBios Emulator? +09-00-2B-00-00-0F 6004 DEC Local Area Transport (LAT) +09-00-2B-00-00-1x ???? DEC Experimental +09-00-2B-01-00-00 8038 DEC LanBridge Copy packets + + + +Reynolds & Postel [Page 176] + +RFC 1700 Assigned Numbers October 1994 + + + (All bridges) +09-00-2B-01-00-01 8038 DEC LanBridge Hello packets + (All local bridges) + 1 packet per second, sent by the + designated LanBridge +09-00-2B-02-00-00 ???? DEC DNA Lev. 2 Routing Layer routers? +09-00-2B-02-01-00 803C? DEC DNA Naming Service Advertisement? +09-00-2B-02-01-01 803C? DEC DNA Naming Service Solicitation? +09-00-2B-02-01-02 803E? DEC DNA Time Service? +09-00-2B-03-xx-xx ???? DEC default filtering by bridges? +09-00-2B-04-00-00 8041? DEC Local Area Sys. Transport (LAST)? +09-00-2B-23-00-00 803A? DEC Argonaut Console? +09-00-4E-00-00-02? 8137? Novell IPX +09-00-56-00-00-00- ???? Stanford reserved +09-00-56-FE-FF-FF +09-00-56-FF-00-00- 805C Stanford V Kernel, version 6.0 +09-00-56-FF-FF-FF +09-00-77-00-00-01 ???? Retix spanning tree bridges +09-00-7C-02-00-05 8080? Vitalink diagnostics +09-00-7C-05-00-01 8080? Vitalink gateway? +0D-1E-15-BA-DD-06 ???? HP +AB-00-00-01-00-00 6001 DEC Maintenance Operation Protocol + (MOP) Dump/Load Assistance +AB-00-00-02-00-00 6002 DEC Maintenance Operation Protocol + (MOP) Remote Console + 1 System ID packet every 8-10 minutes, + by every: + DEC LanBridge + DEC DEUNA interface + DEC DELUA interface + DEC DEQNA interface + (in a certain mode) +AB-00-00-03-00-00 6003 DECNET Phase IV end node Hello + packets 1 packet every 15 seconds, + sent by each DECNET host +AB-00-00-04-00-00 6003 DECNET Phase IV Router Hello packets + 1 packet every 15 seconds, sent by + the DECNET router +AB-00-00-05-00-00 ???? Reserved DEC through +AB-00-03-FF-FF-FF +AB-00-03-00-00-00 6004 DEC Local Area Transport (LAT) - old +AB-00-04-00-xx-xx ???? Reserved DEC customer private use +AB-00-04-01-xx-yy 6007 DEC Local Area VAX Cluster groups + Sys. Communication Architecture (SCA) +CF-00-00-00-00-00 9000 Ethernet Configuration Test protocol + (Loopback) + +Broadcast Address: + + + +Reynolds & Postel [Page 177] + +RFC 1700 Assigned Numbers October 1994 + + +FF-FF-FF-FF-FF-FF 0600 XNS packets, Hello or gateway search? + 6 packets every 15 seconds, per XNS + station +FF-FF-FF-FF-FF-FF 0800 IP (e.g. RWHOD via UDP) as needed +FF-FF-FF-FF-FF-FF 0804 CHAOS +FF-FF-FF-FF-FF-FF 0806 ARP (for IP and CHAOS) as needed +FF-FF-FF-FF-FF-FF 0BAD Banyan +FF-FF-FF-FF-FF-FF 1600 VALID packets, Hello or gateway + search? + 1 packets every 30 seconds, per VALID + station +FF-FF-FF-FF-FF-FF 8035 Reverse ARP +FF-FF-FF-FF-FF-FF 807C Merit Internodal (INP) +FF-FF-FF-FF-FF-FF 809B EtherTalk + + + + +REFERENCES + +[RFC894] Hornig, C., "A Standard for the Transmission of IP Datagrams + over Ethernet Networks, STD 41, RFC 894, Symbolics, + April 1984. + +[RFC895] Postel, J., "A Standard for the Transmission of IP Datagrams + over Experimental Ethernet Networks, STD 42, RFC 895, + USC/Information Sciences Institute, April 1984. + +[RFC1112] Deeering, S., "Host Extensions for IP Multicasting", + STD 5, RFC 1112, Stanford University, August 1989. + +PEOPLE + +[AXC] Andrew Cherenson + +[DCP1] David Plummer + +[DT15] Daniel Tappan + +[HWB] Hans-Werner Braun + +[JBP] Jon Postel + +[JKR1] Joyce K. Reynolds + +[JXM] Joseph Murdock <---none---> + +[XEROX] Fonda Pallone (415-813-7164) + + + +Reynolds & Postel [Page 178] + +RFC 1700 Assigned Numbers October 1994 + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ethernet-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 179] + +RFC 1700 Assigned Numbers October 1994 + + +X.25 TYPE NUMBERS + + +CCITT defines the high order two bits of the first octet of call user +data as follows: + + +00 - Used for other CCITT recomendations (such as X.29) +01 - Reserved for use by "national" administrative + authorities +10 - Reserved for use by international administrative authoorities +11 - Reserved for arbitrary use between consenting DTEs + +Call User Data (hex) Protocol Reference +------------------- -------- --------- + +01 PAD [GS2] +C5 Blacker front-end descr dev [AGM] +CC IP [RFC877,AGM]* +CD ISO-IP [AGM] +CF PPP [RFC1598] +DD Network Monitoring [AGM] + +*NOTE: ISO SC6/WG2 approved assignment in ISO 9577 (January 1990). + + +REFERENCES + +[RFC877] Korb, J., "A Standard for the Transmission of IP Datagrams + Over Public Data Networks", RFC 877, Purdue University, + September 1983. + +[RFC1598] Simpson, W., "PPPin X.25", RFC 1598, Daydreamer, March 1994. + + +PEOPLE + +[AGM] Andy Malis + +[GS2] Greg Satz + +[] + + + + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/x25-type-numbers + + + +Reynolds & Postel [Page 180] + +RFC 1700 Assigned Numbers October 1994 + + +PUBLIC DATA NETWORK NUMBERS + + +One of the Internet Class A Networks is the international system of +Public Data Networks. This section lists the mapping between the +Internet Addresses and the Public Data Network Addresses (X.121). + + +Assignments: + + + Internet Public Data Net Description References + -------------- ----------------- ----------- ---------- + 014.000.000.000 Reserved [JBP] + 014.000.000.001 3110-317-00035 00 PURDUE-TN [TN] + 014.000.000.002 3110-608-00027 00 UWISC-TN [TN] + 014.000.000.003 3110-302-00024 00 UDEL-TN [TN] + 014.000.000.004 2342-192-00149 23 UCL-VTEST [PK] + 014.000.000.005 2342-192-00300 23 UCL-TG [PK] + 014.000.000.006 2342-192-00300 25 UK-SATNET [PK] + 014.000.000.007 3110-608-00024 00 UWISC-IBM [MS56] + 014.000.000.008 3110-213-00045 00 RAND-TN [MO2] + 014.000.000.009 2342-192-00300 23 UCL-CS [PK] + 014.000.000.010 3110-617-00025 00 BBN-VAN-GW [JD21] + 014.000.000.011 2405-015-50300 00 CHALMERS [UXB] + 014.000.000.012 3110-713-00165 00 RICE [PAM6] + 014.000.000.013 3110-415-00261 00 DECWRL [PAM6] + 014.000.000.014 3110-408-00051 00 IBM-SJ [SXA3] + 014.000.000.015 2041-117-01000 00 SHAPE [JFW] + 014.000.000.016 2628-153-90075 00 DFVLR4-X25 [GB7] + 014.000.000.017 3110-213-00032 00 ISI-VAN-GW [JD21] + 014.000.000.018 2624-522-80900 52 FGAN-SIEMENS-X25 [GB7] + 014.000.000.019 2041-170-10000 00 SHAPE-X25 [JFW] + 014.000.000.020 5052-737-20000 50 UQNET [AXH] + 014.000.000.021 3020-801-00057 50 DMC-CRC1 [VXT] + 014.000.000.022 2624-522-80329 02 FGAN-FGANFFMVAX-X25 [GB7] + 014.000.000.023 2624-589-00908 01 ECRC-X25 [PXD] + 014.000.000.024 2342-905-24242 83 UK-MOD-RSRE [JXE2] + 014.000.000.025 2342-905-24242 82 UK-VAN-RSRE [AXM] + 014.000.000.026 2624-522-80329 05 DFVLRSUN-X25 [GB7] + 014.000.000.027 2624-457-11015 90 SELETFMSUN-X25 [BXD] + 014.000.000.028 3110-408-00146 00 CDC-SVL [RAM57] + 014.000.000.029 2222-551-04400 00 SUN-CNUCE [ABB2] + 014.000.000.030 2222-551-04500 00 ICNUCEVM-CNUCE [ABB2] + 014.000.000.031 2222-551-04600 00 SPARE-CNUCE [ABB2] + 014.000.000.032 2222-551-04700 00 ICNUCEVX-CNUCE [ABB2] + 014.000.000.033 2222-551-04524 00 CISCO-CNUCE [ABB2] + 014.000.000.034 2342-313-00260 90 SPIDER-GW [AD67] + + + +Reynolds & Postel [Page 181] + +RFC 1700 Assigned Numbers October 1994 + + + 014.000.000.035 2342-313-00260 91 SPIDER-EXP [AD67] + 014.000.000.036 2342-225-00101 22 PRAXIS-X25A [TXR] + 014.000.000.037 2342-225-00101 23 PRAXIS-X25B [TXR] + 014.000.000.038 2403-712-30250 00 DIAB-TABY-GW [FXB] + 014.000.000.039 2403-715-30100 00 DIAB-LKP-GW [FXB] + 014.000.000.040 2401-881-24038 00 DIAB-TABY1-GW [FXB] + 014.000.000.041 2041-170-10060 00 STC [TC27] + 014.000.000.042 2222-551-00652 60 CNUCE [TC27] + 014.000.000.043 2422-510-05900 00 Tollpost-Globe AS [OXG] + 014.000.000.044 2422-670-08900 00 Tollpost-Globe AS [OXG] + 014.000.000.045 2422-516-01000 00 Tollpost-Globe AS [OXG] + 014.000.000.046 2422-450-00800 00 Tollpost-Globe AS [OXG] + 014.000.000.047 2422-610-00200 00 Tollpost-Globe AS [OXG] + 014.000.000.048 2422-310-00300 00 Tollpost-Globe AS [OXG] + 014.000.000.049 2422-470-08800 00 Tollpost-Globe AS [OXG] + 014.000.000.050 2422-210-04600 00 Tollpost-Globe AS [OXG] + 014.000.000.051 2422-130-28900 00 Tollpost-Globe AS [OXG] + 014.000.000.052 2422-310-27200 00 Tollpost-Globe AS [OXG] + 014.000.000.053 2422-250-05800 00 Tollpost-Globe AS [OXG] + 014.000.000.054 2422-634-05900 00 Tollpost-Globe AS [OXG] + 014.000.000.055 2422-670-08800 00 Tollpost-Globe AS [OXG] + 014.000.000.056 2422-430-07400 00 Tollpost-Globe AS [OXG] + 014.000.000.057 2422-674-07800 00 Tollpost-Globe AS [OXG] + 014.000.000.058 2422-230-16900 00 Tollpost-Globe AS [OXG] + 014.000.000.059 2422-518-02900 00 Tollpost-Globe AS [OXG] + 014.000.000.060 2422-370-03100 00 Tollpost-Globe AS [OXG] + 014.000.000.061 2422-516-03400 00 Tollpost-Globe AS [OXG] + 014.000.000.062 2422-616-04400 00 Tollpost-Globe AS [OXG] + 014.000.000.063 2422-650-23500 00 Tollpost-Globe AS [OXG] + 014.000.000.064 2422-330-02500 00 Tollpost-Globe AS [OXG] + 014.000.000.065 2422-350-01900 00 Tollpost-Globe AS [OXG] + 014.000.000.066 2422-410-00700 00 Tollpost-Globe AS [OXG] + 014.000.000.067 2422-539-06200 00 Tollpost-Globe AS [OXG] + 014.000.000.068 2422-630-07200 00 Tollpost-Globe AS [OXG] + 014.000.000.069 2422-470-12300 00 Tollpost-Globe AS [OXG] + 014.000.000.070 2422-470-13000 00 Tollpost-Globe AS [OXG] + 014.000.000.071 2422-170-04600 00 Tollpost-Globe AS [OXG] + 014.000.000.072 2422-516-04300 00 Tollpost-Globe AS [OXG] + 014.000.000.073 2422-530-00700 00 Tollpost-Globe AS [OXG] + 014.000.000.074 2422-650-18800 00 Tollpost-Globe AS [OXG] + 014.000.000.075 2422-450-24500 00 Tollpost-Globe AS [OXG] + 014.000.000.076 2062-243-15631 00 DPT-BXL-DDC [LZ15] + 014.000.000.077 2062-243-15651 00 DPT-BXL-DDC2 [LZ15] + 014.000.000.078 3110-312-00431 00 DPT-CHI [LZ15] + 014.000.000.079 3110-512-00135 00 DPT-SAT-ENG [LZ15] + 014.000.000.080 2080-941-90550 00 DPT-PAR [LZ15] + 014.000.000.081 4545-511-30600 00 DPT-PBSC [LZ15] + 014.000.000.082 4545-513-30900 00 DPT-HONGKONG [LZ15] + + + +Reynolds & Postel [Page 182] + +RFC 1700 Assigned Numbers October 1994 + + + 014.000.000.083 4872-203-55000 00 UECI-TAIPEI [LZ15] + 014.000.000.084 2624-551-10400 20 DPT-HANOVR [LZ15] + 014.000.000.085 2624-569-00401 99 DPT-FNKFRT [LZ15] + 014.000.000.086 3110-512-00134 00 DPT-SAT-SUPT [LZ15] + 014.000.000.087 4602-3010-0103 20 DU-X25A [JK64] + 014.000.000.088 4602-3010-0103 21 FDU-X25B [JK64] + 014.000.000.089 2422-150-33700 00 Tollpost-Globe AS [OXG] + 014.000.000.090 2422-271-07100 00 Tollpost-Globe AS [OXG] + 014.000.000.091 2422-516-00100 00 Tollpost-Globe AS [OXG] + 014.000.000.092 2422-650-18800 00 Norsk Informas. [OXG] + 014.000.000.093 2422-250-30400 00 Tollpost-Globe AS [OXG] + 014.000.000.094 Leissner Data AB [PXF1] + 014.000.000.095 Leissner Data AB [PXF1] + 014.000.000.096 Leissner Data AB [PXF1] + 014.000.000.097 Leissner Data AB [PXF1] + 014.000.000.098 Leissner Data AB [PXF1] + 014.000.000.099 Leissner Data AB [PXF1] + 014.000.000.100 Leissner Data AB [PXF1] + 014.000.000.101 Leissner Data AB [PXF1] + 014.000.000.102 Leissner Data AB [PXF1] + 014.000.000.103 Leissner Data AB [PXF1] + 014.000.000.104 Leissner Data AB [PXF1] + 014.000.000.105 Leissner Data AB [PXF1] + 014.000.000.106 Leissner Data AB [PXF1] + 014.000.000.107 Leissner Data AB [PXF1] + 014.000.000.108 Leissner Data AB [PXF1] + 014.000.000.109 Leissner Data AB [PXF1] + 014.000.000.110 Leissner Data AB [PXF1] + 014.000.000.111 Leissner Data AB [PXF1] + 014.000.000.112 Leissner Data AB [PXF1] + 014.000.000.113 Leissner Data AB [PXF1] + 014.000.000.114 Leissner Data AB [PXF1] + 014.000.000.115 Leissner Data AB [PXF1] + 014.000.000.116 Leissner Data AB [PXF1] + 014.000.000.117 Leissner Data AB [PXF1] + 014.000.000.118 Leissner Data AB [PXF1] + 014.000.000.119 Leissner Data AB [PXF1] + 014.000.000.120 Leissner Data AB [PXF1] + 014.000.000.121 Leissner Data AB [PXF1] + 014.000.000.122 Leissner Data AB [PXF1] + 014.000.000.123 Leissner Data AB [PXF1] + 014.000.000.124 Leissner Data AB [PXF1] + 014.000.000.125 Leissner Data AB [PXF1] + 014.000.000.126 Leissner Data AB [PXF1] + 014.000.000.127 Leissner Data AB [PXF1] + 014.000.000.128 Leissner Data AB [PXF1] + 014.000.000.129 2422-150-17900 00 Tollpost-Globe AS [OXG] + 014.000.000.130 2422-150-42700 00 Tollpost-Globe AS [OXG] + + + +Reynolds & Postel [Page 183] + +RFC 1700 Assigned Numbers October 1994 + + + 014.000.000.131 2422-190-41900 00 T-G Airfreight AS [OXG] + 014.000.000.132 2422-616-16100 00 Tollpost-Globe AS [OXG] + 014.000.000.133 2422-150-50700-00 Tollpost-Globe Int. [OXG] + 014.000.000.134 2422-190-28100-00 Intersped AS [OXG] + + 014.000.000.135-014.255.255.254 Unassigned [JBP] + 014.255.255.255 Reserved [JBP] + +The standard for transmission of IP datagrams over the Public Data +Network is specified in RFC-1356 [69]. + +REFERENCES + +[RFC877] Korb, J., "A Standard for the Transmission of IP Datagrams + Over Public Data Networks", RFC 877, Purdue University, + September 1983. + + +PEOPLE + +[ABB2] A. Blasco Bonito + +[AD67] Andy Davis + +[AXH] Arthur Harvey + +[AXM] Alex Martin <---none---> + +[BXD] Brian Dockter <---none---> + +[FXB] + +[GB7] Gerd Beling + +[JBP] Jon Postel + +[JFW] Jon F. Wilkes + +[JK64] mystery contact! + +[JXE2] Jeanne Evans + +[LZ15] Lee Ziegenhals + +[MS56] Marvin Solomon + + + + +Reynolds & Postel [Page 184] + +RFC 1700 Assigned Numbers October 1994 + + +[MO2] Michael O'Brien + +[OXG] Oyvind Gjerstad + +[PAM6] Paul McNabb + +[PK] Peter Kirstein + +[PXD] Peter Delchiappo <---none---> + +[PXF1] Per Futtrup <---none---> + +[RAM57] Rex Mann <---none---> + +[SXA3] Sten Andler <---none---> + +[TN] Thomas Narten + +[TC27] Thomas Calderwood + +[TXR] Tim Rylance + +[UXB] + +[VXT] V. Taylor + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/public-data-network- +numbers + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 185] + +RFC 1700 Assigned Numbers October 1994 + + +MILNET LINK NUMBERS + + +The word "link" here refers to a field in the original MILNET Host/IMP +interface leader. The link was originally defined as an 8-bit field. +Later specifications defined this field as the "message-id" with a +length of 12 bits. The name link now refers to the high order 8 bits of +this 12-bit message-id field. The Host/IMP interface is defined in BBN +Report 1822 [BBN1822]. + +The low-order 4 bits of the message-id field are called the sub-link. +Unless explicitly specified otherwise for a particular protocol, there +is no sender to receiver significance to the sub-link. The sender may +use the sub-link in any way he chooses (it is returned in the RFNM by +the destination IMP), the receiver should ignore the sub-link. + + +Link Assignments: + +Decimal Description References +------- ----------- ---------- +0-63 BBNCC Monitoring [MB] +64-149 Unassigned [JBP] +150 Xerox NS IDP [ETHERNET,XEROX] +151 Unassigned [JBP] +152 PARC Universal Protocol [PUP,XEROX] +153 TIP Status Reporting [JGH] +154 TIP Accounting [JGH] +155 Internet Protocol [regular] [RFC791,JBP] +156-158 Internet Protocol [experimental] [RFC791,JBP] +159 Figleaf Link [JBW1] +160 Blacker Local Network Protocol [DM28] +161-194 Unassigned [JBP] +195 ISO-IP [RFC926,RXM] +196-247 Experimental Protocols [JBP] +248-255 Network Maintenance [JGH] + + + +MILNET LOGICAL ADDRESSES + +The MILNET facility for "logical addressing" is described in [RFC878] +and [RFC1005]. A portion of the possible logical addresses are +reserved for standard uses. + +There are 49,152 possible logical host addresses. Of these, 256 are +reserved for assignment to well-known functions. Assignments for +well-known functions are made by the IANA. Assignments for other + + + +Reynolds & Postel [Page 186] + +RFC 1700 Assigned Numbers October 1994 + + +logical host addresses are made by the NIC. + + +Logical Address Assignments: + +Decimal Description References +------- ----------- ---------- +0 Reserved [JBP] +1 The BBN Core Gateways [MB] +2-254 Unassigned [JBP] +255 Reserved [JBP] + + + +MILNET X.25 ADDRESS MAPPINGS + + +All MILNET hosts are assigned addresses by the Defense Data Network +(DDN). The address of a MILNET host may be obtained from the Network +Information Center (NIC), represented as an ASCII text string in what +is called "host table format". This section describes the process by +which MILNET X.25 addresses may be derived from addresses in the NIC +host table format. + +A NIC host table address consists of the ASCII text string +representations of four decimal numbers separated by periods, +corresponding to the four octeted of a thirty-two bit Internet +address. The four decimal numbers are referred to in this section as +"n", "h' "l", and "i". Thus, a host table address may be represented +as: "n.h.l.i". Each of these four numbers will have either one, two, +or three decimal digits and will never have a value greater than 255. +For example, in the host table, address: "10.2.0.124", n=10, h=2, l=0, +and i=124. To convert a host table address to a MILNET X.25 address: + +1. If h < 64, the host table address corresponds to the X.25 +physical address: + + +ZZZZ F IIIHHZZ (SS) + +where: + + ZZZZ = 0000 as required + + F = 0 because the address is a physical address; + + III is a three decimal digit respresentation of + "i", right-adjusted and padded with leading + + + +Reynolds & Postel [Page 187] + +RFC 1700 Assigned Numbers October 1994 + + + zeros if required; + + HH is a two decimal digit representation of "h", + right-adjusted and padded with leading zeros + if required; + + ZZ = 00 and + + (SS) is optional + + +In the example given above, the host table address 10.2.0.124 +corresponds to the X.25 physical address 000001240200. + +2. If h > 64 or h = 64, the host table address corresponds to the +X.25 logical address + + +ZZZZ F RRRRRZZ (SS) + +where: + + ZZZZ = 0000 as required + + F = 1 because the address is a logical address; + + RRRRR is a five decimal digit representation of + the result "r" of the calculation + + r = h * 256 + i + + (Note that the decimal representation of + "r" will always require five digits); + + ZZ = 00 and + + (SS) is optional + +Thus, the host table address 10.83.0.207 corresponds to the X.25 +logical address 000012145500. + +In both cases, the "n" and "l" fields of the host table address are +not used. + + +REFERENCES + +[BBN1822] BBN, "Specifications for the Interconnection of a Host and + + + +Reynolds & Postel [Page 188] + +RFC 1700 Assigned Numbers October 1994 + + + an IMP", Report 1822, Bolt Beranek and Newman, Cambridge, + Massachusetts, revised, December 1981. + +[ETHERNET] "The Ethernet, A Local Area Network: Data Link Layer and + Physical Layer Specification", AA-K759B-TK, Digital + Equipment Corporation, Maynard, MA. Also as: "The Ethernet + - A Local Area Network", Version 1.0, Digital Equipment + Corporation, Intel Corporation, Xerox Corporation, + September 1980. And: "The Ethernet, A Local Area Network: + Data Link Layer and Physical Layer Specifications", + Digital, Intel and Xerox, November 1982. And: XEROX, "The + Ethernet, A Local Area Network: Data Link Layer and + Physical Layer Specification", X3T51/80-50, Xerox + Corporation, Stamford, CT., October 1980. + +[PUP] Boggs, D., J. Shoch, E. Taft, and R. Metcalfe, "PUP: An + Internetwork Architecture", XEROX Palo Alto Research Center, + CSL-79-10, July 1979; also in IEEE Transactions on + Communication, Volume COM-28, Number 4, April 1980. + +[RFC791] Postel, J., ed., "Internet Protocol - DARPA Internet Program + Protocol Specification", STD 5, RFC 791, USC/Information + Sciences Institute, September 1981. + +[RFC878] Malis, Andrew, "The ARPANET 1822L Host Access Protocol", + RFC 878, BBN Communications Corp., December 1983. + +[RFC926] International Standards Organization, "Protocol for Providing + the Connectionless-Mode Network Services", RFC 926, ISO, + December 1984. + +[RFC1005] Khanna, A., and A. Malis, "The ARPANET AHIP-E Host Access + Protocol (Enhanced AHIP)", RFC 1005, BBN Communications + Corp., May 1987. + + +PEOPLE + +[DM28] Dennis Morris + +[JBP] Jon Postel + +[JBW1] Joseph Walters, Jr. + +[JGH] Jim Herman + +[MB] Michael Brescia + + + + +Reynolds & Postel [Page 189] + +RFC 1700 Assigned Numbers October 1994 + + +[RXM] Robert Myhill + +[XEROX] Fonda Pallone <---none---> + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/milnet-parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 190] + +RFC 1700 Assigned Numbers October 1994 + + +XNS PROTOCOL TYPES + + +Assigned well-known socket numbers + + Routing Information 1 + Echo 2 + Router Error 3 + Experimental 40-77 + +Assigned internet packet types + + Routing Information 1 + Echo 2 + Error 3 + Packet Exchange 4 + Sequenced Packet 5 + PUP 12 + DoD IP 13 + Experimental 20-37 + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/xns-protocol-types + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 191] + +RFC 1700 Assigned Numbers October 1994 + + +INTERNET / XNS PROTOCOL MAPPINGS + + +Below are two tables describing the arrangement of protocol fields or +type field assignments so that one could send XNS Datagrams on the +MILNET or Internet Datagrams on 10Mb Ethernet, and also protocol and +type fields so one could encapsulate each kind of Datagram in the +other. + + + upper| DoD IP | PUP | NS IP | +lower | | | | +--------------|--------|--------|--------| + | Type | Type | Type | +3Mb Ethernet | 1001 | 1000 | 3000 | + | octal | octal | octal | +--------------|--------|--------|--------| + | Type | Type | Type | +10 Mb Ethernet| 0800 | 0200 | 0600 | + | hex | hex | hex | +--------------|--------|--------|--------| + | Link | Link | Link | +MILNET | 155 | 152 | 150 | + | decimal| decimal| decimal| +--------------|--------|--------|--------| + + + + upper| DoD IP | PUP | NS IP | +lower | | | | +--------------|--------|--------|--------| + | |Protocol|Protocol| +DoD IP | X | 12 | 22 | + | | decimal| decimal| +--------------|--------|--------|--------| + | | | | +PUP | ? | X | ? | + | | | | +--------------|--------|--------|--------| + | Type | Type | | +NS IP | 13 | 12 | X | + | decimal| decimal| | +--------------|--------|--------|--------| + + + +[] + + + + +Reynolds & Postel [Page 192] + +RFC 1700 Assigned Numbers October 1994 + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ip-xns-mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 193] + +RFC 1700 Assigned Numbers October 1994 + + +PRONET 80 TYPE NUMBERS + + +Below is the current list of PRONET 80 Type Numbers. Note: a protocol +that is on this list does not necessarily mean that there is any +implementation of it on ProNET. + +Of these, protocols 1, 14, and 20 are the only ones that have ever +been seen in ARP packets. + +For reference, the header is (one byte/line): + + destination hardware address + source hardware address + data link header version (2) + data link header protocol number + data link header reserved (0) + data link header reserved (0) + +Some protocols have been known to tuck stuff in the reserved fields. + +Those who need a protocol number on ProNET-10/80 should contact John +Shriver (jas@proteon.com). + + +1 IP +2 IP with trailing headers +3 Address Resolution Protocol +4 Proteon HDLC +5 VAX Debugging Protocol (MIT) +10 Novell NetWare (IPX and pre-IPX) (old format, + 3 byte trailer) +11 Vianetix +12 PUP +13 Watstar protocol (University of Waterloo) +14 XNS +15 Diganostics +16 Echo protocol (link level) +17 Banyan Vines +20 DECnet (DEUNA Emulation) +21 Chaosnet +23 IEEE 802.2 or ISO 8802/2 Data Link +24 Reverse Address Resolution Protocol +29 TokenVIEW-10 +31 AppleTalk LAP Data Packet +33 Cornell Boot Server Location Protocol +34 Novell NetWare IPX (new format, no trailer, + new XOR checksum) + + + +Reynolds & Postel [Page 194] + +RFC 1700 Assigned Numbers October 1994 + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/pronet80-type-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 195] + +RFC 1700 Assigned Numbers October 1994 + + +NOVELL SAP NUMBERS OF INTEREST + +For the convenience of the Internet community the IANA maitains a list +of Novell Service Access Point (SAP) numbers. This list is kept +up-to-date- by contributions from the community. Please send +corrections and additions to IANA@ISI.EDU. + +Novell SAPs +====== ==== + +Decimal Hex SAP Description +======= ==== =============== + +0 0000 Unknown +1 0001 User +2 0002 User Group +3 0003 Print Queue or Print Group +4 0004 File Server (SLIST source) +5 0005 Job Server +6 0006 Gateway +7 0007 Print Server or Silent Print Server +8 0008 Archive Queue +9 0009 Archive Server +10 000a Job Queue +11 000b Administration +15 000F Novell TI-RPC +23 0017 Diagnostics +32 0020 NetBIOS +33 0021 NAS SNA Gateway +35 0023 NACS Async Gateway or Asynchronous Gateway +36 0024 Remote Bridge or Routing Service +38 0026 Bridge Server or Asynchronous Bridge Server +39 0027 TCP/IP Gateway Server +40 0028 Point to Point (Eicon) X.25 Bridge Server +41 0029 Eicon 3270 Gateway +42 002a CHI Corp ??? +44 002c PC Chalkboard +45 002d Time Synchronization Server or Asynchronous Timer +46 002e SAP Archive Server or SMS Target Service Agent +69 0045 DI3270 Gateway +71 0047 Advertising Print Server +75 004b Btrieve VAP/NLM 5.0 +76 004c Netware SQL VAP/NLM Server +77 004d Xtree Network Version Netware XTree +80 0050 Btrieve VAP 4.11 +82 0052 QuickLink (Cubix) +83 0053 Print Queue User +88 0058 Multipoint X.25 Eicon Router + + + +Reynolds & Postel [Page 196] + +RFC 1700 Assigned Numbers October 1994 + + +96 0060 STLB/NLM ??? +100 0064 ARCserve +102 0066 ARCserve 3.0 +114 0072 WAN Copy Utility +122 007a TES-Netware for VMS +146 0092 WATCOM Debugger or Emerald Tape Backup Server +149 0095 DDA OBGYN ??? +152 0098 Netware Access Server (Asynchronous gateway) +154 009a Netware for VMS II or Named Pipe Server +155 009b Netware Access Server +158 009e Portable Netware Server or SunLink NVT +161 00a1 Powerchute APC UPS NLM +170 00aa LAWserve ??? +172 00ac Compaq IDA Status Monitor +256 0100 PIPE STAIL ??? +258 0102 LAN Protect Bindery +259 0103 Oracle DataBase Server +263 0107 Netware 386 or RSPX Remote Console +271 010f Novell SNA Gateway +274 0112 Print Server (HP) +276 0114 CSA MUX (f/Communications Executive) +277 0115 CSA LCA (f/Communications Executive) +278 0116 CSA CM (f/Communications Executive) +279 0117 CSA SMA (f/Communications Executive) +280 0118 CSA DBA (f/Communications Executive) +281 0119 CSA NMA (f/Communications Executive) +282 011a CSA SSA (f/Communications Executive) +283 011b CSA STATUS (f/Communications Executive) +286 011e CSA APPC (f/Communications Executive) +294 0126 SNA TEST SSA Profile +298 012a CSA TRACE (f/Communications Executive) +304 0130 Communications Executive +307 0133 NNS Domain Server or Netware Naming Services Domain +309 0135 Netware Naming Services Profile +311 0137 Netware 386 Print Queue or NNS Print Queue +321 0141 LAN Spool Server (Vap, Intel) +338 0152 IRMALAN Gateway +340 0154 Named Pipe Server +360 0168 Intel PICKIT Comm Server or Intel CAS Talk Server +369 171 UNKNOWN??? +371 0173 Compaq +372 0174 Compaq SNMP Agent +373 0175 Compaq +384 0180 XTree Server or XTree Tools +394 18A UNKNOWN??? Running on a Novell Server +432 01b0 GARP Gateway (net research) +433 01b1 Binfview (Lan Support Group) +447 01bf Intel LanDesk Manager + + + +Reynolds & Postel [Page 197] + +RFC 1700 Assigned Numbers October 1994 + + +458 01ca AXTEC ??? +459 01cb Netmode ??? +460 1CC UNKNOWN??? Sheva netmodem??? +472 01d8 Castelle FAXPress Server +474 01da Castelle LANPress Print Server +476 1DC Castille FAX/Xerox 7033 Fax Server/Excel Lan Fax +496 01f0 LEGATO ??? +501 01f5 LEGATO ??? +563 0233 NMS Agent or Netware Management Agent +567 0237 NMS IPX Discovery or LANtern Read/Write Channel +568 0238 NMS IP Discovery or LANtern Trap/Alarm Channel +570 023a LABtern +572 023c MAVERICK ??? +574 23E UNKNOWN??? Running on a Novell Server +575 023f Used by eleven various Novell Servers +590 024e Remote Something ??? +618 026a Network Management (NMS) Service Console +619 026b Time Synchronization Server (Netware 4.x) +632 0278 Directory Server (Netware 4.x) +772 0304 Novell SAA Gateway +776 0308 COM or VERMED 1 ??? +778 030a Gallacticom BBS +780 030c Intel Netport 2 or HP JetDirect or HP Quicksilver +800 0320 Attachmate Gateway +807 0327 Microsoft Diagnostiocs ??? +821 0335 MultiTech Systems Multisynch Comm Server +853 0355 Arcada Backup Exec +858 0358 MSLCD1 ??? +865 0361 NETINELO ??? +894 037e Twelve Novell file servers in the PC3M family +895 037f ViruSafe Notify +902 0386 HP Bridge +903 0387 HP Hub +916 0394 NetWare SAA Gateway +923 039b Lotus Notes +951 03b7 Certus Anti Virus NLM +964 03c4 ARCserve 4.0 (Cheyenne) +967 03c7 LANspool 3.5 (Intel) +990 03de Gupta Sequel Base Server or NetWare SQL +993 03e1 Univel Unixware +996 03e4 Univel Unixware +1020 03fc Intel Netport +1021 03fd Print SErver Queue ??? +1034 40A ipnServer??? Running on a Novell Server +1035 40B UNKNOWN??? +1037 40D LVERRMAN??? Running on a Novell Server +1038 40E LVLIC??? Running on a Novell Server +1040 410 UNKNOWN??? Running on a Novell Server + + + +Reynolds & Postel [Page 198] + +RFC 1700 Assigned Numbers October 1994 + + +1044 0414 Kyocera +1065 0429 Site Lock Virus (Brightworks) +1074 0432 UFHELP R ??? +1075 433 Sunoptics SNMP Agent??? +1100 044c Backup ??? +1111 457 Canon GP55??? Running on a Canon GP55 network printer +1115 045b Dell SCSI Array (DSA) Monitor +1200 04b0 CD-Net (Meridian) +1217 4C1 UNKNOWN??? +1299 513 Emulux NQA??? Something from Emulex +1312 0520 Site Lock Checks +1321 0529 Site Lock Checks (Brightworks) +1325 052d Citrix OS/2 App Server +1344 536 Milan ??? +1408 0580 McAfee's NetShield anti-virus +1569 621 ?? Something from Emulex +1571 623 UNKNOWN??? Running on a Novell Server +1900 076C Xerox +2857 0b29 Site Lock +3113 0c29 Site Lock Applications +3116 0c2c Licensing Server +9088 2380 LAI Site Lock +9100 238c Meeting Maker +18440 4808 Site Lock Server or Site Lock Metering VAP/NLM +21845 5555 Site Lock User +25362 6312 Tapeware +28416 6f00 Rabbit Gateway (3270) +30467 7703 MODEM?? +32770 8002 NetPort Printers (Intel) or LANport +32776 8008 WordPerfect Network Version +34238 85BE Cisco Enhanced Interior Routing Protocol (EIGRP) +34952 8888 WordPerfect Network Version or Quick Network Management +36864 9000 McAfee's NetShield anti-virus +38404 9604 ?? CSA-NT_MON +61727 f11f Site Lock Metering VAP/NLM +61951 f1ff Site Lock +62723 F503 ?? SCA-NT +65535 ffff Any Service or Wildcard + +This file is + + ftp://ftp.isi.edu/in-notes/iana/assignments/novell-sap-numbers + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/novell-sap-numbers + + + + +Reynolds & Postel [Page 199] + +RFC 1700 Assigned Numbers October 1994 + + +POINT-TO-POINT PROTOCOL FIELD ASSIGNMENTS + +PPP DLL PROTOCOL NUMBERS + +The Point-to-Point Protocol (PPP) Data Link Layer [146,147,175] +contains a 16 bit Protocol field to identify the the encapsulated +protocol. The Protocol field is consistent with the ISO 3309 (HDLC) +extension mechanism for Address fields. All Protocols MUST be +assigned such that the least significant bit of the most significant +octet equals "0", and the least significant bit of the least +significant octet equals "1". + +Assigned PPP DLL Protocol Numbers + +Value (in hex) Protocol Name + +0001 Padding Protocol +0003 to 001f reserved (transparency inefficient) +0021 Internet Protocol +0023 OSI Network Layer +0025 Xerox NS IDP +0027 DECnet Phase IV +0029 Appletalk +002b Novell IPX +002d Van Jacobson Compressed TCP/IP +002f Van Jacobson Uncompressed TCP/IP +0031 Bridging PDU +0033 Stream Protocol (ST-II) +0035 Banyan Vines +0037 reserved (until 1993) +0039 AppleTalk EDDP +003b AppleTalk SmartBuffered +003d Multi-Link +003f NETBIOS Framing +0041 Cisco Systems +0043 Ascom Timeplex +0045 Fujitsu Link Backup and Load Balancing (LBLB) +0047 DCA Remote Lan +0049 Serial Data Transport Protocol (PPP-SDTP) +004b SNA over 802.2 +004d SNA +004f IP6 Header Compression +006f Stampede Bridging +007d reserved (Control Escape) [RFC1661] +007f reserved (compression inefficient) [RFC1662] +00cf reserved (PPP NLPID) +00fb compression on single link in multilink group +00fd 1st choice compression + + + +Reynolds & Postel [Page 200] + +RFC 1700 Assigned Numbers October 1994 + + +00ff reserved (compression inefficient) + +0201 802.1d Hello Packets +0203 IBM Source Routing BPDU +0205 DEC LANBridge100 Spanning Tree +0231 Luxcom +0233 Sigma Network Systems + +8001-801f Not Used - reserved [RFC1661] +8021 Internet Protocol Control Protocol +8023 OSI Network Layer Control Protocol +8025 Xerox NS IDP Control Protocol +8027 DECnet Phase IV Control Protocol +8029 Appletalk Control Protocol +802b Novell IPX Control Protocol +802d reserved +802f reserved +8031 Bridging NCP +8033 Stream Protocol Control Protocol +8035 Banyan Vines Control Protocol +8037 reserved till 1993 +8039 reserved +803b reserved +803d Multi-Link Control Protocol +803f NETBIOS Framing Control Protocol +807d Not Used - reserved [RFC1661] +8041 Cisco Systems Control Protocol +8043 Ascom Timeplex +8045 Fujitsu LBLB Control Protocol +8047 DCA Remote Lan Network Control Protocol (RLNCP) +8049 Serial Data Control Protocol (PPP-SDCP) +804b SNA over 802.2 Control Protocol +804d SNA Control Protocol +804f IP6 Header Compression Control Protocol +006f Stampede Bridging Control Protocol +80cf Not Used - reserved [RFC1661] +80fb compression on single link in multilink group control +80fd Compression Control Protocol +80ff Not Used - reserved [RFC1661] + +c021 Link Control Protocol +c023 Password Authentication Protocol +c025 Link Quality Report +c027 Shiva Password Authentication Protocol +c029 CallBack Control Protocol (CBCP) +c081 Container Control Protocol [KEN] +c223 Challenge Handshake Authentication Protocol +c281 Proprietary Authentication Protocol [KEN] + + + +Reynolds & Postel [Page 201] + +RFC 1700 Assigned Numbers October 1994 + + +c26f Stampede Bridging Authorization Protocol +c481 Proprietary Node ID Authentication Protocol [KEN] + +Protocol field values in the "0xxx" to "3xxx" range identify the +network-layer protocol of specific datagrams, and values in the "8xxx" +to "bxxx" range identify datagrams belonging to the associated Network +Control Protocol (NCP), if any. + +It is recommended that values in the "02xx" to "1exx" and "xx01" to +"xx1f" ranges not be assigned, as they are compression inefficient. + +Protocol field values in the "4xxx" to "7xxx" range are used for +protocols with low volume traffic which have no associated NCP. + +Protocol field values in the "cxxx" to "exxx" range identify datagrams +as Control Protocols (such as LCP). + +PPP LCP AND IPCP CODES + +The Point-to-Point Protocol (PPP) Link Control Protocol (LCP), [146] +the Compression Control Protocol (CCP), Internet Protocol Control +Protocol (IPCP), [147] and other control protocols, contain an 8 bit +Code field which identifies the type of packet. These Codes are +assigned as follows: + +Code Packet Type +---- ----------- + 1 Configure-Request + 2 Configure-Ack + 3 Configure-Nak + 4 Configure-Reject + 5 Terminate-Request + 6 Terminate-Ack + 7 Code-Reject + 8 * Protocol-Reject + 9 * Echo-Request + 10 * Echo-Reply + 11 * Discard-Request + 12 * Identification + 13 * Time-Remaining + 14 + Reset-Request + 15 + Reset-Reply + +* LCP Only ++ CCP Only + +PPP LCP CONFIGURATION OPTION TYPES + + + + +Reynolds & Postel [Page 202] + +RFC 1700 Assigned Numbers October 1994 + + +The Point-to-Point Protocol (PPP) Link Control Protocol (LCP) +specifies a number of Configuration Options [146] which are +distinguished by an 8 bit Type field. These Types are assigned as +follows: + +Type Configuration Option +---- -------------------- + 1 Maximum-Receive-Unit + 2 Async-Control-Character-Map + 3 Authentication-Protocol + 4 Quality-Protocol + 5 Magic-Number + 6 RESERVED + 7 Protocol-Field-Compression + 8 Address-and-Control-Field-Compression + 9 FCS-Alternatives + 10 Self-Describing-Pad + 11 Numbered-Mode + 12 Multi-Link-Procedure + 13 Callback + 14 Connect-Time + 15 Compound-Frames + 16 Nominal-Data-Encapsulation + 17 Multilink-MRRU + 18 Multilink-Short-Sequence-Number-Header-Format + 19 Multilink-Endpoint-Discriminator + 20 Proprietary [KEN] + 21 DCE-Identifier [SCHNEIDER] + +PPP LCP FCS-ALTERNATIVES + +The Point-to-Point Protocol (PPP) Link Control Protocol (LCP) +FCS-Alternatives Configuration Option contains an 8-bit Options field +which identifies the FCS used. These are assigned as follows: + +Bit FCS +---- ---------- + 1 Null FCS + 2 CCITT 16-Bit FCS + 4 CCITT 32-bit FCS + + +PPP LCP CALLBACK OPERATION FIELDS + +The Point-to-Point Protocol (PPP) Link Control Protocol (LCP) Callback +Configuration Option contains an 8-bit Operations field which +identifies the format of the Message. These are assigned as follows: + + + + +Reynolds & Postel [Page 203] + +RFC 1700 Assigned Numbers October 1994 + + +Operation Description +--------- --------------------------- + 0 Location determined by user authentication. + 1 Dialing string. + 2 Location identifier. + 3 E.164 number. + 4 X.500 distinguished name. + 5 unassigned + 6 Location is determined during CBCP negotiation. + +PPP IPCP CONFIGURATION OPTION TYPES + +The Point-to-Point Protocol (PPP) Internet Protocol Control Protocol +(IPCP) specifies a number of Configuration Options [147] which are +distinguished by an 8 bit Type field. These Types are assigned as +follows: + +Type Configuration Option +---- -------------------- + 1 IP-Addresses (deprecated) + 2 IP-Compression-Protocol + 3 IP-Address + +PPP ATCP CONFIGURATION OPTION TYPES + +The Point-to-Point Protocol (PPP) Apple Talk Control Protocol (ATCP) +specifies a number of Configuration Options [RFC-1378] which are +distinguished by an 8 bit Type field. These Types are assigned as +follows: + +Type Configuration Option +---- -------------------- + 1 AppleTalk-Address + 2 Routing-Protocol + 3 Suppress-Broadcasts + 4 AT-Compression-Protocol + 5 Reserved + 6 Server-information + 7 Zone-information + 8 Default-Router-Address + +PPP OSINLCP CONFIGURATION OPTION TYPES + +The Point-to-Point Protocol (PPP) OSI Network Layer Control Protocol +(OSINLCP) specifies a number of Configuration Options [RFC-1377] which +are distinguished by an 8 bit Type field. These Types are assigned as +follows: + + + + +Reynolds & Postel [Page 204] + +RFC 1700 Assigned Numbers October 1994 + + +Type Configuration Option +---- -------------------- + 1 Align-NPDU + +PPP BRIDGING CONFIGURATION OPTION TYPES + +The Point-to-Point Protocol (PPP) Bridging Control Protocol (BCP) +specifies a number of Configuration Options which are distinguished by +an 8 bit Type field. These Types are assigned as follows: + +Type Configuration Option +---- -------------------- + 1 Bridge-Identification + 2 Line-Identification + 3 MAC-Support + 4 Tinygram-Compression + 5 LAN-Identification + 6 MAC-Address + 7 Spanning-Tree-Protocol + +PPP BRIDGING MAC TYPES + +The Point-to-Point Protocol (PPP) Bridging Control Protocol (BCP) +contains an 8 bit MAC Type field which identifies the MAC +encapsulated. These Types are assigned as follows: + +Type MAC +---- ----------- + 0 Reserved + 1 IEEE 802.3/Ethernet with cannonical addresses + 2 IEEE 802.4 with cannonical addresses + 3 IEEE 802.5 with non-cannonical addresses + 4 FDDI with non-cannonical addresses + 5-10 reserved + 11 IEEE 802.5 with cannonical addresses + 12 FDDI with cannonical addresses + +PPP BRIDGING SPANNING TREE + +The Point-to-Point Protocol (PPP) Bridging Control Protocol (BCP) +Spanning Tree Configuration Option contains an 8-bit Protocol field +which identifies the spanning tree used. These are assigned as +follows: + +Protocol Spanning Tree +-------- --------------- + 0 Null - no spanning tree protocol supported + 1 IEEE 802.1D spanning tree protocol + + + +Reynolds & Postel [Page 205] + +RFC 1700 Assigned Numbers October 1994 + + + 2 IEEE 802.1G extended spanning tree protocol + 3 IBM source route spanning tree protocol + 4 DEC LANbridge 100 spanning tree protocol + + +REFERENCES + +[RFC1661] Simpson, W., Editor, "The Point-to-Point Protocol (PPP)", + STD 51, RFC 1661, Daydreamer, July 1994. + +[RFC1662] Simpson, W., Editor, "PPP in HDLC-like Framing", STD 51, RFC + 1662, Daydreamer, July 1994. + + +PEOPLE + +[KEN] + +[SCHNEIDER] Kevin Schneider + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/ppp-numbers + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 206] + +RFC 1700 Assigned Numbers October 1994 + + +MACHINE NAMES + + +These are the Official Machine Names as they appear in the Domain Name +System HINFO records and the NIC Host Table. Their use is described +in [RFC952]. + +A machine name or CPU type may be up to 40 characters taken from the +set of uppercase letters, digits, and the two punctuation characters +hyphen and slash. It must start with a letter, and end with a letter +or digit. + +AMIGA-500 +AMIGA-500/010 +AMIGA-500/020 +AMIGA-500/EC030 +AMIGA-500/030 +AMIGA-600 +AMIGA-1000 +AMIGA-1000/010 +AMIGA-1000/020 +AMIGA-1000/EC030 +AMIGA-1000/030 +AMIGA-1200 +AMIGA-1200/EC030 +AMIGA-1200/030 +AMIGA-1200/EC040 +AMIGA-1200/LC040 +AMIGA-1200/040 +AMIGA-2000 +AMIGA-2000/010 +AMIGA-2000/020 +AMIGA-2000/EC030 +AMIGA-2000/030 +AMIGA-2000/LC040 +AMIGA-2000/EC040 +AMIGA-2000/040 +AMIGA-3000 +AMIGA-3000/EC040 +AMIGA-3000/LC040 +AMIGA-3000/040 +AMIGA-3000/060 +AMIGA-4000/EC030 +AMIGA-4000/030 +AMIGA-4000/LC040 +AMIGA-4000/040 +AMIGA-4000/060 +ALTO + + + +Reynolds & Postel [Page 207] + +RFC 1700 Assigned Numbers October 1994 + + +ALTOS-6800 +AMDAHL-V7 +APOLLO +APPLE-MACINTOSH +APPLE-POWERBOOK +ATARI-104ST +ATT-3B1 +ATT-3B2 +ATT-3B20 +ATT-7300 +AXP +BBN-C/60 +BURROUGHS-B/29 +BURROUGHS-B/4800 +BUTTERFLY +C/30 +C/70 +CADLINC +CADR +CDC-170 +CDC-170/750 +CDC-173 +CDTV +CDTV/060 +CD32 +CELERITY-1200 +CLUB-386 +COMPAQ-386/20 +COMTEN-3690 +CP8040 +CRAY-1 +CRAY-X/MP +CRAY-2 +CTIWS-117 +DANDELION +DEC-10 +DEC-1050 +DEC-1077 +DEC-1080 +DEC-1090 +DEC-1090B +DEC-1090T +DEC-2020T +DEC-2040 +DEC-2040T +DEC-2050T +DEC-2060 +DEC-2060T + + + +Reynolds & Postel [Page 208] + +RFC 1700 Assigned Numbers October 1994 + + +DEC-2065 +DEC-AXP +DEC-FALCON +DEC-KS10 +DECSTATION +DEC-VAX +DEC-VAXCLUSTER +DEC-VAXSTATION +DEC-VAX-11730 +DORADO +DPS8/70M +ELXSI-6400 +EVEREX-386 +FOONLY-F2 +FOONLY-F3 +FOONLY-F4 +GOULD +GOULD-6050 +GOULD-6080 +GOULD-9050 +GOULD-9080 +H-316 +H-60/68 +H-68 +H-68/80 +H-89 +HONEYWELL-DPS-6 +HONEYWELL-DPS-8/70 +HP3000 +HP3000/64 +IBM-158 +IBM-360/67 +IBM-370/3033 +IBM-3081 +IBM-3084QX +IBM-3101 +IBM-4331 +IBM-4341 +IBM-4361 +IBM-4381 +IBM-4956 +IBM-6152 +IBM-PC +IBM-PC/AT +IBM-PC/RT +IBM-PC/XT +IBM-RS/6000 +IBM-SERIES/1 + + + +Reynolds & Postel [Page 209] + +RFC 1700 Assigned Numbers October 1994 + + +IMAGEN +IMAGEN-8/300 +IMSAI +INTEGRATED-SOLUTIONS +INTEGRATED-SOLUTIONS-68K +INTEGRATED-SOLUTIONS-CREATOR +INTEGRATED-SOLUTIONS-CREATOR-8 +INTEL-386 +INTEL-IPSC +IS-1 +IS-68010 +LMI +LSI-11 +LSI-11/2 +LSI-11/23 +LSI-11/73 +M68000 +MAC-II +MAC-POWERBOOK +MACINTOSH +MASSCOMP +MC500 +MC68000 +MICROPORT +MICROVAX +MICROVAX-I +MV/8000 +NAS3-5 +NCR-COMTEN-3690 +NEXT/N1000-316 +NOW +ONYX-Z8000 +PDP-11 +PDP-11/3 +PDP-11/23 +PDP-11/24 +PDP-11/34 +PDP-11/40 +PDP-11/44 +PDP-11/45 +PDP-11/50 +PDP-11/70 +PDP-11/73 +PE-7/32 +PE-3205 +PERQ +PLEXUS-P/60 +PLI + + + +Reynolds & Postel [Page 210] + +RFC 1700 Assigned Numbers October 1994 + + +PLURIBUS +PRIME-2350 +PRIME-2450 +PRIME-2755 +PRIME-9655 +PRIME-9755 +PRIME-9955II +PRIME-2250 +PRIME-2655 +PRIME-9955 +PRIME-9950 +PRIME-9650 +PRIME-9750 +PRIME-2250 +PRIME-750 +PRIME-850 +PRIME-550II +PYRAMID-90 +PYRAMID-90MX +PYRAMID-90X +RIDGE +RIDGE-32 +RIDGE-32C +ROLM-1666 +RS/6000 +S1-MKIIA +SMI +SEQUENT-BALANCE-8000 +SIEMENS +SILICON-GRAPHICS +SILICON-GRAPHICS-IRIS +SGI-IRIS-2400 +SGI-IRIS-2500 +SGI-IRIS-3010 +SGI-IRIS-3020 +SGI-IRIS-3030 +SGI-IRIS-3110 +SGI-IRIS-3115 +SGI-IRIS-3120 +SGI-IRIS-3130 +SGI-IRIS-4D/20 +SGI-IRIS-4D/20G +SGI-IRIS-4D/25 +SGI-IRIS-4D/25G +SGI-IRIS-4D/25S +SGI-IRIS-4D/50 +SGI-IRIS-4D/50G +SGI-IRIS-4D/50GT + + + +Reynolds & Postel [Page 211] + +RFC 1700 Assigned Numbers October 1994 + + +SGI-IRIS-4D/60 +SGI-IRIS-4D/60G +SGI-IRIS-4D/60T +SGI-IRIS-4D/60GT +SGI-IRIS-4D/70 +SGI-IRIS-4D/70G +SGI-IRIS-4D/70GT +SGI-IRIS-4D/80GT +SGI-IRIS-4D/80S +SGI-IRIS-4D/120GTX +SGI-IRIS-4D/120S +SGI-IRIS-4D/210GTX +SGI-IRIS-4D/210S +SGI-IRIS-4D/220GTX +SGI-IRIS-4D/220S +SGI-IRIS-4D/240GTX +SGI-IRIS-4D/240S +SGI-IRIS-4D/280GTX +SGI-IRIS-4D/280S +SGI-IRIS-CS/12 +SGI-IRIS-4SERVER-8 +SPERRY-DCP/10 +SUN +SUN-2 +SUN-2/50 +SUN-2/100 +SUN-2/120 +SUN-2/130 +SUN-2/140 +SUN-2/150 +SUN-2/160 +SUN-2/170 +SUN-3/50 +SUN-3/60 +SUN-3/75 +SUN-3/80 +SUN-3/110 +SUN-3/140 +SUN-3/150 +SUN-3/160 +SUN-3/180 +SUN-3/200 +SUN-3/260 +SUN-3/280 +SUN-3/470 +SUN-3/480 +SUN-4/60 +SUN-4/110 + + + +Reynolds & Postel [Page 212] + +RFC 1700 Assigned Numbers October 1994 + + +SUN-4/150 +SUN-4/200 +SUN-4/260 +SUN-4/280 +SUN-4/330 +SUN-4/370 +SUN-4/390 +SUN-50 +SUN-100 +SUN-120 +SUN-130 +SUN-150 +SUN-170 +SUN-386i/250 +SUN-68000 +SYMBOLICS-3600 +SYMBOLICS-3670 +SYMMETRIC-375 +SYMULT +TANDEM-TXP +TANDY-6000 +TEK-6130 +TI-EXPLORER +TP-4000 +TRS-80 +UNIVAC-1100 +UNIVAC-1100/60 +UNIVAC-1100/62 +UNIVAC-1100/63 +UNIVAC-1100/64 +UNIVAC-1100/70 +UNIVAC-1160 +UNKNOWN +VAX +VAX-11/725 +VAX-11/730 +VAX-11/750 +VAX-11/780 +VAX-11/785 +VAX-11/790 +VAX-11/8600 +VAX-8600 +VAXCLUSTER +VAXSTATION +WANG-PC002 +WANG-VS100 +WANG-VS400 +WYSE-386 + + + +Reynolds & Postel [Page 213] + +RFC 1700 Assigned Numbers October 1994 + + +WYSE-WN5004 +WYSE-WN5008 +WYSE-WN5104 +WYSE-WN5108 +WYSE-WX15C +WYSE-WX17C +WYSE-WX17M +WYSE-WX19C +WYSE-WX19M +WYSE-WYX14M +WYSE-WYX5 +XEROX-1108 +XEROX-8010 +ZENITH-148 + + +REFERENCES + +[RFC952] Harrenstien, K., Stahl, M., and E. Feinler, "DoD Internet + Host Table Specification", RFC 952, SRI, October 1985. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/machine-names + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 214] + +RFC 1700 Assigned Numbers October 1994 + + +OPERATING SYSTEM NAMES + + +These are the Official System Names as they appear in the Domain Name +System HINFO records and the NIC Host Table. Their use is described in +[RFC952]. + +A system name may be up to 40 characters taken from the set of +uppercase letters, digits, and the three punctuation characters +hyphen, period, and slash. It must start with a letter, and end with +a letter or digit. + + +AEGIS +AMIGA-OS-1.2 +AMIGA-OS-1.3 +AMIGA-OS-2.0 +AMIGA-OS-2.1 +AMIGA-OS-3.0 +AMIGA-OS-3.1 +APOLLO +AIX/370 +AIX-PS/2 +BS-2000 +CEDAR +CGW +CHORUS +CHRYSALIS +CMOS +CMS +COS +CPIX +CTOS +CTSS +DCN +DDNOS +DOMAIN +DOS +EDX +ELF +EMBOS +EMMOS +EPOS +FOONEX +FORTH +FUZZ +GCOS +GPOS + + + +Reynolds & Postel [Page 215] + +RFC 1700 Assigned Numbers October 1994 + + +HDOS +IMAGEN +INTERCOM +IMPRESS +INTERLISP +IOS +IRIX +ISI-68020 +ITS +LISP +LISPM +LOCUS +MACOS +MINOS +MOS +MPE5 +MPE/V +MPE/IX +MSDOS +MULTICS +MUSIC +MUSIC/SP +MVS +MVS/SP +NEXUS +NMS +NONSTOP +NOS-2 +NTOS +OPENVMS +OS/DDP +OS/2 +OS4 +OS86 +OSX +PCDOS +PERQ/OS +PLI +PSDOS/MIT +PRIMOS +RMX/RDOS +ROS +RSX11M +RTE-A +SATOPS +SCO-OPEN-DESKTOP-1.0 +SCO-OPEN-DESKTOP-1.1 +SCO-OPEN-DESKTOP-2.0 + + + +Reynolds & Postel [Page 216] + +RFC 1700 Assigned Numbers October 1994 + + +SCO-OPEN-DESKTOP-3.0 +SCO-OPEN-DESKTOP-LITE-3.0 +SCO-OPEN-SERVER-3.0 +SCO-UNIX-3.2.0 +SCO-UNIX-3.2V2.0 +SCO-UNIX-3.2V2.1 +SCO-UNIX-3.2V4.0 +SCO-UNIX-3.2V4.1 +SCO-UNIX-3.2V4.2 +SCO-XENIX-386-2.3.2 +SCO-XENIX-386-2.3.3 +SCO-XENIX-386-2.3.4 +SCS +SIMP +SUN +SUN-OS-3.5 +SUN-OS-4.0 +SWIFT +TAC +TANDEM +TENEX +THE-MAJOR-BBS +TOPS10 +TOPS20 +TOS +TP3010 +TRSDOS +ULTRIX +UNIX +UNIX-BSD +UNIX-V1AT +UNIX-V +UNIX-V.1 +UNIX-V.2 +UNIX-V.3 +UNIX-PC +UNKNOWN +UT2D +V +VM +VM/370 +VM/CMS +VM/SP +VMS +VMS/EUNICE +VRTX +WAITS +WANG + + + +Reynolds & Postel [Page 217] + +RFC 1700 Assigned Numbers October 1994 + + +WIN32 +WYSE-WYXWARE +X11R3 +XDE +XENIX + + +REFERENCES + +[RFC952] Harrenstien, K., Stahl, M., and E. Feinler, "DoD Internet + Host Table Specification", RFC 952, SRI, October 1985. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/operating-system-names + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 218] + +RFC 1700 Assigned Numbers October 1994 + + +TERMINAL TYPE NAMES + + +These are the Official Terminal Type Names. Their use is described in +[RFC930]. The maximum length of a name is 40 characters. + +A terminal names may be up to 40 characters taken from the set of +uppercase letters, digits, and the two punctuation characters hyphen +and slash. It must start with a letter, and end with a letter or +digit. + + +ADDS-CONSUL-980 +ADDS-REGENT-100 +ADDS-REGENT-20 +ADDS-REGENT-200 +ADDS-REGENT-25 +ADDS-REGENT-40 +ADDS-REGENT-60 +ADDS-VIEWPOINT +ADDS-VIEWPOINT-60 +AED-512 +AMPEX-DIALOGUE-210 +AMPEX-DIALOGUE-80 +AMPEX-210 +AMPEX-230 +ANDERSON-JACOBSON-510 +ANDERSON-JACOBSON-630 +ANDERSON-JACOBSON-832 +ANDERSON-JACOBSON-841 +ANN-ARBOR-AMBASSADOR +ANSI +ARDS +BITGRAPH +BUSSIPLEXER +CALCOMP-565 +CDC-456 +CDI-1030 +CDI-1203 +C-ITOH-101 +C-ITOH-50 +C-ITOH-80 +CLNZ +COMPUCOLOR-II +CONCEPT-100 +CONCEPT-104 +CONCEPT-108 +DATA-100 + + + +Reynolds & Postel [Page 219] + +RFC 1700 Assigned Numbers October 1994 + + +DATA-GENERAL-6053 +DATAGRAPHIX-132A +DATAMEDIA-1520 +DATAMEDIA-1521 +DATAMEDIA-2500 +DATAMEDIA-3025 +DATAMEDIA-3025A +DATAMEDIA-3045 +DATAMEDIA-3045A +DATAMEDIA-DT80/1 +DATAPOINT-2200 +DATAPOINT-3000 +DATAPOINT-3300 +DATAPOINT-3360 +DEC-DECWRITER-I +DEC-DECWRITER-II +DEC-GIGI +DEC-GT40 +DEC-GT40A +DEC-GT42 +DEC-LA120 +DEC-LA30 +DEC-LA36 +DEC-LA38 +DEC-VT05 +DEC-VT100 +DEC-VT101 +DEC-VT102 +DEC-VT125 +DEC-VT131 +DEC-VT132 +DEC-VT200 +DEC-VT220 +DEC-VT240 +DEC-VT241 +DEC-VT300 +DEC-VT320 +DEC-VT340 +DEC-VT50 +DEC-VT50H +DEC-VT52 +DEC-VT55 +DEC-VT61 +DEC-VT62 +DELTA-DATA-5000 +DELTA-DATA-NIH-7000 +DELTA-TELTERM-2 +DIABLO-1620 + + + +Reynolds & Postel [Page 220] + +RFC 1700 Assigned Numbers October 1994 + + +DIABLO-1640 +DIGILOG-333 +DTC-300S +DTC-382 +EDT-1200 +ETOS52-APL +ETOS52-CRT +ETOS52-FDW +ETOS52-FUP +ETOS52-GFM +ETOS52-SPR +EXECUPORT-4000 +EXECUPORT-4080 +FACIT-TWIST-4440 +FREEDOM-100 +FREEDOM-110 +FREEDOM-200 +GENERAL-TERMINAL-100A +GENERAL-TERMINAL-101 +GIPSI-TX-M +GIPSI-TX-ME +GIPSI-TX-C4 +GIPSI-TX-C8 +GSI +HAZELTINE-1420 +HAZELTINE-1500 +HAZELTINE-1510 +HAZELTINE-1520 +HAZELTINE-1552 +HAZELTINE-2000 +HAZELTINE-ESPRIT +HITACHI-5601 +HITACHI-5603 +HITACHI-5603E +HITACHI-5603EA +HITACHI-560X +HITACHI-560XE +HITACHI-560XEA +HITACHI-560PR +HITACHI-HOAP1 +HITACHI-HOAP2 +HITACHI-HOAP3 +HITACHI-HOAP4 +HP-2392 +HP-2621 +HP-2621A +HP-2621P +HP-2623 + + + +Reynolds & Postel [Page 221] + +RFC 1700 Assigned Numbers October 1994 + + +HP-2626 +HP-2626A +HP-2626P +HP-2627 +HP-2640 +HP-2640A +HP-2640B +HP-2645 +HP-2645A +HP-2648 +HP-2648A +HP-2649 +HP-2649A +IBM-1050 +IBM-2741 +IBM-3101 +IBM-3101-10 +IBM-3151 +IBM-3179-2 +IBM-3180-2 +IBM-3196-A1 +IBM-3275-2 +IBM-3276-2 +IBM-3276-3 +IBM-3276-4 +IBM-3277-2 +IBM-3278-2 +IBM-3278-3 +IBM-3278-4 +IBM-3278-5 +IBM-3279-2 +IBM-3279-3 +IBM-3477-FC +IBM-3477-FG +IBM-5081 +IBM-5151 +IBM-5154 +IBM-5251-11 +IBM-5291-1 +IBM-5292-2 +IBM-5555-B01 +IBM-5555-C01 +IBM-6153 +IBM-6154 +IBM-6155 +IBM-AED +IBM-3278-2-E +IBM-3278-3-E + + + +Reynolds & Postel [Page 222] + +RFC 1700 Assigned Numbers October 1994 + + +IBM-3278-4-E +IBM-3278-5-E +IBM-3279-2-E +IBM-3279-3-E +IMLAC +INFOTON-100 +INFOTON-400 +INFOTONKAS +ISC-8001 +LSI-ADM-1 +LSI-ADM-11 +LSI-ADM-12 +LSI-ADM-2 +LSI-ADM-20 +LSI-ADM-22 +LSI-ADM-220 +LSI-ADM-3 +LSI-ADM-31 +LSI-ADM-3A +LSI-ADM-42 +LSI-ADM-5 +MEMOREX-1240 +MICROBEE +MICROTERM-ACT-IV +MICROTERM-ACT-V +MICROTERM-ERGO-301 +MICROTERM-MIME-1 +MICROTERM-MIME-2 +MICROTERM-ACT-5A +MICROTERM-TWIST +NEC-5520 +NETRONICS +NETWORK-VIRTUAL-TERMINAL +OMRON-8025AG +PERKIN-ELMER-550 +PERKIN-ELMER-1100 +PERKIN-ELMER-1200 +PERQ +PLASMA-PANEL +QUME-SPRINT-5 +QUME-101 +QUME-102 +SOROC +SOROC-120 +SOUTHWEST-TECHNICAL-PRODUCTS-CT82 +SUN +SUPERBEE +SUPERBEE-III-M + + + +Reynolds & Postel [Page 223] + +RFC 1700 Assigned Numbers October 1994 + + +TEC +TEKTRONIX-4006 +TEKTRONIX-4010 +TEKTRONIX-4012 +TEKTRONIX-4013 +TEKTRONIX-4014 +TEKTRONIX-4023 +TEKTRONIX-4024 +TEKTRONIX-4025 +TEKTRONIX-4027 +TEKTRONIX-4105 +TEKTRONIX-4107 +TEKTRONIX-4110 +TEKTRONIX-4112 +TEKTRONIX-4113 +TEKTRONIX-4114 +TEKTRONIX-4115 +TEKTRONIX-4125 +TEKTRONIX-4404 +TELERAY-1061 +TELERAY-3700 +TELERAY-3800 +TELETEC-DATASCREEN +TELETERM-1030 +TELETYPE-33 +TELETYPE-35 +TELETYPE-37 +TELETYPE-38 +TELETYPE-40 +TELETYPE-43 +TELEVIDEO-910 +TELEVIDEO-912 +TELEVIDEO-920 +TELEVIDEO-920B +TELEVIDEO-920C +TELEVIDEO-925 +TELEVIDEO-955 +TELEVIDEO-950 +TELEVIDEO-970 +TELEVIDEO-975 +TERMINET-1200 +TERMINET-300 +TI-700 +TI-733 +TI-735 +TI-743 +TI-745 +TI-800 + + + +Reynolds & Postel [Page 224] + +RFC 1700 Assigned Numbers October 1994 + + +TYCOM +UNIVAC-DCT-500 +VIDEO-SYSTEMS-1200 +VIDEO-SYSTEMS-5000 +VOLKER-CRAIG-303 +VOLKER-CRAIG-303A +VOLKER-CRAIG-404 +VISUAL-200 +VISUAL-55 +WYSE-30 +WYSE-50 +WYSE-60 +WYSE-75 +WYSE-85 +WYSE-99GT +WYSE-100 +WYSE-120 +WYSE-120ES +WYSE-150 +WYSE-150ES +WYSE-160 +WYSE-160ES +WYSE-185 +WYSE-185ES +WYSE-285 +WYSE-285ES +WYSE-325 +WYSE-325ES +WYSE-350 +WYSE-370 +XEROX-1720 +XTERM +ZENITH-H19 +ZENITH-Z29 +ZENTEC-30 + + +REFERENCES + +[RFC930] Solomon, M., and E. Wimmers, "Telnet Terminal Type Option", + RFC 930, University of Wisconsin, Madison, January 1985. + + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/terminal-type-names + + + + +Reynolds & Postel [Page 225] + +RFC 1700 Assigned Numbers October 1994 + + +PROTOCOL AND SERVICE NAMES + + +These are the Official Protocol Names as they appear in the Domain +Name System WKS records and the NIC Host Table. Their use is +described in [RFC952]. + +A protocol or service may be up to 40 characters taken from the set of +uppercase letters, digits, and the punctuation character hyphen. It +must start with a letter, and end with a letter or digit. + + +ARGUS - ARGUS Protocol +ARP - Address Resolution Protocol +AUTH - Authentication Service +BBN-RCC-MON - BBN RCC Monitoring +BL-IDM - Britton Lee Intelligent Database Machine +BOOTP - Bootstrap Protocol +BOOTPC - Bootstrap Protocol Client +BOOTPS - Bootstrap Protocol Server +BR-SAT-MON - Backroom SATNET Monitoring +CFTP - CFTP +CHAOS - CHAOS Protocol +CHARGEN - Character Generator Protocol +CISCO-FNA - CISCO FNATIVE +CISCO-TNA - CISCO TNATIVE +CISCO-SYS - CISCO SYSMAINT +CLOCK - DCNET Time Server Protocol +CMOT - Common Mgmnt Info Ser and Prot over TCP/IP +COOKIE-JAR - Authentication Scheme +CSNET-NS - CSNET Mailbox Nameserver Protocol +DAYTIME - Daytime Protocol +DCN-MEAS - DCN Measurement Subsystems Protocol +DCP - Device Control Protocol +DGP - Dissimilar Gateway Protocol +DISCARD - Discard Protocol +DMF-MAIL - Digest Message Format for Mail +DOMAIN - Domain Name System +ECHO - Echo Protocol +EGP - Exterior Gateway Protocol +EHF-MAIL - Encoding Header Field for Mail +EMCON - Emission Control Protocol +EMFIS-CNTL - EMFIS Control Service +EMFIS-DATA - EMFIS Data Service +FCONFIG - Fujitsu Config Protocol +FINGER - Finger Protocol +FTP - File Transfer Protocol +FTP-DATA - File Transfer Protocol Data + + + +Reynolds & Postel [Page 226] + +RFC 1700 Assigned Numbers October 1994 + + +GGP - Gateway Gateway Protocol +GRAPHICS - Graphics Protocol +HMP - Host Monitoring Protocol +HOST2-NS - Host2 Name Server +HOSTNAME - Hostname Protocol +ICMP - Internet Control Message Protocol +IGMP - Internet Group Management Protocol +IGP - Interior Gateway Protocol +IMAP2 - Interim Mail Access Protocol version 2 +INGRES-NET - INGRES-NET Service +IP - Internet Protocol +IPCU - Internet Packet Core Utility +IPPC - Internet Pluribus Packet Core +IP-ARC - Internet Protocol on ARCNET +IP-ARPA - Internet Protocol on ARPANET +IP-CMPRS - Compressing TCP/IP Headers +IP-DC - Internet Protocol on DC Networks +IP-DVMRP - Distance Vector Multicast Routing Protocol +IP-E - Internet Protocol on Ethernet Networks +IP-EE - Internet Protocol on Exp. Ethernet Nets +IP-FDDI - Transmission of IP over FDDI +IP-HC - Internet Protocol on Hyperchannnel +IP-IEEE - Internet Protocol on IEEE 802 +IP-IPX - Transmission of 802.2 over IPX Networks +IP-MTU - IP MTU Discovery Options +IP-NETBIOS - Internet Protocol over NetBIOS Networks +IP-SLIP - Transmission of IP over Serial Lines +IP-WB - Internet Protocol on Wideband Network +IP-X25 - Internet Protocol on X.25 Networks +IRTP - Internet Reliable Transaction Protocol +ISI-GL - ISI Graphics Language Protocol +ISO-TP4 - ISO Transport Protocol Class 4 +ISO-TSAP - ISO TSAP +LA-MAINT - IMP Logical Address Maintenance +LARP - Locus Address Resoultion Protocol +LDP - Loader Debugger Protocol +LEAF-1 - Leaf-1 Protocol +LEAF-2 - Leaf-2 Protocol +LINK - Link Protocol +LOC-SRV - Location Service +LOGIN - Login Host Protocol +MAIL - Format of Electronic Mail Messages +MERIT-INP - MERIT Internodal Protocol +METAGRAM - Metagram Relay +MIB - Management Information Base +MIT-ML-DEV - MIT ML Device +MFE-NSP - MFE Network Services Protocol +MIT-SUBNET - MIT Subnet Support + + + +Reynolds & Postel [Page 227] + +RFC 1700 Assigned Numbers October 1994 + + +MIT-DOV - MIT Dover Spooler +MPM - Internet Message Protocol (Multimedia Mail) +MPM-FLAGS - MPM Flags Protocol +MPM-SND - MPM Send Protocol +MSG-AUTH - MSG Authentication Protocol +MSG-ICP - MSG ICP Protocol +MUX - Multiplexing Protocol +NAMESERVER - Host Name Server +NETBIOS-DGM - NETBIOS Datagram Service +NETBIOS-NS - NETBIOS Name Service +NETBIOS-SSN - NETBIOS Session Service +NETBLT - Bulk Data Transfer Protocol +NETED - Network Standard Text Editor +NETRJS - Remote Job Service +NI-FTP - NI File Transfer Protocol +NI-MAIL - NI Mail Protocol +NICNAME - Who Is Protocol +NFILE - A File Access Protocol +NNTP - Network News Transfer Protocol +NSW-FE - NSW User System Front End +NTP - Network Time Protocol +NVP-II - Network Voice Protocol +OSPF - Open Shortest Path First Interior GW Protocol +PCMAIL - Pcmail Transport Protocol +POP2 - Post Office Protocol - Version 2 +POP3 - Post Office Protocol - Version 3 +PPP - Point-to-Point Protocol +PRM - Packet Radio Measurement +PUP - PUP Protocol +PWDGEN - Password Generator Protocol +QUOTE - Quote of the Day Protocol +RARP - A Reverse Address Resolution Protocol +RATP - Reliable Asynchronous Transfer Protocol +RE-MAIL-CK - Remote Mail Checking Protocol +RDP - Reliable Data Protocol +RIP - Routing Information Protocol +RJE - Remote Job Entry +RLP - Resource Location Protocol +RTELNET - Remote Telnet Service +RVD - Remote Virtual Disk Protocol +SAT-EXPAK - Satnet and Backroom EXPAK +SAT-MON - SATNET Monitoring +SEP - Sequential Exchange Protocol +SFTP - Simple File Transfer Protocol +SGMP - Simple Gateway Monitoring Protocol +SNMP - Simple Network Management Protocol +SMI - Structure of Management Information +SMTP - Simple Mail Transfer Protocol + + + +Reynolds & Postel [Page 228] + +RFC 1700 Assigned Numbers October 1994 + + +SQLSRV - SQL Service +ST - Stream Protocol +STATSRV - Statistics Service +SU-MIT-TG - SU/MIT Telnet Gateway Protocol +SUN-RPC - SUN Remote Procedure Call +SUPDUP - SUPDUP Protocol +SUR-MEAS - Survey Measurement +SWIFT-RVF - Remote Virtual File Protocol +TACACS-DS - TACACS-Database Service +TACNEWS - TAC News +TCP - Transmission Control Protocol +TCP-ACO - TCP Alternate Checksum Option +TELNET - Telnet Protocol +TFTP - Trivial File Transfer Protocol +THINWIRE - Thinwire Protocol +TIME - Time Server Protocol +TP-TCP - ISO Transport Service on top of the TCP +TRUNK-1 - Trunk-1 Protocol +TRUNK-2 - Trunk-2 Protocol +UCL - University College London Protocol +UDP - User Datagram Protocol +NNTP - Network News Transfer Protocol +USERS - Active Users Protocol +UUCP-PATH - UUCP Path Service +VIA-FTP - VIA Systems-File Transfer Protocol +VISA - VISA Protocol +VMTP - Versatile Message Transaction Protocol +WB-EXPAK - Wideband EXPAK +WB-MON - Wideband Monitoring +XNET - Cross Net Debugger +XNS-IDP - Xerox NS IDP + + +REFERENCES + +[RFC952] Harrenstien, K., Stahl, M., and E. Feinler, "DoD Internet + Host Table Specification", RFC 952, SRI, October 1985. + +[] + + +URL = ftp://ftp.isi.edu/in-notes/iana/assignments/service-names + + + + + + + + + +Reynolds & Postel [Page 229] + +RFC 1700 Assigned Numbers October 1994 + + +Security Considerations + + Security issues are not discussed in this memo. + +Authors' Addresses + + Joyce K. Reynolds + USC/Information Sciences Institute + 4676 Admiralty Way + Marina del Rey, California 90292-6695 + + Phone: +1 310-822-1511 + EMail: jkrey@isi.edu + + + Jon Postel + USC/Information Sciences Institute + 4676 Admiralty Way + Marina del Rey, California 90292-6695 + + Phone: +1 310-822-1511 + EMail: postel@isi.edu + + [] + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reynolds & Postel [Page 230] + + + diff --git a/doc/rfc/rfc854.txt b/doc/rfc/rfc854.txt new file mode 100644 index 00000000..5e8c5975 --- /dev/null +++ b/doc/rfc/rfc854.txt @@ -0,0 +1,855 @@ +Network Working Group J. Postel +Request for Comments: 854 J. Reynolds + ISI +Obsoletes: NIC 18639 May 1983 + + TELNET PROTOCOL SPECIFICATION + + +This RFC specifies a standard for the ARPA Internet community. Hosts on +the ARPA Internet are expected to adopt and implement this standard. + +INTRODUCTION + + The purpose of the TELNET Protocol is to provide a fairly general, + bi-directional, eight-bit byte oriented communications facility. Its + primary goal is to allow a standard method of interfacing terminal + devices and terminal-oriented processes to each other. It is + envisioned that the protocol may also be used for terminal-terminal + communication ("linking") and process-process communication + (distributed computation). + +GENERAL CONSIDERATIONS + + A TELNET connection is a Transmission Control Protocol (TCP) + connection used to transmit data with interspersed TELNET control + information. + + The TELNET Protocol is built upon three main ideas: first, the + concept of a "Network Virtual Terminal"; second, the principle of + negotiated options; and third, a symmetric view of terminals and + processes. + + 1. When a TELNET connection is first established, each end is + assumed to originate and terminate at a "Network Virtual Terminal", + or NVT. An NVT is an imaginary device which provides a standard, + network-wide, intermediate representation of a canonical terminal. + This eliminates the need for "server" and "user" hosts to keep + information about the characteristics of each other's terminals and + terminal handling conventions. All hosts, both user and server, map + their local device characteristics and conventions so as to appear to + be dealing with an NVT over the network, and each can assume a + similar mapping by the other party. The NVT is intended to strike a + balance between being overly restricted (not providing hosts a rich + enough vocabulary for mapping into their local character sets), and + being overly inclusive (penalizing users with modest terminals). + + NOTE: The "user" host is the host to which the physical terminal + is normally attached, and the "server" host is the host which is + normally providing some service. As an alternate point of view, + + + + +Postel & Reynolds [Page 1] + + + +RFC 854 May 1983 + + + applicable even in terminal-to-terminal or process-to-process + communications, the "user" host is the host which initiated the + communication. + + 2. The principle of negotiated options takes cognizance of the fact + that many hosts will wish to provide additional services over and + above those available within an NVT, and many users will have + sophisticated terminals and would like to have elegant, rather than + minimal, services. Independent of, but structured within the TELNET + Protocol are various "options" that will be sanctioned and may be + used with the "DO, DON'T, WILL, WON'T" structure (discussed below) to + allow a user and server to agree to use a more elaborate (or perhaps + just different) set of conventions for their TELNET connection. Such + options could include changing the character set, the echo mode, etc. + + The basic strategy for setting up the use of options is to have + either party (or both) initiate a request that some option take + effect. The other party may then either accept or reject the + request. If the request is accepted the option immediately takes + effect; if it is rejected the associated aspect of the connection + remains as specified for an NVT. Clearly, a party may always refuse + a request to enable, and must never refuse a request to disable some + option since all parties must be prepared to support the NVT. + + The syntax of option negotiation has been set up so that if both + parties request an option simultaneously, each will see the other's + request as the positive acknowledgment of its own. + + 3. The symmetry of the negotiation syntax can potentially lead to + nonterminating acknowledgment loops -- each party seeing the incoming + commands not as acknowledgments but as new requests which must be + acknowledged. To prevent such loops, the following rules prevail: + + a. Parties may only request a change in option status; i.e., a + party may not send out a "request" merely to announce what mode it + is in. + + b. If a party receives what appears to be a request to enter some + mode it is already in, the request should not be acknowledged. + This non-response is essential to prevent endless loops in the + negotiation. It is required that a response be sent to requests + for a change of mode -- even if the mode is not changed. + + c. Whenever one party sends an option command to a second party, + whether as a request or an acknowledgment, and use of the option + will have any effect on the processing of the data being sent from + the first party to the second, then the command must be inserted + in the data stream at the point where it is desired that it take + + +Postel & Reynolds [Page 2] + + + +RFC 854 May 1983 + + + effect. (It should be noted that some time will elapse between + the transmission of a request and the receipt of an + acknowledgment, which may be negative. Thus, a host may wish to + buffer data, after requesting an option, until it learns whether + the request is accepted or rejected, in order to hide the + "uncertainty period" from the user.) + + Option requests are likely to flurry back and forth when a TELNET + connection is first established, as each party attempts to get the + best possible service from the other party. Beyond that, however, + options can be used to dynamically modify the characteristics of the + connection to suit changing local conditions. For example, the NVT, + as will be explained later, uses a transmission discipline well + suited to the many "line at a time" applications such as BASIC, but + poorly suited to the many "character at a time" applications such as + NLS. A server might elect to devote the extra processor overhead + required for a "character at a time" discipline when it was suitable + for the local process and would negotiate an appropriate option. + However, rather than then being permanently burdened with the extra + processing overhead, it could switch (i.e., negotiate) back to NVT + when the detailed control was no longer necessary. + + It is possible for requests initiated by processes to stimulate a + nonterminating request loop if the process responds to a rejection by + merely re-requesting the option. To prevent such loops from + occurring, rejected requests should not be repeated until something + changes. Operationally, this can mean the process is running a + different program, or the user has given another command, or whatever + makes sense in the context of the given process and the given option. + A good rule of thumb is that a re-request should only occur as a + result of subsequent information from the other end of the connection + or when demanded by local human intervention. + + Option designers should not feel constrained by the somewhat limited + syntax available for option negotiation. The intent of the simple + syntax is to make it easy to have options -- since it is + correspondingly easy to profess ignorance about them. If some + particular option requires a richer negotiation structure than + possible within "DO, DON'T, WILL, WON'T", the proper tack is to use + "DO, DON'T, WILL, WON'T" to establish that both parties understand + the option, and once this is accomplished a more exotic syntax can be + used freely. For example, a party might send a request to alter + (establish) line length. If it is accepted, then a different syntax + can be used for actually negotiating the line length -- such a + "sub-negotiation" might include fields for minimum allowable, maximum + allowable and desired line lengths. The important concept is that + + + + +Postel & Reynolds [Page 3] + + + +RFC 854 May 1983 + + + such expanded negotiations should never begin until some prior + (standard) negotiation has established that both parties are capable + of parsing the expanded syntax. + + In summary, WILL XXX is sent, by either party, to indicate that + party's desire (offer) to begin performing option XXX, DO XXX and + DON'T XXX being its positive and negative acknowledgments; similarly, + DO XXX is sent to indicate a desire (request) that the other party + (i.e., the recipient of the DO) begin performing option XXX, WILL XXX + and WON'T XXX being the positive and negative acknowledgments. Since + the NVT is what is left when no options are enabled, the DON'T and + WON'T responses are guaranteed to leave the connection in a state + which both ends can handle. Thus, all hosts may implement their + TELNET processes to be totally unaware of options that are not + supported, simply returning a rejection to (i.e., refusing) any + option request that cannot be understood. + + As much as possible, the TELNET protocol has been made server-user + symmetrical so that it easily and naturally covers the user-user + (linking) and server-server (cooperating processes) cases. It is + hoped, but not absolutely required, that options will further this + intent. In any case, it is explicitly acknowledged that symmetry is + an operating principle rather than an ironclad rule. + + A companion document, "TELNET Option Specifications," should be + consulted for information about the procedure for establishing new + options. + +THE NETWORK VIRTUAL TERMINAL + + The Network Virtual Terminal (NVT) is a bi-directional character + device. The NVT has a printer and a keyboard. The printer responds + to incoming data and the keyboard produces outgoing data which is + sent over the TELNET connection and, if "echoes" are desired, to the + NVT's printer as well. "Echoes" will not be expected to traverse the + network (although options exist to enable a "remote" echoing mode of + operation, no host is required to implement this option). The code + set is seven-bit USASCII in an eight-bit field, except as modified + herein. Any code conversion and timing considerations are local + problems and do not affect the NVT. + + TRANSMISSION OF DATA + + Although a TELNET connection through the network is intrinsically + full duplex, the NVT is to be viewed as a half-duplex device + operating in a line-buffered mode. That is, unless and until + + + + +Postel & Reynolds [Page 4] + + + +RFC 854 May 1983 + + + options are negotiated to the contrary, the following default + conditions pertain to the transmission of data over the TELNET + connection: + + 1) Insofar as the availability of local buffer space permits, + data should be accumulated in the host where it is generated + until a complete line of data is ready for transmission, or + until some locally-defined explicit signal to transmit occurs. + This signal could be generated either by a process or by a + human user. + + The motivation for this rule is the high cost, to some hosts, + of processing network input interrupts, coupled with the + default NVT specification that "echoes" do not traverse the + network. Thus, it is reasonable to buffer some amount of data + at its source. Many systems take some processing action at the + end of each input line (even line printers or card punches + frequently tend to work this way), so the transmission should + be triggered at the end of a line. On the other hand, a user + or process may sometimes find it necessary or desirable to + provide data which does not terminate at the end of a line; + therefore implementers are cautioned to provide methods of + locally signaling that all buffered data should be transmitted + immediately. + + 2) When a process has completed sending data to an NVT printer + and has no queued input from the NVT keyboard for further + processing (i.e., when a process at one end of a TELNET + connection cannot proceed without input from the other end), + the process must transmit the TELNET Go Ahead (GA) command. + + This rule is not intended to require that the TELNET GA command + be sent from a terminal at the end of each line, since server + hosts do not normally require a special signal (in addition to + end-of-line or other locally-defined characters) in order to + commence processing. Rather, the TELNET GA is designed to help + a user's local host operate a physically half duplex terminal + which has a "lockable" keyboard such as the IBM 2741. A + description of this type of terminal may help to explain the + proper use of the GA command. + + The terminal-computer connection is always under control of + either the user or the computer. Neither can unilaterally + seize control from the other; rather the controlling end must + relinguish its control explicitly. At the terminal end, the + hardware is constructed so as to relinquish control each time + that a "line" is terminated (i.e., when the "New Line" key is + typed by the user). When this occurs, the attached (local) + + +Postel & Reynolds [Page 5] + + + +RFC 854 May 1983 + + + computer processes the input data, decides if output should be + generated, and if not returns control to the terminal. If + output should be generated, control is retained by the computer + until all output has been transmitted. + + The difficulties of using this type of terminal through the + network should be obvious. The "local" computer is no longer + able to decide whether to retain control after seeing an + end-of-line signal or not; this decision can only be made by + the "remote" computer which is processing the data. Therefore, + the TELNET GA command provides a mechanism whereby the "remote" + (server) computer can signal the "local" (user) computer that + it is time to pass control to the user of the terminal. It + should be transmitted at those times, and only at those times, + when the user should be given control of the terminal. Note + that premature transmission of the GA command may result in the + blocking of output, since the user is likely to assume that the + transmitting system has paused, and therefore he will fail to + turn the line around manually. + + The foregoing, of course, does not apply to the user-to-server + direction of communication. In this direction, GAs may be sent at + any time, but need not ever be sent. Also, if the TELNET + connection is being used for process-to-process communication, GAs + need not be sent in either direction. Finally, for + terminal-to-terminal communication, GAs may be required in + neither, one, or both directions. If a host plans to support + terminal-to-terminal communication it is suggested that the host + provide the user with a means of manually signaling that it is + time for a GA to be sent over the TELNET connection; this, + however, is not a requirement on the implementer of a TELNET + process. + + Note that the symmetry of the TELNET model requires that there is + an NVT at each end of the TELNET connection, at least + conceptually. + + STANDARD REPRESENTATION OF CONTROL FUNCTIONS + + As stated in the Introduction to this document, the primary goal + of the TELNET protocol is the provision of a standard interfacing + of terminal devices and terminal-oriented processes through the + network. Early experiences with this type of interconnection have + shown that certain functions are implemented by most servers, but + that the methods of invoking these functions differ widely. For a + human user who interacts with several server systems, these + differences are highly frustrating. TELNET, therefore, defines a + standard representation for five of these functions, as described + + +Postel & Reynolds [Page 6] + + + +RFC 854 May 1983 + + + below. These standard representations have standard, but not + required, meanings (with the exception that the Interrupt Process + (IP) function may be required by other protocols which use + TELNET); that is, a system which does not provide the function to + local users need not provide it to network users and may treat the + standard representation for the function as a No-operation. On + the other hand, a system which does provide the function to a + local user is obliged to provide the same function to a network + user who transmits the standard representation for the function. + + Interrupt Process (IP) + + Many systems provide a function which suspends, interrupts, + aborts, or terminates the operation of a user process. This + function is frequently used when a user believes his process is + in an unending loop, or when an unwanted process has been + inadvertently activated. IP is the standard representation for + invoking this function. It should be noted by implementers + that IP may be required by other protocols which use TELNET, + and therefore should be implemented if these other protocols + are to be supported. + + Abort Output (AO) + + Many systems provide a function which allows a process, which + is generating output, to run to completion (or to reach the + same stopping point it would reach if running to completion) + but without sending the output to the user's terminal. + Further, this function typically clears any output already + produced but not yet actually printed (or displayed) on the + user's terminal. AO is the standard representation for + invoking this function. For example, some subsystem might + normally accept a user's command, send a long text string to + the user's terminal in response, and finally signal readiness + to accept the next command by sending a "prompt" character + (preceded by ) to the user's terminal. If the AO were + received during the transmission of the text string, a + reasonable implementation would be to suppress the remainder of + the text string, but transmit the prompt character and the + preceding . (This is possibly in distinction to the + action which might be taken if an IP were received; the IP + might cause suppression of the text string and an exit from the + subsystem.) + + It should be noted, by server systems which provide this + function, that there may be buffers external to the system (in + + + + +Postel & Reynolds [Page 7] + + + +RFC 854 May 1983 + + + the network and the user's local host) which should be cleared; + the appropriate way to do this is to transmit the "Synch" + signal (described below) to the user system. + + Are You There (AYT) + + Many systems provide a function which provides the user with + some visible (e.g., printable) evidence that the system is + still up and running. This function may be invoked by the user + when the system is unexpectedly "silent" for a long time, + because of the unanticipated (by the user) length of a + computation, an unusually heavy system load, etc. AYT is the + standard representation for invoking this function. + + Erase Character (EC) + + Many systems provide a function which deletes the last + preceding undeleted character or "print position"* from the + stream of data being supplied by the user. This function is + typically used to edit keyboard input when typing mistakes are + made. EC is the standard representation for invoking this + function. + + *NOTE: A "print position" may contain several characters + which are the result of overstrikes, or of sequences such as + BS ... + + Erase Line (EL) + + Many systems provide a function which deletes all the data in + the current "line" of input. This function is typically used + to edit keyboard input. EL is the standard representation for + invoking this function. + + THE TELNET "SYNCH" SIGNAL + + Most time-sharing systems provide mechanisms which allow a + terminal user to regain control of a "runaway" process; the IP and + AO functions described above are examples of these mechanisms. + Such systems, when used locally, have access to all of the signals + supplied by the user, whether these are normal characters or + special "out of band" signals such as those supplied by the + teletype "BREAK" key or the IBM 2741 "ATTN" key. This is not + necessarily true when terminals are connected to the system + through the network; the network's flow control mechanisms may + cause such a signal to be buffered elsewhere, for example in the + user's host. + + + +Postel & Reynolds [Page 8] + + + +RFC 854 May 1983 + + + To counter this problem, the TELNET "Synch" mechanism is + introduced. A Synch signal consists of a TCP Urgent notification, + coupled with the TELNET command DATA MARK. The Urgent + notification, which is not subject to the flow control pertaining + to the TELNET connection, is used to invoke special handling of + the data stream by the process which receives it. In this mode, + the data stream is immediately scanned for "interesting" signals + as defined below, discarding intervening data. The TELNET command + DATA MARK (DM) is the synchronizing mark in the data stream which + indicates that any special signal has already occurred and the + recipient can return to normal processing of the data stream. + + The Synch is sent via the TCP send operation with the Urgent + flag set and the DM as the last (or only) data octet. + + When several Synchs are sent in rapid succession, the Urgent + notifications may be merged. It is not possible to count Urgents + since the number received will be less than or equal the number + sent. When in normal mode, a DM is a no operation; when in urgent + mode, it signals the end of the urgent processing. + + If TCP indicates the end of Urgent data before the DM is found, + TELNET should continue the special handling of the data stream + until the DM is found. + + If TCP indicates more Urgent data after the DM is found, it can + only be because of a subsequent Synch. TELNET should continue + the special handling of the data stream until another DM is + found. + + "Interesting" signals are defined to be: the TELNET standard + representations of IP, AO, and AYT (but not EC or EL); the local + analogs of these standard representations (if any); all other + TELNET commands; other site-defined signals which can be acted on + without delaying the scan of the data stream. + + Since one effect of the SYNCH mechanism is the discarding of + essentially all characters (except TELNET commands) between the + sender of the Synch and its recipient, this mechanism is specified + as the standard way to clear the data path when that is desired. + For example, if a user at a terminal causes an AO to be + transmitted, the server which receives the AO (if it provides that + function at all) should return a Synch to the user. + + Finally, just as the TCP Urgent notification is needed at the + TELNET level as an out-of-band signal, so other protocols which + make use of TELNET may require a TELNET command which can be + viewed as an out-of-band signal at a different level. + + +Postel & Reynolds [Page 9] + + + +RFC 854 May 1983 + + + By convention the sequence [IP, Synch] is to be used as such a + signal. For example, suppose that some other protocol, which uses + TELNET, defines the character string STOP analogously to the + TELNET command AO. Imagine that a user of this protocol wishes a + server to process the STOP string, but the connection is blocked + because the server is processing other commands. The user should + instruct his system to: + + 1. Send the TELNET IP character; + + 2. Send the TELNET SYNC sequence, that is: + + Send the Data Mark (DM) as the only character + in a TCP urgent mode send operation. + + 3. Send the character string STOP; and + + 4. Send the other protocol's analog of the TELNET DM, if any. + + The user (or process acting on his behalf) must transmit the + TELNET SYNCH sequence of step 2 above to ensure that the TELNET IP + gets through to the server's TELNET interpreter. + + The Urgent should wake up the TELNET process; the IP should + wake up the next higher level process. + + THE NVT PRINTER AND KEYBOARD + + The NVT printer has an unspecified carriage width and page length + and can produce representations of all 95 USASCII graphics (codes + 32 through 126). Of the 33 USASCII control codes (0 through 31 + and 127), and the 128 uncovered codes (128 through 255), the + following have specified meaning to the NVT printer: + + NAME CODE MEANING + + NULL (NUL) 0 No Operation + Line Feed (LF) 10 Moves the printer to the + next print line, keeping the + same horizontal position. + Carriage Return (CR) 13 Moves the printer to the left + margin of the current line. + + + + + + + + +Postel & Reynolds [Page 10] + + + +RFC 854 May 1983 + + + In addition, the following codes shall have defined, but not + required, effects on the NVT printer. Neither end of a TELNET + connection may assume that the other party will take, or will + have taken, any particular action upon receipt or transmission + of these: + + BELL (BEL) 7 Produces an audible or + visible signal (which does + NOT move the print head). + Back Space (BS) 8 Moves the print head one + character position towards + the left margin. + Horizontal Tab (HT) 9 Moves the printer to the + next horizontal tab stop. + It remains unspecified how + either party determines or + establishes where such tab + stops are located. + Vertical Tab (VT) 11 Moves the printer to the + next vertical tab stop. It + remains unspecified how + either party determines or + establishes where such tab + stops are located. + Form Feed (FF) 12 Moves the printer to the top + of the next page, keeping + the same horizontal position. + + All remaining codes do not cause the NVT printer to take any + action. + + The sequence "CR LF", as defined, will cause the NVT to be + positioned at the left margin of the next print line (as would, + for example, the sequence "LF CR"). However, many systems and + terminals do not treat CR and LF independently, and will have to + go to some effort to simulate their effect. (For example, some + terminals do not have a CR independent of the LF, but on such + terminals it may be possible to simulate a CR by backspacing.) + Therefore, the sequence "CR LF" must be treated as a single "new + line" character and used whenever their combined action is + intended; the sequence "CR NUL" must be used where a carriage + return alone is actually desired; and the CR character must be + avoided in other contexts. This rule gives assurance to systems + which must decide whether to perform a "new line" function or a + multiple-backspace that the TELNET stream contains a character + following a CR that will allow a rational decision. + + Note that "CR LF" or "CR NUL" is required in both directions + + +Postel & Reynolds [Page 11] + + + +RFC 854 May 1983 + + + (in the default ASCII mode), to preserve the symmetry of the + NVT model. Even though it may be known in some situations + (e.g., with remote echo and suppress go ahead options in + effect) that characters are not being sent to an actual + printer, nonetheless, for the sake of consistency, the protocol + requires that a NUL be inserted following a CR not followed by + a LF in the data stream. The converse of this is that a NUL + received in the data stream after a CR (in the absence of + options negotiations which explicitly specify otherwise) should + be stripped out prior to applying the NVT to local character + set mapping. + + The NVT keyboard has keys, or key combinations, or key sequences, + for generating all 128 USASCII codes. Note that although many + have no effect on the NVT printer, the NVT keyboard is capable of + generating them. + + In addition to these codes, the NVT keyboard shall be capable of + generating the following additional codes which, except as noted, + have defined, but not reguired, meanings. The actual code + assignments for these "characters" are in the TELNET Command + section, because they are viewed as being, in some sense, generic + and should be available even when the data stream is interpreted + as being some other character set. + + Synch + + This key allows the user to clear his data path to the other + party. The activation of this key causes a DM (see command + section) to be sent in the data stream and a TCP Urgent + notification is associated with it. The pair DM-Urgent is to + have required meaning as defined previously. + + Break (BRK) + + This code is provided because it is a signal outside the + USASCII set which is currently given local meaning within many + systems. It is intended to indicate that the Break Key or the + Attention Key was hit. Note, however, that this is intended to + provide a 129th code for systems which require it, not as a + synonym for the IP standard representation. + + Interrupt Process (IP) + + Suspend, interrupt, abort or terminate the process to which the + NVT is connected. Also, part of the out-of-band signal for + other protocols which use TELNET. + + + +Postel & Reynolds [Page 12] + + + +RFC 854 May 1983 + + + Abort Output (AO) + + Allow the current process to (appear to) run to completion, but + do not send its output to the user. Also, send a Synch to the + user. + + Are You There (AYT) + + Send back to the NVT some visible (i.e., printable) evidence + that the AYT was received. + + Erase Character (EC) + + The recipient should delete the last preceding undeleted + character or "print position" from the data stream. + + Erase Line (EL) + + The recipient should delete characters from the data stream + back to, but not including, the last "CR LF" sequence sent over + the TELNET connection. + + The spirit of these "extra" keys, and also the printer format + effectors, is that they should represent a natural extension of + the mapping that already must be done from "NVT" into "local". + Just as the NVT data byte 68 (104 octal) should be mapped into + whatever the local code for "uppercase D" is, so the EC character + should be mapped into whatever the local "Erase Character" + function is. Further, just as the mapping for 124 (174 octal) is + somewhat arbitrary in an environment that has no "vertical bar" + character, the EL character may have a somewhat arbitrary mapping + (or none at all) if there is no local "Erase Line" facility. + Similarly for format effectors: if the terminal actually does + have a "Vertical Tab", then the mapping for VT is obvious, and + only when the terminal does not have a vertical tab should the + effect of VT be unpredictable. + +TELNET COMMAND STRUCTURE + + All TELNET commands consist of at least a two byte sequence: the + "Interpret as Command" (IAC) escape character followed by the code + for the command. The commands dealing with option negotiation are + three byte sequences, the third byte being the code for the option + referenced. This format was chosen so that as more comprehensive use + of the "data space" is made -- by negotiations from the basic NVT, of + course -- collisions of data bytes with reserved command values will + be minimized, all such collisions requiring the inconvenience, and + + + +Postel & Reynolds [Page 13] + + + +RFC 854 May 1983 + + + inefficiency, of "escaping" the data bytes into the stream. With the + current set-up, only the IAC need be doubled to be sent as data, and + the other 255 codes may be passed transparently. + + The following are the defined TELNET commands. Note that these codes + and code sequences have the indicated meaning only when immediately + preceded by an IAC. + + NAME CODE MEANING + + SE 240 End of subnegotiation parameters. + NOP 241 No operation. + Data Mark 242 The data stream portion of a Synch. + This should always be accompanied + by a TCP Urgent notification. + Break 243 NVT character BRK. + Interrupt Process 244 The function IP. + Abort output 245 The function AO. + Are You There 246 The function AYT. + Erase character 247 The function EC. + Erase Line 248 The function EL. + Go ahead 249 The GA signal. + SB 250 Indicates that what follows is + subnegotiation of the indicated + option. + WILL (option code) 251 Indicates the desire to begin + performing, or confirmation that + you are now performing, the + indicated option. + WON'T (option code) 252 Indicates the refusal to perform, + or continue performing, the + indicated option. + DO (option code) 253 Indicates the request that the + other party perform, or + confirmation that you are expecting + the other party to perform, the + indicated option. + DON'T (option code) 254 Indicates the demand that the + other party stop performing, + or confirmation that you are no + longer expecting the other party + to perform, the indicated option. + IAC 255 Data Byte 255. + + + + + + + +Postel & Reynolds [Page 14] + + + +RFC 854 May 1983 + + +CONNECTION ESTABLISHMENT + + The TELNET TCP connection is established between the user's port U + and the server's port L. The server listens on its well known port L + for such connections. Since a TCP connection is full duplex and + identified by the pair of ports, the server can engage in many + simultaneous connections involving its port L and different user + ports U. + + Port Assignment + + When used for remote user access to service hosts (i.e., remote + terminal access) this protocol is assigned server port 23 + (27 octal). That is L=23. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 15] + + + diff --git a/doc/rfc/std5.txt b/doc/rfc/std5.txt new file mode 100644 index 00000000..e32de917 --- /dev/null +++ b/doc/rfc/std5.txt @@ -0,0 +1,7227 @@ + +RFC: 791 + + + + + + + + INTERNET PROTOCOL + + + DARPA INTERNET PROGRAM + + PROTOCOL SPECIFICATION + + + + September 1981 + + + + + + + + + + + + + + prepared for + + Defense Advanced Research Projects Agency + Information Processing Techniques Office + 1400 Wilson Boulevard + Arlington, Virginia 22209 + + + + + + + + by + + Information Sciences Institute + University of Southern California + 4676 Admiralty Way + Marina del Rey, California 90291 + + + +September 1981 + Internet Protocol + + + + TABLE OF CONTENTS + + PREFACE ........................................................ iii + +1. INTRODUCTION ..................................................... 1 + + 1.1 Motivation .................................................... 1 + 1.2 Scope ......................................................... 1 + 1.3 Interfaces .................................................... 1 + 1.4 Operation ..................................................... 2 + +2. OVERVIEW ......................................................... 5 + + 2.1 Relation to Other Protocols ................................... 9 + 2.2 Model of Operation ............................................ 5 + 2.3 Function Description .......................................... 7 + 2.4 Gateways ...................................................... 9 + +3. SPECIFICATION ................................................... 11 + + 3.1 Internet Header Format ....................................... 11 + 3.2 Discussion ................................................... 23 + 3.3 Interfaces ................................................... 31 + +APPENDIX A: Examples & Scenarios ................................... 34 +APPENDIX B: Data Transmission Order ................................ 39 + +GLOSSARY ............................................................ 41 + +REFERENCES .......................................................... 45 + + + + + + + + + + + + + + + + + + + + + + [Page i] + + + September 1981 +Internet Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page ii] + + +September 1981 + Internet Protocol + + + + PREFACE + + + +This document specifies the DoD Standard Internet Protocol. This +document is based on six earlier editions of the ARPA Internet Protocol +Specification, and the present text draws heavily from them. There have +been many contributors to this work both in terms of concepts and in +terms of text. This edition revises aspects of addressing, error +handling, option codes, and the security, precedence, compartments, and +handling restriction features of the internet protocol. + + Jon Postel + + Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page iii] + + + + September 1981 + + +RFC: 791 +Replaces: RFC 760 +IENs 128, 123, 111, +80, 54, 44, 41, 28, 26 + + INTERNET PROTOCOL + + DARPA INTERNET PROGRAM + PROTOCOL SPECIFICATION + + + + 1. INTRODUCTION + +1.1. Motivation + + The Internet Protocol is designed for use in interconnected systems of + packet-switched computer communication networks. Such a system has + been called a "catenet" [1]. The internet protocol provides for + transmitting blocks of data called datagrams from sources to + destinations, where sources and destinations are hosts identified by + fixed length addresses. The internet protocol also provides for + fragmentation and reassembly of long datagrams, if necessary, for + transmission through "small packet" networks. + +1.2. Scope + + The internet protocol is specifically limited in scope to provide the + functions necessary to deliver a package of bits (an internet + datagram) from a source to a destination over an interconnected system + of networks. There are no mechanisms to augment end-to-end data + reliability, flow control, sequencing, or other services commonly + found in host-to-host protocols. The internet protocol can capitalize + on the services of its supporting networks to provide various types + and qualities of service. + +1.3. Interfaces + + This protocol is called on by host-to-host protocols in an internet + environment. This protocol calls on local network protocols to carry + the internet datagram to the next gateway or destination host. + + For example, a TCP module would call on the internet module to take a + TCP segment (including the TCP header and user data) as the data + portion of an internet datagram. The TCP module would provide the + addresses and other parameters in the internet header to the internet + module as arguments of the call. The internet module would then + create an internet datagram and call on the local network interface to + transmit the internet datagram. + + In the ARPANET case, for example, the internet module would call on a + + + [Page 1] + + + September 1981 +Internet Protocol +Introduction + + + + local net module which would add the 1822 leader [2] to the internet + datagram creating an ARPANET message to transmit to the IMP. The + ARPANET address would be derived from the internet address by the + local network interface and would be the address of some host in the + ARPANET, that host might be a gateway to other networks. + +1.4. Operation + + The internet protocol implements two basic functions: addressing and + fragmentation. + + The internet modules use the addresses carried in the internet header + to transmit internet datagrams toward their destinations. The + selection of a path for transmission is called routing. + + The internet modules use fields in the internet header to fragment and + reassemble internet datagrams when necessary for transmission through + "small packet" networks. + + The model of operation is that an internet module resides in each host + engaged in internet communication and in each gateway that + interconnects networks. These modules share common rules for + interpreting address fields and for fragmenting and assembling + internet datagrams. In addition, these modules (especially in + gateways) have procedures for making routing decisions and other + functions. + + The internet protocol treats each internet datagram as an independent + entity unrelated to any other internet datagram. There are no + connections or logical circuits (virtual or otherwise). + + The internet protocol uses four key mechanisms in providing its + service: Type of Service, Time to Live, Options, and Header Checksum. + + The Type of Service is used to indicate the quality of the service + desired. The type of service is an abstract or generalized set of + parameters which characterize the service choices provided in the + networks that make up the internet. This type of service indication + is to be used by gateways to select the actual transmission parameters + for a particular network, the network to be used for the next hop, or + the next gateway when routing an internet datagram. + + The Time to Live is an indication of an upper bound on the lifetime of + an internet datagram. It is set by the sender of the datagram and + reduced at the points along the route where it is processed. If the + time to live reaches zero before the internet datagram reaches its + destination, the internet datagram is destroyed. The time to live can + be thought of as a self destruct time limit. + + +[Page 2] + + +September 1981 + Internet Protocol + Introduction + + + + The Options provide for control functions needed or useful in some + situations but unnecessary for the most common communications. The + options include provisions for timestamps, security, and special + routing. + + The Header Checksum provides a verification that the information used + in processing internet datagram has been transmitted correctly. The + data may contain errors. If the header checksum fails, the internet + datagram is discarded at once by the entity which detects the error. + + The internet protocol does not provide a reliable communication + facility. There are no acknowledgments either end-to-end or + hop-by-hop. There is no error control for data, only a header + checksum. There are no retransmissions. There is no flow control. + + Errors detected may be reported via the Internet Control Message + Protocol (ICMP) [3] which is implemented in the internet protocol + module. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 3] + + + September 1981 +Internet Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 4] + + +September 1981 + Internet Protocol + + + + 2. OVERVIEW + +2.1. Relation to Other Protocols + + The following diagram illustrates the place of the internet protocol + in the protocol hierarchy: + + + +------+ +-----+ +-----+ +-----+ + |Telnet| | FTP | | TFTP| ... | ... | + +------+ +-----+ +-----+ +-----+ + | | | | + +-----+ +-----+ +-----+ + | TCP | | UDP | ... | ... | + +-----+ +-----+ +-----+ + | | | + +--------------------------+----+ + | Internet Protocol & ICMP | + +--------------------------+----+ + | + +---------------------------+ + | Local Network Protocol | + +---------------------------+ + + Protocol Relationships + + Figure 1. + + Internet protocol interfaces on one side to the higher level + host-to-host protocols and on the other side to the local network + protocol. In this context a "local network" may be a small network in + a building or a large network such as the ARPANET. + +2.2. Model of Operation + + The model of operation for transmitting a datagram from one + application program to another is illustrated by the following + scenario: + + We suppose that this transmission will involve one intermediate + gateway. + + The sending application program prepares its data and calls on its + local internet module to send that data as a datagram and passes the + destination address and other parameters as arguments of the call. + + The internet module prepares a datagram header and attaches the data + to it. The internet module determines a local network address for + this internet address, in this case it is the address of a gateway. + + + [Page 5] + + + September 1981 +Internet Protocol +Overview + + + + It sends this datagram and the local network address to the local + network interface. + + The local network interface creates a local network header, and + attaches the datagram to it, then sends the result via the local + network. + + The datagram arrives at a gateway host wrapped in the local network + header, the local network interface strips off this header, and + turns the datagram over to the internet module. The internet module + determines from the internet address that the datagram is to be + forwarded to another host in a second network. The internet module + determines a local net address for the destination host. It calls + on the local network interface for that network to send the + datagram. + + This local network interface creates a local network header and + attaches the datagram sending the result to the destination host. + + At this destination host the datagram is stripped of the local net + header by the local network interface and handed to the internet + module. + + The internet module determines that the datagram is for an + application program in this host. It passes the data to the + application program in response to a system call, passing the source + address and other parameters as results of the call. + + + Application Application + Program Program + \ / + Internet Module Internet Module Internet Module + \ / \ / + LNI-1 LNI-1 LNI-2 LNI-2 + \ / \ / + Local Network 1 Local Network 2 + + + + Transmission Path + + Figure 2 + + + + + + + +[Page 6] + + +September 1981 + Internet Protocol + Overview + + + +2.3. Function Description + + The function or purpose of Internet Protocol is to move datagrams + through an interconnected set of networks. This is done by passing + the datagrams from one internet module to another until the + destination is reached. The internet modules reside in hosts and + gateways in the internet system. The datagrams are routed from one + internet module to another through individual networks based on the + interpretation of an internet address. Thus, one important mechanism + of the internet protocol is the internet address. + + In the routing of messages from one internet module to another, + datagrams may need to traverse a network whose maximum packet size is + smaller than the size of the datagram. To overcome this difficulty, a + fragmentation mechanism is provided in the internet protocol. + + Addressing + + A distinction is made between names, addresses, and routes [4]. A + name indicates what we seek. An address indicates where it is. A + route indicates how to get there. The internet protocol deals + primarily with addresses. It is the task of higher level (i.e., + host-to-host or application) protocols to make the mapping from + names to addresses. The internet module maps internet addresses to + local net addresses. It is the task of lower level (i.e., local net + or gateways) procedures to make the mapping from local net addresses + to routes. + + Addresses are fixed length of four octets (32 bits). An address + begins with a network number, followed by local address (called the + "rest" field). There are three formats or classes of internet + addresses: in class a, the high order bit is zero, the next 7 bits + are the network, and the last 24 bits are the local address; in + class b, the high order two bits are one-zero, the next 14 bits are + the network and the last 16 bits are the local address; in class c, + the high order three bits are one-one-zero, the next 21 bits are the + network and the last 8 bits are the local address. + + Care must be taken in mapping internet addresses to local net + addresses; a single physical host must be able to act as if it were + several distinct hosts to the extent of using several distinct + internet addresses. Some hosts will also have several physical + interfaces (multi-homing). + + That is, provision must be made for a host to have several physical + interfaces to the network with each having several logical internet + addresses. + + + + [Page 7] + + + September 1981 +Internet Protocol +Overview + + + + Examples of address mappings may be found in "Address Mappings" [5]. + + Fragmentation + + Fragmentation of an internet datagram is necessary when it + originates in a local net that allows a large packet size and must + traverse a local net that limits packets to a smaller size to reach + its destination. + + An internet datagram can be marked "don't fragment." Any internet + datagram so marked is not to be internet fragmented under any + circumstances. If internet datagram marked don't fragment cannot be + delivered to its destination without fragmenting it, it is to be + discarded instead. + + Fragmentation, transmission and reassembly across a local network + which is invisible to the internet protocol module is called + intranet fragmentation and may be used [6]. + + The internet fragmentation and reassembly procedure needs to be able + to break a datagram into an almost arbitrary number of pieces that + can be later reassembled. The receiver of the fragments uses the + identification field to ensure that fragments of different datagrams + are not mixed. The fragment offset field tells the receiver the + position of a fragment in the original datagram. The fragment + offset and length determine the portion of the original datagram + covered by this fragment. The more-fragments flag indicates (by + being reset) the last fragment. These fields provide sufficient + information to reassemble datagrams. + + The identification field is used to distinguish the fragments of one + datagram from those of another. The originating protocol module of + an internet datagram sets the identification field to a value that + must be unique for that source-destination pair and protocol for the + time the datagram will be active in the internet system. The + originating protocol module of a complete datagram sets the + more-fragments flag to zero and the fragment offset to zero. + + To fragment a long internet datagram, an internet protocol module + (for example, in a gateway), creates two new internet datagrams and + copies the contents of the internet header fields from the long + datagram into both new internet headers. The data of the long + datagram is divided into two portions on a 8 octet (64 bit) boundary + (the second portion might not be an integral multiple of 8 octets, + but the first must be). Call the number of 8 octet blocks in the + first portion NFB (for Number of Fragment Blocks). The first + portion of the data is placed in the first new internet datagram, + and the total length field is set to the length of the first + + +[Page 8] + + +September 1981 + Internet Protocol + Overview + + + + datagram. The more-fragments flag is set to one. The second + portion of the data is placed in the second new internet datagram, + and the total length field is set to the length of the second + datagram. The more-fragments flag carries the same value as the + long datagram. The fragment offset field of the second new internet + datagram is set to the value of that field in the long datagram plus + NFB. + + This procedure can be generalized for an n-way split, rather than + the two-way split described. + + To assemble the fragments of an internet datagram, an internet + protocol module (for example at a destination host) combines + internet datagrams that all have the same value for the four fields: + identification, source, destination, and protocol. The combination + is done by placing the data portion of each fragment in the relative + position indicated by the fragment offset in that fragment's + internet header. The first fragment will have the fragment offset + zero, and the last fragment will have the more-fragments flag reset + to zero. + +2.4. Gateways + + Gateways implement internet protocol to forward datagrams between + networks. Gateways also implement the Gateway to Gateway Protocol + (GGP) [7] to coordinate routing and other internet control + information. + + In a gateway the higher level protocols need not be implemented and + the GGP functions are added to the IP module. + + + +-------------------------------+ + | Internet Protocol & ICMP & GGP| + +-------------------------------+ + | | + +---------------+ +---------------+ + | Local Net | | Local Net | + +---------------+ +---------------+ + + Gateway Protocols + + Figure 3. + + + + + + + + [Page 9] + + + September 1981 +Internet Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 10] + + +September 1981 + Internet Protocol + + + + 3. SPECIFICATION + +3.1. Internet Header Format + + A summary of the contents of the internet header follows: + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Version| IHL |Type of Service| Total Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification |Flags| Fragment Offset | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time to Live | Protocol | Header Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Source Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Destination Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Options | Padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Example Internet Datagram Header + + Figure 4. + + Note that each tick mark represents one bit position. + + Version: 4 bits + + The Version field indicates the format of the internet header. This + document describes version 4. + + IHL: 4 bits + + Internet Header Length is the length of the internet header in 32 + bit words, and thus points to the beginning of the data. Note that + the minimum value for a correct header is 5. + + + + + + + + + + + + + [Page 11] + + + September 1981 +Internet Protocol +Specification + + + + Type of Service: 8 bits + + The Type of Service provides an indication of the abstract + parameters of the quality of service desired. These parameters are + to be used to guide the selection of the actual service parameters + when transmitting a datagram through a particular network. Several + networks offer service precedence, which somehow treats high + precedence traffic as more important than other traffic (generally + by accepting only traffic above a certain precedence at time of high + load). The major choice is a three way tradeoff between low-delay, + high-reliability, and high-throughput. + + Bits 0-2: Precedence. + Bit 3: 0 = Normal Delay, 1 = Low Delay. + Bits 4: 0 = Normal Throughput, 1 = High Throughput. + Bits 5: 0 = Normal Relibility, 1 = High Relibility. + Bit 6-7: Reserved for Future Use. + + 0 1 2 3 4 5 6 7 + +-----+-----+-----+-----+-----+-----+-----+-----+ + | | | | | | | + | PRECEDENCE | D | T | R | 0 | 0 | + | | | | | | | + +-----+-----+-----+-----+-----+-----+-----+-----+ + + Precedence + + 111 - Network Control + 110 - Internetwork Control + 101 - CRITIC/ECP + 100 - Flash Override + 011 - Flash + 010 - Immediate + 001 - Priority + 000 - Routine + + The use of the Delay, Throughput, and Reliability indications may + increase the cost (in some sense) of the service. In many networks + better performance for one of these parameters is coupled with worse + performance on another. Except for very unusual cases at most two + of these three indications should be set. + + The type of service is used to specify the treatment of the datagram + during its transmission through the internet system. Example + mappings of the internet type of service to the actual service + provided on networks such as AUTODIN II, ARPANET, SATNET, and PRNET + is given in "Service Mappings" [8]. + + + +[Page 12] + + +September 1981 + Internet Protocol + Specification + + + + The Network Control precedence designation is intended to be used + within a network only. The actual use and control of that + designation is up to each network. The Internetwork Control + designation is intended for use by gateway control originators only. + If the actual use of these precedence designations is of concern to + a particular network, it is the responsibility of that network to + control the access to, and use of, those precedence designations. + + Total Length: 16 bits + + Total Length is the length of the datagram, measured in octets, + including internet header and data. This field allows the length of + a datagram to be up to 65,535 octets. Such long datagrams are + impractical for most hosts and networks. All hosts must be prepared + to accept datagrams of up to 576 octets (whether they arrive whole + or in fragments). It is recommended that hosts only send datagrams + larger than 576 octets if they have assurance that the destination + is prepared to accept the larger datagrams. + + The number 576 is selected to allow a reasonable sized data block to + be transmitted in addition to the required header information. For + example, this size allows a data block of 512 octets plus 64 header + octets to fit in a datagram. The maximal internet header is 60 + octets, and a typical internet header is 20 octets, allowing a + margin for headers of higher level protocols. + + Identification: 16 bits + + An identifying value assigned by the sender to aid in assembling the + fragments of a datagram. + + Flags: 3 bits + + Various Control Flags. + + Bit 0: reserved, must be zero + Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment. + Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments. + + 0 1 2 + +---+---+---+ + | | D | M | + | 0 | F | F | + +---+---+---+ + + Fragment Offset: 13 bits + + This field indicates where in the datagram this fragment belongs. + + + [Page 13] + + + September 1981 +Internet Protocol +Specification + + + + The fragment offset is measured in units of 8 octets (64 bits). The + first fragment has offset zero. + + Time to Live: 8 bits + + This field indicates the maximum time the datagram is allowed to + remain in the internet system. If this field contains the value + zero, then the datagram must be destroyed. This field is modified + in internet header processing. The time is measured in units of + seconds, but since every module that processes a datagram must + decrease the TTL by at least one even if it process the datagram in + less than a second, the TTL must be thought of only as an upper + bound on the time a datagram may exist. The intention is to cause + undeliverable datagrams to be discarded, and to bound the maximum + datagram lifetime. + + Protocol: 8 bits + + This field indicates the next level protocol used in the data + portion of the internet datagram. The values for various protocols + are specified in "Assigned Numbers" [9]. + + Header Checksum: 16 bits + + A checksum on the header only. Since some header fields change + (e.g., time to live), this is recomputed and verified at each point + that the internet header is processed. + + The checksum algorithm is: + + The checksum field is the 16 bit one's complement of the one's + complement sum of all 16 bit words in the header. For purposes of + computing the checksum, the value of the checksum field is zero. + + This is a simple to compute checksum and experimental evidence + indicates it is adequate, but it is provisional and may be replaced + by a CRC procedure, depending on further experience. + + Source Address: 32 bits + + The source address. See section 3.2. + + Destination Address: 32 bits + + The destination address. See section 3.2. + + + + + +[Page 14] + + +September 1981 + Internet Protocol + Specification + + + + Options: variable + + The options may appear or not in datagrams. They must be + implemented by all IP modules (host and gateways). What is optional + is their transmission in any particular datagram, not their + implementation. + + In some environments the security option may be required in all + datagrams. + + The option field is variable in length. There may be zero or more + options. There are two cases for the format of an option: + + Case 1: A single octet of option-type. + + Case 2: An option-type octet, an option-length octet, and the + actual option-data octets. + + The option-length octet counts the option-type octet and the + option-length octet as well as the option-data octets. + + The option-type octet is viewed as having 3 fields: + + 1 bit copied flag, + 2 bits option class, + 5 bits option number. + + The copied flag indicates that this option is copied into all + fragments on fragmentation. + + 0 = not copied + 1 = copied + + The option classes are: + + 0 = control + 1 = reserved for future use + 2 = debugging and measurement + 3 = reserved for future use + + + + + + + + + + + + [Page 15] + + + September 1981 +Internet Protocol +Specification + + + + The following internet options are defined: + + CLASS NUMBER LENGTH DESCRIPTION + ----- ------ ------ ----------- + 0 0 - End of Option list. This option occupies only + 1 octet; it has no length octet. + 0 1 - No Operation. This option occupies only 1 + octet; it has no length octet. + 0 2 11 Security. Used to carry Security, + Compartmentation, User Group (TCC), and + Handling Restriction Codes compatible with DOD + requirements. + 0 3 var. Loose Source Routing. Used to route the + internet datagram based on information + supplied by the source. + 0 9 var. Strict Source Routing. Used to route the + internet datagram based on information + supplied by the source. + 0 7 var. Record Route. Used to trace the route an + internet datagram takes. + 0 8 4 Stream ID. Used to carry the stream + identifier. + 2 4 var. Internet Timestamp. + + + + Specific Option Definitions + + End of Option List + + +--------+ + |00000000| + +--------+ + Type=0 + + This option indicates the end of the option list. This might + not coincide with the end of the internet header according to + the internet header length. This is used at the end of all + options, not the end of each option, and need only be used if + the end of the options would not otherwise coincide with the end + of the internet header. + + May be copied, introduced, or deleted on fragmentation, or for + any other reason. + + + + + + +[Page 16] + + +September 1981 + Internet Protocol + Specification + + + + No Operation + + +--------+ + |00000001| + +--------+ + Type=1 + + This option may be used between options, for example, to align + the beginning of a subsequent option on a 32 bit boundary. + + May be copied, introduced, or deleted on fragmentation, or for + any other reason. + + Security + + This option provides a way for hosts to send security, + compartmentation, handling restrictions, and TCC (closed user + group) parameters. The format for this option is as follows: + + +--------+--------+---//---+---//---+---//---+---//---+ + |10000010|00001011|SSS SSS|CCC CCC|HHH HHH| TCC | + +--------+--------+---//---+---//---+---//---+---//---+ + Type=130 Length=11 + + Security (S field): 16 bits + + Specifies one of 16 levels of security (eight of which are + reserved for future use). + + 00000000 00000000 - Unclassified + 11110001 00110101 - Confidential + 01111000 10011010 - EFTO + 10111100 01001101 - MMMM + 01011110 00100110 - PROG + 10101111 00010011 - Restricted + 11010111 10001000 - Secret + 01101011 11000101 - Top Secret + 00110101 11100010 - (Reserved for future use) + 10011010 11110001 - (Reserved for future use) + 01001101 01111000 - (Reserved for future use) + 00100100 10111101 - (Reserved for future use) + 00010011 01011110 - (Reserved for future use) + 10001001 10101111 - (Reserved for future use) + 11000100 11010110 - (Reserved for future use) + 11100010 01101011 - (Reserved for future use) + + + + + + [Page 17] + + + September 1981 +Internet Protocol +Specification + + + + Compartments (C field): 16 bits + + An all zero value is used when the information transmitted is + not compartmented. Other values for the compartments field + may be obtained from the Defense Intelligence Agency. + + Handling Restrictions (H field): 16 bits + + The values for the control and release markings are + alphanumeric digraphs and are defined in the Defense + Intelligence Agency Manual DIAM 65-19, "Standard Security + Markings". + + Transmission Control Code (TCC field): 24 bits + + Provides a means to segregate traffic and define controlled + communities of interest among subscribers. The TCC values are + trigraphs, and are available from HQ DCA Code 530. + + Must be copied on fragmentation. This option appears at most + once in a datagram. + + Loose Source and Record Route + + +--------+--------+--------+---------//--------+ + |10000011| length | pointer| route data | + +--------+--------+--------+---------//--------+ + Type=131 + + The loose source and record route (LSRR) option provides a means + for the source of an internet datagram to supply routing + information to be used by the gateways in forwarding the + datagram to the destination, and to record the route + information. + + The option begins with the option type code. The second octet + is the option length which includes the option type code and the + length octet, the pointer octet, and length-3 octets of route + data. The third octet is the pointer into the route data + indicating the octet which begins the next source address to be + processed. The pointer is relative to this option, and the + smallest legal value for the pointer is 4. + + A route data is composed of a series of internet addresses. + Each internet address is 32 bits or 4 octets. If the pointer is + greater than the length, the source route is empty (and the + recorded route full) and the routing is to be based on the + destination address field. + + +[Page 18] + + +September 1981 + Internet Protocol + Specification + + + + If the address in destination address field has been reached and + the pointer is not greater than the length, the next address in + the source route replaces the address in the destination address + field, and the recorded route address replaces the source + address just used, and pointer is increased by four. + + The recorded route address is the internet module's own internet + address as known in the environment into which this datagram is + being forwarded. + + This procedure of replacing the source route with the recorded + route (though it is in the reverse of the order it must be in to + be used as a source route) means the option (and the IP header + as a whole) remains a constant length as the datagram progresses + through the internet. + + This option is a loose source route because the gateway or host + IP is allowed to use any route of any number of other + intermediate gateways to reach the next address in the route. + + Must be copied on fragmentation. Appears at most once in a + datagram. + + Strict Source and Record Route + + +--------+--------+--------+---------//--------+ + |10001001| length | pointer| route data | + +--------+--------+--------+---------//--------+ + Type=137 + + The strict source and record route (SSRR) option provides a + means for the source of an internet datagram to supply routing + information to be used by the gateways in forwarding the + datagram to the destination, and to record the route + information. + + The option begins with the option type code. The second octet + is the option length which includes the option type code and the + length octet, the pointer octet, and length-3 octets of route + data. The third octet is the pointer into the route data + indicating the octet which begins the next source address to be + processed. The pointer is relative to this option, and the + smallest legal value for the pointer is 4. + + A route data is composed of a series of internet addresses. + Each internet address is 32 bits or 4 octets. If the pointer is + greater than the length, the source route is empty (and the + + + + [Page 19] + + + September 1981 +Internet Protocol +Specification + + + + recorded route full) and the routing is to be based on the + destination address field. + + If the address in destination address field has been reached and + the pointer is not greater than the length, the next address in + the source route replaces the address in the destination address + field, and the recorded route address replaces the source + address just used, and pointer is increased by four. + + The recorded route address is the internet module's own internet + address as known in the environment into which this datagram is + being forwarded. + + This procedure of replacing the source route with the recorded + route (though it is in the reverse of the order it must be in to + be used as a source route) means the option (and the IP header + as a whole) remains a constant length as the datagram progresses + through the internet. + + This option is a strict source route because the gateway or host + IP must send the datagram directly to the next address in the + source route through only the directly connected network + indicated in the next address to reach the next gateway or host + specified in the route. + + Must be copied on fragmentation. Appears at most once in a + datagram. + + Record Route + + +--------+--------+--------+---------//--------+ + |00000111| length | pointer| route data | + +--------+--------+--------+---------//--------+ + Type=7 + + The record route option provides a means to record the route of + an internet datagram. + + The option begins with the option type code. The second octet + is the option length which includes the option type code and the + length octet, the pointer octet, and length-3 octets of route + data. The third octet is the pointer into the route data + indicating the octet which begins the next area to store a route + address. The pointer is relative to this option, and the + smallest legal value for the pointer is 4. + + A recorded route is composed of a series of internet addresses. + Each internet address is 32 bits or 4 octets. If the pointer is + + +[Page 20] + + +September 1981 + Internet Protocol + Specification + + + + greater than the length, the recorded route data area is full. + The originating host must compose this option with a large + enough route data area to hold all the address expected. The + size of the option does not change due to adding addresses. The + intitial contents of the route data area must be zero. + + When an internet module routes a datagram it checks to see if + the record route option is present. If it is, it inserts its + own internet address as known in the environment into which this + datagram is being forwarded into the recorded route begining at + the octet indicated by the pointer, and increments the pointer + by four. + + If the route data area is already full (the pointer exceeds the + length) the datagram is forwarded without inserting the address + into the recorded route. If there is some room but not enough + room for a full address to be inserted, the original datagram is + considered to be in error and is discarded. In either case an + ICMP parameter problem message may be sent to the source + host [3]. + + Not copied on fragmentation, goes in first fragment only. + Appears at most once in a datagram. + + Stream Identifier + + +--------+--------+--------+--------+ + |10001000|00000010| Stream ID | + +--------+--------+--------+--------+ + Type=136 Length=4 + + This option provides a way for the 16-bit SATNET stream + identifier to be carried through networks that do not support + the stream concept. + + Must be copied on fragmentation. Appears at most once in a + datagram. + + + + + + + + + + + + + + [Page 21] + + + September 1981 +Internet Protocol +Specification + + + + Internet Timestamp + + +--------+--------+--------+--------+ + |01000100| length | pointer|oflw|flg| + +--------+--------+--------+--------+ + | internet address | + +--------+--------+--------+--------+ + | timestamp | + +--------+--------+--------+--------+ + | . | + . + . + Type = 68 + + The Option Length is the number of octets in the option counting + the type, length, pointer, and overflow/flag octets (maximum + length 40). + + The Pointer is the number of octets from the beginning of this + option to the end of timestamps plus one (i.e., it points to the + octet beginning the space for next timestamp). The smallest + legal value is 5. The timestamp area is full when the pointer + is greater than the length. + + The Overflow (oflw) [4 bits] is the number of IP modules that + cannot register timestamps due to lack of space. + + The Flag (flg) [4 bits] values are + + 0 -- time stamps only, stored in consecutive 32-bit words, + + 1 -- each timestamp is preceded with internet address of the + registering entity, + + 3 -- the internet address fields are prespecified. An IP + module only registers its timestamp if it matches its own + address with the next specified internet address. + + The Timestamp is a right-justified, 32-bit timestamp in + milliseconds since midnight UT. If the time is not available in + milliseconds or cannot be provided with respect to midnight UT + then any time may be inserted as a timestamp provided the high + order bit of the timestamp field is set to one to indicate the + use of a non-standard value. + + The originating host must compose this option with a large + enough timestamp data area to hold all the timestamp information + expected. The size of the option does not change due to adding + + +[Page 22] + + +September 1981 + Internet Protocol + Specification + + + + timestamps. The intitial contents of the timestamp data area + must be zero or internet address/zero pairs. + + If the timestamp data area is already full (the pointer exceeds + the length) the datagram is forwarded without inserting the + timestamp, but the overflow count is incremented by one. + + If there is some room but not enough room for a full timestamp + to be inserted, or the overflow count itself overflows, the + original datagram is considered to be in error and is discarded. + In either case an ICMP parameter problem message may be sent to + the source host [3]. + + The timestamp option is not copied upon fragmentation. It is + carried in the first fragment. Appears at most once in a + datagram. + + Padding: variable + + The internet header padding is used to ensure that the internet + header ends on a 32 bit boundary. The padding is zero. + +3.2. Discussion + + The implementation of a protocol must be robust. Each implementation + must expect to interoperate with others created by different + individuals. While the goal of this specification is to be explicit + about the protocol there is the possibility of differing + interpretations. In general, an implementation must be conservative + in its sending behavior, and liberal in its receiving behavior. That + is, it must be careful to send well-formed datagrams, but must accept + any datagram that it can interpret (e.g., not object to technical + errors where the meaning is still clear). + + The basic internet service is datagram oriented and provides for the + fragmentation of datagrams at gateways, with reassembly taking place + at the destination internet protocol module in the destination host. + Of course, fragmentation and reassembly of datagrams within a network + or by private agreement between the gateways of a network is also + allowed since this is transparent to the internet protocols and the + higher-level protocols. This transparent type of fragmentation and + reassembly is termed "network-dependent" (or intranet) fragmentation + and is not discussed further here. + + Internet addresses distinguish sources and destinations to the host + level and provide a protocol field as well. It is assumed that each + protocol will provide for whatever multiplexing is necessary within a + host. + + + [Page 23] + + + September 1981 +Internet Protocol +Specification + + + + Addressing + + To provide for flexibility in assigning address to networks and + allow for the large number of small to intermediate sized networks + the interpretation of the address field is coded to specify a small + number of networks with a large number of host, a moderate number of + networks with a moderate number of hosts, and a large number of + networks with a small number of hosts. In addition there is an + escape code for extended addressing mode. + + Address Formats: + + High Order Bits Format Class + --------------- ------------------------------- ----- + 0 7 bits of net, 24 bits of host a + 10 14 bits of net, 16 bits of host b + 110 21 bits of net, 8 bits of host c + 111 escape to extended addressing mode + + A value of zero in the network field means this network. This is + only used in certain ICMP messages. The extended addressing mode + is undefined. Both of these features are reserved for future use. + + The actual values assigned for network addresses is given in + "Assigned Numbers" [9]. + + The local address, assigned by the local network, must allow for a + single physical host to act as several distinct internet hosts. + That is, there must be a mapping between internet host addresses and + network/host interfaces that allows several internet addresses to + correspond to one interface. It must also be allowed for a host to + have several physical interfaces and to treat the datagrams from + several of them as if they were all addressed to a single host. + + Address mappings between internet addresses and addresses for + ARPANET, SATNET, PRNET, and other networks are described in "Address + Mappings" [5]. + + Fragmentation and Reassembly. + + The internet identification field (ID) is used together with the + source and destination address, and the protocol fields, to identify + datagram fragments for reassembly. + + The More Fragments flag bit (MF) is set if the datagram is not the + last fragment. The Fragment Offset field identifies the fragment + location, relative to the beginning of the original unfragmented + datagram. Fragments are counted in units of 8 octets. The + + +[Page 24] + + +September 1981 + Internet Protocol + Specification + + + + fragmentation strategy is designed so than an unfragmented datagram + has all zero fragmentation information (MF = 0, fragment offset = + 0). If an internet datagram is fragmented, its data portion must be + broken on 8 octet boundaries. + + This format allows 2**13 = 8192 fragments of 8 octets each for a + total of 65,536 octets. Note that this is consistent with the the + datagram total length field (of course, the header is counted in the + total length and not in the fragments). + + When fragmentation occurs, some options are copied, but others + remain with the first fragment only. + + Every internet module must be able to forward a datagram of 68 + octets without further fragmentation. This is because an internet + header may be up to 60 octets, and the minimum fragment is 8 octets. + + Every internet destination must be able to receive a datagram of 576 + octets either in one piece or in fragments to be reassembled. + + The fields which may be affected by fragmentation include: + + (1) options field + (2) more fragments flag + (3) fragment offset + (4) internet header length field + (5) total length field + (6) header checksum + + If the Don't Fragment flag (DF) bit is set, then internet + fragmentation of this datagram is NOT permitted, although it may be + discarded. This can be used to prohibit fragmentation in cases + where the receiving host does not have sufficient resources to + reassemble internet fragments. + + One example of use of the Don't Fragment feature is to down line + load a small host. A small host could have a boot strap program + that accepts a datagram stores it in memory and then executes it. + + The fragmentation and reassembly procedures are most easily + described by examples. The following procedures are example + implementations. + + General notation in the following pseudo programs: "=<" means "less + than or equal", "#" means "not equal", "=" means "equal", "<-" means + "is set to". Also, "x to y" includes x and excludes y; for example, + "4 to 7" would include 4, 5, and 6 (but not 7). + + + + [Page 25] + + + September 1981 +Internet Protocol +Specification + + + + An Example Fragmentation Procedure + + The maximum sized datagram that can be transmitted through the + next network is called the maximum transmission unit (MTU). + + If the total length is less than or equal the maximum transmission + unit then submit this datagram to the next step in datagram + processing; otherwise cut the datagram into two fragments, the + first fragment being the maximum size, and the second fragment + being the rest of the datagram. The first fragment is submitted + to the next step in datagram processing, while the second fragment + is submitted to this procedure in case it is still too large. + + Notation: + + FO - Fragment Offset + IHL - Internet Header Length + DF - Don't Fragment flag + MF - More Fragments flag + TL - Total Length + OFO - Old Fragment Offset + OIHL - Old Internet Header Length + OMF - Old More Fragments flag + OTL - Old Total Length + NFB - Number of Fragment Blocks + MTU - Maximum Transmission Unit + + Procedure: + + IF TL =< MTU THEN Submit this datagram to the next step + in datagram processing ELSE IF DF = 1 THEN discard the + datagram ELSE + To produce the first fragment: + (1) Copy the original internet header; + (2) OIHL <- IHL; OTL <- TL; OFO <- FO; OMF <- MF; + (3) NFB <- (MTU-IHL*4)/8; + (4) Attach the first NFB*8 data octets; + (5) Correct the header: + MF <- 1; TL <- (IHL*4)+(NFB*8); + Recompute Checksum; + (6) Submit this fragment to the next step in + datagram processing; + To produce the second fragment: + (7) Selectively copy the internet header (some options + are not copied, see option definitions); + (8) Append the remaining data; + (9) Correct the header: + IHL <- (((OIHL*4)-(length of options not copied))+3)/4; + + +[Page 26] + + +September 1981 + Internet Protocol + Specification + + + + TL <- OTL - NFB*8 - (OIHL-IHL)*4); + FO <- OFO + NFB; MF <- OMF; Recompute Checksum; + (10) Submit this fragment to the fragmentation test; DONE. + + In the above procedure each fragment (except the last) was made + the maximum allowable size. An alternative might produce less + than the maximum size datagrams. For example, one could implement + a fragmentation procedure that repeatly divided large datagrams in + half until the resulting fragments were less than the maximum + transmission unit size. + + An Example Reassembly Procedure + + For each datagram the buffer identifier is computed as the + concatenation of the source, destination, protocol, and + identification fields. If this is a whole datagram (that is both + the fragment offset and the more fragments fields are zero), then + any reassembly resources associated with this buffer identifier + are released and the datagram is forwarded to the next step in + datagram processing. + + If no other fragment with this buffer identifier is on hand then + reassembly resources are allocated. The reassembly resources + consist of a data buffer, a header buffer, a fragment block bit + table, a total data length field, and a timer. The data from the + fragment is placed in the data buffer according to its fragment + offset and length, and bits are set in the fragment block bit + table corresponding to the fragment blocks received. + + If this is the first fragment (that is the fragment offset is + zero) this header is placed in the header buffer. If this is the + last fragment ( that is the more fragments field is zero) the + total data length is computed. If this fragment completes the + datagram (tested by checking the bits set in the fragment block + table), then the datagram is sent to the next step in datagram + processing; otherwise the timer is set to the maximum of the + current timer value and the value of the time to live field from + this fragment; and the reassembly routine gives up control. + + If the timer runs out, the all reassembly resources for this + buffer identifier are released. The initial setting of the timer + is a lower bound on the reassembly waiting time. This is because + the waiting time will be increased if the Time to Live in the + arriving fragment is greater than the current timer value but will + not be decreased if it is less. The maximum this timer value + could reach is the maximum time to live (approximately 4.25 + minutes). The current recommendation for the initial timer + setting is 15 seconds. This may be changed as experience with + + + [Page 27] + + + September 1981 +Internet Protocol +Specification + + + + this protocol accumulates. Note that the choice of this parameter + value is related to the buffer capacity available and the data + rate of the transmission medium; that is, data rate times timer + value equals buffer size (e.g., 10Kb/s X 15s = 150Kb). + + Notation: + + FO - Fragment Offset + IHL - Internet Header Length + MF - More Fragments flag + TTL - Time To Live + NFB - Number of Fragment Blocks + TL - Total Length + TDL - Total Data Length + BUFID - Buffer Identifier + RCVBT - Fragment Received Bit Table + TLB - Timer Lower Bound + + Procedure: + + (1) BUFID <- source|destination|protocol|identification; + (2) IF FO = 0 AND MF = 0 + (3) THEN IF buffer with BUFID is allocated + (4) THEN flush all reassembly for this BUFID; + (5) Submit datagram to next step; DONE. + (6) ELSE IF no buffer with BUFID is allocated + (7) THEN allocate reassembly resources + with BUFID; + TIMER <- TLB; TDL <- 0; + (8) put data from fragment into data buffer with + BUFID from octet FO*8 to + octet (TL-(IHL*4))+FO*8; + (9) set RCVBT bits from FO + to FO+((TL-(IHL*4)+7)/8); + (10) IF MF = 0 THEN TDL <- TL-(IHL*4)+(FO*8) + (11) IF FO = 0 THEN put header in header buffer + (12) IF TDL # 0 + (13) AND all RCVBT bits from 0 + to (TDL+7)/8 are set + (14) THEN TL <- TDL+(IHL*4) + (15) Submit datagram to next step; + (16) free all reassembly resources + for this BUFID; DONE. + (17) TIMER <- MAX(TIMER,TTL); + (18) give up until next fragment or timer expires; + (19) timer expires: flush all reassembly with this BUFID; DONE. + + In the case that two or more fragments contain the same data + + +[Page 28] + + +September 1981 + Internet Protocol + Specification + + + + either identically or through a partial overlap, this procedure + will use the more recently arrived copy in the data buffer and + datagram delivered. + + Identification + + The choice of the Identifier for a datagram is based on the need to + provide a way to uniquely identify the fragments of a particular + datagram. The protocol module assembling fragments judges fragments + to belong to the same datagram if they have the same source, + destination, protocol, and Identifier. Thus, the sender must choose + the Identifier to be unique for this source, destination pair and + protocol for the time the datagram (or any fragment of it) could be + alive in the internet. + + It seems then that a sending protocol module needs to keep a table + of Identifiers, one entry for each destination it has communicated + with in the last maximum packet lifetime for the internet. + + However, since the Identifier field allows 65,536 different values, + some host may be able to simply use unique identifiers independent + of destination. + + It is appropriate for some higher level protocols to choose the + identifier. For example, TCP protocol modules may retransmit an + identical TCP segment, and the probability for correct reception + would be enhanced if the retransmission carried the same identifier + as the original transmission since fragments of either datagram + could be used to construct a correct TCP segment. + + Type of Service + + The type of service (TOS) is for internet service quality selection. + The type of service is specified along the abstract parameters + precedence, delay, throughput, and reliability. These abstract + parameters are to be mapped into the actual service parameters of + the particular networks the datagram traverses. + + Precedence. An independent measure of the importance of this + datagram. + + Delay. Prompt delivery is important for datagrams with this + indication. + + Throughput. High data rate is important for datagrams with this + indication. + + + + + [Page 29] + + + September 1981 +Internet Protocol +Specification + + + + Reliability. A higher level of effort to ensure delivery is + important for datagrams with this indication. + + For example, the ARPANET has a priority bit, and a choice between + "standard" messages (type 0) and "uncontrolled" messages (type 3), + (the choice between single packet and multipacket messages can also + be considered a service parameter). The uncontrolled messages tend + to be less reliably delivered and suffer less delay. Suppose an + internet datagram is to be sent through the ARPANET. Let the + internet type of service be given as: + + Precedence: 5 + Delay: 0 + Throughput: 1 + Reliability: 1 + + In this example, the mapping of these parameters to those available + for the ARPANET would be to set the ARPANET priority bit on since + the Internet precedence is in the upper half of its range, to select + standard messages since the throughput and reliability requirements + are indicated and delay is not. More details are given on service + mappings in "Service Mappings" [8]. + + Time to Live + + The time to live is set by the sender to the maximum time the + datagram is allowed to be in the internet system. If the datagram + is in the internet system longer than the time to live, then the + datagram must be destroyed. + + This field must be decreased at each point that the internet header + is processed to reflect the time spent processing the datagram. + Even if no local information is available on the time actually + spent, the field must be decremented by 1. The time is measured in + units of seconds (i.e. the value 1 means one second). Thus, the + maximum time to live is 255 seconds or 4.25 minutes. Since every + module that processes a datagram must decrease the TTL by at least + one even if it process the datagram in less than a second, the TTL + must be thought of only as an upper bound on the time a datagram may + exist. The intention is to cause undeliverable datagrams to be + discarded, and to bound the maximum datagram lifetime. + + Some higher level reliable connection protocols are based on + assumptions that old duplicate datagrams will not arrive after a + certain time elapses. The TTL is a way for such protocols to have + an assurance that their assumption is met. + + + + +[Page 30] + + +September 1981 + Internet Protocol + Specification + + + + Options + + The options are optional in each datagram, but required in + implementations. That is, the presence or absence of an option is + the choice of the sender, but each internet module must be able to + parse every option. There can be several options present in the + option field. + + The options might not end on a 32-bit boundary. The internet header + must be filled out with octets of zeros. The first of these would + be interpreted as the end-of-options option, and the remainder as + internet header padding. + + Every internet module must be able to act on every option. The + Security Option is required if classified, restricted, or + compartmented traffic is to be passed. + + Checksum + + The internet header checksum is recomputed if the internet header is + changed. For example, a reduction of the time to live, additions or + changes to internet options, or due to fragmentation. This checksum + at the internet level is intended to protect the internet header + fields from transmission errors. + + There are some applications where a few data bit errors are + acceptable while retransmission delays are not. If the internet + protocol enforced data correctness such applications could not be + supported. + + Errors + + Internet protocol errors may be reported via the ICMP messages [3]. + +3.3. Interfaces + + The functional description of user interfaces to the IP is, at best, + fictional, since every operating system will have different + facilities. Consequently, we must warn readers that different IP + implementations may have different user interfaces. However, all IPs + must provide a certain minimum set of services to guarantee that all + IP implementations can support the same protocol hierarchy. This + section specifies the functional interfaces required of all IP + implementations. + + Internet protocol interfaces on one side to the local network and on + the other side to either a higher level protocol or an application + program. In the following, the higher level protocol or application + + + [Page 31] + + + September 1981 +Internet Protocol +Specification + + + + program (or even a gateway program) will be called the "user" since it + is using the internet module. Since internet protocol is a datagram + protocol, there is minimal memory or state maintained between datagram + transmissions, and each call on the internet protocol module by the + user supplies all information necessary for the IP to perform the + service requested. + + An Example Upper Level Interface + + The following two example calls satisfy the requirements for the user + to internet protocol module communication ("=>" means returns): + + SEND (src, dst, prot, TOS, TTL, BufPTR, len, Id, DF, opt => result) + + where: + + src = source address + dst = destination address + prot = protocol + TOS = type of service + TTL = time to live + BufPTR = buffer pointer + len = length of buffer + Id = Identifier + DF = Don't Fragment + opt = option data + result = response + OK = datagram sent ok + Error = error in arguments or local network error + + Note that the precedence is included in the TOS and the + security/compartment is passed as an option. + + RECV (BufPTR, prot, => result, src, dst, TOS, len, opt) + + where: + + BufPTR = buffer pointer + prot = protocol + result = response + OK = datagram received ok + Error = error in arguments + len = length of buffer + src = source address + dst = destination address + TOS = type of service + opt = option data + + + +[Page 32] + + +September 1981 + Internet Protocol + Specification + + + + When the user sends a datagram, it executes the SEND call supplying + all the arguments. The internet protocol module, on receiving this + call, checks the arguments and prepares and sends the message. If the + arguments are good and the datagram is accepted by the local network, + the call returns successfully. If either the arguments are bad, or + the datagram is not accepted by the local network, the call returns + unsuccessfully. On unsuccessful returns, a reasonable report must be + made as to the cause of the problem, but the details of such reports + are up to individual implementations. + + When a datagram arrives at the internet protocol module from the local + network, either there is a pending RECV call from the user addressed + or there is not. In the first case, the pending call is satisfied by + passing the information from the datagram to the user. In the second + case, the user addressed is notified of a pending datagram. If the + user addressed does not exist, an ICMP error message is returned to + the sender, and the data is discarded. + + The notification of a user may be via a pseudo interrupt or similar + mechanism, as appropriate in the particular operating system + environment of the implementation. + + A user's RECV call may then either be immediately satisfied by a + pending datagram, or the call may be pending until a datagram arrives. + + The source address is included in the send call in case the sending + host has several addresses (multiple physical connections or logical + addresses). The internet module must check to see that the source + address is one of the legal address for this host. + + An implementation may also allow or require a call to the internet + module to indicate interest in or reserve exclusive use of a class of + datagrams (e.g., all those with a certain value in the protocol + field). + + This section functionally characterizes a USER/IP interface. The + notation used is similar to most procedure of function calls in high + level languages, but this usage is not meant to rule out trap type + service calls (e.g., SVCs, UUOs, EMTs), or any other form of + interprocess communication. + + + + + + + + + + + [Page 33] + + + September 1981 +Internet Protocol + + + +APPENDIX A: Examples & Scenarios + +Example 1: + + This is an example of the minimal data carrying internet datagram: + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Ver= 4 |IHL= 5 |Type of Service| Total Length = 21 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification = 111 |Flg=0| Fragment Offset = 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time = 123 | Protocol = 1 | header checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+ + + Example Internet Datagram + + Figure 5. + + Note that each tick mark represents one bit position. + + This is a internet datagram in version 4 of internet protocol; the + internet header consists of five 32 bit words, and the total length of + the datagram is 21 octets. This datagram is a complete datagram (not + a fragment). + + + + + + + + + + + + + + + + + + +[Page 34] + + +September 1981 + Internet Protocol + + + +Example 2: + + In this example, we show first a moderate size internet datagram (452 + data octets), then two internet fragments that might result from the + fragmentation of this datagram if the maximum sized transmission + allowed were 280 octets. + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Ver= 4 |IHL= 5 |Type of Service| Total Length = 472 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification = 111 |Flg=0| Fragment Offset = 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time = 123 | Protocol = 6 | header checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + \ \ + \ \ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Example Internet Datagram + + Figure 6. + + + + + + + + + + + + + + + + + + [Page 35] + + + September 1981 +Internet Protocol + + + + Now the first fragment that results from splitting the datagram after + 256 data octets. + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Ver= 4 |IHL= 5 |Type of Service| Total Length = 276 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification = 111 |Flg=1| Fragment Offset = 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time = 119 | Protocol = 6 | Header Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + \ \ + \ \ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Example Internet Fragment + + Figure 7. + + + + + + + + + + + + + + + + + + + + + +[Page 36] + + +September 1981 + Internet Protocol + + + + And the second fragment. + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Ver= 4 |IHL= 5 |Type of Service| Total Length = 216 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification = 111 |Flg=0| Fragment Offset = 32 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time = 119 | Protocol = 6 | Header Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + \ \ + \ \ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Example Internet Fragment + + Figure 8. + + + + + + + + + + + + + + + + + + + + + + + [Page 37] + + + September 1981 +Internet Protocol + + + +Example 3: + + Here, we show an example of a datagram containing options: + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Ver= 4 |IHL= 8 |Type of Service| Total Length = 576 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identification = 111 |Flg=0| Fragment Offset = 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Time = 123 | Protocol = 6 | Header Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Opt. Code = x | Opt. Len.= 3 | option value | Opt. Code = x | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Opt. Len. = 4 | option value | Opt. Code = 1 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Opt. Code = y | Opt. Len. = 3 | option value | Opt. Code = 0 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + \ \ + \ \ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Example Internet Datagram + + Figure 9. + + + + + + + + + + + + + + + + +[Page 38] + + +September 1981 + Internet Protocol + + + +APPENDIX B: Data Transmission Order + +The order of transmission of the header and data described in this +document is resolved to the octet level. Whenever a diagram shows a +group of octets, the order of transmission of those octets is the normal +order in which they are read in English. For example, in the following +diagram the octets are transmitted in the order they are numbered. + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 1 | 2 | 3 | 4 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 5 | 6 | 7 | 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 9 | 10 | 11 | 12 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Transmission Order of Bytes + + Figure 10. + +Whenever an octet represents a numeric quantity the left most bit in the +diagram is the high order or most significant bit. That is, the bit +labeled 0 is the most significant bit. For example, the following +diagram represents the value 170 (decimal). + + + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + |1 0 1 0 1 0 1 0| + +-+-+-+-+-+-+-+-+ + + Significance of Bits + + Figure 11. + +Similarly, whenever a multi-octet field represents a numeric quantity +the left most bit of the whole field is the most significant bit. When +a multi-octet quantity is transmitted the most significant octet is +transmitted first. + + + + + + + + + + [Page 39] + + + September 1981 +Internet Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 40] + + +September 1981 + Internet Protocol + + + + GLOSSARY + + + +1822 + BBN Report 1822, "The Specification of the Interconnection of + a Host and an IMP". The specification of interface between a + host and the ARPANET. + +ARPANET leader + The control information on an ARPANET message at the host-IMP + interface. + +ARPANET message + The unit of transmission between a host and an IMP in the + ARPANET. The maximum size is about 1012 octets (8096 bits). + +ARPANET packet + A unit of transmission used internally in the ARPANET between + IMPs. The maximum size is about 126 octets (1008 bits). + +Destination + The destination address, an internet header field. + +DF + The Don't Fragment bit carried in the flags field. + +Flags + An internet header field carrying various control flags. + +Fragment Offset + This internet header field indicates where in the internet + datagram a fragment belongs. + +GGP + Gateway to Gateway Protocol, the protocol used primarily + between gateways to control routing and other gateway + functions. + +header + Control information at the beginning of a message, segment, + datagram, packet or block of data. + +ICMP + Internet Control Message Protocol, implemented in the internet + module, the ICMP is used from gateways to hosts and between + hosts to report errors and make routing suggestions. + + + + + [Page 41] + + + September 1981 +Internet Protocol +Glossary + + + +Identification + An internet header field carrying the identifying value + assigned by the sender to aid in assembling the fragments of a + datagram. + +IHL + The internet header field Internet Header Length is the length + of the internet header measured in 32 bit words. + +IMP + The Interface Message Processor, the packet switch of the + ARPANET. + +Internet Address + A four octet (32 bit) source or destination address consisting + of a Network field and a Local Address field. + +internet datagram + The unit of data exchanged between a pair of internet modules + (includes the internet header). + +internet fragment + A portion of the data of an internet datagram with an internet + header. + +Local Address + The address of a host within a network. The actual mapping of + an internet local address on to the host addresses in a + network is quite general, allowing for many to one mappings. + +MF + The More-Fragments Flag carried in the internet header flags + field. + +module + An implementation, usually in software, of a protocol or other + procedure. + +more-fragments flag + A flag indicating whether or not this internet datagram + contains the end of an internet datagram, carried in the + internet header Flags field. + +NFB + The Number of Fragment Blocks in a the data portion of an + internet fragment. That is, the length of a portion of data + measured in 8 octet units. + + + +[Page 42] + + +September 1981 + Internet Protocol + Glossary + + + +octet + An eight bit byte. + +Options + The internet header Options field may contain several options, + and each option may be several octets in length. + +Padding + The internet header Padding field is used to ensure that the + data begins on 32 bit word boundary. The padding is zero. + +Protocol + In this document, the next higher level protocol identifier, + an internet header field. + +Rest + The local address portion of an Internet Address. + +Source + The source address, an internet header field. + +TCP + Transmission Control Protocol: A host-to-host protocol for + reliable communication in internet environments. + +TCP Segment + The unit of data exchanged between TCP modules (including the + TCP header). + +TFTP + Trivial File Transfer Protocol: A simple file transfer + protocol built on UDP. + +Time to Live + An internet header field which indicates the upper bound on + how long this internet datagram may exist. + +TOS + Type of Service + +Total Length + The internet header field Total Length is the length of the + datagram in octets including internet header and data. + +TTL + Time to Live + + + + + [Page 43] + + + September 1981 +Internet Protocol +Glossary + + + +Type of Service + An internet header field which indicates the type (or quality) + of service for this internet datagram. + +UDP + User Datagram Protocol: A user level protocol for transaction + oriented applications. + +User + The user of the internet protocol. This may be a higher level + protocol module, an application program, or a gateway program. + +Version + The Version field indicates the format of the internet header. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 44] + + +September 1981 + Internet Protocol + + + + REFERENCES + + + +[1] Cerf, V., "The Catenet Model for Internetworking," Information + Processing Techniques Office, Defense Advanced Research Projects + Agency, IEN 48, July 1978. + +[2] Bolt Beranek and Newman, "Specification for the Interconnection of + a Host and an IMP," BBN Technical Report 1822, Revised May 1978. + +[3] Postel, J., "Internet Control Message Protocol - DARPA Internet + Program Protocol Specification," RFC 792, USC/Information Sciences + Institute, September 1981. + +[4] Shoch, J., "Inter-Network Naming, Addressing, and Routing," + COMPCON, IEEE Computer Society, Fall 1978. + +[5] Postel, J., "Address Mappings," RFC 796, USC/Information Sciences + Institute, September 1981. + +[6] Shoch, J., "Packet Fragmentation in Inter-Network Protocols," + Computer Networks, v. 3, n. 1, February 1979. + +[7] Strazisar, V., "How to Build a Gateway", IEN 109, Bolt Beranek and + Newman, August 1979. + +[8] Postel, J., "Service Mappings," RFC 795, USC/Information Sciences + Institute, September 1981. + +[9] Postel, J., "Assigned Numbers," RFC 790, USC/Information Sciences + Institute, September 1981. + + + + + + + + + + + + + + + + + + + + [Page 45] + + +======================================================================== + +Network Working Group J. Mogul (Stanford) +Request for Comments: 950 J. Postel (ISI) + August 1985 + + Internet Standard Subnetting Procedure + + +Status Of This Memo + + This RFC specifies a protocol for the ARPA-Internet community. If + subnetting is implemented it is strongly recommended that these + procedures be followed. Distribution of this memo is unlimited. + +Overview + + This memo discusses the utility of "subnets" of Internet networks, + which are logically visible sub-sections of a single Internet + network. For administrative or technical reasons, many organizations + have chosen to divide one Internet network into several subnets, + instead of acquiring a set of Internet network numbers. This memo + specifies procedures for the use of subnets. These procedures are + for hosts (e.g., workstations). The procedures used in and between + subnet gateways are not fully described. Important motivation and + background information for a subnetting standard is provided in + RFC-940 [7]. + +Acknowledgment + + This memo is based on RFC-917 [1]. Many people contributed to the + development of the concepts described here. J. Noel Chiappa, Chris + Kent, and Tim Mann, in particular, provided important suggestions. + Additional contributions in shaping this memo were made by Zaw-Sing + Su, Mike Karels, and the Gateway Algorithms and Data Structures Task + Force (GADS). + + + + + + + + + + + + + + + + + + + +Mogul & Postel [Page 1] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + +1. Motivation + + The original view of the Internet universe was a two-level hierarchy: + the top level the Internet as a whole, and the level below it + individual networks, each with its own network number. The Internet + does not have a hierarchical topology, rather the interpretation of + addresses is hierarchical. In this two-level model, each host sees + its network as a single entity; that is, the network may be treated + as a "black box" to which a set of hosts is connected. + + While this view has proved simple and powerful, a number of + organizations have found it inadequate, and have added a third level + to the interpretation of Internet addresses. In this view, a given + Internet network is divided into a collection of subnets. + + The three-level model is useful in networks belonging to moderately + large organizations (e.g., Universities or companies with more than + one building), where it is often necessary to use more than one LAN + cable to cover a "local area". Each LAN may then be treated as a + subnet. + + There are several reasons why an organization might use more than one + cable to cover a campus: + + - Different technologies: Especially in a research environment, + there may be more than one kind of LAN in use; e.g., an + organization may have some equipment that supports Ethernet, and + some that supports a ring network. + + - Limits of technologies: Most LAN technologies impose limits, + based on electrical parameters, on the number of hosts + connected, and on the total length of the cable. It is easy to + exceed these limits, especially those on cable length. + + - Network congestion: It is possible for a small subset of the + hosts on a LAN to monopolize most of the bandwidth. A common + solution to this problem is to divide the hosts into cliques of + high mutual communication, and put these cliques on separate + cables. + + - Point-to-Point links: Sometimes a "local area", such as a + university campus, is split into two locations too far apart to + connect using the preferred LAN technology. In this case, + high-speed point-to-point links might connect several LANs. + + An organization that has been forced to use more than one LAN has + three choices for assigning Internet addresses: + + +Mogul & Postel [Page 2] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + 1. Acquire a distinct Internet network number for each cable; + subnets are not used at all. + + 2. Use a single network number for the entire organization, but + assign host numbers without regard to which LAN a host is on + ("transparent subnets"). + + 3. Use a single network number, and partition the host address + space by assigning subnet numbers to the LANs ("explicit + subnets"). + + Each of these approaches has disadvantages. The first, although not + requiring any new or modified protocols, results in an explosion in + the size of Internet routing tables. Information about the internal + details of local connectivity is propagated everywhere, although it + is of little or no use outside the local organization. Especially as + some current gateway implementations do not have much space for + routing tables, it would be good to avoid this problem. + + The second approach requires some convention or protocol that makes + the collection of LANs appear to be a single Internet network. For + example, this can be done on LANs where each Internet address is + translated to a hardware address using an Address Resolution Protocol + (ARP), by having the bridges between the LANs intercept ARP requests + for non-local targets, see RFC-925 [2]. However, it is not possible + to do this for all LAN technologies, especially those where ARP + protocols are not currently used, or if the LAN does not support + broadcasts. A more fundamental problem is that bridges must discover + which LAN a host is on, perhaps by using a broadcast algorithm. As + the number of LANs grows, the cost of broadcasting grows as well; + also, the size of translation caches required in the bridges grows + with the total number of hosts in the network. + + The third approach is to explicitly support subnets. This does have + a disadvantage, in that it is a modification of the Internet + Protocol, and thus requires changes to IP implementations already in + use (if these implementations are to be used on a subnetted network). + However, these changes are relatively minor, and once made, yield a + simple and efficient solution to the problem. Also, the approach + avoids any changes that would be incompatible with existing hosts on + non-subnetted networks. + + Further, when appropriate design choices are made, it is possible for + hosts which believe they are on a non-subnetted network to be used on + a subnetted one, as explained in RFC-917 [1]. This is useful when it + is not possible to modify some of the hosts to support subnets + explicitly, or when a gradual transition is preferred. + + +Mogul & Postel [Page 3] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + +2. Standards for Subnet Addressing + + This section first describes a proposal for interpretation of + Internet addresses to support subnets. Next it discusses changes to + host software to support subnets. Finally, it presents a procedures + for discovering what address interpretation is in use on a given + network (i.e., what address mask is in use). + + 2.1. Interpretation of Internet Addresses + + Suppose that an organization has been assigned an Internet network + number, has further divided that network into a set of subnets, + and wants to assign host addresses: how should this be done? + Since there are minimal restrictions on the assignment of the + "local address" part of the Internet address, several approaches + have been proposed for representing the subnet number: + + 1. Variable-width field: Any number of the bits of the local + address part are used for the subnet number; the size of + this field, although constant for a given network, varies + from network to network. If the field width is zero, then + subnets are not in use. + + 2. Fixed-width field: A specific number of bits (e.g., eight) + is used for the subnet number, if subnets are in use. + + 3. Self-encoding variable-width field: Just as the width + (i.e., class) of the network number field is encoded by its + high-order bits, the width of the subnet field is similarly + encoded. + + 4. Self-encoding fixed-width field: A specific number of bits + is used for the subnet number. + + 5. Masked bits: Use a bit mask ("address mask") to identify + which bits of the local address field indicate the subnet + number. + + What criteria can be used to choose one of these five schemes? + First, should we use a self-encoding scheme? And, should it be + possible to tell from examining an Internet address if it refers + to a subnetted network, without reference to any other + information? + + An interesting feature of self-encoding is that it allows the + + + + +Mogul & Postel [Page 4] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + address space of a network to be divided into subnets of + different sizes, typically one subnet of half the address space + and a set of small subnets. + + For example, consider a class C network that uses a + self-encoding scheme with one bit to indicate if it is the + large subnet or not and an additional three bits to identify + the small subnet. If the first bit is zero then this is the + large subnet, if the first bit is one then the following + bits (3 in this example) give the subnet number. There is + one subnet with 128 host addresses, and eight subnets with + 16 hosts each. + + To establish a subnetting standard the parameters and + interpretation of the self-encoding scheme must be fixed and + consistent throughout the Internet. + + It could be assumed that all networks are subnetted. This + would allow addresses to be interpreted without reference to + any other information. + + This is a significant advantage, that given the Internet + address no additional information is needed for an + implementation to determine if two addresses are on the same + subnet. However, this can also be viewed as a disadvantage: + it may cause problems for networks which have existing host + numbers that use arbitrary bits in the local address part. + In other words, it is useful to be able to control whether a + network is subnetted independently from the assignment of + host addresses. + + The alternative is to have the fact that a network is subnetted + kept separate from the address. If one finds, somehow, that + the network is subnetted then the standard self-encoded + subnetted network address rules are followed, otherwise the + non-subnetted network addressing rules are followed. + + If a self-encoding scheme is not used, there is no reason to use a + fixed-width field scheme: since there must in any case be some + per-network "flag" to indicate if subnets are in use, the + additional cost of using an integer (a subnet field width or + address mask) instead of a boolean is negligible. The advantage + of using the address mask scheme is that it allows each + organization to choose the best way to allocate relatively scarce + bits of local address to subnet and host numbers. Therefore, we + choose the address-mask scheme: it is the most flexible scheme, + yet costs no more to implement than any other. + + +Mogul & Postel [Page 5] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + For example, the Internet address might be interpreted as: + + + + where the field is as defined by IP [3], the + field is at least 1-bit wide, and the width of the + field is constant for a given network. No further + structure is required for the or + fields. If the width of the field is zero, then + the network is not subnetted (i.e., the interpretation of [3] is + used). + + For example, on a Class B network with a 6-bit wide subnet field, + an address would be broken down like this: + + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |1 0| NETWORK | SUBNET | Host Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Since the bits that identify the subnet are specified by a + bitmask, they need not be adjacent in the address. However, we + recommend that the subnet bits be contiguous and located as the + most significant bits of the local address. + + Special Addresses: + + From the Assigned Numbers memo [9]: + + "In certain contexts, it is useful to have fixed addresses + with functional significance rather than as identifiers of + specific hosts. When such usage is called for, the address + zero is to be interpreted as meaning "this", as in "this + network". The address of all ones are to be interpreted as + meaning "all", as in "all hosts". For example, the address + 128.9.255.255 could be interpreted as meaning all hosts on + the network 128.9. Or, the address 0.0.0.37 could be + interpreted as meaning host 37 on this network." + + It is useful to preserve and extend the interpretation of these + special addresses in subnetted networks. This means the values + of all zeros and all ones in the subnet field should not be + assigned to actual (physical) subnets. + + In the example above, the 6-bit wide subnet field may have + any value except 0 and 63. + + +Mogul & Postel [Page 6] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + Please note that there is no effect or new restriction on the + addresses of hosts on non-subnetted networks. + + 2.2. Changes to Host Software to Support Subnets + + In most implementations of IP, there is code in the module that + handles outgoing datagrams to decide if a datagram can be sent + directly to the destination on the local network or if it must be + sent to a gateway. + + Generally the code is something like this: + + IF ip_net_number(dg.ip_dest) = ip_net_number(my_ip_addr) + THEN + send_dg_locally(dg, dg.ip_dest) + ELSE + send_dg_locally(dg, + gateway_to(ip_net_number(dg.ip_dest))) + + (If the code supports multiply-connected networks, it will be more + complicated, but this is irrelevant to the current discussion.) + + To support subnets, it is necessary to store one more 32-bit + quantity, called my_ip_mask. This is a bit-mask with bits set in + the fields corresponding to the IP network number, and additional + bits set corresponding to the subnet number field. + + The code then becomes: + + IF bitwise_and(dg.ip_dest, my_ip_mask) + = bitwise_and(my_ip_addr, my_ip_mask) + THEN + send_dg_locally(dg, dg.ip_dest) + ELSE + send_dg_locally(dg, + gateway_to(bitwise_and(dg.ip_dest, my_ip_mask))) + + Of course, part of the expression in the conditional can be + pre-computed. + + It may or may not be necessary to modify the "gateway_to" + function, so that it too takes the subnet field bits into account + when performing comparisons. + + To support multiply-connected hosts, the code can be changed to + + + + +Mogul & Postel [Page 7] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + keep the "my_ip_addr" and "my_ip_mask" quantities on a + per-interface basis; the expression in the conditional must then + be evaluated for each interface. + + 2.3. Finding the Address Mask + + How can a host determine what address mask is in use on a subnet + to which it is connected? The problem is analogous to several + other "bootstrapping" problems for Internet hosts: how a host + determines its own address, and how it locates a gateway on its + local network. In all three cases, there are two basic solutions: + "hardwired" information, and broadcast-based protocols. + + Hardwired information is that available to a host in isolation + from a network. It may be compiled-in, or (preferably) stored in + a disk file. However, for the increasingly common case of a + diskless workstation that is bootloaded over a LAN, neither + hardwired solution is satisfactory. + + Instead, since most LAN technology supports broadcasting, a better + method is for the newly-booted host to broadcast a request for the + necessary information. For example, for the purpose of + determining its Internet address, a host may use the "Reverse + Address Resolution Protocol" (RARP) [4]. + + However, since a newly-booted host usually needs to gather several + facts (e.g., its IP address, the hardware address of a gateway, + the IP address of a domain name server, the subnet address mask), + it would be better to acquire all this information in one request + if possible, rather than doing numerous broadcasts on the network. + The mechanisms designed to boot diskless workstations can also + load per-host specific configuration files that contain the + required information (e.g., see RFC-951 [8]). It is possible, and + desirable, to obtain all the facts necessary to operate a host + from a boot server using only one broadcast message. + + In the case where it is necessary for a host to find the address + mask as a separate operation the following mechanism is provided: + + To provide the address mask information the ICMP protocol [5] + is extended by adding a new pair of ICMP message types, + "Address Mask Request" and "Address Mask Reply", analogous to + the "Information Request" and "Information Reply" ICMP + messages. These are described in detail in Appendix I. + + The intended use of these new ICMP messages is that a host, + when booting, broadcast an "Address Mask Request" message. A + + +Mogul & Postel [Page 8] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + gateway (or a host acting in lieu of a gateway) that receives + this message responds with an "Address Mask Reply". If there + is no indication in the request which host sent it (i.e., the + IP Source Address is zero), the reply is broadcast as well. + The requesting host will hear the response, and from it + determine the address mask. + + Since there is only one possible value that can be sent in an + "Address Mask Reply" on any given LAN, there is no need for the + requesting host to match the responses it hears against the + request it sent; similarly, there is no problem if more than + one gateway responds. We assume that hosts reboot + infrequently, so the broadcast load on a network from use of + this protocol should be small. + + If a host is connected to more than one LAN, it might have to find + the address mask for each. + + One potential problem is what a host should do if it can not find + out the address mask, even after a reasonable number of tries. + Three interpretations can be placed on the situation: + + 1. The local net exists in (permanent) isolation from all other + nets. + + 2. Subnets are not in use, and no host can supply the address + mask. + + 3. All gateways on the local net are (temporarily) down. + + The first and second situations imply that the address mask is + identical with the Internet network number mask. In the third + situation, there is no way to determine what the proper value is; + the safest choice is thus a mask identical with the Internet + network number mask. Although this might later turn out to be + wrong, it will not prevent transmissions that would otherwise + succeed. It is possible for a host to recover from a wrong + choice: when a gateway comes up, it should broadcast an "Address + Mask Reply"; when a host receives such a message that disagrees + with its guess, it should change its mask to conform to the + received value. No host or gateway should send an "Address Mask + Reply" based on a "guessed" value. + + Finally, note that no host is required to use this ICMP protocol + to discover the address mask; it is perfectly reasonable for a + host with non-volatile storage to use stored information + (including a configuration file from a boot server). + + +Mogul & Postel [Page 9] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + +Appendix I. Address Mask ICMP + + Address Mask Request or Address Mask Reply + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Address Mask | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Addresses + + The address of the source in an address mask request message + will be the destination of the address mask reply message. + To form an address mask reply message, the source address of + the request becomes the destination address of the reply, + the source address of the reply is set to the replier's + address, the type code changed to AM2, the address mask + value inserted into the Address Mask field, and the checksum + recomputed. However, if the source address in the request + message is zero, then the destination address for the reply + message should denote a broadcast. + + ICMP Fields: + + Type + + AM1 for address mask request message + + AM2 for address mask reply message + + Code + + 0 for address mask request message + + 0 for address mask reply message + + Checksum + + The checksum is the 16-bit one's complement of the one's + + + +Mogul & Postel [Page 10] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + complement sum of the ICMP message starting with the ICMP + Type. For computing the checksum, the checksum field should + be zero. This checksum may be replaced in the future. + + Identifier + + An identifier to aid in matching requests and replies, may + be zero. + + Sequence Number + + A sequence number to aid in matching requests and replies, + may be zero. + + Address Mask + + A 32-bit mask. + + Description + + A gateway receiving an address mask request should return it + with the address mask field set to the 32-bit mask of the bits + identifying the subnet and network, for the subnet on which the + request was received. + + If the requesting host does not know its own IP address, it may + leave the source field zero; the reply should then be + broadcast. However, this approach should be avoided if at all + possible, since it increases the superfluous broadcast load on + the network. Even when the replies are broadcast, since there + is only one possible address mask for a subnet, there is no + need to match requests with replies. The "Identifier" and + "Sequence Number" fields can be ignored. + + Type AM1 may be received from a gateway or a host. + + Type AM2 may be received from a gateway, or a host acting in + lieu of a gateway. + + + + + + + + + + + +Mogul & Postel [Page 11] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + +Appendix II. Examples + + These examples show how a host can find out the address mask using + the ICMP Address Mask Request and Address Mask Reply messages. For + the following examples, assume that address 255.255.255.255 denotes + "broadcast to this physical medium" [6]. + + 1. A Class A Network Case + + For this case, assume that the requesting host is on class A + network 36.0.0.0, has address 36.40.0.123, that there is a gateway + at 36.40.0.62, and that a 8-bit wide subnet field is in use, that + is, the address mask is 255.255.0.0. + + The most efficient method, and the one we recommend, is for a host + to first discover its own address (perhaps using "RARP" [4]), and + then to send the ICMP request to 255.255.255.255: + + Source address: 36.40.0.123 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + The gateway can then respond directly to the requesting host. + + Source address: 36.40.0.62 + Destination address: 36.40.0.123 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.0.0 + + Suppose that 36.40.0.123 is a diskless workstation, and does not + know even its own host number. It could send the following + datagram: + + Source address: 0.0.0.0 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 36.40.0.62 will hear the datagram, and should respond with this + datagram: + + +Mogul & Postel [Page 12] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + Source address: 36.40.0.62 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.0.0 + + Note that the gateway uses the narrowest possible broadcast to + reply. Even so, the over use of broadcasts presents an + unnecessary load to all hosts on the subnet, and so the use of the + "anonymous" (0.0.0.0) source address must be kept to a minimum. + + If broadcasting is not allowed, we assume that hosts have wired-in + information about neighbor gateways; thus, 36.40.0.123 might send + this datagram: + + Source address: 36.40.0.123 + Destination address: 36.40.0.62 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 36.40.0.62 should respond exactly as in the previous case. + + Source address: 36.40.0.62 + Destination address: 36.40.0.123 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.0.0 + + 2. A Class B Network Case + + For this case, assume that the requesting host is on class B + network 128.99.0.0, has address 128.99.4.123, that there is a + gateway at 128.99.4.62, and that a 6-bit wide subnet field is in + use, that is, the address mask is 255.255.252.0. + + The host sends the ICMP request to 255.255.255.255: + + Source address: 128.99.4.123 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + +Mogul & Postel [Page 13] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + The gateway can then respond directly to the requesting host. + + Source address: 128.99.4.62 + Destination address: 128.99.4.123 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.252.0 + + In the diskless workstation case the host sends: + + Source address: 0.0.0.0 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 128.99.4.62 will hear the datagram, and should respond with this + datagram: + + Source address: 128.99.4.62 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.252.0 + + If broadcasting is not allowed 128.99.4.123 sends: + + Source address: 128.99.4.123 + Destination address: 128.99.4.62 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 128.99.4.62 should respond exactly as in the previous case. + + Source address: 128.99.4.62 + Destination address: 128.99.4.123 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.252.0 + + + + +Mogul & Postel [Page 14] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + 3. A Class C Network Case (illustrating non-contiguous subnet bits) + + For this case, assume that the requesting host is on class C + network 192.1.127.0, has address 192.1.127.19, that there is a + gateway at 192.1.127.50, and that on network an 3-bit subnet field + is in use (01011000), that is, the address mask is 255.255.255.88. + + The host sends the ICMP request to 255.255.255.255: + + Source address: 192.1.127.19 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + The gateway can then respond directly to the requesting host. + + Source address: 192.1.127.50 + Destination address: 192.1.127.19 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.255.88. + + In the diskless workstation case the host sends: + + Source address: 0.0.0.0 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 192.1.127.50 will hear the datagram, and should respond with this + datagram: + + Source address: 192.1.127.50 + Destination address: 255.255.255.255 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.255.88. + + If broadcasting is not allowed 192.1.127.19 sends: + + + + +Mogul & Postel [Page 15] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + Source address: 192.1.127.19 + Destination address: 192.1.127.50 + Protocol: ICMP = 1 + Type: Address Mask Request = AM1 + Code: 0 + Mask: 0 + + 192.1.127.50 should respond exactly as in the previous case. + + Source address: 192.1.127.50 + Destination address: 192.1.127.19 + Protocol: ICMP = 1 + Type: Address Mask Reply = AM2 + Code: 0 + Mask: 255.255.255.88 + +Appendix III. Glossary + + Bridge + + A node connected to two or more administratively indistinguishable + but physically distinct subnets, that automatically forwards + datagrams when necessary, but whose existence is not known to + other hosts. Also called a "software repeater". + + Gateway + + A node connected to two or more administratively distinct networks + and/or subnets, to which hosts send datagrams to be forwarded. + + Host Field + + The bit field in an Internet address used for denoting a specific + host. + + Internet + + The collection of connected networks using the IP protocol. + + Local Address + + The rest field of the Internet address (as defined in [3]). + + Network + + A single Internet network (which may or may not be divided into + subnets). + + +Mogul & Postel [Page 16] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + + Network Number + + The network field of the Internet address. + + Subnet + + One or more physical networks forming a subset of an Internet + network. A subnet is explicitly identified in the Internet + address. + + Subnet Field + + The bit field in an Internet address denoting the subnet number. + The bits making up this field are not necessarily contiguous in + the address. + + Subnet Number + + A number identifying a subnet within a network. + +Appendix IV. Assigned Numbers + + The following assignments are made for protocol parameters used in + the support of subnets. The only assignments needed are for the + Internet Control Message Protocol (ICMP) [5]. + + ICMP Message Types + + AM1 = 17 + + AM2 = 18 + + + + + + + + + + + + + + + + + + +Mogul & Postel [Page 17] + + + +RFC 950 August 1985 +Internet Standard Subnetting Procedure + + +References + + [1] Mogul, J., "Internet Subnets", RFC-917, Stanford University, + October 1984. + + [2] Postel, J., "Multi-LAN Address Resolution", RFC-925, + USC/Information Sciences Institute, October 1984. + + [3] Postel, J., "Internet Protocol", RFC-791, USC/Information + Sciences Institute, September 1981. + + [4] Finlayson, R., T. Mann, J. Mogul, M. Theimer, "A Reverse Address + Resolution Protocol", RFC-903, Stanford University, June 1984. + + [5] Postel, J., "Internet Control Message Protocol", RFC-792, + USC/Information Sciences Institute, September 1981. + + [6] Mogul, J., "Broadcasting Internet Datagrams", RFC-919, Stanford + University, October 1984. + + [7] GADS, "Towards an Internet Standard Scheme for Subnetting", + RFC-940, Network Information Center, SRI International, + April 1985. + + [8] Croft, B., and J. Gilmore, "BOOTP -- UDP Bootstrap Protocol", + RFC-951, Stanford University, August 1985. + + [9] Reynolds, J., and J. Postel, "Assigned Numbers", RFC-943, + USC/Information Sciences Institute, April 1985. + + + + + + + + + + + + + + + + + + + + +Mogul & Postel [Page 18] + +======================================================================== + +Network Working Group Jeffrey Mogul +Request for Comments: 919 Computer Science Department + Stanford University + October 1984 + + BROADCASTING INTERNET DATAGRAMS + + +Status of this Memo + + We propose simple rules for broadcasting Internet datagrams on local + networks that support broadcast, for addressing broadcasts, and for + how gateways should handle them. + + This RFC suggests a proposed protocol for the ARPA-Internet + community, and requests discussion and suggestions for improvements. + Distribution of this memo is unlimited. + +Acknowledgement + + This proposal is the result of discussion with several other people, + especially J. Noel Chiappa and Christopher A. Kent, both of whom both + pointed me at important references. + +1. Introduction + + The use of broadcasts, especially on high-speed local area networks, + is a good base for many applications. Since broadcasting is not + covered in the basic IP specification [13], there is no agreed-upon + way to do it, and so protocol designers have not made use of it. (The + issue has been touched upon before, e.g. [6], but has not been the + subject of a standard.) + + We consider here only the case of unreliable, unsequenced, possibly + duplicated datagram broadcasts (for a discussion of TCP broadcasting, + see [11].) Even though unreliable and limited in length, datagram + broadcasts are quite useful [1]. + + We assume that the data link layer of the local network supports + efficient broadcasting. Most common local area networks do support + broadcast; for example, Ethernet [7, 5], ChaosNet [10], token ring + networks [2], etc. + + We do not assume, however, that broadcasts are reliably delivered. + (One might consider providing a reliable broadcast protocol as a + layer above IP.) It is quite expensive to guarantee delivery of + broadcasts; instead, what we assume is that a host will receive most + of the broadcasts that are sent. This is important to avoid + excessive use of broadcasts; since every host on the network devotes + at least some effort to every broadcast, they are costly. + + + +Mogul [Page 1] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + + When a datagram is broadcast, it imposes a cost on every host that + hears it. Therefore, broadcasting should not be used + indiscriminately, but rather only when it is the best solution to a + problem. + + Note: some organizations have divided their IP networks into subnets, + for which a standard [8] has been proposed. This RFC does not cover + the numerous complications arising from the interactions between + subnets and broadcasting; see [9] for a complete discussion. + +2. Terminology + + Because broadcasting depends on the specific data link layer in use + on a local network, we must discuss it with reference to both + physical networks and logical networks. + + The terms we will use in referring to physical networks are, from the + point of view of the host sending or forwarding a broadcast: + + Local Hardware Network + + The physical link to which the host is attached. + + Remote Hardware Network + + A physical network which is separated from the host by at least + one gateway. + + Collection of Hardware Networks + + A set of hardware networks (transitively) connected by gateways. + + The IP world includes several kinds of logical network. To avoid + ambiguity, we will use the following terms: + + Internet + + The DARPA Internet collection of IP networks. + + IP Network + + One or a collection of several hardware networks that have one + specific IP network number. + + + + + + +Mogul [Page 2] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + +3. Why Broadcast? + + Broadcasts are useful when a host needs to find information without + knowing exactly what other host can supply it, or when a host wants + to provide information to a large set of hosts in a timely manner. + + When a host needs information that one or more of its neighbors might + have, it could have a list of neighbors to ask, or it could poll all + of its possible neighbors until one responds. Use of a wired-in list + creates obvious network management problems (early binding is + inflexible). On the other hand, asking all of one's neighbors is + slow if one must generate plausible host addresses, and try them + until one works. On the ARPANET, for example, there are roughly 65 + thousand plausible host numbers. Most IP implementations have used + wired-in lists (for example, addresses of "Prime" gateways.) + Fortunately, broadcasting provides a fast and simple way for a host + to reach all of its neighbors. + + A host might also use a broadcast to provide all of its neighbors + with some information; for example, a gateway might announce its + presence to other gateways. + + One way to view broadcasting is as an imperfect substitute for + multicasting, the sending of messages to a subset of the hosts on a + network. In practice, broadcasts are usually used where multicasts + are what is wanted; packets are broadcast at the hardware level, but + filtering software in the receiving hosts gives the effect of + multicasting. + + For more examples of broadcast applications, see [1, 3]. + +4. Broadcast Classes + + There are several classes of IP broadcasting: + + - Single-destination datagram broadcast on the local IP net: A + datagrams is destined for a specific IP host, but the sending + host broadcasts it at the data link layer, perhaps to avoid + having to do routing. Since this is not an IP broadcast, the IP + layer is not involved, except that a host should discard + datagrams not meant for it without becoming flustered (i.e., + printing an error message). + + - Broadcast to all hosts on the local IP net: A distinguished + value for the host-number part of the IP address denotes + broadcast instead of a specific host. The receiving IP layer + must be able to recognize this address as well as its own. + + +Mogul [Page 3] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + + However, it might still be useful to distinguish at higher + levels between broadcasts and non-broadcasts, especially in + gateways. This is the most useful case of broadcast; it allows a + host to discover gateways without wired-in tables, it is the + basis for address resolution protocols, and it is also useful + for accessing such utilities as name servers, time servers, + etc., without requiring wired-in addresses. + + - Broadcast to all hosts on a remote IP network: It is + occasionally useful to send a broadcast to all hosts on a + non-local network; for example, to find the latest version of a + hostname database, to bootload a host on an IP network without a + bootserver, or to monitor the timeservers on the IP network. + This case is the same as local-network broadcasts; the datagram + is routed by normal mechanisms until it reaches a gateway + attached to the destination IP network, at which point it is + broadcast. This class of broadcasting is also known as "directed + broadcasting", or quaintly as sending a "letter bomb" [1]. + + - Broadcast to the entire Internet: This is probably not useful, + and almost certainly not desirable. + + For reasons of performance or security, a gateway may choose not to + forward broadcasts; especially, it may be a good idea to ban + broadcasts into or out of an autonomous group of networks. + +5. Broadcast Methods + + A host's IP receiving layer must be modified to support broadcasting. + In the absence of broadcasting, a host determines if it is the + recipient of a datagram by matching the destination address against + all of its IP addresses. With broadcasting, a host must compare the + destination address not only against the host's addresses, but also + against the possible broadcast addresses for that host. + + The problem of how best to send a broadcast has been extensively + discussed [1, 3, 4, 14, 15]. Since we assume that the problem has + already been solved at the data link layer, an IP host wishing to + send either a local broadcast or a directed broadcast need only + specify the appropriate destination address and send the datagram as + usual. Any sophisticated algorithms need only reside in gateways. + + + + + + + + +Mogul [Page 4] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + +6. Gateways and Broadcasts + + Most of the complexity in supporting broadcasts lies in gateways. If + a gateway receives a directed broadcast for a network to which it is + not connected, it simply forwards it using the usual mechanism. + Otherwise, it must do some additional work. + + When a gateway receives a local broadcast datagram, there are several + things it might have to do with it. The situation is unambiguous, + but without due care it is possible to create infinite loops. + + The appropriate action to take on receipt of a broadcast datagram + depends on several things: the subnet it was received on, the + destination network, and the addresses of the gateway. + + - The primary rule for avoiding loops is "never broadcast a + datagram on the hardware network it was received on". It is not + sufficient simply to avoid repeating datagrams that a gateway + has heard from itself; this still allows loops if there are + several gateways on a hardware network. + + - If the datagram is received on the hardware network to which it + is addressed, then it should not be forwarded. However, the + gateway should consider itself to be a destination of the + datagram (for example, it might be a routing table update.) + + - Otherwise, if the datagram is addressed to a hardware network to + which the gateway is connected, it should be sent as a (data + link layer) broadcast on that network. Again, the gateway + should consider itself a destination of the datagram. + + - Otherwise, the gateway should use its normal routing procedure + to choose a subsequent gateway, and send the datagram along to + it. + +7. Broadcast IP Addressing - Proposed Standards + + If different IP implementations are to be compatible, there must be a + distinguished number to denote "all hosts". + + Since the local network layer can always map an IP address into data + link layer address, the choice of an IP "broadcast host number" is + somewhat arbitrary. For simplicity, it should be one not likely to + be assigned to a real host. The number whose bits are all ones has + this property; this assignment was first proposed in [6]. In the few + cases where a host has been assigned an address with a host-number + part of all ones, it does not seem onerous to require renumbering. + + +Mogul [Page 5] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + + The address 255.255.255.255 denotes a broadcast on a local hardware + network, which must not be forwarded. This address may be used, for + example, by hosts that do not know their network number and are + asking some server for it. + + Thus, a host on net 36, for example, may: + + - broadcast to all of its immediate neighbors by using + 255.255.255.255 + + - broadcast to all of net 36 by using 36.255.255.255 + + (Note that unless the network has been broken up into subnets, these + two methods have identical effects.) + + If the use of "all ones" in a field of an IP address means + "broadcast", using "all zeros" could be viewed as meaning + "unspecified". There is probably no reason for such addresses to + appear anywhere but as the source address of an ICMP Information + Request datagram. However, as a notational convention, we refer to + networks (as opposed to hosts) by using addresses with zero fields. + For example, 36.0.0.0 means "network number 36" while 36.255.255.255 + means "all hosts on network number 36". + + 7.1. ARP Servers and Broadcasts + + The Address Resolution Protocol (ARP) described in [12] can, if + incorrectly implemented, cause problems when broadcasts are used + on a network where not all hosts share an understanding of what a + broadcast address is. The temptation exists to modify the ARP + server so that it provides the mapping between an IP broadcast + address and the hardware broadcast address. + + This temptation must be resisted. An ARP server should never + respond to a request whose target is a broadcast address. Such a + request can only come from a host that does not recognize the + broadcast address as such, and so honoring it would almost + certainly lead to a forwarding loop. If there are N such hosts on + the physical network that do not recognize this address as a + broadcast, then a datagram sent with a Time-To-Live of T could + potentially give rise to T**N spurious re-broadcasts. + + + + + + + + +Mogul [Page 6] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + +8. References + + 1. David Reeves Boggs. Internet Broadcasting. Ph.D. Th., Stanford + University, January 1982. + + 2. D.D. Clark, K.T. Pogran, and D.P. Reed. "An Introduction to + Local Area Networks". Proc. IEEE 66, 11, pp1497-1516, 1978. + + 3. Yogan Kantilal Dalal. Broadcast Protocols in Packet Switched + Computer Networks. Ph.D. Th., Stanford University, April 1977. + + 4. Yogan K. Dalal and Robert M. Metcalfe. "Reverse Path Forwarding + of Broadcast Packets". Comm. ACM 21, 12, pp1040-1048, December + 1978. + + 5. The Ethernet, A Local Area Network: Data Link Layer and Physical + Layer Specifications. Version 1.0, Digital Equipment + Corporation, Intel, Xerox, September 1980. + + 6. Robert Gurwitz and Robert Hinden. IP - Local Area Network + Addressing Issues. IEN-212, Bolt Beranek and Newman, September + 1982. + + 7. R.M. Metcalfe and D.R. Boggs. "Ethernet: Distributed Packet + Switching for Local Computer Networks". Comm. ACM 19, 7, + pp395-404, July 1976. Also CSL-75-7, Xerox Palo Alto Research + Center, reprinted in CSL-80-2. + + 8. Jeffrey Mogul. Internet Subnets. RFC-917, Stanford University, + October 1984. + + 9. Jeffrey Mogul. Broadcasting Internet Packets in the Presence of + Subnets. RFC-922, Stanford University, October 1984. + + 10. David A. Moon. Chaosnet. A.I. Memo 628, Massachusetts + Institute of Technology Artificial Intelligence Laboratory, June + 1981. + + 11. William W. Plummer. Internet Broadcast Protocols. IEN-10, Bolt + Beranek and Newman, March 1977. + + 12. David Plummer. An Ethernet Address Resolution Protocol. + RFC-826, Symbolics, September 1982. + + 13. Jon Postel. Internet Protocol. RFC 791, ISI, September 1981. + + + + +Mogul [Page 7] + + + +RFC 919 October 1984 +Broadcasting Internet Datagrams + + + 14. David W. Wall. Mechanisms for Broadcast and Selective + Broadcast. Ph.D. Th., Stanford University, June 1980. + + 15. David W. Wall and Susan S. Owicki. Center-based Broadcasting. + Computer Systems Lab Technical Report TR189, Stanford + University, June 1980. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mogul [Page 8] + +======================================================================== + +Network Working Group Jeffrey Mogul +Request for Comments: 922 Computer Science Department + Stanford University + October 1984 + + BROADCASTING INTERNET DATAGRAMS IN THE PRESENCE OF SUBNETS + + +Status of this Memo + + We propose simple rules for broadcasting Internet datagrams on local + networks that support broadcast, for addressing broadcasts, and for + how gateways should handle them. + + This RFC suggests a proposed protocol for the ARPA-Internet + community, and requests discussion and suggestions for improvements. + Distribution of this memo is unlimited. + +Acknowledgement + + This proposal here is the result of discussion with several other + people, especially J. Noel Chiappa and Christopher A. Kent, both of + whom both pointed me at important references. + +1. Introduction + + The use of broadcasts, especially on high-speed local area networks, + is a good base for many applications. Since broadcasting is not + covered in the basic IP specification [12], there is no agreed-upon + way to do it, and so protocol designers have not made use of it. (The + issue has been touched upon before, e.g. [6], but has not been the + subject of a standard.) + + We consider here only the case of unreliable, unsequenced, possibly + duplicated datagram broadcasts (for a discussion of TCP broadcasting, + see [10].) Even though unreliable and limited in length, datagram + broadcasts are quite useful [1]. + + We assume that the data link layer of the local network supports + efficient broadcasting. Most common local area networks do support + broadcast; for example, Ethernet [7, 5], ChaosNet [9], token ring + networks [2], etc. + + We do not assume, however, that broadcasts are reliably delivered. + (One might consider providing a reliable datagram broadcast protocol + as a layer above IP.) It is quite expensive to guarantee delivery of + broadcasts; instead, what we assume is that a host will receive most + of the broadcasts that are sent. This is important to avoid + excessive use of broadcasts; since every host on the network devotes + at least some effort to every broadcast, they are costly. + + + +Mogul [Page 1] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + When a datagram is broadcast, it imposes a cost on every host that + hears it. Therefore, broadcasting should not be used + indiscriminately, but rather only when it is the best solution to a + problem. + +2. Terminology + + Because broadcasting depends on the specific data link layer in use + on a local network, we must discuss it with reference to both + physical networks and logical networks. + + The terms we will use in referring to physical networks are, from the + point of view of the host sending or forwarding a broadcast: + + Local Hardware Network + + The physical link to which the host is attached. + + Remote Hardware Network + + A physical network which is separated from the host by at least + one gateway. + + Collection of Hardware Networks + + A set of hardware networks (transitively) connected by gateways. + + The IP world includes several kinds of logical network. To avoid + ambiguity, we will use the following terms: + + Internet + + The DARPA Internet collection of IP networks. + + IP Network + + One or a collection of several hardware networks that have one + specific IP network number. + + Subnet + + A single member of the collection of hardware networks that + compose an IP network. Host addresses on a given subnet share an + IP network number with hosts on all other subnets of that IP + network, but the local-address part is divided into subnet-number + + + + +Mogul [Page 2] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + and host-number fields to indicate which subnet a host is on. We + do not assume a particular division of the local-address part; + this could vary from network to network. + + The introduction of a subnet level in the addressing hierarchy is at + variance with the IP specification [12], but as the use of + addressable subnets proliferates it is obvious that a broadcasting + scheme should support subnetting. For more on subnets, see [8]. + + In this paper, the term "host address" refers to the host-on-subnet + address field of a subnetted IP network, or the host-part field + otherwise. + + An IP network may consist of a single hardware network or a + collection of subnets; from the point of view of a host on another IP + network, it should not matter. + +3. Why Broadcast? + + Broadcasts are useful when a host needs to find information without + knowing exactly what other host can supply it, or when a host wants + to provide information to a large set of hosts in a timely manner. + + When a host needs information that one or more of its neighbors might + have, it could have a list of neighbors to ask, or it could poll all + of its possible neighbors until one responds. Use of a wired-in list + creates obvious network management problems (early binding is + inflexible). On the other hand, asking all of one's neighbors is + slow if one must generate plausible host addresses, and try them + until one works. On the ARPANET, for example, there are roughly 65 + thousand plausible host numbers. Most IP implementations have used + wired-in lists (for example, addresses of "Prime" gateways.) + Fortunately, broadcasting provides a fast and simple way for a host + to reach all of its neighbors. + + A host might also use a broadcast to provide all of its neighbors + with some information; for example, a gateway might announce its + presence to other gateways. + + One way to view broadcasting is as an imperfect substitute for + multicasting, the sending of messages to a subset of the hosts on a + network. In practice, broadcasts are usually used where multicasts + are what is wanted; datagrams are broadcast at the hardware level, + but filtering software in the receiving hosts gives the effect of + multicasting. + + For more examples of broadcast applications, see [1, 3]. + + +Mogul [Page 3] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + +4. Broadcast Classes + + There are several classes of IP broadcasting: + + - Single-destination datagrams broadcast on the local hardware + net: A datagram is destined for a specific IP host, but the + sending host broadcasts it at the data link layer, perhaps to + avoid having to do routing. Since this is not an IP broadcast, + the IP layer is not involved, except that a host should discard + datagram not meant for it without becoming flustered (i.e., + printing an error message). + + - Broadcast to all hosts on the local hardware net: A + distinguished value for the host-number part of the IP address + denotes broadcast instead of a specific host. The receiving IP + layer must be able to recognize this address as well as its own. + However, it might still be useful to distinguish at higher + levels between broadcasts and non-broadcasts, especially in + gateways. This is the most useful case of broadcast; it allows + a host to discover gateways without wired-in tables, it is the + basis for address resolution protocols, and it is also useful + for accessing such utilities as name servers, time servers, + etc., without requiring wired-in addresses. + + - Broadcast to all hosts on a remote hardware network: It is + occasionally useful to send a broadcast to all hosts on a + non-local network; for example, to find the latest version of a + hostname database, to bootload a host on a subnet without a + bootserver, or to monitor the timeservers on the subnet. This + case is the same as local-network broadcasts; the datagram is + routed by normal mechanisms until it reaches a gateway attached + to the destination hardware network, at which point it is + broadcast. This class of broadcasting is also known as + "directed broadcasting", or quaintly as sending a "letter bomb" + [1]. + + - Broadcast to all hosts on a subnetted IP network (Multi-subnet + broadcasts): A distinguished value for the subnet-number part of + the IP address is used to denote "all subnets". Broadcasts to + all hosts of a remote subnetted IP network are done just as + directed broadcasts to a single subnet. + + - Broadcast to the entire Internet: This is probably not useful, + and almost certainly not desirable. + + + + + +Mogul [Page 4] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + For reasons of performance or security, a gateway may choose not to + forward broadcasts; especially, it may be a good idea to ban + broadcasts into or out of an autonomous group of networks. + +5. Broadcast Methods + + A host's IP receiving layer must be modified to support broadcasting. + In the absence of broadcasting, a host determines if it is the + recipient of a datagram by matching the destination address against + all of its IP addresses. With broadcasting, a host must compare the + destination address not only against the host's addresses, but also + against the possible broadcast addresses for that host. + + The problem of how best to send a broadcast has been extensively + discussed [1, 3, 4, 13, 14]. Since we assume that the problem has + already been solved at the data link layer, an IP host wishing to + send either a local broadcast or a directed broadcast need only + specify the appropriate destination address and send the datagram as + usual. Any sophisticated algorithms need only reside in gateways. + + The problem of broadcasting to all hosts on a subnetted IP network is + apparently somewhat harder. However, even in this case it turns out + that the best known algorithms require no additional complexity in + non-gateway hosts. A good broadcast method will meet these + additional criteria: + + - No modification of the IP datagram format. + + - Reasonable efficiency in terms of the number of excess copies + generated and the cost of paths chosen. + + - Minimization of gateway modification, in both code and data + space. + + - High likelihood of delivery. + + The algorithm that appears best is the Reverse Path Forwarding (RPF) + method [4]. While RPF is suboptimal in cost and reliability, it is + quite good, and is extremely simple to implement, requiring no + additional data space in a gateway. + + + + + + + + + +Mogul [Page 5] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + +6. Gateways and Broadcasts + + Most of the complexity in supporting broadcasts lies in gateways. If + a gateway receives a directed broadcast for a network to which it is + not connected, it simply forwards it using the usual mechanism. + Otherwise, it must do some additional work. + + 6.1. Local Broadcasts + + When a gateway receives a local broadcast datagram, there are + several things it might have to do with it. The situation is + unambiguous, but without due care it is possible to create + infinite loops. + + The appropriate action to take on receipt of a broadcast datagram + depends on several things: the subnet it was received on, the + destination network, and the addresses of the gateway. + + - The primary rule for avoiding loops is "never broadcast a + datagram on the hardware network it was received on". It is + not sufficient simply to avoid repeating datagram that a + gateway has heard from itself; this still allows loops if + there are several gateways on a hardware network. + + - If the datagram is received on the hardware network to which + it is addressed, then it should not be forwarded. However, + the gateway should consider itself to be a destination of the + datagram (for example, it might be a routing table update.) + + - Otherwise, if the datagram is addressed to a hardware network + to which the gateway is connected, it should be sent as a + (data link layer) broadcast on that network. Again, the + gateway should consider itself a destination of the datagram. + + - Otherwise, the gateway should use its normal routing + procedure to choose a subsequent gateway, and send the + datagram along to it. + + + + + + + + + + + + +Mogul [Page 6] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + 6.2. Multi-subnet broadcasts + + When a gateway receives a broadcast meant for all subnets of an IP + network, it must use the Reverse Path Forwarding algorithm to + decide what to do. The method is simple: the gateway should + forward copies of the datagram along all connected links, if and + only if the datagram arrived on the link which is part of the best + route between the gateway and the source of the datagram. + Otherwise, the datagram should be discarded. + + This algorithm may be improved if some or all of the gateways + exchange among themselves additional information; this can be done + transparently from the point of view of other hosts and even other + gateways. See [4, 3] for details. + + 6.3. Pseudo-Algol Routing Algorithm + + This is a pseudo-Algol description of the routing algorithm a + gateway should use. The algorithm is shown in figure 1. Some + definitions are: + + RouteLink(host) + + A function taking a host address as a parameter and returning + the first-hop link from the gateway to the host. + + RouteHost(host) + + As above but returns the first-hop host address. + + ResolveAddress(host) + + Returns the hardware address for an IP host. + + IncomingLink + + The link on which the packet arrived. + + OutgoingLinkSet + + The set of links on which the packet should be sent. + + OutgoingHardwareHost + + The hardware host address to send the packet to. + + + + +Mogul [Page 7] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + Destination.host + + The host-part of the destination address. + + Destination.subnet + + The subnet-part of the destination address. + + Destination.ipnet + + The IP-network-part of the destination address. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mogul [Page 8] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + +BEGIN + IF Destination.ipnet IN AllLinks THEN + BEGIN + IF IsSubnetted(Destination.ipnet) THEN + BEGIN + IF Destination.subnet = BroadcastSubnet THEN + BEGIN /* use Reverse Path Forwarding algorithm */ + IF IncomingLink = RouteLink(Source) THEN + BEGIN IF Destination.host = BroadcastHost THEN + OutgoingLinkSet <- AllLinks - + IncomingLink; + OutgoingHost <- BroadcastHost; + Examine packet for possible internal use; + END + ELSE /* duplicate from another gateway, discard */ + Discard; + END + ELSE + IF Destination.subnet = IncomingLink.subnet THEN + BEGIN /* forwarding would cause a loop */ + IF Destination.host = BroadcastHost THEN + Examine packet for possible internal use; + Discard; + END + ELSE BEGIN /* forward to (possibly local) subnet */ + OutgoingLinkSet <- RouteLink(Destination); + OutgoingHost <- RouteHost(Destination); + END + END + ELSE BEGIN /* destined for one of our local networks */ + IF Destination.ipnet = IncomingLink.ipnet THEN + BEGIN /* forwarding would cause a loop */ + IF Destination.host = BroadcastHost THEN + Examine packet for possible internal use; + Discard; + END + ELSE BEGIN /* might be a broadcast */ + OutgoingLinkSet <- RouteLink(Destination); + OutgoingHost <- RouteHost(Destination); + END + END + END + ELSE BEGIN /* forward to a non-local IP network */ + OutgoingLinkSet <- RouteLink(Destination); + OutgoingHost <- RouteHost(Destination); + END + OutgoingHardwareHost <- ResolveAddress(OutgoingHost); +END + +Figure 1: Pseudo-Algol algorithm for routing broadcasts by gateways + +Mogul [Page 9] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + +7. Broadcast IP Addressing - Conventions + + If different IP implementations are to be compatible, there must be + convention distinguished number to denote "all hosts" and "all + subnets". + + Since the local network layer can always map an IP address into data + link layer address, the choice of an IP "broadcast host number" is + somewhat arbitrary. For simplicity, it should be one not likely to + be assigned to a real host. The number whose bits are all ones has + this property; this assignment was first proposed in [6]. In the few + cases where a host has been assigned an address with a host-number + part of all ones, it does not seem onerous to require renumbering. + + The "all subnets" number is also all ones; this means that a host + wishing to broadcast to all hosts on a remote IP network need not + know how the destination address is divided up into subnet and host + fields, or if it is even divided at all. For example, 36.255.255.255 + may denote all the hosts on a single hardware network, or all the + hosts on a subnetted IP network with 1 byte of subnet field and 2 + bytes of host field, or any other possible division. + + The address 255.255.255.255 denotes a broadcast on a local hardware + network that must not be forwarded. This address may be used, for + example, by hosts that do not know their network number and are + asking some server for it. + + Thus, a host on net 36, for example, may: + + - broadcast to all of its immediate neighbors by using + 255.255.255.255 + + - broadcast to all of net 36 by using 36.255.255.255 + + without knowing if the net is subnetted; if it is not, then both + addresses have the same effect. A robust application might try the + former address, and if no response is received, then try the latter. + See [1] for a discussion of such "expanding ring search" techniques. + + If the use of "all ones" in a field of an IP address means + "broadcast", using "all zeros" could be viewed as meaning + "unspecified". There is probably no reason for such addresses to + appear anywhere but as the source address of an ICMP Information + Request datagram. However, as a notational convention, we refer to + networks (as opposed to hosts) by using addresses with zero fields. + For example, 36.0.0.0 means "network number 36" while 36.255.255.255 + means "all hosts on network number 36". + + +Mogul [Page 10] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + 7.1. ARP Servers and Broadcasts + + The Address Resolution Protocol (ARP) described in [11] can, if + incorrectly implemented, cause problems when broadcasts are used + on a network where not all hosts share an understanding of what a + broadcast address is. The temptation exists to modify the ARP + server so that it provides the mapping between an IP broadcast + address and the hardware broadcast address. + + This temptation must be resisted. An ARP server should never + respond to a request whose target is a broadcast address. Such a + request can only come from a host that does not recognize the + broadcast address as such, and so honoring it would almost + certainly lead to a forwarding loop. If there are N such hosts on + the physical network that do not recognize this address as a + broadcast, then a datagram sent with a Time-To-Live of T could + potentially give rise to T**N spurious re-broadcasts. + +8. References + + 1. David Reeves Boggs. Internet Broadcasting. Ph.D. Th., Stanford + University, January 1982. + + 2. D.D. Clark, K.T. Pogran, and D.P. Reed. "An Introduction to + Local Area Networks". Proc. IEEE 66, 11, pp1497-1516, + November 1978. + + 3. Yogan Kantilal Dalal. Broadcast Protocols in Packet Switched + Computer Networks. Ph.D. Th., Stanford University, April 1977. + + 4. Yogan K. Dalal and Robert M. Metcalfe. "Reverse Path Forwarding + of Broadcast Packets". Comm. ACM 21, 12, pp1040-1048, + December 1978. + + 5. The Ethernet, A Local Area Network: Data Link Layer and Physical + Layer Specifications. Version 1.0, Digital Equipment + Corporation, Intel, Xerox, September 1980. + + 6. Robert Gurwitz and Robert Hinden. IP - Local Area Network + Addressing Issues. IEN-212, BBN, September 1982. + + 7. R.M. Metcalfe and D.R. Boggs. "Ethernet: Distributed Packet + Switching for Local Computer Networks". Comm. ACM 19, 7, + pp395-404, July 1976. Also CSL-75-7, Xerox Palo Alto Research + Center, reprinted in CSL-80-2. + + + + +Mogul [Page 11] + + + +RFC 922 October 1984 +Broadcasting Internet Datagrams in the Presence of Subnets + + + 8. Jeffrey Mogul. Internet Subnets. RFC-917, Stanford University, + October 1984. + + 9. David A. Moon. Chaosnet. A.I. Memo 628, Massachusetts + Institute of Technology Artificial Intelligence Laboratory, + June 1981. + + 10. William W. Plummer. Internet Broadcast Protocols. IEN-10, BBN, + March 1977. + + 11. David Plummer. An Ethernet Address Resolution Protocol. + RFC-826, Symbolics, September 1982. + + 12. Jon Postel. Internet Protocol. RFC-791, ISI, September 1981. + + 13. David W. Wall. Mechanisms for Broadcast and Selective + Broadcast. Ph.D. Th., Stanford University, June 1980. + + 14. David W. Wall and Susan S. Owicki. Center-based Broadcasting. + Computer Systems Lab Technical Report TR189, Stanford + University, June 1980. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mogul [Page 12] + +======================================================================== + +Network Working Group J. Postel +Request for Comments: 792 ISI + September 1981 +Updates: RFCs 777, 760 +Updates: IENs 109, 128 + + INTERNET CONTROL MESSAGE PROTOCOL + + DARPA INTERNET PROGRAM + PROTOCOL SPECIFICATION + + + +Introduction + + The Internet Protocol (IP) [1] is used for host-to-host datagram + service in a system of interconnected networks called the + Catenet [2]. The network connecting devices are called Gateways. + These gateways communicate between themselves for control purposes + via a Gateway to Gateway Protocol (GGP) [3,4]. Occasionally a + gateway or destination host will communicate with a source host, for + example, to report an error in datagram processing. For such + purposes this protocol, the Internet Control Message Protocol (ICMP), + is used. ICMP, uses the basic support of IP as if it were a higher + level protocol, however, ICMP is actually an integral part of IP, and + must be implemented by every IP module. + + ICMP messages are sent in several situations: for example, when a + datagram cannot reach its destination, when the gateway does not have + the buffering capacity to forward a datagram, and when the gateway + can direct the host to send traffic on a shorter route. + + The Internet Protocol is not designed to be absolutely reliable. The + purpose of these control messages is to provide feedback about + problems in the communication environment, not to make IP reliable. + There are still no guarantees that a datagram will be delivered or a + control message will be returned. Some datagrams may still be + undelivered without any report of their loss. The higher level + protocols that use IP must implement their own reliability procedures + if reliable communication is required. + + The ICMP messages typically report errors in the processing of + datagrams. To avoid the infinite regress of messages about messages + etc., no ICMP messages are sent about ICMP messages. Also ICMP + messages are only sent about errors in handling fragment zero of + fragemented datagrams. (Fragment zero has the fragment offeset equal + zero). + + + + + + + + [Page 1] + + + September 1981 +RFC 792 + + + +Message Formats + + ICMP messages are sent using the basic IP header. The first octet of + the data portion of the datagram is a ICMP type field; the value of + this field determines the format of the remaining data. Any field + labeled "unused" is reserved for later extensions and must be zero + when sent, but receivers should not use these fields (except to + include them in the checksum). Unless otherwise noted under the + individual format descriptions, the values of the internet header + fields are as follows: + + Version + + 4 + + IHL + + Internet header length in 32-bit words. + + Type of Service + + 0 + + Total Length + + Length of internet header and data in octets. + + Identification, Flags, Fragment Offset + + Used in fragmentation, see [1]. + + Time to Live + + Time to live in seconds; as this field is decremented at each + machine in which the datagram is processed, the value in this + field should be at least as great as the number of gateways which + this datagram will traverse. + + Protocol + + ICMP = 1 + + Header Checksum + + The 16 bit one's complement of the one's complement sum of all 16 + bit words in the header. For computing the checksum, the checksum + field should be zero. This checksum may be replaced in the + future. + + +[Page 2] + + +September 1981 +RFC 792 + + + + Source Address + + The address of the gateway or host that composes the ICMP message. + Unless otherwise noted, this can be any of a gateway's addresses. + + Destination Address + + The address of the gateway or host to which the message should be + sent. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 3] + + + September 1981 +RFC 792 + + + +Destination Unreachable Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unused | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Internet Header + 64 bits of Original Data Datagram | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Destination Address + + The source network and address from the original datagram's data. + + ICMP Fields: + + Type + + 3 + + Code + + 0 = net unreachable; + + 1 = host unreachable; + + 2 = protocol unreachable; + + 3 = port unreachable; + + 4 = fragmentation needed and DF set; + + 5 = source route failed. + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Internet Header + 64 bits of Data Datagram + + The internet header plus the first 64 bits of the original + + +[Page 4] + + +September 1981 +RFC 792 + + + + datagram's data. This data is used by the host to match the + message to the appropriate process. If a higher level protocol + uses port numbers, they are assumed to be in the first 64 data + bits of the original datagram's data. + + Description + + If, according to the information in the gateway's routing tables, + the network specified in the internet destination field of a + datagram is unreachable, e.g., the distance to the network is + infinity, the gateway may send a destination unreachable message + to the internet source host of the datagram. In addition, in some + networks, the gateway may be able to determine if the internet + destination host is unreachable. Gateways in these networks may + send destination unreachable messages to the source host when the + destination host is unreachable. + + If, in the destination host, the IP module cannot deliver the + datagram because the indicated protocol module or process port is + not active, the destination host may send a destination + unreachable message to the source host. + + Another case is when a datagram must be fragmented to be forwarded + by a gateway yet the Don't Fragment flag is on. In this case the + gateway must discard the datagram and may return a destination + unreachable message. + + Codes 0, 1, 4, and 5 may be received from a gateway. Codes 2 and + 3 may be received from a host. + + + + + + + + + + + + + + + + + + + + + + [Page 5] + + + September 1981 +RFC 792 + + + +Time Exceeded Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unused | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Internet Header + 64 bits of Original Data Datagram | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Destination Address + + The source network and address from the original datagram's data. + + ICMP Fields: + + Type + + 11 + + Code + + 0 = time to live exceeded in transit; + + 1 = fragment reassembly time exceeded. + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Internet Header + 64 bits of Data Datagram + + The internet header plus the first 64 bits of the original + datagram's data. This data is used by the host to match the + message to the appropriate process. If a higher level protocol + uses port numbers, they are assumed to be in the first 64 data + bits of the original datagram's data. + + Description + + If the gateway processing a datagram finds the time to live field + + +[Page 6] + + +September 1981 +RFC 792 + + + + is zero it must discard the datagram. The gateway may also notify + the source host via the time exceeded message. + + If a host reassembling a fragmented datagram cannot complete the + reassembly due to missing fragments within its time limit it + discards the datagram, and it may send a time exceeded message. + + If fragment zero is not available then no time exceeded need be + sent at all. + + Code 0 may be received from a gateway. Code 1 may be received + from a host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 7] + + + September 1981 +RFC 792 + + + +Parameter Problem Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer | unused | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Internet Header + 64 bits of Original Data Datagram | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Destination Address + + The source network and address from the original datagram's data. + + ICMP Fields: + + Type + + 12 + + Code + + 0 = pointer indicates the error. + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Pointer + + If code = 0, identifies the octet where an error was detected. + + Internet Header + 64 bits of Data Datagram + + The internet header plus the first 64 bits of the original + datagram's data. This data is used by the host to match the + message to the appropriate process. If a higher level protocol + uses port numbers, they are assumed to be in the first 64 data + bits of the original datagram's data. + + + + +[Page 8] + + +September 1981 +RFC 792 + + + + Description + + If the gateway or host processing a datagram finds a problem with + the header parameters such that it cannot complete processing the + datagram it must discard the datagram. One potential source of + such a problem is with incorrect arguments in an option. The + gateway or host may also notify the source host via the parameter + problem message. This message is only sent if the error caused + the datagram to be discarded. + + The pointer identifies the octet of the original datagram's header + where the error was detected (it may be in the middle of an + option). For example, 1 indicates something is wrong with the + Type of Service, and (if there are options present) 20 indicates + something is wrong with the type code of the first option. + + Code 0 may be received from a gateway or a host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 9] + + + September 1981 +RFC 792 + + + +Source Quench Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unused | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Internet Header + 64 bits of Original Data Datagram | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Destination Address + + The source network and address of the original datagram's data. + + ICMP Fields: + + Type + + 4 + + Code + + 0 + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Internet Header + 64 bits of Data Datagram + + The internet header plus the first 64 bits of the original + datagram's data. This data is used by the host to match the + message to the appropriate process. If a higher level protocol + uses port numbers, they are assumed to be in the first 64 data + bits of the original datagram's data. + + Description + + A gateway may discard internet datagrams if it does not have the + buffer space needed to queue the datagrams for output to the next + network on the route to the destination network. If a gateway + + +[Page 10] + + +September 1981 +RFC 792 + + + + discards a datagram, it may send a source quench message to the + internet source host of the datagram. A destination host may also + send a source quench message if datagrams arrive too fast to be + processed. The source quench message is a request to the host to + cut back the rate at which it is sending traffic to the internet + destination. The gateway may send a source quench message for + every message that it discards. On receipt of a source quench + message, the source host should cut back the rate at which it is + sending traffic to the specified destination until it no longer + receives source quench messages from the gateway. The source host + can then gradually increase the rate at which it sends traffic to + the destination until it again receives source quench messages. + + The gateway or host may send the source quench message when it + approaches its capacity limit rather than waiting until the + capacity is exceeded. This means that the data datagram which + triggered the source quench message may be delivered. + + Code 0 may be received from a gateway or a host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 11] + + + September 1981 +RFC 792 + + + +Redirect Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Gateway Internet Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Internet Header + 64 bits of Original Data Datagram | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Destination Address + + The source network and address of the original datagram's data. + + ICMP Fields: + + Type + + 5 + + Code + + 0 = Redirect datagrams for the Network. + + 1 = Redirect datagrams for the Host. + + 2 = Redirect datagrams for the Type of Service and Network. + + 3 = Redirect datagrams for the Type of Service and Host. + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Gateway Internet Address + + Address of the gateway to which traffic for the network specified + in the internet destination network field of the original + datagram's data should be sent. + + + + +[Page 12] + + +September 1981 +RFC 792 + + + + Internet Header + 64 bits of Data Datagram + + The internet header plus the first 64 bits of the original + datagram's data. This data is used by the host to match the + message to the appropriate process. If a higher level protocol + uses port numbers, they are assumed to be in the first 64 data + bits of the original datagram's data. + + Description + + The gateway sends a redirect message to a host in the following + situation. A gateway, G1, receives an internet datagram from a + host on a network to which the gateway is attached. The gateway, + G1, checks its routing table and obtains the address of the next + gateway, G2, on the route to the datagram's internet destination + network, X. If G2 and the host identified by the internet source + address of the datagram are on the same network, a redirect + message is sent to the host. The redirect message advises the + host to send its traffic for network X directly to gateway G2 as + this is a shorter path to the destination. The gateway forwards + the original datagram's data to its internet destination. + + For datagrams with the IP source route options and the gateway + address in the destination address field, a redirect message is + not sent even if there is a better route to the ultimate + destination than the next address in the source route. + + Codes 0, 1, 2, and 3 may be received from a gateway. + + + + + + + + + + + + + + + + + + + + + + + [Page 13] + + + September 1981 +RFC 792 + + + +Echo or Echo Reply Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Data ... + +-+-+-+-+- + + IP Fields: + + Addresses + + The address of the source in an echo message will be the + destination of the echo reply message. To form an echo reply + message, the source and destination addresses are simply reversed, + the type code changed to 0, and the checksum recomputed. + + IP Fields: + + Type + + 8 for echo message; + + 0 for echo reply message. + + Code + + 0 + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + If the total length is odd, the received data is padded with one + octet of zeros for computing the checksum. This checksum may be + replaced in the future. + + Identifier + + If code = 0, an identifier to aid in matching echos and replies, + may be zero. + + Sequence Number + + +[Page 14] + + +September 1981 +RFC 792 + + + + If code = 0, a sequence number to aid in matching echos and + replies, may be zero. + + Description + + The data received in the echo message must be returned in the echo + reply message. + + The identifier and sequence number may be used by the echo sender + to aid in matching the replies with the echo requests. For + example, the identifier might be used like a port in TCP or UDP to + identify a session, and the sequence number might be incremented + on each echo request sent. The echoer returns these same values + in the echo reply. + + Code 0 may be received from a gateway or a host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 15] + + + September 1981 +RFC 792 + + + +Timestamp or Timestamp Reply Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Originate Timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Receive Timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Transmit Timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Addresses + + The address of the source in a timestamp message will be the + destination of the timestamp reply message. To form a timestamp + reply message, the source and destination addresses are simply + reversed, the type code changed to 14, and the checksum + recomputed. + + IP Fields: + + Type + + 13 for timestamp message; + + 14 for timestamp reply message. + + Code + + 0 + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Identifier + + + + +[Page 16] + + +September 1981 +RFC 792 + + + + If code = 0, an identifier to aid in matching timestamp and + replies, may be zero. + + Sequence Number + + If code = 0, a sequence number to aid in matching timestamp and + replies, may be zero. + + Description + + The data received (a timestamp) in the message is returned in the + reply together with an additional timestamp. The timestamp is 32 + bits of milliseconds since midnight UT. One use of these + timestamps is described by Mills [5]. + + The Originate Timestamp is the time the sender last touched the + message before sending it, the Receive Timestamp is the time the + echoer first touched it on receipt, and the Transmit Timestamp is + the time the echoer last touched the message on sending it. + + If the time is not available in miliseconds or cannot be provided + with respect to midnight UT then any time can be inserted in a + timestamp provided the high order bit of the timestamp is also set + to indicate this non-standard value. + + The identifier and sequence number may be used by the echo sender + to aid in matching the replies with the requests. For example, + the identifier might be used like a port in TCP or UDP to identify + a session, and the sequence number might be incremented on each + request sent. The destination returns these same values in the + reply. + + Code 0 may be received from a gateway or a host. + + + + + + + + + + + + + + + + + + [Page 17] + + + September 1981 +RFC 792 + + + +Information Request or Information Reply Message + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + IP Fields: + + Addresses + + The address of the source in a information request message will be + the destination of the information reply message. To form a + information reply message, the source and destination addresses + are simply reversed, the type code changed to 16, and the checksum + recomputed. + + IP Fields: + + Type + + 15 for information request message; + + 16 for information reply message. + + Code + + 0 + + Checksum + + The checksum is the 16-bit ones's complement of the one's + complement sum of the ICMP message starting with the ICMP Type. + For computing the checksum , the checksum field should be zero. + This checksum may be replaced in the future. + + Identifier + + If code = 0, an identifier to aid in matching request and replies, + may be zero. + + Sequence Number + + If code = 0, a sequence number to aid in matching request and + replies, may be zero. + + +[Page 18] + + +September 1981 +RFC 792 + + + + Description + + This message may be sent with the source network in the IP header + source and destination address fields zero (which means "this" + network). The replying IP module should send the reply with the + addresses fully specified. This message is a way for a host to + find out the number of the network it is on. + + The identifier and sequence number may be used by the echo sender + to aid in matching the replies with the requests. For example, + the identifier might be used like a port in TCP or UDP to identify + a session, and the sequence number might be incremented on each + request sent. The destination returns these same values in the + reply. + + Code 0 may be received from a gateway or a host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 19] + + + September 1981 +RFC 792 + + + +Summary of Message Types + + 0 Echo Reply + + 3 Destination Unreachable + + 4 Source Quench + + 5 Redirect + + 8 Echo + + 11 Time Exceeded + + 12 Parameter Problem + + 13 Timestamp + + 14 Timestamp Reply + + 15 Information Request + + 16 Information Reply + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 20] + + +September 1981 +RFC 792 + + + +References + + [1] Postel, J. (ed.), "Internet Protocol - DARPA Internet Program + Protocol Specification," RFC 791, USC/Information Sciences + Institute, September 1981. + + [2] Cerf, V., "The Catenet Model for Internetworking," IEN 48, + Information Processing Techniques Office, Defense Advanced + Research Projects Agency, July 1978. + + [3] Strazisar, V., "Gateway Routing: An Implementation + Specification", IEN 30, Bolt Beranek and Newman, April 1979. + + [4] Strazisar, V., "How to Build a Gateway", IEN 109, Bolt Beranek + and Newman, August 1979. + + [5] Mills, D., "DCNET Internet Clock Service," RFC 778, COMSAT + Laboratories, April 1981. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 21] + +======================================================================== + + + + +Network Working Group S. Deering +Request for Comments: 1112 Stanford University +Obsoletes: RFCs 988, 1054 August 1989 + + + Host Extensions for IP Multicasting + +1. STATUS OF THIS MEMO + + This memo specifies the extensions required of a host implementation + of the Internet Protocol (IP) to support multicasting. It is the + recommended standard for IP multicasting in the Internet. + Distribution of this memo is unlimited. + +2. INTRODUCTION + + IP multicasting is the transmission of an IP datagram to a "host + group", a set of zero or more hosts identified by a single IP + destination address. A multicast datagram is delivered to all + members of its destination host group with the same "best-efforts" + reliability as regular unicast IP datagrams, i.e., the datagram is + not guaranteed to arrive intact at all members of the destination + group or in the same order relative to other datagrams. + + The membership of a host group is dynamic; that is, hosts may join + and leave groups at any time. There is no restriction on the + location or number of members in a host group. A host may be a + member of more than one group at a time. A host need not be a member + of a group to send datagrams to it. + + A host group may be permanent or transient. A permanent group has a + well-known, administratively assigned IP address. It is the address, + not the membership of the group, that is permanent; at any time a + permanent group may have any number of members, even zero. Those IP + multicast addresses that are not reserved for permanent groups are + available for dynamic assignment to transient groups which exist only + as long as they have members. + + Internetwork forwarding of IP multicast datagrams is handled by + "multicast routers" which may be co-resident with, or separate from, + internet gateways. A host transmits an IP multicast datagram as a + local network multicast which reaches all immediately-neighboring + members of the destination host group. If the datagram has an IP + time-to-live greater than 1, the multicast router(s) attached to the + local network take responsibility for forwarding it towards all other + networks that have members of the destination group. On those other + member networks that are reachable within the IP time-to-live, an + attached multicast router completes delivery by transmitting the + + + +Deering [Page 1] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + datagram as a local multicast. + + This memo specifies the extensions required of a host IP + implementation to support IP multicasting, where a "host" is any + internet host or gateway other than those acting as multicast + routers. The algorithms and protocols used within and between + multicast routers are transparent to hosts and will be specified in + separate documents. This memo also does not specify how local + network multicasting is accomplished for all types of network, + although it does specify the required service interface to an + arbitrary local network and gives an Ethernet specification as an + example. Specifications for other types of network will be the + subject of future memos. + +3. LEVELS OF CONFORMANCE + + There are three levels of conformance to this specification: + + Level 0: no support for IP multicasting. + + There is, at this time, no requirement that all IP implementations + support IP multicasting. Level 0 hosts will, in general, be + unaffected by multicast activity. The only exception arises on some + types of local network, where the presence of level 1 or 2 hosts may + cause misdelivery of multicast IP datagrams to level 0 hosts. Such + datagrams can easily be identified by the presence of a class D IP + address in their destination address field; they should be quietly + discarded by hosts that do not support IP multicasting. Class D + addresses are described in section 4 of this memo. + + Level 1: support for sending but not receiving multicast IP + datagrams. + + Level 1 allows a host to partake of some multicast-based services, + such as resource location or status reporting, but it does not allow + a host to join any host groups. An IP implementation may be upgraded + from level 0 to level 1 very easily and with little new code. Only + sections 4, 5, and 6 of this memo are applicable to level 1 + implementations. + + Level 2: full support for IP multicasting. + + Level 2 allows a host to join and leave host groups, as well as send + IP datagrams to host groups. It requires implementation of the + Internet Group Management Protocol (IGMP) and extension of the IP and + local network service interfaces within the host. All of the + following sections of this memo are applicable to level 2 + implementations. + + + +Deering [Page 2] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +4. HOST GROUP ADDRESSES + + Host groups are identified by class D IP addresses, i.e., those with + "1110" as their high-order four bits. Class E IP addresses, i.e., + those with "1111" as their high-order four bits, are reserved for + future addressing modes. + + In Internet standard "dotted decimal" notation, host group addresses + range from 224.0.0.0 to 239.255.255.255. The address 224.0.0.0 is + guaranteed not to be assigned to any group, and 224.0.0.1 is assigned + to the permanent group of all IP hosts (including gateways). This is + used to address all multicast hosts on the directly connected + network. There is no multicast address (or any other IP address) for + all hosts on the total Internet. The addresses of other well-known, + permanent groups are to be published in "Assigned Numbers". + + Appendix II contains some background discussion of several issues + related to host group addresses. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deering [Page 3] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +5. MODEL OF A HOST IP IMPLEMENTATION + + The multicast extensions to a host IP implementation are specified in + terms of the layered model illustrated below. In this model, ICMP + and (for level 2 hosts) IGMP are considered to be implemented within + the IP module, and the mapping of IP addresses to local network + addresses is considered to be the responsibility of local network + modules. This model is for expository purposes only, and should not + be construed as constraining an actual implementation. + + | | + | Upper-Layer Protocol Modules | + |__________________________________________________________| + + --------------------- IP Service Interface ----------------------- + __________________________________________________________ + | | | | + | | ICMP | IGMP | + | IP |______________|______________| + | Module | + | | + |__________________________________________________________| + + ---------------- Local Network Service Interface ----------------- + __________________________________________________________ + | | | + | Local | IP-to-local address mapping | + | Network | (e.g., ARP) | + | Modules |_____________________________| + | (e.g., Ethernet) | + | | + + To provide level 1 multicasting, a host IP implementation must + support the transmission of multicast IP datagrams. To provide level + 2 multicasting, a host must also support the reception of multicast + IP datagrams. Each of these two new services is described in a + separate section, below. For each service, extensions are specified + for the IP service interface, the IP module, the local network + service interface, and an Ethernet local network module. Extensions + to local network modules other than Ethernet are mentioned briefly, + but are not specified in detail. + + + + + + + + + + +Deering [Page 4] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +6. SENDING MULTICAST IP DATAGRAMS + +6.1. Extensions to the IP Service Interface + + Multicast IP datagrams are sent using the same "Send IP" operation + used to send unicast IP datagrams; an upper-layer protocol module + merely specifies an IP host group address, rather than an individual + IP address, as the destination. However, a number of extensions may + be necessary or desirable. + + First, the service interface should provide a way for the upper-layer + protocol to specify the IP time-to-live of an outgoing multicast + datagram, if such a capability does not already exist. If the + upper-layer protocol chooses not to specify a time-to-live, it should + default to 1 for all multicast IP datagrams, so that an explicit + choice is required to multicast beyond a single network. + + Second, for hosts that may be attached to more than one network, the + service interface should provide a way for the upper-layer protocol + to identify which network interface is be used for the multicast + transmission. Only one interface is used for the initial + transmission; multicast routers are responsible for forwarding to any + other networks, if necessary. If the upper-layer protocol chooses + not to identify an outgoing interface, a default interface should be + used, preferably under the control of system management. + + Third (level 2 implementations only), for the case in which the host + is itself a member of a group to which a datagram is being sent, the + service interface should provide a way for the upper-layer protocol + to inhibit local delivery of the datagram; by default, a copy of the + datagram is looped back. This is a performance optimization for + upper-layer protocols that restrict the membership of a group to one + process per host (such as a routing protocol), or that handle + loopback of group communication at a higher layer (such as a + multicast transport protocol). + +6.2. Extensions to the IP Module + + To support the sending of multicast IP datagrams, the IP module must + be extended to recognize IP host group addresses when routing + outgoing datagrams. Most IP implementations include the following + logic: + + if IP-destination is on the same local network, + send datagram locally to IP-destination + else + send datagram locally to GatewayTo( IP-destination ) + + + + +Deering [Page 5] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + To allow multicast transmissions, the routing logic must be changed + to: + + if IP-destination is on the same local network + or IP-destination is a host group, + send datagram locally to IP-destination + else + send datagram locally to GatewayTo( IP-destination ) + + + If the sending host is itself a member of the destination group on + the outgoing interface, a copy of the outgoing datagram must be + looped-back for local delivery, unless inhibited by the sender. + (Level 2 implementations only.) + + The IP source address of the outgoing datagram must be one of the + individual addresses corresponding to the outgoing interface. + + A host group address must never be placed in the source address field + or anywhere in a source route or record route option of an outgoing + IP datagram. + +6.3. Extensions to the Local Network Service Interface + + No change to the local network service interface is required to + support the sending of multicast IP datagrams. The IP module merely + specifies an IP host group destination, rather than an individual IP + destination, when it invokes the existing "Send Local" operation. + +6.4. Extensions to an Ethernet Local Network Module + + The Ethernet directly supports the sending of local multicast packets + by allowing multicast addresses in the destination field of Ethernet + packets. All that is needed to support the sending of multicast IP + datagrams is a procedure for mapping IP host group addresses to + Ethernet multicast addresses. + + An IP host group address is mapped to an Ethernet multicast address + by placing the low-order 23-bits of the IP address into the low-order + 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex). + Because there are 28 significant bits in an IP host group address, + more than one host group address may map to the same Ethernet + multicast address. + +6.5. Extensions to Local Network Modules other than Ethernet + + Other networks that directly support multicasting, such as rings or + buses conforming to the IEEE 802.2 standard, may be handled the same + + + +Deering [Page 6] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + way as Ethernet for the purpose of sending multicast IP datagrams. + For a network that supports broadcast but not multicast, such as the + Experimental Ethernet, all IP host group addresses may be mapped to a + single local broadcast address (at the cost of increased overhead on + all local hosts). For a point-to-point link joining two hosts (or a + host and a multicast router), multicasts should be transmitted + exactly like unicasts. For a store-and-forward network like the + ARPANET or a public X.25 network, all IP host group addresses might + be mapped to the well-known local address of an IP multicast router; + a router on such a network would take responsibility for completing + multicast delivery within the network as well as among networks. + +7. RECEIVING MULTICAST IP DATAGRAMS + +7.1. Extensions to the IP Service Interface + + Incoming multicast IP datagrams are received by upper-layer protocol + modules using the same "Receive IP" operation as normal, unicast + datagrams. Selection of a destination upper-layer protocol is based + on the protocol field in the IP header, regardless of the destination + IP address. However, before any datagrams destined to a particular + group can be received, an upper-layer protocol must ask the IP module + to join that group. Thus, the IP service interface must be extended + to provide two new operations: + + JoinHostGroup ( group-address, interface ) + + LeaveHostGroup ( group-address, interface ) + + The JoinHostGroup operation requests that this host become a member + of the host group identified by "group-address" on the given network + interface. The LeaveGroup operation requests that this host give up + its membership in the host group identified by "group-address" on the + given network interface. The interface argument may be omitted on + hosts that support only one interface. For hosts that may be + attached to more than one network, the upper-layer protocol may + choose to leave the interface unspecified, in which case the request + will apply to the default interface for sending multicast datagrams + (see section 6.1). + + It is permissible to join the same group on more than one interface, + in which case duplicate multicast datagrams may be received. It is + also permissible for more than one upper-layer protocol to request + membership in the same group. + + Both operations should return immediately (i.e., they are non- + blocking operations), indicating success or failure. Either + operation may fail due to an invalid group address or interface + + + +Deering [Page 7] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + identifier. JoinHostGroup may fail due to lack of local resources. + LeaveHostGroup may fail because the host does not belong to the given + group on the given interface. LeaveHostGroup may succeed, but the + membership persist, if more than one upper-layer protocol has + requested membership in the same group. + +7.2. Extensions to the IP Module + + To support the reception of multicast IP datagrams, the IP module + must be extended to maintain a list of host group memberships + associated with each network interface. An incoming datagram + destined to one of those groups is processed exactly the same way as + datagrams destined to one of the host's individual addresses. + + Incoming datagrams destined to groups to which the host does not + belong are discarded without generating any error report or log + entry. On hosts with more than one network interface, if a datagram + arrives via one interface, destined for a group to which the host + belongs only on a different interface, the datagram is quietly + discarded. (These cases should occur only as a result of inadequate + multicast address filtering in a local network module.) + + An incoming datagram is not rejected for having an IP time-to-live of + 1 (i.e., the time-to-live should not automatically be decremented on + arriving datagrams that are not being forwarded). An incoming + datagram with an IP host group address in its source address field is + quietly discarded. An ICMP error message (Destination Unreachable, + Time Exceeded, Parameter Problem, Source Quench, or Redirect) is + never generated in response to a datagram destined to an IP host + group. + + The list of host group memberships is updated in response to + JoinHostGroup and LeaveHostGroup requests from upper-layer protocols. + Each membership should have an associated reference count or similar + mechanism to handle multiple requests to join and leave the same + group. On the first request to join and the last request to leave a + group on a given interface, the local network module for that + interface is notified, so that it may update its multicast reception + filter (see section 7.3). + + The IP module must also be extended to implement the IGMP protocol, + specified in Appendix I. IGMP is used to keep neighboring multicast + routers informed of the host group memberships present on a + particular local network. To support IGMP, every level 2 host must + join the "all-hosts" group (address 224.0.0.1) on each network + interface at initialization time and must remain a member for as long + as the host is active. + + + + +Deering [Page 8] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + (Datagrams addressed to the all-hosts group are recognized as a + special case by the multicast routers and are never forwarded beyond + a single network, regardless of their time-to-live. Thus, the all- + hosts address may not be used as an internet-wide broadcast address. + For the purpose of IGMP, membership in the all-hosts group is really + necessary only while the host belongs to at least one other group. + However, it is specified that the host shall remain a member of the + all-hosts group at all times because (1) it is simpler, (2) the + frequency of reception of unnecessary IGMP queries should be low + enough that overhead is negligible, and (3) the all-hosts address may + serve other routing-oriented purposes, such as advertising the + presence of gateways or resolving local addresses.) + +7.3. Extensions to the Local Network Service Interface + + Incoming local network multicast packets are delivered to the IP + module using the same "Receive Local" operation as local network + unicast packets. To allow the IP module to tell the local network + module which multicast packets to accept, the local network service + interface is extended to provide two new operations: + + JoinLocalGroup ( group-address ) + + LeaveLocalGroup ( group-address ) + + where "group-address" is an IP host group address. The + JoinLocalGroup operation requests the local network module to accept + and deliver up subsequently arriving packets destined to the given IP + host group address. The LeaveLocalGroup operation requests the local + network module to stop delivering up packets destined to the given IP + host group address. The local network module is expected to map the + IP host group addresses to local network addresses as required to + update its multicast reception filter. Any local network module is + free to ignore LeaveLocalGroup requests, and may deliver up packets + destined to more addresses than just those specified in + JoinLocalGroup requests, if it is unable to filter incoming packets + adequately. + + The local network module must not deliver up any multicast packets + that were transmitted from that module; loopback of multicasts is + handled at the IP layer or higher. + +7.4. Extensions to an Ethernet Local Network Module + + To support the reception of multicast IP datagrams, an Ethernet + module must be able to receive packets addressed to the Ethernet + multicast addresses that correspond to the host's IP host group + addresses. It is highly desirable to take advantage of any address + + + +Deering [Page 9] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + filtering capabilities that the Ethernet hardware interface may have, + so that the host receives only those packets that are destined to it. + + Unfortunately, many current Ethernet interfaces have a small limit on + the number of addresses that the hardware can be configured to + recognize. Nevertheless, an implementation must be capable of + listening on an arbitrary number of Ethernet multicast addresses, + which may mean "opening up" the address filter to accept all + multicast packets during those periods when the number of addresses + exceeds the limit of the filter. + + For interfaces with inadequate hardware address filtering, it may be + desirable (for performance reasons) to perform Ethernet address + filtering within the software of the Ethernet module. This is not + mandatory, however, because the IP module performs its own filtering + based on IP destination addresses. + +7.5. Extensions to Local Network Modules other than Ethernet + + Other multicast networks, such as IEEE 802.2 networks, can be handled + the same way as Ethernet for the purpose of receiving multicast IP + datagrams. For pure broadcast networks, such as the Experimental + Ethernet, all incoming broadcast packets can be accepted and passed + to the IP module for IP-level filtering. On point-to-point or + store-and-forward networks, multicast IP datagrams will arrive as + local network unicasts, so no change to the local network module + should be necessary. + + + + + + + + + + + + + + + + + + + + + + + + +Deering [Page 10] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +APPENDIX I. INTERNET GROUP MANAGEMENT PROTOCOL (IGMP) + + The Internet Group Management Protocol (IGMP) is used by IP hosts to + report their host group memberships to any immediately-neighboring + multicast routers. IGMP is an asymmetric protocol and is specified + here from the point of view of a host, rather than a multicast + router. (IGMP may also be used, symmetrically or asymmetrically, + between multicast routers. Such use is not specified here.) + + Like ICMP, IGMP is a integral part of IP. It is required to be + implemented by all hosts conforming to level 2 of the IP multicasting + specification. IGMP messages are encapsulated in IP datagrams, with + an IP protocol number of 2. All IGMP messages of concern to hosts + have the following format: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |Version| Type | Unused | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Group Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Version + + This memo specifies version 1 of IGMP. Version 0 is specified + in RFC-988 and is now obsolete. + + Type + + There are two types of IGMP message of concern to hosts: + + 1 = Host Membership Query + 2 = Host Membership Report + + Unused + + Unused field, zeroed when sent, ignored when received. + + Checksum + + The checksum is the 16-bit one's complement of the one's + complement sum of the 8-octet IGMP message. For computing + the checksum, the checksum field is zeroed. + + Group Address + + In a Host Membership Query message, the group address field + + + +Deering [Page 11] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + is zeroed when sent, ignored when received. + + In a Host Membership Report message, the group address field + holds the IP host group address of the group being reported. + +Informal Protocol Description + + Multicast routers send Host Membership Query messages (hereinafter + called Queries) to discover which host groups have members on their + attached local networks. Queries are addressed to the all-hosts + group (address 224.0.0.1), and carry an IP time-to-live of 1. + + Hosts respond to a Query by generating Host Membership Reports + (hereinafter called Reports), reporting each host group to which they + belong on the network interface from which the Query was received. + In order to avoid an "implosion" of concurrent Reports and to reduce + the total number of Reports transmitted, two techniques are used: + + 1. When a host receives a Query, rather than sending Reports + immediately, it starts a report delay timer for each of its + group memberships on the network interface of the incoming + Query. Each timer is set to a different, randomly-chosen + value between zero and D seconds. When a timer expires, a + Report is generated for the corresponding host group. Thus, + Reports are spread out over a D second interval instead of + all occurring at once. + + 2. A Report is sent with an IP destination address equal to the + host group address being reported, and with an IP + time-to-live of 1, so that other members of the same group on + the same network can overhear the Report. If a host hears a + Report for a group to which it belongs on that network, the + host stops its own timer for that group and does not generate + a Report for that group. Thus, in the normal case, only one + Report will be generated for each group present on the + network, by the member host whose delay timer expires first. + Note that the multicast routers receive all IP multicast + datagrams, and therefore need not be addressed explicitly. + Further note that the routers need not know which hosts + belong to a group, only that at least one host belongs to a + group on a particular network. + + There are two exceptions to the behavior described above. First, if + a report delay timer is already running for a group membership when a + Query is received, that timer is not reset to a new random value, but + rather allowed to continue running with its current value. Second, a + report delay timer is never set for a host's membership in the all- + hosts group (224.0.0.1), and that membership is never reported. + + + +Deering [Page 12] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + If a host uses a pseudo-random number generator to compute the + reporting delays, one of the host's own individual IP address should + be used as part of the seed for the generator, to reduce the chance + of multiple hosts generating the same sequence of delays. + + A host should confirm that a received Report has the same IP host + group address in its IP destination field and its IGMP group address + field, to ensure that the host's own Report is not cancelled by an + erroneous received Report. A host should quietly discard any IGMP + message of type other than Host Membership Query or Host Membership + Report. + + Multicast routers send Queries periodically to refresh their + knowledge of memberships present on a particular network. If no + Reports are received for a particular group after some number of + Queries, the routers assume that that group has no local members and + that they need not forward remotely-originated multicasts for that + group onto the local network. Queries are normally sent infrequently + (no more than once a minute) so as to keep the IGMP overhead on hosts + and networks very low. However, when a multicast router starts up, + it may issue several closely-spaced Queries in order to build up its + knowledge of local memberships quickly. + + When a host joins a new group, it should immediately transmit a + Report for that group, rather than waiting for a Query, in case it is + the first member of that group on the network. To cover the + possibility of the initial Report being lost or damaged, it is + recommended that it be repeated once or twice after short delays. (A + simple way to accomplish this is to act as if a Query had been + received for that group only, setting the group's random report delay + timer. The state transition diagram below illustrates this + approach.) + + Note that, on a network with no multicast routers present, the only + IGMP traffic is the one or more Reports sent whenever a host joins a + new group. + +State Transition Diagram + + IGMP behavior is more formally specified by the state transition + diagram below. A host may be in one of three possible states, with + respect to any single IP host group on any single network interface: + + - Non-Member state, when the host does not belong to the group + on the interface. This is the initial state for all + memberships on all network interfaces; it requires no storage + in the host. + + + + +Deering [Page 13] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + - Delaying Member state, when the host belongs to the group on + the interface and has a report delay timer running for that + membership. + + - Idle Member state, when the host belongs to the group on the + interface and does not have a report delay timer running for + that membership. + + There are five significant events that can cause IGMP state + transitions: + + - "join group" occurs when the host decides to join the group on + the interface. It may occur only in the Non-Member state. + + - "leave group" occurs when the host decides to leave the group + on the interface. It may occur only in the Delaying Member + and Idle Member states. + + - "query received" occurs when the host receives a valid IGMP + Host Membership Query message. To be valid, the Query message + must be at least 8 octets long, have a correct IGMP + checksum and have an IP destination address of 224.0.0.1. + A single Query applies to all memberships on the + interface from which the Query is received. It is ignored for + memberships in the Non-Member or Delaying Member state. + + - "report received" occurs when the host receives a valid IGMP + Host Membership Report message. To be valid, the Report + message must be at least 8 octets long, have a correct IGMP + checksum, and contain the same IP host group address in its IP + destination field and its IGMP group address field. A Report + applies only to the membership in the group identified by the + Report, on the interface from which the Report is received. + It is ignored for memberships in the Non-Member or Idle Member + state. + + - "timer expired" occurs when the report delay timer for the + group on the interface expires. It may occur only in the + Delaying Member state. + + All other events, such as receiving invalid IGMP messages, or IGMP + messages other than Query or Report, are ignored in all states. + + There are three possible actions that may be taken in response to the + above events: + + - "send report" for the group on the interface. + + + + +Deering [Page 14] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + + - "start timer" for the group on the interface, using a random + delay value between 0 and D seconds. + + - "stop timer" for the group on the interface. + + In the following diagram, each state transition arc is labelled with + the event that causes the transition, and, in parentheses, any + actions taken during the transition. + + ________________ + | | + | | + | | + | | + --------->| Non-Member |<--------- + | | | | + | | | | + | | | | + | |________________| | + | | | + | leave group | join group | leave group + | (stop timer) |(send report, | + | | start timer) | + ________|________ | ________|________ + | |<--------- | | + | | | | + | |<-------------------| | + | | query received | | + | Delaying Member | (start timer) | Idle Member | + | |------------------->| | + | | report received | | + | | (stop timer) | | + |_________________|------------------->|_________________| + timer expired + (send report) + + The all-hosts group (address 224.0.0.1) is handled as a special case. + The host starts in Idle Member state for that group on every + interface, never transitions to another state, and never sends a + report for that group. + +Protocol Parameters + + The maximum report delay, D, is 10 seconds. + + + + + + + +Deering [Page 15] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +APPENDIX II. HOST GROUP ADDRESS ISSUES + + This appendix is not part of the IP multicasting specification, but + provides background discussion of several issues related to IP host + group addresses. + +Group Address Binding + + The binding of IP host group addresses to physical hosts may be + considered a generalization of the binding of IP unicast addresses. + An IP unicast address is statically bound to a single local network + interface on a single IP network. An IP host group address is + dynamically bound to a set of local network interfaces on a set of IP + networks. + + It is important to understand that an IP host group address is NOT + bound to a set of IP unicast addresses. The multicast routers do not + need to maintain a list of individual members of each host group. + For example, a multicast router attached to an Ethernet need + associate only a single Ethernet multicast address with each host + group having local members, rather than a list of the members' + individual IP or Ethernet addresses. + +Allocation of Transient Host Group Addresses + + This memo does not specify how transient group address are allocated. + It is anticipated that different portions of the IP transient host + group address space will be allocated using different techniques. + For example, there may be a number of servers that can be contacted + to acquire a new transient group address. Some higher-level + protocols (such as VMTP, specified in RFC-1045) may generate higher- + level transient "process group" or "entity group" addresses which are + then algorithmically mapped to a subset of the IP transient host + group addresses, similarly to the way that IP host group addresses + are mapped to Ethernet multicast addresses. A portion of the IP + group address space may be set aside for random allocation by + applications that can tolerate occasional collisions with other + multicast users, perhaps generating new addresses until a suitably + "quiet" one is found. + + In general, a host cannot assume that datagrams sent to any host + group address will reach only the intended hosts, or that datagrams + received as a member of a transient host group are intended for the + recipient. Misdelivery must be detected at a level above IP, using + higher-level identifiers or authentication tokens. Information + transmitted to a host group address should be encrypted or governed + by administrative routing controls if the sender is concerned about + unwanted listeners. + + + +Deering [Page 16] + +RFC 1112 Host Extensions for IP Multicasting August 1989 + + +Author's Address + + Steve Deering + Stanford University + Computer Science Department + Stanford, CA 94305-2140 + + Phone: (415) 723-9427 + + EMail: deering@PESCADERO.STANFORD.EDU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deering [Page 17] + + diff --git a/doc/rfc/std7.txt b/doc/rfc/std7.txt new file mode 100644 index 00000000..a7c36a14 --- /dev/null +++ b/doc/rfc/std7.txt @@ -0,0 +1,5248 @@ + +RFC: 793 + + + + + + + + TRANSMISSION CONTROL PROTOCOL + + + DARPA INTERNET PROGRAM + + PROTOCOL SPECIFICATION + + + + September 1981 + + + + + + + + + + + + + + prepared for + + Defense Advanced Research Projects Agency + Information Processing Techniques Office + 1400 Wilson Boulevard + Arlington, Virginia 22209 + + + + + + + + by + + Information Sciences Institute + University of Southern California + 4676 Admiralty Way + Marina del Rey, California 90291 + + + +September 1981 + Transmission Control Protocol + + + + TABLE OF CONTENTS + + PREFACE ........................................................ iii + +1. INTRODUCTION ..................................................... 1 + + 1.1 Motivation .................................................... 1 + 1.2 Scope ......................................................... 2 + 1.3 About This Document ........................................... 2 + 1.4 Interfaces .................................................... 3 + 1.5 Operation ..................................................... 3 + +2. PHILOSOPHY ....................................................... 7 + + 2.1 Elements of the Internetwork System ........................... 7 + 2.2 Model of Operation ............................................ 7 + 2.3 The Host Environment .......................................... 8 + 2.4 Interfaces .................................................... 9 + 2.5 Relation to Other Protocols ................................... 9 + 2.6 Reliable Communication ........................................ 9 + 2.7 Connection Establishment and Clearing ........................ 10 + 2.8 Data Communication ........................................... 12 + 2.9 Precedence and Security ...................................... 13 + 2.10 Robustness Principle ......................................... 13 + +3. FUNCTIONAL SPECIFICATION ........................................ 15 + + 3.1 Header Format ................................................ 15 + 3.2 Terminology .................................................. 19 + 3.3 Sequence Numbers ............................................. 24 + 3.4 Establishing a connection .................................... 30 + 3.5 Closing a Connection ......................................... 37 + 3.6 Precedence and Security ...................................... 40 + 3.7 Data Communication ........................................... 40 + 3.8 Interfaces ................................................... 44 + 3.9 Event Processing ............................................. 52 + +GLOSSARY ............................................................ 79 + +REFERENCES .......................................................... 85 + + + + + + + + + + + + [Page i] + + + September 1981 +Transmission Control Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page ii] + + +September 1981 + Transmission Control Protocol + + + + PREFACE + + + +This document describes the DoD Standard Transmission Control Protocol +(TCP). There have been nine earlier editions of the ARPA TCP +specification on which this standard is based, and the present text +draws heavily from them. There have been many contributors to this work +both in terms of concepts and in terms of text. This edition clarifies +several details and removes the end-of-letter buffer-size adjustments, +and redescribes the letter mechanism as a push function. + + Jon Postel + + Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page iii] + + + + +RFC: 793 +Replaces: RFC 761 +IENs: 129, 124, 112, 81, +55, 44, 40, 27, 21, 5 + + TRANSMISSION CONTROL PROTOCOL + + DARPA INTERNET PROGRAM + PROTOCOL SPECIFICATION + + + + 1. INTRODUCTION + +The Transmission Control Protocol (TCP) is intended for use as a highly +reliable host-to-host protocol between hosts in packet-switched computer +communication networks, and in interconnected systems of such networks. + +This document describes the functions to be performed by the +Transmission Control Protocol, the program that implements it, and its +interface to programs or users that require its services. + +1.1. Motivation + + Computer communication systems are playing an increasingly important + role in military, government, and civilian environments. This + document focuses its attention primarily on military computer + communication requirements, especially robustness in the presence of + communication unreliability and availability in the presence of + congestion, but many of these problems are found in the civilian and + government sector as well. + + As strategic and tactical computer communication networks are + developed and deployed, it is essential to provide means of + interconnecting them and to provide standard interprocess + communication protocols which can support a broad range of + applications. In anticipation of the need for such standards, the + Deputy Undersecretary of Defense for Research and Engineering has + declared the Transmission Control Protocol (TCP) described herein to + be a basis for DoD-wide inter-process communication protocol + standardization. + + TCP is a connection-oriented, end-to-end reliable protocol designed to + fit into a layered hierarchy of protocols which support multi-network + applications. The TCP provides for reliable inter-process + communication between pairs of processes in host computers attached to + distinct but interconnected computer communication networks. Very few + assumptions are made as to the reliability of the communication + protocols below the TCP layer. TCP assumes it can obtain a simple, + potentially unreliable datagram service from the lower level + protocols. In principle, the TCP should be able to operate above a + wide spectrum of communication systems ranging from hard-wired + connections to packet-switched or circuit-switched networks. + + + [Page 1] + + + September 1981 +Transmission Control Protocol +Introduction + + + + TCP is based on concepts first described by Cerf and Kahn in [1]. The + TCP fits into a layered protocol architecture just above a basic + Internet Protocol [2] which provides a way for the TCP to send and + receive variable-length segments of information enclosed in internet + datagram "envelopes". The internet datagram provides a means for + addressing source and destination TCPs in different networks. The + internet protocol also deals with any fragmentation or reassembly of + the TCP segments required to achieve transport and delivery through + multiple networks and interconnecting gateways. The internet protocol + also carries information on the precedence, security classification + and compartmentation of the TCP segments, so this information can be + communicated end-to-end across multiple networks. + + Protocol Layering + + +---------------------+ + | higher-level | + +---------------------+ + | TCP | + +---------------------+ + | internet protocol | + +---------------------+ + |communication network| + +---------------------+ + + Figure 1 + + Much of this document is written in the context of TCP implementations + which are co-resident with higher level protocols in the host + computer. Some computer systems will be connected to networks via + front-end computers which house the TCP and internet protocol layers, + as well as network specific software. The TCP specification describes + an interface to the higher level protocols which appears to be + implementable even for the front-end case, as long as a suitable + host-to-front end protocol is implemented. + +1.2. Scope + + The TCP is intended to provide a reliable process-to-process + communication service in a multinetwork environment. The TCP is + intended to be a host-to-host protocol in common use in multiple + networks. + +1.3. About this Document + + This document represents a specification of the behavior required of + any TCP implementation, both in its interactions with higher level + protocols and in its interactions with other TCPs. The rest of this + + +[Page 2] + + +September 1981 + Transmission Control Protocol + Introduction + + + + section offers a very brief view of the protocol interfaces and + operation. Section 2 summarizes the philosophical basis for the TCP + design. Section 3 offers both a detailed description of the actions + required of TCP when various events occur (arrival of new segments, + user calls, errors, etc.) and the details of the formats of TCP + segments. + +1.4. Interfaces + + The TCP interfaces on one side to user or application processes and on + the other side to a lower level protocol such as Internet Protocol. + + The interface between an application process and the TCP is + illustrated in reasonable detail. This interface consists of a set of + calls much like the calls an operating system provides to an + application process for manipulating files. For example, there are + calls to open and close connections and to send and receive data on + established connections. It is also expected that the TCP can + asynchronously communicate with application programs. Although + considerable freedom is permitted to TCP implementors to design + interfaces which are appropriate to a particular operating system + environment, a minimum functionality is required at the TCP/user + interface for any valid implementation. + + The interface between TCP and lower level protocol is essentially + unspecified except that it is assumed there is a mechanism whereby the + two levels can asynchronously pass information to each other. + Typically, one expects the lower level protocol to specify this + interface. TCP is designed to work in a very general environment of + interconnected networks. The lower level protocol which is assumed + throughout this document is the Internet Protocol [2]. + +1.5. Operation + + As noted above, the primary purpose of the TCP is to provide reliable, + securable logical circuit or connection service between pairs of + processes. To provide this service on top of a less reliable internet + communication system requires facilities in the following areas: + + Basic Data Transfer + Reliability + Flow Control + Multiplexing + Connections + Precedence and Security + + The basic operation of the TCP in each of these areas is described in + the following paragraphs. + + + [Page 3] + + + September 1981 +Transmission Control Protocol +Introduction + + + + Basic Data Transfer: + + The TCP is able to transfer a continuous stream of octets in each + direction between its users by packaging some number of octets into + segments for transmission through the internet system. In general, + the TCPs decide when to block and forward data at their own + convenience. + + Sometimes users need to be sure that all the data they have + submitted to the TCP has been transmitted. For this purpose a push + function is defined. To assure that data submitted to a TCP is + actually transmitted the sending user indicates that it should be + pushed through to the receiving user. A push causes the TCPs to + promptly forward and deliver data up to that point to the receiver. + The exact push point might not be visible to the receiving user and + the push function does not supply a record boundary marker. + + Reliability: + + The TCP must recover from data that is damaged, lost, duplicated, or + delivered out of order by the internet communication system. This + is achieved by assigning a sequence number to each octet + transmitted, and requiring a positive acknowledgment (ACK) from the + receiving TCP. If the ACK is not received within a timeout + interval, the data is retransmitted. At the receiver, the sequence + numbers are used to correctly order segments that may be received + out of order and to eliminate duplicates. Damage is handled by + adding a checksum to each segment transmitted, checking it at the + receiver, and discarding damaged segments. + + As long as the TCPs continue to function properly and the internet + system does not become completely partitioned, no transmission + errors will affect the correct delivery of data. TCP recovers from + internet communication system errors. + + Flow Control: + + TCP provides a means for the receiver to govern the amount of data + sent by the sender. This is achieved by returning a "window" with + every ACK indicating a range of acceptable sequence numbers beyond + the last segment successfully received. The window indicates an + allowed number of octets that the sender may transmit before + receiving further permission. + + + + + + + +[Page 4] + + +September 1981 + Transmission Control Protocol + Introduction + + + + Multiplexing: + + To allow for many processes within a single Host to use TCP + communication facilities simultaneously, the TCP provides a set of + addresses or ports within each host. Concatenated with the network + and host addresses from the internet communication layer, this forms + a socket. A pair of sockets uniquely identifies each connection. + That is, a socket may be simultaneously used in multiple + connections. + + The binding of ports to processes is handled independently by each + Host. However, it proves useful to attach frequently used processes + (e.g., a "logger" or timesharing service) to fixed sockets which are + made known to the public. These services can then be accessed + through the known addresses. Establishing and learning the port + addresses of other processes may involve more dynamic mechanisms. + + Connections: + + The reliability and flow control mechanisms described above require + that TCPs initialize and maintain certain status information for + each data stream. The combination of this information, including + sockets, sequence numbers, and window sizes, is called a connection. + Each connection is uniquely specified by a pair of sockets + identifying its two sides. + + When two processes wish to communicate, their TCP's must first + establish a connection (initialize the status information on each + side). When their communication is complete, the connection is + terminated or closed to free the resources for other uses. + + Since connections must be established between unreliable hosts and + over the unreliable internet communication system, a handshake + mechanism with clock-based sequence numbers is used to avoid + erroneous initialization of connections. + + Precedence and Security: + + The users of TCP may indicate the security and precedence of their + communication. Provision is made for default values to be used when + these features are not needed. + + + + + + + + + + [Page 5] + + + September 1981 +Transmission Control Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 6] + + +September 1981 + Transmission Control Protocol + + + + 2. PHILOSOPHY + +2.1. Elements of the Internetwork System + + The internetwork environment consists of hosts connected to networks + which are in turn interconnected via gateways. It is assumed here + that the networks may be either local networks (e.g., the ETHERNET) or + large networks (e.g., the ARPANET), but in any case are based on + packet switching technology. The active agents that produce and + consume messages are processes. Various levels of protocols in the + networks, the gateways, and the hosts support an interprocess + communication system that provides two-way data flow on logical + connections between process ports. + + The term packet is used generically here to mean the data of one + transaction between a host and its network. The format of data blocks + exchanged within the a network will generally not be of concern to us. + + Hosts are computers attached to a network, and from the communication + network's point of view, are the sources and destinations of packets. + Processes are viewed as the active elements in host computers (in + accordance with the fairly common definition of a process as a program + in execution). Even terminals and files or other I/O devices are + viewed as communicating with each other through the use of processes. + Thus, all communication is viewed as inter-process communication. + + Since a process may need to distinguish among several communication + streams between itself and another process (or processes), we imagine + that each process may have a number of ports through which it + communicates with the ports of other processes. + +2.2. Model of Operation + + Processes transmit data by calling on the TCP and passing buffers of + data as arguments. The TCP packages the data from these buffers into + segments and calls on the internet module to transmit each segment to + the destination TCP. The receiving TCP places the data from a segment + into the receiving user's buffer and notifies the receiving user. The + TCPs include control information in the segments which they use to + ensure reliable ordered data transmission. + + The model of internet communication is that there is an internet + protocol module associated with each TCP which provides an interface + to the local network. This internet module packages TCP segments + inside internet datagrams and routes these datagrams to a destination + internet module or intermediate gateway. To transmit the datagram + through the local network, it is embedded in a local network packet. + + The packet switches may perform further packaging, fragmentation, or + + + [Page 7] + + + September 1981 +Transmission Control Protocol +Philosophy + + + + other operations to achieve the delivery of the local packet to the + destination internet module. + + At a gateway between networks, the internet datagram is "unwrapped" + from its local packet and examined to determine through which network + the internet datagram should travel next. The internet datagram is + then "wrapped" in a local packet suitable to the next network and + routed to the next gateway, or to the final destination. + + A gateway is permitted to break up an internet datagram into smaller + internet datagram fragments if this is necessary for transmission + through the next network. To do this, the gateway produces a set of + internet datagrams; each carrying a fragment. Fragments may be + further broken into smaller fragments at subsequent gateways. The + internet datagram fragment format is designed so that the destination + internet module can reassemble fragments into internet datagrams. + + A destination internet module unwraps the segment from the datagram + (after reassembling the datagram, if necessary) and passes it to the + destination TCP. + + This simple model of the operation glosses over many details. One + important feature is the type of service. This provides information + to the gateway (or internet module) to guide it in selecting the + service parameters to be used in traversing the next network. + Included in the type of service information is the precedence of the + datagram. Datagrams may also carry security information to permit + host and gateways that operate in multilevel secure environments to + properly segregate datagrams for security considerations. + +2.3. The Host Environment + + The TCP is assumed to be a module in an operating system. The users + access the TCP much like they would access the file system. The TCP + may call on other operating system functions, for example, to manage + data structures. The actual interface to the network is assumed to be + controlled by a device driver module. The TCP does not call on the + network device driver directly, but rather calls on the internet + datagram protocol module which may in turn call on the device driver. + + The mechanisms of TCP do not preclude implementation of the TCP in a + front-end processor. However, in such an implementation, a + host-to-front-end protocol must provide the functionality to support + the type of TCP-user interface described in this document. + + + + + + +[Page 8] + + +September 1981 + Transmission Control Protocol + Philosophy + + + +2.4. Interfaces + + The TCP/user interface provides for calls made by the user on the TCP + to OPEN or CLOSE a connection, to SEND or RECEIVE data, or to obtain + STATUS about a connection. These calls are like other calls from user + programs on the operating system, for example, the calls to open, read + from, and close a file. + + The TCP/internet interface provides calls to send and receive + datagrams addressed to TCP modules in hosts anywhere in the internet + system. These calls have parameters for passing the address, type of + service, precedence, security, and other control information. + +2.5. Relation to Other Protocols + + The following diagram illustrates the place of the TCP in the protocol + hierarchy: + + + +------+ +-----+ +-----+ +-----+ + |Telnet| | FTP | |Voice| ... | | Application Level + +------+ +-----+ +-----+ +-----+ + | | | | + +-----+ +-----+ +-----+ + | TCP | | RTP | ... | | Host Level + +-----+ +-----+ +-----+ + | | | + +-------------------------------+ + | Internet Protocol & ICMP | Gateway Level + +-------------------------------+ + | + +---------------------------+ + | Local Network Protocol | Network Level + +---------------------------+ + + Protocol Relationships + + Figure 2. + + It is expected that the TCP will be able to support higher level + protocols efficiently. It should be easy to interface higher level + protocols like the ARPANET Telnet or AUTODIN II THP to the TCP. + +2.6. Reliable Communication + + A stream of data sent on a TCP connection is delivered reliably and in + order at the destination. + + + + [Page 9] + + + September 1981 +Transmission Control Protocol +Philosophy + + + + Transmission is made reliable via the use of sequence numbers and + acknowledgments. Conceptually, each octet of data is assigned a + sequence number. The sequence number of the first octet of data in a + segment is transmitted with that segment and is called the segment + sequence number. Segments also carry an acknowledgment number which + is the sequence number of the next expected data octet of + transmissions in the reverse direction. When the TCP transmits a + segment containing data, it puts a copy on a retransmission queue and + starts a timer; when the acknowledgment for that data is received, the + segment is deleted from the queue. If the acknowledgment is not + received before the timer runs out, the segment is retransmitted. + + An acknowledgment by TCP does not guarantee that the data has been + delivered to the end user, but only that the receiving TCP has taken + the responsibility to do so. + + To govern the flow of data between TCPs, a flow control mechanism is + employed. The receiving TCP reports a "window" to the sending TCP. + This window specifies the number of octets, starting with the + acknowledgment number, that the receiving TCP is currently prepared to + receive. + +2.7. Connection Establishment and Clearing + + To identify the separate data streams that a TCP may handle, the TCP + provides a port identifier. Since port identifiers are selected + independently by each TCP they might not be unique. To provide for + unique addresses within each TCP, we concatenate an internet address + identifying the TCP with a port identifier to create a socket which + will be unique throughout all networks connected together. + + A connection is fully specified by the pair of sockets at the ends. A + local socket may participate in many connections to different foreign + sockets. A connection can be used to carry data in both directions, + that is, it is "full duplex". + + TCPs are free to associate ports with processes however they choose. + However, several basic concepts are necessary in any implementation. + There must be well-known sockets which the TCP associates only with + the "appropriate" processes by some means. We envision that processes + may "own" ports, and that processes can initiate connections only on + the ports they own. (Means for implementing ownership is a local + issue, but we envision a Request Port user command, or a method of + uniquely allocating a group of ports to a given process, e.g., by + associating the high order bits of a port name with a given process.) + + A connection is specified in the OPEN call by the local port and + foreign socket arguments. In return, the TCP supplies a (short) local + + +[Page 10] + + +September 1981 + Transmission Control Protocol + Philosophy + + + + connection name by which the user refers to the connection in + subsequent calls. There are several things that must be remembered + about a connection. To store this information we imagine that there + is a data structure called a Transmission Control Block (TCB). One + implementation strategy would have the local connection name be a + pointer to the TCB for this connection. The OPEN call also specifies + whether the connection establishment is to be actively pursued, or to + be passively waited for. + + A passive OPEN request means that the process wants to accept incoming + connection requests rather than attempting to initiate a connection. + Often the process requesting a passive OPEN will accept a connection + request from any caller. In this case a foreign socket of all zeros + is used to denote an unspecified socket. Unspecified foreign sockets + are allowed only on passive OPENs. + + A service process that wished to provide services for unknown other + processes would issue a passive OPEN request with an unspecified + foreign socket. Then a connection could be made with any process that + requested a connection to this local socket. It would help if this + local socket were known to be associated with this service. + + Well-known sockets are a convenient mechanism for a priori associating + a socket address with a standard service. For instance, the + "Telnet-Server" process is permanently assigned to a particular + socket, and other sockets are reserved for File Transfer, Remote Job + Entry, Text Generator, Echoer, and Sink processes (the last three + being for test purposes). A socket address might be reserved for + access to a "Look-Up" service which would return the specific socket + at which a newly created service would be provided. The concept of a + well-known socket is part of the TCP specification, but the assignment + of sockets to services is outside this specification. (See [4].) + + Processes can issue passive OPENs and wait for matching active OPENs + from other processes and be informed by the TCP when connections have + been established. Two processes which issue active OPENs to each + other at the same time will be correctly connected. This flexibility + is critical for the support of distributed computing in which + components act asynchronously with respect to each other. + + There are two principal cases for matching the sockets in the local + passive OPENs and an foreign active OPENs. In the first case, the + local passive OPENs has fully specified the foreign socket. In this + case, the match must be exact. In the second case, the local passive + OPENs has left the foreign socket unspecified. In this case, any + foreign socket is acceptable as long as the local sockets match. + Other possibilities include partially restricted matches. + + + + [Page 11] + + + September 1981 +Transmission Control Protocol +Philosophy + + + + If there are several pending passive OPENs (recorded in TCBs) with the + same local socket, an foreign active OPEN will be matched to a TCB + with the specific foreign socket in the foreign active OPEN, if such a + TCB exists, before selecting a TCB with an unspecified foreign socket. + + The procedures to establish connections utilize the synchronize (SYN) + control flag and involves an exchange of three messages. This + exchange has been termed a three-way hand shake [3]. + + A connection is initiated by the rendezvous of an arriving segment + containing a SYN and a waiting TCB entry each created by a user OPEN + command. The matching of local and foreign sockets determines when a + connection has been initiated. The connection becomes "established" + when sequence numbers have been synchronized in both directions. + + The clearing of a connection also involves the exchange of segments, + in this case carrying the FIN control flag. + +2.8. Data Communication + + The data that flows on a connection may be thought of as a stream of + octets. The sending user indicates in each SEND call whether the data + in that call (and any preceeding calls) should be immediately pushed + through to the receiving user by the setting of the PUSH flag. + + A sending TCP is allowed to collect data from the sending user and to + send that data in segments at its own convenience, until the push + function is signaled, then it must send all unsent data. When a + receiving TCP sees the PUSH flag, it must not wait for more data from + the sending TCP before passing the data to the receiving process. + + There is no necessary relationship between push functions and segment + boundaries. The data in any particular segment may be the result of a + single SEND call, in whole or part, or of multiple SEND calls. + + The purpose of push function and the PUSH flag is to push data through + from the sending user to the receiving user. It does not provide a + record service. + + There is a coupling between the push function and the use of buffers + of data that cross the TCP/user interface. Each time a PUSH flag is + associated with data placed into the receiving user's buffer, the + buffer is returned to the user for processing even if the buffer is + not filled. If data arrives that fills the user's buffer before a + PUSH is seen, the data is passed to the user in buffer size units. + + TCP also provides a means to communicate to the receiver of data that + at some point further along in the data stream than the receiver is + + +[Page 12] + + +September 1981 + Transmission Control Protocol + Philosophy + + + + currently reading there is urgent data. TCP does not attempt to + define what the user specifically does upon being notified of pending + urgent data, but the general notion is that the receiving process will + take action to process the urgent data quickly. + +2.9. Precedence and Security + + The TCP makes use of the internet protocol type of service field and + security option to provide precedence and security on a per connection + basis to TCP users. Not all TCP modules will necessarily function in + a multilevel secure environment; some may be limited to unclassified + use only, and others may operate at only one security level and + compartment. Consequently, some TCP implementations and services to + users may be limited to a subset of the multilevel secure case. + + TCP modules which operate in a multilevel secure environment must + properly mark outgoing segments with the security, compartment, and + precedence. Such TCP modules must also provide to their users or + higher level protocols such as Telnet or THP an interface to allow + them to specify the desired security level, compartment, and + precedence of connections. + +2.10. Robustness Principle + + TCP implementations will follow a general principle of robustness: be + conservative in what you do, be liberal in what you accept from + others. + + + + + + + + + + + + + + + + + + + + + + + + [Page 13] + + + September 1981 +Transmission Control Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 14] + + +September 1981 + Transmission Control Protocol + + + + 3. FUNCTIONAL SPECIFICATION + +3.1. Header Format + + TCP segments are sent as internet datagrams. The Internet Protocol + header carries several information fields, including the source and + destination host addresses [2]. A TCP header follows the internet + header, supplying information specific to the TCP protocol. This + division allows for the existence of host level protocols other than + TCP. + + TCP Header Format + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Source Port | Destination Port | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Acknowledgment Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Data | |U|A|P|R|S|F| | + | Offset| Reserved |R|C|S|S|Y|I| Window | + | | |G|K|H|T|N|N| | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Checksum | Urgent Pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Options | Padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + TCP Header Format + + Note that one tick mark represents one bit position. + + Figure 3. + + Source Port: 16 bits + + The source port number. + + Destination Port: 16 bits + + The destination port number. + + + + + [Page 15] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + Sequence Number: 32 bits + + The sequence number of the first data octet in this segment (except + when SYN is present). If SYN is present the sequence number is the + initial sequence number (ISN) and the first data octet is ISN+1. + + Acknowledgment Number: 32 bits + + If the ACK control bit is set this field contains the value of the + next sequence number the sender of the segment is expecting to + receive. Once a connection is established this is always sent. + + Data Offset: 4 bits + + The number of 32 bit words in the TCP Header. This indicates where + the data begins. The TCP header (even one including options) is an + integral number of 32 bits long. + + Reserved: 6 bits + + Reserved for future use. Must be zero. + + Control Bits: 6 bits (from left to right): + + URG: Urgent Pointer field significant + ACK: Acknowledgment field significant + PSH: Push Function + RST: Reset the connection + SYN: Synchronize sequence numbers + FIN: No more data from sender + + Window: 16 bits + + The number of data octets beginning with the one indicated in the + acknowledgment field which the sender of this segment is willing to + accept. + + Checksum: 16 bits + + The checksum field is the 16 bit one's complement of the one's + complement sum of all 16 bit words in the header and text. If a + segment contains an odd number of header and text octets to be + checksummed, the last octet is padded on the right with zeros to + form a 16 bit word for checksum purposes. The pad is not + transmitted as part of the segment. While computing the checksum, + the checksum field itself is replaced with zeros. + + The checksum also covers a 96 bit pseudo header conceptually + + +[Page 16] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + prefixed to the TCP header. This pseudo header contains the Source + Address, the Destination Address, the Protocol, and TCP length. + This gives the TCP protection against misrouted segments. This + information is carried in the Internet Protocol and is transferred + across the TCP/Network interface in the arguments or results of + calls by the TCP on the IP. + + +--------+--------+--------+--------+ + | Source Address | + +--------+--------+--------+--------+ + | Destination Address | + +--------+--------+--------+--------+ + | zero | PTCL | TCP Length | + +--------+--------+--------+--------+ + + The TCP Length is the TCP header length plus the data length in + octets (this is not an explicitly transmitted quantity, but is + computed), and it does not count the 12 octets of the pseudo + header. + + Urgent Pointer: 16 bits + + This field communicates the current value of the urgent pointer as a + positive offset from the sequence number in this segment. The + urgent pointer points to the sequence number of the octet following + the urgent data. This field is only be interpreted in segments with + the URG control bit set. + + Options: variable + + Options may occupy space at the end of the TCP header and are a + multiple of 8 bits in length. All options are included in the + checksum. An option may begin on any octet boundary. There are two + cases for the format of an option: + + Case 1: A single octet of option-kind. + + Case 2: An octet of option-kind, an octet of option-length, and + the actual option-data octets. + + The option-length counts the two octets of option-kind and + option-length as well as the option-data octets. + + Note that the list of options may be shorter than the data offset + field might imply. The content of the header beyond the + End-of-Option option must be header padding (i.e., zero). + + A TCP must implement all options. + + + [Page 17] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + Currently defined options include (kind indicated in octal): + + Kind Length Meaning + ---- ------ ------- + 0 - End of option list. + 1 - No-Operation. + 2 4 Maximum Segment Size. + + + Specific Option Definitions + + End of Option List + + +--------+ + |00000000| + +--------+ + Kind=0 + + This option code indicates the end of the option list. This + might not coincide with the end of the TCP header according to + the Data Offset field. This is used at the end of all options, + not the end of each option, and need only be used if the end of + the options would not otherwise coincide with the end of the TCP + header. + + No-Operation + + +--------+ + |00000001| + +--------+ + Kind=1 + + This option code may be used between options, for example, to + align the beginning of a subsequent option on a word boundary. + There is no guarantee that senders will use this option, so + receivers must be prepared to process options even if they do + not begin on a word boundary. + + Maximum Segment Size + + +--------+--------+---------+--------+ + |00000010|00000100| max seg size | + +--------+--------+---------+--------+ + Kind=2 Length=4 + + + + + + +[Page 18] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + Maximum Segment Size Option Data: 16 bits + + If this option is present, then it communicates the maximum + receive segment size at the TCP which sends this segment. + This field must only be sent in the initial connection request + (i.e., in segments with the SYN control bit set). If this + option is not used, any segment size is allowed. + + Padding: variable + + The TCP header padding is used to ensure that the TCP header ends + and data begins on a 32 bit boundary. The padding is composed of + zeros. + +3.2. Terminology + + Before we can discuss very much about the operation of the TCP we need + to introduce some detailed terminology. The maintenance of a TCP + connection requires the remembering of several variables. We conceive + of these variables being stored in a connection record called a + Transmission Control Block or TCB. Among the variables stored in the + TCB are the local and remote socket numbers, the security and + precedence of the connection, pointers to the user's send and receive + buffers, pointers to the retransmit queue and to the current segment. + In addition several variables relating to the send and receive + sequence numbers are stored in the TCB. + + Send Sequence Variables + + SND.UNA - send unacknowledged + SND.NXT - send next + SND.WND - send window + SND.UP - send urgent pointer + SND.WL1 - segment sequence number used for last window update + SND.WL2 - segment acknowledgment number used for last window + update + ISS - initial send sequence number + + Receive Sequence Variables + + RCV.NXT - receive next + RCV.WND - receive window + RCV.UP - receive urgent pointer + IRS - initial receive sequence number + + + + + + + [Page 19] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + The following diagrams may help to relate some of these variables to + the sequence space. + + Send Sequence Space + + 1 2 3 4 + ----------|----------|----------|---------- + SND.UNA SND.NXT SND.UNA + +SND.WND + + 1 - old sequence numbers which have been acknowledged + 2 - sequence numbers of unacknowledged data + 3 - sequence numbers allowed for new data transmission + 4 - future sequence numbers which are not yet allowed + + Send Sequence Space + + Figure 4. + + + + The send window is the portion of the sequence space labeled 3 in + figure 4. + + Receive Sequence Space + + 1 2 3 + ----------|----------|---------- + RCV.NXT RCV.NXT + +RCV.WND + + 1 - old sequence numbers which have been acknowledged + 2 - sequence numbers allowed for new reception + 3 - future sequence numbers which are not yet allowed + + Receive Sequence Space + + Figure 5. + + + + The receive window is the portion of the sequence space labeled 2 in + figure 5. + + There are also some variables used frequently in the discussion that + take their values from the fields of the current segment. + + + + +[Page 20] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + Current Segment Variables + + SEG.SEQ - segment sequence number + SEG.ACK - segment acknowledgment number + SEG.LEN - segment length + SEG.WND - segment window + SEG.UP - segment urgent pointer + SEG.PRC - segment precedence value + + A connection progresses through a series of states during its + lifetime. The states are: LISTEN, SYN-SENT, SYN-RECEIVED, + ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, + TIME-WAIT, and the fictional state CLOSED. CLOSED is fictional + because it represents the state when there is no TCB, and therefore, + no connection. Briefly the meanings of the states are: + + LISTEN - represents waiting for a connection request from any remote + TCP and port. + + SYN-SENT - represents waiting for a matching connection request + after having sent a connection request. + + SYN-RECEIVED - represents waiting for a confirming connection + request acknowledgment after having both received and sent a + connection request. + + ESTABLISHED - represents an open connection, data received can be + delivered to the user. The normal state for the data transfer phase + of the connection. + + FIN-WAIT-1 - represents waiting for a connection termination request + from the remote TCP, or an acknowledgment of the connection + termination request previously sent. + + FIN-WAIT-2 - represents waiting for a connection termination request + from the remote TCP. + + CLOSE-WAIT - represents waiting for a connection termination request + from the local user. + + CLOSING - represents waiting for a connection termination request + acknowledgment from the remote TCP. + + LAST-ACK - represents waiting for an acknowledgment of the + connection termination request previously sent to the remote TCP + (which includes an acknowledgment of its connection termination + request). + + + + [Page 21] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + TIME-WAIT - represents waiting for enough time to pass to be sure + the remote TCP received the acknowledgment of its connection + termination request. + + CLOSED - represents no connection state at all. + + A TCP connection progresses from one state to another in response to + events. The events are the user calls, OPEN, SEND, RECEIVE, CLOSE, + ABORT, and STATUS; the incoming segments, particularly those + containing the SYN, ACK, RST and FIN flags; and timeouts. + + The state diagram in figure 6 illustrates only state changes, together + with the causing events and resulting actions, but addresses neither + error conditions nor actions which are not connected with state + changes. In a later section, more detail is offered with respect to + the reaction of the TCP to events. + + NOTE BENE: this diagram is only a summary and must not be taken as + the total specification. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 22] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + + +---------+ ---------\ active OPEN + | CLOSED | \ ----------- + +---------+<---------\ \ create TCB + | ^ \ \ snd SYN + passive OPEN | | CLOSE \ \ + ------------ | | ---------- \ \ + create TCB | | delete TCB \ \ + V | \ \ + +---------+ CLOSE | \ + | LISTEN | ---------- | | + +---------+ delete TCB | | + rcv SYN | | SEND | | + ----------- | | ------- | V + +---------+ snd SYN,ACK / \ snd SYN +---------+ + | |<----------------- ------------------>| | + | SYN | rcv SYN | SYN | + | RCVD |<-----------------------------------------------| SENT | + | | snd ACK | | + | |------------------ -------------------| | + +---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+ + | -------------- | | ----------- + | x | | snd ACK + | V V + | CLOSE +---------+ + | ------- | ESTAB | + | snd FIN +---------+ + | CLOSE | | rcv FIN + V ------- | | ------- + +---------+ snd FIN / \ snd ACK +---------+ + | FIN |<----------------- ------------------>| CLOSE | + | WAIT-1 |------------------ | WAIT | + +---------+ rcv FIN \ +---------+ + | rcv ACK of FIN ------- | CLOSE | + | -------------- snd ACK | ------- | + V x V snd FIN V + +---------+ +---------+ +---------+ + |FINWAIT-2| | CLOSING | | LAST-ACK| + +---------+ +---------+ +---------+ + | rcv ACK of FIN | rcv ACK of FIN | + | rcv FIN -------------- | Timeout=2MSL -------------- | + | ------- x V ------------ x V + \ snd ACK +---------+delete TCB +---------+ + ------------------------>|TIME WAIT|------------------>| CLOSED | + +---------+ +---------+ + + TCP Connection State Diagram + Figure 6. + + + [Page 23] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + +3.3. Sequence Numbers + + A fundamental notion in the design is that every octet of data sent + over a TCP connection has a sequence number. Since every octet is + sequenced, each of them can be acknowledged. The acknowledgment + mechanism employed is cumulative so that an acknowledgment of sequence + number X indicates that all octets up to but not including X have been + received. This mechanism allows for straight-forward duplicate + detection in the presence of retransmission. Numbering of octets + within a segment is that the first data octet immediately following + the header is the lowest numbered, and the following octets are + numbered consecutively. + + It is essential to remember that the actual sequence number space is + finite, though very large. This space ranges from 0 to 2**32 - 1. + Since the space is finite, all arithmetic dealing with sequence + numbers must be performed modulo 2**32. This unsigned arithmetic + preserves the relationship of sequence numbers as they cycle from + 2**32 - 1 to 0 again. There are some subtleties to computer modulo + arithmetic, so great care should be taken in programming the + comparison of such values. The symbol "=<" means "less than or equal" + (modulo 2**32). + + The typical kinds of sequence number comparisons which the TCP must + perform include: + + (a) Determining that an acknowledgment refers to some sequence + number sent but not yet acknowledged. + + (b) Determining that all sequence numbers occupied by a segment + have been acknowledged (e.g., to remove the segment from a + retransmission queue). + + (c) Determining that an incoming segment contains sequence numbers + which are expected (i.e., that the segment "overlaps" the + receive window). + + + + + + + + + + + + + + +[Page 24] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + In response to sending data the TCP will receive acknowledgments. The + following comparisons are needed to process the acknowledgments. + + SND.UNA = oldest unacknowledged sequence number + + SND.NXT = next sequence number to be sent + + SEG.ACK = acknowledgment from the receiving TCP (next sequence + number expected by the receiving TCP) + + SEG.SEQ = first sequence number of a segment + + SEG.LEN = the number of octets occupied by the data in the segment + (counting SYN and FIN) + + SEG.SEQ+SEG.LEN-1 = last sequence number of a segment + + A new acknowledgment (called an "acceptable ack"), is one for which + the inequality below holds: + + SND.UNA < SEG.ACK =< SND.NXT + + A segment on the retransmission queue is fully acknowledged if the sum + of its sequence number and length is less or equal than the + acknowledgment value in the incoming segment. + + When data is received the following comparisons are needed: + + RCV.NXT = next sequence number expected on an incoming segments, and + is the left or lower edge of the receive window + + RCV.NXT+RCV.WND-1 = last sequence number expected on an incoming + segment, and is the right or upper edge of the receive window + + SEG.SEQ = first sequence number occupied by the incoming segment + + SEG.SEQ+SEG.LEN-1 = last sequence number occupied by the incoming + segment + + A segment is judged to occupy a portion of valid receive sequence + space if + + RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND + + or + + RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND + + + + [Page 25] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + The first part of this test checks to see if the beginning of the + segment falls in the window, the second part of the test checks to see + if the end of the segment falls in the window; if the segment passes + either part of the test it contains data in the window. + + Actually, it is a little more complicated than this. Due to zero + windows and zero length segments, we have four cases for the + acceptability of an incoming segment: + + Segment Receive Test + Length Window + ------- ------- ------------------------------------------- + + 0 0 SEG.SEQ = RCV.NXT + + 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND + + >0 0 not acceptable + + >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND + or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND + + Note that when the receive window is zero no segments should be + acceptable except ACK segments. Thus, it is be possible for a TCP to + maintain a zero receive window while transmitting data and receiving + ACKs. However, even when the receive window is zero, a TCP must + process the RST and URG fields of all incoming segments. + + We have taken advantage of the numbering scheme to protect certain + control information as well. This is achieved by implicitly including + some control flags in the sequence space so they can be retransmitted + and acknowledged without confusion (i.e., one and only one copy of the + control will be acted upon). Control information is not physically + carried in the segment data space. Consequently, we must adopt rules + for implicitly assigning sequence numbers to control. The SYN and FIN + are the only controls requiring this protection, and these controls + are used only at connection opening and closing. For sequence number + purposes, the SYN is considered to occur before the first actual data + octet of the segment in which it occurs, while the FIN is considered + to occur after the last actual data octet in a segment in which it + occurs. The segment length (SEG.LEN) includes both data and sequence + space occupying controls. When a SYN is present then SEG.SEQ is the + sequence number of the SYN. + + + + + + + +[Page 26] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + Initial Sequence Number Selection + + The protocol places no restriction on a particular connection being + used over and over again. A connection is defined by a pair of + sockets. New instances of a connection will be referred to as + incarnations of the connection. The problem that arises from this is + -- "how does the TCP identify duplicate segments from previous + incarnations of the connection?" This problem becomes apparent if the + connection is being opened and closed in quick succession, or if the + connection breaks with loss of memory and is then reestablished. + + To avoid confusion we must prevent segments from one incarnation of a + connection from being used while the same sequence numbers may still + be present in the network from an earlier incarnation. We want to + assure this, even if a TCP crashes and loses all knowledge of the + sequence numbers it has been using. When new connections are created, + an initial sequence number (ISN) generator is employed which selects a + new 32 bit ISN. The generator is bound to a (possibly fictitious) 32 + bit clock whose low order bit is incremented roughly every 4 + microseconds. Thus, the ISN cycles approximately every 4.55 hours. + Since we assume that segments will stay in the network no more than + the Maximum Segment Lifetime (MSL) and that the MSL is less than 4.55 + hours we can reasonably assume that ISN's will be unique. + + For each connection there is a send sequence number and a receive + sequence number. The initial send sequence number (ISS) is chosen by + the data sending TCP, and the initial receive sequence number (IRS) is + learned during the connection establishing procedure. + + For a connection to be established or initialized, the two TCPs must + synchronize on each other's initial sequence numbers. This is done in + an exchange of connection establishing segments carrying a control bit + called "SYN" (for synchronize) and the initial sequence numbers. As a + shorthand, segments carrying the SYN bit are also called "SYNs". + Hence, the solution requires a suitable mechanism for picking an + initial sequence number and a slightly involved handshake to exchange + the ISN's. + + The synchronization requires each side to send it's own initial + sequence number and to receive a confirmation of it in acknowledgment + from the other side. Each side must also receive the other side's + initial sequence number and send a confirming acknowledgment. + + 1) A --> B SYN my sequence number is X + 2) A <-- B ACK your sequence number is X + 3) A <-- B SYN my sequence number is Y + 4) A --> B ACK your sequence number is Y + + + + [Page 27] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + Because steps 2 and 3 can be combined in a single message this is + called the three way (or three message) handshake. + + A three way handshake is necessary because sequence numbers are not + tied to a global clock in the network, and TCPs may have different + mechanisms for picking the ISN's. The receiver of the first SYN has + no way of knowing whether the segment was an old delayed one or not, + unless it remembers the last sequence number used on the connection + (which is not always possible), and so it must ask the sender to + verify this SYN. The three way handshake and the advantages of a + clock-driven scheme are discussed in [3]. + + Knowing When to Keep Quiet + + To be sure that a TCP does not create a segment that carries a + sequence number which may be duplicated by an old segment remaining in + the network, the TCP must keep quiet for a maximum segment lifetime + (MSL) before assigning any sequence numbers upon starting up or + recovering from a crash in which memory of sequence numbers in use was + lost. For this specification the MSL is taken to be 2 minutes. This + is an engineering choice, and may be changed if experience indicates + it is desirable to do so. Note that if a TCP is reinitialized in some + sense, yet retains its memory of sequence numbers in use, then it need + not wait at all; it must only be sure to use sequence numbers larger + than those recently used. + + The TCP Quiet Time Concept + + This specification provides that hosts which "crash" without + retaining any knowledge of the last sequence numbers transmitted on + each active (i.e., not closed) connection shall delay emitting any + TCP segments for at least the agreed Maximum Segment Lifetime (MSL) + in the internet system of which the host is a part. In the + paragraphs below, an explanation for this specification is given. + TCP implementors may violate the "quiet time" restriction, but only + at the risk of causing some old data to be accepted as new or new + data rejected as old duplicated by some receivers in the internet + system. + + TCPs consume sequence number space each time a segment is formed and + entered into the network output queue at a source host. The + duplicate detection and sequencing algorithm in the TCP protocol + relies on the unique binding of segment data to sequence space to + the extent that sequence numbers will not cycle through all 2**32 + values before the segment data bound to those sequence numbers has + been delivered and acknowledged by the receiver and all duplicate + copies of the segments have "drained" from the internet. Without + such an assumption, two distinct TCP segments could conceivably be + + +[Page 28] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + assigned the same or overlapping sequence numbers, causing confusion + at the receiver as to which data is new and which is old. Remember + that each segment is bound to as many consecutive sequence numbers + as there are octets of data in the segment. + + Under normal conditions, TCPs keep track of the next sequence number + to emit and the oldest awaiting acknowledgment so as to avoid + mistakenly using a sequence number over before its first use has + been acknowledged. This alone does not guarantee that old duplicate + data is drained from the net, so the sequence space has been made + very large to reduce the probability that a wandering duplicate will + cause trouble upon arrival. At 2 megabits/sec. it takes 4.5 hours + to use up 2**32 octets of sequence space. Since the maximum segment + lifetime in the net is not likely to exceed a few tens of seconds, + this is deemed ample protection for foreseeable nets, even if data + rates escalate to l0's of megabits/sec. At 100 megabits/sec, the + cycle time is 5.4 minutes which may be a little short, but still + within reason. + + The basic duplicate detection and sequencing algorithm in TCP can be + defeated, however, if a source TCP does not have any memory of the + sequence numbers it last used on a given connection. For example, if + the TCP were to start all connections with sequence number 0, then + upon crashing and restarting, a TCP might re-form an earlier + connection (possibly after half-open connection resolution) and emit + packets with sequence numbers identical to or overlapping with + packets still in the network which were emitted on an earlier + incarnation of the same connection. In the absence of knowledge + about the sequence numbers used on a particular connection, the TCP + specification recommends that the source delay for MSL seconds + before emitting segments on the connection, to allow time for + segments from the earlier connection incarnation to drain from the + system. + + Even hosts which can remember the time of day and used it to select + initial sequence number values are not immune from this problem + (i.e., even if time of day is used to select an initial sequence + number for each new connection incarnation). + + Suppose, for example, that a connection is opened starting with + sequence number S. Suppose that this connection is not used much + and that eventually the initial sequence number function (ISN(t)) + takes on a value equal to the sequence number, say S1, of the last + segment sent by this TCP on a particular connection. Now suppose, + at this instant, the host crashes, recovers, and establishes a new + incarnation of the connection. The initial sequence number chosen is + S1 = ISN(t) -- last used sequence number on old incarnation of + connection! If the recovery occurs quickly enough, any old + + + [Page 29] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + duplicates in the net bearing sequence numbers in the neighborhood + of S1 may arrive and be treated as new packets by the receiver of + the new incarnation of the connection. + + The problem is that the recovering host may not know for how long it + crashed nor does it know whether there are still old duplicates in + the system from earlier connection incarnations. + + One way to deal with this problem is to deliberately delay emitting + segments for one MSL after recovery from a crash- this is the "quite + time" specification. Hosts which prefer to avoid waiting are + willing to risk possible confusion of old and new packets at a given + destination may choose not to wait for the "quite time". + Implementors may provide TCP users with the ability to select on a + connection by connection basis whether to wait after a crash, or may + informally implement the "quite time" for all connections. + Obviously, even where a user selects to "wait," this is not + necessary after the host has been "up" for at least MSL seconds. + + To summarize: every segment emitted occupies one or more sequence + numbers in the sequence space, the numbers occupied by a segment are + "busy" or "in use" until MSL seconds have passed, upon crashing a + block of space-time is occupied by the octets of the last emitted + segment, if a new connection is started too soon and uses any of the + sequence numbers in the space-time footprint of the last segment of + the previous connection incarnation, there is a potential sequence + number overlap area which could cause confusion at the receiver. + +3.4. Establishing a connection + + The "three-way handshake" is the procedure used to establish a + connection. This procedure normally is initiated by one TCP and + responded to by another TCP. The procedure also works if two TCP + simultaneously initiate the procedure. When simultaneous attempt + occurs, each TCP receives a "SYN" segment which carries no + acknowledgment after it has sent a "SYN". Of course, the arrival of + an old duplicate "SYN" segment can potentially make it appear, to the + recipient, that a simultaneous connection initiation is in progress. + Proper use of "reset" segments can disambiguate these cases. + + Several examples of connection initiation follow. Although these + examples do not show connection synchronization using data-carrying + segments, this is perfectly legitimate, so long as the receiving TCP + doesn't deliver the data to the user until it is clear the data is + valid (i.e., the data must be buffered at the receiver until the + connection reaches the ESTABLISHED state). The three-way handshake + reduces the possibility of false connections. It is the + + + +[Page 30] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + implementation of a trade-off between memory and messages to provide + information for this checking. + + The simplest three-way handshake is shown in figure 7 below. The + figures should be interpreted in the following way. Each line is + numbered for reference purposes. Right arrows (-->) indicate + departure of a TCP segment from TCP A to TCP B, or arrival of a + segment at B from A. Left arrows (<--), indicate the reverse. + Ellipsis (...) indicates a segment which is still in the network + (delayed). An "XXX" indicates a segment which is lost or rejected. + Comments appear in parentheses. TCP states represent the state AFTER + the departure or arrival of the segment (whose contents are shown in + the center of each line). Segment contents are shown in abbreviated + form, with sequence number, control flags, and ACK field. Other + fields such as window, addresses, lengths, and text have been left out + in the interest of clarity. + + + + TCP A TCP B + + 1. CLOSED LISTEN + + 2. SYN-SENT --> --> SYN-RECEIVED + + 3. ESTABLISHED <-- <-- SYN-RECEIVED + + 4. ESTABLISHED --> --> ESTABLISHED + + 5. ESTABLISHED --> --> ESTABLISHED + + Basic 3-Way Handshake for Connection Synchronization + + Figure 7. + + In line 2 of figure 7, TCP A begins by sending a SYN segment + indicating that it will use sequence numbers starting with sequence + number 100. In line 3, TCP B sends a SYN and acknowledges the SYN it + received from TCP A. Note that the acknowledgment field indicates TCP + B is now expecting to hear sequence 101, acknowledging the SYN which + occupied sequence 100. + + At line 4, TCP A responds with an empty segment containing an ACK for + TCP B's SYN; and in line 5, TCP A sends some data. Note that the + sequence number of the segment in line 5 is the same as in line 4 + because the ACK does not occupy sequence number space (if it did, we + would wind up ACKing ACK's!). + + + + [Page 31] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + Simultaneous initiation is only slightly more complex, as is shown in + figure 8. Each TCP cycles from CLOSED to SYN-SENT to SYN-RECEIVED to + ESTABLISHED. + + + + TCP A TCP B + + 1. CLOSED CLOSED + + 2. SYN-SENT --> ... + + 3. SYN-RECEIVED <-- <-- SYN-SENT + + 4. ... --> SYN-RECEIVED + + 5. SYN-RECEIVED --> ... + + 6. ESTABLISHED <-- <-- SYN-RECEIVED + + 7. ... --> ESTABLISHED + + Simultaneous Connection Synchronization + + Figure 8. + + The principle reason for the three-way handshake is to prevent old + duplicate connection initiations from causing confusion. To deal with + this, a special control message, reset, has been devised. If the + receiving TCP is in a non-synchronized state (i.e., SYN-SENT, + SYN-RECEIVED), it returns to LISTEN on receiving an acceptable reset. + If the TCP is in one of the synchronized states (ESTABLISHED, + FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), it + aborts the connection and informs its user. We discuss this latter + case under "half-open" connections below. + + + + + + + + + + + + + + + +[Page 32] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + + + TCP A TCP B + + 1. CLOSED LISTEN + + 2. SYN-SENT --> ... + + 3. (duplicate) ... --> SYN-RECEIVED + + 4. SYN-SENT <-- <-- SYN-RECEIVED + + 5. SYN-SENT --> --> LISTEN + + + 6. ... --> SYN-RECEIVED + + 7. SYN-SENT <-- <-- SYN-RECEIVED + + 8. ESTABLISHED --> --> ESTABLISHED + + Recovery from Old Duplicate SYN + + Figure 9. + + As a simple example of recovery from old duplicates, consider + figure 9. At line 3, an old duplicate SYN arrives at TCP B. TCP B + cannot tell that this is an old duplicate, so it responds normally + (line 4). TCP A detects that the ACK field is incorrect and returns a + RST (reset) with its SEQ field selected to make the segment + believable. TCP B, on receiving the RST, returns to the LISTEN state. + When the original SYN (pun intended) finally arrives at line 6, the + synchronization proceeds normally. If the SYN at line 6 had arrived + before the RST, a more complex exchange might have occurred with RST's + sent in both directions. + + Half-Open Connections and Other Anomalies + + An established connection is said to be "half-open" if one of the + TCPs has closed or aborted the connection at its end without the + knowledge of the other, or if the two ends of the connection have + become desynchronized owing to a crash that resulted in loss of + memory. Such connections will automatically become reset if an + attempt is made to send data in either direction. However, half-open + connections are expected to be unusual, and the recovery procedure is + mildly involved. + + If at site A the connection no longer exists, then an attempt by the + + + [Page 33] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + user at site B to send any data on it will result in the site B TCP + receiving a reset control message. Such a message indicates to the + site B TCP that something is wrong, and it is expected to abort the + connection. + + Assume that two user processes A and B are communicating with one + another when a crash occurs causing loss of memory to A's TCP. + Depending on the operating system supporting A's TCP, it is likely + that some error recovery mechanism exists. When the TCP is up again, + A is likely to start again from the beginning or from a recovery + point. As a result, A will probably try to OPEN the connection again + or try to SEND on the connection it believes open. In the latter + case, it receives the error message "connection not open" from the + local (A's) TCP. In an attempt to establish the connection, A's TCP + will send a segment containing SYN. This scenario leads to the + example shown in figure 10. After TCP A crashes, the user attempts to + re-open the connection. TCP B, in the meantime, thinks the connection + is open. + + + + TCP A TCP B + + 1. (CRASH) (send 300,receive 100) + + 2. CLOSED ESTABLISHED + + 3. SYN-SENT --> --> (??) + + 4. (!!) <-- <-- ESTABLISHED + + 5. SYN-SENT --> --> (Abort!!) + + 6. SYN-SENT CLOSED + + 7. SYN-SENT --> --> + + Half-Open Connection Discovery + + Figure 10. + + When the SYN arrives at line 3, TCP B, being in a synchronized state, + and the incoming segment outside the window, responds with an + acknowledgment indicating what sequence it next expects to hear (ACK + 100). TCP A sees that this segment does not acknowledge anything it + sent and, being unsynchronized, sends a reset (RST) because it has + detected a half-open connection. TCP B aborts at line 5. TCP A will + + + +[Page 34] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + continue to try to establish the connection; the problem is now + reduced to the basic 3-way handshake of figure 7. + + An interesting alternative case occurs when TCP A crashes and TCP B + tries to send data on what it thinks is a synchronized connection. + This is illustrated in figure 11. In this case, the data arriving at + TCP A from TCP B (line 2) is unacceptable because no such connection + exists, so TCP A sends a RST. The RST is acceptable so TCP B + processes it and aborts the connection. + + + + TCP A TCP B + + 1. (CRASH) (send 300,receive 100) + + 2. (??) <-- <-- ESTABLISHED + + 3. --> --> (ABORT!!) + + Active Side Causes Half-Open Connection Discovery + + Figure 11. + + In figure 12, we find the two TCPs A and B with passive connections + waiting for SYN. An old duplicate arriving at TCP B (line 2) stirs B + into action. A SYN-ACK is returned (line 3) and causes TCP A to + generate a RST (the ACK in line 3 is not acceptable). TCP B accepts + the reset and returns to its passive LISTEN state. + + + + TCP A TCP B + + 1. LISTEN LISTEN + + 2. ... --> SYN-RECEIVED + + 3. (??) <-- <-- SYN-RECEIVED + + 4. --> --> (return to LISTEN!) + + 5. LISTEN LISTEN + + Old Duplicate SYN Initiates a Reset on two Passive Sockets + + Figure 12. + + + + [Page 35] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + A variety of other cases are possible, all of which are accounted for + by the following rules for RST generation and processing. + + Reset Generation + + As a general rule, reset (RST) must be sent whenever a segment arrives + which apparently is not intended for the current connection. A reset + must not be sent if it is not clear that this is the case. + + There are three groups of states: + + 1. If the connection does not exist (CLOSED) then a reset is sent + in response to any incoming segment except another reset. In + particular, SYNs addressed to a non-existent connection are rejected + by this means. + + If the incoming segment has an ACK field, the reset takes its + sequence number from the ACK field of the segment, otherwise the + reset has sequence number zero and the ACK field is set to the sum + of the sequence number and segment length of the incoming segment. + The connection remains in the CLOSED state. + + 2. If the connection is in any non-synchronized state (LISTEN, + SYN-SENT, SYN-RECEIVED), and the incoming segment acknowledges + something not yet sent (the segment carries an unacceptable ACK), or + if an incoming segment has a security level or compartment which + does not exactly match the level and compartment requested for the + connection, a reset is sent. + + If our SYN has not been acknowledged and the precedence level of the + incoming segment is higher than the precedence level requested then + either raise the local precedence level (if allowed by the user and + the system) or send a reset; or if the precedence level of the + incoming segment is lower than the precedence level requested then + continue as if the precedence matched exactly (if the remote TCP + cannot raise the precedence level to match ours this will be + detected in the next segment it sends, and the connection will be + terminated then). If our SYN has been acknowledged (perhaps in this + incoming segment) the precedence level of the incoming segment must + match the local precedence level exactly, if it does not a reset + must be sent. + + If the incoming segment has an ACK field, the reset takes its + sequence number from the ACK field of the segment, otherwise the + reset has sequence number zero and the ACK field is set to the sum + of the sequence number and segment length of the incoming segment. + The connection remains in the same state. + + + +[Page 36] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + 3. If the connection is in a synchronized state (ESTABLISHED, + FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), + any unacceptable segment (out of window sequence number or + unacceptible acknowledgment number) must elicit only an empty + acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected + to be received, and the connection remains in the same state. + + If an incoming segment has a security level, or compartment, or + precedence which does not exactly match the level, and compartment, + and precedence requested for the connection,a reset is sent and + connection goes to the CLOSED state. The reset takes its sequence + number from the ACK field of the incoming segment. + + Reset Processing + + In all states except SYN-SENT, all reset (RST) segments are validated + by checking their SEQ-fields. A reset is valid if its sequence number + is in the window. In the SYN-SENT state (a RST received in response + to an initial SYN), the RST is acceptable if the ACK field + acknowledges the SYN. + + The receiver of a RST first validates it, then changes state. If the + receiver was in the LISTEN state, it ignores it. If the receiver was + in SYN-RECEIVED state and had previously been in the LISTEN state, + then the receiver returns to the LISTEN state, otherwise the receiver + aborts the connection and goes to the CLOSED state. If the receiver + was in any other state, it aborts the connection and advises the user + and goes to the CLOSED state. + +3.5. Closing a Connection + + CLOSE is an operation meaning "I have no more data to send." The + notion of closing a full-duplex connection is subject to ambiguous + interpretation, of course, since it may not be obvious how to treat + the receiving side of the connection. We have chosen to treat CLOSE + in a simplex fashion. The user who CLOSEs may continue to RECEIVE + until he is told that the other side has CLOSED also. Thus, a program + could initiate several SENDs followed by a CLOSE, and then continue to + RECEIVE until signaled that a RECEIVE failed because the other side + has CLOSED. We assume that the TCP will signal a user, even if no + RECEIVEs are outstanding, that the other side has closed, so the user + can terminate his side gracefully. A TCP will reliably deliver all + buffers SENT before the connection was CLOSED so a user who expects no + data in return need only wait to hear the connection was CLOSED + successfully to know that all his data was received at the destination + TCP. Users must keep reading connections they close for sending until + the TCP says no more data. + + + [Page 37] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + There are essentially three cases: + + 1) The user initiates by telling the TCP to CLOSE the connection + + 2) The remote TCP initiates by sending a FIN control signal + + 3) Both users CLOSE simultaneously + + Case 1: Local user initiates the close + + In this case, a FIN segment can be constructed and placed on the + outgoing segment queue. No further SENDs from the user will be + accepted by the TCP, and it enters the FIN-WAIT-1 state. RECEIVEs + are allowed in this state. All segments preceding and including FIN + will be retransmitted until acknowledged. When the other TCP has + both acknowledged the FIN and sent a FIN of its own, the first TCP + can ACK this FIN. Note that a TCP receiving a FIN will ACK but not + send its own FIN until its user has CLOSED the connection also. + + Case 2: TCP receives a FIN from the network + + If an unsolicited FIN arrives from the network, the receiving TCP + can ACK it and tell the user that the connection is closing. The + user will respond with a CLOSE, upon which the TCP can send a FIN to + the other TCP after sending any remaining data. The TCP then waits + until its own FIN is acknowledged whereupon it deletes the + connection. If an ACK is not forthcoming, after the user timeout + the connection is aborted and the user is told. + + Case 3: both users close simultaneously + + A simultaneous CLOSE by users at both ends of a connection causes + FIN segments to be exchanged. When all segments preceding the FINs + have been processed and acknowledged, each TCP can ACK the FIN it + has received. Both will, upon receiving these ACKs, delete the + connection. + + + + + + + + + + + + + + +[Page 38] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + + + TCP A TCP B + + 1. ESTABLISHED ESTABLISHED + + 2. (Close) + FIN-WAIT-1 --> --> CLOSE-WAIT + + 3. FIN-WAIT-2 <-- <-- CLOSE-WAIT + + 4. (Close) + TIME-WAIT <-- <-- LAST-ACK + + 5. TIME-WAIT --> --> CLOSED + + 6. (2 MSL) + CLOSED + + Normal Close Sequence + + Figure 13. + + + + TCP A TCP B + + 1. ESTABLISHED ESTABLISHED + + 2. (Close) (Close) + FIN-WAIT-1 --> ... FIN-WAIT-1 + <-- <-- + ... --> + + 3. CLOSING --> ... CLOSING + <-- <-- + ... --> + + 4. TIME-WAIT TIME-WAIT + (2 MSL) (2 MSL) + CLOSED CLOSED + + Simultaneous Close Sequence + + Figure 14. + + + + + + [Page 39] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + +3.6. Precedence and Security + + The intent is that connection be allowed only between ports operating + with exactly the same security and compartment values and at the + higher of the precedence level requested by the two ports. + + The precedence and security parameters used in TCP are exactly those + defined in the Internet Protocol (IP) [2]. Throughout this TCP + specification the term "security/compartment" is intended to indicate + the security parameters used in IP including security, compartment, + user group, and handling restriction. + + A connection attempt with mismatched security/compartment values or a + lower precedence value must be rejected by sending a reset. Rejecting + a connection due to too low a precedence only occurs after an + acknowledgment of the SYN has been received. + + Note that TCP modules which operate only at the default value of + precedence will still have to check the precedence of incoming + segments and possibly raise the precedence level they use on the + connection. + + The security paramaters may be used even in a non-secure environment + (the values would indicate unclassified data), thus hosts in + non-secure environments must be prepared to receive the security + parameters, though they need not send them. + +3.7. Data Communication + + Once the connection is established data is communicated by the + exchange of segments. Because segments may be lost due to errors + (checksum test failure), or network congestion, TCP uses + retransmission (after a timeout) to ensure delivery of every segment. + Duplicate segments may arrive due to network or TCP retransmission. + As discussed in the section on sequence numbers the TCP performs + certain tests on the sequence and acknowledgment numbers in the + segments to verify their acceptability. + + The sender of data keeps track of the next sequence number to use in + the variable SND.NXT. The receiver of data keeps track of the next + sequence number to expect in the variable RCV.NXT. The sender of data + keeps track of the oldest unacknowledged sequence number in the + variable SND.UNA. If the data flow is momentarily idle and all data + sent has been acknowledged then the three variables will be equal. + + When the sender creates a segment and transmits it the sender advances + SND.NXT. When the receiver accepts a segment it advances RCV.NXT and + sends an acknowledgment. When the data sender receives an + + +[Page 40] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + acknowledgment it advances SND.UNA. The extent to which the values of + these variables differ is a measure of the delay in the communication. + The amount by which the variables are advanced is the length of the + data in the segment. Note that once in the ESTABLISHED state all + segments must carry current acknowledgment information. + + The CLOSE user call implies a push function, as does the FIN control + flag in an incoming segment. + + Retransmission Timeout + + Because of the variability of the networks that compose an + internetwork system and the wide range of uses of TCP connections the + retransmission timeout must be dynamically determined. One procedure + for determining a retransmission time out is given here as an + illustration. + + An Example Retransmission Timeout Procedure + + Measure the elapsed time between sending a data octet with a + particular sequence number and receiving an acknowledgment that + covers that sequence number (segments sent do not have to match + segments received). This measured elapsed time is the Round Trip + Time (RTT). Next compute a Smoothed Round Trip Time (SRTT) as: + + SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT) + + and based on this, compute the retransmission timeout (RTO) as: + + RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]] + + where UBOUND is an upper bound on the timeout (e.g., 1 minute), + LBOUND is a lower bound on the timeout (e.g., 1 second), ALPHA is + a smoothing factor (e.g., .8 to .9), and BETA is a delay variance + factor (e.g., 1.3 to 2.0). + + The Communication of Urgent Information + + The objective of the TCP urgent mechanism is to allow the sending user + to stimulate the receiving user to accept some urgent data and to + permit the receiving TCP to indicate to the receiving user when all + the currently known urgent data has been received by the user. + + This mechanism permits a point in the data stream to be designated as + the end of urgent information. Whenever this point is in advance of + the receive sequence number (RCV.NXT) at the receiving TCP, that TCP + must tell the user to go into "urgent mode"; when the receive sequence + number catches up to the urgent pointer, the TCP must tell user to go + + + [Page 41] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + into "normal mode". If the urgent pointer is updated while the user + is in "urgent mode", the update will be invisible to the user. + + The method employs a urgent field which is carried in all segments + transmitted. The URG control flag indicates that the urgent field is + meaningful and must be added to the segment sequence number to yield + the urgent pointer. The absence of this flag indicates that there is + no urgent data outstanding. + + To send an urgent indication the user must also send at least one data + octet. If the sending user also indicates a push, timely delivery of + the urgent information to the destination process is enhanced. + + Managing the Window + + The window sent in each segment indicates the range of sequence + numbers the sender of the window (the data receiver) is currently + prepared to accept. There is an assumption that this is related to + the currently available data buffer space available for this + connection. + + Indicating a large window encourages transmissions. If more data + arrives than can be accepted, it will be discarded. This will result + in excessive retransmissions, adding unnecessarily to the load on the + network and the TCPs. Indicating a small window may restrict the + transmission of data to the point of introducing a round trip delay + between each new segment transmitted. + + The mechanisms provided allow a TCP to advertise a large window and to + subsequently advertise a much smaller window without having accepted + that much data. This, so called "shrinking the window," is strongly + discouraged. The robustness principle dictates that TCPs will not + shrink the window themselves, but will be prepared for such behavior + on the part of other TCPs. + + The sending TCP must be prepared to accept from the user and send at + least one octet of new data even if the send window is zero. The + sending TCP must regularly retransmit to the receiving TCP even when + the window is zero. Two minutes is recommended for the retransmission + interval when the window is zero. This retransmission is essential to + guarantee that when either TCP has a zero window the re-opening of the + window will be reliably reported to the other. + + When the receiving TCP has a zero window and a segment arrives it must + still send an acknowledgment showing its next expected sequence number + and current window (zero). + + The sending TCP packages the data to be transmitted into segments + + +[Page 42] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + which fit the current window, and may repackage segments on the + retransmission queue. Such repackaging is not required, but may be + helpful. + + In a connection with a one-way data flow, the window information will + be carried in acknowledgment segments that all have the same sequence + number so there will be no way to reorder them if they arrive out of + order. This is not a serious problem, but it will allow the window + information to be on occasion temporarily based on old reports from + the data receiver. A refinement to avoid this problem is to act on + the window information from segments that carry the highest + acknowledgment number (that is segments with acknowledgment number + equal or greater than the highest previously received). + + The window management procedure has significant influence on the + communication performance. The following comments are suggestions to + implementers. + + Window Management Suggestions + + Allocating a very small window causes data to be transmitted in + many small segments when better performance is achieved using + fewer large segments. + + One suggestion for avoiding small windows is for the receiver to + defer updating a window until the additional allocation is at + least X percent of the maximum allocation possible for the + connection (where X might be 20 to 40). + + Another suggestion is for the sender to avoid sending small + segments by waiting until the window is large enough before + sending data. If the the user signals a push function then the + data must be sent even if it is a small segment. + + Note that the acknowledgments should not be delayed or unnecessary + retransmissions will result. One strategy would be to send an + acknowledgment when a small segment arrives (with out updating the + window information), and then to send another acknowledgment with + new window information when the window is larger. + + The segment sent to probe a zero window may also begin a break up + of transmitted data into smaller and smaller segments. If a + segment containing a single data octet sent to probe a zero window + is accepted, it consumes one octet of the window now available. + If the sending TCP simply sends as much as it can whenever the + window is non zero, the transmitted data will be broken into + alternating big and small segments. As time goes on, occasional + pauses in the receiver making window allocation available will + + + [Page 43] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + result in breaking the big segments into a small and not quite so + big pair. And after a while the data transmission will be in + mostly small segments. + + The suggestion here is that the TCP implementations need to + actively attempt to combine small window allocations into larger + windows, since the mechanisms for managing the window tend to lead + to many small windows in the simplest minded implementations. + +3.8. Interfaces + + There are of course two interfaces of concern: the user/TCP interface + and the TCP/lower-level interface. We have a fairly elaborate model + of the user/TCP interface, but the interface to the lower level + protocol module is left unspecified here, since it will be specified + in detail by the specification of the lowel level protocol. For the + case that the lower level is IP we note some of the parameter values + that TCPs might use. + + User/TCP Interface + + The following functional description of user commands to the TCP is, + at best, fictional, since every operating system will have different + facilities. Consequently, we must warn readers that different TCP + implementations may have different user interfaces. However, all + TCPs must provide a certain minimum set of services to guarantee + that all TCP implementations can support the same protocol + hierarchy. This section specifies the functional interfaces + required of all TCP implementations. + + TCP User Commands + + The following sections functionally characterize a USER/TCP + interface. The notation used is similar to most procedure or + function calls in high level languages, but this usage is not + meant to rule out trap type service calls (e.g., SVCs, UUOs, + EMTs). + + The user commands described below specify the basic functions the + TCP must perform to support interprocess communication. + Individual implementations must define their own exact format, and + may provide combinations or subsets of the basic functions in + single calls. In particular, some implementations may wish to + automatically OPEN a connection on the first SEND or RECEIVE + issued by the user for a given connection. + + + + + +[Page 44] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + In providing interprocess communication facilities, the TCP must + not only accept commands, but must also return information to the + processes it serves. The latter consists of: + + (a) general information about a connection (e.g., interrupts, + remote close, binding of unspecified foreign socket). + + (b) replies to specific user commands indicating success or + various types of failure. + + Open + + Format: OPEN (local port, foreign socket, active/passive + [, timeout] [, precedence] [, security/compartment] [, options]) + -> local connection name + + We assume that the local TCP is aware of the identity of the + processes it serves and will check the authority of the process + to use the connection specified. Depending upon the + implementation of the TCP, the local network and TCP identifiers + for the source address will either be supplied by the TCP or the + lower level protocol (e.g., IP). These considerations are the + result of concern about security, to the extent that no TCP be + able to masquerade as another one, and so on. Similarly, no + process can masquerade as another without the collusion of the + TCP. + + If the active/passive flag is set to passive, then this is a + call to LISTEN for an incoming connection. A passive open may + have either a fully specified foreign socket to wait for a + particular connection or an unspecified foreign socket to wait + for any call. A fully specified passive call can be made active + by the subsequent execution of a SEND. + + A transmission control block (TCB) is created and partially + filled in with data from the OPEN command parameters. + + On an active OPEN command, the TCP will begin the procedure to + synchronize (i.e., establish) the connection at once. + + The timeout, if present, permits the caller to set up a timeout + for all data submitted to TCP. If data is not successfully + delivered to the destination within the timeout period, the TCP + will abort the connection. The present global default is five + minutes. + + The TCP or some component of the operating system will verify + the users authority to open a connection with the specified + + + [Page 45] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + precedence or security/compartment. The absence of precedence + or security/compartment specification in the OPEN call indicates + the default values must be used. + + TCP will accept incoming requests as matching only if the + security/compartment information is exactly the same and only if + the precedence is equal to or higher than the precedence + requested in the OPEN call. + + The precedence for the connection is the higher of the values + requested in the OPEN call and received from the incoming + request, and fixed at that value for the life of the + connection.Implementers may want to give the user control of + this precedence negotiation. For example, the user might be + allowed to specify that the precedence must be exactly matched, + or that any attempt to raise the precedence be confirmed by the + user. + + A local connection name will be returned to the user by the TCP. + The local connection name can then be used as a short hand term + for the connection defined by the + pair. + + Send + + Format: SEND (local connection name, buffer address, byte + count, PUSH flag, URGENT flag [,timeout]) + + This call causes the data contained in the indicated user buffer + to be sent on the indicated connection. If the connection has + not been opened, the SEND is considered an error. Some + implementations may allow users to SEND first; in which case, an + automatic OPEN would be done. If the calling process is not + authorized to use this connection, an error is returned. + + If the PUSH flag is set, the data must be transmitted promptly + to the receiver, and the PUSH bit will be set in the last TCP + segment created from the buffer. If the PUSH flag is not set, + the data may be combined with data from subsequent SENDs for + transmission efficiency. + + If the URGENT flag is set, segments sent to the destination TCP + will have the urgent pointer set. The receiving TCP will signal + the urgent condition to the receiving process if the urgent + pointer indicates that data preceding the urgent pointer has not + been consumed by the receiving process. The purpose of urgent + is to stimulate the receiver to process the urgent data and to + indicate to the receiver when all the currently known urgent + + +[Page 46] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + data has been received. The number of times the sending user's + TCP signals urgent will not necessarily be equal to the number + of times the receiving user will be notified of the presence of + urgent data. + + If no foreign socket was specified in the OPEN, but the + connection is established (e.g., because a LISTENing connection + has become specific due to a foreign segment arriving for the + local socket), then the designated buffer is sent to the implied + foreign socket. Users who make use of OPEN with an unspecified + foreign socket can make use of SEND without ever explicitly + knowing the foreign socket address. + + However, if a SEND is attempted before the foreign socket + becomes specified, an error will be returned. Users can use the + STATUS call to determine the status of the connection. In some + implementations the TCP may notify the user when an unspecified + socket is bound. + + If a timeout is specified, the current user timeout for this + connection is changed to the new one. + + In the simplest implementation, SEND would not return control to + the sending process until either the transmission was complete + or the timeout had been exceeded. However, this simple method + is both subject to deadlocks (for example, both sides of the + connection might try to do SENDs before doing any RECEIVEs) and + offers poor performance, so it is not recommended. A more + sophisticated implementation would return immediately to allow + the process to run concurrently with network I/O, and, + furthermore, to allow multiple SENDs to be in progress. + Multiple SENDs are served in first come, first served order, so + the TCP will queue those it cannot service immediately. + + We have implicitly assumed an asynchronous user interface in + which a SEND later elicits some kind of SIGNAL or + pseudo-interrupt from the serving TCP. An alternative is to + return a response immediately. For instance, SENDs might return + immediate local acknowledgment, even if the segment sent had not + been acknowledged by the distant TCP. We could optimistically + assume eventual success. If we are wrong, the connection will + close anyway due to the timeout. In implementations of this + kind (synchronous), there will still be some asynchronous + signals, but these will deal with the connection itself, and not + with specific segments or buffers. + + In order for the process to distinguish among error or success + indications for different SENDs, it might be appropriate for the + + + [Page 47] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + buffer address to be returned along with the coded response to + the SEND request. TCP-to-user signals are discussed below, + indicating the information which should be returned to the + calling process. + + Receive + + Format: RECEIVE (local connection name, buffer address, byte + count) -> byte count, urgent flag, push flag + + This command allocates a receiving buffer associated with the + specified connection. If no OPEN precedes this command or the + calling process is not authorized to use this connection, an + error is returned. + + In the simplest implementation, control would not return to the + calling program until either the buffer was filled, or some + error occurred, but this scheme is highly subject to deadlocks. + A more sophisticated implementation would permit several + RECEIVEs to be outstanding at once. These would be filled as + segments arrive. This strategy permits increased throughput at + the cost of a more elaborate scheme (possibly asynchronous) to + notify the calling program that a PUSH has been seen or a buffer + filled. + + If enough data arrive to fill the buffer before a PUSH is seen, + the PUSH flag will not be set in the response to the RECEIVE. + The buffer will be filled with as much data as it can hold. If + a PUSH is seen before the buffer is filled the buffer will be + returned partially filled and PUSH indicated. + + If there is urgent data the user will have been informed as soon + as it arrived via a TCP-to-user signal. The receiving user + should thus be in "urgent mode". If the URGENT flag is on, + additional urgent data remains. If the URGENT flag is off, this + call to RECEIVE has returned all the urgent data, and the user + may now leave "urgent mode". Note that data following the + urgent pointer (non-urgent data) cannot be delivered to the user + in the same buffer with preceeding urgent data unless the + boundary is clearly marked for the user. + + To distinguish among several outstanding RECEIVEs and to take + care of the case that a buffer is not completely filled, the + return code is accompanied by both a buffer pointer and a byte + count indicating the actual length of the data received. + + Alternative implementations of RECEIVE might have the TCP + + + +[Page 48] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + allocate buffer storage, or the TCP might share a ring buffer + with the user. + + Close + + Format: CLOSE (local connection name) + + This command causes the connection specified to be closed. If + the connection is not open or the calling process is not + authorized to use this connection, an error is returned. + Closing connections is intended to be a graceful operation in + the sense that outstanding SENDs will be transmitted (and + retransmitted), as flow control permits, until all have been + serviced. Thus, it should be acceptable to make several SEND + calls, followed by a CLOSE, and expect all the data to be sent + to the destination. It should also be clear that users should + continue to RECEIVE on CLOSING connections, since the other side + may be trying to transmit the last of its data. Thus, CLOSE + means "I have no more to send" but does not mean "I will not + receive any more." It may happen (if the user level protocol is + not well thought out) that the closing side is unable to get rid + of all its data before timing out. In this event, CLOSE turns + into ABORT, and the closing TCP gives up. + + The user may CLOSE the connection at any time on his own + initiative, or in response to various prompts from the TCP + (e.g., remote close executed, transmission timeout exceeded, + destination inaccessible). + + Because closing a connection requires communication with the + foreign TCP, connections may remain in the closing state for a + short time. Attempts to reopen the connection before the TCP + replies to the CLOSE command will result in error responses. + + Close also implies push function. + + Status + + Format: STATUS (local connection name) -> status data + + This is an implementation dependent user command and could be + excluded without adverse effect. Information returned would + typically come from the TCB associated with the connection. + + This command returns a data block containing the following + information: + + local socket, + + + [Page 49] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + + foreign socket, + local connection name, + receive window, + send window, + connection state, + number of buffers awaiting acknowledgment, + number of buffers pending receipt, + urgent state, + precedence, + security/compartment, + and transmission timeout. + + Depending on the state of the connection, or on the + implementation itself, some of this information may not be + available or meaningful. If the calling process is not + authorized to use this connection, an error is returned. This + prevents unauthorized processes from gaining information about a + connection. + + Abort + + Format: ABORT (local connection name) + + This command causes all pending SENDs and RECEIVES to be + aborted, the TCB to be removed, and a special RESET message to + be sent to the TCP on the other side of the connection. + Depending on the implementation, users may receive abort + indications for each outstanding SEND or RECEIVE, or may simply + receive an ABORT-acknowledgment. + + TCP-to-User Messages + + It is assumed that the operating system environment provides a + means for the TCP to asynchronously signal the user program. When + the TCP does signal a user program, certain information is passed + to the user. Often in the specification the information will be + an error message. In other cases there will be information + relating to the completion of processing a SEND or RECEIVE or + other user call. + + The following information is provided: + + Local Connection Name Always + Response String Always + Buffer Address Send & Receive + Byte count (counts bytes received) Receive + Push flag Receive + Urgent flag Receive + + +[Page 50] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + TCP/Lower-Level Interface + + The TCP calls on a lower level protocol module to actually send and + receive information over a network. One case is that of the ARPA + internetwork system where the lower level module is the Internet + Protocol (IP) [2]. + + If the lower level protocol is IP it provides arguments for a type + of service and for a time to live. TCP uses the following settings + for these parameters: + + Type of Service = Precedence: routine, Delay: normal, Throughput: + normal, Reliability: normal; or 00000000. + + Time to Live = one minute, or 00111100. + + Note that the assumed maximum segment lifetime is two minutes. + Here we explicitly ask that a segment be destroyed if it cannot + be delivered by the internet system within one minute. + + If the lower level is IP (or other protocol that provides this + feature) and source routing is used, the interface must allow the + route information to be communicated. This is especially important + so that the source and destination addresses used in the TCP + checksum be the originating source and ultimate destination. It is + also important to preserve the return route to answer connection + requests. + + Any lower level protocol will have to provide the source address, + destination address, and protocol fields, and some way to determine + the "TCP length", both to provide the functional equivlent service + of IP and to be used in the TCP checksum. + + + + + + + + + + + + + + + + + + + [Page 51] + + + September 1981 +Transmission Control Protocol +Functional Specification + + + +3.9. Event Processing + + The processing depicted in this section is an example of one possible + implementation. Other implementations may have slightly different + processing sequences, but they should differ from those in this + section only in detail, not in substance. + + The activity of the TCP can be characterized as responding to events. + The events that occur can be cast into three categories: user calls, + arriving segments, and timeouts. This section describes the + processing the TCP does in response to each of the events. In many + cases the processing required depends on the state of the connection. + + Events that occur: + + User Calls + + OPEN + SEND + RECEIVE + CLOSE + ABORT + STATUS + + Arriving Segments + + SEGMENT ARRIVES + + Timeouts + + USER TIMEOUT + RETRANSMISSION TIMEOUT + TIME-WAIT TIMEOUT + + The model of the TCP/user interface is that user commands receive an + immediate return and possibly a delayed response via an event or + pseudo interrupt. In the following descriptions, the term "signal" + means cause a delayed response. + + Error responses are given as character strings. For example, user + commands referencing connections that do not exist receive "error: + connection not open". + + Please note in the following that all arithmetic on sequence numbers, + acknowledgment numbers, windows, et cetera, is modulo 2**32 the size + of the sequence number space. Also note that "=<" means less than or + equal to (modulo 2**32). + + + +[Page 52] + + +September 1981 + Transmission Control Protocol + Functional Specification + + + + A natural way to think about processing incoming segments is to + imagine that they are first tested for proper sequence number (i.e., + that their contents lie in the range of the expected "receive window" + in the sequence number space) and then that they are generally queued + and processed in sequence number order. + + When a segment overlaps other already received segments we reconstruct + the segment to contain just the new data, and adjust the header fields + to be consistent. + + Note that if no state change is mentioned the TCP stays in the same + state. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 53] + + + September 1981 +Transmission Control Protocol +Functional Specification + OPEN Call + + + + OPEN Call + + CLOSED STATE (i.e., TCB does not exist) + + Create a new transmission control block (TCB) to hold connection + state information. Fill in local socket identifier, foreign + socket, precedence, security/compartment, and user timeout + information. Note that some parts of the foreign socket may be + unspecified in a passive OPEN and are to be filled in by the + parameters of the incoming SYN segment. Verify the security and + precedence requested are allowed for this user, if not return + "error: precedence not allowed" or "error: security/compartment + not allowed." If passive enter the LISTEN state and return. If + active and the foreign socket is unspecified, return "error: + foreign socket unspecified"; if active and the foreign socket is + specified, issue a SYN segment. An initial send sequence number + (ISS) is selected. A SYN segment of the form + is sent. Set SND.UNA to ISS, SND.NXT to ISS+1, enter SYN-SENT + state, and return. + + If the caller does not have access to the local socket specified, + return "error: connection illegal for this process". If there is + no room to create a new connection, return "error: insufficient + resources". + + LISTEN STATE + + If active and the foreign socket is specified, then change the + connection from passive to active, select an ISS. Send a SYN + segment, set SND.UNA to ISS, SND.NXT to ISS+1. Enter SYN-SENT + state. Data associated with SEND may be sent with SYN segment or + queued for transmission after entering ESTABLISHED state. The + urgent bit if requested in the command must be sent with the data + segments sent as a result of this command. If there is no room to + queue the request, respond with "error: insufficient resources". + If Foreign socket was not specified, then return "error: foreign + socket unspecified". + + + + + + + + + + + + +[Page 54] + + +September 1981 + Transmission Control Protocol + Functional Specification +OPEN Call + + + + SYN-SENT STATE + SYN-RECEIVED STATE + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + CLOSE-WAIT STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Return "error: connection already exists". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 55] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEND Call + + + + SEND Call + + CLOSED STATE (i.e., TCB does not exist) + + If the user does not have access to such a connection, then return + "error: connection illegal for this process". + + Otherwise, return "error: connection does not exist". + + LISTEN STATE + + If the foreign socket is specified, then change the connection + from passive to active, select an ISS. Send a SYN segment, set + SND.UNA to ISS, SND.NXT to ISS+1. Enter SYN-SENT state. Data + associated with SEND may be sent with SYN segment or queued for + transmission after entering ESTABLISHED state. The urgent bit if + requested in the command must be sent with the data segments sent + as a result of this command. If there is no room to queue the + request, respond with "error: insufficient resources". If + Foreign socket was not specified, then return "error: foreign + socket unspecified". + + SYN-SENT STATE + SYN-RECEIVED STATE + + Queue the data for transmission after entering ESTABLISHED state. + If no space to queue, respond with "error: insufficient + resources". + + ESTABLISHED STATE + CLOSE-WAIT STATE + + Segmentize the buffer and send it with a piggybacked + acknowledgment (acknowledgment value = RCV.NXT). If there is + insufficient space to remember this buffer, simply return "error: + insufficient resources". + + If the urgent flag is set, then SND.UP <- SND.NXT-1 and set the + urgent pointer in the outgoing segments. + + + + + + + + + + +[Page 56] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEND Call + + + + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Return "error: connection closing" and do not service request. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 57] + + + September 1981 +Transmission Control Protocol +Functional Specification + RECEIVE Call + + + + RECEIVE Call + + CLOSED STATE (i.e., TCB does not exist) + + If the user does not have access to such a connection, return + "error: connection illegal for this process". + + Otherwise return "error: connection does not exist". + + LISTEN STATE + SYN-SENT STATE + SYN-RECEIVED STATE + + Queue for processing after entering ESTABLISHED state. If there + is no room to queue this request, respond with "error: + insufficient resources". + + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + + If insufficient incoming segments are queued to satisfy the + request, queue the request. If there is no queue space to + remember the RECEIVE, respond with "error: insufficient + resources". + + Reassemble queued incoming segments into receive buffer and return + to user. Mark "push seen" (PUSH) if this is the case. + + If RCV.UP is in advance of the data currently being passed to the + user notify the user of the presence of urgent data. + + When the TCP takes responsibility for delivering data to the user + that fact must be communicated to the sender via an + acknowledgment. The formation of such an acknowledgment is + described below in the discussion of processing an incoming + segment. + + + + + + + + + + + + +[Page 58] + + +September 1981 + Transmission Control Protocol + Functional Specification +RECEIVE Call + + + + CLOSE-WAIT STATE + + Since the remote side has already sent FIN, RECEIVEs must be + satisfied by text already on hand, but not yet delivered to the + user. If no text is awaiting delivery, the RECEIVE will get a + "error: connection closing" response. Otherwise, any remaining + text can be used to satisfy the RECEIVE. + + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Return "error: connection closing". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 59] + + + September 1981 +Transmission Control Protocol +Functional Specification + CLOSE Call + + + + CLOSE Call + + CLOSED STATE (i.e., TCB does not exist) + + If the user does not have access to such a connection, return + "error: connection illegal for this process". + + Otherwise, return "error: connection does not exist". + + LISTEN STATE + + Any outstanding RECEIVEs are returned with "error: closing" + responses. Delete TCB, enter CLOSED state, and return. + + SYN-SENT STATE + + Delete the TCB and return "error: closing" responses to any + queued SENDs, or RECEIVEs. + + SYN-RECEIVED STATE + + If no SENDs have been issued and there is no pending data to send, + then form a FIN segment and send it, and enter FIN-WAIT-1 state; + otherwise queue for processing after entering ESTABLISHED state. + + ESTABLISHED STATE + + Queue this until all preceding SENDs have been segmentized, then + form a FIN segment and send it. In any case, enter FIN-WAIT-1 + state. + + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + + Strictly speaking, this is an error and should receive a "error: + connection closing" response. An "ok" response would be + acceptable, too, as long as a second FIN is not emitted (the first + FIN may be retransmitted though). + + + + + + + + + + + +[Page 60] + + +September 1981 + Transmission Control Protocol + Functional Specification +CLOSE Call + + + + CLOSE-WAIT STATE + + Queue this request until all preceding SENDs have been + segmentized; then send a FIN segment, enter CLOSING state. + + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Respond with "error: connection closing". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 61] + + + September 1981 +Transmission Control Protocol +Functional Specification + ABORT Call + + + + ABORT Call + + CLOSED STATE (i.e., TCB does not exist) + + If the user should not have access to such a connection, return + "error: connection illegal for this process". + + Otherwise return "error: connection does not exist". + + LISTEN STATE + + Any outstanding RECEIVEs should be returned with "error: + connection reset" responses. Delete TCB, enter CLOSED state, and + return. + + SYN-SENT STATE + + All queued SENDs and RECEIVEs should be given "connection reset" + notification, delete the TCB, enter CLOSED state, and return. + + SYN-RECEIVED STATE + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + CLOSE-WAIT STATE + + Send a reset segment: + + + + All queued SENDs and RECEIVEs should be given "connection reset" + notification; all segments queued for transmission (except for the + RST formed above) or retransmission should be flushed, delete the + TCB, enter CLOSED state, and return. + + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Respond with "ok" and delete the TCB, enter CLOSED state, and + return. + + + + + + + + +[Page 62] + + +September 1981 + Transmission Control Protocol + Functional Specification +STATUS Call + + + + STATUS Call + + CLOSED STATE (i.e., TCB does not exist) + + If the user should not have access to such a connection, return + "error: connection illegal for this process". + + Otherwise return "error: connection does not exist". + + LISTEN STATE + + Return "state = LISTEN", and the TCB pointer. + + SYN-SENT STATE + + Return "state = SYN-SENT", and the TCB pointer. + + SYN-RECEIVED STATE + + Return "state = SYN-RECEIVED", and the TCB pointer. + + ESTABLISHED STATE + + Return "state = ESTABLISHED", and the TCB pointer. + + FIN-WAIT-1 STATE + + Return "state = FIN-WAIT-1", and the TCB pointer. + + FIN-WAIT-2 STATE + + Return "state = FIN-WAIT-2", and the TCB pointer. + + CLOSE-WAIT STATE + + Return "state = CLOSE-WAIT", and the TCB pointer. + + CLOSING STATE + + Return "state = CLOSING", and the TCB pointer. + + LAST-ACK STATE + + Return "state = LAST-ACK", and the TCB pointer. + + + + + + [Page 63] + + + September 1981 +Transmission Control Protocol +Functional Specification + STATUS Call + + + + TIME-WAIT STATE + + Return "state = TIME-WAIT", and the TCB pointer. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 64] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + SEGMENT ARRIVES + + If the state is CLOSED (i.e., TCB does not exist) then + + all data in the incoming segment is discarded. An incoming + segment containing a RST is discarded. An incoming segment not + containing a RST causes a RST to be sent in response. The + acknowledgment and sequence field values are selected to make the + reset sequence acceptable to the TCP that sent the offending + segment. + + If the ACK bit is off, sequence number zero is used, + + + + If the ACK bit is on, + + + + Return. + + If the state is LISTEN then + + first check for an RST + + An incoming RST should be ignored. Return. + + second check for an ACK + + Any acknowledgment is bad if it arrives on a connection still in + the LISTEN state. An acceptable reset segment should be formed + for any arriving ACK-bearing segment. The RST should be + formatted as follows: + + + + Return. + + third check for a SYN + + If the SYN bit is set, check the security. If the + security/compartment on the incoming segment does not exactly + match the security/compartment in the TCB then send a reset and + return. + + + + + + [Page 65] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + If the SEG.PRC is greater than the TCB.PRC then if allowed by + the user and the system set TCB.PRC<-SEG.PRC, if not allowed + send a reset and return. + + + + If the SEG.PRC is less than the TCB.PRC then continue. + + Set RCV.NXT to SEG.SEQ+1, IRS is set to SEG.SEQ and any other + control or text should be queued for processing later. ISS + should be selected and a SYN segment sent of the form: + + + + SND.NXT is set to ISS+1 and SND.UNA to ISS. The connection + state should be changed to SYN-RECEIVED. Note that any other + incoming control or data (combined with SYN) will be processed + in the SYN-RECEIVED state, but processing of SYN and ACK should + not be repeated. If the listen was not fully specified (i.e., + the foreign socket was not fully specified), then the + unspecified fields should be filled in now. + + fourth other text or control + + Any other control or text-bearing segment (not containing SYN) + must have an ACK and thus would be discarded by the ACK + processing. An incoming RST segment could not be valid, since + it could not have been sent in response to anything sent by this + incarnation of the connection. So you are unlikely to get here, + but if you do, drop the segment, and return. + + If the state is SYN-SENT then + + first check the ACK bit + + If the ACK bit is set + + If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send a reset (unless + the RST bit is set, if so drop the segment and return) + + + + and discard the segment. Return. + + If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable. + + second check the RST bit + + +[Page 66] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + If the RST bit is set + + If the ACK was acceptable then signal the user "error: + connection reset", drop the segment, enter CLOSED state, + delete TCB, and return. Otherwise (no ACK) drop the segment + and return. + + third check the security and precedence + + If the security/compartment in the segment does not exactly + match the security/compartment in the TCB, send a reset + + If there is an ACK + + + + Otherwise + + + + If there is an ACK + + The precedence in the segment must match the precedence in the + TCB, if not, send a reset + + + + If there is no ACK + + If the precedence in the segment is higher than the precedence + in the TCB then if allowed by the user and the system raise + the precedence in the TCB to that in the segment, if not + allowed to raise the prec then send a reset. + + + + If the precedence in the segment is lower than the precedence + in the TCB continue. + + If a reset was sent, discard the segment and return. + + fourth check the SYN bit + + This step should be reached only if the ACK is ok, or there is + no ACK, and it the segment did not contain a RST. + + If the SYN bit is on and the security/compartment and precedence + + + [Page 67] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + are acceptable then, RCV.NXT is set to SEG.SEQ+1, IRS is set to + SEG.SEQ. SND.UNA should be advanced to equal SEG.ACK (if there + is an ACK), and any segments on the retransmission queue which + are thereby acknowledged should be removed. + + If SND.UNA > ISS (our SYN has been ACKed), change the connection + state to ESTABLISHED, form an ACK segment + + + + and send it. Data or controls which were queued for + transmission may be included. If there are other controls or + text in the segment then continue processing at the sixth step + below where the URG bit is checked, otherwise return. + + Otherwise enter SYN-RECEIVED, form a SYN,ACK segment + + + + and send it. If there are other controls or text in the + segment, queue them for processing after the ESTABLISHED state + has been reached, return. + + fifth, if neither of the SYN or RST bits is set then drop the + segment and return. + + + + + + + + + + + + + + + + + + + + + + + + +[Page 68] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + Otherwise, + + first check sequence number + + SYN-RECEIVED STATE + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + CLOSE-WAIT STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + Segments are processed in sequence. Initial tests on arrival + are used to discard old duplicates, but further processing is + done in SEG.SEQ order. If a segment's contents straddle the + boundary between old and new, only the new parts should be + processed. + + There are four cases for the acceptability test for an incoming + segment: + + Segment Receive Test + Length Window + ------- ------- ------------------------------------------- + + 0 0 SEG.SEQ = RCV.NXT + + 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND + + >0 0 not acceptable + + >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND + or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND + + If the RCV.WND is zero, no segments will be acceptable, but + special allowance should be made to accept valid ACKs, URGs and + RSTs. + + If an incoming segment is not acceptable, an acknowledgment + should be sent in reply (unless the RST bit is set, if so drop + the segment and return): + + + + After sending the acknowledgment, drop the unacceptable segment + and return. + + + [Page 69] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + In the following it is assumed that the segment is the idealized + segment that begins at RCV.NXT and does not exceed the window. + One could tailor actual segments to fit this assumption by + trimming off any portions that lie outside the window (including + SYN and FIN), and only processing further if the segment then + begins at RCV.NXT. Segments with higher begining sequence + numbers may be held for later processing. + + second check the RST bit, + + SYN-RECEIVED STATE + + If the RST bit is set + + If this connection was initiated with a passive OPEN (i.e., + came from the LISTEN state), then return this connection to + LISTEN state and return. The user need not be informed. If + this connection was initiated with an active OPEN (i.e., came + from SYN-SENT state) then the connection was refused, signal + the user "connection refused". In either case, all segments + on the retransmission queue should be removed. And in the + active OPEN case, enter the CLOSED state and delete the TCB, + and return. + + ESTABLISHED + FIN-WAIT-1 + FIN-WAIT-2 + CLOSE-WAIT + + If the RST bit is set then, any outstanding RECEIVEs and SEND + should receive "reset" responses. All segment queues should be + flushed. Users should also receive an unsolicited general + "connection reset" signal. Enter the CLOSED state, delete the + TCB, and return. + + CLOSING STATE + LAST-ACK STATE + TIME-WAIT + + If the RST bit is set then, enter the CLOSED state, delete the + TCB, and return. + + + + + + + + +[Page 70] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + third check security and precedence + + SYN-RECEIVED + + If the security/compartment and precedence in the segment do not + exactly match the security/compartment and precedence in the TCB + then send a reset, and return. + + ESTABLISHED STATE + + If the security/compartment and precedence in the segment do not + exactly match the security/compartment and precedence in the TCB + then send a reset, any outstanding RECEIVEs and SEND should + receive "reset" responses. All segment queues should be + flushed. Users should also receive an unsolicited general + "connection reset" signal. Enter the CLOSED state, delete the + TCB, and return. + + Note this check is placed following the sequence check to prevent + a segment from an old connection between these ports with a + different security or precedence from causing an abort of the + current connection. + + fourth, check the SYN bit, + + SYN-RECEIVED + ESTABLISHED STATE + FIN-WAIT STATE-1 + FIN-WAIT STATE-2 + CLOSE-WAIT STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + If the SYN is in the window it is an error, send a reset, any + outstanding RECEIVEs and SEND should receive "reset" responses, + all segment queues should be flushed, the user should also + receive an unsolicited general "connection reset" signal, enter + the CLOSED state, delete the TCB, and return. + + If the SYN is not in the window this step would not be reached + and an ack would have been sent in the first step (sequence + number check). + + + + + + + [Page 71] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + fifth check the ACK field, + + if the ACK bit is off drop the segment and return + + if the ACK bit is on + + SYN-RECEIVED STATE + + If SND.UNA =< SEG.ACK =< SND.NXT then enter ESTABLISHED state + and continue processing. + + If the segment acknowledgment is not acceptable, form a + reset segment, + + + + and send it. + + ESTABLISHED STATE + + If SND.UNA < SEG.ACK =< SND.NXT then, set SND.UNA <- SEG.ACK. + Any segments on the retransmission queue which are thereby + entirely acknowledged are removed. Users should receive + positive acknowledgments for buffers which have been SENT and + fully acknowledged (i.e., SEND buffer should be returned with + "ok" response). If the ACK is a duplicate + (SEG.ACK < SND.UNA), it can be ignored. If the ACK acks + something not yet sent (SEG.ACK > SND.NXT) then send an ACK, + drop the segment, and return. + + If SND.UNA < SEG.ACK =< SND.NXT, the send window should be + updated. If (SND.WL1 < SEG.SEQ or (SND.WL1 = SEG.SEQ and + SND.WL2 =< SEG.ACK)), set SND.WND <- SEG.WND, set + SND.WL1 <- SEG.SEQ, and set SND.WL2 <- SEG.ACK. + + Note that SND.WND is an offset from SND.UNA, that SND.WL1 + records the sequence number of the last segment used to update + SND.WND, and that SND.WL2 records the acknowledgment number of + the last segment used to update SND.WND. The check here + prevents using old segments to update the window. + + + + + + + + + +[Page 72] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + FIN-WAIT-1 STATE + + In addition to the processing for the ESTABLISHED state, if + our FIN is now acknowledged then enter FIN-WAIT-2 and continue + processing in that state. + + FIN-WAIT-2 STATE + + In addition to the processing for the ESTABLISHED state, if + the retransmission queue is empty, the user's CLOSE can be + acknowledged ("ok") but do not delete the TCB. + + CLOSE-WAIT STATE + + Do the same processing as for the ESTABLISHED state. + + CLOSING STATE + + In addition to the processing for the ESTABLISHED state, if + the ACK acknowledges our FIN then enter the TIME-WAIT state, + otherwise ignore the segment. + + LAST-ACK STATE + + The only thing that can arrive in this state is an + acknowledgment of our FIN. If our FIN is now acknowledged, + delete the TCB, enter the CLOSED state, and return. + + TIME-WAIT STATE + + The only thing that can arrive in this state is a + retransmission of the remote FIN. Acknowledge it, and restart + the 2 MSL timeout. + + sixth, check the URG bit, + + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + + If the URG bit is set, RCV.UP <- max(RCV.UP,SEG.UP), and signal + the user that the remote side has urgent data if the urgent + pointer (RCV.UP) is in advance of the data consumed. If the + user has already been signaled (or is still in the "urgent + mode") for this continuous sequence of urgent data, do not + signal the user again. + + + + [Page 73] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + CLOSE-WAIT STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT + + This should not occur, since a FIN has been received from the + remote side. Ignore the URG. + + seventh, process the segment text, + + ESTABLISHED STATE + FIN-WAIT-1 STATE + FIN-WAIT-2 STATE + + Once in the ESTABLISHED state, it is possible to deliver segment + text to user RECEIVE buffers. Text from segments can be moved + into buffers until either the buffer is full or the segment is + empty. If the segment empties and carries an PUSH flag, then + the user is informed, when the buffer is returned, that a PUSH + has been received. + + When the TCP takes responsibility for delivering the data to the + user it must also acknowledge the receipt of the data. + + Once the TCP takes responsibility for the data it advances + RCV.NXT over the data accepted, and adjusts RCV.WND as + apporopriate to the current buffer availability. The total of + RCV.NXT and RCV.WND should not be reduced. + + Please note the window management suggestions in section 3.7. + + Send an acknowledgment of the form: + + + + This acknowledgment should be piggybacked on a segment being + transmitted if possible without incurring undue delay. + + + + + + + + + + + + +[Page 74] + + +September 1981 + Transmission Control Protocol + Functional Specification +SEGMENT ARRIVES + + + + CLOSE-WAIT STATE + CLOSING STATE + LAST-ACK STATE + TIME-WAIT STATE + + This should not occur, since a FIN has been received from the + remote side. Ignore the segment text. + + eighth, check the FIN bit, + + Do not process the FIN if the state is CLOSED, LISTEN or SYN-SENT + since the SEG.SEQ cannot be validated; drop the segment and + return. + + If the FIN bit is set, signal the user "connection closing" and + return any pending RECEIVEs with same message, advance RCV.NXT + over the FIN, and send an acknowledgment for the FIN. Note that + FIN implies PUSH for any segment text not yet delivered to the + user. + + SYN-RECEIVED STATE + ESTABLISHED STATE + + Enter the CLOSE-WAIT state. + + FIN-WAIT-1 STATE + + If our FIN has been ACKed (perhaps in this segment), then + enter TIME-WAIT, start the time-wait timer, turn off the other + timers; otherwise enter the CLOSING state. + + FIN-WAIT-2 STATE + + Enter the TIME-WAIT state. Start the time-wait timer, turn + off the other timers. + + CLOSE-WAIT STATE + + Remain in the CLOSE-WAIT state. + + CLOSING STATE + + Remain in the CLOSING state. + + LAST-ACK STATE + + Remain in the LAST-ACK state. + + + [Page 75] + + + September 1981 +Transmission Control Protocol +Functional Specification + SEGMENT ARRIVES + + + + TIME-WAIT STATE + + Remain in the TIME-WAIT state. Restart the 2 MSL time-wait + timeout. + + and return. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 76] + + +September 1981 + Transmission Control Protocol + Functional Specification +USER TIMEOUT + + + + USER TIMEOUT + + For any state if the user timeout expires, flush all queues, signal + the user "error: connection aborted due to user timeout" in general + and for any outstanding calls, delete the TCB, enter the CLOSED + state and return. + + RETRANSMISSION TIMEOUT + + For any state if the retransmission timeout expires on a segment in + the retransmission queue, send the segment at the front of the + retransmission queue again, reinitialize the retransmission timer, + and return. + + TIME-WAIT TIMEOUT + + If the time-wait timeout expires on a connection delete the TCB, + enter the CLOSED state and return. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 77] + + + September 1981 +Transmission Control Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 78] + + +September 1981 + Transmission Control Protocol + + + + GLOSSARY + + + +1822 + BBN Report 1822, "The Specification of the Interconnection of + a Host and an IMP". The specification of interface between a + host and the ARPANET. + +ACK + A control bit (acknowledge) occupying no sequence space, which + indicates that the acknowledgment field of this segment + specifies the next sequence number the sender of this segment + is expecting to receive, hence acknowledging receipt of all + previous sequence numbers. + +ARPANET message + The unit of transmission between a host and an IMP in the + ARPANET. The maximum size is about 1012 octets (8096 bits). + +ARPANET packet + A unit of transmission used internally in the ARPANET between + IMPs. The maximum size is about 126 octets (1008 bits). + +connection + A logical communication path identified by a pair of sockets. + +datagram + A message sent in a packet switched computer communications + network. + +Destination Address + The destination address, usually the network and host + identifiers. + +FIN + A control bit (finis) occupying one sequence number, which + indicates that the sender will send no more data or control + occupying sequence space. + +fragment + A portion of a logical unit of data, in particular an internet + fragment is a portion of an internet datagram. + +FTP + A file transfer protocol. + + + + + + [Page 79] + + + September 1981 +Transmission Control Protocol +Glossary + + + +header + Control information at the beginning of a message, segment, + fragment, packet or block of data. + +host + A computer. In particular a source or destination of messages + from the point of view of the communication network. + +Identification + An Internet Protocol field. This identifying value assigned + by the sender aids in assembling the fragments of a datagram. + +IMP + The Interface Message Processor, the packet switch of the + ARPANET. + +internet address + A source or destination address specific to the host level. + +internet datagram + The unit of data exchanged between an internet module and the + higher level protocol together with the internet header. + +internet fragment + A portion of the data of an internet datagram with an internet + header. + +IP + Internet Protocol. + +IRS + The Initial Receive Sequence number. The first sequence + number used by the sender on a connection. + +ISN + The Initial Sequence Number. The first sequence number used + on a connection, (either ISS or IRS). Selected on a clock + based procedure. + +ISS + The Initial Send Sequence number. The first sequence number + used by the sender on a connection. + +leader + Control information at the beginning of a message or block of + data. In particular, in the ARPANET, the control information + on an ARPANET message at the host-IMP interface. + + + +[Page 80] + + +September 1981 + Transmission Control Protocol + Glossary + + + +left sequence + This is the next sequence number to be acknowledged by the + data receiving TCP (or the lowest currently unacknowledged + sequence number) and is sometimes referred to as the left edge + of the send window. + +local packet + The unit of transmission within a local network. + +module + An implementation, usually in software, of a protocol or other + procedure. + +MSL + Maximum Segment Lifetime, the time a TCP segment can exist in + the internetwork system. Arbitrarily defined to be 2 minutes. + +octet + An eight bit byte. + +Options + An Option field may contain several options, and each option + may be several octets in length. The options are used + primarily in testing situations; for example, to carry + timestamps. Both the Internet Protocol and TCP provide for + options fields. + +packet + A package of data with a header which may or may not be + logically complete. More often a physical packaging than a + logical packaging of data. + +port + The portion of a socket that specifies which logical input or + output channel of a process is associated with the data. + +process + A program in execution. A source or destination of data from + the point of view of the TCP or other host-to-host protocol. + +PUSH + A control bit occupying no sequence space, indicating that + this segment contains data that must be pushed through to the + receiving user. + +RCV.NXT + receive next sequence number + + + + [Page 81] + + + September 1981 +Transmission Control Protocol +Glossary + + + +RCV.UP + receive urgent pointer + +RCV.WND + receive window + +receive next sequence number + This is the next sequence number the local TCP is expecting to + receive. + +receive window + This represents the sequence numbers the local (receiving) TCP + is willing to receive. Thus, the local TCP considers that + segments overlapping the range RCV.NXT to + RCV.NXT + RCV.WND - 1 carry acceptable data or control. + Segments containing sequence numbers entirely outside of this + range are considered duplicates and discarded. + +RST + A control bit (reset), occupying no sequence space, indicating + that the receiver should delete the connection without further + interaction. The receiver can determine, based on the + sequence number and acknowledgment fields of the incoming + segment, whether it should honor the reset command or ignore + it. In no case does receipt of a segment containing RST give + rise to a RST in response. + +RTP + Real Time Protocol: A host-to-host protocol for communication + of time critical information. + +SEG.ACK + segment acknowledgment + +SEG.LEN + segment length + +SEG.PRC + segment precedence value + +SEG.SEQ + segment sequence + +SEG.UP + segment urgent pointer field + + + + + +[Page 82] + + +September 1981 + Transmission Control Protocol + Glossary + + + +SEG.WND + segment window field + +segment + A logical unit of data, in particular a TCP segment is the + unit of data transfered between a pair of TCP modules. + +segment acknowledgment + The sequence number in the acknowledgment field of the + arriving segment. + +segment length + The amount of sequence number space occupied by a segment, + including any controls which occupy sequence space. + +segment sequence + The number in the sequence field of the arriving segment. + +send sequence + This is the next sequence number the local (sending) TCP will + use on the connection. It is initially selected from an + initial sequence number curve (ISN) and is incremented for + each octet of data or sequenced control transmitted. + +send window + This represents the sequence numbers which the remote + (receiving) TCP is willing to receive. It is the value of the + window field specified in segments from the remote (data + receiving) TCP. The range of new sequence numbers which may + be emitted by a TCP lies between SND.NXT and + SND.UNA + SND.WND - 1. (Retransmissions of sequence numbers + between SND.UNA and SND.NXT are expected, of course.) + +SND.NXT + send sequence + +SND.UNA + left sequence + +SND.UP + send urgent pointer + +SND.WL1 + segment sequence number at last window update + +SND.WL2 + segment acknowledgment number at last window update + + + + [Page 83] + + + September 1981 +Transmission Control Protocol +Glossary + + + +SND.WND + send window + +socket + An address which specifically includes a port identifier, that + is, the concatenation of an Internet Address with a TCP port. + +Source Address + The source address, usually the network and host identifiers. + +SYN + A control bit in the incoming segment, occupying one sequence + number, used at the initiation of a connection, to indicate + where the sequence numbering will start. + +TCB + Transmission control block, the data structure that records + the state of a connection. + +TCB.PRC + The precedence of the connection. + +TCP + Transmission Control Protocol: A host-to-host protocol for + reliable communication in internetwork environments. + +TOS + Type of Service, an Internet Protocol field. + +Type of Service + An Internet Protocol field which indicates the type of service + for this internet fragment. + +URG + A control bit (urgent), occupying no sequence space, used to + indicate that the receiving user should be notified to do + urgent processing as long as there is data to be consumed with + sequence numbers less than the value indicated in the urgent + pointer. + +urgent pointer + A control field meaningful only when the URG bit is on. This + field communicates the value of the urgent pointer which + indicates the data octet associated with the sending user's + urgent call. + + + + + +[Page 84] + + +September 1981 + Transmission Control Protocol + + + + REFERENCES + + + +[1] Cerf, V., and R. Kahn, "A Protocol for Packet Network + Intercommunication", IEEE Transactions on Communications, + Vol. COM-22, No. 5, pp 637-648, May 1974. + +[2] Postel, J. (ed.), "Internet Protocol - DARPA Internet Program + Protocol Specification", RFC 791, USC/Information Sciences + Institute, September 1981. + +[3] Dalal, Y. and C. Sunshine, "Connection Management in Transport + Protocols", Computer Networks, Vol. 2, No. 6, pp. 454-473, + December 1978. + +[4] Postel, J., "Assigned Numbers", RFC 790, USC/Information Sciences + Institute, September 1981. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Page 85] + + + diff --git a/doc/rfc/std9.txt b/doc/rfc/std9.txt new file mode 100644 index 00000000..2357b82f --- /dev/null +++ b/doc/rfc/std9.txt @@ -0,0 +1,3934 @@ + +Network Working Group J. Postel +Request for Comments: 959 J. Reynolds + ISI +Obsoletes RFC: 765 (IEN 149) October 1985 + + FILE TRANSFER PROTOCOL (FTP) + + +Status of this Memo + + This memo is the official specification of the File Transfer + Protocol (FTP). Distribution of this memo is unlimited. + + The following new optional commands are included in this edition of + the specification: + + CDUP (Change to Parent Directory), SMNT (Structure Mount), STOU + (Store Unique), RMD (Remove Directory), MKD (Make Directory), PWD + (Print Directory), and SYST (System). + + Note that this specification is compatible with the previous edition. + +1. INTRODUCTION + + The objectives of FTP are 1) to promote sharing of files (computer + programs and/or data), 2) to encourage indirect or implicit (via + programs) use of remote computers, 3) to shield a user from + variations in file storage systems among hosts, and 4) to transfer + data reliably and efficiently. FTP, though usable directly by a user + at a terminal, is designed mainly for use by programs. + + The attempt in this specification is to satisfy the diverse needs of + users of maxi-hosts, mini-hosts, personal workstations, and TACs, + with a simple, and easily implemented protocol design. + + This paper assumes knowledge of the Transmission Control Protocol + (TCP) [2] and the Telnet Protocol [3]. These documents are contained + in the ARPA-Internet protocol handbook [1]. + +2. OVERVIEW + + In this section, the history, the terminology, and the FTP model are + discussed. The terms defined in this section are only those that + have special significance in FTP. Some of the terminology is very + specific to the FTP model; some readers may wish to turn to the + section on the FTP model while reviewing the terminology. + + + + + + + +Postel & Reynolds [Page 1] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 2.1. HISTORY + + FTP has had a long evolution over the years. Appendix III is a + chronological compilation of Request for Comments documents + relating to FTP. These include the first proposed file transfer + mechanisms in 1971 that were developed for implementation on hosts + at M.I.T. (RFC 114), plus comments and discussion in RFC 141. + + RFC 172 provided a user-level oriented protocol for file transfer + between host computers (including terminal IMPs). A revision of + this as RFC 265, restated FTP for additional review, while RFC 281 + suggested further changes. The use of a "Set Data Type" + transaction was proposed in RFC 294 in January 1982. + + RFC 354 obsoleted RFCs 264 and 265. The File Transfer Protocol + was now defined as a protocol for file transfer between HOSTs on + the ARPANET, with the primary function of FTP defined as + transfering files efficiently and reliably among hosts and + allowing the convenient use of remote file storage capabilities. + RFC 385 further commented on errors, emphasis points, and + additions to the protocol, while RFC 414 provided a status report + on the working server and user FTPs. RFC 430, issued in 1973, + (among other RFCs too numerous to mention) presented further + comments on FTP. Finally, an "official" FTP document was + published as RFC 454. + + By July 1973, considerable changes from the last versions of FTP + were made, but the general structure remained the same. RFC 542 + was published as a new "official" specification to reflect these + changes. However, many implementations based on the older + specification were not updated. + + In 1974, RFCs 607 and 614 continued comments on FTP. RFC 624 + proposed further design changes and minor modifications. In 1975, + RFC 686 entitled, "Leaving Well Enough Alone", discussed the + differences between all of the early and later versions of FTP. + RFC 691 presented a minor revision of RFC 686, regarding the + subject of print files. + + Motivated by the transition from the NCP to the TCP as the + underlying protocol, a phoenix was born out of all of the above + efforts in RFC 765 as the specification of FTP for use on TCP. + + This current edition of the FTP specification is intended to + correct some minor documentation errors, to improve the + explanation of some protocol features, and to add some new + optional commands. + + +Postel & Reynolds [Page 2] + + + +RFC 959 October 1985 +File Transfer Protocol + + + In particular, the following new optional commands are included in + this edition of the specification: + + CDUP - Change to Parent Directory + + SMNT - Structure Mount + + STOU - Store Unique + + RMD - Remove Directory + + MKD - Make Directory + + PWD - Print Directory + + SYST - System + + This specification is compatible with the previous edition. A + program implemented in conformance to the previous specification + should automatically be in conformance to this specification. + + 2.2. TERMINOLOGY + + ASCII + + The ASCII character set is as defined in the ARPA-Internet + Protocol Handbook. In FTP, ASCII characters are defined to be + the lower half of an eight-bit code set (i.e., the most + significant bit is zero). + + access controls + + Access controls define users' access privileges to the use of a + system, and to the files in that system. Access controls are + necessary to prevent unauthorized or accidental use of files. + It is the prerogative of a server-FTP process to invoke access + controls. + + byte size + + There are two byte sizes of interest in FTP: the logical byte + size of the file, and the transfer byte size used for the + transmission of the data. The transfer byte size is always 8 + bits. The transfer byte size is not necessarily the byte size + in which data is to be stored in a system, nor the logical byte + size for interpretation of the structure of the data. + + + +Postel & Reynolds [Page 3] + + + +RFC 959 October 1985 +File Transfer Protocol + + + control connection + + The communication path between the USER-PI and SERVER-PI for + the exchange of commands and replies. This connection follows + the Telnet Protocol. + + data connection + + A full duplex connection over which data is transferred, in a + specified mode and type. The data transferred may be a part of + a file, an entire file or a number of files. The path may be + between a server-DTP and a user-DTP, or between two + server-DTPs. + + data port + + The passive data transfer process "listens" on the data port + for a connection from the active transfer process in order to + open the data connection. + + DTP + + The data transfer process establishes and manages the data + connection. The DTP can be passive or active. + + End-of-Line + + The end-of-line sequence defines the separation of printing + lines. The sequence is Carriage Return, followed by Line Feed. + + EOF + + The end-of-file condition that defines the end of a file being + transferred. + + EOR + + The end-of-record condition that defines the end of a record + being transferred. + + error recovery + + A procedure that allows a user to recover from certain errors + such as failure of either host system or transfer process. In + FTP, error recovery may involve restarting a file transfer at a + given checkpoint. + + + +Postel & Reynolds [Page 4] + + + +RFC 959 October 1985 +File Transfer Protocol + + + FTP commands + + A set of commands that comprise the control information flowing + from the user-FTP to the server-FTP process. + + file + + An ordered set of computer data (including programs), of + arbitrary length, uniquely identified by a pathname. + + mode + + The mode in which data is to be transferred via the data + connection. The mode defines the data format during transfer + including EOR and EOF. The transfer modes defined in FTP are + described in the Section on Transmission Modes. + + NVT + + The Network Virtual Terminal as defined in the Telnet Protocol. + + NVFS + + The Network Virtual File System. A concept which defines a + standard network file system with standard commands and + pathname conventions. + + page + + A file may be structured as a set of independent parts called + pages. FTP supports the transmission of discontinuous files as + independent indexed pages. + + pathname + + Pathname is defined to be the character string which must be + input to a file system by a user in order to identify a file. + Pathname normally contains device and/or directory names, and + file name specification. FTP does not yet specify a standard + pathname convention. Each user must follow the file naming + conventions of the file systems involved in the transfer. + + PI + + The protocol interpreter. The user and server sides of the + protocol have distinct roles implemented in a user-PI and a + server-PI. + + +Postel & Reynolds [Page 5] + + + +RFC 959 October 1985 +File Transfer Protocol + + + record + + A sequential file may be structured as a number of contiguous + parts called records. Record structures are supported by FTP + but a file need not have record structure. + + reply + + A reply is an acknowledgment (positive or negative) sent from + server to user via the control connection in response to FTP + commands. The general form of a reply is a completion code + (including error codes) followed by a text string. The codes + are for use by programs and the text is usually intended for + human users. + + server-DTP + + The data transfer process, in its normal "active" state, + establishes the data connection with the "listening" data port. + It sets up parameters for transfer and storage, and transfers + data on command from its PI. The DTP can be placed in a + "passive" state to listen for, rather than initiate a + connection on the data port. + + server-FTP process + + A process or set of processes which perform the function of + file transfer in cooperation with a user-FTP process and, + possibly, another server. The functions consist of a protocol + interpreter (PI) and a data transfer process (DTP). + + server-PI + + The server protocol interpreter "listens" on Port L for a + connection from a user-PI and establishes a control + communication connection. It receives standard FTP commands + from the user-PI, sends replies, and governs the server-DTP. + + type + + The data representation type used for data transfer and + storage. Type implies certain transformations between the time + of data storage and data transfer. The representation types + defined in FTP are described in the Section on Establishing + Data Connections. + + + + +Postel & Reynolds [Page 6] + + + +RFC 959 October 1985 +File Transfer Protocol + + + user + + A person or a process on behalf of a person wishing to obtain + file transfer service. The human user may interact directly + with a server-FTP process, but use of a user-FTP process is + preferred since the protocol design is weighted towards + automata. + + user-DTP + + The data transfer process "listens" on the data port for a + connection from a server-FTP process. If two servers are + transferring data between them, the user-DTP is inactive. + + user-FTP process + + A set of functions including a protocol interpreter, a data + transfer process and a user interface which together perform + the function of file transfer in cooperation with one or more + server-FTP processes. The user interface allows a local + language to be used in the command-reply dialogue with the + user. + + user-PI + + The user protocol interpreter initiates the control connection + from its port U to the server-FTP process, initiates FTP + commands, and governs the user-DTP if that process is part of + the file transfer. + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 7] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 2.3. THE FTP MODEL + + With the above definitions in mind, the following model (shown in + Figure 1) may be diagrammed for an FTP service. + + ------------- + |/---------\| + || User || -------- + ||Interface|<--->| User | + |\----^----/| -------- + ---------- | | | + |/------\| FTP Commands |/----V----\| + ||Server|<---------------->| User || + || PI || FTP Replies || PI || + |\--^---/| |\----^----/| + | | | | | | + -------- |/--V---\| Data |/----V----\| -------- + | File |<--->|Server|<---------------->| User |<--->| File | + |System| || DTP || Connection || DTP || |System| + -------- |\------/| |\---------/| -------- + ---------- ------------- + + Server-FTP USER-FTP + + NOTES: 1. The data connection may be used in either direction. + 2. The data connection need not exist all of the time. + + Figure 1 Model for FTP Use + + In the model described in Figure 1, the user-protocol interpreter + initiates the control connection. The control connection follows + the Telnet protocol. At the initiation of the user, standard FTP + commands are generated by the user-PI and transmitted to the + server process via the control connection. (The user may + establish a direct control connection to the server-FTP, from a + TAC terminal for example, and generate standard FTP commands + independently, bypassing the user-FTP process.) Standard replies + are sent from the server-PI to the user-PI over the control + connection in response to the commands. + + The FTP commands specify the parameters for the data connection + (data port, transfer mode, representation type, and structure) and + the nature of file system operation (store, retrieve, append, + delete, etc.). The user-DTP or its designate should "listen" on + the specified data port, and the server initiate the data + connection and data transfer in accordance with the specified + parameters. It should be noted that the data port need not be in + + +Postel & Reynolds [Page 8] + + + +RFC 959 October 1985 +File Transfer Protocol + + + the same host that initiates the FTP commands via the control + connection, but the user or the user-FTP process must ensure a + "listen" on the specified data port. It ought to also be noted + that the data connection may be used for simultaneous sending and + receiving. + + In another situation a user might wish to transfer files between + two hosts, neither of which is a local host. The user sets up + control connections to the two servers and then arranges for a + data connection between them. In this manner, control information + is passed to the user-PI but data is transferred between the + server data transfer processes. Following is a model of this + server-server interaction. + + + Control ------------ Control + ---------->| User-FTP |<----------- + | | User-PI | | + | | "C" | | + V ------------ V + -------------- -------------- + | Server-FTP | Data Connection | Server-FTP | + | "A" |<---------------------->| "B" | + -------------- Port (A) Port (B) -------------- + + + Figure 2 + + The protocol requires that the control connections be open while + data transfer is in progress. It is the responsibility of the + user to request the closing of the control connections when + finished using the FTP service, while it is the server who takes + the action. The server may abort data transfer if the control + connections are closed without command. + + The Relationship between FTP and Telnet: + + The FTP uses the Telnet protocol on the control connection. + This can be achieved in two ways: first, the user-PI or the + server-PI may implement the rules of the Telnet Protocol + directly in their own procedures; or, second, the user-PI or + the server-PI may make use of the existing Telnet module in the + system. + + Ease of implementaion, sharing code, and modular programming + argue for the second approach. Efficiency and independence + + + +Postel & Reynolds [Page 9] + + + +RFC 959 October 1985 +File Transfer Protocol + + + argue for the first approach. In practice, FTP relies on very + little of the Telnet Protocol, so the first approach does not + necessarily involve a large amount of code. + +3. DATA TRANSFER FUNCTIONS + + Files are transferred only via the data connection. The control + connection is used for the transfer of commands, which describe the + functions to be performed, and the replies to these commands (see the + Section on FTP Replies). Several commands are concerned with the + transfer of data between hosts. These data transfer commands include + the MODE command which specify how the bits of the data are to be + transmitted, and the STRUcture and TYPE commands, which are used to + define the way in which the data are to be represented. The + transmission and representation are basically independent but the + "Stream" transmission mode is dependent on the file structure + attribute and if "Compressed" transmission mode is used, the nature + of the filler byte depends on the representation type. + + 3.1. DATA REPRESENTATION AND STORAGE + + Data is transferred from a storage device in the sending host to a + storage device in the receiving host. Often it is necessary to + perform certain transformations on the data because data storage + representations in the two systems are different. For example, + NVT-ASCII has different data storage representations in different + systems. DEC TOPS-20s's generally store NVT-ASCII as five 7-bit + ASCII characters, left-justified in a 36-bit word. IBM Mainframe's + store NVT-ASCII as 8-bit EBCDIC codes. Multics stores NVT-ASCII + as four 9-bit characters in a 36-bit word. It is desirable to + convert characters into the standard NVT-ASCII representation when + transmitting text between dissimilar systems. The sending and + receiving sites would have to perform the necessary + transformations between the standard representation and their + internal representations. + + A different problem in representation arises when transmitting + binary data (not character codes) between host systems with + different word lengths. It is not always clear how the sender + should send data, and the receiver store it. For example, when + transmitting 32-bit bytes from a 32-bit word-length system to a + 36-bit word-length system, it may be desirable (for reasons of + efficiency and usefulness) to store the 32-bit bytes + right-justified in a 36-bit word in the latter system. In any + case, the user should have the option of specifying data + representation and transformation functions. It should be noted + + + +Postel & Reynolds [Page 10] + + + +RFC 959 October 1985 +File Transfer Protocol + + + that FTP provides for very limited data type representations. + Transformations desired beyond this limited capability should be + performed by the user directly. + + 3.1.1. DATA TYPES + + Data representations are handled in FTP by a user specifying a + representation type. This type may implicitly (as in ASCII or + EBCDIC) or explicitly (as in Local byte) define a byte size for + interpretation which is referred to as the "logical byte size." + Note that this has nothing to do with the byte size used for + transmission over the data connection, called the "transfer + byte size", and the two should not be confused. For example, + NVT-ASCII has a logical byte size of 8 bits. If the type is + Local byte, then the TYPE command has an obligatory second + parameter specifying the logical byte size. The transfer byte + size is always 8 bits. + + 3.1.1.1. ASCII TYPE + + This is the default type and must be accepted by all FTP + implementations. It is intended primarily for the transfer + of text files, except when both hosts would find the EBCDIC + type more convenient. + + The sender converts the data from an internal character + representation to the standard 8-bit NVT-ASCII + representation (see the Telnet specification). The receiver + will convert the data from the standard form to his own + internal form. + + In accordance with the NVT standard, the sequence + should be used where necessary to denote the end of a line + of text. (See the discussion of file structure at the end + of the Section on Data Representation and Storage.) + + Using the standard NVT-ASCII representation means that data + must be interpreted as 8-bit bytes. + + The Format parameter for ASCII and EBCDIC types is discussed + below. + + + + + + + + +Postel & Reynolds [Page 11] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 3.1.1.2. EBCDIC TYPE + + This type is intended for efficient transfer between hosts + which use EBCDIC for their internal character + representation. + + For transmission, the data are represented as 8-bit EBCDIC + characters. The character code is the only difference + between the functional specifications of EBCDIC and ASCII + types. + + End-of-line (as opposed to end-of-record--see the discussion + of structure) will probably be rarely used with EBCDIC type + for purposes of denoting structure, but where it is + necessary the character should be used. + + 3.1.1.3. IMAGE TYPE + + The data are sent as contiguous bits which, for transfer, + are packed into the 8-bit transfer bytes. The receiving + site must store the data as contiguous bits. The structure + of the storage system might necessitate the padding of the + file (or of each record, for a record-structured file) to + some convenient boundary (byte, word or block). This + padding, which must be all zeros, may occur only at the end + of the file (or at the end of each record) and there must be + a way of identifying the padding bits so that they may be + stripped off if the file is retrieved. The padding + transformation should be well publicized to enable a user to + process a file at the storage site. + + Image type is intended for the efficient storage and + retrieval of files and for the transfer of binary data. It + is recommended that this type be accepted by all FTP + implementations. + + 3.1.1.4. LOCAL TYPE + + The data is transferred in logical bytes of the size + specified by the obligatory second parameter, Byte size. + The value of Byte size must be a decimal integer; there is + no default value. The logical byte size is not necessarily + the same as the transfer byte size. If there is a + difference in byte sizes, then the logical bytes should be + packed contiguously, disregarding transfer byte boundaries + and with any necessary padding at the end. + + + +Postel & Reynolds [Page 12] + + + +RFC 959 October 1985 +File Transfer Protocol + + + When the data reaches the receiving host, it will be + transformed in a manner dependent on the logical byte size + and the particular host. This transformation must be + invertible (i.e., an identical file can be retrieved if the + same parameters are used) and should be well publicized by + the FTP implementors. + + For example, a user sending 36-bit floating-point numbers to + a host with a 32-bit word could send that data as Local byte + with a logical byte size of 36. The receiving host would + then be expected to store the logical bytes so that they + could be easily manipulated; in this example putting the + 36-bit logical bytes into 64-bit double words should + suffice. + + In another example, a pair of hosts with a 36-bit word size + may send data to one another in words by using TYPE L 36. + The data would be sent in the 8-bit transmission bytes + packed so that 9 transmission bytes carried two host words. + + 3.1.1.5. FORMAT CONTROL + + The types ASCII and EBCDIC also take a second (optional) + parameter; this is to indicate what kind of vertical format + control, if any, is associated with a file. The following + data representation types are defined in FTP: + + A character file may be transferred to a host for one of + three purposes: for printing, for storage and later + retrieval, or for processing. If a file is sent for + printing, the receiving host must know how the vertical + format control is represented. In the second case, it must + be possible to store a file at a host and then retrieve it + later in exactly the same form. Finally, it should be + possible to move a file from one host to another and process + the file at the second host without undue trouble. A single + ASCII or EBCDIC format does not satisfy all these + conditions. Therefore, these types have a second parameter + specifying one of the following three formats: + + 3.1.1.5.1. NON PRINT + + This is the default format to be used if the second + (format) parameter is omitted. Non-print format must be + accepted by all FTP implementations. + + + + +Postel & Reynolds [Page 13] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The file need contain no vertical format information. If + it is passed to a printer process, this process may + assume standard values for spacing and margins. + + Normally, this format will be used with files destined + for processing or just storage. + + 3.1.1.5.2. TELNET FORMAT CONTROLS + + The file contains ASCII/EBCDIC vertical format controls + (i.e., , , , , ) which the printer + process will interpret appropriately. , in exactly + this sequence, also denotes end-of-line. + + 3.1.1.5.2. CARRIAGE CONTROL (ASA) + + The file contains ASA (FORTRAN) vertical format control + characters. (See RFC 740 Appendix C; and Communications + of the ACM, Vol. 7, No. 10, p. 606, October 1964.) In a + line or a record formatted according to the ASA Standard, + the first character is not to be printed. Instead, it + should be used to determine the vertical movement of the + paper which should take place before the rest of the + record is printed. + + The ASA Standard specifies the following control + characters: + + Character Vertical Spacing + + blank Move paper up one line + 0 Move paper up two lines + 1 Move paper to top of next page + + No movement, i.e., overprint + + Clearly there must be some way for a printer process to + distinguish the end of the structural entity. If a file + has record structure (see below) this is no problem; + records will be explicitly marked during transfer and + storage. If the file has no record structure, the + end-of-line sequence is used to separate printing lines, + but these format effectors are overridden by the ASA + controls. + + + + + + +Postel & Reynolds [Page 14] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 3.1.2. DATA STRUCTURES + + In addition to different representation types, FTP allows the + structure of a file to be specified. Three file structures are + defined in FTP: + + file-structure, where there is no internal structure and + the file is considered to be a + continuous sequence of data bytes, + + record-structure, where the file is made up of sequential + records, + + and page-structure, where the file is made up of independent + indexed pages. + + File-structure is the default to be assumed if the STRUcture + command has not been used but both file and record structures + must be accepted for "text" files (i.e., files with TYPE ASCII + or EBCDIC) by all FTP implementations. The structure of a file + will affect both the transfer mode of a file (see the Section + on Transmission Modes) and the interpretation and storage of + the file. + + The "natural" structure of a file will depend on which host + stores the file. A source-code file will usually be stored on + an IBM Mainframe in fixed length records but on a DEC TOPS-20 + as a stream of characters partitioned into lines, for example + by . If the transfer of files between such disparate + sites is to be useful, there must be some way for one site to + recognize the other's assumptions about the file. + + With some sites being naturally file-oriented and others + naturally record-oriented there may be problems if a file with + one structure is sent to a host oriented to the other. If a + text file is sent with record-structure to a host which is file + oriented, then that host should apply an internal + transformation to the file based on the record structure. + Obviously, this transformation should be useful, but it must + also be invertible so that an identical file may be retrieved + using record structure. + + In the case of a file being sent with file-structure to a + record-oriented host, there exists the question of what + criteria the host should use to divide the file into records + which can be processed locally. If this division is necessary, + the FTP implementation should use the end-of-line sequence, + + +Postel & Reynolds [Page 15] + + + +RFC 959 October 1985 +File Transfer Protocol + + + for ASCII, or for EBCDIC text files, as the + delimiter. If an FTP implementation adopts this technique, it + must be prepared to reverse the transformation if the file is + retrieved with file-structure. + + 3.1.2.1. FILE STRUCTURE + + File structure is the default to be assumed if the STRUcture + command has not been used. + + In file-structure there is no internal structure and the + file is considered to be a continuous sequence of data + bytes. + + 3.1.2.2. RECORD STRUCTURE + + Record structures must be accepted for "text" files (i.e., + files with TYPE ASCII or EBCDIC) by all FTP implementations. + + In record-structure the file is made up of sequential + records. + + 3.1.2.3. PAGE STRUCTURE + + To transmit files that are discontinuous, FTP defines a page + structure. Files of this type are sometimes known as + "random access files" or even as "holey files". In these + files there is sometimes other information associated with + the file as a whole (e.g., a file descriptor), or with a + section of the file (e.g., page access controls), or both. + In FTP, the sections of the file are called pages. + + To provide for various page sizes and associated + information, each page is sent with a page header. The page + header has the following defined fields: + + Header Length + + The number of logical bytes in the page header + including this byte. The minimum header length is 4. + + Page Index + + The logical page number of this section of the file. + This is not the transmission sequence number of this + page, but the index used to identify this page of the + file. + + +Postel & Reynolds [Page 16] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Data Length + + The number of logical bytes in the page data. The + minimum data length is 0. + + Page Type + + The type of page this is. The following page types + are defined: + + 0 = Last Page + + This is used to indicate the end of a paged + structured transmission. The header length must + be 4, and the data length must be 0. + + 1 = Simple Page + + This is the normal type for simple paged files + with no page level associated control + information. The header length must be 4. + + 2 = Descriptor Page + + This type is used to transmit the descriptive + information for the file as a whole. + + 3 = Access Controlled Page + + This type includes an additional header field + for paged files with page level access control + information. The header length must be 5. + + Optional Fields + + Further header fields may be used to supply per page + control information, for example, per page access + control. + + All fields are one logical byte in length. The logical byte + size is specified by the TYPE command. See Appendix I for + further details and a specific case at the page structure. + + A note of caution about parameters: a file must be stored and + retrieved with the same parameters if the retrieved version is to + + + + +Postel & Reynolds [Page 17] + + + +RFC 959 October 1985 +File Transfer Protocol + + + be identical to the version originally transmitted. Conversely, + FTP implementations must return a file identical to the original + if the parameters used to store and retrieve a file are the same. + + 3.2. ESTABLISHING DATA CONNECTIONS + + The mechanics of transferring data consists of setting up the data + connection to the appropriate ports and choosing the parameters + for transfer. Both the user and the server-DTPs have a default + data port. The user-process default data port is the same as the + control connection port (i.e., U). The server-process default + data port is the port adjacent to the control connection port + (i.e., L-1). + + The transfer byte size is 8-bit bytes. This byte size is relevant + only for the actual transfer of the data; it has no bearing on + representation of the data within a host's file system. + + The passive data transfer process (this may be a user-DTP or a + second server-DTP) shall "listen" on the data port prior to + sending a transfer request command. The FTP request command + determines the direction of the data transfer. The server, upon + receiving the transfer request, will initiate the data connection + to the port. When the connection is established, the data + transfer begins between DTP's, and the server-PI sends a + confirming reply to the user-PI. + + Every FTP implementation must support the use of the default data + ports, and only the USER-PI can initiate a change to non-default + ports. + + It is possible for the user to specify an alternate data port by + use of the PORT command. The user may want a file dumped on a TAC + line printer or retrieved from a third party host. In the latter + case, the user-PI sets up control connections with both + server-PI's. One server is then told (by an FTP command) to + "listen" for a connection which the other will initiate. The + user-PI sends one server-PI a PORT command indicating the data + port of the other. Finally, both are sent the appropriate + transfer commands. The exact sequence of commands and replies + sent between the user-controller and the servers is defined in the + Section on FTP Replies. + + In general, it is the server's responsibility to maintain the data + connection--to initiate it and to close it. The exception to this + + + + +Postel & Reynolds [Page 18] + + + +RFC 959 October 1985 +File Transfer Protocol + + + is when the user-DTP is sending the data in a transfer mode that + requires the connection to be closed to indicate EOF. The server + MUST close the data connection under the following conditions: + + 1. The server has completed sending data in a transfer mode + that requires a close to indicate EOF. + + 2. The server receives an ABORT command from the user. + + 3. The port specification is changed by a command from the + user. + + 4. The control connection is closed legally or otherwise. + + 5. An irrecoverable error condition occurs. + + Otherwise the close is a server option, the exercise of which the + server must indicate to the user-process by either a 250 or 226 + reply only. + + 3.3. DATA CONNECTION MANAGEMENT + + Default Data Connection Ports: All FTP implementations must + support use of the default data connection ports, and only the + User-PI may initiate the use of non-default ports. + + Negotiating Non-Default Data Ports: The User-PI may specify a + non-default user side data port with the PORT command. The + User-PI may request the server side to identify a non-default + server side data port with the PASV command. Since a connection + is defined by the pair of addresses, either of these actions is + enough to get a different data connection, still it is permitted + to do both commands to use new ports on both ends of the data + connection. + + Reuse of the Data Connection: When using the stream mode of data + transfer the end of the file must be indicated by closing the + connection. This causes a problem if multiple files are to be + transfered in the session, due to need for TCP to hold the + connection record for a time out period to guarantee the reliable + communication. Thus the connection can not be reopened at once. + + There are two solutions to this problem. The first is to + negotiate a non-default port. The second is to use another + transfer mode. + + A comment on transfer modes. The stream transfer mode is + + +Postel & Reynolds [Page 19] + + + +RFC 959 October 1985 +File Transfer Protocol + + + inherently unreliable, since one can not determine if the + connection closed prematurely or not. The other transfer modes + (Block, Compressed) do not close the connection to indicate the + end of file. They have enough FTP encoding that the data + connection can be parsed to determine the end of the file. + Thus using these modes one can leave the data connection open + for multiple file transfers. + + 3.4. TRANSMISSION MODES + + The next consideration in transferring data is choosing the + appropriate transmission mode. There are three modes: one which + formats the data and allows for restart procedures; one which also + compresses the data for efficient transfer; and one which passes + the data with little or no processing. In this last case the mode + interacts with the structure attribute to determine the type of + processing. In the compressed mode, the representation type + determines the filler byte. + + All data transfers must be completed with an end-of-file (EOF) + which may be explicitly stated or implied by the closing of the + data connection. For files with record structure, all the + end-of-record markers (EOR) are explicit, including the final one. + For files transmitted in page structure a "last-page" page type is + used. + + NOTE: In the rest of this section, byte means "transfer byte" + except where explicitly stated otherwise. + + For the purpose of standardized transfer, the sending host will + translate its internal end of line or end of record denotation + into the representation prescribed by the transfer mode and file + structure, and the receiving host will perform the inverse + translation to its internal denotation. An IBM Mainframe record + count field may not be recognized at another host, so the + end-of-record information may be transferred as a two byte control + code in Stream mode or as a flagged bit in a Block or Compressed + mode descriptor. End-of-line in an ASCII or EBCDIC file with no + record structure should be indicated by or , + respectively. Since these transformations imply extra work for + some systems, identical systems transferring non-record structured + text files might wish to use a binary representation and stream + mode for the transfer. + + + + + + +Postel & Reynolds [Page 20] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The following transmission modes are defined in FTP: + + 3.4.1. STREAM MODE + + The data is transmitted as a stream of bytes. There is no + restriction on the representation type used; record structures + are allowed. + + In a record structured file EOR and EOF will each be indicated + by a two-byte control code. The first byte of the control code + will be all ones, the escape character. The second byte will + have the low order bit on and zeros elsewhere for EOR and the + second low order bit on for EOF; that is, the byte will have + value 1 for EOR and value 2 for EOF. EOR and EOF may be + indicated together on the last byte transmitted by turning both + low order bits on (i.e., the value 3). If a byte of all ones + was intended to be sent as data, it should be repeated in the + second byte of the control code. + + If the structure is a file structure, the EOF is indicated by + the sending host closing the data connection and all bytes are + data bytes. + + 3.4.2. BLOCK MODE + + The file is transmitted as a series of data blocks preceded by + one or more header bytes. The header bytes contain a count + field, and descriptor code. The count field indicates the + total length of the data block in bytes, thus marking the + beginning of the next data block (there are no filler bits). + The descriptor code defines: last block in the file (EOF) last + block in the record (EOR), restart marker (see the Section on + Error Recovery and Restart) or suspect data (i.e., the data + being transferred is suspected of errors and is not reliable). + This last code is NOT intended for error control within FTP. + It is motivated by the desire of sites exchanging certain types + of data (e.g., seismic or weather data) to send and receive all + the data despite local errors (such as "magnetic tape read + errors"), but to indicate in the transmission that certain + portions are suspect). Record structures are allowed in this + mode, and any representation type may be used. + + The header consists of the three bytes. Of the 24 bits of + header information, the 16 low order bits shall represent byte + count, and the 8 high order bits shall represent descriptor + codes as shown below. + + + +Postel & Reynolds [Page 21] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Block Header + + +----------------+----------------+----------------+ + | Descriptor | Byte Count | + | 8 bits | 16 bits | + +----------------+----------------+----------------+ + + + The descriptor codes are indicated by bit flags in the + descriptor byte. Four codes have been assigned, where each + code number is the decimal value of the corresponding bit in + the byte. + + Code Meaning + + 128 End of data block is EOR + 64 End of data block is EOF + 32 Suspected errors in data block + 16 Data block is a restart marker + + With this encoding, more than one descriptor coded condition + may exist for a particular block. As many bits as necessary + may be flagged. + + The restart marker is embedded in the data stream as an + integral number of 8-bit bytes representing printable + characters in the language being used over the control + connection (e.g., default--NVT-ASCII). (Space, in the + appropriate language) must not be used WITHIN a restart marker. + + For example, to transmit a six-character marker, the following + would be sent: + + +--------+--------+--------+ + |Descrptr| Byte count | + |code= 16| = 6 | + +--------+--------+--------+ + + +--------+--------+--------+ + | Marker | Marker | Marker | + | 8 bits | 8 bits | 8 bits | + +--------+--------+--------+ + + +--------+--------+--------+ + | Marker | Marker | Marker | + | 8 bits | 8 bits | 8 bits | + +--------+--------+--------+ + + +Postel & Reynolds [Page 22] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 3.4.3. COMPRESSED MODE + + There are three kinds of information to be sent: regular data, + sent in a byte string; compressed data, consisting of + replications or filler; and control information, sent in a + two-byte escape sequence. If n>0 bytes (up to 127) of regular + data are sent, these n bytes are preceded by a byte with the + left-most bit set to 0 and the right-most 7 bits containing the + number n. + + Byte string: + + 1 7 8 8 + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + |0| n | | d(1) | ... | d(n) | + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + ^ ^ + |---n bytes---| + of data + + String of n data bytes d(1),..., d(n) + Count n must be positive. + + To compress a string of n replications of the data byte d, the + following 2 bytes are sent: + + Replicated Byte: + + 2 6 8 + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + |1 0| n | | d | + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + + A string of n filler bytes can be compressed into a single + byte, where the filler byte varies with the representation + type. If the type is ASCII or EBCDIC the filler byte is + (Space, ASCII code 32, EBCDIC code 64). If the type is Image + or Local byte the filler is a zero byte. + + Filler String: + + 2 6 + +-+-+-+-+-+-+-+-+ + |1 1| n | + +-+-+-+-+-+-+-+-+ + + The escape sequence is a double byte, the first of which is the + + +Postel & Reynolds [Page 23] + + + +RFC 959 October 1985 +File Transfer Protocol + + + escape byte (all zeros) and the second of which contains + descriptor codes as defined in Block mode. The descriptor + codes have the same meaning as in Block mode and apply to the + succeeding string of bytes. + + Compressed mode is useful for obtaining increased bandwidth on + very large network transmissions at a little extra CPU cost. + It can be most effectively used to reduce the size of printer + files such as those generated by RJE hosts. + + 3.5. ERROR RECOVERY AND RESTART + + There is no provision for detecting bits lost or scrambled in data + transfer; this level of error control is handled by the TCP. + However, a restart procedure is provided to protect users from + gross system failures (including failures of a host, an + FTP-process, or the underlying network). + + The restart procedure is defined only for the block and compressed + modes of data transfer. It requires the sender of data to insert + a special marker code in the data stream with some marker + information. The marker information has meaning only to the + sender, but must consist of printable characters in the default or + negotiated language of the control connection (ASCII or EBCDIC). + The marker could represent a bit-count, a record-count, or any + other information by which a system may identify a data + checkpoint. The receiver of data, if it implements the restart + procedure, would then mark the corresponding position of this + marker in the receiving system, and return this information to the + user. + + In the event of a system failure, the user can restart the data + transfer by identifying the marker point with the FTP restart + procedure. The following example illustrates the use of the + restart procedure. + + The sender of the data inserts an appropriate marker block in the + data stream at a convenient point. The receiving host marks the + corresponding data point in its file system and conveys the last + known sender and receiver marker information to the user, either + directly or over the control connection in a 110 reply (depending + on who is the sender). In the event of a system failure, the user + or controller process restarts the server at the last server + marker by sending a restart command with server's marker code as + its argument. The restart command is transmitted over the control + + + + +Postel & Reynolds [Page 24] + + + +RFC 959 October 1985 +File Transfer Protocol + + + connection and is immediately followed by the command (such as + RETR, STOR or LIST) which was being executed when the system + failure occurred. + +4. FILE TRANSFER FUNCTIONS + + The communication channel from the user-PI to the server-PI is + established as a TCP connection from the user to the standard server + port. The user protocol interpreter is responsible for sending FTP + commands and interpreting the replies received; the server-PI + interprets commands, sends replies and directs its DTP to set up the + data connection and transfer the data. If the second party to the + data transfer (the passive transfer process) is the user-DTP, then it + is governed through the internal protocol of the user-FTP host; if it + is a second server-DTP, then it is governed by its PI on command from + the user-PI. The FTP replies are discussed in the next section. In + the description of a few of the commands in this section, it is + helpful to be explicit about the possible replies. + + 4.1. FTP COMMANDS + + 4.1.1. ACCESS CONTROL COMMANDS + + The following commands specify access control identifiers + (command codes are shown in parentheses). + + USER NAME (USER) + + The argument field is a Telnet string identifying the user. + The user identification is that which is required by the + server for access to its file system. This command will + normally be the first command transmitted by the user after + the control connections are made (some servers may require + this). Additional identification information in the form of + a password and/or an account command may also be required by + some servers. Servers may allow a new USER command to be + entered at any point in order to change the access control + and/or accounting information. This has the effect of + flushing any user, password, and account information already + supplied and beginning the login sequence again. All + transfer parameters are unchanged and any file transfer in + progress is completed under the old access control + parameters. + + + + + + +Postel & Reynolds [Page 25] + + + +RFC 959 October 1985 +File Transfer Protocol + + + PASSWORD (PASS) + + The argument field is a Telnet string specifying the user's + password. This command must be immediately preceded by the + user name command, and, for some sites, completes the user's + identification for access control. Since password + information is quite sensitive, it is desirable in general + to "mask" it or suppress typeout. It appears that the + server has no foolproof way to achieve this. It is + therefore the responsibility of the user-FTP process to hide + the sensitive password information. + + ACCOUNT (ACCT) + + The argument field is a Telnet string identifying the user's + account. The command is not necessarily related to the USER + command, as some sites may require an account for login and + others only for specific access, such as storing files. In + the latter case the command may arrive at any time. + + There are reply codes to differentiate these cases for the + automation: when account information is required for login, + the response to a successful PASSword command is reply code + 332. On the other hand, if account information is NOT + required for login, the reply to a successful PASSword + command is 230; and if the account information is needed for + a command issued later in the dialogue, the server should + return a 332 or 532 reply depending on whether it stores + (pending receipt of the ACCounT command) or discards the + command, respectively. + + CHANGE WORKING DIRECTORY (CWD) + + This command allows the user to work with a different + directory or dataset for file storage or retrieval without + altering his login or accounting information. Transfer + parameters are similarly unchanged. The argument is a + pathname specifying a directory or other system dependent + file group designator. + + CHANGE TO PARENT DIRECTORY (CDUP) + + This command is a special case of CWD, and is included to + simplify the implementation of programs for transferring + directory trees between operating systems having different + + + + +Postel & Reynolds [Page 26] + + + +RFC 959 October 1985 +File Transfer Protocol + + + syntaxes for naming the parent directory. The reply codes + shall be identical to the reply codes of CWD. See + Appendix II for further details. + + STRUCTURE MOUNT (SMNT) + + This command allows the user to mount a different file + system data structure without altering his login or + accounting information. Transfer parameters are similarly + unchanged. The argument is a pathname specifying a + directory or other system dependent file group designator. + + REINITIALIZE (REIN) + + This command terminates a USER, flushing all I/O and account + information, except to allow any transfer in progress to be + completed. All parameters are reset to the default settings + and the control connection is left open. This is identical + to the state in which a user finds himself immediately after + the control connection is opened. A USER command may be + expected to follow. + + LOGOUT (QUIT) + + This command terminates a USER and if file transfer is not + in progress, the server closes the control connection. If + file transfer is in progress, the connection will remain + open for result response and the server will then close it. + If the user-process is transferring files for several USERs + but does not wish to close and then reopen connections for + each, then the REIN command should be used instead of QUIT. + + An unexpected close on the control connection will cause the + server to take the effective action of an abort (ABOR) and a + logout (QUIT). + + 4.1.2. TRANSFER PARAMETER COMMANDS + + All data transfer parameters have default values, and the + commands specifying data transfer parameters are required only + if the default parameter values are to be changed. The default + value is the last specified value, or if no value has been + specified, the standard default value is as stated here. This + implies that the server must "remember" the applicable default + values. The commands may be in any order except that they must + precede the FTP service request. The following commands + specify data transfer parameters: + + +Postel & Reynolds [Page 27] + + + +RFC 959 October 1985 +File Transfer Protocol + + + DATA PORT (PORT) + + The argument is a HOST-PORT specification for the data port + to be used in data connection. There are defaults for both + the user and server data ports, and under normal + circumstances this command and its reply are not needed. If + this command is used, the argument is the concatenation of a + 32-bit internet host address and a 16-bit TCP port address. + This address information is broken into 8-bit fields and the + value of each field is transmitted as a decimal number (in + character string representation). The fields are separated + by commas. A port command would be: + + PORT h1,h2,h3,h4,p1,p2 + + where h1 is the high order 8 bits of the internet host + address. + + PASSIVE (PASV) + + This command requests the server-DTP to "listen" on a data + port (which is not its default data port) and to wait for a + connection rather than initiate one upon receipt of a + transfer command. The response to this command includes the + host and port address this server is listening on. + + REPRESENTATION TYPE (TYPE) + + The argument specifies the representation type as described + in the Section on Data Representation and Storage. Several + types take a second parameter. The first parameter is + denoted by a single Telnet character, as is the second + Format parameter for ASCII and EBCDIC; the second parameter + for local byte is a decimal integer to indicate Bytesize. + The parameters are separated by a (Space, ASCII code + 32). + + The following codes are assigned for type: + + \ / + A - ASCII | | N - Non-print + |-><-| T - Telnet format effectors + E - EBCDIC| | C - Carriage Control (ASA) + / \ + I - Image + + L - Local byte Byte size + + +Postel & Reynolds [Page 28] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The default representation type is ASCII Non-print. If the + Format parameter is changed, and later just the first + argument is changed, Format then returns to the Non-print + default. + + FILE STRUCTURE (STRU) + + The argument is a single Telnet character code specifying + file structure described in the Section on Data + Representation and Storage. + + The following codes are assigned for structure: + + F - File (no record structure) + R - Record structure + P - Page structure + + The default structure is File. + + TRANSFER MODE (MODE) + + The argument is a single Telnet character code specifying + the data transfer modes described in the Section on + Transmission Modes. + + The following codes are assigned for transfer modes: + + S - Stream + B - Block + C - Compressed + + The default transfer mode is Stream. + + 4.1.3. FTP SERVICE COMMANDS + + The FTP service commands define the file transfer or the file + system function requested by the user. The argument of an FTP + service command will normally be a pathname. The syntax of + pathnames must conform to server site conventions (with + standard defaults applicable), and the language conventions of + the control connection. The suggested default handling is to + use the last specified device, directory or file name, or the + standard default defined for local users. The commands may be + in any order except that a "rename from" command must be + followed by a "rename to" command and the restart command must + be followed by the interrupted service command (e.g., STOR or + RETR). The data, when transferred in response to FTP service + + +Postel & Reynolds [Page 29] + + + +RFC 959 October 1985 +File Transfer Protocol + + + commands, shall always be sent over the data connection, except + for certain informative replies. The following commands + specify FTP service requests: + + RETRIEVE (RETR) + + This command causes the server-DTP to transfer a copy of the + file, specified in the pathname, to the server- or user-DTP + at the other end of the data connection. The status and + contents of the file at the server site shall be unaffected. + + STORE (STOR) + + This command causes the server-DTP to accept the data + transferred via the data connection and to store the data as + a file at the server site. If the file specified in the + pathname exists at the server site, then its contents shall + be replaced by the data being transferred. A new file is + created at the server site if the file specified in the + pathname does not already exist. + + STORE UNIQUE (STOU) + + This command behaves like STOR except that the resultant + file is to be created in the current directory under a name + unique to that directory. The 250 Transfer Started response + must include the name generated. + + APPEND (with create) (APPE) + + This command causes the server-DTP to accept the data + transferred via the data connection and to store the data in + a file at the server site. If the file specified in the + pathname exists at the server site, then the data shall be + appended to that file; otherwise the file specified in the + pathname shall be created at the server site. + + ALLOCATE (ALLO) + + This command may be required by some servers to reserve + sufficient storage to accommodate the new file to be + transferred. The argument shall be a decimal integer + representing the number of bytes (using the logical byte + size) of storage to be reserved for the file. For files + sent with record or page structure a maximum record or page + size (in logical bytes) might also be necessary; this is + indicated by a decimal integer in a second argument field of + + +Postel & Reynolds [Page 30] + + + +RFC 959 October 1985 +File Transfer Protocol + + + the command. This second argument is optional, but when + present should be separated from the first by the three + Telnet characters R . This command shall be + followed by a STORe or APPEnd command. The ALLO command + should be treated as a NOOP (no operation) by those servers + which do not require that the maximum size of the file be + declared beforehand, and those servers interested in only + the maximum record or page size should accept a dummy value + in the first argument and ignore it. + + RESTART (REST) + + The argument field represents the server marker at which + file transfer is to be restarted. This command does not + cause file transfer but skips over the file to the specified + data checkpoint. This command shall be immediately followed + by the appropriate FTP service command which shall cause + file transfer to resume. + + RENAME FROM (RNFR) + + This command specifies the old pathname of the file which is + to be renamed. This command must be immediately followed by + a "rename to" command specifying the new file pathname. + + RENAME TO (RNTO) + + This command specifies the new pathname of the file + specified in the immediately preceding "rename from" + command. Together the two commands cause a file to be + renamed. + + ABORT (ABOR) + + This command tells the server to abort the previous FTP + service command and any associated transfer of data. The + abort command may require "special action", as discussed in + the Section on FTP Commands, to force recognition by the + server. No action is to be taken if the previous command + has been completed (including data transfer). The control + connection is not to be closed by the server, but the data + connection must be closed. + + There are two cases for the server upon receipt of this + command: (1) the FTP service command was already completed, + or (2) the FTP service command is still in progress. + + + +Postel & Reynolds [Page 31] + + + +RFC 959 October 1985 +File Transfer Protocol + + + In the first case, the server closes the data connection + (if it is open) and responds with a 226 reply, indicating + that the abort command was successfully processed. + + In the second case, the server aborts the FTP service in + progress and closes the data connection, returning a 426 + reply to indicate that the service request terminated + abnormally. The server then sends a 226 reply, + indicating that the abort command was successfully + processed. + + DELETE (DELE) + + This command causes the file specified in the pathname to be + deleted at the server site. If an extra level of protection + is desired (such as the query, "Do you really wish to + delete?"), it should be provided by the user-FTP process. + + REMOVE DIRECTORY (RMD) + + This command causes the directory specified in the pathname + to be removed as a directory (if the pathname is absolute) + or as a subdirectory of the current working directory (if + the pathname is relative). See Appendix II. + + MAKE DIRECTORY (MKD) + + This command causes the directory specified in the pathname + to be created as a directory (if the pathname is absolute) + or as a subdirectory of the current working directory (if + the pathname is relative). See Appendix II. + + PRINT WORKING DIRECTORY (PWD) + + This command causes the name of the current working + directory to be returned in the reply. See Appendix II. + + LIST (LIST) + + This command causes a list to be sent from the server to the + passive DTP. If the pathname specifies a directory or other + group of files, the server should transfer a list of files + in the specified directory. If the pathname specifies a + file then the server should send current information on the + file. A null argument implies the user's current working or + default directory. The data transfer is over the data + connection in type ASCII or type EBCDIC. (The user must + + +Postel & Reynolds [Page 32] + + + +RFC 959 October 1985 +File Transfer Protocol + + + ensure that the TYPE is appropriately ASCII or EBCDIC). + Since the information on a file may vary widely from system + to system, this information may be hard to use automatically + in a program, but may be quite useful to a human user. + + NAME LIST (NLST) + + This command causes a directory listing to be sent from + server to user site. The pathname should specify a + directory or other system-specific file group descriptor; a + null argument implies the current directory. The server + will return a stream of names of files and no other + information. The data will be transferred in ASCII or + EBCDIC type over the data connection as valid pathname + strings separated by or . (Again the user must + ensure that the TYPE is correct.) This command is intended + to return information that can be used by a program to + further process the files automatically. For example, in + the implementation of a "multiple get" function. + + SITE PARAMETERS (SITE) + + This command is used by the server to provide services + specific to his system that are essential to file transfer + but not sufficiently universal to be included as commands in + the protocol. The nature of these services and the + specification of their syntax can be stated in a reply to + the HELP SITE command. + + SYSTEM (SYST) + + This command is used to find out the type of operating + system at the server. The reply shall have as its first + word one of the system names listed in the current version + of the Assigned Numbers document [4]. + + STATUS (STAT) + + This command shall cause a status response to be sent over + the control connection in the form of a reply. The command + may be sent during a file transfer (along with the Telnet IP + and Synch signals--see the Section on FTP Commands) in which + case the server will respond with the status of the + operation in progress, or it may be sent between file + transfers. In the latter case, the command may have an + argument field. If the argument is a pathname, the command + is analogous to the "list" command except that data shall be + + +Postel & Reynolds [Page 33] + + + +RFC 959 October 1985 +File Transfer Protocol + + + transferred over the control connection. If a partial + pathname is given, the server may respond with a list of + file names or attributes associated with that specification. + If no argument is given, the server should return general + status information about the server FTP process. This + should include current values of all transfer parameters and + the status of connections. + + HELP (HELP) + + This command shall cause the server to send helpful + information regarding its implementation status over the + control connection to the user. The command may take an + argument (e.g., any command name) and return more specific + information as a response. The reply is type 211 or 214. + It is suggested that HELP be allowed before entering a USER + command. The server may use this reply to specify + site-dependent parameters, e.g., in response to HELP SITE. + + NOOP (NOOP) + + This command does not affect any parameters or previously + entered commands. It specifies no action other than that the + server send an OK reply. + + The File Transfer Protocol follows the specifications of the Telnet + protocol for all communications over the control connection. Since + the language used for Telnet communication may be a negotiated + option, all references in the next two sections will be to the + "Telnet language" and the corresponding "Telnet end-of-line code". + Currently, one may take these to mean NVT-ASCII and . No other + specifications of the Telnet protocol will be cited. + + FTP commands are "Telnet strings" terminated by the "Telnet end of + line code". The command codes themselves are alphabetic characters + terminated by the character (Space) if parameters follow and + Telnet-EOL otherwise. The command codes and the semantics of + commands are described in this section; the detailed syntax of + commands is specified in the Section on Commands, the reply sequences + are discussed in the Section on Sequencing of Commands and Replies, + and scenarios illustrating the use of commands are provided in the + Section on Typical FTP Scenarios. + + FTP commands may be partitioned as those specifying access-control + identifiers, data transfer parameters, or FTP service requests. + Certain commands (such as ABOR, STAT, QUIT) may be sent over the + control connection while a data transfer is in progress. Some + + +Postel & Reynolds [Page 34] + + + +RFC 959 October 1985 +File Transfer Protocol + + + servers may not be able to monitor the control and data connections + simultaneously, in which case some special action will be necessary + to get the server's attention. The following ordered format is + tentatively recommended: + + 1. User system inserts the Telnet "Interrupt Process" (IP) signal + in the Telnet stream. + + 2. User system sends the Telnet "Synch" signal. + + 3. User system inserts the command (e.g., ABOR) in the Telnet + stream. + + 4. Server PI, after receiving "IP", scans the Telnet stream for + EXACTLY ONE FTP command. + + (For other servers this may not be necessary but the actions listed + above should have no unusual effect.) + + 4.2. FTP REPLIES + + Replies to File Transfer Protocol commands are devised to ensure + the synchronization of requests and actions in the process of file + transfer, and to guarantee that the user process always knows the + state of the Server. Every command must generate at least one + reply, although there may be more than one; in the latter case, + the multiple replies must be easily distinguished. In addition, + some commands occur in sequential groups, such as USER, PASS and + ACCT, or RNFR and RNTO. The replies show the existence of an + intermediate state if all preceding commands have been successful. + A failure at any point in the sequence necessitates the repetition + of the entire sequence from the beginning. + + The details of the command-reply sequence are made explicit in + a set of state diagrams below. + + An FTP reply consists of a three digit number (transmitted as + three alphanumeric characters) followed by some text. The number + is intended for use by automata to determine what state to enter + next; the text is intended for the human user. It is intended + that the three digits contain enough encoded information that the + user-process (the User-PI) will not need to examine the text and + may either discard it or pass it on to the user, as appropriate. + In particular, the text may be server-dependent, so there are + likely to be varying texts for each reply code. + + A reply is defined to contain the 3-digit code, followed by Space + + +Postel & Reynolds [Page 35] + + + +RFC 959 October 1985 +File Transfer Protocol + + + , followed by one line of text (where some maximum line length + has been specified), and terminated by the Telnet end-of-line + code. There will be cases however, where the text is longer than + a single line. In these cases the complete text must be bracketed + so the User-process knows when it may stop reading the reply (i.e. + stop processing input on the control connection) and go do other + things. This requires a special format on the first line to + indicate that more than one line is coming, and another on the + last line to designate it as the last. At least one of these must + contain the appropriate reply code to indicate the state of the + transaction. To satisfy all factions, it was decided that both + the first and last line codes should be the same. + + Thus the format for multi-line replies is that the first line + will begin with the exact required reply code, followed + immediately by a Hyphen, "-" (also known as Minus), followed by + text. The last line will begin with the same code, followed + immediately by Space , optionally some text, and the Telnet + end-of-line code. + + For example: + 123-First line + Second line + 234 A line beginning with numbers + 123 The last line + + The user-process then simply needs to search for the second + occurrence of the same reply code, followed by (Space), at + the beginning of a line, and ignore all intermediary lines. If + an intermediary line begins with a 3-digit number, the Server + must pad the front to avoid confusion. + + This scheme allows standard system routines to be used for + reply information (such as for the STAT reply), with + "artificial" first and last lines tacked on. In rare cases + where these routines are able to generate three digits and a + Space at the beginning of any line, the beginning of each + text line should be offset by some neutral text, like Space. + + This scheme assumes that multi-line replies may not be nested. + + The three digits of the reply each have a special significance. + This is intended to allow a range of very simple to very + sophisticated responses by the user-process. The first digit + denotes whether the response is good, bad or incomplete. + (Referring to the state diagram), an unsophisticated user-process + will be able to determine its next action (proceed as planned, + + +Postel & Reynolds [Page 36] + + + +RFC 959 October 1985 +File Transfer Protocol + + + redo, retrench, etc.) by simply examining this first digit. A + user-process that wants to know approximately what kind of error + occurred (e.g. file system error, command syntax error) may + examine the second digit, reserving the third digit for the finest + gradation of information (e.g., RNTO command without a preceding + RNFR). + + There are five values for the first digit of the reply code: + + 1yz Positive Preliminary reply + + The requested action is being initiated; expect another + reply before proceeding with a new command. (The + user-process sending another command before the + completion reply would be in violation of protocol; but + server-FTP processes should queue any commands that + arrive while a preceding command is in progress.) This + type of reply can be used to indicate that the command + was accepted and the user-process may now pay attention + to the data connections, for implementations where + simultaneous monitoring is difficult. The server-FTP + process may send at most, one 1yz reply per command. + + 2yz Positive Completion reply + + The requested action has been successfully completed. A + new request may be initiated. + + 3yz Positive Intermediate reply + + The command has been accepted, but the requested action + is being held in abeyance, pending receipt of further + information. The user should send another command + specifying this information. This reply is used in + command sequence groups. + + 4yz Transient Negative Completion reply + + The command was not accepted and the requested action did + not take place, but the error condition is temporary and + the action may be requested again. The user should + return to the beginning of the command sequence, if any. + It is difficult to assign a meaning to "transient", + particularly when two distinct sites (Server- and + User-processes) have to agree on the interpretation. + Each reply in the 4yz category might have a slightly + different time value, but the intent is that the + + +Postel & Reynolds [Page 37] + + + +RFC 959 October 1985 +File Transfer Protocol + + + user-process is encouraged to try again. A rule of thumb + in determining if a reply fits into the 4yz or the 5yz + (Permanent Negative) category is that replies are 4yz if + the commands can be repeated without any change in + command form or in properties of the User or Server + (e.g., the command is spelled the same with the same + arguments used; the user does not change his file access + or user name; the server does not put up a new + implementation.) + + 5yz Permanent Negative Completion reply + + The command was not accepted and the requested action did + not take place. The User-process is discouraged from + repeating the exact request (in the same sequence). Even + some "permanent" error conditions can be corrected, so + the human user may want to direct his User-process to + reinitiate the command sequence by direct action at some + point in the future (e.g., after the spelling has been + changed, or the user has altered his directory status.) + + The following function groupings are encoded in the second + digit: + + x0z Syntax - These replies refer to syntax errors, + syntactically correct commands that don't fit any + functional category, unimplemented or superfluous + commands. + + x1z Information - These are replies to requests for + information, such as status or help. + + x2z Connections - Replies referring to the control and + data connections. + + x3z Authentication and accounting - Replies for the login + process and accounting procedures. + + x4z Unspecified as yet. + + x5z File system - These replies indicate the status of the + Server file system vis-a-vis the requested transfer or + other file system action. + + The third digit gives a finer gradation of meaning in each of + the function categories, specified by the second digit. The + list of replies below will illustrate this. Note that the text + + +Postel & Reynolds [Page 38] + + + +RFC 959 October 1985 +File Transfer Protocol + + + associated with each reply is recommended, rather than + mandatory, and may even change according to the command with + which it is associated. The reply codes, on the other hand, + must strictly follow the specifications in the last section; + that is, Server implementations should not invent new codes for + situations that are only slightly different from the ones + described here, but rather should adapt codes already defined. + + A command such as TYPE or ALLO whose successful execution + does not offer the user-process any new information will + cause a 200 reply to be returned. If the command is not + implemented by a particular Server-FTP process because it + has no relevance to that computer system, for example ALLO + at a TOPS20 site, a Positive Completion reply is still + desired so that the simple User-process knows it can proceed + with its course of action. A 202 reply is used in this case + with, for example, the reply text: "No storage allocation + necessary." If, on the other hand, the command requests a + non-site-specific action and is unimplemented, the response + is 502. A refinement of that is the 504 reply for a command + that is implemented, but that requests an unimplemented + parameter. + + 4.2.1 Reply Codes by Function Groups + + 200 Command okay. + 500 Syntax error, command unrecognized. + This may include errors such as command line too long. + 501 Syntax error in parameters or arguments. + 202 Command not implemented, superfluous at this site. + 502 Command not implemented. + 503 Bad sequence of commands. + 504 Command not implemented for that parameter. + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 39] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 110 Restart marker reply. + In this case, the text is exact and not left to the + particular implementation; it must read: + MARK yyyy = mmmm + Where yyyy is User-process data stream marker, and mmmm + server's equivalent marker (note the spaces between markers + and "="). + 211 System status, or system help reply. + 212 Directory status. + 213 File status. + 214 Help message. + On how to use the server or the meaning of a particular + non-standard command. This reply is useful only to the + human user. + 215 NAME system type. + Where NAME is an official system name from the list in the + Assigned Numbers document. + + 120 Service ready in nnn minutes. + 220 Service ready for new user. + 221 Service closing control connection. + Logged out if appropriate. + 421 Service not available, closing control connection. + This may be a reply to any command if the service knows it + must shut down. + 125 Data connection already open; transfer starting. + 225 Data connection open; no transfer in progress. + 425 Can't open data connection. + 226 Closing data connection. + Requested file action successful (for example, file + transfer or file abort). + 426 Connection closed; transfer aborted. + 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). + + 230 User logged in, proceed. + 530 Not logged in. + 331 User name okay, need password. + 332 Need account for login. + 532 Need account for storing files. + + + + + + + + + + +Postel & Reynolds [Page 40] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 150 File status okay; about to open data connection. + 250 Requested file action okay, completed. + 257 "PATHNAME" created. + 350 Requested file action pending further information. + 450 Requested file action not taken. + File unavailable (e.g., file busy). + 550 Requested action not taken. + File unavailable (e.g., file not found, no access). + 451 Requested action aborted. Local error in processing. + 551 Requested action aborted. Page type unknown. + 452 Requested action not taken. + Insufficient storage space in system. + 552 Requested file action aborted. + Exceeded storage allocation (for current directory or + dataset). + 553 Requested action not taken. + File name not allowed. + + + 4.2.2 Numeric Order List of Reply Codes + + 110 Restart marker reply. + In this case, the text is exact and not left to the + particular implementation; it must read: + MARK yyyy = mmmm + Where yyyy is User-process data stream marker, and mmmm + server's equivalent marker (note the spaces between markers + and "="). + 120 Service ready in nnn minutes. + 125 Data connection already open; transfer starting. + 150 File status okay; about to open data connection. + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 41] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 200 Command okay. + 202 Command not implemented, superfluous at this site. + 211 System status, or system help reply. + 212 Directory status. + 213 File status. + 214 Help message. + On how to use the server or the meaning of a particular + non-standard command. This reply is useful only to the + human user. + 215 NAME system type. + Where NAME is an official system name from the list in the + Assigned Numbers document. + 220 Service ready for new user. + 221 Service closing control connection. + Logged out if appropriate. + 225 Data connection open; no transfer in progress. + 226 Closing data connection. + Requested file action successful (for example, file + transfer or file abort). + 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). + 230 User logged in, proceed. + 250 Requested file action okay, completed. + 257 "PATHNAME" created. + + 331 User name okay, need password. + 332 Need account for login. + 350 Requested file action pending further information. + + 421 Service not available, closing control connection. + This may be a reply to any command if the service knows it + must shut down. + 425 Can't open data connection. + 426 Connection closed; transfer aborted. + 450 Requested file action not taken. + File unavailable (e.g., file busy). + 451 Requested action aborted: local error in processing. + 452 Requested action not taken. + Insufficient storage space in system. + + + + + + + + + + + +Postel & Reynolds [Page 42] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 500 Syntax error, command unrecognized. + This may include errors such as command line too long. + 501 Syntax error in parameters or arguments. + 502 Command not implemented. + 503 Bad sequence of commands. + 504 Command not implemented for that parameter. + 530 Not logged in. + 532 Need account for storing files. + 550 Requested action not taken. + File unavailable (e.g., file not found, no access). + 551 Requested action aborted: page type unknown. + 552 Requested file action aborted. + Exceeded storage allocation (for current directory or + dataset). + 553 Requested action not taken. + File name not allowed. + + +5. DECLARATIVE SPECIFICATIONS + + 5.1. MINIMUM IMPLEMENTATION + + In order to make FTP workable without needless error messages, the + following minimum implementation is required for all servers: + + TYPE - ASCII Non-print + MODE - Stream + STRUCTURE - File, Record + COMMANDS - USER, QUIT, PORT, + TYPE, MODE, STRU, + for the default values + RETR, STOR, + NOOP. + + The default values for transfer parameters are: + + TYPE - ASCII Non-print + MODE - Stream + STRU - File + + All hosts must accept the above as the standard defaults. + + + + + + + + +Postel & Reynolds [Page 43] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 5.2. CONNECTIONS + + The server protocol interpreter shall "listen" on Port L. The + user or user protocol interpreter shall initiate the full-duplex + control connection. Server- and user- processes should follow the + conventions of the Telnet protocol as specified in the + ARPA-Internet Protocol Handbook [1]. Servers are under no + obligation to provide for editing of command lines and may require + that it be done in the user host. The control connection shall be + closed by the server at the user's request after all transfers and + replies are completed. + + The user-DTP must "listen" on the specified data port; this may be + the default user port (U) or a port specified in the PORT command. + The server shall initiate the data connection from his own default + data port (L-1) using the specified user data port. The direction + of the transfer and the port used will be determined by the FTP + service command. + + Note that all FTP implementation must support data transfer using + the default port, and that only the USER-PI may initiate the use + of non-default ports. + + When data is to be transferred between two servers, A and B (refer + to Figure 2), the user-PI, C, sets up control connections with + both server-PI's. One of the servers, say A, is then sent a PASV + command telling him to "listen" on his data port rather than + initiate a connection when he receives a transfer service command. + When the user-PI receives an acknowledgment to the PASV command, + which includes the identity of the host and port being listened + on, the user-PI then sends A's port, a, to B in a PORT command; a + reply is returned. The user-PI may then send the corresponding + service commands to A and B. Server B initiates the connection + and the transfer proceeds. The command-reply sequence is listed + below where the messages are vertically synchronous but + horizontally asynchronous: + + + + + + + + + + + + + +Postel & Reynolds [Page 44] + + + +RFC 959 October 1985 +File Transfer Protocol + + + User-PI - Server A User-PI - Server B + ------------------ ------------------ + + C->A : Connect C->B : Connect + C->A : PASV + A->C : 227 Entering Passive Mode. A1,A2,A3,A4,a1,a2 + C->B : PORT A1,A2,A3,A4,a1,a2 + B->C : 200 Okay + C->A : STOR C->B : RETR + B->A : Connect to HOST-A, PORT-a + + Figure 3 + + The data connection shall be closed by the server under the + conditions described in the Section on Establishing Data + Connections. If the data connection is to be closed following a + data transfer where closing the connection is not required to + indicate the end-of-file, the server must do so immediately. + Waiting until after a new transfer command is not permitted + because the user-process will have already tested the data + connection to see if it needs to do a "listen"; (remember that the + user must "listen" on a closed data port BEFORE sending the + transfer request). To prevent a race condition here, the server + sends a reply (226) after closing the data connection (or if the + connection is left open, a "file transfer completed" reply (250) + and the user-PI should wait for one of these replies before + issuing a new transfer command). + + Any time either the user or server see that the connection is + being closed by the other side, it should promptly read any + remaining data queued on the connection and issue the close on its + own side. + + 5.3. COMMANDS + + The commands are Telnet character strings transmitted over the + control connections as described in the Section on FTP Commands. + The command functions and semantics are described in the Section + on Access Control Commands, Transfer Parameter Commands, FTP + Service Commands, and Miscellaneous Commands. The command syntax + is specified here. + + The commands begin with a command code followed by an argument + field. The command codes are four or fewer alphabetic characters. + Upper and lower case alphabetic characters are to be treated + identically. Thus, any of the following may represent the + retrieve command: + + +Postel & Reynolds [Page 45] + + + +RFC 959 October 1985 +File Transfer Protocol + + + RETR Retr retr ReTr rETr + + This also applies to any symbols representing parameter values, + such as A or a for ASCII TYPE. The command codes and the argument + fields are separated by one or more spaces. + + The argument field consists of a variable length character string + ending with the character sequence (Carriage Return, Line + Feed) for NVT-ASCII representation; for other negotiated languages + a different end of line character might be used. It should be + noted that the server is to take no action until the end of line + code is received. + + The syntax is specified below in NVT-ASCII. All characters in the + argument field are ASCII characters including any ASCII + represented decimal integers. Square brackets denote an optional + argument field. If the option is not taken, the appropriate + default is implied. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 46] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 5.3.1. FTP COMMANDS + + The following are the FTP commands: + + USER + PASS + ACCT + CWD + CDUP + SMNT + QUIT + REIN + PORT + PASV + TYPE + STRU + MODE + RETR + STOR + STOU + APPE + ALLO + [ R ] + REST + RNFR + RNTO + ABOR + DELE + RMD + MKD + PWD + LIST [ ] + NLST [ ] + SITE + SYST + STAT [ ] + HELP [ ] + NOOP + + + + + + + + + + + +Postel & Reynolds [Page 47] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 5.3.2. FTP COMMAND ARGUMENTS + + The syntax of the above argument fields (using BNF notation + where applicable) is: + + ::= + ::= + ::= + ::= | + ::= any of the 128 ASCII characters except and + + ::= + ::= | + ::= printable characters, any + ASCII code 33 through 126 + ::= + ::= , + ::= ,,, + ::= , + ::= any decimal integer 1 through 255 + ::= N | T | C + ::= A [ ] + | E [ ] + | I + | L + ::= F | R | P + ::= S | B | C + ::= + ::= any decimal integer + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 48] + + + +RFC 959 October 1985 +File Transfer Protocol + + + 5.4. SEQUENCING OF COMMANDS AND REPLIES + + The communication between the user and server is intended to be an + alternating dialogue. As such, the user issues an FTP command and + the server responds with a prompt primary reply. The user should + wait for this initial primary success or failure response before + sending further commands. + + Certain commands require a second reply for which the user should + also wait. These replies may, for example, report on the progress + or completion of file transfer or the closing of the data + connection. They are secondary replies to file transfer commands. + + One important group of informational replies is the connection + greetings. Under normal circumstances, a server will send a 220 + reply, "awaiting input", when the connection is completed. The + user should wait for this greeting message before sending any + commands. If the server is unable to accept input right away, a + 120 "expected delay" reply should be sent immediately and a 220 + reply when ready. The user will then know not to hang up if there + is a delay. + + Spontaneous Replies + + Sometimes "the system" spontaneously has a message to be sent + to a user (usually all users). For example, "System going down + in 15 minutes". There is no provision in FTP for such + spontaneous information to be sent from the server to the user. + It is recommended that such information be queued in the + server-PI and delivered to the user-PI in the next reply + (possibly making it a multi-line reply). + + The table below lists alternative success and failure replies for + each command. These must be strictly adhered to; a server may + substitute text in the replies, but the meaning and action implied + by the code numbers and by the specific command reply sequence + cannot be altered. + + Command-Reply Sequences + + In this section, the command-reply sequence is presented. Each + command is listed with its possible replies; command groups are + listed together. Preliminary replies are listed first (with + their succeeding replies indented and under them), then + positive and negative completion, and finally intermediary + + + + +Postel & Reynolds [Page 49] + + + +RFC 959 October 1985 +File Transfer Protocol + + + replies with the remaining commands from the sequence + following. This listing forms the basis for the state + diagrams, which will be presented separately. + + Connection Establishment + 120 + 220 + 220 + 421 + Login + USER + 230 + 530 + 500, 501, 421 + 331, 332 + PASS + 230 + 202 + 530 + 500, 501, 503, 421 + 332 + ACCT + 230 + 202 + 530 + 500, 501, 503, 421 + CWD + 250 + 500, 501, 502, 421, 530, 550 + CDUP + 200 + 500, 501, 502, 421, 530, 550 + SMNT + 202, 250 + 500, 501, 502, 421, 530, 550 + Logout + REIN + 120 + 220 + 220 + 421 + 500, 502 + QUIT + 221 + 500 + + + + +Postel & Reynolds [Page 50] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Transfer parameters + PORT + 200 + 500, 501, 421, 530 + PASV + 227 + 500, 501, 502, 421, 530 + MODE + 200 + 500, 501, 504, 421, 530 + TYPE + 200 + 500, 501, 504, 421, 530 + STRU + 200 + 500, 501, 504, 421, 530 + File action commands + ALLO + 200 + 202 + 500, 501, 504, 421, 530 + REST + 500, 501, 502, 421, 530 + 350 + STOR + 125, 150 + (110) + 226, 250 + 425, 426, 451, 551, 552 + 532, 450, 452, 553 + 500, 501, 421, 530 + STOU + 125, 150 + (110) + 226, 250 + 425, 426, 451, 551, 552 + 532, 450, 452, 553 + 500, 501, 421, 530 + RETR + 125, 150 + (110) + 226, 250 + 425, 426, 451 + 450, 550 + 500, 501, 421, 530 + + + + +Postel & Reynolds [Page 51] + + + +RFC 959 October 1985 +File Transfer Protocol + + + LIST + 125, 150 + 226, 250 + 425, 426, 451 + 450 + 500, 501, 502, 421, 530 + NLST + 125, 150 + 226, 250 + 425, 426, 451 + 450 + 500, 501, 502, 421, 530 + APPE + 125, 150 + (110) + 226, 250 + 425, 426, 451, 551, 552 + 532, 450, 550, 452, 553 + 500, 501, 502, 421, 530 + RNFR + 450, 550 + 500, 501, 502, 421, 530 + 350 + RNTO + 250 + 532, 553 + 500, 501, 502, 503, 421, 530 + DELE + 250 + 450, 550 + 500, 501, 502, 421, 530 + RMD + 250 + 500, 501, 502, 421, 530, 550 + MKD + 257 + 500, 501, 502, 421, 530, 550 + PWD + 257 + 500, 501, 502, 421, 550 + ABOR + 225, 226 + 500, 501, 502, 421 + + + + + + +Postel & Reynolds [Page 52] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Informational commands + SYST + 215 + 500, 501, 502, 421 + STAT + 211, 212, 213 + 450 + 500, 501, 502, 421, 530 + HELP + 211, 214 + 500, 501, 502, 421 + Miscellaneous commands + SITE + 200 + 202 + 500, 501, 530 + NOOP + 200 + 500 421 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 53] + + + +RFC 959 October 1985 +File Transfer Protocol + + +6. STATE DIAGRAMS + + Here we present state diagrams for a very simple minded FTP + implementation. Only the first digit of the reply codes is used. + There is one state diagram for each group of FTP commands or command + sequences. + + The command groupings were determined by constructing a model for + each command then collecting together the commands with structurally + identical models. + + For each command or command sequence there are three possible + outcomes: success (S), failure (F), and error (E). In the state + diagrams below we use the symbol B for "begin", and the symbol W for + "wait for reply". + + We first present the diagram that represents the largest group of FTP + commands: + + + 1,3 +---+ + ----------->| E | + | +---+ + | + +---+ cmd +---+ 2 +---+ + | B |---------->| W |---------->| S | + +---+ +---+ +---+ + | + | 4,5 +---+ + ----------->| F | + +---+ + + + This diagram models the commands: + + ABOR, ALLO, DELE, CWD, CDUP, SMNT, HELP, MODE, NOOP, PASV, + QUIT, SITE, PORT, SYST, STAT, RMD, MKD, PWD, STRU, and TYPE. + + + + + + + + + + + + +Postel & Reynolds [Page 54] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The other large group of commands is represented by a very similar + diagram: + + + 3 +---+ + ----------->| E | + | +---+ + | + +---+ cmd +---+ 2 +---+ + | B |---------->| W |---------->| S | + +---+ --->+---+ +---+ + | | | + | | | 4,5 +---+ + | 1 | ----------->| F | + ----- +---+ + + + This diagram models the commands: + + APPE, LIST, NLST, REIN, RETR, STOR, and STOU. + + Note that this second model could also be used to represent the first + group of commands, the only difference being that in the first group + the 100 series replies are unexpected and therefore treated as error, + while the second group expects (some may require) 100 series replies. + Remember that at most, one 100 series reply is allowed per command. + + The remaining diagrams model command sequences, perhaps the simplest + of these is the rename sequence: + + + +---+ RNFR +---+ 1,2 +---+ + | B |---------->| W |---------->| E | + +---+ +---+ -->+---+ + | | | + 3 | | 4,5 | + -------------- ------ | + | | | +---+ + | ------------->| S | + | | 1,3 | | +---+ + | 2| -------- + | | | | + V | | | + +---+ RNTO +---+ 4,5 ----->+---+ + | |---------->| W |---------->| F | + +---+ +---+ +---+ + + + +Postel & Reynolds [Page 55] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The next diagram is a simple model of the Restart command: + + + +---+ REST +---+ 1,2 +---+ + | B |---------->| W |---------->| E | + +---+ +---+ -->+---+ + | | | + 3 | | 4,5 | + -------------- ------ | + | | | +---+ + | ------------->| S | + | | 3 | | +---+ + | 2| -------- + | | | | + V | | | + +---+ cmd +---+ 4,5 ----->+---+ + | |---------->| W |---------->| F | + +---+ -->+---+ +---+ + | | + | 1 | + ------ + + + Where "cmd" is APPE, STOR, or RETR. + + We note that the above three models are similar. The Restart differs + from the Rename two only in the treatment of 100 series replies at + the second stage, while the second group expects (some may require) + 100 series replies. Remember that at most, one 100 series reply is + allowed per command. + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 56] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The most complicated diagram is for the Login sequence: + + + 1 + +---+ USER +---+------------->+---+ + | B |---------->| W | 2 ---->| E | + +---+ +---+------ | -->+---+ + | | | | | + 3 | | 4,5 | | | + -------------- ----- | | | + | | | | | + | | | | | + | --------- | + | 1| | | | + V | | | | + +---+ PASS +---+ 2 | ------>+---+ + | |---------->| W |------------->| S | + +---+ +---+ ---------->+---+ + | | | | | + 3 | |4,5| | | + -------------- -------- | + | | | | | + | | | | | + | ----------- + | 1,3| | | | + V | 2| | | + +---+ ACCT +---+-- | ----->+---+ + | |---------->| W | 4,5 -------->| F | + +---+ +---+------------->+---+ + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 57] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Finally, we present a generalized diagram that could be used to model + the command and reply interchange: + + + ------------------------------------ + | | + Begin | | + | V | + | +---+ cmd +---+ 2 +---+ | + -->| |------->| |---------->| | | + | | | W | | S |-----| + -->| | -->| |----- | | | + | +---+ | +---+ 4,5 | +---+ | + | | | | | | | + | | | 1| |3 | +---+ | + | | | | | | | | | + | | ---- | ---->| F |----- + | | | | | + | | | +---+ + ------------------- + | + | + V + End + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 58] + + + +RFC 959 October 1985 +File Transfer Protocol + + +7. TYPICAL FTP SCENARIO + + User at host U wanting to transfer files to/from host S: + + In general, the user will communicate to the server via a mediating + user-FTP process. The following may be a typical scenario. The + user-FTP prompts are shown in parentheses, '---->' represents + commands from host U to host S, and '<----' represents replies from + host S to host U. + + LOCAL COMMANDS BY USER ACTION INVOLVED + + ftp (host) multics Connect to host S, port L, + establishing control connections. + <---- 220 Service ready . + username Doe USER Doe----> + <---- 331 User name ok, + need password. + password mumble PASS mumble----> + <---- 230 User logged in. + retrieve (local type) ASCII + (local pathname) test 1 User-FTP opens local file in ASCII. + (for. pathname) test.pl1 RETR test.pl1 ----> + <---- 150 File status okay; + about to open data + connection. + Server makes data connection + to port U. + + <---- 226 Closing data connection, + file transfer successful. + type Image TYPE I ----> + <---- 200 Command OK + store (local type) image + (local pathname) file dump User-FTP opens local file in Image. + (for.pathname) >udd>cn>fd STOR >udd>cn>fd ----> + <---- 550 Access denied + terminate QUIT ----> + Server closes all + connections. + +8. CONNECTION ESTABLISHMENT + + The FTP control connection is established via TCP between the user + process port U and the server process port L. This protocol is + assigned the service port 21 (25 octal), that is L=21. + + + +Postel & Reynolds [Page 59] + + + +RFC 959 October 1985 +File Transfer Protocol + + +APPENDIX I - PAGE STRUCTURE + + The need for FTP to support page structure derives principally from + the need to support efficient transmission of files between TOPS-20 + systems, particularly the files used by NLS. + + The file system of TOPS-20 is based on the concept of pages. The + operating system is most efficient at manipulating files as pages. + The operating system provides an interface to the file system so that + many applications view files as sequential streams of characters. + However, a few applications use the underlying page structures + directly, and some of these create holey files. + + A TOPS-20 disk file consists of four things: a pathname, a page + table, a (possibly empty) set of pages, and a set of attributes. + + The pathname is specified in the RETR or STOR command. It includes + the directory name, file name, file name extension, and generation + number. + + The page table contains up to 2**18 entries. Each entry may be + EMPTY, or may point to a page. If it is not empty, there are also + some page-specific access bits; not all pages of a file need have the + same access protection. + + A page is a contiguous set of 512 words of 36 bits each. + + The attributes of the file, in the File Descriptor Block (FDB), + contain such things as creation time, write time, read time, writer's + byte-size, end-of-file pointer, count of reads and writes, backup + system tape numbers, etc. + + Note that there is NO requirement that entries in the page table be + contiguous. There may be empty page table slots between occupied + ones. Also, the end of file pointer is simply a number. There is no + requirement that it in fact point at the "last" datum in the file. + Ordinary sequential I/O calls in TOPS-20 will cause the end of file + pointer to be left after the last datum written, but other operations + may cause it not to be so, if a particular programming system so + requires. + + In fact, in both of these special cases, "holey" files and + end-of-file pointers NOT at the end of the file, occur with NLS data + files. + + + + + +Postel & Reynolds [Page 60] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The TOPS-20 paged files can be sent with the FTP transfer parameters: + TYPE L 36, STRU P, and MODE S (in fact, any mode could be used). + + Each page of information has a header. Each header field, which is a + logical byte, is a TOPS-20 word, since the TYPE is L 36. + + The header fields are: + + Word 0: Header Length. + + The header length is 5. + + Word 1: Page Index. + + If the data is a disk file page, this is the number of that + page in the file's page map. Empty pages (holes) in the file + are simply not sent. Note that a hole is NOT the same as a + page of zeros. + + Word 2: Data Length. + + The number of data words in this page, following the header. + Thus, the total length of the transmission unit is the Header + Length plus the Data Length. + + Word 3: Page Type. + + A code for what type of chunk this is. A data page is type 3, + the FDB page is type 2. + + Word 4: Page Access Control. + + The access bits associated with the page in the file's page + map. (This full word quantity is put into AC2 of an SPACS by + the program reading from net to disk.) + + After the header are Data Length data words. Data Length is + currently either 512 for a data page or 31 for an FDB. Trailing + zeros in a disk file page may be discarded, making Data Length less + than 512 in that case. + + + + + + + + + +Postel & Reynolds [Page 61] + + + +RFC 959 October 1985 +File Transfer Protocol + + +APPENDIX II - DIRECTORY COMMANDS + + Since UNIX has a tree-like directory structure in which directories + are as easy to manipulate as ordinary files, it is useful to expand + the FTP servers on these machines to include commands which deal with + the creation of directories. Since there are other hosts on the + ARPA-Internet which have tree-like directories (including TOPS-20 and + Multics), these commands are as general as possible. + + Four directory commands have been added to FTP: + + MKD pathname + + Make a directory with the name "pathname". + + RMD pathname + + Remove the directory with the name "pathname". + + PWD + + Print the current working directory name. + + CDUP + + Change to the parent of the current working directory. + + The "pathname" argument should be created (removed) as a + subdirectory of the current working directory, unless the "pathname" + string contains sufficient information to specify otherwise to the + server, e.g., "pathname" is an absolute pathname (in UNIX and + Multics), or pathname is something like "" to + TOPS-20. + + REPLY CODES + + The CDUP command is a special case of CWD, and is included to + simplify the implementation of programs for transferring directory + trees between operating systems having different syntaxes for + naming the parent directory. The reply codes for CDUP be + identical to the reply codes of CWD. + + The reply codes for RMD be identical to the reply codes for its + file analogue, DELE. + + The reply codes for MKD, however, are a bit more complicated. A + freshly created directory will probably be the object of a future + + +Postel & Reynolds [Page 62] + + + +RFC 959 October 1985 +File Transfer Protocol + + + CWD command. Unfortunately, the argument to MKD may not always be + a suitable argument for CWD. This is the case, for example, when + a TOPS-20 subdirectory is created by giving just the subdirectory + name. That is, with a TOPS-20 server FTP, the command sequence + + MKD MYDIR + CWD MYDIR + + will fail. The new directory may only be referred to by its + "absolute" name; e.g., if the MKD command above were issued while + connected to the directory , the new subdirectory + could only be referred to by the name . + + Even on UNIX and Multics, however, the argument given to MKD may + not be suitable. If it is a "relative" pathname (i.e., a pathname + which is interpreted relative to the current directory), the user + would need to be in the same current directory in order to reach + the subdirectory. Depending on the application, this may be + inconvenient. It is not very robust in any case. + + To solve these problems, upon successful completion of an MKD + command, the server should return a line of the form: + + 257"" + + That is, the server will tell the user what string to use when + referring to the created directory. The directory name can + contain any character; embedded double-quotes should be escaped by + double-quotes (the "quote-doubling" convention). + + For example, a user connects to the directory /usr/dm, and creates + a subdirectory, named pathname: + + CWD /usr/dm + 200 directory changed to /usr/dm + MKD pathname + 257 "/usr/dm/pathname" directory created + + An example with an embedded double quote: + + MKD foo"bar + 257 "/usr/dm/foo""bar" directory created + CWD /usr/dm/foo"bar + 200 directory changed to /usr/dm/foo"bar + + + + + +Postel & Reynolds [Page 63] + + + +RFC 959 October 1985 +File Transfer Protocol + + + The prior existence of a subdirectory with the same name is an + error, and the server must return an "access denied" error reply + in that case. + + CWD /usr/dm + 200 directory changed to /usr/dm + MKD pathname + 521-"/usr/dm/pathname" directory already exists; + 521 taking no action. + + The failure replies for MKD are analogous to its file creating + cousin, STOR. Also, an "access denied" return is given if a file + name with the same name as the subdirectory will conflict with the + creation of the subdirectory (this is a problem on UNIX, but + shouldn't be one on TOPS-20). + + Essentially because the PWD command returns the same type of + information as the successful MKD command, the successful PWD + command uses the 257 reply code as well. + + SUBTLETIES + + Because these commands will be most useful in transferring + subtrees from one machine to another, carefully observe that the + argument to MKD is to be interpreted as a sub-directory of the + current working directory, unless it contains enough information + for the destination host to tell otherwise. A hypothetical + example of its use in the TOPS-20 world: + + CWD + 200 Working directory changed + MKD overrainbow + 257 "" directory created + CWD overrainbow + 431 No such directory + CWD + 200 Working directory changed + + CWD + 200 Working directory changed to + MKD + 257 "" directory created + CWD + + Note that the first example results in a subdirectory of the + connected directory. In contrast, the argument in the second + example contains enough information for TOPS-20 to tell that the + + +Postel & Reynolds [Page 64] + + + +RFC 959 October 1985 +File Transfer Protocol + + + directory is a top-level directory. Note also that + in the first example the user "violated" the protocol by + attempting to access the freshly created directory with a name + other than the one returned by TOPS-20. Problems could have + resulted in this case had there been an directory; + this is an ambiguity inherent in some TOPS-20 implementations. + Similar considerations apply to the RMD command. The point is + this: except where to do so would violate a host's conventions for + denoting relative versus absolute pathnames, the host should treat + the operands of the MKD and RMD commands as subdirectories. The + 257 reply to the MKD command must always contain the absolute + pathname of the created directory. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 65] + + + +RFC 959 October 1985 +File Transfer Protocol + + +APPENDIX III - RFCs on FTP + + Bhushan, Abhay, "A File Transfer Protocol", RFC 114 (NIC 5823), + MIT-Project MAC, 16 April 1971. + + Harslem, Eric, and John Heafner, "Comments on RFC 114 (A File + Transfer Protocol)", RFC 141 (NIC 6726), RAND, 29 April 1971. + + Bhushan, Abhay, et al, "The File Transfer Protocol", RFC 172 + (NIC 6794), MIT-Project MAC, 23 June 1971. + + Braden, Bob, "Comments on DTP and FTP Proposals", RFC 238 (NIC 7663), + UCLA/CCN, 29 September 1971. + + Bhushan, Abhay, et al, "The File Transfer Protocol", RFC 265 + (NIC 7813), MIT-Project MAC, 17 November 1971. + + McKenzie, Alex, "A Suggested Addition to File Transfer Protocol", + RFC 281 (NIC 8163), BBN, 8 December 1971. + + Bhushan, Abhay, "The Use of "Set Data Type" Transaction in File + Transfer Protocol", RFC 294 (NIC 8304), MIT-Project MAC, + 25 January 1972. + + Bhushan, Abhay, "The File Transfer Protocol", RFC 354 (NIC 10596), + MIT-Project MAC, 8 July 1972. + + Bhushan, Abhay, "Comments on the File Transfer Protocol (RFC 354)", + RFC 385 (NIC 11357), MIT-Project MAC, 18 August 1972. + + Hicks, Greg, "User FTP Documentation", RFC 412 (NIC 12404), Utah, + 27 November 1972. + + Bhushan, Abhay, "File Transfer Protocol (FTP) Status and Further + Comments", RFC 414 (NIC 12406), MIT-Project MAC, 20 November 1972. + + Braden, Bob, "Comments on File Transfer Protocol", RFC 430 + (NIC 13299), UCLA/CCN, 7 February 1973. + + Thomas, Bob, and Bob Clements, "FTP Server-Server Interaction", + RFC 438 (NIC 13770), BBN, 15 January 1973. + + Braden, Bob, "Print Files in FTP", RFC 448 (NIC 13299), UCLA/CCN, + 27 February 1973. + + McKenzie, Alex, "File Transfer Protocol", RFC 454 (NIC 14333), BBN, + 16 February 1973. + + +Postel & Reynolds [Page 66] + + + +RFC 959 October 1985 +File Transfer Protocol + + + Bressler, Bob, and Bob Thomas, "Mail Retrieval via FTP", RFC 458 + (NIC 14378), BBN-NET and BBN-TENEX, 20 February 1973. + + Neigus, Nancy, "File Transfer Protocol", RFC 542 (NIC 17759), BBN, + 12 July 1973. + + Krilanovich, Mark, and George Gregg, "Comments on the File Transfer + Protocol", RFC 607 (NIC 21255), UCSB, 7 January 1974. + + Pogran, Ken, and Nancy Neigus, "Response to RFC 607 - Comments on the + File Transfer Protocol", RFC 614 (NIC 21530), BBN, 28 January 1974. + + Krilanovich, Mark, George Gregg, Wayne Hathaway, and Jim White, + "Comments on the File Transfer Protocol", RFC 624 (NIC 22054), UCSB, + Ames Research Center, SRI-ARC, 28 February 1974. + + Bhushan, Abhay, "FTP Comments and Response to RFC 430", RFC 463 + (NIC 14573), MIT-DMCG, 21 February 1973. + + Braden, Bob, "FTP Data Compression", RFC 468 (NIC 14742), UCLA/CCN, + 8 March 1973. + + Bhushan, Abhay, "FTP and Network Mail System", RFC 475 (NIC 14919), + MIT-DMCG, 6 March 1973. + + Bressler, Bob, and Bob Thomas "FTP Server-Server Interaction - II", + RFC 478 (NIC 14947), BBN-NET and BBN-TENEX, 26 March 1973. + + White, Jim, "Use of FTP by the NIC Journal", RFC 479 (NIC 14948), + SRI-ARC, 8 March 1973. + + White, Jim, "Host-Dependent FTP Parameters", RFC 480 (NIC 14949), + SRI-ARC, 8 March 1973. + + Padlipsky, Mike, "An FTP Command-Naming Problem", RFC 506 + (NIC 16157), MIT-Multics, 26 June 1973. + + Day, John, "Memo to FTP Group (Proposal for File Access Protocol)", + RFC 520 (NIC 16819), Illinois, 25 June 1973. + + Merryman, Robert, "The UCSD-CC Server-FTP Facility", RFC 532 + (NIC 17451), UCSD-CC, 22 June 1973. + + Braden, Bob, "TENEX FTP Problem", RFC 571 (NIC 18974), UCLA/CCN, + 15 November 1973. + + + + +Postel & Reynolds [Page 67] + + + +RFC 959 October 1985 +File Transfer Protocol + + + McKenzie, Alex, and Jon Postel, "Telnet and FTP Implementation - + Schedule Change", RFC 593 (NIC 20615), BBN and MITRE, + 29 November 1973. + + Sussman, Julie, "FTP Error Code Usage for More Reliable Mail + Service", RFC 630 (NIC 30237), BBN, 10 April 1974. + + Postel, Jon, "Revised FTP Reply Codes", RFC 640 (NIC 30843), + UCLA/NMC, 5 June 1974. + + Harvey, Brian, "Leaving Well Enough Alone", RFC 686 (NIC 32481), + SU-AI, 10 May 1975. + + Harvey, Brian, "One More Try on the FTP", RFC 691 (NIC 32700), SU-AI, + 28 May 1975. + + Lieb, J., "CWD Command of FTP", RFC 697 (NIC 32963), 14 July 1975. + + Harrenstien, Ken, "FTP Extension: XSEN", RFC 737 (NIC 42217), SRI-KL, + 31 October 1977. + + Harrenstien, Ken, "FTP Extension: XRSQ/XRCP", RFC 743 (NIC 42758), + SRI-KL, 30 December 1977. + + Lebling, P. David, "Survey of FTP Mail and MLFL", RFC 751, MIT, + 10 December 1978. + + Postel, Jon, "File Transfer Protocol Specification", RFC 765, ISI, + June 1980. + + Mankins, David, Dan Franklin, and Buzz Owen, "Directory Oriented FTP + Commands", RFC 776, BBN, December 1980. + + Padlipsky, Michael, "FTP Unique-Named Store Command", RFC 949, MITRE, + July 1985. + + + + + + + + + + + + + + +Postel & Reynolds [Page 68] + + + +RFC 959 October 1985 +File Transfer Protocol + + +REFERENCES + + [1] Feinler, Elizabeth, "Internet Protocol Transition Workbook", + Network Information Center, SRI International, March 1982. + + [2] Postel, Jon, "Transmission Control Protocol - DARPA Internet + Program Protocol Specification", RFC 793, DARPA, September 1981. + + [3] Postel, Jon, and Joyce Reynolds, "Telnet Protocol + Specification", RFC 854, ISI, May 1983. + + [4] Reynolds, Joyce, and Jon Postel, "Assigned Numbers", RFC 943, + ISI, April 1985. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel & Reynolds [Page 69] + + + diff --git a/include/syscalls.h b/include/syscalls.h index 21ef8305..84108fee 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -80,6 +80,9 @@ extern int wait __P((int *statloc)); extern int write __P((int d, void *buf, uint nbytes)); extern int reboot __P((char p1, char p2)); extern int systrace __P((int onoff)); +#if 1 /* Nick */ +extern int sysdebug __P((int onoff)); +#endif extern int unix __P((int callno, ...)); /* ensures IAR doesn't use regparms */ extern long unix_long __P((int callno, ...)); /* ensures IAR doesn't use reg */ diff --git a/lib/libsysb.lib b/lib/libsysb.lib index 6c982515..503b75f4 100644 --- a/lib/libsysb.lib +++ b/lib/libsysb.lib @@ -47,6 +47,7 @@ relsysb\symlink.rel relsysb\sync.rel relsysb\sys0b.rel relsysb\sys1b.rel +relsysb\sysdebug.rel relsysb\systrace.rel relsysb\time.rel relsysb\times.rel diff --git a/lib/libsysl.lib b/lib/libsysl.lib index 1cb0d327..e77395d9 100644 --- a/lib/libsysl.lib +++ b/lib/libsysl.lib @@ -47,6 +47,7 @@ relsysl\symlink.rel relsysl\sync.rel relsysl\sys0l.rel relsysl\sys1l.rel +relsysl\sysdebug.rel relsysl\systrace.rel relsysl\time.rel relsysl\times.rel diff --git a/lib/relsysb/sysdebug.rel b/lib/relsysb/sysdebug.rel new file mode 100644 index 00000000..a64d4cd1 --- /dev/null +++ b/lib/relsysb/sysdebug.rel @@ -0,0 +1,22 @@ +XL4 +H 2 areas 7 global symbols +M _sysdebug +S unix Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 1A flags 0 +S sysdebug Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 D5 21 0C 00 E5 21 +R 00 00 01 00 02 05 02 00 +T 09 00 00 00 07 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 00 00 +T 0F 00 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 00 00 02 09 03 00 +T 16 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 06 01 00 diff --git a/lib/relsysl/sysdebug.rel b/lib/relsysl/sysdebug.rel new file mode 100644 index 00000000..c293814b --- /dev/null +++ b/lib/relsysl/sysdebug.rel @@ -0,0 +1,19 @@ +XL4 +H 2 areas 6 global symbols +M _sysdebug +S ?CL64180L_4_06_L00 Ref00000000 +S unix Ref00000000 +S ?LEAVE_DIRECT_L09 Ref00000000 +S ?ENT_PARM_DIRECT_L09 Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 15 flags 0 +S sysdebug Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 D5 21 0C 00 E5 21 +R 00 00 01 00 02 05 03 00 +T 09 00 00 00 07 00 E5 CD 00 00 00 00 F1 F1 F1 +R 00 00 01 00 02 08 01 00 +T 12 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 02 00 diff --git a/relnotes/20030512.txt b/relnotes/20030512.txt new file mode 100644 index 00000000..d427663b --- /dev/null +++ b/relnotes/20030512.txt @@ -0,0 +1,667 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030512SD + +MANIFEST + +-rw-r--r-- 1 nick users 8907957 May 12 16:02 uzi.zip + +Please download the files for this release from: +http://www.hytechscales.com/release/nld/test/030512SD + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. In the +folders within the zip we have a complete set of binaries, libraries and +source, including pre-built flash card images. Contains a version of Joost's +login and test programs, with X/Y positioning of text slightly modified by +Nick. This operating system release is much more stable than the previous one, +and should be adopted as the platform for application level development. + +The kernel is not substantially changed from the previous 030306SD testrelease, +except for the addition of debugging changes, and a bugfix for a problem +discovered by Joost. The utility programs received a few enhancements and +bugfixes. The most major change is to the filesystem, ie. the folder structure +of the flash card, the scripts which control the building of the card, and the +subsequent loading phases. + +Support for the touchscreen is also improved, with new font files being +available on the flash card for downloading to the touchscreen. These are also +downloaded automatically once, during the initial loading process. The source +image files for the fonts are easily edited, using Photoshop or similar. Using +the new font compiler, we can easily add new typefaces, or arbitrary graphics +and images specific to the application. + +DETAILS OF CHANGES TO THE KERNEL + +1. Extensive support for debuglevels in the kernel. An example of the new +format for debugging code in the kernel is as follows: + + ... + variable = 1; +#if DEBUG >= 2 + dprintf(2, "the value of variable = %d\n", variable); +#endif + switch (variable) + ... + +In this case the programmer wanted to inspect the value of some variable during +a critical operation. To better control when this diagnostic should be +printed, the programmer has selected debuglevel 2, with the minimum debuglevel +being 1, and an increasing debuglevel indicating more and more detailed +information. The dprintf() function is new in this release. It works the same +as kprintf() but the first argument is an integer debuglevel. + +2. We now have both compile-time and run-time selection of the debuglevel. +The compile-time setting is controlled by "/uzi/src/kernel/build.ban" and +should be edited on every line beginning with "iccz80". For example: + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 +..\libc\memcpy +@if errorlevel 1 goto failure +del memcpy.r01 +as-z80 -l -o memcpy.s01 +@if errorlevel 1 goto failure +If we want to change the debuglevel compiled into kernel's internal "memcpy" +function, we would change the -DDEBUG=2 option to the compiler into something +different. In particular, if the option is set to 0, or omitted entirely, no +debuglevel support is compiled in, and we achieve a smaller kernel executable. +There is no specific limit to what the debuglevel could be set to, other than +the range of an "int", but commonsense limits us to about 10. + +3. Typically the compile-time selection will be the same for all modules, so +you can just load up the file "/uzi/src/kernel/build.ban" into your text editor +and perform a search and replace eg. change "DEBUG=2" into "DEBUG=4" if you +require more detailed debugging output. Then recompile the kernel and load. +You must run "mkboot.bat" then "n.bat" in "/uzi/bin". Nick has configured the +debuglevels in this release, so that most of the system calls will provide some +output at debuglevel 2, with more detailed information (eg. dumps of directory +searches and block cache operations) being available at debuglevels 3 and 4. + +4. Changing the compile-time debuglevel selection will not have any immediate +effect, because debugging output is turned off by default, when the system +boots. At the moment there is no key combination which will allow changing the +debuglevel, (unlike the Ctrl-N command which enables/disables global system +tracing), but instead, requests for kernel debugging output must be compiled +into your programs. The "/uzi/src/libsys/sysdebug.c" module and the +corresponding system call handling in the kernel have been provided to control +this. + +5. For example, when Nick was debugging a problem in the falign() system call, +the offending call was bracketed with sysdebug(4) and sysdebug(0) calls. Thus, +an extensive amount of debugging information was turned on while processing +this one particular system call, with no debugging information being printed at +bootup or after finishing the call. This control is very important because it +can take an impossibly long time to boot the system when full debugging output +is turned on. Similarly the systrace() call is available for your use. + +6. Fixed a bug which was causing problems for Joost's development. This +subtle bug was due to IAR's default of "unsigned char" whereas the original +author of the filesystem code had obviously expected char to default to "signed +char". The bug could be observed in the fork() system call, as it tried to +increment reference counts for all the inherited handles. The kernel thought +all handles were open, and so it went and incremented a byte of memory which +happened to lie in the disk block cache. Strange and subtle corruption of the +disks was the result, manifested in an ECORRUPTFS error down the track. Now +fixed! + +7. Removed support for the original UZI filesystem. Since the 030306SD +release, we have been running on a customised filesystem containing various new +locking fields and bitmaps. These are needed to make the "align" command +perform its magic. The older UZI filesystem was still useable although it +didn't support the "align" command. This meant we wasted a lot of space in the +superblock for the "inode free list" and "block free list", which have now been +replaced by the "inode free bitmap" and "block free bitmap". To make the disks +more compact, all references to the older filesystem in the kernel and +utilities are gone. + +8. Fixed a subtle bug in the alignment procedure, which was caused by a script +"unlinking" itself during running. Normally, in this case, the file remains +intact on disk until the last handle is closed, at which point its space is +reclaimed. This led to an inconsistency between the inode's linkcount and its +reference count, which caused the alignment routine to think the filesystem was +corrupt and bomb out. I decided to modify the i_open routine so a linkcount of +zero is allowed, as long as the in-core reference count is nonzero. + +DETAILS OF CHANGES TO SUPPORT PROGRAMS + +1. The "ls" command no longer relies on the line-wrap performed by your +terminal. Instead the "ls" program counts how many filenames have been +printed, and issues a newline after 5 columns. This works better on broken +terminals such as Hyperterminal and Minicom, which don't correctly perform a +linewrap if the end of the screen was reached by tabbing. Instead they leave +the cursor on the last column of the display ie. just before the tab stop. +This was rather unsightly when viewing the "ls" output, so it's now been fixed. + +2. We now have "banked" versions of the "fsck" and "mkfs" support utilities. +Previously it didn't make sense to run these programs after the system had been +loaded, but we now keep a "banked" version of the "fsck" program in memory all +the time. The startup scripts have been changed so that we always perform a +filesystem check at boot. Errors are fixed automatically, although this might +not be appropriate for the running system. For now, we just want to detect +corruption. Please note: The filesystem is mounted read/write during the +filecheck. This will soon be fixed by Nick, with support for "mount -o +remount,rw". + +3. Removed support for the original UZI filesystem. Since the 030306SD +release, we have been running on a customised filesystem containing various new +locking fields and bitmaps. As mentioned in the section on kernel level +changes, all references to the older filesystem in the kernel and utilities are +gone. This meant quite a few changes to the "mkfs" and "fsck" utilities, in +particular their use of malloc() to allocate memory for the bitmaps. The +switch "-b" to "mkfs" is now redundant and is longer accepted, since the +filesystem is always a bitmapped filesystem. So I also removed "-b" from the +"/uzi/bin/*.bat" scripts. + +4. Added the commands "chown" and "chgrp" to our "ucp" (unix copy) utility. +As mentioned further down, this is needed to set the ownerships for home +directories in the pre-prepared filesystem. Code was lifted out of +"/uzi/src/simple/chown.c" and "/uzi/src/simple/chgrp.c" and inserted into +"/uzi/src/fsutil/ucp.c" and "/uzi/src/fsutil/ucpsub.c". I also added a new +wrapper function "UZIXchown()" for interfacing to the kernel code. Please +note: "ucp" also needs a setting to allow operating on a disk file other than +"uzidisk.dat". Coming soon. We'll probably provide a command line switch, +plus an option to the "root" command. + +5. Added several "fatal error" messages to the Minix shell, in particular +where it does heap and stack management. A subtle incompatibility with the +"uzix" C runtime library was discovered when running a shell script which used +globbing. The opendir() and closedir() functions had used malloc() and free(), +which is not allowed because the Minix shell relies on doing its own heap +management using brk() and sbrk(). Next time the Minix shell tried to push an +object on its stack, it bombed out using abort(), but now we have a proper +error message. The actual bug is fixed by adding functions nick_opendir(), +nick_readdir(), etc. + +6. Changes to the time/date setting in the "/uzio/src/init/init.c" program. +Previously there had been an inconsistency because the date was printed first, +followed by the time, whereas the keyboard input format required the time +first, followed by the date. We've now standardised on "time followed by date" +and the "init.c" code was changed to reflect this. Please follow this example +whenever times and dates must be printed. We now prompt the user to "Please +enter time/date" rather than "Please enter date/time". The "setclock" utility +in "/uzi/src/simple/setclock.c" received a cosmetic change because of this. + +DETAILS OF CHANGES TO THE FILESYSTEM + +1. The "w.sh", "w.bat" and "w.ucp" scripts have now changed to "appinst.sh", +"appinst.bat" and "appinst.ucp". The name better reflects the function of the +scripts, and the folder position of the "w.sh" file on the running system has +also changed. Previously the "w.sh" file was held in /wnd on the flash card, +and copied to /wnd on the memory filesystem. It's now always executed from +/boot on the flash card, or /usr/boot when the card is mounted on /usr as it +normally is. + +2. We now have the following extra directories in "/uzi/bin": +data Joost's screenfiles. Soon to be upgraded to XML. +font Nick's fontfiles. Suitable for copying to /dev/lcdx. +The files from these directories end up in "/wnd" and "/usr/lib/font", +respectively, when the system reaches its running state. The intermediate +directories "/uzi/bin/data" and "/uzi/bin/font" are only present on your PC, +and are referenced from the "*.ucp" scripts. Please feel free to add new +folders under "/uzi/bin" if this helps keep things organised. + +3. We now have a prototype "fstab.txt", which states where the filesystems +should be mounted in the running system. The file "/uzi/bin/fstab.txt" becomes +the "/etc/fstab" of the running system. The file "/uzi/bin/xfstab.txt" is the +"/etc/fstab" of the flash card - this is not normally referenced, but would be +significant if the system is booted directly from the card, ie. if the card is +for some reason mounted as the root filesystem. + +4. We now have a prototype "mtab.txt", which is really a dummy file since it +gets deleted immediately on startup, but the mere existence of the file is +needed to prevent an ugly error message on the initial boot. The file +"/uzi/bin/mtab.txt" becomes the "/etc/mtab" of the running system. The file +"/uzi/bin/xmtab.txt" is the "/etc/mtab" of the flash card - this is not +normally referenced, but would be significant if the system is booted directly +from the card, ie. if the card is for some reason mounted as the root +filesystem. + +5. The prototype group.txt has been edited by Nick. The "users" group has +been removed and we now have groups called "operator" and "manager" instead. +The entries in the /etc/passwd file of the running system are graded in access +level by specifying which "group" the user belongs to. Application programs +should inspect the group id (gid) to see which level of userinterface +functionality should be revealed to the user. + +6. The prototype passwd.txt has been edited by Nick. The "90" user remains +unchanged, so as not to break Joost's login code, but Nick has added several +new users in the style we wish to adopt. For the added users, the Unix user +number is also the Hytech user number which gets entered as the first 2 digits +of the PIN. This should be less confusing, and it means the Unix username can +now be set to arbitrary text. + +user=downingn pass=666 uid=60 gid=100 name=Downing, Nick +user=morsinkj pass=777 uid=70 gid=100 name=Morsink, Joost +user=buijsr pass=888 uid=80 gid=100 name=Buijs, Rob +user=90 pass=999 uid=11 gid=101 (we'll delete this later on) + +7. The format of /etc/inittab has been extended. This is a simple list of +programs which are executed by "init" before any spawning of ttys begins. We +can now specify arguments to the programs to be executed (though there is no +shell-like substitution or quote expansion), and we can specify "silent" +entries, which won't show any indication whether the command could be executed +or not. This is specifically for the new "runonce.sh" functionality, which +will be described below. + +8. The prototype inittab.txt has been edited by Nick. This is the starting +point of the new loading structure, so it should be understood thoroughly +before examining the other scripts. The file /uzi/bin/inittab.txt becomes the +/etc/inittab of the running system, whereas the file /uzi/bin/xinittab.txt +becomes the /etc/inittab of the flash card. As with xfstab.txt, this file is +only significant if the system is booted directly from the flash card (not the +default way). + +The commands in the new /uzi/bin/inittab.txt are as follows: + +# Hytech initialisation table for running system + +@/etc/rc.d/rc.sysinit +@/etc/rc.d/rc.runonce +/bin/grlogin + +The first 2 lines are required for the loading system and should not be +changed. The @ indicates that the entries are silent, so if you want to +disable the functionality of the "rc.runonce" or "rc.sysinit" scripts, just +make sure those scripts are not loaded onto the flash card. The last line +refers to Joost's front-end login program, and can be changed to whatever is +most appropriate for a particular customer. + +9. The scripts "rc.sysinit" and "rc.runonce" have been added to the system by +Nick. These reside in a special folder called "/etc/rc.d" (runlevel control +directory). For better compatibility with DOS style text editors the master +files are "/uzi/bin/sysinit.rc" and "/uzi/bin/runonce.rc" and the renaming +takes place inside the scripts which build the flash card filesystem: +"/uzi/bin/n.ucp" and "/uzi/bin/mkboot.ucp". The scripts "rc.sysinit" and +"rc.runonce" are copied into the RAM filesystem's "/etc/rc.d" folder during the +initial boot. + +The commands in the new /uzi/bin/sysinit.rc are as follows: + +#!/bin/sh + +echo "/etc/rc.d/rc.sysinit" +fsck -y /dev/hd0 + +The "echo" command compensates for the fact that the script is invoked by a +"silent" inittab entry. The string is output on the console (SERIAL 1) so we +can see which scripts are being executed. The "fsck" command causes a startup +filecheck on every bootstrap. + +The commands in the new /uzi/bin/runonce.rc are as follows: + +#!/bin/sh + +echo "/etc/rc.d/rc.runonce" +rm -v /etc/rc.d/rc.runonce +exec /usr/boot/runonce.sh + +As before, the "echo" command just allows us to see which script is being +executed. After this, we execute an "rm -v" command which deletes the +executing script "rc.runonce" from the RAM filesystem. Thus, on a subsequent +bootstrap, the "silent" inittab entry referring to the non-existent file +/etc/rc.d/rc.runonce will have no effect. We then proceed to do any required +first-time initialisation, for both operating system and application programs. + +This file, which gets deleted after the first bootstrap, has deliberately been +kept as short as possible. Thus, not so much information is lost when we +delete the file. The real initialisation sequence is executed from the flash +card, by invoking a further script "/usr/boot/runonce.sh". This is +deliberately not copied to the RAM filesystem, for reasons which will be +outlined further down. The initialisation can of course be repeated at any +time, by executing /usr/boot/runonce.sh from the console. (eg. to re-download +font files). + +10. As outlined in the description for "rc.runonce", the real initialisation +of the system is performed by a further script held on the flash card in /boot. +The master file for this further script is "/uzi/bin/runonce.sh", which appears +as "/usr/boot/runonce.sh" after the flash card has been mounted on /usr, as it +usually is. However, this script should not be modified, except by Nick, since +a deliberate hook has been provided in the new "appinst.sh". + +The commands in the new /uzi/bin/runonce.sh are as follows: + +#!/bin/sh + +echo "" +echo "Installing LCD character sets" +echo "" + +cp -v /usr/lib/font/lcd0.cmd /dev/lcd0 +cp -v /usr/lib/font/lcd1.cmd /dev/lcd1 + +umask 022 +mkdir /wnd +exec /usr/boot/appinst.sh + +Notice that we are now trying to be more user-friendly by printing a few blank +lines and a large banner saying what we are doing. This script is executed on +initial loading, and it takes a while to execute. So we want to tell the user +what we're doing. This only appears on the console for now, but we could later +extend it to display on the touchscreen also. + +This "runonce.sh" file is intended to contain operating system initialisation, +which will probably be extended further by Nick (eg. initialising a hostname, +setting up an IP address, downloading to the thermal printer and the Cognitive +printer, etc). For the moment, we just download the required command files to +the touchscreen and customer display. Once this is done, we proceed to the +application-dependent initialisation by executing the new +"/usr/boot/appinst.sh", formerly "/usr/wnd/w.sh". + +11. In addition to the renaming of "w.sh" to "appinst.sh", Nick has edited the +contents. The new installation sequence for the application software is as +follows: + +#!/bin/sh + +echo "" +echo "Installing application program" +echo "" + +rm -f /wnd/*.scr +cp -v /usr/boot/inst/wnd/*.scr /wnd + +rm -f /bin/grlogin /bin/test +cp -v /usr/boot/inst/bin/grlogin /usr/boot/inst/bin/test /bin +align -v /bin/grlogin /bin/test + +echo "" +echo "Finished installing application" +echo "" + +Notice that we remove the "/wnd/*.scr" files before copying them afresh. This +might be important if files are renamed or deleted. However we could probably +optimise the install by copying only changed files. Nick will look into this +in due course. For the moment, we also have to delete any aligned executables +before copying the replacements in. This is described in "030306SD test +readme.txt". Hence the "rm -f /bin/grlogin /bin/test" command. + +Please note that this relies on having a "/boot/inst/wnd" directory on the +flash card which contains the "*.scr" files, and a separate "/boot/inst/bin" +directory with the binaries. Nick has added these new directories by editing +the script "appinst.ucp", formerly "w.ucp". Of course the layout and filenames +are completely up to the developer, so the files "appinst.*" will probably need +to be changed as the application development progresses. + +The function of the new "/boot/inst" folder (which appears as "/usr/boot/inst" +after the flash card has been mounted on /usr as it normally is), is somewhat +analogous to the already existing "/boot/skel" folder that contains the +skeleton filesystem. For early development we used "/wnd" and "/boot/skel/wnd" +but this has been superseded by the new "/boot/inst". Therefore we keep the +operating system files separate from the application files. This will become +important if we want to distribute pre-built flash card images of the system. + +12. Home directories are now created. In the previous release, there was an +oversight meaning that the sample home directory "/home/90" was not writeable +by the user 90, and so could not be used as a home directory. In this release, +the "mkramfs.sh" script is not yet fixed, since it's not operational. So if +you are using home directories, you must boot via the filesystem self-extractor +described in the next section. Fortunately this is already selected for you. +The home directories in the pre-prepared filesystem have the correct ownership, +set by the new "chown" and "chgrp" commands in our "ucp" (unix copy) utility. + +DETAILS OF THE FILESYSTEM SELF-EXTRACTOR + +1. The loading phase, from a completely cold boot, is normally controlled by +the "/boot/mkramfs.sh" script, at least until the change described here. +Because the loading from cold was taking an excessively long time (4 or 5 +minutes), we now initialise the filesystem from a pre-prepared image, rather +than using scripts to copy the required files. This means less redundant +copying, and we get the benefit of data compression as well. + +2. The "mkramfs.sh" script is no longer referenced, although we can revert to +the earlier loading method at any time. The same applies to the "/boot/skel" +folder on the flash card. The "mkramfs.sh" and "/boot/skel" files have been +updated with this release, and will continue to be updated by Nick, although +they're not directly used. To select the earlier loading method, edit the file +"/uzi/bin/n.bat" and refer to the "@rem" comments. + +3. The new filesystem image is prepared with the usual "mkfs.exe" and +"ucp.exe" programs. For details please see the new "/uzi/bin/mkboot.bat" and +"/uzi/bin/mkboot.ucp" scripts prepared by Nick. After we have prepared the +"uzidisk.dat" image for a filesystem of the correct size (768k), with the +correct locking options, and the unallocated space not written, we then +compress the disk image using "gzip" to produce the "/uzi/bin/uzboot.gz" +compressed filesystem image. This might eventually be distributed in pre-built +form by Nick. + +4. Since the bootstrap is controlled by a fixed size area (2 kbytes is +reserved from the 768 kbyte disk for the "gboot.bin" boot loader), it was not +possible to include unzipping code in the boot loader. Instead, the +"uzboot.gz" image is packaged into a self extracting executable, which looks +like a kernel for boot loading purposes. This packaging is done by +concatenating the "uzboot.ldr" executable with the "uzboot.gz" data to produce +"uzboot.bin". For the source code of "uzboot.ldr", please see the files +"/uzi/src/gboot/uz*.asm". + +5. The boot loader did not need to be changed to accommodate the new self +extractor. Instead, the self extractor masquerades as a kernel, and then +reboots once its job is done. By the time of the reboot, the filesystem has +been unzipped and we execute the (real) kernel found on the pre-prepared +filesystem. Because of the new requirement for two different kernels (one for +the initial loading, and one for building into the pre-prepared filesystem), we +now keep separate copies in the "/boot" and "/boot/skel/boot" folders of the +flash card. + +6. This means the "mkramfs.sh" script is simplified, since it now copies +everything from "/boot/skel" instead of needing an extra step to copy the +kernel from "/boot". However, the process of building the flash card is +slightly complicated because of the different kernels needed. While the flash +card is being built, we grab "uzboot.bin" (the initial kernel) and rename it to +"kernel.bin" for the "/boot" folder of the flash card. Then we grab +"kernel.bin" (the real kernel) and place it in the "/boot/skel/boot" folder of +the card. + +7. The "/boot/skel/boot/kernel.bin" would be the kernel copied into "/boot" of +the RAM filesystem during the initial copying of files controlled by +"/boot/mkramfs.sh". However, since we now have the kernel self-extractor, the +"/boot/skel/boot/kernel.bin" file is not referenced, and instead we must ensure +the correct (real) kernel has been preloaded into the "uzboot.bin" filesystem +that was built with "/uzi/bin/mkboot.bat". Fortunately, this doesn't need any +renaming, but it means you must run "mkboot.bat" before running "n.bat". + +8. Another tricky step is the generation of the "/boot/checksum" and +"/boot/crc" files on the flash card. These are needed for compatibility with +the Hytech version 5.544+ EPROM. We use the old "crc.com" program from a POS +distribution for this purpose. In this operating system release, the +"/uzi/bin/n.bat" command is modified so that the checksum files are always +regenerated when the flash card is rebuilt. This should be more reliable, but +you need to be aware that software releases in "/nlddl" would get rudely +overwritten each time you run "/uzi/bin/n.bat". This is a limitation of the +"crc" program and will be fixed soon. + +9. The "/boot/checksum" file controls loading by the Hytech version 5.544+ +EPROM. It will read this file, from the hard coded location of "/boot", and +then read any further files specified here. For the current setup we request +the EPROM to load "/boot/kernel.bin" and "/boot/boot.bin", these end up as +"A:KERNEL.BIN" and "A:BOOT.BIN" after being downloaded by the EPROM code. The +"/boot/crc" file is a hardlinked copy of "/boot/checksum", and this is needed +if we are forced to boot from an earlier version EPROM by downloading the +version 5.544+ RAM operating system first. This was needed by Nick in +developing the new EPROM. + +10. The filename "BOOT.BIN" is special and allows our custom boot loader to +get control when the EPROM reboots after downloading the needed files from +"/boot" on the flash card. The filename "KERNEL.BIN" is arbitrary, although it +must match the filename expected by the BOOT.BIN code. This could be changed +by editing "/uzi/src/gboot.asm". However, I did not want to change the boot +loader, so instead I specified that "uzboot.bin" be renamed to "kernel.bin". +Later we could clean this up, but I wanted to keep supporting the old style +bootstrap copying of files for the moment. Hence, we are stuck with the name +"KERNEL.BIN". + +11. The maximum size of the "uzboot.bin" image is 256 kbytes. This is because +it gets loaded at physical addresses C:0000 thru F:FFFF during the initial +boot. The filesystem contained within "uzboot.bin" could potentially be up to +512 kbytes in size, and this gets loaded at physical addresses 4:0000 thru +B:FFFF. We could also increase these limits by overwriting the compressed data +during decompression, but I didn't think it was necessary for now. The +unzipper is based on the "ZIPFILE.INC" decompressor from the 5.529+ EPROM, with +modifications to handle "gzip" rather than "pkzip" format. Most "gzip" options +are not supported, so we use the commandline "gzip --best < infile > outfile" +to compress. + +12. When the self-extractor has done its work and the filesystem has been +unpacked to the terminal's RAM drive, we reboot and execute the +"/etc/rc.d/rc.sysinit" and "/etc/rc.d/rc.runonce" scripts that have been +preloaded onto the gzipped filesystem. It is expected that system +initialisation performed by "rc.sysinit" will be specific to the kernel +unpacked. However, the first-time initialisation triggered by "rc.runonce" is +dependent on the application, and might be changed independent of any kernel +changes. So the first-time initialisation is really done by "/boot/runonce.sh" +from the flash card, and it is expected that the "rc.runonce" script will not +need to be changed. Thus the "uzboot.bin" file can be distributed +independently of the application specific files, and should be very stable. + +DETAILS OF SUPPORT FOR THE TOUCHSCREEN + +1. The new character set compiler suite is built in "/uzi/src/mkfont" and the +executables are placed in "/uzi/src/bin". As mentioned in "030306SD test +readme.txt", the folder "/uzi/src/bin" must be placed in your path for correct +building of the software. The new executables are "bmp2txt.exe", "txt2chs.exe" +and "chs2cmd.exe". We perform the conversion in 3 stages. Intermediate files +of "setxx.txt" and "setxx.chs" are built before creating the final "lcdx.cmd" +file containing all character sets for a particular device. + +2. The new fonts themselves are built in "/uzi/src/font" and the font files +"lcdx.cmd" are placed in "/uzi/bin/font". The fonts are easily editable by +changing "setxx.bmp" with some kind of image editor, such as Photoshop or The +Gimp. After editing the source image files, just run "n.bat" in +"/uzi/src/font" and then rebuild the flash card. If the assignment of fonts to +devices must be changed, you must edit "n.bat". Look for the lines containing: + +chs2cmd set01.chs 1 +chs2cmd set02.chs 2 +chs2cmd set03.chs 3 +chs2cmd set04.chs 4 +chs2cmd set05.chs 5 +chs2cmd set06.chs 6 + +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd+set06.cmd lcd0.cmd +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd lcd1.cmd + +This indicates that the operator display (lcd0) is to receive fonts 1 thru 6. +The customer display (lcd1) is to receive fonts 1 thru 5. The difference is +necessary because of the reduced RAM available on the customer display +controller (32 kbytes rather than 128 kbytes). At the moment, the font numbers +are chosen so that they are identical on both devices. However this may not +always be possible in the future. If some kind of font translation needs to be +performed, the building sequence could be changed as follows: + +chs2cmd set01.chs 1 +chs2cmd set02.chs 2 +chs2cmd set03.chs 3 +chs2cmd set04.chs 4 +chs2cmd set05.chs 5 +chs2cmd set06.chs 6 +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd+set06.cmd lcd0.cmd + +chs2cmd set07.chs 1 +chs2cmd set08.chs 2 +chs2cmd set09.chs 3 +chs2cmd set10.chs 4 +chs2cmd set11.chs 5 +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd lcd1.cmd + +In this example, the operator display assignments are unchanged, but the 5 +fonts loaded to the customer display are completely new fonts designed for the +purpose. The bitmaps would be "set07.bmp" through "set11.bmp" but the fonts +would be selected as fonts 1 thru 5. We need this translation because the +customer display is only capable of addressing 1 thru 5. + +3. The purpose of the initial step, performed by "bmp2txt.exe", is to analyse +the user's bitmap and try to locate the lines of text within the bitmap. We +then try to determine the baseline of the text using a weighted average of the +pixel contents of each line. Finally we break each line of text into +individual characters, and spit them out individually in an intermediate text +format. Here is the lowercase "j" from "/uzi/src/font/set02.txt": + +at 103,67 size 4,10 + + #### + +###### + #### + #### + #### +__####__ + #### +#### + +The header line, "at 103,67 size 4,10" tells us that the character was located +at location 103,67 in the user's bitmap and the detected size of the character +is 4 pixels wide by 10 pixels high. The height of all characters in each line +of text gathered from the bitmap should be the same, since they are determined +as a group. Similarly, the relative position of the baseline (shown above by +the underline characters) should be the same for the entire line of text. + +If the user's bitmap is split into several lines of text, they might be output +with different heights eg. all characters on the line containing the "$" sign +might be output a few pixels taller, because of the ascender on the "$" coming +up a bit higher than the other characters. This doesn't matter though, because +the subsequent step, performed by "txt2chs.exe", will trim all characters to +size. In this case the "j" would be trimmed to size 3,9. + +As you can see from the example above, the text files are output in "double +width", so that 2 consecutive "#" signs indicate a single dark pixel. Two +consecutive spaces or underlines indicate a single light pixel. This is simply +to aid readability. Also, a fixed amount of inter-character space is appended +to each character on the right. In this case it is one single pixel, as can be +seen by the fact that the underline extends 2 columns to the right of the +character. The converter "bmp2txt.exe" always appends one single pixel of +space. + +4. The purpose of the subsequent step, performed by "txt2chs.exe", is to +examine the individual character bitmaps found in the previous step, along with +their size and baseline information, then trim each character to its exact +extents. In the process, "offset" X/Y values are generated, which tell the +touchscreen or customer display exactly where the trimmed bitmap should be +drawn, relative to a given cursor position. Finally the bitmaps are padded to +a multiple of 8 bits horizontally, and stored in a compact binary format. + +The binary format of the "*.chs" files is determined by the AVR code running in +the touchscreen and customer display modules, and can't be easily changed. +Briefly, the format consists of 16 dummy header bytes, followed by an index for +256 characters, followed by a few miscellaneous byte-sized fields. The index +consists of 256 "word" sized pointers into the data (specified relative to the +starting position of the index). The touchscreen or customer display follows +the index pointer corresponding to the ASCII value of a character to be drawn, +to find the character data (X/Y size bytes followed by a raw bitmap array). + +In the miscellaneous data area immediately following the index, we have a few +fields that can be determined automatically (for example the X and Y cell size +when fixed spacing is being used), and a few fields which need to be specified +via the command line to "bmp2chs.exe". This includes inter-character and +inter-line space, which can be set to arbitrary values. For example in the +subsequent processing of the "j" example we use the command: + +txt2chs set02.txt 1 3 +This means that the input file "/uzi/src/font/set02.txt" should be converted to +the output file "/uzi/src/font/set02.chs" with an inter-character spacing of 1 +and an inter-line spacing of 3. Given that a normal uppercase character in the +set has height 8, we end up with a total cell height of 8 + 3 = 11 pixels, of +which 3 will usually be blank separators. The height of an uppercase character +is determined by a clever "median" algorithm in which the heights of all +characters are post processed after being trimmed to size. In general we can +determine the cell width and height automatically, but the inter-character and +inter-line space need to be adjusted manually, to visually pleasing values. + +5. If arbitrary images are to be added into the character sets, for example +the customer's logo, or icons representing letters or parcels, they should be +added by extending the font bitmap vertically and placing the image on a line +by itself. This way any awkwardly shaped images will not upset the normal +process of determining the baselines and heights of text. The system will +still assign a baseline intelligently, by ignoring any narrow protrusions from +the bottom of the image, but this will not upset the baselines of other +characters. In some cases we DO want this interaction, for example if you +define a set of 4 "arrow" characters pointing in different directions, they +should become a single "line" of text in the font. Thus they are assigned a +common baseline and will drawn aligned with each other. + +6. Please note that Nick is working on a utility to extract the widths of +characters from the "*.chs" files and generate a smaller binary format for use +by Joost's GUI and other applications. Sorry, this didn't make it into the +current release. I thought it was more important to document the changes to +date and get them out the door. The new width tables will be generated using a +modification of the public domain "mkfont" utility downloaded by Nick. Thus +they will be compatible with text formatters like "groff", "ditroff" and "man". + diff --git a/silly.bat b/silly.bat deleted file mode 100644 index 1b8cb908..00000000 --- a/silly.bat +++ /dev/null @@ -1,3 +0,0 @@ -del uzi.zip -pkzipc -add=update -path=relative -recurse -excl=build -excl=build-b -excl=build-l -excl=*.s01 -excl=*.lst -excl=*.i86 -excl=*.rst -excl=*.obj -excl=*.pdb -excl=*.ilk silly * -xcopy silly.zip \\darkstar\public\uzi.backup.zip diff --git a/src/as-z80/as-z80.exe b/src/as-z80/as-z80.exe deleted file mode 100644 index 632a28d56156ab272a7d3e22ecf13d12ee127930..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110637 zcmeFa3w%`7wLgC55g5XR37BY?tABba$iZTb$CXjfN zn&B`?TWoDhE4kQ;x3<-46|G`IFabnGq%BrzgJQdf6K!f!7<6R*-?jERli_9i|9|fP z^Sk$VLFZ(jz1LoQ?X}lld+oI!$AA4=#i1yQ6TehSQ8wc*{qyqks~`K2+;8a1{gmhX zyg6*MZPuH^t_|O@tZ?bQci(>R&36{wdh=a(-5n{s<+j3m)w>GsxT|pL>^X&Z-o5Cy zaXC5JMJDQ9YaZ!t{N%usJ-?18pTPT}&pvxn$KRViJM?4}fBXLZZ%;nN@5Yn6@VDZQ zTf>y+bQA`BiZaWVrS$#n{L3wv4yB*1udSD&6xtN!85z6mxA>cj-+07PttpHj@q_+Z zf0YiTQyTsezxajU@i61fKb)#OV^c=S(5auzHbwMD63QKPYKT+D7CmcIlBZ0Ok>et_ zt%x9KD=_J$x*kWEq7*91P2=uebaUipMR_L+z*KjFVIJVG`Ogc6jFVu>wk3%40uGV< z7k{jOUPWmhcZURA1ol$h8DA~_X8iLK+`YFgx%*Z{xjzpH%}6iA-?b;fl_U1dzcU;- z!+|p#IKzQ695};)GaNX>fioO9!+|p#IKzSeLJsVrfAJq=D@wc;^Tzlqx8QNn4S0;b z9giz0t`l?V_zRR!ejOe^T!hCM0(p``$9{}QT|OQj4UgGF@aWqIj}c4p=tGZ-2}_fT z#~RA<6MB5M43BduwG~s#_}vfU@#0iG&N~~A?-0nEFdh}x<8cL*F`Xy~(c^{Dc)ULr zk1!>C`$u?OiCJ`9p}Z>xOF{(cu8V~7#KJMb`W#$y$wewRqQgcADSjmO}7@c1p&qx@@lOs&CV z7(ME!p!_HveTb^hiA{GCX%oMR$JRS3t{#t%OYxXSTpKnHkKT27oJ%wxs;1YKcsx$! z-b>jE?08In5D!lMD}O{P*&UqY)%D4zP24n@&Ji3-tD;ddSsyl^d`64CnbdPc%@q_vxX|^Yb|z+7CKLtJeZRTj5gFzPjI~hq|Ic zm(f?N=~5zDVj3_a*|TMatzkzb$Fn6AZ`gzQaftV9@x>dOBfXKUt;}ZAL;D<|{n60A z_-8ie(%8r#;9n9s8_!vhTs&`&WaByA)9?gpp!>R_z7DOXLx~Kcf`hJ-P=`v?wtJy# zP}eNcj>>zs_~R%$OT3I1FgqIBtNZq9Vr&%8n!Q)t7t%v}i+8ME{rz*iN~$Qf3V(Fp zz7pU5fjf@8hYA~LqJ5J?`v*3AqrQE{NZr40vVZ@;JxBfsVvTbw*fIj`1JKd37GqEg z5EBq@$rgzDMNn*&VJ2g@?%S=25m7vAcF*-ZbeJj?+D)W53Ye5XfE2A}pAzwCHT#uF zpLX9aAmv8fMK#oYyFgKVD}n^3GMEam?UYLLvYp^{|8~$8hgJvveV$)Q`qto;(5h#( z`^fXGR6QVm^EnHg(HE5}-g89VPZeH_m-Brbya9FZ>)%f`4V;+w{*&^8I~SqAVlK}Z z3N*TZ|GOQ8a{%J$F+k4=JW{3{c?V#9--(8{8E97|Q)JY) zjpb}xH0W&NuIM`$UrKWJ@%&chY_IZJzE}Ajejnl2hF>4VDOsocXQKrB=~A<@9F*id z1RQ(udmO)C;x`a2GYY?4{DOF2f#09;n}m18mYtn#$1mGK59^;ZJIe~5=5Md;?B2&E zxia7SKoteWT?x`Tq*^>%8aG^3rf3J8B;ANG`s<-&h1hw7+fWW@C)_g^4xCWMP9{!bb47@-y8yzm%`e?2390ma*ko4HEi ziIn`ajO1aIToax`@egOjW2{$<+rl#_etAax6pHtU0~Eg?BmQ!VpA^21;-_WA!%|R; z!Qq=Ieq2U8%o0*HzdM{tF=auM)k(0;v!y@OotHJB3(a&fTBx{rwH<9&cy$?iqf5T6 zrMHru5xbFxhSZvE)Wm+5)?$nLUB(MvolEr~&qnGAn^`*yL{2XF#02mzEfBdeUspg> zfM_&dl@jxJ1;s!3%@qrERfuzC4Rv3)nWe51c9qgJh%1W-b~aoJaNmYc$}DuaH@W zsb5DHLY`n^F?u2U5HpLM zadW!D7ew58sJlX3(#@=h+hqRXo`#nRoN;KSPuy3gD3MEm>{}VgS~^@3AL8%Ih^P8r zzdl27ur-^)k1xKkeE?$bU z6>W4mxB3)yso7F5autc>posp1tBX!Pnjj&D+-5DptdV@pU|C$igh%Y^a<`jc8q3_A zv7Z@NE92rV07Jqz$qeYO@icr4E{YpbTGY2r53Nh9E?Yyhr@ob2WL;3a^cj-_Ty1t+ z)xwx>eLxIm5?$@SbpZ*c#nIK)X*KJVNG?$6zICf-W&NmeR{nb90NPMH^vxrG9JojO z@H1`eG9)%$o3%dXUmp~2$-2S}#F*~cQtobOR*RrpR|j)yciLdZH3pz+O#=s(RU%sM ziXX+i0+Gmp8aI+0BdC`bK$@*^ZnVr5e+O{l7|2J5@@)Aw>*Wva4SPKGotUyn`LWE= z$Mn!+o-KB*V^w-!D1^r8i)d}DEgE{v_(1mo!lfN8@-$#7q@eP6DplDmqtU+;mt0X_ z7nyF=XQPteXwG(!k+n`d3>whejd%5&@cj^lpfeik)M`4FNU`qggmvef>|du2riS%( z>NC(;Sl}q^rjFyH3Wqv%d(_uyv{$KOmTZ&w->_VoSp!o!%7M*$JpCP@AI1@Mo5=|q zbZZ|(vc7yw_diy=XLbLy5YYH#H*Q5Vx2?&asBf+AU#rE-qj=V=z4*Rz-M1F`)?PM( zOs+>q;!nFT3HB=SbD&NUCSx+*SB5dKSK`#y5uZ!pf8YUO9IxIZ?f?hDB(zo3zeW$O z(GHbI@vK>M@qO3o{xzstT>}@=a8FMmqFClKzHXKzhMN(Eh@j#`e>1{kmMIh&VYVL) z`cTsW(f+sNTJRhie}3g(=kRwyvc(%+vI%!{YyXsCooM7!*<9<$=4vFH3(3;vYGlD| zgv}K%ai(Pl15bdJ{naOy4MXBrp>+<-214t^>~z^*QC|IV<<)a}^;F&)JZb8N)Mld* zgk2&7(?`(MpnD`u4Z6=~odB43!7{KT>Vwj#)#B$z@vNzJ+&4xK)uMf0>0!NbuE}yE z*JL$W%-pQv$EXk5(qgey%|)M{z~bYo8J3w081`t6a)zZ2-A0p}b?4`^w%rrSYhq=) zTlcT)yFD7KPNh-?R3reH)sIpHDPB&A&Tz(eQfH@eiMotbL7Ocs!# zrsLxf1?)>K?9y8F9*3N()iL<$(7hn=3AfB zRizL)FxbTfniEy2w~Drc%G`{iFFd*Eg3}fKFbT@3xagHd8%tRzddr5PVa$hN zY=*mGhl(CUBU+Buf$H_h+&0v!?8i^ww;R81 z{1m6n>2%uh!#@Z9%fIBfM%;MREoIlpME{eb;bA64h zKGz7f_huTIjM;c$^WQZVQN1Z@3ZkYk)a8hx%}~aLh+2Rb3>%68myT;BUL5oSe}$_W zFX$dUGdrS`J0_e$B)aY8l##3*)33vV=vL%p3(*_buYpODL(ix`snsOyG%h3^k@0vs zBUiO&QIZ`v+Ox=SMceY)+0&rZQi!x}Y85EB+)7Vb=>Ra(0bmSCr>D&Pic)K(r&f_* z|6lG6JyX3i95};)GaUH$IUv1{7`T+0A>!GO$g0M)!kr#YX_SKh_aN*7_*gMJRX(rjQM|~X}35fnC9sXn+4SY$SwkJ*ZTTo;(1{&WA zX?#ugQSI=w!B1!s$~?pTUXFoSGtiksgoOh{O9u~9Y}ddjIJd5pcvu)KQzAK>T@yBD zrX2M<+*NINt>if2vN zRL?`-27vDGqDk=XuhC4q;d%VACSc1Ea09}))0&AbLLi4?Za@HTGsURDvudGVL@2@lADGl%nEdnxp zd)CtklNUW+h#9L@B?ZVA~o<39xyV@I6}A##~@Zf1&5XZ1EcpGskgr2ywB z$y$QoDxaRi)E#iuwGeqhS)EdoJkF>)A0_fOQf(wSn53XM`WOG^u~Z6X?KQFxf<+2> zkr{DRLds^iy_PENL~kHJJgx%N_he?yfEffbz^qSVK9+`GE#d!t)%(8!lE;_pw9*1J zJXT1x(sgKj=&JY!nB`bK!JjFd(VR_y)k^89sN+qTm3isTMsAvolxmzMWrM^XvJ%bb z$N`oha~vbn^ShC!qKSwIi0GfF?Ok=HQ;=yOe#_3&b12+qE7bETz!FXYiZ@uA^WwWOL6d0h>VUAo42&P*;QLIkp8ptFXD#h_f~DxWil<>EW==9&mU?H? zdXOuZ-5n&@9nQ!A(6Eh&ffuc7w?)-{1ayCAFnkkHgB2ySdY3aXxsqUJUN9^OHlK*a z;)_g=4+XJiVf(St%!Tcjg>_qnC9T3-epy&XIlsq*F3m=}B^VBMj>XS?STSdQ?vwn? z1rFxtAOw!%=b{t%`AtThCuV_f@%!M}M$g``1{xXT(>JLmgYZ&!h@xQ7n3bTd23*`; z=Snb2AR97tjiOTf;hiSWcproJDl7QuC-C9dfei>ohXg2qqH*{Hxpw>lqh`#x8lFuo#F^spN5<_6hmUWlM;WIZa3>P; z=6g(xY%zEUp(Z6RTE5_B)E;mu)nk}A9p2CEm&scot(|CSw;9ia1T}gz+c-;Bq$*qV zsiCT18De*QEJl_1IdCCJQM7p)R%M9dT~mc@Me^F<{RzB77O^pihBR{X!|bjQZ~dW1 z7EPj_2BalU^O+#5p^@}qsY=SCFFBe-5R2LghhIefSS=H9QpenDqkfV_v-e+vTA=mA zkrNuq#YjmQPo%~xsgW`@!>Pq#d9YAj<>WY8z^xu5iPQVH*|XVm#ZK+0?-eT^3Ynp! zxmbXg{Q|OB^MEOfuSi+cS^P*X+K*R@cUjH2S*zL1(y>`e$7W(F$>KH&kSy*dR{1&u z;T0z|-`yQ?In}ry+MOj+Vfh?^IY2VvNU0p)@7BJFiXpnm{+(~C(B~c z)Kt%CHP5hgJR?O>xyB^jjeyiZrrxfmD)gxKTN!blnD~2$;zHYrqNwMvUW~Ia!uB>L z|7oq}X)f;RJ84GNlTpwRN;pVG!s#s_-?6+p%qOZWt=hu4UE$gjTI!pOlZ5d^YM$FGH6u$9 z7D-`}OR);TXeX)E?uRsvlf>!vHYNKd){F;e9vJm+vJ%)TWhu5n9%bKvJbrSYDUX}t zqiK!EvK|Me$Ljy2+WB%ze0eK->HfT^AF`K3oI)GZtO+Ge;BsrO!Q5Bx&vj3Lr*5sq z8TGrxKi{P)&@KxsCY#-amNbLm@jYzinJ#Q&m$-Wck>oa-w3-4Xav?aYhkCZKl6E%{yPLk*1S7+LWI1Q7fJ^y2OjjO1H6r=^h370K3vGDru?74^KrtZar9Z zlJUmAIL&h<*-!yAtI_?rC4M41lot(UkezlT_>(1m;&#YQtKSea8rt33R;-}A#Y1}} zw`qOBRcDI9K|OS^B0MWyJbN~1BapC}R9oDpu{{qwmtKyN-Qf1MR9jP7-C1{UgF<}v?c)qG^qm2 zIFCf3gI3ij3cJr)%O$Z#8l0h=SR{vsCkHv}K2*Hq?Vu%l%g4eXg(rj1+^6WzG+z9h zU1_yH*$5tnl2+R%xaoA-LM7P&DcbZDchk z>|`}3*8q&yo}Zuq@qaUAe=CaR5jYmW#<%Ed=aL0ClTWB;9ejJDFt0L z!zV)IhL*@Ei;#S1GxT)YKI~kLFlR$d7xm9BV~_DX_QOIufyv!4C!&5V0`5c8KZq!E zr|ikqN5xBgoi#V={tm)Db+r?_V9f+u{pUy)Zv5%SlH0Kve+sC?1IL;whqdm zi+D%svqM*tdfxYCt`Z4Qeadrb zD-L#S=d=8Uc4MD0%inI6zk|-%QvMFQDFFF9n1=v1+G0F72;xEWBP=6sqkni1C!rOp zrP!b()C%K=R=O4fs6@!^76=y+7zs?s%$ZL{V|cuk`*InL+@3AL9F2A}Ma~LOv66>M z^N$?vj@UR6Qp};sOqen=xA+^m6-z?#4E%>z-{00O_i?i5Xjl(Qx_xLuJ zDR8X-N(v)BwmzFC*DG4hD~<>%@rpBYlT`}Yl3dDWS;{k3DVwcQnkg{fsx(=H4F9}@ z-)_P0w&3?sV60hbGV>Vx842EDfp=Qq-3Va6Hw3|~$b-=D80^hXkZwZShE<80V&@>4 z-@H{4uWWf^E1ZkW?&+JSqxPmf@ia$5ZvYAwH@xMpVAXWd4;zBPr>O5~?D}S{vJah9 zTLE#NOF7t{qAakc;Or+;inm_Cj;eU60_d#)bQ5UM?dAqi8*PhrRa8}oU*hl)| z9)!+W_y+4_=mM@yNBk&Dn5hV%N$Ng?9;>}S>nd&Mv2s-Mmj5?YtUomsVT+3Orq>HN z1LD!0Op5UUlu?Ply9TBL8qegi_PMhLD&;F%u<)hAj26UZy^~w8P;@RaIq;bAcsNPo zNo5<7qPU<#1Ycds@%A?MjGkOdw)mD+%DS*OJy`Co;-Y&7OPY+J@bx>)aZ!MLXr)(R zJVgEEvQi>vVYbS0jH&K^8uIoVe?866Aw02%(N^jFXgt{iFvMDHL|-iNiyCa#+)qQ* ze&b`DpkN)m&+OA{v7?du^jg`cl>jRpv?;y9NPRL z31&!bUPRGU`=uGV-D#~xwVi><$6jlWw+5Ra9g#_RLP?vnHflAEOlza0bv%*CI+_AR zYnTEHEOl6~)zmY5y@ao~;5S(CuTX#{SC60xLbcfS$MCfhexC*3ZNcXTsTO-7nHf6n zC*PoU&W+ENL0<7m7SU`@nADv19wLwl)%!rQ3fmM%fV6)ggzx4Dpa zs?3WG(QDZC3U|$(Eriak=Tq*e^U*?3%R2xVZF{L-kgz zlsKnE3aV`3{U{wX^nkcm;@`+l+EQYp1n3|D@)re7fMo06P;B~F;mt}tia#)tOVg99_BPrkl4e2OX=zG#0G)E?OB%+z4)h< zk`ySBeps_cx(z#Wh7-C{5}4znzkHRVWi?D_JD|S>GTO6dnGM>WwTPq||Jt((({UTp zAv)?u?&I|kUo)T0ZQf&~M229t*zToMIcT!3_A)nzEWgfvNPW7x zVc7NbuRZG~gc`}p7idTkA->Uh$SOs=`3i;M9-|Xa+PPLmbN!@LeEd(O<9zaJbZE|m-va5ljrB&TOf(jyIj{P(3P7=?l#gki}ozqr(y$H zV&BVjN5OWigPP9Jn{bUO2BY*&MLV5l+yq!t93olqQh>BKY=;C;&2WN`4&1iC!~%-} zhfd~I57HkcfN$){c7!^k92RXT3&WoACW`{xBfq>>ihl~XK zATcKvyu4!knTcIwX~@w;RnR>;pEw`QCk=3#k}z{*Q26Ww`EJFu&CE_&?JT*-kzIAC z_%^fIiBV1!4KgfSlLo{1*kj~`=sB$k=a_m{Ps7!F(Bfl|i%)39R)7aVu~wEOzJtGL z9kk75o`%WCHTW#b=R!U+oqP*85ca`~%wSV<#u^A;KwKuN+DOe=S8Ay*HM?q@*vmyh zvCsgbs1qcA;fjS1EKz5R4EX$Eu?U7QMsFxRv&SJ4< z-ZE5MnH!5P1mDCh3O}?wHY!^oSYTY7Q4(EWKzyAnNlT-JEkY>tU~YwY`2}tZ>L55i z$3)G@soi0g(s)%)MhpBr3D}zMQcr{ZI2QKl2Nu2#hDjEdf`xQU??;T1IHdE39c|-k7x2WWWbd%Z-QyKXl8E-YYS#_N}>Xjtu+ELIb(r=nfyly z1QxY1Yq!DXl^nx2_etx?*%^`P>S~vQN=bnSOvci=X zKz5B^&nHuWjcp1v(L-lF7{%UNw5|kbqK1Z{Oy->SD(PBW52NQ$EYC4002OwJ*!nz6 zMvu_QVI#`Si0_2~$VF&V7&#sIJ|2lI4r3>m)NGr~_T@@KeY-?$j5V{+HhwBMgTfM- z4@UAG;?hh?z#k=EiPA08XSkljRn3c0K~WZDNg4L6QwrCn8w|sUBWuGr1^`E647^IO1)hhVCBPWHpygW8a(w@U7>R?2o4_Cr{~GW)48H?xp@7UT8K0rgW>JCgsPckW$qe^05;(W4r&tIy za=^cU4h3`$SEq{u9LLrK-7eK#66#ckh&N;`bRHHeBe>HA7Q^GuGPexevw*=QV7_gM z>);RVoe(Q!6nD{)K)|*!YsGecbFr(}9gPhlUcE|Bdt|r_I3gFyfHN}QRHgkHoy!=9 zchUiU&G#Xu78q;3_cP&#%Xe`<{z|Pq##8SC=UHCQa*5@bF|>lQ0+@^lO2ZJ4Y_MmyXr zvD4I2G@O9_5kvyJFS**^-3SxW^t6b7^uVcDa!R&=6C~TMzht&$V0QpJjbd_$naHKP zEK6vtXG_)ws0PT58$wM%w z{Y;~>gzN9JsykAG(-r}9bi+z5jc#I4x+-HL%`9<^zc`U~+nt%HJ2)MCK@O54HP7RS zy@)kg;%Rse31X{^Igu@c#T6#MGVElNEyhx&pqHe8YC}dwP~0htv`mnvWV&goL||Q^ z8_vMhCVka&uv|@}W9T4t2!En4ZXod|*joRC%q1?uUrFhh$a=FO9zz^1pddXMeVVIp zSw%NkWp!YWixR;Zqk}Z-qm3Skl3*U&t~C)6Qo{2f6tR^rQ$g2CvgIvb#R zd7jn*heKqrXaty8{PR?b`?DN(q-|+j!TMpQ#AE7*L;MD9U|Lx!rpLQa9MK@QVM03w z4_Q8sZgdHSXh$3hzF)kCGNTOzXhS_lPc80^%D}7idg*;Wom0sfS`ubw=mq!#=L!aS z!be_53PZ;$2E2}zQ_2`9!{qKUJU#K^ZIozW|B?lm!5TXd_Poj?P}1Rwu8sbNXD@Y# zE)P*zr>S6=JPwo?`Qlq)P&CouB6*f77Td+L8J)vAL3$fw_4yQw-AkhNKj|+GD8qSd z9;i+fKH`VzckYY~k3ISZ=8Ka<$z_;~oS@kZJN|pi!2L9x$PtS%B#t*?=7-~r-5JLl z0XIk(TpIQ?DCA)ysKpq`CS-bUn`XzMf<85Ms3C5@6(yrfT&_fr? z><@^Wo|4VD`cp_F+%k{O$6bEr@6sE+%Deal@jmkw+#!g+--B^ixxlNuv{3#YxXG(* zxXr8l5$Tjhzg1@VBczqx+!Ie}M}Xr32 zE%%!Mv(?&XS7O0;CrtQmC4{zw2_oCVg*WM`e_$5n%!Q}^hfgv~GaBpZnWj8&W3fy@ zvQ00T)(P!}Z3Dd-$XWV@qA1G?iRf@a8v7u|?gsWL55KWj((uQDpsE?e?N#5O;q+N#9qX6hI7k$R5(0oZO*U&AM z>DU|LX0jVQ_y9vEMifr!#C~ybNS?Yy3=cerNwg_&Cnb1mAt2qny$=omT-Tw}-4s+r zs2j0{t7!)Ijmn*SxU`Rt>tHW(7iaB4@5Bbm#N*Pk!gXQ3B=vg}vGE3mAU?C4zz9M$ zm(E6fh^)vRg@$?#7c*%y0&cNV``-E~gvY!ao?(qDb$diI09N`z6E~ zVMvH=oyO7aNrCF&T!xi2hMQdzk~yFFb-f3 z!!O;Rua`r4PF^L}uCQ7}f64Tb zff|>?1RTjEVv*}~fOZq`(SL=}W&#fQO2GINl28l!;E(#B@Ek+CkB_#C^{0w^7()_qtDM6_ZG z6t%l*Yj@>h>cs_%WmX1{nPI4eNdqK)U}F4~AzcO?J%I5J+uVVzJv9j@Rwn(qIJ=4a zCqlW}&KWpZXrLeDy2DH?lb=C*?VGjWj2kEM<^1n37hv@#Pkj?;t-{It_3)rp2$@RV ziaBb=j+eBgxsTI4gb`;tu#X#-Gsv(L88pkp>NxK@Pc{{xJFWKT!X2AWLGD=;XrgX3 zwieU#(R}wF_HZMDI^c0&Jo(6#{F1W-2h9t3EhIgYG27Ww|94a)Eh^-B%y3^1<0{jv zhnDWGs@`D59#>UgI@T0498P3G^VHV?tGVan)SSRvF3Fro9>)nBHbnjS4B`n@{I@xQ zv&_AiFlTrWaEU{YNsVCg!PJdsTlzC6Tu4ycB$TNHS$}%!H)b;Gd&H-jfr4<27=iV zx;={|f{MYuL4*jNi4HP@96nbmd7t3lXGwAR-E~I^`re%IM1YI^-)C;rm0D=jo8@X* z1)re8K?DYX8;Um^U}{en?_i4p6^0oyw-4>Eqjy;b-LZ9&IFj^;m9j8%TFV7w5iygw z5}t3>5=$>-L~{R8Rf*&&k1BPC2)077`x@jJ>G@mnckX%U-8k9YlQdo?#W#R7^E9|RSGt!f^Unb#lQog~)j_X@_>GTvt zuItJ5vl9@m?@7{Sl4ncK2DA!>iQ@1pNVQsT2`AIZYDy-Z7H+0wb90)XlW}OyTr4?d zGhBOeGhBgY&>qNDa1Aft$csHW7!|R}k!~wE7%j)S?}OaJ2N8o?Io3&i0Vj|P-YMg^ z#*a^Ka+Fd6Z&mEaV7GPDNYK`)a#xA3E7G%t%h2ibK)?Pj<81eJ0-il7om?Whw7oTz zbfLR-##V|>8C+A?uTv5d|0dN1Cs6&8@uT=Pw7x6VUNF3^rx~1=%3j7NyriEj5Z<1_ z>5ncU0E~OQV_C&+5cr$&XiUTou!``m9#k(eWUfK?M#0}~qZ|7Hlt*R*ZmbW6I|!|* z1J{_qqb+$F&QN(|jp*g>K)5@DhJ_N?q#vD;VGFE}CndtJxjmRCFt9mlNe5L$*bM+v zRSe*CoXx_?cG{ptU-s$BMLKzNyYdJVu6YUoFi>K(+`aual(So01!B3?C4qh=l z4zAU7Fuc4Qs(Y3Nf2{?7BLWa=v<$A4F}Xa_B-|SJ+0ekP6m$Ta4*k~uI;|oU_3L1L z&-E1KaD+RLkV<6WIr}GFV)rCwhq26RXnZLPIs2z?2_Q1UODL;kAP}>5bcsjJte0BN z4qqv43&Yyw}&vl{n)!)l^fwwfr= zMB9jAMn;i9L5=ojQQ$;tJAW>5l{V}h@muBx&*eQ zbqNIAt+};tdLfJ?V@c}wE{7@#x_n~Yu`2iEkmE_l2Fw4^@h=7yG&n34!budYOmn>numHX0kZpW#} zFT^SXR){vvgvx);XsGh1;k%&B@+>J|bp*aY7c(pOs?2OD7xTk0Ga#1% zk(5BEwX^}U>MKDEy5&3|uK!9P2Kn|^f|#}_f7Irr3AtFqRXP1U+nT;UD%pK{Kx;zm zw1^?g@KjTLYl>a>l|`R8A)oV=&@8*s#ZdpR0IeFe{wqSQ3Hdhtt9WGU0v8{pw_aKj zC%)&NkY3R9o;l;bif7zVYdqtoyXkqxJpk>D+v066Eun2`bfBLGDL}ck9k4DiAH>M# z9HI19losJY57Z6}?b|{NP@zQ2hjKu3%G3DtB@vo6VOouDm>{oFC0DR#e)>8(8s?`w z+(3l}#T*8}3K^AxZNN0H1Vzk@Wh-0W@5}BQ(z+Y~JnUBbRslYJLQ_4Z23_G63ObjNYcbh${|4EYu%-m*KO-55!t;K%w9G13Q z5BwgL!EZ3UMbL`aas0*}R@903ol=yO`0WsXiIPBl1;0OHfD`#Wcr|6iSVTSR zzZbvvGri$E6dlA&EUf$$g$lE!%Qb|u9J z7f=?r@kV&Ol_+*{9IZ28GNn{cmHX4kcY#SV_K&0in`CCW8I4b{(#`3?us02{%0yp| z1J*QKledTm!ZXqk^DP{do^c9xRvMy2LRgH(y@q@#^s*~ZPu@v{qbYQ^p?O$QEY{c{ zluHEkDIb3#7``@*u5+ZU@e3wrtL_z_KFB%PJgmA|{5kXW9{79#jtwN<&e;ji zCJ6(OM6s6_&Vf!kcaB$VIRoqZXb0$1O?G@)86QsEiaBPd@f+ejZm2^qB0wrNX_X3b zMyW|EH9=>O^?W*xPZl)0sITcMn%seOG@9?aqfa>k2Iqe06@miC5iVJC@t$+cud#1y z5V>%lY0n}jaU)?iU2W_&Ha7!CMxmB4^R0!ndsk6S;f9eP1cpZ{Nk=`C#-5BX%DT*j zxL?-zp(blD%axGH_VPRqL8iO~W+<(D;jKm&CFb&zF^`4d^VN{F zBabJSM{Vlq%6QZGl_ja%Qrm`5OF7xk2STyc^%6)3#s*%v!;s}S2fAMbK_%(!!-qXQZx=aBE&9qa>CL*mAJrSYY|~` zH&L1cAJw71n0wznu7Rpqk_;dBaV(04*m*AQx|xmf9MN zR^70`6#hJAcqu_Rj)%bKdb%f&)Q1w%rLKLRg-^@-66|i$61~)!;+6X?QZ9^q4U&)h z8W4kGKo%*q8b*m8+YPDXe4wz=#;5&RFpsWaaD2o4IwGM~=C;fs+!5XlSyRL?;4#X= zn+WE{lVOGv%$JBa1|tU+4&mGyk5hxJDqtvgYzLW**?={_KPV1? zASv^7glhrv$LW?JuG=h0tmNnK&q7PAJ0DTxm4o)lLjq(16nM5+ zN>uA~n;!z}7R!+y5T7n*D0B3pAtmIBId`(2q=^CSoC~060>UF{g~bA6g`o7QJDtYa z>Cw(;Ma#;Milr@qpjjB%EfUvMCWj2S%RriEi ziytjS*B^IkrS%vY6%}_ebY8zQz4AkcwwiTZ6&#-;FAOg7JoJ5B;-QC{@fGUVf9^%A z;&AW&Wn4!5TSy9jf?g|j${1St5?jpFFjB=bkbtHy4mXpAdmzFY&7qgRX`F2N&;gu% zw+6(wWIlAd7JwN!;T?o|sfq18DvQ|R;BO+dy3qJJ}iADan}(48D%6cBHq&^AQNzN{T+ zhYY*LETmbcRH(ZzX^N-JymOF)&MTs&E@Kj1G5_A6xJi#mm4J3vH_q5y=mxZ%TF4Ubfq8=(QV=3Nav`sQT<7}aUlK~q{A7IQN;(S zyzjf|$Ua)@8Y`PHH^_)Jvb;R8lu#2f7g;d06G2gjqX53OwL6FcW?Kb-dqWBJ6rct- zhpM9>0=*f!hn!&<(0@lb-cLdg^E7xcW&%G#Ssdz|s-iP@_d!FUXZ!f&D)~~uFXbdt z{(Wr5Z|4ba(ymUx`07|S205lia%6`-dN+3h3_UF!n6^Pqg5qNt7k{KLW1kwy7Pk;N ztN1;crCtF%_Q+&Bd(qdX6IoPb0w$XhrgeMqgo%{a+pJEt)(^etwPh+Ic^q7e;pD6&A5U@;EXLJ66GQXCv z!)JMsxI*SMhRTKKu`Ufxo$)yne7r@8R2Trq zJr#qiCWzb8;H2*AO>i57L$gfg?O!<-$rII4sDrj+X;6%j8Bx87@_r3uFEO)kbsg8J zIJhiuw$RLwn5cfe>SEmB&Gk;_Cmrww$H9HXz5NsU7LPDCQK(*oN)AH1q_ z)2H%|QfHZ9X4>DITX(2Bn#&o1OcPj)i|Nbk2Q@JP-Q1lW5H>Tz&p89C0IdM_k3`)$ zgD6(dBi$XJfZm4{>Y#Z08_b;e{m3CIKtcR&gksc0BPBhga<2nk9v22!aikZAsSA!* zMlfHX0r3G1Y*)h)wO3L@@`tP2U|ZZ`7Uq`q8Kw>aG`)%kK0hQ3w@vWKhr zC~3Irsd9<)&7?PxB&a>&tq3u#56Gg3)@DHAY%8{!jv);MGinrVSra2=ZrM8fs$`d6 zD&CTz_zFVWi|R?ze36Au>X-#m5is|u$tI)8e54e(TDnBRjkwB0cOjF1@Iv)`S>Wv^ zjE_ccw>KavO+bapeGjz74`p&w%0z{=kY8sM1h%A+(oiAg~M(L4Ftm zn09nmh|llf+HoU%D#P)|fE|=ys1`|res99~llbh5wxcX4wwaK30a8pSiWU(?Bnku5 zrCa5KhI666kk?e=-!gNL=W@hEm99E-j}M4D%>??Y9%K)8t*rTEpNI@cW^L#A3Nb?h znW|?#zq#TE;W$Edhhcv%soE|H#P#khr&~9q!gW*#ms!ZKIY;M}DyCiFwA0-;AUeZR z#J`6$aW@K&uR%zfv`=QBgyZq+7(@e+(J0OOt^=8y1*<$L3e}0t+6_l)H*DNdKqJbL z+0-CoxK89yz{g5tdEAt}Bz_n((ekn;T=T%b>00`5 z&Oe9WVfW)}eV^N4Z`=XM_%4S<|6e7%6a{(CnB5tf=HZV3!@JwwME@ds(V*2#m!x;s z?XoXO>&W0YS3I09Lp#2VY2byN$oGu8-Qr>Z0XON^LK8Ph;?gv38d4rHal3(=L0c`< zB-J*xFx*Nipd_7%NWI?7^aofX^i>?{dQkEoNgxeMen2=**_<*a{!0Lghk!Z$1VVZa z&6Rkg4F%$B5hr`V-o>()5S`m)IDRiudGxz5O_{hGcrAr84RlUcORz)}6u*;sB(jIn z$XK3N$X8RIWBlfd=MiQ90d(B9ZIWJebMDe!)+?CwlgS~GPB4+O(lE`qA!*EHrxu%- zUxxiCz6*r$XAojleR~?c_yM4p-*c=usYOmvQD+P7QM1})6J7H$|aRndbSt47Ki-DINYo{Qc>GsjsnE`FFA@ok{syPKKbjhP6C zswR?w7Lv5xhwB|oB+mi~3ZDqaFi&m&wnz&1MDei<#UGInYzIQ-E|75TCfp+Nsu_|J zx`*Ff#*JbUXfZvN%VKUSK0DouQLB<@^{hWUWI-y{{%OAJmFQIMEWuOedDKIWjf-f0QN5Y zE<$_>euRTyDbI^PKmBj;Q(ook_|3+z|9^Uwdi;Ke-xB1Zg?j9F3o8u;gE5mxXX$uH{D6`XH0 z7c^QzlJ7JZRt3MocZ!XHy@H~jOf&|Q%V}q?3i0JFvc)Cz011s%m>H-5w-qc7OmgyY zt)NL8t@5?YT#RH|h1h%?k~jIy1tjoxSj!Q}oTZ-K?sK72n=_;bWiEq=@70sW6Q9Lq z8os#Xx`fjvrt@88rk#hhOI554yEu*Wjgx8c3R*iavCtMFu2k_>>jhy??si2LL~@{&3`iBU`!F1L!YTyFGf2KDEfTuywHv zv`x1w>6eAAjb>`49w~Co)!t6&)7+c9kt}U{%D8Nk7MWNnir^Be)Dz-`KESvPeKS!VMnyY`YiZ&WtobtOX zacjDoo4UriB3tk0dBIi|?Pv6^6fqPuPfMgCXE*kqJ|#Pn1yJ?9+6xrDb-}_L=C_vA zxYWNFzi)H_?VL&-Tdt%56ieI=t=}eIg~|syjws+)(?@5fiZ%(9k?j1yvuz|2=Q< zk!fz1ZEj?dKFy_HJ~|PbVT<kcwV|4>ZpW%n=?qi@_IscGoD@zCbPXR{f2Z zL>4xs>&^z{Fs>L}At}{O5pz)) z{M8ec!h@i;tw3*IxZwB!RKK>!2@!N1*-Cv*oub<>v#H~ zE3>QTBC`KwH#^i^NFUB(Wgk@c=&9o7*0lqh-|6tS>Zv1iAt3czdpVHA%aEbt$W}5z zBAXWD1B6=%_a4OVB-}fIy9I{>j5VoA?iKjt1q4wL5%cD?YSl%~j{Alq$|(jRikjr? z$q?sAF30`&Y#H|fif0KfnY0Vsy{~VjNS!B>1~nX39aXjkTAN4vOIKx;lA6@{eUy@4 z{cM@CK<1iTsjtixQ^@19*!{MaO3g##wd-%6rtxZTa(+qOq&AXOltcs2XEElAO|n}+ z>YJLME>kM2@*0{K!2F@>8jW5hZ8g31wvCihg*|fak*MFs6+fVhRp+V0s+^V4Nt7o3 zF(Na;Rdt@ogT9+rykqlth^C%TS)$JVT5}<|U-}FxTYac_&r4oP+^T;@6#vB%H{IDq zy$N3-RvlWOl-5#MUUzf@AglK-XcbSvsZ(3p33Cc7Eb#=&C5wvWAbL^sdS~i)O>!0w7g_Bm|IYhuMiaEkf5jKt(ZbjJmb0uf>ydpxtt3o}hb#9ey z;pEb8)L!k6Y_3%Pc*sK_l|Kf5AaaQiwaZmmpLbyC+%F zb?;evFX%r|t$pe&nM5GVK3Nbhnhuf&`9ShTD01Gs@R*s17&QYC=W;~D`!_%bqUb1- zk;)&1k{6m{jG8UWN#kvE8lRxWvM(T!R&A{TWTUM76B?S1S>i>Mn||UQGzZnPXPlGx-=ox^_K_o! zBLR^5wX4;CP?O%UU}5W#b{?e%P*zXZda65+q!$etyFOISlbQHZ$@oIh6IX zhO)D@HggF707Kar3}r*iq0B9ZGPNywj$wTv_8g<1c~tcr!&$tCaTYhvjAR!#M|)$O zoT(;2u-ahJxN8@*<6ON4^9yZ9>a$;#9eHmyj_!Q<*)OMG+M746+4c71!X2%<(CAKm zw7#rhQ3;N#qHFZ26cf)U20OK5N@RTO%EEv+3Xb<}hK{(hu#|cQMxrZ=5HVm*YPXT2 zUpXjHDatq#ZT`G6Pi)7F{;qz#Q-8pv-|Hq$XbGFPThVXH1?JQ(c|26|vFJ*;CZfI$ z=x^+-Ee8pKn6Cqx91DSH)l~t}h;bN=oAMvjyH>zG)=^uC4I zu``(#?APPLdx)&m3fdv7dC7D5Xk0fwhA~yg#o>T z0YL}BYKQP3Su0gATG%l~Tr!$W9Sjlc5eTP1P%57^BMl&Fpy?LSeF)4mp{UEr9@lU< zQdB7-vSO7HtW$iK!t)kDu~;L<6hJR%ofE1g<1nwJbP8(e(Y}T9FjyRssy8->NBWk( zICRJ1spFlt$Q^TqIt~m^U{sl+rQjgdQg-!h9Qa#+XnZbJh!6tvN?xBA88lbSq%ic* zR1^jlXQ%SL2^|~Ear3-rujn*abehu~4>4py?7vMd zix>gnrD2MV!Ue5|r{#Df9x?=1fYc-V<}Dc5+*;fW#?T1tE`EP5nPuCx1CH9GcJ-3Q zPq}Q7ubXC5Lu%#7xdF=ip@W6Eq#Zk3c_{5y^d*K;qc@p2+8Z!KU1X|7do6_VcS9?# zSR(sj9txRTe7N}i;?!gwFIW1TXhhVV&p-uViaQDpw`h^^(BHW>)e{ioNDmU@2VZHN zN3n`}*5MX=q+dXsWhSZizKLlijI8=O&ZxIWpbZwHR5mG?Z=U*XD4s0LSLm-jlFgF}F94^hwm(I)q0559Aae-~%D3y4?!#LjR43}!Y13woKoy zceNZP%ON%;Mun63dJa$hI>fg!AYMR^Aud7(rA5n_jUHFPWAGqI>kN|7eXx2}jHD#6 z5Z7kZwNF6kPy_RfLcKQ$?Uyn13BC1nvU)?S);X0rSeSe~!uTh&K-WBoqpND5=!;H2 zFFJ|n!w1DcdLf!3_AP=e=~{MPEm`*cQf52^+S8dn3CQqU=YARlH0-2=e2GBzt;ZjYOAMG7$ z ztg6G;;phGJwyCX^TZqkUq(EK1@Hx8LNDKvS&bng?I9L5K&;RN=^Ux*W z@|%NmQ!H;D?S3?i-lG5gWRaf&24+UG9u<=(rxm=?-P+C2?ANSIvXiY%OHC{NqeeT*z&-2v3 zd5kWfr*VL$P0>;+%s6|ruj{luZ%1n?YZIWtq(j6#pP{e8W`w?iS2mKP&2+ok%UHh{ z{qf?AmE|D;QKXjjGM9EUl(mf&i_|OkIxr{0Fwij+nnicBT3J06Ge%4iS+9~_d=pBT zI@En~2CkBWpszU#zqQJCog|4S-)p3(nMjTM8j1!V>RK544p9}G5~L$hIv4s`ID}AKn9%g=`vu8UyeYnKUo`} zBxCIHF%|LJNyGSAW<2wK*R3}wHSG%-hDK%>gq<$51 zW509Kc%0z_|CRVVcw|x|%Ox@*C4zQDK*dqkfcRu2 z*B;w>;p3ao?%PM`jSDq#ePn_r`b1uz;i(shi@Q)kv5zdCM$U?Tfdne?KwZWE3f^!< zp92te^kSTG!z^^nVc(ao$T^@NFMgzC~7|wD3!ki0P_g@09YJ7(Tg~m**aFuK||VNuf7CEfx~mfwQ=ZycoMW| z;to$eFhZjb-ypxDOj~Lnd zTxV>RkQ)DsN~p4`P@IEQxOFHd<~u}&wTg-H1Q~m{72W4>t1~0Vc=0jNAqRb=Fj7XJ zKwL?6*XJiA^zb5&M-1dlBF^4xms)s=G_npcj*?0pb&Vb4IXxzmtq zP(a`e0cX2{vbA0f;rWmzfHY6i6sN90rI;@+_$113o1gWL#KoKnW2q?@=1DY%o~;~~ zPnh!_6yr?oCKc#}?E%9B|5quK;Rs@b%d@T-8fwwAWczO<|8yi@JO$RGDLj_@;U=Ua zA7!6Y{Ql&@2LTq+$C6iK<*%UCXtIxf@GbaOxYL=+Oap-RD$^ zdwXlmd4@oV5E%Mg3U1-Wl%i5E%hf*{eUDqe9@lFo=eB(6(cjV^NZzr-3FUHiv?du_ zW1}-@(fQpttggE;`^PDTgu1HbsI%&dnG11=Udh|b9T@)gS!X#*W}W4teSB{1XyLL! zuYt7McmEcfWpf_+!?5aSrXK5~V%wc-*kq$fYw0kP0c}FO^2|2m08lRix*y9aXSww1 zvz$>5IuUd^<|m@}yFiToMN7&#TT5NB+);G}pS?W*x;kO(0L5r*&-i~|&S_p^IOM)5HQ-`g6_Yl*zXV|qp)c0rV z&18%EJ;T-=M|}`G@`2K&&vZtwl3}MllP|oYZGoMN+6OCAp86BwZQGkXk4wr z==&<=Gw|-wFo@P~SQiw`-k#krEj*4Pr37c5Vj&XNJO$ur?KH7`_cI4T)SPzzaDT}) zoe`y~8O?^@%w{$gU-$h=BCcd57BvU?Dv7CMUttL2#HjtKZOBz8PPvoMDL74Qd!%;?a8 zW6dXkDy9~Mj+5{ZxGe>@N=#1inImk4Km||#2$svqDS;Hla!)^tRCOh2fze^4Q9oqqyG74N0+o@`(duAylCo}OP(D$Agt}#FBooc z9c!VNj*c95MTO7sJ3$iiZ3;9IIB{d$-3n;*a>SL;v$4y!N~vnvNc2HY8_p?$N$31` zqt}103zx6W>w`@Ybm0N3$6aY_Ts?qmfsc0p>xzMQj(*)w=yD?O{Tf=b!?*N6Ob*V7 zcH4gU&`k}&oh-NTejVvI9{s8xE-UE3{9u5;zdvtKC$bDKO zs1p@Mhq^lSOJSc_>XQa1Hh{@r6JEt08ozL~wo&>Zs9z&(Bn$ieQ&Pm6s}vQSS{`?? z$X3l_!?LzF6{{UxiBRXqLdQ_w3}pms689=1iPW_NQ&J$|1olE+LC>AV#y z;ZHQTqCK6OjP|s<%30Y;!`tn_CJh_gu-@fT`dzs6L3u04^KF%)?F&`HD#!pBUD?nt z=LOP)5Gc6k2A@WI!DuIuJbwkI`O2Sx= z9sIU0Re=NF>w+^orwQm>DS;9T`hf+Es8jX8LgWgPx2kz290?x_=T+--;6l@o7@iZo zae1FA=RDYfg$iLIhEE##Z|E9pI@s`ebY#hfuEBp88$Q2>v5E1M=-@w35tyk&lzwt3 z0{2lT!;Pxr--(+}I;x!Nfu})}z-o;1Ni>oN^R%5^!od6s!E_AqDS=hSOm7hHQz-?}jnn0^$2ZX%oviI7xKW!y#(W zzcZMvLl^Sr#Zfn$n-rW9=bzN+&(?J?t!k{tP6jPiK`T*oe$qI^j6Ql>XRw4vCr$Cs zPa;MK5AZq?au#6ffU0Pwa(g>vCddLnAz`M{I~Af$ihaQO8081jIVA~WZ{Vd%SeupRw1kfSM2EeRx)62+8*Uc`+r=XD9X(ckkr?H4$YblyJJ_6Pf)= z3!^r)4aPmuktGpF=C_d{B8q}}5o1TM(a=7E_$!wDSzi3}_xo3$Qa!K*Ay^NM1UxB> z^%h1yR5b_bqsdAB)$e2S9sG&J2#*COE7$BLeuL|V{i{R%)rbAwJrqNg%fI@hfAwjI zJ=pKGiV%PFdL9|H4Y zn@ZLEHXLg%6Mt2$Z-d*?pzRDQw5n!0ED>lI{!#yks`&{*+C}^q+cHYkI_UUE0_^9V zEq(ASE(rCxJGdZA1=}EjDOeV1=Ysbt10M=|v1F`jdXd@}<`C1{g#qHd81jWS)%}$e zZ5!8!@t{rRyMq$kzXZ2eENT6eEAz`w@TLd{Zf?qDqIfd3Kun}9et`ul|E9=5lSHi}s&akfP8~l!YNBHKd z%i$ZVz73D6x)i>?>Yw4^RTuE9+2_N9t1jZ?)Hxij_(!-;ReLzT>g(e0>(btNk?N0F z!|+`>75HRD@>P0kd<4ELZWcxy!fbm*azRLa0r~5g*BtSVFRW5V#g_(R5FPLw<+GD6 z9d1@C46VcfP74pI;g>NXfeyhC)?cM9Zpa}Wg+)~fd}M*Vqn_PkNBx$It|XtBoFDr0 z2dFOENRI=XPHh;H3k?+0 zb5+gTfM-&?NmBhZ2HdVHT<@qJEr zK(BeH5t!locMxM~-tV0^VE-9h84&S>7K_--$n=E<&>m7Buj}HQtzMz=ZP%Fs1Y72J zcr$VOo)TU2dE^Zoin7VxL!;jBa4zfS4cdPl|AGHSGi9_On!J|Ic5SsP3x zHgD@Id?%&_E(!lcd1s_V{51-HO_IMx>Cg1nq?2ThWiYgAs8wyo?%cmptD*@dMBMeS@ES3>D{w+HiUaM+jTcC}!nV^t{9ci%RazAT;R5YnE6;O9EfI#TGGM6n@ zHlI*64S}EU+eB}YZ;_IsKSQk6_bqnK>2w;dhDXQuLw?3DCNMX)Tzr?og&FfqF0KWO z7*c|F!jVGZ!0I7E{j~8%g8COjXx+5exi{%n?H&H8?xPV7@`L%qWT`tCjK+wF!f7DFFF=tU7@sGj1-&@?aMJM#_Rx8_G!CPGsv+&_Y% z^IyMk!M?;|w-exNK6A#h)wQexkg1cM?|IHgx-qP*hcdx zZ}!^!I9KC0qr`F02+dHv^xnn$+aAv16k<{&4(fV+)~2*vJH^G^A24_L9R?^GZ{(&> z1XEn$$;>B_1+PtUsa`sM(bqGQ#IDTy8KkuQY_q++YVI|T~G%kri zq)Owk{ibR2g5qwP56PaUgg<^yw6Bk?#ON43G9Xf&626)w!&DN7SDAN6LC zW=oow+_*AsR4_lzs|f50V+mSGV+OPX(o`FF`RAq`2?vhehKsufPNt0P?Nc%(5(l;0 zwJFHwt-jT19JF+h6(_PHT5%|k6ElH0tVa?1Nc53tqv}Dx1W+v!=Q>ji9?VJ!f<@xa z3?(okCirmTA}1A`i1u1$&DxT_iui0`;zl$Xte>0!yG29w@{tc9m!22F9SDO;8y*`O zvVqAU!ndlXFX1DFLB!&uL#-W<+tvU=8%mPCS2gVdyu@;SV6QmP+}$Tm=RBg#`uv>@j+*)rN$ysGA!)fWARp1~P&;x}ab#DMpV0R^%frbqoZM z61x6F>L(>*urx3x1@ng%%HHm90ckwt3EvXSh~`+dnQsW}!-!!{^L|UOi{tmX0-?E~ zGU}+*ouQy|F+5-{_6*lyw8EqZ3oA_&;a<|(py2^Jr-uqB>omoaH5xQ`{HO$pK%JN& zqlI5`F=0p5Ox%y{RFbk1x{!ZzXTXybxJOBnOldG_xvycpf)jHJ=LYXgiOgBAn7;rq zK*N|{X#-Y4Xv;;~uTmhiupsmy1C;m-+N9a*m7#f;kYB}m|KucmtHcKg3h38|w~$25 zh0~ct6COg5S49d!4@=+AXWmiaY%VGD2gU`m((?mZY5AeMWF!nuTS)O1`paT6sC=`} z{sQ=B9PSk9MC73~ytb&(9wI#8pDLFE8(Ai-ogK~>X7@L2N=r7HajVz9Xcvn$5opb9OqIDBx8 z?BB#g<2W?>0NTSm$*U+o_!@l@df=@{#D#rE+wyTzNPg%Zc##emh5JH6RYF2XMI&N> z{Ct>bpAu|dL?TQ%i}h__OCCk}p~GE3#Ud8^20S7!RijK2PJZb3@To|_)JcxT%7`_n)fP(A;Xr5sV_-a2g4M!CwsHDe-y}}Y$Q1T`jntx9srIL|yl1$3LuC`MN zLJLvS+c(fisnfQj^npK_G{SZe(FLWbMh#4|lYT_QIp5`L>PPr4k6Do>>5q|AvOA#o zpcANDNug}_n#()kS3h{oTte98 zNr%oJDMGg@!{@N(IX-0 zCP|92EK+|QqD}3ogo!gU%7hQYp|&p)1D{G-#I&7TD5<9vd1n8x)~nB^jd+c68)Iic za05(;6H{_UWv=&{0!-tS1(?qz6jWV|40(h)e_wyPhHt&&$5iVW$qOaz$0E<%9*U2) zE?x1yOpP&4G+`?PN;Yzrx`A&Uzh6w5CMu_SugRyB^C{*0?v#B=8q7a`JY^JEDz7KK zmoDB#=;Fl%6>VZdfWrpu_ch1a^i6l-Vos8>P)vY!(Zw7nekU{@Y=l=MIiPU^ZC^=Y z)jL?yOw14c3RB{FB##vni%o1i=z_Qgol<F!)$Irs+P&9Yl`8R#a0X&549!KC z!x4sgjR(;#60xDHV06Mcx|Wjt3Y={q`L4TUc2wkHQeXbd4YHo$#q1+!UK#lHCyEK3 zWfQ6ioZxERuT@bz>1sbisU=*i&mjmyLOE2z<_b$G;D_0z`)|H3@jn_u-qp*Dg3Bj3h@&svb zwkEN^q+klgQkn^oa_MF%yH<&$Rf+SkV=<&Vqf+NR8<99*R0KnfIdSJO<=&(mTYZec$~00$vdENb)>&H zac|%L;k2qa++Tw!kqd{LF!E9e#3H1N{3A=M`=^4*hEqUY5oPZ4lnaH7Z|O6BHP#5B z6V&lzokW&PA%C`dIi6)jkCT&2gHw_Fq748)N zy-Vi;$KXnWeKeefR*eH_v>HNwN6s8MapcP*#|FIRy>RI~)T7GBqyZxv2f02^I8r}Q z0Nx5^eP02%%j0J7?@>3|mBK|&fE5s`oE(dgC5Pn}B(@9Msrf9q6ePz^C-q8hKaxv* z5U&(Dtt6y15NRowE5{@6*UcG|3R?*~>C$m%a2@A*CXP&?W8st~4oYE<29j=D;7Gz= z;mUHQ(4o42B^s=JW-Jwl&3u1Jz6S_^`yh{3Q3Iri;s!-5Gh@R{rvI33`X_&P{>e_Hd+HxZC35LwP@lgTn>0c1ptNBP~-CW+393M7fuGL`(US!@KL~t9akn zjQZ<(U~cGvhuouda$S9u;QN|tRCWLD=>9#vK-?RV{wA0wV79@$0J9Tj56nj}pmRFt zoDMq;b{gzd*yxQ9q`*cuc_0ZkI>ZA?*tjeC0R?Qu)%7CLrycQiz$nk74ZuX{i+rQ> zJ?eqMC~c2AkZ>fwtLiPtQ1%W(3?OivCsKu@F^O})LVgr&lj>GbT{TmNmX=kR60va%NLMsrExGF z91zP0g%{fzi=eHTgfRd7kk}7;1$%QMDd7Q)?g$nb&!YQsJ7_f>Ylnj_zUlHREs4e8 zhL}E2k2F>#1lksi-aCG`I5AfonJdZz8A*x$5$q5|2KXoROX1PVesC2I7rP7$jz$bL zzK#^}Mqh_o#BpPd*x%RT^1kZ#wugs64U{GpVVsSW^g$E+^V?scpWoZTp(LXZyuswn z{r4HLJbX~R8LCnvAXefV(FPk#Mb(VU9C4Fw2aCr92T>rL>GyVo#{mUvb>eW?SfdvE z;V$ceXB-kf0@%;Zvei!vqOUi?qj?{GqCWWr$iSD5jGmqfy0N3@xKE+~ns*QmdR&aV zxChHi11{kti;{UN!~LI15&JNAN@x$Q>mS3t3c{y9Bp^AexI(C72609b>ds6z6GF`s zB!#vMm&C!C;L7sYb#P|GKPr|f5HT)hIP)R$A)WS_9&v^Hkz_{Iq{KY(&xC@JcwXRq z;9ydmbRw)JXF$(GVU6wqxfq`n-jz81EE>8M_2f=JyU}+&j1MS>vFj^Lb9$_;{+#lh+7F*K8>9k9GK`0(m2-5VNCl00!gMv_TSA5>2 zg3wR)B5xQ(!^24L1kDU$DYl~eHbTHr2ic)Awkpg7xHQbUNmOVdNeJ_H!-StTa1p|m|6oc{INK~2!rC+SJ`QdR^@FTyU> z|NNA&TG;ZFEBsY=l;@ub>Str4pzU+T)4@ldLXH{*E^ttsuy$6QwDbj)*l&b=E1>q+ zx%QzAKu~U=Xk5a+<^RmeYP4|P_p#mR+pUChfug<*>;^w%gEAxMT>e%neP}Ob?4?ck z_Kod;pL}xOR?7R6;kk%lRRldD7cCph$x;rLE;~)!>(3R2*1?vLyCV(v@sFSc_*NF% zGtWE|PPU8~OPzjT2y4b%=sCPFGf6<5Nz3&R*nJs<0jgf{rtC{3H)SxAv7M3nyQ@97 zG0#q~Y70qL-RO*OO?(2KR~+TTZ#56~g_6ajT#?jKcPP+(ckdX?-U_s+-8%-6yQs=F z4_T%9L#@e~W^~y~rC^jm85T+_6m;VPRGbU3Sxuzt(G;#le)(25A8lz$Jd4?dOW0d~ zVQtPo_BIow#@Toijwj7MuX?FJ)R={~6(gX|x09h}?NH-khvLsa6F3O2eg5f5lh#g( zG(q2b;T^cTuK6qu(M1eYFH+Jtz(CO!=HvY9aukQ*U2 zDv0mNcqdRo-<}e_H5jBMmjni33L{=CRej3ZjfrQGNXv#+ls=q}S&Wz>1*s_rafkof zxS0ZRB|{bn@J4u=Och^8R{bzv$L%XpqjBwTY*V+iu$XS}b(Gd$6K=A*$E0rm=Uq1CM#_AuC zFI&H1^2`ndlYD6-`!M`EVblQrE%}lnhaA#{E6Xgsf$m4j4@wy#gyMYejTbxigya0DaE4+&$A3~d- zFva|e?UF~uCbG9`;2HUFs~*-Ca%1v)ZR9X%>WTxmkS{zEaW6*T7=%nZqrnU|peQzs z3|Ny4ci=LFiLaw$6aQtq(4jnVD7rSPkiRI5pmW12-w<^8?_H^MF?+uPi!YbK3##HE z!;EU{mO?Pz(-FO@c=-44@>eyH2t+$i%m#~jgWzuGEhNi21X9- zV&Og~mL;KMHLe8!%Oy;RG3wpXlpuUlOljedd`##`r0q*u38l4Ds8nNLvLHkP>AZPi z*J_Ax%wuJ11X9!OXDJpsp1zX^-+t+n>n>jU1Pa2D=!y?TA_;M9y^6lZ27nb`L)yZg zbXZHbdo%w{QM1s~)7Kz%cWFx*mM_mLdj-m_XjFIj!P`V)Ysv|>M ziB`}rKP`N!YTAU)NSj@8ov$@vOlN2iL<1Bru*aWsk~Y`F5Ic+6UOSHLF`vNv)0WjI z#Ure;Wcr(7pfa9sb?2T1HS|l=3_u1f)El^v^%V@;taJ&-@9dA%N6B6<@&4t@m`V ztRcgjke{L=ucD|Z+(*hxVS%(PMWv!ODViRrn(l&F5ZHSL7l%hMp~QriCX|K2TO-(v z!~sK`gFiP7dPnC0Ebt~`MMtqauuE=E9Y5BbNZLl;w=6o@PKF?V8@f{0DGO|aQh4OJw7<6O|dqwO+lAIIM%kk&NXse1`KDx4Bea9_}P8o3q#iSh$UM4Dx1THDyut502XhTIdGwoe@M_naNSKd`4cF7O#n zx49JgyAMS&NS7>i8*5wh*2O$ffxm16o^qEMu8XwVibr` zAVz^01!5G4Q6NTv7zJV!h*2O$ffxm16o^qEMu8XwVibr`AVz^01!5G4Q6NTv7zJV! z`0u3vG?QXai~=zV#3&G>K#T%03jFs`;DzQp98_vLEHE)ze7fEg4>Zyv{7x4)6$Xdc z`q1gF6b|Rv`oyOwa&mGK=`m=yd_q=_HRl)iRdObcrYIk$ebs8Ze}+>os#t`FlH@3!GT@5FtANQGy8v;}Btr07ixz+Ca`r3Lm z$0hgYxH)+<3koD30=a@|Gp61H_L*(e=*-FeC#tLuQqGKyPWR$5)n5}DDuwKeXQmEtX>B3WvY zirAGet%bhpE_ZF68xhymcxpk1a`*DevL3iHjod5i+-0J>oKdEmiX72L%jn}piZaeJ zZ?#w{R@A#o%R!;CJA32*I9=qA%1gykWH-5g>EfE&`eh(MU48A+`qE`;(Oti+vgT?! zYgl=HuzuV%pkQsyGIx!L_>fl(E6)$&mew!z5~3$cUyY9Fw4}Ng$<-`X*VR_mh^!gF zr`%mG(Q|rbS$(aic8RDitn^S-O&&j9JzH*|d6kRnOY2urJMNE08THPgc000v|9q)X zRy1KQGc%L3MN3&ziq`F|xwEErMGbo7RJWK{>JhWh1eUw=YwNsq%uj-gDr?GXS8&ta z9#82~_oP}}{pIzz>v>&fd380VEIrhJR&!b08W?hG zK#T%03dAT7qd<%TF$%;e5Tihh0x=5wH&Nj1OD@iadxT<7i~=zVNECSRPp%j#Vibr` zAVvX3fr3@b7S~p*=g`gqd1PU=zZ>c%(&pQwivYWQx?N9D*nn<0>e>$f-cMun;Tjw9 z|GkIs;}p2Vi^EG1r?~s>diE?{3?F!KS?r1Xfrq~Nm*EsE7Z;zPNbJ*B*{}bAq~w9B zltF{9NgZwMm9@p(zF?}lgpero28ivKXPUkOCFgsX3mM?%1$mbZ)Oqm z%bhkg7mmz=DU%pnFeQg<1alNbdCn`EolW+nd2@1j+18WCk31QfIu8Y9==7cpgIAs5 z>Ca{Gx^B1D;>pnHizOTb+(y~W!)<16b@W3Zsbyrk_A`o0F2c;9xT0z3dZc0UAWX_f z&$u$QCQ7eXN}Hu8yEX9FY6<9xPYE(VmS8Ox#bNPurK|1EgN4%NS^0a$lc6;ueuKA1 zy0RPJYP1>xdg4=Zgw2X<_99F|`hT6SMkmoztw!E?R#u`T%ZG+%d5FS=8a`92<+!A* z0^0XgXL&sCW#Ak2s6n-QY=&pt1a%!YuhbddOxnB6b+5z*TUjM-{N0gJK5%j{@5GA0@fnFfQ@1}AFunOeP6A9giIMOUkD#-rxwO*R9`mK<<#au|hP?Z)@g zXHrlX9*YRLU7>O~)uSG{rDjBN0Ys~T4Tq8Wo0&gaGb;q*r-n_a_y+Bfa9Q1}xdw8} zg;&dkht0mrn8+J4`5!2=TJ52o@(g4`jZM z0(6J2tEUT$m=97F@4M&s^G-wyN)#Sbo>arKQ!ip1Kux zFPX1iQd#ZRs_!66#{gc99q{?o4$DDqs3Az*zq-;xoA2a*7x~vR7NA!5@Lx&(6>erl z{ncYJ)|NsIfhm!w)k_J-TLaI^8YnS%nDF9JF9VxVFRiX!T*`LJ)#_5hgNlWkw$OhN z4M`JD8N?mY&5{FD>lN#~qEx6mGOIn}d=8#H@M;%VL4BeZUcI}T@W2AQ;*&Dg3lE-z zS4VhYlcfG2rA%50L_wmnT3tioHMLO`(iW**(nS!$>q!;0dIjOHs00OMVvJG-y?NpfFSm z<(8VInfU1|d3@{tqvM-27SXu$f78>5yFKe*NT+Ky%p4dh0lA}g)Q{lejIxY!IC9k) z#p+V@5DW>$a{r2UCc>N5jaM7RtNj7I>~1`76wmtuc+=HXZ~eI}W}^*CoVz$WED^Vt z{c59r#N=f^Z`6;Ndx0FsZ1)n#7E3TjLhiyyOZldeRkF=dn2i+}SY;an2@q%~mhog8 zg9tn@-ZG&HHWQf0W`Yvp{!cs|MOmD>IEyQRX@J=b^FGW4n6dM4*)YsgFs(2bVCb=B zI*8e+M`fz*>P+=`wGDbuj!{g{iTOz|XDfA}Z<&{g+%PKu!Vr3Onwq?jO>7vy!#WwJMuq^1gb){R2IBV;d5;vKhlgFAE z6-3G_bgk64sF&5am(|u(mUVqo=TO&G5DR4KTh-O2i`~_v<|Z+RvWn6gu;``g#cpwh z8;W&xrI2<#Y8|p!uI4%0UC2{q7tJb{LFcOuV-3AZ#oBt$gf1O722gg~)s@RCq4`F_ zrmfx)<*UTuyXoUaJ@y*lz_H6fYJ7S9u@wJILq_;NF#$}XooI_&4XbouZvxom;79rw8L=FY^xs@Vu4Rvm|QLi;?xKhuuuK1=DE?{ouk}PgOmoMgtGOUpOQe-$v zhSXm8X)>H7?l*IGUcT7n}DS&1zR(Nq=mm32rSGHk zQUV^>BmR_La2jA$k8pJ_cr4&(TO%}0FW3w?xySdeUT|(NI3I8imc$kJf*19ID*&hV zh`+8Eyb|z`9^s9>;3mL>dW5(1g4Y2a+#`HrFL)E+YkGt~(F@)NxL=R(9lhYzUhp2k zbaQ(2In)b&A29u@dGtBi3qA!nEgA?r)C+F!1$O|BwgvWC#nrG9unhq&76^U?*bes| z8BPTZwQX*f45tBh!X3>+I$+|z(Ka#$unTZ23_W83XTf$6fMz}c`H3Bcn5jA4LlVG!2P0MCMZgAC^aCK>+`8O{Sd1@6r8GcHJO8`%W`>!&*2yiakZ_03m47bT}HDH>josi)=z_-GERE9;sx4|8y z-%1&lgSiG7j?%kPhKWbe(!`o!|V;SBq!!pRdAj8XLkDW3c?E|ec9Oaq& zW%vde|BwtvdD#0hY?8x|0fxB1{Z58Y%J9oFd|HOL$Z$x8pOxWu8Gc%ZFUasKGTbS{ zkIOJuDW&(E3@c?g+J2H`INIJ)Wq7lUpC-f6_NSI%YV-7rkzxAnH+m+>@bePL>1FsC z8MevrRvFHgVXAX_@?@C$5Iu8bxK;wWVi{g4!zF-8E{i_pfbRehkUgqp_*XJ4%CJv{ z8)W#WGTbD?(fV%zTq1{&wGJ?r(z?dOjetqgqBcy=BY+pej`E95fES^2Pg2cP1tfI3@!*j#*r$JOhbNL}(TURF14n_g!pyOBR;i zAmL&^Xz?o1O?LTW4*%qjH?xCI)ahW*DL@R8v#btUH ziy}%QTU;hB9|Cr-#54;lNOj)D)s;&qGM;!0Xe^Kc%xkv8a8#$mn=Q^t9` zi$NE_sQWT}TZ?a3;^ju3>b#x`ileT!4&Ncni+GSqeRUaE54`$%d|zG4dFshjgKmf) zEuyS!3F4|ooul4SpKdZMS8~`v_fsK@t+i@81QTgpp0Qb1gFm1LM3 zr>2k($sg+ia7+HxC<_e3sYZe@%w2!vK01+r=V zqU%ZNa&YrDU4_w4WoFIVaQg&u(Hd3R6Z&j8S)azL_oi7sz%I zY>Iy#45eKSL-8zwQNz^15KZb~D6dow!f%A3Jg<@M`(abK4~D{ zoAUbv45jy57{dD#4CU_~7z+OghQiZ86r#`dS6n}6?!POGBSX3E{Wli3AxM9{Lw*R( zMcesTe@!S;@4u_@*MJ()zc}vS`|BCQ{ap87JgD&R{6)W4g95Rqn*wq1^z+zgXXucN z?q7BPNIB>?pGuA`PfGTh$4*g~=3MtSGW#juw{1PXRV@X7@4e=V7ynKCEE)eL z;J^F$>Bon2e|tRiIL%_Oe!AkncMJPs78uB^;|q?fxrN88j_a;Q2DIkru}@B2<~Z%W z(Jv*GI9Qo5WXGNu1!5G4Q6NTv7zJV!h*2O$ffxm16!_0lVC?p8NxT1xaom_^yWyTG z)jc1_O?WPjv%<`PSqvk>+z;~r%%d>dU|xqg408(RD;N&nCBY1b84F{CnF2EhrW{5M zoOQ4thuI19A+w>&NA|mLMM~PBi4y1h61r%{)8JsFnu#;Rh^s5mqJT%yJFq6nkBVa+^6wH z_0X{-4DQz~C)sX~SYNw}`xS#GGlhSSdn3M3x|5M*^wlUN5r%u5;m&qT;EuRyo=K(U zEaH5zp1UP}wpcy4W(Dm%{XTwf4OB%@obsHNW$rpsOhw|XG-D`t)7gF<asZQ zIgXOd>AumhKqQS$PZsz5kAxI)@5L8EyK{0yY5knq>7)reiFRN6Q2gJIh*SQsKbF`U zh`v3j`7}4B8XJ0)yGb}+#Z*(%;%DQ+M@B$S&q?$mD2sc8)qFk?ntPetS(CAxr=`?p z=1eEIgWS}5vLuaS=+4CD;g&`D0!5U*lyZ<$Q$BNvl)~w_uJX*OjTVx7BQ9_9^wK(s zGWe>sCya6wP&!g5wF6)jUhM;%+j3^l$jR${f8u|VkHq4NQ6NTv7zJV!h*2O$ffxm1 z6o^sae>(+IB>nHx{4o6q{TKRI4Z93ejMI%y(=^ipQ?2Pflh5=&rhsX^>8GZTOeajA zn*M6~!W1@rZ8~qdWct<=F)cIy!u$vG9`l#xc*}5$&T^}z(z3?#3(K>Xw=ADo6xMN8 zlXanWnRS)*A?qnCZ~KF7hwVe#efAQE$MF-#XAXmNigSsx$@#Lg)d^~-p+^ntdQFDr zdChB@_cWum6Sb4Ho3-h>44qwfm+lw3OS*b~7jM_!Xt){oGUyCO!(9fiVU=OEVU1y@ zq1CX*u-|aPaFa3DSZNeZcbk4@dd&1Y)AOb`OmCTvq6BA<_nYlg?fLe3_B-uf`&Rqk z>=}-G96`s!jz2n{cf8`*oevs`nZrdboz{7myJ&F?hZH7_CGZ)y%|KGvMle6BgG`9>3`?XMlAy-qs{WpQeA zwbQi)+B>x6+A8fz?S0xN?ON@F+9$NnXkXC2s%_OC(|)d9$*As^#%G$eZ78#ezo4G59+t* zcj|ZP59*KUPw6k}BYLG_kYTuCEU2b8SPjz+Wrk`{?ta6AhF==C8eT@-?=!q@IBNK_ z;gaEsL1FA~9BjPB=rk@cmK&>#wZ?76SB$%jXN?`kI8%~ojOiAW*;HsMGgX`JM;qB_ z`nBn|rWZ}Gn%YczO~*~`rpu;ybBg%}^H{UiJk^|Uo@>6{yvST-ZZZeV8_Yj5KWcu} zd=M??Yx6(N-DGx-d!@FXRfv!U|!v;1m49o5E4y z&q5#DAlq=;jW(z4R@)rg3fpnpDcfLsnmyD0ko^(+0sFgX3)37k9F1t3PdVOl%yO1E z-Ojt5Yn?xHKI(kUxf?CvZ_clr=bhg;ITvP{Xcn9%QFE`eKGt2(ar{u;$WP;|`1|;up{9S!|AF7b zzs-Nhf5Klt?e@{%qR-aft}oM9>qY%q{ZI9q^jq~Wvl<;_{JXKr^bXqdXC}_)E6;cP%zHab6|_KX>LC=UDW z$hm-=&(stn?^PPF=3b3o^N{A3$p5pNmr;TP=!c(ZzSLaQL^Q+EipOd-T7!0mc9C|e zwpx3ac9ph8`+)Xm+Fzj+|3UkP_D$`(+EZx7?bgMPc=$7idx_fo& zbU)K=)%{-gCtaKFpzZ_Rr@Aw`cHK8R1)t1c!;j?0@)LQUpUp4eYxzz5Z}{!}3;fIc zQMCRr|26+l{xToo6ZHM`$@*0Nc)d$MQ(vsF(+Bh$^-t=5k2e3I{%Y{0 zrT+)o{x|w7`glVhLw~~zL!rTKr~$Y5iQ!qp>xQtQ!*IQEv~e7`-U8!m#HQD^O4YtQ@PuX6v9k9J`J7GI*`@8MD?HgNyeW+b+ztKM4uCr&`3+yHKGJB=H z#=hL%V*j~)i+#KOEBh6De}~GE>KN|GbeJ4=$7IJe#~qGsRL_fW76|oxA6nvJ&4=Jg z-)i*QZ0$VlL)z!GJGIBP@w)4DHr;Kyxw?hAdfnT)VZ4qXq|ekZ(XZ71kAAcMH~MY* zBl?s2&p^=*ys)K6RVk!0USSk&6AFc8f=5^hj|+{W8e|%3y1_KoWHn7T6_^&8eq!2$HWrT(rI?4HJR{BH%sTUA zbFsP9Txo7F`@t)JY5tx0kLDNA!}ps%G@k(1Y)8owEd9{#(k-JbH(Ipl^H~^wXIU0n z$}D$U?y@vm)?0pVdCc;pCgJWcjltgjV^TCBfRydad<3Yo^r(o;uY!$9lW9 z5~H-oy29FIeaRZKp0jpi6) z3W>G>HoNT^+d11z`y6{M#?>bKFYS+^ZSJ)nvj5qB-hSDh=1@CsbYwZEI7%H=82?u} zS{$1k&pBRo>~S1&{KXM=TyS(c20O2Fj&bUo3!ST+_c?!oarhPI`_8YO7pN^aLN5~a zk)}!4jK(Nz(%3XpHTjyYnrht|onQBm?g_?W-_jk?9oL-&m;FwsC zt1z;zS6vE{~2m9PTwCjc(b0@--Z#iME_g;JNgL*0d2etoMMIH8N*A4Hw;p_Al+{?3e7F z=+W0WhB>ZxOmr9>6^><&{f-YDA;&pKhvPd(eH+;> z{m0;w35FfUH6|r`)fBTE?JXZI=rzk}%LU8zXfsxDwQB2m;YRSTr%<+Sc5XAy zi=cXp=*1UJx0`POCwx|wc-_ZnC7%g@6V3>K7tRU)6fO(j330YWTR&Se#^WKj zVYU&rk+uxmINL;<)@HC-(2}xjIksuG>9$$6xwZ@T5#VOrc1i#8G1O0-VSwRA$am|E z4;f!K?nmG13+^)7lxdm--d$)~XsToUdklDj-t0hMdf5CpdeF<}H_Us@hs|fq=g@oN zEqyH`FjlS-?iGF|JSjXcye{lTF252wge2rF&2~McggVtsJ)l)?m#r&8=vcH5wmefLFnHuV|FoaasrDzWcQs zv~AjbsE@C-iMs1`hjsn#X35oN!`e*fjVshtum{I&w z-^Y+-xB-&6+LCF>fkcuI?&P+3!J8hkJZjlyc@CWEHOm3CtuHO#So&L2tfQ+Mh4x7iPahn%r<;2uwdTf7Zk!JU$Lfmt(0Q=xf8vl&$WKy#;dh1RcK zuYFwmJY?ykkU}nNlXN%ebQs~L>h920>Xz#oboc8X0H@fY+o!t>>gRzoEasQ{HZhYHx()5)n6)Rd3E7~<_A}eBY%ij(y>FXnH$e)Rfe~K`DK+SL z#&H-1L<0v@Qgm+Ri8Ihw8(6lfhw_ zZ>Yiy;vR6v^M-qkj~JgcK4*N>_^$DovA-$JbTjziEK|Ly0dvT8m>+Dz%wQkJ^y8+# znfhYv9)X#G&TKPJGB=yon>S)6`Kb9%=GV*(JNt|FSI}P$+K<{lwx7bh z;G%sn56y?zYFD-C9SHvJ@hu6~Ao4rU6AAhA_r{vSd|j$B&A7+3-*m`y*z~^X7<$Jk(`i%4 zbQUwfY+J6a!M4t}$+pe5({>2-K5Of=CE3%#qimpbiM`t1U|$CgwGG_qko~0nEXKVg zN4jHz!{*3ylsKv#4UTn?61F*ZLPj|0I133O$(in);IujOFgvTpjAos4lXDy9>W7>s z!G$}S%nLmL zZ{oLMwtfipb{3RP(x>YuppNn&RaEO6^y@IzZUc8b1Zn!LzEhuMNH - 0003:000037a0 _fflag 004177a0 - 0003:000037a4 _hilo 004177a4 z80ext.obj - 0003:000037a8 __cflush 004177a8 LIBC:_file.obj - 0003:000037ac _errno 004177ac LIBC:crt0dat.obj - 0003:000037b0 __doserrno 004177b0 LIBC:crt0dat.obj - 0003:000037b4 __umaskval 004177b4 LIBC:crt0dat.obj - 0003:000037b8 __osver 004177b8 LIBC:crt0dat.obj - 0003:000037bc __winver 004177bc LIBC:crt0dat.obj - 0003:000037c0 __winmajor 004177c0 LIBC:crt0dat.obj - 0003:000037c4 __winminor 004177c4 LIBC:crt0dat.obj - 0003:000037c8 ___argc 004177c8 LIBC:crt0dat.obj - 0003:000037cc ___argv 004177cc LIBC:crt0dat.obj - 0003:000037d0 ___wargv 004177d0 LIBC:crt0dat.obj - 0003:000037d4 __environ 004177d4 LIBC:crt0dat.obj - 0003:000037d8 ___initenv 004177d8 LIBC:crt0dat.obj - 0003:000037dc __wenviron 004177dc LIBC:crt0dat.obj - 0003:000037e0 ___winitenv 004177e0 LIBC:crt0dat.obj - 0003:000037e4 __pgmptr 004177e4 LIBC:crt0dat.obj - 0003:000037e8 __wpgmptr 004177e8 LIBC:crt0dat.obj - 0003:000037ec __exitflag 004177ec LIBC:crt0dat.obj - 0003:000037f0 __C_Termination_Done 004177f0 LIBC:crt0dat.obj - 0003:000037f4 __C_Exit_Done 004177f4 LIBC:crt0dat.obj - 0003:000037f8 __aenvptr 004177f8 LIBC:crt0.obj - 0003:000037fc __wenvptr 004177fc LIBC:crt0.obj - 0003:00003800 ___error_mode 00417800 LIBC:crt0.obj - 0003:00003804 __stdbuf 00417804 LIBC:_sftbuf.obj - 0003:0000380c __newmode 0041780c LIBC:_newmode.obj - 0003:00003810 ?_pnhHeap@@3P6AHI@ZA 00417810 LIBC:handler.obj - 0003:00003814 __pxcptinfoptrs 00417814 LIBC:winxfltr.obj - 0003:00003920 __adbgmsg 00417920 LIBC:crt0msg.obj - 0003:00003924 __commode 00417924 LIBC:ncommode.obj - 0003:00003938 ___lc_handle 00417938 LIBC:nlsdata2.obj - 0003:00003950 ___lc_codepage 00417950 LIBC:nlsdata2.obj - 0003:00003954 ___lc_collate_cp 00417954 LIBC:nlsdata2.obj - 0003:00003958 __fmode 00417958 LIBC:txtmode.obj - 0003:00003964 _tlevel 00417964 - 0003:00003968 _symp 00417968 - 0003:0000396c _inpfil 0041796c - 0003:00003970 _rel 00417970 - 0003:00003980 _txt 00417980 - 0003:00003990 _afp 00417990 - 0003:00003994 _lmode 00417994 - 0003:00003998 _laddr 00417998 - 0003:0000399c _cpt 0041799c - 0003:000039a0 _module 004179a0 - 0003:000039f4 _fuzz 004179f4 - 0003:000039f8 _incfil 004179f8 - 0003:000039fc _cfile 004179fc - 0003:00003a00 _afn 00417a00 - 0003:00003b00 _cbt 00417b00 - 0003:00003d00 _symhash 00417d00 - 0003:00003e00 _mnehash 00417e00 - 0003:00003f00 _srcfn 00417f00 - 0003:00004500 _srcfp 00418500 - 0003:00004518 _lfp 00418518 - 0003:0000451c _gflag 0041851c - 0003:00004520 _erb 00418520 - 0003:000045a4 _a_mask 004185a4 - 0003:000045a8 _line 004185a8 - 0003:000045ac _lop 004185ac - 0003:000045b0 _ofp 004185b0 - 0003:000045b4 _zflag 004185b4 - 0003:000045b8 _oflag 004185b8 - 0003:000045bc _areap 004185bc - 0003:000045c0 _incfn 004185c0 - 0003:00004bc0 _incfp 00418bc0 - 0003:00004bd8 _tfp 00418bd8 - 0003:00004bdc _page 00418bdc - 0003:00004be0 _ifp 00418be0 - 0003:00004bf8 _pass 00418bf8 - 0003:00004bfc _sflag 00418bfc - 0003:00004c00 _srcline 00418c00 - 0003:00004c18 _eb 00418c18 - 0003:00004c1c _cp 00418c1c - 0003:00004c20 _sfp 00418c20 - 0003:00004c38 _aserr 00418c38 - 0003:00004c3c _ep 00418c3c - 0003:00004c40 _stb 00418c40 - 0003:00004c90 _wflag 00418c90 - 0003:00004c94 _ip 00418c94 - 0003:00004c98 _lflag 00418c98 - 0003:00004c9c _a_bytes 00418c9c - 0003:00004ca0 _cb 00418ca0 - 0003:00004d20 _ib 00418d20 - 0003:00004da0 _afntmp 00418da0 - 0003:00004ea0 _tb 00418ea0 - 0003:00004ef0 _afptmp 00418ef0 - 0003:00004ef4 _pflag 00418ef4 - 0003:00004ef8 _aflag 00418ef8 - 0003:00004efc _s_mask 00418efc - 0003:00004f00 _incline 00418f00 - 0003:00004f18 _xflag 00418f18 - 0003:00004f1c _radix 00418f1c - 0003:00004f20 _ifcnd 00418f20 - 0003:00004f4c _flevel 00418f4c - 0003:00004f50 _v_mask 00418f50 - 0003:00004f60 _jump_env 00418f60 - 0003:00004fa0 _iflvl 00418fa0 - 0003:0000552c ___mbcodepage 0041952c - 0003:000055b0 ___mbulinfo 004195b0 - 0003:000055bc ___ismbcodepage 004195bc - 0003:000055c0 __mbcasemap 004195c0 - 0003:000056c0 __mbctype 004196c0 - 0003:000057c4 ___mblcid 004197c4 - 0003:000057c8 ___sbh_sizeHeaderList 004197c8 - 0003:000057d8 ___sbh_indGroupDefer 004197d8 - 0003:000057dc ___sbh_pHeaderScan 004197dc - 0003:000057e0 ___sbh_pHeaderDefer 004197e0 - 0003:000057e4 ___sbh_cntHeaderList 004197e4 - 0003:000057e8 ___sbh_pHeaderList 004197e8 - 0003:000057ec __crtheap 004197ec - 0003:00005800 ___pioinfo 00419800 - 0003:0000593c __nhandle 0041993c - 0003:00005940 __acmdln 00419940 - 0003:0000594c __setjmpexused 0041994c - 0003:00005958 ___env_initialized 00419958 - 0003:00005968 ___mbctype_initialized 00419968 - 0003:0000596c ___onexitend 0041996c - 0003:00005970 ___onexitbegin 00419970 - 0003:00005974 __FPinit 00419974 - 0003:00005978 ___piob 00419978 - 0003:00005cc0 __bufin 00419cc0 - 0003:00006cc0 __nstream 0041acc0 - 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 0041b000 kernel32:KERNEL32.dll - 0004:00000014 __NULL_IMPORT_DESCRIPTOR 0041b014 kernel32:KERNEL32.dll - 0004:00000124 __imp__UnhandledExceptionFilter@4 0041b124 kernel32:KERNEL32.dll - 0004:00000128 __imp__ExitProcess@4 0041b128 kernel32:KERNEL32.dll - 0004:0000012c __imp__TerminateProcess@8 0041b12c kernel32:KERNEL32.dll - 0004:00000130 __imp__GetCurrentProcess@0 0041b130 kernel32:KERNEL32.dll - 0004:00000134 __imp__GetCommandLineA@0 0041b134 kernel32:KERNEL32.dll - 0004:00000138 __imp__GetVersion@0 0041b138 kernel32:KERNEL32.dll - 0004:0000013c __imp__HeapFree@12 0041b13c kernel32:KERNEL32.dll - 0004:00000140 __imp__GetLastError@0 0041b140 kernel32:KERNEL32.dll - 0004:00000144 __imp__CloseHandle@4 0041b144 kernel32:KERNEL32.dll - 0004:00000148 __imp__SetFilePointer@16 0041b148 kernel32:KERNEL32.dll - 0004:0000014c __imp__SetHandleCount@4 0041b14c kernel32:KERNEL32.dll - 0004:00000150 __imp__GetStdHandle@4 0041b150 kernel32:KERNEL32.dll - 0004:00000154 __imp__GetFileType@4 0041b154 kernel32:KERNEL32.dll - 0004:00000158 __imp__GetStartupInfoA@4 0041b158 kernel32:KERNEL32.dll - 0004:0000015c __imp__WriteFile@20 0041b15c kernel32:KERNEL32.dll - 0004:00000160 __imp__HeapDestroy@4 0041b160 kernel32:KERNEL32.dll - 0004:00000164 __imp__HeapCreate@12 0041b164 kernel32:KERNEL32.dll - 0004:00000168 __imp__VirtualFree@12 0041b168 kernel32:KERNEL32.dll - 0004:0000016c __imp__VirtualAlloc@16 0041b16c kernel32:KERNEL32.dll - 0004:00000170 __imp__HeapReAlloc@16 0041b170 kernel32:KERNEL32.dll - 0004:00000174 __imp__IsBadWritePtr@8 0041b174 kernel32:KERNEL32.dll - 0004:00000178 __imp__RtlUnwind@16 0041b178 kernel32:KERNEL32.dll - 0004:0000017c __imp__HeapAlloc@12 0041b17c kernel32:KERNEL32.dll - 0004:00000180 __imp__GetModuleFileNameA@12 0041b180 kernel32:KERNEL32.dll - 0004:00000184 __imp__FreeEnvironmentStringsA@4 0041b184 kernel32:KERNEL32.dll - 0004:00000188 __imp__FreeEnvironmentStringsW@4 0041b188 kernel32:KERNEL32.dll - 0004:0000018c __imp__WideCharToMultiByte@32 0041b18c kernel32:KERNEL32.dll - 0004:00000190 __imp__GetEnvironmentStrings@0 0041b190 kernel32:KERNEL32.dll - 0004:00000194 __imp__GetEnvironmentStringsW@0 0041b194 kernel32:KERNEL32.dll - 0004:00000198 __imp__SetStdHandle@8 0041b198 kernel32:KERNEL32.dll - 0004:0000019c __imp__FlushFileBuffers@4 0041b19c kernel32:KERNEL32.dll - 0004:000001a0 __imp__ReadFile@20 0041b1a0 kernel32:KERNEL32.dll - 0004:000001a4 __imp__CreateFileA@28 0041b1a4 kernel32:KERNEL32.dll - 0004:000001a8 __imp__GetCPInfo@8 0041b1a8 kernel32:KERNEL32.dll - 0004:000001ac __imp__GetACP@0 0041b1ac kernel32:KERNEL32.dll - 0004:000001b0 __imp__GetOEMCP@0 0041b1b0 kernel32:KERNEL32.dll - 0004:000001b4 __imp__GetProcAddress@8 0041b1b4 kernel32:KERNEL32.dll - 0004:000001b8 __imp__LoadLibraryA@4 0041b1b8 kernel32:KERNEL32.dll - 0004:000001bc __imp__SetEndOfFile@4 0041b1bc kernel32:KERNEL32.dll - 0004:000001c0 __imp__MultiByteToWideChar@24 0041b1c0 kernel32:KERNEL32.dll - 0004:000001c4 __imp__LCMapStringA@24 0041b1c4 kernel32:KERNEL32.dll - 0004:000001c8 __imp__LCMapStringW@24 0041b1c8 kernel32:KERNEL32.dll - 0004:000001cc __imp__GetStringTypeA@20 0041b1cc kernel32:KERNEL32.dll - 0004:000001d0 __imp__GetStringTypeW@16 0041b1d0 kernel32:KERNEL32.dll - 0004:000001d4 \177KERNEL32_NULL_THUNK_DATA 0041b1d4 kernel32:KERNEL32.dll - - entry point at 0001:0000ab73 - diff --git a/src/avr/2313def.inc b/src/avr/2313def.inc new file mode 100644 index 00000000..969a3c56 --- /dev/null +++ b/src/avr/2313def.inc @@ -0,0 +1,232 @@ +;*************************************************************************** +;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y +;* +;* Number :AVR000 +;* File Name :"2313def.inc" +;* Title :Register/Bit Definitions for the AT90S2313 +;* Date :98.05.22 +;* Version :1.22 +;* Support telephone :+47 72 88 43 88 (ATMEL Norway) +;* Support fax :+47 72 88 43 99 (ATMEL Norway) +;* Support E-Mail :avr@atmel.com +;* Target MCU :AT90S2313 +;* +;* DESCRIPTION +;* When including this file in the assembly program file, all I/O register +;* names and I/O register bit names appearing in the data book can be used. +;* +;* The Register names are represented by their hexadecimal addresses. +;* +;* The Register Bit names are represented by their bit number (0-7). +;* +;* Please observe the difference in using the bit names with instructions +;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" +;* (skip if bit in register set/cleared). The following example illustrates +;* this: +;* +;* in r16,PORTB ;read PORTB latch +;* sbr r16,(1< + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + diff --git a/src/avr/CFLASHV0.HEX b/src/avr/CFLASHV0.HEX new file mode 100644 index 00000000..30751b36 --- /dev/null +++ b/src/avr/CFLASHV0.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F445E0EB +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE849B94FEB54227724559841 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE809B900E90AB933244424AA +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742B2ACEC +:00000001FF diff --git a/src/avr/CFLASHV1.HEX b/src/avr/CFLASHV1.HEX new file mode 100644 index 00000000..be960cc1 --- /dev/null +++ b/src/avr/CFLASHV1.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F445E0EB +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE849B94FEB54227724559841 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE809B900E90AB933244424AA +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742BAACE4 +:00000001FF diff --git a/src/avr/CFLASHV2.HEX b/src/avr/CFLASHV2.HEX new file mode 100644 index 00000000..a62f4788 --- /dev/null +++ b/src/avr/CFLASHV2.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F443E0ED +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE549B94FEB54227724559844 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE509B900E90AB933244424AD +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742B2ACEC +:00000001FF diff --git a/src/avr/CHSET00.WIN b/src/avr/CHSET00.WIN new file mode 100644 index 0000000000000000000000000000000000000000..2217627d7854541fcdf4873dc96ed0c1c81f3277 GIT binary patch literal 869 zcmbtSJBSoP5bdgFcRCPk17R_cUJL{=n7dPCL1e*SB08Cv?Fqt($sh&`B6J|qi8zt0 zkq0JiARI;qCW{y>h?$6qc##;6*#ri@su4K^BWq@$sCw`9d(B*0KXswpSexKmUprGy zuGs&34E>95bu*-cG@>z`pba`p7wIZp|BErB+jN)i(?fbpPw6?mq}TL@-q8p8L|^GU z{UFDO_y`~4lYE-b@nx=f|Cu-VCg0(E{D2?v6Mn`o_!aN+TYk?U`3ryJmVdIf2kc>c z)E>8`o!ImHG8;SGq>hR@E%GYWRD@YTp{bMeVTx7fgLks>Wz}@vV-j1ZlX4o{B&$xa z)2XnMyxPp2pJ|i2l&AnwUYW!g1+&+rl$t#ejBSi^mNro_yD81700Qj9;{qfpDx8$? zQ?tF?ZXn%nz)zoZ23lyVypRTNPyox>N|#A)w)#69I-+almhJZ{279&2cXAUUsE1xd zq*B#Sa?X{ks!;U@q7$%Qg=8_Nc5{h literal 0 HcmV?d00001 diff --git a/src/avr/CS64V4.HEX b/src/avr/CS64V4.HEX new file mode 100644 index 00000000..e5b357b9 --- /dev/null +++ b/src/avr/CS64V4.HEX @@ -0,0 +1,385 @@ +:020000020000FC +:100000000DC087C387C3189518951895189518952E +:1000100082C31895189527C711C762C702E00EBFA3 +:100020000FE50DBF10E818B9A8951FE011BD00E05D +:1000300009BF0BBF08EF01BB08EB02BB0FE107BB19 +:100040000FEF0ABB04BB00270BBB03E008BB00E0BB +:1000500005BB00E2B02E1FE519B910E91AB9442416 +:10006000552422243324EE246624CC24552750938F +:100070000101509323015093430150934401509345 +:100080004501969AE0E0F0E0A8953197E9F7979856 +:1000900000E0B8D0B7D002E4B1D000E2B3D000E0C5 +:1000A000B1D003E4ABD000E8A9D000E9A7D000E0CC +:1000B000A9D0A8D004E2A2D000EBA0D0E0E0F8E004 +:1000C00000E0A2D03197E1F702EB9AD008E996D090 +:1000D000979A789410E3B9D2CF93DF93C4D2BF91AB +:1000E000AF911BD5212F1D2F12950DD31217B1F4EF +:1000F000119613D5212F1D2F06D3121779F41196BF +:100100000CD5212F1C2F1295FED2121739F41196FF +:1001100004D5212F1C2FF7D2121749F1E6E7F2E19F +:10012000A6E6B3E0D8E1D0930201C0D0D0E8C0E0A9 +:10013000DBBBC39AC398D0930101F89435B33C2735 +:1001400030783C27789435BBC8950BBAC29ABA98D8 +:10015000C1980000C19AC298BA9A119741F031969D +:10016000C3951C2F1F7349F7C054D395E1CF20E1ED +:100170002093F30020E22093F40028E12093F5007F +:1001800021D6112710935101EE27FF271EEF109360 +:10019000FD001BEA1093FC0022E01BD21C7F109391 +:1001A000FE0023E016D21093FF001091FE00209174 +:1001B000FF001A380DEF200720F01B3A0FEF200741 +:1001C00030F01EEF1093FF0010E41093FE001EEFBE +:1001D00019BD1BEA18BD1CEF1DBD1EEC1CBD10E5B2 +:1001E0001FBD11E01EBD00E003BF04E008BF09BF52 +:1001F0000AE005BF00EC0ABF0BBF92C219D006C0CF +:1002000011D004C015D001C00DD0A8980BBB0000C0 +:1002100000000000F894C1980000000000007894ED +:10022000C19A08950F930BD003FFFDCF0F9108954E +:100230000F9305D000FD01FFFCCF0F910895A89A00 +:1002400000E00ABBF894C098000000000000000025 +:10025000C09A09B378940F930FEF0ABB0F910895DA +:1002600002E00EBF0FE50DBF1FE7B122AF98C498A3 +:10027000409101014BBBC39AC39850E05FBD5EBD86 +:1002800094989598C298BA9A96989798C098C19859 +:100290005FEF5ABB50E05BBB50E059BF5BBF5FE113 +:1002A00051BD57E151BD5AE655BF889508957894E0 +:1002B0001FEDE12210E01EBB1FBB62D21B3129F1F2 +:1002C000B3FC0DC0103258F4183009F4FEC01D30D4 +:1002D00009F40DC11A3009F48BC0173041F7B2FC94 +:1002E00012C0103381F4C091F300D091F40020913A +:1002F000F500CC5FDD4FF89435B320FB36F97894E8 +:1003000035BBF1D4102D72D2D2CF3AD21B3139F392 +:100310001E3209F475C11F3209F44FC01F3309F4AE +:1003200084C1113409F4A6C0123409F427C213346D +:1003300009F404C1133609F451C9143409F4EBC0AB +:10034000153409F4D8C0163409F408C1163609F476 +:1003500051C9173409F49EC0183409F463C918361A +:1003600009F454C91B3409F461C01C3409F4D4C124 +:100370001D3409F42BC01E3409F4FCC0103509F4F7 +:1003800097C0123509F4DCC0133509F4D2C0153515 +:1003900009F4F4C1163519F410E2E12AF7C0173553 +:1003A00009F4ECC1183509F4B8C11A3509F4E2C1F1 +:1003B000103310F01A3398F07ACFE2D110FF03C057 +:1003C00014E0B12A74CF1BEFB12271CFD9D1103311 +:1003D00021F4F89400E4B02A43CF69CFD1D135D1CC +:1003E000C0E1C093F300D093F4002093F5005FCFF9 +:1003F00001D05DCF0F92C091F300D091F400209115 +:10040000F500DE5FC395F89435B320FB36F9789498 +:1004100035BB69D4182F100D100D1A95103418F033 +:10042000EED00F900895800D0F900895979800E0FA +:10043000E9DEE8DE02E4E2DE00E2E4DE00E0E2DE45 +:1004400003E4DCDE00E8DADE00E9D8DE00E0DADE34 +:10045000D9DE04E2D3DE00EBD1DEE0E0F8E000E03C +:10046000D3DE3197E1F702EBCBDE08E9C7DE979ADE +:10047000A9D41DCF85D1117051F41FE7B122AF98D7 +:10048000C498409101014BBBC39AC39810CF10E8A8 +:10049000B12A0DCF75D1103309F404C0113309F41A +:1004A00004C005CF07EFB02202CF08E0B02AFFCE8C +:1004B00067D1103309F403C0113309F403C00FEE00 +:1004C000B022F5CE00E1B02AF2CEC091F300D09177 +:1004D000F4002091F500DE5FF89435B320FB36F987 +:1004E000789435BB00D470191FB712FFE0CE01D04D +:1004F000DECE7727089544D111FD07C010FD03C05B +:100500000FEDB022D4CE00E2B02A002700932301E1 +:1005100082D2F1F7CCCE34D1103309F404C01133B8 +:1005200009F404C0C4CE0EEFB022C1CE01E0B02A5F +:10053000BECE26D1712F24D1812FB9CE02E0B02AB0 +:1005400070933401809335011BD11093360118D17B +:1005500010933701E5D20DEFB022A9CE7093380188 +:10056000809339010DD110933A010AD110933B01C8 +:100570002CD39DCE709338018093390101D1109313 +:100580003A01FED010933B0145D391CEF9D010FF34 +:100590000BC01091FE002091FF001C5F2F4F1B3AF3 +:1005A0000FEF2007A8F40AC01091FE002091FF0071 +:1005B000145020401A380DEF200750F01093FE0021 +:1005C0002093FF0022E00DD01091FF0023E009D01E +:1005D0006ECEE199FECF2EBB22272FBBE09A1DB332 +:1005E0000895E199FECFE5FEFFCF2EBB22272FBB5A +:1005F0001DBBF894E5FEFFCFE29AE19A18951AC563 +:10060000BFD023D0BDD0A12FBBD0B12FB9D0F8948B +:1006100035B320FB36F9789435BB80D221961197FB +:100620001A2F1B2B09F0F2CF42CEAAD00ED01F9367 +:100630001AD01BE1C6D01FE3C4D01F91105DC1D0FA +:100640001D2F5AD01C2F58D032CEC0E0D0E022E669 +:100650001F70163008F4210F2695D7952695D7954B +:10066000D695D6950895A6E1B2E0AC0FBD1FF894DB +:1006700035B320FB36F9789435BB4FD2E12F119674 +:100680004CD2F12FAC2FBD2F1496CFEFDFEF319767 +:10069000FF70349780F1319640D2119601E220E14B +:1006A000D127CC0FDD1F10F4C027D227CC0FDD1FC0 +:1006B00010F4C027D227CC0FDD1F10F4C027D2279B +:1006C000CC0FDD1F10F4C027D227CC0FDD1F10F494 +:1006D000C027D227CC0FDD1F10F4C027D227CC0FA4 +:1006E000DD1F10F4C027D227CC0FDD1F10F4C02768 +:1006F000D227319789F608951F93129504D061D0BF +:100700001F9101D05EC01F7010631A3308F0195F8B +:100710000895F7C3FFC307C4AAC432D010FD13C0A5 +:100720007093460180934701B09248011091F30005 +:10073000109349011091F40010934A011091F500B3 +:1007400010934B01B4CD709146018091470110EC9C +:10075000B122109148011F73B12A109149011093E1 +:10076000F30010914A011093F40010914B01109383 +:10077000F5009DCD05D004D003D002D001D097CD97 +:1007800010EC10934401A89510E01EBB1FBB10ECA9 +:10079000809910934401B5FC3ED13320A1F310E0C1 +:1007A00010934401CF93DF93C22DC059DD271881E8 +:1007B000F8943A942394CFE72C227894DF91CF9148 +:1007C00008951F93A895152D1031E0F71F91CF9331 +:1007D000DF93DFB7F894C52DC40DDFBFCF70C05ACB +:1007E000DD2718835394DF91CF91089578940027E3 +:1007F00000930001982E672F6AD26093F200A092B6 +:10080000F000C12FDD27CC0FDD1F1091F300C10FC9 +:100810001091F400D11F1091F50026D564D22196D5 +:10082000F02C61D2CF2DD02D1091F300C10F10917B +:10083000F400D11F58D2802C1C2F2D2F219785FC1E +:1008400007C0C091F300D091F400DE5F4CD21DC010 +:100850004AD2B4FC1AC0C091F300D091F400DE5F1C +:10086000F02C41D20F1808F40024069400920001E5 +:10087000672F600D2CD26093F200A092F000C0911F +:10088000F300D091F400DE5F2ED2B3FC1AC0072F24 +:10089000000D08F016C01F932F932BDEABDD0091E7 +:1008A0000001700F982E672F12D26093F200A09271 +:1008B000F00000910001701B1091F500D5D42F912C +:1008C0001F91700D86FE05C0C12FD22F22970BD22B +:1008D000900CC12FD22F219606D2702C0FEF0ABB9D +:1008E000C09A0FE180228092F1000027801201C09F +:1008F00087C0AA27B92DB695A795B695A795B05FDD +:1009000007C09394A05CBF4F8090F100A090F000CE +:10091000AA2A222721961091F500A6D4E4D1112706 +:100920006091F200662339F08894079417956A95D0 +:10093000E1F7022A212F08E1F89435B300FB36F9DC +:10094000789435BBF89435B33A25307C3A257894C1 +:1009500035BB3B2F330F330FA7FA31F9A6FA30F925 +:100960003BBBF894C39AC398789430930101002755 +:100970000ABBF894C29ABA98C0980000C09A09B30A +:100980000026B0FC002A0FEF0ABB0BBAC19800008A +:10099000C19A7894C298BA9AA3948A9409F0BACF6B +:1009A000222351F1F89435B33A25307C3A257894D6 +:1009B00035BB3B2F330F330FA7FA31F9A6FA30F9C5 +:1009C0003BBBF894C39AC3987894309301010027F5 +:1009D0000ABBF894C29ABA98C0980000C09A09B3AA +:1009E0002027B0FC202B0FEF0ABB2BBBC1980000C7 +:1009F000C19A7894C298BA9A04D07A9409F081CFB7 +:100A00000895CF93DF93192D78D01881122B188376 +:100A1000DF91CF9108952F93CF93DF93109123010E +:100A20006CD01881122309F45EC028812127288305 +:100A300010E010934401AF93BF93A3E0B1E0CC2743 +:100A4000D0912301D695C795D695C795D05F18E16B +:100A50000BD42EE1F89435B33C27307C3C277894B6 +:100A600035BB3D2F330F330FC7FB31F9C6FB30F9D0 +:100A70003BBBF894C39AC398789430930101002744 +:100A80000ABBF894C29ABA98C0980000C09A19B3E9 +:100A90007894C298BA9A0FEF0ABB1D93C3952A9512 +:100AA00009F0D8CFBF91AF91CC27D0912301D69533 +:100AB000C795D695C795D695C79597980C2FA2DB65 +:100AC0000D2FA0DB04E29ADB00EB98DB2EE1C3E004 +:100AD000D1E0099199DB2A95E1F702EB91DB979A36 +:100AE00010EC109344011091230113951F73109380 +:100AF0002301DF91CF912F910895C4E2D1E0212FFE +:100B0000269526952695C20F20E0D21F21E017706A +:100B100019F0220F1A95E9F7089562C385C3C7CB70 +:100B200078949090350160913401D1D06093F200B7 +:100B3000A092F00070903701CC27D92DD695C7959B +:100B4000D695C795D05F18E18FD307C0C05CDF4F43 +:100B500093946091F200A090F000AC2A1FEF809077 +:100B6000360100E0801641F008E08016B8F06623F8 +:100B700019F016956A95E9F7DAD008E01091F200BD +:100B8000011B801AA3941FEF08E0801638F0B1F023 +:100B9000CED01FEF08E0801AA394F6CF882079F01A +:100BA00016958A94E9F71095662341F02227169549 +:100BB00027956A95E1F7BBD0A394122FB8D021DF17 +:100BC0007A9400277012C2CF089500913A010A95D5 +:100BD0000230D0F300913B010330B0F300913801B3 +:100BE0000395009334010091390100933501809001 +:100BF0003A018A948A948092360101E00093370189 +:100C00008FDF009138010093340180903A01809287 +:100C100036013AC000913A010A950230A8F20091DB +:100C20003B01033088F200913801039500933401B1 +:100C3000009139010093350180903A018A948A9499 +:100C40008092360101E0009337016ADF009138019C +:100C500000933401009139010395009335017090A0 +:100C60003B017A947A947092370101E00093360147 +:100C700057DF80903A0100913801080D0A950093E2 +:100C8000340101E00093360100913901039500938E +:100C9000350170903B017A947A947092370140DF6D +:100CA0000091380103950093340180903A018A94B1 +:100CB0008A948092360170903B0100913901070DB2 +:100CC0000A950093350101E00093370129CFAA244A +:100CD00000EFA01A67FFAA246F77685014F0A3945E +:100CE000FCCF685F0895F89435B33C27307C3C27EF +:100CF000789435BB3D2F330F330FC7FB31F9C6FB5B +:100D000030F93BBBF894C39AC398789430930101AF +:100D100000270ABBF894C29ABA98C0980000C09AFB +:100D200009B27894C298BA9A0FEF0ABB0895F89462 +:100D300035B33A25307C3A25789435BB3D2F330FB7 +:100D4000330FA7FA31F9A6FA30F93BBBF894C39AEE +:100D5000C39878943093010100270ABBF894C29A93 +:100D6000BA98C0980000C09AF9B27894C298BA9A1A +:100D70000FEF0ABBB1FE03C01095F12203C0F126AC +:100D8000B0FCF12AF89435B33A25307C3A257894B2 +:100D900035BB3D2F330F330FA7FA31F9A6FA30F9DF +:100DA0003BBBF894C39AC398789430930101FBBA83 +:100DB000F894C29ABA98C1980000C19A7894C298DF +:100DC000BA9A08959924C0E0D0E118E14DD2AA243E +:100DD000A092F0001091F0001C2BF89435B331274D +:100DE000307C3127789435BB3D2F330F330F17FB01 +:100DF00031F916FB30F93BBBF894C39AC398789449 +:100E00003093010100E00BBBF894C29ABA98C198E4 +:100E10000000C19A7894C298BA9AA39400E2A016EE +:100E200019F0A092F000D6CFECDD9394C05CDF4FB8 +:100E3000D03209F0CCCF7727882708951FB60F93BB +:100E40000FEDC02EEF93FF93E42DE05AFF270081B2 +:100E5000FF91EF910CB95A9443940FE040226A94A9 +:100E60000AF046C04BC01FB60F930FEDC02E0CB159 +:100E70005C9938C0E7FC26C0E6FC08C0033029F4C2 +:100E800003E009B9539A00E4E02A38C0602E00E874 +:100E900003190AF40FE7662012F4052D00680CB957 +:100EA000061508F4602E062D0F7739F000ECE02AC5 +:100EB0006A9422F55798559A21C00FEBE022569A72 +:100EC0005E9A1CC0EF93FF93E32DE20DEF77E0599C +:100ED000FF270083FF91EF9133946A947AF40CC05A +:100EE0001FB60F9353980FE509B90FEBE022CC24FE +:100EF00055985698579A0CB10FE7E0220F911FBEF4 +:100F000018951FB68A9A4CB55DB55093FB00409377 +:100F1000FA008EC01FB68B9A4CB55DB55093F900A0 +:100F20004093F80085C01FB65AB35F935BB35F93DD +:100F30005FEF5ABBB7FE14C0509151015395553223 +:100F400028F4523159F4AF98C49A03C0AF9AC498A8 +:100F500050E0409101014BBBC39AC398509351019B +:100F600055B35F93509101015F9350914501505CDF +:100F70005093450149F450914401539550934401D5 +:100F800019F45FEBB5226CC950EB5FBD4CB55DB594 +:100F9000485F5F4F5BBD4ABD59BD48BD8A9A929A72 +:100FA0008B9A939A8D9895985091FD004091FC00F2 +:100FB0008D9A859907C040389DEF59074AF04150F6 +:100FC000504006C0453D9FEF590712F44F5F5F4FF9 +:100FD0005093FD004093FC005BBD4ABD9091FE0024 +:100FE000491B9091FF00590B1AF445EF5FEF02C0C7 +:100FF00040E85DEF59BD48BD000000000000000062 +:10100000000000005DEF5DBD55E75CBD8A989298D9 +:101010008B98939850EE5FBD5F915BBBC39AC3986A +:10102000509301015F9155BB5F915BBB5F915ABBD0 +:101030001FBE18959924C0E0D0E1A0E0B0E118E10E +:1010400013D1A05CBF4F0A94E1F720E22F93C8D0E0 +:10105000EBD0A395C3952F912A9509F0F7CFD1DC5A +:101060009394A0969096B03209F0EFCFB0CE88DB83 +:101070001F9386DB10934C0183DB1695169516950E +:1010800009F410E210934F017BDB10935001172FEE +:1010900016951695169510934D0180934E0118E103 +:1010A000E3D01F9110FD46C0CC27D0914E019D2E5C +:1010B000D695C795D695C79510914D01C10FD05FB4 +:1010C0002091500110914C01121720F5211BAA27E5 +:1010D000B0914E01B10FB695A795B695A795109111 +:1010E0004D01A10FB05F2F93AF93BF93CF93DF93C9 +:1010F00020914F0168D085DCDF91CF91BF91AF91F6 +:101100002F919394A05CBF4FC05CDF4F2A9559F795 +:1011100020914C012F93CF93DF9320914F015AD010 +:1011200070DCDF91CF912F919394C05CDF4F2A95B3 +:1011300089F7F5CCCC27D0914E0100915001D00F0A +:101140009D2ED695C795D695C79510914D01C10F87 +:10115000D05F202F10914C01121728F5211BAA27D0 +:10116000B0914E01B00FB11BB695A795B695A79556 +:1011700010914D01A10FB05F9A94A054B040C0549B +:10118000D0402F93AF93BF93CF93DF9320914F0124 +:101190001AD037DCDF91CF91BF91AF912F912A9573 +:1011A00059F720914C019A94C054D0402F93CF937B +:1011B000DF9320914F010ED024DCDF91CF912F914E +:1011C0002A9589F7ACCC0CD011962ED021962A9571 +:1011D000D1F7089510E028D021962A95E1F70895D7 +:1011E000F89435B33A27307C3A27789435BB3B2FB7 +:1011F000330F330FA7FB31F9A6FB30F93BBBF89453 +:10120000C39AC39878943093010100270ABBF894DD +:10121000C29ABA98C0980000C09A19B37894C2983C +:10122000BA9A0FEF0ABB0895F89435B33C27307C87 +:101230003C27789435BB3D2F330F330FC7FB31F973 +:10124000C6FB30F93BBBF894C39AC39878943093AB +:1012500001011BBBF894C29ABA98C1980000C19AC8 +:101260007894C298BA9A0895F89435B310FB36F979 +:10127000789435BB089546323444303331393033B5 +:101280003132313730394C034C034C034C034C039F +:101290004C034C034C034C034C034C034C034C03D6 +:1012A0004C034C034C034C034C034C034C034C03C6 +:1012B0004C034C034C034C034C034C034C034C03B6 +:1012C0004C034C034C0300014C034C034C034C03F4 +:1012D0004C034C034C034C034C034C034C034C0396 +:1012E00003014C034C0306010F01180121012A01DF +:1012F00033013C0145014E0157014C034C034C03A3 +:101300004C034C034C034C036001690172017B01E7 +:1013100084018D0196019F01A901B201BB01C401A5 +:10132000CD01D601DF01E801F101080211021A0224 +:1013300023022C0235023E02470250024C034C03AA +:101340004C034C034C034C03590262026B027402BF +:101350007D0286028F029902A302AD02B802C20288 +:10136000CB02D402DD02E602F002FC0203030C030E +:1013700015031E0327033003390343034C034C03B7 +:101380004C034C034C030003066101F8010770880D +:1013900098A8C888700107206020202020700107CD +:1013A000708808102040F80107F810201008887095 +:1013B000010710305090F810100107F880F008086D +:1013C00088700107304080F08888700107F80810A5 +:1013D000204040400107708888708888700107703D +:1013E000888878081060010770888888F8888801E4 +:1013F00007F08888F08888F00107708880808088EE +:10140000700107E09088888890E00107F88080F0FC +:101410008080F80107F88080F08080800107708864 +:1014200080B88888780107888888F88888880221A9 +:10143000078080808080808001070808080808886D +:101440007001078890A0C0A09088010780808080EC +:101450008080F8010788D8A8A8888888010788882C +:10146000C8A89888880107708888888888700107CC +:10147000F08888F0808080010770888888A890684C +:101480004C034C034C03060801014F0065030107A0 +:10149000F08888F0A09088010770888070088870B4 +:1014A0000107F820202020202001078888888888CC +:1014B0008870010788888888885020010788888874 +:1014C000A8A8A8500107888850205088880107885C +:1014D0008888502020200107F80810204080F8015B +:1014E000070000700878887801078080F088888875 +:1014F000F00107000078808080780107080878886C +:10150000888878010700007088F88070010718202B +:10151000F8202020200108000078888878087001D1 +:10152000078080B0C888888802210780008080807A +:101530008080052108100010101010906005210710 +:10154000808090A0C0A090032107C0404040404050 +:101550004001070000F0A8A8A8A801070000B0C833 +:10156000888888010700007088888870010800005A +:10157000F08888F080800108000078888878080862 +:1015800002056105B0C0808080010700007880708E +:1015900008F001072020F82020201801070000880B +:1015A0008888986801070000888888502001070013 +:1015B000008888A8A85001070000885020508801A2 +:1015C00008000088888878087001070000F810205B +:1015D00040F80107F8F8F8F8F8F8F80070933801C7 +:1015E00080933901CDD810933A01CAD810933B01AA +:1015F00026D05DC67093380180933901C1D810930D +:101600003A01BED810933B012FD051C670933401DC +:1016100080933501B5D810933601B2D810933701B5 +:1016200078D045C67093340180933501A9D81093C2 +:101630003601A6D81093370171D039C608950091AC +:101640003801009334010091390100933501009174 +:101650003A010093360100913B010093370102E00B +:10166000B02A5EDA0DEFB02200913A010A950230FD +:1016700028F300913B01033008F3009138010093F7 +:101680003401009139010093350100913A01009332 +:10169000360101E00093370143DA009138010093ED +:1016A00034010091390103950093350100913B010C +:1016B00002500093370101E00093360131DA809047 +:1016C0003A0100913801080D0A950093340101E0B8 +:1016D0000093360100913901039500933501009183 +:1016E0003B010250009337011BDA0091380100934F +:1016F000340100913A010093360170903B01009152 +:101700003901070D0A950093350101E00093370177 +:1017100007CA02E0B02A04DA0DEFB0227894909064 +:10172000350160913401D3DA6093F200A092F000A9 +:1017300070903701CC27D92D15E5D0FF1AEA012E7C +:10174000D695C795D695C795D05F18E18DDD07C0B2 +:10175000C05CDF4F93946091F200A090F000AC2A3F +:101760001FEF8090360100E0801641F008E08016FF +:10177000C8F0662319F016956A95E9F71021D7DAB3 +:1017800008E01091F200011B801AA3941FEF08E0FB +:10179000801640F0C1F01021CADA1FEF08E0801A6D +:1017A000A394F5CF882089F016958A94E9F71095CF +:1017B000662349F02227169527956A95E1F71021AF +:1017C000B6DAA394122F1021B2DA00941AD97A94BF +:0817D00000277012BDCF08953F +:0220000003419A +:00000001FF diff --git a/src/avr/CS64V5.ASM b/src/avr/CS64V5.ASM new file mode 100644 index 00000000..813e9353 --- /dev/null +++ b/src/avr/CS64V5.ASM @@ -0,0 +1,3077 @@ +; CS64V5.ASM + +; 01FEB02 REVISE FOR 7.3728MHz XTAL +; 22NOV01 REVISE FOR OPERATION FROM VCC INSTEAD OF VBAT +; INVERT SENSE OF SRAM CHIP SELECT +; STILL NEED TO REMOVE VCC COMPENSATION CODE + +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APICS.INC" ; NOT API.INC BECAUSE APICS.INC HAS WDR IN TX_WAIT_LOOP + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS XPAGE,YH + RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL +; THIS WILL CORRUPT BACKLIGHT + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 + ANDI R19,$80 + EOR R19,@0 + SEI + OUT PORTC,R19 +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @0,1 ; A15 +; BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @1,7 ; A15 +; BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =-818 ;$FB35 +.EQU T1_FULL_SCALE =-651 ;$FC2F + +.EQU VEE_MIN =-640 ;$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX = -43 ;$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =-341 ;$FE00 + +.EQU CONTRAST_LONG =-640 ;$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT = -11 ;$FFF0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =-341 ;$FE00 + +.EQU VCC_NOMINAL =-536 ;$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =-630 ;$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX = -85 ;$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =-448 ;$FD60 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS +.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +TEMP: .BYTE 1 ; 10C + +LATCH11_SAV: .BYTE 1 +XPAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 2 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +BACKLIGHT_COUNT: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RETI ; TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + +RESTART_ENTRY: + LDI F,$00 + OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED + OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F ; D6 = LOW TO RESET T6963C + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + +; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO + LDI F,$03 ; CS, RD, WR HI, LEs ALL LO + OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT + + LDI F,$00 + OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT + + LDI F,$20 ;$A0 NO BACKLIGHT INVERSION INITIALLY + MOV FLAGS,F ; START WITH DISPLAY ON + + INIT_API_BUS + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT+1,D ; KLUDGE FOR EXTRA 2 BITS OF RESOLUTION + + ; INITIALISE T6963C DISPLAY CONTROLLER + SBI PORTD,6 ; COME OUT OF RESET + + LDI ZL,0 + LDI ZH,0 +RESET_DELAY: + WDR ; 10OCT02 RESET WATCHDOG + SBIW ZL,1 + BRNE RESET_DELAY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOP: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: +; LDIZ CHSET00 ; POINT Z TO FLASH + LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + +; LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + CLR A + STS BACKLIGHT_COUNT,A ; ENSURE BACKLIGHT COUNT IS IN RANGE + + CLR ZL + CLR ZH ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$04 ;$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +WRITE_COMMAND: + RCALL WAIT_STATUS ; LEAVES C/D = 1 + RJMP WRITE_ENTRY +WRITE_COMMAND_AUTO: + RCALL WAIT_AUTO ; LEAVES C/D = 1 + RJMP WRITE_ENTRY + +WRITE_DATA: + RCALL WAIT_STATUS + RJMP WRITE_DATA_ENTRY +WRITE_DATA_AUTO: + RCALL WAIT_AUTO +WRITE_DATA_ENTRY: + CBI PORTC,0 ; C/D = 0 +WRITE_ENTRY: + OUT PORTA,F + NOP + NOP + NOP + CLI + CBI PORTB,1 ; WR = 0 + NOP + NOP + NOP + SEI + SBI PORTB,1 ; WR = 1 + RET + +WAIT_AUTO: + PUSH F +WAIT_AUTO_LOOP: + RCALL READ_STATUS + SBRS F,3 + RJMP WAIT_AUTO_LOOP + POP F + RET + +WAIT_STATUS: + PUSH F +WAIT_STATUS_LOOP: + RCALL READ_STATUS + SBRC F,0 + SBRS F,1 + RJMP WAIT_STATUS_LOOP + POP F + RET + +READ_STATUS: + SBI PORTC,0 ; C/D = 1 + LDI F,0 + OUT DDRA,F ; D0-D7 = INPUTS + CLI + CBI PORTB,0 ; RD = 0 + NOP + NOP + NOP + NOP + SBI PORTB,0 ; RD = 1 + IN F,PINA ; READ DATA BEFORE RD COMES UP + SEI + PUSH F + LDI F,$FF + OUT DDRA,F ; D0-D7 = OUTPUTS + POP F + RET + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; TURN OFF VEE MEASURING + + CBI PORTB,2 ; REMOVE WEAK PULL UP (SRAM SELECT = 1) + SBI DDRB,2 ; NOW DRIVE LOW + CBI PORTD,6 ; T6963C RESET = 0 + CBI PORTD,7 ; T6963C SELECT = 0 + CBI PORTB,0 ; RD = 0 + CBI PORTB,1 ; WR = 0 + + LDI D,$FF + OUT DDRA,D ; D0-D7 = OUTPUTS + LDI D,0 + OUT PORTA,D ; D0-D7 = 0 + + LDI D,0 ;$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + ;LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$1F ; WATCHDOG TURN OFF ENABLE = 1 + OUT WDTCR,D + LDI D,$17 ; WATCHDOG ENABLE = 0 + OUT WDTCR,D + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,XPAGE +; INC YH +; ANDI YH,$1F +; STS XPAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: +; CLI ; FOR BEST SAFETY +; +; LDI F,$00 +; OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED +; OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED +; +; LDI F,$F8 ; INIT_PORTS +; OUT DDRD,F +; LDI F,$B8 ;$F8 +; OUT PORTD,F ; D6 = LOW TO RESET T6963C +; LDI F,$1F +; OUT DDRB,F +; LDI F,$FF +; OUT DDRA,F +; OUT DDRC,F +; +; CLR F +; OUT PORTA,F +; +;; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO +;; LDI F,$03 ; CS, RD, WR HI, LEs ALL LO +; IN F,PORTB +; ANDI F,$10 ; PRESERVE B4 FOR BACKLIGHT +; ORI F,$03 ; CS, RD, WR HI, LEs ALL LO +; OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT +; +;; LDI F,$00 +; IN F,PORTC +; ANDI F,$80 ; PRESERVE C7 FOR BACKLIGHT +; OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT +; +; SEI ; FOR BEST SAFETY +; CBI PORTD,6 ; SEE OUT PORTD,F ABOVE +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYX: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYX +; +; ; INITIALISE T6963C DISPLAY CONTROLLER +; SBI PORTD,6 ; COME OUT OF RESET +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYY: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOPZ: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOPZ + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + +; CLI ; FOR BEST SAFETY +; +; LDI A,HIGH(CONTRAST_MID) +; OUT OCR1BH,A +; LDI A,LOW(CONTRAST_MID) +; OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH +; +; LDI A,HIGH(T1_INIT) +; OUT TCNT1H,A +; LDI A,LOW(T1_INIT) +; OUT TCNT1L,A +; +; LDI A,$50 +; OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH +; LDI A,$01 +; OUT TCCR1B,A ; TIMER 1 RUNNING +; +; LDI F,$00 +; OUT TCCR0,F ; TIMER 0 NOT RUNNING YET +; +; LDI F,$04 ;$05 +; OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS +; OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS +; +; LDI F,$0A +; OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE +; LDI F,$C0 +; OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS +; OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 +; +; SEI ; FOR BEST SAFETY + + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT + ANDI A,1 + BRNE SET_BACKLIGHT_ON + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + RJMP MAIN_LOOP +SET_BACKLIGHT_ON: + LDI A,1<<7 + OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + +; LDS A,CONTRASTL +; RCALL TX_WAIT +; LDS A,CONTRASTH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 1 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_XPAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + LDI XL,LOW(ROWBUF) + LDI XH,HIGH(ROWBUF) ; X -> SINGLE LINE BUFFER IN AVR SRAM + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + LDI B,30 ; BYTES TO COPY +DO_MORE: + A0_A13 YL,YH + RAMRD A + ST X+,A + INC YL + DEC B + RJNE DO_MORE ;BRNE DO_MORE + + POP XH + POP XL + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> SINGLE LINE IN T6963C BUFFER + + CBI PORTD,7 ; CS0 = 0 + MOV F,YL + RCALL WRITE_DATA + MOV F,YH + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI B,30 + LDI YL,LOW(ROWBUF) + LDI YH,HIGH(ROWBUF) ; Y -> SINGLE LINE BUFFER IN AVR SRAM +NICK_SUB2_LOOP: + LD F,Y+ + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + DEC B + BRNE NICK_SUB2_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + SBI PORTD,7 ; CS0 = 1 + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +; SBI DDRB,7 +; IN D,PORTB +; SUBI D,$80 +; OUT PORTB,D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + SBRS FLAGS,7 + RJMP BACKLIGHT_SKIP + LDS D,BACKLIGHT_COUNT + INC D +; LDS C,CONTRASTL +; LSL C +; CP D,C + CPI D,37 ;62 ;64 ; 64 COUNTS = 150 HZ + BRSH BACKLIGHT_EVEN +; LSR C +; CP D,C + CPI D,18 ;31 ;32 + BRNE BACKLIGHT_SAVE +;BACKLIGHT_ODD: + CBI PORTC,7 + SBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 + RJMP BACKLIGHT_CONT +BACKLIGHT_EVEN: + SBI PORTC,7 + CBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + LDI D,0 +BACKLIGHT_CONT: + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 +BACKLIGHT_SAVE: + STS BACKLIGHT_COUNT,D +BACKLIGHT_SKIP: + + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS D,BREAK_COUNT+1 ; WORD IS STORED IN REVERSE ORDER + SUBI D,-$40 + STS BREAK_COUNT+1,D ; START OF 4 INTERRUPT BLOCK? + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + LDI D,$B0 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, CLR OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + +; 10mar03 for better API bus performance (let the chips fall where they may) +; ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN +; ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD +; LDI D,$0B+$AB ; WAIT FOR 3uSEC +;SETTLE_CL2: +; DEC D +; BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + +; LDS C,VCCL +; LDS D,VCCH +; LDI E,LOW(VCC_NOMINAL) +; SUB C,E +; LDI E,HIGH(VCC_NOMINAL) +; SBC D,E +; +; ROR D +; ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +;; PUSH D +;; PUSH C +; ASR D +; ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +;; POP E +;; ADD C,E +;; POP E +;; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 +; +;; CLR D +;; CLR C +; +; LDS E,VEEL +; ADD C,E +; LDS E,VEEH +; ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH WE ARE NO LONGER SETTING TIMER 0 + NOP + NOP + NOP + NOP + NOP + NOP + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + +;END_INT: + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_XPAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +CHSET00: +.INCLUDE "CHSET00.INC" +CHSET00_END: + +; ----------------------------------------------------------------------------- + +GET_CLEAR_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL CLEAR_FRAME_RECT + RJMP MAIN_LOOP + +GET_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FRAME_RECT + RJMP MAIN_LOOP + +GET_CLEAR_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL CLEAR_HALFTONE_RECT + RJMP MAIN_LOOP + +GET_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL HALFTONE_RECT + RJMP MAIN_LOOP + +NO_GOX: RET + +CLEAR_FRAME_RECT: + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS F,RECTNC_YY + STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +FRAME_RECT: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GOX + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GOX + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CLEAR_HALFTONE_RECT: +; LDS F,RECTNC_X +; STS RECT_X,F +; LDS F,RECTNC_Y +; STS RECT_Y,F +; LDS F,RECTNC_XX +; STS RECT_XX,F +; LDS F,RECTNC_YY +; STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +HALFTONE_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LDI A,$55 + SBRS YH,0 + LDI A,$AA + MOV PATTERN,A + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP X03A3 +X039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +X03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ X03B0 + LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + TST XPIXEL + BREQ X03B0 +X03AD: LSR A + DEC XPIXEL + BRNE X03AD +X03B0: AND A,PATTERN + RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +X03B8: LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + BREQ X03D2 + AND A,PATTERN + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP X03B8 +X03C2: TST X_SIZE + BREQ X03D3 +X03C4: LSR A + DEC X_SIZE + BRNE X03C4 + COM A + TST XPIXEL + BREQ X03D2 + CLR B +X03CB: LSR A + ROR B + DEC XPIXEL + BRNE X03CB + AND A,PATTERN + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +X03D2: AND A,PATTERN + RCALL WR_DISP_MEM +X03D3: COM PATTERN + RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP X039A + RET + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/CS64V5.HEX b/src/avr/CS64V5.HEX new file mode 100644 index 00000000..6b6abee7 --- /dev/null +++ b/src/avr/CS64V5.HEX @@ -0,0 +1,385 @@ +:020000020000FC +:100000000DC087C387C3189518951895189518952E +:1000100082C31895189527C711C762C702E00EBFA3 +:100020000FE50DBF10E818B9A8951FE011BD00E05D +:1000300009BF0BBF08EF01BB08EB02BB0FE107BB19 +:100040000FEF0ABB04BB00270BBB03E008BB00E0BB +:1000500005BB00E2B02E17E119B910E91AB9442422 +:10006000552422243324EE246624CC24552750938F +:100070000101509323015093430150934401509345 +:100080004501969AE0E0F0E0A8953197E9F7979856 +:1000900000E0B8D0B7D002E4B1D000E2B3D000E0C5 +:1000A000B1D003E4ABD000E8A9D000E9A7D000E0CC +:1000B000A9D0A8D004E2A2D000EBA0D0E0E0F8E004 +:1000C00000E0A2D03197E1F702EB9AD008E996D090 +:1000D000979A789410E3B9D2CF93DF93C4D2BF91AB +:1000E000AF911BD5212F1D2F12950DD31217B1F4EF +:1000F000119613D5212F1D2F06D3121779F41196BF +:100100000CD5212F1C2F1295FED2121739F41196FF +:1001100004D5212F1C2FF7D2121749F1E6E7F2E19F +:10012000A6E6B3E0D8E1D0930201C0D0D0E8C0E0A9 +:10013000DBBBC39AC398D0930101F89435B33C2735 +:1001400030783C27789435BBC8950BBAC29ABA98D8 +:10015000C1980000C19AC298BA9A119741F031969D +:10016000C3951C2F1F7349F7C054D395E1CF20E1ED +:100170002093F30020E22093F40028E12093F5007F +:1001800021D6112710935101EE27FF271EEF109360 +:10019000FD001BEA1093FC0022E01BD21C7F109391 +:1001A000FE0023E016D21093FF001091FE00209174 +:1001B000FF001A380DEF200720F01B3A0FEF200741 +:1001C00030F01EEF1093FF0010E41093FE001EEFBE +:1001D00019BD1BEA18BD1CEF1DBD1EEC1CBD10E5B2 +:1001E0001FBD11E01EBD00E003BF04E008BF09BF52 +:1001F0000AE005BF00EC0ABF0BBF92C219D006C0CF +:1002000011D004C015D001C00DD0A8980BBB0000C0 +:1002100000000000F894C1980000000000007894ED +:10022000C19A08950F930BD003FFFDCF0F9108954E +:100230000F9305D000FD01FFFCCF0F910895A89A00 +:1002400000E00ABBF894C098000000000000000025 +:10025000C09A09B378940F930FEF0ABB0F910895DA +:1002600002E00EBF0FE50DBF1FE7B122AF98C498A3 +:10027000409101014BBBC39AC39850E05FBD5EBD86 +:1002800094989598C298BA9A96989798C098C19859 +:100290005FEF5ABB50E05BBB50E059BF5BBF5FE113 +:1002A00051BD57E151BD5AE655BF889508957894E0 +:1002B0001FEDE12210E01EBB1FBB62D21B3129F1F2 +:1002C000B3FC0DC0103258F4183009F4FEC01D30D4 +:1002D00009F40DC11A3009F48BC0173041F7B2FC94 +:1002E00012C0103381F4C091F300D091F40020913A +:1002F000F500CC5FDD4FF89435B320FB36F97894E8 +:1003000035BBF1D4102D72D2D2CF3AD21B3139F392 +:100310001E3209F475C11F3209F44FC01F3309F4AE +:1003200084C1113409F4A6C0123409F427C213346D +:1003300009F404C1133609F451C9143409F4EBC0AB +:10034000153409F4D8C0163409F408C1163609F476 +:1003500051C9173409F49EC0183409F463C918361A +:1003600009F454C91B3409F461C01C3409F4D4C124 +:100370001D3409F42BC01E3409F4FCC0103509F4F7 +:1003800097C0123509F4DCC0133509F4D2C0153515 +:1003900009F4F4C1163519F410E2E12AF7C0173553 +:1003A00009F4ECC1183509F4B8C11A3509F4E2C1F1 +:1003B000103310F01A3398F07ACFE2D110FF03C057 +:1003C00014E0B12A74CF1BEFB12271CFD9D1103311 +:1003D00021F4F89400E4B02A43CF69CFD1D135D1CC +:1003E000C0E1C093F300D093F4002093F5005FCFF9 +:1003F00001D05DCF0F92C091F300D091F400209115 +:10040000F500DE5FC395F89435B320FB36F9789498 +:1004100035BB69D4182F100D100D1A95103418F033 +:10042000EED00F900895800D0F900895979800E0FA +:10043000E9DEE8DE02E4E2DE00E2E4DE00E0E2DE45 +:1004400003E4DCDE00E8DADE00E9D8DE00E0DADE34 +:10045000D9DE04E2D3DE00EBD1DEE0E0F8E000E03C +:10046000D3DE3197E1F702EBCBDE08E9C7DE979ADE +:10047000A9D41DCF85D1117051F41FE7B122AF98D7 +:10048000C498409101014BBBC39AC39810CF10E8A8 +:10049000B12A0DCF75D1103309F404C0113309F41A +:1004A00004C005CF07EFB02202CF08E0B02AFFCE8C +:1004B00067D1103309F403C0113309F403C00FEE00 +:1004C000B022F5CE00E1B02AF2CEC091F300D09177 +:1004D000F4002091F500DE5FF89435B320FB36F987 +:1004E000789435BB00D470191FB712FFE0CE01D04D +:1004F000DECE7727089544D111FD07C010FD03C05B +:100500000FEDB022D4CE00E2B02A002700932301E1 +:1005100082D2F1F7CCCE34D1103309F404C01133B8 +:1005200009F404C0C4CE0EEFB022C1CE01E0B02A5F +:10053000BECE26D1712F24D1812FB9CE02E0B02AB0 +:1005400070933401809335011BD11093360118D17B +:1005500010933701E5D20DEFB022A9CE7093380188 +:10056000809339010DD110933A010AD110933B01C8 +:100570002CD39DCE709338018093390101D1109313 +:100580003A01FED010933B0145D391CEF9D010FF34 +:100590000BC01091FE002091FF001C5F2F4F1B3AF3 +:1005A0000FEF2007A8F40AC01091FE002091FF0071 +:1005B000145020401A380DEF200750F01093FE0021 +:1005C0002093FF0022E00DD01091FF0023E009D01E +:1005D0006ECEE199FECF2EBB22272FBBE09A1DB332 +:1005E0000895E199FECFE5FEFFCF2EBB22272FBB5A +:1005F0001DBBF894E5FEFFCFE29AE19A18951AC563 +:10060000BFD023D0BDD0A12FBBD0B12FB9D0F8948B +:1006100035B320FB36F9789435BB80D221961197FB +:100620001A2F1B2B09F0F2CF42CEAAD00ED01F9367 +:100630001AD01BE1C6D01FE3C4D01F91105DC1D0FA +:100640001D2F5AD01C2F58D032CEC0E0D0E022E669 +:100650001F70163008F4210F2695D7952695D7954B +:10066000D695D6950895A6E1B2E0AC0FBD1FF894DB +:1006700035B320FB36F9789435BB4FD2E12F119674 +:100680004CD2F12FAC2FBD2F1496CFEFDFEF319767 +:10069000FF70349780F1319640D2119601E220E14B +:1006A000D127CC0FDD1F10F4C027D227CC0FDD1FC0 +:1006B00010F4C027D227CC0FDD1F10F4C027D2279B +:1006C000CC0FDD1F10F4C027D227CC0FDD1F10F494 +:1006D000C027D227CC0FDD1F10F4C027D227CC0FA4 +:1006E000DD1F10F4C027D227CC0FDD1F10F4C02768 +:1006F000D227319789F608951F93129504D061D0BF +:100700001F9101D05EC01F7010631A3308F0195F8B +:100710000895F7C3FFC307C4AAC432D010FD13C0A5 +:100720007093460180934701B09248011091F30005 +:10073000109349011091F40010934A011091F500B3 +:1007400010934B01B4CD709146018091470110EC9C +:10075000B122109148011F73B12A109149011093E1 +:10076000F30010914A011093F40010914B01109383 +:10077000F5009DCD05D004D003D002D001D097CD97 +:1007800010EC10934401A89510E01EBB1FBB10ECA9 +:10079000809910934401B5FC3ED13320A1F310E0C1 +:1007A00010934401CF93DF93C22DC059DD271881E8 +:1007B000F8943A942394CFE72C227894DF91CF9148 +:1007C00008951F93A895152D1031E0F71F91CF9331 +:1007D000DF93DFB7F894C52DC40DDFBFCF70C05ACB +:1007E000DD2718835394DF91CF91089578940027E3 +:1007F00000930001982E672F6AD26093F200A092B6 +:10080000F000C12FDD27CC0FDD1F1091F300C10FC9 +:100810001091F400D11F1091F50026D564D22196D5 +:10082000F02C61D2CF2DD02D1091F300C10F10917B +:10083000F400D11F58D2802C1C2F2D2F219785FC1E +:1008400007C0C091F300D091F400DE5F4CD21DC010 +:100850004AD2B4FC1AC0C091F300D091F400DE5F1C +:10086000F02C41D20F1808F40024069400920001E5 +:10087000672F600D2CD26093F200A092F000C0911F +:10088000F300D091F400DE5F2ED2B3FC1AC0072F24 +:10089000000D08F016C01F932F932BDEABDD0091E7 +:1008A0000001700F982E672F12D26093F200A09271 +:1008B000F00000910001701B1091F500D5D42F912C +:1008C0001F91700D86FE05C0C12FD22F22970BD22B +:1008D000900CC12FD22F219606D2702C0FEF0ABB9D +:1008E000C09A0FE180228092F1000027801201C09F +:1008F00087C0AA27B92DB695A795B695A795B05FDD +:1009000007C09394A05CBF4F8090F100A090F000CE +:10091000AA2A222721961091F500A6D4E4D1112706 +:100920006091F200662339F08894079417956A95D0 +:10093000E1F7022A212F08E1F89435B300FB36F9DC +:10094000789435BBF89435B33A25307C3A257894C1 +:1009500035BB3B2F330F330FA7FA31F9A6FA30F925 +:100960003BBBF894C39AC398789430930101002755 +:100970000ABBF894C29ABA98C0980000C09A09B30A +:100980000026B0FC002A0FEF0ABB0BBAC19800008A +:10099000C19A7894C298BA9AA3948A9409F0BACF6B +:1009A000222351F1F89435B33A25307C3A257894D6 +:1009B00035BB3B2F330F330FA7FA31F9A6FA30F9C5 +:1009C0003BBBF894C39AC3987894309301010027F5 +:1009D0000ABBF894C29ABA98C0980000C09A09B3AA +:1009E0002027B0FC202B0FEF0ABB2BBBC1980000C7 +:1009F000C19A7894C298BA9A04D07A9409F081CFB7 +:100A00000895CF93DF93192D78D01881122B188376 +:100A1000DF91CF9108952F93CF93DF93109123010E +:100A20006CD01881122309F45EC028812127288305 +:100A300010E010934401AF93BF93A3E0B1E0CC2743 +:100A4000D0912301D695C795D695C795D05F18E16B +:100A50000BD42EE1F89435B33C27307C3C277894B6 +:100A600035BB3D2F330F330FC7FB31F9C6FB30F9D0 +:100A70003BBBF894C39AC398789430930101002744 +:100A80000ABBF894C29ABA98C0980000C09A19B3E9 +:100A90007894C298BA9A0FEF0ABB1D93C3952A9512 +:100AA00009F0D8CFBF91AF91CC27D0912301D69533 +:100AB000C795D695C795D695C79597980C2FA2DB65 +:100AC0000D2FA0DB04E29ADB00EB98DB2EE1C3E004 +:100AD000D1E0099199DB2A95E1F702EB91DB979A36 +:100AE00010EC109344011091230113951F73109380 +:100AF0002301DF91CF912F910895C4E2D1E0212FFE +:100B0000269526952695C20F20E0D21F21E017706A +:100B100019F0220F1A95E9F7089562C385C3C7CB70 +:100B200078949090350160913401D1D06093F200B7 +:100B3000A092F00070903701CC27D92DD695C7959B +:100B4000D695C795D05F18E18FD307C0C05CDF4F43 +:100B500093946091F200A090F000AC2A1FEF809077 +:100B6000360100E0801641F008E08016B8F06623F8 +:100B700019F016956A95E9F7DAD008E01091F200BD +:100B8000011B801AA3941FEF08E0801638F0B1F023 +:100B9000CED01FEF08E0801AA394F6CF882079F01A +:100BA00016958A94E9F71095662341F02227169549 +:100BB00027956A95E1F7BBD0A394122FB8D021DF17 +:100BC0007A9400277012C2CF089500913A010A95D5 +:100BD0000230D0F300913B010330B0F300913801B3 +:100BE0000395009334010091390100933501809001 +:100BF0003A018A948A948092360101E00093370189 +:100C00008FDF009138010093340180903A01809287 +:100C100036013AC000913A010A950230A8F20091DB +:100C20003B01033088F200913801039500933401B1 +:100C3000009139010093350180903A018A948A9499 +:100C40008092360101E0009337016ADF009138019C +:100C500000933401009139010395009335017090A0 +:100C60003B017A947A947092370101E00093360147 +:100C700057DF80903A0100913801080D0A950093E2 +:100C8000340101E00093360100913901039500938E +:100C9000350170903B017A947A947092370140DF6D +:100CA0000091380103950093340180903A018A94B1 +:100CB0008A948092360170903B0100913901070DB2 +:100CC0000A950093350101E00093370129CFAA244A +:100CD00000EFA01A67FFAA246F77685014F0A3945E +:100CE000FCCF685F0895F89435B33C27307C3C27EF +:100CF000789435BB3D2F330F330FC7FB31F9C6FB5B +:100D000030F93BBBF894C39AC398789430930101AF +:100D100000270ABBF894C29ABA98C0980000C09AFB +:100D200009B27894C298BA9A0FEF0ABB0895F89462 +:100D300035B33A25307C3A25789435BB3D2F330FB7 +:100D4000330FA7FA31F9A6FA30F93BBBF894C39AEE +:100D5000C39878943093010100270ABBF894C29A93 +:100D6000BA98C0980000C09AF9B27894C298BA9A1A +:100D70000FEF0ABBB1FE03C01095F12203C0F126AC +:100D8000B0FCF12AF89435B33A25307C3A257894B2 +:100D900035BB3D2F330F330FA7FA31F9A6FA30F9DF +:100DA0003BBBF894C39AC398789430930101FBBA83 +:100DB000F894C29ABA98C1980000C19A7894C298DF +:100DC000BA9A08959924C0E0D0E118E14DD2AA243E +:100DD000A092F0001091F0001C2BF89435B331274D +:100DE000307C3127789435BB3D2F330F330F17FB01 +:100DF00031F916FB30F93BBBF894C39AC398789449 +:100E00003093010100E00BBBF894C29ABA98C198E4 +:100E10000000C19A7894C298BA9AA39400E2A016EE +:100E200019F0A092F000D6CFECDD9394C05CDF4FB8 +:100E3000D03209F0CCCF7727882708951FB60F93BB +:100E40000FEDC02EEF93FF93E42DE05AFF270081B2 +:100E5000FF91EF910CB95A9443940FE040226A94A9 +:100E60000AF046C04BC01FB60F930FEDC02E0CB159 +:100E70005C9938C0E7FC26C0E6FC08C0033029F4C2 +:100E800000E009B9539A00E4E02A38C0602E00E877 +:100E900003190AF40FE7662012F4052D00680CB957 +:100EA000061508F4602E062D0F7739F000ECE02AC5 +:100EB0006A9422F55798559A21C00FEBE022569A72 +:100EC0005E9A1CC0EF93FF93E32DE20DEF77E0599C +:100ED000FF270083FF91EF9133946A947AF40CC05A +:100EE0001FB60F93539807E109B90FEBE022CC240A +:100EF00055985698579A0CB10FE7E0220F911FBEF4 +:100F000018951FB68A9A4CB55DB55093FB00409377 +:100F1000FA008EC01FB68B9A4CB55DB55093F900A0 +:100F20004093F80085C01FB65AB35F935BB35F93DD +:100F30005FEF5ABBB7FE14C0509151015395553223 +:100F400028F4523159F4AF98C49A03C0AF9AC498A8 +:100F500050E0409101014BBBC39AC398509351019B +:100F600055B35F93509101015F9350914501505CDF +:100F70005093450149F450914401539550934401D5 +:100F800019F45FEBB5226CC950EB5FBD4CB55DB594 +:100F9000485F5F4F5BBD4ABD59BD48BD8A9A929A72 +:100FA0008B9A939A8D9895985091FD004091FC00F2 +:100FB0008D9A859907C040389DEF59074AF04150F6 +:100FC000504006C0453D9FEF590712F44F5F5F4FF9 +:100FD0005093FD004093FC005BBD4ABD9091FE0024 +:100FE000491B9091FF00590B1AF445EF5FEF02C0C7 +:100FF00040E85DEF59BD48BD000000000000000062 +:10100000000000005DEF5DBD55E75CBD8A989298D9 +:101010008B98939850EE5FBD5F915BBBC39AC3986A +:10102000509301015F9155BB5F915BBB5F915ABBD0 +:101030001FBE18959924C0E0D0E1A0E0B0E118E10E +:1010400013D1A05CBF4F0A94E1F720E22F93C8D0E0 +:10105000EBD0A395C3952F912A9509F0F7CFD1DC5A +:101060009394A0969096B03209F0EFCFB0CE88DB83 +:101070001F9386DB10934C0183DB1695169516950E +:1010800009F410E210934F017BDB10935001172FEE +:1010900016951695169510934D0180934E0118E103 +:1010A000E3D01F9110FD46C0CC27D0914E019D2E5C +:1010B000D695C795D695C79510914D01C10FD05FB4 +:1010C0002091500110914C01121720F5211BAA27E5 +:1010D000B0914E01B10FB695A795B695A795109111 +:1010E0004D01A10FB05F2F93AF93BF93CF93DF93C9 +:1010F00020914F0168D085DCDF91CF91BF91AF91F6 +:101100002F919394A05CBF4FC05CDF4F2A9559F795 +:1011100020914C012F93CF93DF9320914F015AD010 +:1011200070DCDF91CF912F919394C05CDF4F2A95B3 +:1011300089F7F5CCCC27D0914E0100915001D00F0A +:101140009D2ED695C795D695C79510914D01C10F87 +:10115000D05F202F10914C01121728F5211BAA27D0 +:10116000B0914E01B00FB11BB695A795B695A79556 +:1011700010914D01A10FB05F9A94A054B040C0549B +:10118000D0402F93AF93BF93CF93DF9320914F0124 +:101190001AD037DCDF91CF91BF91AF912F912A9573 +:1011A00059F720914C019A94C054D0402F93CF937B +:1011B000DF9320914F010ED024DCDF91CF912F914E +:1011C0002A9589F7ACCC0CD011962ED021962A9571 +:1011D000D1F7089510E028D021962A95E1F70895D7 +:1011E000F89435B33A27307C3A27789435BB3B2FB7 +:1011F000330F330FA7FB31F9A6FB30F93BBBF89453 +:10120000C39AC39878943093010100270ABBF894DD +:10121000C29ABA98C0980000C09A19B37894C2983C +:10122000BA9A0FEF0ABB0895F89435B33C27307C87 +:101230003C27789435BB3D2F330F330FC7FB31F973 +:10124000C6FB30F93BBBF894C39AC39878943093AB +:1012500001011BBBF894C29ABA98C1980000C19AC8 +:101260007894C298BA9A0895F89435B310FB36F979 +:10127000789435BB089546323444303331393033B5 +:101280003132313730394C034C034C034C034C039F +:101290004C034C034C034C034C034C034C034C03D6 +:1012A0004C034C034C034C034C034C034C034C03C6 +:1012B0004C034C034C034C034C034C034C034C03B6 +:1012C0004C034C034C0300014C034C034C034C03F4 +:1012D0004C034C034C034C034C034C034C034C0396 +:1012E00003014C034C0306010F01180121012A01DF +:1012F00033013C0145014E0157014C034C034C03A3 +:101300004C034C034C034C036001690172017B01E7 +:1013100084018D0196019F01A901B201BB01C401A5 +:10132000CD01D601DF01E801F101080211021A0224 +:1013300023022C0235023E02470250024C034C03AA +:101340004C034C034C034C03590262026B027402BF +:101350007D0286028F029902A302AD02B802C20288 +:10136000CB02D402DD02E602F002FC0203030C030E +:1013700015031E0327033003390343034C034C03B7 +:101380004C034C034C030003066101F8010770880D +:1013900098A8C888700107206020202020700107CD +:1013A000708808102040F80107F810201008887095 +:1013B000010710305090F810100107F880F008086D +:1013C00088700107304080F08888700107F80810A5 +:1013D000204040400107708888708888700107703D +:1013E000888878081060010770888888F8888801E4 +:1013F00007F08888F08888F00107708880808088EE +:10140000700107E09088888890E00107F88080F0FC +:101410008080F80107F88080F08080800107708864 +:1014200080B88888780107888888F88888880221A9 +:10143000078080808080808001070808080808886D +:101440007001078890A0C0A09088010780808080EC +:101450008080F8010788D8A8A8888888010788882C +:10146000C8A89888880107708888888888700107CC +:10147000F08888F0808080010770888888A890684C +:101480004C034C034C03060801014F0065030107A0 +:10149000F08888F0A09088010770888070088870B4 +:1014A0000107F820202020202001078888888888CC +:1014B0008870010788888888885020010788888874 +:1014C000A8A8A8500107888850205088880107885C +:1014D0008888502020200107F80810204080F8015B +:1014E000070000700878887801078080F088888875 +:1014F000F00107000078808080780107080878886C +:10150000888878010700007088F88070010718202B +:10151000F8202020200108000078888878087001D1 +:10152000078080B0C888888802210780008080807A +:101530008080052108100010101010906005210710 +:10154000808090A0C0A090032107C0404040404050 +:101550004001070000F0A8A8A8A801070000B0C833 +:10156000888888010700007088888870010800005A +:10157000F08888F080800108000078888878080862 +:1015800002056105B0C0808080010700007880708E +:1015900008F001072020F82020201801070000880B +:1015A0008888986801070000888888502001070013 +:1015B000008888A8A85001070000885020508801A2 +:1015C00008000088888878087001070000F810205B +:1015D00040F80107F8F8F8F8F8F8F80070933801C7 +:1015E00080933901CDD810933A01CAD810933B01AA +:1015F00026D05DC67093380180933901C1D810930D +:101600003A01BED810933B012FD051C670933401DC +:1016100080933501B5D810933601B2D810933701B5 +:1016200078D045C67093340180933501A9D81093C2 +:101630003601A6D81093370171D039C608950091AC +:101640003801009334010091390100933501009174 +:101650003A010093360100913B010093370102E00B +:10166000B02A5EDA0DEFB02200913A010A950230FD +:1016700028F300913B01033008F3009138010093F7 +:101680003401009139010093350100913A01009332 +:10169000360101E00093370143DA009138010093ED +:1016A00034010091390103950093350100913B010C +:1016B00002500093370101E00093360131DA809047 +:1016C0003A0100913801080D0A950093340101E0B8 +:1016D0000093360100913901039500933501009183 +:1016E0003B010250009337011BDA0091380100934F +:1016F000340100913A010093360170903B01009152 +:101700003901070D0A950093350101E00093370177 +:1017100007CA02E0B02A04DA0DEFB0227894909064 +:10172000350160913401D3DA6093F200A092F000A9 +:1017300070903701CC27D92D15E5D0FF1AEA012E7C +:10174000D695C795D695C795D05F18E18DDD07C0B2 +:10175000C05CDF4F93946091F200A090F000AC2A3F +:101760001FEF8090360100E0801641F008E08016FF +:10177000C8F0662319F016956A95E9F71021D7DAB3 +:1017800008E01091F200011B801AA3941FEF08E0FB +:10179000801640F0C1F01021CADA1FEF08E0801A6D +:1017A000A394F5CF882089F016958A94E9F71095CF +:1017B000662349F02227169527956A95E1F71021AF +:1017C000B6DAA394122F1021B2DA00941AD97A94BF +:0817D00000277012BDCF08953F +:0220000003419A +:00000001FF diff --git a/src/avr/ISPD.EXE b/src/avr/ISPD.EXE new file mode 100644 index 0000000000000000000000000000000000000000..747ba7373c9217f26b5b124b19d3fb0f73b19cbb GIT binary patch literal 69514 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 + STS XPAGE,YH + RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 +.ENDMACRO + +.MACRO A14_A18 + CLI + LDS R19,LATCH10_SAV ; AND THIS + EOR R19,@0 + ANDI R19,$E0 + EOR R19,@0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + SEI + STS LATCH10_SAV,R19 ; MUST BE ATOMIC DUE TO TOGGLING M +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@1 + + LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,1 + BST @1,6 ; A14 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + NOP + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO + OUT PORTA,@0 ; SELECT PHOTODIODE CHANNEL + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LED + OUT PORTA,@0 ; MAIN LED DRIVE PORT + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LEDLO + LDS D,LATCH12_SAV ; DRIVE LED COMMON LO + CBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO LEDHI + LDS D,LATCH12_SAV ; DRIVE LED COMMON HI + SBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKHI + LDS D,LATCH12_SAV ; DRIVE SPEAKER HI + SBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKLO + LDS D,LATCH12_SAV ; DRIVE SPEAKER LO + CBR D,1<<3 + SBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKOFF + LDS D,LATCH12_SAV ; DRIVE SPEAKER OFF + CBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.EQU T1_INIT =-818 ;$FB35 +.EQU T1_FULL_SCALE =-716 ;50.0HZ ; SETS LCD FRAME RATE TEMPORARY TO STOP FLIKER +;.EQU T1_FULL_SCALE =-651 ;53.5HZ ; SETS LCD FRAME RATE +;.EQU T1_FULL_SCALE =-600 ;54.8HZ ; SETS LCD FRAME RATE + +.EQU CONTRAST_LONG =-340 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +;.EQU CONTRAST_LONG =-250 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +.EQU CONTRAST_MID =-200 +.EQU CONTRAST_SHORT = -43 ; ALL SHORT PULSES IS FULLY LIGHT + +.EQU VCC_NOMINAL =-552 ;$FCC4 + +.EQU VEE_MIN =-710 ; MIN IS FULLY DARK +.EQU VEE_INIT =-340 +.EQU VEE_MAX = -43 ; MAX IS FULLY LIGHT + +; WHEN VCC = $FCC4 FOR 6.0V: +.EQU CONTRAST_MIN =-710 ; MIN IS FULLY DARK +.EQU CONTRAST_INIT =-640 +.EQU CONTRAST_MAX =-580 ; MAX IS FULLY LIGHT + +; GENEROUS LIMITS FOR EXPERIMENTATION: +;.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FE10 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =10 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$20 +.EQU RX_SIZE =$80 + +.EQU TK_LED_PULSE =14 ; 18US ?? CLOCKS OF /8 +.EQU TK_DELAY_0 =19 ; ??US DELAY TILL START OF LED PULSE (/8) +;.EQU TK_DELAY_0 =$20 ;$38 ; ??US DELAY TILL START OF LED PULSE +;.EQU TK_DELAY_0 =$25 ;$38 ; 54US ?? CLOCKS OF /8 +.EQU TK_DELAY_1 =$10 ;$28 ; CLOCKS OF /64, CHANNEL SELECT DELAY +.EQU TK_DELAY_2 =$00 ; CLOCKS OF /1024, VDD POWER ON DELAY + ; $D0 IS TOO SHORT, $E0 SEEMS TO WORK + +.EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS +.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 USED TO CONTROL LED PULSING FOR TOUCHSCREEN EVERY 2ND CYCLE +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +; for AVRA / TAVRASM: +;.def XL =R26 +;.def XH =R27 +;.def YL =R28 +;.def YH =R29 +;.def ZL =R30 +;.def ZH =R31 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +BUZZ_PERIOD: .BYTE 1 +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +XPAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +CHAR_X: .BYTE 1 +CHAR_Y: .BYTE 1 +CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC_64K: .BYTE 1 +TIME_HSEC_256: .BYTE 1 +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_STATE: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RJMP GO_TIM2_OVF ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_T1_OVERFLOW + RJMP GO_T0_OVERFLOW + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + LDI F,0 + STS TIME_HSEC_64K,F + STS TIME_HSEC_256,F + STS TIME_HSEC,F + STS TIME_SECOND,F + STS TIME_MINUTE,F + STS TIME_HOUR,F + LDI F,1 + STS DATE_DAY,F + STS DATE_MONTH,F + LDI F,20 + STS DATE_YEAR,F + +RESTART_ENTRY: +;**: + LDI F,8 ; TIMER 2 CLOCKED BY 32 KHZ +;** LDI F,0 ; TIMER 2 CLOCKED BY 11 MHZ + OUT ASSR,F +;**: + ; MUST MATCH SET_TIME ROUTINE % + LDI F,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;!! LDI F,$11 ; DIVIDE BY 2, TOGGLE OC2 (PIN 21) + ; (RTC DIAGNOSTIC) +;** LDI F,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,F + ; % + LDI F,$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + LDI F,$00 + OUT GIMSK,F + + LDI F,$B8 ; INIT_PORTS + OUT DDRD,F + OUT PORTD,F ; D2 = TRI-STATE, VSWT ON + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + OUT PORTC,F + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + + LDI D,$18 ; A18|A17|A16|A15|A14=11000 + OUT PORTA,D ; CL1=M=FLM=0 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BUZZ_TIME,D ; NOT BUZZING (SHORT BEEP COMES LATER) + + CLR SCAN + STS ROW_INDEX,SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + + LDI D,$F4 ; BIT 6 = 1 VDD ON, BIT 7 = 1 LCD ON + STS LATCH5_SAV,D + PHOTO D + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +RTNCDE: ;LDIZ RTN_CODE ; POINT Z TO FLASH + LDI ZL,LOW((RTN_CODE)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER + LDI XL,LOW((RTN_CODE_END-RTN_CODE)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((RTN_CODE_END-RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + CLR R0 ; TEMPORARY CLEAR KB + RAMWRX R0 ; WRITE DATA TO DSPRAM + DEC XL + BREQ RTNCDE_END ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CDE1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CDE0 +RTNCDE_END: + + ; INITIALISE DEFAULT CHARACTER SET + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + ;LDIZ CHSET00 ; POINT Z TO FLASH + LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + ; CLEAR REFRESH BUFFER TO AVOID A BRIEF FLICKER + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL GO_SELECT_XPAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +CLEAR_REFRESH: + PUSH B + PUSH YL + PUSH YH + + LDI B,32 + RCALL GO_CLEAR_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + ADIW YL,6 + LDI B,2 + RCALL GO_CLEAR_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP YH + POP YL + POP B + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE CLEAR_REFRESH + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,0 + STS BUZZ_PERIOD,A ; HIGHEST FREQUENCY + LDI A,54 ;$40 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + LDI A,0 + STS SCAN_STATE,A ; START ON FIRST LED / PHOTODIODE PAIR + + LDI A,0 + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + LDI F,$45 + OUT TIMSK,F ; TURN ON TIMER 0, 1, 2 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL HELLO_DISPLAY ; SHOW EXAMPLE DISPLAY + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + SBI PORTD,4 ; TURN TRANSISTOR OFF + CBI PORTD,5 ; DROP CL2 + + LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + LDI D,$74 ; BIT 6 = 1 VDD ON, BIT 7 = 0 LCD OFF + SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + LDI D,$34 ; BIT 6 = 0 VDD OFF, BIT 7 = 0 LCD OFF + STS LATCH5_SAV,D + PHOTO D + + LDI D,$41 + OUT TIMSK,D ; DISABLE TIMER 1 INTERRUPTS + + LDI D,0 + OUT TCCR0,D ; DISABLE TIMER 0 TEMPORARILY ONLY + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + + LDI F,4 + STS TURNON_COUNT,F ; .25 SEC TO BREAK, .75 SEC TO MAKE + + INIT_API_BUS ; RESET UART TO RECEIVE TURNON COMMAND + +SLEEP_LOOP: + CLI + IN F,TCCR0 + TST F + LDI F,$4A ; SE=1 SM1:SM0=00 FOR IDLE MODE + BRNE SLEEP_SETUP ; TIMER 0 RUNNING, STAY IN IDLE MODE + SBIS PIND,0 ; BREAK OFF, UART ACTIVE, STAY IN IDLE + LDI F,$7A ; SE=1 SM1:SM0=11 FOR POWER SAVE MODE +SLEEP_SETUP: + OUT MCUCR,F + SEI + SLEEP + + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDS F,TURNON_COUNT + TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;SBIS PIND,0 ; AND BREAK HAS DISAPPEARED, WAKE UP + BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP + + CLI + RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + +; ----------------------------------------------------------------------------- + +ADRYP: LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL + OUT PORTA,YH + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,XPAGE +; INC YH +; ANDI YH,$1F +; STS XPAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +;HELLO_DISPLAY: +; LDI A,0 +; STS RECTNC_X,A +; STS RECTNC_Y,A +; STS RECTNC_XX,A +; LDI A,$80 +; STS RECTNC_YY,A +; RCALL DRAW_RECTNC +; +; LDI A,16 +; STS CHAR_X,A +; STS CHAR_Y,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; RCALL STRING_DRAW +; +; LDI A,240 +; STS CHAR_X,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; +;STRING_RIGHT_JUST: +; PUSH B +; PUSH ZL +; PUSH ZH +; RCALL STRING_WIDTH +; POP ZH +; POP ZL +; POP B +; LDS A,CHAR_X +; SUB A,R0 +; STS CHAR_X,A +; +;STRING_DRAW: +; PUSH B +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; PUSH R0 +; RCALL DRAW_CHAR +; POP R0 +; POP ZH +; POP ZL +; LDS A,CHAR_X +; ADD A,R0 +; STS CHAR_X,A +; POP B +; DEC B +; BRNE STRING_DRAW +; RET +; +;STRING_WIDTH: +; CLR R0 +;STRING_WIDTH_LOOP: +; PUSH B +; PUSH R0 +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; POP ZH +; POP ZL +; POP A +; ADD R0,A +; POP B +; DEC B +; BRNE STRING_WIDTH_LOOP +; RET +; +;HELLO_MESSAGE: .DB 'H','E','L','L','O',0 + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +SET_TIME: + LDI A,0 + OUT TCCR2,A ; STOP COUNTING WHILE SETTING CLOCK + STS TIME_HSEC_64K,A + STS TIME_HSEC_256,A + STS TIME_HSEC,A + RCALL RX_WAIT + STS TIME_HOUR,A + RCALL RX_WAIT + STS TIME_MINUTE,A + RCALL RX_WAIT + STS TIME_SECOND,A + RCALL RX_WAIT + STS DATE_MONTH,A + RCALL RX_WAIT + STS DATE_DAY,A + RCALL RX_WAIT + STS DATE_YEAR,A + LDI A,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;** LDI A,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,A + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE +;L01A3: + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: CLR CURSORX + RJMP MAIN_LOOP + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRCC DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRCC DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + RCALL FIND_CHAR ; SET UP CHAR_PTR FROM A = CHAR + RCALL CHAR_WIDTH ; SET UP R0 = PROP WIDTH FROM CHAR PTR + + CLR F + STS TEMP,F ; NUDGE FOR FIXED SPACING MODE + + SBRC FLAGS,4 + RJMP PROP_MODE ; FORCED TO FIXED SPACING MODE? + + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS ; GET R0 = CELL WIDTH FOR CHARACTER SET + PUSH R0 + SUB R0,W + BRCC NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + POP R0 ; RESTORE R0 = FIXED CELL WIDTH + +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE ; FORCED TO GRAPHICS MODE? + + MOV F,CURSORX + ADD F,R0 ; CHECK IF CHAR WILL FIT ON THIS LINE + BRCC OK_LINE + + CLR CURSORX + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 + RCALL SELECT_XPAGE ; IN CASE WE SCROLLED THE DISPLAY + +OK_LINE: + LDS F,TEMP + ADD F,CURSORX + STS CHAR_X,F + STS CHAR_Y,CURSORY ; SET UP TOP LEFT COORDINATES + + ADD CURSORX,R0 ; ADVANCE CURSOR + +DRAW_CHAR: + LDS XPIXEL,CHAR_X + LDS LINE_CNT,CHAR_Y + + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE ; Y OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 + +Y_OFFSET_DONE: + SBRS X_SIZE,7 + RJMP X_OFFSET_DONE ; X OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$03 + RCALL LPMS + ADD XPIXEL,R0 + +X_OFFSET_DONE: + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + ADIW YL,$01 + RCALL LPMS ; GET R0 = Y LINES FOR CHARACTER + MOV Y_SIZE,R0 + + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +FIND_CHAR: + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + STS CHAR_PTR,YL + STS CHAR_PTR+1,YH + RET + +CHAR_WIDTH: + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + RCALL LPMS + MOV X_SIZE,R0 + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP LPMS ; PROPORTIONAL WIDTH IS PRESENT + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RJMP LPMS ; NO PROPORTIONAL WIDTH, USE CELL WIDTH + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + ; LET'S BE SAFE + ANDI A,$7F + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +GO_SELECT_XPAGE: + RJMP SELECT_XPAGE + +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +GO_EXT_INT0: + RJMP EXT_INT0 + +GO_EXT_INT1: + RJMP EXT_INT1 + +GO_TIM2_OVF: + RJMP TIM2_OVF + +GO_T1_OVERFLOW: + RJMP T1_OVERFLOW + +GO_T0_OVERFLOW: + RJMP T0_OVERFLOW + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +; ----------------------------------------------------------------------------- + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +; ----------------------------------------------------------------------------- + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR CURSORX ; HOME CURSOR + CLR CURSORY + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE +CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE CLEAR_DISPLAY_LOOP + RET + +; ----------------------------------------------------------------------------- + +EXT_INT0: +;**: +RETI +;** IN SR,SREG ; MEASURE VCC +;** SBI DDRD,2 +;** IN C,TCNT1L +;** IN D,TCNT1H +;** STS VCCH,D +;** STS VCCL,C +;** RJMP EXT_INT_RET + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP EXT_INT_RET + +T1_OVERFLOW: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDI D,$70 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, TOGGLE OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + LDS C,CLOCKING_PTR +; TST C ; START OF 4 LINE BLOCK? (1 BASED) + lds d,CLOCKING_PTR+1 + andi d,1 + or c,d ; checks for start of an 8 line block +; rjmp BREAK0 ; temporary (prevents switching off via power switch) + BRNE BREAK0 ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK1 ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION +GO_SLEEP_ENTRY: + RJMP SLEEP_ENTRY + +BREAK0: NOP + NOP + NOP + NOP + NOP + NOP + NOP +BREAK1: SBI DDRD,3 ; PRECHARGE TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D ; STOP TIMER1 + OUT TCNT1H,D ; AND CLEAR COUNT + OUT TCNT1L,D + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + LDS D,LATCH10_SAV + OUT PORTA,D + SBI PORTB,4 + SBI PORTA,5 ; PULSE CL1 + CBI PORTA,5 + CBI PORTB,4 + NOP ; EQUALIZE DELAY + NOP + NOP + NOP + NOP + NOP + RJMP L04F9 + +L04E6: LDS D,LATCH10_SAV + ORI D,$80 ; RAISE FLM + ORI D,$20 ; RAISE CL1 + OUT PORTA,D + + SBI PORTB,4 + LDI C,$60 ; TOGGLE M AND CL1 + EOR D,C + OUT PORTA,D + ANDI D,$7F ; DROP FLM + OUT PORTA,D + CBI PORTB,4 + STS LATCH10_SAV,D + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D + +; LDI D,1 ; TO CLOCK AT 5.5/2 MHZ + OUT OCR1AL,D ; TO CLOCK AT 7.3/2 MHZ + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + +;!!! LDI D,$7A ; WAIT FOR 32uSEC +; LDI D,58 ;$7A ; WAIT FOR 32uSEC GOOD + LDI D,60 ; WAIT FOR 32uSEC +; LDI D,61 ;$7A ; WAIT FOR 32uSEC +; LDI D,62 ;$7A ; WAIT FOR 32uSEC GOOD + +L050E: DEC D + BRNE L050E + + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + LDI D,$01 ; KILL CLR ON COMPARE MATCH + NOP ; !WITH OC1A LEFT IN LOW STATE + OUT TCCR1B,D + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0536 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + RJMP L0536 + +L0535: NOP ; EQUALIZE DELAYS + NOP + NOP + NOP +L0536: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VEEL + LDS D,VEEH + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + NOP + NOP + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,2 ; SET TIME FOR START OF LED PULSE + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_DELAY_0 ; 54uSEC + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,3 ; START TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + + RJMP T1_OVERFLOW_RET + +T0_OVERFLOW: + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + PUSH ZH + PUSH ZL + PUSH R0 + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_STATE + INC D + STS SCAN_STATE,D + DEC D + BREQ SCAN_START ; IF SCAN_STATE WAS = 0 + DEC D + BREQ SCAN_BEEPER ; IF SCAN_STATE WAS = 1 + ; IMPLEMENT ENTRY POINT FOR SCAN_PULSE_LED HERE + DEC D + RJEQ SCAN_PHOTO ; IF SCAN_STATE WAS = 2 + +T0_OVERFLOW_RET: + POP R0 + POP ZL + POP ZH + +T1_OVERFLOW_RET: + POP D ; RESTORE STATE OF THE WORLD + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +EXT_INT_RET: + OUT SREG,SR + RETI + +SCAN_START: + LDI D,3 ;5 + OUT TCCR0,D ; PRESCALE=CK/1024 + LDI D,-TK_DELAY_1 ;TK_DELAY_2 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + RJMP L0617_RESET + +SCAN_BEEPER: + LDS D,BUZZ_TIME + TST D + BREQ SCAN_PULSE_LED + LDS D,BUZZ_PERIOD + SUBI D,$10 + BRLO BUZZ_TOGGLE + STS BUZZ_PERIOD,D + RJMP SCAN_PULSE_LED +BUZZ_TOGGLE: ; ASSUME D = $F0 + PERIOD-1 + MOV C,D ; EG. C = $F3 FOR PERIOD = 4 + SWAP C ; EG. C = $3F FOR PERIOD = 4 + AND D,C ; EG. D = $33 FOR PERIOD = 4 + STS BUZZ_PERIOD,D + LDS C,LATCH12_SAV + SBRS C,3 ; TEST PREVIOUS SPEAKER STATE + RJMP BEEPER_SPKHI + LDS D,BUZZ_TIME + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP SCAN_PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP SCAN_PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +SCAN_PULSE_LED: + LDS D,LATCH5_SAV +;**: + SBRS D,7 ; ARE WE INSIDE SLEEP_LOOP? +;** SBRC D,7 + RJMP SCAN_PULSE_LED_OK ; YES, KEEP TIMER 0 TO RETAIN CONTROL + + LDI D,1<<7 + EOR FLAGS,D + BRPL SCAN_PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP T0_OVERFLOW_RET ; AND WASTE EVERY REMAINING CYCLE + +SCAN_PULSE_LED_OK: + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + + ;LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM ; R0 = LED DRIVE VALUE + LDI D,13*4 + CP SCAN,D + BRSH L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + RJMP T0_OVERFLOW_RET + +SCAN_PHOTO: + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + CLC + SBRC D,6 + RJMP L0593 ; ROW/COLUMN IS INACTIVE + + ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF + IN C,SREG + + LDI D,13*4 + CP SCAN,D + BRSH L05A8 + + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS ZL,ROW_BITMAP + LDS ZH,ROW_BITMAP+1 + ROL ZL + ROL ZH + STS ROW_BITMAP,ZL + STS ROW_BITMAP+1,ZH + RJMP L05F9 + +L05A8: ; WE HAVE A COLUMN STATUS +; LDS D,LATCH5_SAV +;;**: +; SBRS D,7 ; TURNED OFF? +;;** SBRC D,7 +; RJMP L05F9 ; YES, NO FURTHER PROCESSING + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRCS L05AB + RJMP L05F9 + +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 + +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS ZH,ROW_BITMAP+1 + LDS ZL,ROW_BITMAP + + LDS D,ROW_INDEX + TST D + BREQ ROW_BITMAP_LOOP + + MOV C,D +ROW_BITMAP_SKIP: + ROR ZH + ROR ZL + SUBI C,4 + BRNE ROW_BITMAP_SKIP + +ROW_BITMAP_LOOP: + SUBI D,-4 + ROR ZH + ROR ZL + BRCS FOUND_INTERSECTION +ROW_BITMAP_LOOPE: + CPI D,13*4 + BRLO ROW_BITMAP_LOOP + + ; NO FURTHER INTERSECTING ROWS FOUND + RJMP L05F9 + +FOUND_INTERSECTION: + ; FOUND AN INTERSECTING ROW FOR COLUMN + STS ROW_INDEX,D + + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + TST R0 + BRNE VALID_INTERSECTION + + ; INTERSECTION IS NULL, GO ON TO NEXT + LDS D,ROW_INDEX + CPI D,13*4 + BRSH L05F9 ; DONE LAST ROW, GO ON TO NEXT COLUMN +GO_L0617: + RJMP L0617 ; GO ON TO NEXT ROW, SAME COLUMN + +VALID_INTERSECTION: + ; INTERSECTION IS VALID, WE HAVE KEY MAKE + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,54 ;43 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + + MOV D,TX_COUNT + CPI D,TX_SIZE-1 + BRSH L05F9 + + PUSH A + MOV A,R0 + RCALL TX_CHAR + CPI A,$1B + BRNE TX_CONT + RCALL TX_CHAR +TX_CONT: + POP A + +L05F9: + LDI D,4 ; SCAN TO NEXT LED / PHOTODIODE PAIR + ADD SCAN,D + + LDS D,LATCH5_SAV + SBRC D,7 + RJMP TURNED_ON + + LDI D,3 + OUT TCCR0,D ; PRESCALE=CK/64 + LDI D,-TK_DELAY_1 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI C,13*4 + CP SCAN,C + BRLO GO_L0617 + + ; KEEP VDD ON, TO AVOID THE LONG TK_DELAY_2 + ;LDS D,LATCH5_SAV + ;ANDI D,$BF ; BIT 6 = 0 VDD OFF + ;STS LATCH5_SAV,D + ;PHOTO D ; READY TO SLEEP FOR ANOTHER 0.25 SEC + + LDI D,0 + OUT TCCR0,D ; STOP TIMER SINCE COMPLETE SCAN DONE + ;RJMP T0_OVERFLOW_RET + + ;LDI D,$05 + ;OUT UBRR,D + ;LDI D,$18 + ;OUT UCR,D + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + ;OUT UDR,C + ;OUT UDR,D + OR C,D ; HAVE WE SOME ACTIVITY? + + LDS D,TURNON_COUNT + CPI D,4 + BRSH TURNON_BREAK ; WAITING FOR BREAK + CPI D,1 + BRSH TURNON_MAKE ; WAITING FOR MAKE +GO_T0_OVERFLOW_RET: + RJMP T0_OVERFLOW_RET ; ALREADY HAD MAKE, NOT TURNED ON YET + +TURNON_BREAK: + TST C ; HAD SOME ACTIVITY? + BREQ TURNON_SAVE ; NO, COUNT DOWN TO BREAK + LDI D,4+1 ; YES, RESTART COUNTDOWN TO BREAK + RJMP TURNON_SAVE +TURNON_MAKE: + TST C ; HAD SOME ACTIVITY? + BRNE TURNON_SAVE ; YES, COUNT DOWN TO MAKE + LDI D,3+1 ; NO, RESTART COUNTDOWN TO MAKE +TURNON_SAVE: + DEC D ; COUNT DOWN TO MAKE OR BREAK + STS TURNON_COUNT,D + BRNE GO_T0_OVERFLOW_RET ; NOT READY TO TRY TURNON YET + + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + CBI DDRD,2 ; D2 = TRI-STATE, VSWT ON + RJMP GO_SLEEP_ENTRY ; WE WILL NOW WAIT FOR TURNON COMMAND + +TURNED_ON: + LDI D,0 ; STOP TIMER, WE WILL REGAIN + OUT TCCR0,D ; CONTROL VIA NEXT CLOCKING INTERRUPT + STS ROW_INDEX,D + + LDI C,50*4 + CP SCAN,C + BRLO L0617 + + LDS D,DEBOUNCE ; COMPLETED ENTIRE SCAN, START NEW SCAN + TST D + BREQ L0617_RESET + DEC D + STS DEBOUNCE,D + BRNE L0617_RESET + + LDS D,ACTIVE_ZONE + TST D + BREQ L0617_RESET + + MOV D,TX_COUNT + CPI D,TX_SIZE + BRSH L0617_RESET + + PUSH A + LDI A,0 + RCALL TX_CHAR + POP A + +L0617_RESET: + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + ;LDIZ SCAN_TBL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$80 ; BIT 7 = PRESERVED, LCD ON/OFF STATUS + ORI D,$40 ; BIT 6 = 1 VDD ON + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + RJMP T0_OVERFLOW_RET + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP CLEAR_DISPLAY_LOOP + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_XPAGE: + A14_A18 A + RET + +; HOW MANY SECS/6553600 PER 4HZ INTERRUPT ? +; EACH TIME THROUGH ADD 1638400 SECS/6553600 = 1/4 SEC +; OSCILLATOR IS SLOW SO WE WILL ADD 1 PART IN 10000 +; HENCE EACH TIME THROUGH ADD 1638400+164 = 1638564 UNITS TO COUNT + +TIM2_OVF: + IN SR,SREG + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +;!! LDI A,$10 ; DIAGNOSTIC +;!! STS BUZZ_TIME,A ; SHORT BEEP + + LDS D,TIME_HSEC_64K + SUBI D,LOW(-1638564) + STS TIME_HSEC_64K,D + + LDS D,TIME_HSEC_256 + SBCI D,HIGH(-1638564) + STS TIME_HSEC_256,D + + LDS D,TIME_HSEC + SBCI D,HIGH(-1638564>>8) + CPI D,100 + BRSH TIM2_CARRY + STS TIME_HSEC,D + +TIM2_END: + OUT SREG,SR + SBRS FLAGS,6 ; IF WE TURNED OFF VIA COMMAND, + RETI ; START A NEW SCAN, OTHERWISE DONE + + LDI D,0 + STS SCAN_STATE,D ; WE WILL EXECUTE SCAN_START ROUTINE + RJMP T0_OVERFLOW ; GO AND TURN VDD ON + +GO_TX_CHAR: + RJMP TX_CHAR + +TIM2_CARRY: + LDI D,0 + STS TIME_HSEC,D + + LDS D,TIME_SECOND + INC D + CPI D,60 + BRLO TIM2_SECOND + + LDS D,TIME_MINUTE + INC D + CPI D,60 + BRLO TIM2_MINUTE + + LDS D,TIME_HOUR + INC D + CPI D,24 + BRLO TIM2_HOUR + + PUSH ZL + PUSH ZH + PUSH R0 + LDI ZL,LOW(MONTH_TABLE*2-1) + LDI ZH,HIGH(MONTH_TABLE*2-1) + LDS E,DATE_MONTH + ADD ZL,E + LDI E,0 + ADC ZH,E + LPM + MOV E,R0 + CPI E,28 + BRNE FEBRUARY_OK + LDS E,DATE_YEAR + ANDI E,3 + LDI E,28 + BRNE FEBRUARY_OK + LDI E,29 +FEBRUARY_OK: + POP R0 + POP ZH + POP ZL + + LDS D,DATE_DAY + CP D,E + BRLO TIM2_DAY + + LDS D,DATE_MONTH + CPI D,12 + BRLO TIM2_MONTH + + LDS D,DATE_YEAR + INC D + STS DATE_YEAR,D + CLR D +TIM2_MONTH: + INC D + STS DATE_MONTH,D + CLR D +TIM2_DAY: + INC D + STS DATE_DAY,D + CLR D +TIM2_HOUR: + STS TIME_HOUR,D + CLR D +TIM2_MINUTE: + STS TIME_MINUTE,D + CLR D +TIM2_SECOND: + STS TIME_SECOND,D + +TIM2_SEND: + MOV D,TX_COUNT + CPI D,TX_SIZE-7 + BRSH TIM2_SEND_SKIP + + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'T' + RCALL TX_CHAR +; LDS A,VCCL +; RCALL TX_CHAR +; LDS A,VCCH +; RCALL TX_CHAR +; LDS A,VEEL +; RCALL TX_CHAR +; LDS A,VEEH +; RCALL TX_CHAR +; LDI A,$0D +; RCALL TX_CHAR + LDS A,TIME_HOUR + RCALL GO_TX_CHAR + LDS A,TIME_MINUTE + RCALL GO_TX_CHAR + LDS A,TIME_SECOND + RCALL GO_TX_CHAR + LDS A,DATE_MONTH + RCALL GO_TX_CHAR + LDS A,DATE_DAY + RCALL GO_TX_CHAR + LDS A,DATE_YEAR + RCALL GO_TX_CHAR + POP A + +TIM2_SEND_SKIP: + RJMP TIM2_END + +; ----------------------------------------------------------------------------- + +MONTH_TABLE: + .DB 31,28,31,30,31,30,31,31,30,31,30,31 + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: +.INCLUDE "CHSET00.INC" +CHSET00_END: + +; ----------------------------------------------------------------------------- + +GET_CLEAR_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL CLEAR_FRAME_RECT + RJMP MAIN_LOOP + +GET_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FRAME_RECT + RJMP MAIN_LOOP + +GET_CLEAR_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL CLEAR_HALFTONE_RECT + RJMP MAIN_LOOP + +GET_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL HALFTONE_RECT + RJMP MAIN_LOOP + +NO_GOX: RET + +CLEAR_FRAME_RECT: + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS F,RECTNC_YY + STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +FRAME_RECT: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GOX + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GOX + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CLEAR_HALFTONE_RECT: +; LDS F,RECTNC_X +; STS RECT_X,F +; LDS F,RECTNC_Y +; STS RECT_Y,F +; LDS F,RECTNC_XX +; STS RECT_XX,F +; LDS F,RECTNC_YY +; STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +HALFTONE_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LDI A,$55 + SBRS YH,0 + LDI A,$AA + MOV PATTERN,A + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP X03A3 +X039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +X03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ X03B0 + LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + TST XPIXEL + BREQ X03B0 +X03AD: LSR A + DEC XPIXEL + BRNE X03AD +X03B0: AND A,PATTERN + RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +X03B8: LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + BREQ X03D2 + AND A,PATTERN + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP X03B8 +X03C2: TST X_SIZE + BREQ X03D3 +X03C4: LSR A + DEC X_SIZE + BRNE X03C4 + COM A + TST XPIXEL + BREQ X03D2 + CLR B +X03CB: LSR A + ROR B + DEC XPIXEL + BRNE X03CB + AND A,PATTERN + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +X03D2: AND A,PATTERN + RCALL WR_DISP_MEM +X03D3: COM PATTERN + RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP X039A + RET + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/TSV4.HEX b/src/avr/TSV4.HEX new file mode 100644 index 00000000..4107a0d3 --- /dev/null +++ b/src/avr/TSV4.HEX @@ -0,0 +1,504 @@ +:020000020000FC +:100000000DC006C606C6189505C61895189518950C +:1000100002C602C61895EDC6D7C62EC702E00EBFAF +:100020000FE50DBF10E818B9A8951FE011BD00E05D +:1000300000935F01009360010093610100936201EE +:10004000009363010093640101E000936501009354 +:10005000660104E10093670108E002BD03E005BD0D +:1000600000E409BF00E00BBF08EB01BB02BB0FE1DE +:1000700007BB0FEF0ABB04BB00270BBB03E008BBA9 +:1000800000E105BBC29AC2980093190100E2B02EAC +:1000900017E119B910E91AB944245524222433244C +:1000A000EE246624CC2458E15BBBC49AC4985093D8 +:1000B000170155275093180150933B0150936A0143 +:1000C00050936B0150931001DD24D0921401D09213 +:1000D0001501D092160154EF509369015BBB50910A +:1000E000190155BBA89AC29AC298A898C29AC298F8 +:1000F0007894E2E0F9E1A2EEB0E0DBE1D0931A01FE +:1001000008D1D0E8C0ECDBBBC39AC398D0931801E8 +:10011000C5BBC89500240BBAC198C0980000C09A0E +:10012000C19AAA9541F03196C3951C2F1F7381F790 +:10013000C054D395E8CF10E3D9D2CF93DF93E4D264 +:10014000BF91AF915FD5212F1D2F129533D3121779 +:10015000B1F4119657D5212F1D2F2CD3121779F4F6 +:10016000119650D5212F1C2F129524D3121739F434 +:10017000119648D5212F1C2F1DD3121709F1E4EE3B +:10018000F9E1A6E6B3E0D9E1D0931A01C2D0D0E0FC +:10019000C0E4DBBBC39AC398D0931801C5BBC89514 +:1001A0000BBAC198C0980000C09AC19A119741F04B +:1001B0003196C3951C2F1F7389F7C054D395E9CF8F +:1001C00020E12093030120E42093040129E12093FE +:1001D0000501C0E0D0E218E118D520E82F93CF93B5 +:1001E000DF9320E211D5269622E00ED5DF91CF9144 +:1001F0002F91C05CDF4F2A9589F7B4D610E0109399 +:10020000110116E31093100110E01093680110E043 +:1002100010934C0110934D011EEF10930D011CEA39 +:1002200010930C0122E020D21C7F10930E0123E0DA +:100230001BD210930F0110910E0120910F011A3360 +:100240000DEF200720F01C3B0DEF200730F01DEFD5 +:1002500010930F0110E810930E011FEF19BD18E362 +:1002600018BD1CEF1DBD1EEC1CBD10E51FBD11E02F +:100270001EBD00E003BF05E008BF05E409BF0AE0BA +:1002800005BF00EC0ABF0BBF9EC202E00EBF0FE528 +:100290000DBF50E05FBD5EBD949A959850911701D7 +:1002A0005F7B5BBBC49AC4985093170154E7B6FEBA +:1002B00054E3509369015BBB5091190155BBA89A57 +:1002C000C29AC298A898C29AC29851E459BF50E005 +:1002D00053BF5BBF04E000936A0117E119B910E94D +:1002E0001AB94424552422243324EE246624CC2431 +:1002F000F89403B700230AE411F4809B0AE705BFD2 +:1003000078948895A89500916A01002389F7F8945C +:10031000A3CED0911A01C0911701C07EDC2BDBBBAC +:10032000C49AC498D0931701089578941FEDE122E0 +:1003300010E01EBB1FBBE2D21B3159F1B3FC0DC054 +:10034000103258F4183009F407C11D3009F41CC1EB +:100350001A3009F4C0C0173041F7B2FC18C010338E +:10036000B1F4C0910301D091040120910501CC5F4B +:10037000DD4FF894309117013227307E32273BBB96 +:10038000C49AC49878943093170193D5102DECD269 +:10039000CCCFB4D21B3109F31E3209F47CC11F3219 +:1003A00009F452C01F3309F491C1123409F45EC03C +:1003B000123609F45FC0133409F40BC1133609F483 +:1003C000C4CC143409F4F2C0153409F4DFC0163477 +:1003D00009F40FC1163609F4C4CC173409F4A1C0CE +:1003E000183409F4D6CC183609F4C7CC1B3409F4F8 +:1003F00096C01C3409F40AC41D3409F42EC01E34FE +:1004000009F403C1103509F49AC0123509F4E3C0A8 +:10041000133509F4D9C0143509F440C0153509F471 +:100420006BC2163519F410E2E12AFBC0173509F446 +:1004300063C2183509F4C4C11A3509F4EEC110338A +:1004400010F01A3310F171CF59D210FF03C014E02D +:10045000B12A6BCF1BEFB12268CF50D2103329F4F1 +:10046000F89400E4B02A8A9A10CF5FCF47D21F9346 +:1004700010E004C043D21F9341D21F7010931101AA +:100480001F911093100151CF39D230D1C0E1C093E8 +:100490000301D09304012093050147CF10E015BD5F +:1004A00010935F01109360011093610127D21093A4 +:1004B000640124D21093630121D2109362011ED2F1 +:1004C000109366011BD21093650118D21093670137 +:1004D00013E015BD2ACF01D028CF0F92C0910301A0 +:1004E000D091040120910501DE5FC395F89430910D +:1004F00017013227307E32273BBBC49AC4987894C8 +:1005000030931701D6D4182F100D100D1A951038EE +:1005100018F0C0D00F900895800D0F90089522D547 +:1005200004CFECD1103309F404C0113309F404C032 +:10053000FCCE07EFB022F9CE08E0B02AF6CEDED12D +:10054000103309F403C0113309F403C00FEEB022D5 +:10055000ECCE00E1B02AE9CEC0910301D0910401B4 +:1005600020910501DE5FF894309117013227307E2B +:1005700032273BBBC49AC49878943093170199D41E +:1005800070191FB712FFD1CE7727CFCEB7D111FD8B +:1005900007C010FD03C00FEDB022C7CE00E2B02AA5 +:1005A000002700933B01EAD2F1F7BFCEA7D1103369 +:1005B00009F404C0113309F404C0B7CE0EEFB02221 +:1005C000B4CE01E0B02AB1CE99D1712F97D1812F4D +:1005D000ACCE02E0B02A70935201809353018ED1C9 +:1005E000109354018BD11093550117D30DEFB02206 +:1005F0009CCE709356018093570180D1109358017F +:100600007DD1109359015ED390CE709356018093A3 +:10061000570174D11093580171D11093590177D3B8 +:1006200084CE6CD110FF0BC010910E0120910F01F0 +:100630001C5F2F4F1C3B0DEF2007A8F40AC0109140 +:100640000E0120910F01145020401A330DEF2007A6 +:1006500050F010930E0120930F0122E00DD0109165 +:100660000F0123E009D061CEE199FECF2EBB2227F6 +:100670002FBBE09A1DB30895E199FECFE5FEFFCFB1 +:100680002EBB22272FBB1DBBF894E5FEFFCFE29ABD +:10069000E19A189536C732D129D030D1A12F2ED169 +:1006A000B12F2CD1F894309117013227307E3227A8 +:1006B0003BBBC49AC498789430931701A4D2219676 +:1006C00011971A2F1B2B09F0ECCF2FCE17D10ED07C +:1006D0001F931AD01BE133D11FE331D11F91105D5D +:1006E0002ED11D2F60D01C2F5ED01FCEC0E0D0E0D9 +:1006F00024E61F701A3008F4210F2695D795269509 +:10070000D795D695D6950895A6E1B2E0AC0FBD1F5A +:10071000F894309117013227307E32273BBBC49AC0 +:10072000C4987894309317016DD2E12F11966AD254 +:10073000F12FAC2FBD2F1496CFEFDFEF3197FF7065 +:10074000349780F131965ED2119601E220E1D127F3 +:10075000CC0FDD1F10F4C027D227CC0FDD1F10F403 +:10076000C027D227CC0FDD1F10F4C027D227CC0F13 +:10077000DD1F10F4C027D227CC0FDD1F10F4C027D7 +:10078000D227CC0FDD1F10F4C027D227CC0FDD1FDE +:1007900010F4C027D227CC0FDD1F10F4C027D227BA +:1007A000319789F608951F93129504D0C8D01F91F0 +:1007B00001D0C5C01F7010631A3308F0195F089587 +:1007C0009DD010FD13C070936C0180936D01B092A9 +:1007D0006E011091030110936F01109104011093A9 +:1007E000700110910501109371019FCD70916C0102 +:1007F00080916D0110ECB12210916E011F73B12A2E +:1008000010916F0110930301109170011093040176 +:10081000109171011093050188CD70D010935A0189 +:100820006DD0C12F175F5DD020935B0167D0D12FB2 +:100830001C5F5CD020935C0161D01C0F1F5051D015 +:1008400020935D015BD01D0F115150D020935E01AC +:10085000D0915C0110915E011D1B08F441C0C09154 +:100860005B011C2F1D0F2D2F220F220F220F120FA5 +:10087000220F120FA0E0B0EE20E0A10FB21F2BE17B +:10088000F894309117013227307E32273BBBC49A4F +:10089000C49878943093170110915D011C1BF0F0FF +:1008A0003A2F3F7335BB3B2F330F330FA7FB31F983 +:1008B000A6FB30F93BBBF894C39AC3987894309365 +:1008C000180110915A011BBBF894C198C098000000 +:1008D000C09A7894C19A1196C395DECFD395BACFBA +:1008E00024CD2FEF23951A50E8F708952FEF239585 +:1008F0001D50E8F7089502D001D017CD10EC1093E9 +:100900006B01A89510E01EBB1FBB10EC80991093E3 +:100910006B01B5FC33D13320A1F310E010936B01D0 +:10092000CF93DF93C22DC058DD271881F8943A94F5 +:100930002394CFE72C227894DF91CF9108951F93D1 +:10094000A895152D1032E0F71F91CF93DF93DFB7F5 +:10095000F894C52DC40DDFBFCF71C05ADD271883B1 +:100960005394DF91CF910895D2D0EFD00027009318 +:100970001201B4FC0FC0C0910301D0910401DE5FED +:10098000F02C97D20F920F1808F4002406940092CE +:1009900012010F90B3FC08C0072F000D28F4772731 +:1009A0009CDD10910501B9D600911201070F00934B +:1009B0004E0180934F01700D60914E0190904F0158 +:1009C00086FE07C0C0915001D0915101229771D28B +:1009D000900C87FE07C0C0915001D0915101239720 +:1009E00068D2600D5AD260930201A0920001C091BA +:1009F0005001D091510121965CD2702C0FEF0ABBAF +:100A0000C09A0FE18022809201010027801201C06C +:100A10007DC0AA27B92DB695A795B695A795B05EC6 +:100A200007C09394A05CBF4F80900101A09000018B +:100A3000AA2A22272196109105016FD63AD21127B2 +:100A400060910201662339F08894079417956A959E +:100A5000E1F7022A212F08E1F8943091170130279D +:100A6000307E30273BBBC49AC498789430931701EA +:100A70003A2D3F7335BB3B2F330F330FA7FA31F9B4 +:100A8000A6FA30F93BBBF894C39AC3987894309394 +:100A9000180100270ABBF894C0980000C19809B358 +:100AA0000026B0FC002A0FEF0ABB0BBA0000C09A68 +:100AB0007894C19AA3948A9409F0BCCF222311F1AF +:100AC0003A2D3F7335BB3B2F330F330FA7FA31F964 +:100AD000A6FA30F93BBBF894C39AC3987894309344 +:100AE000180100270ABBF894C0980000C19809B308 +:100AF0002027B0FC202B0FEF0ABB2BBB0000C09AB5 +:100B00007894C19A31D07A9409F08BCF0895C12F8F +:100B1000DD27CC0FDD1F10910301C10F10910401DF +:100B2000D11F10910501F9D5C4D12196F02CC1D166 +:100B3000CF2DD02D10910301C10F10910401D11FB1 +:100B4000C0935001D09351010895C0915001D091AC +:100B50005101AFD1802C219785FCABC1C09103011D +:100B6000D0910401DE5FA5C1CF93DF93192D39D059 +:100B70001881122B1883DF91CF9108952F93CF9373 +:100B8000DF9310913B012DD01881122309F41FC06F +:100B900028812127288310E010936B01AF93BF9326 +:100BA000CC27D0913B01D695C795D695C795AC2F4C +:100BB000BD2FB05E18E1B1D520E26CD51297269614 +:100BC00022E068D5BF91AF9110EC10936B011091AA +:100BD0003B0113951F7710933B01DF91CF912F912C +:100BE0000895CCE3D1E01F77212F269526952695F1 +:100BF000C20F20E0D21F21E0177019F0220F1A95C2 +:100C0000E9F7089554C56FC54CC587C597C48DCB0A +:100C1000DFC1DFC18FC5E6C1C6C278949090530191 +:100C2000609152013AD160930201A092000170904C +:100C30005501CC27D92DD695C795D695C795D05EA9 +:100C400018E16BD507C0C05CDF4F9394609102013F +:100C5000A0900001AC2A1FEF8090540100E08016A4 +:100C600041F008E08016B8F0662319F016956A95F1 +:100C7000E9F73BD108E010910201011B801AA3940F +:100C80001FEF08E0801638F0B1F02FD11FEF08E019 +:100C9000801AA394F6CF882079F016958A94E9F704 +:100CA0001095662341F02227169527956A95E1F75E +:100CB0001CD1A394122F19D157DF7A9400277012F8 +:100CC000C2CF0895009158010A950230D0F30091E7 +:100CD00059010330B0F3009156010395009352017E +:100CE0000091570100935301809058018A948A948F +:100CF0008092540101E0009355018FDF009156016D +:100D00000093520180905801809254013AC00091A2 +:100D100058010A950230A8F200915901033088F277 +:100D200000915601039500935201009157010093E1 +:100D30005301809058018A948A948092540101E072 +:100D4000009355016ADF0091560100935201009112 +:100D50005701039500935301709059017A947A9446 +:100D60007092550101E00093540157DF80905801C3 +:100D700000915601080D0A950093520101E000937D +:100D8000540100915701039500935301709059014C +:100D90007A947A947092550140DF00915601039540 +:100DA00000935201809058018A948A948092540151 +:100DB0007090590100915701070D0A950093530156 +:100DC00001E00093550129CF1FB60F930FEDC02E00 +:100DD000EF93FF93E42DE05AFF270081FF91EF91FD +:100DE0000CB95A9443940FE140226A940AF04CC023 +:100DF00051C01FB60F930FEDC02E0CB15C993EC0D1 +:100E0000E7FC2CC0E6FC0EC0023031F400E009B96A +:100E1000539A00E4E02A3EC00A3A19F400E0009335 +:100E20006A0138C0602E00E803190AF40FE7662053 +:100E300012F4052D00680CB9061508F4602E062D75 +:100E40000F7739F000ECE02A6A9422F55798559A0A +:100E500021C00FEBE022569A5E9A1CC0EF93FF93DD +:100E6000E32DE20DEF77E058FF270083FF91EF912C +:100E700033946A947AF40CC01FB60F93539807E129 +:100E800009B90FEBE022CC2455985698579A0CB12B +:100E90000FE7E0220F911FBE1895AA2400EFA01AB9 +:100EA00067FFAA246F77685014F0A394FCCF685FA3 +:100EB00008953C2F3F7335BB3D2F330F330FC7FBD6 +:100EC00031F9C6FB30F93BBBF894C39AC3987894C8 +:100ED0003093180100270ABBF894C0980000C09A0C +:100EE00009B278940FEF0ABB08953A2D3F7335BBD2 +:100EF0003D2F330F330FA7FA31F9A6FA30F93BBB78 +:100F0000F894C39AC39878943093180100270ABBC9 +:100F1000F894C0980000C09AF9B278940FEF0ABB19 +:100F2000B1FE03C01095F12203C0F126B0FCF12AF6 +:100F30003A2D3F7335BB3D2F330F330FA7FA31F9ED +:100F4000A6FA30F93BBBF894C39AC39878943093CF +:100F50001801FBBAF894C198C0980000C09A789420 +:100F6000C19A0895772788279924C0E0D0E218E134 +:100F7000D4D3AA24A0920001109100011C2B312F80 +:100F80003F7335BB3D2F330F330F17FB31F916FB82 +:100F900030F93BBBF894C39AC39878943093180106 +:100FA00000E00BBBF894C198C0980000C09A7894F8 +:100FB000C19AA39400E2A01619F0A0920001DCCF20 +:100FC000D3DD9394C05CDF4FD03409F0D2CF0895C5 +:100FD00018951FB68B9A4CB55DB550930901409397 +:100FE000080114C11FB65AB35F935BB35F9355B347 +:100FF0005F93509118015F935FEF5ABB50E75FBD5D +:101000004CB55DB5485F5F4F5BBD4ABD59BD48BD3E +:1010100040914C0150914D015170452B49F4509134 +:101020006B01539550936B0151F45FEBB5222DC9C1 +:1010300000000000000000000000000000008B9A8B +:10104000939A55275EBD5DBD5CBD50914D01542BFB +:1010500071F0509117015BBBC49ADD9ADD98C4987A +:101060000000000000000000000000000EC05091D1 +:101070001701506850625BBBC49A40E654275BBBC3 +:101080005F775BBBC49850931701509117015F9332 +:10109000EF93FF93E0914C01F0914D01E05CFF4F25 +:1010A000FF713F933E2F3F7335BB3F2F330F330FFD +:1010B000E7FB31F9E6FB30F93BBBC39AC398F093E9 +:1010C000180130911701F7FB31F9F6FB30F93BBB02 +:1010D000C49AC498309317013F91C198C19A9798C8 +:1010E00044274ABB40EC44BBC09855275BBD5ABD62 +:1010F00059E05EBDE0934C01F0934D01FF91EF91FB +:101100005CE35A95F1F7C09A5FEF5ABB979A54BBCC +:101110008D98959851E000005EBD5BE05A95F1F71F +:1011200050910D0140910C018D9A859907C04A3369 +:101130009DEF590752F0415050400BC0453D9FEF85 +:1011400059071AF44F5F5F4F04C000000000000011 +:10115000000050930D0140930C015BBD4ABD4091CE +:101160000C0150910D0190910E01491B90910F01BE +:10117000590B1AF445ED5FEF04C04CEA5EEF000036 +:10118000000059BD48BD52E053BF5DEE52BF51E073 +:10119000509368015DEF5DBD54E35CBD8B989398FF +:1011A00050EE5FBD21C01FB65AB35F935BB35F9330 +:1011B00055B35F93509118015F93509117015F935E +:1011C000FF93EF930F925FEF5ABB509168015395D5 +:1011D000509368015A95E1F05A9511F15A9509F426 +:1011E00089C00F90EF91FF915F915BBBC49AC49847 +:1011F000509317015F915BBBC39AC398509318013A +:101200005F9155BB5F915BBB5F915ABB1FBE189549 +:1012100053E053BF50EF52BF51E05093680153C1A8 +:1012200050911001552399F150911101505118F02E +:10123000509311012CC0452F429554235093110116 +:101240004091190143FF10C0509110015A955093DD +:101250001001A1F050911901577F546055BBC29AFB +:10126000C2985093190113C05091190158605B7FC7 +:1012700055BBC29AC2985093190109C050911901E7 +:10128000577F5B7F55BBC29AC2985093190150910A +:10129000690157FF06C050E8B5261AF4552753BF19 +:1012A000A0CF52E053BF52EF52BFEAE3F8E1552717 +:1012B000ED0DF51FC89554E3D51648F4509119016A +:1012C0005F7E55BBC29AC2985093190108C05091D5 +:1012D0001901506155BBC29AC298509319010BBABB +:1012E0000090190105BAA99AC29AC298A998C29AFF +:1012F000C29877CF50B340EE4BBB4091190145BB2C +:10130000A99AC29AC298A998C29AC298889456FD7E +:1013100008C050911301552319F054E05093130164 +:1013200008944FB754E3D51660F44FBFE091150110 +:10133000F0911601EE1FFF1FE0931501F0931601C7 +:101340007BC04FBF08F078C050911301552321F0A6 +:1013500054E05093130170C0F0911601E091150113 +:1013600050911401552329F0452FF795E7954450E6 +:10137000E1F75C5FF795E79518F05433D0F35CC064 +:101380005093140144E3451BECE3F8E15527E40FC7 +:10139000F51FC895402D000C000C000C400D000CF2 +:1013A000400DECE3F8E15527ED0DF51FC895400D14 +:1013B000E0E0F0EE5527E40FF51F3F933E2F3F731B +:1013C00035BB3F2F330F330FE7FB31F9E6FB30F925 +:1013D0003BBBC39AC398F093180130911701F7FBF8 +:1013E00031F9F6FB30F93BBBC49AC498309317012E +:1013F0003F910F9300270ABBC0980000C09A09B222 +:101400000FEF0ABB0F91002029F4509114015433BF +:1014100098F45EC054E0509313010092070156E324 +:1014200050931001552D5F3138F41F93102D8DDA34 +:101430001B3109F48ADA1F9154E0D50E50916901ED +:1014400057FD27C053E053BF50EF52BF51E05093B8 +:10145000680144E3D416E8F250E053BF50911601FE +:1014600040911501452B50916A01543018F45130C8 +:1014700028F4B7CE442329F055E003C0442309F4EF +:1014800054E05A9550936A01A1F75FEBB5228A9810 +:10149000CECD50E053BF5093140148ECD416C0F0A9 +:1014A00050911301552379F05A955093130159F433 +:1014B00050910701552339F0552D503220F41F93D8 +:1014C00010E043DA1F91DD24D0921501D09216016D +:1014D000EAE3F8E131965527ED0DF51FC8955091D7 +:1014E0006901507850645029509369015BBB509159 +:1014F000190155BBA89AC29AC298A898C29AC298D4 +:1015000070CE9924C0E0D0E2A0E0B0E218E105D1AD +:10151000A05CBF4F0A94E1F720E22F93C8D0E3D03C +:10152000A395C3952F912A9509F0F7CF1DDB9394CE +:10153000A0969096B03409F0EFCF1BCDDFD91F9362 +:10154000DDD910937201DAD916951695169509F41E +:1015500010E210937501D2D910937601172F1695CA +:1015600016951695109373018093740118E1D5D0E8 +:101570001F9110FD46C0CC27D09174019D2ED695A9 +:10158000C795D695C79510917301C10FD05E209174 +:10159000760110917201121720F5211BAA27B09134 +:1015A0007401B10FB695A795B695A79510917301E3 +:1015B000A10FB05E2F93AF93BF93CF93DF93209192 +:1015C000750168D0D1DADF91CF91BF91AF912F91A2 +:1015D0009394A05CBF4FC05CDF4F2A9559F72091D0 +:1015E00072012F93CF93DF93209175015AD0BCDA0B +:1015F000DF91CF912F919394C05CDF4F2A9589F7AB +:1016000006CBCC27D091740100917601D00F9D2E8E +:10161000D695C795D695C79510917301C10FD05E29 +:10162000202F10917201121728F5211BAA27B091C3 +:101630007401B00FB11BB695A795B695A7951091FB +:101640007301A10FB05E9A94A054B040C054D04032 +:101650002F93AF93BF93CF93DF93209175011AD04F +:1016600083DADF91CF91BF91AF912F912A9559F7EE +:10167000209172019A94C054D0402F93CF93DF935E +:10168000209175010ED070DADF91CF912F912A95BC +:1016900089F7BDCA0CD0119626D021962A95D1F78C +:1016A000089510E020D021962A95E1F708953A2F69 +:1016B0003F7335BB3B2F330F330FA7FB31F9A6FB2D +:1016C00030F93BBBF894C39AC398789430931801CF +:1016D00000270ABBF894C0980000C09A19B3789408 +:1016E0000FEF0ABB08953C2F3F7335BB3D2F330FDF +:1016F000330FC7FB31F9C6FB30F93BBBF894C39AF3 +:10170000C3987894309318011BBBF894C198C09883 +:101710000000C09A7894C19A0895F8943091170106 +:101720003127307E31273BBBC49AC49878943093DC +:10173000170108951FB650915F015C5550935F01EA +:10174000509160015F4F5093600150916101564E7E +:10175000543650F4509361011FBEB6FE189550E008 +:101760005093680120CDF1C850E050936101509131 +:10177000620153955C33E8F15091630153955C33FA +:10178000A8F1509164015395583168F1EF93FF939C +:101790000F92EDE2F8E190916601E90F90E0F91FF8 +:1017A000C895902D9C3131F49091670193709CE124 +:1017B00009F49DE10F90FF91EF9150916501591748 +:1017C00070F0509166015C3030F050916701539594 +:1017D00050936701552753955093660155275395AC +:1017E0005093650155275093640155275093630129 +:1017F000552750936201552D5931C0F41F931BE1B9 +:10180000A4D814E5A2D810916401ADDF1091630152 +:10181000AADF10916201A7DF10916601A4DF109189 +:101820006501A1DF109167019EDF1F9195CF1F1CFD +:101830001F1E1F1E1F1F1E1F1E1FF0340000E83436 +:101840000100F0330100E8330200E4330300E83222 +:101850000300E4320400E2320500E4310500E23125 +:101860000600E1310700E2300700E1300800C12A3C +:101870000000C22A0100C12B0100C22B0200C42BB0 +:101880000300C22C0300C42C0400C82C0500C4189B +:101890000500C8180600D0180700C8190700D0199D +:1018A0000800A1190900D01A0900A11A0A00A21AF9 +:1018B0000B00A11B0B00A21B0C00A41B0D00A21C03 +:1018C0000D00A41C0E00A81C0F00A41D0F00A81DD5 +:1018D0001000B01D1100A81E1100B01E1200611EE4 +:1018E0001300B01F1300611F1400621F1500612850 +:1018F0001500622816006428170062291700642961 +:1019000018000000000000000000000000000000BF +:1019100000000000000000000808080000000000AF +:1019200000000000000000000000000000000000B7 +:10193000000000007E00310032003300340035002A +:10194000360037003800390030002D003D0000001F +:101950000000000000000000000000000000000087 +:1019600000000000000051005700450052005400E4 +:101970005900550049004F0050005B005D005C00BD +:101980000000000000000000000000000000000057 +:101990000000000000000000410053004400460029 +:1019A000470048004A004B004C003B0027000D0D4B +:1019B0000D0000000000000000000000000000001A +:1019C0000000000000000000000000005A00580065 +:1019D0004300560042004E004D002C002E002F0008 +:1019E0000000000046323444303331393033313274 +:1019F000313730394C034C034C034C034C034C033C +:101A00004C034C034C034C034C034C034C034C035E +:101A10004C034C034C034C034C034C034C034C034E +:101A20004C034C034C034C034C034C034C034C033E +:101A30004C034C0300014C034C034C034C034C037C +:101A40004C034C034C034C034C034C034C03030169 +:101A50004C034C0306010F01180121012A01330137 +:101A60003C0145014E0157014C034C034C034C0310 +:101A70004C034C034C036001690172017B0184013A +:101A80008D0196019F01A901B201BB01C401CD01E5 +:101A9000D601DF01E801F101080211021A02230256 +:101AA0002C0235023E02470250024C034C034C0309 +:101AB0004C034C034C03590262026B0274027D0218 +:101AC00086028F029902A302AD02B802C202CB02C3 +:101AD000D402DD02E602F002FC0203030C0315034C +:101AE0001E0327033003390343034C034C034C0309 +:101AF0004C034C030003066101F80107708898A8A5 +:101B0000C88870010720602020202070010770889D +:101B100008102040F80107F810201008887001070D +:101B200010305090F810100107F880F00808887005 +:101B30000107304080F08888700107F808102040C5 +:101B40004040010770888870888870010770888815 +:101B500078081060010770888888F888880107F085 +:101B60008888F08888F001077088808080887001FC +:101B700007E09088888890E00107F88080F08080F6 +:101B8000F80107F88080F08080800107708880B8B5 +:101B90008888780107888888F888888802210780E3 +:101BA000808080808080010708080808088870010C +:101BB000078890A0C0A090880107808080808080E6 +:101BC000F8010788D8A8A888888801078888C8A845 +:101BD0009888880107708888888888700107F0884D +:101BE00088F0808080010770888888A890684C03FE +:101BF0004C034C03060801014F0065030107F08800 +:101C000088F0A090880107708880700888700107AC +:101C1000F820202020202001078888888888887064 +:101C20000107888888888850200107888888A8A8A4 +:101C3000A850010788885020508888010788888824 +:101C4000502020200107F80810204080F8010700EC +:101C500000700878887801078080F0888888F00113 +:101C600007000078808080780107080878888888D5 +:101C700078010700007088F8807001071820F820AC +:101C800020202001080000788888780870010780EB +:101C900080B0C8888888022107800080808080808A +:101CA0000521081000101010109060052107808099 +:101CB00090A0C0A090032107C04040404040400198 +:101CC000070000F0A8A8A8A801070000B0C88888ED +:101CD0008801070000708888887001080000F0887B +:101CE00088F080800108000078888878080802055C +:101CF0006105B0C08080800107000078807008F026 +:101D000001072020F820202018010700008888887B +:101D10009868010700008888885020010700008823 +:101D200088A8A850010700008850205088010800AA +:101D30000088888878087001070000F8102040F8B3 +:101D40000107F8F8F8F8F8F8F80070935601809356 +:101D50005701D4D510935801D1D51093590126D0ED +:101D6000E4C27093560180935701C8D5109358016F +:101D7000C5D5109359012FD0D8C2709352018093CA +:101D80005301BCD510935401B9D51093550178D0A7 +:101D9000CCC27093520180935301B0D5109354017B +:101DA000ADD51093550171D0C0C208950091560170 +:101DB0000093520100915701009353010091580183 +:101DC00000935401009159010093550102E0B02A9B +:101DD00024D70DEFB022009158010A95023028F364 +:101DE00000915901033008F300915601009352010C +:101DF0000091570100935301009158010093540141 +:101E000001E00093550109D700915601009352015A +:101E1000009157010395009353010091590102501D +:101E20000093550101E000935401F7D680905801CA +:101E300000915601080D0A950093520101E00093AC +:101E400054010091570103950093530100915901EA +:101E5000025000935501E1D60091560100935201C2 +:101E6000009158010093540170905901009157015D +:101E7000070D0A950093530101E000935501CDC66B +:101E800002E0B02ACAD60DEFB022789490905301A8 +:101E90006091520102D860930201A09200017090FB +:101EA0005501CC27D92D15E5D0FF1AEA012ED6957C +:101EB000C795D695C795D05E18E12FDC07C0C05CEA +:101EC000DF4F939460910201A0900001AC2A1FEFB4 +:101ED0008090540100E0801641F008E08016C8F0C0 +:101EE000662319F016956A95E9F71021FED708E0E8 +:101EF00010910201011B801AA3941FEF08E08016C5 +:101F000040F0C1F01021F1D71FEF08E0801AA39430 +:101F1000F5CF882089F016958A94E9F71095662305 +:101F200049F02227169527956A95E1F71021DDD70C +:101F3000A394122F1021D9D7009416D67A94002793 +:061F40007012BDCF0895F0 +:0220000002419B +:00000001FF diff --git a/src/avr/WPO15V1.HEX b/src/avr/WPO15V1.HEX new file mode 100644 index 00000000..4f579fba --- /dev/null +++ b/src/avr/WPO15V1.HEX @@ -0,0 +1,132 @@ +:020000020000FC +:020000000EC030 +:06001200DCC1A3C270C1B5 +:10001C0064C302E00EBF0FE50DBF00E808B9A89558 +:10002C000FE001BD0AE50093CC0000E00DB90AB960 +:10003C000FEF04BBC79ABE9AD79A8E9A929A939A4C +:10004C00959A8D9ADE98D69897988F9A94988C9AC0 +:10005C00C398BB9A9198899A07E00DD106E00BD111 +:10006C0005E009D104E007D101E005D100E003D19E +:10007C000FE509B908E10AB92AD10AEA0CB90CB999 +:10008C0029D1949A27D1949825D1949A0027E0E607 +:10009C00FF27019301930193EFEB019301930193DC +:1000AC00019301930193019301930093BC0000937E +:1000BC00CA000093BD000093BE0000E4008300E082 +:1000CC000093C80004E00093C9004427662711245C +:1000DC0088249924AA2455246624772402E00093CA +:1000EC00B70001E00093B3000093B4000093B50097 +:1000FC000093B6000093B8000093B9000093CB00B6 +:10010C0000E00093BA000093BB0000EF202E00EF3C +:10011C00402E02E003BF01E009BF0EB10FB108EEA3 +:10012C000DB900E00DBD0CBD0BBD0ABD01EC0FBD42 +:10013C0001E00EBD05E007B90EED06B9789402E0BA +:10014C001EE1E2E6F7E0A8D00091CC000A3509F0F8 +:10015C0066C041FD6FC043FD7AC040FFF5CF0091F2 +:10016C00CB00033041F0023091F002E01FE0EEE9E9 +:10017C00F7E092D006C002E01FE0EEEDF7E08CD085 +:10018C0000C003E01EE1E0E8F7E086D00FC002E01B +:10019C001CE0EEEAF7E080D003E01EE1E2E6F7E0D7 +:1001AC007BD003E01CE0EEEAF7E076D01CD00B31FC +:1001BC0009F0FCCF18D0043409F0F8CF14D0037038 +:1001CC0039F0013039F0023039F0033039F0EECF2C +:1001DC00969A05C0969803C0DF9A01C0DF9810E389 +:1001EC00100FE4CF78940091CC000A35C1F441FD96 +:1001FC0021C043FD2CC0F8949920A1F30091B300C9 +:10020C00093081F7EF93FF93E82DED59FF2700811B +:10021C009A948394EFE38E22FF91EF91189502E06C +:10022C001EE1E2E6F7E038D002E01FE0EEEEF7E088 +:10023C0033D00AC002E01EE1E2E6F7E02DD002E086 +:10024C001FE0EAEBF7E028D043FD01C0FDCF02E050 +:10025C001EE1E2E6F7E020D002E01FE0EAECF7E076 +:10026C001BD00AEF37D00A95E9F702E013E0EAED6C +:10027C00F7E012D0F6CFC39802FF919802FD919A45 +:10028C0029D001FF919801FD919A26D000FF9198F9 +:10029C0000FD919AC39A22C078940000F894AA2089 +:1002AC00D9F70093B400C895002D04D031961A9557 +:1002BC00D1F71895EF93FF93E92DEA0DE80DEF7345 +:1002CC00ED59FF270083FF91EF91A3940895E0EF80 +:1002DC00FAE006C0E8EC03C0E4E101C0E2E0F0E0C3 +:1002EC0020E02A95F1F73197E1F70895FFB666FD06 +:1002FC0022C03CB13125F2F0312552F0EF93FF933F +:10030C00EEEBF091B300EF0FFF273083FF91EF91ED +:10031C00131608F0132E6F7E6064312D3F7741F079 +:10032C0011202AF157986F7D3FEF232E606146C054 +:10033C0038EF40C03EC03091B600313019F031E09A +:10034C003093BB003CB1EF93FF93E62DE70DE50D29 +:10035C00EF70ED55FF273083E091B500F091B600BA +:10036C00EF1711F4639401C07394FF91EF913FEF79 +:10037C00232E1A940AF530EF232E60611FC0EF93E1 +:10038C00FF93EEEBF091B300EF0FFF2730813A951E +:10039C003083E82DED59FF273081FF91EF913CB967 +:1003AC003FEF232E9A9483943FE383221A9431F4E3 +:1003BC0003C030EF232E6F7E57986F79FFBE1895D0 +:1003CC00FFB63091BD007091BE00732B49F03150D7 +:1003DC003093BD003091BE0030403093BE0091F0A0 +:1003EC00442051F0439441F430E03DB93EB13FB16B +:1003FC0038EE3DB9D69A687F222011F02394B9F0DB +:10040C00FFBE189506CE67FD18C0890C3FE383220A +:10041C0099249092BA00EF93FF93EEEBF091B30016 +:10042C00EF0FFF2730E43083FF91EF9106C065FD9D +:10043C00EACF66FDA4CF64FD7AC038EF232E30914D +:10044C00BC00332359F03A953093BC0031F0C3987B +:10045C009198899A30E03AB9B1CFDBCD57983FE506 +:10046C0039B93091BA0039293A2939F43091B800A8 +:10047C003A9549F03093B80037C03091B9003A95AD +:10048C0091F03093B90030E13093B800992030915D +:10049C00B30041F4AA2041F09A2CAA243091B40064 +:1004AC003093B300393001F16F779920B9F4AA2059 +:1004BC0059F43091BA003A9542F43091B300339527 +:1004CC00393048F031E007C031E03093BA009A2C53 +:1004DC00AA243091B4003093B30025C031E030939E +:1004EC00BA003091B3001FC030E13093B90060689E +:1004FC003091BB00332331F03A953093BB003091EF +:10050C00B60011C03091B600772069F47091B70035 +:10051C003093B700372F313021F03395393008F054 +:10052C0032E03093B6003CB960616F7947CF30EF61 +:10053C00232E33E039B9392D67FF04C030E1361969 +:10054C00371930683CB9132E579A3CB1606236CFDC +:10055C00FFB6D6983FB162FD8EC060FD5EC061FDF6 +:10056C0057C03A3090F1303899F0313899F0313930 +:10057C00A1F0323991F0333981F0353A99F03A3AA9 +:10058C00E1F0353CD9F030E03DB944244260A3C0E1 +:10059C0097989FC04160979A9CC030593093CB007C +:1005AC00416097C03FEF3093BC0030E03DB9949868 +:1005BC003FEF70E07BBD3ABD8CC02BCD38EE309355 +:1005CC00BD0033E03093BE0084C0332379F46860FF +:1005DC00662049F47720C1F0672C77243090B60060 +:1005EC003092B50012C03090B5000FC0677F332E2B +:1005FC00AA2021F03091B400331531F431E030935E +:10060C00BA003092B40001C033243FB8626061C0BC +:10061C006D7F332009F061605CC0332E6E7F332018 +:10062C0063FF05C05AF5362D30681FC051C0F2F378 +:10063C00EF93FF93EEEBF091B400EF0FFF273081B7 +:10064C00E091B300F091B400EF1731F0E0E4E91958 +:10065C003E1730F03E2F04C0303408F030E4391926 +:10066C003A19FF91EF910AF43FE7331508F4332E52 +:10067C003FB964602EC033208AF43A944AF5616025 +:10068C00EF93FF93E52DED55FF2730813FB9FF9197 +:10069C00EF916A9453943FE053221BC060FF14C047 +:1006AC00EF93FF93E92DEA0DE80DEF73ED59FF275A +:1006BC003083E091B300F091B400EF1711F49394F0 +:1006CC0001C0A394FF91EF913A9412F0616001C0C4 +:1006DC006B7F30EF432EFFBE1895FFB6A89534B153 +:1006EC00532F35B1379557953795579544FD12C013 +:1006FC0040613091BC00332331F530E070E05C5147 +:10070C0000F130E670E05038E0F45695352F5695F0 +:10071C00350F17C04F7E5093CA00583A30E074E042 +:10072C0058F43091C8007091C9003150704021F4D8 +:10073C0030E03DB9442448603093C8007093C90040 +:10074C0002C07BBD3ABD34E044FF35E037B93EED25 +:10075C0036B9FFBE18951B44301B47301B50311B5C +:10076C0045301B4B1B301B2F301B5300001B4E0006 +:10077C00801B45311B44301B47301B50311B45300F +:10078C001B4B1B301B2F301B5300001B4EF0401B10 +:10079C0045311B53100D48595445434820313030D6 +:1007AC0030001B53100D57504F33302056351B5310 +:1007BC00100D42414420434F4D4D414E44001B53BC +:1007CC00100D42415454455259204C4F57001B4D6B +:1007DC0030001B53100D48595445434820313530D7 +:1007EC0030001B53100D535441434B204F56455270 +:0407FC00464C4F57C1 +:042000000041BFAC30 +:00000001FF diff --git a/src/avr/WPOV0.HEX b/src/avr/WPOV0.HEX new file mode 100644 index 00000000..ef6e47ff --- /dev/null +++ b/src/avr/WPOV0.HEX @@ -0,0 +1,135 @@ +:020000020000FC +:020000000BC033 +:06000C00DBC1A2C26DC1C0 +:1000160063C30FED0DBF00E808B9A8950FE001BD59 +:100026000AE50093CD0000E00DB90AB9C59ABC9A5D +:100036008D9A8E9AAC9A929A939AC19AB99AC098C6 +:10004600B89897988F9A94988C9AAA98A29A919809 +:10005600899A07E00CD106E00AD105E008D104E050 +:1000660006D101E004D100E002D10FE809B908E1A8 +:100076000AB929D10AEA0CB90CB928D1949A0027F1 +:10008600E0E6FF27019301930193EFEB01930193C0 +:100096000193019301930193019301930093BC0093 +:1000A6000093CB000093BD000093BE0000E40083E4 +:1000B60000E00093C80004E00093C90000E100934B +:1000C600CA0044276627112488249924AA24552483 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CC0000E00093BA0000938F +:10010600BB0007EE202E07EE402E02E003BF02E002 +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1EEE8F7E0A8D0ED +:100146000091CD000A3509F066C041FD6FC043FD40 +:100156007AC040FFF5CF0091CC00033041F0023069 +:1001660091F002E01FE0EAECF7E092D006C002E070 +:100176001FE0EAE0F8E08CD000C003E01EE1ECEA04 +:10018600F7E086D00FC002E01CE0EAEDF7E080D091 +:1001960003E01EE1EEE8F7E07BD003E01CE0EAEDC9 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CD000A35C1F441FD21C043FD2CC0F89471 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1EEE8F7E038D085 +:1002260002E01FE0EAE1F8E033D00AC002E01EE196 +:10023600EEE8F7E02DD002E01FE0E6EEF7E028D08A +:1002460043FD01C0FDCF02E01EE1EEE8F7E020D05D +:1002560002E01FE0E6EFF7E01BD00AEF37D00A9581 +:10026600E9F702E013E0E6E0F8E012D0F6CFAA984C +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A27D000FF919800FD919AAA9A23C0CF +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895ECEDFFE007C0E2E2F1E0C0 +:1002D60004C0EDE101C0E3E0F0E020E02A95F1F78B +:1002E6003197E1F70895FFB666FD22C03CB131258E +:1002F600F2F0312552F0EF93FF93EEEBF091B3005D +:10030600EF0FFF273083FF91EF91131608F0132E9E +:100316006F7E6064312D3F7741F011202AF15798A6 +:100326006F7D3FEF232E606148C033EF42C040C06F +:100336003091B600313019F031E03093BB003CB15A +:10034600EF93FF93E62DE70DE50DEF70ED55FF27D3 +:100356003083E091B500F091B600EF1711F4639485 +:1003660001C07394FF91EF913EEF232E1A941AF574 +:1003760037EE232E606121C0EF93FF93EEEBF091F1 +:10038600B300EF0FFF2730813A953083E82DED5902 +:10039600FF273081FF91EF913CB93695330B3A95A3 +:1003A600232E9A9483943FE383221A9431F403C054 +:1003B60037EE232E6F7E57986F79FFBE1895FFB6DE +:1003C6003091BD007091BE00732B49F031503093CF +:1003D600BD003091BE0030403093BE0091F0442005 +:1003E60051F0439441F430E03DB93EB13FB138EEAF +:1003F6003DB9B89A687F222011F02394B9F0FFBE68 +:10040600189507CE67FD18C0890C3FE3832299240F +:100416009092BA00EF93FF93EEEBF091B300EF0FDB +:10042600FF2730E43083FF91EF9106C065FDEACFE8 +:1004360066FDA2CF64FD7AC033EF232E3091BC0057 +:10044600332359F03A953093BC0031F0AA9891982D +:10045600899A30E03AB9B1CFDCCD57983FE839B93F +:100466003091BA0039293A2939F43091B8003A95D1 +:1004760049F03093B80037C03091B9003A9591F001 +:100486003093B90030E13093B80099203091B30031 +:1004960041F4AA2041F09A2CAA243091B40030935A +:1004A600B300393001F16F779920B9F4AA2059F4D5 +:1004B6003091BA003A9542F43091B3003395393011 +:1004C60048F031E007C031E03093BA009A2CAA24F4 +:1004D6003091B4003093B30025C031E03093BA00B8 +:1004E6003091B3001FC030E13093B900606830919D +:1004F600BB00332331F03A953093BB003091B60000 +:1005060011C03091B600772069F47091B70030932E +:10051600B700372F313021F03395393008F032E00B +:100526003093B6003CB960616F7947CF37EE232E22 +:1005360035E039B9392D67FF04C030E1361937196E +:1005460030683CB9132E579A3CB1606236CFFFB67D +:10055600B8983FB162FD8EC060FD5EC061FD57C0B8 +:100566003A3090F1303899F0313899F03139A1F0BC +:10057600323991F0333981F0353A99F03A3AE1F06F +:10058600353CD9F030E03DB944244260A3C0979889 +:100596009FC04160979A9CC030593093CC0041600F +:1005A60097C03FEF3093BC0030E03DB994983FEFE1 +:1005B60070E07BBD3ABD8CC02CCD38EE3093BD00CB +:1005C60033E03093BE0084C0332379F4686066203C +:1005D60049F47720C1F0672C77243090B60030922A +:1005E600B50012C03090B5000FC0677F332EAA2029 +:1005F60021F03091B400331531F431E03093BA0074 +:100606003092B40001C033243FB8626061C06D7F90 +:10061600332009F061605CC0332E6E7F332063FFA8 +:1006260005C05AF5362D30681FC051C0F2F3EF935E +:10063600FF93EEEBF091B400EF0FFF273081E091CE +:10064600B300F091B400EF1731F0E0E4E9193E177A +:1006560030F03E2F04C0303408F030E439193A192E +:10066600FF91EF910AF43FE7331508F4332E3FB9B3 +:1006760064602EC033208AF43A944AF56160EF93A1 +:10068600FF93E52DED55FF2730813FB9FF91EF919F +:100696006A9453943FE053221BC060FF14C0EF934B +:1006A600FF93E92DEA0DE80DEF73ED59FF2730832F +:1006B600E091B300F091B400EF1711F4939401C0E8 +:1006C600A394FF91EF913A9412F0616001C06B7FA1 +:1006D60037EE432EFFBE1895FFB6A89534B1532FBB +:1006E60035B1379557953795579544FD12C04061FA +:1006F6003091BC003323C9F430E070E05C51C0F1A6 +:1007060030E670E05038A0F55695352F5695350FE2 +:100716002FC04F7E45FD0DC0583F40F03091CA00B6 +:100726003A953093CA0031F5406224C030E13093E7 +:10073600CA005093CB00593330E074E058F0309142 +:10074600C8007091C9003150704021F430E03DB9C5 +:10075600442448603093C8007093C900563450F062 +:100766003FEF3093BC0030E03DB994983FEF70E026 +:100776007BBD3ABD35E445FF34E044FF35E037B98B +:100786003EED36B9FFBE18951B44301B47301B5053 +:10079600311B45301B4B1B301B2F301B5300001BDE +:1007A6004E00801B45311B44301B47301B50311B0C +:1007B60045301B4B1B301B2F301B5300001B4EF0CC +:1007C600401B45311B53100D4859544543482031B1 +:1007D600303030001B53100D57504F3330205635F4 +:1007E6001B53100D42414420434F4D4D414E440092 +:1007F6001B53100D42415454455259204C4F57003B +:100806001B4D30001B53100D4859544543482031A9 +:10081600353030001B53100D535441434B204F5677 +:060826004552464C4F57FD +:042000000041B4AC3B +:00000001FF diff --git a/src/avr/WPOV1.HEX b/src/avr/WPOV1.HEX new file mode 100644 index 00000000..52ed13d4 --- /dev/null +++ b/src/avr/WPOV1.HEX @@ -0,0 +1,135 @@ +:020000020000FC +:020000000BC033 +:06000C00DBC1A2C26DC1C0 +:1000160063C30FED0DBF00E808B9A8950FE001BD59 +:100026000AE50093CD0000E00DB90AB9C59ABC9A5D +:100036008D9A8E9AAC9A929A939AC19AB99AC098C6 +:10004600B89897988F9A94988C9AAA98A29A919809 +:10005600899A07E00CD106E00AD105E008D104E050 +:1000660006D101E004D100E002D10FE809B908E1A8 +:100076000AB929D10AEA0CB90CB928D1949A0027F1 +:10008600E0E6FF27019301930193EFEB01930193C0 +:100096000193019301930193019301930093BC0093 +:1000A6000093CB000093BD000093BE0000E40083E4 +:1000B60000E00093C80004E00093C90000E100934B +:1000C600CA0044276627112488249924AA24552483 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CC0000E00093BA0000938F +:10010600BB0007EE202E07EE402E02E003BF02E002 +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1EEE8F7E0A8D0ED +:100146000091CD000A3509F066C041FD6FC043FD40 +:100156007AC040FFF5CF0091CC00033041F0023069 +:1001660091F002E01FE0EAECF7E092D006C002E070 +:100176001FE0EAE0F8E08CD000C003E01EE1ECEA04 +:10018600F7E086D00FC002E01CE0EAEDF7E080D091 +:1001960003E01EE1EEE8F7E07BD003E01CE0EAEDC9 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CD000A35C1F441FD21C043FD2CC0F89471 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1EEE8F7E038D085 +:1002260002E01FE0EAE1F8E033D00AC002E01EE196 +:10023600EEE8F7E02DD002E01FE0E6EEF7E028D08A +:1002460043FD01C0FDCF02E01EE1EEE8F7E020D05D +:1002560002E01FE0E6EFF7E01BD00AEF37D00A9581 +:10026600E9F702E013E0E6E0F8E012D0F6CFAA984C +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A27D000FF919800FD919AAA9A23C0CF +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895ECEDFFE007C0E2E2F1E0C0 +:1002D60004C0EDE101C0E3E0F0E020E02A95F1F78B +:1002E6003197E1F70895FFB666FD22C03CB131258E +:1002F600F2F0312552F0EF93FF93EEEBF091B3005D +:10030600EF0FFF273083FF91EF91131608F0132E9E +:100316006F7E6064312D3F7741F011202AF15798A6 +:100326006F7D3FEF232E606148C033EF42C040C06F +:100336003091B600313019F031E03093BB003CB15A +:10034600EF93FF93E62DE70DE50DEF70ED55FF27D3 +:100356003083E091B500F091B600EF1711F4639485 +:1003660001C07394FF91EF913EEF232E1A941AF574 +:1003760037EE232E606121C0EF93FF93EEEBF091F1 +:10038600B300EF0FFF2730813A953083E82DED5902 +:10039600FF273081FF91EF913CB93695330B3A95A3 +:1003A600232E9A9483943FE383221A9431F403C054 +:1003B60037EE232E6F7E57986F79FFBE1895FFB6DE +:1003C6003091BD007091BE00732B49F031503093CF +:1003D600BD003091BE0030403093BE0091F0442005 +:1003E60051F0439441F430E03DB93EB13FB138EEAF +:1003F6003DB9B89A687F222011F02394B9F0FFBE68 +:10040600189507CE67FD18C0890C3FE3832299240F +:100416009092BA00EF93FF93EEEBF091B300EF0FDB +:10042600FF2730E43083FF91EF9106C065FDEACFE8 +:1004360066FDA2CF64FD7AC033EF232E3091BC0057 +:10044600332359F03A953093BC0031F0AA9891982D +:10045600899A30E03AB9B1CFDCCD57983FE839B93F +:100466003091BA0039293A2939F43091B8003A95D1 +:1004760049F03093B80037C03091B9003A9591F001 +:100486003093B90030E13093B80099203091B30031 +:1004960041F4AA2041F09A2CAA243091B40030935A +:1004A600B300393001F16F779920B9F4AA2059F4D5 +:1004B6003091BA003A9542F43091B3003395393011 +:1004C60048F031E007C031E03093BA009A2CAA24F4 +:1004D6003091B4003093B30025C031E03093BA00B8 +:1004E6003091B3001FC030E13093B900606830919D +:1004F600BB00332331F03A953093BB003091B60000 +:1005060011C03091B600772069F47091B70030932E +:10051600B700372F313021F03395393008F032E00B +:100526003093B6003CB960616F7947CF37EE232E22 +:1005360035E039B9392D67FF04C030E1361937196E +:1005460030683CB9132E579A3CB1606236CFFFB67D +:10055600B8983FB162FD8EC060FD5EC061FD57C0B8 +:100566003A3090F1303899F0313899F03139A1F0BC +:10057600323991F0333981F0353A99F03A3AE1F06F +:10058600353CD9F030E03DB944244260A3C0979889 +:100596009FC04160979A9CC030593093CC0041600F +:1005A60097C03FEF3093BC0030E03DB994983FEFE1 +:1005B60070E07BBD3ABD8CC02CCD38EE3093BD00CB +:1005C60033E03093BE0084C0332379F4686066203C +:1005D60049F47720C1F0672C77243090B60030922A +:1005E600B50012C03090B5000FC0677F332EAA2029 +:1005F60021F03091B400331531F431E03093BA0074 +:100606003092B40001C033243FB8626061C06D7F90 +:10061600332009F061605CC0332E6E7F332063FFA8 +:1006260005C05AF5362D30681FC051C0F2F3EF935E +:10063600FF93EEEBF091B400EF0FFF273081E091CE +:10064600B300F091B400EF1731F0E0E4E9193E177A +:1006560030F03E2F04C0303408F030E439193A192E +:10066600FF91EF910AF43FE7331508F4332E3FB9B3 +:1006760064602EC033208AF43A944AF56160EF93A1 +:10068600FF93E52DED55FF2730813FB9FF91EF919F +:100696006A9453943FE053221BC060FF14C0EF934B +:1006A600FF93E92DEA0DE80DEF73ED59FF2730832F +:1006B600E091B300F091B400EF1711F4939401C0E8 +:1006C600A394FF91EF913A9412F0616001C06B7FA1 +:1006D60037EE432EFFBE1895FFB6A89534B1532FBB +:1006E60035B1379557953795579544FD12C04061FA +:1006F6003091BC003323C9F430E070E05C51C0F1A6 +:1007060030E670E05038A0F55695352F5695350FE2 +:100716002FC04F7E45FD0DC0583F40F03091CA00B6 +:100726003A953093CA0031F5406224C030E13093E7 +:10073600CA005093CB00593330E074E058F0309142 +:10074600C8007091C9003150704021F430E03DB9C5 +:10075600442448603093C8007093C900563450F062 +:100766003FEF3093BC0030E03DB994983FEF70E026 +:100776007BBD3ABD35E445FF34E044FF35E037B98B +:100786003EED36B9FFBE18951B44301B47301B5053 +:10079600311B45301B4B1B301B2F301B5300001BDE +:1007A6004E00801B45311B44301B47301B50311B0C +:1007B60045301B4B1B301B2F301B5300001B4EF0CC +:1007C600401B45311B53100D4859544543482031B1 +:1007D600303030001B53100D57504F3330205635F4 +:1007E6001B53100D42414420434F4D4D414E440092 +:1007F6001B53100D42415454455259204C4F57003B +:100806001B4D30001B53100D4859544543482031A9 +:10081600353030001B53100D535441434B204F5677 +:060826004552464C4F57FD +:042000000041BCAC33 +:00000001FF diff --git a/src/avr/WPOV2.HEX b/src/avr/WPOV2.HEX new file mode 100644 index 00000000..3a2161e2 --- /dev/null +++ b/src/avr/WPOV2.HEX @@ -0,0 +1,131 @@ +:020000020000FC +:020000000BC033 +:06000C00D8C19FC26CC1C7 +:1000160060C30FED0DBF00E808B9A8950FE001BD5C +:100026000AE50093CC0000E00DB90AB9C59ABC9A5E +:100036008D9A8E9A929A939AC19AB99AC098B898BC +:1000460097988F9A94988C9AAA98A29A9198899A36 +:1000560007E00DD106E00BD105E009D104E007D198 +:1000660001E005D100E003D10FE509B908E10AB9BD +:100076002AD10AEA0CB90CB929D1949A27D19498B5 +:1000860025D1949A0027E0E6FF2701930193019377 +:10009600EFEB019301930193019301930193019374 +:1000A60001930093BC000093CA000093BD00009327 +:1000B600BE0000E4008300E00093C80004E0009363 +:1000C600C90044276627112488249924AA24552484 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CB0000E00093BA00009390 +:10010600BB0000EF202E00EF402E02E003BF02E00E +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1E4E5F7E0A8D0FA +:100146000091CC000A3509F066C041FD6FC043FD41 +:100156007AC040FFF5CF0091CB00033041F002306A +:1001660091F002E01FE0E0E9F7E092D006C002E07D +:100176001FE0E0EDF7E08CD000C003E01EE1E2E70F +:10018600F7E086D00FC002E01CE0E0EAF7E080D09E +:1001960003E01EE1E4E5F7E07BD003E01CE0E0EAE3 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CC000A35C1F441FD21C043FD2CC0F89472 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1E4E5F7E038D092 +:1002260002E01FE0E0EEF7E033D00AC002E01EE194 +:10023600E4E5F7E02DD002E01FE0ECEAF7E028D095 +:1002460043FD01C0FDCF02E01EE1E4E5F7E020D06A +:1002560002E01FE0ECEBF7E01BD00AEF37D00A957F +:10026600E9F702E013E0ECECF7E012D0F6CFAA983B +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A26D000FF919800FD919AAA9A22C0D1 +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895E0EFFAE006C0E8EC03C0CE +:1002D600E4E101C0E2E0F0E020E02A95F1F7319791 +:1002E600E1F70895FFB666FD22C03CB13125F2F074 +:1002F600312552F0EF93FF93EEEBF091B300EF0F41 +:10030600FF273083FF91EF91131608F0132E6F7EAF +:100316006064312D3F7741F011202AF157986F7DA7 +:100326003FEF232E606146C038EF40C03EC030919B +:10033600B600313019F031E03093BB003CB1EF9399 +:10034600FF93E62DE70DE50DEF70ED55FF273083A2 +:10035600E091B500F091B600EF1711F4639401C077 +:100366007394FF91EF913FEF232E1A940AF530EF25 +:10037600232E60611FC0EF93FF93EEEBF091B30065 +:10038600EF0FFF2730813A953083E82DED59FF278F +:100396003081FF91EF913CB93FEF232E9A948394DD +:1003A6003FE383221A9431F403C030EF232E6F7E8D +:1003B60057986F79FFBE1895FFB63091BD007091C2 +:1003C600BE00732B49F031503093BD003091BE0012 +:1003D60030403093BE0091F0442051F0439441F4F4 +:1003E60030E03DB93EB13FB138EE3DB9B89A687FCD +:1003F600222011F02394B9F0FFBE18950ACE67FDAE +:1004060018C0890C3FE3832299249092BA00EF9397 +:10041600FF93EEEBF091B300EF0FFF2730E430834C +:10042600FF91EF9106C065FDEACF66FDA4CF64FD9E +:100436007AC038EF232E3091BC00332359F03A9519 +:100446003093BC0031F0AA989198899A30E03AB975 +:10045600B1CFDFCD57983FE539B93091BA00392988 +:100466003A2939F43091B8003A9549F03093B800FA +:1004760037C03091B9003A9591F03093B90030E128 +:100486003093B80099203091B30041F4AA2041F08E +:100496009A2CAA243091B4003093B300393001F17C +:1004A6006F779920B9F4AA2059F43091BA003A9599 +:1004B60042F43091B3003395393048F031E007C04B +:1004C60031E03093BA009A2CAA243091B4003093CC +:1004D600B30025C031E03093BA003091B3001FC09D +:1004E60030E13093B90060683091BB00332331F0BE +:1004F6003A953093BB003091B60011C03091B600EA +:10050600772069F47091B7003093B700372F3130F8 +:1005160021F03395393008F032E03093B6003CB91B +:1005260060616F7947CF30EF232E33E039B9392D2B +:1005360067FF04C030E13619371930683CB9132E0D +:10054600579A3CB1606236CFFFB6B8983FB162FDAC +:100556008EC060FD5EC061FD57C03A3090F1303804 +:1005660099F0313899F03139A1F0323991F03339B7 +:1005760081F0353A99F03A3AE1F0353CD9F030E07D +:100586003DB944244260A3C097989FC04160979AA2 +:100596009CC030593093CB00416097C03FEF3093F9 +:1005A600BC0030E03DB994983FEF70E07BBD3ABDAA +:1005B6008CC02FCD38EE3093BD0033E03093BE00B3 +:1005C60084C0332379F46860662049F47720C1F04B +:1005D600672C77243090B6003092B50012C0309068 +:1005E600B5000FC0677F332EAA2021F03091B400EA +:1005F600331531F431E03093BA003092B40001C0C3 +:1006060033243FB8626061C06D7F332009F06160BA +:100616005CC0332E6E7F332063FF05C05AF5362D3E +:1006260030681FC051C0F2F3EF93FF93EEEBF091E9 +:10063600B400EF0FFF273081E091B300F091B400D2 +:10064600EF1731F0E0E4E9193E1730F03E2F04C011 +:10065600303408F030E439193A19FF91EF910AF471 +:100666003FE7331508F4332E3FB964602EC03320BC +:100676008AF43A944AF56160EF93FF93E52DED55C0 +:10068600FF2730813FB9FF91EF916A9453943FE081 +:1006960053221BC060FF14C0EF93FF93E92DEA0DB0 +:1006A600E80DEF73ED59FF273083E091B300F09129 +:1006B600B400EF1711F4939401C0A394FF91EF9146 +:1006C6003A9412F0616001C06B7F30EF432EFFBE9B +:1006D6001895FFB6A89534B1532F35B13795579570 +:1006E6003795579544FD12C040613091BC003323C5 +:1006F60031F530E070E05C5100F130E670E05038E2 +:10070600E0F45695352F5695350F17C04F7E50930A +:10071600CA00583A30E074E058F43091C80070913D +:10072600C9003150704021F430E03DB9442448609E +:100736003093C8007093C90002C07BBD3ABD34E057 +:1007460044FF35E037B93EED36B9FFBE18951B4478 +:10075600301B47301B50311B45301B4B1B301B2FAA +:10076600301B5300001B4E00801B45311B44301BC1 +:1007760047301B50311B45301B4B1B301B2F301B8A +:100786005300001B4EF0401B45311B53100D4859BA +:10079600544543482031303030001B53100D57501C +:1007A6004F33302056351B53100D42414420434FE2 +:1007B6004D4D414E44001B53100D42415454455279 +:1007C60059204C4F57001B4D30001B53100D4859F4 +:1007D600544543482031353030001B53100D5354D7 +:0C07E60041434B204F564552464C4F57A4 +:042000000041BCAC33 +:00000001FF diff --git a/src/avr/WPOV3.ASM b/src/avr/WPOV3.ASM new file mode 100644 index 00000000..0db9f332 --- /dev/null +++ b/src/avr/WPOV3.ASM @@ -0,0 +1,2502 @@ +; WPOV2.ASM +; COPIED FROM WPO15V1.ASM ON 20JUN02 + +; LOOK FOR BIGBODGE TO SEE CEC'S CHANGES TO FIX STARTUP PROBLEM +; AND TO SKIP VOLTAGE MEASURING + +; REVISED 17DEC01 TO SUPPORT NEW HARDWARE TYPE 3 FOR HYT1500 + +; REVISED 18DEC01 TO TRY A CONSERVATIVE 4.5 VOLT SHUTDOWN, LOW BATTERY +; THIS DOESN'T PROTECT AGAINST REBOOTING WHILE PRINTING, TOO BAD + +; REVISED 18DEC01 TO TRY AN AGGRESSIVE 5.5 VOLT SHUTDOWN, LOW BATTERY +; ALSO ENABLED THE 4.5 VOLT IMMEDIATE RESET, DUE TO UNRELIABLE OPERATION +; NOW TRYING 5.0 VOLT IMMEDIATE RESET, CEC SAYS IT WAS MARGINAL ANYWAY + +; NOW DISABLED THE IMMEDIATE RESET DUE TO TESTING RESULTS OF 08JAN02 +; NOT SURE IF THAT WAS REALLY THE PROBLEM - BUT WISH TO BE CONSERVATIVE + +; REVISED 01FEB02 FOR NEW 7.3728 MHZ XTAL, PREVIOUSLY 11.0592 MHZ, 2/3 +; LOOK FOR ;! TO SEE CHANGES FOR 7.3728 MHZ XTAL, ADDED COMMENTS ALSO + +; ----------------------------------------------------------------------------- + +.EQU LARGE =0 + +;IF LARGE +;.INCLUDE "8535DEF.INC" +;ELSE +.INCLUDE "4433DEF.INC" +;ENDIF + +; ----------------------------------------------------------------------------- +; API BUS TIMING CALCULATIONS: + +; 115200 BITS/SEC = 11520 BYTES/SEC = 86.8 US/BYTE +; 460800 BITS/SEC = 46080 BYTES/SEC = 21.7 US/BYTE + +; FOR MASTER API BUS TX, SEND 1 BYTE PER 9+12 BIT-TIMES, 24 TO BE SAFE +; SO THE CORRECT TX RATE = 86.8 * 2.4 = 208.3 US/BYTE = 4800 BYTES/SEC +; SO THE CORRECT TX RATE = 21.7 * 2.4 = 52.1 US/BYTE = 19200 BYTES/SEC + +; A SUBTLE OPTIMISATION IS POSSIBLE WHEN THE PREVIOUS TRANSMITTED LSB IS 0, +; AS WE CAN THEN GUARANTEE THE 4800 BPS RECEIVERS WILL SEE FALSE START BIT: + +; FOR MASTER API BUS TX EVEN, SEND 1 BYTE PER 2+12 BIT-TIMES, 16 TO BE SAFE +; SO THE CORRECT TX RATE EVEN = 86.8 * 1.6 = 138.9 US/BYTE = 7200 BYTES/SEC +; SO THE CORRECT TX RATE EVEN = 21.7 * 1.6 = 34.7 US/BYTE = 28800 BYTES/SEC + +; OLD: TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ = APPROX 278 US +; NEW: TCK0 ROLLOVER = 256 / 7.3728 MHZ = APPROX 34.7 US +; THUS ALL THE TIMEOUT VALUES BELOW HAVE BEEN INCREASED TO 2* ORIGINAL + +.EQU RAM =$60 ; START OF SRAM + +; note: these are in 34.7us units: +.EQU API_TIMEOUT =6 ; 5 doesn't work +.EQU API_TIMEOUT_TS =16 ;8 ; 7 doesn't work +.EQU API_TIME_IDLE =4 ; 3 doesn't work +.EQU API_TIME_SLOW =18 ; 16 doesn't work (16 is theoretically correct) +.EQU API_TIME_FIRST =1 ; should always be 1 to synchronise with timer +;.EQU API_TIME_FAST =2 ; not used if doing the tx even/odd optimisation +.EQU API_TIME_FAST_TS=16 ;4 ; overrides the tx optimisation for touchscreen + +.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS +.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS + +; note: this is in 278us units: +.EQU SPI_TIMEOUT =1 ; 24mar03 16 ; 12 doesn't work + +;.def drem16uL =R0 ; remainder low +;.def drem16uH =R1 ; remainder high +;.def dres16uL =R2 ; result low DON'T use as general purpose +;.def dres16uH =R3 ; result high DON'T use as general purpose +;.def dd16uL =R2 ; dividend low +;.def dd16uH =R3 ; dividend high +;.def dv16uL =R4 ; divisor low +;.def dv16uH =R5 ; divisor high +; +;.DEF SPI_REMAIN =R6 +; +;.def mc16uL =R7 ;multiplicand low byte +;.def mc16uH =R8 ;multiplicand high byte +;.def mp16uL =R9 ;multiplier low byte +;.def mp16uH =R10 ;multiplier high byte +;.def m16u0 =R9 ;result byte 0 (LSB) +;.def m16u1 =R10 ;result byte 1 +;.def m16u2 =R11 ;result byte 2 +;.def m16u3 =R12 ;result byte 3 (MSB) +; +;.DEF RX_PTR =R13 +;.DEF RX_COUNT0 =R14 + +.DEF API_REMAIN =R1 +.DEF API_WATCHDOG =R2 +.DEF SPI_REMAIN =R3 +.DEF SPI_WATCHDOG =R4 +.DEF RX_PTR =R5 +.DEF RX_COUNT0 =R6 +.DEF RX_COUNT1 =R7 +.DEF TX_PTR =R8 +.DEF TX_COUNT0 =R9 +.DEF TX_COUNT1 =R10 +.DEF TCK0_DIVIDE_8 =R11 + +.DEF SR =R15 +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R23 +.DEF G =R24 + +.DEF FLAGS =R20 +;.def counter =R20 ;loop counter + +.DEF ATOD =R21 ; SO YOU CAN USE SBCI, SUBI, CPI ETC + +.DEF API_STATE =R22 + +;.DEF TX_PTR =R25 +;.DEF API_WATCHDOG =R26 +;.DEF API_REMAIN =R27 +;.DEF SPI_WATCHDOG =R28 +;.DEF TX_COUNT0 =R29 + +.EQU TX_SIZE =$20 ; 09mar03 $40 +.EQU RX_SIZE =$20 ; 09mar03 $10 + + .DSEG + .ORG $60 + +VSWTS: .BYTE 1 ; RETAIN ORDERING % +VCHGS: .BYTE 1 +NEGVS: .BYTE 1 + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +TX_ADDRESS0: .BYTE 1 ; DEST FOR TX_COUNT0 BYTES AT HEAD +TX_ADDRESS1: .BYTE 1 ; DEST FOR TX_COUNT1 BYTES AT TAIL + +RX_ADDRESS0: .BYTE 1 ; SOURCE FOR RX_COUNT0 BYTES AT HEAD +RX_ADDRESS1: .BYTE 1 ; SOURCE FOR RX_COUNT1 BYTES AT TAIL + +; 09mar03 now done by RX_MODULUS and RX_PRIORITY $ +;RX_ADDRESS2: .BYTE 1 ; ALTERNATE VALUE FOR RX_ADDRESS1 +; ; SCAN IS 1,2,1,3,1,4,1,5,1,6,1,7,1,8 +; $ + +TX_OVERRIDE: .BYTE 1 ; COUNTER TO TRANSMIT 1 TIME IN 16 +RX_OVERRIDE: .BYTE 1 ; COUNTER TO RECEIVE 1 TIME IN 16 + +TX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME TX DEVICE +RX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME RX DEVICE + +;ABSENT_COUNT: .BYTE 1 + +TURNOFF_COUNT: .BYTE 1 +WATCHDOG_COUNT: .BYTE 2 + +TX_LIMIT: .BYTE 9 ; MAX Z180 BYTES TO ACCEPT, PER DEVICE +; 09mar03 now got individual priorities per device $ +RX_MODULUS: .BYTE 8 ; 09mar03 cumulative value per device +RX_PRIORITY: .BYTE 8 ; 09mar03 separate increment per device +; $ + +BATTERY_COUNT: .BYTE 2 ; COUNT 1024 ADC READINGS TO POWER DOWN + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +;LM385_COUNT: .BYTE 1 ; COUNT $10 ADC READINGS TO MISSING REF +VOLTAGE_VSWT: .BYTE 1 ; MOST RECENT ADC READING FROM REF + +HARDWARE_TYPE: .BYTE 1 ; COMES SOMEWHAT BEFORE RSEL HI COMMAND + +STACK_GUARD: .BYTE 1 ; DETECTS IF STACK COMES DOWN TO HERE + +; ----------------------------------------------------------------------------- + +; API_STATE DEFINITIONS +.EQU SPISIZE =0 ; SET IF EXPECTING SPI DATA SIZE CMD +.EQU SPIWAIT =1 ; SET IF SENDING SPI ADDRESS RESPONSE +.EQU SPIDATA =2 ; SET IF TRANSFERRING SPI DATA TX/RX +.EQU SPIDIRN =3 ; SET IF TX, BASED ON ADDRESS COMMAND +.EQU APISIZE =4 ; SET IF NEED TO SEND API DATA SIZE CMD +.EQU APIWAIT =5 ; SET IF WAITING FOR API DATA SIZE RESP +.EQU APIDATA =6 ; SET IF TRANSFERRING API DATA TX/RX +.EQU APIDIRN =7 ; SET IF TX, TOGGLED ON NULL TRANSFER + +; ----------------------------------------------------------------------------- + +;IF LARGE +; +;.EQU IRQ =6 +;.EQU IRQ_PORT =PORTA +;.EQU IRQ_DDR =DDRA +; +;.EQU PRG =3 +;.EQU PRG_PORT =PORTB +;.EQU PRG_DDR =DDRB +; +;.EQU OC1 =5 +;.EQU OC1_PORT =PORTD +;.EQU OC1_DDR =DDRD +; +;.EQU OCR1H =OCR1AH +;.EQU OCR1L =OCR1AL +; +;.EQU COM10 =COM1A0 +;.EQU COM11 =COM1A1 +; +;ELSE + +.EQU IRQ =0 +.EQU IRQ_PORT =PORTB +.EQU IRQ_DDR =DDRB + +.EQU PRG =2 +.EQU PRG_PORT =PORTC +.EQU PRG_DDR =DDRC + +.EQU OC1 =1 +.EQU OC1_PORT =PORTB +.EQU OC1_DDR =DDRB + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +;ENDIF + +; ----------------------------------------------------------------------------- + + .CSEG + + RJMP RESET_ENTRY + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER 0 OVERFLOW HANDLER + + .ORG SPIADDR + RJMP SPI_COMPLETE ; SPI TRANSFER COMPLETE HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + + .ORG ADCCaddr + RJMP ADC_COMPLETE + +; ----------------------------------------------------------------------------- + +RESET_ENTRY: + ; INITIALISE AVR +;IF LARGE +; LDI A,HIGH(RAMEND) +; OUT SPH,A +;ENDIF + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + ; INITIALISE STACK GUARD + LDI A,$5A + STS STACK_GUARD,A + + ; INITIALISE PORTS + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + LDI A,0 + OUT SPCR,A ; DISABLE SPI WHILE RESETTING Z180 + OUT UCR,A ; DISABLE UART WHILE RESETTING SLAVES + +;IF LARGE +; LDI A,$FF +; OUT DDRC,A ; PORTC CONFIGURED AS OUTPUT +; +; SBI PORTB,7 ; PB7/SCK CONFIGURED AS PULLED UP INPUT +; SBI DDRB,6 ; PB6/MISO CONFIGURED AS OUTPUT +; +; SBI DDRA,7 ; A7 CONFIGURED AS OUTPUT FOR DTR1 +; SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 +; +;; 18DEC01 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +;; SBI PORTA,4 ; A4 PULLED UP TO DETECT MISSING LM385 +;ELSE + SBI PORTB,5 ; PB5/SCK CONFIGURED AS PULLED UP INPUT + SBI DDRB,4 ; PB4/MISO CONFIGURED AS OUTPUT + + SBI DDRD,5 ; D5 CONFIGURED AS OUTPUT FOR DTR1 + SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 + +; 20JUN02 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +; SBI PORTC,4 ; C4 PULLED UP TO DETECT MISSING LM385 +;ENDIF + + SBI PORTD,2 ; D2 CONFIGURED AS PULL UP FOR IBM CLK + SBI PORTD,3 ; D3 CONFIGURED AS PULL UP FOR IBM DATA + + SBI OC1_PORT,OC1 + SBI OC1_DDR,OC1 ; OUTPUT OC1 = 1, PWM TRANSISTOR OFF + + CBI IRQ_PORT,IRQ + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + CBI PORTD,7 + SBI DDRD,7 ; OUTPUT RSEL = 0 + + CBI PORTD,4 + SBI DDRD,4 ; OUTPUT RES = 0 + + ; HARD RESET API BUS DEVICES + CBI PRG_PORT,PRG + SBI PRG_DDR,PRG ; OUTPUT PRG = 0 + + CBI PORTD,1 + SBI DDRD,1 ; OUTPUT TXD = 0 + + LDI A,7 + RCALL PRG_RESET ; SPECIFIC RESET SPARE + + LDI A,6 + RCALL PRG_RESET ; SPECIFIC RESET M192 RECEIPT PRINTER + + LDI A,5 + RCALL PRG_RESET ; SPECIFIC RESET M192 LABEL PRINTER + + LDI A,4 + RCALL PRG_RESET ; SPECIFIC RESET MT102 RECEIPT PRINTER + + ;LDI A,3 + ;RCALL PRG_RESET ; SPECIFIC RESET SPARE + ; THE ABOVE SHOULD BE OK - WHY NOT ?? 16FEB01 + + ;LDI A,2 + ;RCALL PRG_RESET ; SPECIFIC RESET TOUCHSCREEN + + LDI A,1 + RCALL PRG_RESET ; SPECIFIC RESET CUSTOMER DISPLAY + + LDI A,0 + RCALL PRG_RESET ; REMOVE RESET PULSE + + ; LOADCELL HAS BEEN IN RESET UNTIL NOW, AND WILL START IN 10 MS + + ;SBI PORTD,1 ; OUTPUT TXD = 1 + + LDI A,API_RATE_SLOW ; 4800 BAUD + OUT UBRR,A ; SET BAUD RATE + LDI A,$18 + OUT UCR,A ; ENABLE TX AND RX (OUTPUTS TXD = 1) + + RCALL PRG_DELAY_280_MS ; DELAY FOR TOUCHSCREEN TO REENTER IDLE + + LDI A,$AA + OUT UDR,A ; SEND SLOW TURNON COMMAND + OUT UDR,A ; AND AGAIN FOR EXTRA SAFETY + + RCALL PRG_DELAY_20_MS ; DELAY TO ALLOW DEVICES TO INITIALISE + + ; ALLOW Z180 TO START + SBI PORTD,4 ; OUTPUT RES = 1 + ;CBI DDRD,4 ; OUTPUT RES = TRI-STATE + +; BIGBODGE FOR ANOTHER RESET PULSE!!!! +RCALL PRG_DELAY_20_MS +CBI PORTD,4 ; RES=0 +RCALL PRG_DELAY_20_MS +SBI PORTD,4 ; OUTPUT RES = 1 + + ; INITIALISE VARIABLES + CLR A + LDI ZL,VSWTS + CLR ZH + ST Z+,A + ST Z+,A + ST Z+,A + LDI ZL,TX_LIMIT + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A ; CAREFUL - Z WILL BE USED AGAIN BELOW + STS TURNOFF_COUNT,A + STS VOLTAGE_VSWT,A + + ;LDI A,LOW(1000) + STS WATCHDOG_COUNT,A + ;LDI A,HIGH(1000) ; 100 MS + STS WATCHDOG_COUNT+1,A + + LDI A,TX_SIZE + ST Z+,A ; 09mar03 Z ; RX_LIMIT FOR 9TH (INTERNAL) DEVICE + +; 09mar03 initialise RX_MODULUS and RX_PRIORITY $ + clr a ; modulus value doesn't matter! + st z+,a ; RX_MODULUS, array of 8 values + st z+,a + st z+,a + st z+,a + st z+,a + st z+,a + st z+,a + st z+,a + ldi a,15 ; priority value can't be zero + st z+,a ; RX_PRIORITY, array of 8 values + st z+,a + st z+,a + st z+,a + st z+,a + st z+,a + st z+,a + st z,a +; $ + + LDI A,LOW(1024) + STS BATTERY_COUNT,A + LDI A,HIGH(1024) + STS BATTERY_COUNT+1,A + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI A,$10 ; START COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,A + + CLR FLAGS + + CLR API_STATE + CLR API_REMAIN + + CLR TX_PTR + CLR TX_COUNT0 + CLR TX_COUNT1 + + CLR RX_PTR + CLR RX_COUNT0 + CLR RX_COUNT1 + +; LDI A,4 +; STS ABSENT_COUNT,A ; TOP UP ABSENT COUNTER FOR TX_ADDRESS + + ; START COMMUNICATIONS TASK +; 09mar03 now done by RX_MODULUS and RX_PRIORITY $ +; LDI A,2 +; STS RX_ADDRESS2,A ; ALTERNATE VALUE FOR RX_ADDRESS1 +; $ + + LDI A,1 + STS TX_ADDRESS0,A + STS TX_ADDRESS1,A + STS RX_ADDRESS0,A + STS RX_ADDRESS1,A + STS TX_OVERRIDE,A + STS RX_OVERRIDE,A + STS HARDWARE_TYPE,A ; AS FOR OLD ALGORITHM WITH FLAGS,2 = 0 + + LDI A,0 + STS TX_STICKY,A + STS RX_STICKY,A + + LDI A,-API_TIME_IDLE ; 10mar03 -API_TIMEOUT + MOV API_WATCHDOG,A ; SET UP TIME TO FIRST API BUS POLL + LDI A,-SPI_TIMEOUT + MOV SPI_WATCHDOG,A ; SET UP TIME TO FIRST SPI BUS POLL + +; 10mar03 we now have a faster interrupt and finer control over timing $ + ldi a,$01 ; TCK0 = CK + mov TCK0_DIVIDE_8,a +; else +; LDI A,$02 ; TCK0 = CK/8 +; $ + OUT TCCR0,A ; TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ + ; = APPROX 278 US + ;!TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ + ;! = APPROX 185 US +;IF LARGE +; LDI A,$01 +;ELSE + LDI A,$02 +;ENDIF + OUT TIMSK,A ; ENABLE TIMER 0 OVERFLOW INTERRUPTS + + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + IN A,SPSR + IN A,SPDR ; CLEAR SPI INTERRUPT PENDING FLAG + LDI A,$E8 + OUT SPCR,A ; SPI SLAVE, SAMPLE ON SCK FALLING EDGE + + ; START -5V GENERATOR TASK + LDI A,0 + OUT TCNT1H,A + OUT TCNT1L,A + OUT OCR1H,A + OUT OCR1L,A ; ASSUME NO LOAD TO BEGIN WITH + + LDI A,1< 0 + OR E,TX_COUNT0 + OR E,TX_COUNT1 + BRNE API_TRY_TX + +API_TRY_RX: ; 09mar03 + LDS E,TX_OVERRIDE + DEC E + BREQ API_DIRECTION_TX ; FORCED TRANSMIT EVERY SO OFTEN + STS TX_OVERRIDE,E + RJMP API_DIRECTION_RX + +API_TRY_TX: + LDS E,RX_OVERRIDE + DEC E + BREQ BREQ_API_DIRECTION_RX ; FORCED RECEIVE EVERY SO OFTEN + STS RX_OVERRIDE,E + +API_DIRECTION_TX: + LDI E,$10 + STS TX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + ; SUSPEND TX OPERATIONS WHEN 9TH (INTERNAL) DEVICE ADDRESSED % + TST TX_COUNT0 ; ANY BYTES AT HEAD ? + LDS E,TX_ADDRESS0 + BRNE API_SUSPEND_TX0 ; YES, GO AND CHECK HEAD DEVICE + + TST TX_COUNT1 ; ANY BYTES AT TAIL ? + BREQ API_SUSPEND_TX1 ; NO, GO AND PERFORM TX OPERATION + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE TX_COUNT1 BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 + STS TX_ADDRESS0,E ; ADOPT TAIL DEVICE FOR BYTES AT HEAD + +API_SUSPEND_TX0: + CPI E,9 +BREQ_API_DIRECTION_RX: + BREQ API_DIRECTION_RX + +API_SUSPEND_TX1: + ; % + +; LDS E,ABSENT_COUNT +; TST E +; BRNE API_DEVICE_PRESENT +; +;;API_DEVICE_ABSENT: +; ADD TX_PTR,TX_COUNT0 ; SKIP TX_COUNT0 BYTES AT HEAD +; LDI E,TX_SIZE-1 +; AND TX_PTR,E +; +; CLR TX_COUNT0 ; ABANDON TX_COUNT0 DATA IN TX_BUF +; STS TX_STICKY,TX_COUNT0 ; DO NOT GO STICKY ON ABSENT DEVICE +; +; PUSH ZL +; PUSH ZH +; LDI ZL,TX_LIMIT-1 +; LDS ZH,TX_ADDRESS0 +; ADD ZL,ZH +; CLR ZH +; ;ST Z,TX_COUNT0 ; SAVE MAX BYTES TO ACCEPT, PER DEVICE +; LDI E,TX_SIZE +; ST Z,E ; SO THAT WE WILL GOBBLE UP DATA FOR ABSENT DEVICES +; POP ZH +; POP ZL +; +; LDI E,4 +; STS ABSENT_COUNT,E ; TOP UP ABSENT COUNTER FOR NEXT DEVICE +; +;API_DEVICE_PRESENT: + CBR API_STATE,1< 0 + DEC E + BRPL API_TX_ADDRESS_STICKY ; STAYING STICKY, ADOPT NEW DEVICE + + LDS E,TX_ADDRESS0 + INC E ; BUMP TX_ADDRESS BEFORE USING IT + CPI E,9 + BRLO API_TX_ADDRESS_SAVE + LDI E,1 + RJMP API_TX_ADDRESS_SAVE + +API_TX_ADDRESS_ADOPT: + LDI E,3 ; 09mar03 1 +API_TX_ADDRESS_STICKY: + STS TX_STICKY,E ; DECREMENT, OR TOP UP, STICKY COUNT + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 ; DEST FOR TX_COUNT1 BYTES AT HEAD +API_TX_ADDRESS_SAVE: + STS TX_ADDRESS0,E ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_TX_ADDRESS_SAME: + LDI E,3 ; 09mar03 1 + STS TX_STICKY,E ; TOP UP STICKY COUNT + + LDS E,TX_ADDRESS0 ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_DIRECTION_RX: + LDI E,$10 + STS RX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + SBR API_STATE,1< 0th + cpi e,9 + brsh spi_bad_command ; device needs to be < 9th (internal) + + swap f + andi f,$07 ; priority must be valid (from 1 to 7) + cpi f,4 + brlo spi_priority_save ; values 1,2,3 saved without change + inc f + cpi f,6 + brlo spi_priority_save ; value 4 translated to 5 + inc f + cpi f,8 + brlo spi_priority_save ; value 5 translated to 7 + subi f,-3 + cpi f,12 + brlo spi_priority_save ; value 6 translated to 11 + ldi f,15 ; value 7 translated to 15 + +spi_priority_save: + push zl + push zh + ldi zl,RX_PRIORITY-1 + add zl,e ; find device entry in priority array + clr zh + st z,f ; save priority for device + pop zh + pop zl + + rjmp SPI_DONE ; await a new command (timeout???) +; $ + +SPI_COMPLETE: + IN SR,SREG + + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + IN E,SPDR + + SBRC API_STATE,SPIDATA + RJMP SPI_DATA + + SBRC API_STATE,SPISIZE + RJMP SPI_RESPOND + + SBRC API_STATE,SPIWAIT + RJMP SPI_WAIT + +;SPI_ADDRESS: + CPI E,10 ; VALID ADDRESSES ARE 1-9 + BRLO SPI_SELECT + CPI E,$80 +; 09mar03 now got individual priorities per device $ + brlo spi_priority ; accept command to set device priority +; $ + BREQ SPI_RSEL_LO + CPI E,$81 + BREQ SPI_RSEL_HI + CPI E,$91 + BREQ SPI_HARDWARE ; HYTECH 1000 + CPI E,$92 + BREQ SPI_HARDWARE ; WPO30 V5 + CPI E,$93 + BREQ SPI_HARDWARE ; HYTECH 1500 + CPI E,$A5 + BREQ SPI_TURNOFF + CPI E,$AA + BREQ SPI_RESET + CPI E,$C5 + BREQ SPI_WATCHDOG_RESET + +; 09mar03 now got individual priorities per device $ +spi_bad_command: +; $ + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<1 ; HAD WRONG COMMAND + RJMP SPI_DONE_ENTRY ; RETURN LEAVING SPI_WATCHDOG = 0 + +SPI_RSEL_LO: + CBI PORTD,7 + RJMP SPI_DONE + +SPI_RSEL_HI: + SBR FLAGS,1<<0 ; SHOW MESSAGE - FOR COMPATIBILITY + SBI PORTD,7 + RJMP SPI_DONE + +SPI_HARDWARE: ;_HYT1000 + SUBI E,$90 ; THE MAGIC CRACKER + STS HARDWARE_TYPE,E ; IT WAS PREVIOUSLY 1 FOR COMPATIBILITY + + ;CBR FLAGS,1<<2 ; HARDWARE TYPE IS HYTECH 1000 + SBR FLAGS,1<<0 ; SHOW MESSAGE + RJMP SPI_DONE + +;SPI_HARDWARE_WPO30: +; SBR FLAGS,1<<2 | 1<<0 ; HARDWARE TYPE IS WPO30, SHOW MESSAGE +; RJMP SPI_DONE + +SPI_TURNOFF: + LDI E,$FF + STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 + + CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM + + LDI E,$FF + LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + RJMP SPI_DONE + +SPI_RESET: + RJMP RESET_ENTRY + +SPI_WATCHDOG_RESET: + LDI E,LOW(1000) + STS WATCHDOG_COUNT,E + LDI E,HIGH(1000) ; 0.1 SECOND + STS WATCHDOG_COUNT+1,E + RJMP SPI_DONE + +SPI_SELECT: + ; RECEIVED ADDRESS COMMAND + TST E ; TEST DIRECTION FROM ADDRESS COMMAND + BRNE SPI_SELECT_TX + +;SPI_SELECT_RX: + ; HAD ENQUIRY, SEND ACTIVE DEVICE + SBR API_STATE,1< $10 + ;MOV E,ATOD + ;LSL ATOD ; $01 HALF SCALE -> $20 + ;ADD E,ATOD ; $01 HALF SCALE -> $30 HALF WIDTH + + LSR ATOD ; $40 HALF SCALE -> $20 + MOV E,ATOD + LSR ATOD ; $40 HALF SCALE -> $10 + ADD E,ATOD ; $40 HALF SCALE -> $30 HALF WIDTH + RJMP ADC_PULSE + +ADC_REFERENCE: + CBR FLAGS,1<<4 ; SAY NEXT RESULT WILL BE -5V GENERATOR + + ;STS VOLTAGE_VSWT,ATOD + ;RJMP ADC_DONE + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; SBRC FLAGS,5 ; CURRENT REFERENCE IS BANDGAP ? +; RJMP ADC_BANDGAP +; +; ; CURRENT REFERENCE IS LM385 (18DEC01 IT'S NOW A 100K/100K DIVIDER) +; CPI ATOD,$F8 ; IF =>$F8 ASSUME WE HAVE PULLUP ONLY +; BRLO ADC_LM385 +; +; LDS E,LM385_COUNT +; DEC E ; COUNT DOWN TO MISSING LM385 +; STS LM385_COUNT,E +; BRNE ADC_DONE ; KEEP TRYING LM385 +; +; SBR FLAGS,1<<5 ; SAY WE HAVE SWITCHED TO BANDGAP +;GO_ADC_DONE: +; RJMP ADC_DONE +; +;ADC_LM385: +; LDI E,$10 ; TOP UP COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,E +; +;; LSR ATOD ; LM385 VOLTAGE = APPROX 2*BANDGAP +; ; USE LM385Z-1.2 +; +;ADC_BANDGAP: + STS VOLTAGE_VSWT,ATOD + + ; 18DEC01 USE 5.5 VOLTS AS FOR THE ORIGINAL HYTECH 1000 SYSTEM + ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC + ;CPI ATOD,137 ; 256*0.5*4.5/4.2 + ;CPI ATOD,152 ; 256*0.5*5.0/4.2 + CPI ATOD,168 ; 256*0.5*5.5/4.2 + +; ;CPI ATOD,70 ; 256*1.22/4.5 +; ;CPI ATOD,63 ; 256*1.22/5.0 +; CPI ATOD,57 ; 256*1.22/5.5 + + LDI E,LOW(1024) + LDI F,HIGH(1024) + ; 18DEC01 FOR HYT1500 REVERSED THE SENSE DUE TO NEW 100K/100K DIVIDER + ;BRLO ADC_BATTERY_SAVE + BRSH ADC_BATTERY_SAVE + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 THIS IS NOW DONE FURTHER DOWN, AFTER LOW BATTERY TEST +;RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + + ; VSWT < 5.5 VOLTS, STABILISE READING FOR BATTERY LOW + LDS E,BATTERY_COUNT + LDS F,BATTERY_COUNT+1 + SUBI E,LOW(1) + SBCI F,HIGH(1) + BRNE ADC_BATTERY_SAVE ; COUNT 1024 LOW BATTERY READINGS + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<3 ; SHOW BATTERY MESSAGE AND POWER DOWN + +ADC_BATTERY_SAVE: + STS BATTERY_COUNT,E + STS BATTERY_COUNT+1,F + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 WE'LL ALSO COMMENT THE WHOLE THING OUT FOR NEATNESS +RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + +; ; 18DEC01 USE 5.0 VOLTS, MORE AGGRESSIVE THAN HYTECH 1000 SYSTEM +; ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC +; ;CPI ATOD,137 ; 256*0.5*4.5/4.2 +; CPI ATOD,152 ; 256*0.5*5.0/4.2 +; ;CPI ATOD,168 ; 256*0.5*5.5/4.2 +; BRSH ADC_DONE +; +;; ;CPI ATOD,90 ; 256*1.22/3.5 +;; ;CPI ATOD,79 ; 256*1.22/4.0 +;; CPI ATOD,70 ; 256*1.22/4.5 +;; BRLO ADC_DONE +; +; ; 18DEC01 VSWT < 5.0 VOLTS, RESET MAIN PROCESSOR IMMEDIATELY +; LDI E,$FF +; STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON +; +; LDI E,0 +; OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 +; +; CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM +; +; LDI E,$FF +; LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT + +ADC_PULSE: + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + +ADC_DONE: +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI E,$45 ; START MEASURING BANDGAP +; SBRS FLAGS,5 + LDI E,$04 ; START MEASURING LM385 + SBRS FLAGS,4 + LDI E,$05 ; START MEASURING -5V GENERATOR + OUT ADMUX,E + LDI E,$DE + OUT ADCSR,E ; ENABLE A/D, START, SINGLE CONVERSION + + OUT SREG,SR + RETI + +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 5 +; RCALL MULTIPLY +;DIAG_VOLTS_AT_A5: +; ;OUT PORTC,M16U1 ; res in byte 2(ignore ls,byte),volts pin 5 +; MOV A,B ; get saved VSWT +; SUB A,M16U1 ; voltage 47K = VSWT-Voltage at pin 35 +; MOV D,A ; which is 1/3 of total supply ie +V+(-V) +; ADD A,D +; ADD A,D ; TOTAL SUPPLY +; SUB A,B ; TOTAL SUPPLY-VSWT=NEG SUPPLY +;DIAG_NEG: +; ;OUT PORTC,A +; +; LDI A,4 +; OUT ADMUX,A ; NEXT TIME READ VCHG +;ADC_DONE: +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI + +;VSWT: ;OUT PORTC,ATOD ; count value for 2.5 V ref +; LDI A,$FF +; MOV DD16UH,A ; divide by full scale ie VSWT +; SUB DD16UL,DD16UL ; clear low reg +; SUB DV16UH,DV16UH ; clear high reg divisor +; MOV DV16UL,ATOD ; use ATOD value as divisor +; ;OUT PORTC,ATOD +; RCALL DIVIDE ; ***** NOTE AN FF RESULT IS NO INPUT ******* +; MOV MC16UH,DRES16UH ; load multiplicand high from result high +; MOV MC16UL,DRES16UL ; load multiplicand low from result low +; SUB MP16UH,MP16UH ; clear high byte in multiplier reg +; LDI A,25 +; MOV MP16UL,A ; mult by zener ref voltage (2.5V) +; RCALL MULTIPLY +;DIAG_VOLT_VSWT: +;xi: +; LDS A,VSWTS ; previous value of VSWT +; MOV B,MP16UL ; new value of VSWT +; ;RCALL SMOOTH +; STS VSWTS,B +; LDS B,VSWTS +; +; ;OUT PORTC,B;M16U1 ; VSWT IN 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; +; ;STS VSWTS,B ; SAVE NEW SMOOTHED VALUE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; MOV B,M16U1 ; save copy of VSWT for neg 5V routine +; MOV DD16UH,M16U1 +; SUB DD16UL,DD16UL +; LDI A,255 ; calculate the atod volts per division +; MOV DV16UL,A +; SUB DV16UH,DV16UH +; RCALL DIVIDE ; result to be found in dres high & low +; +; LDI A,3 +; OUT ADMUX,A ; NEXT TIME READ VCHG +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;VCHG: +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 37 (1/3 VCHG) +; RCALL MULTIPLY +; MOV A,M16U1 +; ADD M16U1,A ; B\C A3 IS 1/3 VCHG +; ADD M16U1,A +;DIAG_VOLT_VHG: +; ;OUT PORTC,M16U1 ; REUSULT 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; LDI A,5 +; OUT ADMUX,A ; NEXT TIME READ VSWT +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;;*************************************************************************** +;;* +;;* "div16u" - 16/16 Bit Unsigned Division +;;* +;;* This subroutine divides the two 16-bit numbers +;;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). +;;* The result is placed in "dres16uH:dres16uL" and the remainder in +;;* "drem16uH:drem16uL". +;;* +;;* Number of words :19 +;;* Number of cycles :235/251 (Min/Max) +;;* Low registers used :2 (drem16uL,drem16uH) +;;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, +;;* dcnt16u) +;;* +;;*************************************************************************** +;divide: +;div16u: clr drem16uL ;clear remainder Low byte +; sub drem16uH,drem16uH ;clear remainder High byte and carry +; ldi counter,17 ;init loop counter +;d16u_1: rol dd16uL ;shift left dividend +; rol dd16uH +; dec counter ;decrement counter +; brne d16u_2 ;if done +; ret ; return +;d16u_2: rol drem16uL ;shift dividend into remainder +; rol drem16uH +; sub drem16uL,dv16uL ;remainder = remainder - divisor +; sbc drem16uH,dv16uH ; +; brcc d16u_3 ;if result negative +; add drem16uL,dv16uL ; restore remainder +; adc drem16uH,dv16uH +; clc ; clear carry to be shifted into result +; rjmp d16u_1 ;else +;d16u_3: sec ; set carry to be shifted into result +; rjmp d16u_1 +; +;;********* 16 X 16 multiplication routine from app note avr200 ************* +;;* +;;* "mpy16u" - 16x16 Bit Unsigned Multiplication +;;* +;;* This subroutine multiplies the two 16-bit register variables +;;* mp16uH:mp16uL and mc16uH:mc16uL. +;;* The result is placed in m16u3:m16u2:m16u1:m16u0. +;;* +;;* Number of words :14 + return +;;* Number of cycles :153 + return +;;* Low registers used :None +;;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, +;;* m16u3,mcnt16u) +;;* +;;*************************************************************************** +;multiply: +;mpy16u: clr m16u3 ;clear high byte of result +; sub m16u2,m16u2 ;clear result byte 2 and carry +; clr m16u2 +; ldi counter,16 ;init loop counter +; lsr mp16uH +; ror mp16uL +; +;m16u_1: brcc noad8 ;if bit 0 of multiplier set +; add m16u2,mc16uL ;add multiplicand Low to byte 2 of res +; adc m16u3,mc16uH ;add multiplicand high to byte 3 of res +;noad8: ror m16u3 ;shift right result byte 3 +; ror m16u2 ;rotate right result byte 2 +; ror m16u1 ;rotate result byte 1 and multiplier High +; ror m16u0 ;rotate result byte 0 and multiplier Low +; dec counter ;decrement loop counter +; brne m16u_1 ;if not done, loop more +; ret +;;************************* Exponential smoothing routine ******************** +;;Receives : Previous value in A +;; : New value in B +;;Passes : Smoothed result back in B reg +;;Uses : d reg +; +;Smooth: +; mov d,a ; save a copy of previous value +; lsr a +; lsr a +; lsr b +; lsr b ; prev.ave - prev.ave + new.data +; sub d,a ; -------- -------- +; add b,d ; n n +; ret + +; ----------------------------------------------------------------------------- + +MESSAGE_0: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',0,128,$1B + .DB 'E','1' + +MESSAGE_1: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',240,64,$1B + .DB 'E','1' + +MESSAGE_2: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','0','0','0',0 + +MESSAGE_3: + .DB $1B,'S',16,13 + .DB 'W','P','O','3','0',' ','V','5' + +MESSAGE_4: + .DB $1B,'S',16,13 + .DB 'B','A','D',' ','C','O','M','M','A','N','D',0 + +MESSAGE_5: + .DB $1B,'S',16,13 + .DB 'B','A','T','T','E','R','Y',' ','L','O','W',0 + +MESSAGE_6: + .DB $1B,'M','0',0 + +MESSAGE_7: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','5','0','0',0 + +MESSAGE_8: + .DB $1B,'S',16,13 + .DB 'S','T','A','C','K',' ','O','V','E','R','F','L','O','W' + +; ----------------------------------------------------------------------------- + + .ORG $1000 + +;IF LARGE (THE ORIGINAL WPO15V1.HEX SETTINGS) +; .DW $4100 ; SELECT ADDRESS COMMAND +; ; FSTRT = 0 FOR 1.1 MS R/C STARTUP DELAY +; ;.DW $ACBE ; WRITE FUSE BITS COMMAND +;; BIGBODGE (NOT REALLY - JUST IN CASE TYPE OF CHANGE) +;; FSTRT = 1 FOR 16 MS R/C STARTUP DELAY +; .DW $ACBF ; WRITE FUSE BITS COMMAND +;ELSE + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 100 FOR 16K * 11MHZ STARTUP DELAY (NO R/C STARTUP DELAY) + + .DW $4100 ; SELECT ADDRESS COMMAND + .DW $ACBC ; WRITE FUSE BITS COMMAND +;ENDIF + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/WPOV3.HEX b/src/avr/WPOV3.HEX new file mode 100644 index 00000000..81259fa7 --- /dev/null +++ b/src/avr/WPOV3.HEX @@ -0,0 +1,146 @@ +:020000020000FC +:020000000BC033 +:06000C00F7C118C37EC11C +:10001600DAC30FED0DBF00E808B9A8950FE001BDE2 +:100026000AE50093CB0000E00DB90AB9C59ABC9A5F +:100036008D9A8E9A929A939AC19AB99AC098B898BC +:1000460097988F9A94988C9AAA98A29A9198899A36 +:1000560007E01DD106E01BD105E019D104E017D158 +:1000660001E015D100E013D107E109B908E10AB9A9 +:100076003CD10AEA0CB90CB93BD1949A39D194987F +:1000860037D1949A0027E0E6FF2701930193019365 +:10009600EEEA019301930193019301930193019376 +:1000A60001930093AB000093C9000093AC0000934A +:1000B600AD0000E2019300270193019301930193A0 +:1000C60001930193019301930FE00193019301932F +:1000D6000193019301930193008300E00093C7000D +:1000E60004E00093C8004427662711248824992435 +:1000F600AA2455246624772401E00093A3000093E4 +:10010600A4000093A5000093A6000093A700009307 +:10011600A8000093CA0000E00093A9000093AA007B +:100126000CEF202E0FEF402E01E0B02E03BF02E0B1 +:1001360009BF0EB10FB108EE0DB900E00DBD0CBD43 +:100146000BBD0ABD01EC0FBD01E00EBD05E007B910 +:100156000EED06B9789402E01EE1E8E4F8E0A8D0D6 +:100166000091CB000A3509F066C041FD6FC043FD22 +:100176007AC040FFF5CF0091CA00033041F002304B +:1001860091F002E01FE0E4E8F8E092D006C002E059 +:100196001FE0E4ECF8E08CD000C003E01EE1E6E6E8 +:1001A600F8E086D00FC002E01CE0E4E9F8E080D079 +:1001B60003E01EE1E8E4F8E07BD003E01CE0E4E9BC +:1001C600F8E076D01CD00B3109F0FCCF18D00434FF +:1001D60009F0F8CF14D0037039F0013039F002304D +:1001E60039F0033039F0EECF969A05C0969803C0E1 +:1001F600959A01C0959810E3100FE4CF789400917A +:10020600CB000A35C1F441FD21C043FD2CC0F89452 +:100216009920A1F30091A300093081F7EF93FF9392 +:10022600E82DED59FF2700819A948394EFE18E2201 +:10023600FF91EF91189502E01EE1E8E4F8E038D06E +:1002460002E01FE0E4EDF8E033D00AC002E01EE170 +:10025600E8E4F8E02DD002E01FE0E0EAF8E028D07C +:1002660043FD01C0FDCF02E01EE1E8E4F8E020D046 +:1002760002E01FE0E0EBF8E01BD00AEF39D00A9568 +:10028600E9F702E013E0E0ECF8E012D0F6CFAA9826 +:1002960002FF919802FD919A2BD001FF919801FDE2 +:1002A600919A28D000FF919800FD919AAA9A24C0AD +:1002B60078940000F8949920D9F7AA20C9F70093FA +:1002C600A400C895002D04D031961A95D1F718953B +:1002D600EF93FF93E92DEA0DE80DEF71ED59FF2736 +:1002E6000083FF91EF91A3940895E0EFFAE006C032 +:1002F600E8EC03C0E4E101C0E2E0F0E020E02A958A +:10030600F1F73197E1F70895FFB666FD22C03CB1DB +:100316003125F2F0312552F0EF93FF93EDEAF0919B +:10032600A300EF0FFF273083FF91EF91131608F01C +:10033600132E6F7E6064312D3F7741F011202AF134 +:1003460057986F7D3FEF232E606153C03CEF4DC041 +:100356004BC03091A600313019F033E03093AA003B +:100366003CB1EF93FF93E62DE70DE50DEF71ED57E9 +:10037600FF273083E091A500F091A600EF1711F456 +:10038600639401C07394FF91EF913FEF232E1A946B +:1003960072F53091A600323030EF09F03AEF232E95 +:1003A600606127C033E03093A900EF93FF93EDEA35 +:1003B6007091A300E70FFF2730813A953083E82D2F +:1003C600ED59FF273081FF91EF913CB93695330BFC +:1003D6003A95723009F430EF232E9A9483943FE1D4 +:1003E60083221A9431F403C03AEF232E6F7E579876 +:1003F6006F79FFBE1895FFB630E032BF32E038BFE6 +:10040600BA94B1F438E0B32E3091AC007091AD00DF +:10041600732B49F031503093AC003091AD00304031 +:100426003093AD0059F0442019F0439409F4B89A7A +:10043600222011F0239419F1FFBE1895EACD67FD2D +:1004460012C0890C3FE1832299249092A900EF9370 +:10045600FF93EDEAF091A300EF0FFF2730E2308320 +:10046600FF91EF9112C0EF93FF93EEEBF091A60090 +:10047600EF0FFF273FE03083FF91EF9106C065FD48 +:10048600DECF66FD8FCF64FD8CC03EEE232E30910D +:10049600AB00332359F03A953093AB0031F0AA986C +:1004A6009198899A30E03AB9A4CFB3CD579837E1FD +:1004B60039B93091AA00332329F43091A90039299A +:1004C6003A2939F43091A7003A9549F03093A700BC +:1004D60037C03091A8003A9591F03093A80030E1EA +:1004E6003093A70099203091A30041F4AA2041F04F +:1004F6009A2CAA243091A4003093A300393001F13C +:100506006F779920B9F4AA2059F43091A9003A9549 +:1005160042F43091A3003395393048F031E007C0FA +:1005260033E03093A9009A2CAA243091A40030938A +:10053600A30033C033E03093A9003091A3002DC04F +:1005460030E13093A80060683091A600772029F545 +:100556007091AA00772321F07A957093AA001DC0A6 +:10056600EF93FF93E7EBFF273191E093A60071919C +:1005760073171AF4372FE093A6007FEBE713F7CF34 +:10058600E091A600379670813897370F30833E2F5B +:10059600365BFF91EF913093A6003CB960616F79AD +:1005A60028CF30E039B967FD13C07091A3007230CF +:1005B60030EF09F03AEF232E392D723011F07730F3 +:1005C60031F4332321F0305108F430E0339513C071 +:1005D6007091A600723030EF09F03AEF232E30E228 +:1005E60036193719773031F4332321F0305108F4B6 +:1005F60030E0339530683CB9132E579A3CB16062AF +:10060600F8CE732F3F70A9F1393098F5729577704F +:10061600743050F07395763038F07395783020F05A +:100626007D5F7C3008F07FE0EF93FF93EEEBE30F06 +:10063600FF277083FF91EF91C2C0FFB6B8983FB114 +:1006460062FD8FC060FD5FC061FD58C03A3098F111 +:100656003038B8F299F0313899F03139A1F03239A1 +:1006660091F0333981F0353A99F03A3AE1F0353C78 +:10067600D9F030E03DB944244260A3C097989FC0AA +:100686004160979A9CC030593093CA00416097C028 +:100696003FEF3093AB0030E03DB994983FEF70E008 +:1006A6007BBD3ABD8CC0B5CC38EE3093AC0033E0A0 +:1006B6003093AD0084C0332379F46860662049F432 +:1006C6007720C1F0672C77243090A6003092A500E1 +:1006D60012C03090A5000FC0677F332EAA2021F0EC +:1006E6003091A400331531F433E03093A9003092F1 +:1006F600A40001C033243FB8626061C06D7F33201F +:1007060009F061605CC0332E6E7F332063FF05C045 +:100716005AF5362D30681FC051C0F2F3EF93FF93A0 +:10072600EDEAF091A400EF0FFF273081E091A300DE +:10073600F091A400EF1731F0E0E2E9193E1730F02E +:100746003E2F04C0303208F030E239193A19FF91D1 +:10075600EF910AF43FE7331508F4332E3FB964608E +:100766002EC033208AF43A944AF56160EF93FF93E2 +:10077600E52DED57FF2730813FB9FF91EF916A9440 +:1007860053943FE153221BC060FF14C0EF93FF93C5 +:10079600E92DEA0DE80DEF71ED59FF273083E09161 +:1007A600A300F091A400EF1711F4939401C0A39451 +:1007B600FF91EF913A9412F0616001C06B7F3FEFB9 +:1007C600432EFFBE1895FFB6A89534B1532F35B109 +:1007D600379557953795579544FD12C0406130912E +:1007E600AB00332331F530E070E05C5100F130E6C8 +:1007F60070E05038E0F45695352F5695350F17C0F2 +:100806004F7E5093C900583A30E074E058F4309166 +:10081600C7007091C8003150704021F430E03DB9F6 +:10082600442448603093C7007093C80002C07BBD63 +:100836003ABD34E044FF35E037B93EED36B9FFBE88 +:1008460018951B44301B47301B50311B45301B4B42 +:100856001B301B2F301B5300001B4E00801B4531E5 +:100866001B44301B47301B50311B45301B4B1B3084 +:100876001B2F301B5300001B4EF0401B45311B53F2 +:10088600100D4859544543482031303030001B5331 +:10089600100D57504F33302056351B53100D424123 +:1008A6004420434F4D4D414E44001B53100D4241D1 +:1008B6005454455259204C4F57001B4D30001B5382 +:1008C600100D4859544543482031353030001B53EC +:1008D600100D535441434B204F564552464C4F57EB +:042000000041BCAC33 +:00000001FF diff --git a/src/avr/a.bat b/src/avr/a.bat new file mode 100644 index 00000000..b19434ec --- /dev/null +++ b/src/avr/a.bat @@ -0,0 +1 @@ +tavrasm -a %1.asm -e %1.lst diff --git a/src/avr/a_avra.bat b/src/avr/a_avra.bat new file mode 100644 index 00000000..ab516ae2 --- /dev/null +++ b/src/avr/a_avra.bat @@ -0,0 +1 @@ +avra -fI %1.asm diff --git a/src/avr/a_orig.bat b/src/avr/a_orig.bat new file mode 100644 index 00000000..479cc0e2 --- /dev/null +++ b/src/avr/a_orig.bat @@ -0,0 +1 @@ +AVRASM %1.ASM %1.LST %1.HEX diff --git a/src/avr/aa.bat b/src/avr/aa.bat new file mode 100644 index 00000000..24781e5c --- /dev/null +++ b/src/avr/aa.bat @@ -0,0 +1 @@ +c:\bin\diff --ignore-case --ignore-file-name-case --ignore-tab-expansion --ignore-space-change --ignore-blank-lines --text --unified --minimal --new-file --speed-large-files %1.asm %2.asm > %1-%2.diff \ No newline at end of file diff --git a/src/avr/api.inc b/src/avr/api.inc new file mode 100644 index 00000000..92a8af6f --- /dev/null +++ b/src/avr/api.inc @@ -0,0 +1,270 @@ +; API.INC + +; ----------------------------------------------------------------------------- +; API BUS FOREGROUND TASK + +.MACRO INT_HANDLERS + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER +.ENDMACRO + +.MACRO INIT_API_BUS + LDI A,API_RATE_SLOW ; 4800 BPS + OUT UBRR,A ; SET UART RATE + + LDI A,$90 ; ENABLE RX WITH INTERRUPTS + OUT UCR,A + ;SBI UCR,TXEN ; TX ENABLE + + CLR TX_PTR + CLR TX_COUNT + + CLR RX_PTR + CLR RX_COUNT + + CLR API_STATE + CLR API_REMAIN + CLR API_WATCHDOG +.ENDMACRO + +.MACRO MRX_WAIT + TST RX_COUNT + BREQ RX_WAIT +.ENDMACRO + +.MACRO MRX_CHAR + PUSH YL + PUSH YH + + MOV YL,RX_PTR + SUBI YL,-RX_BUF + CLR YH + LD A,Y + + CLI + DEC RX_COUNT + INC RX_PTR + LDI YL,RX_SIZE-1 + AND RX_PTR,YL + SEI + + POP YH + POP YL + RET +; FALL INTO MTX_WAIT FOR LOOPBACK TEST +.ENDMACRO + +.MACRO MTX_WAIT + PUSH A +TX_WAIT_LOOP: + MOV A,TX_COUNT + CPI A,TX_SIZE + BRSH TX_WAIT_LOOP + POP A +.ENDMACRO + +.MACRO MTX_CHAR + PUSH YL + PUSH YH + IN YH,SREG + CLI + MOV YL,TX_COUNT + ADD YL,TX_PTR + OUT SREG,YH ;SEI + ANDI YL,TX_SIZE-1 + SUBI YL,-TX_BUF + CLR YH + ST Y,A + + INC TX_COUNT + + POP YH + POP YL + RET +.ENDMACRO + +; ----------------------------------------------------------------------------- +; API BUS BACKGROUND TASK + +.MACRO MTX_EMPTY + IN SR,SREG + PUSH F + + LDI F,-API_TIMEOUT ; FEED TX/RX WATCHDOG + MOV API_WATCHDOG,F + + PUSH ZL + PUSH ZH + MOV ZL,TX_PTR + SUBI ZL,-TX_BUF + CLR ZH + LD F,Z ; GET CHARACTER FROM TX BUFFER + POP ZH + POP ZL + + OUT UDR,F + + DEC TX_COUNT + INC TX_PTR + LDI F,TX_SIZE-1 + AND TX_PTR,F + + DEC API_REMAIN ; MORE TO SEND? + BRMI GO_API_DONE1 ; YES, AWAIT NEXT TX EMPTY INTERRUPT + RJMP API_REINIT ; NO, AWAIT NEXT DATA SIZE COMMAND +GO_API_DONE1: + RJMP API_DONE +.ENDMACRO + +.MACRO MRX_COMPLETE + IN SR,SREG + PUSH F + + LDI F,-API_TIMEOUT ; FEED TX/RX WATCHDOG + MOV API_WATCHDOG,F + + IN F,UDR + SBIC USR,FE ; BREAK DETECTED? + RJMP API_FRAMING_ERROR + + SBRC API_STATE,APIDATA + RJMP API_RX_DATA ; WITH F = CHARACTER + SBRC API_STATE,APISIZE + RJMP API_DATA_SIZE ; WITH F = CHARACTER + + ; RECEIVED 4800 BPS ADDRESS COMMAND + CPI F,API_ADDRESS ; CHARACTER = MY ADDRESS? + BRNE API_ADDRESS_DONE + + LDI F,API_RATE_FAST ; 115200 BPS + OUT UBRR,F ; SET UART RATE + + SBI UCR,TXEN ; ENABLE UART TX AND TXD PIN + + LDI F,1<1?rbdDE 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 INCR TO 18 CYCLES PER + +; ALSO FOUND EXCESSIVE JITTER IN TEMP MEASUREMENT PARTLY DUE TO SERVO +; ONTO SIGNAL EDGE AND PARTLY TO 33MHZ NOISE ON THERMISTOR => FIX TIMING, +; AND PACE DATA OUTPUT (SOME PROBLEM STILL REMAINS) + +; ALSO HAD STACK OVERFLOW => REORDER SRAM VARIABLES + + +.INCLUDE "4433DEF.INC" ; FOR AVR ASSEMBLER +;.INCLUDE "4433DEFX.INC" ; FOR NICK ASSEMBLER +.INCLUDE "MACLC.INC" +;.INCLUDE "APILC.INC" +.INCLUDE "TERLC.INC" + +; WE SHOULD CHANGE THE CODE TO USE UCSRA AND UCSRB +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU RAM =$60 ; START OF SRAM +.EQU CR =$0D +.EQU LF =$0A +.EQU RX_SIZE =1 +.EQU TX_SIZE =8 ; LEAVES 10 BYTES FREE +.EQU API_ADDRESS =$01 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU CYC_MAX =256 ; MAXIMUM WEIGHING CYCLE TIME +.EQU CYC_MIN =160 ; MINIMUM WEIGHING CYCLE TIME > 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +;MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 +DSPRES: .BYTE 4 +ZROGMS: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +DSPGMS: .BYTE 4 ; MOVED 02JUL01 +LSTGMS: .BYTE 4 ; MOVED 17MAY01 +LSTDEV: .BYTE 4 ; MOVED 17MAY01 +AVESTD: .BYTE 4 ; MOVED 17MAY01 +AVEGMS: .BYTE 4 ; MOVED 17MAY01 + +.ESEG +.ORG $000 ; ALL CONSTANTS IN IEEE754 FORMAT +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 DEFAULT TO 1 +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +;K0: .DB $00,$00 ; 0.000000E+00 +;K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 DON'T MOVE! +;K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 +HYSCNF: ;.DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 +;K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +CNFHYS: ;.DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +;K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K228: .DB $39,$8E,$63,$43 ; 2.275556E+02 = 256*16/18 REVISED 17MAY01 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +; CHARACTERIZE ONLY % +K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +FMAT3: .DB 6,0 + .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: + OUTI SPL,RAMEND ; INIT STACK POINTER + OUTI ACSR,$80 ; POWER DOWN ANALOG COMPARATOR + +; SBI DDRB,5 ; SET SK TO OUTPUT FOR DIAGNOSTICS + + SBI DDRD,2 ; SET BIT 2 TO OUTPUT FOR TEMP SENSOR + SBI DDRD,3 ; SET BIT 3 TO OUTPUT FOR TILT SENSOR + + OUTI TCCR1B,1 ; SET COUNTER1 TO CLOCK AT 11.0592 MHZ + ; AND INPUT CAPTURE ON FALLING EDGE +; OUTI MCUCR,2 ; SET INT0 FALLING EDGE FOR TEMP SENSOR + OUTI MCUCR,0 ; SET INT0 LOW SENSE FOR TEMP SENSOR + ; 17MAY01 BOMBS GRACEFULLY AT EACH EXTREME + + CLR CYC_0 + CLR CYC_1 + + CLR A + STS RANGE,A + RCALL STS_STATUS_A + STS STARTUP,A + STS TMP_PHASE,A + + ;LDER A,EEMODE +; CHARACTERIZE ONLY % + LDI A,$F0 +; % + STS MODE,A + +; WEIGHING ONLY % +; LDI A,1 +; STS MODE_CYCLE,A +; % + + FLDF K1 + FST DSPRES + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST LSTGMS + FST LSTDEV + FST AVEGMS + FST AVESTD + FST INTGMS +; CHARACTERIZE ONLY % + FST WGTFRQ ; MAY NOT BE NECESSARY + FST REF_30MHZ ; NECESSARY +; % + + INIT_API_BUS ; SET UART RATE AND CLEAR FLAGS/PTRS + + IN A,TIMSK + ORI A,8 ; ENABLE INTERRUPT ON T1 INPUT CAPTURE + OUT TIMSK,A + + WDR ; RESET WATCHDOG + OUTI WDTCR,1< E +; RCALL SNDSTR + +LOOP: ; MAIN PROGRAM + ; IF THE INTERRUPT ALREADY CAME, + ; THROW AWAY THE DATA AND WAIT FOR A NEW ONE + CBR FLAGS,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) + FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD +; WEIGHING ONLY % +; LDI F,AVESTD +; % RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST + FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST INTGMS ; INTGMS=0 + RCALL LDS_A_STATUS + CBR A,1<= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE + FML DSPRES ; DISPLAY RESOLUTION + ; % +; WEIGHING ONLY % +; FST DSPGMS + +STB5: +; ;LDS A,MODE ; IF NOT WEIGHING MODE +; ;SBRS A,DSPGMS_FLG +; ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS +; +; LDI E,CYC_MIN*2/3 +; RCALL TX_WAIT_EMPTY +; BRCS FMT +; RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE +; +;FMT: RCALL LDS_A_STATUS +; SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? +; RJMP SKIP_SN +; +; CBR A,1<=0 +; BRPL FMT2 ; THEN CONTINUE +;; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) +; INC E ; INC " -LO-" COUNTER (STARTUP) +; CPI E,CYC_START+8 ; IF STARTUP E +; ;RCALL SNDSTR +; ;LDI A,'0' +; ;RCALL TX_WAIT +; ;RJMP DSP8 +; ; % +; RJMP DSP7 +;FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" +; BRCS FMT3 +; LDI E,CYC_START ; THEN STARTUP=CYC_START +; STS STARTUP,E +;FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX +; BRCS FMT4 +; SBR F,1< E +; LDFL D,FMAT0 ; " 0.000" +; ADIW ZL,2 +;DSP2: CP F,D +; BRCC DSP4 +;DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 +; BREQ DSP8 ; WHEN ALL DONE +; CPI D,4 +; BRNE DSP2 +; DEC F ; TO COMPENSATE FOR EXTRA DEC C +; RJMP DSP3 ; DO DECIMAL PT +;DSP4: +; ; FOR TENTHS OF GRAMS % +; ;INC F +; ; % +; RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +;DSP5: DEC F +; BREQ DSP8 +; CPI F,4 +; ; FOR TENTHS OF GRAMS % +; ;CPI F,5 +; ; % +; BRNE DSP6 +; LDI A,'.' +; RCALL TX_WAIT +; DEC F +;DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP DSP5 +;DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR +;DSP8: +;; ASCII STABILITY INDICATION FOR TESTING % +;; LDI A,' ' +;; RCALL TX_WAIT +;; RCALL LDS_A_STATUS +;; ANDI A,1< 1 SECOND ? + BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION + + FSBF K33M + FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE + + SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL STS_FA ; AND SAVE +SMTH0: RET + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % +; INC FA3 ; CHECK FOR NAN +; BRNE SND0 +; DEC FA3 ; TO COMPLY WITH IEEE754 +;SND0: DEC FA3 +; ROL FA2 ; CONVERT TO IEEE754 +; ROR FA3 +; ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % +; LDS B,MODE_CYCLE +; AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + +; WEIGHING ONLY % +; LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL TX_WAIT_EMPTY +; BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM +; % + +SNDFPX: +; CHARACTERIZE ONLY % + SBRS FLAGS,SNDDAT + RET + CPI A,$80 + LDI A,$0A + BRNE SEPOK + LDI A,$0D +SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % +; LDI A,$1B +; RCALL TX_WAIT +; MOV A,F ; INDICATE WHICH DATA IS BEING SENT +; RCALL TX_WAIT +;;SND_FA: +; LDI XL,FA ; LOAD TX BUFFER +; LDI D,4 +;SND1: LD A,X+ +; RCALL TX_WAIT ; LS BYTE FIRST +; DEC D +; BRNE SND1 +; RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -48 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION < +16 + BRLO CORRECTION_OK + PUSH A + LDS A,TX_COUNT + CPI A,TX_SIZE + BRSH SKIP_DOLLAR + LDI A,'$' + RCALL TX_CHAR +SKIP_DOLLAR: + POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + + CLI ; 17MAY01 + LDS G,TMP_PHASE ; START TEMPERATURE MEASUREMENT % + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT TO SYNCHRONISE SUBSEQUENT INT0 + BRNE TMP0 + +; CLI + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT + IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + ; 17MAY01 MOVED: +; SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO +; SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT +; LDI G,$40 ; SHIFTED TO LATER +; OUT GIFR,G ; CLEAR PENDING INT0 RESULTING FROM +; OUT GIMSK,G ; ACTIVITY ON PIN, AND ENABLE INT0 + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP +; CBI PORTB,5 ; FOR TESTING ONLY + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<

=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA:LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA:LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +SNDEXP: + PUSH A ; SEPARATOR + FMLF K30M ; CONVERT TO HERTZ + RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +EXP5: FCPF KR0001 ; IF N<.0001 + BRCC EXP6 + FMLF K100K ; THEN N=N*100K + SUBI F,5 ; E=E-5 + RJMP EXP5 +EXP6: FCPF K1 ; IF N<1 + BRCC EXP7 + FMLF K10 ; THEN N=N*10 + SUBI F,1 ; E=E-1 + RJMP EXP6 +EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 + RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 + RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT + LDI A,'.' + RCALL TX_WAIT + LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + DEC E + BRNE EXP8 + LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY + RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION + LDI A,'0' + RCALL TX_WAIT + LDI A,'E' ; NOW FOR THE EXPONENT + RCALL TX_WAIT + LDI A,'+' ; SEND SIGN + TST F + BRPL EXP9 + LDI A,'-' + NEG F ; ABS(E) +EXP9: RCALL TX_WAIT + LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +EXP10: INC A + SUBI F,10 + BRPL EXP10 + RCALL TX_WAIT + LDI A,'0'+10 ; NOW LS DIGIT + ADD A,F + RCALL TX_WAIT + POP A + RCALL TX_WAIT ; SEPARATOR +EXP11: FLD F0 ; AND RESTORE FA + RET + +EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 + LDI A,' ' ; SEND SIGN (SPACE FOR +) + TST FA2 + BRPL EXP1 + LDI A,'-' +EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT +; FMLF K_1 ; LET'S BE SAFE KILLED 17MAY01 +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS + RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1< INCR TO 18 CYCLES PER + +; ALSO FOUND EXCESSIVE JITTER IN TEMP MEASUREMENT PARTLY DUE TO SERVO +; ONTO SIGNAL EDGE AND PARTLY TO 33MHZ NOISE ON THERMISTOR => FIX TIMING, +; AND PACE DATA OUTPUT (SOME PROBLEM STILL REMAINS) + +; ALSO HAD STACK OVERFLOW => REORDER SRAM VARIABLES + +; ATmega8: +.INCLUDE "MEGA8DEF.INC" ; FOR AVR ASSEMBLER +;.INCLUDE "4433DEFX.INC" ; FOR NICK ASSEMBLER +.INCLUDE "MACLC.INC" +;.INCLUDE "APILC.INC" +; ATmega8: +.INCLUDE "TERLC8.INC" + +; WE SHOULD CHANGE THE CODE TO USE UCSRA AND UCSRB +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU RAM =$60 ; START OF SRAM +.EQU CR =$0D +.EQU LF =$0A +.EQU RX_SIZE =1 +.EQU TX_SIZE =8 ; LEAVES 10 BYTES FREE +.EQU API_ADDRESS =$01 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU CYC_MAX =256 ; MAXIMUM WEIGHING CYCLE TIME +.EQU CYC_MIN =160 ; MINIMUM WEIGHING CYCLE TIME > 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +;MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 +DSPRES: .BYTE 4 +ZROGMS: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +DSPGMS: .BYTE 4 ; MOVED 02JUL01 +LSTGMS: .BYTE 4 ; MOVED 17MAY01 +LSTDEV: .BYTE 4 ; MOVED 17MAY01 +AVESTD: .BYTE 4 ; MOVED 17MAY01 +AVEGMS: .BYTE 4 ; MOVED 17MAY01 + +.ESEG +.ORG $000 ; ALL CONSTANTS IN IEEE754 FORMAT +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 DEFAULT TO 1 +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR ; NOT USED IN CHARACTERIZE MODE + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +;K0: .DB $00,$00 ; 0.000000E+00 +;K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 DON'T MOVE! +;K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 +HYSCNF: ;.DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 +;K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +CNFHYS: ;.DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +;K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K228: .DB $39,$8E,$63,$43 ; 2.275556E+02 = 256*16/18 REVISED 17MAY01 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +; CHARACTERIZE ONLY % +K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +FMAT3: .DB 6,0 + .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: +; ATmega8: + OUTI SPL,LOW(RAMEND) ; INIT STACK POINTER + OUTI SPH,HIGH(RAMEND) + OUTI ACSR,$80 ; POWER DOWN ANALOG COMPARATOR + +; SBI DDRB,5 ; SET SK TO OUTPUT FOR DIAGNOSTICS + + SBI DDRD,2 ; SET BIT 2 TO OUTPUT FOR TEMP SENSOR + SBI DDRD,3 ; SET BIT 3 TO OUTPUT FOR TILT SENSOR + + OUTI TCCR1B,1 ; SET COUNTER1 TO CLOCK AT 11.0592 MHZ + ; AND INPUT CAPTURE ON FALLING EDGE + OUTI MCUCR,0 ; SET INT0 LOW SENSE FOR TEMP SENSOR + ; 17MAY01 BOMBS GRACEFULLY AT EACH EXTREME + + CLR CYC_0 + CLR CYC_1 + + CLR A + STS RANGE,A + RCALL STS_STATUS_A + STS STARTUP,A + STS TMP_PHASE,A + + ;LDER A,EEMODE +; CHARACTERIZE ONLY % + LDI A,$F0 +; % + STS MODE,A + +; WEIGHING ONLY % +; LDI A,1 +; STS MODE_CYCLE,A +; % + + FLDF K1 + FST DSPRES + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST LSTGMS + FST LSTDEV + FST AVEGMS + FST AVESTD + FST INTGMS +; CHARACTERIZE ONLY % + FST WGTFRQ ; MAY NOT BE NECESSARY + FST REF_30MHZ ; NECESSARY +; % + + INIT_API_BUS ; SET UART RATE AND CLEAR FLAGS/PTRS + + IN A,TIMSK +; ATmega8: +; ORI A,8 ; ENABLE INTERRUPT ON T1 INPUT CAPTURE + SBR A,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) + FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD +; WEIGHING ONLY % +; LDI F,AVESTD +; % RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST + FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST INTGMS ; INTGMS=0 + RCALL LDS_A_STATUS + CBR A,1<= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE + FML DSPRES ; DISPLAY RESOLUTION + ; % +; WEIGHING ONLY % +; FST DSPGMS + +STB5: +; ;LDS A,MODE ; IF NOT WEIGHING MODE +; ;SBRS A,DSPGMS_FLG +; ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS +; +; LDI E,CYC_MIN*2/3 +; RCALL TX_WAIT_EMPTY +; BRCS FMT +; RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE +; +;FMT: RCALL LDS_A_STATUS +; SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? +; RJMP SKIP_SN +; +; CBR A,1<=0 +; BRPL FMT2 ; THEN CONTINUE +;; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) +; INC E ; INC " -LO-" COUNTER (STARTUP) +; CPI E,CYC_START+8 ; IF STARTUP E +; ;RCALL SNDSTR +; ;LDI A,'0' +; ;RCALL TX_WAIT +; ;RJMP DSP8 +; ; % +; RJMP DSP7 +;FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" +; BRCS FMT3 +; LDI E,CYC_START ; THEN STARTUP=CYC_START +; STS STARTUP,E +;FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX +; BRCS FMT4 +; SBR F,1< E +; LDFL D,FMAT0 ; " 0.000" +; ADIW ZL,2 +;DSP2: CP F,D +; BRCC DSP4 +;DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 +; BREQ DSP8 ; WHEN ALL DONE +; CPI D,4 +; BRNE DSP2 +; DEC F ; TO COMPENSATE FOR EXTRA DEC C +; RJMP DSP3 ; DO DECIMAL PT +;DSP4: +; ; FOR TENTHS OF GRAMS % +; ;INC F +; ; % +; RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +;DSP5: DEC F +; BREQ DSP8 +; CPI F,4 +; ; FOR TENTHS OF GRAMS % +; ;CPI F,5 +; ; % +; BRNE DSP6 +; LDI A,'.' +; RCALL TX_WAIT +; DEC F +;DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP DSP5 +;DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR +;DSP8: +;; ASCII STABILITY INDICATION FOR TESTING % +;; LDI A,' ' +;; RCALL TX_WAIT +;; RCALL LDS_A_STATUS +;; ANDI A,1< 1 SECOND ? + BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION + + FSBF K33M + FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE + + SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL STS_FA ; AND SAVE +SMTH0: RET + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % +; INC FA3 ; CHECK FOR NAN +; BRNE SND0 +; DEC FA3 ; TO COMPLY WITH IEEE754 +;SND0: DEC FA3 +; ROL FA2 ; CONVERT TO IEEE754 +; ROR FA3 +; ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % +; LDS B,MODE_CYCLE +; AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + +; WEIGHING ONLY % +; LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL TX_WAIT_EMPTY +; BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM +; % + +SNDFPX: +; CHARACTERIZE ONLY % + SBRS FLAGS,SNDDAT + RET + CPI A,$80 + LDI A,$0A + BRNE SEPOK + LDI A,$0D +SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % +; LDI A,$1B +; RCALL TX_WAIT +; MOV A,F ; INDICATE WHICH DATA IS BEING SENT +; RCALL TX_WAIT +;;SND_FA: +; LDI XL,FA ; LOAD TX BUFFER +; LDI D,4 +;SND1: LD A,X+ +; RCALL TX_WAIT ; LS BYTE FIRST +; DEC D +; BRNE SND1 +; RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -16 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION > +5 + BRLO CORRECTION_OK + PUSH A + LDS A,TX_COUNT + CPI A,TX_SIZE + BRSH SKIP_DOLLAR + LDI A,'$' + RCALL TX_CHAR +SKIP_DOLLAR: + POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + +; ATmega8: + POP J + POP K + + CLI ; 17MAY01 + LDS G,TMP_PHASE ; START TEMPERATURE MEASUREMENT % + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT TO SYNCHRONISE SUBSEQUENT INT0 + BRNE TMP0 + +; CLI + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT +; ATmega8: +; IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + IN G,GICR ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + ; 17MAY01 MOVED: +; SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO +; SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT +; LDI G,$40 ; SHIFTED TO LATER +; OUT GIFR,G ; CLEAR PENDING INT0 RESULTING FROM +; OUT GIMSK,G ; ACTIVITY ON PIN, AND ENABLE INT0 + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP +; CBI PORTB,5 ; FOR TESTING ONLY + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA: + CLR YH + LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA: + CLR YH + LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +SNDEXP: + PUSH A ; SEPARATOR + FMLF K30M ; CONVERT TO HERTZ + RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +EXP5: FCPF KR0001 ; IF N<.0001 + BRCC EXP6 + FMLF K100K ; THEN N=N*100K + SUBI F,5 ; E=E-5 + RJMP EXP5 +EXP6: FCPF K1 ; IF N<1 + BRCC EXP7 + FMLF K10 ; THEN N=N*10 + SUBI F,1 ; E=E-1 + RJMP EXP6 +EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 + RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 + RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT + LDI A,'.' + RCALL TX_WAIT + LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + DEC E + BRNE EXP8 + LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY + RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION + LDI A,'0' + RCALL TX_WAIT + LDI A,'E' ; NOW FOR THE EXPONENT + RCALL TX_WAIT + LDI A,'+' ; SEND SIGN + TST F + BRPL EXP9 + LDI A,'-' + NEG F ; ABS(E) +EXP9: RCALL TX_WAIT + LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +EXP10: INC A + SUBI F,10 + BRPL EXP10 + RCALL TX_WAIT + LDI A,'0'+10 ; NOW LS DIGIT + ADD A,F + RCALL TX_WAIT + POP A + RCALL TX_WAIT ; SEPARATOR +EXP11: FLD F0 ; AND RESTORE FA + RET + +EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 + LDI A,' ' ; SEND SIGN (SPACE FOR +) + TST FA2 + BRPL EXP1 + LDI A,'-' +EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT +; FMLF K_1 ; LET'S BE SAFE KILLED 17MAY01 +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS + RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1<0FH + +PUBLIC CHKLIN + +CHKLIN: PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + PUSH DS + PUSH ES + PUSHF + + LDS SI,[BP+6] ; DS:SI -> FLAG% + SUB AX,AX + XCHG AX,[SI] ; AX = FLAG%, FLAG% = 0 + MOV DX,640/8 + MUL DX + XCHG DI,AX + MOV AX,0A000H + MOV ES,AX ; ES:DI -> SCREEN LINE + + MOV DX,GC_ADDR + MOV AL,2 + CALL READ_REG + PUSH AX + MOV AH,0FH + OUT DX,AX ; SET UP COLOUR COMPARE WITH 0FH + MOV AL,5 + CALL READ_REG + PUSH AX + OR AH,8 + OUT DX,AX ; SET UP COLOUR COMPARE MODE + + MOV AL,0FFH ; CHECK FOR BLANK (WHITE 0FH -> TRUE) + MOV CX,80 + REPZ SCASB ; MUST HAVE A LINE'S WORTH + JZ GOT_FLAG + + DEC W [SI] ; FLAG%=-1 + JMP GOT_FLAG + +READ_REG: + OUT DX,AL + INC DX + XCHG AL,AH + IN AL,DX + XCHG AL,AH + DEC DX + RET + +GOT_FLAG: + POP AX + OUT DX,AX ; RESTORE GC MODE REG + POP AX + OUT DX,AX ; RESTORE COLOUR COMPARE REG + + POPF + POP ES + POP DS + POP DI + POP SI + POP BP + RETF 4 + +CODE ENDS + END + \ No newline at end of file diff --git a/src/avr/chset00.inc b/src/avr/chset00.inc new file mode 100644 index 00000000..d584841a --- /dev/null +++ b/src/avr/chset00.inc @@ -0,0 +1,58 @@ +; chset00.inc generated from chset00.win, do not edit! + + .db $46,$32,$34,$44,$30,$33,$31,$39,$30,$33,$31,$32,$31,$37,$30,$39 + .db $4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $00,$01,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$03,$01,$4c,$03,$4c,$03 + .db $06,$01,$0f,$01,$18,$01,$21,$01,$2a,$01,$33,$01,$3c,$01,$45,$01 + .db $4e,$01,$57,$01,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$60,$01,$69,$01,$72,$01,$7b,$01,$84,$01,$8d,$01,$96,$01 + .db $9f,$01,$a9,$01,$b2,$01,$bb,$01,$c4,$01,$cd,$01,$d6,$01,$df,$01 + .db $e8,$01,$f1,$01,$08,$02,$11,$02,$1a,$02,$23,$02,$2c,$02,$35,$02 + .db $3e,$02,$47,$02,$50,$02,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $4c,$03,$59,$02,$62,$02,$6b,$02,$74,$02,$7d,$02,$86,$02,$8f,$02 + .db $99,$02,$a3,$02,$ad,$02,$b8,$02,$c2,$02,$cb,$02,$d4,$02,$dd,$02 + .db $e6,$02,$f0,$02,$fc,$02,$03,$03,$0c,$03,$15,$03,$1e,$03,$27,$03 + .db $30,$03,$39,$03,$43,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03,$4c,$03 + .db $00,$03,$06,$61,$01,$f8,$01,$07,$70,$88,$98,$a8,$c8,$88,$70,$01 + .db $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .db $f8,$01,$07,$f8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .db $f8,$10,$10,$01,$07,$f8,$80,$f0,$08,$08,$88,$70,$01,$07,$30,$40 + .db $80,$f0,$88,$88,$70,$01,$07,$f8,$08,$10,$20,$40,$40,$40,$01,$07 + .db $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .db $01,$07,$70,$88,$88,$88,$f8,$88,$88,$01,$07,$f0,$88,$88,$f0,$88 + .db $88,$f0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$e0,$90,$88 + .db $88,$88,$90,$e0,$01,$07,$f8,$80,$80,$f0,$80,$80,$f8,$01,$07,$f8 + .db $80,$80,$f0,$80,$80,$80,$01,$07,$70,$88,$80,$b8,$88,$88,$78,$01 + .db $07,$88,$88,$88,$f8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .db $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$a0 + .db $c0,$a0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$f8,$01,$07,$88 + .db $d8,$a8,$a8,$88,$88,$88,$01,$07,$88,$88,$c8,$a8,$98,$88,$88,$01 + .db $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$f0,$88,$88,$f0,$80,$80 + .db $80,$01,$07,$70,$88,$88,$88,$a8,$90,$68,$4c,$03,$4c,$03,$4c,$03 + .db $06,$08,$01,$01,$4f,$00,$65,$03,$01,$07,$f0,$88,$88,$f0,$a0,$90 + .db $88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$f8,$20,$20,$20 + .db $20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07,$88,$88 + .db $88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$a8,$a8,$a8,$50,$01,$07 + .db $88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20,$20,$20 + .db $01,$07,$f8,$08,$10,$20,$40,$80,$f8,$01,$07,$00,$00,$70,$08,$78 + .db $88,$78,$01,$07,$80,$80,$f0,$88,$88,$88,$f0,$01,$07,$00,$00,$78 + .db $80,$80,$80,$78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00 + .db $00,$70,$88,$f8,$80,$70,$01,$07,$18,$20,$f8,$20,$20,$20,$20,$01 + .db $08,$00,$00,$78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$b0,$c8,$88 + .db $88,$88,$02,$21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10 + .db $00,$10,$10,$10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$a0,$c0,$a0 + .db $90,$03,$21,$07,$c0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$f0 + .db $a8,$a8,$a8,$a8,$01,$07,$00,$00,$b0,$c8,$88,$88,$88,$01,$07,$00 + .db $00,$70,$88,$88,$88,$70,$01,$08,$00,$00,$f0,$88,$88,$f0,$80,$80 + .db $01,$08,$00,$00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$b0,$c0 + .db $80,$80,$80,$01,$07,$00,$00,$78,$80,$70,$08,$f0,$01,$07,$20,$20 + .db $f8,$20,$20,$20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07 + .db $00,$00,$88,$88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$a8,$a8,$50 + .db $01,$07,$00,$00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88 + .db $78,$08,$70,$01,$07,$00,$00,$f8,$10,$20,$40,$f8,$01,$07,$f8,$f8 + .db $f8,$f8,$f8,$f8,$f8,$00 + diff --git a/src/avr/chtest.asm b/src/avr/chtest.asm new file mode 100644 index 00000000..c47cfdee --- /dev/null +++ b/src/avr/chtest.asm @@ -0,0 +1,2411 @@ +; CHTEST.ASM +; CHARACTERIZE MODE + +.INCLUDE "4433DEF.INC" ; FOR AVR ASSEMBLER +;.INCLUDE "4433DEFX.INC" ; FOR NICK ASSEMBLER +.INCLUDE "MACLC.INC" +;.INCLUDE "APILC.INC" +.INCLUDE "TERLC.INC" + +; WE SHOULD CHANGE THE CODE TO USE UCSRA AND UCSRB +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU RAM =$60 ; START OF SRAM +.EQU CR =$0D +.EQU LF =$0A +.EQU RX_SIZE =1 +.EQU TX_SIZE =8 ; LEAVES 10 BYTES FREE +.EQU API_ADDRESS =$01 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU CYC_MAX =256 ; MAXIMUM WEIGHING CYCLE TIME +.EQU CYC_MIN =160 ; MINIMUM WEIGHING CYCLE TIME > 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +LSTGMS: .BYTE 4 +LSTDEV: .BYTE 4 +AVEGMS: .BYTE 4 +AVESTD: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +;MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 +DSPGMS: .BYTE 4 +ZROGMS: .BYTE 4 +;DSPRES: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +.ESEG +.ORG $000 +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 DEFAULT TO 1 +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD + +CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 +CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) + +CNFHYS: .DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +HYSCNF: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +K0: .DB $00,$00 ; 0.000000E+00 +K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 DON'T MOVE! +K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 +K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +;K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +; CHARACTERIZE ONLY % +K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +FMAT3: .DB 6,0 + .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: + OUTI SPL,RAMEND ; INIT STACK POINTER + OUTI ACSR,$80 ; POWER DOWN ANALOG COMPARATOR + +; SBI DDRB,5 ; SET SK TO OUTPUT FOR DIAGNOSTICS + + SBI DDRD,2 ; SET BIT 2 TO OUTPUT FOR TEMP SENSOR + SBI DDRD,3 ; SET BIT 3 TO OUTPUT FOR TILT SENSOR + + OUTI TCCR1B,1 ; SET COUNTER1 TO CLOCK AT 11.0592 MHZ + ; AND INPUT CAPTURE ON FALLING EDGE + OUTI MCUCR,2 ; SET INT0 FALLING EDGE FOR TEMP SENSOR + + CLR CYC_0 + CLR CYC_1 + + CLR A + STS RANGE,A + RCALL STS_STATUS_A + STS STARTUP,A + STS TMP_PHASE,A + + ;LDE A,EEMODE +; CHARACTERIZE ONLY % + LDI A,$F0 +; % + STS MODE,A + +; WEIGHING ONLY % +; LDI A,1 +; STS MODE_CYCLE,A +; % + + FLDF K1 +; FST DSPRES + FST COUNT + FLDF K0 + FST LSTGMS + FST LSTDEV + FST AVEGMS + FST AVESTD + FST INTGMS +; CHARACTERIZE ONLY % + FST WGTFRQ ; MAY NOT BE NECESSARY + FST REF_30MHZ ; NECESSARY +; % + + INIT_API_BUS ; SET UART RATE AND CLEAR FLAGS/PTRS + + IN A,TIMSK + ORI A,8 ; ENABLE INTERRUPT ON T1 INPUT CAPTURE + OUT TIMSK,A + +; WEIGHING ONLY % +; WDR ; RESET WATCHDOG +; LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT +; OUT WDTCR,A +; % + + ; START FOREGROUND TASK + SEI + +; LDFL D,SIGNON ; SEND SIGNON MESSAGE +; LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR + +LOOP: ; MAIN PROGRAM + ; IF THE INTERRUPT ALREADY CAME, + ; THROW AWAY THE DATA AND WAIT FOR A NEW ONE + CBR FLAGS,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) +; FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD + LDI F,AVESTD + RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST +; FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT + FLDF K0 ; INTGMS=0 + FST INTGMS + RCALL LDS_A_STATUS + CBR A,1<= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE +; FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE +; FML DSPRES ; DISPLAY RESOLUTION + ; % + FST DSPGMS + +STB5: +; WEIGHING ONLY % +; ;LDS A,MODE ; IF NOT WEIGHING MODE +; ;SBRS A,DSPGMS_FLG +; ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS +; +; LDI E,CYC_MIN*2/3 +; RCALL TX_WAIT_EMPTY +; BRCS FMT +; RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE +; +;FMT: RCALL LDS_A_STATUS +; SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? +; RJMP SKIP_SN +; +; CBR A,1<=0 +; BRPL FMT2 ; THEN CONTINUE +;; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) +; INC E ; INC " -LO-" COUNTER (STARTUP) +; CPI E,CYC_START+8 ; IF STARTUP E +; ;RCALL SNDSTR +; ;LDI A,'0' +; ;RCALL TX_WAIT +; ;RJMP DSP8 +; ; % +; RJMP DSP7 +;FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" +; BRCS FMT3 +; LDI E,CYC_START ; THEN STARTUP=CYC_START +; STS STARTUP,E +;FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX +; BRCS FMT4 +; SBR F,1< E +; LDFL D,FMAT0 ; " 0.000" +; ADIW ZL,2 +;DSP2: CP F,D +; BRCC DSP4 +;DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 +; BREQ DSP8 ; WHEN ALL DONE +; CPI D,4 +; BRNE DSP2 +; DEC F ; TO COMPENSATE FOR EXTRA DEC C +; RJMP DSP3 ; DO DECIMAL PT +;DSP4: +; ; FOR TENTHS OF GRAMS % +; ;INC F +; ; % +; RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +;DSP5: DEC F +; BREQ DSP8 +; CPI F,4 +; ; FOR TENTHS OF GRAMS % +; ;CPI F,5 +; ; % +; BRNE DSP6 +; LDI A,'.' +; RCALL TX_WAIT +; DEC F +;DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP DSP5 +;DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR +;DSP8: +;; ASCII STABILITY INDICATION FOR TESTING % +;; LDI A,' ' +;; RCALL TX_WAIT +;; RCALL LDS_A_STATUS +;; ANDI A,1< 1 SECOND ? + BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION + + FSBF K33M + FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE + + SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL STS_FA ; AND SAVE +SMTH0: RET + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % +; INC FA3 ; CHECK FOR NAN +; BRNE SND0 +; DEC FA3 ; TO COMPLY WITH IEEE754 +;SND0: DEC FA3 +; ROL FA2 ; CONVERT TO IEEE754 +; ROR FA3 +; ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % +; LDS B,MODE_CYCLE +; AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + + LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E + RCALL TX_WAIT_EMPTY + BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM + +SNDFPX: +; CHARACTERIZE ONLY % + SBRS FLAGS,SNDDAT + RET + CPI A,$80 + LDI A,$0A + BRNE SEPOK + LDI A,$0D +SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % +; LDI A,$1B +; RCALL TX_WAIT +; MOV A,F ; INDICATE WHICH DATA IS BEING SENT +; RCALL TX_WAIT +;;SND_FA: +; LDI XL,FA ; LOAD TX BUFFER +; LDI D,4 +;SND1: LD A,X+ +; RCALL TX_WAIT ; LS BYTE FIRST +; DEC D +; BRNE SND1 +; RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -16 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION > +5 + BRLO CORRECTION_OK + PUSH A + LDS A,TX_COUNT + CPI A,TX_SIZE + BRSH SKIP_DOLLAR + LDI A,'$' + RCALL TX_CHAR +SKIP_DOLLAR: + POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + ; WARNING CANNOT CORRUPT H, I, J % +;TEMPERATURE: ; START TEMPERATURE MEASUREMENT + LDS G,TMP_PHASE ; LIMIT TO 25uSEC (HALF PERIOD 20KHZ) + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT FOR HIGH ON WGT TO SYNCHRONISE + BRNE TMP0 + + CLI +; SBI PORTB,5 ; FOR TESTING ONLY + IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT + LDI G,$40 + OUT GIFR,G ; CLEAR PENDING INT0 RESULTING FROM + OUT GIMSK,G ; ACTIVITY ON PIN, AND ENABLE INT0 + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + ; % + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA:LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA:LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +SNDEXP: + PUSH A ; SEPARATOR + RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +EXP5: FCPF KR0001 ; IF N<.0001 + BRCC EXP6 + FMLF K100K ; THEN N=N*100K + SUBI F,5 ; E=E-5 + RJMP EXP5 +EXP6: FCPF K1 ; IF N<1 + BRCC EXP7 + FMLF K10 ; THEN N=N*10 + SUBI F,1 ; E=E-1 + RJMP EXP6 +EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 + RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 + RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT + LDI A,'.' + RCALL TX_WAIT + LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + DEC E + BRNE EXP8 + LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY + RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION + LDI A,'0' + RCALL TX_WAIT + LDI A,'E' ; NOW FOR THE EXPONENT + RCALL TX_WAIT + LDI A,'+' ; SEND SIGN + TST F + BRPL EXP9 + LDI A,'-' + NEG F ; ABS(E) +EXP9: RCALL TX_WAIT + LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +EXP10: INC A + SUBI F,10 + BRPL EXP10 + RCALL TX_WAIT + LDI A,'0'+10 ; NOW LS DIGIT + ADD A,F + RCALL TX_WAIT + POP A + RCALL TX_WAIT ; SEPARATOR +EXP11: FLD F0 ; AND RESTORE FA + RET + +EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 + LDI A,' ' ; SEND SIGN (SPACE FOR +) + TST FA2 + BRPL EXP1 + LDI A,'-' +EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT + FMLF K_1 ; LET'S BE SAFE +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS + RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1< BUFFER + ; RETURN WITH + ; NEW CRC IN BX + + CLD + MOV DX,1021H +@@L1: LODSB + XOR BH,AL + REPT 8 + SHL BX,1 + JNC $+4 + XOR BX,DX + ENDM + LOOP @@L1 + + LDS SI,[BP+10] + MOV [SI],BX ; CRC% + +@@L0: POP DS + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- + +CODE ENDS + +; ----------------------------------------------------------------------------- + +DATA SEGMENT +DATA ENDS + +; ----------------------------------------------------------------------------- + + END diff --git a/src/avr/crcsubx.inc b/src/avr/crcsubx.inc new file mode 100644 index 00000000..d8d04bc2 --- /dev/null +++ b/src/avr/crcsubx.inc @@ -0,0 +1,10 @@ +' CRCSUBX.INC + +' ----------------------------------------------------------------------------- + +$LINK "CRCSUBX.OBJ" + +DECLARE SUB CRC_CALCULATE(INTEGER,STRING) + +' ----------------------------------------------------------------------------- + diff --git a/src/avr/cs128v0.asm b/src/avr/cs128v0.asm new file mode 100644 index 00000000..ff82c2fb --- /dev/null +++ b/src/avr/cs128v0.asm @@ -0,0 +1,3076 @@ +; CS128V0.ASM + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "API.INC" + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS + BST @0,1 ; A15 + BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFC0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FD80 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =4 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_CNT: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $0000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RJMP GO_TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + +RESTART_ENTRY: + ;LDI F,8 + ;OUT ASSR,F ; TIMER 2 CLOCKED BY 32 KHZ XTAL + ;LDI F,1 + ;OUT TCCR2,F ; TIMER 2 DIVIDE BY 1 + LDI F,$00 ;$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + ;LDI F,$00 + OUT GIMSK,F + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + ;OUT PORTC,F + ;SBI PORTB,2 + ;CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + +; LDI D,$18 ; A18|A17|A16|A15|A14=11000 +; OUT PORTA,D ; CL1=M=FLM=0 +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + +;RTNCDE: LDIZ RTN_CODE ; POINT Z TO FLASH +; LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER +; LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +;CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +;CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM +; LPM ; GET DATA FROM FLASH +; CLR R0 ; TEMPORARY CLEAR KB +; RAMWRX R0 ; WRITE DATA TO DSPRAM +; DEC XL +; BREQ RTNCDE_END ; CHECK IF ALL DONE +; ADIW ZL,$01 ; INC FLASH ADDRESS +; INC YL ; INC ADDRESS L FOR DSPRAM +; MOV A,YL ; +; ANDI A,$3F ;YL,$3F +; BRNE CDE1 +; SUBI YL,$40 ; +; INC YH ; INC ADDRESS H (ON L ROLLOVER) +; RJMP CDE0 +;RTNCDE_END: + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,$10 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + CLR A + STS SCAN_CNT,A ; START ON FIRST LED / PHOTODIODE PAIR + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; DROP CL2 + + IN D,PORTD ;LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTD,D ;PORTA,D + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,D + + LDI D,$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + RCALL RX_WAIT + + CPI A,$1B + BREQ ESC_SEQUENCE + + SBRC FLAGS,3 + RJMP REGULAR_CHAR + CPI A,$20 + BRSH REGULAR_CHAR + + CPI A,$08 + RJEQ BACK_SPACE + CPI A,$0D + RJEQ CR + CPI A,$0A + RJEQ LF + CPI A,7 + BRNE MAIN_LOOP + +REGULAR_CHAR: + SBRC FLAGS,2 ; CROSSED ZEROS ON? + RJMP L013B ; YES, DON'T BOTHER TESTING FOR ZERO + CPI A,'0' + BRNE L013B + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YL,LOW(-$204) + SBCI YH,HIGH(-$204) + A14_A18 B + RCALL LPMS + MOV A,R0 +L013B: RCALL DRAW_CHAR_TTY + RJMP MAIN_LOOP + +ESC_SEQUENCE: + RCALL RX_WAIT + CPI A,$1B + BREQ REGULAR_CHAR + CPI A,'.' + RJEQ CHARACTER_SET_DOWNLOAD + CPI A,'/' + RJEQ CROSSED_ZEROS + CPI A,'?' + RJEQ CHARACTER_SET_QUERY + CPI A,'A' + RJEQ SET_BACKLIGHT + CPI A,'B' + RJEQ BUZZER + CPI A,'C' + RJEQ CLEAR_RECTANGLE + CPI A,'D' + RJEQ DRAW_MODE + CPI A,'E' + RJEQ ENABLE_CNTRL + CPI A,'F' + RJEQ GET_FILLED_RECTNC_SIZE + CPI A,'G' + RJEQ INTERPRET_MODE + CPI A,'K' + RJEQ CLR_DISP + CPI A,'L' + RJEQ GO_SCROLL_REGION + CPI A,'M' + RJEQ MOSFET_CONTROL + CPI A,'N' + RJEQ GET_RECTNC_SIZE + CPI A,'P' + RJEQ PROP_FIXED_MODE + CPI A,'R' + RJEQ GET_RECT_SIZE + CPI A,'S' + RJEQ SET_CURSOR + CPI A,'U' + RJEQ NULLSUB + CPI A,'V' + RJEQ CONTRAST_CONTROL + CPI A,'W' + RJEQ NULLSUB + CPI A,'X' + RJEQ SAVE_STATE + CPI A,'Z' + RJEQ TOUCH_ZONE + CPI A,'0' + BRLO ESC_SEQUENCE_ABORT + CPI A,'9'+1 + BRLO SET_CHSET_A +ESC_SEQUENCE_ABORT: + RJMP MAIN_LOOP + +CROSSED_ZEROS: + RCALL RX_WAIT + SBRS A,0 + RJMP CROSSED_ZEROS_OFF + LDI A,1<<2 + OR FLAGS,A + RJMP MAIN_LOOP +CROSSED_ZEROS_OFF: + LDI A,~(1<<2) + AND FLAGS,A + RJMP MAIN_LOOP + +MOSFET_CONTROL: + RCALL RX_WAIT + CPI A,$30 ; DO NOT TURN OFF BY ACCIDENT + BRNE MOSFET_CONTROL_DONE + CLI + LDI F,1<<6 + OR FLAGS,F ; SAY WE TURNED OFF VIA COMMAND + RJMP SLEEP_ENTRY ; GO AND SHUT DOWN DISPLAY +MOSFET_CONTROL_DONE: + RJMP MAIN_LOOP + +BUZZER: RCALL RX_WAIT + STS BUZZ_TIME,A ; SAVE REQUESTED DURATION + RJMP MAIN_LOOP + +SET_CHSET: + RCALL RX_WAIT +SET_CHSET_A: + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT +; ANDI A,1 +; BRNE SET_BACKLIGHT_ON +; LDI A,~(1<<7) +; AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION +; CBI PORTC,7 +; CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT +; RJMP MAIN_LOOP +;SET_BACKLIGHT_ON: +; LDI A,1<<7 +; OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + CLI + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_TIM0_OVF: + RJMP TIM0_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRSH DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRSH DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_PAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS C,CLOCKING_PTR + TST C ; START OF 4 LINE BLOCK? (1 BASED) + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D + OUT TCNT1H,D + OUT TCNT1L,D + CBI PORTD,5 ; DROP CL2 + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + ;LDS D,LATCH10_SAV + ;OUT PORTA,D + ;SBI PORTB,4 + SBI PORTB,2 ;PORTA,5 ; PULSE CL1 + CBI PORTB,2 ;PORTA,5 + ;CBI PORTB,4 + RJMP L04F9 + +L04E6: IN D,PORTB ;LDS D,LATCH10_SAV + ORI D,$10 ;$80 ; RAISE FLM + ORI D,$04 ;$20 ; RAISE CL1 + OUT PORTB,D ;PORTA,D + ANDI D,$FB ; ; DROP CL1 + OUT PORTB,D ; + + IN D,PORTD ;SBI PORTB,4 + LDI C,$40 ;$60 ; TOGGLE M (FORMERLY CL1 ALSO) + EOR D,C + OUT PORTD,D ;OUT PORTA,D + IN D,PORTB ; + ANDI D,$EF ;$7F ; DROP FLM + OUT PORTB,D ;PORTA,D + ;CBI PORTB,4 + ;STS LATCH10_SAV,D + +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D + OUT OCR1AL,D + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + + LDI D,$39 ; WAIT FOR 16uSEC +L050E: DEC D + BRNE L050E + + LDI D,$01 + OUT TCCR1B,D + SBI PORTD,5 ; CL2 HIGH + + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VCCL + LDS D,VCCH + LDI E,LOW(VCC_NOMINAL) + SUB C,E + LDI E,HIGH(VCC_NOMINAL) + SBC D,E + + ROR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +; PUSH D +; PUSH C + ASR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +; POP E +; ADD C,E +; POP E +; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + + LDS E,VEEL + ADD C,E + LDS E,VEEH + ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,$02 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,$C8 ;$B8 ; 54uSEC + OUT TCNT0,D + CLR D + STS SCAN_CNT,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + RJMP END_INT + +TIM0_OVF: + RETI + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_CNT + INC D + STS SCAN_CNT,D + DEC D + BREQ BEEPER ; IF SCAN_CNT WAS = 0 + DEC D + RJEQ PHOTO ; IF SCAN_CNT WAS = 1 + +END_INT: + POP D ; RESTORE STATE OF THE WORLD + ;OUT PORTA,D + ;SBI PORTB,4 + ;CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +BEEPER: LDS D,BUZZ_TIME + TST D + BREQ PULSE_LED + LDS C,LATCH12_SAV + SBRS C,3 + RJMP BEEPER_SPKHI + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +PULSE_LED: + LDI D,1<<7 + EOR FLAGS,D + BRPL PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP END_INT ; AND WASTE EVERY REMAINING CYCLE + +PULSE_LED_OK: + LDI D,$E2 ; 22uSEC + OUT TCNT0,D + PUSH ZH + PUSH ZL + PUSH R0 + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDI D,$E0 + CP R0,D + BRLO L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + POP R0 + POP ZL + POP ZH + RJMP END_INT + +PHOTO: CLR D ; STOP TIMER SINCE + OUT TCCR0,D ; WANT INTERRUPT EVERY 2ND CYCLE + + PUSH ZH + PUSH ZL + PUSH R0 + + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + SBRS D,6 + RJMP L058A + + ; ROW/COLUMN IS INACTIVE + CLC + IN C,SREG + RJMP L0593 + +L058A: ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + IN C,SREG + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF AND C + + ; MOV D,TX_COUNT + ; CPI D,TX_SIZE + ; BRSH L0617X + ; PUSH A + ; LDS A,ROW_COLUMN + ; OUT SREG,C + ; ROL A + ; SBRS A,7 + ; RJMP L0617XX + ; RCALL TX_CHAR + ; LDI A,1 + ;L0617XX: + ; STS ROW_COLUMN,A + ; POP A + ;L0617X: + + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDI D,$E0 + CP R0,D + BRLO L05A8 + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS D,ROW_BITMAP + ROL D + STS ROW_BITMAP,D + LDS D,ROW_BITMAP+1 + ROL D + STS ROW_BITMAP+1,D + RJMP L05F9 +L05A8: ; WE HAVE A COLUMN STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRLO L05AB + RJMP L05F9 +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + PUSH A + LDI A,$38 +L05B9: SUBI A,$04 + RJEQ L05F8 ;BREQ L05F8 + ROR D + ROR C + BRSH L05B9 + ; WE FOUND AN INTERSECTION + PUSH D + PUSH C + + LDS D,LATCH5_SAV + SBRS D,7 + RJMP ALREADY_ON + + ;LDS D,TURNON_COUNT + ;TST D + ;BREQ TURNON_OK + ;DEC D + ;STS TURNON_COUNT,D + ;BRNE TURNON_OK + + LDI D,~(1<<6) + AND FLAGS,D ; RESET TURNOFF REQUEST + +;TURNON_OK: + RJMP L05F8 + +ALREADY_ON: + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + MOV C,A + SUBI C,$04 + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + POP C + POP D + TST R0 + RJEQ L05B9 ; NULL INTERSECTION, FIND ANOTHER + + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,$10 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + MOV D,TX_COUNT + CPI D,TX_SIZE-2 + BRSH L05F8 + LDI A,$1B + RCALL TX_CHAR + LDI A,'Z' + RCALL TX_CHAR + MOV A,R0 + RCALL TX_CHAR + +L05F8: ; SCAN TO NEXT LED / PHOTODIODE PAIR + POP A +L05F9: LDI D,$04 + ADD SCAN,D + LDI C,$C8 + CP SCAN,C + BRLO L0617 + + ; MOV D,TX_COUNT + ; CPI D,TX_SIZE-1 + ; BRSH L0617Y + ; PUSH A + ; LDS A,ROW_COLUMN + ; LSR A + ;L0617YY: + ; ROL A + ; SBRS A,7 + ; RJMP L0617YY + ; RCALL TX_CHAR + ; LDI A,1 + ; STS ROW_COLUMN,A + ; LDI A,$0D + ; RCALL TX_CHAR + ; POP A + ;L0617Y: + + ; COMPLETED ENTIRE SCAN, START NEW SCAN +; SBI DDRC,7 +; SBI PORTC,7 ; DIAGNOSTIC SYNC FOR LED SCAN +; CBI PORTC,7 + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + LDS D,DEBOUNCE + TST D + BREQ L0617 + DEC D + STS DEBOUNCE,D + BRNE L0617 + LDS D,ACTIVE_ZONE + TST D + BREQ L0617 + MOV D,TX_COUNT + CPI D,TX_SIZE-2 + BRSH L0617 + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'Z' + RCALL TX_CHAR + LDI A,0 + RCALL TX_CHAR + POP A +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + LDIZ SCAN_TBL + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$C0 + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + POP R0 + POP ZL + POP ZH +; SBI PORTC,6 ; DIAGNOSTIC DURATION FOR PHOTO ROUTINE +; CBI PORTC,6 + RJMP END_INT + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/cs64v0.asm b/src/avr/cs64v0.asm new file mode 100644 index 00000000..8e6c256e --- /dev/null +++ b/src/avr/cs64v0.asm @@ -0,0 +1,3076 @@ +; CS64V0.ASM + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "API.INC" ; DIDN'T CHANGE THIS TO APICS.INC SINCE NO WDR IN CS64V0.ASM + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS + BST @0,1 ; A15 + BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFC0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FD80 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_CNT: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $0000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RJMP GO_TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + +RESTART_ENTRY: + ;LDI F,8 + ;OUT ASSR,F ; TIMER 2 CLOCKED BY 32 KHZ XTAL + ;LDI F,1 + ;OUT TCCR2,F ; TIMER 2 DIVIDE BY 1 + LDI F,$00 ;$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + ;LDI F,$00 + OUT GIMSK,F + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + ;OUT PORTC,F + ;SBI PORTB,2 + ;CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + +; LDI D,$18 ; A18|A17|A16|A15|A14=11000 +; OUT PORTA,D ; CL1=M=FLM=0 +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + +;RTNCDE: LDIZ RTN_CODE ; POINT Z TO FLASH +; LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER +; LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +;CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +;CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM +; LPM ; GET DATA FROM FLASH +; CLR R0 ; TEMPORARY CLEAR KB +; RAMWRX R0 ; WRITE DATA TO DSPRAM +; DEC XL +; BREQ RTNCDE_END ; CHECK IF ALL DONE +; ADIW ZL,$01 ; INC FLASH ADDRESS +; INC YL ; INC ADDRESS L FOR DSPRAM +; MOV A,YL ; +; ANDI A,$3F ;YL,$3F +; BRNE CDE1 +; SUBI YL,$40 ; +; INC YH ; INC ADDRESS H (ON L ROLLOVER) +; RJMP CDE0 +;RTNCDE_END: + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,$10 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + CLR A + STS SCAN_CNT,A ; START ON FIRST LED / PHOTODIODE PAIR + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; DROP CL2 + + IN D,PORTD ;LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTD,D ;PORTA,D + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,D + + LDI D,$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + RCALL RX_WAIT + + CPI A,$1B + BREQ ESC_SEQUENCE + + SBRC FLAGS,3 + RJMP REGULAR_CHAR + CPI A,$20 + BRSH REGULAR_CHAR + + CPI A,$08 + RJEQ BACK_SPACE + CPI A,$0D + RJEQ CR + CPI A,$0A + RJEQ LF + CPI A,7 + BRNE MAIN_LOOP + +REGULAR_CHAR: + SBRC FLAGS,2 ; CROSSED ZEROS ON? + RJMP L013B ; YES, DON'T BOTHER TESTING FOR ZERO + CPI A,'0' + BRNE L013B + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YL,LOW(-$204) + SBCI YH,HIGH(-$204) + A14_A18 B + RCALL LPMS + MOV A,R0 +L013B: RCALL DRAW_CHAR_TTY + RJMP MAIN_LOOP + +ESC_SEQUENCE: + RCALL RX_WAIT + CPI A,$1B + BREQ REGULAR_CHAR + CPI A,'.' + RJEQ CHARACTER_SET_DOWNLOAD + CPI A,'/' + RJEQ CROSSED_ZEROS + CPI A,'?' + RJEQ CHARACTER_SET_QUERY + CPI A,'A' + RJEQ SET_BACKLIGHT + CPI A,'B' + RJEQ BUZZER + CPI A,'C' + RJEQ CLEAR_RECTANGLE + CPI A,'D' + RJEQ DRAW_MODE + CPI A,'E' + RJEQ ENABLE_CNTRL + CPI A,'F' + RJEQ GET_FILLED_RECTNC_SIZE + CPI A,'G' + RJEQ INTERPRET_MODE + CPI A,'K' + RJEQ CLR_DISP + CPI A,'L' + RJEQ GO_SCROLL_REGION + CPI A,'M' + RJEQ MOSFET_CONTROL + CPI A,'N' + RJEQ GET_RECTNC_SIZE + CPI A,'P' + RJEQ PROP_FIXED_MODE + CPI A,'R' + RJEQ GET_RECT_SIZE + CPI A,'S' + RJEQ SET_CURSOR + CPI A,'U' + RJEQ NULLSUB + CPI A,'V' + RJEQ CONTRAST_CONTROL + CPI A,'W' + RJEQ NULLSUB + CPI A,'X' + RJEQ SAVE_STATE + CPI A,'Z' + RJEQ TOUCH_ZONE + CPI A,'0' + BRLO ESC_SEQUENCE_ABORT + CPI A,'9'+1 + BRLO SET_CHSET_A +ESC_SEQUENCE_ABORT: + RJMP MAIN_LOOP + +CROSSED_ZEROS: + RCALL RX_WAIT + SBRS A,0 + RJMP CROSSED_ZEROS_OFF + LDI A,1<<2 + OR FLAGS,A + RJMP MAIN_LOOP +CROSSED_ZEROS_OFF: + LDI A,~(1<<2) + AND FLAGS,A + RJMP MAIN_LOOP + +MOSFET_CONTROL: + RCALL RX_WAIT + CPI A,$30 ; DO NOT TURN OFF BY ACCIDENT + BRNE MOSFET_CONTROL_DONE + CLI + LDI F,1<<6 + OR FLAGS,F ; SAY WE TURNED OFF VIA COMMAND + RJMP SLEEP_ENTRY ; GO AND SHUT DOWN DISPLAY +MOSFET_CONTROL_DONE: + RJMP MAIN_LOOP + +BUZZER: RCALL RX_WAIT + STS BUZZ_TIME,A ; SAVE REQUESTED DURATION + RJMP MAIN_LOOP + +SET_CHSET: + RCALL RX_WAIT +SET_CHSET_A: + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT +; ANDI A,1 +; BRNE SET_BACKLIGHT_ON +; LDI A,~(1<<7) +; AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION +; CBI PORTC,7 +; CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT +; RJMP MAIN_LOOP +;SET_BACKLIGHT_ON: +; LDI A,1<<7 +; OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + CLI + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_TIM0_OVF: + RJMP TIM0_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRSH DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRSH DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_PAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,30 + RCALL COPY_BYTES ; 240 PIXELS, SKIP 16 FOR SAMSUNG + + ;SBIW XL,2 + ;ADIW YL,6 + ;LDI B,2 + ;RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS C,CLOCKING_PTR + TST C ; START OF 4 LINE BLOCK? (1 BASED) + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D + OUT TCNT1H,D + OUT TCNT1L,D + CBI PORTD,5 ; DROP CL2 + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + ;LDS D,LATCH10_SAV + ;OUT PORTA,D + ;SBI PORTB,4 + SBI PORTB,2 ;PORTA,5 ; PULSE CL1 + CBI PORTB,2 ;PORTA,5 + ;CBI PORTB,4 + RJMP L04F9 + +L04E6: IN D,PORTB ;LDS D,LATCH10_SAV + ORI D,$10 ;$80 ; RAISE FLM + ORI D,$04 ;$20 ; RAISE CL1 + OUT PORTB,D ;PORTA,D + ANDI D,$FB ; ; DROP CL1 + OUT PORTB,D ; + + IN D,PORTD ;SBI PORTB,4 + LDI C,$40 ;$60 ; TOGGLE M (FORMERLY CL1 ALSO) + EOR D,C + OUT PORTD,D ;OUT PORTA,D + IN D,PORTB ; + ANDI D,$EF ;$7F ; DROP FLM + OUT PORTB,D ;PORTA,D + ;CBI PORTB,4 + ;STS LATCH10_SAV,D + +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$E0 ;$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D + OUT OCR1AL,D ; TO CLOCK AT 5.5 MHZ + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + + LDI D,$AB ;$39 ; WAIT FOR 16uSEC +L050E: DEC D + BRNE L050E + + LDI D,$01 + OUT TCCR1B,D + SBI PORTD,5 ; CL2 HIGH + + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VCCL + LDS D,VCCH + LDI E,LOW(VCC_NOMINAL) + SUB C,E + LDI E,HIGH(VCC_NOMINAL) + SBC D,E + + ROR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +; PUSH D +; PUSH C + ASR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +; POP E +; ADD C,E +; POP E +; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + + LDS E,VEEL + ADD C,E + LDS E,VEEH + ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,$02 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,$C8 ;$B8 ; 54uSEC + OUT TCNT0,D + CLR D + STS SCAN_CNT,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + RJMP END_INT + +TIM0_OVF: + RETI + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_CNT + INC D + STS SCAN_CNT,D + DEC D + BREQ BEEPER ; IF SCAN_CNT WAS = 0 + DEC D + RJEQ PHOTO ; IF SCAN_CNT WAS = 1 + +END_INT: + POP D ; RESTORE STATE OF THE WORLD + ;OUT PORTA,D + ;SBI PORTB,4 + ;CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +BEEPER: LDS D,BUZZ_TIME + TST D + BREQ PULSE_LED + LDS C,LATCH12_SAV + SBRS C,3 + RJMP BEEPER_SPKHI + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +PULSE_LED: + LDI D,1<<7 + EOR FLAGS,D + BRPL PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP END_INT ; AND WASTE EVERY REMAINING CYCLE + +PULSE_LED_OK: + LDI D,$E2 ; 22uSEC + OUT TCNT0,D + PUSH ZH + PUSH ZL + PUSH R0 + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDI D,$E0 + CP R0,D + BRLO L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + POP R0 + POP ZL + POP ZH + RJMP END_INT + +PHOTO: CLR D ; STOP TIMER SINCE + OUT TCCR0,D ; WANT INTERRUPT EVERY 2ND CYCLE + + PUSH ZH + PUSH ZL + PUSH R0 + + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + SBRS D,6 + RJMP L058A + + ; ROW/COLUMN IS INACTIVE + CLC + IN C,SREG + RJMP L0593 + +L058A: ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + IN C,SREG + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF AND C + + ; MOV D,TX_COUNT + ; CPI D,TX_SIZE + ; BRSH L0617X + ; PUSH A + ; LDS A,ROW_COLUMN + ; OUT SREG,C + ; ROL A + ; SBRS A,7 + ; RJMP L0617XX + ; RCALL TX_CHAR + ; LDI A,1 + ;L0617XX: + ; STS ROW_COLUMN,A + ; POP A + ;L0617X: + + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDI D,$E0 + CP R0,D + BRLO L05A8 + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS D,ROW_BITMAP + ROL D + STS ROW_BITMAP,D + LDS D,ROW_BITMAP+1 + ROL D + STS ROW_BITMAP+1,D + RJMP L05F9 +L05A8: ; WE HAVE A COLUMN STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRLO L05AB + RJMP L05F9 +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + PUSH A + LDI A,$38 +L05B9: SUBI A,$04 + RJEQ L05F8 ;BREQ L05F8 + ROR D + ROR C + BRSH L05B9 + ; WE FOUND AN INTERSECTION + PUSH D + PUSH C + + LDS D,LATCH5_SAV + SBRS D,7 + RJMP ALREADY_ON + + ;LDS D,TURNON_COUNT + ;TST D + ;BREQ TURNON_OK + ;DEC D + ;STS TURNON_COUNT,D + ;BRNE TURNON_OK + + LDI D,~(1<<6) + AND FLAGS,D ; RESET TURNOFF REQUEST + +;TURNON_OK: + RJMP L05F8 + +ALREADY_ON: + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + MOV C,A + SUBI C,$04 + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + POP C + POP D + TST R0 + RJEQ L05B9 ; NULL INTERSECTION, FIND ANOTHER + + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,$10 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + MOV D,TX_COUNT + CPI D,TX_SIZE-2 + BRSH L05F8 + LDI A,$1B + RCALL TX_CHAR + LDI A,'Z' + RCALL TX_CHAR + MOV A,R0 + RCALL TX_CHAR + +L05F8: ; SCAN TO NEXT LED / PHOTODIODE PAIR + POP A +L05F9: LDI D,$04 + ADD SCAN,D + LDI C,$C8 + CP SCAN,C + BRLO L0617 + + ; MOV D,TX_COUNT + ; CPI D,TX_SIZE-1 + ; BRSH L0617Y + ; PUSH A + ; LDS A,ROW_COLUMN + ; LSR A + ;L0617YY: + ; ROL A + ; SBRS A,7 + ; RJMP L0617YY + ; RCALL TX_CHAR + ; LDI A,1 + ; STS ROW_COLUMN,A + ; LDI A,$0D + ; RCALL TX_CHAR + ; POP A + ;L0617Y: + + ; COMPLETED ENTIRE SCAN, START NEW SCAN +; SBI DDRC,7 +; SBI PORTC,7 ; DIAGNOSTIC SYNC FOR LED SCAN +; CBI PORTC,7 + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + LDS D,DEBOUNCE + TST D + BREQ L0617 + DEC D + STS DEBOUNCE,D + BRNE L0617 + LDS D,ACTIVE_ZONE + TST D + BREQ L0617 + MOV D,TX_COUNT + CPI D,TX_SIZE-2 + BRSH L0617 + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'Z' + RCALL TX_CHAR + LDI A,0 + RCALL TX_CHAR + POP A +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + LDIZ SCAN_TBL + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$C0 + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + POP R0 + POP ZL + POP ZH +; SBI PORTC,6 ; DIAGNOSTIC DURATION FOR PHOTO ROUTINE +; CBI PORTC,6 + RJMP END_INT + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/cs64v1.asm b/src/avr/cs64v1.asm new file mode 100644 index 00000000..a8e77d97 --- /dev/null +++ b/src/avr/cs64v1.asm @@ -0,0 +1,2912 @@ +; CS64V1.ASM +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APICS.INC" ; NOT API.INC BECAUSE APICS.INC HAS WDR IN TX_WAIT_LOOP + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL +; THIS WILL CORRUPT BACKLIGHT + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 + ANDI R19,$80 + EOR R19,@0 + SEI + OUT PORTC,R19 +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @0,1 ; A15 +; BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @1,7 ; A15 +; BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,2 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,2 + CBI PORTB,1 + NOP + SBI PORTB,1 + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SEI + SBI PORTB,2 + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SBI PORTB,2 + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFF0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FD60 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +TEMP: .BYTE 1 ; 10C + +LATCH11_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 2 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +BACKLIGHT_COUNT: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RETI ; TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + +RESTART_ENTRY: + LDI F,$00 + OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED + OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F ; D6 = LOW TO RESET T6963C + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$07 ; CS, RD, WR HI, LEs ALL LO + OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT + + LDI F,$00 + OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT + + LDI F,$20 ;$A0 NO BACKLIGHT INVERSION INITIALLY + MOV FLAGS,F ; START WITH DISPLAY ON + + INIT_API_BUS + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT+1,D ; KLUDGE FOR EXTRA 2 BITS OF RESOLUTION + + ; INITIALISE T6963C DISPLAY CONTROLLER + SBI PORTD,6 ; COME OUT OF RESET + + LDI ZL,0 + LDI ZH,0 +RESET_DELAY: + WDR ; 10OCT02 RESET WATCHDOG + SBIW ZL,1 + BRNE RESET_DELAY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOP: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + CLR A + STS BACKLIGHT_COUNT,A ; ENSURE BACKLIGHT COUNT IS IN RANGE + + CLR ZL + CLR ZH ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$04 ;$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +WRITE_COMMAND: + RCALL WAIT_STATUS ; LEAVES C/D = 1 + RJMP WRITE_ENTRY +WRITE_COMMAND_AUTO: + RCALL WAIT_AUTO ; LEAVES C/D = 1 + RJMP WRITE_ENTRY + +WRITE_DATA: + RCALL WAIT_STATUS + RJMP WRITE_DATA_ENTRY +WRITE_DATA_AUTO: + RCALL WAIT_AUTO +WRITE_DATA_ENTRY: + CBI PORTC,0 ; C/D = 0 +WRITE_ENTRY: + OUT PORTA,F + NOP + NOP + NOP + CLI + CBI PORTB,1 ; WR = 0 + NOP + NOP + NOP + SEI + SBI PORTB,1 ; WR = 1 + RET + +WAIT_AUTO: + PUSH F +WAIT_AUTO_LOOP: + RCALL READ_STATUS + SBRS F,3 + RJMP WAIT_AUTO_LOOP + POP F + RET + +WAIT_STATUS: + PUSH F +WAIT_STATUS_LOOP: + RCALL READ_STATUS + SBRC F,0 + SBRS F,1 + RJMP WAIT_STATUS_LOOP + POP F + RET + +READ_STATUS: + SBI PORTC,0 ; C/D = 1 + LDI F,0 + OUT DDRA,F ; D0-D7 = INPUTS + CLI + CBI PORTB,0 ; RD = 0 + NOP + NOP + NOP + NOP + SBI PORTB,0 ; RD = 1 + IN F,PINA ; READ DATA BEFORE RD COMES UP + SEI + PUSH F + LDI F,$FF + OUT DDRA,F ; D0-D7 = OUTPUTS + POP F + RET + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; TURN OFF VEE MEASURING + + SBI PORTB,2 ; SRAM SELECT = 1 + CBI PORTD,6 ; T6963C RESET = 0 + CBI PORTD,7 ; T6963C SELECT = 0 + CBI PORTB,0 ; RD = 0 + CBI PORTB,1 ; WR = 0 + + LDI D,$FF + OUT DDRA,D ; D0-D7 = OUTPUTS + LDI D,0 + OUT PORTA,D ; D0-D7 = 0 + + LDI D,0 ;$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + ;LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$1F ; WATCHDOG TURN OFF ENABLE = 1 + OUT WDTCR,D + LDI D,$17 ; WATCHDOG ENABLE = 0 + OUT WDTCR,D + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: +; CLI ; FOR BEST SAFETY +; +; LDI F,$00 +; OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED +; OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED +; +; LDI F,$F8 ; INIT_PORTS +; OUT DDRD,F +; LDI F,$B8 ;$F8 +; OUT PORTD,F ; D6 = LOW TO RESET T6963C +; LDI F,$1F +; OUT DDRB,F +; LDI F,$FF +; OUT DDRA,F +; OUT DDRC,F +; +; CLR F +; OUT PORTA,F +; +;; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO +;; LDI F,$03 ; CS, RD, WR HI, LEs ALL LO +; IN F,PORTB +; ANDI F,$10 ; PRESERVE B4 FOR BACKLIGHT +; ORI F,$03 ; CS, RD, WR HI, LEs ALL LO +; OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT +; +;; LDI F,$00 +; IN F,PORTC +; ANDI F,$80 ; PRESERVE C7 FOR BACKLIGHT +; OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT +; +; SEI ; FOR BEST SAFETY +; CBI PORTD,6 ; SEE OUT PORTD,F ABOVE +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYX: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYX +; +; ; INITIALISE T6963C DISPLAY CONTROLLER +; SBI PORTD,6 ; COME OUT OF RESET +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYY: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOPZ: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOPZ + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + +; CLI ; FOR BEST SAFETY +; +; LDI A,HIGH(CONTRAST_MID) +; OUT OCR1BH,A +; LDI A,LOW(CONTRAST_MID) +; OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH +; +; LDI A,HIGH(T1_INIT) +; OUT TCNT1H,A +; LDI A,LOW(T1_INIT) +; OUT TCNT1L,A +; +; LDI A,$50 +; OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH +; LDI A,$01 +; OUT TCCR1B,A ; TIMER 1 RUNNING +; +; LDI F,$00 +; OUT TCCR0,F ; TIMER 0 NOT RUNNING YET +; +; LDI F,$04 ;$05 +; OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS +; OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS +; +; LDI F,$0A +; OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE +; LDI F,$C0 +; OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS +; OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 +; +; SEI ; FOR BEST SAFETY + + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT + ANDI A,1 + BRNE SET_BACKLIGHT_ON + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + RJMP MAIN_LOOP +SET_BACKLIGHT_ON: + LDI A,1<<7 + OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + +; LDS A,CONTRASTL +; RCALL TX_WAIT +; LDS A,CONTRASTH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 1 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_PAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + LDI XL,LOW(ROWBUF) + LDI XH,HIGH(ROWBUF) ; X -> SINGLE LINE BUFFER IN AVR SRAM + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,30 ; BYTES TO COPY +DO_MORE: + A0_A13 YL,YH + RAMRD A + ST X+,A + INC YL + DEC B + RJNE DO_MORE ;BRNE DO_MORE + + POP XH + POP XL + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> SINGLE LINE IN T6963C BUFFER + + CBI PORTD,7 ; CS0 = 0 + MOV F,YL + RCALL WRITE_DATA + MOV F,YH + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI B,30 + LDI YL,LOW(ROWBUF) + LDI YH,HIGH(ROWBUF) ; Y -> SINGLE LINE BUFFER IN AVR SRAM +NICK_SUB2_LOOP: + LD F,Y+ + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + DEC B + BRNE NICK_SUB2_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + SBI PORTD,7 ; CS0 = 1 + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +; SBI DDRB,7 +; IN D,PORTB +; SUBI D,$80 +; OUT PORTB,D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + SBRS FLAGS,7 + RJMP BACKLIGHT_SKIP + LDS D,BACKLIGHT_COUNT + INC D +; LDS C,CONTRASTL +; LSL C +; CP D,C + CPI D,62 ;64 ; 64 COUNTS = 150 HZ + BRSH BACKLIGHT_EVEN +; LSR C +; CP D,C + CPI D,31 ;32 + BRNE BACKLIGHT_SAVE +;BACKLIGHT_ODD: + CBI PORTC,7 + SBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 + RJMP BACKLIGHT_CONT +BACKLIGHT_EVEN: + SBI PORTC,7 + CBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + LDI D,0 +BACKLIGHT_CONT: + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 +BACKLIGHT_SAVE: + STS BACKLIGHT_COUNT,D +BACKLIGHT_SKIP: + + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS D,BREAK_COUNT+1 ; WORD IS STORED IN REVERSE ORDER + SUBI D,-$40 + STS BREAK_COUNT+1,D ; START OF 4 INTERRUPT BLOCK? + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + LDI D,$B0 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, CLR OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD + LDI D,$0B+$AB ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VCCL + LDS D,VCCH + LDI E,LOW(VCC_NOMINAL) + SUB C,E + LDI E,HIGH(VCC_NOMINAL) + SBC D,E + + ROR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +; PUSH D +; PUSH C + ASR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +; POP E +; ADD C,E +; POP E +; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + +; CLR D +; CLR C + + LDS E,VEEL + ADD C,E + LDS E,VEEH + ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH WE ARE NO LONGER SETTING TIMER 0 + NOP + NOP + NOP + NOP + NOP + NOP + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + +;END_INT: + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/cs64v1a.asm b/src/avr/cs64v1a.asm new file mode 100644 index 00000000..fd75aab1 --- /dev/null +++ b/src/avr/cs64v1a.asm @@ -0,0 +1,2913 @@ +; CS64V1A.ASM +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APICS.INC" ; NOT API.INC BECAUSE APICS.INC HAS WDR IN TX_WAIT_LOOP + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL +; THIS WILL CORRUPT BACKLIGHT + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 + ANDI R19,$80 + EOR R19,@0 + SEI + OUT PORTC,R19 +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @0,1 ; A15 +; BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @1,7 ; A15 +; BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,2 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,2 + CBI PORTB,1 + NOP + SBI PORTB,1 + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + SBI PORTB,2 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SEI + SBI PORTB,2 + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,2 + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SBI PORTB,2 + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFF0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FD60 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$5F ;$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ;$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +TEMP: .BYTE 1 ; 10C + +LATCH11_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 2 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +BACKLIGHT_COUNT: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RETI ; TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + +RESTART_ENTRY: + LDI F,$00 + OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED + OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F ; D6 = LOW TO RESET T6963C + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$07 ; CS, RD, WR HI, LEs ALL LO + OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT + + LDI F,$00 + OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT + + LDI F,$20 ;$A0 NO BACKLIGHT INVERSION INITIALLY + MOV FLAGS,F ; START WITH DISPLAY ON + + INIT_API_BUS + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT+1,D ; KLUDGE FOR EXTRA 2 BITS OF RESOLUTION + + ; INITIALISE T6963C DISPLAY CONTROLLER + SBI PORTD,6 ; COME OUT OF RESET + + LDI ZL,0 + LDI ZH,0 +RESET_DELAY: + WDR ; 10OCT02 RESET WATCHDOG + SBIW ZL,1 + BRNE RESET_DELAY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOP: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + CLR A + STS BACKLIGHT_COUNT,A ; ENSURE BACKLIGHT COUNT IS IN RANGE + + CLR ZL + CLR ZH ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$04 ;$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +WRITE_COMMAND: + RCALL WAIT_STATUS ; LEAVES C/D = 1 + RJMP WRITE_ENTRY +WRITE_COMMAND_AUTO: + RCALL WAIT_AUTO ; LEAVES C/D = 1 + RJMP WRITE_ENTRY + +WRITE_DATA: + RCALL WAIT_STATUS + RJMP WRITE_DATA_ENTRY +WRITE_DATA_AUTO: + RCALL WAIT_AUTO +WRITE_DATA_ENTRY: + CBI PORTC,0 ; C/D = 0 +WRITE_ENTRY: + OUT PORTA,F + NOP + NOP + NOP + CLI + CBI PORTB,1 ; WR = 0 + NOP + NOP + NOP + SEI + SBI PORTB,1 ; WR = 1 + RET + +WAIT_AUTO: + PUSH F +WAIT_AUTO_LOOP: + RCALL READ_STATUS + SBRS F,3 + RJMP WAIT_AUTO_LOOP + POP F + RET + +WAIT_STATUS: + PUSH F +WAIT_STATUS_LOOP: + RCALL READ_STATUS + SBRC F,0 + SBRS F,1 + RJMP WAIT_STATUS_LOOP + POP F + RET + +READ_STATUS: + SBI PORTC,0 ; C/D = 1 + LDI F,0 + OUT DDRA,F ; D0-D7 = INPUTS + CLI + CBI PORTB,0 ; RD = 0 + NOP + NOP + NOP + NOP + SBI PORTB,0 ; RD = 1 + IN F,PINA ; READ DATA BEFORE RD COMES UP + SEI + PUSH F + LDI F,$FF + OUT DDRA,F ; D0-D7 = OUTPUTS + POP F + RET + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; TURN OFF VEE MEASURING + + SBI PORTB,2 ; SRAM SELECT = 1 + CBI PORTD,6 ; T6963C RESET = 0 + CBI PORTD,7 ; T6963C SELECT = 0 + CBI PORTB,0 ; RD = 0 + CBI PORTB,1 ; WR = 0 + + LDI D,$FF + OUT DDRA,D ; D0-D7 = OUTPUTS + LDI D,0 + OUT PORTA,D ; D0-D7 = 0 + + LDI D,0 ;$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + ;LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$1F ; WATCHDOG TURN OFF ENABLE = 1 + OUT WDTCR,D + LDI D,$17 ; WATCHDOG ENABLE = 0 + OUT WDTCR,D + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: +; CLI ; FOR BEST SAFETY +; +; LDI F,$00 +; OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED +; OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED +; +; LDI F,$F8 ; INIT_PORTS +; OUT DDRD,F +; LDI F,$B8 ;$F8 +; OUT PORTD,F ; D6 = LOW TO RESET T6963C +; LDI F,$1F +; OUT DDRB,F +; LDI F,$FF +; OUT DDRA,F +; OUT DDRC,F +; +; CLR F +; OUT PORTA,F +; +;; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO +;; LDI F,$03 ; CS, RD, WR HI, LEs ALL LO +; IN F,PORTB +; ANDI F,$10 ; PRESERVE B4 FOR BACKLIGHT +; ORI F,$03 ; CS, RD, WR HI, LEs ALL LO +; OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT +; +;; LDI F,$00 +; IN F,PORTC +; ANDI F,$80 ; PRESERVE C7 FOR BACKLIGHT +; OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT +; +; SEI ; FOR BEST SAFETY +; CBI PORTD,6 ; SEE OUT PORTD,F ABOVE +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYX: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYX +; +; ; INITIALISE T6963C DISPLAY CONTROLLER +; SBI PORTD,6 ; COME OUT OF RESET +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYY: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOPZ: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOPZ + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + +; CLI ; FOR BEST SAFETY +; +; LDI A,HIGH(CONTRAST_MID) +; OUT OCR1BH,A +; LDI A,LOW(CONTRAST_MID) +; OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH +; +; LDI A,HIGH(T1_INIT) +; OUT TCNT1H,A +; LDI A,LOW(T1_INIT) +; OUT TCNT1L,A +; +; LDI A,$50 +; OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH +; LDI A,$01 +; OUT TCCR1B,A ; TIMER 1 RUNNING +; +; LDI F,$00 +; OUT TCCR0,F ; TIMER 0 NOT RUNNING YET +; +; LDI F,$04 ;$05 +; OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS +; OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS +; +; LDI F,$0A +; OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE +; LDI F,$C0 +; OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS +; OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 +; +; SEI ; FOR BEST SAFETY + + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT + ANDI A,1 + BRNE SET_BACKLIGHT_ON + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + RJMP MAIN_LOOP +SET_BACKLIGHT_ON: + LDI A,1<<7 + OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + +; LDS A,CONTRASTL +; RCALL TX_WAIT +; LDS A,CONTRASTH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 1 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_PAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + LDI XL,LOW(ROWBUF) + LDI XH,HIGH(ROWBUF) ; X -> SINGLE LINE BUFFER IN AVR SRAM + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,30 ; BYTES TO COPY +DO_MORE: + A0_A13 YL,YH + RAMRD A + ST X+,A + INC YL + DEC B + RJNE DO_MORE ;BRNE DO_MORE + + POP XH + POP XL + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> SINGLE LINE IN T6963C BUFFER + + CBI PORTD,7 ; CS0 = 0 + MOV F,YL + RCALL WRITE_DATA + MOV F,YH + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI B,30 + LDI YL,LOW(ROWBUF) + LDI YH,HIGH(ROWBUF) ; Y -> SINGLE LINE BUFFER IN AVR SRAM +NICK_SUB2_LOOP: + LD F,Y+ + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + DEC B + BRNE NICK_SUB2_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + SBI PORTD,7 ; CS0 = 1 + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +; SBI DDRB,7 +; IN D,PORTB +; SUBI D,$80 +; OUT PORTB,D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + SBRS FLAGS,7 + RJMP BACKLIGHT_SKIP + LDS D,BACKLIGHT_COUNT + INC D +; LDS C,CONTRASTL +; LSL C +; CP D,C + CPI D,37 ;62 ;64 ; 64 COUNTS = 150 HZ + BRSH BACKLIGHT_EVEN +; LSR C +; CP D,C + CPI D,18 ;31 ;32 + BRNE BACKLIGHT_SAVE +;BACKLIGHT_ODD: + CBI PORTC,7 + SBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 + RJMP BACKLIGHT_CONT +BACKLIGHT_EVEN: + SBI PORTC,7 + CBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + LDI D,0 +BACKLIGHT_CONT: + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 +BACKLIGHT_SAVE: + STS BACKLIGHT_COUNT,D +BACKLIGHT_SKIP: + + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS D,BREAK_COUNT+1 ; WORD IS STORED IN REVERSE ORDER + SUBI D,-$40 + STS BREAK_COUNT+1,D ; START OF 4 INTERRUPT BLOCK? + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + LDI D,$B0 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, CLR OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD + LDI D,$0B+$AB ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VCCL + LDS D,VCCH + LDI E,LOW(VCC_NOMINAL) + SUB C,E + LDI E,HIGH(VCC_NOMINAL) + SBC D,E + + ROR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +; PUSH D +; PUSH C + ASR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +; POP E +; ADD C,E +; POP E +; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + +; CLR D +; CLR C + + LDS E,VEEL + ADD C,E + LDS E,VEEH + ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH WE ARE NO LONGER SETTING TIMER 0 + NOP + NOP + NOP + NOP + NOP + NOP + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + +;END_INT: + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/cs64v2.asm b/src/avr/cs64v2.asm new file mode 100644 index 00000000..2de7eabb --- /dev/null +++ b/src/avr/cs64v2.asm @@ -0,0 +1,2928 @@ +; CS64V2.ASM +; 22NOV01 REVISE FOR OPERATION FROM VCC INSTEAD OF VBAT +; INVERT SENSE OF SRAM CHIP SELECT +; STILL NEED TO REMOVE VCC COMPENSATION CODE + +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APICS.INC" ; NOT API.INC BECAUSE APICS.INC HAS WDR IN TX_WAIT_LOOP + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL +; THIS WILL CORRUPT BACKLIGHT + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 + ANDI R19,$80 + EOR R19,@0 + SEI + OUT PORTC,R19 +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @0,1 ; A15 +; BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @1,7 ; A15 +; BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFF0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FD60 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +TEMP: .BYTE 1 ; 10C + +LATCH11_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 2 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +BACKLIGHT_COUNT: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RETI ; TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + +RESTART_ENTRY: + LDI F,$00 + OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED + OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F ; D6 = LOW TO RESET T6963C + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + +; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO + LDI F,$03 ; CS, RD, WR HI, LEs ALL LO + OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT + + LDI F,$00 + OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT + + LDI F,$20 ;$A0 NO BACKLIGHT INVERSION INITIALLY + MOV FLAGS,F ; START WITH DISPLAY ON + + INIT_API_BUS + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT+1,D ; KLUDGE FOR EXTRA 2 BITS OF RESOLUTION + + ; INITIALISE T6963C DISPLAY CONTROLLER + SBI PORTD,6 ; COME OUT OF RESET + + LDI ZL,0 + LDI ZH,0 +RESET_DELAY: + WDR ; 10OCT02 RESET WATCHDOG + SBIW ZL,1 + BRNE RESET_DELAY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOP: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + CLR A + STS BACKLIGHT_COUNT,A ; ENSURE BACKLIGHT COUNT IS IN RANGE + + CLR ZL + CLR ZH ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$04 ;$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +WRITE_COMMAND: + RCALL WAIT_STATUS ; LEAVES C/D = 1 + RJMP WRITE_ENTRY +WRITE_COMMAND_AUTO: + RCALL WAIT_AUTO ; LEAVES C/D = 1 + RJMP WRITE_ENTRY + +WRITE_DATA: + RCALL WAIT_STATUS + RJMP WRITE_DATA_ENTRY +WRITE_DATA_AUTO: + RCALL WAIT_AUTO +WRITE_DATA_ENTRY: + CBI PORTC,0 ; C/D = 0 +WRITE_ENTRY: + OUT PORTA,F + NOP + NOP + NOP + CLI + CBI PORTB,1 ; WR = 0 + NOP + NOP + NOP + SEI + SBI PORTB,1 ; WR = 1 + RET + +WAIT_AUTO: + PUSH F +WAIT_AUTO_LOOP: + RCALL READ_STATUS + SBRS F,3 + RJMP WAIT_AUTO_LOOP + POP F + RET + +WAIT_STATUS: + PUSH F +WAIT_STATUS_LOOP: + RCALL READ_STATUS + SBRC F,0 + SBRS F,1 + RJMP WAIT_STATUS_LOOP + POP F + RET + +READ_STATUS: + SBI PORTC,0 ; C/D = 1 + LDI F,0 + OUT DDRA,F ; D0-D7 = INPUTS + CLI + CBI PORTB,0 ; RD = 0 + NOP + NOP + NOP + NOP + SBI PORTB,0 ; RD = 1 + IN F,PINA ; READ DATA BEFORE RD COMES UP + SEI + PUSH F + LDI F,$FF + OUT DDRA,F ; D0-D7 = OUTPUTS + POP F + RET + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; TURN OFF VEE MEASURING + + CBI PORTB,2 ; REMOVE WEAK PULL UP (SRAM SELECT = 1) + SBI DDRB,2 ; NOW DRIVE LOW + CBI PORTD,6 ; T6963C RESET = 0 + CBI PORTD,7 ; T6963C SELECT = 0 + CBI PORTB,0 ; RD = 0 + CBI PORTB,1 ; WR = 0 + + LDI D,$FF + OUT DDRA,D ; D0-D7 = OUTPUTS + LDI D,0 + OUT PORTA,D ; D0-D7 = 0 + + LDI D,0 ;$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + ;LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$1F ; WATCHDOG TURN OFF ENABLE = 1 + OUT WDTCR,D + LDI D,$17 ; WATCHDOG ENABLE = 0 + OUT WDTCR,D + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: +; CLI ; FOR BEST SAFETY +; +; LDI F,$00 +; OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED +; OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED +; +; LDI F,$F8 ; INIT_PORTS +; OUT DDRD,F +; LDI F,$B8 ;$F8 +; OUT PORTD,F ; D6 = LOW TO RESET T6963C +; LDI F,$1F +; OUT DDRB,F +; LDI F,$FF +; OUT DDRA,F +; OUT DDRC,F +; +; CLR F +; OUT PORTA,F +; +;; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO +;; LDI F,$03 ; CS, RD, WR HI, LEs ALL LO +; IN F,PORTB +; ANDI F,$10 ; PRESERVE B4 FOR BACKLIGHT +; ORI F,$03 ; CS, RD, WR HI, LEs ALL LO +; OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT +; +;; LDI F,$00 +; IN F,PORTC +; ANDI F,$80 ; PRESERVE C7 FOR BACKLIGHT +; OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT +; +; SEI ; FOR BEST SAFETY +; CBI PORTD,6 ; SEE OUT PORTD,F ABOVE +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYX: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYX +; +; ; INITIALISE T6963C DISPLAY CONTROLLER +; SBI PORTD,6 ; COME OUT OF RESET +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYY: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOPZ: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOPZ + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + +; CLI ; FOR BEST SAFETY +; +; LDI A,HIGH(CONTRAST_MID) +; OUT OCR1BH,A +; LDI A,LOW(CONTRAST_MID) +; OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH +; +; LDI A,HIGH(T1_INIT) +; OUT TCNT1H,A +; LDI A,LOW(T1_INIT) +; OUT TCNT1L,A +; +; LDI A,$50 +; OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH +; LDI A,$01 +; OUT TCCR1B,A ; TIMER 1 RUNNING +; +; LDI F,$00 +; OUT TCCR0,F ; TIMER 0 NOT RUNNING YET +; +; LDI F,$04 ;$05 +; OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS +; OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS +; +; LDI F,$0A +; OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE +; LDI F,$C0 +; OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS +; OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 +; +; SEI ; FOR BEST SAFETY + + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT + ANDI A,1 + BRNE SET_BACKLIGHT_ON + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + RJMP MAIN_LOOP +SET_BACKLIGHT_ON: + LDI A,1<<7 + OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + +; LDS A,CONTRASTL +; RCALL TX_WAIT +; LDS A,CONTRASTH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 1 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_PAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + LDI XL,LOW(ROWBUF) + LDI XH,HIGH(ROWBUF) ; X -> SINGLE LINE BUFFER IN AVR SRAM + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,30 ; BYTES TO COPY +DO_MORE: + A0_A13 YL,YH + RAMRD A + ST X+,A + INC YL + DEC B + RJNE DO_MORE ;BRNE DO_MORE + + POP XH + POP XL + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> SINGLE LINE IN T6963C BUFFER + + CBI PORTD,7 ; CS0 = 0 + MOV F,YL + RCALL WRITE_DATA + MOV F,YH + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI B,30 + LDI YL,LOW(ROWBUF) + LDI YH,HIGH(ROWBUF) ; Y -> SINGLE LINE BUFFER IN AVR SRAM +NICK_SUB2_LOOP: + LD F,Y+ + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + DEC B + BRNE NICK_SUB2_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + SBI PORTD,7 ; CS0 = 1 + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +; SBI DDRB,7 +; IN D,PORTB +; SUBI D,$80 +; OUT PORTB,D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + SBRS FLAGS,7 + RJMP BACKLIGHT_SKIP + LDS D,BACKLIGHT_COUNT + INC D +; LDS C,CONTRASTL +; LSL C +; CP D,C + CPI D,62 ;64 ; 64 COUNTS = 150 HZ + BRSH BACKLIGHT_EVEN +; LSR C +; CP D,C + CPI D,31 ;32 + BRNE BACKLIGHT_SAVE +;BACKLIGHT_ODD: + CBI PORTC,7 + SBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 + RJMP BACKLIGHT_CONT +BACKLIGHT_EVEN: + SBI PORTC,7 + CBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + LDI D,0 +BACKLIGHT_CONT: + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 +BACKLIGHT_SAVE: + STS BACKLIGHT_COUNT,D +BACKLIGHT_SKIP: + + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS D,BREAK_COUNT+1 ; WORD IS STORED IN REVERSE ORDER + SUBI D,-$40 + STS BREAK_COUNT+1,D ; START OF 4 INTERRUPT BLOCK? + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + LDI D,$B0 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, CLR OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD + LDI D,$0B+$AB ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VCCL + LDS D,VCCH + LDI E,LOW(VCC_NOMINAL) + SUB C,E + LDI E,HIGH(VCC_NOMINAL) + SBC D,E + + ROR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +; PUSH D +; PUSH C + ASR D + ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +; POP E +; ADD C,E +; POP E +; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + +; CLR D +; CLR C + + LDS E,VEEL + ADD C,E + LDS E,VEEH + ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH WE ARE NO LONGER SETTING TIMER 0 + NOP + NOP + NOP + NOP + NOP + NOP + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + +;END_INT: + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/cs64v4-cs64v5.diff b/src/avr/cs64v4-cs64v5.diff new file mode 100644 index 00000000..8c3c2156 --- /dev/null +++ b/src/avr/cs64v4-cs64v5.diff @@ -0,0 +1,625 @@ +--- cs64v4.asm 2003-03-18 12:26:48.000000000 +1100 ++++ cs64v5.asm 2003-03-20 16:55:20.000000000 +1100 +@@ -1,4 +1,4 @@ +-; CS64V4.ASM ++; CS64V5.ASM + + ; 01FEB02 REVISE FOR 7.3728MHz XTAL + ; 22NOV01 REVISE FOR OPERATION FROM VCC INSTEAD OF VBAT +@@ -15,8 +15,8 @@ + .LISTMAC + .MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) +- STS PAGE,YH +- RCALL ADRYP ; AND SET PAGE ++ STS XPAGE,YH ++ RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) + .ENDMACRO +@@ -285,12 +285,13 @@ + + .EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS + .EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +-.EQU API_RATE_SLOW =$5F ;$8F ; DIVISOR FOR 4800 BPS +-.EQU API_RATE_FAST =$03 ;$05 ; DIVISOR FOR 115200 BPS ++.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS ++.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS + .EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM + .EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD + .EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + ++.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE + .DEF SR =R1 + .DEF RX_PTR =R2 + .DEF RX_COUNT =R3 +@@ -355,7 +356,7 @@ + TEMP: .BYTE 1 ; 10C + + LATCH11_SAV: .BYTE 1 +-PAGE: .BYTE 1 ++XPAGE: .BYTE 1 + ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + + LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +@@ -572,9 +573,15 @@ + BREQ CHARACTER_SET_INIT_DONE + + CHARACTER_SET_INIT: +- LDIZ CHSET00 ; POINT Z TO FLASH +- LDIX CHSET00_END-CHSET00 ; BYTE COUNTER +- LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE ++; LDIZ CHSET00 ; POINT Z TO FLASH ++ LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++; LDIX CHSET00_END-CHSET00 ; BYTE COUNTER ++ LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER ++ LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++ LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE + CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT + CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM +@@ -612,11 +619,11 @@ + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + +- LDI B,EE_CONTRAST*2 ++ LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A +- LDI B,EE_CONTRAST*2+1 ++ LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + +@@ -808,7 +815,7 @@ + ; ----------------------------------------------------------------------------- + + ADRYP: +-; LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM ++; LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM + ; LDS YL,LATCH10_SAV + ; ANDI YL,$E0 + ; OR YH,YL +@@ -822,10 +829,10 @@ + ; CLR YL + ; INC YH + ; BRNE INCRET +-; LDS YH,PAGE ++; LDS YH,XPAGE + ; INC YH + ; ANDI YH,$1F +-; STS PAGE,YH ++; STS XPAGE,YH + ; CLR YH + ;INCRET: RET + +@@ -892,14 +899,22 @@ + RJEQ NULLSUB + CPI A,'C' + RJEQ CLEAR_RECTANGLE ++ CPI A,'c' ++ RJEQ GET_CLEAR_FRAME_RECT_SIZE + CPI A,'D' + RJEQ DRAW_MODE + CPI A,'E' + RJEQ ENABLE_CNTRL + CPI A,'F' + RJEQ GET_FILLED_RECTNC_SIZE ++ CPI A,'f' ++ RJEQ GET_FRAME_RECT_SIZE + CPI A,'G' + RJEQ INTERPRET_MODE ++ CPI A,'H' ++ RJEQ GET_HALFTONE_RECT_SIZE ++ CPI A,'h' ++ RJEQ GET_CLEAR_HALFTONE_RECT_SIZE + CPI A,'K' + RJEQ CLR_DISP + CPI A,'L' +@@ -1320,10 +1335,10 @@ + ; LDI A,$0D + ; RCALL TX_WAIT + +- LDI B,EE_CONTRAST*2 ++ LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH +- LDI B,EE_CONTRAST*2+1 ++ LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + + CONTRAST_DONE: +@@ -1702,7 +1717,7 @@ + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 +@@ -1772,7 +1787,7 @@ + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + POP B + POP A + OK_LINE: +@@ -1823,7 +1838,7 @@ + + MORE_X: ADIW YL,$01 + LDS A,PTR+2 +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RCALL LPMS + + CLR A +@@ -1910,7 +1925,7 @@ + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + LDI B,30 ; BYTES TO COPY + DO_MORE: +@@ -2089,7 +2104,7 @@ + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RJMP L03A3 + L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) +@@ -2285,7 +2300,7 @@ + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE + L065C: LDS A,XBYTE_SAV +@@ -2439,12 +2454,13 @@ + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + +- ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN +- ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD +- LDI D,$0B+$AB ; WAIT FOR 3uSEC +-SETTLE_CL2: +- DEC D +- BRNE SETTLE_CL2 ++; 10mar03 for better API bus performance (let the chips fall where they may) ++; ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN ++; ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD ++; LDI D,$0B+$AB ; WAIT FOR 3uSEC ++;SETTLE_CL2: ++; DEC D ++; BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL +@@ -2474,31 +2490,31 @@ + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + +- LDS C,VCCL +- LDS D,VCCH +- LDI E,LOW(VCC_NOMINAL) +- SUB C,E +- LDI E,HIGH(VCC_NOMINAL) +- SBC D,E +- +- ROR D +- ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +-; PUSH D +-; PUSH C +- ASR D +- ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +-; POP E ++; LDS C,VCCL ++; LDS D,VCCH ++; LDI E,LOW(VCC_NOMINAL) ++; SUB C,E ++; LDI E,HIGH(VCC_NOMINAL) ++; SBC D,E ++; ++; ROR D ++; ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 ++;; PUSH D ++;; PUSH C ++; ASR D ++; ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 ++;; POP E ++;; ADD C,E ++;; POP E ++;; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 ++; ++;; CLR D ++;; CLR C ++; ++; LDS E,VEEL + ; ADD C,E +-; POP E +-; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 +- +-; CLR D +-; CLR C +- +- LDS E,VEEL +- ADD C,E +- LDS E,VEEH +- ADC D,E ++; LDS E,VEEH ++; ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH +@@ -2562,7 +2578,7 @@ + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) +@@ -2614,7 +2630,7 @@ + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 +@@ -2815,113 +2831,244 @@ + RAMWR A + RET + +-SELECT_PAGE: ++SELECT_XPAGE: + A14_A18 A + RET + + ; ----------------------------------------------------------------------------- + + CHSET00: +- .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 +- .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 +- .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 +- .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 +- .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 +- .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 +- .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 +- .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 +- .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 +- .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 +- .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 +- .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 +- .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 +- .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 +- .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 +- .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 +- .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 +- .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 +- .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 +- .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 +- .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 +- .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 +- .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 +- .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 +- .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 +- .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 +- .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 +- .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 +- .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 +- .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 +- .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 +- .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 +- .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 +- .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 +- .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 +- .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 +- .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 +- .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 +- .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 +- .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 +- .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 +- .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 +- .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 +- .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 +- .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 +- .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 +- .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 +- .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 +- .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 +- .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 +- .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 +- .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 +- .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 +- .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 +- .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 +- .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 +- .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 +- .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 +- .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 +- .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 +- .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 +- .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 +- .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 +- .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 +- .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 +- .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 +- .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 +- .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 +- .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 +- .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 +- .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A ++.INCLUDE "CHSET00.INC" + CHSET00_END: + + ; ----------------------------------------------------------------------------- + ++GET_CLEAR_FRAME_RECT_SIZE: ++ STS RECTNC_X,CURSORX ++ STS RECTNC_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECTNC_XX,A ++ RCALL RX_WAIT ++ STS RECTNC_YY,A ++ RCALL CLEAR_FRAME_RECT ++ RJMP MAIN_LOOP ++ ++GET_FRAME_RECT_SIZE: ++ STS RECTNC_X,CURSORX ++ STS RECTNC_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECTNC_XX,A ++ RCALL RX_WAIT ++ STS RECTNC_YY,A ++ RCALL FRAME_RECT ++ RJMP MAIN_LOOP ++ ++GET_CLEAR_HALFTONE_RECT_SIZE: ++ STS RECT_X,CURSORX ++ STS RECT_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECT_XX,A ++ RCALL RX_WAIT ++ STS RECT_YY,A ++ RCALL CLEAR_HALFTONE_RECT ++ RJMP MAIN_LOOP ++ ++GET_HALFTONE_RECT_SIZE: ++ STS RECT_X,CURSORX ++ STS RECT_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECT_XX,A ++ RCALL RX_WAIT ++ STS RECT_YY,A ++ RCALL HALFTONE_RECT ++ RJMP MAIN_LOOP ++ ++NO_GOX: RET ++ ++CLEAR_FRAME_RECT: ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ STS RECT_Y,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDS F,RECTNC_YY ++ STS RECT_YY,F ++ ++ LDI F,$02 ++ OR FLAGS,F ++ ++ RCALL DRAW_RECT ++ ++ LDI F,$FD ++ AND FLAGS,F ++ ++FRAME_RECT: ++ LDS F,RECTNC_XX ++ DEC F ++ CPI F,2 ++ BRLO NO_GOX ++ LDS F,RECTNC_YY ++ CPI F,3 ++ BRLO NO_GOX ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ STS RECT_Y,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDI F,$01 ++ STS RECT_YY,F ++ RCALL DRAW_RECT ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ INC F ++ STS RECT_Y,F ++ LDS F,RECTNC_YY ++ SUBI F,2 ++ STS RECT_YY,F ++ LDI F,$01 ++ STS RECT_XX,F ++ RCALL DRAW_RECT ++ ++ LDS X_SIZE,RECTNC_XX ++ LDS F,RECTNC_X ++ ADD F,X_SIZE ++ DEC F ++ STS RECT_X,F ++ LDI F,$01 ++ STS RECT_XX,F ++ LDS F,RECTNC_Y ++ INC F ++ STS RECT_Y,F ++ LDS F,RECTNC_YY ++ SUBI F,2 ++ STS RECT_YY,F ++ RCALL DRAW_RECT ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDS Y_SIZE,RECTNC_YY ++ LDS F,RECTNC_Y ++ ADD F,Y_SIZE ++ DEC F ++ STS RECT_Y,F ++ LDI F,$01 ++ STS RECT_YY,F ++ RJMP DRAW_RECT ++ ++CLEAR_HALFTONE_RECT: ++; LDS F,RECTNC_X ++; STS RECT_X,F ++; LDS F,RECTNC_Y ++; STS RECT_Y,F ++; LDS F,RECTNC_XX ++; STS RECT_XX,F ++; LDS F,RECTNC_YY ++; STS RECT_YY,F ++ ++ LDI F,$02 ++ OR FLAGS,F ++ ++ RCALL DRAW_RECT ++ ++ LDI F,$FD ++ AND FLAGS,F ++ ++HALFTONE_RECT: ++ SEI ++ LDS LINE_CNT,RECT_Y ++ LDS XPIXEL,RECT_X ++ RCALL CALCULATE_XBYTE ++ STS XPIXEL_SAV,XPIXEL ++ STS XBYTE_SAV,XBYTE ++ LDS Y_SIZE,RECT_YY ++ CLR YL ++ MOV YH,LINE_CNT ++ LDI A,$55 ++ SBRS YH,0 ++ LDI A,$AA ++ MOV PATTERN,A ++ LSR YH ++ ROR YL ++ LSR YH ++ ROR YL ++ SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER ++ LDI A,HIGH(DRAW_DSPRAM>>6) ++ RCALL SELECT_XPAGE ++ RJMP X03A3 ++X039A: SUBI YL,LOW(-$40) ++ SBCI YH,HIGH(-$40) ++ INC LINE_CNT ++ LDS XPIXEL,XPIXEL_SAV ++ LDS XBYTE,XBYTE_SAV ++X03A3: OR XBYTE,YL ++ LDI A,$FF ++ LDS X_SIZE,RECT_XX ++ LDI F,$00 ++ CP X_SIZE,F ++ BREQ X03B0 ++ LDI F,$08 ++ CP X_SIZE,F ++ BRLO X03C2 ++ TST XPIXEL ++ BREQ X03B0 ++X03AD: LSR A ++ DEC XPIXEL ++ BRNE X03AD ++X03B0: AND A,PATTERN ++ RCALL WR_DISP_MEM ++ LDI F,$08 ++ LDS A,XPIXEL_SAV ++ SUB F,A ++ SUB X_SIZE,F ++ INC XBYTE ++ LDI A,$FF ++X03B8: LDI F,$08 ++ CP X_SIZE,F ++ BRLO X03C2 ++ BREQ X03D2 ++ AND A,PATTERN ++ RCALL WR_DISP_MEM ++ LDI A,$FF ++ LDI F,$08 ++ SUB X_SIZE,F ++ INC XBYTE ++ RJMP X03B8 ++X03C2: TST X_SIZE ++ BREQ X03D3 ++X03C4: LSR A ++ DEC X_SIZE ++ BRNE X03C4 ++ COM A ++ TST XPIXEL ++ BREQ X03D2 ++ CLR B ++X03CB: LSR A ++ ROR B ++ DEC XPIXEL ++ BRNE X03CB ++ AND A,PATTERN ++ RCALL WR_DISP_MEM ++ INC XBYTE ++ MOV A,B ++X03D2: AND A,PATTERN ++ RCALL WR_DISP_MEM ++X03D3: COM PATTERN ++ RCALL NICK_SUB1 ++ DEC Y_SIZE ++ CLR F ++ CPSE Y_SIZE,F ++ RJMP X039A ++ RET ++ ++; ----------------------------------------------------------------------------- ++ + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND diff --git a/src/avr/cs64v4.asm b/src/avr/cs64v4.asm new file mode 100644 index 00000000..f1c9a503 --- /dev/null +++ b/src/avr/cs64v4.asm @@ -0,0 +1,3077 @@ +; CS64V4.ASM + +; 01FEB02 REVISE FOR 7.3728MHz XTAL +; 22NOV01 REVISE FOR OPERATION FROM VCC INSTEAD OF VBAT +; INVERT SENSE OF SRAM CHIP SELECT +; STILL NEED TO REMOVE VCC COMPENSATION CODE + +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APICS.INC" ; NOT API.INC BECAUSE APICS.INC HAS WDR IN TX_WAIT_LOOP + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS XPAGE,YH + RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL +; THIS WILL CORRUPT BACKLIGHT + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 + ANDI R19,$80 + EOR R19,@0 + SEI + OUT PORTC,R19 +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + CLI + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + SEI + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 ;@1 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @0,1 ; A15 +; BLD R19,7 ;1 + BST @0,0 ; A14 + BLD R19,6 ;0 + SEI + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + IN R19,PORTC ;MOV R19,@0 + EOR R19,@0 ; + ANDI R19,$C0 ;$3F + EOR R19,@0 ; + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,R19 ;@1 + ;POP @1 + + IN R19,PORTC ;LDS R19,LATCH10_SAV ; AND THIS +; REMOVE TO AVOID CORRUPTING BACKLIGHT +; BST @1,7 ; A15 +; BLD R19,7 ;1 + BST @1,6 ; A14 + BLD R19,6 ;0 + OUT PORTC,R19 ;PORTA,R19 + ;SBI PORTB,4 + ;CBI PORTB,4 + ;STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,1 + NOP + SBI PORTB,1 + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + CBI PORTB,1 + NOP + SBI PORTB,1 + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + SEI + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + SBI PORTB,2 ; DRIVE HIGH + CBI DDRB,2 ; NOW SWITCH TO WEAK PULL UP + CBI PORTB,0 + NOP + SBI PORTB,0 + IN @0,PINA ; READ DATA + CBI PORTB,2 ; REMOVE WEAK PULL UP + SBI DDRB,2 ; NOW DRIVE LOW + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO +.ENDMACRO + +.MACRO LED +.ENDMACRO + +.MACRO LEDLO +.ENDMACRO + +.MACRO LEDHI +.ENDMACRO + +.MACRO SPKHI +.ENDMACRO + +.MACRO SPKLO +.ENDMACRO + +.MACRO SPKOFF +.ENDMACRO + +.EQU T1_INIT =-818 ;$FB35 +.EQU T1_FULL_SCALE =-651 ;$FC2F + +.EQU VEE_MIN =-640 ;$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX = -43 ;$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =-341 ;$FE00 + +.EQU CONTRAST_LONG =-640 ;$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT = -11 ;$FFF0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =-341 ;$FE00 + +.EQU VCC_NOMINAL =-536 ;$FCDC + +; WITH VCC = $FCDC FOR 6.0V: +;.EQU CONTRAST_MIN =$FD18 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FD78 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FD48 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +.EQU CONTRAST_MIN =-630 ;$FC80 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX = -85 ;$FF80 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =-448 ;$FD60 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$61000 ;$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$62000 ;$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$40 +.EQU CHARACTER_SETS =6 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$10 +.EQU RX_SIZE =$80 + +.EQU API_ADDRESS =$03 ; CUSTOMER DISPLAY ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$5F ;$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ;$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF BOXSIZEX =R7 ; ASSIGNED TWICE +.DEF BOXSIZEY =R8 ; ASSIGNED TWICE +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 0=BACKLIGHT INVERSION OFF 1=BACKLIGHT INVERSION ON +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +TEMP: .BYTE 1 ; 10C + +LATCH11_SAV: .BYTE 1 +XPAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +; MUST CONVERT TO USE DRAW_CHAR_TTY ROUTINE +;CHAR_X: .BYTE 1 +;CHAR_Y: .BYTE 1 +;CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 2 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +BACKLIGHT_COUNT: .BYTE 1 + +AVECNT: .BYTE 1 +AVEVCC: .BYTE 1 +AVEVCCL: .BYTE 1 +AVEVCCH: .BYTE 1 +AVEVEE: .BYTE 1 +AVEVEEL: .BYTE 1 +AVEVEEH: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RETI ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_TIM1_OVF + RETI ; TIM0_OVF + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + +RESTART_ENTRY: + LDI F,$00 + OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED + OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED + + LDI F,$F8 ; INIT_PORTS + OUT DDRD,F + LDI F,$B8 ;$F8 + OUT PORTD,F ; D6 = LOW TO RESET T6963C + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + +; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO + LDI F,$03 ; CS, RD, WR HI, LEs ALL LO + OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT + + LDI F,$00 + OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT + + LDI F,$20 ;$A0 NO BACKLIGHT INVERSION INITIALLY + MOV FLAGS,F ; START WITH DISPLAY ON + + INIT_API_BUS + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT+1,D ; KLUDGE FOR EXTRA 2 BITS OF RESOLUTION + + ; INITIALISE T6963C DISPLAY CONTROLLER + SBI PORTD,6 ; COME OUT OF RESET + + LDI ZL,0 + LDI ZH,0 +RESET_DELAY: + WDR ; 10OCT02 RESET WATCHDOG + SBIW ZL,1 + BRNE RESET_DELAY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOP: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: +; LDIZ CHSET00 ; POINT Z TO FLASH + LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + +; LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + ; ADRL MACRO WILL CORRUPT BACKLIGHT +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + CLR A + STS BACKLIGHT_COUNT,A ; ENSURE BACKLIGHT COUNT IS IN RANGE + + CLR ZL + CLR ZH ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$04 ;$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +WRITE_COMMAND: + RCALL WAIT_STATUS ; LEAVES C/D = 1 + RJMP WRITE_ENTRY +WRITE_COMMAND_AUTO: + RCALL WAIT_AUTO ; LEAVES C/D = 1 + RJMP WRITE_ENTRY + +WRITE_DATA: + RCALL WAIT_STATUS + RJMP WRITE_DATA_ENTRY +WRITE_DATA_AUTO: + RCALL WAIT_AUTO +WRITE_DATA_ENTRY: + CBI PORTC,0 ; C/D = 0 +WRITE_ENTRY: + OUT PORTA,F + NOP + NOP + NOP + CLI + CBI PORTB,1 ; WR = 0 + NOP + NOP + NOP + SEI + SBI PORTB,1 ; WR = 1 + RET + +WAIT_AUTO: + PUSH F +WAIT_AUTO_LOOP: + RCALL READ_STATUS + SBRS F,3 + RJMP WAIT_AUTO_LOOP + POP F + RET + +WAIT_STATUS: + PUSH F +WAIT_STATUS_LOOP: + RCALL READ_STATUS + SBRC F,0 + SBRS F,1 + RJMP WAIT_STATUS_LOOP + POP F + RET + +READ_STATUS: + SBI PORTC,0 ; C/D = 1 + LDI F,0 + OUT DDRA,F ; D0-D7 = INPUTS + CLI + CBI PORTB,0 ; RD = 0 + NOP + NOP + NOP + NOP + SBI PORTB,0 ; RD = 1 + IN F,PINA ; READ DATA BEFORE RD COMES UP + SEI + PUSH F + LDI F,$FF + OUT DDRA,F ; D0-D7 = OUTPUTS + POP F + RET + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + CBI PORTD,4 ; TURN TRANSISTOR ON (PULL DOWN VSWT) + CBI PORTD,5 ; TURN OFF VEE MEASURING + + CBI PORTB,2 ; REMOVE WEAK PULL UP (SRAM SELECT = 1) + SBI DDRB,2 ; NOW DRIVE LOW + CBI PORTD,6 ; T6963C RESET = 0 + CBI PORTD,7 ; T6963C SELECT = 0 + CBI PORTB,0 ; RD = 0 + CBI PORTB,1 ; WR = 0 + + LDI D,$FF + OUT DDRA,D ; D0-D7 = OUTPUTS + LDI D,0 + OUT PORTA,D ; D0-D7 = 0 + + LDI D,0 ;$40 + OUT TIMSK,D ; DISABLE TIMER 0 / 1 INTERRUPTS + + ;LDI D,0 + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + +; LDI F,$18 +; STS TURNON_COUNT,F ; .1 SECOND TO BREAK, .2 SECOND TO MAKE +; +; SEI +; +;SLEEP_LOOP: +; SLEEP +; +; LDS F,TURNON_COUNT +; TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? +; BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP +; +; CLI +; RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + + LDI D,$1F ; WATCHDOG TURN OFF ENABLE = 1 + OUT WDTCR,D + LDI D,$17 ; WATCHDOG ENABLE = 0 + OUT WDTCR,D + + LDI D,$6A + OUT MCUCR,D ; SE=0 SM1:SM0=10 FOR POWER DOWN MODE + SLEEP ; WE WILL NEVER WAKE UP + +; ----------------------------------------------------------------------------- + +ADRYP: +; LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM +; LDS YL,LATCH10_SAV +; ANDI YL,$E0 +; OR YH,YL +; OUT PORTA,YH +; SBI PORTB,4 +; CBI PORTB,4 +; STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,XPAGE +; INC YH +; ANDI YH,$1F +; STS XPAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: +; CLI ; FOR BEST SAFETY +; +; LDI F,$00 +; OUT TIMSK,F ; TIMER 0 / 1 / 2 INTERRUPTS DISABLED +; OUT GIMSK,F ; THERMISTOR / VCC INTERRUPTS DISABLED +; +; LDI F,$F8 ; INIT_PORTS +; OUT DDRD,F +; LDI F,$B8 ;$F8 +; OUT PORTD,F ; D6 = LOW TO RESET T6963C +; LDI F,$1F +; OUT DDRB,F +; LDI F,$FF +; OUT DDRA,F +; OUT DDRC,F +; +; CLR F +; OUT PORTA,F +; +;; LDI F,$07 ; CS, RD, WR HI, LEs ALL LO +;; LDI F,$03 ; CS, RD, WR HI, LEs ALL LO +; IN F,PORTB +; ANDI F,$10 ; PRESERVE B4 FOR BACKLIGHT +; ORI F,$03 ; CS, RD, WR HI, LEs ALL LO +; OUT PORTB,F ; INITIALISE B4 FOR BACKLIGHT +; +;; LDI F,$00 +; IN F,PORTC +; ANDI F,$80 ; PRESERVE C7 FOR BACKLIGHT +; OUT PORTC,F ; INITIALISE C7 FOR BACKLIGHT +; +; SEI ; FOR BEST SAFETY +; CBI PORTD,6 ; SEE OUT PORTD,F ABOVE +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYX: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYX +; +; ; INITIALISE T6963C DISPLAY CONTROLLER +; SBI PORTD,6 ; COME OUT OF RESET +; +; LDI ZL,0 +; LDI ZH,0 +;RESET_DELAYY: +; WDR ; RESET WATCHDOG +; SBIW ZL,1 +; BRNE RESET_DELAYY + + CBI PORTD,7 ; CS0 = 0 + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$42 + RCALL WRITE_COMMAND ; SET GRAPHIC HOME ADDRESS + LDI F,$20 + RCALL WRITE_DATA + LDI F,$00 + RCALL WRITE_DATA + LDI F,$43 + RCALL WRITE_COMMAND ; SET GRAPHIC AREA + LDI F,$80 + RCALL WRITE_COMMAND ; OR MODE + LDI F,$90 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS OFF + + LDI F,$00 + RCALL WRITE_DATA + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI ZL,LOW($800) + LDI ZH,HIGH($800) +CLEAR_LOOPZ: + LDI F,$00 + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + SBIW ZL,1 + BRNE CLEAR_LOOPZ + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + + LDI F,$98 + RCALL WRITE_COMMAND ; CURSOR OFF, TEXT OFF, GRAPHICS ON + SBI PORTD,7 ; CS0 = 1 + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + +; CLI ; FOR BEST SAFETY +; +; LDI A,HIGH(CONTRAST_MID) +; OUT OCR1BH,A +; LDI A,LOW(CONTRAST_MID) +; OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH +; +; LDI A,HIGH(T1_INIT) +; OUT TCNT1H,A +; LDI A,LOW(T1_INIT) +; OUT TCNT1L,A +; +; LDI A,$50 +; OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH +; LDI A,$01 +; OUT TCCR1B,A ; TIMER 1 RUNNING +; +; LDI F,$00 +; OUT TCCR0,F ; TIMER 0 NOT RUNNING YET +; +; LDI F,$04 ;$05 +; OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS +; OUT TIMSK,F ; TURN ON TIMER 0, 1 INTERRUPTS +; +; LDI F,$0A +; OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE +; LDI F,$C0 +; OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS +; OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 +; +; SEI ; FOR BEST SAFETY + + RJMP MAIN_LOOP + +SET_BACKLIGHT: + RCALL RX_WAIT + ANDI A,1 + BRNE SET_BACKLIGHT_ON + LDI A,~(1<<7) + AND FLAGS,A ; DISABLE INTERRUPT BACKLIGHT INVERSION + CBI PORTC,7 + CBI PORTB,4 ; EXPLICITLY TURN OFF BACKLIGHT + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 + RJMP MAIN_LOOP +SET_BACKLIGHT_ON: + LDI A,1<<7 + OR FLAGS,A ; ENABLE INTERRUPT BACKLIGHT INVERSION + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: RCALL CARRIAGE_RET + RJMP MAIN_LOOP + +CARRIAGE_RET: + CLR CURSORX + RET + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + +; LDS A,CONTRASTL +; RCALL TX_WAIT +; LDS A,CONTRASTH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +GO_EXT_INT0: + RJMP EXT_INT0 +GO_EXT_INT1: + RJMP EXT_INT1 +GO_TIM1_OVF: + RJMP TIM1_OVF +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT + RCALL RX_WAIT +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +;NICK_REPORT: +; LDI A,~(1<<7) +; AND FLAGS,A +; +; PUSH B +; +; CLI +; LDS A,AVEVCC +; LDS B,VCCL +; ADD A,B +; STS AVEVCC,A +; LDS A,AVEVCCL +; LDS B,VCCH +; SEI +; ADC A,B +; STS AVEVCCL,A +; LDS A,AVEVCCH +; LDI B,0 +; ADC A,B +; STS AVEVCCH,A +; +; CLI +; LDS A,AVEVEE +; LDS B,VEEL +; ADD A,B +; STS AVEVEE,A +; LDS A,AVEVEEL +; LDS B,VEEH +; SEI +; ADC A,B +; STS AVEVEEL,A +; LDS A,AVEVEEH +; LDI B,0 +; ADC A,B +; STS AVEVEEH,A +; +; POP B +; +; LDS A,AVECNT +; INC A +; STS AVECNT,A +; BRNE NICK_REPORT_DONE +; +; LDS A,AVEVCCL +; RCALL TX_WAIT +; LDS A,AVEVCCH +; RCALL TX_WAIT +; LDS A,AVEVEEL +; RCALL TX_WAIT +; LDS A,AVEVEEH +; RCALL TX_WAIT +; LDI A,$0D +; RCALL TX_WAIT +; +; CLR A +; STS AVEVCC,A +; STS AVEVCCL,A +; STS AVEVCCH,A +; STS AVEVEE,A +; STS AVEVEEL,A +; STS AVEVEEH,A +;NICK_REPORT_DONE: +; RET + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 1 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + +; SBRC FLAGS,7 +; RCALL NICK_REPORT + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + SEI + CLR F + STS TEMP,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + RCALL LPMS + MOV X_SIZE,R0 + MOV A,YL + MOV B,YH + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP PROP_WIDTH + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS + RJMP PROP_MODE + +PROP_WIDTH: + RCALL LPMS + SBRC FLAGS,4 + RJMP PROP_MODE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS + SUB R0,W + BRSH NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + MOV XPIXEL,CURSORX + ADD XPIXEL,R0 + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RCALL LPMS +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE + MOV F,CURSORX + ADD F,R0 + BRLO CR_LF + RJMP OK_LINE + +CR_LF: PUSH A + PUSH B + RCALL CARRIAGE_RET + RCALL LINE_FEED + LDS F,TEMP + ADD CURSORX,F + MOV LINE_CNT,CURSORY + MOV XPIXEL,CURSORX + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS F,TEMP + SUB CURSORX,F + LDS A,PTR+2 + RCALL SELECT_XPAGE + POP B + POP A +OK_LINE: + ADD CURSORX,R0 + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE + MOV YL,A + MOV YH,B + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 +Y_OFFSET_DONE: + MOV YL,A + MOV YH,B + ADIW YL,$01 + RCALL LPMS + MOV Y_SIZE,R0 + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS WHY ?? + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + LDI XL,LOW(ROWBUF) + LDI XH,HIGH(ROWBUF) ; X -> SINGLE LINE BUFFER IN AVR SRAM + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y -> SINGLE LINE FROM DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + LDI B,30 ; BYTES TO COPY +DO_MORE: + A0_A13 YL,YH + RAMRD A + ST X+,A + INC YL + DEC B + RJNE DO_MORE ;BRNE DO_MORE + + POP XH + POP XL + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> SINGLE LINE IN T6963C BUFFER + + CBI PORTD,7 ; CS0 = 0 + MOV F,YL + RCALL WRITE_DATA + MOV F,YH + RCALL WRITE_DATA + LDI F,$24 + RCALL WRITE_COMMAND ; SET ADDRESS POINTER + LDI F,$B0 + RCALL WRITE_COMMAND ; SET DATA AUTO WRITE + LDI B,30 + LDI YL,LOW(ROWBUF) + LDI YH,HIGH(ROWBUF) ; Y -> SINGLE LINE BUFFER IN AVR SRAM +NICK_SUB2_LOOP: + LD F,Y+ + RCALL WRITE_DATA_AUTO ; FILL DISPLAY RAM + DEC B + BRNE NICK_SUB2_LOOP + LDI F,$B2 + RCALL WRITE_COMMAND_AUTO ; AUTO RESET + SBI PORTD,7 ; CS0 = 1 + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE +L0659: CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L0659 +; BRNE L0659 + CLR CURSORX ; HOME CURSOR + CLR CURSORY + RET + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +EXT_INT0: + IN SR,SREG ; MEASURE VCC + SBI DDRD,2 + IN C,TCNT1L + IN D,TCNT1H + STS VCCH,D + STS VCCL,C + RJMP END_EXT_INT + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP END_EXT_INT + +TIM1_OVF: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +; SBI DDRB,7 +; IN D,PORTB +; SUBI D,$80 +; OUT PORTB,D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + SBRS FLAGS,7 + RJMP BACKLIGHT_SKIP + LDS D,BACKLIGHT_COUNT + INC D +; LDS C,CONTRASTL +; LSL C +; CP D,C + CPI D,37 ;62 ;64 ; 64 COUNTS = 150 HZ + BRSH BACKLIGHT_EVEN +; LSR C +; CP D,C + CPI D,18 ;31 ;32 + BRNE BACKLIGHT_SAVE +;BACKLIGHT_ODD: + CBI PORTC,7 + SBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 + RJMP BACKLIGHT_CONT +BACKLIGHT_EVEN: + SBI PORTC,7 + CBI PORTB,4 ; PROVIDE COMPLEMENTARY INPUTS TO AC573 +; LDI D,1<<7 +; OR FLAGS,D ; FOR NICK_REPORT + LDI D,0 +BACKLIGHT_CONT: + LDS C,LATCH11_SAV + OUT PORTA,C ; JUST TO AVOID CLOBBERING HC573 + SBI PORTB,3 + CBI PORTB,3 ; PROVIDE LATCH PULSE, HC573 AND AC573 +BACKLIGHT_SAVE: + STS BACKLIGHT_COUNT,D +BACKLIGHT_SKIP: + + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + +; SBRC FLAGS,6 ; TURNOFF REQUESTED? +; RJMP SLEEP_ENTRY ; YES, SKIP CLOCKING AND SHUT DOWN + + LDS D,BREAK_COUNT+1 ; WORD IS STORED IN REVERSE ORDER + SUBI D,-$40 + STS BREAK_COUNT+1,D ; START OF 4 INTERRUPT BLOCK? + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + RJMP SLEEP_ENTRY +BREAK_CONT: + + LDI D,$B0 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, CLR OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + SBI DDRD,2 ; PRECHARGE VCC AND + SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + +; 10mar03 for better API bus performance (let the chips fall where they may) +; ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN +; ; REMAIN THE SAME ALTHOUGH THERE IS NOW NO CLOCKING PERIOD +; LDI D,$0B+$AB ; WAIT FOR 3uSEC +;SETTLE_CL2: +; DEC D +; BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + +; LDS C,VCCL +; LDS D,VCCH +; LDI E,LOW(VCC_NOMINAL) +; SUB C,E +; LDI E,HIGH(VCC_NOMINAL) +; SBC D,E +; +; ROR D +; ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +;; PUSH D +;; PUSH C +; ASR D +; ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +;; POP E +;; ADD C,E +;; POP E +;; ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 +; +;; CLR D +;; CLR C +; +; LDS E,VEEL +; ADD C,E +; LDS E,VEEH +; ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + ; ULTRA BODGY EXTRA DELAY SO THAT VCC COMPENSATION CAN + ; REMAIN THE SAME ALTHOUGH WE ARE NO LONGER SETTING TIMER 0 + NOP + NOP + NOP + NOP + NOP + NOP + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,2 ; START VCC AND + CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + +;END_INT: + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +END_EXT_INT: + OUT SREG,SR + RETI + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP L0659 + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_XPAGE: + A14_A18 A + RET + +; ----------------------------------------------------------------------------- + +CHSET00: +.INCLUDE "CHSET00.INC" +CHSET00_END: + +; ----------------------------------------------------------------------------- + +GET_CLEAR_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL CLEAR_FRAME_RECT + RJMP MAIN_LOOP + +GET_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FRAME_RECT + RJMP MAIN_LOOP + +GET_CLEAR_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL CLEAR_HALFTONE_RECT + RJMP MAIN_LOOP + +GET_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL HALFTONE_RECT + RJMP MAIN_LOOP + +NO_GOX: RET + +CLEAR_FRAME_RECT: + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS F,RECTNC_YY + STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +FRAME_RECT: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GOX + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GOX + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CLEAR_HALFTONE_RECT: +; LDS F,RECTNC_X +; STS RECT_X,F +; LDS F,RECTNC_Y +; STS RECT_Y,F +; LDS F,RECTNC_XX +; STS RECT_XX,F +; LDS F,RECTNC_YY +; STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +HALFTONE_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LDI A,$55 + SBRS YH,0 + LDI A,$AA + MOV PATTERN,A + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP X03A3 +X039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +X03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ X03B0 + LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + TST XPIXEL + BREQ X03B0 +X03AD: LSR A + DEC XPIXEL + BRNE X03AD +X03B0: AND A,PATTERN + RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +X03B8: LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + BREQ X03D2 + AND A,PATTERN + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP X03B8 +X03C2: TST X_SIZE + BREQ X03D3 +X03C4: LSR A + DEC X_SIZE + BRNE X03C4 + COM A + TST XPIXEL + BREQ X03D2 + CLR B +X03CB: LSR A + ROR B + DEC XPIXEL + BRNE X03CB + AND A,PATTERN + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +X03D2: AND A,PATTERN + RCALL WR_DISP_MEM +X03D3: COM PATTERN + RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP X039A + RET + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4103 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/dos.asm b/src/avr/dos.asm new file mode 100644 index 00000000..9c0d0ca1 --- /dev/null +++ b/src/avr/dos.asm @@ -0,0 +1,366 @@ +; DOS.ASM + +; ----------------------------------------------------------------------------- + +EXTRN GETSTRLOC:FAR +EXTRN GETSTRALLOC:FAR +EXTRN RLSSTRALLOC:FAR + +EXTRN DOS_READY:WORD +EXTRN DOS_ERROR:WORD +EXTRN DOS_COUNT:WORD + +CODE SEGMENT + + ASSUME CS:CODE,DS:CODE + +B EQU BYTE PTR +W EQU WORD PTR +D EQU DWORD PTR + + JUMPS + LOCALS + +; ----------------------------------------------------------------------------- + +PUBLIC DOS_PRINT + +DOS_PRINT: ; DOS_DATA$ + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+6] ; DOS_DATA$ + CALL STRING_PTR_DS_DX ; DS:DX -> CX BYTE STRING + + MOV AH,40H + MOV BX,1 ; STDOUT + INT 21H + + CALL DOS_DONE ; SET UP COUNT/ERROR/READY + + POP DI + POP SI + POP DS + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + + PUBLIC DOS_PRINT_LINE + +DOS_PRINT_LINE: ; DOS_DATA$ + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+6] ; DOS_DATA$ + CALL STRING_PTR_DS_SI + PUSH DS + PUSH SI + PUSH CX + + PUSH CS + POP DS + MOV SI,OFFSET DOS_BUF + MOV AX,CX + ADD AX,2 + PUSH AX + CALL STRING_ALLOC ; ALLOCATE LEN(DOS_DATA$)+2 BYTES + + CALL STRING_PTR_ES_DI + POP AX + MOV DX,DI + MOV BX,ES + + POP CX + POP SI + POP DS + REP MOVSB ; COPY USER STRING TO TEMPORARY BUFFER + + MOV DS,BX ; DS:DX -> TEMPORARY BUFFER + XCHG CX,AX + + MOV AX,0A0DH + STOSW ; ADD CR/LF + + MOV AH,40H + MOV BX,1 ; STDOUT + INT 21H + + CALL DOS_DONE ; SET UP COUNT/ERROR/READY + + PUSH CS + POP DS + MOV SI,OFFSET DOS_BUF + CALL STRING_FREE + + POP DI + POP SI + POP DS + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + + PUBLIC DOS_GET_DATE ; YEAR%, MONTH%, DAY% + +DOS_GET_DATE: + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,2AH + INT 21H ; GET DATE + + LES DI,[BP+14] ; YEAR% + XCHG AX,CX + STOSW + + LES DI,[BP+10] ; MONTH% + MOV AL,DH + SUB AH,AH + STOSW + + LES DI,[BP+6] ; DAY% + MOV AL,DL + STOSW + + CALL DOS_OK ; SET DOS_COUNT% DOS_READY% DOS_ERROR% + + POP DI + POP SI + POP DS + POP BP + RETF 12 + +; ----------------------------------------------------------------------------- + + PUBLIC DOS_GET_TIME ; HOUR%, MINUTE%, SECOND%, HSEC% + +DOS_GET_TIME: + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,2CH + INT 21H ; GET TIME + + LES DI,[BP+18] ; HOUR% + MOV AL,CH + SUB AH,AH + STOSW + + LES DI,[BP+14] ; MINUTE% + MOV AL,CL + STOSW + + LES DI,[BP+10] ; SECOND% + MOV AL,DH + STOSW + + LES DI,[BP+6] ; HSEC% + MOV AL,DL + STOSW + + CALL DOS_OK ; SET DOS_COUNT% DOS_READY% DOS_ERROR% + + POP DI + POP SI + POP DS + POP BP + RETF 16 + +; ----------------------------------------------------------------------------- + + PUBLIC BIOS_KEY + +BIOS_KEY: ; K% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + PUSH [BP+8] + PUSH [BP+6] + PUSH CS + CALL BIOS_KEY_TEST ; BIOS_KEY_TEST K% + + LDS SI,[BP+6] + CMP W [SI],0 + JZ @@DONE ; IF K% THEN + + PUSH [BP+8] + PUSH [BP+6] + PUSH CS + CALL BIOS_KEY_WAIT ; BIOS_KEY_WAIT K% + +@@DONE: POP DI + POP SI + POP DS + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + + PUBLIC BIOS_KEY_TEST + +BIOS_KEY_TEST: ; K% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LES DI,[BP+6] + SUB AX,AX + STOSW ; K% = 0 + + SUB AX,AX + MOV DS,AX + MOV AX,DS:[41AH] + CMP AX,DS:[41CH] + JZ @@DONE ; DON'T GIVE UP A TIME SLICE + + MOV AH,1 + INT 16H ; TEST FOR KEY + JZ @@DONE + + LES DI,[BP+6] + TEST AL,AL + JZ @@EXTD + SUB AH,AH +@@EXTD: STOSW ; K% = RETURNED AX + +@@DONE: POP DI + POP SI + POP DS + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + + PUBLIC BIOS_KEY_WAIT + +BIOS_KEY_WAIT: ; K% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + SUB AH,AH + INT 16H ; WAIT FOR KEY + + LES DI,[BP+6] + TEST AL,AL + JZ @@EXTD + SUB AH,AH +@@EXTD: STOSW ; K% = RETURNED AX + + POP DI + POP SI + POP DS + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + +DOS_DONE: + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [DOS_COUNT],AX + MOV W [DOS_ERROR],0 + MOV W [DOS_READY],-1 + RET + +@@BAD: MOV W [DOS_COUNT],0 + MOV W [DOS_ERROR],AX + MOV W [DOS_READY],0 + RET + +; ----------------------------------------------------------------------------- + +DOS_OK: + MOV SI,DATA + MOV DS,SI + + MOV W [DOS_COUNT],0 + MOV W [DOS_ERROR],0 + MOV W [DOS_READY],-1 + RET + +; ----------------------------------------------------------------------------- + +STRING_PTR_DS_DX: + PUSH [SI] + CALL GETSTRLOC + + MOV DS,DX + XCHG DX,AX ; DS:DX -> CX BYTE STRING + RET + +STRING_PTR_DS_SI: + PUSH [SI] + CALL GETSTRLOC + + MOV DS,DX + XCHG SI,AX ; DS:SI -> CX BYTE STRING + RET + +STRING_PTR_ES_DI: + PUSH [SI] + CALL GETSTRLOC + + MOV ES,DX + XCHG DI,AX ; ES:DI -> CX BYTE STRING + RET + +STRING_FREE: + CMP W [SI],0 + JZ @@RET + + PUSH [SI] + MOV W [SI],0 + CALL RLSSTRALLOC +@@RET: RET + +STRING_ALLOC: + PUSH DS + PUSH SI + + PUSH AX + CALL GETSTRALLOC + + POP SI + POP DS + MOV [SI],AX + RET + +; ----------------------------------------------------------------------------- + +DOS_BUF DW 0 + +; ----------------------------------------------------------------------------- + +CODE ENDS + +; ----------------------------------------------------------------------------- + +DATA SEGMENT +DATA ENDS + +; ----------------------------------------------------------------------------- + + END diff --git a/src/avr/dos.inc b/src/avr/dos.inc new file mode 100644 index 00000000..081aa3a9 --- /dev/null +++ b/src/avr/dos.inc @@ -0,0 +1,20 @@ +' DOS.INC + +' ----------------------------------------------------------------------------- + +$LINK "DOS.OBJ" + +PUBLIC DOS_READY% +PUBLIC DOS_COUNT% +PUBLIC DOS_ERROR% + +DECLARE SUB DOS_PRINT(STRING) +DECLARE SUB DOS_PRINT_LINE(STRING) +DECLARE SUB DOS_GET_TIME(INTEGER,INTEGER,INTEGER,INTEGER) +DECLARE SUB DOS_GET_DATE(INTEGER,INTEGER,INTEGER) +DECLARE SUB BIOS_KEY(INTEGER) +DECLARE SUB BIOS_KEY_TEST(INTEGER) +DECLARE SUB BIOS_KEY_WAIT(INTEGER) + +' ----------------------------------------------------------------------------- + diff --git a/src/avr/file.asm b/src/avr/file.asm new file mode 100644 index 00000000..f1bdf71c --- /dev/null +++ b/src/avr/file.asm @@ -0,0 +1,3040 @@ +; FILE.ASM + +; ----------------------------------------------------------------------------- + +EXTRN GETSTRLOC:FAR +EXTRN GETSTRALLOC:FAR +EXTRN RLSSTRALLOC:FAR + +EXTRN FILE_ERROR:WORD +EXTRN FILE_COUNT:WORD +EXTRN FILE_POINTER:DWORD +EXTRN FILE_DRIVES:WORD + +EXTRN FILE_BOMB_OUT:FAR + +CODE SEGMENT + + ASSUME CS:CODE,DS:CODE + +B EQU BYTE PTR +W EQU WORD PTR +D EQU DWORD PTR + + JUMPS + LOCALS + +BLOCK_SIZE EQU 400H ;1000H +LINE_SIZE EQU 400H ;1000H + +; HANDLE_STRING ENTRIES: + +BUF_FLAG EQU 0 +BUF_STRING EQU 2 +BUF_OFFSET EQU 4 +BUF_COUNT EQU 6 +BUF_SIZE EQU 8 + +BUF_FLAG_READ EQU 1 +BUF_FLAG_WRITE EQU 2 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_OPEN + +FILE_OPEN: ; HANDLE%, FILE_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AX,3D02H ; TRY TO OPEN FOR READ/WRITE + MOV DX,OFFSET BUF_NAME + INT 21H + JNC @@OK + + MOV AX,3D00H ; TRY TO OPEN FOR READ + MOV DX,OFFSET BUF_NAME + INT 21H + +@@OK: MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LES DI,[BP+14] ; HANDLE% + STOSW + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_CREATE + +FILE_CREATE: ; HANDLE%, FILE_NAME$, ATTR%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + LDS SI,[BP+10] ; ATTR% + MOV CX,[SI] + + PUSH CS + POP DS + + MOV AH,3CH + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LES DI,[BP+18] ; HANDLE% + STOSW + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_CLOSE + +FILE_CLOSE: ; HANDLE%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + + SUB AX,AX ; 0 = NO BUFFER WANTED + CALL BUF_SETUP ; SET BUFFER DIRECTION OR KILL + CALL BUF_FREE ; FREE UP BUFFER STRING + + LDS SI,[BP+10] ; HANDLE% + MOV BX,[SI] + + MOV AH,3EH + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_READ + +FILE_READ: ; HANDLE%, FILE_DATA$, COUNT%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; COUNT% + CALL USER_ALLOC ; ALLOCATE USER BUFFER + MOV SI,OFFSET USER_STRING + CALL STRING_PTR_DS_DX ; DS:DX -> USER BUFFER + + LES DI,[BP+18] ; HANDLE% + MOV BX,ES:[DI] + LES DI,[BP+10] ; COUNT% + MOV CX,ES:[DI] + + MOV AH,3FH + INT 21H + + LES DI,[BP+14] ; FILE_DATA$ + LDS SI,[BP+10] ; COUNT% + MOV BX,AX ; BYTES TRANSFERRED + CALL READ_DONE ; RETURN USER BUFFER IN FILE_DATA$ + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_READ_BUF + +FILE_READ_BUF: ; HANDLE%, FILE_DATA$, COUNT%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; COUNT% + CALL USER_ALLOC ; ALLOCATE BUFFER, SET UP USER_PTR + + LDS SI,[BP+18] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + CALL HANDLE_ALLOC ; ENSURE WE HAVE A HANDLE_STRING ENTRY + + MOV AX,BUF_FLAG_READ ; 1 = DIRECTION + CALL BUF_SETUP ; SET BUFFER DIRECTION + CALL BUF_ALLOC ; ENSURE WE HAVE A BUF_STRING ENTRY + + MOV AX,ES:[DI+BUF_OFFSET] + CMP AX,ES:[DI+BUF_COUNT] + JAE @@MORE + +@@LOOP: CALL READ_COPY ; COPY OUT TO USER BUFFER + MOV AX,[USER_OFFSET] + CMP AX,[USER_COUNT] + JAE @@DONE ; NC, GOT ENOUGH + +@@MORE: CALL READ_MORE ; GET MORE INTO READ BUFFER + JC @@DONE + TEST AX,AX + JNZ @@LOOP + +@@DONE: MOV AX,[USER_OFFSET] ; CF = ERROR STATUS FROM READ + ; AX/CF NOW SET UP AS FOR RETURN FROM INT 21H + + LES DI,[BP+14] ; FILE_DATA$ + LDS SI,[BP+10] ; COUNT% + MOV BX,AX ; BYTES TRANSFERRED + CALL READ_DONE ; RETURN USER BUFFER IN FILE_DATA$ + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_READ_LINE + +FILE_READ_LINE: ; HANDLE%, FILE_DATA$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + PUSH CS + POP DS + MOV SI,OFFSET READ_LINE_MAX ; COUNT% + CALL USER_ALLOC ; ALLOCATE BUFFER, SET UP USER_PTR + + MOV W [READ_LINE_CR],0 + MOV W [READ_SKIP_COUNT],0 + + LDS SI,[BP+14] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + CALL HANDLE_ALLOC ; ENSURE WE HAVE A HANDLE_STRING ENTRY + + MOV AX,BUF_FLAG_READ ; 1 = DIRECTION + CALL BUF_SETUP ; SET BUFFER DIRECTION + CALL BUF_ALLOC ; ENSURE WE HAVE A BUF_STRING ENTRY + + MOV AX,ES:[DI+BUF_OFFSET] + CMP AX,ES:[DI+BUF_COUNT] + JAE @@MORE + +@@LOOP: CALL READ_SCAN ; CHECK READ BUFFER FOR CR + CALL READ_COPY ; COPY OUT TO USER BUFFER + MOV AX,[USER_OFFSET] + CMP AX,[USER_COUNT] + JAE @@SKIP ; GOT ENOUGH, SKIP TO CR/LF + +@@MORE: CALL READ_MORE ; GET MORE INTO READ BUFFER + JC @@DONE + TEST AX,AX + JZ @@DONE ; NC, DON'T WORRY ABOUT CR/LF IF EOF + JMP @@LOOP + +@@SKIP: CALL READ_SKIP ; SCAN READ BUFFER FOR CR/LF AND SKIP + CMP W [READ_LINE_CR],2 + JAE @@DONE + + CALL READ_MORE ; GET MORE INTO READ BUFFER + JC @@DONE + TEST AX,AX + JNZ @@SKIP + +@@DONE: MOV AX,[USER_OFFSET] ; CF = ERROR STATUS FROM READ + ; AX/CF NOW SET UP AS FOR RETURN FROM INT 21H + + PUSHF + MOV BX,AX ; BYTES TRANSFERRED + ADD BX,[READ_SKIP_COUNT] ; INCLUDING CR/LF + POPF + + LES DI,[BP+10] ; FILE_DATA$ + PUSH CS + POP DS + MOV SI,OFFSET READ_LINE_MAX ; COUNT% + CALL READ_DONE ; RETURN USER BUFFER IN FILE_DATA$ + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_READ_DIRECT + +FILE_READ_DIRECT: ; HANDLE%, POINTER, COUNT%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+18] ; HANDLE% + MOV BX,[SI] + LDS SI,[BP+10] ; COUNT% + MOV CX,[SI] + LDS SI,[BP+14] ; POINTER + LDS DX,[SI] + + MOV AH,3FH + INT 21H + + CALL WRITE_DONE ; SET UP READY% FILE_COUNT% FILE_ERROR% + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_WRITE + +FILE_WRITE: ; HANDLE%, FILE_DATA$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; FILE_DATA$ + CALL STRING_PTR_DS_DX ; DS:DX -> CX BYTE STRING + + LES DI,[BP+14] ; HANDLE% + MOV BX,ES:[DI] + + MOV AH,40H + INT 21H + + CALL WRITE_DONE ; SET UP READY% FILE_COUNT% FILE_ERROR% + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_WRITE_BUF + +FILE_WRITE_BUF: ; HANDLE%, FILE_DATA$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; FILE_DATA$ + CALL USER_PTR_SETUP ; USER_PTR, USER COUNT, USER OFFSET + + LDS SI,[BP+14] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + CALL HANDLE_ALLOC ; ENSURE WE HAVE A HANDLE_STRING ENTRY + + MOV AX,BUF_FLAG_WRITE ; 2 = DIRECTION + CALL BUF_SETUP ; SET BUFFER DIRECTION + CALL BUF_ALLOC ; ENSURE WE HAVE A BUF_STRING ENTRY + + MOV AX,ES:[DI+BUF_OFFSET] + CMP AX,BLOCK_SIZE + JAE @@FLSH + +@@LOOP: CALL WRITE_COPY ; COPY OUT TO WRITE BUFFER + MOV AX,[USER_OFFSET] + CMP AX,[USER_COUNT] + JAE @@DONE ; NC, WRITTEN ENOUGH + +@@FLSH: CALL WRITE_FLUSH ; FREE UP WRITE BUFFER + JC @@DONE + TEST AX,AX + JNZ @@LOOP + +@@DONE: MOV AX,[USER_OFFSET] ; CF = ERROR STATUS FROM WRITE + ; AX/CF NOW SET UP AS FOR RETURN FROM INT 21H + + CALL WRITE_DONE ; SET UP READY% FILE_COUNT% FILE_ERROR% + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_WRITE_LINE + +FILE_WRITE_LINE: ; HANDLE%, FILE_DATA$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + PUSH [BP+16] + PUSH [BP+14] ; HANDLE% + PUSH [BP+12] + PUSH [BP+10] ; FILE_DATA$ + PUSH [BP+8] + PUSH [BP+6] ; READY% + PUSH CS + CALL FILE_WRITE_BUF + + LDS SI,[BP+6] ; READY% + CMP W [SI],0 + JZ @@RET + + MOV SI,DATA + MOV DS,SI + PUSH [FILE_COUNT] + + PUSH CS + POP DS + + MOV AX,2 + MOV SI,OFFSET CRLF_STRING + CALL STRING_ALLOC + CALL STRING_PTR_ES_DI + + MOV AX,0A0DH + STOSW + + PUSH [BP+16] + PUSH [BP+14] ; HANDLE% + MOV DI,OFFSET CRLF_STRING + PUSH CS + PUSH DI ; CHR$(&HD,&HA) + PUSH [BP+8] + PUSH [BP+6] ; READY% + PUSH CS + CALL FILE_WRITE_BUF + + MOV SI,OFFSET CRLF_STRING + CALL STRING_FREE + + MOV SI,DATA + MOV DS,SI + + POP AX + ADD [FILE_COUNT],AX + + PUSH CS + POP DS + + MOV AX,[CURRENT_PSP] + TEST AX,AX + JNZ @@NPSP + + MOV AH,51H + INT 21H + XCHG AX,BX + MOV [CURRENT_PSP],AX + +@@NPSP: LDS SI,[BP+14] ; HANDLE% + MOV BX,[SI] + + MOV DS,AX + LDS SI,D DS:[34H] ; HANDLE TABLE + CMP B DS:[BX+SI],1 ; DOES HANDLE BX REFER TO CON? + JNZ @@RET + + PUSH [BP+16] + PUSH [BP+14] ; HANDLE% + PUSH [BP+8] + PUSH [BP+6] ; READY% + PUSH CS + CALL FILE_FLUSH ; ENSURE IMMEDIATE DISPLAY + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_WRITE_DIRECT + +FILE_WRITE_DIRECT: ; HANDLE%, POINTER, COUNT%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+18] ; HANDLE% + MOV BX,[SI] + LDS SI,[BP+10] ; COUNT% + MOV CX,[SI] + LDS SI,[BP+14] ; POINTER + LDS DX,[SI] + + MOV AH,40H + INT 21H + + CALL WRITE_DONE ; SET UP READY% FILE_COUNT% FILE_ERROR% + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SEEK +PUBLIC FILE_SEEK_REL +PUBLIC FILE_SEEK_END + +FILE_SEEK_END: ; HANDLE%, POINTER&, READY% +; CALL TEST_HANDLE_STRING + MOV AL,2 + JMP FILE_SEEK_ENTRY + +FILE_SEEK_REL: ; HANDLE%, POINTER&, READY% +; CALL TEST_HANDLE_STRING + MOV AL,1 + JMP FILE_SEEK_ENTRY + +FILE_SEEK: ; HANDLE%, POINTER&, READY% +; CALL TEST_HANDLE_STRING + SUB AL,AL + ;JMP FILE_SEEK_ENTRY + +FILE_SEEK_ENTRY: + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + PUSH AX + LDS SI,[BP+14] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + + SUB AX,AX ; 0 = NO BUFFER WANTED + CALL BUF_SETUP ; SET BUFFER DIRECTION OR KILL + POP AX + + LDS SI,[BP+10] ; POINTER& + MOV DX,[SI] + MOV CX,[SI+2] + + LDS SI,[BP+14] ; HANDLE% + MOV BX,[SI] + + MOV AH,42H + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_POINTER],AX + MOV W [FILE_POINTER+2],DX + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SEEK_GET + +FILE_SEEK_GET: ; HANDLE%, POINTER&, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + + CALL BUF_ADJUST ; SET UP FILE_PTR_ADJUST USING AX + + SUB CX,CX + SUB DX,DX + + LDS SI,[BP+14] ; HANDLE% + MOV BX,[SI] + + MOV AX,4201H + INT 21H ; SEEK RELATIVE BY 0 BYTES + JC @@BAD + + PUSH CS + POP DS + ADD AX,[FILE_PTR_ADJUST] + ADC DX,[FILE_PTR_ADJUST+2] + + LDS SI,[BP+10] + MOV [SI],AX + MOV [SI+2],DX + + MOV SI,DATA + MOV DS,SI + + MOV W [FILE_POINTER],AX + MOV W [FILE_POINTER+2],DX + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV SI,DATA + MOV DS,SI + + MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_PRINT + +FILE_PRINT: ; FILE_DATA$ +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV DI,OFFSET PRINT_HANDLE + PUSH CS + PUSH DI + LDS SI,[BP+6] ; FILE_DATA$ + PUSH DS + PUSH SI + MOV DI,OFFSET PRINT_READY + PUSH CS + PUSH DI + PUSH CS + CALL FILE_WRITE_LINE + +IF 0 + MOV DI,OFFSET PRINT_HANDLE + PUSH CS + PUSH DI + MOV DI,OFFSET PRINT_READY + PUSH CS + PUSH DI + PUSH CS + CALL FILE_FLUSH +ENDIF + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 4 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_FLUSH + +FILE_FLUSH: ; HANDLE%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; HANDLE% + CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + + SUB AX,AX ; 0 = NO BUFFER WANTED + CALL BUF_SETUP ; SET BUFFER DIRECTION OR KILL + + CALL WRITE_DONE ; SET UP READY% FILE_COUNT% FILE_ERROR% + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +FILE_DUPLICATE_HANDLE: ; HANDLE%, HANDLE_NEW%, READY% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; HANDLE% + MOV BX,[SI] + + MOV AH,45H + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LES DI,[BP+10] ; HANDLE_NEW% + STOSW + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +FILE_REDIRECT_HANDLE: ; HANDLE%, HANDLE_NEW%, READY% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; HANDLE% + MOV BX,[SI] + + LDS SI,[BP+10] ; HANDLE% + MOV CX,[SI] + + MOV AH,46H + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_GET_DATE_TIME + +FILE_GET_DATE_TIME: ; HANDLE%, DOS_DATE%, DOS_TIME%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+18] ; HANDLE% + MOV BX,[SI] + + MOV AX,5700H + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LDS SI,[BP+14] ; DOS_DATE% + MOV [SI],DX + + LDS SI,[BP+10] ; DOS_TIME% + MOV [SI],CX + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SET_DATE_TIME + +FILE_SET_DATE_TIME: ; HANDLE%, DOS_DATE%, DOS_TIME%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+18] ; HANDLE% + MOV BX,[SI] + + LDS SI,[BP+14] ; DOS_DATE% + MOV DX,[SI] + + LDS SI,[BP+10] ; DOS_TIME% + MOV CX,[SI] + + MOV AX,5701H + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_GET_ATTRIBUTES + +FILE_GET_ATTRIBUTES: ; FILE_NAME$, ATTR%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AX,4300H + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LDS SI,[BP+10] ; ATTR% + MOV [SI],CX + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SET_ATTRIBUTES + +FILE_SET_ATTRIBUTES: ; FILE_NAME$, ATTR%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + LDS SI,[BP+10] ; ATTR% + MOV CX,[SI] + + PUSH CS + POP DS + + MOV AX,4301H + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_RENAME + +FILE_RENAME: ; FILE_NAME$, FILE_NEW$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + LDS SI,[BP+10] ; FILE_NEW$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NEW + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NEW + + PUSH CS + POP DS + PUSH CS + POP ES + + MOV AH,56H + MOV DX,OFFSET BUF_NAME + MOV DI,OFFSET BUF_NEW + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_DELETE + +FILE_DELETE: ; FILE_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AH,41H + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- +; CALL FILE_SEARCH_FIRST(FILE_MASK$,ATTR%,DTA$,READY%) + +PUBLIC FILE_SEARCH_FIRST + +FILE_SEARCH_FIRST: +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,2FH + INT 21H + PUSH ES + PUSH BX ; SAVE DTA + + PUSH CS + POP DS + + MOV AH,1AH + MOV DX,OFFSET BUF_DTA + INT 21H ; SET DTA + + LDS SI,[BP+18] ; FILE_MASK$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + LDS SI,[BP+14] ; ATTR% + MOV CX,[SI] + + PUSH CS + POP DS + + MOV AH,4EH + MOV DX,OFFSET BUF_NAME + INT 21H ; SEARCH FIRST + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + PUSH CS + POP ES + MOV DI,OFFSET BUF_DTA+1EH + SUB AL,AL + MOV CX,13 ;11 + REPNZ SCASB + MOV AX,1EH+12 ;10 + SUB AX,CX ; AX = LENGTH OF RETURNED DTA + + LDS SI,[BP+10] ; DTA$ + CALL STRING_REALLOC + CALL STRING_PTR_ES_DI ; ES:DI -> NEW CX BYTE STRING + + PUSH CS + POP DS + MOV SI,OFFSET BUF_DTA + REP MOVSB + JMP @@RET + +@@BAD: MOV [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DX + POP DS + MOV AH,1AH + INT 21H ; RESTORE DTA + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 16 + +; ----------------------------------------------------------------------------- +; CALL FILE_SEARCH_NEXT(DTA$,READY%) + +PUBLIC FILE_SEARCH_NEXT + +FILE_SEARCH_NEXT: +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,2FH + INT 21H + PUSH ES + PUSH BX ; SAVE DTA + + PUSH CS + POP DS + + MOV AH,1AH + MOV DX,OFFSET BUF_DTA + INT 21H ; SET DTA + + LDS SI,[BP+10] ; DTA$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_DTA + MOV AX,1EH+11 + CALL STRING_COPY ; COPY STRING TO DTA AREA + + MOV AH,4FH + INT 21H ; SEARCH NEXT + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + PUSH CS + POP ES + MOV DI,OFFSET BUF_DTA+1EH + SUB AL,AL + MOV CX,13 ;11 + REPNZ SCASB + MOV AX,1EH+12 ;10 + SUB AX,CX ; AX = LENGTH OF RETURNED DTA + + LDS SI,[BP+10] ; DTA$ + CALL STRING_REALLOC + CALL STRING_PTR_ES_DI ; ES:DI -> NEW CX BYTE STRING + + PUSH CS + POP DS + MOV SI,OFFSET BUF_DTA + REP MOVSB + JMP @@RET + +@@BAD: MOV [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DX + POP DS + MOV AH,1AH + INT 21H ; RESTORE DTA + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_CREATE_DIRECTORY + +FILE_CREATE_DIRECTORY: ; DIRECTORY_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; DIRECTORY_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AH,39H + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_DELETE_DIRECTORY + +FILE_DELETE_DIRECTORY: ; DIRECTORY_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; DIRECTORY_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AH,3AH + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_GET_DIRECTORY + +FILE_GET_DIRECTORY: ; DRIVE%, DIRECTORY_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; DRIVE% + MOV DL,[SI] + + PUSH CS + POP DS + + MOV AH,47H + MOV SI,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + SUB AL,AL + MOV CX,128 + REPNZ SCASB + MOV AX,127 + SUB AX,CX ; AX = LENGTH OF RETURNED STRING + + LDS SI,[BP+10] ; FILE_DATA$ + CALL STRING_REALLOC + CALL STRING_PTR_ES_DI + + PUSH CS + POP DS + MOV SI,OFFSET BUF_NAME + REP MOVSB ; COPY STRING TO USER + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SET_DIRECTORY + +FILE_SET_DIRECTORY: ; DIRECTORY_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; DIRECTORY_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + PUSH CS + POP DS + + MOV AH,3BH + MOV DX,OFFSET BUF_NAME + INT 21H + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_GET_DRIVE + +FILE_GET_DRIVE: ; DRIVE%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,19H + INT 21H + + LES DI,[BP+10] ; DRIVE% + SUB AH,AH + STOSW + + MOV SI,DATA + MOV DS,SI + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SET_DRIVE + +FILE_SET_DRIVE: ; DRIVE%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+10] ; DRIVE% + MOV DL,[SI] + + MOV AH,0EH + INT 21H + + PUSH CS + POP DS + SUB AH,AH + MOV [FILE_DRIVES],AX + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_GET_DRIVE_INFO + +FILE_GET_DRIVE_INFO: ; DRIVE%, BYTES_SECTOR%, +; CALL TEST_HANDLE_STRING + ; SECTORS_CLUSTER%, AVAIL_CLUSTERS%, + ; TOTAL_CLUSTERS%, READY% + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+26] ; DRIVE% + MOV DL,[SI] + + MOV AH,36H + INT 21H + + MOV SI,DATA + MOV DS,SI + CMP AX,-1 + JZ @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + LDS SI,[BP+22] ; BYTES_SECTOR% + MOV [SI],CX + + LES DI,[BP+18] ; SECTORS_CLUSTER% + STOSW + + LDS SI,[BP+14] ; AVAIL_CLUSTERS% + MOV [SI],BX + + LDS SI,[BP+10] ; TOTAL_CLUSTERS% + MOV [SI],DX + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 24 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_COPY + +FILE_COPY: ; FILE_NAME$, FILE_NEW$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + + PUSH CS + POP DS + MOV W [TEMP_STRING],0 + + MOV DI,OFFSET TEMP_SOURCE ; HANDLE + PUSH CS + PUSH DI + LES DI,[BP+14] ; FILE_NAME$ + PUSH ES + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_OPEN ; OPEN SOURCE FILE + CMP W [TEMP_READY],0 + JZ @@BAD2 + + ; SHOULD GET FILE SIZE AND CHECK DISK SPACE + + MOV DI,OFFSET TEMP_DEST ; HANDLE + PUSH CS + PUSH DI + LES DI,[BP+10] ; FILE_NEW$ + PUSH ES + PUSH DI + MOV DI,OFFSET TEMP_ATTR ; ATTR% = 0 + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_CREATE ; CREATE DESTINATION FILE + CMP W [TEMP_READY],0 + JZ @@BAD1 + +@@LOOP: MOV DI,OFFSET TEMP_SOURCE ; HANDLE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_STRING ; BUF$ + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_COUNT ; COUNT% = &H1000 + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_READ ; READ SOURCE FILE + CMP W [TEMP_READY],0 + JZ @@BAD0 + + MOV SI,OFFSET TEMP_STRING ; DID WE GET ANYTHING? + CALL STRING_PTR_ES_DI ; CX = COUNT + JCXZ @@DONE ; NO, DONE + + MOV DI,OFFSET TEMP_DEST ; HANDLE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_STRING ; BUF$ + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_WRITE ; WRITE DESTINATION FILE + CMP W [TEMP_READY],0 + JZ @@BAD0 + + MOV SI,OFFSET TEMP_STRING + CALL STRING_PTR_ES_DI ; CX = COUNT + CMP CX,BLOCK_SIZE ; DID WE GET A FULL BLOCK? + JAE @@LOOP ; YES, TRY FOR MORE + +@@DONE: MOV DI,OFFSET TEMP_SOURCE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_DATE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_TIME + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY + PUSH CS + PUSH DI + PUSH CS + CALL FILE_GET_DATE_TIME + CMP W [TEMP_READY],0 + JZ @@BAD0 + + MOV DI,OFFSET TEMP_DEST + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_DATE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_TIME + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY + PUSH CS + PUSH DI + PUSH CS + CALL FILE_SET_DATE_TIME + CMP W [TEMP_READY],0 + JZ @@BAD0 + + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + +@@BAD0: PUSH CS + POP DS + MOV SI,OFFSET TEMP_STRING + CALL STRING_FREE + + MOV SI,DATA + MOV DS,SI + PUSH [FILE_ERROR] + + MOV DI,OFFSET TEMP_DEST ; HANDLE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_CLOSE ; CLOSE DESTINATION FILE + + ; SHOULD DELETE FILE HERE IF ERROR + + POP W [FILE_ERROR] + +@@BAD1: MOV SI,DATA + MOV DS,SI + PUSH [FILE_ERROR] + + MOV DI,OFFSET TEMP_SOURCE ; HANDLE + PUSH CS + PUSH DI + MOV DI,OFFSET TEMP_READY ; READY% + PUSH CS + PUSH DI + PUSH CS + CALL FILE_CLOSE ; CLOSE SOURCE FILE + + POP W [FILE_ERROR] + +@@BAD2: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_INVOCATION + +FILE_INVOCATION: ; FILE_NAME$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AH,62H + INT 21H ; GET CURRENT PSP + MOV DS,BX + + SUB AL,AL ; ASCIZ SEARCH + + MOV ES,DS:[2CH] + SUB DI,DI + MOV CX,-1 ; ES:DI -> ENVIRONMENT (MAX FFFF BYTES) + +@@LOOP: REPNZ SCASB + JNZ @@BAD + SCASB + JZ @@ENVE + DEC DI + JMP @@LOOP + +@@ENVE: INC DI ; GOT ENVIRONMENT END + INC DI + + PUSH ES + PUSH DI ; -> INVOCATION NAME + + MOV CX,128 + REPNZ SCASB + MOV AX,127 + SUB AX,CX ; AX = LENGTH OF INVOCATION STRING + PUSH AX + + LDS SI,[BP+10] ; FILE_NAME$ + CALL STRING_REALLOC + CALL STRING_PTR_ES_DI + + POP CX + POP SI + POP DS + +@@CPY0: LODSB ; COPY STRING TO USER, UPPERCASE + CMP AL,'a' + JB @@CPY1 + CMP AL,'z' + JA @@CPY1 + AND AL,0DFH +@@CPY1: STOSB + LOOP @@CPY0 + + MOV SI,DATA + MOV DS,SI + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV SI,DATA + MOV DS,SI + + MOV W [FILE_ERROR],-1 + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SET_HANDLES + +FILE_SET_HANDLES: ; HANDLES%, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + MOV AX,5800H + INT 21H ; GET ALLOCATION STRATEGY + JC @@BAD + XCHG DI,AX + MOV AX,5801H + MOV BX,2 ; LAST FIT + INT 21H ; SET ALLOCATION STRATEGY + JC @@BAD + + LDS SI,[BP+10] ; HANDLES% + MOV BX,[SI] ; REQUESTED NUMBER OF HANDLES + + MOV AH,67H + INT 21H ; TRY TO ALLOCATE HANDLES + + PUSHF + MOV AX,5801H + MOV BX,DI + INT 21H ; TRY TO RESTORE ALLOCATION STRATEGY + POPF + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 8 + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_SHELL + +FILE_SHELL: ; FILE_NAME$, COMMAND_LINE$, READY% +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LDS SI,[BP+14] ; FILE_NAME$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NAME + MOV AX,128 + CALL STRING_COPY ; COPY STRING TO BUF_NAME + + LDS SI,[BP+10] ; COMMAND_LINE$ + PUSH CS + POP ES + MOV DI,OFFSET BUF_NEW+1 + MOV AX,126 + CALL STRING_COPY ; COPY STRING TO BUF_NEW+1 + MOV DI,OFFSET BUF_NEW + XCHG AX,CX + STOSB ; LENGTH BYTE + ADD DI,AX + MOV AL,0DH + STOSB ; TRAILING CR + + PUSH CS + POP DS + + MOV AX,4B00H + MOV DX,OFFSET BUF_NAME + MOV BX,OFFSET EXEC_PARAMS + MOV [BX+4],CS + INT 21H ; EXECUTE PROGRAM + + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV AH,4DH + INT 21H ; GET RETURN CODE + SUB AH,AH + MOV W [FILE_ERROR],AX + + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + JMP @@RET + +@@BAD: MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + +@@RET: POP DI + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 12 + +; ----------------------------------------------------------------------------- + +STRING_LEN: + PUSH [SI] + CALL GETSTRLOC + RET + +STRING_PTR_DS_DX: + PUSH [SI] + CALL GETSTRLOC + + MOV DS,DX + XCHG DX,AX ; DS:DX -> CX BYTE STRING + RET + +STRING_PTR_DS_SI: + PUSH [SI] + CALL GETSTRLOC + + MOV DS,DX + XCHG SI,AX ; DS:SI -> CX BYTE STRING + RET + +STRING_PTR_ES_DI: + PUSH [SI] + CALL GETSTRLOC + + MOV ES,DX + XCHG DI,AX ; ES:DI -> CX BYTE STRING + RET + +STRING_PTR_SETUP: + PUSH [SI] + CALL GETSTRLOC + + STOSW + XCHG AX,DX + STOSW ; MEMORY PTR -> CX BYTE STRING + RET + +STRING_FREE: + CMP W [SI],0 + JZ @@RET + + PUSH [SI] + MOV W [SI],0 + CALL RLSSTRALLOC +@@RET: RET + +STRING_REALLOC: + PUSH DS + PUSH SI + PUSH AX + CALL STRING_FREE + POP AX + POP SI + POP DS + ;JMP STRING_ALLOC + +STRING_ALLOC: + TEST AX,AX + JZ @@NONE + + PUSH DS + PUSH SI + PUSH AX + CALL GETSTRALLOC + POP SI + POP DS + + TEST AX,AX + JZ ERROR_STRING_ALLOC + +@@NONE: MOV [SI],AX + RET + +STRING_RESIZE: + PUSH DS + + PUSH [SI] + PUSH AX + PUSH DS + PUSH SI + CALL STRING_ALLOC + POP SI + POP DS + CALL STRING_PTR_ES_DI + POP AX ; ES:DI -> AX BYTE NEW STRING + POP BX ; BX = OLD STRING HANDLE + + PUSH CS + POP DS + MOV SI,OFFSET OLD_STRING + MOV [SI],BX + CALL STRING_COPY + MOV SI,OFFSET OLD_STRING + CALL STRING_FREE + + POP DS + RET + +STRING_COPY: + PUSH DS + + PUSH ES + PUSH DI + PUSH AX + CALL STRING_PTR_DS_SI + POP AX + POP DI + POP ES + + CMP CX,AX + JBE @@FITS + MOV CX,AX + +@@FITS: PUSH CX + + SUB AX,CX + REP MOVSB + XCHG CX,AX ; LEAVES AL = 0 + REP STOSB + + POP CX + POP DS + RET + +; ----------------------------------------------------------------------------- + +ERROR_STRING_ALLOC: + MOV SI,OFFSET MESS_STRING_ALLOC + +ERROR_HANDLER: + PUSH CS + POP DS + PUSH CS + POP ES + MOV [ERROR_MESS_PTR],SI + + MOV AH,2AH + INT 21H ; GET DATE + + MOV DI,OFFSET MESS_DATE_TIME+2 + MOV AL,DL + CALL ERROR_DECIMAL + MOV AL,DH + SUB AH,AH + MOV SI,OFFSET ERROR_MONTHS + ADD SI,AX + ADD SI,AX + ADD SI,AX + MOVSW + MOVSB + MOV AX,CX + SUB AX,2000 + JNC @@OK + ADD AX,100 +@@OK: CALL ERROR_DECIMAL + INC DI + + MOV AH,2CH + INT 21H + + MOV AL,CH + CALL ERROR_DECIMAL + INC DI + MOV AL,CL + CALL ERROR_DECIMAL + INC DI + MOV AL,DH + CALL ERROR_DECIMAL + + MOV AH,2 + SUB BH,BH + MOV DX,24*100H + INT 10H ; SET CURSOR POSITION + + MOV SI,OFFSET MESS_DATE_TIME + CALL ERROR_BIOS_PRINT + MOV SI,[ERROR_MESS_PTR] + CALL ERROR_BIOS_PRINT + + MOV AH,62H + INT 21H ; GET CURRENT PSP + MOV DS,BX + + SUB AL,AL ; ASCIZ SEARCH + MOV ES,DS:[2CH] + SUB DI,DI + MOV CX,-1 ; ES:DI -> ENVIRONMENT (MAX FFFF BYTES) + +@@SRCH: REPNZ SCASB + JNZ @@BAD + SCASB + JZ @@ENVE + DEC DI + JMP @@SRCH + +@@BAD: PUSH CS + POP ES + MOV DI,OFFSET ERROR_LOG_PATH + JMP @@CONT + +@@ENVE: INC DI ; GOT ENVIRONMENT END + INC DI + + PUSH ES + POP DS + MOV SI,DI + + PUSH CS + POP ES + MOV DI,OFFSET ERROR_LOG_PATH + + MOV CX,64 + MOV BX,DI ; WHERE LAST \ FOUND +@@COPY: LODSB + STOSB + CMP AL,'\' + JNZ @@COPE + MOV BX,DI +@@COPE: TEST AL,AL + LOOPNZ @@COPY + MOV DI,BX + +@@CONT: PUSH CS + POP DS + MOV SI,OFFSET ERROR_LOG_NAME + MOV CX,10 ; ERROR.LOG + REP MOVSB + + MOV AX,3D02H + MOV DX,OFFSET ERROR_LOG_PATH + INT 21H ; TRY TO OPEN EXISTING ERROR.LOG + JC ERROR_LOG_CREATE + XCHG BX,AX + + MOV AX,4202H + SUB CX,CX + SUB DX,DX + INT 21H ; SEEK TO END OF ERROR.LOG + JMP ERROR_LOG_WRITE + +ERROR_LOG_CREATE: + MOV AH,3CH + SUB CX,CX + MOV DX,OFFSET ERROR_LOG_PATH + INT 21H ; CREATE NEW ZERO LENGTH ERROR.LOG + JC ERROR_HANDLER_DONE + XCHG BX,AX + +ERROR_LOG_WRITE: + MOV SI,OFFSET MESS_DATE_TIME + CALL ERROR_FILE_PRINT + MOV SI,[ERROR_MESS_PTR] + CALL ERROR_FILE_PRINT + MOV SI,OFFSET MESS_CRLF + CALL ERROR_FILE_PRINT + + MOV AH,3EH + INT 21H ; CLOSE ERROR.LOG + +ERROR_HANDLER_DONE: + MOV AX,DATA + MOV DS,AX + JMP FILE_BOMB_OUT + +ERROR_DECIMAL: + SUB AH,AH + MOV BL,10 + DIV BL ; AL = TENS, AH = UNITS + OR AX,3030H + STOSW + RET + +ERROR_BIOS_PRINT: + PUSH SI + LODSW + XCHG CX,AX +@@LOOP: LODSB + PUSH CX + PUSH SI + MOV AH,0EH + MOV BX,7 + INT 10H + POP SI + POP CX + LOOP @@LOOP + POP SI + RET + +ERROR_FILE_PRINT: + MOV AH,40H + MOV CX,[SI] + LEA DX,[SI+2] + INT 21H ; WRITE TO ERROR.LOG + RET + +ERROR_MESS_PTR DW 0 +ERROR_LOG_NAME DB 'ERROR.LOG',0 +ERROR_LOG_PATH DB 129 DUP (?) + +ERROR_MONTHS DB '???JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC' + +MESS_DATE_TIME DW 17 + DB '01JAN80 00:00:00 ' + +MESS_STRING_ALLOC DW 29 + DB 'FILE.ASM: Out of string space' + +MESS_CRLF DW 2 + DB 0DH,0AH + +; ----------------------------------------------------------------------------- +; SET UP USER BUFFER + +USER_ALLOC: + PUSH [SI] ; COUNT% + CALL GETSTRALLOC + + PUSH CS + POP DS + MOV SI,OFFSET USER_STRING + MOV [SI],AX + ;JMP USER_PTR_SETUP + +USER_PTR_SETUP: + PUSH CS + POP ES + MOV DI,OFFSET USER_PTR + CALL STRING_PTR_SETUP + + PUSH CS + POP DS + MOV [USER_COUNT],CX + MOV W [USER_OFFSET],0 + RET + +; ----------------------------------------------------------------------------- +; FREE UP READ BUFFER + +READ_FLUSH: + MOV DX,ES:[DI+BUF_OFFSET] + SUB DX,ES:[DI+BUF_COUNT] ; DX = -BYTES LEFT IN READ BUFFER + JAE @@DONE ; NC FOR CALLER + + MOV AX,4201H + MOV BX,[BUF_HANDLE] + MOV CX,-1 + INT 21H ; SEEK RELATIVE + ; ERRORS HANDLED BY CALLER + +@@DONE: MOV W ES:[DI+BUF_COUNT],0 + MOV W ES:[DI+BUF_OFFSET],0 + RET + +; ----------------------------------------------------------------------------- +; SCAN USER BUFFER FOR CR + +READ_SCAN: + MOV BX,[USER_COUNT] + SUB BX,[USER_OFFSET] ; BX = USER BYTES LEFT + + MOV CX,ES:[DI+BUF_COUNT] + SUB CX,ES:[DI+BUF_OFFSET] ; CX = NATIVE BYTES LEFT + + CMP CX,BX + JB @@SCAN + MOV CX,BX +@@SCAN: JCXZ @@RET + + LDS SI,D [BUF_PTR] + ADD SI,ES:[DI+BUF_OFFSET] ; DS:SI -> NATIVE BUFFER + MOV BX,SI ; TO CALCULATE LENGTH + +@@LOOP: LODSB + CMP AL,1AH + JZ @@DONE + CMP AL,0DH + LOOPNZ @@LOOP + JNZ @@RET + +@@DONE: PUSH CS + POP DS + + DEC SI + SUB SI,BX + ADD SI,[USER_OFFSET] + MOV [USER_COUNT],SI ; MAKE THE REQUEST SHORTER + RET + +@@RET: PUSH CS + POP DS + RET + +; ----------------------------------------------------------------------------- +; SCAN USER BUFFER FOR CR/LF AND SKIP + +READ_SKIP: + MOV CX,ES:[DI+BUF_COUNT] + SUB CX,ES:[DI+BUF_OFFSET] ; CX = NATIVE BYTES LEFT + JZ @@RET + + LDS SI,D [BUF_PTR] + ADD SI,ES:[DI+BUF_OFFSET] ; DS:SI -> NATIVE BUFFER + MOV BX,SI ; TO CALCULATE LENGTH + + CMP W CS:[READ_LINE_CR],1 ; ALREADY FOUND CR? + JZ @@LF + +@@CR: LODSB + CMP AL,1AH + JZ @@BACK + CMP AL,0DH + LOOPNZ @@CR + JNZ @@RET + + MOV W CS:[READ_LINE_CR],1 ; SAY WE FOUND CR + JCXZ @@RET ; NO NEED TO UPDATE BUF_OFFSET, DODGY + +@@LF: LODSB + CMP AL,0AH + JZ @@DONE + +@@BACK: DEC SI +@@DONE: MOV W CS:[READ_LINE_CR],2 ; SAY WE FOUND LF + +@@RET: PUSH CS + POP DS + + SUB SI,BX + ADD [READ_SKIP_COUNT],SI + ADD ES:[DI+BUF_OFFSET],SI ; SKIP THE BYTES + RET + +; ----------------------------------------------------------------------------- +; COPY OUT TO USER BUFFER + +READ_COPY: + PUSH ES + PUSH DI + + MOV BX,[USER_COUNT] + SUB BX,[USER_OFFSET] ; BX = USER BYTES LEFT + + MOV CX,ES:[DI+BUF_COUNT] + SUB CX,ES:[DI+BUF_OFFSET] ; CX = NATIVE BYTES LEFT + + LDS SI,D [BUF_PTR] + ADD SI,ES:[DI+BUF_OFFSET] ; DS:SI -> NATIVE BUFFER + + LES DI,D CS:[USER_PTR] + ADD DI,CS:[USER_OFFSET] ; ES:DI -> USER BUFFER + + CMP CX,BX + JB @@COPY + MOV CX,BX + +@@COPY: MOV AX,CX + REP MOVSB + + POP DI + POP ES + ADD ES:[DI+BUF_OFFSET],AX + + PUSH CS + POP DS + ADD [USER_OFFSET],AX + RET + +; ----------------------------------------------------------------------------- +; GET MORE INTO READ BUFFER + +READ_MORE: + MOV AX,ES:[DI+BUF_COUNT] + CMP AX,ES:[DI+BUF_OFFSET] + JB @@RET + + MOV AH,3FH + MOV BX,[BUF_HANDLE] + MOV CX,BLOCK_SIZE + LDS DX,D [BUF_PTR] + INT 21H + PUSH CS + POP DS + ; ERRORS HANDLED BY CALLER + + MOV W ES:[DI+BUF_OFFSET],0 + MOV W ES:[DI+BUF_COUNT],0 + JC @@RET + MOV ES:[DI+BUF_COUNT],AX +@@RET: RET + +; ----------------------------------------------------------------------------- +; RETURN USER BUFFER IN FILE_DATA$ + +READ_DONE: + MOV CX,[SI] ; CX = COUNT% + + PUSH CS + POP DS + MOV [FILE_DATA_PTR],DI + MOV [FILE_DATA_PTR+2],ES + + MOV SI,DATA + MOV DS,SI + JC @@BAD ; ERROR OCCURRED, DEALLOCATE BUF + + MOV W [FILE_COUNT],BX ; BX = BYTES TRANSFERRED, INC CR/LF + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + + CMP AX,CX ; AX = BYTES TRANSFERRED, NO CR/LF + JAE @@DONE + + ; ONLY PARTIALLY FILLED, TRUNCATE BUF + + PUSH CS + POP DS + MOV SI,OFFSET USER_STRING + CALL STRING_RESIZE ; RESIZE USER BUFFER TO AX BYTES + +@@DONE: ; SUCCESSFUL, DEALLOCATE FILE_DATA$ AND REPLACE WITH BUF + + PUSH CS + POP DS + LDS SI,D [FILE_DATA_PTR] ; FILE_DATA$ + CALL STRING_FREE + + PUSH CS + POP DS + MOV SI,OFFSET USER_STRING + + LES DI,D [FILE_DATA_PTR] ; FILE_DATA$ + SUB AX,AX + XCHG AX,[SI] + STOSW + RET + +@@BAD: ; ERROR OCCURRED, DEALLOCATE BUF + + MOV W [FILE_COUNT],0 + + MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + + PUSH CS + POP DS + MOV SI,OFFSET USER_STRING + JMP STRING_FREE + +; ----------------------------------------------------------------------------- +; FREE UP WRITE BUFFER + +WRITE_FLUSH: + CMP W ES:[DI+BUF_OFFSET],0 + JZ @@DONE ; NC FOR CALLER + + MOV AH,40H + MOV BX,BUF_HANDLE + MOV CX,ES:[DI+BUF_OFFSET] + LDS DX,D [BUF_PTR] + INT 21H ; WRITE OUT WRITE BUFFER + PUSH CS + POP DS + ; ERRORS HANDLED BY CALLER + +@@DONE: MOV W ES:[DI+BUF_COUNT],0 + MOV W ES:[DI+BUF_OFFSET],0 + RET + +; ----------------------------------------------------------------------------- +; COPY OUT TO WRITE BUFFER + +WRITE_COPY: + PUSH ES + PUSH DI + + MOV CX,BLOCK_SIZE + SUB CX,ES:[DI+BUF_OFFSET] ; CX = NATIVE BYTES LEFT + + MOV BX,[USER_COUNT] + SUB BX,[USER_OFFSET] ; BX = USER BYTES LEFT + + MOV DX,ES:[DI+BUF_OFFSET] + LES DI,D [BUF_PTR] + ADD DI,DX ; ES:DI -> NATIVE BUFFER + + LDS SI,D [USER_PTR] + ADD SI,CS:[USER_OFFSET] ; DS:SI -> USER BUFFER + + CMP CX,BX + JB @@COPY + MOV CX,BX + +@@COPY: MOV AX,CX + REP MOVSB + + POP DI + POP ES + ADD ES:[DI+BUF_OFFSET],AX + + PUSH CS + POP DS + ADD [USER_OFFSET],AX + RET + +; ----------------------------------------------------------------------------- +; SET UP READY% FILE_COUNT% FILE_ERROR% + +WRITE_DONE: + MOV SI,DATA + MOV DS,SI + JC @@BAD + + MOV W [FILE_COUNT],AX + + MOV W [FILE_ERROR],0 + LDS SI,[BP+6] ; READY% + MOV W [SI],-1 + RET + +@@BAD: MOV W [FILE_COUNT],0 + + MOV W [FILE_ERROR],AX + LDS SI,[BP+6] ; READY% + MOV W [SI],0 + RET + +; ----------------------------------------------------------------------------- +; USAGE OF HANDLE_ AND BUF_ ROUTINES: + +; CALLERS WANTING TO INTERROGATE BUFFER SITUATION SHOULD USE: + +; LDS SI,[BP+14] ; HANDLE% +; CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + +; CALL BUF_ADJUST ; RETURN FILE_PTR_ADJUST + +; CALLERS WANTING TO FLUSH BUFFERS TRANSPARENTLY SHOULD USE: + +; LDS SI,[BP+14] ; HANDLE% +; CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS + +; SUB AX,AX ; 0 = NO BUFFER WANTED +; CALL BUF_SETUP ; SET BUFFER DIRECTION OR KILL + +; CALLERS WANTING TO SET UP BUFFERS SHOULD USE: + +; LDS SI,[BP+14] ; HANDLE% +; CALL HANDLE_SETUP ; SAVE HANDLE AND SET UP POINTERS +; CALL HANDLE_ALLOC ; ENSURE WE HAVE A HANDLE_STRING ENTRY + +; MOV AX,BUF_FLAG_READ ; 1,2 = DIRECTION +; CALL BUF_SETUP ; SET BUFFER DIRECTION OR KILL +; CALL BUF_ALLOC ; ENSURE WE HAVE A BUF_STRING ENTRY + +; AFTER HANDLE_SETUP: + +; DS = CS, PRESERVE +; HANDLE_STRING ENTRY IS ACCESSED FROM ES:DI, PRESERVE +; FILE HANDLE IS ACCESSED FROM BUF_HANDLE + +; ----------------------------------------------------------------------------- +; ENSURE THERE IS AN INITIALISED ENTRY IN HANDLE_STRING FOR HANDLE% + +HANDLE_ALLOC: + MOV AX,[HANDLE_OFFSET] + CMP AX,[HANDLE_LEN] + JB @@RET + + MOV SI,OFFSET HANDLE_STRING + ADD AX,BUF_SIZE + CALL STRING_RESIZE ; MAKE IT BIGGER + + JMP HANDLE_PTR_SETUP + +@@RET: RET + +; ----------------------------------------------------------------------------- +; SAVE HANDLE, SET UP ES:DI AND HANDLE_LEN + +HANDLE_SETUP: + LODSW ; HANDLE% + PUSH CS + POP DS + MOV [BUF_HANDLE],AX ; AX = HANDLE TO USE FOR BUF_FLUSH ETC + + SHL AX,1 + SHL AX,1 + SHL AX,1 + MOV [HANDLE_OFFSET],AX ; AX = OFFSET INTO HANDLE_STRING + ;JMP HANDLE_PTR_SETUP + +HANDLE_PTR_SETUP: + PUSH CS + POP DS + + SUB CX,CX + CMP CX,[HANDLE_STRING] + JZ @@DONE + + MOV SI,OFFSET HANDLE_STRING + CALL STRING_PTR_ES_DI + ADD DI,[HANDLE_OFFSET] + +@@DONE: MOV [HANDLE_LEN],CX + RET + +; ----------------------------------------------------------------------------- +; RETURN BUFFER DIRECTION IN AX, OR NO BUFFER IF AX = 0 + +BUF_TEST: + SUB AX,AX + + MOV BX,[HANDLE_OFFSET] + CMP BX,[HANDLE_LEN] + JAE @@RET ; NO HANDLE ALLOCATED + + MOV AX,ES:[DI+BUF_FLAG] +@@RET: RET + +; ----------------------------------------------------------------------------- + +BUF_ADJUST: + CALL BUF_TEST ; RETURNS AX = BUFFER DIRECTION + + MOV W [FILE_PTR_ADJUST],0 + MOV W [FILE_PTR_ADJUST+2],0 + + CMP AX,BUF_FLAG_READ + JNZ @@CONT + + MOV AX,ES:[DI+BUF_OFFSET] + SUB AX,ES:[DI+BUF_COUNT] ; AX = -BYTES LEFT IN READ BUFFER + JNC @@RET + + MOV W [FILE_PTR_ADJUST+2],-1 + JMP @@DONE + +@@CONT: CMP AX,BUF_FLAG_WRITE + JNZ @@RET + + MOV AX,ES:[DI+BUF_OFFSET] +@@DONE: MOV [FILE_PTR_ADJUST],AX +@@RET: RET + +; ----------------------------------------------------------------------------- +; SET BUFFER DIRECTION FROM AX, OR KILL BUFFER IF AX = 0 + +BUF_SETUP: + MOV BX,[HANDLE_OFFSET] + CMP BX,[HANDLE_LEN] + JAE @@NULL ; NO HANDLE ALLOCATED + + PUSH AX + CALL BUF_PTR_SETUP + POP AX + + CMP AX,ES:[DI+BUF_FLAG] + JZ @@NULL ; ALREADY SET UP, OR ALREADY DEAD + + PUSH AX + CALL BUF_FLUSH + POP AX + + MOV ES:[DI+BUF_FLAG],AX + MOV W ES:[DI+BUF_OFFSET],0 + MOV W ES:[DI+BUF_COUNT],0 +@@RET: RET + +@@NULL: SUB AX,AX ; NC + RET + +; ----------------------------------------------------------------------------- + +BUF_PTR_SETUP: + CMP W ES:[DI+BUF_STRING],0 + JZ @@RET + + PUSH ES + PUSH DI + + PUSH ES + POP DS + LEA SI,[DI+BUF_STRING] + PUSH CS + POP ES + MOV DI,OFFSET BUF_PTR + CALL STRING_PTR_SETUP + PUSH CS + POP DS + + POP DI + POP ES +@@RET: RET + +; ----------------------------------------------------------------------------- + +BUF_ALLOC: + CMP W ES:[DI+BUF_STRING],0 + JNZ @@RET + + PUSH ES + POP DS + LEA SI,[DI+BUF_STRING] + MOV AX,BLOCK_SIZE + CALL STRING_ALLOC + PUSH CS + POP DS + + CALL BUF_PTR_SETUP + + MOV W ES:[DI+BUF_COUNT],0 + MOV W ES:[DI+BUF_OFFSET],0 +@@RET: RET + +; ----------------------------------------------------------------------------- + +BUF_FREE: + MOV BX,[HANDLE_OFFSET] + CMP BX,[HANDLE_LEN] + JAE @@RET ; NO HANDLE ALLOCATED + + PUSH ES + POP DS + LEA SI,[DI+BUF_STRING] + CALL STRING_FREE + PUSH CS + POP DS + + MOV W ES:[DI+BUF_COUNT],0 + MOV W ES:[DI+BUF_OFFSET],0 +@@RET: RET + +; ----------------------------------------------------------------------------- + +BUF_FLUSH: + MOV AX,ES:[DI+BUF_FLAG] + CMP AX,BUF_FLAG_READ + JNZ @@CONT + + CALL READ_FLUSH + JMP @@DONE + +@@CONT: CMP AX,BUF_FLAG_WRITE + JNZ @@NULL + + CALL WRITE_FLUSH +@@DONE: MOV W ES:[DI+BUF_FLAG],0 + RET + +@@NULL: SUB AX,AX ; NC + RET + +; ----------------------------------------------------------------------------- + +PUBLIC FILE_DIAG + +FILE_DIAG: +; CALL TEST_HANDLE_STRING + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + LDS SI,[BP+6] + MOV AX,CS:[HANDLE_STRING] + MOV [SI],AX + POP SI + POP DS + POP BP +; CALL SAVE_HANDLE_STRING + RETF 4 + +; ----------------------------------------------------------------------------- + +IF 0 +TEST_HANDLE_STRING: + PUSHF + CLD + PUSH DS + PUSH ES + PUSH SI + PUSH DI + + PUSH CS + POP DS + MOV SI,OFFSET HANDLE_STRING + SUB CX,CX + CMP CX,[SI] + JZ TEST_NO_HANDLE_STRING + CALL STRING_PTR_ES_DI + +TEST_NO_HANDLE_STRING: + CMP CX,[SAVED_HANDLE_LEN] + JNZ ERROR_HANDLE_STRING + JCXZ OK_HANDLE_STRING + + MOV SI,OFFSET SAVED_HANDLE_STRING + REPZ CMPSB + JNZ ERROR_HANDLE_STRING + + ; CHECK FOR DUPLICATE BUF HANDLES + JMP OK_HANDLE_STRING + +ERROR_HANDLE_STRING: + MOV AX,3C00H + SUB CX,CX + MOV DX,OFFSET NAME_FILE_LOG + INT 21H + JC OK_HANDLE_STRING + + XCHG BX,AX + MOV AH,3EH + INT 21H + +OK_HANDLE_STRING: + POP DI + POP SI + POP ES + POP DS + POPF + RET + +SAVE_HANDLE_STRING: + PUSHF + CLD + PUSH DS + PUSH ES + PUSH SI + PUSH DI + + PUSH CS + POP DS + MOV SI,OFFSET HANDLE_STRING + SUB CX,CX + CMP CX,[SI] + JZ SAVE_NO_HANDLE_STRING + CALL STRING_PTR_DS_SI + +SAVE_NO_HANDLE_STRING: + MOV CS:[SAVED_HANDLE_LEN],CX + + PUSH CS + POP ES + MOV DI,OFFSET SAVED_HANDLE_STRING + REP MOVSB + + POP DI + POP SI + POP ES + POP DS + POPF + RET + +SAVED_HANDLE_LEN DW 0 +SAVED_HANDLE_STRING DB 100H*8 DUP (0) + +NAME_FILE_LOG DB 'C:\JRNXL\FILE.LOG',0 +ENDIF + +; ----------------------------------------------------------------------------- + +EXEC_PARAMS DW 0 ; SEGMENT OF ENVIRONMENT + DW BUF_NEW,0 ; DWORD -> COMMAND LINE + DD -1,-1 + +CURRENT_PSP DW 0 + +PRINT_HANDLE DW 0 +PRINT_READY DW 0 + +BUF_HANDLE DW 0 +BUF_PTR DW 0,0 +BUF_SEEK_PTR DW 0,0 + +;HANDLE_PTR DW 0,0 +HANDLE_OFFSET DW 0 +HANDLE_LEN DW 0 +HANDLE_STRING DW 0 + +FILE_PTR_ADJUST DW 0,0 +FILE_DATA_PTR DW 0,0 + +CRLF_STRING DW 0 ; STRING HANDLE FOR CHR$(&HD,&HA) + +READ_LINE_MAX DW LINE_SIZE +READ_LINE_CR DW 0 ; 0=NOTHING, 1=CR FOUND, 2=CR/LF OR EOF +READ_SKIP_COUNT DW 0 + +USER_STRING DW 0 ; STRING HANDLE FOR DYNAMIC FILE BUFFER + +USER_PTR DW 0,0 +USER_OFFSET DW 0 +USER_COUNT DW 0 + +TEMP_SOURCE DW 0 ; FOR FILE_COPY % +TEMP_DEST DW 0 +TEMP_STRING DW 0 +TEMP_ATTR DW 0 +TEMP_DATE DW 0 +TEMP_TIME DW 0 +TEMP_READY DW 0 ; % + +TEMP_COUNT DW BLOCK_SIZE ; VARIOUS + +OLD_STRING DW 0 ; FOR STRING_RESIZE + +BUF_DTA DB 2BH DUP (0) + +BUF_NAME DB 129 DUP (0) +BUF_NEW DB 129 DUP (0) + +; ----------------------------------------------------------------------------- + +CODE ENDS + +; ----------------------------------------------------------------------------- + +DATA SEGMENT +DATA ENDS + +; ----------------------------------------------------------------------------- + + END diff --git a/src/avr/file.inc b/src/avr/file.inc new file mode 100644 index 00000000..7816f1b3 --- /dev/null +++ b/src/avr/file.inc @@ -0,0 +1,58 @@ +' FILE.INC + +' ----------------------------------------------------------------------------- + +$LINK "FILE.OBJ" + +DECLARE SUB FILE_OPEN(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_CREATE(INTEGER,STRING,INTEGER,INTEGER) +DECLARE SUB FILE_CLOSE(INTEGER,INTEGER) +DECLARE SUB FILE_READ(INTEGER,STRING,INTEGER,INTEGER) +DECLARE SUB FILE_READ_BUF(INTEGER,STRING,INTEGER,INTEGER) +DECLARE SUB FILE_READ_LINE(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_READ_DIRECT(INTEGER,POINTER,INTEGER,INTEGER) +DECLARE SUB FILE_WRITE(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_WRITE_BUF(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_WRITE_LINE(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_WRITE_DIRECT(INTEGER,POINTER,INTEGER,INTEGER) +DECLARE SUB FILE_SEEK(INTEGER,LONG,INTEGER) +DECLARE SUB FILE_SEEK_REL(INTEGER,LONG,INTEGER) +DECLARE SUB FILE_SEEK_END(INTEGER,LONG,INTEGER) +DECLARE SUB FILE_SEEK_GET(INTEGER,LONG,INTEGER) +DECLARE SUB FILE_PRINT(STRING) +DECLARE SUB FILE_FLUSH(INTEGER,INTEGER) +DECLARE SUB FILE_DUPLICATE_HANDLE(INTEGER,INTEGER,INTEGER) +DECLARE SUB FILE_REDIRECT_HANDLE(INTEGER,INTEGER,INTEGER) +DECLARE SUB FILE_GET_DATE_TIME(INTEGER,INTEGER,INTEGER,INTEGER) +DECLARE SUB FILE_SET_DATE_TIME(INTEGER,INTEGER,INTEGER,INTEGER) +DECLARE SUB FILE_GET_ATTRIBUTES(STRING,INTEGER,INTEGER) +DECLARE SUB FILE_SET_ATTRIBUTES(STRING,INTEGER,INTEGER) +DECLARE SUB FILE_RENAME(STRING,STRING,INTEGER) +DECLARE SUB FILE_DELETE(STRING,INTEGER) +DECLARE SUB FILE_SEARCH_FIRST(STRING,INTEGER,STRING,INTEGER) +DECLARE SUB FILE_SEARCH_NEXT(STRING,INTEGER) +DECLARE SUB FILE_CREATE_DIRECTORY(STRING,INTEGER) +DECLARE SUB FILE_DELETE_DIRECTORY(STRING,INTEGER) +DECLARE SUB FILE_GET_DIRECTORY(INTEGER,STRING,INTEGER) +DECLARE SUB FILE_SET_DIRECTORY(STRING,INTEGER) +DECLARE SUB FILE_GET_DRIVE(INTEGER,INTEGER) +DECLARE SUB FILE_SET_DRIVE(INTEGER,INTEGER) +DECLARE SUB FILE_GET_DRIVE_INFO(INTEGER,INTEGER,INTEGER,INTEGER,INTEGER, _ + INTEGER) +DECLARE SUB FILE_COPY(STRING,STRING,INTEGER) +DECLARE SUB FILE_INVOCATION(STRING,INTEGER) +DECLARE SUB FILE_SET_HANDLES(INTEGER,INTEGER) +DECLARE SUB FILE_SHELL(STRING,STRING,INTEGER) +DECLARE SUB FILE_DIAG(INTEGER) + +PUBLIC FILE_ERROR% +PUBLIC FILE_COUNT% +PUBLIC FILE_POINTER& +PUBLIC FILE_DRIVES% + +SUB FILE_BOMB_OUT + END +END SUB + +' ----------------------------------------------------------------------------- + diff --git a/src/avr/iocall.asm b/src/avr/iocall.asm new file mode 100644 index 00000000..4b1fcbe7 --- /dev/null +++ b/src/avr/iocall.asm @@ -0,0 +1,1015 @@ +; IOCALL.ASM + +EXTRN GETSTRLOC:FAR +EXTRN GETSTRALLOC:FAR +EXTRN RLSSTRALLOC:FAR + +EXTRN IO_READY:WORD + +; ----------------------------------------------------------------------------- + +CODE SEGMENT + + ASSUME CS:CODE,DS:DATA + +B EQU BYTE PTR +W EQU WORD PTR +D EQU DWORD PTR + + JUMPS + LOCALS + +; ----------------------------------------------------------------------------- +; IO_TEST +; IF IO_READY%=0 THEN PRINT "OSCAR IO NOT INSTALLED":END + +PUBLIC IO_TEST + +IO_TEST: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + MOV AX,35F8H + INT 21H + LEA DI,[BX-8] ; ES:DI -> 8 BYTES BEFORE INT + + MOV SI,OFFSET OSCAR_IO ; DS:SI -> COMPARISON STRING + + MOV CX,4 + REPZ CMPSW ; CHECK THE BASTARD + JNZ @@BAD + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF + +; ----------------------------------------------------------------------------- +; ID$="90000 RECALIBRATION 3072 "+ _ +; "AUS SW:04APR97 0000 PC SYS:0.000 "+ _ +; MKI$(MODEM_PORT%)+MKI$(LOOP_PORT%)+CHR$(ESCAPE_CHAR%) +; IO_TEACH_ID ID$ + +PUBLIC IO_TEACH_ID + +IO_TEACH_ID: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; ES:SI -> ID$ DESCRIPTOR + CALL STRING_PTR + MOV CX,DX ; CX:AX -> ID$ DATA + + MOV BX,76H ; TEACH ID + INT 0F8H + + POP DI + POP SI + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- +; IO_INIT PORT%, RATE& + +PUBLIC IO_INIT + +IO_INIT: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] ; DX = PORT + + LES SI,[BP+6] ; RATE% + MOV DI,ES:[SI+2] + MOV SI,ES:[SI] ; DI:SI = RATE DWORD + + MOV AX,4D01H ; D8PN, SET DTR/RTS ON + MOV BX,26H ; NEW SET PORT PARAMETERS + INT 0F8H ; ALSO CLEARS ADLC MODE, AUTOS OFF + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_INIT_D7PE PORT%, RATE& + +PUBLIC IO_INIT_D7PE + +IO_INIT_D7PE: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] ; DX = PORT + + LES SI,[BP+6] ; RATE% + MOV DI,ES:[SI+2] + MOV SI,ES:[SI] ; DI:SI = RATE DWORD + + MOV AX,7901H ; D7PE, SET DTR/RTS ON + MOV BX,26H ; NEW SET PORT PARAMETERS + INT 0F8H ; ALSO CLEARS ADLC MODE, AUTOS OFF + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_INIT_PRESERVE PORT%, RATE& + +PUBLIC IO_INIT_PRESERVE + +IO_INIT_PRESERVE: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] ; DX = PORT + + LES SI,[BP+6] ; RATE% + MOV DI,ES:[SI+2] + MOV SI,ES:[SI] ; DI:SI = RATE DWORD + + MOV AX,4D02H ; D8PN, PRESERVE DTR/RTS + MOV BX,26H ; NEW SET PORT PARAMETERS + INT 0F8H ; ALSO CLEARS ADLC MODE, AUTOS OFF + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_REINIT PORT%, RATE& + +PUBLIC IO_REINIT + +IO_REINIT: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] ; DX = PORT + + LES SI,[BP+6] ; RATE% + MOV DI,ES:[SI+2] + MOV SI,ES:[SI] ; DI:SI = RATE DWORD + + MOV AX,4D03H ; D8PN, JUST SET PARAMETERS + MOV BX,26H ; NEW SET PORT PARAMETERS + INT 0F8H ; ALSO CLEARS ADLC MODE, AUTOS OFF + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_REINIT_WAIT PORT%, RATE& + +PUBLIC IO_REINIT_WAIT + +IO_REINIT_WAIT: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] ; DX = PORT + + LES SI,[BP+6] ; RATE% + MOV DI,ES:[SI+2] + MOV SI,ES:[SI] ; DI:SI = RATE DWORD + + MOV AX,4D04H ; D8PN, JUST SET PARAMETERS, WAIT TX + MOV BX,26H ; NEW SET PORT PARAMETERS + INT 0F8H ; ALSO CLEARS ADLC MODE, AUTOS OFF + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_FLUSH PORT% + +PUBLIC IO_FLUSH + +IO_FLUSH: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; PORT% + MOV DX,ES:[SI] + + SUB BX,BX ; FLUSH RECEIVER + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- +; IO_FLUSH_ADLC PORT% + +PUBLIC IO_FLUSH_ADLC + +IO_FLUSH_ADLC: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; PORT% + MOV DX,ES:[SI] + + MOV BX,7AH ; FLUSH ADLC BUFFERS + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- +; IO_TX PORT%, CHAR% + +PUBLIC IO_TX + +IO_TX: PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; CHAR% + LODS B ES:[SI] + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,0AH ; SEND BYTE IF READY + INT 0F8H + JZ @@BAD + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_TX_WAIT PORT%, CHAR% + +PUBLIC IO_TX_WAIT + +IO_TX_WAIT: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; CHAR% + LODS B ES:[SI] + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,0CH ; WAIT TO SEND BYTE + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_TX_STATUS PORT%, FLAG% + +PUBLIC IO_TX_STATUS + +IO_TX_STATUS: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,8 ; TX STATUS + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_TX_COMPLETE PORT%, FLAG% + +PUBLIC IO_TX_COMPLETE + +IO_TX_COMPLETE: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,8EH ; TX COMPLETE + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; FRAME$=CMD$+DAT$ +; CALL IO_TX_ADLC PORT%, DEST$, FRAME$ + +PUBLIC IO_TX_ADLC + +IO_TX_ADLC: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+14] + MOV DX,ES:[SI] ; DX = PORT% + + MOV BX,8 ; TX STATUS + INT 0F8H + JNZ @@BAD + MOV [POOL_PTR],AX + MOV [POOL_PTR+2],CX ; POOL_PTR -> RESERVED FRAME + + LES SI,[BP+6] ; FRAME$ + CALL STRING_PTR ; DX:AX -> FRAME$ DATA SPACE + JCXZ @@BAD + MOV [FRAME_LEN],CX ; FRAME_LEN = LEN(FRAME$) + MOV [FRAME_PTR],AX + MOV [FRAME_PTR+2],DX ; FRAME_PTR -> FRAME$ DATA SPACE + + LES SI,[BP+10] ; DEST$ + CALL STRING_PTR ; DX:AX -> DEST$ DATA SPACE + CMP CX,5 + JNZ @@BAD + MOV [DEST_PTR],AX + MOV [DEST_PTR+2],DX ; DEST_PTR -> DEST$ DATA SPACE + + LES DI,D [POOL_PTR] + INC DI ; DI -> CHN THEN START XMITTED PART + + MOV AL,2 ; ??? + STOSB + + MOV AL,1+1+1+5+5+1+1+2 + ADD AL,B [FRAME_LEN] + STOSB ; LEN + + PUSH DS + LDS SI,[BP+14] ; PORT% + MOV AX,301H ; ??? + ADD AL,B [SI] + POP DS + STOSW ; CHN, RAT + + PUSH DS + LDS SI,D [DEST_PTR] ; DS:SI -> DEST$ DATA + MOV CX,5 + REP MOVSB ; DESTINATION ADDRESS + POP DS + + ADD DI,5 + XCHG AX,CX ; AX = 0 + STOSW + + PUSH DS + MOV CX,[FRAME_LEN] + LDS SI,D [FRAME_PTR] + REP MOVSB + POP DS + + MOV AX,[POOL_PTR] + MOV CX,[POOL_PTR+2] + + LES SI,[BP+14] + MOV DX,ES:[SI] ; DX = PORT% + + MOV BX,0EH ; TX + INT 0F8H + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 12 + +; ----------------------------------------------------------------------------- +; CALL IO_RX PORT%, CHAR% + +PUBLIC IO_RX + +IO_RX: PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,W ES:[SI] + + MOV BX,4 ; RECEIVE BYTE IF READY + INT 0F8H + JZ @@BAD + + LES DI,[BP+6] ; CHAR% + SUB AH,AH + STOSW + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_RX_WAIT PORT%, CHAR% + +PUBLIC IO_RX_WAIT + +IO_RX_WAIT: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,W ES:[SI] + + MOV BX,6 ; WAIT TO RECEIVE BYTE + INT 0F8H + + LES DI,[BP+6] ; CHAR% + SUB AH,AH + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_RX_ADLC PORT%, SOURCE$, FRAME$ +; IF IO_READY% THEN +; CMD%=ASC(FRAME$) +; DAT$=MID$(FRAME$, 2) +; END IF + +PUBLIC IO_RX_ADLC + +IO_RX_ADLC: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+14] ; PORT% + MOV DX,ES:[SI] + + MOV BX,4 ; RX STATUS + INT 0F8H + JZ @@BAD + MOV [POOL_PTR],AX + MOV [POOL_PTR+2],CX + + XCHG SI,AX + MOV ES,CX + MOV AL,ES:[SI+2] + SUB AH,AH ; CX = RECEIVED FRAME LENGTH + SUB AX,1+1+1+5+5+1+1+2 + MOV [FRAME_LEN],AX + + XCHG CX,AX + LES SI,[BP+6] ; FRAME$ + CALL STRING_REALLOC + CALL STRING_PTR ; DX:AX -> FRAME$ DATA SPACE + MOV [FRAME_PTR],AX + MOV [FRAME_PTR+2],DX ; FRAME_PTR -> FRAME$ DATA SPACE + + MOV CX,5 + LES SI,[BP+10] ; SOURCE$ + CALL STRING_REALLOC + CALL STRING_PTR ; DX:AX -> SOURCE$ DATA SPACE + + MOV CX,5 + XCHG DI,AX + MOV ES,DX ; ES:DI -> SOURCE$ DATA SPACE + + PUSH DS + LDS SI,D [POOL_PTR] + ADD SI,2+1+1+1+5 ; DS:SI -> SOURCE ADDRESS IN POOL + REP MOVSB + POP DS + + MOV CX,[FRAME_LEN] + LES DI,D [FRAME_PTR] ; ES:DI -> FRAME$ DATA SPACE + + PUSH DS + LDS SI,D [POOL_PTR] + PUSH SI + ADD SI,2+1+1+1+5+5+2 ; DS:SI -> COMMAND + DATA IN POOL + REP MOVSB + POP SI ; SI -> FRAME FLAG + AND B [SI],11111101B ; CLEAR BIT 1 + POP DS + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 12 + +; ----------------------------------------------------------------------------- +; IO_SET_DTR PORT%, FLAG% + +PUBLIC IO_SET_DTR + +IO_SET_DTR: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; FLAG% + LODSW + OR AL,AH + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,10H ; DTR ON/OFF + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_SET_RTS PORT%, FLAG% + +PUBLIC IO_SET_RTS + +IO_SET_RTS: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; FLAG% + LODSW + OR AL,AH + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,12H ; RTS ON/OFF + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_SET_BREAK PORT%, FLAG% + +PUBLIC IO_SET_BREAK + +IO_SET_BREAK: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; FLAG% + LODSW + OR AL,AH + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,28H ; BREAK ON/OFF + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_SET_ADLC PORT%, FLAG% + +PUBLIC IO_SET_ADLC + +IO_SET_ADLC: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; FLAG% + LODSW + OR AL,AH + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,74H ; ADLC ON/OFF + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_SET_AUTOS PORT%, FLAG% + +PUBLIC IO_SET_AUTOS + +IO_SET_AUTOS: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+6] ; FLAG% + LODSW + OR AL,AH + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,14H ; AUTOS ON/OFF + INT 0F8H + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_READ_DCD PORT%, FLAG% + +PUBLIC IO_READ_DCD + +IO_READ_DCD: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,16H ; DCD STATUS + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_READ_DSR PORT%, FLAG% + +PUBLIC IO_READ_DSR + +IO_READ_DSR: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,18H ; DSR STATUS + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_READ_CTS PORT%, FLAG% + +PUBLIC IO_READ_CTS + +IO_READ_CTS: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,1AH ; CTS STATUS + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; IO_READ_RI PORT%, FLAG% + +PUBLIC IO_READ_RI + +IO_READ_RI: + PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + + LES SI,[BP+10] ; PORT% + MOV DX,ES:[SI] + + MOV BX,1CH ; RI STATUS + INT 0F8H + + MOV AX,0 + JZ @@NULL + DEC AX +@@NULL: LES DI,[BP+6] ; FLAG% + STOSW + + MOV W [IO_READY],-1 + + POP DI + POP SI + POP BP + RETF 8 + +; ----------------------------------------------------------------------------- +; QUEUE$="STUFF THIS" +; IO_QUEUE QUEUE$ + +PUBLIC IO_QUEUE + +IO_QUEUE: + PUSH BP + MOV BP,SP + PUSH DS + PUSH SI + PUSH DI + + LES SI,[BP+6] ; QUEUE$ + CALL STRING_PTR + MOV [QUEUE_LEN],CX + MOV [QUEUE_PTR],AX + MOV [QUEUE_PTR+2],DX + + INC CX + INC CX + PUSH DS + POP ES + MOV SI,OFFSET STRING_TEMP + CALL STRING_ALLOC + CALL STRING_PTR ; DX:AX -> TEMPORARY DATA SPACE + + MOV CX,[QUEUE_LEN] + XCHG DI,AX + MOV ES,DX + + PUSH DS + LDS SI,D [QUEUE_PTR] + REP MOVSB + POP DS + + MOV AX,[QUEUE_LEN] + STOSW + + DEC DI + DEC DI + XCHG AX,DI + MOV CX,ES ; CX:AX -> LENGTH WORD IN COPIED STRING + + MOV BX,62H ; ADD TO QUEUE, BUFFERED + INT 0F8H + + PUSHF + PUSH DS + POP ES + MOV SI,OFFSET STRING_TEMP + CALL STRING_FREE + POPF + JZ @@BAD + + MOV W [IO_READY],-1 + JMP @@RET + +@@BAD: MOV W [IO_READY],0 + +@@RET: POP DI + POP SI + POP BP + RETF 4 + +; ----------------------------------------------------------------------------- + +STRING_PTR: + PUSH ES + PUSH SI + PUSH W ES:[SI] + CALL GETSTRLOC + POP SI + POP ES + RET + +STRING_FREE: + CMP W ES:[SI],0 + JZ @@RET + PUSH ES + PUSH SI + PUSH ES:[SI] + CALL RLSSTRALLOC + POP SI + POP ES + MOV W ES:[SI],0 +@@RET: RET + +STRING_REALLOC: + PUSH CX + CALL STRING_FREE + POP CX +STRING_ALLOC: + PUSH ES + PUSH SI + PUSH CX + CALL GETSTRALLOC + POP SI + POP ES + MOV ES:[SI],AX + RET + +; ----------------------------------------------------------------------------- + +CODE ENDS + +; ----------------------------------------------------------------------------- + +DATA SEGMENT + +OSCAR_IO DB 'OSCAR IO' + + EVENDATA + +STRING_TEMP DW ? + +QUEUE_LEN DW ? +QUEUE_PTR DW ? + +FRAME_LEN DW ? +FRAME_PTR DW ?,? + +POOL_PTR DW ?,? +DEST_PTR DW ?,? + +DATA ENDS + +; ----------------------------------------------------------------------------- + + END diff --git a/src/avr/iocall.inc b/src/avr/iocall.inc new file mode 100644 index 00000000..b148e3cb --- /dev/null +++ b/src/avr/iocall.inc @@ -0,0 +1,44 @@ +' IOCALL.INC + +' ----------------------------------------------------------------------------- + +PUBLIC IO_READY% + +$LINK "IOCALL.OBJ" + +DECLARE SUB IO_TEST() +DECLARE SUB IO_TEACH_ID(STRING) + +DECLARE SUB IO_INIT(INTEGER,LONG) +DECLARE SUB IO_INIT_D7PE(INTEGER,LONG) +DECLARE SUB IO_INIT_PRESERVE(INTEGER,LONG) +DECLARE SUB IO_REINIT(INTEGER,LONG) +DECLARE SUB IO_REINIT_WAIT(INTEGER,LONG) +DECLARE SUB IO_FLUSH(INTEGER) +DECLARE SUB IO_FLUSH_ADLC(INTEGER) + +DECLARE SUB IO_TX(INTEGER,INTEGER) +DECLARE SUB IO_TX_WAIT(INTEGER,INTEGER) +DECLARE SUB IO_TX_STATUS(INTEGER,INTEGER) +DECLARE SUB IO_TX_COMPLETE(INTEGER,INTEGER) +DECLARE SUB IO_TX_ADLC(INTEGER,STRING,STRING) + +DECLARE SUB IO_RX(INTEGER,INTEGER) +DECLARE SUB IO_RX_WAIT(INTEGER,INTEGER) +DECLARE SUB IO_RX_ADLC(INTEGER,STRING,STRING) + +DECLARE SUB IO_SET_DTR(INTEGER,INTEGER) +DECLARE SUB IO_SET_RTS(INTEGER,INTEGER) +DECLARE SUB IO_SET_BREAK(INTEGER,INTEGER) +DECLARE SUB IO_SET_ADLC(INTEGER,INTEGER) +DECLARE SUB IO_SET_AUTOS(INTEGER,INTEGER) + +DECLARE SUB IO_READ_DCD(INTEGER,INTEGER) +DECLARE SUB IO_READ_DSR(INTEGER,INTEGER) +DECLARE SUB IO_READ_CTS(INTEGER,INTEGER) +DECLARE SUB IO_READ_RI(INTEGER,INTEGER) + +DECLARE SUB IO_QUEUE(INTEGER) + +' ----------------------------------------------------------------------------- + diff --git a/src/avr/lcter.asm b/src/avr/lcter.asm new file mode 100644 index 00000000..892cb1f2 --- /dev/null +++ b/src/avr/lcter.asm @@ -0,0 +1,2398 @@ +; LC.ASM +; WEIGHING MODE + +.INCLUDE "4433DEF.INC" ; FOR AVR ASSEMBLER +;.INCLUDE "4433DEFX.INC" ; FOR NICK ASSEMBLER +.INCLUDE "MACLC.INC" +;.INCLUDE "APILC.INC" +.INCLUDE "TERLC.INC" + +; WE SHOULD CHANGE THE CODE TO USE UCSRA AND UCSRB +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU RAM =$60 ; START OF SRAM +.EQU CR =$0D +.EQU LF =$0A +.EQU RX_SIZE =1 +.EQU TX_SIZE =8 ; LEAVES 10 BYTES FREE +.EQU API_ADDRESS =$01 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU CYC_MAX =256 ; MAXIMUM WEIGHING CYCLE TIME +.EQU CYC_MIN =160 ; MINIMUM WEIGHING CYCLE TIME > 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +LSTGMS: .BYTE 4 +LSTDEV: .BYTE 4 +AVEGMS: .BYTE 4 +AVESTD: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +;WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +;REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 ; CAREFUL +DSPGMS: .BYTE 4 +ZROGMS: .BYTE 4 +DSPRES: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +.ESEG +.ORG $000 +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 SPAN FOR MELB/DELAWARE +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD +;SPAN: .DB $6C,$21,$80,$3F ; 1.0010200E+00 SPAN FOR QATAR + +;CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +;CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) + +CNFHYS: .DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +HYSCNF: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +;K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 +;K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 COULD PERHAPS USE KR0001 INSTEAD +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 COULD PERHAPS ELIMINATE THIS +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +;K0: .DB $00,$00 ; 0.000000E+00 DON'T MOVE! +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 ! +;K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +;K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K228: .DB $39,$8E,$63,$43 ; 2.275556E+02 = 256*16/18 REVISED 17MAY01 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 SHOULD PUT ZERO RANGE IN EEPROM +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +; CHARACTERIZE ONLY % +;K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +;K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +;K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +;FMAT3: .DB 6,0 +; .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: + OUTI SPL,RAMEND ; INIT STACK POINTER + OUTI ACSR,$80 ; POWER DOWN ANALOG COMPARATOR + +; SBI DDRB,5 ; SET SK TO OUTPUT FOR DIAGNOSTICS + + SBI DDRD,2 ; SET BIT 2 TO OUTPUT FOR TEMP SENSOR + SBI DDRD,3 ; SET BIT 3 TO OUTPUT FOR TILT SENSOR + + OUTI TCCR1B,1 ; SET COUNTER1 TO CLOCK AT 11.0592 MHZ + ; AND INPUT CAPTURE ON FALLING EDGE +; OUTI MCUCR,2 ; SET INT0 FALLING EDGE FOR TEMP SENSOR + OUTI MCUCR,0 ; SET INT0 LOW SENSE FOR TEMP SENSOR + ; 17MAY01 BOMBS GRACEFULLY AT EACH EXTREME + + CLR CYC_0 + CLR CYC_1 + + CLR A + STS RANGE,A + RCALL STS_STATUS_A + STS STARTUP,A + STS TMP_PHASE,A + + ;LDER A,EEMODE +; CHARACTERIZE ONLY % +; LDI A,$F0 +; % + STS MODE,A + +; WEIGHING ONLY % + LDI A,1 + STS MODE_CYCLE,A +; % + + FLDF K1 + FST DSPRES + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST LSTGMS + FST LSTDEV + FST AVEGMS + FST AVESTD + FST INTGMS +; CHARACTERIZE ONLY % +; FST WGTFRQ ; MAY NOT BE NECESSARY +; FST REF_30MHZ ; NECESSARY +; % + + INIT_API_BUS ; SET UART RATE AND CLEAR FLAGS/PTRS + + IN A,TIMSK + ORI A,8 ; ENABLE INTERRUPT ON T1 INPUT CAPTURE + OUT TIMSK,A + +; WEIGHING ONLY % + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A +; % + + ; START FOREGROUND TASK + SEI + +; LDFL D,SIGNON ; SEND SIGNON MESSAGE +; LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR + +LOOP: ; MAIN PROGRAM + ; IF THE INTERRUPT ALREADY CAME, + ; THROW AWAY THE DATA AND WAIT FOR A NEW ONE + CBR FLAGS,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) + FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD + LDI F,AVESTD + RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST + FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST INTGMS ; INTGMS=0 + RCALL LDS_A_STATUS + CBR A,1<LDER) GET RANGE COUNT + LDI ZL,RANGE1*2 ; POINT TO FIRST RANGE BOUNDARY +RNGE: RCALL CPE_FA ; COMPARE FA WITH BOUNDARY + BRCS GOTRNG + ADIW ZL,4 ; POINT TO NEXT RNG + DEC E + BRNE RNGE + SBIW ZL,4 ; POINT BACK TO PREVIOUS RESOLUTION +GOTRNG: RCALL LDE_FA ; GET DISPLAY RESOLUTION FOR THIS RANGE + FST DSPRES + +; STABILIZE DISPLAYED WEIGHT USING HYSTERESIS +STAB: FLD F0 + MOV F,FA2 ; SAVE SIGN BIT + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + FST F2 + RCALL FIX_FA ; TRUNCATE TO 3 BYTE INTEGER + RCALL LD3 ; CONVERT BACK TO FP FORMAT + FST F0 ; INTEGER PART + FLD F2 + FSB F0 ; FA = FRACTIONAL PART + FCPF HSTRSL + BRCS STB2 ; FRACTION < HSTRSL, ROUND DOWN + FCPF HSTRSH + BRCC STB1 ; FRACTION >= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE + FML DSPRES ; DISPLAY RESOLUTION + ; % + FST DSPGMS + +STB5: ;LDS A,MODE ; IF NOT WEIGHING MODE + ;SBRS A,DSPGMS_FLG + ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS + + LDI E,CYC_MIN*2/3 + RCALL TX_WAIT_EMPTY + BRCS FMT + RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE + +FMT: RCALL LDS_A_STATUS + SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? + RJMP SKIP_SN + + CBR A,1<=0 + BRPL FMT2 ; THEN CONTINUE +; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) + INC E ; INC " -LO-" COUNTER (STARTUP) + CPI E,CYC_START+8 ; IF STARTUP E + ;RCALL SNDSTR + ;LDI A,'0' + ;RCALL TX_WAIT + ;RJMP DSP8 + ; % + RJMP DSP7 +FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" + BRCS FMT3 + LDI E,CYC_START ; THEN STARTUP=CYC_START + STS STARTUP,E +FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX + BRCS FMT4 + SBR F,1< E + LDFL D,FMAT0 ; " 0.000" + ADIW ZL,2 +DSP2: CP F,D + BRCC DSP4 +DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 + BREQ DSP8 ; WHEN ALL DONE + CPI D,4 + BRNE DSP2 + DEC F ; TO COMPENSATE FOR EXTRA DEC C + RJMP DSP3 ; DO DECIMAL PT +DSP4: + ; FOR TENTHS OF GRAMS % + ;INC F + ; % + RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +DSP5: DEC F + BREQ DSP8 + CPI F,4 + ; FOR TENTHS OF GRAMS % + ;CPI F,5 + ; % + BRNE DSP6 + LDI A,'.' + RCALL TX_WAIT + DEC F +DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + RJMP DSP5 +DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E + RCALL SNDSTR +DSP8: +; ASCII STABILITY INDICATION FOR TESTING % +; LDI A,' ' +; RCALL TX_WAIT +; RCALL LDS_A_STATUS +; ANDI A,1< 1 SECOND ? +; BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION +; +; FSBF K33M +; FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE +; +; SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RJMP STS_FA ; AND SAVE + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % + INC FA3 ; CHECK FOR NAN + BRNE SND0 + DEC FA3 ; TO COMPLY WITH IEEE754 +SND0: DEC FA3 + ROL FA2 ; CONVERT TO IEEE754 + ROR FA3 + ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % + LDS B,MODE_CYCLE + AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + +; WEIGHING ONLY % + LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E + RCALL TX_WAIT_EMPTY + BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM +; % + +SNDFPX: +; CHARACTERIZE ONLY % +; SBRS FLAGS,SNDDAT +; RET +; CPI A,$80 +; LDI A,$0A +; BRNE SEPOK +; LDI A,$0D +;SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % + LDI A,$1B + RCALL TX_WAIT + MOV A,F ; INDICATE WHICH DATA IS BEING SENT + RCALL TX_WAIT +;SND_FA: + LDI XL,FA ; LOAD TX BUFFER + LDI D,4 +SND1: LD A,X+ + RCALL TX_WAIT ; LS BYTE FIRST + DEC D + BRNE SND1 + RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -16 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION > +5 + BRLO CORRECTION_OK +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_DOLLAR +; LDI A,'$' +; RCALL TX_CHAR +;SKIP_DOLLAR: +; POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + + CLI ; 17MAY01 + LDS G,TMP_PHASE ; START TEMPERATURE MEASUREMENT % + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT TO SYNCHRONISE SUBSEQUENT INT0 + BRNE TMP0 + + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT + IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA:LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA:LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +;SNDEXP: +; PUSH A ; SEPARATOR +; RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +;EXP5: FCPF KR0001 ; IF N<.0001 +; BRCC EXP6 +; FMLF K100K ; THEN N=N*100K +; SUBI F,5 ; E=E-5 +; RJMP EXP5 +;EXP6: FCPF K1 ; IF N<1 +; BRCC EXP7 +; FMLF K10 ; THEN N=N*10 +; SUBI F,1 ; E=E-1 +; RJMP EXP6 +;EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 +; RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +; LDI A,'.' +; RCALL TX_WAIT +; LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +;EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; DEC E +; BRNE EXP8 +; LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY +; RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION +; LDI A,'0' +; RCALL TX_WAIT +; LDI A,'E' ; NOW FOR THE EXPONENT +; RCALL TX_WAIT +; LDI A,'+' ; SEND SIGN +; TST F +; BRPL EXP9 +; LDI A,'-' +; NEG F ; ABS(E) +;EXP9: RCALL TX_WAIT +; LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +;EXP10: INC A +; SUBI F,10 +; BRPL EXP10 +; RCALL TX_WAIT +; LDI A,'0'+10 ; NOW LS DIGIT +; ADD A,F +; RCALL TX_WAIT +; POP A +; RCALL TX_WAIT ; SEPARATOR +;EXP11: FLD F0 ; AND RESTORE FA +; RET +; +;EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 +; LDI A,' ' ; SEND SIGN (SPACE FOR +) +; TST FA2 +; BRPL EXP1 +; LDI A,'-' +;EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +;EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT + ;;FMLF K_1 ; LET'S BE SAFE ;; LET'S NOT +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS +EXP4: RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1< 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +LSTGMS: .BYTE 4 +LSTDEV: .BYTE 4 +AVEGMS: .BYTE 4 +AVESTD: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +;WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +;REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 ; CAREFUL +DSPGMS: .BYTE 4 +ZROGMS: .BYTE 4 +DSPRES: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +.ESEG +.ORG $000 +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 SPAN FOR MELB/DELAWARE +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD +;SPAN: .DB $6C,$21,$80,$3F ; 1.0010200E+00 SPAN FOR QATAR + +;CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +;CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) + +CNFHYS: .DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +HYSCNF: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +;K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 +;K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 COULD PERHAPS USE KR0001 INSTEAD +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 COULD PERHAPS ELIMINATE THIS +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +;K0: .DB $00,$00 ; 0.000000E+00 DON'T MOVE! +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 ! +;K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +;K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K228: .DB $39,$8E,$63,$43 ; 2.275556E+02 = 256*16/18 REVISED 17MAY01 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 SHOULD PUT ZERO RANGE IN EEPROM +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +; CHARACTERIZE ONLY % +;K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +;K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +;K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +;FMAT3: .DB 6,0 +; .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: + OUTI SPL,RAMEND ; INIT STACK POINTER + OUTI ACSR,$80 ; POWER DOWN ANALOG COMPARATOR + +; SBI DDRB,5 ; SET SK TO OUTPUT FOR DIAGNOSTICS + + SBI DDRD,2 ; SET BIT 2 TO OUTPUT FOR TEMP SENSOR + SBI DDRD,3 ; SET BIT 3 TO OUTPUT FOR TILT SENSOR + + OUTI TCCR1B,1 ; SET COUNTER1 TO CLOCK AT 11.0592 MHZ + ; AND INPUT CAPTURE ON FALLING EDGE +; OUTI MCUCR,2 ; SET INT0 FALLING EDGE FOR TEMP SENSOR + OUTI MCUCR,0 ; SET INT0 LOW SENSE FOR TEMP SENSOR + ; 17MAY01 BOMBS GRACEFULLY AT EACH EXTREME + + CLR CYC_0 + CLR CYC_1 + + CLR A + STS RANGE,A + RCALL STS_STATUS_A + STS STARTUP,A + STS TMP_PHASE,A + + ;LDER A,EEMODE +; CHARACTERIZE ONLY % +; LDI A,$F0 +; % + STS MODE,A + +; WEIGHING ONLY % + LDI A,1 + STS MODE_CYCLE,A +; % + + FLDF K1 + FST DSPRES + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST LSTGMS + FST LSTDEV + FST AVEGMS + FST AVESTD + FST INTGMS +; CHARACTERIZE ONLY % +; FST WGTFRQ ; MAY NOT BE NECESSARY +; FST REF_30MHZ ; NECESSARY +; % + + INIT_API_BUS ; SET UART RATE AND CLEAR FLAGS/PTRS + + IN A,TIMSK + ORI A,8 ; ENABLE INTERRUPT ON T1 INPUT CAPTURE + OUT TIMSK,A + +; WEIGHING ONLY % + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A +; % + + ; START FOREGROUND TASK + SEI + +; LDFL D,SIGNON ; SEND SIGNON MESSAGE +; LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E +; RCALL SNDSTR + +LOOP: ; MAIN PROGRAM + ; IF THE INTERRUPT ALREADY CAME, + ; THROW AWAY THE DATA AND WAIT FOR A NEW ONE + CBR FLAGS,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) + FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD + LDI F,AVESTD + RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST + FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST INTGMS ; INTGMS=0 + RCALL LDS_A_STATUS + CBR A,1<LDER) GET RANGE COUNT + LDI ZL,RANGE1*2 ; POINT TO FIRST RANGE BOUNDARY +RNGE: RCALL CPE_FA ; COMPARE FA WITH BOUNDARY + BRCS GOTRNG + ADIW ZL,4 ; POINT TO NEXT RNG + DEC E + BRNE RNGE + SBIW ZL,4 ; POINT BACK TO PREVIOUS RESOLUTION +GOTRNG: RCALL LDE_FA ; GET DISPLAY RESOLUTION FOR THIS RANGE + FST DSPRES + +; STABILIZE DISPLAYED WEIGHT USING HYSTERESIS +STAB: FLD F0 + MOV F,FA2 ; SAVE SIGN BIT + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + FST F2 + RCALL FIX_FA ; TRUNCATE TO 3 BYTE INTEGER + RCALL LD3 ; CONVERT BACK TO FP FORMAT + FST F0 ; INTEGER PART + FLD F2 + FSB F0 ; FA = FRACTIONAL PART + FCPF HSTRSL + BRCS STB2 ; FRACTION < HSTRSL, ROUND DOWN + FCPF HSTRSH + BRCC STB1 ; FRACTION >= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE + FML DSPRES ; DISPLAY RESOLUTION + ; % + FST DSPGMS + +STB5: ;LDS A,MODE ; IF NOT WEIGHING MODE + ;SBRS A,DSPGMS_FLG + ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS + + LDI E,CYC_MIN*2/3 + RCALL TX_WAIT_EMPTY + BRCS FMT + RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE + +FMT: RCALL LDS_A_STATUS + SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? + RJMP SKIP_SN + + CBR A,1<=0 + BRPL FMT2 ; THEN CONTINUE +; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) + INC E ; INC " -LO-" COUNTER (STARTUP) + CPI E,CYC_START+8 ; IF STARTUP E + ;RCALL SNDSTR + ;LDI A,'0' + ;RCALL TX_WAIT + ;RJMP DSP8 + ; % + RJMP DSP7 +FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" + BRCS FMT3 + LDI E,CYC_START ; THEN STARTUP=CYC_START + STS STARTUP,E +FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX + BRCS FMT4 + SBR F,1< E + LDFL D,FMAT0 ; " 0.000" + ADIW ZL,2 +DSP2: CP F,D + BRCC DSP4 +DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 + BREQ DSP8 ; WHEN ALL DONE + CPI D,4 + BRNE DSP2 + DEC F ; TO COMPENSATE FOR EXTRA DEC C + RJMP DSP3 ; DO DECIMAL PT +DSP4: + ; FOR TENTHS OF GRAMS % + ;INC F + ; % + RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +DSP5: DEC F + BREQ DSP8 + CPI F,4 + ; FOR TENTHS OF GRAMS % + ;CPI F,5 + ; % + BRNE DSP6 + LDI A,'.' + RCALL TX_WAIT + DEC F +DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + RJMP DSP5 +DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E + RCALL SNDSTR +DSP8: +; ASCII STABILITY INDICATION FOR TESTING % +; LDI A,' ' +; RCALL TX_WAIT +; RCALL LDS_A_STATUS +; ANDI A,1< 1 SECOND ? +; BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION +; +; FSBF K33M +; FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE +; +; SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RJMP STS_FA ; AND SAVE + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % + INC FA3 ; CHECK FOR NAN + BRNE SND0 + DEC FA3 ; TO COMPLY WITH IEEE754 +SND0: DEC FA3 + ROL FA2 ; CONVERT TO IEEE754 + ROR FA3 + ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % + LDS B,MODE_CYCLE + AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + +; WEIGHING ONLY % + LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E + RCALL TX_WAIT_EMPTY + BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM +; % + +SNDFPX: +; CHARACTERIZE ONLY % +; SBRS FLAGS,SNDDAT +; RET +; CPI A,$80 +; LDI A,$0A +; BRNE SEPOK +; LDI A,$0D +;SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % + LDI A,$1B + RCALL TX_WAIT + MOV A,F ; INDICATE WHICH DATA IS BEING SENT + RCALL TX_WAIT +;SND_FA: + LDI XL,FA ; LOAD TX BUFFER + LDI D,4 +SND1: LD A,X+ + RCALL TX_WAIT ; LS BYTE FIRST + DEC D + BRNE SND1 + RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -16 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION > +5 + BRLO CORRECTION_OK +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_DOLLAR +; LDI A,'$' +; RCALL TX_CHAR +;SKIP_DOLLAR: +; POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + + CLI ; 17MAY01 + LDS G,TMP_PHASE ; START TEMPERATURE MEASUREMENT % + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT TO SYNCHRONISE SUBSEQUENT INT0 + BRNE TMP0 + + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT + IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA:LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA:LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +;SNDEXP: +; PUSH A ; SEPARATOR +; RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +;EXP5: FCPF KR0001 ; IF N<.0001 +; BRCC EXP6 +; FMLF K100K ; THEN N=N*100K +; SUBI F,5 ; E=E-5 +; RJMP EXP5 +;EXP6: FCPF K1 ; IF N<1 +; BRCC EXP7 +; FMLF K10 ; THEN N=N*10 +; SUBI F,1 ; E=E-1 +; RJMP EXP6 +;EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 +; RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +; LDI A,'.' +; RCALL TX_WAIT +; LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +;EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; DEC E +; BRNE EXP8 +; LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY +; RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION +; LDI A,'0' +; RCALL TX_WAIT +; LDI A,'E' ; NOW FOR THE EXPONENT +; RCALL TX_WAIT +; LDI A,'+' ; SEND SIGN +; TST F +; BRPL EXP9 +; LDI A,'-' +; NEG F ; ABS(E) +;EXP9: RCALL TX_WAIT +; LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +;EXP10: INC A +; SUBI F,10 +; BRPL EXP10 +; RCALL TX_WAIT +; LDI A,'0'+10 ; NOW LS DIGIT +; ADD A,F +; RCALL TX_WAIT +; POP A +; RCALL TX_WAIT ; SEPARATOR +;EXP11: FLD F0 ; AND RESTORE FA +; RET +; +;EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 +; LDI A,' ' ; SEND SIGN (SPACE FOR +) +; TST FA2 +; BRPL EXP1 +; LDI A,'-' +;EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +;EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT + ;;FMLF K_1 ; LET'S BE SAFE ;; LET'S NOT +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS +EXP4: RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1< 6 + ; < 210 ELSE OVERFLOW FOR FREQ < 27KHZ + +.EQU CYC_ZERO =16 ; INITIAL ZEROING COUNT +.EQU CYC_START =32 ; INITIAL SMOOTHING COUNT + + ; BITS IN RANGE +.EQU RNG =$0F ; RANGE BITS 0-3 +.EQU RND =6 ; ROUND UP (FOR HYSTERESIS) +.EQU SGN =7 ; SIGN (FOR HYSTERESIS) + ; SGN MUST BE BIT 7 FOR EOR INSTRUCTION + + ; BITS IN STATUS +.EQU OUCHFLG =0 ; OVERLOAD +.EQU LOWFLG =1 ; UNDERLOAD +.EQU UNSTBL =2 ; UNSTABLE +.EQU VSTBL =3 ; VERY STABLE +.EQU ZROFLG =4 ; DISPLAY SHOWS ZERO +.EQU TRYZRO =5 ; TRYING TO SET ZERO +.EQU SEND_SN =6 ; TRYING TO SEND S/N MESSAGE +.EQU SEND_SPAN =7 ; TRYING TO SEND SPAN MESSAGE + + ; BITS IN FLAGS +.EQU SNDDAT =0 ; SEND CHARACTERIZE DATA +.EQU ESC =1 ; SET AFTER RECEIVING ESC +.EQU ESCM =2 ; SET AFTER RECEIVING ESC M +.EQU BOMB =3 ; SET DURING TILT MEASUREMENT +.EQU NEWDAT =4 ; NEW SCALE DATA AVAILABLE +.EQU DIR =5 ; DIRECTION OF CHANGE IN WGT +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + + ; BITS IN MODE +.EQU ABSGMS_FLG =0 ; ABSOLUTE WEIGHT IN FP FORMAT +.EQU ZROGMS_FLG =1 ; ZERO REGISTER IN FP FORMAT +.EQU TMPDEG_FLG =2 ; TEMPERATURE (DEGREES) IN FP FORMAT +.EQU TLTBUB_FLG =3 ; TILT BUBBLE POSITION IN INT FORMAT +.EQU WGTFRQ_FLG =4 ; WEIGHT FREQUENCY IN FP FORMAT +.EQU TMPFRQ_FLG =5 ; TEMPERATURE FREQUENCY IN FP FORMAT +.EQU TLRFRQ_FLG =6 ; TILT LEFT/RIGHT IN FP FORMAT +.EQU TFBFRQ_FLG =7 ; TILT FRONT/BACK IN FP FORMAT + +.DEF FC0 =R0 ; AUXILLIARY FP ACCUMULATOR +.DEF FC1 =R1 +.DEF FC2 =R2 + +.EQU FB =$03 +.DEF FB0 =R3 ; ARGUMENT FP ACCUMULATOR +.DEF FB1 =R4 +.DEF FB2 =R5 +.DEF FB3 =R6 + +.EQU FA =$07 +.DEF FA0 =R7 ; PRINCIPAL FP ACCUMULATOR +.DEF FA1 =R8 +.DEF FA2 =R9 +.DEF FA3 =R10 + +.DEF CYC_0 =R11 +.DEF CYC_1 =R12 + +.DEF WT_0 =R13 ; RUNNING COUNT FOR 16 WEIGHT CYCLES +.DEF WT_1 =R14 ; TIMER1 INPUT CAPTURE LOW +.DEF WT_2 =R15 ; TIMER1 INPUT CAPTURE HIGH + +.DEF A =R17 ; GLOBAL REGISTERS +.DEF B =R18 +.DEF D =R19 +.DEF E =R20 +.DEF F =R21 + +.DEF SR =R22 ; SECONDARY REGISTER SET +.DEF G =R23 +.DEF H =R24 +.DEF I =R25 +.DEF J =R27 ; XH +.DEF K =R29 ; YH + +.DEF FLAGS =R16 ; MUST BE REGISTER, FOR ATOMIC ACCESS + +.DSEG +.ORG RAM + +STARTUP: .BYTE 1 ; SMOOTHING COUNT FOR INITIAL STARTUP +F3: +TLTL_BUF: .BYTE 2 ; DATA OUTPUT BUFFERS +TLTR_BUF: .BYTE 2 +F4: +TLTF_BUF: .BYTE 2 +TLTB_BUF: .BYTE 2 +WGT: .BYTE 3 ; ACCUMULATOR FOR 64 GROUPS OF 16 +TMP: .BYTE 3 ; ACCUMULATOR FOR 256 TEMPERATURE +TLTL: .BYTE 2 ; ACCUMULATOR FOR 64 TILT CYCLES (TLT0) +TLTR: .BYTE 2 +TLTF: .BYTE 2 ; (TLT1) +TLTB: .BYTE 2 +DTMP: .BYTE 2 ; DIFFERENCE COUNT FOR CURRENT TEMP CYC +WGTLST: .BYTE 3 ; VALUE OF ADDITION TO WGT ON LAST CYC +TL: .BYTE 4 ; AVERAGED TLTLR +TF: .BYTE 4 ; AVERAGED TLTFB +TMPFRQ: .BYTE 4 ; TEMPERATURE FREQUENCY CYCLES/30MHZ +GMS: .BYTE 4 +LSTGMS: .BYTE 4 +LSTDEV: .BYTE 4 +AVEGMS: .BYTE 4 +AVESTD: .BYTE 4 +INTGMS: .BYTE 4 +COUNT: .BYTE 4 + +F0: .BYTE 4 ; FLOATING POINT REGISTERS +F1: .BYTE 4 +F2: .BYTE 4 +RANGE: .BYTE 1 +STATUS: .BYTE 1 +MODE: .BYTE 1 +MODE_CYCLE: .BYTE 1 ; WEIGHING ONLY +;WGTFRQ: .BYTE 4 ; CHARACTERIZE ONLY +;REF_30MHZ: .BYTE 4 ; CHARACTERIZE ONLY +TMP_PHASE: .BYTE 1 ; CAREFUL +DSPGMS: .BYTE 4 +ZROGMS: .BYTE 4 +DSPRES: .BYTE 4 + +API_REMAIN: .BYTE 1 +RX_PTR: .BYTE 1 +RX_COUNT: .BYTE 1 +RX_BUF: .BYTE RX_SIZE +TX_PTR: .BYTE 1 +TX_COUNT: .BYTE 1 +TX_BUF: .BYTE TX_SIZE ; CAREFUL - COULD BE CLOBBERED BY STACK + +.ESEG +.ORG $000 +VOID: .DB $00,$00 ; DON'T USE ADDR $000 +;EEMODE: .DB $00,$00 ; SEND ASCII WEIGHT DATA ONLY + +;SPAN: .DB $00,$00,$80,$3F ; 1.0000000E+00 SPAN FOR MELB/DELAWARE +SPAN: .DB $1B,$BA,$7F,$3F ; 0.9989335E+00 SPAN FOR JSY/NLD +;SPAN: .DB $6C,$21,$80,$3F ; 1.0010200E+00 SPAN FOR QATAR + +;CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +;CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +;CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +RANGES: .DB $04,$00 ; OIML APO30 +RANGE1: .DB $00,$40,$1C,$45 ; 2500 + .DB $00,$00,$80,$3F ; 1 + .DB $00,$40,$9C,$45 ; 5000 + .DB $00,$00,$A0,$40 ; 5 + .DB $00,$40,$1C,$46 ; 10000 + .DB $00,$00,$20,$41 ; 10 +RNGMAX: .DB $00,$D8,$EA,$46 ; 30060 + .DB $00,$00,$A0,$41 ; 20 + +.CSEG + + .ORG 0 + RJMP RESET_ENTRY + + .ORG INT0ADDR + RJMP TMP_INT ; INT0 HANDLER FOR TEMPERATURE MEASUREMENT + + .ORG ICP1ADDR + RJMP WGT_INT ; TIMER1 CAPTURE HANDLER + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER + +.INCLUDE "PRM.INC" ; LOAD CELL CHARACTERIZE PARAMETERS + +TLT2: .DB $C7,$75,$41,$AF ;-1.759509E-10 TILT LINEARISATION PARAMETERS +TLT1: .DB $25,$7E,$0B,$35 ; 5.196510E-07 +TLT0: .DB $04,$31,$E3,$39 ; 4.333333E-04 + +TICKS: .DB $AE,$11,$8D,$45 ; 4.514210E+03 = 4096*33.06306M/30M + +HSTRSL: .DB $33,$33,$B3,$3E ; 3.500000E-01 = (0.5-0.15) +HSTRSH: .DB $66,$66,$26,$3F ; 6.500000E-01 = (0.5+0.15) + +CNFHYS: .DB $00,$00,$A0,$41 ; 2.000000E+01 = 3/.15 +HYSCNF: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 = .3/3 +QUANT: .DB $CD,$CC,$4C,$3E ; 2.000000E-01 + +;K_1: .DB $00,$00,$80,$BF ;-1.000000E+00 +;K_R5: .DB $00,$00,$00,$BF ;-5.000000E-01 +KR0001: .DB $17,$B7,$D1,$38 ; 1.000000E-04 +KR005: .DB $0A,$D7,$A3,$3B ; 5.000000E-03 COULD PERHAPS USE KR0001 INSTEAD +KR1: .DB $CD,$CC,$CC,$3D ; 1.000000E-01 +KR3: .DB $9A,$99,$99,$3E ; 3.000000E-01 COULD PERHAPS ELIMINATE THIS +KR5: .DB $00,$00,$00,$3F ; 5.000000E-01 +;K0: .DB $00,$00 ; 0.000000E+00 DON'T MOVE! +K1: .DB $00,$00,$80,$3F ; 1.000000E+00 ! +;K2: .DB $00,$00,$00,$40 ; 2.000000E+00 +K3: .DB $00,$00,$40,$40 ; 3.000000E+00 +K4: .DB $00,$00,$80,$40 ; 4.000000E+00 +K10: .DB $00,$00,$20,$41 ; 1.000000E+01 +K16: .DB $00,$00,$80,$41 ; 1.600000E+01 +K20: .DB $00,$00,$A0,$41 ; 2.000000E+01 +K30: .DB $00,$00,$F0,$41 ; 3.000000E+01 +K64: .DB $00,$00,$80,$42 ; 6.400000E+01 +;K100: .DB $00,$00,$C8,$42 ; 1.000000E+02 +;K256: .DB $00,$00,$80,$43 ; 2.560000E+02 +K228: .DB $39,$8E,$63,$43 ; 2.275556E+02 = 256*16/18 REVISED 17MAY01 +K400: .DB $00,$00,$C8,$43 ; 4.000000E+02 +K450: .DB $00,$00,$E1,$43 ; 4.500000E+02 SHOULD PUT ZERO RANGE IN EEPROM +;K1450: .DB $00,$40,$B5,$44 ; 1.450000E+03 +;K10K: .DB $00,$40,$1C,$46 ; 1.000000E+04 +; CHARACTERIZE ONLY % +;K100K: .DB $00,$50,$C3,$47 ; 1.000000E+05 +;K30M: .DB $C0,$E1,$E4,$4B ; 3.000000E+07 +;K33M: .DB $00,$20,$FD,$4B ; 3.317760E+07 +; % + +; PUT THIS IN EEPROM: +;SIGNON: .DB 3,0 ; MUST HAVE EVEN NUMBER OF CHARS +; .DB "LC" +; .DB $0D,$0A +FMAT0: .DB 6,0 + .DB " 0.000" +FMAT1: .DB 6,0 + .DB "-OUCH " +FMAT2: .DB 6,0 + .DB " -LO- " +;FMAT3: .DB 6,0 +; .DB "HELLO " +;FMAT4: .DB 6,0 +; .DB "Error " +FMAT5: .DB 6,0 + .DB " " +FMAT6: .DB 2,0 + .DB $0D,$0A +;FMAT6: .DB 3,0 +; .DB $20,$0D,$0A,0 + +;------------------------------------------------------------------------------ + +RESET_ENTRY: +; ATmega8: + OUTI SPL,LOW(RAMEND) ; INIT STACK POINTER + OUTI SPH,HIGH(RAMEND) +; OUTI SPL,RAMEND ; INIT STACK POINTER + OUTI ACSR,1< E +; RCALL SNDSTR + +LOOP: ; MAIN PROGRAM + ; IF THE INTERRUPT ALREADY CAME, + ; THROW AWAY THE DATA AND WAIT FOR A NEW ONE + CBR FLAGS,1< QUANT) + FST F0 ; ELSE STD=ABS(DEV) (APPROX STD DEV) + + ; SET AVERAGING PERIOD +AV1: FLD COUNT ; IF STD/AVESTD > CNT/(CNT+1) + FML AVESTD ; (STILL TOO NOISY) + FST F1 + FLD COUNT + FADF K1 + FST F2 + FML F0 + FCP F1 + BRCS AV2 + FLD F2 ; THEN INCR CNT (EXTEND AVERAGE) + FST COUNT +AV2: FLD AVESTD ; MAXCNT=(AVESTD/DSPRES)*(CONF/HYST) + FDV DSPRES + FMLF CNFHYS + FST F1 + FCP COUNT ; IF CNT > MAXCNT + BRCC AV3 ; (UNTIL STD DEV < HYST) + RCALL LDS_A_STATUS ; THEN VERY STABLE=1 + SBR A,1< MAXCNT + BRCC AV4 + FLD F1 ; THEN CNT=MAXCNT + FST COUNT + + ; AVERAGE THE DEVIATION +AV4: FLD COUNT ; NN=CNT (WEIGHTING FOR AVESTD) + FST F1 + FLD F0 ; IF STD*3 < AVESTD (VERY QUIET) + FMLF K3 + FCP AVESTD + BRCC AV5 + FLD F1 ; THEN IF NN>10 THEN NN=10 + FCPF K10 ; (ADAPT LOWER QUICKLY) + BRCS AV5 + FLDF K10 + FST F1 ; NN +AV5: FLD F0 ; STD + LDI F,AVESTD + RCALL SMOOTH_FP ; AVESTD=(STD+AVESTD*(NN-1))/NN + FLD COUNT ; IF AVESTD < CNT*DSPRES*HYST + FML DSPRES ; (NO DISPLAY FLICKER) + FMLF HYSCNF + FCP AVESTD + BRCS AV6 + RCALL LDS_A_STATUS ; THEN UNSTABLE=0 (STABLE) + CBR A,1<64 (JUMP CONDITION) + FCPF K64 + BRCS AV13 + FLDF K1 ; THEN CNT=1 + FST COUNT +; FLDF K0 + FCLR ; 17MAY01 + FST INTGMS ; INTGMS=0 + RCALL LDS_A_STATUS + CBR A,1<LDER) GET RANGE COUNT + LDI ZL,RANGE1*2 ; POINT TO FIRST RANGE BOUNDARY +RNGE: RCALL CPE_FA ; COMPARE FA WITH BOUNDARY + BRCS GOTRNG + ADIW ZL,4 ; POINT TO NEXT RNG + DEC E + BRNE RNGE + SBIW ZL,4 ; POINT BACK TO PREVIOUS RESOLUTION +GOTRNG: RCALL LDE_FA ; GET DISPLAY RESOLUTION FOR THIS RANGE + FST DSPRES + +; STABILIZE DISPLAYED WEIGHT USING HYSTERESIS +STAB: FLD F0 + MOV F,FA2 ; SAVE SIGN BIT + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + FST F2 + RCALL FIX_FA ; TRUNCATE TO 3 BYTE INTEGER + RCALL LD3 ; CONVERT BACK TO FP FORMAT + FST F0 ; INTEGER PART + FLD F2 + FSB F0 ; FA = FRACTIONAL PART + FCPF HSTRSL + BRCS STB2 ; FRACTION < HSTRSL, ROUND DOWN + FCPF HSTRSH + BRCC STB1 ; FRACTION >= HSTRSH, ROUND UP + + LDS A,RANGE ; PREVIOUS RANGE, RND, SGN + MOV B,A + EOR B,F ; COMPARE WITH CURRENT SIGN (BIT 7) + BRMI STB2 ; JUST CHANGED SIGN, ROUND DOWN + ANDI A,RNG ; PREVIOUS RANGE + CP A,E ; COMPARE WITH CURRENT RANGE + BRCS STB1 ; JUST GONE TO LOWER RANGE, ROUND UP + BRNE STB2 ; JUST GONE TO HIGHER RANGE, ROUND DOWN + + FLD DSPGMS ; RECALCULATE VALUE FROM LAST TIME + LDI A,$7F + AND FA2,A ; ABS + ; FOR TENTHS OF GRAMS % + ;FDVF KR1 + ; ELSE + FDV DSPRES ; DISPLAY RESOLUTION + ; % + LDS A,RANGE ; PREVIOUS STATE + SBRS A,RND ; IF ROUNDED UP LAST TIME + RJMP STB0 + FSBF K1 ; THEN DECREMENT +STB0: FST F2 ; CORRESPONDING VALUE FROM LAST TIME + FCP F0 + BRCS STB2 ; GONE TO HIGHER VALUE, ROUND DOWN + FLD F0 + FCP F2 + BRCS STB1 ; GONE TO LOWER VALUE, ROUND UP + RJMP STB5 ; ELSE RETAIN EXISTING DSPGMS + +STB1: FLD F0 ; ROUND UPWARDS + FADF K1 + SBR E,1<0 + BREQ STB4 + BLD FA2,7 ; THEN RESTORE SIGN +STB4: BLD E,SGN ; SUPERIMPOSE ON CURRENT RANGE + STS RANGE,E ; SAVE CURRENT RANGE, RND, SGN + ; FOR TENTHS OF GRAMS % + ;FMLF KR1 + ; ELSE + FML DSPRES ; DISPLAY RESOLUTION + ; % + FST DSPGMS + +STB5: ;LDS A,MODE ; IF NOT WEIGHING MODE + ;SBRS A,DSPGMS_FLG + ;RJMP DSP9 ; THEN SKIP OUTPUT IN GRAMS + + LDI E,CYC_MIN*2/3 + RCALL TX_WAIT_EMPTY + BRCS FMT + RJMP DSP9 ; NO TX_BUFFER TO SEND ITEM THIS CYCLE + +FMT: RCALL LDS_A_STATUS + SBRS A,SEND_SN ; NEED TO SEND S/N MESSAGE ? + RJMP SKIP_SN + + CBR A,1<=0 + BRPL FMT2 ; THEN CONTINUE +; FSBF KR005 ; ELIMINATE TRUNCATION ERROR (- VALUES) + INC E ; INC " -LO-" COUNTER (STARTUP) + CPI E,CYC_START+8 ; IF STARTUP E + ;RCALL SNDSTR + ;LDI A,'0' + ;RCALL TX_WAIT + ;RJMP DSP8 + ; % + RJMP DSP7 +FMT1: SBR F,1<CYC_START ' CLEAR " -LO-" + BRCS FMT3 + LDI E,CYC_START ; THEN STARTUP=CYC_START + STS STARTUP,E +FMT3: FCPE RNGMAX ; IF DSPGMS>RNGMAX + BRCS FMT4 + SBR F,1< E + LDFL D,FMAT0 ; " 0.000" + ADIW ZL,2 +DSP2: CP F,D + BRCC DSP4 +DSP3: RCALL STR1 ; GET NEXT CHARACTER FROM FMAT0 + BREQ DSP8 ; WHEN ALL DONE + CPI D,4 + BRNE DSP2 + DEC F ; TO COMPENSATE FOR EXTRA DEC C + RJMP DSP3 ; DO DECIMAL PT +DSP4: + ; FOR TENTHS OF GRAMS % + ;INC F + ; % + RCALL DGT0 ; CONVERT TO ASCII & SEND FIRST DIGIT +DSP5: DEC F + BREQ DSP8 + CPI F,4 + ; FOR TENTHS OF GRAMS % + ;CPI F,5 + ; % + BRNE DSP6 + LDI A,'.' + RCALL TX_WAIT + DEC F +DSP6: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT + RJMP DSP5 +DSP7: ;LDI E,CYC_MIN-10 ; TIMEOUT IS WHEN CYC_1 => E + RCALL SNDSTR +DSP8: +; ASCII STABILITY INDICATION FOR TESTING % +; LDI A,' ' +; RCALL TX_WAIT +; RCALL LDS_A_STATUS +; ANDI A,1< 1 SECOND ? +; BRLO LOOP_END ; NO, CONTINUE CURRENT INTEGRATION +; +; FSBF K33M +; FST REF_30MHZ ; WRAP ELAPSED TIME FOR NEW CYCLE +; +; SBR FLAGS,1<AVERAGE + TST A ; IF N=0 NOTE: CLOBBERS F0, F1 + BREQ SMTH0 ; THEN DO NOTHING + FST F0 ; SAVE CURRENT DATA + MOV FA0,A ; CONVERT N + CLR FA1 + CLR FA2 + RCALL LD3_FA ; TO FP FORMAT + FST F1 ; AND SAVE + FLD F0 ; RETRIEVE CURRENT DATA +SMOOTH_FP: ; ENTRY POINT WITH F1=N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL SUB_FA + FDV F1 ; N + MOV YL,F ; POINT TO EXISTING AVERAGE + RCALL ADD_FA + MOV YL,F ; POINT TO EXISTING AVERAGE + RJMP STS_FA ; AND SAVE + +LIN_TLT: + RCALL LDS2_FA ; CONVERT 2 BYTE TILT COUNT TO FP + MOV F,YL ; TEMP SAVE + FST F0 ; TLTL + MOV YL,F + RCALL LDS2_FA ; CONVERT OPPOSING TILT COUNT TO FP + FDV F2 + FMLF K16 + FST F1 ; TLTR + FML F1 ; TLTR^2 + FST F3 + FLD F0 + FDV F2 + FMLF K16 + FST F0 ; TLTL + FML F0 ; TLTL^2 + FSB F3 ; TLTL^2-TLTR^2 + FMLF TLT2 + FST F3 + FLD F1 + FSB F0 ; TLTR-TLTL + FMLF TLT1 + FSB F3 + FADF TLT0 +SNDFP2: RET + +SNDFP: +; WEIGHING ONLY % + INC FA3 ; CHECK FOR NAN + BRNE SND0 + DEC FA3 ; TO COMPLY WITH IEEE754 +SND0: DEC FA3 + ROL FA2 ; CONVERT TO IEEE754 + ROR FA3 + ROR FA2 +; % + + TST A + BREQ SNDFPX ; ITEM MUST ALWAYS BE SENT + +SNDFPE: LDS B,MODE ; SEND DIAGNOSTIC DATA + AND A,B ; MODE BIT FOR THIS DATA ITEM SET? +; WEIGHING ONLY % + LDS B,MODE_CYCLE + AND A,B ; ROUND ROBIN UP TO THIS DATA ITEM YET? +; % + BREQ SNDFP2 ; DO NOT SEND THIS DATA ITEM THIS CYCLE + +; WEIGHING ONLY % + LDI E,0 ; TIMEOUT IS WHEN CYC_1 => E + RCALL TX_WAIT_EMPTY + BRCC SNDFP2 ; NO TX_BUFFER SPACE TO SEND ITEM +; % + +SNDFPX: +; CHARACTERIZE ONLY % +; SBRS FLAGS,SNDDAT +; RET +; CPI A,$80 +; LDI A,$0A +; BRNE SEPOK +; LDI A,$0D +;SEPOK: RJMP SNDEXP +; % + +; WEIGHING ONLY % + LDI A,$1B + RCALL TX_WAIT + MOV A,F ; INDICATE WHICH DATA IS BEING SENT + RCALL TX_WAIT +;SND_FA: + LDI XL,FA ; LOAD TX BUFFER +; ATmega8: + CLR XH + LDI D,4 +SND1: LD A,X+ + RCALL TX_WAIT ; LS BYTE FIRST + DEC D + BRNE SND1 + RET +; % + +; ----------------------------------------------------------------------------- + +PROCESS_ESC: + SBRC FLAGS,ESCM + RJMP PROCESS_ESC_M1 + + CPI A,'#' + BREQ PROCESS_ESC_HASH + CPI A,'M' + BREQ PROCESS_ESC_M0 +; CPI A,'S' +; BREQ PROCESS_ESC_S + CPI A,'Z' + BREQ PROCESS_ESC_Z + +PROCESS_ESC_DONE: + CBR FLAGS,1< H|I|J + ADC I,I + ADC J,J + ADD H,G + ADC I,K + CLR G + ADC J,G + + MOV G,I + MOV K,J + LSR K + ROR G + + ; ALLOW +/-128 COUNTS OF ERROR DUE TO XTAL TOLERANCES (-60 TYP) + + POP G ; RETRIEVE HC590 DIFFERENCE COUNT + SUB G,H ; CALCULATE AMOUNT TO ADJUST H|I|J +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_COUNT +; MOV A,G +; RCALL TX_CHAR +;SKIP_COUNT: +; POP A + LDS K,STARTUP ; CHANGED 26MAR01 TO ALLOW FOR + TST K ; NEW BATCH OF 11MHZ XTALS + BREQ CORRECTION_OK + CPI G,-48 ; ASSUME NORMAL CORRECTION > -16 + BRSH CORRECTION_OK + CPI G,16 ; OR CORRECTION > +5 + BRLO CORRECTION_OK +; PUSH A +; LDS A,TX_COUNT +; CPI A,TX_SIZE +; BRSH SKIP_DOLLAR +; LDI A,'$' +; RCALL TX_CHAR +;SKIP_DOLLAR: +; POP A + SUB WT_0,G + LDI G,-12 ; BUT TYPICALLY -12 + ADD WT_0,G +CORRECTION_OK: + LDI K,0 + TST G + BRPL SIGN_EXTEND + LDI K,$FF ; IF NEG +SIGN_EXTEND: + ADD H,G + ADC I,K + ADC J,K ; ADD INTO H|I|J + + LDS G,WGTLST ; TEST DIRECTION OF CHANGE + CP H,G ; DIFFERENCE NOW IN H|I|J + LDS G,WGTLST+1 + CPC I,G + LDS G,WGTLST+2 + CPC J,G + + STS WGTLST,H ; AND SAVE SAMPLE FOR NEXT CYCLE + STS WGTLST+1,I + STS WGTLST+2,J + +; ATmega8: + POP J + POP K + + CLI ; 17MAY01 + LDS G,TMP_PHASE ; START TEMPERATURE MEASUREMENT % + INC G +TMP0: RJMP TMP1 +TMP1: DEC G ; WAIT TO SYNCHRONISE SUBSEQUENT INT0 + BRNE TMP0 + + SBI PORTD,2 ; ENGAGE PULLUP SO TEMP OUTPUT WILL GO + SBI DDRD,2 ; HIGH, AND SET BIT 2 TO OUTPUT + +; ATmega8: + IN G,GICR ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) +; IN G,GIMSK ; IF PREV INT0 DIDN'T HAPPEN (STILL ON) + SBRC G,INT0 + RCALL TMP_INT00 ; THEN WE MUST PROCESS ANYWAY + CBI DDRD,2 ; SET BIT 2 TO INPUT TO START DISCHARGE + CBI PORTD,2 ; AND REMOVE PULLUP + IN G,TCNT1L ; GET STARTING COUNT FROM TIMER1 + STS DTMP,G + IN G,TCNT1H ; NOW HIGH BYTE + STS DTMP+1,G + SEI + + MOV G,CYC_1 ; CYCLE COUNT, NOT INCLUDING CURRENT + INC CYC_1 ; INCLUDE CURRENT CYCLE + BRCS DEC0 ; NOW LOOK AT CHANGE + CBR FLAGS,1<=24 THEN RETURN + CPI A,24 ; IF EXPONENT<0 + BRCC GO_MIN_FA ; THEN FA=0 + RCALL SGN_FA ; SAVE SIGN & INSERT IMPLICIT BIT +FIX2: LSR FA2 ; SHIFT MANTISSA RIGHT + ROR FA1 + ROR FA0 + DEC A ; (24-EXPONENT) BITS + BRNE FIX2 +FIX0: RET + +GO_MIN_FA: + RJMP MIN_FA + +; REMOVED TO SAVE FLASH % +;CHSS: LDD B,Y+2 ; CHANGE SIGN OF SRAM ARGUMENT +; LDI A,$80 +; EOR B,A ; TOGGLE SIGN BIT +; STD Y+2,B ; AND SAVE +; RET +; % + +LDS2_FA: +; ATmega8: + CLR YH + LD FA0,Y+ ; LOAD FA WITH 2 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + CLR FA2 + RJMP LD3_FA +LDS3_FA: +; ATmega8: + CLR YH + LD FA0,Y+ ; LOAD FA WITH 3 BYTE POSITIVE INTEGER + LD FA1,Y+ ; Y POINTS TO SOURCE + LD FA2,Y+ +LD3_FA: CLT ; SET SIGN POSITIVE +LD3: LDI A,23+BIAS ; SET EXPONENT AND FALL INTO NORMALIZE + MOV FA3,A + +NRM_FA: MOV A,FA0 ; NORMALIZE FA REGISTER + OR A,FA1 + OR A,FA2 + BREQ NRM3 ; IF ZERO THEN CLEAR EXPONENT & EXIT +NRM0: TST FA2 +NRM1: BRMI NRM2 ; IF MANTISSA DENORMALIZED + DEC FA3 ; THEN ADJUST EXPONENT + BREQ MIN_FA ; IF UNDERFLOW THEN RETURN MIN + RCALL LSL_FA ; ELSE SHIFT MANTISSA LEFT + RJMP NRM1 +NRM2: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT + RET +NRM3: CLR FA3 + RET + +;------------------------------------------------------------------------------ + +ADD_FA: RCALL LDS_FB ; ADD SRAM ARGUMENT TO FA REGISTER +ADD0: TST FB3 ; IF FB=0 + BREQ RET0 ; THEN DO NOTHING + TST FA3 ; IF FA=0 + BREQ SWP_FA ; THEN SWAP FA,FB AND EXIT + MOV D,FB2 ; GET SIGN OF ARGUMENT + EOR D,FA2 ; BIT 7 SET IF SIGNS DIFFERENT + MOV A,FA3 + SUB A,FB3 ; IF FA EXPONENT < ARG EXPONENT + BRCC ADD1 + NEG A ; THEN (EXP DIFF)=-(EXP DIFF) + RCALL SWP_FA ; SWAP FA,FB +ADD1: CPI A,24 ; IF EXP DIFFERENCE >= 24 + BRCC RET0 ; THEN DO NOTHING + RCALL SGN_FA ; ELSE SAVE SIGN & INSERT IMPLICIT BIT + OR FB2,B ; INSERT IMPLICIT BIT IN FB ALSO + TST A +ADD2: BREQ ADD3 + LSR FB2 ; SHIFT FB RIGHT TO ALIGN + ROR FB1 + ROR FB0 + DEC A + RJMP ADD2 +ADD3: TST D ; IF SIGNS SAME + BRMI ADD5 + RCALL ADD_FB ; THEN FA=FA+FB + BRCC ADD4 ; IF CARRY + RCALL ROR_FA ; THEN RIGHT SHIFT + INC FA3 ; INC EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +ADD4: BLD FA2,7 ; ELSE OVERLAY WITH SIGN BIT +RET0: RET +ADD5: RCALL SUB_FB ; ELSE FA=FA-FB + BREQ NRM3 ; IF ZERO THEN CLEAR EXP & EXIT + BRCC NRM0 ; IF CARRY + RCALL COM_FA ; THEN FA=-FA + LDI A,-1 + SUB FA0,A + SBC FA1,A + SBC FA2,A + BLD A,7 ; TOGGLE SIGN BIT + COM A + BST A,7 + RJMP NRM0 ; NORMALIZE + +ADDE_FA:RCALL LDE_FB ; ADD EEPROM CONSTANT TO FA REGISTER + RJMP ADD0 + +ADDF_FA:RCALL LDF_FB ; ADD FLASH CONSTANT TO FA REGISTER + RJMP ADD0 + +SUB_FA: RCALL LDS_FB ; SUBTRACT SRAM ARGUMENT FROM FA REG +SUB0: LDI A,$80 + EOR FB2,A ; TOGGLE SIGN + RJMP ADD0 + +SUBE_FA:RCALL LDE_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +SUBF_FA:RCALL LDF_FB ; SUBTRACT FLASH CONSTANT FROM FP REG + RJMP SUB0 + +;------------------------------------------------------------------------------ + +; VARIOUS SUBROUTINES + +MIN_FA: CLR FA3 ; FA=0 +CLR_FA: CLR FA2 ; CLEAR FA + CLR FA1 + CLR FA0 + RET + +SWP_FA: RCALL SWP0 ; SWAP CONTENTS OF FA & FB + RCALL SWP1 +SWP0: EOR FA0,FB0 + EOR FA1,FB1 + EOR FA2,FB2 + EOR FA3,FB3 + RET +SWP1: EOR FB0,FA0 + EOR FB1,FA1 + EOR FB2,FA2 + EOR FB3,FA3 + RET + +OUTRNG: BRPL MIN_FA ; UNDERFLOW +; RJMP MAX_FA ; OVERFLOW + +; UNDERFLOW BY A LITTLE: $80 + $FF = $7F POSITIVE +; -128 - 1 = -129 +; UNDERFLOW BY A LOT: $80 + $80 = $00 POSITIVE +; -128 - 128 = -256 +; OVERFLOW BY A LITTLE: $7F + $0F = $80 NEGATIVE +; 127 + 1 = 128 +; OVERFLOW BY A LOT: $7F + $7F = $FE NEGATIVE +; 127 + 127 = 254 + +MAX_FA: CLR FA3 ; FA=MAX + COM FA3 + MOV FA2,FA3 + MOV FA1,FA3 + MOV FA0,FA3 + BLD FA2,7 ; SET SIGN + RET + + +;------------------------------------------------------------------------------ + +MUL_FA: RCALL LDS_FB ; MULTIPLY FA REGISTER BY SRAM ARGUMENT +MUL0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + TST FB3 ; IF FB=0 + BREQ MIN_FA ; THEN FA=0 + RCALL SGNS ; PROCESS SIGN OF RESULT & REMOVE BIAS + ADD FA3,FB3 ; ADD EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; ELSE RESTORE BIAS + MOV FC0,FA0 ; FC=FA + MOV FC1,FA1 + MOV FC2,FA2 + RCALL CLR_FA ; FA=0 + CLC + LDI A,24 ; LOOP COUNTER +MUL1: RCALL ROR_FA ; RIGHT SHIFT + LSR FC2 + ROR FC1 + ROR FC0 + BRCC MUL2 + RCALL ADD_FB ; FA=FA+FB +MUL2: DEC A + BRNE MUL1 + BRCC MUL3 ; IF CARRY + RCALL ROR_FA ; THEN NORMALIZE BY 1 BIT + INC FA3 ; ADJUST EXPONENT + BREQ MAX_FA ; IF OVERFLOW RETURN MAX +MUL3: BLD FA2,7 ; ELSE RESTORE SIGN +RET1: RET + +MULE_FA:RCALL LDE_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +MULF_FA:RCALL LDF_FB ; FP MULTIPLY BY FLASH CONSTANT + RJMP MUL0 + +DIV_FA: RCALL LDS_FB ; DIVIDE FA REGISTER BY SRAM ARGUMENT +DIV0: TST FA3 ; IF FA=0 + BREQ RET1 ; THEN DO NOTHING + BST FA2,7 ; GET SIGN OF FA + TST FB3 ; IF FB=0 + BREQ MAX_FA ; THEN RETURN MAX + RCALL SGNS ; PROCESS SIGN OF RESULT + SUB FA3,FB3 ; SUBTRACT EXPONENTS + BRVS OUTRNG ; IF UNDER/OVERFLOW RETURN MIN/MAX + LDI A,BIAS + ADD FA3,A ; RESTORE BIAS + LSR FA2 ; DENORMALIZE SO THAT CARRY IS NOT LOST + ROR FA1 ; DURING SUBTRACTION AND SUBSEQUENT ADD + ROR FA0 + LSR FB2 + ROR FB1 + ROR FB0 + LDI A,24 ; LOOP COUNTER +DIV1: RCALL SUB_FB ; FA=FA-FB + BRCC DIV2 + RCALL ADD_FB ; FA=FA+FB +DIV2: ROL FC0 ; SHIFT CARRY INTO LSB + ROL FC1 + ROL FC2 + RCALL LSL_FA + DEC A + BRNE DIV1 + MOV FA0,FC0 ; FA=FC + MOV FA1,FC1 + MOV FA2,FC2 + RCALL COM_FA ; SINCE CARRY WAS WRONG SENSE + RJMP NRM0 ; NORMALIZE & RESTORE SIGN + +DIVE_FA:RCALL LDE_FB ; DIVIDE FA REGISTER BY EEPROM CONSTANT + RJMP DIV0 + +DIVF_FA:RCALL LDF_FB ; DIVIDE FA REGISTER BY FLASH CONSTANT + RJMP DIV0 + +CP_FA: RCALL LDS_FB ; COMPARE FA WITH SRAM ARGUMENT +CP0: MOV A,FA3 ; FIRST CHECK FOR SPECIAL ZERO CASE + OR A,FB3 + BREQ CP6 ; FA=0, FB=0 + MOV A,FA2 ; NOW, IF SIGNS DIFFERENT + EOR A,FB2 + BRMI CP3 ; THEN ANSWER DETERMINED BY THE SIGNS + BST FA2,7 ; ELSE SAVE SIGN FOR LATER + SUB FB3,FA3 ; TEST EXPONENT WITHOUT CORRUPTING FA + BRCS CP2 ; IF EXP FA > EXP FB + BRNE CP1 ; IF EXP FA < EXP FB + SUB FB0,FA0 ; IF EXPS EQUAL, MUST TEST MANTISSA + SBC FB1,FA1 + SBC FB2,FA2 + BRCS CP2 + BREQ CP6 +CP1: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP4 ; THEN CLEAR CARRY + RJMP CP5 ; ELSE SET CARRY +CP2: BLD A,7 ; RETRIEVE SIGN + TST A ; IF BOTH NEGATIVE + BRMI CP5 ; THEN SET CARRY + RJMP CP4 ; ELSE CLEAR CARRY +CP3: TST FA2 ; CHECK SIGN + BRMI CP5 +CP4: CLC ; FA > FB + CLZ + RET +CP5: SEC ; FA < FB + CLZ +CP6: RET ; FA = FB + +CPF_FA: RCALL LDF_FB ; COMPARE FA WITH FLASH CONSTANT + RJMP CP0 + +CPE_FA: RCALL LDE_FB ; COMPARE FA WITH EEPROM CONSTANT + RJMP CP0 + +;------------------------------------------------------------------------------ + +SNDSTR: ADIW ZL,2 ; OUTPUT STRING FROM FLASH +STR0: RCALL STR1 ; RETRIEVE MESSAGE + BRNE STR0 + RET +STR1: LPM ; GET NEXT CHARACTER + MOV A,R0 + RCALL TX_WAIT + ADIW ZL,1 + DEC D + RET + +;------------------------------------------------------------------------------ + +;SNDASC: +; RCALL EXP0 ; SEND IN ASCII FORMAT +; INC F ; DIGITS TO LEFT OF DECIMAL POINT +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +;ASC0: DEC F +; BREQ EXP11 +; RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; RJMP ASC0 + +; CHARACTERIZE ONLY % +;SNDEXP: +; PUSH A ; SEPARATOR +; RCALL EXP0 ; SEND EXPONENTIAL FORMAT +N.NNNNNNE+^^ +;EXP5: FCPF KR0001 ; IF N<.0001 +; BRCC EXP6 +; FMLF K100K ; THEN N=N*100K +; SUBI F,5 ; E=E-5 +; RJMP EXP5 +;EXP6: FCPF K1 ; IF N<1 +; BRCC EXP7 +; FMLF K10 ; THEN N=N*10 +; SUBI F,1 ; E=E-1 +; RJMP EXP6 +;EXP7: FADF TLT1 ; BY MEREST COINCIDENCE CLOSE TO 5.0E-7 +; RCALL EXP3 ; IN CASE WE JUMPED UP TO 10.000000 +; RCALL DGT0 ; CONVERT TO ASCII & SEND DIGIT +; LDI A,'.' +; RCALL TX_WAIT +; LDI E,6 ; 7 SIGNIFICANT DIGITS IN ALL +;EXP8: RCALL DGTN ; *10 THEN CONVERT TO ASCII, SEND DIGIT +; DEC E +; BRNE EXP8 +; LDI A,'0' ; 2 TRAILING ZEROS FOR COMPATIBILITY +; RCALL TX_WAIT ; WITH PREVIOUS CHARACTERIZE VERSION +; LDI A,'0' +; RCALL TX_WAIT +; LDI A,'E' ; NOW FOR THE EXPONENT +; RCALL TX_WAIT +; LDI A,'+' ; SEND SIGN +; TST F +; BRPL EXP9 +; LDI A,'-' +; NEG F ; ABS(E) +;EXP9: RCALL TX_WAIT +; LDI A,'0'-1 ; CONVERT MS DIGIT TO ASCII +;EXP10: INC A +; SUBI F,10 +; BRPL EXP10 +; RCALL TX_WAIT +; LDI A,'0'+10 ; NOW LS DIGIT +; ADD A,F +; RCALL TX_WAIT +; POP A +; RCALL TX_WAIT ; SEPARATOR +;EXP11: FLD F0 ; AND RESTORE FA +; RET +; +;EXP0: FST F0 ; ADJUST EXPONENT FOR ABS(N)>1 +; LDI A,' ' ; SEND SIGN (SPACE FOR +) +; TST FA2 +; BRPL EXP1 +; LDI A,'-' +;EXP1: RCALL TX_WAIT +; % + +DIGN: LDI A,$7F + AND FA2,A ; ABS(N) + CLR F ; HOLDS ADJUSTED EXPONENT FOR 110K + BRCS EXP3 + FMLF KR0001 ; THEN N=N/10K + ADDI F,4 ; E=E+4 + RJMP EXP2 +EXP3: FCPF K10 ; IF N>10 + BRCS EXP4 + FMLF KR1 ; THEN N=N/10 + SUBI F,-1 ; E=E+1 + RJMP EXP3 +;EXP4: RET + +DGTN: FSB F1 ; N=(N-I)*10 + FMLF K10 ; REALLY N=(I-N)*10, SIGN UNIMPORTANT + ;;FMLF K_1 ; LET'S BE SAFE ;; LET'S NOT +DGT0: FST F1 ; N (ADJUSTED) + RCALL FIX_FA ; I=INT(N) + MOV B,FA0 ; SAVE LS DIGIT + RCALL LD3 ; CONVERT BACK TO FP FORMAT + LDI A,'0' + ADD A,B ; A = LS DIGIT IN ASCII + RJMP TX_WAIT + +;------------------------------------------------------------------------------ + +LDS_A_STATUS: + LDS A,STATUS +EXP4: RET + +SET_TRYZRO: + LDS A,STATUS ; THEN SET ZERO + SBR A,1< LOW + + SBRS D,2 + RJMP TP_SEARCH + + ; RSW FALLING EDGE DETECTED + SBIC PORTC,4 ; MOTOR ON? + RJMP TP_FEED ; YES, GO AND PRINT + + ; WE STOPPED THE MOTOR, MONITOR RSW WHILE IT SLOWS DOWN + CLR TP_COUNT ; REPLENISH COUNT OF TP EDGES TO RSW + + TST FEEDS + BREQ TP_SEARCH + DEC FEEDS ; DECREMENT FEEDS TO MINIMUM OF 0 + RJMP TP_SEARCH + +TP_COAST: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + MOV D,TP_COUNT + CPI D,3 + BRSH TP_PAPER_SKIP ; ON LAST OR 2ND LAST TP EDGE, + + SBIC PORTB,2 + RJMP TP_PAPER_SKIP ; WITH TP GENERATOR IN KNOWN STATE, + +;T0_PAPER_SETUP: + LDI A,0 + OUT GIMSK,A ; DISABLE INT 1 INTERRUPTS + + ;CBI PORTB,2 ; SET TP GENERATOR TO KNOWN STATE + SBI PORTB,1 ; MUST BE OPPOSITE TO PORTB,2 STATE + SBI DDRB,1 ; D1 = HIGH / LOW TO LIGHT LED + + LDI D,-3 + OUT TCNT0,D ; TEST PAPER IN 2 * 0.1 MS = 0.2 MS + +TP_PAPER_SKIP: + DEC TP_COUNT ; COUNT EDGES/2 TO PRINTABLE AREA-4 + BRNE TP_COAST + +TP_FEED: + ;SBRS STATUS,PAPER ; PAPER IN? + ;RJMP TP_BRAKE_NOW ; NO, STOP PRINTING IMMEDIATELY + + MOV D,FLAGS + ANDI D,(1< 3 INTERNAL FEEDS + CPI D,1 + BRSH TP_FEED_SLOW ; COAST IF => 1 INTERNAL FEED + + SBRC FLAGS,IMAGE + RJMP TP_PRINT_IMAGE ; PRINT IF GRAPHICS WAITING + + RJMP TP_PRINT_TEXT ; OTHERWISE ASSUME TEXT IS WAITING + +TP_BRAKE: + MOV D,FEEDS + CPI D,3+FEED_INITIAL + BRSH TP_FEED_FAST ; TRIGGER IF => 3+n INTERNAL FEEDS + CPI D,1+FEED_INITIAL + BRSH TP_FEED_SLOW ; COAST IF => 1+n INTERNAL FEED + +TP_BRAKE_NOW: +; TST FEEDS ; JUST MISSED RSW -> 0, COMPENSATE +; BREQ TP_BRAKE_NOW_CONT +; DEC FEEDS ; DECREMENT TO MINIMUM OF 0 +;TP_BRAKE_NOW_CONT: + CLR FEEDS + RJMP TP_KILL ; GO AND KILL MOTOR + +TP_FEED_SLOW: + DEC FEEDS + + LDI D,150 + MOV TP_COUNT,D + RJMP TP_COAST + +TP_FEED_FAST: ; AT PRINTABLE AREA-2 + SUBI D,3 + MOV FEEDS,D + + SBI PORTB,0 ; APPLY TRIGGER SOLENOID + + LDI D,9 + MOV TP_COUNT,D +TP_TRIGGERING: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + DEC TP_COUNT + BRNE TP_TRIGGERING + + CBI PORTB,0 ; CLEAR TRIGGER SOLENOID + + LDI D,150-9 + MOV TP_COUNT,D + RJMP TP_COAST + +; ----------------------------------------------------------------------------- +; TP INTERRUPT ROUTINES FOR TEXT PRINTING + +; TP_TEXT_START DOES NOT RE-ENABLE ACCESS TO FEEDS. +; FEEDS IS USED AS A COUNTER FOR DESCENDER PRINTING, +; SO WE RELY ON TIMER_COPY TO RESET NOFEED, AFTER THE +; LINE HAS BEEN CHECKED FOR DESCENDERS AND IS ABOUT TO +; BE CLOBBERED BY NEW DATA. + +TP_PRINT_TEXT: + LDI D,2 + MOV TEXT_MASK,D + MOV FEEDS,SPACING ; SET UP STANDARD FEED AFTER TEXT LINE + +TP_PRINT_TEXT_START: + LDI E,0 ; CURRENT CHARACTER FOR PRINT HEAD, 0-4 + +TP_PRINT_TEXT_CHAR: + LDI F,0 ; CURRENT PIXEL FOR CHARACTER, 0-5 + +TP_PRINT_TEXT_PIXEL: + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-30 ; E = CURRENT CHARACTER + 30 + RCALL TP_TEXT_FIRE2 + SUBI E,15 ; E = CURRENT CHARACTER + 15 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH0 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-35 ; E = CURRENT CHARACTER + 35 + RCALL TP_TEXT_FIRE1 + SUBI E,15 ; E = CURRENT CHARACTER + 20 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 5 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH1 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-20 ; E = CURRENT CHARACTER + 25 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 10 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH2 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + SUBI E,10 ; E = CURRENT CHARACTER + + INC F ; NEXT PIXEL FOR CHARACTER + CPI F,6 ; GONE PAST LAST PIXEL FOR CHARACTER? + BRLO TP_PRINT_TEXT_PIXEL ; REPEAT UNLESS ALL PIXELS DONE + + INC E ; NEXT CHARACTER FOR PRINT HEAD + CPI E,5 ; GONE PAST LAST CHAR FOR PRINT HEAD? + BRLO TP_PRINT_TEXT_CHAR ; REPEAT UNLESS ALL CHARACTERS DONE + + CLR H + RCALL TP_LATCH0 ; CLEAR D4-D7 AND C0-C3 + + SBRC TEXT_MASK,7 ; LAST DOT LINE FOR CHARACTER LINE? + CBR FLAGS,1< CHARACTER SET SLICE IN FLASH + + LPM ; R0 = CORRECT VERTICAL SLICE OF CHAR + RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + LSL ZL ; ZL = CHARACTER DEFINITION * 8 + SUB ZL,D ; ZL = CHARACTER DEFINITION * 7 + ;CLR ZH + + SUBI ZL,-(EE_COUNT*2+2) ; PAST CRC, COUNT, AND CHARACTER CODE + ADD ZL,F ; ZL = BASE + CHAR * 6 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN R0,EEDR ; GET LATCHED DATA BYTE + RET + +; ----------------------------------------------------------------------------- +; FOREGROUND ROUTINES FOR API BUS + +RX_WAIT: + SBRC FLAGS,BOMB + RJMP TEXT_RESET + + SBRS STATUS,NOTIFY + RJMP RX_WAIT_TEST + + MOV A,TX_COUNT + CPI A,TX_SIZE ;-2 + BRSH RX_WAIT_TEST + + CLR NOTIFY_COUNT ; 6.5536 SECONDS TO NEXT NOTIFICATION + CBR STATUS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + +; ----------------------------------------------------------------------------- + +TEXT_RESET: + ; ENTRY POINT FROM RX_WAIT + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + +TEXT_RECEIVE: + ; NEXT LINE STARTS WITH RECEIVED CHAR + CLR CHAR_SAVE + + CLR ABORT_COUNT ; NO NEED TO ABORT ESC SEQUENCE + CBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI XL,$21 + LDI XH,$10 ; X = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,XL + EOR YH,XH +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +WAIT_ADD_FEEDS: + PUSH A + ADD A,FEEDS + POP A + BRCS WAIT_ADD_FEEDS + + ADD FEEDS,A + +MOTOR_START: + ;SBRS STATUS,PAPER + ;RET + + SBIC PORTC,4 + RET + + CBR FLAGS,1< ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$00,$9E,$00,$00,$00 + .DB $00,$0E,$00,$0E,$00,$00 + .DB $28,$FE,$28,$FE,$28,$00 + .DB $4C,$92,$FF,$92,$64,$00 + .DB $46,$26,$10,$C8,$C4,$00 + .DB $6C,$92,$AA,$44,$A0,$00 + .DB $00,$0B,$07,$00,$00,$00 + .DB $00,$38,$44,$82,$00,$00 + .DB $00,$82,$44,$38,$00,$00 + .DB $28,$10,$7C,$10,$28,$00 + .DB $10,$10,$7C,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $10,$10,$10,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $40,$20,$10,$08,$04,$00 + .DB $7C,$A2,$92,$8A,$7C,$00 + .DB $00,$84,$FE,$80,$00,$00 + .DB $84,$C2,$A2,$92,$8C,$00 + .DB $42,$82,$8A,$96,$62,$00 + .DB $30,$28,$24,$FE,$20,$00 + .DB $4E,$8A,$8A,$8A,$72,$00 + .DB $78,$94,$92,$92,$60,$00 + .DB $02,$E2,$12,$0A,$06,$00 + .DB $6C,$92,$92,$92,$6C,$00 + .DB $0C,$92,$92,$52,$3C,$00 + .DB $00,$6C,$6C,$00,$00,$00 + .DB $00,$6C,$EC,$00,$00,$00 + .DB $10,$28,$44,$82,$00,$00 + .DB $28,$28,$28,$28,$28,$00 + .DB $00,$82,$44,$28,$10,$00 + .DB $04,$02,$A2,$12,$0C,$00 + .DB $7C,$82,$BA,$AA,$3C,$00 + .DB $FC,$22,$22,$22,$FC,$00 + .DB $FE,$92,$92,$92,$6C,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $FE,$82,$82,$44,$38,$00 + .DB $FE,$92,$92,$92,$82,$00 + .DB $FE,$12,$12,$12,$02,$00 + .DB $7C,$82,$92,$92,$F4,$00 + .DB $FE,$10,$10,$10,$FE,$00 + .DB $00,$82,$FE,$82,$00,$00 + .DB $40,$80,$82,$7E,$02,$00 + .DB $FE,$10,$28,$44,$82,$00 + .DB $FE,$80,$80,$80,$80,$00 + .DB $FE,$04,$18,$04,$FE,$00 + .DB $FE,$08,$10,$20,$FE,$00 + .DB $7C,$82,$82,$82,$7C,$00 + .DB $FE,$12,$12,$12,$0C,$00 + .DB $7C,$82,$A2,$42,$BC,$00 + .DB $FE,$12,$32,$52,$8C,$00 + .DB $4C,$92,$92,$92,$64,$00 + .DB $02,$02,$FE,$02,$02,$00 + .DB $7E,$80,$80,$80,$7E,$00 + .DB $3E,$40,$80,$40,$3E,$00 + .DB $7E,$80,$70,$80,$7E,$00 + .DB $C6,$28,$10,$28,$C6,$00 + .DB $0E,$10,$E0,$10,$0E,$00 + .DB $C2,$A2,$92,$8A,$86,$00 + .DB $00,$FE,$82,$82,$00,$00 + .DB $04,$08,$10,$20,$40,$00 + .DB $00,$82,$82,$FE,$00,$00 + .DB $08,$04,$02,$04,$08,$00 + .DB $80,$80,$80,$80,$80,$00 + .DB $00,$00,$0E,$0D,$00,$00 + .DB $40,$A8,$A8,$A8,$F0,$00 + .DB $FE,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$88,$88,$88,$FE,$00 + .DB $70,$A8,$A8,$A8,$30,$00 + .DB $08,$08,$FC,$0A,$0A,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $FE,$10,$08,$08,$F0,$00 + .DB $00,$88,$FA,$80,$00,$00 + .DB $00,$00,$08,$FA,$00,$00 + .DB $FE,$20,$50,$88,$00,$00 + .DB $00,$82,$FE,$80,$00,$00 + .DB $F8,$08,$F8,$08,$F0,$00 + .DB $F8,$10,$08,$08,$F0,$00 + .DB $70,$88,$88,$88,$70,$00 + .DB $F8,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $F8,$10,$08,$08,$00,$00 + .DB $90,$A8,$A8,$A8,$48,$00 + .DB $08,$08,$7E,$88,$88,$00 + .DB $78,$80,$80,$40,$F8,$00 + .DB $38,$40,$80,$40,$38,$00 + .DB $78,$80,$60,$80,$78,$00 + .DB $88,$50,$20,$50,$88,$00 + .DB $78,$80,$80,$80,$F8,$00 + .DB $88,$C8,$A8,$98,$88,$00 + .DB $10,$6C,$82,$82,$00,$00 + .DB $00,$00,$EE,$00,$00,$00 + .DB $00,$82,$82,$6C,$10,$00 + .DB $04,$02,$04,$08,$04,$00 + .DB $E0,$90,$88,$90,$E0,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $7A,$80,$80,$40,$FA,$00 + .DB $70,$A8,$AA,$A9,$30,$00 + .DB $40,$AA,$A9,$AA,$F0,$00 + .DB $42,$A8,$A8,$A8,$F2,$00 + .DB $40,$A9,$AA,$A8,$F0,$00 + .DB $40,$AE,$AA,$AE,$F0,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$AA,$A9,$AA,$30,$00 + .DB $72,$A8,$A8,$A8,$32,$00 + .DB $70,$A9,$AA,$A8,$30,$00 + .DB $02,$88,$F8,$80,$02,$00 + .DB $00,$8A,$F9,$82,$00,$00 + .DB $00,$89,$FA,$80,$00,$00 + .DB $F9,$24,$24,$24,$F9,$00 + .DB $F8,$27,$25,$27,$F8,$00 + .DB $F8,$A8,$AA,$A9,$88,$00 + .DB $68,$A8,$F8,$A8,$B0,$00 + .DB $FC,$12,$FE,$92,$92,$00 + .DB $70,$8A,$89,$8A,$70,$00 + .DB $72,$88,$88,$88,$72,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$82,$81,$42,$F8,$00 + .DB $78,$81,$82,$40,$F8,$00 + .DB $7A,$80,$80,$80,$FA,$00 + .DB $79,$84,$84,$84,$79,$00 + .DB $7D,$80,$80,$80,$7D,$00 + .DB $70,$88,$88,$FC,$88,$00 + .DB $90,$7C,$92,$92,$C4,$00 + .DB $52,$54,$F8,$54,$52,$00 + .DB $82,$82,$44,$44,$28,$28 + .DB $10,$10,$28,$54,$54,$28 + .DB $40,$A8,$AA,$A9,$F0,$00 + .DB $00,$8A,$F9,$80,$00,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$80,$82,$41,$F8,$00 + .DB $FA,$11,$0A,$09,$F0,$00 + .DB $FA,$11,$22,$41,$F8,$00 + .DB $90,$AA,$AA,$AA,$BC,$00 + .DB $9C,$A2,$A2,$A2,$9C,$00 + .DB $60,$90,$8A,$80,$40,$00 + .DB $FE,$02,$02,$02,$02,$02 + .DB $02,$02,$02,$02,$02,$FE + .DB $2F,$10,$48,$24,$C0,$00 + .DB $2F,$90,$48,$E4,$00,$00 + .DB $00,$00,$F2,$00,$00,$00 + .DB $FE,$80,$80,$80,$80,$80 + .DB $80,$80,$80,$80,$80,$FE + .DB $00,$80,$00,$00,$80,$00 + .DB $55,$AA,$55,$AA,$55,$AA + .DB $33,$CC,$33,$CC,$33,$CC + .DB $00,$00,$FF,$00,$00,$00 + .DB $10,$10,$FF,$00,$00,$00 + .DB $28,$28,$FF,$00,$00,$00 + .DB $10,$FF,$00,$FF,$00,$00 + .DB $10,$F0,$10,$F0,$00,$00 + .DB $28,$28,$F8,$00,$00,$00 + .DB $28,$EF,$00,$FF,$00,$00 + .DB $00,$FF,$00,$FF,$00,$00 + .DB $28,$E8,$08,$F8,$00,$00 + .DB $28,$2F,$20,$3F,$00,$00 + .DB $10,$1F,$10,$1F,$00,$00 + .DB $28,$28,$3F,$00,$00,$00 + .DB $10,$10,$F0,$00,$00,$00 + .DB $00,$00,$1F,$10,$10,$10 + .DB $10,$10,$1F,$10,$10,$10 + .DB $10,$10,$F0,$10,$10,$10 + .DB $00,$00,$FF,$10,$10,$10 + .DB $10,$10,$10,$10,$10,$10 + .DB $10,$10,$FF,$10,$10,$10 + .DB $00,$00,$FF,$28,$28,$28 + .DB $00,$FF,$00,$FF,$10,$10 + .DB $00,$3F,$20,$2F,$28,$28 + .DB $00,$F8,$08,$E8,$28,$28 + .DB $28,$2F,$20,$2F,$28,$28 + .DB $28,$E8,$08,$E8,$28,$28 + .DB $00,$FF,$00,$EF,$28,$28 + .DB $28,$28,$28,$28,$28,$28 + .DB $28,$EF,$00,$EF,$28,$28 + .DB $28,$28,$2F,$28,$28,$28 + .DB $10,$1F,$10,$1F,$10,$10 + .DB $28,$28,$E8,$28,$28,$28 + .DB $10,$F0,$10,$F0,$10,$10 + .DB $00,$1F,$10,$1F,$10,$10 + .DB $00,$00,$3F,$28,$28,$28 + .DB $00,$00,$F8,$28,$28,$28 + .DB $00,$F0,$10,$F0,$10,$10 + .DB $10,$FF,$10,$FF,$10,$10 + .DB $28,$28,$FF,$28,$28,$28 + .DB $10,$10,$1F,$00,$00,$00 + .DB $00,$00,$F0,$10,$10,$10 + .DB $FF,$FF,$FF,$FF,$FF,$FF + .DB $E0,$E0,$E0,$E0,$E0,$E0 + .DB $FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF + .DB $1F,$1F,$1F,$1F,$1F,$1F + .DB $70,$88,$88,$70,$88,$00 + .DB $FC,$02,$92,$92,$6C,$00 + .DB $FE,$02,$02,$02,$06,$00 + .DB $08,$F8,$08,$F8,$08,$00 + .DB $C6,$AA,$92,$82,$C6,$00 + .DB $70,$88,$88,$78,$08,$00 + .DB $00,$F8,$80,$80,$78,$00 + .DB $10,$08,$F0,$08,$00,$00 + .DB $10,$AA,$EE,$AA,$10,$00 + .DB $7C,$92,$92,$92,$7C,$00 + .DB $9C,$E2,$02,$E2,$9C,$00 + .DB $60,$94,$9A,$92,$60,$00 + .DB $70,$88,$70,$88,$70,$00 + .DB $70,$88,$FC,$88,$70,$00 + .DB $38,$54,$92,$92,$00,$00 + .DB $FC,$02,$02,$02,$FC,$00 + .DB $54,$54,$54,$54,$54,$00 + .DB $88,$88,$BE,$88,$88,$00 + .DB $A2,$A2,$94,$94,$88,$00 + .DB $88,$94,$94,$A2,$A2,$00 + .DB $00,$00,$F8,$04,$08,$00 + .DB $40,$80,$7F,$00,$00,$00 + .DB $10,$10,$54,$10,$10,$00 + .DB $48,$24,$48,$24,$00,$00 + .DB $0C,$12,$12,$0C,$00,$00 + .DB $00,$18,$18,$00,$00,$00 + .DB $00,$00,$10,$00,$00,$00 + .DB $20,$40,$FF,$01,$01,$00 + .DB $1F,$02,$01,$1E,$00,$00 + .DB $00,$12,$19,$16,$00,$00 + .DB $00,$38,$38,$38,$00,$00 + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$02,$02,$02,$01,$00 + .DB $01,$02,$02,$01,$00,$00 + .DB $03,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$03,$00 + .DB $00,$00,$02,$03,$02,$00 + .DB $00,$01,$01,$03,$01,$00 + .DB $00,$00,$01,$00,$00,$00 + .DB $00,$00,$00,$01,$00,$00 + .DB $02,$01,$00,$00,$00,$00 + .DB $00,$02,$01,$00,$00,$00 + .DB $00,$00,$02,$01,$00,$00 + .DB $00,$01,$00,$00,$00,$00 + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4106 ; HARDWARE ADDRESS COMMAND + .DW $4204 ; SOFTWARE ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/m192ter.asm b/src/avr/m192ter.asm new file mode 100644 index 00000000..ae477c3c --- /dev/null +++ b/src/avr/m192ter.asm @@ -0,0 +1,1685 @@ +; M192TER.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +;.INCLUDE "API.INC" +.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =6 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ;$11 ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ;$11 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =30 ; 240 / 8 = 30 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =40 ; 240 / 6 = 40 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =5 ; 40 / 8 = 5 TEXT WIDTH FLAGS + +.EQU TIME_EMERGENCY =1000 ; 1000 * 0.1 MS = APPROX 100 MS + +.EQU FEED_INITIAL =2 ; LINES ALLOWED FOR MOTOR SLOWDOWN +.EQU FEED_SPACING =3 ; LINES TO FEED IN BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF TP_COUNT =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF NOTIFY_COUNT =R14 ; COUNTER TO SEND EVERY 6.5536 SECONDS +.DEF ABORT_COUNT =R15 ; COUNTER TO ABORT ESC AFTER 0.1 SECS + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF SR =R23 +.DEF FLAGS =R24 +.DEF STATUS =R25 + +.EQU TX_SIZE =2 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_CHARS+WIDTH_FLAGS +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU RSWSAVE =2 ; SET IF RSW HI, MUST BE BIT POSITION 2 +.EQU IMAGE =3 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =4 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +;.EQU NODESC =5 ; SET BY FG WHILE PRINTING TOP 7 DOTS +;.EQU BIGDESC =6 ; SET BY FG WHILE PRINTING LOWER 2 DOTS +.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY FG JUST PRIOR TO NOTIFICATION +.EQU TP_ERROR =2 ; SET BY BG IF WE HAVE TIMEOUT ON TP +.EQU RSW_ERROR =3 ; SET BY BG IF WE HAVE TIMEOUT ON RSW +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; NODESC + +; FLAG RESET BY FOREGROUND AFTER DESCENDER TRANSLATION, IF DESCENDERS PRESENT. +; FLAG SET BY FOREGROUND AFTER DESCENDERS FINISHED AND BUFFER CLOBBERED. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE, FOR SPECIAL DESCENDER +; PROCESSING. + +; BIGDESC + +; FLAG SET UP BY FOREGROUND DURING DESCENDER TRANSLATION. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE IN COMBINATION WITH +; TEXT_MASK, TO CONTINUE DESCENDER OR REVERT TO FEEDS. + +; NOWFAST + +; FLAG SET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 115200 BPS. +; FLAG RESET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 4800 BPS. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG INT1ADDR + RJMP TP_EDGE ; EXTERNAL INT 1 HANDLER + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','1','9','2',' ' +; .DB 'P','R','I','N','T','E','R',$0D + +; ----------------------------------------------------------------------------- +; TP EDGE INTERRUPT HANDLER + +TP_EDGE: + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + IN SR,SREG ; SAVE FLAGS + + IN D,MCUCR + SBRS D,ISC10 + CBI PORTB,2 ; IF WE WERE LOOKING FOR A FALLING EDGE + SBRC D,ISC10 + SBI PORTB,2 ; IF WE WERE LOOKING FOR A RISING EDGE + LDI G,1< LOW + + SBRS D,2 + RJMP TP_SEARCH + + ; RSW FALLING EDGE DETECTED + SBIC PORTC,4 ; MOTOR ON? + RJMP TP_FEED ; YES, GO AND PRINT + + ; WE STOPPED THE MOTOR, MONITOR RSW WHILE IT SLOWS DOWN + CLR TP_COUNT ; REPLENISH COUNT OF TP EDGES TO RSW + + TST FEEDS + BREQ TP_SEARCH + DEC FEEDS ; DECREMENT FEEDS TO MINIMUM OF 0 + RJMP TP_SEARCH + +TP_COAST: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + MOV D,TP_COUNT + CPI D,3 + BRSH TP_PAPER_SKIP ; ON LAST OR 2ND LAST TP EDGE, + + SBIC PORTB,2 + RJMP TP_PAPER_SKIP ; WITH TP GENERATOR IN KNOWN STATE, + +;T0_PAPER_SETUP: + LDI A,0 + OUT GIMSK,A ; DISABLE INT 1 INTERRUPTS + + ;CBI PORTB,2 ; SET TP GENERATOR TO KNOWN STATE + SBI PORTB,1 ; MUST BE OPPOSITE TO PORTB,2 STATE + SBI DDRB,1 ; D1 = HIGH / LOW TO LIGHT LED + + LDI D,-3 + OUT TCNT0,D ; TEST PAPER IN 2 * 0.1 MS = 0.2 MS + +TP_PAPER_SKIP: + DEC TP_COUNT ; COUNT EDGES/2 TO PRINTABLE AREA-4 + BRNE TP_COAST + +TP_FEED: + ;SBRS STATUS,PAPER ; PAPER IN? + ;RJMP TP_BRAKE_NOW ; NO, STOP PRINTING IMMEDIATELY + + MOV D,FLAGS + ANDI D,(1< 3 INTERNAL FEEDS + CPI D,1 + BRSH TP_FEED_SLOW ; COAST IF => 1 INTERNAL FEED + + SBRC FLAGS,IMAGE + RJMP TP_PRINT_IMAGE ; PRINT IF GRAPHICS WAITING + + RJMP TP_PRINT_TEXT ; OTHERWISE ASSUME TEXT IS WAITING + +TP_BRAKE: + MOV D,FEEDS + CPI D,3+FEED_INITIAL + BRSH TP_FEED_FAST ; TRIGGER IF => 3+n INTERNAL FEEDS + CPI D,1+FEED_INITIAL + BRSH TP_FEED_SLOW ; COAST IF => 1+n INTERNAL FEED + +TP_BRAKE_NOW: +; TST FEEDS ; JUST MISSED RSW -> 0, COMPENSATE +; BREQ TP_BRAKE_NOW_CONT +; DEC FEEDS ; DECREMENT TO MINIMUM OF 0 +;TP_BRAKE_NOW_CONT: + CLR FEEDS + RJMP TP_KILL ; GO AND KILL MOTOR + +TP_FEED_SLOW: + DEC FEEDS + + LDI D,150 + MOV TP_COUNT,D + RJMP TP_COAST + +TP_FEED_FAST: ; AT PRINTABLE AREA-2 + SUBI D,3 + MOV FEEDS,D + + SBI PORTB,0 ; APPLY TRIGGER SOLENOID + + LDI D,9 + MOV TP_COUNT,D +TP_TRIGGERING: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + DEC TP_COUNT + BRNE TP_TRIGGERING + + CBI PORTB,0 ; CLEAR TRIGGER SOLENOID + + LDI D,150-9 + MOV TP_COUNT,D + RJMP TP_COAST + +; ----------------------------------------------------------------------------- +; TP INTERRUPT ROUTINES FOR TEXT PRINTING + +; TP_TEXT_START DOES NOT RE-ENABLE ACCESS TO FEEDS. +; FEEDS IS USED AS A COUNTER FOR DESCENDER PRINTING, +; SO WE RELY ON TIMER_COPY TO RESET NOFEED, AFTER THE +; LINE HAS BEEN CHECKED FOR DESCENDERS AND IS ABOUT TO +; BE CLOBBERED BY NEW DATA. + +TP_PRINT_TEXT: + LDI D,2 + MOV TEXT_MASK,D + MOV FEEDS,SPACING ; SET UP STANDARD FEED AFTER TEXT LINE + +TP_PRINT_TEXT_START: + LDI E,0 ; CURRENT CHARACTER FOR PRINT HEAD, 0-4 + +TP_PRINT_TEXT_CHAR: + LDI F,0 ; CURRENT PIXEL FOR CHARACTER, 0-5 + +TP_PRINT_TEXT_PIXEL: + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-30 ; E = CURRENT CHARACTER + 30 + RCALL TP_TEXT_FIRE2 + SUBI E,15 ; E = CURRENT CHARACTER + 15 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH0 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-35 ; E = CURRENT CHARACTER + 35 + RCALL TP_TEXT_FIRE1 + SUBI E,15 ; E = CURRENT CHARACTER + 20 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 5 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH1 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-20 ; E = CURRENT CHARACTER + 25 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 10 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH2 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + SUBI E,10 ; E = CURRENT CHARACTER + + INC F ; NEXT PIXEL FOR CHARACTER + CPI F,6 ; GONE PAST LAST PIXEL FOR CHARACTER? + BRLO TP_PRINT_TEXT_PIXEL ; REPEAT UNLESS ALL PIXELS DONE + + INC E ; NEXT CHARACTER FOR PRINT HEAD + CPI E,5 ; GONE PAST LAST CHAR FOR PRINT HEAD? + BRLO TP_PRINT_TEXT_CHAR ; REPEAT UNLESS ALL CHARACTERS DONE + + CLR H + RCALL TP_LATCH0 ; CLEAR D4-D7 AND C0-C3 + + SBRC TEXT_MASK,7 ; LAST DOT LINE FOR CHARACTER LINE? + CBR FLAGS,1< CHARACTER SET SLICE IN FLASH + + LPM ; R0 = CORRECT VERTICAL SLICE OF CHAR + RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + LSL ZL ; ZL = CHARACTER DEFINITION * 8 + SUB ZL,D ; ZL = CHARACTER DEFINITION * 7 + ;CLR ZH + + SUBI ZL,-(EE_COUNT*2+2) ; PAST CRC, COUNT, AND CHARACTER CODE + ADD ZL,F ; ZL = BASE + CHAR * 6 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN R0,EEDR ; GET LATCHED DATA BYTE + RET + +; ----------------------------------------------------------------------------- +; FOREGROUND ROUTINES FOR API BUS + +RX_WAIT: + SBRC FLAGS,BOMB + RJMP TEXT_RESET + + SBRS STATUS,NOTIFY + RJMP RX_WAIT_TEST + + MOV A,TX_COUNT + CPI A,TX_SIZE ;-2 + BRSH RX_WAIT_TEST + + CLR NOTIFY_COUNT ; 6.5536 SECONDS TO NEXT NOTIFICATION + CBR STATUS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + +; ----------------------------------------------------------------------------- + +TEXT_RESET: + ; ENTRY POINT FROM RX_WAIT + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + +TEXT_RECEIVE: + ; NEXT LINE STARTS WITH RECEIVED CHAR + CLR CHAR_SAVE + + CLR ABORT_COUNT ; NO NEED TO ABORT ESC SEQUENCE + CBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI XL,$21 + LDI XH,$10 ; X = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,XL + EOR YH,XH +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +WAIT_ADD_FEEDS: + PUSH A + ADD A,FEEDS + POP A + BRCS WAIT_ADD_FEEDS + + ADD FEEDS,A + +MOTOR_START: + ;SBRS STATUS,PAPER + ;RET + + SBIC PORTC,4 + RET + + CBR FLAGS,1< ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$00,$9E,$00,$00,$00 + .DB $00,$0E,$00,$0E,$00,$00 + .DB $28,$FE,$28,$FE,$28,$00 + .DB $4C,$92,$FF,$92,$64,$00 + .DB $46,$26,$10,$C8,$C4,$00 + .DB $6C,$92,$AA,$44,$A0,$00 + .DB $00,$0B,$07,$00,$00,$00 + .DB $00,$38,$44,$82,$00,$00 + .DB $00,$82,$44,$38,$00,$00 + .DB $28,$10,$7C,$10,$28,$00 + .DB $10,$10,$7C,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $10,$10,$10,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $40,$20,$10,$08,$04,$00 + .DB $7C,$A2,$92,$8A,$7C,$00 + .DB $00,$84,$FE,$80,$00,$00 + .DB $84,$C2,$A2,$92,$8C,$00 + .DB $42,$82,$8A,$96,$62,$00 + .DB $30,$28,$24,$FE,$20,$00 + .DB $4E,$8A,$8A,$8A,$72,$00 + .DB $78,$94,$92,$92,$60,$00 + .DB $02,$E2,$12,$0A,$06,$00 + .DB $6C,$92,$92,$92,$6C,$00 + .DB $0C,$92,$92,$52,$3C,$00 + .DB $00,$6C,$6C,$00,$00,$00 + .DB $00,$6C,$EC,$00,$00,$00 + .DB $10,$28,$44,$82,$00,$00 + .DB $28,$28,$28,$28,$28,$00 + .DB $00,$82,$44,$28,$10,$00 + .DB $04,$02,$A2,$12,$0C,$00 + .DB $7C,$82,$BA,$AA,$3C,$00 + .DB $FC,$22,$22,$22,$FC,$00 + .DB $FE,$92,$92,$92,$6C,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $FE,$82,$82,$44,$38,$00 + .DB $FE,$92,$92,$92,$82,$00 + .DB $FE,$12,$12,$12,$02,$00 + .DB $7C,$82,$92,$92,$F4,$00 + .DB $FE,$10,$10,$10,$FE,$00 + .DB $00,$82,$FE,$82,$00,$00 + .DB $40,$80,$82,$7E,$02,$00 + .DB $FE,$10,$28,$44,$82,$00 + .DB $FE,$80,$80,$80,$80,$00 + .DB $FE,$04,$18,$04,$FE,$00 + .DB $FE,$08,$10,$20,$FE,$00 + .DB $7C,$82,$82,$82,$7C,$00 + .DB $FE,$12,$12,$12,$0C,$00 + .DB $7C,$82,$A2,$42,$BC,$00 + .DB $FE,$12,$32,$52,$8C,$00 + .DB $4C,$92,$92,$92,$64,$00 + .DB $02,$02,$FE,$02,$02,$00 + .DB $7E,$80,$80,$80,$7E,$00 + .DB $3E,$40,$80,$40,$3E,$00 + .DB $7E,$80,$70,$80,$7E,$00 + .DB $C6,$28,$10,$28,$C6,$00 + .DB $0E,$10,$E0,$10,$0E,$00 + .DB $C2,$A2,$92,$8A,$86,$00 + .DB $00,$FE,$82,$82,$00,$00 + .DB $04,$08,$10,$20,$40,$00 + .DB $00,$82,$82,$FE,$00,$00 + .DB $08,$04,$02,$04,$08,$00 + .DB $80,$80,$80,$80,$80,$00 + .DB $00,$00,$0E,$0D,$00,$00 + .DB $40,$A8,$A8,$A8,$F0,$00 + .DB $FE,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$88,$88,$88,$FE,$00 + .DB $70,$A8,$A8,$A8,$30,$00 + .DB $08,$08,$FC,$0A,$0A,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $FE,$10,$08,$08,$F0,$00 + .DB $00,$88,$FA,$80,$00,$00 + .DB $00,$00,$08,$FA,$00,$00 + .DB $FE,$20,$50,$88,$00,$00 + .DB $00,$82,$FE,$80,$00,$00 + .DB $F8,$08,$F8,$08,$F0,$00 + .DB $F8,$10,$08,$08,$F0,$00 + .DB $70,$88,$88,$88,$70,$00 + .DB $F8,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $F8,$10,$08,$08,$00,$00 + .DB $90,$A8,$A8,$A8,$48,$00 + .DB $08,$08,$7E,$88,$88,$00 + .DB $78,$80,$80,$40,$F8,$00 + .DB $38,$40,$80,$40,$38,$00 + .DB $78,$80,$60,$80,$78,$00 + .DB $88,$50,$20,$50,$88,$00 + .DB $78,$80,$80,$80,$F8,$00 + .DB $88,$C8,$A8,$98,$88,$00 + .DB $10,$6C,$82,$82,$00,$00 + .DB $00,$00,$EE,$00,$00,$00 + .DB $00,$82,$82,$6C,$10,$00 + .DB $04,$02,$04,$08,$04,$00 + .DB $E0,$90,$88,$90,$E0,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $7A,$80,$80,$40,$FA,$00 + .DB $70,$A8,$AA,$A9,$30,$00 + .DB $40,$AA,$A9,$AA,$F0,$00 + .DB $42,$A8,$A8,$A8,$F2,$00 + .DB $40,$A9,$AA,$A8,$F0,$00 + .DB $40,$AE,$AA,$AE,$F0,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$AA,$A9,$AA,$30,$00 + .DB $72,$A8,$A8,$A8,$32,$00 + .DB $70,$A9,$AA,$A8,$30,$00 + .DB $02,$88,$F8,$80,$02,$00 + .DB $00,$8A,$F9,$82,$00,$00 + .DB $00,$89,$FA,$80,$00,$00 + .DB $F9,$24,$24,$24,$F9,$00 + .DB $F8,$27,$25,$27,$F8,$00 + .DB $F8,$A8,$AA,$A9,$88,$00 + .DB $68,$A8,$F8,$A8,$B0,$00 + .DB $FC,$12,$FE,$92,$92,$00 + .DB $70,$8A,$89,$8A,$70,$00 + .DB $72,$88,$88,$88,$72,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$82,$81,$42,$F8,$00 + .DB $78,$81,$82,$40,$F8,$00 + .DB $7A,$80,$80,$80,$FA,$00 + .DB $79,$84,$84,$84,$79,$00 + .DB $7D,$80,$80,$80,$7D,$00 + .DB $70,$88,$88,$FC,$88,$00 + .DB $90,$7C,$92,$92,$C4,$00 + .DB $52,$54,$F8,$54,$52,$00 + .DB $82,$82,$44,$44,$28,$28 + .DB $10,$10,$28,$54,$54,$28 + .DB $40,$A8,$AA,$A9,$F0,$00 + .DB $00,$8A,$F9,$80,$00,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$80,$82,$41,$F8,$00 + .DB $FA,$11,$0A,$09,$F0,$00 + .DB $FA,$11,$22,$41,$F8,$00 + .DB $90,$AA,$AA,$AA,$BC,$00 + .DB $9C,$A2,$A2,$A2,$9C,$00 + .DB $60,$90,$8A,$80,$40,$00 + .DB $FE,$02,$02,$02,$02,$02 + .DB $02,$02,$02,$02,$02,$FE + .DB $2F,$10,$48,$24,$C0,$00 + .DB $2F,$90,$48,$E4,$00,$00 + .DB $00,$00,$F2,$00,$00,$00 + .DB $FE,$80,$80,$80,$80,$80 + .DB $80,$80,$80,$80,$80,$FE + .DB $00,$80,$00,$00,$80,$00 + .DB $55,$AA,$55,$AA,$55,$AA + .DB $33,$CC,$33,$CC,$33,$CC + .DB $00,$00,$FF,$00,$00,$00 + .DB $10,$10,$FF,$00,$00,$00 + .DB $28,$28,$FF,$00,$00,$00 + .DB $10,$FF,$00,$FF,$00,$00 + .DB $10,$F0,$10,$F0,$00,$00 + .DB $28,$28,$F8,$00,$00,$00 + .DB $28,$EF,$00,$FF,$00,$00 + .DB $00,$FF,$00,$FF,$00,$00 + .DB $28,$E8,$08,$F8,$00,$00 + .DB $28,$2F,$20,$3F,$00,$00 + .DB $10,$1F,$10,$1F,$00,$00 + .DB $28,$28,$3F,$00,$00,$00 + .DB $10,$10,$F0,$00,$00,$00 + .DB $00,$00,$1F,$10,$10,$10 + .DB $10,$10,$1F,$10,$10,$10 + .DB $10,$10,$F0,$10,$10,$10 + .DB $00,$00,$FF,$10,$10,$10 + .DB $10,$10,$10,$10,$10,$10 + .DB $10,$10,$FF,$10,$10,$10 + .DB $00,$00,$FF,$28,$28,$28 + .DB $00,$FF,$00,$FF,$10,$10 + .DB $00,$3F,$20,$2F,$28,$28 + .DB $00,$F8,$08,$E8,$28,$28 + .DB $28,$2F,$20,$2F,$28,$28 + .DB $28,$E8,$08,$E8,$28,$28 + .DB $00,$FF,$00,$EF,$28,$28 + .DB $28,$28,$28,$28,$28,$28 + .DB $28,$EF,$00,$EF,$28,$28 + .DB $28,$28,$2F,$28,$28,$28 + .DB $10,$1F,$10,$1F,$10,$10 + .DB $28,$28,$E8,$28,$28,$28 + .DB $10,$F0,$10,$F0,$10,$10 + .DB $00,$1F,$10,$1F,$10,$10 + .DB $00,$00,$3F,$28,$28,$28 + .DB $00,$00,$F8,$28,$28,$28 + .DB $00,$F0,$10,$F0,$10,$10 + .DB $10,$FF,$10,$FF,$10,$10 + .DB $28,$28,$FF,$28,$28,$28 + .DB $10,$10,$1F,$00,$00,$00 + .DB $00,$00,$F0,$10,$10,$10 + .DB $FF,$FF,$FF,$FF,$FF,$FF + .DB $E0,$E0,$E0,$E0,$E0,$E0 + .DB $FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF + .DB $1F,$1F,$1F,$1F,$1F,$1F + .DB $70,$88,$88,$70,$88,$00 + .DB $FC,$02,$92,$92,$6C,$00 + .DB $FE,$02,$02,$02,$06,$00 + .DB $08,$F8,$08,$F8,$08,$00 + .DB $C6,$AA,$92,$82,$C6,$00 + .DB $70,$88,$88,$78,$08,$00 + .DB $00,$F8,$80,$80,$78,$00 + .DB $10,$08,$F0,$08,$00,$00 + .DB $10,$AA,$EE,$AA,$10,$00 + .DB $7C,$92,$92,$92,$7C,$00 + .DB $9C,$E2,$02,$E2,$9C,$00 + .DB $60,$94,$9A,$92,$60,$00 + .DB $70,$88,$70,$88,$70,$00 + .DB $70,$88,$FC,$88,$70,$00 + .DB $38,$54,$92,$92,$00,$00 + .DB $FC,$02,$02,$02,$FC,$00 + .DB $54,$54,$54,$54,$54,$00 + .DB $88,$88,$BE,$88,$88,$00 + .DB $A2,$A2,$94,$94,$88,$00 + .DB $88,$94,$94,$A2,$A2,$00 + .DB $00,$00,$F8,$04,$08,$00 + .DB $40,$80,$7F,$00,$00,$00 + .DB $10,$10,$54,$10,$10,$00 + .DB $48,$24,$48,$24,$00,$00 + .DB $0C,$12,$12,$0C,$00,$00 + .DB $00,$18,$18,$00,$00,$00 + .DB $00,$00,$10,$00,$00,$00 + .DB $20,$40,$FF,$01,$01,$00 + .DB $1F,$02,$01,$1E,$00,$00 + .DB $00,$12,$19,$16,$00,$00 + .DB $00,$38,$38,$38,$00,$00 + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$02,$02,$02,$01,$00 + .DB $01,$02,$02,$01,$00,$00 + .DB $03,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$03,$00 + .DB $00,$00,$02,$03,$02,$00 + .DB $00,$01,$01,$03,$01,$00 + .DB $00,$00,$01,$00,$00,$00 + .DB $00,$00,$00,$01,$00,$00 + .DB $02,$01,$00,$00,$00,$00 + .DB $00,$02,$01,$00,$00,$00 + .DB $00,$00,$02,$01,$00,$00 + .DB $00,$01,$00,$00,$00,$00 + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4107 ; HARDWARE ADDRESS COMMAND + .DW $4206 ; SOFTWARE ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/m192v0.asm b/src/avr/m192v0.asm new file mode 100644 index 00000000..904f1f21 --- /dev/null +++ b/src/avr/m192v0.asm @@ -0,0 +1,1685 @@ +; M192V0.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =6 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ;$11 ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ;$11 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =30 ; 240 / 8 = 30 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =40 ; 240 / 6 = 40 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =5 ; 40 / 8 = 5 TEXT WIDTH FLAGS + +.EQU TIME_EMERGENCY =1000 ; 1000 * 0.1 MS = APPROX 100 MS + +.EQU FEED_INITIAL =2 ; LINES ALLOWED FOR MOTOR SLOWDOWN +.EQU FEED_SPACING =3 ; LINES TO FEED IN BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF TP_COUNT =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF NOTIFY_COUNT =R14 ; COUNTER TO SEND EVERY 6.5536 SECONDS +.DEF ABORT_COUNT =R15 ; COUNTER TO ABORT ESC AFTER 0.1 SECS + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF SR =R23 +.DEF FLAGS =R24 +.DEF STATUS =R25 + +.EQU TX_SIZE =2 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_CHARS+WIDTH_FLAGS +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU RSWSAVE =2 ; SET IF RSW HI, MUST BE BIT POSITION 2 +.EQU IMAGE =3 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =4 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +;.EQU NODESC =5 ; SET BY FG WHILE PRINTING TOP 7 DOTS +;.EQU BIGDESC =6 ; SET BY FG WHILE PRINTING LOWER 2 DOTS +.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY FG JUST PRIOR TO NOTIFICATION +.EQU TP_ERROR =2 ; SET BY BG IF WE HAVE TIMEOUT ON TP +.EQU RSW_ERROR =3 ; SET BY BG IF WE HAVE TIMEOUT ON RSW +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; NODESC + +; FLAG RESET BY FOREGROUND AFTER DESCENDER TRANSLATION, IF DESCENDERS PRESENT. +; FLAG SET BY FOREGROUND AFTER DESCENDERS FINISHED AND BUFFER CLOBBERED. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE, FOR SPECIAL DESCENDER +; PROCESSING. + +; BIGDESC + +; FLAG SET UP BY FOREGROUND DURING DESCENDER TRANSLATION. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE IN COMBINATION WITH +; TEXT_MASK, TO CONTINUE DESCENDER OR REVERT TO FEEDS. + +; NOWFAST + +; FLAG SET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 115200 BPS. +; FLAG RESET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 4800 BPS. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG INT1ADDR + RJMP TP_EDGE ; EXTERNAL INT 1 HANDLER + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','1','9','2',' ' +; .DB 'P','R','I','N','T','E','R',$0D + +; ----------------------------------------------------------------------------- +; TP EDGE INTERRUPT HANDLER + +TP_EDGE: + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + IN SR,SREG ; SAVE FLAGS + + IN D,MCUCR + SBRS D,ISC10 + CBI PORTB,2 ; IF WE WERE LOOKING FOR A FALLING EDGE + SBRC D,ISC10 + SBI PORTB,2 ; IF WE WERE LOOKING FOR A RISING EDGE + LDI G,1< LOW + + SBRS D,2 + RJMP TP_SEARCH + + ; RSW FALLING EDGE DETECTED + SBIC PORTC,4 ; MOTOR ON? + RJMP TP_FEED ; YES, GO AND PRINT + + ; WE STOPPED THE MOTOR, MONITOR RSW WHILE IT SLOWS DOWN + CLR TP_COUNT ; REPLENISH COUNT OF TP EDGES TO RSW + + TST FEEDS + BREQ TP_SEARCH + DEC FEEDS ; DECREMENT FEEDS TO MINIMUM OF 0 + RJMP TP_SEARCH + +TP_COAST: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + MOV D,TP_COUNT + CPI D,3 + BRSH TP_PAPER_SKIP ; ON LAST OR 2ND LAST TP EDGE, + + SBIC PORTB,2 + RJMP TP_PAPER_SKIP ; WITH TP GENERATOR IN KNOWN STATE, + +;T0_PAPER_SETUP: + LDI A,0 + OUT GIMSK,A ; DISABLE INT 1 INTERRUPTS + + ;CBI PORTB,2 ; SET TP GENERATOR TO KNOWN STATE + SBI PORTB,1 ; MUST BE OPPOSITE TO PORTB,2 STATE + SBI DDRB,1 ; D1 = HIGH / LOW TO LIGHT LED + + LDI D,-3 + OUT TCNT0,D ; TEST PAPER IN 2 * 0.1 MS = 0.2 MS + +TP_PAPER_SKIP: + DEC TP_COUNT ; COUNT EDGES/2 TO PRINTABLE AREA-4 + BRNE TP_COAST + +TP_FEED: + ;SBRS STATUS,PAPER ; PAPER IN? + ;RJMP TP_BRAKE_NOW ; NO, STOP PRINTING IMMEDIATELY + + MOV D,FLAGS + ANDI D,(1< 3 INTERNAL FEEDS + CPI D,1 + BRSH TP_FEED_SLOW ; COAST IF => 1 INTERNAL FEED + + SBRC FLAGS,IMAGE + RJMP TP_PRINT_IMAGE ; PRINT IF GRAPHICS WAITING + + RJMP TP_PRINT_TEXT ; OTHERWISE ASSUME TEXT IS WAITING + +TP_BRAKE: + MOV D,FEEDS + CPI D,3+FEED_INITIAL + BRSH TP_FEED_FAST ; TRIGGER IF => 3+n INTERNAL FEEDS + CPI D,1+FEED_INITIAL + BRSH TP_FEED_SLOW ; COAST IF => 1+n INTERNAL FEED + +TP_BRAKE_NOW: +; TST FEEDS ; JUST MISSED RSW -> 0, COMPENSATE +; BREQ TP_BRAKE_NOW_CONT +; DEC FEEDS ; DECREMENT TO MINIMUM OF 0 +;TP_BRAKE_NOW_CONT: + CLR FEEDS + RJMP TP_KILL ; GO AND KILL MOTOR + +TP_FEED_SLOW: + DEC FEEDS + + LDI D,150 + MOV TP_COUNT,D + RJMP TP_COAST + +TP_FEED_FAST: ; AT PRINTABLE AREA-2 + SUBI D,3 + MOV FEEDS,D + + SBI PORTB,0 ; APPLY TRIGGER SOLENOID + + LDI D,9 + MOV TP_COUNT,D +TP_TRIGGERING: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + DEC TP_COUNT + BRNE TP_TRIGGERING + + CBI PORTB,0 ; CLEAR TRIGGER SOLENOID + + LDI D,150-9 + MOV TP_COUNT,D + RJMP TP_COAST + +; ----------------------------------------------------------------------------- +; TP INTERRUPT ROUTINES FOR TEXT PRINTING + +; TP_TEXT_START DOES NOT RE-ENABLE ACCESS TO FEEDS. +; FEEDS IS USED AS A COUNTER FOR DESCENDER PRINTING, +; SO WE RELY ON TIMER_COPY TO RESET NOFEED, AFTER THE +; LINE HAS BEEN CHECKED FOR DESCENDERS AND IS ABOUT TO +; BE CLOBBERED BY NEW DATA. + +TP_PRINT_TEXT: + LDI D,2 + MOV TEXT_MASK,D + MOV FEEDS,SPACING ; SET UP STANDARD FEED AFTER TEXT LINE + +TP_PRINT_TEXT_START: + LDI E,0 ; CURRENT CHARACTER FOR PRINT HEAD, 0-4 + +TP_PRINT_TEXT_CHAR: + LDI F,0 ; CURRENT PIXEL FOR CHARACTER, 0-5 + +TP_PRINT_TEXT_PIXEL: + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-30 ; E = CURRENT CHARACTER + 30 + RCALL TP_TEXT_FIRE2 + SUBI E,15 ; E = CURRENT CHARACTER + 15 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH0 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-35 ; E = CURRENT CHARACTER + 35 + RCALL TP_TEXT_FIRE1 + SUBI E,15 ; E = CURRENT CHARACTER + 20 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 5 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH1 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-20 ; E = CURRENT CHARACTER + 25 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 10 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH2 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + SUBI E,10 ; E = CURRENT CHARACTER + + INC F ; NEXT PIXEL FOR CHARACTER + CPI F,6 ; GONE PAST LAST PIXEL FOR CHARACTER? + BRLO TP_PRINT_TEXT_PIXEL ; REPEAT UNLESS ALL PIXELS DONE + + INC E ; NEXT CHARACTER FOR PRINT HEAD + CPI E,5 ; GONE PAST LAST CHAR FOR PRINT HEAD? + BRLO TP_PRINT_TEXT_CHAR ; REPEAT UNLESS ALL CHARACTERS DONE + + CLR H + RCALL TP_LATCH0 ; CLEAR D4-D7 AND C0-C3 + + SBRC TEXT_MASK,7 ; LAST DOT LINE FOR CHARACTER LINE? + CBR FLAGS,1< CHARACTER SET SLICE IN FLASH + + LPM ; R0 = CORRECT VERTICAL SLICE OF CHAR + RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + LSL ZL ; ZL = CHARACTER DEFINITION * 8 + SUB ZL,D ; ZL = CHARACTER DEFINITION * 7 + ;CLR ZH + + SUBI ZL,-(EE_COUNT*2+2) ; PAST CRC, COUNT, AND CHARACTER CODE + ADD ZL,F ; ZL = BASE + CHAR * 6 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN R0,EEDR ; GET LATCHED DATA BYTE + RET + +; ----------------------------------------------------------------------------- +; FOREGROUND ROUTINES FOR API BUS + +RX_WAIT: + SBRC FLAGS,BOMB + RJMP TEXT_RESET + + SBRS STATUS,NOTIFY + RJMP RX_WAIT_TEST + + MOV A,TX_COUNT + CPI A,TX_SIZE ;-2 + BRSH RX_WAIT_TEST + + CLR NOTIFY_COUNT ; 6.5536 SECONDS TO NEXT NOTIFICATION + CBR STATUS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + +; ----------------------------------------------------------------------------- + +TEXT_RESET: + ; ENTRY POINT FROM RX_WAIT + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + +TEXT_RECEIVE: + ; NEXT LINE STARTS WITH RECEIVED CHAR + CLR CHAR_SAVE + + CLR ABORT_COUNT ; NO NEED TO ABORT ESC SEQUENCE + CBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI XL,$21 + LDI XH,$10 ; X = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,XL + EOR YH,XH +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +WAIT_ADD_FEEDS: + PUSH A + ADD A,FEEDS + POP A + BRCS WAIT_ADD_FEEDS + + ADD FEEDS,A + +MOTOR_START: + ;SBRS STATUS,PAPER + ;RET + + SBIC PORTC,4 + RET + + CBR FLAGS,1< ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$00,$9E,$00,$00,$00 + .DB $00,$0E,$00,$0E,$00,$00 + .DB $28,$FE,$28,$FE,$28,$00 + .DB $4C,$92,$FF,$92,$64,$00 + .DB $46,$26,$10,$C8,$C4,$00 + .DB $6C,$92,$AA,$44,$A0,$00 + .DB $00,$0B,$07,$00,$00,$00 + .DB $00,$38,$44,$82,$00,$00 + .DB $00,$82,$44,$38,$00,$00 + .DB $28,$10,$7C,$10,$28,$00 + .DB $10,$10,$7C,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $10,$10,$10,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $40,$20,$10,$08,$04,$00 + .DB $7C,$A2,$92,$8A,$7C,$00 + .DB $00,$84,$FE,$80,$00,$00 + .DB $84,$C2,$A2,$92,$8C,$00 + .DB $42,$82,$8A,$96,$62,$00 + .DB $30,$28,$24,$FE,$20,$00 + .DB $4E,$8A,$8A,$8A,$72,$00 + .DB $78,$94,$92,$92,$60,$00 + .DB $02,$E2,$12,$0A,$06,$00 + .DB $6C,$92,$92,$92,$6C,$00 + .DB $0C,$92,$92,$52,$3C,$00 + .DB $00,$6C,$6C,$00,$00,$00 + .DB $00,$6C,$EC,$00,$00,$00 + .DB $10,$28,$44,$82,$00,$00 + .DB $28,$28,$28,$28,$28,$00 + .DB $00,$82,$44,$28,$10,$00 + .DB $04,$02,$A2,$12,$0C,$00 + .DB $7C,$82,$BA,$AA,$3C,$00 + .DB $FC,$22,$22,$22,$FC,$00 + .DB $FE,$92,$92,$92,$6C,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $FE,$82,$82,$44,$38,$00 + .DB $FE,$92,$92,$92,$82,$00 + .DB $FE,$12,$12,$12,$02,$00 + .DB $7C,$82,$92,$92,$F4,$00 + .DB $FE,$10,$10,$10,$FE,$00 + .DB $00,$82,$FE,$82,$00,$00 + .DB $40,$80,$82,$7E,$02,$00 + .DB $FE,$10,$28,$44,$82,$00 + .DB $FE,$80,$80,$80,$80,$00 + .DB $FE,$04,$18,$04,$FE,$00 + .DB $FE,$08,$10,$20,$FE,$00 + .DB $7C,$82,$82,$82,$7C,$00 + .DB $FE,$12,$12,$12,$0C,$00 + .DB $7C,$82,$A2,$42,$BC,$00 + .DB $FE,$12,$32,$52,$8C,$00 + .DB $4C,$92,$92,$92,$64,$00 + .DB $02,$02,$FE,$02,$02,$00 + .DB $7E,$80,$80,$80,$7E,$00 + .DB $3E,$40,$80,$40,$3E,$00 + .DB $7E,$80,$70,$80,$7E,$00 + .DB $C6,$28,$10,$28,$C6,$00 + .DB $0E,$10,$E0,$10,$0E,$00 + .DB $C2,$A2,$92,$8A,$86,$00 + .DB $00,$FE,$82,$82,$00,$00 + .DB $04,$08,$10,$20,$40,$00 + .DB $00,$82,$82,$FE,$00,$00 + .DB $08,$04,$02,$04,$08,$00 + .DB $80,$80,$80,$80,$80,$00 + .DB $00,$00,$0E,$0D,$00,$00 + .DB $40,$A8,$A8,$A8,$F0,$00 + .DB $FE,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$88,$88,$88,$FE,$00 + .DB $70,$A8,$A8,$A8,$30,$00 + .DB $08,$08,$FC,$0A,$0A,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $FE,$10,$08,$08,$F0,$00 + .DB $00,$88,$FA,$80,$00,$00 + .DB $00,$00,$08,$FA,$00,$00 + .DB $FE,$20,$50,$88,$00,$00 + .DB $00,$82,$FE,$80,$00,$00 + .DB $F8,$08,$F8,$08,$F0,$00 + .DB $F8,$10,$08,$08,$F0,$00 + .DB $70,$88,$88,$88,$70,$00 + .DB $F8,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $F8,$10,$08,$08,$00,$00 + .DB $90,$A8,$A8,$A8,$48,$00 + .DB $08,$08,$7E,$88,$88,$00 + .DB $78,$80,$80,$40,$F8,$00 + .DB $38,$40,$80,$40,$38,$00 + .DB $78,$80,$60,$80,$78,$00 + .DB $88,$50,$20,$50,$88,$00 + .DB $78,$80,$80,$80,$F8,$00 + .DB $88,$C8,$A8,$98,$88,$00 + .DB $10,$6C,$82,$82,$00,$00 + .DB $00,$00,$EE,$00,$00,$00 + .DB $00,$82,$82,$6C,$10,$00 + .DB $04,$02,$04,$08,$04,$00 + .DB $E0,$90,$88,$90,$E0,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $7A,$80,$80,$40,$FA,$00 + .DB $70,$A8,$AA,$A9,$30,$00 + .DB $40,$AA,$A9,$AA,$F0,$00 + .DB $42,$A8,$A8,$A8,$F2,$00 + .DB $40,$A9,$AA,$A8,$F0,$00 + .DB $40,$AE,$AA,$AE,$F0,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$AA,$A9,$AA,$30,$00 + .DB $72,$A8,$A8,$A8,$32,$00 + .DB $70,$A9,$AA,$A8,$30,$00 + .DB $02,$88,$F8,$80,$02,$00 + .DB $00,$8A,$F9,$82,$00,$00 + .DB $00,$89,$FA,$80,$00,$00 + .DB $F9,$24,$24,$24,$F9,$00 + .DB $F8,$27,$25,$27,$F8,$00 + .DB $F8,$A8,$AA,$A9,$88,$00 + .DB $68,$A8,$F8,$A8,$B0,$00 + .DB $FC,$12,$FE,$92,$92,$00 + .DB $70,$8A,$89,$8A,$70,$00 + .DB $72,$88,$88,$88,$72,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$82,$81,$42,$F8,$00 + .DB $78,$81,$82,$40,$F8,$00 + .DB $7A,$80,$80,$80,$FA,$00 + .DB $79,$84,$84,$84,$79,$00 + .DB $7D,$80,$80,$80,$7D,$00 + .DB $70,$88,$88,$FC,$88,$00 + .DB $90,$7C,$92,$92,$C4,$00 + .DB $52,$54,$F8,$54,$52,$00 + .DB $82,$82,$44,$44,$28,$28 + .DB $10,$10,$28,$54,$54,$28 + .DB $40,$A8,$AA,$A9,$F0,$00 + .DB $00,$8A,$F9,$80,$00,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$80,$82,$41,$F8,$00 + .DB $FA,$11,$0A,$09,$F0,$00 + .DB $FA,$11,$22,$41,$F8,$00 + .DB $90,$AA,$AA,$AA,$BC,$00 + .DB $9C,$A2,$A2,$A2,$9C,$00 + .DB $60,$90,$8A,$80,$40,$00 + .DB $FE,$02,$02,$02,$02,$02 + .DB $02,$02,$02,$02,$02,$FE + .DB $2F,$10,$48,$24,$C0,$00 + .DB $2F,$90,$48,$E4,$00,$00 + .DB $00,$00,$F2,$00,$00,$00 + .DB $FE,$80,$80,$80,$80,$80 + .DB $80,$80,$80,$80,$80,$FE + .DB $00,$80,$00,$00,$80,$00 + .DB $55,$AA,$55,$AA,$55,$AA + .DB $33,$CC,$33,$CC,$33,$CC + .DB $00,$00,$FF,$00,$00,$00 + .DB $10,$10,$FF,$00,$00,$00 + .DB $28,$28,$FF,$00,$00,$00 + .DB $10,$FF,$00,$FF,$00,$00 + .DB $10,$F0,$10,$F0,$00,$00 + .DB $28,$28,$F8,$00,$00,$00 + .DB $28,$EF,$00,$FF,$00,$00 + .DB $00,$FF,$00,$FF,$00,$00 + .DB $28,$E8,$08,$F8,$00,$00 + .DB $28,$2F,$20,$3F,$00,$00 + .DB $10,$1F,$10,$1F,$00,$00 + .DB $28,$28,$3F,$00,$00,$00 + .DB $10,$10,$F0,$00,$00,$00 + .DB $00,$00,$1F,$10,$10,$10 + .DB $10,$10,$1F,$10,$10,$10 + .DB $10,$10,$F0,$10,$10,$10 + .DB $00,$00,$FF,$10,$10,$10 + .DB $10,$10,$10,$10,$10,$10 + .DB $10,$10,$FF,$10,$10,$10 + .DB $00,$00,$FF,$28,$28,$28 + .DB $00,$FF,$00,$FF,$10,$10 + .DB $00,$3F,$20,$2F,$28,$28 + .DB $00,$F8,$08,$E8,$28,$28 + .DB $28,$2F,$20,$2F,$28,$28 + .DB $28,$E8,$08,$E8,$28,$28 + .DB $00,$FF,$00,$EF,$28,$28 + .DB $28,$28,$28,$28,$28,$28 + .DB $28,$EF,$00,$EF,$28,$28 + .DB $28,$28,$2F,$28,$28,$28 + .DB $10,$1F,$10,$1F,$10,$10 + .DB $28,$28,$E8,$28,$28,$28 + .DB $10,$F0,$10,$F0,$10,$10 + .DB $00,$1F,$10,$1F,$10,$10 + .DB $00,$00,$3F,$28,$28,$28 + .DB $00,$00,$F8,$28,$28,$28 + .DB $00,$F0,$10,$F0,$10,$10 + .DB $10,$FF,$10,$FF,$10,$10 + .DB $28,$28,$FF,$28,$28,$28 + .DB $10,$10,$1F,$00,$00,$00 + .DB $00,$00,$F0,$10,$10,$10 + .DB $FF,$FF,$FF,$FF,$FF,$FF + .DB $E0,$E0,$E0,$E0,$E0,$E0 + .DB $FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF + .DB $1F,$1F,$1F,$1F,$1F,$1F + .DB $70,$88,$88,$70,$88,$00 + .DB $FC,$02,$92,$92,$6C,$00 + .DB $FE,$02,$02,$02,$06,$00 + .DB $08,$F8,$08,$F8,$08,$00 + .DB $C6,$AA,$92,$82,$C6,$00 + .DB $70,$88,$88,$78,$08,$00 + .DB $00,$F8,$80,$80,$78,$00 + .DB $10,$08,$F0,$08,$00,$00 + .DB $10,$AA,$EE,$AA,$10,$00 + .DB $7C,$92,$92,$92,$7C,$00 + .DB $9C,$E2,$02,$E2,$9C,$00 + .DB $60,$94,$9A,$92,$60,$00 + .DB $70,$88,$70,$88,$70,$00 + .DB $70,$88,$FC,$88,$70,$00 + .DB $38,$54,$92,$92,$00,$00 + .DB $FC,$02,$02,$02,$FC,$00 + .DB $54,$54,$54,$54,$54,$00 + .DB $88,$88,$BE,$88,$88,$00 + .DB $A2,$A2,$94,$94,$88,$00 + .DB $88,$94,$94,$A2,$A2,$00 + .DB $00,$00,$F8,$04,$08,$00 + .DB $40,$80,$7F,$00,$00,$00 + .DB $10,$10,$54,$10,$10,$00 + .DB $48,$24,$48,$24,$00,$00 + .DB $0C,$12,$12,$0C,$00,$00 + .DB $00,$18,$18,$00,$00,$00 + .DB $00,$00,$10,$00,$00,$00 + .DB $20,$40,$FF,$01,$01,$00 + .DB $1F,$02,$01,$1E,$00,$00 + .DB $00,$12,$19,$16,$00,$00 + .DB $00,$38,$38,$38,$00,$00 + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$02,$02,$02,$01,$00 + .DB $01,$02,$02,$01,$00,$00 + .DB $03,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$03,$00 + .DB $00,$00,$02,$03,$02,$00 + .DB $00,$01,$01,$03,$01,$00 + .DB $00,$00,$01,$00,$00,$00 + .DB $00,$00,$00,$01,$00,$00 + .DB $02,$01,$00,$00,$00,$00 + .DB $00,$02,$01,$00,$00,$00 + .DB $00,$00,$02,$01,$00,$00 + .DB $00,$01,$00,$00,$00,$00 + +; ----------------------------------------------------------------------------- + + ; BODEN = 0 ENABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4107 ; HARDWARE ADDRESS COMMAND + .DW $4206 ; SOFTWARE ADDRESS COMMAND + .DW $ACB2 ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/m192v1.asm b/src/avr/m192v1.asm new file mode 100644 index 00000000..1bf5b239 --- /dev/null +++ b/src/avr/m192v1.asm @@ -0,0 +1,1685 @@ +; M192V1.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =6 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ;$11 ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ;$11 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =30 ; 240 / 8 = 30 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =40 ; 240 / 6 = 40 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =5 ; 40 / 8 = 5 TEXT WIDTH FLAGS + +.EQU TIME_EMERGENCY =1000 ; 1000 * 0.1 MS = APPROX 100 MS + +.EQU FEED_INITIAL =2 ; LINES ALLOWED FOR MOTOR SLOWDOWN +.EQU FEED_SPACING =3 ; LINES TO FEED IN BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF TP_COUNT =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF NOTIFY_COUNT =R14 ; COUNTER TO SEND EVERY 6.5536 SECONDS +.DEF ABORT_COUNT =R15 ; COUNTER TO ABORT ESC AFTER 0.1 SECS + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF SR =R23 +.DEF FLAGS =R24 +.DEF STATUS =R25 + +.EQU TX_SIZE =2 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_CHARS+WIDTH_FLAGS +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU RSWSAVE =2 ; SET IF RSW HI, MUST BE BIT POSITION 2 +.EQU IMAGE =3 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =4 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +;.EQU NODESC =5 ; SET BY FG WHILE PRINTING TOP 7 DOTS +;.EQU BIGDESC =6 ; SET BY FG WHILE PRINTING LOWER 2 DOTS +.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY FG JUST PRIOR TO NOTIFICATION +.EQU TP_ERROR =2 ; SET BY BG IF WE HAVE TIMEOUT ON TP +.EQU RSW_ERROR =3 ; SET BY BG IF WE HAVE TIMEOUT ON RSW +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; NODESC + +; FLAG RESET BY FOREGROUND AFTER DESCENDER TRANSLATION, IF DESCENDERS PRESENT. +; FLAG SET BY FOREGROUND AFTER DESCENDERS FINISHED AND BUFFER CLOBBERED. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE, FOR SPECIAL DESCENDER +; PROCESSING. + +; BIGDESC + +; FLAG SET UP BY FOREGROUND DURING DESCENDER TRANSLATION. +; FLAG SAMPLED BY BACKGROUND AT END OF DOT LINE IN COMBINATION WITH +; TEXT_MASK, TO CONTINUE DESCENDER OR REVERT TO FEEDS. + +; NOWFAST + +; FLAG SET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 115200 BPS. +; FLAG RESET BY BACKGROUND COMMS TASK WHEN UART IS PROGRAMMED TO 4800 BPS. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG INT1ADDR + RJMP TP_EDGE ; EXTERNAL INT 1 HANDLER + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','1','9','2',' ' +; .DB 'P','R','I','N','T','E','R',$0D + +; ----------------------------------------------------------------------------- +; TP EDGE INTERRUPT HANDLER + +TP_EDGE: + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + IN SR,SREG ; SAVE FLAGS + + IN D,MCUCR + SBRS D,ISC10 + CBI PORTB,2 ; IF WE WERE LOOKING FOR A FALLING EDGE + SBRC D,ISC10 + SBI PORTB,2 ; IF WE WERE LOOKING FOR A RISING EDGE + LDI G,1< LOW + + SBRS D,2 + RJMP TP_SEARCH + + ; RSW FALLING EDGE DETECTED + SBIC PORTC,4 ; MOTOR ON? + RJMP TP_FEED ; YES, GO AND PRINT + + ; WE STOPPED THE MOTOR, MONITOR RSW WHILE IT SLOWS DOWN + CLR TP_COUNT ; REPLENISH COUNT OF TP EDGES TO RSW + + TST FEEDS + BREQ TP_SEARCH + DEC FEEDS ; DECREMENT FEEDS TO MINIMUM OF 0 + RJMP TP_SEARCH + +TP_COAST: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + MOV D,TP_COUNT + CPI D,3 + BRSH TP_PAPER_SKIP ; ON LAST OR 2ND LAST TP EDGE, + + SBIC PORTB,2 + RJMP TP_PAPER_SKIP ; WITH TP GENERATOR IN KNOWN STATE, + +;T0_PAPER_SETUP: + LDI A,0 + OUT GIMSK,A ; DISABLE INT 1 INTERRUPTS + + ;CBI PORTB,2 ; SET TP GENERATOR TO KNOWN STATE + SBI PORTB,1 ; MUST BE OPPOSITE TO PORTB,2 STATE + SBI DDRB,1 ; D1 = HIGH / LOW TO LIGHT LED + + LDI D,-3 + OUT TCNT0,D ; TEST PAPER IN 2 * 0.1 MS = 0.2 MS + +TP_PAPER_SKIP: + DEC TP_COUNT ; COUNT EDGES/2 TO PRINTABLE AREA-4 + BRNE TP_COAST + +TP_FEED: + ;SBRS STATUS,PAPER ; PAPER IN? + ;RJMP TP_BRAKE_NOW ; NO, STOP PRINTING IMMEDIATELY + + MOV D,FLAGS + ANDI D,(1< 3 INTERNAL FEEDS + CPI D,1 + BRSH TP_FEED_SLOW ; COAST IF => 1 INTERNAL FEED + + SBRC FLAGS,IMAGE + RJMP TP_PRINT_IMAGE ; PRINT IF GRAPHICS WAITING + + RJMP TP_PRINT_TEXT ; OTHERWISE ASSUME TEXT IS WAITING + +TP_BRAKE: + MOV D,FEEDS + CPI D,3+FEED_INITIAL + BRSH TP_FEED_FAST ; TRIGGER IF => 3+n INTERNAL FEEDS + CPI D,1+FEED_INITIAL + BRSH TP_FEED_SLOW ; COAST IF => 1+n INTERNAL FEED + +TP_BRAKE_NOW: +; TST FEEDS ; JUST MISSED RSW -> 0, COMPENSATE +; BREQ TP_BRAKE_NOW_CONT +; DEC FEEDS ; DECREMENT TO MINIMUM OF 0 +;TP_BRAKE_NOW_CONT: + CLR FEEDS + RJMP TP_KILL ; GO AND KILL MOTOR + +TP_FEED_SLOW: + DEC FEEDS + + LDI D,150 + MOV TP_COUNT,D + RJMP TP_COAST + +TP_FEED_FAST: ; AT PRINTABLE AREA-2 + SUBI D,3 + MOV FEEDS,D + + SBI PORTB,0 ; APPLY TRIGGER SOLENOID + + LDI D,9 + MOV TP_COUNT,D +TP_TRIGGERING: + RCALL TP_DONE ; RETURNS NEXT TP EDGE + DEC TP_COUNT + BRNE TP_TRIGGERING + + CBI PORTB,0 ; CLEAR TRIGGER SOLENOID + + LDI D,150-9 + MOV TP_COUNT,D + RJMP TP_COAST + +; ----------------------------------------------------------------------------- +; TP INTERRUPT ROUTINES FOR TEXT PRINTING + +; TP_TEXT_START DOES NOT RE-ENABLE ACCESS TO FEEDS. +; FEEDS IS USED AS A COUNTER FOR DESCENDER PRINTING, +; SO WE RELY ON TIMER_COPY TO RESET NOFEED, AFTER THE +; LINE HAS BEEN CHECKED FOR DESCENDERS AND IS ABOUT TO +; BE CLOBBERED BY NEW DATA. + +TP_PRINT_TEXT: + LDI D,2 + MOV TEXT_MASK,D + MOV FEEDS,SPACING ; SET UP STANDARD FEED AFTER TEXT LINE + +TP_PRINT_TEXT_START: + LDI E,0 ; CURRENT CHARACTER FOR PRINT HEAD, 0-4 + +TP_PRINT_TEXT_CHAR: + LDI F,0 ; CURRENT PIXEL FOR CHARACTER, 0-5 + +TP_PRINT_TEXT_PIXEL: + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-30 ; E = CURRENT CHARACTER + 30 + RCALL TP_TEXT_FIRE2 + SUBI E,15 ; E = CURRENT CHARACTER + 15 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH0 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-35 ; E = CURRENT CHARACTER + 35 + RCALL TP_TEXT_FIRE1 + SUBI E,15 ; E = CURRENT CHARACTER + 20 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 5 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH1 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + PUSH ZL + PUSH ZH + PUSH R0 + + SUBI E,-20 ; E = CURRENT CHARACTER + 25 + RCALL TP_TEXT_FIRE3 + SUBI E,15 ; E = CURRENT CHARACTER + 10 + RCALL TP_TEXT_FIRE3 + RCALL TP_LATCH2 + + POP R0 + POP ZH + POP ZL + + RCALL TP_DONE ; RETURNS NEXT TP EDGE + + SUBI E,10 ; E = CURRENT CHARACTER + + INC F ; NEXT PIXEL FOR CHARACTER + CPI F,6 ; GONE PAST LAST PIXEL FOR CHARACTER? + BRLO TP_PRINT_TEXT_PIXEL ; REPEAT UNLESS ALL PIXELS DONE + + INC E ; NEXT CHARACTER FOR PRINT HEAD + CPI E,5 ; GONE PAST LAST CHAR FOR PRINT HEAD? + BRLO TP_PRINT_TEXT_CHAR ; REPEAT UNLESS ALL CHARACTERS DONE + + CLR H + RCALL TP_LATCH0 ; CLEAR D4-D7 AND C0-C3 + + SBRC TEXT_MASK,7 ; LAST DOT LINE FOR CHARACTER LINE? + CBR FLAGS,1< CHARACTER SET SLICE IN FLASH + + LPM ; R0 = CORRECT VERTICAL SLICE OF CHAR + RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + LSL ZL ; ZL = CHARACTER DEFINITION * 8 + SUB ZL,D ; ZL = CHARACTER DEFINITION * 7 + ;CLR ZH + + SUBI ZL,-(EE_COUNT*2+2) ; PAST CRC, COUNT, AND CHARACTER CODE + ADD ZL,F ; ZL = BASE + CHAR * 6 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN R0,EEDR ; GET LATCHED DATA BYTE + RET + +; ----------------------------------------------------------------------------- +; FOREGROUND ROUTINES FOR API BUS + +RX_WAIT: + SBRC FLAGS,BOMB + RJMP TEXT_RESET + + SBRS STATUS,NOTIFY + RJMP RX_WAIT_TEST + + MOV A,TX_COUNT + CPI A,TX_SIZE ;-2 + BRSH RX_WAIT_TEST + + CLR NOTIFY_COUNT ; 6.5536 SECONDS TO NEXT NOTIFICATION + CBR STATUS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + +; ----------------------------------------------------------------------------- + +TEXT_RESET: + ; ENTRY POINT FROM RX_WAIT + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + +TEXT_RECEIVE: + ; NEXT LINE STARTS WITH RECEIVED CHAR + CLR CHAR_SAVE + + CLR ABORT_COUNT ; NO NEED TO ABORT ESC SEQUENCE + CBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI XL,$21 + LDI XH,$10 ; X = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,XL + EOR YH,XH +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +WAIT_ADD_FEEDS: + PUSH A + ADD A,FEEDS + POP A + BRCS WAIT_ADD_FEEDS + + ADD FEEDS,A + +MOTOR_START: + ;SBRS STATUS,PAPER + ;RET + + SBIC PORTC,4 + RET + + CBR FLAGS,1< ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$00,$9E,$00,$00,$00 + .DB $00,$0E,$00,$0E,$00,$00 + .DB $28,$FE,$28,$FE,$28,$00 + .DB $4C,$92,$FF,$92,$64,$00 + .DB $46,$26,$10,$C8,$C4,$00 + .DB $6C,$92,$AA,$44,$A0,$00 + .DB $00,$0B,$07,$00,$00,$00 + .DB $00,$38,$44,$82,$00,$00 + .DB $00,$82,$44,$38,$00,$00 + .DB $28,$10,$7C,$10,$28,$00 + .DB $10,$10,$7C,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $10,$10,$10,$10,$10,$00 + .DB $00,$C0,$C0,$00,$00,$00 + .DB $40,$20,$10,$08,$04,$00 + .DB $7C,$A2,$92,$8A,$7C,$00 + .DB $00,$84,$FE,$80,$00,$00 + .DB $84,$C2,$A2,$92,$8C,$00 + .DB $42,$82,$8A,$96,$62,$00 + .DB $30,$28,$24,$FE,$20,$00 + .DB $4E,$8A,$8A,$8A,$72,$00 + .DB $78,$94,$92,$92,$60,$00 + .DB $02,$E2,$12,$0A,$06,$00 + .DB $6C,$92,$92,$92,$6C,$00 + .DB $0C,$92,$92,$52,$3C,$00 + .DB $00,$6C,$6C,$00,$00,$00 + .DB $00,$6C,$EC,$00,$00,$00 + .DB $10,$28,$44,$82,$00,$00 + .DB $28,$28,$28,$28,$28,$00 + .DB $00,$82,$44,$28,$10,$00 + .DB $04,$02,$A2,$12,$0C,$00 + .DB $7C,$82,$BA,$AA,$3C,$00 + .DB $FC,$22,$22,$22,$FC,$00 + .DB $FE,$92,$92,$92,$6C,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $FE,$82,$82,$44,$38,$00 + .DB $FE,$92,$92,$92,$82,$00 + .DB $FE,$12,$12,$12,$02,$00 + .DB $7C,$82,$92,$92,$F4,$00 + .DB $FE,$10,$10,$10,$FE,$00 + .DB $00,$82,$FE,$82,$00,$00 + .DB $40,$80,$82,$7E,$02,$00 + .DB $FE,$10,$28,$44,$82,$00 + .DB $FE,$80,$80,$80,$80,$00 + .DB $FE,$04,$18,$04,$FE,$00 + .DB $FE,$08,$10,$20,$FE,$00 + .DB $7C,$82,$82,$82,$7C,$00 + .DB $FE,$12,$12,$12,$0C,$00 + .DB $7C,$82,$A2,$42,$BC,$00 + .DB $FE,$12,$32,$52,$8C,$00 + .DB $4C,$92,$92,$92,$64,$00 + .DB $02,$02,$FE,$02,$02,$00 + .DB $7E,$80,$80,$80,$7E,$00 + .DB $3E,$40,$80,$40,$3E,$00 + .DB $7E,$80,$70,$80,$7E,$00 + .DB $C6,$28,$10,$28,$C6,$00 + .DB $0E,$10,$E0,$10,$0E,$00 + .DB $C2,$A2,$92,$8A,$86,$00 + .DB $00,$FE,$82,$82,$00,$00 + .DB $04,$08,$10,$20,$40,$00 + .DB $00,$82,$82,$FE,$00,$00 + .DB $08,$04,$02,$04,$08,$00 + .DB $80,$80,$80,$80,$80,$00 + .DB $00,$00,$0E,$0D,$00,$00 + .DB $40,$A8,$A8,$A8,$F0,$00 + .DB $FE,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$88,$88,$88,$FE,$00 + .DB $70,$A8,$A8,$A8,$30,$00 + .DB $08,$08,$FC,$0A,$0A,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $FE,$10,$08,$08,$F0,$00 + .DB $00,$88,$FA,$80,$00,$00 + .DB $00,$00,$08,$FA,$00,$00 + .DB $FE,$20,$50,$88,$00,$00 + .DB $00,$82,$FE,$80,$00,$00 + .DB $F8,$08,$F8,$08,$F0,$00 + .DB $F8,$10,$08,$08,$F0,$00 + .DB $70,$88,$88,$88,$70,$00 + .DB $F8,$88,$88,$88,$70,$00 + .DB $70,$88,$88,$88,$F8,$00 + .DB $F8,$10,$08,$08,$00,$00 + .DB $90,$A8,$A8,$A8,$48,$00 + .DB $08,$08,$7E,$88,$88,$00 + .DB $78,$80,$80,$40,$F8,$00 + .DB $38,$40,$80,$40,$38,$00 + .DB $78,$80,$60,$80,$78,$00 + .DB $88,$50,$20,$50,$88,$00 + .DB $78,$80,$80,$80,$F8,$00 + .DB $88,$C8,$A8,$98,$88,$00 + .DB $10,$6C,$82,$82,$00,$00 + .DB $00,$00,$EE,$00,$00,$00 + .DB $00,$82,$82,$6C,$10,$00 + .DB $04,$02,$04,$08,$04,$00 + .DB $E0,$90,$88,$90,$E0,$00 + .DB $7C,$82,$82,$82,$44,$00 + .DB $7A,$80,$80,$40,$FA,$00 + .DB $70,$A8,$AA,$A9,$30,$00 + .DB $40,$AA,$A9,$AA,$F0,$00 + .DB $42,$A8,$A8,$A8,$F2,$00 + .DB $40,$A9,$AA,$A8,$F0,$00 + .DB $40,$AE,$AA,$AE,$F0,$00 + .DB $70,$88,$88,$88,$88,$00 + .DB $70,$AA,$A9,$AA,$30,$00 + .DB $72,$A8,$A8,$A8,$32,$00 + .DB $70,$A9,$AA,$A8,$30,$00 + .DB $02,$88,$F8,$80,$02,$00 + .DB $00,$8A,$F9,$82,$00,$00 + .DB $00,$89,$FA,$80,$00,$00 + .DB $F9,$24,$24,$24,$F9,$00 + .DB $F8,$27,$25,$27,$F8,$00 + .DB $F8,$A8,$AA,$A9,$88,$00 + .DB $68,$A8,$F8,$A8,$B0,$00 + .DB $FC,$12,$FE,$92,$92,$00 + .DB $70,$8A,$89,$8A,$70,$00 + .DB $72,$88,$88,$88,$72,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$82,$81,$42,$F8,$00 + .DB $78,$81,$82,$40,$F8,$00 + .DB $7A,$80,$80,$80,$FA,$00 + .DB $79,$84,$84,$84,$79,$00 + .DB $7D,$80,$80,$80,$7D,$00 + .DB $70,$88,$88,$FC,$88,$00 + .DB $90,$7C,$92,$92,$C4,$00 + .DB $52,$54,$F8,$54,$52,$00 + .DB $82,$82,$44,$44,$28,$28 + .DB $10,$10,$28,$54,$54,$28 + .DB $40,$A8,$AA,$A9,$F0,$00 + .DB $00,$8A,$F9,$80,$00,$00 + .DB $70,$88,$8A,$89,$70,$00 + .DB $78,$80,$82,$41,$F8,$00 + .DB $FA,$11,$0A,$09,$F0,$00 + .DB $FA,$11,$22,$41,$F8,$00 + .DB $90,$AA,$AA,$AA,$BC,$00 + .DB $9C,$A2,$A2,$A2,$9C,$00 + .DB $60,$90,$8A,$80,$40,$00 + .DB $FE,$02,$02,$02,$02,$02 + .DB $02,$02,$02,$02,$02,$FE + .DB $2F,$10,$48,$24,$C0,$00 + .DB $2F,$90,$48,$E4,$00,$00 + .DB $00,$00,$F2,$00,$00,$00 + .DB $FE,$80,$80,$80,$80,$80 + .DB $80,$80,$80,$80,$80,$FE + .DB $00,$80,$00,$00,$80,$00 + .DB $55,$AA,$55,$AA,$55,$AA + .DB $33,$CC,$33,$CC,$33,$CC + .DB $00,$00,$FF,$00,$00,$00 + .DB $10,$10,$FF,$00,$00,$00 + .DB $28,$28,$FF,$00,$00,$00 + .DB $10,$FF,$00,$FF,$00,$00 + .DB $10,$F0,$10,$F0,$00,$00 + .DB $28,$28,$F8,$00,$00,$00 + .DB $28,$EF,$00,$FF,$00,$00 + .DB $00,$FF,$00,$FF,$00,$00 + .DB $28,$E8,$08,$F8,$00,$00 + .DB $28,$2F,$20,$3F,$00,$00 + .DB $10,$1F,$10,$1F,$00,$00 + .DB $28,$28,$3F,$00,$00,$00 + .DB $10,$10,$F0,$00,$00,$00 + .DB $00,$00,$1F,$10,$10,$10 + .DB $10,$10,$1F,$10,$10,$10 + .DB $10,$10,$F0,$10,$10,$10 + .DB $00,$00,$FF,$10,$10,$10 + .DB $10,$10,$10,$10,$10,$10 + .DB $10,$10,$FF,$10,$10,$10 + .DB $00,$00,$FF,$28,$28,$28 + .DB $00,$FF,$00,$FF,$10,$10 + .DB $00,$3F,$20,$2F,$28,$28 + .DB $00,$F8,$08,$E8,$28,$28 + .DB $28,$2F,$20,$2F,$28,$28 + .DB $28,$E8,$08,$E8,$28,$28 + .DB $00,$FF,$00,$EF,$28,$28 + .DB $28,$28,$28,$28,$28,$28 + .DB $28,$EF,$00,$EF,$28,$28 + .DB $28,$28,$2F,$28,$28,$28 + .DB $10,$1F,$10,$1F,$10,$10 + .DB $28,$28,$E8,$28,$28,$28 + .DB $10,$F0,$10,$F0,$10,$10 + .DB $00,$1F,$10,$1F,$10,$10 + .DB $00,$00,$3F,$28,$28,$28 + .DB $00,$00,$F8,$28,$28,$28 + .DB $00,$F0,$10,$F0,$10,$10 + .DB $10,$FF,$10,$FF,$10,$10 + .DB $28,$28,$FF,$28,$28,$28 + .DB $10,$10,$1F,$00,$00,$00 + .DB $00,$00,$F0,$10,$10,$10 + .DB $FF,$FF,$FF,$FF,$FF,$FF + .DB $E0,$E0,$E0,$E0,$E0,$E0 + .DB $FF,$FF,$FF,$00,$00,$00 + .DB $00,$00,$00,$FF,$FF,$FF + .DB $1F,$1F,$1F,$1F,$1F,$1F + .DB $70,$88,$88,$70,$88,$00 + .DB $FC,$02,$92,$92,$6C,$00 + .DB $FE,$02,$02,$02,$06,$00 + .DB $08,$F8,$08,$F8,$08,$00 + .DB $C6,$AA,$92,$82,$C6,$00 + .DB $70,$88,$88,$78,$08,$00 + .DB $00,$F8,$80,$80,$78,$00 + .DB $10,$08,$F0,$08,$00,$00 + .DB $10,$AA,$EE,$AA,$10,$00 + .DB $7C,$92,$92,$92,$7C,$00 + .DB $9C,$E2,$02,$E2,$9C,$00 + .DB $60,$94,$9A,$92,$60,$00 + .DB $70,$88,$70,$88,$70,$00 + .DB $70,$88,$FC,$88,$70,$00 + .DB $38,$54,$92,$92,$00,$00 + .DB $FC,$02,$02,$02,$FC,$00 + .DB $54,$54,$54,$54,$54,$00 + .DB $88,$88,$BE,$88,$88,$00 + .DB $A2,$A2,$94,$94,$88,$00 + .DB $88,$94,$94,$A2,$A2,$00 + .DB $00,$00,$F8,$04,$08,$00 + .DB $40,$80,$7F,$00,$00,$00 + .DB $10,$10,$54,$10,$10,$00 + .DB $48,$24,$48,$24,$00,$00 + .DB $0C,$12,$12,$0C,$00,$00 + .DB $00,$18,$18,$00,$00,$00 + .DB $00,$00,$10,$00,$00,$00 + .DB $20,$40,$FF,$01,$01,$00 + .DB $1F,$02,$01,$1E,$00,$00 + .DB $00,$12,$19,$16,$00,$00 + .DB $00,$38,$38,$38,$00,$00 + .DB $00,$00,$00,$00,$00,$00 + .DB $00,$02,$02,$02,$01,$00 + .DB $01,$02,$02,$01,$00,$00 + .DB $03,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$03,$00 + .DB $00,$00,$02,$03,$02,$00 + .DB $00,$01,$01,$03,$01,$00 + .DB $00,$00,$01,$00,$00,$00 + .DB $00,$00,$00,$01,$00,$00 + .DB $02,$01,$00,$00,$00,$00 + .DB $00,$02,$01,$00,$00,$00 + .DB $00,$00,$02,$01,$00,$00 + .DB $00,$01,$00,$00,$00,$00 + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4107 ; HARDWARE ADDRESS COMMAND + .DW $4206 ; SOFTWARE ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mac.inc b/src/avr/mac.inc new file mode 100644 index 00000000..f2f9930a --- /dev/null +++ b/src/avr/mac.inc @@ -0,0 +1,195 @@ +; MAC.INC +; MACROS FOR THE AVR PROCESSOR + +.MACRO RJEQ + BRNE LOCAL + RJMP @0 +LOCAL: +.ENDMACRO + +.MACRO RJNE + BREQ LOCAL + RJMP @0 +LOCAL: +.ENDMACRO + +.MACRO OUTI @0,@1 + LDI A,@1 ; OUT IMMEDIATE TO PORT + OUT @0,A +.ENDMACRO + +.MACRO ADDI @0,@1 + SUBI @0,-@1 ; ADD IMMEDIATE +.ENDMACRO + +.MACRO EORI @0,@1 + LDI A,@1 ; EOR IMMEDIATE + EOR @0,A +.ENDMACRO + +.MACRO STI @0,@1 + LDI A,@1 ; STORE IMMEDIATE + ST @0,A +.ENDMACRO + +.MACRO ADDIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + ADD @0,A +.ENDMACRO + +.MACRO SUBIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + SUB @0,A +.ENDMACRO + +.MACRO ANDIL @0,@1 + LDI A,@1 ; AND IMMEDIATE LOWER REGISTER SET + AND @0,A +.ENDMACRO + +.MACRO LDIL @0,@1 + LDI A,@1 ; LOAD IMMEDIATE LOWER REGISTER SET + MOV @0,A +.ENDMACRO + +.MACRO LDIX @0 ; LOAD IMMEDIATE XL, XH WITH FLASH ADDRESS + LDI XL,LOW((@0)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((@0)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION +.ENDMACRO + +.MACRO LDIZ @0 ; LOAD IMMEDIATE ZL, ZH WITH FLASH ADDRESS + LDI ZL,LOW((@0)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((@0)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION +.ENDMACRO + +.MACRO LDE @0,@1 ; LOAD REGISTER FROM EEPROM + RCALL LDE1 + LDI @0,LOW(@1*2) ; POINT TO EEPROM CONSTANT + OUT EEAR,@0 ; SET UP ADDRESS + SBI EECR,EERE ; ASSERT READ STROBE + IN @0,EEDR +.ENDMACRO + +.MACRO LDFL @0,@1 ; LOAD REGISTER FROM FLASH LOW BYTE + LDI ZL,LOW(@1*2) + LDI ZH,HIGH(@1*2) + LPM + MOV @0,R0 +.ENDMACRO + +.MACRO LDFH @0,@1 ; LOAD REGISTER FROM FLASH HIGH BYTE + LDI ZL,LOW(@1*2+1) + LDI ZH,HIGH(@1*2+1) + LPM + MOV @0,R0 +.ENDMACRO + +;.MACRO LDF @0,@1 ; LOAD REGISTER FROM FLASH +; LDI ZL,@1 ; POINT TO FLASH CONSTANT +; LPM +; MOV @0,R0 +;.ENDMACRO + +;------------------------------------------------------------------------------ + +.MACRO FLD @0 ; LOAD FA REGISTER FROM SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL LDS_FA +.ENDMACRO + +.MACRO FLDF @0 ; LOAD FA REGISTER FROM FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL LDF_FA +.ENDMACRO + +.MACRO FLDE @0 ; LOAD FA REGISTER FROM EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL LDE_FA +.ENDMACRO + +.MACRO FLD3 @0 ; LOAD FA REGISTER WITH 3 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS3_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FLD2 @0 ; LOAD FA REGISTER WITH 2 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS2_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FST @0 ; STORE FP REGISTER TO FP ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL STS_FA +.ENDMACRO + +.MACRO FCHS @0 ; CHANGE SIGN OF SRAM ARGUMENT + LDI YL,LOW(@0) + RCALL CHSS +.ENDMACRO + +.MACRO FAD @0 ; ADD SRAM ARGUMENT TO FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL ADD_FA +.ENDMACRO + +.MACRO FADF @0 ; ADD FLASH CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL ADDF_FA +.ENDMACRO + +.MACRO FADE @0 ; ADD EEPROM CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL ADDE_FA +.ENDMACRO + +.MACRO FSB @0 ; SUBTRACT SRAM ARGUMENT FROM FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL SUB_FA +.ENDMACRO + +.MACRO FSBF @0 ; SUBTRACT FLASH CONSTANT FROM FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL SUBF_FA +.ENDMACRO + +.MACRO FML @0 ; MULTIPLY FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL MUL_FA +.ENDMACRO + +.MACRO FMLF @0 ; MULTIPLY FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL MULF_FA +.ENDMACRO + +.MACRO FDV @0 ; DIVIDE FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL DIV_FA +.ENDMACRO + +.MACRO FDVF @0 ; DIVIDE FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL DIVF_FA +.ENDMACRO + +.MACRO FCP @0 ; COMPARE FA REGISTER WITH SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL CP_FA +.ENDMACRO + +.MACRO FCPF @0 ; COMPARE FA REGISTER WITH FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL CPF_FA +.ENDMACRO + +.MACRO FCPE @0 ; COMPARE FA REGISTER WITH EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + RCALL CPE_FA +.ENDMACRO + diff --git a/src/avr/maclc.inc b/src/avr/maclc.inc new file mode 100644 index 00000000..7e378ad8 --- /dev/null +++ b/src/avr/maclc.inc @@ -0,0 +1,242 @@ +; MACLC.INC +; MACROS FOR THE AVR PROCESSOR + +.LISTMAC + +.MACRO OUTI @0,@1 + LDI A,@1 ; sends immediate data out port eg outi porta,$0f + OUT @0,A +.ENDMACRO + +.MACRO PUL_H @0,@1 + SBI @0,@1 ; pulses bit in port high eg pul_h portb,1 + CBI @0,@1 +.ENDMACRO + +.MACRO PUL_L @0,@1 + CBI @0,@1 ; pulses bit in port low eg pul_l portb,1 + SBI @0,@1 +.ENDMACRO + +.MACRO RAMW @0 + CBI PORTD,WE + CBI PORTD,CS + LDI A,@0 ; writes immed data to static ram eg ramw $34 + OUT PORTA,A + SBI PORTD,CS + SBI PORTD,WE ; NOT PORTABLE -USED FOR LCD CONTROL +.ENDMACRO + +.MACRO RAMWR @0 + CBI PORTD,WE + CBI PORTD,CS + MOV A,@0 ; writes REG data to static ram eg ramw R21 + OUT PORTA,A + SBI PORTD,CS + SBI PORTD,WE ; NOT PORTABLE -USED FOR LCD CONTROL +.ENDMACRO + +.MACRO ADDI @0,@1 + SUBI @0,-@1 ; add immediate data to reg +.ENDMACRO + +.MACRO EORI @0,@1 + LDI A,@1 ; EOR IMMEDIATE + EOR @0,A +.ENDMACRO + +.MACRO STI @0,@1 + LDI A,@1 ; STORE IMMEDIATE + ST @0,A +.ENDMACRO + +.MACRO ADDIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + ADD @0,A +.ENDMACRO + +.MACRO SUBIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + SUB @0,A +.ENDMACRO + +.MACRO ANDIL @0,@1 + LDI A,@1 ; AND IMMEDIATE LOWER REGISTER SET + AND @0,A +.ENDMACRO + +.MACRO LDIL @0,@1 + LDI A,@1 ; LOAD IMMEDIATE LOWER REGISTER SET + MOV @0,A +.ENDMACRO + +.MACRO LDIZ @0 ; LOAD IMMEDIATE ZL, ZH WITH FLASH ADDRESS + LDI ZL,LOW(@0*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH(@0*2) +.ENDMACRO + +.MACRO LDE @0,@1 ; LOAD REGISTER FROM EEPROM + RCALL LDE1 + LDI @0,LOW(@1*2) ; POINT TO EEPROM CONSTANT + OUT EEAR,@0 ; SET UP ADDRESS + SBI EECR,EERE ; ASSERT READ STROBE + IN @0,EEDR +.ENDMACRO + +.MACRO LDER @0,@1 ; LOAD REGISTER FROM EEPROM 17MAY01 +; RCALL LDE1 + LDI @0,LOW(@1*2) ; POINT TO EEPROM CONSTANT + OUT EEAR,@0 ; SET UP ADDRESS + SBI EECR,EERE ; ASSERT READ STROBE + IN @0,EEDR +.ENDMACRO + +.MACRO LDFL @0,@1 ; LOAD REGISTER FROM FLASH LOW BYTE + LDI ZL,LOW(@1*2) + LDI ZH,HIGH(@1*2) + LPM + MOV @0,R0 +.ENDMACRO + +.MACRO LDFH @0,@1 ; LOAD REGISTER FROM FLASH HIGH BYTE + LDI ZL,LOW(@1*2+1) + LDI ZH,HIGH(@1*2+1) + LPM + MOV @0,R0 +.ENDMACRO + +;.MACRO LDF @0,@1 ; LOAD REGISTER FROM FLASH +; LDI ZL,@1 ; POINT TO FLASH CONSTANT +; LPM +; MOV @0,R0 +;.ENDMACRO + +;.MACRO FDVI @0,@1 ; DIVIDE FLASH CONSTANT BY 3 BYTE SRAM INTEGER +; LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT +; LDI YL,LOW(@1) ; POINT TO SRAM INTEGER +; RCALL FP_DIVI +;.ENDMACRO + + +;------------------------------------------------------------------------------ + +.MACRO FLD @0 ; LOAD FA REGISTER FROM SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL LDS_FA +.ENDMACRO + +.MACRO FLDF @0 ; LOAD FA REGISTER FROM FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL LDF_FA +.ENDMACRO + +.MACRO FLDE @0 ; LOAD FA REGISTER FROM EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL LDE_FA +.ENDMACRO + +.MACRO FLD3 @0 ; LOAD FA REGISTER WITH 3 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS3_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FLD2 @0 ; LOAD FA REGISTER WITH 2 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS2_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FST @0 ; STORE FP REGISTER TO FP ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL STS_FA +.ENDMACRO + +.MACRO FCHS @0 ; CHANGE SIGN OF SRAM ARGUMENT + LDI YL,LOW(@0) + RCALL CHSS +.ENDMACRO + +.MACRO FAD @0 ; ADD SRAM ARGUMENT TO FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL ADD_FA +.ENDMACRO + +.MACRO FADE @0 ; ADD EEPROM CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL ADDE_FA +.ENDMACRO + +.MACRO FADF @0 ; ADD FLASH CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL ADDF_FA +.ENDMACRO + +.MACRO FSB @0 ; SUBTRACT SRAM ARGUMENT FROM FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL SUB_FA +.ENDMACRO + +.MACRO FSBE @0 ; SUBTRACT EEPROM CONSTANT FROM FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL SUBE_FA +.ENDMACRO + +.MACRO FSBF @0 ; SUBTRACT FLASH CONSTANT FROM FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL SUBF_FA +.ENDMACRO + +.MACRO FML @0 ; MULTIPLY FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL MUL_FA +.ENDMACRO + +.MACRO FMLE @0 ; MULTIPLY FA REGISTER BY EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL MULE_FA +.ENDMACRO + +.MACRO FMLF @0 ; MULTIPLY FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL MULF_FA +.ENDMACRO + +.MACRO FDV @0 ; DIVIDE FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL DIV_FA +.ENDMACRO + +.MACRO FDVE @0 ; DIVIDE FA REGISTER BY EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL DIVE_FA +.ENDMACRO + +.MACRO FDVF @0 ; DIVIDE FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL DIVF_FA +.ENDMACRO + +.MACRO FCP @0 ; COMPARE FA REGISTER WITH SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL CP_FA +.ENDMACRO + +.MACRO FCPE @0 ; COMPARE FA REGISTER WITH EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + RCALL CPE_FA +.ENDMACRO + +.MACRO FCPF @0 ; COMPARE FA REGISTER WITH FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL CPF_FA +.ENDMACRO + +.MACRO FCLR ; CLEAR FA REGISTER 17MAY01 + RCALL MIN_FA +.ENDMACRO + diff --git a/src/avr/makchr.bas b/src/avr/makchr.bas new file mode 100644 index 00000000..143c1fa2 --- /dev/null +++ b/src/avr/makchr.bas @@ -0,0 +1,650 @@ + ' MAKCHR.BAS + ' POWERBASIC VERSION + +' ----------------------------------------------------------------------------- + +$LIB VGA + +$LINK "PUTPCX.OBJ" +DECLARE SUB PUTPCX(STRING) + +$LINK "CHKLIN.OBJ" +DECLARE SUB CHKLIN(INTEGER) + + $INCLUDE "CRCSUBX.INC" + +' ----------------------------------------------------------------------------- + + DIM BLANKT%(300),BLANKB%(300) + DIM DIG%(18,3,4) + DIM BYTES%(16),PREFIX$(255) + + DEF FNH$(N%,L%)=RIGHT$("000"+HEX$(N%),L%) + + FOR D%=0 TO 18 + FOR Y%=0 TO 4 + FOR X%=0 TO 2 + READ Z% + IF Z%=0 THEN DIG%(D%,X%,Y%)=15 + NEXT X% + DIG%(D%,X%,Y%)=15 + NEXT Y% + NEXT D% + INDEX%=0 + + F$=LTRIM$(RTRIM$(COMMAND$)) + I%=INSTR(F$," ") + IF I% THEN + OUTFIL$=LTRIM$(MID$(F$,I%)) + F$=RTRIM$(LEFT$(F$,I%)) + END IF + IF LEN(F$) THEN NO.QUESTION + + CLS + INTERACTIVE%=-1 + INPUT "Filename: [SET00.PCX] ",F$ + +NO.QUESTION: + IF LEN(F$)=0 THEN F$="SET00" + I%=INSTR(F$,".") + IF I% THEN + F0$=LEFT$(F$,I%-1) + F1$=MID$(F$,I%) + ELSE + F0$=F$ + F1$=".PCX" + END IF + + DAT$="" + IDX$=STRING$(512,0) + OVL$="" ' OVERLAYS CHARACTERS 60-FE INCLUSIVE + + IF LEN(F0$)<=5 THEN + COUNTRY$=LEFT$(UCASE$(ENVIRON$("CSC")),3) + F$=F0$+COUNTRY$+F1$ + GOSUB LOAD.PCX + IF PCX.ERROR.FLAG%=0 THEN COUNTRY.SPECIFIC + END IF + F$=F0$+F1$ + GOSUB LOAD.PCX + IF PCX.ERROR.FLAG% THEN + IF CSRLIN=25 THEN PRINT:LOCATE 24,1 + PRINT "FILE NOT FOUND" + END + END IF +COUNTRY.SPECIFIC: + + ' DEFAULTS FOR HEX INFO + XCELL%=5 + YCELL%=7 + ICS%=1 + ILS%=1 + XL0%=&H4F + + ' INTERPRET HEX INFO + Y%=0 +BODGELOOP: + BYT%=0 + X%=0 +BYTLOOP: + FOR II%=0 TO 4 + GOSUB GETHEX + IF DIGITS% THEN BYTES%(BYT%)=HEXNUM%:INCR BYT%:GOTO BYTLOOP + INCR X% + NEXT II% + IF BYT% THEN + LINE (0,Y%)-(X%-1,Y%+4),,BF + IF Y%=0 THEN + IF LEN(OUTFIL$)=0 THEN OUTFIL$="CHSET"+FNH$(BYTES%(0),2)+".WIN" + IF BYT%>1 THEN XCELL%=BYTES%(1) + IF BYT%>2 THEN YCELL%=BYTES%(2) + IF BYT%>3 THEN ICS%=BYTES%(3) + IF BYT%>4 THEN ILS%=BYTES%(4) + IF BYT%>5 THEN XL0%=BYTES%(5) + ELSE + FOR II%=1 TO BYT%-1 + PREFIX$(BYTES%(0))=PREFIX$(BYTES%(0))+CHR$(BYTES%(II%)) + NEXT II% + END IF + INCR Y%,6 + GOTO BODGELOOP + END IF + + IF INTERACTIVE% THEN K$=INPUT$(1) + + ' FIND BLOCKS OF =>3 BLANK LINES IN PICTURE + BSIZ%=0 + BLANKT%(0)=-3 + LAST.FLAG%=0 + FOR Y%=0 TO 479 + FLAG%=Y% + CALL CHKLIN(FLAG%) + IF FLAG%<>LAST.FLAG% THEN + IF LAST.FLAG% THEN + BLANKT%(BSIZ%)=Y% + ELSE + BLANKB%(BSIZ%)=Y% + IF BLANKB%(BSIZ%)-BLANKT%(BSIZ%)=>3 THEN INCR BSIZ% + END IF + END IF + LAST.FLAG%=FLAG% + NEXT Y% + IF LAST.FLAG% THEN BLANKT%(BSIZ%)=480 + BLANKB%(BSIZ%)=483 + INCR BSIZ% + + ' CHECK FOR 1 SET OF CHAR DEFINITIONS BETWEEN EACH PAIR OF BLANKS + FOR BL%=0 TO BSIZ%-3 + YT%=BLANKB%(BL%) + YB%=BLANKT%(BL%+1)-1 + ASCII.FLAG%=0 + FOR XL%=0 TO 639 + IF POINT(XL%,YT%)=0 THEN GOTL + NEXT XL% + ' SHOULD NEVER GET HERE +GOTL: + IF POINT(XL%+1,YT%)=0 THEN SKIP + IF POINT(XL%,YB%) THEN + IF YB%-YT%<8 THEN SKIP ' NO ROOM FOR ASCII + FLAG%=YB%-5 + CALL CHKLIN(FLAG%) + IF FLAG% THEN SKIP ' NO BLANK LINE PRECEDING ASCII + FOR J%=YB%-4 TO YB% + FLAG%=J% + CALL CHKLIN(FLAG%) + IF FLAG%=0 THEN SKIP ' BLANK LINE IN ASCII REGION + NEXT J% + YB%=YB%-6 + ASCII.FLAG%=-1 + XASC%=0 + IF POINT(XL%,YB%) THEN SKIP + END IF + IF POINT(XL%+1,YB%)=0 THEN SKIP + + FLAG%=YT%+1 + CALL CHKLIN(FLAG%) + IF FLAG% THEN SKIP ' NO BLANK LINE BELOW TOP + FLAG%=YB%-1 + CALL CHKLIN(FLAG%) + IF FLAG% THEN SKIP ' NO BLANK LINE ABOVE BOT + + FOR XR%=639 TO 0 STEP -1 + IF POINT(XR%,YT%)=0 THEN GOTR + NEXT XR% + ' SHOULD NEVER GET HERE +GOTR: + IF XR%-XL%<2 THEN SKIP + FOR YY%=YT% TO YB% + IF POINT(XL%,YY%)<>POINT(XR%,YY%) THEN SKIP + NEXT YY% + BREAKS%=0 + FOR YY%=YT%+2 TO YB%-2 + IF POINT(XL%,YY%) THEN INCR BREAKS% + NEXT YY% + IF BREAKS%>2 THEN SKIP + + ASCEND.FLAG%=0 + DESCEND.FLAG%=0 + IF BREAKS% THEN + FOR YY%=YB%-2 TO YT%+2 STEP -1 + IF POINT(XL%,YY%) THEN DESCEND.FLAG%=YB%-YY%-1:GOTO GOTDES + NEXT YY% + END IF +GOTDES: + IF BREAKS%>1 THEN + FOR YY%=YT%+2 TO YB%-2 + IF POINT(XL%,YY%) THEN ASCEND.FLAG%=YY%-YT%-1:GOTO GOTAS + NEXT YY% + END IF +GOTAS: + HEIGHT%=YB%-YT%-3-ASCEND.FLAG%-DESCEND.FLAG% + + Y0%=YT%+2 + Y1%=YB%-2 + FOR XX%=XL%+2 TO XR%-2 + IF POINT(XX%,YT%)=0 OR POINT(XX%,YB%)=0 THEN + X0%=XX% + FOR XX%=XX% TO XR%-3 + IF POINT(XX%+1,YT%) AND POINT(XX%+1,YB%) THEN GOTX1 + NEXT XX% +GOTX1: + X1%=XX% + GOSUB CHAR + END IF + NEXT XX% + +SKIP: + NEXT BL% + + IDX_20$=MID$(IDX$,&H20*2+1,2) + IDX_30$=MID$(IDX$,&H30*2+1,2) + IDX_4F$=MID$(IDX$,&H4F*2+1,2) + IDX_FF$=MID$(IDX$,&HFF*2+1,2) + + FOR CHK%=0 TO 254 + IDX_CHK$=MID$(IDX$,CHK%*2+1,2) + IF IDX_CHK$=MKI$(0) THEN + IF LEN(PREFIX$(CHK%)) THEN + INDEX%=CHK% + P$="" + D$="" + XB%=0 + GOSUB ADDCHR + ELSE + IF CHK%=&H30 THEN IDX_CHK$=IDX_4F$ + IF CHK%=&H4F THEN IDX_CHK$=IDX_30$ + IF IDX_CHK$=MKI$(0) THEN IDX_CHK$=IDX_FF$ + IF IDX_CHK$=MKI$(0) THEN IDX_CHK$=IDX_20$ + MID$(IDX$,CHK%*2+1,2)=IDX_CHK$ + END IF + END IF + NEXT CHK% + + MID$(IDX$, 1+&H100)=OVL$ ' OVERLAYS CHARACTERS 80-FF INCLUSIVE + + ' SEARCH FOR &H208 IF ADD ANYTHING HERE + IDX$=IDX$+CHR$(XCELL%+ICS%)+CHR$(YCELL%+ILS%)+ _ + CHR$(ICS%)+CHR$(ILS%)+ _ + CHR$(XL0%)+CHR$(0)+MKI$(0) ' SPARE BYTE, FILE LENGTH WORD + + IF LEN(OUTFIL$) THEN + L0%=LEN(IDX$)+LEN(DAT$)+16 + L1%=L0% ' TSV4 (L0%+&H7F) AND &HFF80 + PAD$=STRING$(L1%-L0%, &H1A) + MID$(IDX$, 1+&H206)=MKI$(L1%) + + TT$=TIME$ + DD$=DATE$ + TD$=RIGHT$(DD$,2)+MID$(DD$,4,2)+LEFT$(DD$,2) + TD$=TD$+LEFT$(TT$,2)+MID$(TT$,4,2)+RIGHT$(TT$,2) + CRC%=-1 + CRC_CALCULATE CRC%, TD$ + CRC_CALCULATE CRC%, IDX$ + CRC_CALCULATE CRC%, DAT$ + CRC_CALCULATE CRC%, PAD$ + TD$=FNH$(CRC%,4)+TD$ + + ON ERROR GOTO HUJ + KILL OUTFIL$ + ON ERROR GOTO 0 +HUJU: + OPEN OUTFIL$ FOR BINARY AS #1 + PUT$ #1,TD$ + PUT$ #1,IDX$ + PUT$ #1,DAT$ + PUT$ #1,PAD$ + CLOSE #1 + END IF + + OPEN "MAKCHR.LOG" FOR OUTPUT AS #1 + FOR I%=0 TO &H5F '&HFF + P%=CVI(MID$(IDX$,I%*2+1,2)) + IF P% THEN + L$="CHR="+FNH$(I%,2)+" PTR="+FNH$(P%,4)+" " + P%=P%+1 ' TSV4 -LEN(IDX$)+1 + XS%=ASC(MID$(IDX$+DAT$,P%,1)) ' TSV4 DAT$,P%,1)) + IF (XS% AND &H1F) THEN + L$=L$+"XB="+USING$("####",XS% AND &H1F)+" " + YS%=ASC(MID$(IDX$+DAT$,P%+1,1)) ' TSV4 DAT$,P%+1,1)) + L$=L$+"YB="+USING$("####",YS%)+" " + ELSE + L$=L$+SPACE$(16) + END IF + IF (XS% AND &H80) THEN + XO%=ASC(MID$(IDX$+DAT$,P%-3,1)) ' TSV4 DAT$,P%-3,1)) + L$=L$+"XO="+USING$("####",XO%)+" " + ELSE + L$=L$+SPACE$(8) + END IF + IF (XS% AND &H40) THEN + YO%=ASC(MID$(IDX$+DAT$,P%-2,1)) ' TSV4 DAT$,P%-2,1)) + L$=L$+"YO="+USING$("####",YO%)+" " + ELSE + L$=L$+SPACE$(8) + END IF + IF (XS% AND &H20) THEN + PW%=ASC(MID$(IDX$+DAT$,P%-1,1)) ' TSV4 DAT$,P%-1,1)) + L$=L$+"PW="+USING$("####",PW%)+" " + ELSE + L$=L$+SPACE$(8) + END IF + PRINT #1,RTRIM$(L$) + END IF + NEXT I% + + IF INTERACTIVE% THEN K$=INPUT$(1) + SCREEN 0 + END + +HUJ: + RESUME HUJU + +' ----------------------------------------------------------------------------- + +CHAR: + ' CHECK FOR ASCII CODE BENEATH MATRIX + IF ASCII.FLAG% AND X0%=>XASC% THEN + X%=X0% + Y%=YB%+2 + FOR YY%=Y% TO Y%+4 + IF POINT(X%,YY%)=0 THEN + GOSUB GETHEX + IF DIGITS% THEN + INDEX%=HEXNUM% ':PRINT " " HEX$(INDEX%); + XASC%=X% + END IF + GOTO GOTINDEX + END IF + NEXT YY% + END IF +GOTINDEX: + + ' SET VERTICAL ANCHOR + IF BREAKS% THEN + YA%=Y0%+ASCEND.FLAG%+HEIGHT%-YCELL% + ELSE + YA%=Y0% + END IF + + ' INTERPRET TOP GUARD BAR (FIRST PIXEL GIVES HORIZONTAL ANCHOR) + FOR XA%=X0% TO X1% + IF POINT(XA%,YT%)=0 THEN GOTANCHOR + NEXT XA% +GOTANCHOR: + ' INTERPRET BOTTOM GUARD BAR (LAST PIXEL GIVES WIDTH) + FOR X%=X1% TO XA% STEP -1 + IF POINT(X%,YB%)=0 THEN GOTWID + NEXT X% +GOTWID: + WID%=X%+1-XA% + IF WID%>0 THEN WID%=WID%+ICS% + P$="" + D$="" + + ' FIND CHAR EXTENTS + XMIN%=999:XMAX%=-1 + YMIN%=999:YMAX%=-1 + FOR X%=X0% TO X1% + FOR Y%=Y0% TO Y1% + IF POINT(X%,Y%)=0 THEN + IF X%XMAX% THEN XMAX%=X% + IF Y%YMAX% THEN YMAX%=Y% + END IF + NEXT Y% + NEXT X% + XS%=XMAX%+1-XMIN% + YS%=YMAX%+1-YMIN% + IF XS%<=0 OR YS%<=0 THEN XB%=0:GOTO BLANKCHR + + XB%=INT((XS%+7)/8) + + ' ELIMINATE X/Y OFFSETS IF MORE ECONOMICAL + FIXED%=0 + IF WID%<>XCELL%+ICS% THEN FIXED%=1 + ' TRY WITHOUT Y OFFSET, BUT ONLY TO SET FIXED% YMIN2% YS2% + YMIN2%=YMIN%:YS2%=YS% + IF YMIN2%>YA% THEN + YS3%=YMAX%+1-YA% + IF (XB%*YS3%+FIXED%)<=(XB%*YS%+2) THEN YMIN2%=YA%:YS2%=YS3% + END IF + IF YMIN2%<>YA% THEN FIXED%=2 + ' TRY WITHOUT X OFFSET + IF XMIN%>XA% THEN + XS2%=XMAX%+1-XA% + XB2%=INT((XS2%+7)/8) + IF (XB2%*YS2%+FIXED%)<=(XB%*YS%+3) THEN XMIN%=XA%:XS%=XS2%:XB%=XB2% + END IF + IF XMIN%=XA% THEN YMIN%=YMIN2%:YS%=YS2% + + ' ENCODE CHARACTER + D$=CHR$(YS%) + XMAX%=XMIN%+XB%*8-1 + IF XMAX%>X1% THEN XMAX%=X1% + FOR Y%=YMIN% TO YMAX% + C%=0 + O%=&H80 + BG%=7 '9 + FOR X%=XMIN% TO XMAX% + IF POINT(X%,Y%)=0 THEN C%=C% OR O% ELSE PSET (X%,Y%),BG% + O%=INT(O%/2) + IF O%=0 THEN + D$=D$+CHR$(C%) + C%=0 + O%=&H80 + ' BG%=BG% XOR 8 + END IF + NEXT X% + IF O%<>&H80 THEN D$=D$+CHR$(C%) + NEXT Y% + IF XA%<>XMIN% THEN XOFF + IF YA%<>YMIN% THEN YOFF +BLANKCHR: + IF WID%<>XCELL%+ICS% THEN WD + GOTO ADDCHR + +XOFF: + P$=CHR$((XMIN%-XA%) AND &HFF) + XB%=XB% OR &H80 +YOFF: + P$=P$+CHR$((YMIN%-YA%) AND &HFF) + XB%=XB% OR &H40 +WD: + P$=P$+CHR$(WID%) + XB%=XB% OR &H20 + +ADDCHR: + I%=LEN(PREFIX$(INDEX%)) + IF I%>LEN(P$) THEN + P$=PREFIX$(INDEX%) + XB%=XB% OR &H20 + IF I%=>2 THEN XB%=XB% OR &H40 + IF I%=>3 THEN XB%=XB% OR &H80 + ELSEIF I%>0 THEN + P$=LEFT$(P$,LEN(P$)-I%)+PREFIX$(INDEX%) + END IF + PD$=P$+CHR$(XB%)+D$ + I%=INSTR(OVL$,PD$) ' TSV4 + IF I%=0 THEN + IF LEN(OVL$)+LEN(PD$)>&HFE THEN ' OVERLAYS CHARACTERS 80-FE INCLUSIVE + I%=INSTR(DAT$,PD$) + IF I%=0 THEN I%=LEN(DAT$)+1:DAT$=DAT$+PD$ + MID$(IDX$,INDEX%*2+1,2)=MKI$(I%+LEN(P$)+&H208-1) + INCR INDEX% + RETURN + END IF + I%=LEN(OVL$)+1:OVL$=OVL$+PD$ + END IF + MID$(IDX$,INDEX%*2+1,2)=MKI$(I%+LEN(P$)+&H100-1) + INCR INDEX% + RETURN + + ' IF ASCEND.FLAG% THEN LINE (X0%,YT%+2)-(X1%,YT%+1+ASCEND.FLAG%),4,BF + ' LINE (X0%,YT%+2+ASCEND.FLAG%)-(X1%,YB%-2-DESCEND.FLAG%),12,BF + ' IF DESCEND.FLAG% THEN LINE (X0%,YB%-1-DESCEND.FLAG%)-(X1%,YB%-2),4,BF + ' RETURN + +' ----------------------------------------------------------------------------- + +LOAD.PCX: + ON ERROR GOTO PCX.ERROR + OPEN F$ FOR INPUT AS #1 + CLOSE #1 + ON ERROR GOTO 0 + OPEN F$ FOR BINARY AS #1 + GET$ #1,32700,A$ + CLOSE + IF LEN(A$)=0 THEN KILL F$:RETURN + SCREEN 12 + CALL PUTPCX(A$) + A$="" + PCX.ERROR.FLAG%=0 + RETURN + +PCX.ERROR: + PCX.ERROR.FLAG%=-1 + RESUME PCX.ERROR.2 +PCX.ERROR.2: + RETURN + +' ----------------------------------------------------------------------------- + +GETHEX: + DIGITS%=0 + HEXNUM%=0 +HEXLOOP: + FOR D%=0 TO 18 + IF D%=16 THEN WID%=2 ELSE WID%=4 + FOR XH%=0 TO WID%-1 + FOR YH%=0 TO 4 + IF POINT(X%+XH%,Y%+YH%)<>DIG%(D%,XH%,YH%) THEN NOTDIG + NEXT YH% + NEXT XH% + IF D%=16 THEN D%=1 + IF D%=17 THEN D%=6 + IF D%=18 THEN D%=9 + HEXNUM%=HEXNUM%*16+D% + INCR DIGITS% + INCR X%,WID% + IF DIGITS%=>2 THEN RETURN ' BYTES ONLY + GOTO HEXLOOP +NOTDIG: + NEXT D% + RETURN + + ' 0 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,0,1 + DATA 1,0,1 + DATA 1,1,1 + + ' 1 + DATA 0,0,1 + DATA 0,0,1 + DATA 0,0,1 + DATA 0,0,1 + DATA 0,0,1 + + ' 2 + DATA 1,1,1 + DATA 0,0,1 + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + + ' 3 + DATA 1,1,1 + DATA 0,0,1 + DATA 1,1,1 + DATA 0,0,1 + DATA 1,1,1 + + ' 4 + DATA 1,0,1 + DATA 1,0,1 + DATA 1,1,1 + DATA 0,0,1 + DATA 0,0,1 + + ' 5 + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + DATA 0,0,1 + DATA 1,1,1 + + ' 6 + DATA 1,0,0 + DATA 1,0,0 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + + ' 7 + DATA 1,1,1 + DATA 0,0,1 + DATA 0,0,1 + DATA 0,0,1 + DATA 0,0,1 + + ' 8 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + + ' 9 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + DATA 0,0,1 + DATA 0,0,1 + + ' A + DATA 0,1,0 + DATA 1,0,1 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,0,1 + + ' B + DATA 1,1,0 + DATA 1,0,1 + DATA 1,1,0 + DATA 1,0,1 + DATA 1,1,0 + + ' C + DATA 0,1,0 + DATA 1,0,1 + DATA 1,0,0 + DATA 1,0,1 + DATA 0,1,0 + + ' D + DATA 1,1,0 + DATA 1,0,1 + DATA 1,0,1 + DATA 1,0,1 + DATA 1,1,0 + + ' E + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + + ' F + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + DATA 1,0,0 + DATA 1,0,0 + + ' 1 ALTERNATE + DATA 1,0,0 + DATA 1,0,0 + DATA 1,0,0 + DATA 1,0,0 + DATA 1,0,0 + + ' 6 ALTERNATE + DATA 1,1,1 + DATA 1,0,0 + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + + ' 9 ALTERNATE + DATA 1,1,1 + DATA 1,0,1 + DATA 1,1,1 + DATA 0,0,1 + DATA 1,1,1 + +' ----------------------------------------------------------------------------- + diff --git a/src/avr/makchr.exe b/src/avr/makchr.exe new file mode 100644 index 0000000000000000000000000000000000000000..4386ca75a2d17ae7c447761455e101a83bbad192 GIT binary patch literal 53976 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 CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + +; ----------------------------------------------------------------------------- + +;TEXT_RESET: +; ; ENTRY POINT FROM RX_WAIT +; LDI A,LOW(RAMEND) +; OUT SPL,A ; INIT STACK POINTER + +TEXT_RECEIVE: + ; NEXT LINE STARTS WITH RECEIVED CHAR + CLR CHAR_SAVE + +; CLR ABORT_COUNT ; NO NEED TO ABORT ESC SEQUENCE +; CBR FLAGS,1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT*2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mt102v0.asm b/src/avr/mt102v0.asm new file mode 100644 index 00000000..a9902eaf --- /dev/null +++ b/src/avr/mt102v0.asm @@ -0,0 +1,1831 @@ +; MT102V0.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =5 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =48 ; 384 / 8 = 48 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =42 ; 384 / 9 = 42 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =6 ; (42+7) / 8 = 6 WIDTH FLAG BYTES + +.EQU TIME_STEP =72 ; 72 * 25 US = APPROX 1.8 MS +.EQU TIME_CLOCK =2 ; 2 * 25 US = APPROX 50 US + +.EQU TIME_STROBE =24 ; 24 * 25 US = APPROX 600 US +.EQU TIME_HOLD_PWM =1 ; DELAY UNIT FOR ABOVE = APPROX 25 US + +.EQU TIME_PAPER_OUT =12 ; 12 * 25 US = APPROX 300 US + +.EQU TIME_DEBOUNCE0 =1000 ; 1000 * 100 US = APPROX 100.0 MS +;.EQU TIME_DEBOUNCE1 =1 ; 10 * 100 US = APPROX 1.0 MS +.EQU TIME_SHORTING =1000 ; 1000 * 100 US = APPROX 100.0 MS +.EQU TIME_CUTTER =20000 ; 20000 * 100 US = APPROX 2.0 S +.EQU TIME_SAMPLE =4 ; DELAY UNIT FOR ABOVE = APPROX 100 US + +;.EQU FEED_INITIAL =2 ; LINES WASTED STARTING MOTOR +.EQU FEED_SPACING =3 ; LINES TO FEED BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF MOTOR_STATE =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF STATUS =R14 +.DEF SR =R15 + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF FLAGS =R23 + +.DEF DOTS_ON_LO =R24 +.DEF DOTS_ON_HI =R25 ; COUNT OF DOTS ON FOR LINE + +.EQU TX_SIZE =1 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_IMAGE +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE +SCALE_TEXT: .BYTE 1 +SCALE_IMAGE: .BYTE 1 +NOTIFY_COUNT: .BYTE 1 + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU IMAGE =2 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =3 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU CUT =4 ; SET BY FG FOR BG TO OPERATE CUTTER +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +.EQU ASCEND =7 ; SET BY FG, ASCENDER ALLOWED NEXT LINE +;.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY BG TO NOTIFY MOTOR RUN STATUS +.EQU CUTTER =2 ; SET BY BG TO NOTIFY CUTTER RUN STATUS +.EQU HEADUP =3 ; SET BY BG TO NOTIFY HEAD UP STATUS +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE PROCESSING ESC . CMD +; UPPER 2 BITS ARE USED TO COUNT 4 * 256 * 25 US = 25.6 MS BETWEEN PAPER TESTS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','T','1','0','2' +; .DB 'A',' ','P','R','I','N','T','E' +; .DB 'R',$0D + +; ----------------------------------------------------------------------------- +; TIMER 0 OVERFLOW INTERRUPT HANDLER + +T0_OVERFLOW: + IN SR,SREG ; SAVE FLAGS + + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + + LDI G,-TIME_STEP + OUT TCNT0,G ; DEFAULT DELAY TO NEXT STEP INTERRUPT + + WDR ; FEED WATCHDOG + RET ; VECTOR TO INTERRUPT SERVICE ROUTINE + +T0_DONE: + POP H + POP G ; RETRIEVE INTERRUPT SERVICE VECTOR + +T0_RET: + OUT SREG,SR ; RESTORE FLAGS + RETI + +; ----------------------------------------------------------------------------- + +T0_FEED: + DEC FEEDS + + RCALL T0_STEP_EVEN ; OUTPUT NEXT MOTOR STATE + + RCALL T0_DONE + + RCALL T0_STEP_ODD ; OUTPUT NEXT MOTOR STATE + +T0_MAIN: + RCALL T0_DONE + +T0_MAIN_ENTRY: + ;MOV D,FEEDS + ;CPI D,1+FEED_INITIAL + ;BRSH T0_PRINT ; WE HAVE SOMETHING TO PRINT + TST FEEDS + BRNE T0_PRINT ; WE HAVE SOMETHING TO PRINT + + MOV D,FLAGS + ANDI D,(1< CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT+2) ; 06apr03 tavrasm (EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC ; 06apr03 tavrasm *2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + LDI A,~(1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT ; 06apr03 tavrasm *2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 0 ENABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACB2 ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mt102v1.asm b/src/avr/mt102v1.asm new file mode 100644 index 00000000..2d1247d3 --- /dev/null +++ b/src/avr/mt102v1.asm @@ -0,0 +1,1831 @@ +; MT102V1.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =5 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =48 ; 384 / 8 = 48 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =42 ; 384 / 9 = 42 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =6 ; (42+7) / 8 = 6 WIDTH FLAG BYTES + +.EQU TIME_STEP =72 ; 72 * 25 US = APPROX 1.8 MS +.EQU TIME_CLOCK =2 ; 2 * 25 US = APPROX 50 US + +.EQU TIME_STROBE =24 ; 24 * 25 US = APPROX 600 US +.EQU TIME_HOLD_PWM =1 ; DELAY UNIT FOR ABOVE = APPROX 25 US + +.EQU TIME_PAPER_OUT =12 ; 12 * 25 US = APPROX 300 US + +.EQU TIME_DEBOUNCE0 =1000 ; 1000 * 100 US = APPROX 100.0 MS +;.EQU TIME_DEBOUNCE1 =1 ; 10 * 100 US = APPROX 1.0 MS +.EQU TIME_SHORTING =1000 ; 1000 * 100 US = APPROX 100.0 MS +.EQU TIME_CUTTER =20000 ; 20000 * 100 US = APPROX 2.0 S +.EQU TIME_SAMPLE =4 ; DELAY UNIT FOR ABOVE = APPROX 100 US + +;.EQU FEED_INITIAL =2 ; LINES WASTED STARTING MOTOR +.EQU FEED_SPACING =3 ; LINES TO FEED BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF MOTOR_STATE =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF STATUS =R14 +.DEF SR =R15 + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF FLAGS =R23 + +.DEF DOTS_ON_LO =R24 +.DEF DOTS_ON_HI =R25 ; COUNT OF DOTS ON FOR LINE + +.EQU TX_SIZE =1 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_IMAGE +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE +SCALE_TEXT: .BYTE 1 +SCALE_IMAGE: .BYTE 1 +NOTIFY_COUNT: .BYTE 1 + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU IMAGE =2 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =3 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU CUT =4 ; SET BY FG FOR BG TO OPERATE CUTTER +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +.EQU ASCEND =7 ; SET BY FG, ASCENDER ALLOWED NEXT LINE +;.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY BG TO NOTIFY MOTOR RUN STATUS +.EQU CUTTER =2 ; SET BY BG TO NOTIFY CUTTER RUN STATUS +.EQU HEADUP =3 ; SET BY BG TO NOTIFY HEAD UP STATUS +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE PROCESSING ESC . CMD +; UPPER 2 BITS ARE USED TO COUNT 4 * 256 * 25 US = 25.6 MS BETWEEN PAPER TESTS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','T','1','0','2' +; .DB 'A',' ','P','R','I','N','T','E' +; .DB 'R',$0D + +; ----------------------------------------------------------------------------- +; TIMER 0 OVERFLOW INTERRUPT HANDLER + +T0_OVERFLOW: + IN SR,SREG ; SAVE FLAGS + + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + + LDI G,-TIME_STEP + OUT TCNT0,G ; DEFAULT DELAY TO NEXT STEP INTERRUPT + + WDR ; FEED WATCHDOG + RET ; VECTOR TO INTERRUPT SERVICE ROUTINE + +T0_DONE: + POP H + POP G ; RETRIEVE INTERRUPT SERVICE VECTOR + +T0_RET: + OUT SREG,SR ; RESTORE FLAGS + RETI + +; ----------------------------------------------------------------------------- + +T0_FEED: + DEC FEEDS + + RCALL T0_STEP_EVEN ; OUTPUT NEXT MOTOR STATE + + RCALL T0_DONE + + RCALL T0_STEP_ODD ; OUTPUT NEXT MOTOR STATE + +T0_MAIN: + RCALL T0_DONE + +T0_MAIN_ENTRY: + ;MOV D,FEEDS + ;CPI D,1+FEED_INITIAL + ;BRSH T0_PRINT ; WE HAVE SOMETHING TO PRINT + TST FEEDS + BRNE T0_PRINT ; WE HAVE SOMETHING TO PRINT + + MOV D,FLAGS + ANDI D,(1< CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT+2) ; 06apr03 tavrasm (EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC ; 06apr03 tavrasm *2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + LDI A,~(1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT ; 06apr03 tavrasm *2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mt102v1.asm.orig b/src/avr/mt102v1.asm.orig new file mode 100644 index 00000000..aaffef07 --- /dev/null +++ b/src/avr/mt102v1.asm.orig @@ -0,0 +1,1831 @@ +; MT102V1.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =5 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$47 ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$23 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$11 ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =48 ; 384 / 8 = 48 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =42 ; 384 / 9 = 42 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =6 ; (42+7) / 8 = 6 WIDTH FLAG BYTES + +.EQU TIME_STEP =72 ; 72 * 25 US = APPROX 1.8 MS +.EQU TIME_CLOCK =2 ; 2 * 25 US = APPROX 50 US + +.EQU TIME_STROBE =24 ; 24 * 25 US = APPROX 600 US +.EQU TIME_HOLD_PWM =1 ; DELAY UNIT FOR ABOVE = APPROX 25 US + +.EQU TIME_PAPER_OUT =12 ; 12 * 25 US = APPROX 300 US + +.EQU TIME_DEBOUNCE0 =1000 ; 1000 * 100 US = APPROX 100.0 MS +;.EQU TIME_DEBOUNCE1 =1 ; 10 * 100 US = APPROX 1.0 MS +.EQU TIME_SHORTING =1000 ; 1000 * 100 US = APPROX 100.0 MS +.EQU TIME_CUTTER =20000 ; 20000 * 100 US = APPROX 2.0 S +.EQU TIME_SAMPLE =4 ; DELAY UNIT FOR ABOVE = APPROX 100 US + +;.EQU FEED_INITIAL =2 ; LINES WASTED STARTING MOTOR +.EQU FEED_SPACING =3 ; LINES TO FEED BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF MOTOR_STATE =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF STATUS =R14 +.DEF SR =R15 + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF FLAGS =R23 + +.DEF DOTS_ON_LO =R24 +.DEF DOTS_ON_HI =R25 ; COUNT OF DOTS ON FOR LINE + +.EQU TX_SIZE =1 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_IMAGE +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE +SCALE_TEXT: .BYTE 1 +SCALE_IMAGE: .BYTE 1 +NOTIFY_COUNT: .BYTE 1 + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU IMAGE =2 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =3 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU CUT =4 ; SET BY FG FOR BG TO OPERATE CUTTER +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +.EQU ASCEND =7 ; SET BY FG, ASCENDER ALLOWED NEXT LINE +;.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY BG TO NOTIFY MOTOR RUN STATUS +.EQU CUTTER =2 ; SET BY BG TO NOTIFY CUTTER RUN STATUS +.EQU HEADUP =3 ; SET BY BG TO NOTIFY HEAD UP STATUS +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE PROCESSING ESC . CMD +; UPPER 2 BITS ARE USED TO COUNT 4 * 256 * 25 US = 25.6 MS BETWEEN PAPER TESTS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','T','1','0','2' +; .DB 'A',' ','P','R','I','N','T','E' +; .DB 'R',$0D + +; ----------------------------------------------------------------------------- +; TIMER 0 OVERFLOW INTERRUPT HANDLER + +T0_OVERFLOW: + IN SR,SREG ; SAVE FLAGS + + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + + LDI G,-TIME_STEP + OUT TCNT0,G ; DEFAULT DELAY TO NEXT STEP INTERRUPT + + WDR ; FEED WATCHDOG + RET ; VECTOR TO INTERRUPT SERVICE ROUTINE + +T0_DONE: + POP H + POP G ; RETRIEVE INTERRUPT SERVICE VECTOR + +T0_RET: + OUT SREG,SR ; RESTORE FLAGS + RETI + +; ----------------------------------------------------------------------------- + +T0_FEED: + DEC FEEDS + + RCALL T0_STEP_EVEN ; OUTPUT NEXT MOTOR STATE + + RCALL T0_DONE + + RCALL T0_STEP_ODD ; OUTPUT NEXT MOTOR STATE + +T0_MAIN: + RCALL T0_DONE + +T0_MAIN_ENTRY: + ;MOV D,FEEDS + ;CPI D,1+FEED_INITIAL + ;BRSH T0_PRINT ; WE HAVE SOMETHING TO PRINT + TST FEEDS + BRNE T0_PRINT ; WE HAVE SOMETHING TO PRINT + + MOV D,FLAGS + ANDI D,(1< CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + LDI A,~(1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT*2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACBA ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mt102v2.asm b/src/avr/mt102v2.asm new file mode 100644 index 00000000..c285aadd --- /dev/null +++ b/src/avr/mt102v2.asm @@ -0,0 +1,1831 @@ +; MT102V2.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =5 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$5F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$2F ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$17 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$0B ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$03 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =48 ; 384 / 8 = 48 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =42 ; 384 / 9 = 42 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =6 ; (42+7) / 8 = 6 WIDTH FLAG BYTES + +.EQU TIME_STEP =72 ; 72 * 25 US = APPROX 1.8 MS +.EQU TIME_CLOCK =2 ; 2 * 25 US = APPROX 50 US + +.EQU TIME_STROBE =24 ; 24 * 25 US = APPROX 600 US +.EQU TIME_HOLD_PWM =1 ; DELAY UNIT FOR ABOVE = APPROX 25 US + +.EQU TIME_PAPER_OUT =12 ; 12 * 25 US = APPROX 300 US + +.EQU TIME_DEBOUNCE0 =1000 ; 1000 * 100 US = APPROX 100.0 MS +;.EQU TIME_DEBOUNCE1 =1 ; 10 * 100 US = APPROX 1.0 MS +.EQU TIME_SHORTING =1000 ; 1000 * 100 US = APPROX 100.0 MS +.EQU TIME_CUTTER =20000 ; 20000 * 100 US = APPROX 2.0 S +.EQU TIME_SAMPLE =4 ; DELAY UNIT FOR ABOVE = APPROX 100 US + +;.EQU FEED_INITIAL =2 ; LINES WASTED STARTING MOTOR +.EQU FEED_SPACING =3 ; LINES TO FEED BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF MOTOR_STATE =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF STATUS =R14 +.DEF SR =R15 + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF FLAGS =R23 + +.DEF DOTS_ON_LO =R24 +.DEF DOTS_ON_HI =R25 ; COUNT OF DOTS ON FOR LINE + +.EQU TX_SIZE =1 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_IMAGE +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE +SCALE_TEXT: .BYTE 1 +SCALE_IMAGE: .BYTE 1 +NOTIFY_COUNT: .BYTE 1 + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU IMAGE =2 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =3 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU CUT =4 ; SET BY FG FOR BG TO OPERATE CUTTER +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +.EQU ASCEND =7 ; SET BY FG, ASCENDER ALLOWED NEXT LINE +;.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY BG TO NOTIFY MOTOR RUN STATUS +.EQU CUTTER =2 ; SET BY BG TO NOTIFY CUTTER RUN STATUS +.EQU HEADUP =3 ; SET BY BG TO NOTIFY HEAD UP STATUS +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE PROCESSING ESC . CMD +; UPPER 2 BITS ARE USED TO COUNT 4 * 256 * 25 US = 25.6 MS BETWEEN PAPER TESTS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','T','1','0','2' +; .DB 'A',' ','P','R','I','N','T','E' +; .DB 'R',$0D + +; ----------------------------------------------------------------------------- +; TIMER 0 OVERFLOW INTERRUPT HANDLER + +T0_OVERFLOW: + IN SR,SREG ; SAVE FLAGS + + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + + LDI G,-TIME_STEP + OUT TCNT0,G ; DEFAULT DELAY TO NEXT STEP INTERRUPT + + WDR ; FEED WATCHDOG + RET ; VECTOR TO INTERRUPT SERVICE ROUTINE + +T0_DONE: + POP H + POP G ; RETRIEVE INTERRUPT SERVICE VECTOR + +T0_RET: + OUT SREG,SR ; RESTORE FLAGS + RETI + +; ----------------------------------------------------------------------------- + +T0_FEED: + DEC FEEDS + + RCALL T0_STEP_EVEN ; OUTPUT NEXT MOTOR STATE + + RCALL T0_DONE + + RCALL T0_STEP_ODD ; OUTPUT NEXT MOTOR STATE + +T0_MAIN: + RCALL T0_DONE + +T0_MAIN_ENTRY: + ;MOV D,FEEDS + ;CPI D,1+FEED_INITIAL + ;BRSH T0_PRINT ; WE HAVE SOMETHING TO PRINT + TST FEEDS + BRNE T0_PRINT ; WE HAVE SOMETHING TO PRINT + + MOV D,FLAGS + ANDI D,(1< CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT+2) ; 06apr03 tavrasm (EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC ; 06apr03 tavrasm *2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + LDI A,~(1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT ; 06apr03 tavrasm *2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 0 ENABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACB2 ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/mt102v2.asm.orig b/src/avr/mt102v2.asm.orig new file mode 100644 index 00000000..84db6f95 --- /dev/null +++ b/src/avr/mt102v2.asm.orig @@ -0,0 +1,1831 @@ +; MT102V2.ASM + +; ----------------------------------------------------------------------------- + +.INCLUDE "4433DEF.INC" +.INCLUDE "API.INC" +;.INCLUDE "TER.INC" + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_ADDRESS =5 ; MY ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 US = APPROX 5.0 MS +.EQU API_RATE_SLOW =$5F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ; DIVISOR FOR 115200 BPS +;.EQU TER_RATE =$2F ; DIVISOR FOR 9600 BPS +;.EQU TER_RATE =$17 ; DIVISOR FOR 19200 BPS +;.EQU TER_RATE =$0B ; DIVISOR FOR 38400 BPS +.EQU TER_RATE =$03 ; DIVISOR FOR 115200 BPS + +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.EQU DEFINABLE_CHARS =32 ; REALLY ONLY 22 + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +.EQU WIDTH_IMAGE =48 ; 384 / 8 = 48 IMAGE BYTES ACROSS +.EQU WIDTH_CHARS =42 ; 384 / 9 = 42 TEXT CHARACTERS ACROSS +.EQU WIDTH_FLAGS =6 ; (42+7) / 8 = 6 WIDTH FLAG BYTES + +.EQU TIME_STEP =72 ; 72 * 25 US = APPROX 1.8 MS +.EQU TIME_CLOCK =2 ; 2 * 25 US = APPROX 50 US + +.EQU TIME_STROBE =24 ; 24 * 25 US = APPROX 600 US +.EQU TIME_HOLD_PWM =1 ; DELAY UNIT FOR ABOVE = APPROX 25 US + +.EQU TIME_PAPER_OUT =12 ; 12 * 25 US = APPROX 300 US + +.EQU TIME_DEBOUNCE0 =1000 ; 1000 * 100 US = APPROX 100.0 MS +;.EQU TIME_DEBOUNCE1 =1 ; 10 * 100 US = APPROX 1.0 MS +.EQU TIME_SHORTING =1000 ; 1000 * 100 US = APPROX 100.0 MS +.EQU TIME_CUTTER =20000 ; 20000 * 100 US = APPROX 2.0 S +.EQU TIME_SAMPLE =4 ; DELAY UNIT FOR ABOVE = APPROX 100 US + +;.EQU FEED_INITIAL =2 ; LINES WASTED STARTING MOTOR +.EQU FEED_SPACING =3 ; LINES TO FEED BETWEEN TEXT LINES +.EQU FEED_TAKE_UP =120 ; LINES TO FEED WHEN PAPER INSERTED + +.DEF RX_PTR =R01 +.DEF RX_COUNT =R02 +.DEF TX_PTR =R03 +.DEF TX_COUNT =R04 +.DEF API_STATE =R05 +.DEF API_REMAIN =R06 +.DEF API_WATCHDOG =R07 +.DEF CHAR_SAVE =R08 +.DEF BUF_PTR =R09 ; BYTES NOT YET COMMITTED FOR PRINT +.DEF MOTOR_STATE =R10 ; TIMING PULSE COUNT +.DEF FEEDS =R11 ; INTERNAL FEED COUNT +.DEF SPACING =R12 ; SET WITH ESC A +.DEF TEXT_MASK =R13 ; MASK FOR CURRENT DOT LINE +.DEF STATUS =R14 +.DEF SR =R15 + +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R20 +.DEF G =R21 +.DEF H =R22 +.DEF FLAGS =R23 + +.DEF DOTS_ON_LO =R24 +.DEF DOTS_ON_HI =R25 ; COUNT OF DOTS ON FOR LINE + +.EQU TX_SIZE =1 +.EQU RX_SIZE =$40 + + .DSEG + .ORG $60 + +PRINT_BUF: .BYTE WIDTH_IMAGE +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE +SCALE_TEXT: .BYTE 1 +SCALE_IMAGE: .BYTE 1 +NOTIFY_COUNT: .BYTE 1 + +; ----------------------------------------------------------------------------- + + .ESEG + + .DB 0,0 ; DON'T USE ADDRESS 0 +EE_CRC: .DB 0,0 +EE_LENGTH: .DB 0,0 +EE_COUNT: .DB 0,0 + +; ----------------------------------------------------------------------------- + +; FLAGS DEFINITIONS +.EQU NARROW =0 ; SET IF SAVING NARROW CHARACTERS +.EQU WHITE =1 ; SET IF LINE IS WHITE SPACE SO FAR +.EQU IMAGE =2 ; SET BY FG FOR BG TO PRINT IMAGE LINE +.EQU TEXT =3 ; SET BY FG FOR BG TO PRINT TEXT LINE +.EQU CUT =4 ; SET BY FG FOR BG TO OPERATE CUTTER +.EQU RXFULL =5 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =6 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED +.EQU ASCEND =7 ; SET BY FG, ASCENDER ALLOWED NEXT LINE +;.EQU BOMB =7 ; SET BY BG FOR FG TO BOMB OUT / RESET + +; STATUS DEFINITIONS +.EQU PAPER =0 ; SET BY BG TO DETECT CHANGE IN STATUS +.EQU MOTOR =1 ; SET BY BG TO NOTIFY MOTOR RUN STATUS +.EQU CUTTER =2 ; SET BY BG TO NOTIFY CUTTER RUN STATUS +.EQU HEADUP =3 ; SET BY BG TO NOTIFY HEAD UP STATUS +.EQU NOTIFY =4 ; SET BY BG FOR FG TO REPORT STATUS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE PROCESSING ESC . CMD +; UPPER 2 BITS ARE USED TO COUNT 4 * 256 * 25 US = 25.6 MS BETWEEN PAPER TESTS + +; NARROW + +; FLAG SET BY FOREGROUND WHEN COMPRESSED COMMAND RECEIVED. +; FLAG RESET BY FOREGROUND WHEN DOUBLE-WIDTH COMMAND RECEIVED. + +; WHITE + +; FLAG SET BY FOREGROUND AT START OF PROCESSING FOR TEXT OR IMAGE LINE. +; FLAG RESET BY FOREGROUND IF NON-BLANK BYTE ENCOUNTERED DURING PROCESSING. +; IF FLAG STILL SET WHEN READY TO PRINT, FEEDING INITIATED INSTEAD. + +; IMAGE + +; FLAG SET BY FOREGROUND IF BUFFER CONTAINS IMAGE DATA, RESET IF TEXT DATA +; FLAG SAMPLED AT PRINTABLE AREA TO INSTALL FIRST PRINT INTERRUPT HANDLER +; FLAG MUST BE SET UP BEFORE COMMITTING DATA FOR PRINT. + +; ----------------------------------------------------------------------------- + +.CSEG + + RJMP RESET_ENTRY + + .ORG OVF1ADDR + RJMP T1_OVERFLOW ; TIMER1 OVERFLOW HANDLER + RJMP T0_OVERFLOW ; TIMER0 OVERFLOW HANDLER + + .ORG URXCADDR + INT_HANDLERS ; API BUS + +;IDENTIFY_MESS: +; .DB 17,$1B,'I','M','T','1','0','2' +; .DB 'A',' ','P','R','I','N','T','E' +; .DB 'R',$0D + +; ----------------------------------------------------------------------------- +; TIMER 0 OVERFLOW INTERRUPT HANDLER + +T0_OVERFLOW: + IN SR,SREG ; SAVE FLAGS + + PUSH G + PUSH H ; SAVE INTERRUPT SERVICE VECTOR + + LDI G,-TIME_STEP + OUT TCNT0,G ; DEFAULT DELAY TO NEXT STEP INTERRUPT + + WDR ; FEED WATCHDOG + RET ; VECTOR TO INTERRUPT SERVICE ROUTINE + +T0_DONE: + POP H + POP G ; RETRIEVE INTERRUPT SERVICE VECTOR + +T0_RET: + OUT SREG,SR ; RESTORE FLAGS + RETI + +; ----------------------------------------------------------------------------- + +T0_FEED: + DEC FEEDS + + RCALL T0_STEP_EVEN ; OUTPUT NEXT MOTOR STATE + + RCALL T0_DONE + + RCALL T0_STEP_ODD ; OUTPUT NEXT MOTOR STATE + +T0_MAIN: + RCALL T0_DONE + +T0_MAIN_ENTRY: + ;MOV D,FEEDS + ;CPI D,1+FEED_INITIAL + ;BRSH T0_PRINT ; WE HAVE SOMETHING TO PRINT + TST FEEDS + BRNE T0_PRINT ; WE HAVE SOMETHING TO PRINT + + MOV D,FLAGS + ANDI D,(1< CHARACTER SET SLICE IN FLASH + + MOV H,R0 + LPM ; R0 = CORRECT HORIZONTAL SLICE OF CHAR + MOV D,R0 + MOV R0,H + RJMP LOOKUP_CHAR_DONE ;RET + +LOOKUP_EEPROM: + MOV ZL,D + LSL ZL ; ZL = CHARACTER DEFINITION * 2 + LSL ZL ; ZL = CHARACTER DEFINITION * 4 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 5 + LSL ZL ; ZL = CHARACTER DEFINITION * 10 + ADD ZL,D ; ZL = CHARACTER DEFINITION * 11 + + SUBI ZL,-(EE_COUNT*2+2) ;+3) ; PAST CRC, COUNT, CHARACTER CODE + MOV D,TEXT_MASK + ANDI D,$0F + ADD ZL,D ;TEXT_MASK ; ZL = BASE + CHAR * 11 + SLICE INDEX + +LOOKUP_EEPROM_WAIT: + SBIC EECR,EEWE + RJMP LOOKUP_EEPROM_WAIT ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN D,EEDR ; GET LATCHED DATA BYTE +LOOKUP_CHAR_DONE: + ;RET + + POP ZH + POP ZL + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; F*1 PIXELS PADDING FROM D = 0 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + SBRC F,7 + LDI G,-TIME_CLOCK + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + SBRC F,7 + INC E + CPI E,WIDTH_CHARS ; GONE PAST LAST CHARACTER FOR LINE? + ;BRLO T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE + BRSH T0_PRINT_TEXT_SETUP_DONE + RJMP T0_PRINT_TEXT_SETUP_LINE ; REPEAT UNLESS ALL CHARACTERS DONE +T0_PRINT_TEXT_SETUP_DONE: + + LDI D,0 + LDI F,6 + LDI H,1 + RCALL SETUP_SLICE_ENTRY ; 6 PIXELS PADDING FROM D = 0 + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D + CPI D,$80 + BRSH T0_PRINT_TEXT_MORE_TEST + INC D +T0_PRINT_TEXT_MORE_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRLO T0_PRINT_TEXT_MORE + + CBR FLAGS,1<> 4 ITERATIONS + BRSH T0_PRINT_TEXT_STEP_LOOP ; APPLY VERTICAL SCALE FACTOR + + MOV D,TEXT_MASK + CPI D,$C0 + BRSH T0_MAIN_TEST + INC D + CPI D,$80 + BRSH T0_MAIN_TEST + INC D +T0_MAIN_TEST: + ANDI D,$0F + CPI D,9 ;6 + BRSH GO_T0_MAIN + + INC TEXT_MASK ; UPDATE MASK FOR NEXT LOWER DOT LINE + RJMP T0_PRINT_TEXT_SETUP ; REPEAT UNLESS ALL DOT LINES DONE + +GO_T0_MAIN: + RJMP T0_MAIN + +; ----------------------------------------------------------------------------- + +T0_PRINT_IMAGE: + LDI D,-TIME_CLOCK/2 + OUT TCNT0,D ; SHORT DELAY TO NEXT CLOCKING INT + + LDI XL,LOW(384) + LDI XH,HIGH(384) ; COUNT OF DOTS REMAINING + LDI DOTS_ON_LO,0 + LDI DOTS_ON_HI,0 ; COUNT OF DOTS ON FOR LINE + + LDI E,0 ; BYTE INDEX FOR DOT LINE + +T0_PRINT_IMAGE_SETUP_LINE: + PUSH ZL + + MOV ZL,E + SUBI ZL,-PRINT_BUF + ;CLR ZH + LD D,Z ; ZL = IMAGE BYTE + + POP ZL + + LDS F,SCALE_IMAGE ; IMAGE X/Y SCALE FACTORS + ANDI F,$0F ; EXTRACT HORIZONTAL SCALE FACTOR-1 + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + RCALL SETUP_SLICE ; F*8 PIXELS DATA FROM D + + RCALL T0_DONE ; BREAK TO ALLOW COMMS TRAFFIC + + LDI G,-TIME_CLOCK/2 + OUT TCNT0,G ; SHORT DELAY TO NEXT CLOCKING INT + + INC E + CPI E,WIDTH_IMAGE ; GONE PAST LAST BYTE FOR LINE? + BRLO T0_PRINT_IMAGE_SETUP_LINE ; REPEAT UNLESS ALL BYTES DONE + + CBR FLAGS,1< STORED CRC WORD FROM EEPROM + RCALL EE_READ + CP A,YL + BRNE CHARACTER_SET_INIT + INC ZL + RCALL EE_READ + CP A,YH + BREQ CHARACTER_SET_INIT_DONE + DEC ZL + +CHARACTER_SET_INIT: + LDI A,$AC + RCALL EE_WRITE + INC ZL + LDI A,$FB + RCALL EE_WRITE + INC ZL + LDI A,1 + RCALL EE_WRITE + INC ZL + LDI A,0 + RCALL EE_WRITE + INC ZL + RCALL EE_WRITE + ;RCALL CHARACTER_SET_CRC + ;LDI ZL,EE_CRC*2 + ;MOV A,YL + ;RCALL EE_WRITE + ;INC ZL + ;MOV A,YH + ;RCALL EE_WRITE + +CHARACTER_SET_INIT_DONE: + LDI A,~(1<> 4 ITERATIONS + BRSH REVERSE_FEED_ENTRY ; APPLY VERTICAL SCALE FACTOR + + SBRC FLAGS,ASCEND ; NEED AN EXTRA FEED FOR ASCENDERS ? +REVERSE_FEED_DONE: + RJMP TEXT_RECEIVE ; NO, WE ARE DONE + + SBR FLAGS,1< LENGTH FOLLOWED BY DATA BLOCK + RCALL EE_READ + MOV ZH,A ; ZH = DATA LENGTH + SUBI ZH,-2 ; ZH = DATA LENGTH INCL LENGTH WORD + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + LDI B,$21 + MOV R0,B + LDI B,$10 ; B:R0 = CRC POLYNOMIAL + +CHARACTER_SET_CRC_BYTE: + RCALL EE_READ + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + INC ZL + + LDI A,8 +CHARACTER_SET_CRC_BIT: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,R0 + EOR YH,B +CHARACTER_SET_CRC_BIT0: + DEC A + BRNE CHARACTER_SET_CRC_BIT + + DEC ZH + BRNE CHARACTER_SET_CRC_BYTE + RET + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + OUT EEAR,ZL + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RETI + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + CLI ; IN CASE ACCESSED VIA INTERRUPT + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEAR,ZL + OUT EEDR,A ; LATCH NEW VALUE + + SBRS STATUS,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +; ----------------------------------------------------------------------------- + +PAPER_CUT: + SBR FLAGS,1<> 4 ITERATIONS + BRSH WAIT_ADD_FEEDS_ENTRY ; APPLY VERTICAL SCALE FACTOR + + RET + +; ----------------------------------------------------------------------------- + +TEXT_SAVE: + MOV YL,A + LDI YH,0 + + LDI ZL,EE_COUNT*2 + ;CLR ZH + RCALL EE_READ + MOV ZH,A ; ZH = COUNT OF CHARACTER DEFINITIONS + INC ZL + +TEXT_SAVE_SEARCH: + RCALL EE_READ ; READ CHARACTER CODE FOR DEFINITION + CP A,YL + BREQ TEXT_SAVE_FOUND ; WITH YL = CHARACTER CODE, TRANSLATED + SUBI ZL,-11 + + INC YH + DEC ZH + BRNE TEXT_SAVE_SEARCH + + MOV YH,YL ; YL = CHARACTER CODE, NOT TRANSLATED + +TEXT_SAVE_FOUND: + MOV ZL,BUF_PTR + SUBI ZL,-(PRINT_BUF+WIDTH_FLAGS) + ;CLR ZH + ST Z,YH + + MOV ZL,BUF_PTR + LSR ZL + LSR ZL + LSR ZL + SUBI ZL,-PRINT_BUF + ;CLR ZH ; Z -> ONE OF WIDTH_FLAGS FLAG BYTES + + INC BUF_PTR + + LD A,Z + LSR A ; PREPARE TO STORE WIDE FLAG + RET + +; ----------------------------------------------------------------------------- + +IMAGE_SAVE: + MOV ZL,BUF_PTR + SUBI ZL,-PRINT_BUF + ;CLR ZH + ST Z,A + + INC BUF_PTR + RET + +; ----------------------------------------------------------------------------- + +CHARACTER_SET: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 20 + .DB $00,$18,$18,$18,$18,$18,$00,$18,$00,$00 ; 21 ! + .DB $00,$E7,$63,$C6,$00,$00,$00,$00,$00,$00 ; 22 " + .DB $00,$66,$66,$FF,$66,$FF,$66,$66,$00,$00 ; 23 # + .DB $18,$7E,$DB,$D8,$7E,$1B,$DB,$7E,$18,$00 ; 24 $ + .DB $00,$E3,$E6,$0C,$18,$30,$67,$C7,$00,$00 ; 25 % + .DB $00,$78,$CC,$D8,$73,$DE,$CC,$7B,$00,$00 ; 26 & + .DB $00,$3C,$0C,$18,$00,$00,$00,$00,$00,$00 ; 27 ' + .DB $00,$0C,$18,$30,$30,$30,$18,$0C,$00,$00 ; 28 ( + .DB $00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00 ; 29 ) + .DB $00,$18,$DB,$7E,$3C,$7E,$DB,$18,$00,$00 ; 2A * + .DB $00,$00,$18,$18,$FF,$18,$18,$00,$00,$00 ; 2B + + .DB $00,$00,$00,$00,$00,$00,$3C,$0C,$18,$00 ; 2C , + .DB $00,$00,$00,$00,$FF,$00,$00,$00,$00,$00 ; 2D - + .DB $00,$00,$00,$00,$00,$00,$3C,$3C,$00,$00 ; 2E . + .DB $00,$03,$06,$0C,$18,$30,$60,$C0,$00,$00 ; 2F / + .DB $00,$7E,$C7,$CF,$DB,$F3,$E3,$7E,$00,$00 ; 30 0 + .DB $00,$0C,$1C,$3C,$0C,$0C,$0C,$0C,$00,$00 ; 31 1 + .DB $00,$7E,$C3,$03,$0E,$38,$60,$FF,$00,$00 ; 32 2 + .DB $00,$7E,$C3,$03,$3E,$03,$C3,$7E,$00,$00 ; 33 3 + .DB $00,$1C,$3C,$6C,$CC,$FF,$0C,$0C,$00,$00 ; 34 4 + .DB $00,$FF,$C0,$FE,$03,$03,$C3,$7E,$00,$00 ; 35 5 + .DB $00,$3E,$60,$C0,$FE,$C3,$C3,$7E,$00,$00 ; 36 6 + .DB $00,$FF,$03,$06,$0C,$18,$18,$18,$00,$00 ; 37 7 + .DB $00,$7E,$C3,$C3,$7E,$C3,$C3,$7E,$00,$00 ; 38 8 + .DB $00,$7E,$C3,$C3,$7F,$03,$06,$7C,$00,$00 ; 39 9 + .DB $00,$00,$3C,$3C,$00,$3C,$3C,$00,$00,$00 ; 3A : + .DB $00,$00,$3C,$3C,$00,$3C,$0C,$18,$00,$00 ; 3B ; + .DB $00,$0C,$18,$30,$60,$30,$18,$0C,$00,$00 ; 3C < + .DB $00,$00,$00,$FF,$00,$FF,$00,$00,$00,$00 ; 3D = + .DB $00,$30,$18,$0C,$06,$0C,$18,$30,$00,$00 ; 3E > + .DB $00,$7E,$C3,$03,$0E,$18,$00,$18,$00,$00 ; 3F ? + .DB $00,$7E,$C3,$DB,$DB,$DF,$C0,$7C,$00,$00 ; 40 @ + .DB $00,$3C,$66,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 41 A + .DB $00,$FE,$C3,$C3,$FE,$C3,$C3,$FE,$00,$00 ; 42 B + .DB $00,$7E,$C3,$C0,$C0,$C0,$C3,$7E,$00,$00 ; 43 C + .DB $00,$FC,$C6,$C3,$C3,$C3,$C6,$FC,$00,$00 ; 44 D + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$FF,$00,$00 ; 45 E + .DB $00,$FF,$C0,$C0,$FE,$C0,$C0,$C0,$00,$00 ; 46 F + .DB $00,$7E,$C3,$C0,$C0,$CF,$C3,$7F,$00,$00 ; 47 G + .DB $00,$C3,$C3,$C3,$FF,$C3,$C3,$C3,$00,$00 ; 48 H + .DB $00,$18,$18,$18,$18,$18,$18,$18,$00,$00 ; 49 I + .DB $00,$03,$03,$03,$03,$03,$C3,$7E,$00,$00 ; 4A J + .DB $00,$C3,$C6,$CC,$F8,$CC,$C6,$C3,$00,$00 ; 4B K + .DB $00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$00,$00 ; 4C L + .DB $00,$C3,$E7,$FF,$DB,$C3,$C3,$C3,$00,$00 ; 4D M + .DB $00,$C3,$E3,$F3,$DB,$CF,$C7,$C3,$00,$00 ; 4E N + .DB $00,$7E,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 4F O + .DB $00,$FE,$C3,$C3,$FE,$C0,$C0,$C0,$00,$00 ; 50 P + .DB $00,$7E,$C3,$C3,$C3,$C3,$CF,$7E,$03,$00 ; 51 Q + .DB $00,$FE,$C3,$C3,$FE,$CC,$C6,$C3,$00,$00 ; 52 R + .DB $00,$7E,$C3,$C0,$7E,$03,$C3,$7E,$00,$00 ; 53 S + .DB $00,$FF,$18,$18,$18,$18,$18,$18,$00,$00 ; 54 T + .DB $00,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$00,$00 ; 55 U + .DB $00,$C3,$C3,$C3,$C3,$66,$3C,$18,$00,$00 ; 56 V + .DB $00,$C3,$C3,$C3,$C3,$DB,$FF,$66,$00,$00 ; 57 W + .DB $00,$C3,$66,$3C,$18,$3C,$66,$C3,$00,$00 ; 58 X + .DB $00,$C3,$C3,$66,$3C,$18,$18,$18,$00,$00 ; 59 Y + .DB $00,$FF,$06,$0C,$18,$30,$60,$FF,$00,$00 ; 5A Z + .DB $00,$3C,$30,$30,$30,$30,$30,$3C,$00,$00 ; 5B [ + .DB $00,$C0,$60,$30,$18,$0C,$06,$03,$00,$00 ; 5C \ + .DB $00,$3C,$0C,$0C,$0C,$0C,$0C,$3C,$00,$00 ; 5D ] + .DB $18,$3C,$66,$C3,$00,$00,$00,$00,$00,$00 ; 5E ^ + .DB $00,$00,$00,$00,$00,$00,$00,$FF,$00,$00 ; 5F _ + .DB $0C,$18,$1E,$00,$00,$00,$00,$00,$00,$00 ; 60 ` + .DB $00,$00,$00,$7E,$03,$7F,$C3,$7F,$00,$00 ; 61 a + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$FE,$00,$00 ; 62 b + .DB $00,$00,$00,$7E,$C3,$C0,$C3,$7E,$00,$00 ; 63 c + .DB $00,$03,$03,$7F,$C3,$C3,$C3,$7F,$00,$00 ; 64 d + .DB $00,$00,$00,$7E,$C3,$FF,$C0,$7E,$00,$00 ; 65 e + .DB $00,$1E,$33,$30,$FC,$30,$30,$30,$00,$00 ; 66 f + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$7E ; 67 g + .DB $00,$C0,$C0,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 68 h + .DB $00,$18,$00,$18,$18,$18,$18,$18,$00,$00 ; 69 i + .DB $00,$06,$00,$06,$06,$06,$06,$06,$06,$7C ; 6A j + .DB $00,$C0,$C0,$C6,$CC,$F8,$CC,$C6,$00,$00 ; 6B k + .DB $00,$30,$30,$30,$30,$30,$30,$1C,$00,$00 ; 6C l + .DB $00,$00,$00,$FE,$DB,$DB,$DB,$DB,$00,$00 ; 6D m + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$C3,$00,$00 ; 6E n + .DB $00,$00,$00,$7E,$C3,$C3,$C3,$7E,$00,$00 ; 6F o + .DB $00,$00,$00,$FE,$C3,$C3,$C3,$FE,$C0,$C0 ; 70 p + .DB $00,$00,$00,$7F,$C3,$C3,$C3,$7F,$03,$03 ; 71 q + .DB $00,$00,$00,$FE,$C3,$C0,$C0,$C0,$00,$00 ; 72 r + .DB $00,$00,$00,$7E,$C0,$7E,$03,$7E,$00,$00 ; 73 s + .DB $00,$18,$18,$7E,$18,$18,$18,$0E,$00,$00 ; 74 t + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$00,$00 ; 75 u + .DB $00,$00,$00,$C3,$C3,$66,$3C,$18,$00,$00 ; 76 v + .DB $00,$00,$00,$C3,$C3,$DB,$FF,$66,$00,$00 ; 77 w + .DB $00,$00,$00,$C3,$66,$3C,$66,$C3,$00,$00 ; 78 x + .DB $00,$00,$00,$C3,$C3,$C3,$C3,$7F,$03,$7E ; 79 y + .DB $00,$00,$00,$FF,$0C,$18,$30,$FF,$00,$00 ; 7A z + .DB $00,$0E,$18,$18,$70,$18,$18,$0E,$00,$00 ; 7B { + .DB $00,$18,$18,$18,$00,$18,$18,$18,$00,$00 ; 7C | + .DB $00,$70,$18,$18,$0E,$18,$18,$70,$00,$00 ; 7D } + .DB $00,$76,$DC,$00,$00,$00,$00,$00,$00,$00 ; 7E ~ + .DB $00,$00,$00,$18,$3C,$66,$C3,$FF,$00,$00 ; 7F  + +; ----------------------------------------------------------------------------- + + ; BODEN = 0 ENABLED + ; BODLEVEL = 1 FOR 2.7V + ; PAPER CUTTER DOESN'T WORK WITH BODLEVEL = 0 FOR 4.0V + + ; CKSEL = 010 FOR 64 MS R/C + 16K * 11 MHZ STARTUP DELAY + + .ORG $1000 + + .DW $4105 ; SELECT ADDRESS COMMAND + .DW $ACB2 ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/prm.inc b/src/avr/prm.inc new file mode 100644 index 00000000..f4efc1b3 --- /dev/null +++ b/src/avr/prm.inc @@ -0,0 +1,104 @@ +SN: .DB 6,0,$1B,'#' + .DW 3 ; THE EVENT COUNTER, IT WILL BE < 1000 + .DW 5594 ; THE SERIAL NUMBER, IT WILL BE => 1000 + +SEGS1: ; NUMBER OF PARABOLIC SEGMENTS-1 +DEGS: .DB $03,$06 ; POLYNOMIAL DEGREE FOR THERMAL CORRECTION + +SEG1: .DB $2F,$BE,$B1,$B6 ;-5.2971513E-06 POLY SEGS FOR CONV TO GMS +D21: .DB $F5,$02,$FB,$D1 ;-1.3476080E+11 +D11: .DB $BE,$0C,$A1,$CD ;-3.3774586E+08 +D01: .DB $16,$D8,$8B,$BF ;-1.0925319E+00 +SEG2: .DB $D3,$4F,$8B,$B8 ;-6.6429049E-05 +D22: .DB $C7,$16,$E6,$D1 ;-1.2352808E+11 +D12: .DB $6B,$EF,$A0,$CD ;-3.3750563E+08 +D02: .DB $E6,$8C,$0A,$BE ;-1.3530311E-01 +SEG3: .DB $7F,$45,$BB,$B8 ;-8.9297995E-05 +D23: .DB $1F,$46,$EE,$D1 ;-1.2792233E+11 +D13: .DB $80,$85,$A1,$CD ;-3.3873510E+08 +D03: .DB $8B,$A9,$79,$C2 ;-6.2415569E+01 +D24: .DB $22,$DA,$52,$D3 ;-9.0560279E+11 +D14: .DB $08,$2D,$E6,$CD ;-4.8271386E+08 +D04: .DB $D7,$F0,$D1,$C5 ;-6.7181050E+03 + + .ESEG + +CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 RECALIBRATION COEFFICENTS +CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +A11: .DB $FF,$A8,$22,$C3 ;-1.6266014E+02 THERMAL COMP AT 0 GMS +A10: .DB $45,$5F,$32,$43 ; 1.7837215E+02 +A9: .DB $34,$A9,$0E,$42 ; 3.5665237E+01 +A8: .DB $51,$4F,$93,$C2 ;-7.3654915E+01 +A7: .DB $62,$52,$E3,$C1 ;-2.8415226E+01 +A6: .DB $C1,$3D,$A2,$41 ; 2.0280153E+01 +A5: .DB $00,$00,$94,$29 ; 6.5725203E-14 + +K500: .DB $00,$00,$FA,$43 ; 5.0000000E+02 +A18: .DB $9F,$B9,$4C,$42 ; 5.1181271E+01 THERMAL COMP AT 500 GMS +A17: .DB $5C,$B2,$02,$C2 ;-3.2674179E+01 +A16: .DB $02,$A1,$97,$C1 ;-1.8953617E+01 +A15: .DB $BD,$21,$42,$41 ; 1.2133237E+01 +A14: .DB $E4,$90,$A5,$3F ; 1.2934842E+00 +A13: .DB $54,$F9,$87,$3D ; 6.6393524E-02 +A12: .DB $00,$00,$40,$A6 ;-6.6613381E-16 + +K1K5: .DB $00,$80,$BB,$44 ; 1.5000000E+03 +K2K: .DB $00,$00,$FA,$44 ; 2.0000000E+03 +A25: .DB $8F,$4B,$D5,$41 ; 2.6661894E+01 THERMAL COMP AT 2000 GMS +A24: .DB $C0,$A3,$3D,$42 ; 4.7409912E+01 +A23: .DB $26,$A4,$1F,$C2 ;-3.9910301E+01 +A22: .DB $BA,$57,$BE,$C0 ;-5.9482088E+00 +A21: .DB $6C,$2E,$A9,$40 ; 5.2869167E+00 +A20: .DB $C5,$29,$14,$40 ; 2.3150494E+00 +A19: .DB $00,$00,$00,$25 ; 1.1102230E-16 + +K8K: .DB $00,$00,$FA,$45 ; 8.0000000E+03 +K10K: .DB $00,$40,$1C,$46 ; 1.0000000E+04 +A32: .DB $A5,$41,$8B,$43 ; 2.7851285E+02 THERMAL COMP AT 10000 GMS +A31: .DB $5F,$55,$E3,$C2 ;-1.1366674E+02 +A30: .DB $3F,$41,$25,$C3 ;-1.6525487E+02 +A29: .DB $9E,$B2,$6B,$42 ; 5.8924431E+01 +A28: .DB $72,$A6,$E6,$41 ; 2.8831272E+01 +A27: .DB $AC,$22,$0C,$41 ; 8.7584648E+00 +A26: .DB $00,$00,$40,$A9 ;-4.2632564E-14 + +K15K: .DB $00,$60,$6A,$46 ; 1.5000000E+04 +_WREF: .DB $E7,$60,$84,$BA ;-1.0099680E-03 +A39: .DB $AD,$CA,$1B,$C3 ;-1.5579170E+02 THERMAL COMP AT 15000 GMS +A38: .DB $B6,$D9,$C8,$41 ; 2.5106304E+01 +A37: .DB $6B,$3F,$5F,$42 ; 5.5811932E+01 +A36: .DB $CE,$F9,$45,$41 ; 1.2373487E+01 +A35: .DB $D1,$75,$2E,$40 ; 2.7259409E+00 +A34: .DB $3F,$0E,$06,$42 ; 3.3513912E+01 +A33: .DB $00,$00,$30,$A8 ;-9.7699626E-15 + +C3: .DB $F6,$CC,$B3,$58 ; 1.5815431E+15 POLY CONV TO NORM TEMP +C2: .DB $C0,$DE,$18,$D1 ;-4.1035760E+10 +C1: .DB $BD,$2F,$D5,$48 ; 4.3660591E+05 +C0: .DB $51,$2F,$9E,$BF ;-1.2358190E+00 + + .CSEG + +TLTA21: .DB $D8,$E1,$CB,$49 ; 1.6702030E+06 TILT FB POSITION +TLTA11: .DB $56,$84,$21,$C5 ;-2.5842710E+03 +TLTA01: .DB $12,$F5,$49,$3F ; 7.8889573E-01 +TLTA31: .DB $2F,$FD,$86,$42 ; 6.7494499E+01 + +TLTA20: .DB $36,$91,$56,$49 ; 8.7886738E+05 TILT LR POSITION +TLTA10: .DB $2D,$62,$79,$43 ; 2.4938350E+02 +TLTA00: .DB $BF,$60,$87,$BE ;-2.6440999E-01 +TLTA30: .DB $8B,$5A,$C8,$41 ; 2.5044210E+01 + +TLTC21: .DB $9F,$05,$FC,$3E ; 4.9223039E-01 TILT SPAN +TLTC11: .DB $61,$B7,$E9,$3A ; 1.7831140E-03 +TLTC20: .DB $F0,$0C,$02,$3F ; 5.0800991E-01 +TLTC10: .DB $82,$F3,$C8,$3B ; 6.1325440E-03 + +TLTB21: .DB $1B,$23,$90,$44 ; 1.1530970E+03 TILT ZERO +TLTB11: .DB $82,$A9,$5B,$C0 ;-3.4322209E+00 +TLTB20: .DB $B0,$AA,$96,$44 ; 1.2053340E+03 +TLTB10: .DB $0A,$92,$DE,$C0 ;-6.9553270E+00 + diff --git a/src/avr/prm0.inc b/src/avr/prm0.inc new file mode 100644 index 00000000..7dcae6ca --- /dev/null +++ b/src/avr/prm0.inc @@ -0,0 +1,103 @@ +SN: .DB 4,0,$1B,'#' + .DW 5594 ; THE SERIAL NUMBER, IT WILL BE => 1000 + +SEGS1: ; NUMBER OF PARABOLIC SEGMENTS-1 +DEGS: .DB $03,$06 ; POLYNOMIAL DEGREE FOR THERMAL CORRECTION + +SEG1: .DB $2F,$BE,$B1,$B6 ;-5.2971513E-06 POLY SEGS FOR CONV TO GMS +D21: .DB $F5,$02,$FB,$D1 ;-1.3476080E+11 +D11: .DB $BE,$0C,$A1,$CD ;-3.3774586E+08 +D01: .DB $16,$D8,$8B,$BF ;-1.0925319E+00 +SEG2: .DB $D3,$4F,$8B,$B8 ;-6.6429049E-05 +D22: .DB $C7,$16,$E6,$D1 ;-1.2352808E+11 +D12: .DB $6B,$EF,$A0,$CD ;-3.3750563E+08 +D02: .DB $E6,$8C,$0A,$BE ;-1.3530311E-01 +SEG3: .DB $7F,$45,$BB,$B8 ;-8.9297995E-05 +D23: .DB $1F,$46,$EE,$D1 ;-1.2792233E+11 +D13: .DB $80,$85,$A1,$CD ;-3.3873510E+08 +D03: .DB $8B,$A9,$79,$C2 ;-6.2415569E+01 +D24: .DB $22,$DA,$52,$D3 ;-9.0560279E+11 +D14: .DB $08,$2D,$E6,$CD ;-4.8271386E+08 +D04: .DB $D7,$F0,$D1,$C5 ;-6.7181050E+03 + + .ESEG + +CAL3: .DB $00,$00,$00,$00 ; 0.0000000E+00 RECALIBRATION COEFFICENTS +CAL2: .DB $00,$00,$00,$00 ; 0.0000000E+00 +CAL1: .DB $00,$00,$80,$3F ; 1.0000000E+00 +CAL0: .DB $00,$00,$00,$00 ; 0.0000000E+00 + +A11: .DB $FF,$A8,$22,$C3 ;-1.6266014E+02 THERMAL COMP AT 0 GMS +A10: .DB $45,$5F,$32,$43 ; 1.7837215E+02 +A9: .DB $34,$A9,$0E,$42 ; 3.5665237E+01 +A8: .DB $51,$4F,$93,$C2 ;-7.3654915E+01 +A7: .DB $62,$52,$E3,$C1 ;-2.8415226E+01 +A6: .DB $C1,$3D,$A2,$41 ; 2.0280153E+01 +A5: .DB $00,$00,$94,$29 ; 6.5725203E-14 + +K500: .DB $00,$00,$FA,$43 ; 5.0000000E+02 +A18: .DB $9F,$B9,$4C,$42 ; 5.1181271E+01 THERMAL COMP AT 500 GMS +A17: .DB $5C,$B2,$02,$C2 ;-3.2674179E+01 +A16: .DB $02,$A1,$97,$C1 ;-1.8953617E+01 +A15: .DB $BD,$21,$42,$41 ; 1.2133237E+01 +A14: .DB $E4,$90,$A5,$3F ; 1.2934842E+00 +A13: .DB $54,$F9,$87,$3D ; 6.6393524E-02 +A12: .DB $00,$00,$40,$A6 ;-6.6613381E-16 + +K1K5: .DB $00,$80,$BB,$44 ; 1.5000000E+03 +K2K: .DB $00,$00,$FA,$44 ; 2.0000000E+03 +A25: .DB $8F,$4B,$D5,$41 ; 2.6661894E+01 THERMAL COMP AT 2000 GMS +A24: .DB $C0,$A3,$3D,$42 ; 4.7409912E+01 +A23: .DB $26,$A4,$1F,$C2 ;-3.9910301E+01 +A22: .DB $BA,$57,$BE,$C0 ;-5.9482088E+00 +A21: .DB $6C,$2E,$A9,$40 ; 5.2869167E+00 +A20: .DB $C5,$29,$14,$40 ; 2.3150494E+00 +A19: .DB $00,$00,$00,$25 ; 1.1102230E-16 + +K8K: .DB $00,$00,$FA,$45 ; 8.0000000E+03 +K10K: .DB $00,$40,$1C,$46 ; 1.0000000E+04 +A32: .DB $A5,$41,$8B,$43 ; 2.7851285E+02 THERMAL COMP AT 10000 GMS +A31: .DB $5F,$55,$E3,$C2 ;-1.1366674E+02 +A30: .DB $3F,$41,$25,$C3 ;-1.6525487E+02 +A29: .DB $9E,$B2,$6B,$42 ; 5.8924431E+01 +A28: .DB $72,$A6,$E6,$41 ; 2.8831272E+01 +A27: .DB $AC,$22,$0C,$41 ; 8.7584648E+00 +A26: .DB $00,$00,$40,$A9 ;-4.2632564E-14 + +K15K: .DB $00,$60,$6A,$46 ; 1.5000000E+04 +_WREF: .DB $E7,$60,$84,$BA ;-1.0099680E-03 +A39: .DB $AD,$CA,$1B,$C3 ;-1.5579170E+02 THERMAL COMP AT 15000 GMS +A38: .DB $B6,$D9,$C8,$41 ; 2.5106304E+01 +A37: .DB $6B,$3F,$5F,$42 ; 5.5811932E+01 +A36: .DB $CE,$F9,$45,$41 ; 1.2373487E+01 +A35: .DB $D1,$75,$2E,$40 ; 2.7259409E+00 +A34: .DB $3F,$0E,$06,$42 ; 3.3513912E+01 +A33: .DB $00,$00,$30,$A8 ;-9.7699626E-15 + +C3: .DB $F6,$CC,$B3,$58 ; 1.5815431E+15 POLY CONV TO NORM TEMP +C2: .DB $C0,$DE,$18,$D1 ;-4.1035760E+10 +C1: .DB $BD,$2F,$D5,$48 ; 4.3660591E+05 +C0: .DB $51,$2F,$9E,$BF ;-1.2358190E+00 + + .CSEG + +TLTA21: .DB $D8,$E1,$CB,$49 ; 1.6702030E+06 TILT FB POSITION +TLTA11: .DB $56,$84,$21,$C5 ;-2.5842710E+03 +TLTA01: .DB $12,$F5,$49,$3F ; 7.8889573E-01 +TLTA31: .DB $2F,$FD,$86,$42 ; 6.7494499E+01 + +TLTA20: .DB $36,$91,$56,$49 ; 8.7886738E+05 TILT LR POSITION +TLTA10: .DB $2D,$62,$79,$43 ; 2.4938350E+02 +TLTA00: .DB $BF,$60,$87,$BE ;-2.6440999E-01 +TLTA30: .DB $8B,$5A,$C8,$41 ; 2.5044210E+01 + +TLTC21: .DB $9F,$05,$FC,$3E ; 4.9223039E-01 TILT SPAN +TLTC11: .DB $61,$B7,$E9,$3A ; 1.7831140E-03 +TLTC20: .DB $F0,$0C,$02,$3F ; 5.0800991E-01 +TLTC10: .DB $82,$F3,$C8,$3B ; 6.1325440E-03 + +TLTB21: .DB $1B,$23,$90,$44 ; 1.1530970E+03 TILT ZERO +TLTB11: .DB $82,$A9,$5B,$C0 ;-3.4322209E+00 +TLTB20: .DB $B0,$AA,$96,$44 ; 1.2053340E+03 +TLTB10: .DB $0A,$92,$DE,$C0 ;-6.9553270E+00 + diff --git a/src/avr/product/CFLASHV0.HEX b/src/avr/product/CFLASHV0.HEX new file mode 100644 index 00000000..30751b36 --- /dev/null +++ b/src/avr/product/CFLASHV0.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F445E0EB +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE849B94FEB54227724559841 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE809B900E90AB933244424AA +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742B2ACEC +:00000001FF diff --git a/src/avr/product/CFLASHV1.HEX b/src/avr/product/CFLASHV1.HEX new file mode 100644 index 00000000..be960cc1 --- /dev/null +++ b/src/avr/product/CFLASHV1.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F445E0EB +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE849B94FEB54227724559841 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE809B900E90AB933244424AA +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742BAACE4 +:00000001FF diff --git a/src/avr/product/CFLASHV2.HEX b/src/avr/product/CFLASHV2.HEX new file mode 100644 index 00000000..a62f4788 --- /dev/null +++ b/src/avr/product/CFLASHV2.HEX @@ -0,0 +1,76 @@ +:020000020000FC +:02000000C7C077 +:02000C0004C02E +:1000100071C05BC0ACC0FFB67460FFBE1895A895F8 +:1000200072FF23C07B7FEE2019F0EA94F1F4DEC06A +:10003000DA9409F4726017E0A5D107FF04C070FDDF +:1000400072607E7F07C070FD05C082D18AD111F435 +:1000500093D1736071FF09C0042D003430F4DD24A6 +:100060007D7F072F017000631BD02220C1F2EE209C +:1000700011F005E1E02ECF93DF93C12DC056DD27AF +:100080000881F8942A941394CFE11C227894DF918C +:10009000CF9108950F93A895042D0034E0F70F91A8 +:1000A000EE2021F00F9305E1E02E0F91CF93DF9327 +:1000B000DFB7F894C42DC30DDFBFCF73C05ADD275F +:1000C00008834394DF91CF910895FFB64F934EEC90 +:1000D000742EEF93FF93E32DE05AFF274081FF91A9 +:1000E000EF914CB94A9433944FE334226A940AF066 +:1000F00046C04BC0FFB64F934EEC742E4CB15C998A +:1001000038C057FC26C056FC08C0473029F443E0ED +:1001100049B9539A40E4542A38C0642E40E2421947 +:100120000AF44FE7662012F4442D40684CB9461596 +:1001300008F4642E462D4F7739F040EC542A6A9427 +:1001400022F55798559A21C04FEB5422569A5E9A41 +:100150001CC0EF93FF93E22DE10DEF71E056FF27F6 +:100160004083FF91EF9123946A947AF40CC0FFB618 +:100170004F9353984FE549B94FEB54227724559844 +:100180005698579A4CB14FE754224F91FFBE18959D +:100190000FED0DBF00E808B9A8950FE001BD929AD8 +:1001A0008A9A939A8B9AAC9AA49AAD9AA59AB89A7D +:1001B000B99ABA9AA89AA99AAA9AAB9A949A959A2D +:1001C000969A979A0FE509B900E90AB933244424AD +:1001D00011242224552466247724772705E1D02E84 +:1001E00005E003BF22E028BF29BF78940FED0DBFC3 +:1001F000EE2415DF0B3109F0FBCF05E1E02E0FDF18 +:10020000093439F0043499F0023521F1073581F7CA +:1002100045C09ED0A6D031F4AFD00BE13BDF09E45E +:1002200039DFE6CF0BE136DF09E634DFE1CF00E06E +:1002300016E0C7D00CEE17E0C4D093D031F40BE138 +:1002400029DF04E427DF2FEF14C00BE123DF04E6EE +:1002500021DFCECF51D0E3DE0213CACF68D000E257 +:1002600017E0AFD07ED081F40BE114DF02E512DF9E +:1002700051D0E0E0F2E010E085D0201B0BDF319799 +:10028000D1F7022F07DFB4CF0BE104DF02E702DF73 +:1002900041D000E0FFDE022FFDDEAACF2DD047D0F7 +:1002A00000E317E08ED05DD079F7EFEFF1E0B7DE35 +:1002B000201B10E086D03197D1F7B1DE201B102F24 +:1002C000AEDE02137E7F021391CF012F10E079D0B2 +:1002D00048D041F40BE1DEDE07E5DCDE1BD0022F67 +:1002E000D9DE86CF0BE1D6DE07E7D4DE13D000E0FF +:1002F000D1DE022FCFDE7CCF2FEF91DE201BA02F8F +:100300008EDE201BB02F8BDE201BC02F88DE201B33 +:10031000D02F08950A2F2FEF201BBCDE0B2F201BA0 +:10032000B9DE0C2F201BB6DE0D2F201BB3CE01E053 +:1003300012E047D00A2F13E044D00B2F14E041D035 +:100340000C2F15E03ED00D2F0F70006E16E039C057 +:100350000EE016E065D000E00A95F1F70AE016E03D +:100360005FC0E0E0F0E017E00DD007FF02C031977A +:10037000D1F7007C0034089501E011E022D00FEEA7 +:1003800017E01FC018BB1FE215BB000000000000F3 +:100390000000000000000000000014EF12BB00008D +:1003A000000000000000000000000000000003B397 +:1003B00010B301270F7001271CEF12BB1FE315BB01 +:1003C000089518BB102F1F70106215BB1FE314BBDC +:1003D000102F107F1C6012BB1CEF11BB000000002F +:1003E00000000000000000000000000092980000E3 +:1003F0000000000000000000000000000000929AD1 +:1004000000000000000000000000000000000000EC +:1004100012BB1CE011BB1FE315BB10E314BB089516 +:1004200018BB102F1F70106115BB1FE314BB102FDA +:10043000107F1C6012BB1CEF11BB0000000000000D +:100440000000000000000000000092980000000082 +:10045000000000000000000000000000929A000070 +:10046000000000000000000000000000000012BBBF +:0E0470001CE011BB1FE315BB10E314BB089585 +:0620000006410742B2ACEC +:00000001FF diff --git a/src/avr/product/CS64V4.HEX b/src/avr/product/CS64V4.HEX new file mode 100644 index 00000000..e5b357b9 --- /dev/null +++ b/src/avr/product/CS64V4.HEX @@ -0,0 +1,385 @@ +:020000020000FC +:100000000DC087C387C3189518951895189518952E +:1000100082C31895189527C711C762C702E00EBFA3 +:100020000FE50DBF10E818B9A8951FE011BD00E05D +:1000300009BF0BBF08EF01BB08EB02BB0FE107BB19 +:100040000FEF0ABB04BB00270BBB03E008BB00E0BB +:1000500005BB00E2B02E1FE519B910E91AB9442416 +:10006000552422243324EE246624CC24552750938F +:100070000101509323015093430150934401509345 +:100080004501969AE0E0F0E0A8953197E9F7979856 +:1000900000E0B8D0B7D002E4B1D000E2B3D000E0C5 +:1000A000B1D003E4ABD000E8A9D000E9A7D000E0CC +:1000B000A9D0A8D004E2A2D000EBA0D0E0E0F8E004 +:1000C00000E0A2D03197E1F702EB9AD008E996D090 +:1000D000979A789410E3B9D2CF93DF93C4D2BF91AB +:1000E000AF911BD5212F1D2F12950DD31217B1F4EF +:1000F000119613D5212F1D2F06D3121779F41196BF +:100100000CD5212F1C2F1295FED2121739F41196FF +:1001100004D5212F1C2FF7D2121749F1E6E7F2E19F +:10012000A6E6B3E0D8E1D0930201C0D0D0E8C0E0A9 +:10013000DBBBC39AC398D0930101F89435B33C2735 +:1001400030783C27789435BBC8950BBAC29ABA98D8 +:10015000C1980000C19AC298BA9A119741F031969D +:10016000C3951C2F1F7349F7C054D395E1CF20E1ED +:100170002093F30020E22093F40028E12093F5007F +:1001800021D6112710935101EE27FF271EEF109360 +:10019000FD001BEA1093FC0022E01BD21C7F109391 +:1001A000FE0023E016D21093FF001091FE00209174 +:1001B000FF001A380DEF200720F01B3A0FEF200741 +:1001C00030F01EEF1093FF0010E41093FE001EEFBE +:1001D00019BD1BEA18BD1CEF1DBD1EEC1CBD10E5B2 +:1001E0001FBD11E01EBD00E003BF04E008BF09BF52 +:1001F0000AE005BF00EC0ABF0BBF92C219D006C0CF +:1002000011D004C015D001C00DD0A8980BBB0000C0 +:1002100000000000F894C1980000000000007894ED +:10022000C19A08950F930BD003FFFDCF0F9108954E +:100230000F9305D000FD01FFFCCF0F910895A89A00 +:1002400000E00ABBF894C098000000000000000025 +:10025000C09A09B378940F930FEF0ABB0F910895DA +:1002600002E00EBF0FE50DBF1FE7B122AF98C498A3 +:10027000409101014BBBC39AC39850E05FBD5EBD86 +:1002800094989598C298BA9A96989798C098C19859 +:100290005FEF5ABB50E05BBB50E059BF5BBF5FE113 +:1002A00051BD57E151BD5AE655BF889508957894E0 +:1002B0001FEDE12210E01EBB1FBB62D21B3129F1F2 +:1002C000B3FC0DC0103258F4183009F4FEC01D30D4 +:1002D00009F40DC11A3009F48BC0173041F7B2FC94 +:1002E00012C0103381F4C091F300D091F40020913A +:1002F000F500CC5FDD4FF89435B320FB36F97894E8 +:1003000035BBF1D4102D72D2D2CF3AD21B3139F392 +:100310001E3209F475C11F3209F44FC01F3309F4AE +:1003200084C1113409F4A6C0123409F427C213346D +:1003300009F404C1133609F451C9143409F4EBC0AB +:10034000153409F4D8C0163409F408C1163609F476 +:1003500051C9173409F49EC0183409F463C918361A +:1003600009F454C91B3409F461C01C3409F4D4C124 +:100370001D3409F42BC01E3409F4FCC0103509F4F7 +:1003800097C0123509F4DCC0133509F4D2C0153515 +:1003900009F4F4C1163519F410E2E12AF7C0173553 +:1003A00009F4ECC1183509F4B8C11A3509F4E2C1F1 +:1003B000103310F01A3398F07ACFE2D110FF03C057 +:1003C00014E0B12A74CF1BEFB12271CFD9D1103311 +:1003D00021F4F89400E4B02A43CF69CFD1D135D1CC +:1003E000C0E1C093F300D093F4002093F5005FCFF9 +:1003F00001D05DCF0F92C091F300D091F400209115 +:10040000F500DE5FC395F89435B320FB36F9789498 +:1004100035BB69D4182F100D100D1A95103418F033 +:10042000EED00F900895800D0F900895979800E0FA +:10043000E9DEE8DE02E4E2DE00E2E4DE00E0E2DE45 +:1004400003E4DCDE00E8DADE00E9D8DE00E0DADE34 +:10045000D9DE04E2D3DE00EBD1DEE0E0F8E000E03C +:10046000D3DE3197E1F702EBCBDE08E9C7DE979ADE +:10047000A9D41DCF85D1117051F41FE7B122AF98D7 +:10048000C498409101014BBBC39AC39810CF10E8A8 +:10049000B12A0DCF75D1103309F404C0113309F41A +:1004A00004C005CF07EFB02202CF08E0B02AFFCE8C +:1004B00067D1103309F403C0113309F403C00FEE00 +:1004C000B022F5CE00E1B02AF2CEC091F300D09177 +:1004D000F4002091F500DE5FF89435B320FB36F987 +:1004E000789435BB00D470191FB712FFE0CE01D04D +:1004F000DECE7727089544D111FD07C010FD03C05B +:100500000FEDB022D4CE00E2B02A002700932301E1 +:1005100082D2F1F7CCCE34D1103309F404C01133B8 +:1005200009F404C0C4CE0EEFB022C1CE01E0B02A5F +:10053000BECE26D1712F24D1812FB9CE02E0B02AB0 +:1005400070933401809335011BD11093360118D17B +:1005500010933701E5D20DEFB022A9CE7093380188 +:10056000809339010DD110933A010AD110933B01C8 +:100570002CD39DCE709338018093390101D1109313 +:100580003A01FED010933B0145D391CEF9D010FF34 +:100590000BC01091FE002091FF001C5F2F4F1B3AF3 +:1005A0000FEF2007A8F40AC01091FE002091FF0071 +:1005B000145020401A380DEF200750F01093FE0021 +:1005C0002093FF0022E00DD01091FF0023E009D01E +:1005D0006ECEE199FECF2EBB22272FBBE09A1DB332 +:1005E0000895E199FECFE5FEFFCF2EBB22272FBB5A +:1005F0001DBBF894E5FEFFCFE29AE19A18951AC563 +:10060000BFD023D0BDD0A12FBBD0B12FB9D0F8948B +:1006100035B320FB36F9789435BB80D221961197FB +:100620001A2F1B2B09F0F2CF42CEAAD00ED01F9367 +:100630001AD01BE1C6D01FE3C4D01F91105DC1D0FA +:100640001D2F5AD01C2F58D032CEC0E0D0E022E669 +:100650001F70163008F4210F2695D7952695D7954B +:10066000D695D6950895A6E1B2E0AC0FBD1FF894DB +:1006700035B320FB36F9789435BB4FD2E12F119674 +:100680004CD2F12FAC2FBD2F1496CFEFDFEF319767 +:10069000FF70349780F1319640D2119601E220E14B +:1006A000D127CC0FDD1F10F4C027D227CC0FDD1FC0 +:1006B00010F4C027D227CC0FDD1F10F4C027D2279B +:1006C000CC0FDD1F10F4C027D227CC0FDD1F10F494 +:1006D000C027D227CC0FDD1F10F4C027D227CC0FA4 +:1006E000DD1F10F4C027D227CC0FDD1F10F4C02768 +:1006F000D227319789F608951F93129504D061D0BF +:100700001F9101D05EC01F7010631A3308F0195F8B +:100710000895F7C3FFC307C4AAC432D010FD13C0A5 +:100720007093460180934701B09248011091F30005 +:10073000109349011091F40010934A011091F500B3 +:1007400010934B01B4CD709146018091470110EC9C +:10075000B122109148011F73B12A109149011093E1 +:10076000F30010914A011093F40010914B01109383 +:10077000F5009DCD05D004D003D002D001D097CD97 +:1007800010EC10934401A89510E01EBB1FBB10ECA9 +:10079000809910934401B5FC3ED13320A1F310E0C1 +:1007A00010934401CF93DF93C22DC059DD271881E8 +:1007B000F8943A942394CFE72C227894DF91CF9148 +:1007C00008951F93A895152D1031E0F71F91CF9331 +:1007D000DF93DFB7F894C52DC40DDFBFCF70C05ACB +:1007E000DD2718835394DF91CF91089578940027E3 +:1007F00000930001982E672F6AD26093F200A092B6 +:10080000F000C12FDD27CC0FDD1F1091F300C10FC9 +:100810001091F400D11F1091F50026D564D22196D5 +:10082000F02C61D2CF2DD02D1091F300C10F10917B +:10083000F400D11F58D2802C1C2F2D2F219785FC1E +:1008400007C0C091F300D091F400DE5F4CD21DC010 +:100850004AD2B4FC1AC0C091F300D091F400DE5F1C +:10086000F02C41D20F1808F40024069400920001E5 +:10087000672F600D2CD26093F200A092F000C0911F +:10088000F300D091F400DE5F2ED2B3FC1AC0072F24 +:10089000000D08F016C01F932F932BDEABDD0091E7 +:1008A0000001700F982E672F12D26093F200A09271 +:1008B000F00000910001701B1091F500D5D42F912C +:1008C0001F91700D86FE05C0C12FD22F22970BD22B +:1008D000900CC12FD22F219606D2702C0FEF0ABB9D +:1008E000C09A0FE180228092F1000027801201C09F +:1008F00087C0AA27B92DB695A795B695A795B05FDD +:1009000007C09394A05CBF4F8090F100A090F000CE +:10091000AA2A222721961091F500A6D4E4D1112706 +:100920006091F200662339F08894079417956A95D0 +:10093000E1F7022A212F08E1F89435B300FB36F9DC +:10094000789435BBF89435B33A25307C3A257894C1 +:1009500035BB3B2F330F330FA7FA31F9A6FA30F925 +:100960003BBBF894C39AC398789430930101002755 +:100970000ABBF894C29ABA98C0980000C09A09B30A +:100980000026B0FC002A0FEF0ABB0BBAC19800008A +:10099000C19A7894C298BA9AA3948A9409F0BACF6B +:1009A000222351F1F89435B33A25307C3A257894D6 +:1009B00035BB3B2F330F330FA7FA31F9A6FA30F9C5 +:1009C0003BBBF894C39AC3987894309301010027F5 +:1009D0000ABBF894C29ABA98C0980000C09A09B3AA +:1009E0002027B0FC202B0FEF0ABB2BBBC1980000C7 +:1009F000C19A7894C298BA9A04D07A9409F081CFB7 +:100A00000895CF93DF93192D78D01881122B188376 +:100A1000DF91CF9108952F93CF93DF93109123010E +:100A20006CD01881122309F45EC028812127288305 +:100A300010E010934401AF93BF93A3E0B1E0CC2743 +:100A4000D0912301D695C795D695C795D05F18E16B +:100A50000BD42EE1F89435B33C27307C3C277894B6 +:100A600035BB3D2F330F330FC7FB31F9C6FB30F9D0 +:100A70003BBBF894C39AC398789430930101002744 +:100A80000ABBF894C29ABA98C0980000C09A19B3E9 +:100A90007894C298BA9A0FEF0ABB1D93C3952A9512 +:100AA00009F0D8CFBF91AF91CC27D0912301D69533 +:100AB000C795D695C795D695C79597980C2FA2DB65 +:100AC0000D2FA0DB04E29ADB00EB98DB2EE1C3E004 +:100AD000D1E0099199DB2A95E1F702EB91DB979A36 +:100AE00010EC109344011091230113951F73109380 +:100AF0002301DF91CF912F910895C4E2D1E0212FFE +:100B0000269526952695C20F20E0D21F21E017706A +:100B100019F0220F1A95E9F7089562C385C3C7CB70 +:100B200078949090350160913401D1D06093F200B7 +:100B3000A092F00070903701CC27D92DD695C7959B +:100B4000D695C795D05F18E18FD307C0C05CDF4F43 +:100B500093946091F200A090F000AC2A1FEF809077 +:100B6000360100E0801641F008E08016B8F06623F8 +:100B700019F016956A95E9F7DAD008E01091F200BD +:100B8000011B801AA3941FEF08E0801638F0B1F023 +:100B9000CED01FEF08E0801AA394F6CF882079F01A +:100BA00016958A94E9F71095662341F02227169549 +:100BB00027956A95E1F7BBD0A394122FB8D021DF17 +:100BC0007A9400277012C2CF089500913A010A95D5 +:100BD0000230D0F300913B010330B0F300913801B3 +:100BE0000395009334010091390100933501809001 +:100BF0003A018A948A948092360101E00093370189 +:100C00008FDF009138010093340180903A01809287 +:100C100036013AC000913A010A950230A8F20091DB +:100C20003B01033088F200913801039500933401B1 +:100C3000009139010093350180903A018A948A9499 +:100C40008092360101E0009337016ADF009138019C +:100C500000933401009139010395009335017090A0 +:100C60003B017A947A947092370101E00093360147 +:100C700057DF80903A0100913801080D0A950093E2 +:100C8000340101E00093360100913901039500938E +:100C9000350170903B017A947A947092370140DF6D +:100CA0000091380103950093340180903A018A94B1 +:100CB0008A948092360170903B0100913901070DB2 +:100CC0000A950093350101E00093370129CFAA244A +:100CD00000EFA01A67FFAA246F77685014F0A3945E +:100CE000FCCF685F0895F89435B33C27307C3C27EF +:100CF000789435BB3D2F330F330FC7FB31F9C6FB5B +:100D000030F93BBBF894C39AC398789430930101AF +:100D100000270ABBF894C29ABA98C0980000C09AFB +:100D200009B27894C298BA9A0FEF0ABB0895F89462 +:100D300035B33A25307C3A25789435BB3D2F330FB7 +:100D4000330FA7FA31F9A6FA30F93BBBF894C39AEE +:100D5000C39878943093010100270ABBF894C29A93 +:100D6000BA98C0980000C09AF9B27894C298BA9A1A +:100D70000FEF0ABBB1FE03C01095F12203C0F126AC +:100D8000B0FCF12AF89435B33A25307C3A257894B2 +:100D900035BB3D2F330F330FA7FA31F9A6FA30F9DF +:100DA0003BBBF894C39AC398789430930101FBBA83 +:100DB000F894C29ABA98C1980000C19A7894C298DF +:100DC000BA9A08959924C0E0D0E118E14DD2AA243E +:100DD000A092F0001091F0001C2BF89435B331274D +:100DE000307C3127789435BB3D2F330F330F17FB01 +:100DF00031F916FB30F93BBBF894C39AC398789449 +:100E00003093010100E00BBBF894C29ABA98C198E4 +:100E10000000C19A7894C298BA9AA39400E2A016EE +:100E200019F0A092F000D6CFECDD9394C05CDF4FB8 +:100E3000D03209F0CCCF7727882708951FB60F93BB +:100E40000FEDC02EEF93FF93E42DE05AFF270081B2 +:100E5000FF91EF910CB95A9443940FE040226A94A9 +:100E60000AF046C04BC01FB60F930FEDC02E0CB159 +:100E70005C9938C0E7FC26C0E6FC08C0033029F4C2 +:100E800003E009B9539A00E4E02A38C0602E00E874 +:100E900003190AF40FE7662012F4052D00680CB957 +:100EA000061508F4602E062D0F7739F000ECE02AC5 +:100EB0006A9422F55798559A21C00FEBE022569A72 +:100EC0005E9A1CC0EF93FF93E32DE20DEF77E0599C +:100ED000FF270083FF91EF9133946A947AF40CC05A +:100EE0001FB60F9353980FE509B90FEBE022CC24FE +:100EF00055985698579A0CB10FE7E0220F911FBEF4 +:100F000018951FB68A9A4CB55DB55093FB00409377 +:100F1000FA008EC01FB68B9A4CB55DB55093F900A0 +:100F20004093F80085C01FB65AB35F935BB35F93DD +:100F30005FEF5ABBB7FE14C0509151015395553223 +:100F400028F4523159F4AF98C49A03C0AF9AC498A8 +:100F500050E0409101014BBBC39AC398509351019B +:100F600055B35F93509101015F9350914501505CDF +:100F70005093450149F450914401539550934401D5 +:100F800019F45FEBB5226CC950EB5FBD4CB55DB594 +:100F9000485F5F4F5BBD4ABD59BD48BD8A9A929A72 +:100FA0008B9A939A8D9895985091FD004091FC00F2 +:100FB0008D9A859907C040389DEF59074AF04150F6 +:100FC000504006C0453D9FEF590712F44F5F5F4FF9 +:100FD0005093FD004093FC005BBD4ABD9091FE0024 +:100FE000491B9091FF00590B1AF445EF5FEF02C0C7 +:100FF00040E85DEF59BD48BD000000000000000062 +:10100000000000005DEF5DBD55E75CBD8A989298D9 +:101010008B98939850EE5FBD5F915BBBC39AC3986A +:10102000509301015F9155BB5F915BBB5F915ABBD0 +:101030001FBE18959924C0E0D0E1A0E0B0E118E10E +:1010400013D1A05CBF4F0A94E1F720E22F93C8D0E0 +:10105000EBD0A395C3952F912A9509F0F7CFD1DC5A +:101060009394A0969096B03209F0EFCFB0CE88DB83 +:101070001F9386DB10934C0183DB1695169516950E +:1010800009F410E210934F017BDB10935001172FEE +:1010900016951695169510934D0180934E0118E103 +:1010A000E3D01F9110FD46C0CC27D0914E019D2E5C +:1010B000D695C795D695C79510914D01C10FD05FB4 +:1010C0002091500110914C01121720F5211BAA27E5 +:1010D000B0914E01B10FB695A795B695A795109111 +:1010E0004D01A10FB05F2F93AF93BF93CF93DF93C9 +:1010F00020914F0168D085DCDF91CF91BF91AF91F6 +:101100002F919394A05CBF4FC05CDF4F2A9559F795 +:1011100020914C012F93CF93DF9320914F015AD010 +:1011200070DCDF91CF912F919394C05CDF4F2A95B3 +:1011300089F7F5CCCC27D0914E0100915001D00F0A +:101140009D2ED695C795D695C79510914D01C10F87 +:10115000D05F202F10914C01121728F5211BAA27D0 +:10116000B0914E01B00FB11BB695A795B695A79556 +:1011700010914D01A10FB05F9A94A054B040C0549B +:10118000D0402F93AF93BF93CF93DF9320914F0124 +:101190001AD037DCDF91CF91BF91AF912F912A9573 +:1011A00059F720914C019A94C054D0402F93CF937B +:1011B000DF9320914F010ED024DCDF91CF912F914E +:1011C0002A9589F7ACCC0CD011962ED021962A9571 +:1011D000D1F7089510E028D021962A95E1F70895D7 +:1011E000F89435B33A27307C3A27789435BB3B2FB7 +:1011F000330F330FA7FB31F9A6FB30F93BBBF89453 +:10120000C39AC39878943093010100270ABBF894DD +:10121000C29ABA98C0980000C09A19B37894C2983C +:10122000BA9A0FEF0ABB0895F89435B33C27307C87 +:101230003C27789435BB3D2F330F330FC7FB31F973 +:10124000C6FB30F93BBBF894C39AC39878943093AB +:1012500001011BBBF894C29ABA98C1980000C19AC8 +:101260007894C298BA9A0895F89435B310FB36F979 +:10127000789435BB089546323444303331393033B5 +:101280003132313730394C034C034C034C034C039F +:101290004C034C034C034C034C034C034C034C03D6 +:1012A0004C034C034C034C034C034C034C034C03C6 +:1012B0004C034C034C034C034C034C034C034C03B6 +:1012C0004C034C034C0300014C034C034C034C03F4 +:1012D0004C034C034C034C034C034C034C034C0396 +:1012E00003014C034C0306010F01180121012A01DF +:1012F00033013C0145014E0157014C034C034C03A3 +:101300004C034C034C034C036001690172017B01E7 +:1013100084018D0196019F01A901B201BB01C401A5 +:10132000CD01D601DF01E801F101080211021A0224 +:1013300023022C0235023E02470250024C034C03AA +:101340004C034C034C034C03590262026B027402BF +:101350007D0286028F029902A302AD02B802C20288 +:10136000CB02D402DD02E602F002FC0203030C030E +:1013700015031E0327033003390343034C034C03B7 +:101380004C034C034C030003066101F8010770880D +:1013900098A8C888700107206020202020700107CD +:1013A000708808102040F80107F810201008887095 +:1013B000010710305090F810100107F880F008086D +:1013C00088700107304080F08888700107F80810A5 +:1013D000204040400107708888708888700107703D +:1013E000888878081060010770888888F8888801E4 +:1013F00007F08888F08888F00107708880808088EE +:10140000700107E09088888890E00107F88080F0FC +:101410008080F80107F88080F08080800107708864 +:1014200080B88888780107888888F88888880221A9 +:10143000078080808080808001070808080808886D +:101440007001078890A0C0A09088010780808080EC +:101450008080F8010788D8A8A8888888010788882C +:10146000C8A89888880107708888888888700107CC +:10147000F08888F0808080010770888888A890684C +:101480004C034C034C03060801014F0065030107A0 +:10149000F08888F0A09088010770888070088870B4 +:1014A0000107F820202020202001078888888888CC +:1014B0008870010788888888885020010788888874 +:1014C000A8A8A8500107888850205088880107885C +:1014D0008888502020200107F80810204080F8015B +:1014E000070000700878887801078080F088888875 +:1014F000F00107000078808080780107080878886C +:10150000888878010700007088F88070010718202B +:10151000F8202020200108000078888878087001D1 +:10152000078080B0C888888802210780008080807A +:101530008080052108100010101010906005210710 +:10154000808090A0C0A090032107C0404040404050 +:101550004001070000F0A8A8A8A801070000B0C833 +:10156000888888010700007088888870010800005A +:10157000F08888F080800108000078888878080862 +:1015800002056105B0C0808080010700007880708E +:1015900008F001072020F82020201801070000880B +:1015A0008888986801070000888888502001070013 +:1015B000008888A8A85001070000885020508801A2 +:1015C00008000088888878087001070000F810205B +:1015D00040F80107F8F8F8F8F8F8F80070933801C7 +:1015E00080933901CDD810933A01CAD810933B01AA +:1015F00026D05DC67093380180933901C1D810930D +:101600003A01BED810933B012FD051C670933401DC +:1016100080933501B5D810933601B2D810933701B5 +:1016200078D045C67093340180933501A9D81093C2 +:101630003601A6D81093370171D039C608950091AC +:101640003801009334010091390100933501009174 +:101650003A010093360100913B010093370102E00B +:10166000B02A5EDA0DEFB02200913A010A950230FD +:1016700028F300913B01033008F3009138010093F7 +:101680003401009139010093350100913A01009332 +:10169000360101E00093370143DA009138010093ED +:1016A00034010091390103950093350100913B010C +:1016B00002500093370101E00093360131DA809047 +:1016C0003A0100913801080D0A950093340101E0B8 +:1016D0000093360100913901039500933501009183 +:1016E0003B010250009337011BDA0091380100934F +:1016F000340100913A010093360170903B01009152 +:101700003901070D0A950093350101E00093370177 +:1017100007CA02E0B02A04DA0DEFB0227894909064 +:10172000350160913401D3DA6093F200A092F000A9 +:1017300070903701CC27D92D15E5D0FF1AEA012E7C +:10174000D695C795D695C795D05F18E18DDD07C0B2 +:10175000C05CDF4F93946091F200A090F000AC2A3F +:101760001FEF8090360100E0801641F008E08016FF +:10177000C8F0662319F016956A95E9F71021D7DAB3 +:1017800008E01091F200011B801AA3941FEF08E0FB +:10179000801640F0C1F01021CADA1FEF08E0801A6D +:1017A000A394F5CF882089F016958A94E9F71095CF +:1017B000662349F02227169527956A95E1F71021AF +:1017C000B6DAA394122F1021B2DA00941AD97A94BF +:0817D00000277012BDCF08953F +:0220000003419A +:00000001FF diff --git a/src/avr/product/MT102V0.HEX b/src/avr/product/MT102V0.HEX new file mode 100644 index 00000000..6263fea7 --- /dev/null +++ b/src/avr/product/MT102V0.HEX @@ -0,0 +1,191 @@ +:020000020000FC +:0200000033C209 +:04000A007CC104C0F1 +:10001000DDC1C7C118C2FFB65F936F9358EB52BFE3 +:10002000A89508956F915F91FFBE1895BA9494D0EA +:10003000F9DF90D0F7DFBB2019F4272F2C70B9F02F +:10004000E1FC06C022E1E22A89D0A298AA9AEADF5E +:10005000BB2061F773FF20C172FF82C0382D737F10 +:1000600079D0E0DF79D0DEDF3A95D1F7E4CFE1FE59 +:100070000BC0D8DF2DEFE22220E174FFE22A20E05E +:1000800022BBAA98A29AD6CF74FD38C020E022BF26 +:1000900020E4E20E78F69298A398A298AA9A20E714 +:1000A000E0FE20E822BFBEDF2091D30023952093FD +:1000B000D30011F420E1E22A33B3929AA39AAA98CA +:1000C000A29A33FD06C020E1E0FCE22A2EEFE222F4 +:1000D00004C0E0FC02C021E1E22A32FD0AC0E3FED6 +:1000E000A9CF28E7E0FCB22E20E1E22A27EFE222A6 +:1000F000A1CFE3FC9FCF28E1E22A9CCF7F7E24E1C1 +:10010000E22AA998A0E2BEE438EE43E0119779F024 +:100110002CEF22BF87DF9899F7CF31504040B1F7DD +:10012000119729F02CEF22BF7DDF989BF9CFA99A78 +:10013000A8EEB3E02CEF22BF75DF1197D9F72BEFB4 +:10014000E2222B2D222329F4272F2C7011F420E1F9 +:10015000E22A70CF20EA01C020E5A226A2BA0895C3 +:100160002FEF22BFDD0CDD0C20ECD22277FFD394E1 +:10017000A0E8B1E080E090E030E0EF93FF93E32F60 +:10018000E695E695E695E05A2081532F57705395F2 +:100190004091D1004F7026955A95E9F710F4440F1D +:1001A0004F57E32FEA5920812032C8F0E22FFF2772 +:1001B000EE0FFF1FEE0FFF1FE20F20E0F21FEE0F0A +:1001C000FF1F2D2D2F70E20F20E0F21F20EBE20F1A +:1001D00026E0F21F602DC895202D062E0FC0E22FBD +:1001E000EE0FEE0FE20FEE0FE20FE85F2D2D2F70F6 +:1001F000E20FE199FECFEEBBE09A2DB3FF91EF91B4 +:1002000011DF5FEF47FD5EEF52BF65D061E064D064 +:1002100009DF5FEF47FD5EEF52BF339547FD339532 +:100220003A3208F4AACF20E046E061E055D02D2D07 +:10023000203C20F42395203808F423952F70293092 +:1002400008F0777F4091D100939A9398EBDE84DF9A +:1002500027E028BBE7DE382F292F269537952695EE +:100260003795385E2A2D79DF5FEF52BFDBDE3A9596 +:10027000D1F7A22E20E028BB6DDF405138F72D2D9D +:10028000203C20F42395203808F423952F70293042 +:1002900010F4D3946DCFCECE2FEF22BFA0E8B1E003 +:1002A00080E090E030E0EF93E32FE05A2081EF917F +:1002B0004091D2004F70B6DE5FEF52BF0CD0B2DE7D +:1002C0005FEF52BF3395303370F37B7F2FEFD22E29 +:1002D0004091D200B9CF68E0AA2311F4BB2381F08A +:1002E000220F08F4AB9A542F5F77AD9AAB99019621 +:1002F0001197AD9829F05150C0F7AB986A9581F7E6 +:10030000AB9808952FE121BD27E121BD20E325BF52 +:1003100088950FEF0DBD00E00CBD00E808BF02E8B6 +:1003200009BF00E00EBB809B04C00FEF0DBD00E0D5 +:100330000CBDE4FE0FC0042D013060F400E000931A +:10034000D3000FEEE0220E2D0F7000630A3308F089 +:10035000095F18D0222029F302E009BFCF93DF9371 +:10036000C12DCF56DD270881F8942A941394CFE34A +:100370001C227894DF91CF9108950F93042D0130C2 +:10038000E8F70F91CF93DF93DFB7F894C42DC30D37 +:10039000DFBFC070C057DD2708834394DF91CF9142 +:1003A0000895FFB64F934EEC742EEF93FF93E32D19 +:1003B000E057FF274081FF91EF914CB94A94339465 +:1003C00040E034226A940AF046C04BC0FFB64F9317 +:1003D0004EEC742E4CB15C9938C057FC26C056FCCC +:1003E00008C0453029F445E049B9539A40E4542AFD +:1003F00038C0642E40E442190AF44FE7662012F434 +:10040000442D40684CB9461508F4642E462D4F77AC +:1004100039F040EC542A6A9422F55798559A21C035 +:100420004FEB5422569A5E9A1CC0EF93FF93E22D35 +:10043000E10DEF73EF56FF274083FF91EF91239477 +:100440006A947AF40CC0FFB64F9353984FE849B9B9 +:100450004FEB5422772455985698579A4CB14FE752 +:1004600054224F91FFBE18950FED0DBF00E808B95B +:10047000A8950FE001BD929A8A9A8C9A8D9A8E9ACD +:100480008F9A8B9AA39AA59AB89AB99ABA9AA19A6E +:1004900003E005BB00E002BB0FE809B900E90AB9B7 +:1004A000332444241124222455246624772471EC17 +:1004B00001E2E02E00E20093D10001E20093D200BD +:1004C00003E0C02EBB2400E6A02E5AE160E004E069 +:1004D00003BF08EB02BF02E008BF09BF00E00FBD89 +:1004E00004E00EBD78942CD1E2E041D10C1729F440 +:1004F000E3953DD10D1771F0EA950CEA3FD1E395F4 +:100500000BEF3CD1E39501E039D1E39500E036D122 +:10051000E39534D10FEDE02200E00EBB809BFECFCF +:100520008824726099240FEDE02200E00EBB082DB4 +:10053000003288F40B3119F1083191F3043149F09C +:100540000E3029F00D30F9F0E4DE802EECCF7E7F06 +:10055000FBCF7160F9CF70FD07C0092D0932A8F4F7 +:10056000082D27D10068008300E208117D7F082D47 +:1005700020D100838824092D0A3278F4E5CF092D93 +:10058000013018F42FC08824716071FD24C000E28E +:1005900010D10083092D0A32D0F371FD1CC00091E7 +:1005A00065000695069506950695069506950093B1 +:1005B00065000C2D043008F003E00295D02A786025 +:1005C00073FDFECF7F77CC2029F00C2D035008F06F +:1005D000E6D07068A6CF07E077FF06E0E0D0DED077 +:1005E00070689FCF96DE0E3219F400E2E02A7FC0D9 +:1005F0000F3309F491C0013479F0023481F00334EF +:1006000009F4C8C00A3419F10B34C9F1023579F084 +:10061000043549F17EDE84CF7CDEC02E81CF79DEC9 +:10062000002321F077FF0A95BAD0706879CF71DE88 +:10063000002349F01091D100802E7C6073FDFECF25 +:100640001051D0F777FD6CCF706801E0F3CF61DE19 +:100650000A950F70102F5DDE0A950F700295012B21 +:100660000093D2005DCF55DE0A950F70102F51DE3A +:100670000A950F700295012B0093D10051CF49DEEE +:10068000002E47DEC02F45DED02F0C2B002949F16C +:1006900001E077FD84D0726099243BDE802E00E07B +:1006A00008117D7F082D9FD0092D003348F40015D7 +:1006B000A0F371FD17C000E096D0092D0033D8F3E8 +:1006C00071FD10C0746072FDFECF21970C2F0D2BB1 +:1006D00011F77F77CC2029F00C2D015008F05FD066 +:1006E00070681ECF01E01091D2005BD0EECF11DE1A +:1006F000E2E00FDE43D0E3950CDE40D0E39509DE67 +:10070000F02F3CD0E39505DE39D0E39502DE36D0FC +:10071000E395FA95D9F704CFFCDD0BE12EDE0FE36C +:100720002CDE00E32ADEE2E022D027DEE3951FD0B4 +:1007300024DEE3951CD021DEE39519D01EDEF0CE39 +:10074000E4E015D0F02FFE5FCFEFDFEF11E2012ED6 +:1007500010E10DD0D027E39508E0CC0FDD1F10F499 +:10076000C025D1270A95C9F7FA9599F70895E19917 +:10077000FECFF894EEBBE09A0DB31895E199FECF49 +:10078000F894E5FEFFCFEEBB0DBBE5FEFFCFE29A8E +:10079000E19A1895706174FDFECFC2CE0C2D1091B8 +:1007A000D1000F930B0D0F91E0F3B00E1051C8F76D +:1007B0000895C02FD0E0E6E0DADFF02FE395D7DF31 +:1007C0000C1729F0E55FD395FA95C9F7DC2FE92DD1 +:1007D000EA59D083E92DE695E695E695E05A93949B +:1007E000008106950895E92DE05A008393940895B9 +:1007F0000000000000000000000000181818181881 +:100800000018000000E763C600000000000000665A +:1008100066FF66FF66660000187EDBD87E1BDB7E07 +:10082000180000E3E60C183067C700000078CCD849 +:1008300073DECC7B0000003C0C18000000000000C0 +:10084000000C18303030180C00000030180C0C0C64 +:10085000183000000018DB7E3C7EDB180000000032 +:100860001818FF18180000000000000000003C0CE1 +:10087000180000000000FF00000000000000000061 +:1008800000003C3C00000003060C183060C0000073 +:10089000007EC7CFDBF3E37E0000000C1C3C0C0C99 +:1008A0000C0C0000007EC3030E3860FF0000007EC9 +:1008B000C3033E03C37E0000001C3C6CCCFF0C0C49 +:1008C000000000FFC0FE0303C37E0000003E60C0C6 +:1008D000FEC3C37E000000FF03060C1818180000BA +:1008E000007EC3C37EC3C37E0000007EC3C37F03FC +:1008F000067C000000003C3C003C3C000000000086 +:100900003C3C003C0C180000000C18306030180C07 +:100910000000000000FF00FF000000000030180C85 +:10092000060C18300000007EC3030E1800180000EB +:10093000007EC3DBDBDFC07C0000003C66C3FFC37E +:10094000C3C3000000FEC3C3FEC3C3FE0000007E9D +:10095000C3C0C0C0C37E000000FCC6C3C3C3C6FC86 +:10096000000000FFC0C0FEC0C0FF000000FFC0C00C +:10097000FEC0C0C00000007EC3C0C0CFC37F000067 +:1009800000C3C3C3FFC3C3C300000018181818185E +:1009900018180000000303030303C37E000000C314 +:1009A000C6CCF8CCC6C3000000C0C0C0C0C0C0FFE9 +:1009B000000000C3E7FFDBC3C3C3000000C3E3F3D1 +:1009C000DBCFC7C30000007EC3C3C3C3C37E000028 +:1009D00000FEC3C3FEC0C0C00000007EC3C3C3C3CB +:1009E000CF7E030000FEC3C3FECCC6C30000007E62 +:1009F000C3C07E03C37E000000FF18181818181823 +:100A0000000000C3C3C3C3C3C37E000000C3C3C38D +:100A1000C3663C18000000C3C3C3C3DBFF6600000D +:100A200000C3663C183C66C3000000C3C3663C18A4 +:100A30001818000000FF060C183060FF0000003C92 +:100A400030303030303C000000C06030180C0603FD +:100A50000000003C0C0C0C0C0C3C0000183C66C365 +:100A600000000000000000000000000000FF000087 +:100A70000C181E000000000000000000007E037F34 +:100A8000C37F000000C0C0FEC3C3C3FE000000005F +:100A9000007EC3C0C37E00000003037FC3C3C37FC7 +:100AA00000000000007EC3FFC07E0000001E333047 +:100AB000FC30303000000000007FC3C3C37F037EE2 +:100AC00000C0C0FEC3C3C3C300000018001818183C +:100AD000181800000006000606060606067C00C080 +:100AE000C0C6CCF8CCC60000003030303030301CEE +:100AF0000000000000FEDBDBDBDB0000000000FE8E +:100B0000C3C3C3C300000000007EC3C3C37E000094 +:100B1000000000FEC3C3C3FEC0C00000007FC3C30B +:100B2000C37F0303000000FEC3C0C0C0000000007C +:100B3000007EC07E037E00000018187E1818180E74 +:100B40000000000000C3C3C3C37F0000000000C357 +:100B5000C3663C180000000000C3C3DBFF66000052 +:100B6000000000C3663C66C30000000000C3C3C3AE +:100B7000C37F037E000000FF0C1830FF0000000E52 +:100B800018187018180E00000018181800181818F7 +:100B90000000007018180E18187000000076DC00B5 +:100BA000000000000000000000183C66C3FF0000C9 +:042000000541B2AC38 +:00000001FF diff --git a/src/avr/product/MT102V1.HEX b/src/avr/product/MT102V1.HEX new file mode 100644 index 00000000..1e074a5a --- /dev/null +++ b/src/avr/product/MT102V1.HEX @@ -0,0 +1,191 @@ +:020000020000FC +:0200000033C209 +:04000A007CC104C0F1 +:10001000DDC1C7C118C2FFB65F936F9358EB52BFE3 +:10002000A89508956F915F91FFBE1895BA9494D0EA +:10003000F9DF90D0F7DFBB2019F4272F2C70B9F02F +:10004000E1FC06C022E1E22A89D0A298AA9AEADF5E +:10005000BB2061F773FF20C172FF82C0382D737F10 +:1000600079D0E0DF79D0DEDF3A95D1F7E4CFE1FE59 +:100070000BC0D8DF2DEFE22220E174FFE22A20E05E +:1000800022BBAA98A29AD6CF74FD38C020E022BF26 +:1000900020E4E20E78F69298A398A298AA9A20E714 +:1000A000E0FE20E822BFBEDF2091D30023952093FD +:1000B000D30011F420E1E22A33B3929AA39AAA98CA +:1000C000A29A33FD06C020E1E0FCE22A2EEFE222F4 +:1000D00004C0E0FC02C021E1E22A32FD0AC0E3FED6 +:1000E000A9CF28E7E0FCB22E20E1E22A27EFE222A6 +:1000F000A1CFE3FC9FCF28E1E22A9CCF7F7E24E1C1 +:10010000E22AA998A0E2BEE438EE43E0119779F024 +:100110002CEF22BF87DF9899F7CF31504040B1F7DD +:10012000119729F02CEF22BF7DDF989BF9CFA99A78 +:10013000A8EEB3E02CEF22BF75DF1197D9F72BEFB4 +:10014000E2222B2D222329F4272F2C7011F420E1F9 +:10015000E22A70CF20EA01C020E5A226A2BA0895C3 +:100160002FEF22BFDD0CDD0C20ECD22277FFD394E1 +:10017000A0E8B1E080E090E030E0EF93FF93E32F60 +:10018000E695E695E695E05A2081532F57705395F2 +:100190004091D1004F7026955A95E9F710F4440F1D +:1001A0004F57E32FEA5920812032C8F0E22FFF2772 +:1001B000EE0FFF1FEE0FFF1FE20F20E0F21FEE0F0A +:1001C000FF1F2D2D2F70E20F20E0F21F20EBE20F1A +:1001D00026E0F21F602DC895202D062E0FC0E22FBD +:1001E000EE0FEE0FE20FEE0FE20FE85F2D2D2F70F6 +:1001F000E20FE199FECFEEBBE09A2DB3FF91EF91B4 +:1002000011DF5FEF47FD5EEF52BF65D061E064D064 +:1002100009DF5FEF47FD5EEF52BF339547FD339532 +:100220003A3208F4AACF20E046E061E055D02D2D07 +:10023000203C20F42395203808F423952F70293092 +:1002400008F0777F4091D100939A9398EBDE84DF9A +:1002500027E028BBE7DE382F292F269537952695EE +:100260003795385E2A2D79DF5FEF52BFDBDE3A9596 +:10027000D1F7A22E20E028BB6DDF405138F72D2D9D +:10028000203C20F42395203808F423952F70293042 +:1002900010F4D3946DCFCECE2FEF22BFA0E8B1E003 +:1002A00080E090E030E0EF93E32FE05A2081EF917F +:1002B0004091D2004F70B6DE5FEF52BF0CD0B2DE7D +:1002C0005FEF52BF3395303370F37B7F2FEFD22E29 +:1002D0004091D200B9CF68E0AA2311F4BB2381F08A +:1002E000220F08F4AB9A542F5F77AD9AAB99019621 +:1002F0001197AD9829F05150C0F7AB986A9581F7E6 +:10030000AB9808952FE121BD27E121BD20E325BF52 +:1003100088950FEF0DBD00E00CBD00E808BF02E8B6 +:1003200009BF00E00EBB809B04C00FEF0DBD00E0D5 +:100330000CBDE4FE0FC0042D013060F400E000931A +:10034000D3000FEEE0220E2D0F7000630A3308F089 +:10035000095F18D0222029F302E009BFCF93DF9371 +:10036000C12DCF56DD270881F8942A941394CFE34A +:100370001C227894DF91CF9108950F93042D0130C2 +:10038000E8F70F91CF93DF93DFB7F894C42DC30D37 +:10039000DFBFC070C057DD2708834394DF91CF9142 +:1003A0000895FFB64F934EEC742EEF93FF93E32D19 +:1003B000E057FF274081FF91EF914CB94A94339465 +:1003C00040E034226A940AF046C04BC0FFB64F9317 +:1003D0004EEC742E4CB15C9938C057FC26C056FCCC +:1003E00008C0453029F445E049B9539A40E4542AFD +:1003F00038C0642E40E442190AF44FE7662012F434 +:10040000442D40684CB9461508F4642E462D4F77AC +:1004100039F040EC542A6A9422F55798559A21C035 +:100420004FEB5422569A5E9A1CC0EF93FF93E22D35 +:10043000E10DEF73EF56FF274083FF91EF91239477 +:100440006A947AF40CC0FFB64F9353984FE849B9B9 +:100450004FEB5422772455985698579A4CB14FE752 +:1004600054224F91FFBE18950FED0DBF00E808B95B +:10047000A8950FE001BD929A8A9A8C9A8D9A8E9ACD +:100480008F9A8B9AA39AA59AB89AB99ABA9AA19A6E +:1004900003E005BB00E002BB0FE809B900E90AB9B7 +:1004A000332444241124222455246624772471EC17 +:1004B00001E2E02E00E20093D10001E20093D200BD +:1004C00003E0C02EBB2400E6A02E5AE160E004E069 +:1004D00003BF08EB02BF02E008BF09BF00E00FBD89 +:1004E00004E00EBD78942CD1E2E041D10C1729F440 +:1004F000E3953DD10D1771F0EA950CEA3FD1E395F4 +:100500000BEF3CD1E39501E039D1E39500E036D122 +:10051000E39534D10FEDE02200E00EBB809BFECFCF +:100520008824726099240FEDE02200E00EBB082DB4 +:10053000003288F40B3119F1083191F3043149F09C +:100540000E3029F00D30F9F0E4DE802EECCF7E7F06 +:10055000FBCF7160F9CF70FD07C0092D0932A8F4F7 +:10056000082D27D10068008300E208117D7F082D47 +:1005700020D100838824092D0A3278F4E5CF092D93 +:10058000013018F42FC08824716071FD24C000E28E +:1005900010D10083092D0A32D0F371FD1CC00091E7 +:1005A00065000695069506950695069506950093B1 +:1005B00065000C2D043008F003E00295D02A786025 +:1005C00073FDFECF7F77CC2029F00C2D035008F06F +:1005D000E6D07068A6CF07E077FF06E0E0D0DED077 +:1005E00070689FCF96DE0E3219F400E2E02A7FC0D9 +:1005F0000F3309F491C0013479F0023481F00334EF +:1006000009F4C8C00A3419F10B34C9F1023579F084 +:10061000043549F17EDE84CF7CDEC02E81CF79DEC9 +:10062000002321F077FF0A95BAD0706879CF71DE88 +:10063000002349F01091D100802E7C6073FDFECF25 +:100640001051D0F777FD6CCF706801E0F3CF61DE19 +:100650000A950F70102F5DDE0A950F700295012B21 +:100660000093D2005DCF55DE0A950F70102F51DE3A +:100670000A950F700295012B0093D10051CF49DEEE +:10068000002E47DEC02F45DED02F0C2B002949F16C +:1006900001E077FD84D0726099243BDE802E00E07B +:1006A00008117D7F082D9FD0092D003348F40015D7 +:1006B000A0F371FD17C000E096D0092D0033D8F3E8 +:1006C00071FD10C0746072FDFECF21970C2F0D2BB1 +:1006D00011F77F77CC2029F00C2D015008F05FD066 +:1006E00070681ECF01E01091D2005BD0EECF11DE1A +:1006F000E2E00FDE43D0E3950CDE40D0E39509DE67 +:10070000F02F3CD0E39505DE39D0E39502DE36D0FC +:10071000E395FA95D9F704CFFCDD0BE12EDE0FE36C +:100720002CDE00E32ADEE2E022D027DEE3951FD0B4 +:1007300024DEE3951CD021DEE39519D01EDEF0CE39 +:10074000E4E015D0F02FFE5FCFEFDFEF11E2012ED6 +:1007500010E10DD0D027E39508E0CC0FDD1F10F499 +:10076000C025D1270A95C9F7FA9599F70895E19917 +:10077000FECFF894EEBBE09A0DB31895E199FECF49 +:10078000F894E5FEFFCFEEBB0DBBE5FEFFCFE29A8E +:10079000E19A1895706174FDFECFC2CE0C2D1091B8 +:1007A000D1000F930B0D0F91E0F3B00E1051C8F76D +:1007B0000895C02FD0E0E6E0DADFF02FE395D7DF31 +:1007C0000C1729F0E55FD395FA95C9F7DC2FE92DD1 +:1007D000EA59D083E92DE695E695E695E05A93949B +:1007E000008106950895E92DE05A008393940895B9 +:1007F0000000000000000000000000181818181881 +:100800000018000000E763C600000000000000665A +:1008100066FF66FF66660000187EDBD87E1BDB7E07 +:10082000180000E3E60C183067C700000078CCD849 +:1008300073DECC7B0000003C0C18000000000000C0 +:10084000000C18303030180C00000030180C0C0C64 +:10085000183000000018DB7E3C7EDB180000000032 +:100860001818FF18180000000000000000003C0CE1 +:10087000180000000000FF00000000000000000061 +:1008800000003C3C00000003060C183060C0000073 +:10089000007EC7CFDBF3E37E0000000C1C3C0C0C99 +:1008A0000C0C0000007EC3030E3860FF0000007EC9 +:1008B000C3033E03C37E0000001C3C6CCCFF0C0C49 +:1008C000000000FFC0FE0303C37E0000003E60C0C6 +:1008D000FEC3C37E000000FF03060C1818180000BA +:1008E000007EC3C37EC3C37E0000007EC3C37F03FC +:1008F000067C000000003C3C003C3C000000000086 +:100900003C3C003C0C180000000C18306030180C07 +:100910000000000000FF00FF000000000030180C85 +:10092000060C18300000007EC3030E1800180000EB +:10093000007EC3DBDBDFC07C0000003C66C3FFC37E +:10094000C3C3000000FEC3C3FEC3C3FE0000007E9D +:10095000C3C0C0C0C37E000000FCC6C3C3C3C6FC86 +:10096000000000FFC0C0FEC0C0FF000000FFC0C00C +:10097000FEC0C0C00000007EC3C0C0CFC37F000067 +:1009800000C3C3C3FFC3C3C300000018181818185E +:1009900018180000000303030303C37E000000C314 +:1009A000C6CCF8CCC6C3000000C0C0C0C0C0C0FFE9 +:1009B000000000C3E7FFDBC3C3C3000000C3E3F3D1 +:1009C000DBCFC7C30000007EC3C3C3C3C37E000028 +:1009D00000FEC3C3FEC0C0C00000007EC3C3C3C3CB +:1009E000CF7E030000FEC3C3FECCC6C30000007E62 +:1009F000C3C07E03C37E000000FF18181818181823 +:100A0000000000C3C3C3C3C3C37E000000C3C3C38D +:100A1000C3663C18000000C3C3C3C3DBFF6600000D +:100A200000C3663C183C66C3000000C3C3663C18A4 +:100A30001818000000FF060C183060FF0000003C92 +:100A400030303030303C000000C06030180C0603FD +:100A50000000003C0C0C0C0C0C3C0000183C66C365 +:100A600000000000000000000000000000FF000087 +:100A70000C181E000000000000000000007E037F34 +:100A8000C37F000000C0C0FEC3C3C3FE000000005F +:100A9000007EC3C0C37E00000003037FC3C3C37FC7 +:100AA00000000000007EC3FFC07E0000001E333047 +:100AB000FC30303000000000007FC3C3C37F037EE2 +:100AC00000C0C0FEC3C3C3C300000018001818183C +:100AD000181800000006000606060606067C00C080 +:100AE000C0C6CCF8CCC60000003030303030301CEE +:100AF0000000000000FEDBDBDBDB0000000000FE8E +:100B0000C3C3C3C300000000007EC3C3C37E000094 +:100B1000000000FEC3C3C3FEC0C00000007FC3C30B +:100B2000C37F0303000000FEC3C0C0C0000000007C +:100B3000007EC07E037E00000018187E1818180E74 +:100B40000000000000C3C3C3C37F0000000000C357 +:100B5000C3663C180000000000C3C3DBFF66000052 +:100B6000000000C3663C66C30000000000C3C3C3AE +:100B7000C37F037E000000FF0C1830FF0000000E52 +:100B800018187018180E00000018181800181818F7 +:100B90000000007018180E18187000000076DC00B5 +:100BA000000000000000000000183C66C3FF0000C9 +:042000000541BAAC30 +:00000001FF diff --git a/src/avr/product/MT102V2.HEX b/src/avr/product/MT102V2.HEX new file mode 100644 index 00000000..9d5f9c2b --- /dev/null +++ b/src/avr/product/MT102V2.HEX @@ -0,0 +1,191 @@ +:020000020000FC +:0200000033C209 +:04000A007CC104C0F1 +:10001000DDC1C7C118C2FFB65F936F9358EB52BFE3 +:10002000A89508956F915F91FFBE1895BA9494D0EA +:10003000F9DF90D0F7DFBB2019F4272F2C70B9F02F +:10004000E1FC06C022E1E22A89D0A298AA9AEADF5E +:10005000BB2061F773FF20C172FF82C0382D737F10 +:1000600079D0E0DF79D0DEDF3A95D1F7E4CFE1FE59 +:100070000BC0D8DF2DEFE22220E174FFE22A20E05E +:1000800022BBAA98A29AD6CF74FD38C020E022BF26 +:1000900020E4E20E78F69298A398A298AA9A20E714 +:1000A000E0FE20E822BFBEDF2091D30023952093FD +:1000B000D30011F420E1E22A33B3929AA39AAA98CA +:1000C000A29A33FD06C020E1E0FCE22A2EEFE222F4 +:1000D00004C0E0FC02C021E1E22A32FD0AC0E3FED6 +:1000E000A9CF28E7E0FCB22E20E1E22A27EFE222A6 +:1000F000A1CFE3FC9FCF28E1E22A9CCF7F7E24E1C1 +:10010000E22AA998A0E2BEE438EE43E0119779F024 +:100110002CEF22BF87DF9899F7CF31504040B1F7DD +:10012000119729F02CEF22BF7DDF989BF9CFA99A78 +:10013000A8EEB3E02CEF22BF75DF1197D9F72BEFB4 +:10014000E2222B2D222329F4272F2C7011F420E1F9 +:10015000E22A70CF20EA01C020E5A226A2BA0895C3 +:100160002FEF22BFDD0CDD0C20ECD22277FFD394E1 +:10017000A0E8B1E080E090E030E0EF93FF93E32F60 +:10018000E695E695E695E05A2081532F57705395F2 +:100190004091D1004F7026955A95E9F710F4440F1D +:1001A0004F57E32FEA5920812032C8F0E22FFF2772 +:1001B000EE0FFF1FEE0FFF1FE20F20E0F21FEE0F0A +:1001C000FF1F2D2D2F70E20F20E0F21F20EBE20F1A +:1001D00026E0F21F602DC895202D062E0FC0E22FBD +:1001E000EE0FEE0FE20FEE0FE20FE85F2D2D2F70F6 +:1001F000E20FE199FECFEEBBE09A2DB3FF91EF91B4 +:1002000011DF5FEF47FD5EEF52BF65D061E064D064 +:1002100009DF5FEF47FD5EEF52BF339547FD339532 +:100220003A3208F4AACF20E046E061E055D02D2D07 +:10023000203C20F42395203808F423952F70293092 +:1002400008F0777F4091D100939A9398EBDE84DF9A +:1002500027E028BBE7DE382F292F269537952695EE +:100260003795385E2A2D79DF5FEF52BFDBDE3A9596 +:10027000D1F7A22E20E028BB6DDF405138F72D2D9D +:10028000203C20F42395203808F423952F70293042 +:1002900010F4D3946DCFCECE2FEF22BFA0E8B1E003 +:1002A00080E090E030E0EF93E32FE05A2081EF917F +:1002B0004091D2004F70B6DE5FEF52BF0CD0B2DE7D +:1002C0005FEF52BF3395303370F37B7F2FEFD22E29 +:1002D0004091D200B9CF68E0AA2311F4BB2381F08A +:1002E000220F08F4AB9A542F5F77AD9AAB99019621 +:1002F0001197AD9829F05150C0F7AB986A9581F7E6 +:10030000AB9808952FE121BD27E121BD20E325BF52 +:1003100088950FEF0DBD00E00CBD00E808BF02E8B6 +:1003200009BF00E00EBB809B04C00FEF0DBD00E0D5 +:100330000CBDE4FE0FC0042D013060F400E000931A +:10034000D3000FEEE0220E2D0F7000630A3308F089 +:10035000095F18D0222029F302E009BFCF93DF9371 +:10036000C12DCF56DD270881F8942A941394CFE34A +:100370001C227894DF91CF9108950F93042D0130C2 +:10038000E8F70F91CF93DF93DFB7F894C42DC30D37 +:10039000DFBFC070C057DD2708834394DF91CF9142 +:1003A0000895FFB64F934EEC742EEF93FF93E32D19 +:1003B000E057FF274081FF91EF914CB94A94339465 +:1003C00040E034226A940AF046C04BC0FFB64F9317 +:1003D0004EEC742E4CB15C9938C057FC26C056FCCC +:1003E00008C0453029F443E049B9539A40E4542AFF +:1003F00038C0642E40E442190AF44FE7662012F434 +:10040000442D40684CB9461508F4642E462D4F77AC +:1004100039F040EC542A6A9422F55798559A21C035 +:100420004FEB5422569A5E9A1CC0EF93FF93E22D35 +:10043000E10DEF73EF56FF274083FF91EF91239477 +:100440006A947AF40CC0FFB64F9353984FE549B9BC +:100450004FEB5422772455985698579A4CB14FE752 +:1004600054224F91FFBE18950FED0DBF00E808B95B +:10047000A8950FE001BD929A8A9A8C9A8D9A8E9ACD +:100480008F9A8B9AA39AA59AB89AB99ABA9AA19A6E +:1004900003E005BB00E002BB0FE509B900E90AB9BA +:1004A000332444241124222455246624772471EC17 +:1004B00001E2E02E00E20093D10001E20093D200BD +:1004C00003E0C02EBB2400E6A02E5AE160E004E069 +:1004D00003BF08EB02BF02E008BF09BF00E00FBD89 +:1004E00004E00EBD78942CD1E2E041D10C1729F440 +:1004F000E3953DD10D1771F0EA950CEA3FD1E395F4 +:100500000BEF3CD1E39501E039D1E39500E036D122 +:10051000E39534D10FEDE02200E00EBB809BFECFCF +:100520008824726099240FEDE02200E00EBB082DB4 +:10053000003288F40B3119F1083191F3043149F09C +:100540000E3029F00D30F9F0E4DE802EECCF7E7F06 +:10055000FBCF7160F9CF70FD07C0092D0932A8F4F7 +:10056000082D27D10068008300E208117D7F082D47 +:1005700020D100838824092D0A3278F4E5CF092D93 +:10058000013018F42FC08824716071FD24C000E28E +:1005900010D10083092D0A32D0F371FD1CC00091E7 +:1005A00065000695069506950695069506950093B1 +:1005B00065000C2D043008F003E00295D02A786025 +:1005C00073FDFECF7F77CC2029F00C2D035008F06F +:1005D000E6D07068A6CF07E077FF06E0E0D0DED077 +:1005E00070689FCF96DE0E3219F400E2E02A7FC0D9 +:1005F0000F3309F491C0013479F0023481F00334EF +:1006000009F4C8C00A3419F10B34C9F1023579F084 +:10061000043549F17EDE84CF7CDEC02E81CF79DEC9 +:10062000002321F077FF0A95BAD0706879CF71DE88 +:10063000002349F01091D100802E7C6073FDFECF25 +:100640001051D0F777FD6CCF706801E0F3CF61DE19 +:100650000A950F70102F5DDE0A950F700295012B21 +:100660000093D2005DCF55DE0A950F70102F51DE3A +:100670000A950F700295012B0093D10051CF49DEEE +:10068000002E47DEC02F45DED02F0C2B002949F16C +:1006900001E077FD84D0726099243BDE802E00E07B +:1006A00008117D7F082D9FD0092D003348F40015D7 +:1006B000A0F371FD17C000E096D0092D0033D8F3E8 +:1006C00071FD10C0746072FDFECF21970C2F0D2BB1 +:1006D00011F77F77CC2029F00C2D015008F05FD066 +:1006E00070681ECF01E01091D2005BD0EECF11DE1A +:1006F000E2E00FDE43D0E3950CDE40D0E39509DE67 +:10070000F02F3CD0E39505DE39D0E39502DE36D0FC +:10071000E395FA95D9F704CFFCDD0BE12EDE0FE36C +:100720002CDE00E32ADEE2E022D027DEE3951FD0B4 +:1007300024DEE3951CD021DEE39519D01EDEF0CE39 +:10074000E4E015D0F02FFE5FCFEFDFEF11E2012ED6 +:1007500010E10DD0D027E39508E0CC0FDD1F10F499 +:10076000C025D1270A95C9F7FA9599F70895E19917 +:10077000FECFF894EEBBE09A0DB31895E199FECF49 +:10078000F894E5FEFFCFEEBB0DBBE5FEFFCFE29A8E +:10079000E19A1895706174FDFECFC2CE0C2D1091B8 +:1007A000D1000F930B0D0F91E0F3B00E1051C8F76D +:1007B0000895C02FD0E0E6E0DADFF02FE395D7DF31 +:1007C0000C1729F0E55FD395FA95C9F7DC2FE92DD1 +:1007D000EA59D083E92DE695E695E695E05A93949B +:1007E000008106950895E92DE05A008393940895B9 +:1007F0000000000000000000000000181818181881 +:100800000018000000E763C600000000000000665A +:1008100066FF66FF66660000187EDBD87E1BDB7E07 +:10082000180000E3E60C183067C700000078CCD849 +:1008300073DECC7B0000003C0C18000000000000C0 +:10084000000C18303030180C00000030180C0C0C64 +:10085000183000000018DB7E3C7EDB180000000032 +:100860001818FF18180000000000000000003C0CE1 +:10087000180000000000FF00000000000000000061 +:1008800000003C3C00000003060C183060C0000073 +:10089000007EC7CFDBF3E37E0000000C1C3C0C0C99 +:1008A0000C0C0000007EC3030E3860FF0000007EC9 +:1008B000C3033E03C37E0000001C3C6CCCFF0C0C49 +:1008C000000000FFC0FE0303C37E0000003E60C0C6 +:1008D000FEC3C37E000000FF03060C1818180000BA +:1008E000007EC3C37EC3C37E0000007EC3C37F03FC +:1008F000067C000000003C3C003C3C000000000086 +:100900003C3C003C0C180000000C18306030180C07 +:100910000000000000FF00FF000000000030180C85 +:10092000060C18300000007EC3030E1800180000EB +:10093000007EC3DBDBDFC07C0000003C66C3FFC37E +:10094000C3C3000000FEC3C3FEC3C3FE0000007E9D +:10095000C3C0C0C0C37E000000FCC6C3C3C3C6FC86 +:10096000000000FFC0C0FEC0C0FF000000FFC0C00C +:10097000FEC0C0C00000007EC3C0C0CFC37F000067 +:1009800000C3C3C3FFC3C3C300000018181818185E +:1009900018180000000303030303C37E000000C314 +:1009A000C6CCF8CCC6C3000000C0C0C0C0C0C0FFE9 +:1009B000000000C3E7FFDBC3C3C3000000C3E3F3D1 +:1009C000DBCFC7C30000007EC3C3C3C3C37E000028 +:1009D00000FEC3C3FEC0C0C00000007EC3C3C3C3CB +:1009E000CF7E030000FEC3C3FECCC6C30000007E62 +:1009F000C3C07E03C37E000000FF18181818181823 +:100A0000000000C3C3C3C3C3C37E000000C3C3C38D +:100A1000C3663C18000000C3C3C3C3DBFF6600000D +:100A200000C3663C183C66C3000000C3C3663C18A4 +:100A30001818000000FF060C183060FF0000003C92 +:100A400030303030303C000000C06030180C0603FD +:100A50000000003C0C0C0C0C0C3C0000183C66C365 +:100A600000000000000000000000000000FF000087 +:100A70000C181E000000000000000000007E037F34 +:100A8000C37F000000C0C0FEC3C3C3FE000000005F +:100A9000007EC3C0C37E00000003037FC3C3C37FC7 +:100AA00000000000007EC3FFC07E0000001E333047 +:100AB000FC30303000000000007FC3C3C37F037EE2 +:100AC00000C0C0FEC3C3C3C300000018001818183C +:100AD000181800000006000606060606067C00C080 +:100AE000C0C6CCF8CCC60000003030303030301CEE +:100AF0000000000000FEDBDBDBDB0000000000FE8E +:100B0000C3C3C3C300000000007EC3C3C37E000094 +:100B1000000000FEC3C3C3FEC0C00000007FC3C30B +:100B2000C37F0303000000FEC3C0C0C0000000007C +:100B3000007EC07E037E00000018187E1818180E74 +:100B40000000000000C3C3C3C37F0000000000C357 +:100B5000C3663C180000000000C3C3DBFF66000052 +:100B6000000000C3663C66C30000000000C3C3C3AE +:100B7000C37F037E000000FF0C1830FF0000000E52 +:100B800018187018180E00000018181800181818F7 +:100B90000000007018180E18187000000076DC00B5 +:100BA000000000000000000000183C66C3FF0000C9 +:042000000541B2AC38 +:00000001FF diff --git a/src/avr/product/TSV3.HEX b/src/avr/product/TSV3.HEX new file mode 100644 index 00000000..0b6e310f --- /dev/null +++ b/src/avr/product/TSV3.HEX @@ -0,0 +1,504 @@ +:020000020000FC +:100000000DC006C606C6189505C61895189518950C +:1000100002C602C61895EDC6D7C62EC702E00EBFAF +:100020000FE50DBF10E818B9A8951FE011BD00E05D +:1000300000935F01009360010093610100936201EE +:10004000009363010093640101E000936501009354 +:10005000660104E10093670108E002BD03E005BD0D +:1000600000E409BF00E00BBF08EB01BB02BB0FE1DE +:1000700007BB0FEF0ABB04BB00270BBB03E008BBA9 +:1000800000E105BBC29AC2980093190100E2B02EAC +:100090001FE519B910E91AB9442455242224332440 +:1000A000EE246624CC2458E15BBBC49AC4985093D8 +:1000B000170155275093180150933B0150936A0143 +:1000C00050936B0150931001DD24D0921401D09213 +:1000D0001501D092160154EF509369015BBB50910A +:1000E000190155BBA89AC29AC298A898C29AC298F8 +:1000F0007894E2E0F9E1A2EEB0E0DBE1D0931A01FE +:1001000008D1D0E8C0ECDBBBC39AC398D0931801E8 +:10011000C5BBC89500240BBAC198C0980000C09A0E +:10012000C19AAA9541F03196C3951C2F1F7381F790 +:10013000C054D395E8CF10E3D9D2CF93DF93E4D264 +:10014000BF91AF915FD5212F1D2F129533D3121779 +:10015000B1F4119657D5212F1D2F2CD3121779F4F6 +:10016000119650D5212F1C2F129524D3121739F434 +:10017000119648D5212F1C2F1DD3121709F1E4EE3B +:10018000F9E1A6E6B3E0D9E1D0931A01C2D0D0E0FC +:10019000C0E4DBBBC39AC398D0931801C5BBC89514 +:1001A0000BBAC198C0980000C09AC19A119741F04B +:1001B0003196C3951C2F1F7389F7C054D395E9CF8F +:1001C00020E12093030120E42093040129E12093FE +:1001D0000501C0E0D0E218E118D520E82F93CF93B5 +:1001E000DF9320E211D5269622E00ED5DF91CF9144 +:1001F0002F91C05CDF4F2A9589F7B4D610E0109399 +:10020000110116E31093100110E01093680110E043 +:1002100010934C0110934D011EEF10930D011CEA39 +:1002200010930C0122E020D21C7F10930E0123E0DA +:100230001BD210930F0110910E0120910F011A3360 +:100240000DEF200720F01C3B0DEF200730F01DEFD5 +:1002500010930F0110E810930E011FEF19BD18E362 +:1002600018BD1CEF1DBD1EEC1CBD10E51FBD11E02F +:100270001EBD00E003BF05E008BF05E409BF0AE0BA +:1002800005BF00EC0ABF0BBF9EC202E00EBF0FE528 +:100290000DBF50E05FBD5EBD949A959850911701D7 +:1002A0005F7B5BBBC49AC4985093170154E7B6FEBA +:1002B00054E3509369015BBB5091190155BBA89A57 +:1002C000C29AC298A898C29AC29851E459BF50E005 +:1002D00053BF5BBF04E000936A011FE519B910E941 +:1002E0001AB94424552422243324EE246624CC2431 +:1002F000F89403B700230AE411F4809B0AE705BFD2 +:1003000078948895A89500916A01002389F7F8945C +:10031000A3CED0911A01C0911701C07EDC2BDBBBAC +:10032000C49AC498D0931701089578941FEDE122E0 +:1003300010E01EBB1FBBE2D21B3159F1B3FC0DC054 +:10034000103258F4183009F407C11D3009F41CC1EB +:100350001A3009F4C0C0173041F7B2FC18C010338E +:10036000B1F4C0910301D091040120910501CC5F4B +:10037000DD4FF894309117013227307E32273BBB96 +:10038000C49AC49878943093170193D5102DECD269 +:10039000CCCFB4D21B3109F31E3209F47CC11F3219 +:1003A00009F452C01F3309F491C1123409F45EC03C +:1003B000123609F45FC0133409F40BC1133609F483 +:1003C000C4CC143409F4F2C0153409F4DFC0163477 +:1003D00009F40FC1163609F4C4CC173409F4A1C0CE +:1003E000183409F4D6CC183609F4C7CC1B3409F4F8 +:1003F00096C01C3409F40AC41D3409F42EC01E34FE +:1004000009F403C1103509F49AC0123509F4E3C0A8 +:10041000133509F4D9C0143509F440C0153509F471 +:100420006BC2163519F410E2E12AFBC0173509F446 +:1004300063C2183509F4C4C11A3509F4EEC110338A +:1004400010F01A3310F171CF59D210FF03C014E02D +:10045000B12A6BCF1BEFB12268CF50D2103329F4F1 +:10046000F89400E4B02A8A9A10CF5FCF47D21F9346 +:1004700010E004C043D21F9341D21F7010931101AA +:100480001F911093100151CF39D230D1C0E1C093E8 +:100490000301D09304012093050147CF10E015BD5F +:1004A00010935F01109360011093610127D21093A4 +:1004B000640124D21093630121D2109362011ED2F1 +:1004C000109366011BD21093650118D21093670137 +:1004D00013E015BD2ACF01D028CF0F92C0910301A0 +:1004E000D091040120910501DE5FC395F89430910D +:1004F00017013227307E32273BBBC49AC4987894C8 +:1005000030931701D6D4182F100D100D1A951038EE +:1005100018F0C0D00F900895800D0F90089522D547 +:1005200004CFECD1103309F404C0113309F404C032 +:10053000FCCE07EFB022F9CE08E0B02AF6CEDED12D +:10054000103309F403C0113309F403C00FEEB022D5 +:10055000ECCE00E1B02AE9CEC0910301D0910401B4 +:1005600020910501DE5FF894309117013227307E2B +:1005700032273BBBC49AC49878943093170199D41E +:1005800070191FB712FFD1CE7727CFCEB7D111FD8B +:1005900007C010FD03C00FEDB022C7CE00E2B02AA5 +:1005A000002700933B01EAD2F1F7BFCEA7D1103369 +:1005B00009F404C0113309F404C0B7CE0EEFB02221 +:1005C000B4CE01E0B02AB1CE99D1712F97D1812F4D +:1005D000ACCE02E0B02A70935201809353018ED1C9 +:1005E000109354018BD11093550117D30DEFB02206 +:1005F0009CCE709356018093570180D1109358017F +:100600007DD1109359015ED390CE709356018093A3 +:10061000570174D11093580171D11093590177D3B8 +:1006200084CE6CD110FF0BC010910E0120910F01F0 +:100630001C5F2F4F1C3B0DEF2007A8F40AC0109140 +:100640000E0120910F01145020401A330DEF2007A6 +:1006500050F010930E0120930F0122E00DD0109165 +:100660000F0123E009D061CEE199FECF2EBB2227F6 +:100670002FBBE09A1DB30895E199FECFE5FEFFCFB1 +:100680002EBB22272FBB1DBBF894E5FEFFCFE29ABD +:10069000E19A189536C732D129D030D1A12F2ED169 +:1006A000B12F2CD1F894309117013227307E3227A8 +:1006B0003BBBC49AC498789430931701A4D2219676 +:1006C00011971A2F1B2B09F0ECCF2FCE17D10ED07C +:1006D0001F931AD01BE133D11FE331D11F91105D5D +:1006E0002ED11D2F60D01C2F5ED01FCEC0E0D0E0D9 +:1006F00024E61F701A3008F4210F2695D795269509 +:10070000D795D695D6950895A6E1B2E0AC0FBD1F5A +:10071000F894309117013227307E32273BBBC49AC0 +:10072000C4987894309317016DD2E12F11966AD254 +:10073000F12FAC2FBD2F1496CFEFDFEF3197FF7065 +:10074000349780F131965ED2119601E220E1D127F3 +:10075000CC0FDD1F10F4C027D227CC0FDD1F10F403 +:10076000C027D227CC0FDD1F10F4C027D227CC0F13 +:10077000DD1F10F4C027D227CC0FDD1F10F4C027D7 +:10078000D227CC0FDD1F10F4C027D227CC0FDD1FDE +:1007900010F4C027D227CC0FDD1F10F4C027D227BA +:1007A000319789F608951F93129504D0C8D01F91F0 +:1007B00001D0C5C01F7010631A3308F0195F089587 +:1007C0009DD010FD13C070936C0180936D01B092A9 +:1007D0006E011091030110936F01109104011093A9 +:1007E000700110910501109371019FCD70916C0102 +:1007F00080916D0110ECB12210916E011F73B12A2E +:1008000010916F0110930301109170011093040176 +:10081000109171011093050188CD70D010935A0189 +:100820006DD0C12F175F5DD020935B0167D0D12FB2 +:100830001C5F5CD020935C0161D01C0F1F5051D015 +:1008400020935D015BD01D0F115150D020935E01AC +:10085000D0915C0110915E011D1B08F441C0C09154 +:100860005B011C2F1D0F2D2F220F220F220F120FA5 +:10087000220F120FA0E0B0EE20E0A10FB21F2BE17B +:10088000F894309117013227307E32273BBBC49A4F +:10089000C49878943093170110915D011C1BF0F0FF +:1008A0003A2F3F7335BB3B2F330F330FA7FB31F983 +:1008B000A6FB30F93BBBF894C39AC3987894309365 +:1008C000180110915A011BBBF894C198C098000000 +:1008D000C09A7894C19A1196C395DECFD395BACFBA +:1008E00024CD2FEF23951A50E8F708952FEF239585 +:1008F0001D50E8F7089502D001D017CD10EC1093E9 +:100900006B01A89510E01EBB1FBB10EC80991093E3 +:100910006B01B5FC33D13320A1F310E010936B01D0 +:10092000CF93DF93C22DC058DD271881F8943A94F5 +:100930002394CFE72C227894DF91CF9108951F93D1 +:10094000A895152D1032E0F71F91CF93DF93DFB7F5 +:10095000F894C52DC40DDFBFCF71C05ADD271883B1 +:100960005394DF91CF910895D2D0EFD00027009318 +:100970001201B4FC0FC0C0910301D0910401DE5FED +:10098000F02C97D20F920F1808F4002406940092CE +:1009900012010F90B3FC08C0072F000D28F4772731 +:1009A0009CDD10910501B9D600911201070F00934B +:1009B0004E0180934F01700D60914E0190904F0158 +:1009C00086FE07C0C0915001D0915101229771D28B +:1009D000900C87FE07C0C0915001D0915101239720 +:1009E00068D2600D5AD260930201A0920001C091BA +:1009F0005001D091510121965CD2702C0FEF0ABBAF +:100A0000C09A0FE18022809201010027801201C06C +:100A10007DC0AA27B92DB695A795B695A795B05EC6 +:100A200007C09394A05CBF4F80900101A09000018B +:100A3000AA2A22272196109105016FD63AD21127B2 +:100A400060910201662339F08894079417956A959E +:100A5000E1F7022A212F08E1F8943091170130279D +:100A6000307E30273BBBC49AC498789430931701EA +:100A70003A2D3F7335BB3B2F330F330FA7FA31F9B4 +:100A8000A6FA30F93BBBF894C39AC3987894309394 +:100A9000180100270ABBF894C0980000C19809B358 +:100AA0000026B0FC002A0FEF0ABB0BBA0000C09A68 +:100AB0007894C19AA3948A9409F0BCCF222311F1AF +:100AC0003A2D3F7335BB3B2F330F330FA7FA31F964 +:100AD000A6FA30F93BBBF894C39AC3987894309344 +:100AE000180100270ABBF894C0980000C19809B308 +:100AF0002027B0FC202B0FEF0ABB2BBB0000C09AB5 +:100B00007894C19A31D07A9409F08BCF0895C12F8F +:100B1000DD27CC0FDD1F10910301C10F10910401DF +:100B2000D11F10910501F9D5C4D12196F02CC1D166 +:100B3000CF2DD02D10910301C10F10910401D11FB1 +:100B4000C0935001D09351010895C0915001D091AC +:100B50005101AFD1802C219785FCABC1C09103011D +:100B6000D0910401DE5FA5C1CF93DF93192D39D059 +:100B70001881122B1883DF91CF9108952F93CF9373 +:100B8000DF9310913B012DD01881122309F41FC06F +:100B900028812127288310E010936B01AF93BF9326 +:100BA000CC27D0913B01D695C795D695C795AC2F4C +:100BB000BD2FB05E18E1B1D520E26CD51297269614 +:100BC00022E068D5BF91AF9110EC10936B011091AA +:100BD0003B0113951F7710933B01DF91CF912F912C +:100BE0000895CCE3D1E01F77212F269526952695F1 +:100BF000C20F20E0D21F21E0177019F0220F1A95C2 +:100C0000E9F7089554C56FC54CC587C597C48DCB0A +:100C1000DFC1DFC18FC5E6C1C6C278949090530191 +:100C2000609152013AD160930201A092000170904C +:100C30005501CC27D92DD695C795D695C795D05EA9 +:100C400018E16BD507C0C05CDF4F9394609102013F +:100C5000A0900001AC2A1FEF8090540100E08016A4 +:100C600041F008E08016B8F0662319F016956A95F1 +:100C7000E9F73BD108E010910201011B801AA3940F +:100C80001FEF08E0801638F0B1F02FD11FEF08E019 +:100C9000801AA394F6CF882079F016958A94E9F704 +:100CA0001095662341F02227169527956A95E1F75E +:100CB0001CD1A394122F19D157DF7A9400277012F8 +:100CC000C2CF0895009158010A950230D0F30091E7 +:100CD00059010330B0F3009156010395009352017E +:100CE0000091570100935301809058018A948A948F +:100CF0008092540101E0009355018FDF009156016D +:100D00000093520180905801809254013AC00091A2 +:100D100058010A950230A8F200915901033088F277 +:100D200000915601039500935201009157010093E1 +:100D30005301809058018A948A948092540101E072 +:100D4000009355016ADF0091560100935201009112 +:100D50005701039500935301709059017A947A9446 +:100D60007092550101E00093540157DF80905801C3 +:100D700000915601080D0A950093520101E000937D +:100D8000540100915701039500935301709059014C +:100D90007A947A947092550140DF00915601039540 +:100DA00000935201809058018A948A948092540151 +:100DB0007090590100915701070D0A950093530156 +:100DC00001E00093550129CF1FB60F930FEDC02E00 +:100DD000EF93FF93E42DE05AFF270081FF91EF91FD +:100DE0000CB95A9443940FE140226A940AF04CC023 +:100DF00051C01FB60F930FEDC02E0CB15C993EC0D1 +:100E0000E7FC2CC0E6FC0EC0023031F403E009B967 +:100E1000539A00E4E02A3EC00A3A19F400E0009335 +:100E20006A0138C0602E00E803190AF40FE7662053 +:100E300012F4052D00680CB9061508F4602E062D75 +:100E40000F7739F000ECE02A6A9422F55798559A0A +:100E500021C00FEBE022569A5E9A1CC0EF93FF93DD +:100E6000E32DE20DEF77E058FF270083FF91EF912C +:100E700033946A947AF40CC01FB60F9353980FE51D +:100E800009B90FEBE022CC2455985698579A0CB12B +:100E90000FE7E0220F911FBE1895AA2400EFA01AB9 +:100EA00067FFAA246F77685014F0A394FCCF685FA3 +:100EB00008953C2F3F7335BB3D2F330F330FC7FBD6 +:100EC00031F9C6FB30F93BBBF894C39AC3987894C8 +:100ED0003093180100270ABBF894C0980000C09A0C +:100EE00009B278940FEF0ABB08953A2D3F7335BBD2 +:100EF0003D2F330F330FA7FA31F9A6FA30F93BBB78 +:100F0000F894C39AC39878943093180100270ABBC9 +:100F1000F894C0980000C09AF9B278940FEF0ABB19 +:100F2000B1FE03C01095F12203C0F126B0FCF12AF6 +:100F30003A2D3F7335BB3D2F330F330FA7FA31F9ED +:100F4000A6FA30F93BBBF894C39AC39878943093CF +:100F50001801FBBAF894C198C0980000C09A789420 +:100F6000C19A0895772788279924C0E0D0E218E134 +:100F7000D4D3AA24A0920001109100011C2B312F80 +:100F80003F7335BB3D2F330F330F17FB31F916FB82 +:100F900030F93BBBF894C39AC39878943093180106 +:100FA00000E00BBBF894C198C0980000C09A7894F8 +:100FB000C19AA39400E2A01619F0A0920001DCCF20 +:100FC000D3DD9394C05CDF4FD03409F0D2CF0895C5 +:100FD00018951FB68B9A4CB55DB550930901409397 +:100FE000080114C11FB65AB35F935BB35F9355B347 +:100FF0005F93509118015F935FEF5ABB50E75FBD5D +:101000004CB55DB5485F5F4F5BBD4ABD59BD48BD3E +:1010100040914C0150914D015170452B49F4509134 +:101020006B01539550936B0151F45FEBB5222DC9C1 +:1010300000000000000000000000000000008B9A8B +:10104000939A55275EBD5DBD5CBD50914D01542BFB +:1010500071F0509117015BBBC49ADD9ADD98C4987A +:101060000000000000000000000000000EC05091D1 +:101070001701506850625BBBC49A40E654275BBBC3 +:101080005F775BBBC49850931701509117015F9332 +:10109000EF93FF93E0914C01F0914D01E05CFF4F25 +:1010A000FF713F933E2F3F7335BB3F2F330F330FFD +:1010B000E7FB31F9E6FB30F93BBBC39AC398F093E9 +:1010C000180130911701F7FB31F9F6FB30F93BBB02 +:1010D000C49AC498309317013F91C198C19A9798C8 +:1010E00044274ABB40EC44BBC09855275BBD5ABD62 +:1010F00059E05EBDE0934C01F0934D01FF91EF91FB +:101100005CE35A95F1F7C09A5FEF5ABB979A54BBCC +:101110008D98959851E000005EBD5BE05A95F1F71F +:1011200050910D0140910C018D9A859907C04A3369 +:101130009DEF590752F0415050400BC0453D9FEF85 +:1011400059071AF44F5F5F4F04C000000000000011 +:10115000000050930D0140930C015BBD4ABD4091CE +:101160000C0150910D0190910E01491B90910F01BE +:10117000590B1AF445ED5FEF04C04CEA5EEF000036 +:10118000000059BD48BD52E053BF5DEE52BF51E073 +:10119000509368015DEF5DBD54E35CBD8B989398FF +:1011A00050EE5FBD21C01FB65AB35F935BB35F9330 +:1011B00055B35F93509118015F93509117015F935E +:1011C000FF93EF930F925FEF5ABB509168015395D5 +:1011D000509368015A95E1F05A9511F15A9509F426 +:1011E00089C00F90EF91FF915F915BBBC49AC49847 +:1011F000509317015F915BBBC39AC398509318013A +:101200005F9155BB5F915BBB5F915ABB1FBE189549 +:1012100053E053BF50EF52BF51E05093680153C1A8 +:1012200050911001552399F150911101505118F02E +:10123000509311012CC0452F429554235093110116 +:101240004091190143FF10C0509110015A955093DD +:101250001001A1F050911901577F546055BBC29AFB +:10126000C2985093190113C05091190158605B7FC7 +:1012700055BBC29AC2985093190109C050911901E7 +:10128000577F5B7F55BBC29AC2985093190150910A +:10129000690157FF06C050E8B5261AF4552753BF19 +:1012A000A0CF52E053BF52EF52BFEAE3F8E1552717 +:1012B000ED0DF51FC89554E3D51648F4509119016A +:1012C0005F7E55BBC29AC2985093190108C05091D5 +:1012D0001901506155BBC29AC298509319010BBABB +:1012E0000090190105BAA99AC29AC298A998C29AFF +:1012F000C29877CF50B340EE4BBB4091190145BB2C +:10130000A99AC29AC298A998C29AC298889456FD7E +:1013100008C050911301552319F054E05093130164 +:1013200008944FB754E3D51660F44FBFE091150110 +:10133000F0911601EE1FFF1FE0931501F0931601C7 +:101340007BC04FBF08F078C050911301552321F0A6 +:1013500054E05093130170C0F0911601E091150113 +:1013600050911401552329F0452FF795E7954450E6 +:10137000E1F75C5FF795E79518F05433D0F35CC064 +:101380005093140144E3451BECE3F8E15527E40FC7 +:10139000F51FC895402D000C000C000C400D000CF2 +:1013A000400DECE3F8E15527ED0DF51FC895400D14 +:1013B000E0E0F0EE5527E40FF51F3F933E2F3F731B +:1013C00035BB3F2F330F330FE7FB31F9E6FB30F925 +:1013D0003BBBC39AC398F093180130911701F7FBF8 +:1013E00031F9F6FB30F93BBBC49AC498309317012E +:1013F0003F910F9300270ABBC0980000C09A09B222 +:101400000FEF0ABB0F91002029F4509114015433BF +:1014100098F45EC054E0509313010092070156E324 +:1014200050931001552D5F3138F41F93102D8DDA34 +:101430001B3109F48ADA1F9154E0D50E50916901ED +:1014400057FD27C053E053BF50EF52BF51E05093B8 +:10145000680144E3D416E8F250E053BF50911601FE +:1014600040911501452B50916A01543018F45130C8 +:1014700028F4B7CE442329F055E003C0442309F4EF +:1014800054E05A9550936A01A1F75FEBB5228A9810 +:10149000CECD50E053BF5093140148ECD416C0F0A9 +:1014A00050911301552379F05A955093130159F433 +:1014B00050910701552339F0552D503220F41F93D8 +:1014C00010E043DA1F91DD24D0921501D09216016D +:1014D000EAE3F8E131965527ED0DF51FC8955091D7 +:1014E0006901507850645029509369015BBB509159 +:1014F000190155BBA89AC29AC298A898C29AC298D4 +:1015000070CE9924C0E0D0E2A0E0B0E218E105D1AD +:10151000A05CBF4F0A94E1F720E22F93C8D0E3D03C +:10152000A395C3952F912A9509F0F7CF1DDB9394CE +:10153000A0969096B03409F0EFCF1BCDDFD91F9362 +:10154000DDD910937201DAD916951695169509F41E +:1015500010E210937501D2D910937601172F1695CA +:1015600016951695109373018093740118E1D5D0E8 +:101570001F9110FD46C0CC27D09174019D2ED695A9 +:10158000C795D695C79510917301C10FD05E209174 +:10159000760110917201121720F5211BAA27B09134 +:1015A0007401B10FB695A795B695A79510917301E3 +:1015B000A10FB05E2F93AF93BF93CF93DF93209192 +:1015C000750168D0D1DADF91CF91BF91AF912F91A2 +:1015D0009394A05CBF4FC05CDF4F2A9559F72091D0 +:1015E00072012F93CF93DF93209175015AD0BCDA0B +:1015F000DF91CF912F919394C05CDF4F2A9589F7AB +:1016000006CBCC27D091740100917601D00F9D2E8E +:10161000D695C795D695C79510917301C10FD05E29 +:10162000202F10917201121728F5211BAA27B091C3 +:101630007401B00FB11BB695A795B695A7951091FB +:101640007301A10FB05E9A94A054B040C054D04032 +:101650002F93AF93BF93CF93DF93209175011AD04F +:1016600083DADF91CF91BF91AF912F912A9559F7EE +:10167000209172019A94C054D0402F93CF93DF935E +:10168000209175010ED070DADF91CF912F912A95BC +:1016900089F7BDCA0CD0119626D021962A95D1F78C +:1016A000089510E020D021962A95E1F708953A2F69 +:1016B0003F7335BB3B2F330F330FA7FB31F9A6FB2D +:1016C00030F93BBBF894C39AC398789430931801CF +:1016D00000270ABBF894C0980000C09A19B3789408 +:1016E0000FEF0ABB08953C2F3F7335BB3D2F330FDF +:1016F000330FC7FB31F9C6FB30F93BBBF894C39AF3 +:10170000C3987894309318011BBBF894C198C09883 +:101710000000C09A7894C19A0895F8943091170106 +:101720003127307E31273BBBC49AC49878943093DC +:10173000170108951FB650915F015C5550935F01EA +:10174000509160015F4F5093600150916101564E7E +:10175000543650F4509361011FBEB6FE189550E008 +:101760005093680120CDF1C850E050936101509131 +:10177000620153955C33E8F15091630153955C33FA +:10178000A8F1509164015395583168F1EF93FF939C +:101790000F92EDE2F8E190916601E90F90E0F91FF8 +:1017A000C895902D9C3131F49091670193709CE124 +:1017B00009F49DE10F90FF91EF9150916501591748 +:1017C00070F0509166015C3030F050916701539594 +:1017D00050936701552753955093660155275395AC +:1017E0005093650155275093640155275093630129 +:1017F000552750936201552D5931C0F41F931BE1B9 +:10180000A4D814E5A2D810916401ADDF1091630152 +:10181000AADF10916201A7DF10916601A4DF109189 +:101820006501A1DF109167019EDF1F9195CF1F1CFD +:101830001F1E1F1E1F1F1E1F1E1FF0340000E83436 +:101840000100F0330100E8330200E4330300E83222 +:101850000300E4320400E2320500E4310500E23125 +:101860000600E1310700E2300700E1300800C12A3C +:101870000000C22A0100C12B0100C22B0200C42BB0 +:101880000300C22C0300C42C0400C82C0500C4189B +:101890000500C8180600D0180700C8190700D0199D +:1018A0000800A1190900D01A0900A11A0A00A21AF9 +:1018B0000B00A11B0B00A21B0C00A41B0D00A21C03 +:1018C0000D00A41C0E00A81C0F00A41D0F00A81DD5 +:1018D0001000B01D1100A81E1100B01E1200611EE4 +:1018E0001300B01F1300611F1400621F1500612850 +:1018F0001500622816006428170062291700642961 +:1019000018000000000000000000000000000000BF +:1019100000000000000000000808080000000000AF +:1019200000000000000000000000000000000000B7 +:10193000000000007E00310032003300340035002A +:10194000360037003800390030002D003D0000001F +:101950000000000000000000000000000000000087 +:1019600000000000000051005700450052005400E4 +:101970005900550049004F0050005B005D005C00BD +:101980000000000000000000000000000000000057 +:101990000000000000000000410053004400460029 +:1019A000470048004A004B004C003B0027000D0D4B +:1019B0000D0000000000000000000000000000001A +:1019C0000000000000000000000000005A00580065 +:1019D0004300560042004E004D002C002E002F0008 +:1019E0000000000046323444303331393033313274 +:1019F000313730394C034C034C034C034C034C033C +:101A00004C034C034C034C034C034C034C034C035E +:101A10004C034C034C034C034C034C034C034C034E +:101A20004C034C034C034C034C034C034C034C033E +:101A30004C034C0300014C034C034C034C034C037C +:101A40004C034C034C034C034C034C034C03030169 +:101A50004C034C0306010F01180121012A01330137 +:101A60003C0145014E0157014C034C034C034C0310 +:101A70004C034C034C036001690172017B0184013A +:101A80008D0196019F01A901B201BB01C401CD01E5 +:101A9000D601DF01E801F101080211021A02230256 +:101AA0002C0235023E02470250024C034C034C0309 +:101AB0004C034C034C03590262026B0274027D0218 +:101AC00086028F029902A302AD02B802C202CB02C3 +:101AD000D402DD02E602F002FC0203030C0315034C +:101AE0001E0327033003390343034C034C034C0309 +:101AF0004C034C030003066101F80107708898A8A5 +:101B0000C88870010720602020202070010770889D +:101B100008102040F80107F810201008887001070D +:101B200010305090F810100107F880F00808887005 +:101B30000107304080F08888700107F808102040C5 +:101B40004040010770888870888870010770888815 +:101B500078081060010770888888F888880107F085 +:101B60008888F08888F001077088808080887001FC +:101B700007E09088888890E00107F88080F08080F6 +:101B8000F80107F88080F08080800107708880B8B5 +:101B90008888780107888888F888888802210780E3 +:101BA000808080808080010708080808088870010C +:101BB000078890A0C0A090880107808080808080E6 +:101BC000F8010788D8A8A888888801078888C8A845 +:101BD0009888880107708888888888700107F0884D +:101BE00088F0808080010770888888A890684C03FE +:101BF0004C034C03060801014F0065030107F08800 +:101C000088F0A090880107708880700888700107AC +:101C1000F820202020202001078888888888887064 +:101C20000107888888888850200107888888A8A8A4 +:101C3000A850010788885020508888010788888824 +:101C4000502020200107F80810204080F8010700EC +:101C500000700878887801078080F0888888F00113 +:101C600007000078808080780107080878888888D5 +:101C700078010700007088F8807001071820F820AC +:101C800020202001080000788888780870010780EB +:101C900080B0C8888888022107800080808080808A +:101CA0000521081000101010109060052107808099 +:101CB00090A0C0A090032107C04040404040400198 +:101CC000070000F0A8A8A8A801070000B0C88888ED +:101CD0008801070000708888887001080000F0887B +:101CE00088F080800108000078888878080802055C +:101CF0006105B0C08080800107000078807008F026 +:101D000001072020F820202018010700008888887B +:101D10009868010700008888885020010700008823 +:101D200088A8A850010700008850205088010800AA +:101D30000088888878087001070000F8102040F8B3 +:101D40000107F8F8F8F8F8F8F80070935601809356 +:101D50005701D4D510935801D1D51093590126D0ED +:101D6000E4C27093560180935701C8D5109358016F +:101D7000C5D5109359012FD0D8C2709352018093CA +:101D80005301BCD510935401B9D51093550178D0A7 +:101D9000CCC27093520180935301B0D5109354017B +:101DA000ADD51093550171D0C0C208950091560170 +:101DB0000093520100915701009353010091580183 +:101DC00000935401009159010093550102E0B02A9B +:101DD00024D70DEFB022009158010A95023028F364 +:101DE00000915901033008F300915601009352010C +:101DF0000091570100935301009158010093540141 +:101E000001E00093550109D700915601009352015A +:101E1000009157010395009353010091590102501D +:101E20000093550101E000935401F7D680905801CA +:101E300000915601080D0A950093520101E00093AC +:101E400054010091570103950093530100915901EA +:101E5000025000935501E1D60091560100935201C2 +:101E6000009158010093540170905901009157015D +:101E7000070D0A950093530101E000935501CDC66B +:101E800002E0B02ACAD60DEFB022789490905301A8 +:101E90006091520102D860930201A09200017090FB +:101EA0005501CC27D92D15E5D0FF1AEA012ED6957C +:101EB000C795D695C795D05E18E12FDC07C0C05CEA +:101EC000DF4F939460910201A0900001AC2A1FEFB4 +:101ED0008090540100E0801641F008E08016C8F0C0 +:101EE000662319F016956A95E9F71021FED708E0E8 +:101EF00010910201011B801AA3941FEF08E08016C5 +:101F000040F0C1F01021F1D71FEF08E0801AA39430 +:101F1000F5CF882089F016958A94E9F71095662305 +:101F200049F02227169527956A95E1F71021DDD70C +:101F3000A394122F1021D9D7009416D67A94002793 +:061F40007012BDCF0895F0 +:0220000002419B +:00000001FF diff --git a/src/avr/product/WPO15V1.HEX b/src/avr/product/WPO15V1.HEX new file mode 100644 index 00000000..4f579fba --- /dev/null +++ b/src/avr/product/WPO15V1.HEX @@ -0,0 +1,132 @@ +:020000020000FC +:020000000EC030 +:06001200DCC1A3C270C1B5 +:10001C0064C302E00EBF0FE50DBF00E808B9A89558 +:10002C000FE001BD0AE50093CC0000E00DB90AB960 +:10003C000FEF04BBC79ABE9AD79A8E9A929A939A4C +:10004C00959A8D9ADE98D69897988F9A94988C9AC0 +:10005C00C398BB9A9198899A07E00DD106E00BD111 +:10006C0005E009D104E007D101E005D100E003D19E +:10007C000FE509B908E10AB92AD10AEA0CB90CB999 +:10008C0029D1949A27D1949825D1949A0027E0E607 +:10009C00FF27019301930193EFEB019301930193DC +:1000AC00019301930193019301930093BC0000937E +:1000BC00CA000093BD000093BE0000E4008300E082 +:1000CC000093C80004E00093C9004427662711245C +:1000DC0088249924AA2455246624772402E00093CA +:1000EC00B70001E00093B3000093B4000093B50097 +:1000FC000093B6000093B8000093B9000093CB00B6 +:10010C0000E00093BA000093BB0000EF202E00EF3C +:10011C00402E02E003BF01E009BF0EB10FB108EEA3 +:10012C000DB900E00DBD0CBD0BBD0ABD01EC0FBD42 +:10013C0001E00EBD05E007B90EED06B9789402E0BA +:10014C001EE1E2E6F7E0A8D00091CC000A3509F0F8 +:10015C0066C041FD6FC043FD7AC040FFF5CF0091F2 +:10016C00CB00033041F0023091F002E01FE0EEE9E9 +:10017C00F7E092D006C002E01FE0EEEDF7E08CD085 +:10018C0000C003E01EE1E0E8F7E086D00FC002E01B +:10019C001CE0EEEAF7E080D003E01EE1E2E6F7E0D7 +:1001AC007BD003E01CE0EEEAF7E076D01CD00B31FC +:1001BC0009F0FCCF18D0043409F0F8CF14D0037038 +:1001CC0039F0013039F0023039F0033039F0EECF2C +:1001DC00969A05C0969803C0DF9A01C0DF9810E389 +:1001EC00100FE4CF78940091CC000A35C1F441FD96 +:1001FC0021C043FD2CC0F8949920A1F30091B300C9 +:10020C00093081F7EF93FF93E82DED59FF2700811B +:10021C009A948394EFE38E22FF91EF91189502E06C +:10022C001EE1E2E6F7E038D002E01FE0EEEEF7E088 +:10023C0033D00AC002E01EE1E2E6F7E02DD002E086 +:10024C001FE0EAEBF7E028D043FD01C0FDCF02E050 +:10025C001EE1E2E6F7E020D002E01FE0EAECF7E076 +:10026C001BD00AEF37D00A95E9F702E013E0EAED6C +:10027C00F7E012D0F6CFC39802FF919802FD919A45 +:10028C0029D001FF919801FD919A26D000FF9198F9 +:10029C0000FD919AC39A22C078940000F894AA2089 +:1002AC00D9F70093B400C895002D04D031961A9557 +:1002BC00D1F71895EF93FF93E92DEA0DE80DEF7345 +:1002CC00ED59FF270083FF91EF91A3940895E0EF80 +:1002DC00FAE006C0E8EC03C0E4E101C0E2E0F0E0C3 +:1002EC0020E02A95F1F73197E1F70895FFB666FD06 +:1002FC0022C03CB13125F2F0312552F0EF93FF933F +:10030C00EEEBF091B300EF0FFF273083FF91EF91ED +:10031C00131608F0132E6F7E6064312D3F7741F079 +:10032C0011202AF157986F7D3FEF232E606146C054 +:10033C0038EF40C03EC03091B600313019F031E09A +:10034C003093BB003CB1EF93FF93E62DE70DE50D29 +:10035C00EF70ED55FF273083E091B500F091B600BA +:10036C00EF1711F4639401C07394FF91EF913FEF79 +:10037C00232E1A940AF530EF232E60611FC0EF93E1 +:10038C00FF93EEEBF091B300EF0FFF2730813A951E +:10039C003083E82DED59FF273081FF91EF913CB967 +:1003AC003FEF232E9A9483943FE383221A9431F4E3 +:1003BC0003C030EF232E6F7E57986F79FFBE1895D0 +:1003CC00FFB63091BD007091BE00732B49F03150D7 +:1003DC003093BD003091BE0030403093BE0091F0A0 +:1003EC00442051F0439441F430E03DB93EB13FB16B +:1003FC0038EE3DB9D69A687F222011F02394B9F0DB +:10040C00FFBE189506CE67FD18C0890C3FE383220A +:10041C0099249092BA00EF93FF93EEEBF091B30016 +:10042C00EF0FFF2730E43083FF91EF9106C065FD9D +:10043C00EACF66FDA4CF64FD7AC038EF232E30914D +:10044C00BC00332359F03A953093BC0031F0C3987B +:10045C009198899A30E03AB9B1CFDBCD57983FE506 +:10046C0039B93091BA0039293A2939F43091B800A8 +:10047C003A9549F03093B80037C03091B9003A95AD +:10048C0091F03093B90030E13093B800992030915D +:10049C00B30041F4AA2041F09A2CAA243091B40064 +:1004AC003093B300393001F16F779920B9F4AA2059 +:1004BC0059F43091BA003A9542F43091B300339527 +:1004CC00393048F031E007C031E03093BA009A2C53 +:1004DC00AA243091B4003093B30025C031E030939E +:1004EC00BA003091B3001FC030E13093B90060689E +:1004FC003091BB00332331F03A953093BB003091EF +:10050C00B60011C03091B600772069F47091B70035 +:10051C003093B700372F313021F03395393008F054 +:10052C0032E03093B6003CB960616F7947CF30EF61 +:10053C00232E33E039B9392D67FF04C030E1361969 +:10054C00371930683CB9132E579A3CB1606236CFDC +:10055C00FFB6D6983FB162FD8EC060FD5EC061FDF6 +:10056C0057C03A3090F1303899F0313899F0313930 +:10057C00A1F0323991F0333981F0353A99F03A3AA9 +:10058C00E1F0353CD9F030E03DB944244260A3C0E1 +:10059C0097989FC04160979A9CC030593093CB007C +:1005AC00416097C03FEF3093BC0030E03DB9949868 +:1005BC003FEF70E07BBD3ABD8CC02BCD38EE309355 +:1005CC00BD0033E03093BE0084C0332379F46860FF +:1005DC00662049F47720C1F0672C77243090B60060 +:1005EC003092B50012C03090B5000FC0677F332E2B +:1005FC00AA2021F03091B400331531F431E030935E +:10060C00BA003092B40001C033243FB8626061C0BC +:10061C006D7F332009F061605CC0332E6E7F332018 +:10062C0063FF05C05AF5362D30681FC051C0F2F378 +:10063C00EF93FF93EEEBF091B400EF0FFF273081B7 +:10064C00E091B300F091B400EF1731F0E0E4E91958 +:10065C003E1730F03E2F04C0303408F030E4391926 +:10066C003A19FF91EF910AF43FE7331508F4332E52 +:10067C003FB964602EC033208AF43A944AF5616025 +:10068C00EF93FF93E52DED55FF2730813FB9FF9197 +:10069C00EF916A9453943FE053221BC060FF14C047 +:1006AC00EF93FF93E92DEA0DE80DEF73ED59FF275A +:1006BC003083E091B300F091B400EF1711F49394F0 +:1006CC0001C0A394FF91EF913A9412F0616001C0C4 +:1006DC006B7F30EF432EFFBE1895FFB6A89534B153 +:1006EC00532F35B1379557953795579544FD12C013 +:1006FC0040613091BC00332331F530E070E05C5147 +:10070C0000F130E670E05038E0F45695352F5695F0 +:10071C00350F17C04F7E5093CA00583A30E074E042 +:10072C0058F43091C8007091C9003150704021F4D8 +:10073C0030E03DB9442448603093C8007093C90040 +:10074C0002C07BBD3ABD34E044FF35E037B93EED25 +:10075C0036B9FFBE18951B44301B47301B50311B5C +:10076C0045301B4B1B301B2F301B5300001B4E0006 +:10077C00801B45311B44301B47301B50311B45300F +:10078C001B4B1B301B2F301B5300001B4EF0401B10 +:10079C0045311B53100D48595445434820313030D6 +:1007AC0030001B53100D57504F33302056351B5310 +:1007BC00100D42414420434F4D4D414E44001B53BC +:1007CC00100D42415454455259204C4F57001B4D6B +:1007DC0030001B53100D48595445434820313530D7 +:1007EC0030001B53100D535441434B204F56455270 +:0407FC00464C4F57C1 +:042000000041BFAC30 +:00000001FF diff --git a/src/avr/product/WPOV0.HEX b/src/avr/product/WPOV0.HEX new file mode 100644 index 00000000..ef6e47ff --- /dev/null +++ b/src/avr/product/WPOV0.HEX @@ -0,0 +1,135 @@ +:020000020000FC +:020000000BC033 +:06000C00DBC1A2C26DC1C0 +:1000160063C30FED0DBF00E808B9A8950FE001BD59 +:100026000AE50093CD0000E00DB90AB9C59ABC9A5D +:100036008D9A8E9AAC9A929A939AC19AB99AC098C6 +:10004600B89897988F9A94988C9AAA98A29A919809 +:10005600899A07E00CD106E00AD105E008D104E050 +:1000660006D101E004D100E002D10FE809B908E1A8 +:100076000AB929D10AEA0CB90CB928D1949A0027F1 +:10008600E0E6FF27019301930193EFEB01930193C0 +:100096000193019301930193019301930093BC0093 +:1000A6000093CB000093BD000093BE0000E40083E4 +:1000B60000E00093C80004E00093C90000E100934B +:1000C600CA0044276627112488249924AA24552483 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CC0000E00093BA0000938F +:10010600BB0007EE202E07EE402E02E003BF02E002 +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1EEE8F7E0A8D0ED +:100146000091CD000A3509F066C041FD6FC043FD40 +:100156007AC040FFF5CF0091CC00033041F0023069 +:1001660091F002E01FE0EAECF7E092D006C002E070 +:100176001FE0EAE0F8E08CD000C003E01EE1ECEA04 +:10018600F7E086D00FC002E01CE0EAEDF7E080D091 +:1001960003E01EE1EEE8F7E07BD003E01CE0EAEDC9 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CD000A35C1F441FD21C043FD2CC0F89471 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1EEE8F7E038D085 +:1002260002E01FE0EAE1F8E033D00AC002E01EE196 +:10023600EEE8F7E02DD002E01FE0E6EEF7E028D08A +:1002460043FD01C0FDCF02E01EE1EEE8F7E020D05D +:1002560002E01FE0E6EFF7E01BD00AEF37D00A9581 +:10026600E9F702E013E0E6E0F8E012D0F6CFAA984C +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A27D000FF919800FD919AAA9A23C0CF +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895ECEDFFE007C0E2E2F1E0C0 +:1002D60004C0EDE101C0E3E0F0E020E02A95F1F78B +:1002E6003197E1F70895FFB666FD22C03CB131258E +:1002F600F2F0312552F0EF93FF93EEEBF091B3005D +:10030600EF0FFF273083FF91EF91131608F0132E9E +:100316006F7E6064312D3F7741F011202AF15798A6 +:100326006F7D3FEF232E606148C033EF42C040C06F +:100336003091B600313019F031E03093BB003CB15A +:10034600EF93FF93E62DE70DE50DEF70ED55FF27D3 +:100356003083E091B500F091B600EF1711F4639485 +:1003660001C07394FF91EF913EEF232E1A941AF574 +:1003760037EE232E606121C0EF93FF93EEEBF091F1 +:10038600B300EF0FFF2730813A953083E82DED5902 +:10039600FF273081FF91EF913CB93695330B3A95A3 +:1003A600232E9A9483943FE383221A9431F403C054 +:1003B60037EE232E6F7E57986F79FFBE1895FFB6DE +:1003C6003091BD007091BE00732B49F031503093CF +:1003D600BD003091BE0030403093BE0091F0442005 +:1003E60051F0439441F430E03DB93EB13FB138EEAF +:1003F6003DB9B89A687F222011F02394B9F0FFBE68 +:10040600189507CE67FD18C0890C3FE3832299240F +:100416009092BA00EF93FF93EEEBF091B300EF0FDB +:10042600FF2730E43083FF91EF9106C065FDEACFE8 +:1004360066FDA2CF64FD7AC033EF232E3091BC0057 +:10044600332359F03A953093BC0031F0AA9891982D +:10045600899A30E03AB9B1CFDCCD57983FE839B93F +:100466003091BA0039293A2939F43091B8003A95D1 +:1004760049F03093B80037C03091B9003A9591F001 +:100486003093B90030E13093B80099203091B30031 +:1004960041F4AA2041F09A2CAA243091B40030935A +:1004A600B300393001F16F779920B9F4AA2059F4D5 +:1004B6003091BA003A9542F43091B3003395393011 +:1004C60048F031E007C031E03093BA009A2CAA24F4 +:1004D6003091B4003093B30025C031E03093BA00B8 +:1004E6003091B3001FC030E13093B900606830919D +:1004F600BB00332331F03A953093BB003091B60000 +:1005060011C03091B600772069F47091B70030932E +:10051600B700372F313021F03395393008F032E00B +:100526003093B6003CB960616F7947CF37EE232E22 +:1005360035E039B9392D67FF04C030E1361937196E +:1005460030683CB9132E579A3CB1606236CFFFB67D +:10055600B8983FB162FD8EC060FD5EC061FD57C0B8 +:100566003A3090F1303899F0313899F03139A1F0BC +:10057600323991F0333981F0353A99F03A3AE1F06F +:10058600353CD9F030E03DB944244260A3C0979889 +:100596009FC04160979A9CC030593093CC0041600F +:1005A60097C03FEF3093BC0030E03DB994983FEFE1 +:1005B60070E07BBD3ABD8CC02CCD38EE3093BD00CB +:1005C60033E03093BE0084C0332379F4686066203C +:1005D60049F47720C1F0672C77243090B60030922A +:1005E600B50012C03090B5000FC0677F332EAA2029 +:1005F60021F03091B400331531F431E03093BA0074 +:100606003092B40001C033243FB8626061C06D7F90 +:10061600332009F061605CC0332E6E7F332063FFA8 +:1006260005C05AF5362D30681FC051C0F2F3EF935E +:10063600FF93EEEBF091B400EF0FFF273081E091CE +:10064600B300F091B400EF1731F0E0E4E9193E177A +:1006560030F03E2F04C0303408F030E439193A192E +:10066600FF91EF910AF43FE7331508F4332E3FB9B3 +:1006760064602EC033208AF43A944AF56160EF93A1 +:10068600FF93E52DED55FF2730813FB9FF91EF919F +:100696006A9453943FE053221BC060FF14C0EF934B +:1006A600FF93E92DEA0DE80DEF73ED59FF2730832F +:1006B600E091B300F091B400EF1711F4939401C0E8 +:1006C600A394FF91EF913A9412F0616001C06B7FA1 +:1006D60037EE432EFFBE1895FFB6A89534B1532FBB +:1006E60035B1379557953795579544FD12C04061FA +:1006F6003091BC003323C9F430E070E05C51C0F1A6 +:1007060030E670E05038A0F55695352F5695350FE2 +:100716002FC04F7E45FD0DC0583F40F03091CA00B6 +:100726003A953093CA0031F5406224C030E13093E7 +:10073600CA005093CB00593330E074E058F0309142 +:10074600C8007091C9003150704021F430E03DB9C5 +:10075600442448603093C8007093C900563450F062 +:100766003FEF3093BC0030E03DB994983FEF70E026 +:100776007BBD3ABD35E445FF34E044FF35E037B98B +:100786003EED36B9FFBE18951B44301B47301B5053 +:10079600311B45301B4B1B301B2F301B5300001BDE +:1007A6004E00801B45311B44301B47301B50311B0C +:1007B60045301B4B1B301B2F301B5300001B4EF0CC +:1007C600401B45311B53100D4859544543482031B1 +:1007D600303030001B53100D57504F3330205635F4 +:1007E6001B53100D42414420434F4D4D414E440092 +:1007F6001B53100D42415454455259204C4F57003B +:100806001B4D30001B53100D4859544543482031A9 +:10081600353030001B53100D535441434B204F5677 +:060826004552464C4F57FD +:042000000041B4AC3B +:00000001FF diff --git a/src/avr/product/WPOV1.HEX b/src/avr/product/WPOV1.HEX new file mode 100644 index 00000000..52ed13d4 --- /dev/null +++ b/src/avr/product/WPOV1.HEX @@ -0,0 +1,135 @@ +:020000020000FC +:020000000BC033 +:06000C00DBC1A2C26DC1C0 +:1000160063C30FED0DBF00E808B9A8950FE001BD59 +:100026000AE50093CD0000E00DB90AB9C59ABC9A5D +:100036008D9A8E9AAC9A929A939AC19AB99AC098C6 +:10004600B89897988F9A94988C9AAA98A29A919809 +:10005600899A07E00CD106E00AD105E008D104E050 +:1000660006D101E004D100E002D10FE809B908E1A8 +:100076000AB929D10AEA0CB90CB928D1949A0027F1 +:10008600E0E6FF27019301930193EFEB01930193C0 +:100096000193019301930193019301930093BC0093 +:1000A6000093CB000093BD000093BE0000E40083E4 +:1000B60000E00093C80004E00093C90000E100934B +:1000C600CA0044276627112488249924AA24552483 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CC0000E00093BA0000938F +:10010600BB0007EE202E07EE402E02E003BF02E002 +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1EEE8F7E0A8D0ED +:100146000091CD000A3509F066C041FD6FC043FD40 +:100156007AC040FFF5CF0091CC00033041F0023069 +:1001660091F002E01FE0EAECF7E092D006C002E070 +:100176001FE0EAE0F8E08CD000C003E01EE1ECEA04 +:10018600F7E086D00FC002E01CE0EAEDF7E080D091 +:1001960003E01EE1EEE8F7E07BD003E01CE0EAEDC9 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CD000A35C1F441FD21C043FD2CC0F89471 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1EEE8F7E038D085 +:1002260002E01FE0EAE1F8E033D00AC002E01EE196 +:10023600EEE8F7E02DD002E01FE0E6EEF7E028D08A +:1002460043FD01C0FDCF02E01EE1EEE8F7E020D05D +:1002560002E01FE0E6EFF7E01BD00AEF37D00A9581 +:10026600E9F702E013E0E6E0F8E012D0F6CFAA984C +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A27D000FF919800FD919AAA9A23C0CF +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895ECEDFFE007C0E2E2F1E0C0 +:1002D60004C0EDE101C0E3E0F0E020E02A95F1F78B +:1002E6003197E1F70895FFB666FD22C03CB131258E +:1002F600F2F0312552F0EF93FF93EEEBF091B3005D +:10030600EF0FFF273083FF91EF91131608F0132E9E +:100316006F7E6064312D3F7741F011202AF15798A6 +:100326006F7D3FEF232E606148C033EF42C040C06F +:100336003091B600313019F031E03093BB003CB15A +:10034600EF93FF93E62DE70DE50DEF70ED55FF27D3 +:100356003083E091B500F091B600EF1711F4639485 +:1003660001C07394FF91EF913EEF232E1A941AF574 +:1003760037EE232E606121C0EF93FF93EEEBF091F1 +:10038600B300EF0FFF2730813A953083E82DED5902 +:10039600FF273081FF91EF913CB93695330B3A95A3 +:1003A600232E9A9483943FE383221A9431F403C054 +:1003B60037EE232E6F7E57986F79FFBE1895FFB6DE +:1003C6003091BD007091BE00732B49F031503093CF +:1003D600BD003091BE0030403093BE0091F0442005 +:1003E60051F0439441F430E03DB93EB13FB138EEAF +:1003F6003DB9B89A687F222011F02394B9F0FFBE68 +:10040600189507CE67FD18C0890C3FE3832299240F +:100416009092BA00EF93FF93EEEBF091B300EF0FDB +:10042600FF2730E43083FF91EF9106C065FDEACFE8 +:1004360066FDA2CF64FD7AC033EF232E3091BC0057 +:10044600332359F03A953093BC0031F0AA9891982D +:10045600899A30E03AB9B1CFDCCD57983FE839B93F +:100466003091BA0039293A2939F43091B8003A95D1 +:1004760049F03093B80037C03091B9003A9591F001 +:100486003093B90030E13093B80099203091B30031 +:1004960041F4AA2041F09A2CAA243091B40030935A +:1004A600B300393001F16F779920B9F4AA2059F4D5 +:1004B6003091BA003A9542F43091B3003395393011 +:1004C60048F031E007C031E03093BA009A2CAA24F4 +:1004D6003091B4003093B30025C031E03093BA00B8 +:1004E6003091B3001FC030E13093B900606830919D +:1004F600BB00332331F03A953093BB003091B60000 +:1005060011C03091B600772069F47091B70030932E +:10051600B700372F313021F03395393008F032E00B +:100526003093B6003CB960616F7947CF37EE232E22 +:1005360035E039B9392D67FF04C030E1361937196E +:1005460030683CB9132E579A3CB1606236CFFFB67D +:10055600B8983FB162FD8EC060FD5EC061FD57C0B8 +:100566003A3090F1303899F0313899F03139A1F0BC +:10057600323991F0333981F0353A99F03A3AE1F06F +:10058600353CD9F030E03DB944244260A3C0979889 +:100596009FC04160979A9CC030593093CC0041600F +:1005A60097C03FEF3093BC0030E03DB994983FEFE1 +:1005B60070E07BBD3ABD8CC02CCD38EE3093BD00CB +:1005C60033E03093BE0084C0332379F4686066203C +:1005D60049F47720C1F0672C77243090B60030922A +:1005E600B50012C03090B5000FC0677F332EAA2029 +:1005F60021F03091B400331531F431E03093BA0074 +:100606003092B40001C033243FB8626061C06D7F90 +:10061600332009F061605CC0332E6E7F332063FFA8 +:1006260005C05AF5362D30681FC051C0F2F3EF935E +:10063600FF93EEEBF091B400EF0FFF273081E091CE +:10064600B300F091B400EF1731F0E0E4E9193E177A +:1006560030F03E2F04C0303408F030E439193A192E +:10066600FF91EF910AF43FE7331508F4332E3FB9B3 +:1006760064602EC033208AF43A944AF56160EF93A1 +:10068600FF93E52DED55FF2730813FB9FF91EF919F +:100696006A9453943FE053221BC060FF14C0EF934B +:1006A600FF93E92DEA0DE80DEF73ED59FF2730832F +:1006B600E091B300F091B400EF1711F4939401C0E8 +:1006C600A394FF91EF913A9412F0616001C06B7FA1 +:1006D60037EE432EFFBE1895FFB6A89534B1532FBB +:1006E60035B1379557953795579544FD12C04061FA +:1006F6003091BC003323C9F430E070E05C51C0F1A6 +:1007060030E670E05038A0F55695352F5695350FE2 +:100716002FC04F7E45FD0DC0583F40F03091CA00B6 +:100726003A953093CA0031F5406224C030E13093E7 +:10073600CA005093CB00593330E074E058F0309142 +:10074600C8007091C9003150704021F430E03DB9C5 +:10075600442448603093C8007093C900563450F062 +:100766003FEF3093BC0030E03DB994983FEF70E026 +:100776007BBD3ABD35E445FF34E044FF35E037B98B +:100786003EED36B9FFBE18951B44301B47301B5053 +:10079600311B45301B4B1B301B2F301B5300001BDE +:1007A6004E00801B45311B44301B47301B50311B0C +:1007B60045301B4B1B301B2F301B5300001B4EF0CC +:1007C600401B45311B53100D4859544543482031B1 +:1007D600303030001B53100D57504F3330205635F4 +:1007E6001B53100D42414420434F4D4D414E440092 +:1007F6001B53100D42415454455259204C4F57003B +:100806001B4D30001B53100D4859544543482031A9 +:10081600353030001B53100D535441434B204F5677 +:060826004552464C4F57FD +:042000000041BCAC33 +:00000001FF diff --git a/src/avr/product/WPOV2.HEX b/src/avr/product/WPOV2.HEX new file mode 100644 index 00000000..3a2161e2 --- /dev/null +++ b/src/avr/product/WPOV2.HEX @@ -0,0 +1,131 @@ +:020000020000FC +:020000000BC033 +:06000C00D8C19FC26CC1C7 +:1000160060C30FED0DBF00E808B9A8950FE001BD5C +:100026000AE50093CC0000E00DB90AB9C59ABC9A5E +:100036008D9A8E9A929A939AC19AB99AC098B898BC +:1000460097988F9A94988C9AAA98A29A9198899A36 +:1000560007E00DD106E00BD105E009D104E007D198 +:1000660001E005D100E003D10FE509B908E10AB9BD +:100076002AD10AEA0CB90CB929D1949A27D19498B5 +:1000860025D1949A0027E0E6FF2701930193019377 +:10009600EFEB019301930193019301930193019374 +:1000A60001930093BC000093CA000093BD00009327 +:1000B600BE0000E4008300E00093C80004E0009363 +:1000C600C90044276627112488249924AA24552484 +:1000D6006624772402E00093B70001E00093B300A2 +:1000E6000093B4000093B5000093B6000093B800E7 +:1000F6000093B9000093CB0000E00093BA00009390 +:10010600BB0000EF202E00EF402E02E003BF02E00E +:1001160009BF0EB10FB108EE0DB900E00DBD0CBD63 +:100126000BBD0ABD01EC0FBD01E00EBD05E007B930 +:100136000EED06B9789402E01EE1E4E5F7E0A8D0FA +:100146000091CC000A3509F066C041FD6FC043FD41 +:100156007AC040FFF5CF0091CB00033041F002306A +:1001660091F002E01FE0E0E9F7E092D006C002E07D +:100176001FE0E0EDF7E08CD000C003E01EE1E2E70F +:10018600F7E086D00FC002E01CE0E0EAF7E080D09E +:1001960003E01EE1E4E5F7E07BD003E01CE0E0EAE3 +:1001A600F7E076D01CD00B3109F0FCCF18D0043420 +:1001B60009F0F8CF14D0037039F0013039F002306D +:1001C60039F0033039F0EECF969A05C0969803C001 +:1001D600959A01C0959810E3100FE4CF789400919A +:1001E600CC000A35C1F441FD21C043FD2CC0F89472 +:1001F6009920A1F30091B300093081F7EF93FF93A3 +:10020600E82DED59FF2700819A948394EFE38E221F +:10021600FF91EF91189502E01EE1E4E5F7E038D092 +:1002260002E01FE0E0EEF7E033D00AC002E01EE194 +:10023600E4E5F7E02DD002E01FE0ECEAF7E028D095 +:1002460043FD01C0FDCF02E01EE1E4E5F7E020D06A +:1002560002E01FE0ECEBF7E01BD00AEF37D00A957F +:10026600E9F702E013E0ECECF7E012D0F6CFAA983B +:1002760002FF919802FD919A29D001FF919801FD04 +:10028600919A26D000FF919800FD919AAA9A22C0D1 +:1002960078940000F894AA20D9F70093B400C89582 +:1002A600002D04D031961A95D1F71895EF93FF9348 +:1002B600E92DEA0DE80DEF73ED59FF270083FF9155 +:1002C600EF91A3940895E0EFFAE006C0E8EC03C0CE +:1002D600E4E101C0E2E0F0E020E02A95F1F7319791 +:1002E600E1F70895FFB666FD22C03CB13125F2F074 +:1002F600312552F0EF93FF93EEEBF091B300EF0F41 +:10030600FF273083FF91EF91131608F0132E6F7EAF +:100316006064312D3F7741F011202AF157986F7DA7 +:100326003FEF232E606146C038EF40C03EC030919B +:10033600B600313019F031E03093BB003CB1EF9399 +:10034600FF93E62DE70DE50DEF70ED55FF273083A2 +:10035600E091B500F091B600EF1711F4639401C077 +:100366007394FF91EF913FEF232E1A940AF530EF25 +:10037600232E60611FC0EF93FF93EEEBF091B30065 +:10038600EF0FFF2730813A953083E82DED59FF278F +:100396003081FF91EF913CB93FEF232E9A948394DD +:1003A6003FE383221A9431F403C030EF232E6F7E8D +:1003B60057986F79FFBE1895FFB63091BD007091C2 +:1003C600BE00732B49F031503093BD003091BE0012 +:1003D60030403093BE0091F0442051F0439441F4F4 +:1003E60030E03DB93EB13FB138EE3DB9B89A687FCD +:1003F600222011F02394B9F0FFBE18950ACE67FDAE +:1004060018C0890C3FE3832299249092BA00EF9397 +:10041600FF93EEEBF091B300EF0FFF2730E430834C +:10042600FF91EF9106C065FDEACF66FDA4CF64FD9E +:100436007AC038EF232E3091BC00332359F03A9519 +:100446003093BC0031F0AA989198899A30E03AB975 +:10045600B1CFDFCD57983FE539B93091BA00392988 +:100466003A2939F43091B8003A9549F03093B800FA +:1004760037C03091B9003A9591F03093B90030E128 +:100486003093B80099203091B30041F4AA2041F08E +:100496009A2CAA243091B4003093B300393001F17C +:1004A6006F779920B9F4AA2059F43091BA003A9599 +:1004B60042F43091B3003395393048F031E007C04B +:1004C60031E03093BA009A2CAA243091B4003093CC +:1004D600B30025C031E03093BA003091B3001FC09D +:1004E60030E13093B90060683091BB00332331F0BE +:1004F6003A953093BB003091B60011C03091B600EA +:10050600772069F47091B7003093B700372F3130F8 +:1005160021F03395393008F032E03093B6003CB91B +:1005260060616F7947CF30EF232E33E039B9392D2B +:1005360067FF04C030E13619371930683CB9132E0D +:10054600579A3CB1606236CFFFB6B8983FB162FDAC +:100556008EC060FD5EC061FD57C03A3090F1303804 +:1005660099F0313899F03139A1F0323991F03339B7 +:1005760081F0353A99F03A3AE1F0353CD9F030E07D +:100586003DB944244260A3C097989FC04160979AA2 +:100596009CC030593093CB00416097C03FEF3093F9 +:1005A600BC0030E03DB994983FEF70E07BBD3ABDAA +:1005B6008CC02FCD38EE3093BD0033E03093BE00B3 +:1005C60084C0332379F46860662049F47720C1F04B +:1005D600672C77243090B6003092B50012C0309068 +:1005E600B5000FC0677F332EAA2021F03091B400EA +:1005F600331531F431E03093BA003092B40001C0C3 +:1006060033243FB8626061C06D7F332009F06160BA +:100616005CC0332E6E7F332063FF05C05AF5362D3E +:1006260030681FC051C0F2F3EF93FF93EEEBF091E9 +:10063600B400EF0FFF273081E091B300F091B400D2 +:10064600EF1731F0E0E4E9193E1730F03E2F04C011 +:10065600303408F030E439193A19FF91EF910AF471 +:100666003FE7331508F4332E3FB964602EC03320BC +:100676008AF43A944AF56160EF93FF93E52DED55C0 +:10068600FF2730813FB9FF91EF916A9453943FE081 +:1006960053221BC060FF14C0EF93FF93E92DEA0DB0 +:1006A600E80DEF73ED59FF273083E091B300F09129 +:1006B600B400EF1711F4939401C0A394FF91EF9146 +:1006C6003A9412F0616001C06B7F30EF432EFFBE9B +:1006D6001895FFB6A89534B1532F35B13795579570 +:1006E6003795579544FD12C040613091BC003323C5 +:1006F60031F530E070E05C5100F130E670E05038E2 +:10070600E0F45695352F5695350F17C04F7E50930A +:10071600CA00583A30E074E058F43091C80070913D +:10072600C9003150704021F430E03DB9442448609E +:100736003093C8007093C90002C07BBD3ABD34E057 +:1007460044FF35E037B93EED36B9FFBE18951B4478 +:10075600301B47301B50311B45301B4B1B301B2FAA +:10076600301B5300001B4E00801B45311B44301BC1 +:1007760047301B50311B45301B4B1B301B2F301B8A +:100786005300001B4EF0401B45311B53100D4859BA +:10079600544543482031303030001B53100D57501C +:1007A6004F33302056351B53100D42414420434FE2 +:1007B6004D4D414E44001B53100D42415454455279 +:1007C60059204C4F57001B4D30001B53100D4859F4 +:1007D600544543482031353030001B53100D5354D7 +:0C07E60041434B204F564552464C4F57A4 +:042000000041BCAC33 +:00000001FF diff --git a/src/avr/putpcx.asm b/src/avr/putpcx.asm new file mode 100644 index 00000000..fb026e1e --- /dev/null +++ b/src/avr/putpcx.asm @@ -0,0 +1,79 @@ +; PUTPCX.ASM + +EXTRN GETSTRLOC:FAR + +CODE SEGMENT + + ASSUME CS:CODE,DS:CODE + +B EQU BYTE PTR +W EQU WORD PTR +D EQU DWORD PTR + + LOCALS + +MISC_ADDR EQU 3C2H +SEQU_ADDR EQU 3C4H +CRTC_ADDR EQU 3D4H + +; GET$ #1,32700,F$ +; CALL PUTPCX(F$) + +PUBLIC PUTPCX + +PUTPCX: PUSH BP + MOV BP,SP + PUSH SI + PUSH DI + PUSH DS + PUSH ES + PUSHF + + LDS SI,[BP+6] ; DS:SI -> F$ DESCRIPTOR + LODSW + PUSH AX + CALL GETSTRLOC + XCHG SI,AX + MOV DS,DX ; DS:SI -> F$ DATA + + MOV DX,SEQU_ADDR + MOV AX,0F02H + OUT DX,AX + MOV AX,0A000H + MOV ES,AX + SUB DI,DI + + MOV DX,[SI+10] ; YMAX + SUB DX,[SI+6] ; -YMIN + MOV BP,[SI+66] ; BYTES PER LINE + ADD SI,80H + +@@LINE: MOV BX,BP +@@PCX: LODSB + MOV CX,1 + CMP AL,0C0H + JB @@SNGL + AND AX,3FH + XCHG CX,AX + LODSB +@@SNGL: SUB BX,CX + REP STOSB + JA @@PCX + MOV CX,640/8 + SUB CX,BP + MOV AL,0FFH + REP STOSB + DEC DX + JNZ @@LINE + + POPF + POP ES + POP DS + POP DI + POP SI + POP BP + RETF 4 + +CODE ENDS + END + \ No newline at end of file diff --git a/src/avr/set00.pcx b/src/avr/set00.pcx new file mode 100644 index 0000000000000000000000000000000000000000..33bf29df77b37a6f6232393532c0b0d338e207f7 GIT binary patch literal 3023 zcmeHIPe>F|7Q?pIRKC}Jy zOfampzhy{+0SAwD&|OPDy&yWJneoMA%`jxJ*xFy)dOKv{IEK8bCs@SB1F-IU9{*S9 zNFjR!C8S)DX{+QcbOj6eaUPj~XW0knQU~%BOQGP2q^M4z-!CGDCz5&82=j3pGEXfx z=bC2T9aP@!R*1M*mM|$Xrt!rknH)tGdB?HE9m^`F9EZsrIXA+Sqg-&_5YmHn&4YC( z>Djs4H3l=k!}^@Z!g`<)>7nCtOhGmtXzUwAHkKgetVJScE`e+>h2>G@62-DHC*M@2qcVS!46BU2XRdMC zwu|nuk~A0in_#JPl$hDx+)-xMV}Yss-hfH`NL10JlTBzrk`*&3M(<=0NCZ=c(LibZ_=F`X`TE8fCb-@XWQ|&(Q<;r+b>2OP?fV0GH{OGy-OUVZ!cVGJ z!1ffwbW!ZBj0Ibe-B}}6ayIYI=;-0-BkRw?yt?V( literal 0 HcmV?d00001 diff --git a/src/avr/ter.inc b/src/avr/ter.inc new file mode 100644 index 00000000..c566b9fd --- /dev/null +++ b/src/avr/ter.inc @@ -0,0 +1,211 @@ +; TER.INC + +; ----------------------------------------------------------------------------- +; TER FOREGROUND TASK + +.MACRO INT_HANDLERS + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + RJMP TX_EMPTY ; UART DATA REGISTER EMPTY HANDLER + ; THIS WILL CRASH IF INVOKED: + RJMP TX_COMPLETE ; UART TX COMPLETE HANDLER +.ENDMACRO + +.MACRO INIT_API_BUS + LDI A,TER_RATE ; 9600 BPS + OUT UBRR,A ; SET UART RATE + + LDI A,$98 ; ENABLE TX, AND RX WITH INTERRUPTS + OUT UCR,A + + CLR TX_PTR + CLR TX_COUNT + + CLR RX_PTR + CLR RX_COUNT + + ;CLR API_STATE + ;CLR API_REMAIN + ;CLR API_WATCHDOG +.ENDMACRO + +; ----------------------------------------------------------------------------- +; TER FOREGROUND ROUTINES + +.MACRO MRX_WAIT + TST RX_COUNT + BREQ RX_WAIT +.ENDMACRO + +.MACRO MRX_CHAR + PUSH YL + PUSH YH + + MOV YL,RX_PTR + SUBI YL,-RX_BUF + CLR YH + LD A,Y + + CLI + DEC RX_COUNT + INC RX_PTR + LDI YL,RX_SIZE-1 + AND RX_PTR,YL + + MOV YL,RX_COUNT + CPI YL,RX_SIZE-42 + BRSH MAY_BE_FULL + SBRC FLAGS,RXFULL ; IF BUFFER WAS FULL, + SBR FLAGS,1<42 BYTES LEFT, BUFFER IS NOT FULL +MAY_BE_FULL: + SEI + + POP YH + POP YL + RET +; FALL INTO MTX_WAIT FOR LOOPBACK TEST +.ENDMACRO + +.MACRO MTX_WAIT + PUSH A +TX_WAIT_LOOP: + MOV A,TX_COUNT + CPI A,TX_SIZE + BRSH TX_WAIT_LOOP + POP A +.ENDMACRO + +.MACRO MTX_CHAR + PUSH YL + PUSH YH + + IN YH,SREG + CLI + MOV YL,TX_COUNT + ADD YL,TX_PTR + OUT SREG,YH ;SEI + ANDI YL,TX_SIZE-1 + SUBI YL,-TX_BUF + CLR YH + ST Y,A + + IN YH,SREG + CLI + INC TX_COUNT + + SBI UCR,UDRIE ; ENABLE UART DATA REGISTER EMPTY INT + OUT SREG,YH ;SEI + + POP YH + POP YL +.ENDMACRO + +; ----------------------------------------------------------------------------- +; TER BACKGROUND ROUTINES + +.MACRO MTX_EMPTY + IN SR,SREG + PUSH F + + SBRS FLAGS,RXSEND + RJMP TX_TEST + + CBR FLAGS,1<42 BYTES LEFT, BUFFER IS NOT FULL +MAY_BE_FULL: + SEI + + POP YH + POP YL + RET +; FALL INTO MTX_WAIT FOR LOOPBACK TEST +.ENDMACRO + +.MACRO MTX_WAIT + PUSH A +TX_WAIT_LOOP: + MOV A,TX_COUNT + CPI A,TX_SIZE + BRSH TX_WAIT_LOOP + POP A +.ENDMACRO + +.MACRO MTX_CHAR + PUSH YL + PUSH YH + + IN YH,SREG + CLI + MOV YL,TX_COUNT + ADD YL,TX_PTR + OUT SREG,YH ;SEI + ANDI YL,TX_SIZE-1 + SUBI YL,-TX_BUF + CLR YH + ST Y,A + + IN YH,SREG + CLI + INC TX_COUNT + + SBI UCR,UDRIE ; ENABLE UART DATA REGISTER EMPTY INT + OUT SREG,YH ;SEI + + POP YH + POP YL +.ENDMACRO + +; ----------------------------------------------------------------------------- +; TER BACKGROUND ROUTINES + +.MACRO MTX_EMPTY + IN SR,SREG + PUSH F + + SBRS FLAGS,RXSEND + RJMP TX_TEST + + LDI F,~(1<>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + LDS R19,LATCH10_SAV ; AND THIS + EOR R19,@0 + ANDI R19,$E0 + EOR R19,@0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + SEI + STS LATCH10_SAV,R19 ; MUST BE ATOMIC DUE TO TOGGLING M +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@1 + ;POP @1 + + LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,1 + BST @1,6 ; A14 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + NOP + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO + OUT PORTA,@0 ; SELECT PHOTODIODE CHANNEL + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LED + OUT PORTA,@0 ; MAIN LED DRIVE PORT + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LEDLO + LDS D,LATCH12_SAV ; DRIVE LED COMMON LO + CBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO LEDHI + LDS D,LATCH12_SAV ; DRIVE LED COMMON HI + SBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKHI + LDS D,LATCH12_SAV ; DRIVE SPEAKER HI + SBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKLO + LDS D,LATCH12_SAV ; DRIVE SPEAKER LO + CBR D,1<<3 + SBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKOFF + LDS D,LATCH12_SAV ; DRIVE SPEAKER OFF + CBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FE00 ; ALL LONG PULSES IS FULLY DARK +;!!.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFC0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCC4 + +; WHEN VCC = $FCC4 FOR 6.0V: +.EQU CONTRAST_MIN =$FCA0 ; MIN IS FULLY DARK +.EQU CONTRAST_MAX =$FD00 ; MAX IS FULLY LIGHT +.EQU CONTRAST_INIT =$FCD0 + +; GENEROUS LIMITS FOR EXPERIMENTATION: +;.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FE10 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =10 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$20 +.EQU RX_SIZE =$80 + +.EQU TK_LED_PULSE =$1E ; 22US ?? CLOCKS OF /8 +.EQU TK_DELAY_0 =$38 ; 54US ?? CLOCKS OF /8 +.EQU TK_DELAY_1 =$28 ; CLOCKS OF /64, CHANNEL SELECT DELAY +.EQU TK_DELAY_2 =$00 ; CLOCKS OF /1024, VDD POWER ON DELAY + ; $D0 IS TOO SHORT, $E0 SEEMS TO WORK + +.EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU TER_RATE =$05 ; DIVISOR FOR 115200 BPS +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 UNUSED +.EQU RXFULL =6 ; PROVIDES HYSTERESIS FOR BUFFER FULL +.EQU RXSEND =7 ; SET WHEN IMMEDIATE XON/XOFF REQUIRED + +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +CHAR_X: .BYTE 1 +CHAR_Y: .BYTE 1 +CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC_64K: .BYTE 1 +TIME_HSEC_256: .BYTE 1 +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_STATE: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RJMP GO_TIM2_OVF ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_T1_OVERFLOW + RJMP GO_T0_OVERFLOW + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + LDI F,0 + STS TIME_HSEC_64K,F + STS TIME_HSEC_256,F + STS TIME_HSEC,F + STS TIME_SECOND,F + STS TIME_MINUTE,F + STS TIME_HOUR,F + LDI F,1 + STS DATE_DAY,F + STS DATE_MONTH,F + LDI F,20 + STS DATE_YEAR,F + +RESTART_ENTRY: +;**: + LDI F,8 ; TIMER 2 CLOCKED BY 32 KHZ +;** LDI F,0 ; TIMER 2 CLOCKED BY 11 MHZ + OUT ASSR,F +;**: + ; MUST MATCH SET_TIME ROUTINE % + LDI F,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;!! LDI F,$11 ; DIVIDE BY 2, TOGGLE OC2 (PIN 21) + ; (RTC DIAGNOSTIC) +;** LDI F,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,F + ; % + LDI F,$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + LDI F,$00 + OUT GIMSK,F + + LDI F,$B8 ; INIT_PORTS + OUT DDRD,F + OUT PORTD,F ; D2 = TRI-STATE, VSWT ON + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + OUT PORTC,F + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + + LDI D,$18 ; A18|A17|A16|A15|A14=11000 + OUT PORTA,D ; CL1=M=FLM=0 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + + CLR SCAN + STS ROW_INDEX,SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + + LDI D,$F4 ; BIT 6 = 1 VDD ON, BIT 7 = 1 LCD ON + STS LATCH5_SAV,D + PHOTO D + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +RTNCDE: LDIZ RTN_CODE ; POINT Z TO FLASH + LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER + LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + CLR R0 ; TEMPORARY CLEAR KB + RAMWRX R0 ; WRITE DATA TO DSPRAM + DEC XL + BREQ RTNCDE_END ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CDE1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CDE0 +RTNCDE_END: + + ; INITIALISE DEFAULT CHARACTER SET + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + ; CLEAR REFRESH BUFFER TO AVOID A BRIEF FLICKER + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL GO_SELECT_PAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +CLEAR_REFRESH: + PUSH B + PUSH YL + PUSH YH + + LDI B,32 + RCALL GO_CLEAR_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + ADIW YL,6 + LDI B,2 + RCALL GO_CLEAR_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP YH + POP YL + POP B + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE CLEAR_REFRESH + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,$40 ;$10 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + LDI A,0 + STS SCAN_STATE,A ; START ON FIRST LED / PHOTODIODE PAIR + + LDI A,0 + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + LDI F,$45 + OUT TIMSK,F ; TURN ON TIMER 0, 1, 2 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL HELLO_DISPLAY ; SHOW EXAMPLE DISPLAY + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + SBI PORTD,4 ; TURN TRANSISTOR OFF + CBI PORTD,5 ; DROP CL2 + + LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + LDI D,$74 ; BIT 6 = 1 VDD ON, BIT 7 = 0 LCD OFF + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;LDI D,$34 ; BIT 6 = 0 VDD OFF, BIT 7 = 0 LCD OFF + STS LATCH5_SAV,D + PHOTO D + + LDI D,$41 + OUT TIMSK,D ; DISABLE TIMER 1 INTERRUPTS + + LDI D,0 + OUT TCCR0,D ; DISABLE TIMER 0 TEMPORARILY ONLY + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + + LDI F,4 + STS TURNON_COUNT,F ; .25 SEC TO BREAK, .75 SEC TO MAKE + + INIT_API_BUS ; RESET UART TO RECEIVE TURNON COMMAND + +SLEEP_LOOP: + CLI + IN F,TCCR0 + TST F + LDI F,$4A ; SE=1 SM1:SM0=00 FOR IDLE MODE + BRNE SLEEP_SETUP ; TIMER 0 RUNNING, STAY IN IDLE MODE + SBIS PIND,0 ; BREAK OFF, UART ACTIVE, STAY IN IDLE + LDI F,$7A ; SE=1 SM1:SM0=11 FOR POWER SAVE MODE +SLEEP_SETUP: + OUT MCUCR,F + SEI + SLEEP + + LDS F,TURNON_COUNT + TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;SBIS PIND,0 ; AND BREAK HAS DISAPPEARED, WAKE UP + BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP + + CLI + RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + +; ----------------------------------------------------------------------------- + +ADRYP: LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL + OUT PORTA,YH + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +;HELLO_DISPLAY: +; LDI A,0 +; STS RECTNC_X,A +; STS RECTNC_Y,A +; STS RECTNC_XX,A +; LDI A,$80 +; STS RECTNC_YY,A +; RCALL DRAW_RECTNC +; +; LDI A,16 +; STS CHAR_X,A +; STS CHAR_Y,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; RCALL STRING_DRAW +; +; LDI A,240 +; STS CHAR_X,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; +;STRING_RIGHT_JUST: +; PUSH B +; PUSH ZL +; PUSH ZH +; RCALL STRING_WIDTH +; POP ZH +; POP ZL +; POP B +; LDS A,CHAR_X +; SUB A,R0 +; STS CHAR_X,A +; +;STRING_DRAW: +; PUSH B +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; PUSH R0 +; RCALL DRAW_CHAR +; POP R0 +; POP ZH +; POP ZL +; LDS A,CHAR_X +; ADD A,R0 +; STS CHAR_X,A +; POP B +; DEC B +; BRNE STRING_DRAW +; RET +; +;STRING_WIDTH: +; CLR R0 +;STRING_WIDTH_LOOP: +; PUSH B +; PUSH R0 +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; POP ZH +; POP ZL +; POP A +; ADD R0,A +; POP B +; DEC B +; BRNE STRING_WIDTH_LOOP +; RET +; +;HELLO_MESSAGE: .DB 'H','E','L','L','O',0 + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + RCALL RX_WAIT + + CPI A,$1B + BREQ ESC_SEQUENCE + + SBRC FLAGS,3 + RJMP REGULAR_CHAR + CPI A,$20 + BRSH REGULAR_CHAR + + CPI A,$08 + RJEQ BACK_SPACE +;L0132: + CPI A,$0D + RJEQ CR +;L0135: + CPI A,$0A + BRNE TEST_BELL + RJMP LF +TEST_BELL: + CPI A,7 + BRNE MAIN_LOOP + +REGULAR_CHAR: + SBRC FLAGS,2 ; CROSSED ZEROS ON? + RJMP L013B ; YES, DON'T BOTHER TESTING FOR ZERO + CPI A,'0' + BRNE L013B + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YL,LOW(-$204) + SBCI YH,HIGH(-$204) + A14_A18 B + RCALL LPMS + MOV A,R0 +L013B: RCALL DRAW_CHAR_TTY + RJMP MAIN_LOOP + +ESC_SEQUENCE: + RCALL RX_WAIT + CPI A,$1B + BREQ REGULAR_CHAR + CPI A,'.' + RJEQ CHARACTER_SET_DOWNLOAD + CPI A,'/' + RJEQ CROSSED_ZEROS + CPI A,'?' + RJEQ CHARACTER_SET_QUERY + CPI A,'B' + RJEQ BUZZER + CPI A,'C' + RJEQ CLEAR_RECTANGLE + CPI A,'D' + RJEQ DRAW_MODE + CPI A,'E' + RJEQ ENABLE_CNTRL + CPI A,'F' + RJEQ GET_FILLED_RECTNC_SIZE + CPI A,'G' + RJEQ INTERPRET_MODE + CPI A,'K' + RJEQ CLR_DISP + CPI A,'L' + RJEQ GO_SCROLL_REGION + CPI A,'M' + RJEQ MOSFET_CONTROL + CPI A,'N' + RJEQ GET_RECTNC_SIZE + CPI A,'P' + RJEQ PROP_FIXED_MODE + CPI A,'R' + RJEQ GET_RECT_SIZE + CPI A,'S' + RJEQ SET_CURSOR + CPI A,'T' + RJEQ SET_TIME + CPI A,'U' + RJEQ NULLSUB + CPI A,'V' + RJEQ CONTRAST_CONTROL + CPI A,'W' + RJEQ NULLSUB + CPI A,'X' + RJEQ SAVE_STATE + CPI A,'Z' + RJEQ TOUCH_ZONE + CPI A,'0' + BRLO ESC_SEQUENCE_ABORT + CPI A,'9'+1 + BRLO SET_CHSET_A +ESC_SEQUENCE_ABORT: + RJMP MAIN_LOOP + +CROSSED_ZEROS: + RCALL RX_WAIT + SBRS A,0 + RJMP CROSSED_ZEROS_OFF + LDI A,1<<2 + OR FLAGS,A + RJMP MAIN_LOOP +CROSSED_ZEROS_OFF: + LDI A,~(1<<2) + AND FLAGS,A + RJMP MAIN_LOOP + +MOSFET_CONTROL: + RCALL RX_WAIT + CPI A,$30 ; DO NOT TURN OFF BY ACCIDENT +; BRNE MOSFET_CONTROL_DONE +; CLI +; LDI F,1<<6 +; OR FLAGS,F ; SAY WE TURNED OFF VIA COMMAND +; SBI DDRD,2 ; D2 = LOW, VSWT OFF +; RJMP SLEEP_ENTRY ; GO AND SHUT DOWN DISPLAY +;MOSFET_CONTROL_DONE: + RJMP MAIN_LOOP + +BUZZER: RCALL RX_WAIT + STS BUZZ_TIME,A ; SAVE REQUESTED DURATION + RJMP MAIN_LOOP + +SET_TIME: + LDI A,0 + OUT TCCR2,A ; STOP COUNTING WHILE SETTING CLOCK + STS TIME_HSEC_64K,A + STS TIME_HSEC_256,A + STS TIME_HSEC,A + RCALL RX_WAIT + STS TIME_HOUR,A + RCALL RX_WAIT + STS TIME_MINUTE,A + RCALL RX_WAIT + STS TIME_SECOND,A + RCALL RX_WAIT + STS DATE_MONTH,A + RCALL RX_WAIT + STS DATE_DAY,A + RCALL RX_WAIT + STS DATE_YEAR,A + LDI A,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;** LDI A,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,A + RJMP MAIN_LOOP + +SET_CHSET: + RCALL RX_WAIT +SET_CHSET_A: + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE +;L01A3: + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: CLR CURSORX + RJMP MAIN_LOOP + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + CLI + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRCC DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRCC DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + RCALL FIND_CHAR ; SET UP CHAR_PTR FROM A = CHAR + RCALL CHAR_WIDTH ; SET UP R0 = PROP WIDTH FROM CHAR PTR + + CLR F + STS TEMP,F ; NUDGE FOR FIXED SPACING MODE + + SBRC FLAGS,4 + RJMP PROP_MODE ; FORCED TO FIXED SPACING MODE? + + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS ; GET R0 = CELL WIDTH FOR CHARACTER SET + PUSH R0 + SUB R0,W + BRCC NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + POP R0 ; RESTORE R0 = FIXED CELL WIDTH + +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE ; FORCED TO GRAPHICS MODE? + + MOV F,CURSORX + ADD F,R0 ; CHECK IF CHAR WILL FIT ON THIS LINE + BRCC OK_LINE + + CLR CURSORX + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 + RCALL SELECT_PAGE ; IN CASE WE SCROLLED THE DISPLAY + +OK_LINE: + LDS F,TEMP + ADD F,CURSORX + STS CHAR_X,F + STS CHAR_Y,CURSORY ; SET UP TOP LEFT COORDINATES + + ADD CURSORX,R0 ; ADVANCE CURSOR + +DRAW_CHAR: + LDS XPIXEL,CHAR_X + LDS LINE_CNT,CHAR_Y + + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE ; Y OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 + +Y_OFFSET_DONE: + SBRS X_SIZE,7 + RJMP X_OFFSET_DONE ; X OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$03 + RCALL LPMS + ADD XPIXEL,R0 + +X_OFFSET_DONE: + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + ADIW YL,$01 + RCALL LPMS ; GET R0 = Y LINES FOR CHARACTER + MOV Y_SIZE,R0 + + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +FIND_CHAR: + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + STS CHAR_PTR,YL + STS CHAR_PTR+1,YH + RET + +CHAR_WIDTH: + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + RCALL LPMS + MOV X_SIZE,R0 + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP LPMS ; PROPORTIONAL WIDTH IS PRESENT + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RJMP LPMS ; NO PROPORTIONAL WIDTH, USE CELL WIDTH + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + ; LET'S BE SAFE + ANDI A,$7F + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +GO_SELECT_PAGE: + RJMP SELECT_PAGE + +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +GO_EXT_INT0: + RJMP EXT_INT0 + +GO_EXT_INT1: + RJMP EXT_INT1 + +GO_TIM2_OVF: + RJMP TIM2_OVF + +GO_T1_OVERFLOW: + RJMP T1_OVERFLOW + +GO_T0_OVERFLOW: + RJMP T0_OVERFLOW + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +; ----------------------------------------------------------------------------- + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +; ----------------------------------------------------------------------------- + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR CURSORX ; HOME CURSOR + CLR CURSORY + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE CLEAR_DISPLAY_LOOP + RET + +; ----------------------------------------------------------------------------- + +EXT_INT0: +;**: +RETI +;** IN SR,SREG ; MEASURE VCC +;** SBI DDRD,2 +;** IN C,TCNT1L +;** IN D,TCNT1H +;** STS VCCH,D +;** STS VCCL,C +;** RJMP EXT_INT_RET + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP EXT_INT_RET + +T1_OVERFLOW: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + ; REDUNDANT, NOW DONE IN TIMER 2 OVERFLOW HANDLER + ;WDR + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDI D,$70 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, TOGGLE OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + LDS C,CLOCKING_PTR + TST C ; START OF 4 LINE BLOCK? (1 BASED) + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL +; LDI D,~(1<<6) +; AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION +GO_SLEEP_ENTRY: + RJMP SLEEP_ENTRY +BREAK_CONT: + +;** SBI DDRD,2 ; PRECHARGE VCC AND +;** SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D ; STOP TIMER1 + OUT TCNT1H,D ; AND CLEAR COUNT + OUT TCNT1L,D +;!! CBI PORTD,5 ; DROP CL2 + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + LDS D,LATCH10_SAV + OUT PORTA,D + SBI PORTB,4 + SBI PORTA,5 ; PULSE CL1 + CBI PORTA,5 + CBI PORTB,4 + RJMP L04F9 + +L04E6: LDS D,LATCH10_SAV + ORI D,$80 ; RAISE FLM + ORI D,$20 ; RAISE CL1 + OUT PORTA,D + + SBI PORTB,4 + LDI C,$60 ; TOGGLE M AND CL1 + EOR D,C + OUT PORTA,D + ANDI D,$7F ; DROP FLM + OUT PORTA,D + CBI PORTB,4 + STS LATCH10_SAV,D + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D +;**: + LDI D,1 ; TO CLOCK AT 5.5/2 MHZ + OUT OCR1AL,D + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + +;**: + LDI D,$7A ; WAIT FOR 32uSEC +;!! LDI D,$80 ; WAIT FOR 32uSEC +;** LDI D,$39 ; WAIT FOR 16uSEC +L050E: DEC D + BRNE L050E + +;!! LDI D,$01 +;!! OUT TCCR1B,D ; KILL CLR ON COMPARE MATCH +;!! SBI PORTD,5 ; SET CL2 HI (FOR REV E DOES NOTHING) + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP +;!!: + LDI D,$01 ; KILL CLR ON COMPARE MATCH + OUT TCCR1B,D ; WITH OC1A LEFT IN HIGH STATE + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + +;** LDS C,VCCL +;** LDS D,VCCH +;** LDI E,LOW(VCC_NOMINAL) +;** SUB C,E +;** LDI E,HIGH(VCC_NOMINAL) +;** SBC D,E + +;** ROR D +;** ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +;** PUSH D +;** PUSH C +;** ASR D +;** ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +;** POP E +;** ADD C,E +;** POP E +;** ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + +;**: + LDS C,VEEL + LDS D,VEEH +;** LDS E,VEEL +;** ADD C,E +;** LDS E,VEEH +;** ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_DELAY_0 ; 54uSEC + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + +;** CBI DDRD,2 ; START VCC AND +;** CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 +;!!: + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + + RJMP T1_OVERFLOW_RET + +T0_OVERFLOW: + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + PUSH ZH + PUSH ZL + PUSH R0 + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_STATE + INC D + STS SCAN_STATE,D + DEC D + BREQ SCAN_START ; IF SCAN_STATE WAS = 0 + DEC D + BREQ SCAN_BEEPER ; IF SCAN_STATE WAS = 1 + ; IMPLEMENT ENTRY POINT FOR SCAN_PULSE_LED HERE + DEC D + RJEQ SCAN_PHOTO ; IF SCAN_STATE WAS = 2 + +T0_OVERFLOW_RET: + POP R0 + POP ZL + POP ZH + +T1_OVERFLOW_RET: + POP D ; RESTORE STATE OF THE WORLD + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +EXT_INT_RET: + OUT SREG,SR + RETI + +SCAN_START: + LDI D,3 ;5 + OUT TCCR0,D ; PRESCALE=CK/1024 + LDI D,-TK_DELAY_1 ;TK_DELAY_2 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + RJMP L0617_RESET + +SCAN_BEEPER: + LDS D,BUZZ_TIME + TST D + BREQ SCAN_PULSE_LED + LDS C,LATCH12_SAV + SBRS C,3 + RJMP BEEPER_SPKHI + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP SCAN_PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP SCAN_PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +SCAN_PULSE_LED: + LDS D,LATCH5_SAV +;**: + SBRS D,7 ; ARE WE INSIDE SLEEP_LOOP? +;** SBRC D,7 + RJMP SCAN_PULSE_LED_OK ; YES, KEEP TIMER 0 TO RETAIN CONTROL + + LDI D,1<<7 + EOR FLAGS,D + BRPL SCAN_PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP T0_OVERFLOW_RET ; AND WASTE EVERY REMAINING CYCLE + +SCAN_PULSE_LED_OK: + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM ; R0 = LED DRIVE VALUE + LDI D,13*4 + CP SCAN,D + BRSH L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + RJMP T0_OVERFLOW_RET + +SCAN_PHOTO: + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + CLC + SBRC D,6 + RJMP L0593 ; ROW/COLUMN IS INACTIVE + + ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF + IN C,SREG + + LDI D,13*4 + CP SCAN,D + BRSH L05A8 + + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS ZL,ROW_BITMAP + LDS ZH,ROW_BITMAP+1 + ROL ZL + ROL ZH + STS ROW_BITMAP,ZL + STS ROW_BITMAP+1,ZH + RJMP L05F9 + +L05A8: ; WE HAVE A COLUMN STATUS +; LDS D,LATCH5_SAV +;;**: +; SBRS D,7 ; TURNED OFF? +;;** SBRC D,7 +; RJMP L05F9 ; YES, NO FURTHER PROCESSING + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRCS L05AB + RJMP L05F9 + +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 + +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS ZH,ROW_BITMAP+1 + LDS ZL,ROW_BITMAP + + LDS D,ROW_INDEX + TST D + BREQ ROW_BITMAP_LOOP + + MOV C,D +ROW_BITMAP_SKIP: + ROR ZH + ROR ZL + SUBI C,4 + BRNE ROW_BITMAP_SKIP + +ROW_BITMAP_LOOP: + SUBI D,-4 + ROR ZH + ROR ZL + BRCS FOUND_INTERSECTION +ROW_BITMAP_LOOPE: + CPI D,13*4 + BRLO ROW_BITMAP_LOOP + + ; NO FURTHER INTERSECTING ROWS FOUND + RJMP L05F9 + +FOUND_INTERSECTION: + ; FOUND AN INTERSECTING ROW FOR COLUMN + STS ROW_INDEX,D + + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + TST R0 + BRNE VALID_INTERSECTION + + ; INTERSECTION IS NULL, GO ON TO NEXT + LDS D,ROW_INDEX + CPI D,13*4 + BRSH L05F9 ; DONE LAST ROW, GO ON TO NEXT COLUMN +GO_L0617: + RJMP L0617 ; GO ON TO NEXT ROW, SAME COLUMN + +VALID_INTERSECTION: + ; INTERSECTION IS VALID, WE HAVE KEY MAKE + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,$40 ;$10 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + + MOV D,TX_COUNT + CPI D,TX_SIZE-1 + BRSH L05F9 + + PUSH A + MOV A,R0 + RCALL TX_CHAR + CPI A,$1B + BRNE TX_CONT + RCALL TX_CHAR +TX_CONT: + POP A + +L05F9: ; SCAN TO NEXT LED / PHOTODIODE PAIR + LDI D,4 + ADD SCAN,D + + LDS D,LATCH5_SAV +;**: + SBRC D,7 +;** SBRS D,7 + RJMP TURNED_ON + + LDI D,3 + OUT TCCR0,D ; PRESCALE=CK/64 + LDI D,-TK_DELAY_1 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI C,13*4 + CP SCAN,C + BRLO GO_L0617 + + ; KEEP VDD ON, TO AVOID THE LONG TK_DELAY_2 + ;LDS D,LATCH5_SAV + ;ANDI D,$BF ; BIT 6 = 0 VDD OFF + ;STS LATCH5_SAV,D + ;PHOTO D ; READY TO SLEEP FOR ANOTHER 0.25 SEC + + LDI D,0 + OUT TCCR0,D ; STOP TIMER SINCE COMPLETE SCAN DONE + ;RJMP T0_OVERFLOW_RET + + ;LDI D,$05 + ;OUT UBRR,D + ;LDI D,$18 + ;OUT UCR,D + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + ;OUT UDR,C + ;OUT UDR,D + OR C,D ; HAVE WE SOME ACTIVITY? + + LDS D,TURNON_COUNT + CPI D,4 + BRSH TURNON_BREAK ; WAITING FOR BREAK + CPI D,1 + BRSH TURNON_MAKE ; WAITING FOR MAKE +GO_T0_OVERFLOW_RET: + RJMP T0_OVERFLOW_RET ; ALREADY HAD MAKE, NOT TURNED ON YET + +TURNON_BREAK: + TST C ; HAD SOME ACTIVITY? + BREQ TURNON_SAVE ; NO, COUNT DOWN TO BREAK + LDI D,4+1 ; YES, RESTART COUNTDOWN TO BREAK + RJMP TURNON_SAVE +TURNON_MAKE: + TST C ; HAD SOME ACTIVITY? + BRNE TURNON_SAVE ; YES, COUNT DOWN TO MAKE + LDI D,3+1 ; NO, RESTART COUNTDOWN TO MAKE +TURNON_SAVE: + DEC D ; COUNT DOWN TO MAKE OR BREAK + STS TURNON_COUNT,D + BRNE GO_T0_OVERFLOW_RET ; NOT READY TO TRY TURNON YET + +; LDI D,~(1<<6) +; AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + CBI DDRD,2 ; D2 = TRI-STATE, VSWT ON + RJMP GO_SLEEP_ENTRY ; WE WILL NOW WAIT FOR TURNON COMMAND + +TURNED_ON: + LDI D,0 ; STOP TIMER, WE WILL REGAIN + OUT TCCR0,D ; CONTROL VIA NEXT CLOCKING INTERRUPT + STS ROW_INDEX,D + + LDI C,50*4 + CP SCAN,C + BRLO L0617 + + ; COMPLETED ENTIRE SCAN, START NEW SCAN + LDS D,DEBOUNCE + TST D + BREQ L0617_RESET + DEC D + STS DEBOUNCE,D + BRNE L0617_RESET + + LDS D,ACTIVE_ZONE + TST D + BREQ L0617_RESET + + MOV D,TX_COUNT + CPI D,TX_SIZE + BRSH L0617_RESET + + PUSH A + LDI A,0 + RCALL TX_CHAR + POP A + +L0617_RESET: + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + LDIZ SCAN_TBL + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$80 ; BIT 7 = PRESERVED, LCD ON/OFF STATUS + ORI D,$40 ; BIT 6 = 1 VDD ON + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + RJMP T0_OVERFLOW_RET + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP CLEAR_DISPLAY_LOOP + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; HOW MANY SECS/6553600 PER 4HZ INTERRUPT ? +; EACH TIME THROUGH ADD 1638400 SECS/6553600 = 1/4 SEC +; OSCILLATOR IS SLOW SO WE WILL ADD 1 PART IN 10000 +; HENCE EACH TIME THROUGH ADD 1638400+164 = 1638564 UNITS TO COUNT + +TIM2_OVF: + IN SR,SREG + + WDR ; BETTER TO HAVE THIS NOT IN AN INTERRUPT?? +;!! LDI A,$10 ; DIAGNOSTIC +;!! STS BUZZ_TIME,A ; SHORT BEEP + + LDS D,TIME_HSEC_64K + SUBI D,LOW(-1638564) + STS TIME_HSEC_64K,D + + LDS D,TIME_HSEC_256 + SBCI D,HIGH(-1638564) + STS TIME_HSEC_256,D + + LDS D,TIME_HSEC + SBCI D,HIGH(-1638564>>8) + CPI D,100 + BRSH TIM2_CARRY + STS TIME_HSEC,D + +TIM2_END: + OUT SREG,SR + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA COMMAND, + ;RETI ; START A NEW SCAN, OTHERWISE DONE + + LDI D,0 + STS SCAN_STATE,D ; WE WILL EXECUTE SCAN_START ROUTINE + RJMP T0_OVERFLOW ; GO AND TURN VDD ON + +GO_TX_CHAR: + RJMP TX_CHAR + +TIM2_CARRY: + LDI D,0 + STS TIME_HSEC,D + + LDS D,TIME_SECOND + INC D + CPI D,60 + BRLO TIM2_SECOND + + LDS D,TIME_MINUTE + INC D + CPI D,60 + BRLO TIM2_MINUTE + + LDS D,TIME_HOUR + INC D + CPI D,24 + BRLO TIM2_HOUR + + PUSH ZL + PUSH ZH + PUSH R0 + LDI ZL,LOW(MONTH_TABLE*2-1) + LDI ZH,HIGH(MONTH_TABLE*2-1) + LDS E,DATE_MONTH + ADD ZL,E + LDI E,0 + ADC ZH,E + LPM + MOV E,R0 + CPI E,28 + BRNE FEBRUARY_OK + LDS E,DATE_YEAR + ANDI E,3 + LDI E,28 + BRNE FEBRUARY_OK + LDI E,29 +FEBRUARY_OK: + POP R0 + POP ZH + POP ZL + + LDS D,DATE_DAY + CP D,E + BRLO TIM2_DAY + + LDS D,DATE_MONTH + CPI D,12 + BRLO TIM2_MONTH + + LDS D,DATE_YEAR + INC D + STS DATE_YEAR,D + CLR D +TIM2_MONTH: + INC D + STS DATE_MONTH,D + CLR D +TIM2_DAY: + INC D + STS DATE_DAY,D + CLR D +TIM2_HOUR: + STS TIME_HOUR,D + CLR D +TIM2_MINUTE: + STS TIME_MINUTE,D + CLR D +TIM2_SECOND: + STS TIME_SECOND,D + +TIM2_SEND: + MOV D,TX_COUNT + CPI D,TX_SIZE-7 + BRSH TIM2_SEND_SKIP + + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'T' + RCALL TX_CHAR +; LDS A,VCCL +; RCALL TX_CHAR +; LDS A,VCCH +; RCALL TX_CHAR +; LDS A,VEEL +; RCALL TX_CHAR +; LDS A,VEEH +; RCALL TX_CHAR +; LDI A,$0D +; RCALL TX_CHAR + LDS A,TIME_HOUR + RCALL GO_TX_CHAR + LDS A,TIME_MINUTE + RCALL GO_TX_CHAR + LDS A,TIME_SECOND + RCALL GO_TX_CHAR + LDS A,DATE_MONTH + RCALL GO_TX_CHAR + LDS A,DATE_DAY + RCALL GO_TX_CHAR + LDS A,DATE_YEAR + RCALL GO_TX_CHAR + POP A + +TIM2_SEND_SKIP: + RJMP TIM2_END + +; ----------------------------------------------------------------------------- + +MONTH_TABLE: + .DB 31,28,31,30,31,30,31,31,30,31,30,31 + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/tsv0.asm b/src/avr/tsv0.asm new file mode 100644 index 00000000..ae4fda1e --- /dev/null +++ b/src/avr/tsv0.asm @@ -0,0 +1,3568 @@ +; TSV0.ASM +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS +; ;!! INDICATES CHANGES + +;** INDICATES CHANGES FOR LOW VCC AVR MOD + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APITS.INC" ; NOT API.INC BECAUSE APITS.INC ALSO HAS TURNON COMMAND +;.INCLUDE "TERTS.INC" ; NOT TER.INC BECAUSE FLAGS IN LOWER HALF OF REGISTER SET + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS PAGE,YH + RCALL ADRYP ; AND SET PAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 + ;POP @1 +.ENDMACRO + +.MACRO A14_A18 + CLI + LDS R19,LATCH10_SAV ; AND THIS + EOR R19,@0 + ANDI R19,$E0 + EOR R19,@0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + SEI + STS LATCH10_SAV,R19 ; MUST BE ATOMIC DUE TO TOGGLING M +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + ;LDS R19,LATCH11_SAV ; ALL THIS IS A TOTAL KLUDGE + ;BST @0,7 ; A7 + ;BLD R19,1 + ;BST @0,6 ; A6 + ;BLD R19,0 + ;OUT PORTA,R19 + ;NOP + ;SBI PORTB,3 + ;NOP + ;CBI PORTB,3 + ;STS LATCH11_SAV,R19 + + MOV R19,@1 ;PUSH @1 + LSL R19 ;@1 + LSL R19 ;@1 + ;LDS R19,LATCH11_SAV + BST @0,7 ;R19,1 ; A7 + BLD R19,1 ;@1,1 + BST @0,6 ;R19,0 ; A6 + BLD R19,0 ;@1,0 + OUT PORTA,R19 ;@1 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@1 + ;POP @1 + + LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,1 + BST @1,6 ; A14 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + NOP + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO + OUT PORTA,@0 ; SELECT PHOTODIODE CHANNEL + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LED + OUT PORTA,@0 ; MAIN LED DRIVE PORT + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LEDLO + LDS D,LATCH12_SAV ; DRIVE LED COMMON LO + CBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO LEDHI + LDS D,LATCH12_SAV ; DRIVE LED COMMON HI + SBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKHI + LDS D,LATCH12_SAV ; DRIVE SPEAKER HI + SBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKLO + LDS D,LATCH12_SAV ; DRIVE SPEAKER LO + CBR D,1<<3 + SBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKOFF + LDS D,LATCH12_SAV ; DRIVE SPEAKER OFF + CBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.EQU T1_INIT =$FB35 +.EQU T1_FULL_SCALE =$FC2F + +.EQU VEE_MIN =$FC40 ; MIN IS FULLY DARK +.EQU VEE_MAX =$FFC0 ; MAX IS FULLY LIGHT +.EQU VEE_INIT =$FE00 + +.EQU CONTRAST_LONG =$FE00 ; ALL LONG PULSES IS FULLY DARK +;!!.EQU CONTRAST_LONG =$FC40 ; ALL LONG PULSES IS FULLY DARK +.EQU CONTRAST_SHORT =$FFC0 ; ALL SHORT PULSES IS FULLY LIGHT +.EQU CONTRAST_MID =$FE00 + +.EQU VCC_NOMINAL =$FCC4 + +; WHEN VCC = $FCC4 FOR 6.0V: +;.EQU CONTRAST_MIN =$FCA0 ; MIN IS FULLY DARK +.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK FOR ALBERT'S LCDS +.EQU CONTRAST_MAX =$FD00 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FCD0 +.EQU CONTRAST_INIT =$FCB0 ; FOR ALBERT'S + +; GENEROUS LIMITS FOR EXPERIMENTATION: +;.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FE10 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =10 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$20 +.EQU RX_SIZE =$80 + +.EQU TK_LED_PULSE =$1E ; 22US ?? CLOCKS OF /8 +.EQU TK_DELAY_0 =$38 ; 54US ?? CLOCKS OF /8 +.EQU TK_DELAY_1 =$28 ; CLOCKS OF /64, CHANNEL SELECT DELAY +.EQU TK_DELAY_2 =$00 ; CLOCKS OF /1024, VDD POWER ON DELAY + ; $D0 IS TOO SHORT, $E0 SEEMS TO WORK + +.EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS +.EQU API_TIMEOUT =50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 USED TO CONTROL LED PULSING FOR TOUCHSCREEN EVERY 2ND CYCLE +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +BUZZ_PERIOD: .BYTE 1 +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +PAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +CHAR_X: .BYTE 1 +CHAR_Y: .BYTE 1 +CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC_64K: .BYTE 1 +TIME_HSEC_256: .BYTE 1 +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_STATE: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RJMP GO_TIM2_OVF ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_T1_OVERFLOW + RJMP GO_T0_OVERFLOW + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + LDI F,0 + STS TIME_HSEC_64K,F + STS TIME_HSEC_256,F + STS TIME_HSEC,F + STS TIME_SECOND,F + STS TIME_MINUTE,F + STS TIME_HOUR,F + LDI F,1 + STS DATE_DAY,F + STS DATE_MONTH,F + LDI F,20 + STS DATE_YEAR,F + +RESTART_ENTRY: +;**: + LDI F,8 ; TIMER 2 CLOCKED BY 32 KHZ +;** LDI F,0 ; TIMER 2 CLOCKED BY 11 MHZ + OUT ASSR,F +;**: + ; MUST MATCH SET_TIME ROUTINE % + LDI F,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;!! LDI F,$11 ; DIVIDE BY 2, TOGGLE OC2 (PIN 21) + ; (RTC DIAGNOSTIC) +;** LDI F,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,F + ; % + LDI F,$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + LDI F,$00 + OUT GIMSK,F + + LDI F,$B8 ; INIT_PORTS + OUT DDRD,F + OUT PORTD,F ; D2 = TRI-STATE, VSWT ON + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + OUT PORTC,F + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + + LDI D,$18 ; A18|A17|A16|A15|A14=11000 + OUT PORTA,D ; CL1=M=FLM=0 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BUZZ_TIME,D ; NOT BUZZING (SHORT BEEP COMES LATER) + + CLR SCAN + STS ROW_INDEX,SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + + LDI D,$F4 ; BIT 6 = 1 VDD ON, BIT 7 = 1 LCD ON + STS LATCH5_SAV,D + PHOTO D + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +RTNCDE: LDIZ RTN_CODE ; POINT Z TO FLASH + LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER + LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + CLR R0 ; TEMPORARY CLEAR KB + RAMWRX R0 ; WRITE DATA TO DSPRAM + DEC XL + BREQ RTNCDE_END ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CDE1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CDE0 +RTNCDE_END: + + ; INITIALISE DEFAULT CHARACTER SET + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + LDIZ CHSET00 ; POINT Z TO FLASH + LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + ; CLEAR REFRESH BUFFER TO AVOID A BRIEF FLICKER + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL GO_SELECT_PAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +CLEAR_REFRESH: + PUSH B + PUSH YL + PUSH YH + + LDI B,32 + RCALL GO_CLEAR_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + ADIW YL,6 + LDI B,2 + RCALL GO_CLEAR_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP YH + POP YL + POP B + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE CLEAR_REFRESH + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,0 + STS BUZZ_PERIOD,A ; HIGHEST FREQUENCY + LDI A,$40 ;$10 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + LDI A,0 + STS SCAN_STATE,A ; START ON FIRST LED / PHOTODIODE PAIR + + LDI A,0 + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + LDI F,$45 + OUT TIMSK,F ; TURN ON TIMER 0, 1, 2 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL HELLO_DISPLAY ; SHOW EXAMPLE DISPLAY + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + SBI PORTD,4 ; TURN TRANSISTOR OFF + CBI PORTD,5 ; DROP CL2 + + LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + LDI D,$74 ; BIT 6 = 1 VDD ON, BIT 7 = 0 LCD OFF + SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + LDI D,$34 ; BIT 6 = 0 VDD OFF, BIT 7 = 0 LCD OFF + STS LATCH5_SAV,D + PHOTO D + + LDI D,$41 + OUT TIMSK,D ; DISABLE TIMER 1 INTERRUPTS + + LDI D,0 + OUT TCCR0,D ; DISABLE TIMER 0 TEMPORARILY ONLY + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + + LDI F,4 + STS TURNON_COUNT,F ; .25 SEC TO BREAK, .75 SEC TO MAKE + + INIT_API_BUS ; RESET UART TO RECEIVE TURNON COMMAND + +SLEEP_LOOP: + CLI + IN F,TCCR0 + TST F + LDI F,$4A ; SE=1 SM1:SM0=00 FOR IDLE MODE + BRNE SLEEP_SETUP ; TIMER 0 RUNNING, STAY IN IDLE MODE + SBIS PIND,0 ; BREAK OFF, UART ACTIVE, STAY IN IDLE + LDI F,$7A ; SE=1 SM1:SM0=11 FOR POWER SAVE MODE +SLEEP_SETUP: + OUT MCUCR,F + SEI + SLEEP + + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDS F,TURNON_COUNT + TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;SBIS PIND,0 ; AND BREAK HAS DISAPPEARED, WAKE UP + BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP + + CLI + RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + +; ----------------------------------------------------------------------------- + +ADRYP: LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL + OUT PORTA,YH + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,PAGE +; INC YH +; ANDI YH,$1F +; STS PAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +;HELLO_DISPLAY: +; LDI A,0 +; STS RECTNC_X,A +; STS RECTNC_Y,A +; STS RECTNC_XX,A +; LDI A,$80 +; STS RECTNC_YY,A +; RCALL DRAW_RECTNC +; +; LDI A,16 +; STS CHAR_X,A +; STS CHAR_Y,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; RCALL STRING_DRAW +; +; LDI A,240 +; STS CHAR_X,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; +;STRING_RIGHT_JUST: +; PUSH B +; PUSH ZL +; PUSH ZH +; RCALL STRING_WIDTH +; POP ZH +; POP ZL +; POP B +; LDS A,CHAR_X +; SUB A,R0 +; STS CHAR_X,A +; +;STRING_DRAW: +; PUSH B +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; PUSH R0 +; RCALL DRAW_CHAR +; POP R0 +; POP ZH +; POP ZL +; LDS A,CHAR_X +; ADD A,R0 +; STS CHAR_X,A +; POP B +; DEC B +; BRNE STRING_DRAW +; RET +; +;STRING_WIDTH: +; CLR R0 +;STRING_WIDTH_LOOP: +; PUSH B +; PUSH R0 +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; POP ZH +; POP ZL +; POP A +; ADD R0,A +; POP B +; DEC B +; BRNE STRING_WIDTH_LOOP +; RET +; +;HELLO_MESSAGE: .DB 'H','E','L','L','O',0 + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +SET_TIME: + LDI A,0 + OUT TCCR2,A ; STOP COUNTING WHILE SETTING CLOCK + STS TIME_HSEC_64K,A + STS TIME_HSEC_256,A + STS TIME_HSEC,A + RCALL RX_WAIT + STS TIME_HOUR,A + RCALL RX_WAIT + STS TIME_MINUTE,A + RCALL RX_WAIT + STS TIME_SECOND,A + RCALL RX_WAIT + STS DATE_MONTH,A + RCALL RX_WAIT + STS DATE_DAY,A + RCALL RX_WAIT + STS DATE_YEAR,A + LDI A,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;** LDI A,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,A + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE +;L01A3: + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: CLR CURSORX + RJMP MAIN_LOOP + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRCC DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRCC DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + RCALL FIND_CHAR ; SET UP CHAR_PTR FROM A = CHAR + RCALL CHAR_WIDTH ; SET UP R0 = PROP WIDTH FROM CHAR PTR + + CLR F + STS TEMP,F ; NUDGE FOR FIXED SPACING MODE + + SBRC FLAGS,4 + RJMP PROP_MODE ; FORCED TO FIXED SPACING MODE? + + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS ; GET R0 = CELL WIDTH FOR CHARACTER SET + PUSH R0 + SUB R0,W + BRCC NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + POP R0 ; RESTORE R0 = FIXED CELL WIDTH + +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE ; FORCED TO GRAPHICS MODE? + + MOV F,CURSORX + ADD F,R0 ; CHECK IF CHAR WILL FIT ON THIS LINE + BRCC OK_LINE + + CLR CURSORX + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 + RCALL SELECT_PAGE ; IN CASE WE SCROLLED THE DISPLAY + +OK_LINE: + LDS F,TEMP + ADD F,CURSORX + STS CHAR_X,F + STS CHAR_Y,CURSORY ; SET UP TOP LEFT COORDINATES + + ADD CURSORX,R0 ; ADVANCE CURSOR + +DRAW_CHAR: + LDS XPIXEL,CHAR_X + LDS LINE_CNT,CHAR_Y + + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE ; Y OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 + +Y_OFFSET_DONE: + SBRS X_SIZE,7 + RJMP X_OFFSET_DONE ; X OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$03 + RCALL LPMS + ADD XPIXEL,R0 + +X_OFFSET_DONE: + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + ADIW YL,$01 + RCALL LPMS ; GET R0 = Y LINES FOR CHARACTER + MOV Y_SIZE,R0 + + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +FIND_CHAR: + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_PAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + STS CHAR_PTR,YL + STS CHAR_PTR+1,YH + RET + +CHAR_WIDTH: + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + RCALL LPMS + MOV X_SIZE,R0 + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP LPMS ; PROPORTIONAL WIDTH IS PRESENT + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RJMP LPMS ; NO PROPORTIONAL WIDTH, USE CELL WIDTH + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + ; LET'S BE SAFE + ANDI A,$7F + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +GO_SELECT_PAGE: + RJMP SELECT_PAGE + +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +GO_EXT_INT0: + RJMP EXT_INT0 + +GO_EXT_INT1: + RJMP EXT_INT1 + +GO_TIM2_OVF: + RJMP TIM2_OVF + +GO_T1_OVERFLOW: + RJMP T1_OVERFLOW + +GO_T0_OVERFLOW: + RJMP T0_OVERFLOW + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +; ----------------------------------------------------------------------------- + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +; ----------------------------------------------------------------------------- + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR CURSORX ; HOME CURSOR + CLR CURSORY + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE +CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE CLEAR_DISPLAY_LOOP + RET + +; ----------------------------------------------------------------------------- + +EXT_INT0: +;**: +RETI +;** IN SR,SREG ; MEASURE VCC +;** SBI DDRD,2 +;** IN C,TCNT1L +;** IN D,TCNT1H +;** STS VCCH,D +;** STS VCCL,C +;** RJMP EXT_INT_RET + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP EXT_INT_RET + +T1_OVERFLOW: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + ; REDUNDANT, NOW DONE IN TIMER 2 OVERFLOW HANDLER + ;WDR + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDI D,$70 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, TOGGLE OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + LDS C,CLOCKING_PTR + TST C ; START OF 4 LINE BLOCK? (1 BASED) + BRNE BREAK_CONT ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK_CONT ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION +GO_SLEEP_ENTRY: + RJMP SLEEP_ENTRY +BREAK_CONT: + +;** SBI DDRD,2 ; PRECHARGE VCC AND +;** SBI PORTD,2 + SBI DDRD,3 ; TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D ; STOP TIMER1 + OUT TCNT1H,D ; AND CLEAR COUNT + OUT TCNT1L,D +;!! CBI PORTD,5 ; DROP CL2 + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + LDS D,LATCH10_SAV + OUT PORTA,D + SBI PORTB,4 + SBI PORTA,5 ; PULSE CL1 + CBI PORTA,5 + CBI PORTB,4 + RJMP L04F9 + +L04E6: LDS D,LATCH10_SAV + ORI D,$80 ; RAISE FLM + ORI D,$20 ; RAISE CL1 + OUT PORTA,D + + SBI PORTB,4 + LDI C,$60 ; TOGGLE M AND CL1 + EOR D,C + OUT PORTA,D + ANDI D,$7F ; DROP FLM + OUT PORTA,D + CBI PORTB,4 + STS LATCH10_SAV,D + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D +;**: + LDI D,1 ; TO CLOCK AT 5.5/2 MHZ + OUT OCR1AL,D + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + +;**: + LDI D,$7A ; WAIT FOR 32uSEC +;!! LDI D,$80 ; WAIT FOR 32uSEC +;** LDI D,$39 ; WAIT FOR 16uSEC +L050E: DEC D + BRNE L050E + +;!! LDI D,$01 +;!! OUT TCCR1B,D ; KILL CLR ON COMPARE MATCH +;!! SBI PORTD,5 ; SET CL2 HI (FOR REV E DOES NOTHING) + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP +;!!: + LDI D,$01 ; KILL CLR ON COMPARE MATCH + OUT TCCR1B,D ; WITH OC1A LEFT IN HIGH STATE + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0535 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + +L0535: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + +;** LDS C,VCCL +;** LDS D,VCCH +;** LDI E,LOW(VCC_NOMINAL) +;** SUB C,E +;** LDI E,HIGH(VCC_NOMINAL) +;** SBC D,E + +;** ROR D +;** ROR C ; ALL CORRECTION VALUES, SLOPE=0.5 +;** PUSH D +;** PUSH C +;** ASR D +;** ROR C ; ALL CORRECTION VALUES, SLOPE=0.25 +;** POP E +;** ADD C,E +;** POP E +;** ADC C,D ; ALL CORRECTION VALUES, SLOPE=0.75 + +;**: + LDS C,VEEL + LDS D,VEEH +;** LDS E,VEEL +;** ADD C,E +;** LDS E,VEEH +;** ADC D,E + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_DELAY_0 ; 54uSEC + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + +;** CBI DDRD,2 ; START VCC AND +;** CBI PORTD,2 + CBI DDRD,3 ; TEMPERATURE MEASUREMENT + CBI PORTD,3 +;!!: + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + + RJMP T1_OVERFLOW_RET + +T0_OVERFLOW: + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + PUSH ZH + PUSH ZL + PUSH R0 + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_STATE + INC D + STS SCAN_STATE,D + DEC D + BREQ SCAN_START ; IF SCAN_STATE WAS = 0 + DEC D + BREQ SCAN_BEEPER ; IF SCAN_STATE WAS = 1 + ; IMPLEMENT ENTRY POINT FOR SCAN_PULSE_LED HERE + DEC D + RJEQ SCAN_PHOTO ; IF SCAN_STATE WAS = 2 + +T0_OVERFLOW_RET: + POP R0 + POP ZL + POP ZH + +T1_OVERFLOW_RET: + POP D ; RESTORE STATE OF THE WORLD + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +EXT_INT_RET: + OUT SREG,SR + RETI + +SCAN_START: + LDI D,3 ;5 + OUT TCCR0,D ; PRESCALE=CK/1024 + LDI D,-TK_DELAY_1 ;TK_DELAY_2 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + RJMP L0617_RESET + +SCAN_BEEPER: + LDS D,BUZZ_TIME + TST D + BREQ SCAN_PULSE_LED + LDS D,BUZZ_PERIOD + SUBI D,$10 + BRLO BUZZ_TOGGLE + STS BUZZ_PERIOD,D + RJMP SCAN_PULSE_LED +BUZZ_TOGGLE: ; ASSUME D = $F0 + PERIOD-1 + MOV C,D ; EG. C = $F3 FOR PERIOD = 4 + SWAP C ; EG. C = $3F FOR PERIOD = 4 + AND D,C ; EG. D = $33 FOR PERIOD = 4 + STS BUZZ_PERIOD,D + LDS C,LATCH12_SAV + SBRS C,3 ; TEST PREVIOUS SPEAKER STATE + RJMP BEEPER_SPKHI + LDS D,BUZZ_TIME + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP SCAN_PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP SCAN_PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +SCAN_PULSE_LED: + LDS D,LATCH5_SAV +;**: + SBRS D,7 ; ARE WE INSIDE SLEEP_LOOP? +;** SBRC D,7 + RJMP SCAN_PULSE_LED_OK ; YES, KEEP TIMER 0 TO RETAIN CONTROL + + LDI D,1<<7 + EOR FLAGS,D + BRPL SCAN_PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP T0_OVERFLOW_RET ; AND WASTE EVERY REMAINING CYCLE + +SCAN_PULSE_LED_OK: + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + + LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM ; R0 = LED DRIVE VALUE + LDI D,13*4 + CP SCAN,D + BRSH L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + RJMP T0_OVERFLOW_RET + +SCAN_PHOTO: + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + CLC + SBRC D,6 + RJMP L0593 ; ROW/COLUMN IS INACTIVE + + ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF + IN C,SREG + + LDI D,13*4 + CP SCAN,D + BRSH L05A8 + + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS ZL,ROW_BITMAP + LDS ZH,ROW_BITMAP+1 + ROL ZL + ROL ZH + STS ROW_BITMAP,ZL + STS ROW_BITMAP+1,ZH + RJMP L05F9 + +L05A8: ; WE HAVE A COLUMN STATUS +; LDS D,LATCH5_SAV +;;**: +; SBRS D,7 ; TURNED OFF? +;;** SBRC D,7 +; RJMP L05F9 ; YES, NO FURTHER PROCESSING + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRCS L05AB + RJMP L05F9 + +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 + +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS ZH,ROW_BITMAP+1 + LDS ZL,ROW_BITMAP + + LDS D,ROW_INDEX + TST D + BREQ ROW_BITMAP_LOOP + + MOV C,D +ROW_BITMAP_SKIP: + ROR ZH + ROR ZL + SUBI C,4 + BRNE ROW_BITMAP_SKIP + +ROW_BITMAP_LOOP: + SUBI D,-4 + ROR ZH + ROR ZL + BRCS FOUND_INTERSECTION +ROW_BITMAP_LOOPE: + CPI D,13*4 + BRLO ROW_BITMAP_LOOP + + ; NO FURTHER INTERSECTING ROWS FOUND + RJMP L05F9 + +FOUND_INTERSECTION: + ; FOUND AN INTERSECTING ROW FOR COLUMN + STS ROW_INDEX,D + + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + TST R0 + BRNE VALID_INTERSECTION + + ; INTERSECTION IS NULL, GO ON TO NEXT + LDS D,ROW_INDEX + CPI D,13*4 + BRSH L05F9 ; DONE LAST ROW, GO ON TO NEXT COLUMN +GO_L0617: + RJMP L0617 ; GO ON TO NEXT ROW, SAME COLUMN + +VALID_INTERSECTION: + ; INTERSECTION IS VALID, WE HAVE KEY MAKE + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,$40 ;$10 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + + MOV D,TX_COUNT + CPI D,TX_SIZE-1 + BRSH L05F9 + + PUSH A + MOV A,R0 + RCALL TX_CHAR + CPI A,$1B + BRNE TX_CONT + RCALL TX_CHAR +TX_CONT: + POP A + +L05F9: ; SCAN TO NEXT LED / PHOTODIODE PAIR + LDI D,4 + ADD SCAN,D + + LDS D,LATCH5_SAV +;**: + SBRC D,7 +;** SBRS D,7 + RJMP TURNED_ON + + LDI D,3 + OUT TCCR0,D ; PRESCALE=CK/64 + LDI D,-TK_DELAY_1 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI C,13*4 + CP SCAN,C + BRLO GO_L0617 + + ; KEEP VDD ON, TO AVOID THE LONG TK_DELAY_2 + ;LDS D,LATCH5_SAV + ;ANDI D,$BF ; BIT 6 = 0 VDD OFF + ;STS LATCH5_SAV,D + ;PHOTO D ; READY TO SLEEP FOR ANOTHER 0.25 SEC + + LDI D,0 + OUT TCCR0,D ; STOP TIMER SINCE COMPLETE SCAN DONE + ;RJMP T0_OVERFLOW_RET + + ;LDI D,$05 + ;OUT UBRR,D + ;LDI D,$18 + ;OUT UCR,D + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + ;OUT UDR,C + ;OUT UDR,D + OR C,D ; HAVE WE SOME ACTIVITY? + + LDS D,TURNON_COUNT + CPI D,4 + BRSH TURNON_BREAK ; WAITING FOR BREAK + CPI D,1 + BRSH TURNON_MAKE ; WAITING FOR MAKE +GO_T0_OVERFLOW_RET: + RJMP T0_OVERFLOW_RET ; ALREADY HAD MAKE, NOT TURNED ON YET + +TURNON_BREAK: + TST C ; HAD SOME ACTIVITY? + BREQ TURNON_SAVE ; NO, COUNT DOWN TO BREAK + LDI D,4+1 ; YES, RESTART COUNTDOWN TO BREAK + RJMP TURNON_SAVE +TURNON_MAKE: + TST C ; HAD SOME ACTIVITY? + BRNE TURNON_SAVE ; YES, COUNT DOWN TO MAKE + LDI D,3+1 ; NO, RESTART COUNTDOWN TO MAKE +TURNON_SAVE: + DEC D ; COUNT DOWN TO MAKE OR BREAK + STS TURNON_COUNT,D + BRNE GO_T0_OVERFLOW_RET ; NOT READY TO TRY TURNON YET + + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + CBI DDRD,2 ; D2 = TRI-STATE, VSWT ON + RJMP GO_SLEEP_ENTRY ; WE WILL NOW WAIT FOR TURNON COMMAND + +TURNED_ON: + LDI D,0 ; STOP TIMER, WE WILL REGAIN + OUT TCCR0,D ; CONTROL VIA NEXT CLOCKING INTERRUPT + STS ROW_INDEX,D + + LDI C,50*4 + CP SCAN,C + BRLO L0617 + + ; COMPLETED ENTIRE SCAN, START NEW SCAN + LDS D,DEBOUNCE + TST D + BREQ L0617_RESET + DEC D + STS DEBOUNCE,D + BRNE L0617_RESET + + LDS D,ACTIVE_ZONE + TST D + BREQ L0617_RESET + + MOV D,TX_COUNT + CPI D,TX_SIZE + BRSH L0617_RESET + + PUSH A + LDI A,0 + RCALL TX_CHAR + POP A + +L0617_RESET: + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + LDIZ SCAN_TBL + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$80 ; BIT 7 = PRESERVED, LCD ON/OFF STATUS + ORI D,$40 ; BIT 6 = 1 VDD ON + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + RJMP T0_OVERFLOW_RET + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP CLEAR_DISPLAY_LOOP + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_PAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_PAGE: + A14_A18 A + RET + +; HOW MANY SECS/6553600 PER 4HZ INTERRUPT ? +; EACH TIME THROUGH ADD 1638400 SECS/6553600 = 1/4 SEC +; OSCILLATOR IS SLOW SO WE WILL ADD 1 PART IN 10000 +; HENCE EACH TIME THROUGH ADD 1638400+164 = 1638564 UNITS TO COUNT + +TIM2_OVF: + IN SR,SREG + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +;!! LDI A,$10 ; DIAGNOSTIC +;!! STS BUZZ_TIME,A ; SHORT BEEP + + LDS D,TIME_HSEC_64K + SUBI D,LOW(-1638564) + STS TIME_HSEC_64K,D + + LDS D,TIME_HSEC_256 + SBCI D,HIGH(-1638564) + STS TIME_HSEC_256,D + + LDS D,TIME_HSEC + SBCI D,HIGH(-1638564>>8) + CPI D,100 + BRSH TIM2_CARRY + STS TIME_HSEC,D + +TIM2_END: + OUT SREG,SR + SBRS FLAGS,6 ; IF WE TURNED OFF VIA COMMAND, + RETI ; START A NEW SCAN, OTHERWISE DONE + + LDI D,0 + STS SCAN_STATE,D ; WE WILL EXECUTE SCAN_START ROUTINE + RJMP T0_OVERFLOW ; GO AND TURN VDD ON + +GO_TX_CHAR: + RJMP TX_CHAR + +TIM2_CARRY: + LDI D,0 + STS TIME_HSEC,D + + LDS D,TIME_SECOND + INC D + CPI D,60 + BRLO TIM2_SECOND + + LDS D,TIME_MINUTE + INC D + CPI D,60 + BRLO TIM2_MINUTE + + LDS D,TIME_HOUR + INC D + CPI D,24 + BRLO TIM2_HOUR + + PUSH ZL + PUSH ZH + PUSH R0 + LDI ZL,LOW(MONTH_TABLE*2-1) + LDI ZH,HIGH(MONTH_TABLE*2-1) + LDS E,DATE_MONTH + ADD ZL,E + LDI E,0 + ADC ZH,E + LPM + MOV E,R0 + CPI E,28 + BRNE FEBRUARY_OK + LDS E,DATE_YEAR + ANDI E,3 + LDI E,28 + BRNE FEBRUARY_OK + LDI E,29 +FEBRUARY_OK: + POP R0 + POP ZH + POP ZL + + LDS D,DATE_DAY + CP D,E + BRLO TIM2_DAY + + LDS D,DATE_MONTH + CPI D,12 + BRLO TIM2_MONTH + + LDS D,DATE_YEAR + INC D + STS DATE_YEAR,D + CLR D +TIM2_MONTH: + INC D + STS DATE_MONTH,D + CLR D +TIM2_DAY: + INC D + STS DATE_DAY,D + CLR D +TIM2_HOUR: + STS TIME_HOUR,D + CLR D +TIM2_MINUTE: + STS TIME_MINUTE,D + CLR D +TIM2_SECOND: + STS TIME_SECOND,D + +TIM2_SEND: + MOV D,TX_COUNT + CPI D,TX_SIZE-7 + BRSH TIM2_SEND_SKIP + + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'T' + RCALL TX_CHAR +; LDS A,VCCL +; RCALL TX_CHAR +; LDS A,VCCH +; RCALL TX_CHAR +; LDS A,VEEL +; RCALL TX_CHAR +; LDS A,VEEH +; RCALL TX_CHAR +; LDI A,$0D +; RCALL TX_CHAR + LDS A,TIME_HOUR + RCALL GO_TX_CHAR + LDS A,TIME_MINUTE + RCALL GO_TX_CHAR + LDS A,TIME_SECOND + RCALL GO_TX_CHAR + LDS A,DATE_MONTH + RCALL GO_TX_CHAR + LDS A,DATE_DAY + RCALL GO_TX_CHAR + LDS A,DATE_YEAR + RCALL GO_TX_CHAR + POP A + +TIM2_SEND_SKIP: + RJMP TIM2_END + +; ----------------------------------------------------------------------------- + +MONTH_TABLE: + .DB 31,28,31,30,31,30,31,31,30,31,30,31 + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 + .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 + .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 + .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 + .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 + .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 + .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 + .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 + .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 + .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 + .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 + .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 + .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 + .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 + .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 + .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 + .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 + .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 + .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 + .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 + .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 + .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 + .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 + .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 + .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 + .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 + .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 + .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 + .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 + .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 + .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 + .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 + .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 + .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 + .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 + .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 + .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 + .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 + .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 + .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 + .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 + .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 + .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 + .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 + .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 + .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 + .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 + .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 + .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 + .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 + .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 + .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 + .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 + .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 + .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 + .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 + .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 + .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 + .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 + .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 + .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 + .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 + .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 + .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 + .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 + .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 + .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 + .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 + .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 + .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 + .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A + .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +CHSET00_END: + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/tsv3-tsv4.diff b/src/avr/tsv3-tsv4.diff new file mode 100644 index 00000000..b0c020ac --- /dev/null +++ b/src/avr/tsv3-tsv4.diff @@ -0,0 +1,666 @@ +--- tsv3.asm 2003-03-18 12:26:48.000000000 +1100 ++++ tsv4.asm 2003-03-20 16:55:02.000000000 +1100 +@@ -1,4 +1,4 @@ +-; TSV3.ASM ++; TSV4.ASM + + ; 19FEB02 REVISE FOR GREATER CONTRAST VOLTAGE FOR ALBERT'S 2ND BATCH -15V + ; 01FEB02 REVISE FOR 7.3728MHz XTAL (SEE !!!) +@@ -17,8 +17,8 @@ + .LISTMAC + .MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) +- STS PAGE,YH +- RCALL ADRYP ; AND SET PAGE ++ STS XPAGE,YH ++ RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) + .ENDMACRO +@@ -289,12 +289,13 @@ + + .EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS + .EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +-.EQU API_RATE_SLOW =$5F ;$8F ; DIVISOR FOR 4800 BPS +-.EQU API_RATE_FAST =$03 ;$05 ; DIVISOR FOR 115200 BPS ++.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS ++.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS + .EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM + .EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD + .EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + ++.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE + .DEF SR =R1 + .DEF RX_PTR =R2 + .DEF RX_COUNT =R3 +@@ -332,6 +333,14 @@ + .DEF CURSORX =R23 + .DEF CURSORY =R24 + ++; for AVRA / TAVRASM: ++;.def XL =R26 ++;.def XH =R27 ++;.def YL =R28 ++;.def YH =R29 ++;.def ZL =R30 ++;.def ZH =R31 ++ + .DSEG + .ORG RAM + +@@ -364,7 +373,7 @@ + LATCH10_SAV: .BYTE 1 + LATCH11_SAV: .BYTE 1 + LATCH12_SAV: .BYTE 1 +-PAGE: .BYTE 1 ++XPAGE: .BYTE 1 + ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + + LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +@@ -535,9 +544,15 @@ + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +-RTNCDE: LDIZ RTN_CODE ; POINT Z TO FLASH +- LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER +- LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET PAGE ++RTNCDE: ;LDIZ RTN_CODE ; POINT Z TO FLASH ++ LDI ZL,LOW((RTN_CODE)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++ ;LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER ++ LDI XL,LOW((RTN_CODE_END-RTN_CODE)*2) ; USE AS BYTE COUNTER ++ LDI XH,HIGH((RTN_CODE_END-RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++ LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE + CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM + CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH +@@ -598,9 +613,15 @@ + BREQ CHARACTER_SET_INIT_DONE + + CHARACTER_SET_INIT: +- LDIZ CHSET00 ; POINT Z TO FLASH +- LDIX CHSET00_END-CHSET00 ; BYTE COUNTER +- LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET PAGE ++ ;LDIZ CHSET00 ; POINT Z TO FLASH ++ LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++ ;LDIX CHSET00_END-CHSET00 ; BYTE COUNTER ++ LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER ++ LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ ++ LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE + CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM + CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH +@@ -628,7 +649,7 @@ + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL GO_SELECT_PAGE ++ RCALL GO_SELECT_XPAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +@@ -672,11 +693,11 @@ + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + +- LDI B,EE_CONTRAST*2 ++ LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A +- LDI B,EE_CONTRAST*2+1 ++ LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + +@@ -802,7 +823,7 @@ + + ; ----------------------------------------------------------------------------- + +-ADRYP: LDS YH,PAGE ; SET PAGE ADDRESS FOR DSPRAM ++ADRYP: LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL +@@ -816,10 +837,10 @@ + ; CLR YL + ; INC YH + ; BRNE INCRET +-; LDS YH,PAGE ++; LDS YH,XPAGE + ; INC YH + ; ANDI YH,$1F +-; STS PAGE,YH ++; STS XPAGE,YH + ; CLR YH + ;INCRET: RET + +@@ -972,14 +993,22 @@ + RJEQ BUZZ_AT_FREQ + CPI A,'C' + RJEQ CLEAR_RECTANGLE ++ CPI A,'c' ++ RJEQ GET_CLEAR_FRAME_RECT_SIZE + CPI A,'D' + RJEQ DRAW_MODE + CPI A,'E' + RJEQ ENABLE_CNTRL + CPI A,'F' + RJEQ GET_FILLED_RECTNC_SIZE ++ CPI A,'f' ++ RJEQ GET_FRAME_RECT_SIZE + CPI A,'G' + RJEQ INTERPRET_MODE ++ CPI A,'H' ++ RJEQ GET_HALFTONE_RECT_SIZE ++ CPI A,'h' ++ RJEQ GET_CLEAR_HALFTONE_RECT_SIZE + CPI A,'K' + RJEQ CLR_DISP + CPI A,'L' +@@ -1292,10 +1321,10 @@ + STS CONTRASTL,A + STS CONTRASTH,B + +- LDI B,EE_CONTRAST*2 ++ LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH +- LDI B,EE_CONTRAST*2+1 ++ LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + + CONTRAST_DONE: +@@ -1706,7 +1735,7 @@ + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 +- RCALL SELECT_PAGE ; IN CASE WE SCROLLED THE DISPLAY ++ RCALL SELECT_XPAGE ; IN CASE WE SCROLLED THE DISPLAY + + OK_LINE: + LDS F,TEMP +@@ -1783,7 +1812,7 @@ + + MORE_X: ADIW YL,$01 + LDS A,PTR+2 +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RCALL LPMS + + CLR A +@@ -1833,7 +1862,7 @@ + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 +@@ -1909,7 +1938,7 @@ + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG +@@ -2043,8 +2072,8 @@ + GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +-GO_SELECT_PAGE: +- RJMP SELECT_PAGE ++GO_SELECT_XPAGE: ++ RJMP SELECT_XPAGE + + GO_SCROLL_REGION: + RJMP SCROLL_REGION +@@ -2083,7 +2112,7 @@ + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + RJMP L03A3 + L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) +@@ -2305,7 +2334,7 @@ + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +@@ -2376,7 +2405,11 @@ + OUT OCR1BL,C + + LDS C,CLOCKING_PTR +- TST C ; START OF 4 LINE BLOCK? (1 BASED) ++; TST C ; START OF 4 LINE BLOCK? (1 BASED) ++ lds d,CLOCKING_PTR+1 ++ andi d,1 ++ or c,d ; checks for start of an 8 line block ++; rjmp BREAK0 ; temporary (prevents switching off via power switch) + BRNE BREAK0 ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT +@@ -2689,7 +2722,10 @@ + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + +- LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL ++ ;LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL ++ LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ + CLR D + ADD ZL,SCAN + ADC ZH,D +@@ -2789,7 +2825,10 @@ + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + +- LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL ++ ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL ++ LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ + CLR D + ADD ZL,C + ADC ZH,D +@@ -2801,7 +2840,11 @@ + ADD C,R0 + LSL R0 + ADD C,R0 +- LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL ++ ++ ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL ++ LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ + CLR D + ADD ZL,SCAN + ADC ZH,D +@@ -2951,7 +2994,10 @@ + STS ROW_BITMAP+1,SCAN + + L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE +- LDIZ SCAN_TBL ++ ;LDIZ SCAN_TBL ++ LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION ++ LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION ++ + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN +@@ -2973,7 +3019,7 @@ + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) +@@ -3025,7 +3071,7 @@ + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) +- RCALL SELECT_PAGE ++ RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 +@@ -3226,7 +3272,7 @@ + RAMWR A + RET + +-SELECT_PAGE: ++SELECT_XPAGE: + A14_A18 A + RET + +@@ -3423,106 +3469,237 @@ + ; ----------------------------------------------------------------------------- + + CHSET00: +- .DB $34,$32,$43,$46,$30,$30,$31,$30,$31,$31,$31,$37,$35,$36,$30,$37 +- .DB $6B,$05,$75,$05,$77,$05,$39,$04,$79,$05,$7B,$05,$7D,$05,$7F,$05 +- .DB $81,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$83,$05,$85,$05,$0A,$02,$15,$02 +- .DB $17,$02,$1F,$02,$29,$02,$2E,$02,$37,$02,$40,$02,$49,$02,$53,$02 +- .DB $59,$02,$63,$02,$6C,$02,$74,$02,$7E,$02,$85,$02,$8A,$02,$8E,$02 +- .DB $96,$02,$9F,$02,$A8,$02,$B1,$02,$BA,$02,$C3,$02,$CC,$02,$D5,$02 +- .DB $DE,$02,$E7,$02,$F1,$02,$FA,$02,$04,$03,$0D,$03,$15,$03,$1E,$03 +- .DB $27,$03,$30,$03,$39,$03,$42,$03,$4B,$03,$54,$03,$5D,$03,$66,$03 +- .DB $6F,$03,$79,$03,$82,$03,$8B,$03,$94,$03,$9D,$03,$A6,$03,$AF,$03 +- .DB $B8,$03,$C1,$03,$CA,$03,$D3,$03,$DC,$03,$E5,$03,$EE,$03,$F7,$03 +- .DB $00,$04,$09,$04,$12,$04,$1C,$04,$25,$04,$2E,$04,$37,$04,$3E,$04 +- .DB $41,$04,$46,$04,$4F,$04,$58,$04,$61,$04,$6A,$04,$73,$04,$7C,$04 +- .DB $86,$04,$90,$04,$9A,$04,$A5,$04,$AF,$04,$B8,$04,$C1,$04,$CA,$04 +- .DB $D3,$04,$DD,$04,$E9,$04,$F0,$04,$F9,$04,$02,$05,$0B,$05,$14,$05 +- .DB $1D,$05,$26,$05,$30,$05,$3A,$05,$44,$05,$4E,$05,$59,$05,$5D,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $66,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05,$6B,$05 +- .DB $06,$08,$01,$01,$4F,$00,$00,$06,$FF,$06,$61,$09,$20,$70,$A8,$A0 +- .DB $70,$28,$A8,$70,$20,$01,$07,$00,$20,$70,$80,$80,$70,$20,$02,$21 +- .DB $07,$80,$80,$80,$80,$00,$00,$80,$04,$21,$03,$A0,$A0,$A0,$01,$07 +- .DB $50,$50,$F8,$50,$F8,$50,$50,$01,$07,$20,$78,$A0,$70,$28,$F0,$20 +- .DB $01,$07,$C0,$C8,$10,$20,$40,$98,$18,$01,$07,$60,$90,$A0,$40,$A8 +- .DB $90,$68,$03,$21,$03,$C0,$40,$80,$04,$21,$07,$20,$40,$80,$80,$80 +- .DB $40,$20,$04,$21,$07,$80,$40,$20,$20,$20,$40,$80,$01,$06,$00,$20 +- .DB $A8,$70,$A8,$20,$01,$06,$00,$20,$20,$F8,$20,$20,$05,$03,$61,$03 +- .DB $C0,$40,$80,$03,$06,$61,$01,$F8,$05,$03,$61,$02,$C0,$C0,$01,$06 +- .DB $00,$08,$10,$20,$40,$80,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01 +- .DB $07,$20,$60,$20,$20,$20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40 +- .DB $F8,$01,$07,$F8,$10,$20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90 +- .DB $F8,$10,$10,$01,$07,$F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40 +- .DB $80,$F0,$88,$88,$70,$01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07 +- .DB $70,$88,$88,$70,$88,$88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60 +- .DB $03,$21,$06,$00,$C0,$C0,$00,$C0,$C0,$03,$21,$07,$00,$C0,$C0,$00 +- .DB $C0,$40,$80,$05,$21,$07,$10,$20,$40,$80,$40,$20,$10,$01,$05,$00 +- .DB $00,$F8,$00,$F8,$05,$21,$07,$80,$40,$20,$10,$20,$40,$80,$01,$07 +- .DB $70,$88,$08,$10,$20,$00,$20,$01,$07,$70,$88,$B8,$A8,$B8,$80,$70 +- .DB $01,$07,$70,$88,$88,$88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88 +- .DB $88,$F0,$01,$07,$70,$88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88 +- .DB $88,$88,$90,$E0,$01,$07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8 +- .DB $80,$80,$F0,$80,$80,$80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01 +- .DB $07,$88,$88,$88,$F8,$88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80 +- .DB $80,$80,$01,$07,$08,$08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0 +- .DB $C0,$A0,$90,$88,$01,$07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88 +- .DB $D8,$A8,$A8,$88,$88,$88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01 +- .DB $07,$70,$88,$88,$88,$88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80 +- .DB $80,$01,$07,$70,$88,$88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0 +- .DB $A0,$90,$88,$01,$07,$70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20 +- .DB $20,$20,$20,$20,$20,$01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07 +- .DB $88,$88,$88,$88,$88,$50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50 +- .DB $01,$07,$88,$88,$50,$20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20 +- .DB $20,$20,$01,$07,$F8,$08,$10,$20,$40,$80,$F8,$04,$21,$07,$E0,$80 +- .DB $80,$80,$80,$80,$E0,$01,$06,$00,$80,$40,$20,$10,$08,$04,$21,$07 +- .DB $E0,$20,$20,$20,$20,$20,$E0,$01,$03,$20,$50,$88,$06,$06,$61,$01 +- .DB $F8,$01,$03,$30,$20,$10,$01,$07,$00,$00,$70,$08,$78,$88,$78,$01 +- .DB $07,$80,$80,$F0,$88,$88,$88,$F0,$01,$07,$00,$00,$78,$80,$80,$80 +- .DB $78,$01,$07,$08,$08,$78,$88,$88,$88,$78,$01,$07,$00,$00,$70,$88 +- .DB $F8,$80,$70,$01,$07,$18,$20,$F8,$20,$20,$20,$20,$01,$08,$00,$00 +- .DB $78,$88,$88,$78,$08,$70,$01,$07,$80,$80,$B0,$C8,$88,$88,$88,$02 +- .DB $21,$07,$80,$00,$80,$80,$80,$80,$80,$05,$21,$08,$10,$00,$10,$10 +- .DB $10,$10,$90,$60,$05,$21,$07,$80,$80,$90,$A0,$C0,$A0,$90,$03,$21 +- .DB $07,$C0,$40,$40,$40,$40,$40,$40,$01,$07,$00,$00,$F0,$A8,$A8,$A8 +- .DB $A8,$01,$07,$00,$00,$B0,$C8,$88,$88,$88,$01,$07,$00,$00,$70,$88 +- .DB $88,$88,$70,$01,$08,$00,$00,$F0,$88,$88,$F0,$80,$80,$01,$08,$00 +- .DB $00,$78,$88,$88,$78,$08,$08,$02,$05,$61,$05,$B0,$C0,$80,$80,$80 +- .DB $01,$07,$00,$00,$78,$80,$70,$08,$F0,$01,$07,$20,$20,$F8,$20,$20 +- .DB $20,$18,$01,$07,$00,$00,$88,$88,$88,$98,$68,$01,$07,$00,$00,$88 +- .DB $88,$88,$50,$20,$01,$07,$00,$00,$88,$88,$A8,$A8,$50,$01,$07,$00 +- .DB $00,$88,$50,$20,$50,$88,$01,$08,$00,$00,$88,$88,$88,$78,$08,$70 +- .DB $01,$07,$00,$00,$F8,$10,$20,$40,$F8,$05,$21,$07,$30,$40,$40,$80 +- .DB $40,$40,$30,$02,$21,$07,$80,$80,$80,$00,$80,$80,$80,$05,$21,$07 +- .DB $C0,$20,$20,$10,$20,$20,$C0,$02,$07,$61,$02,$64,$98,$01,$07,$00 +- .DB $00,$20,$50,$88,$88,$F8,$01,$03,$E0,$A0,$E0,$01,$07,$F8,$F8,$F8 +- .DB $F8,$F8,$F8,$F8,$01,$20,$02,$20,$04,$20,$FC,$20,$FD,$20,$FE,$20 +- .DB $FF,$20,$0C,$20,$F4,$20,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A +- .DB $1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A,$1A ++.INCLUDE "CHSET00.INC" + CHSET00_END: + + ; ----------------------------------------------------------------------------- + ++GET_CLEAR_FRAME_RECT_SIZE: ++ STS RECTNC_X,CURSORX ++ STS RECTNC_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECTNC_XX,A ++ RCALL RX_WAIT ++ STS RECTNC_YY,A ++ RCALL CLEAR_FRAME_RECT ++ RJMP MAIN_LOOP ++ ++GET_FRAME_RECT_SIZE: ++ STS RECTNC_X,CURSORX ++ STS RECTNC_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECTNC_XX,A ++ RCALL RX_WAIT ++ STS RECTNC_YY,A ++ RCALL FRAME_RECT ++ RJMP MAIN_LOOP ++ ++GET_CLEAR_HALFTONE_RECT_SIZE: ++ STS RECT_X,CURSORX ++ STS RECT_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECT_XX,A ++ RCALL RX_WAIT ++ STS RECT_YY,A ++ RCALL CLEAR_HALFTONE_RECT ++ RJMP MAIN_LOOP ++ ++GET_HALFTONE_RECT_SIZE: ++ STS RECT_X,CURSORX ++ STS RECT_Y,CURSORY ++ RCALL RX_WAIT ++ STS RECT_XX,A ++ RCALL RX_WAIT ++ STS RECT_YY,A ++ RCALL HALFTONE_RECT ++ RJMP MAIN_LOOP ++ ++NO_GOX: RET ++ ++CLEAR_FRAME_RECT: ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ STS RECT_Y,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDS F,RECTNC_YY ++ STS RECT_YY,F ++ ++ LDI F,$02 ++ OR FLAGS,F ++ ++ RCALL DRAW_RECT ++ ++ LDI F,$FD ++ AND FLAGS,F ++ ++FRAME_RECT: ++ LDS F,RECTNC_XX ++ DEC F ++ CPI F,2 ++ BRLO NO_GOX ++ LDS F,RECTNC_YY ++ CPI F,3 ++ BRLO NO_GOX ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ STS RECT_Y,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDI F,$01 ++ STS RECT_YY,F ++ RCALL DRAW_RECT ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_Y ++ INC F ++ STS RECT_Y,F ++ LDS F,RECTNC_YY ++ SUBI F,2 ++ STS RECT_YY,F ++ LDI F,$01 ++ STS RECT_XX,F ++ RCALL DRAW_RECT ++ ++ LDS X_SIZE,RECTNC_XX ++ LDS F,RECTNC_X ++ ADD F,X_SIZE ++ DEC F ++ STS RECT_X,F ++ LDI F,$01 ++ STS RECT_XX,F ++ LDS F,RECTNC_Y ++ INC F ++ STS RECT_Y,F ++ LDS F,RECTNC_YY ++ SUBI F,2 ++ STS RECT_YY,F ++ RCALL DRAW_RECT ++ ++ LDS F,RECTNC_X ++ STS RECT_X,F ++ LDS F,RECTNC_XX ++ STS RECT_XX,F ++ LDS Y_SIZE,RECTNC_YY ++ LDS F,RECTNC_Y ++ ADD F,Y_SIZE ++ DEC F ++ STS RECT_Y,F ++ LDI F,$01 ++ STS RECT_YY,F ++ RJMP DRAW_RECT ++ ++CLEAR_HALFTONE_RECT: ++; LDS F,RECTNC_X ++; STS RECT_X,F ++; LDS F,RECTNC_Y ++; STS RECT_Y,F ++; LDS F,RECTNC_XX ++; STS RECT_XX,F ++; LDS F,RECTNC_YY ++; STS RECT_YY,F ++ ++ LDI F,$02 ++ OR FLAGS,F ++ ++ RCALL DRAW_RECT ++ ++ LDI F,$FD ++ AND FLAGS,F ++ ++HALFTONE_RECT: ++ SEI ++ LDS LINE_CNT,RECT_Y ++ LDS XPIXEL,RECT_X ++ RCALL CALCULATE_XBYTE ++ STS XPIXEL_SAV,XPIXEL ++ STS XBYTE_SAV,XBYTE ++ LDS Y_SIZE,RECT_YY ++ CLR YL ++ MOV YH,LINE_CNT ++ LDI A,$55 ++ SBRS YH,0 ++ LDI A,$AA ++ MOV PATTERN,A ++ LSR YH ++ ROR YL ++ LSR YH ++ ROR YL ++ SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER ++ LDI A,HIGH(DRAW_DSPRAM>>6) ++ RCALL SELECT_XPAGE ++ RJMP X03A3 ++X039A: SUBI YL,LOW(-$40) ++ SBCI YH,HIGH(-$40) ++ INC LINE_CNT ++ LDS XPIXEL,XPIXEL_SAV ++ LDS XBYTE,XBYTE_SAV ++X03A3: OR XBYTE,YL ++ LDI A,$FF ++ LDS X_SIZE,RECT_XX ++ LDI F,$00 ++ CP X_SIZE,F ++ BREQ X03B0 ++ LDI F,$08 ++ CP X_SIZE,F ++ BRLO X03C2 ++ TST XPIXEL ++ BREQ X03B0 ++X03AD: LSR A ++ DEC XPIXEL ++ BRNE X03AD ++X03B0: AND A,PATTERN ++ RCALL WR_DISP_MEM ++ LDI F,$08 ++ LDS A,XPIXEL_SAV ++ SUB F,A ++ SUB X_SIZE,F ++ INC XBYTE ++ LDI A,$FF ++X03B8: LDI F,$08 ++ CP X_SIZE,F ++ BRLO X03C2 ++ BREQ X03D2 ++ AND A,PATTERN ++ RCALL WR_DISP_MEM ++ LDI A,$FF ++ LDI F,$08 ++ SUB X_SIZE,F ++ INC XBYTE ++ RJMP X03B8 ++X03C2: TST X_SIZE ++ BREQ X03D3 ++X03C4: LSR A ++ DEC X_SIZE ++ BRNE X03C4 ++ COM A ++ TST XPIXEL ++ BREQ X03D2 ++ CLR B ++X03CB: LSR A ++ ROR B ++ DEC XPIXEL ++ BRNE X03CB ++ AND A,PATTERN ++ RCALL WR_DISP_MEM ++ INC XBYTE ++ MOV A,B ++X03D2: AND A,PATTERN ++ RCALL WR_DISP_MEM ++X03D3: COM PATTERN ++ RCALL NICK_SUB1 ++ DEC Y_SIZE ++ CLR F ++ CPSE Y_SIZE,F ++ RJMP X039A ++ RET ++ ++; ----------------------------------------------------------------------------- ++ + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND diff --git a/src/avr/tsv3.asm b/src/avr/tsv3.asm new file mode 100644 index 00000000..7a71ddb6 --- /dev/null +++ b/src/avr/tsv3.asm @@ -0,0 +1,3708 @@ +; TSV3.ASM + +; 19FEB02 REVISE FOR GREATER CONTRAST VOLTAGE FOR ALBERT'S 2ND BATCH -15V +; 01FEB02 REVISE FOR 7.3728MHz XTAL (SEE !!!) + +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS +; ;!! INDICATES CHANGES + +;** INDICATES CHANGES FOR LOW VCC AVR MOD + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APITS.INC" ; NOT API.INC BECAUSE APITS.INC ALSO HAS TURNON COMMAND +;.INCLUDE "TERTS.INC" ; NOT TER.INC BECAUSE FLAGS IN LOWER HALF OF REGISTER SET + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS XPAGE,YH + RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 +.ENDMACRO + +.MACRO A14_A18 + CLI + LDS R19,LATCH10_SAV ; AND THIS + EOR R19,@0 + ANDI R19,$E0 + EOR R19,@0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + SEI + STS LATCH10_SAV,R19 ; MUST BE ATOMIC DUE TO TOGGLING M +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@1 + + LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,1 + BST @1,6 ; A14 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + NOP + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO + OUT PORTA,@0 ; SELECT PHOTODIODE CHANNEL + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LED + OUT PORTA,@0 ; MAIN LED DRIVE PORT + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LEDLO + LDS D,LATCH12_SAV ; DRIVE LED COMMON LO + CBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO LEDHI + LDS D,LATCH12_SAV ; DRIVE LED COMMON HI + SBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKHI + LDS D,LATCH12_SAV ; DRIVE SPEAKER HI + SBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKLO + LDS D,LATCH12_SAV ; DRIVE SPEAKER LO + CBR D,1<<3 + SBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKOFF + LDS D,LATCH12_SAV ; DRIVE SPEAKER OFF + CBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.EQU T1_INIT =-818 ;$FB35 +.EQU T1_FULL_SCALE =-716 ;50.0HZ ; SETS LCD FRAME RATE TEMPORARY TO STOP FLIKER +;.EQU T1_FULL_SCALE =-651 ;53.5HZ ; SETS LCD FRAME RATE +;.EQU T1_FULL_SCALE =-600 ;54.8HZ ; SETS LCD FRAME RATE + +.EQU CONTRAST_LONG =-340 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +;.EQU CONTRAST_LONG =-250 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +.EQU CONTRAST_MID =-200 +.EQU CONTRAST_SHORT = -43 ; ALL SHORT PULSES IS FULLY LIGHT + +.EQU VCC_NOMINAL =-552 ;$FCC4 + +.EQU VEE_MIN =-710 ; MIN IS FULLY DARK +.EQU VEE_INIT =-340 +.EQU VEE_MAX = -43 ; MAX IS FULLY LIGHT + +; WHEN VCC = $FCC4 FOR 6.0V: +.EQU CONTRAST_MIN =-710 ; MIN IS FULLY DARK +.EQU CONTRAST_INIT =-640 +.EQU CONTRAST_MAX =-580 ; MAX IS FULLY LIGHT + +; GENEROUS LIMITS FOR EXPERIMENTATION: +;.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FE10 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =10 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$20 +.EQU RX_SIZE =$80 + +.EQU TK_LED_PULSE =14 ; 18US ?? CLOCKS OF /8 +.EQU TK_DELAY_0 =19 ; ??US DELAY TILL START OF LED PULSE (/8) +;.EQU TK_DELAY_0 =$20 ;$38 ; ??US DELAY TILL START OF LED PULSE +;.EQU TK_DELAY_0 =$25 ;$38 ; 54US ?? CLOCKS OF /8 +.EQU TK_DELAY_1 =$10 ;$28 ; CLOCKS OF /64, CHANNEL SELECT DELAY +.EQU TK_DELAY_2 =$00 ; CLOCKS OF /1024, VDD POWER ON DELAY + ; $D0 IS TOO SHORT, $E0 SEEMS TO WORK + +.EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$5F ;$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ;$05 ; DIVISOR FOR 115200 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 USED TO CONTROL LED PULSING FOR TOUCHSCREEN EVERY 2ND CYCLE +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +; for AVRA / TAVRASM: +;.def XL =R26 +;.def XH =R27 +;.def YL =R28 +;.def YH =R29 +;.def ZL =R30 +;.def ZH =R31 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +BUZZ_PERIOD: .BYTE 1 +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +XPAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +CHAR_X: .BYTE 1 +CHAR_Y: .BYTE 1 +CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC_64K: .BYTE 1 +TIME_HSEC_256: .BYTE 1 +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_STATE: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RJMP GO_TIM2_OVF ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_T1_OVERFLOW + RJMP GO_T0_OVERFLOW + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + LDI F,0 + STS TIME_HSEC_64K,F + STS TIME_HSEC_256,F + STS TIME_HSEC,F + STS TIME_SECOND,F + STS TIME_MINUTE,F + STS TIME_HOUR,F + LDI F,1 + STS DATE_DAY,F + STS DATE_MONTH,F + LDI F,20 + STS DATE_YEAR,F + +RESTART_ENTRY: +;**: + LDI F,8 ; TIMER 2 CLOCKED BY 32 KHZ +;** LDI F,0 ; TIMER 2 CLOCKED BY 11 MHZ + OUT ASSR,F +;**: + ; MUST MATCH SET_TIME ROUTINE % + LDI F,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;!! LDI F,$11 ; DIVIDE BY 2, TOGGLE OC2 (PIN 21) + ; (RTC DIAGNOSTIC) +;** LDI F,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,F + ; % + LDI F,$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + LDI F,$00 + OUT GIMSK,F + + LDI F,$B8 ; INIT_PORTS + OUT DDRD,F + OUT PORTD,F ; D2 = TRI-STATE, VSWT ON + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + OUT PORTC,F + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + + LDI D,$18 ; A18|A17|A16|A15|A14=11000 + OUT PORTA,D ; CL1=M=FLM=0 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BUZZ_TIME,D ; NOT BUZZING (SHORT BEEP COMES LATER) + + CLR SCAN + STS ROW_INDEX,SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + + LDI D,$F4 ; BIT 6 = 1 VDD ON, BIT 7 = 1 LCD ON + STS LATCH5_SAV,D + PHOTO D + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +RTNCDE: ;LDIZ RTN_CODE ; POINT Z TO FLASH + LDI ZL,LOW((RTN_CODE)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER + LDI XL,LOW((RTN_CODE_END-RTN_CODE)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((RTN_CODE_END-RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + CLR R0 ; TEMPORARY CLEAR KB + RAMWRX R0 ; WRITE DATA TO DSPRAM + DEC XL + BREQ RTNCDE_END ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CDE1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CDE0 +RTNCDE_END: + + ; INITIALISE DEFAULT CHARACTER SET + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + ;LDIZ CHSET00 ; POINT Z TO FLASH + LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + ; CLEAR REFRESH BUFFER TO AVOID A BRIEF FLICKER + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL GO_SELECT_XPAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +CLEAR_REFRESH: + PUSH B + PUSH YL + PUSH YH + + LDI B,32 + RCALL GO_CLEAR_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + ADIW YL,6 + LDI B,2 + RCALL GO_CLEAR_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP YH + POP YL + POP B + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE CLEAR_REFRESH + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,0 + STS BUZZ_PERIOD,A ; HIGHEST FREQUENCY + LDI A,54 ;$40 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + LDI A,0 + STS SCAN_STATE,A ; START ON FIRST LED / PHOTODIODE PAIR + + LDI A,0 + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + LDI F,$45 + OUT TIMSK,F ; TURN ON TIMER 0, 1, 2 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL HELLO_DISPLAY ; SHOW EXAMPLE DISPLAY + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + SBI PORTD,4 ; TURN TRANSISTOR OFF + CBI PORTD,5 ; DROP CL2 + + LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + LDI D,$74 ; BIT 6 = 1 VDD ON, BIT 7 = 0 LCD OFF + SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + LDI D,$34 ; BIT 6 = 0 VDD OFF, BIT 7 = 0 LCD OFF + STS LATCH5_SAV,D + PHOTO D + + LDI D,$41 + OUT TIMSK,D ; DISABLE TIMER 1 INTERRUPTS + + LDI D,0 + OUT TCCR0,D ; DISABLE TIMER 0 TEMPORARILY ONLY + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + + LDI F,4 + STS TURNON_COUNT,F ; .25 SEC TO BREAK, .75 SEC TO MAKE + + INIT_API_BUS ; RESET UART TO RECEIVE TURNON COMMAND + +SLEEP_LOOP: + CLI + IN F,TCCR0 + TST F + LDI F,$4A ; SE=1 SM1:SM0=00 FOR IDLE MODE + BRNE SLEEP_SETUP ; TIMER 0 RUNNING, STAY IN IDLE MODE + SBIS PIND,0 ; BREAK OFF, UART ACTIVE, STAY IN IDLE + LDI F,$7A ; SE=1 SM1:SM0=11 FOR POWER SAVE MODE +SLEEP_SETUP: + OUT MCUCR,F + SEI + SLEEP + + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDS F,TURNON_COUNT + TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;SBIS PIND,0 ; AND BREAK HAS DISAPPEARED, WAKE UP + BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP + + CLI + RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + +; ----------------------------------------------------------------------------- + +ADRYP: LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL + OUT PORTA,YH + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,XPAGE +; INC YH +; ANDI YH,$1F +; STS XPAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +;HELLO_DISPLAY: +; LDI A,0 +; STS RECTNC_X,A +; STS RECTNC_Y,A +; STS RECTNC_XX,A +; LDI A,$80 +; STS RECTNC_YY,A +; RCALL DRAW_RECTNC +; +; LDI A,16 +; STS CHAR_X,A +; STS CHAR_Y,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; RCALL STRING_DRAW +; +; LDI A,240 +; STS CHAR_X,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; +;STRING_RIGHT_JUST: +; PUSH B +; PUSH ZL +; PUSH ZH +; RCALL STRING_WIDTH +; POP ZH +; POP ZL +; POP B +; LDS A,CHAR_X +; SUB A,R0 +; STS CHAR_X,A +; +;STRING_DRAW: +; PUSH B +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; PUSH R0 +; RCALL DRAW_CHAR +; POP R0 +; POP ZH +; POP ZL +; LDS A,CHAR_X +; ADD A,R0 +; STS CHAR_X,A +; POP B +; DEC B +; BRNE STRING_DRAW +; RET +; +;STRING_WIDTH: +; CLR R0 +;STRING_WIDTH_LOOP: +; PUSH B +; PUSH R0 +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; POP ZH +; POP ZL +; POP A +; ADD R0,A +; POP B +; DEC B +; BRNE STRING_WIDTH_LOOP +; RET +; +;HELLO_MESSAGE: .DB 'H','E','L','L','O',0 + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +SET_TIME: + LDI A,0 + OUT TCCR2,A ; STOP COUNTING WHILE SETTING CLOCK + STS TIME_HSEC_64K,A + STS TIME_HSEC_256,A + STS TIME_HSEC,A + RCALL RX_WAIT + STS TIME_HOUR,A + RCALL RX_WAIT + STS TIME_MINUTE,A + RCALL RX_WAIT + STS TIME_SECOND,A + RCALL RX_WAIT + STS DATE_MONTH,A + RCALL RX_WAIT + STS DATE_DAY,A + RCALL RX_WAIT + STS DATE_YEAR,A + LDI A,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;** LDI A,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,A + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE +;L01A3: + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: CLR CURSORX + RJMP MAIN_LOOP + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST ; 20mar03 tavrasm *2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST+1 ; 20mar03 tavrasm *2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRCC DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRCC DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + RCALL FIND_CHAR ; SET UP CHAR_PTR FROM A = CHAR + RCALL CHAR_WIDTH ; SET UP R0 = PROP WIDTH FROM CHAR PTR + + CLR F + STS TEMP,F ; NUDGE FOR FIXED SPACING MODE + + SBRC FLAGS,4 + RJMP PROP_MODE ; FORCED TO FIXED SPACING MODE? + + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS ; GET R0 = CELL WIDTH FOR CHARACTER SET + PUSH R0 + SUB R0,W + BRCC NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + POP R0 ; RESTORE R0 = FIXED CELL WIDTH + +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE ; FORCED TO GRAPHICS MODE? + + MOV F,CURSORX + ADD F,R0 ; CHECK IF CHAR WILL FIT ON THIS LINE + BRCC OK_LINE + + CLR CURSORX + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 + RCALL SELECT_XPAGE ; IN CASE WE SCROLLED THE DISPLAY + +OK_LINE: + LDS F,TEMP + ADD F,CURSORX + STS CHAR_X,F + STS CHAR_Y,CURSORY ; SET UP TOP LEFT COORDINATES + + ADD CURSORX,R0 ; ADVANCE CURSOR + +DRAW_CHAR: + LDS XPIXEL,CHAR_X + LDS LINE_CNT,CHAR_Y + + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE ; Y OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 + +Y_OFFSET_DONE: + SBRS X_SIZE,7 + RJMP X_OFFSET_DONE ; X OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$03 + RCALL LPMS + ADD XPIXEL,R0 + +X_OFFSET_DONE: + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + ADIW YL,$01 + RCALL LPMS ; GET R0 = Y LINES FOR CHARACTER + MOV Y_SIZE,R0 + + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +FIND_CHAR: + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + STS CHAR_PTR,YL + STS CHAR_PTR+1,YH + RET + +CHAR_WIDTH: + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + RCALL LPMS + MOV X_SIZE,R0 + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP LPMS ; PROPORTIONAL WIDTH IS PRESENT + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RJMP LPMS ; NO PROPORTIONAL WIDTH, USE CELL WIDTH + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + ; LET'S BE SAFE + ANDI A,$7F + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +GO_SELECT_XPAGE: + RJMP SELECT_XPAGE + +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +GO_EXT_INT0: + RJMP EXT_INT0 + +GO_EXT_INT1: + RJMP EXT_INT1 + +GO_TIM2_OVF: + RJMP TIM2_OVF + +GO_T1_OVERFLOW: + RJMP T1_OVERFLOW + +GO_T0_OVERFLOW: + RJMP T0_OVERFLOW + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +; ----------------------------------------------------------------------------- + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +; ----------------------------------------------------------------------------- + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR CURSORX ; HOME CURSOR + CLR CURSORY + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE +CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE CLEAR_DISPLAY_LOOP + RET + +; ----------------------------------------------------------------------------- + +EXT_INT0: +;**: +RETI +;** IN SR,SREG ; MEASURE VCC +;** SBI DDRD,2 +;** IN C,TCNT1L +;** IN D,TCNT1H +;** STS VCCH,D +;** STS VCCL,C +;** RJMP EXT_INT_RET + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP EXT_INT_RET + +T1_OVERFLOW: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDI D,$70 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, TOGGLE OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + LDS C,CLOCKING_PTR +; TST C ; START OF 4 LINE BLOCK? (1 BASED) + lds d,CLOCKING_PTR+1 + andi d,1 + or c,d ; checks for start of an 8 line block +; rjmp BREAK0 ; temporary (prevents switching off via power switch) + BRNE BREAK0 ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK1 ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION +GO_SLEEP_ENTRY: + RJMP SLEEP_ENTRY + +BREAK0: NOP + NOP + NOP + NOP + NOP + NOP + NOP +BREAK1: SBI DDRD,3 ; PRECHARGE TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D ; STOP TIMER1 + OUT TCNT1H,D ; AND CLEAR COUNT + OUT TCNT1L,D + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + LDS D,LATCH10_SAV + OUT PORTA,D + SBI PORTB,4 + SBI PORTA,5 ; PULSE CL1 + CBI PORTA,5 + CBI PORTB,4 + NOP ; EQUALIZE DELAY + NOP + NOP + NOP + NOP + NOP + RJMP L04F9 + +L04E6: LDS D,LATCH10_SAV + ORI D,$80 ; RAISE FLM + ORI D,$20 ; RAISE CL1 + OUT PORTA,D + + SBI PORTB,4 + LDI C,$60 ; TOGGLE M AND CL1 + EOR D,C + OUT PORTA,D + ANDI D,$7F ; DROP FLM + OUT PORTA,D + CBI PORTB,4 + STS LATCH10_SAV,D + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D + +; LDI D,1 ; TO CLOCK AT 5.5/2 MHZ + OUT OCR1AL,D ; TO CLOCK AT 7.3/2 MHZ + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + +;!!! LDI D,$7A ; WAIT FOR 32uSEC +; LDI D,58 ;$7A ; WAIT FOR 32uSEC GOOD + LDI D,60 ; WAIT FOR 32uSEC +; LDI D,61 ;$7A ; WAIT FOR 32uSEC +; LDI D,62 ;$7A ; WAIT FOR 32uSEC GOOD + +L050E: DEC D + BRNE L050E + + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + LDI D,$01 ; KILL CLR ON COMPARE MATCH + NOP ; !WITH OC1A LEFT IN LOW STATE + OUT TCCR1B,D + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0536 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + RJMP L0536 + +L0535: NOP ; EQUALIZE DELAYS + NOP + NOP + NOP +L0536: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VEEL + LDS D,VEEH + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + NOP + NOP + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,2 ; SET TIME FOR START OF LED PULSE + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_DELAY_0 ; 54uSEC + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,3 ; START TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + + RJMP T1_OVERFLOW_RET + +T0_OVERFLOW: + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + PUSH ZH + PUSH ZL + PUSH R0 + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_STATE + INC D + STS SCAN_STATE,D + DEC D + BREQ SCAN_START ; IF SCAN_STATE WAS = 0 + DEC D + BREQ SCAN_BEEPER ; IF SCAN_STATE WAS = 1 + ; IMPLEMENT ENTRY POINT FOR SCAN_PULSE_LED HERE + DEC D + RJEQ SCAN_PHOTO ; IF SCAN_STATE WAS = 2 + +T0_OVERFLOW_RET: + POP R0 + POP ZL + POP ZH + +T1_OVERFLOW_RET: + POP D ; RESTORE STATE OF THE WORLD + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +EXT_INT_RET: + OUT SREG,SR + RETI + +SCAN_START: + LDI D,3 ;5 + OUT TCCR0,D ; PRESCALE=CK/1024 + LDI D,-TK_DELAY_1 ;TK_DELAY_2 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + RJMP L0617_RESET + +SCAN_BEEPER: + LDS D,BUZZ_TIME + TST D + BREQ SCAN_PULSE_LED + LDS D,BUZZ_PERIOD + SUBI D,$10 + BRLO BUZZ_TOGGLE + STS BUZZ_PERIOD,D + RJMP SCAN_PULSE_LED +BUZZ_TOGGLE: ; ASSUME D = $F0 + PERIOD-1 + MOV C,D ; EG. C = $F3 FOR PERIOD = 4 + SWAP C ; EG. C = $3F FOR PERIOD = 4 + AND D,C ; EG. D = $33 FOR PERIOD = 4 + STS BUZZ_PERIOD,D + LDS C,LATCH12_SAV + SBRS C,3 ; TEST PREVIOUS SPEAKER STATE + RJMP BEEPER_SPKHI + LDS D,BUZZ_TIME + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP SCAN_PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP SCAN_PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +SCAN_PULSE_LED: + LDS D,LATCH5_SAV +;**: + SBRS D,7 ; ARE WE INSIDE SLEEP_LOOP? +;** SBRC D,7 + RJMP SCAN_PULSE_LED_OK ; YES, KEEP TIMER 0 TO RETAIN CONTROL + + LDI D,1<<7 + EOR FLAGS,D + BRPL SCAN_PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP T0_OVERFLOW_RET ; AND WASTE EVERY REMAINING CYCLE + +SCAN_PULSE_LED_OK: + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + + ;LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM ; R0 = LED DRIVE VALUE + LDI D,13*4 + CP SCAN,D + BRSH L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + RJMP T0_OVERFLOW_RET + +SCAN_PHOTO: + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + CLC + SBRC D,6 + RJMP L0593 ; ROW/COLUMN IS INACTIVE + + ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF + IN C,SREG + + LDI D,13*4 + CP SCAN,D + BRSH L05A8 + + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS ZL,ROW_BITMAP + LDS ZH,ROW_BITMAP+1 + ROL ZL + ROL ZH + STS ROW_BITMAP,ZL + STS ROW_BITMAP+1,ZH + RJMP L05F9 + +L05A8: ; WE HAVE A COLUMN STATUS +; LDS D,LATCH5_SAV +;;**: +; SBRS D,7 ; TURNED OFF? +;;** SBRC D,7 +; RJMP L05F9 ; YES, NO FURTHER PROCESSING + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRCS L05AB + RJMP L05F9 + +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 + +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS ZH,ROW_BITMAP+1 + LDS ZL,ROW_BITMAP + + LDS D,ROW_INDEX + TST D + BREQ ROW_BITMAP_LOOP + + MOV C,D +ROW_BITMAP_SKIP: + ROR ZH + ROR ZL + SUBI C,4 + BRNE ROW_BITMAP_SKIP + +ROW_BITMAP_LOOP: + SUBI D,-4 + ROR ZH + ROR ZL + BRCS FOUND_INTERSECTION +ROW_BITMAP_LOOPE: + CPI D,13*4 + BRLO ROW_BITMAP_LOOP + + ; NO FURTHER INTERSECTING ROWS FOUND + RJMP L05F9 + +FOUND_INTERSECTION: + ; FOUND AN INTERSECTING ROW FOR COLUMN + STS ROW_INDEX,D + + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + TST R0 + BRNE VALID_INTERSECTION + + ; INTERSECTION IS NULL, GO ON TO NEXT + LDS D,ROW_INDEX + CPI D,13*4 + BRSH L05F9 ; DONE LAST ROW, GO ON TO NEXT COLUMN +GO_L0617: + RJMP L0617 ; GO ON TO NEXT ROW, SAME COLUMN + +VALID_INTERSECTION: + ; INTERSECTION IS VALID, WE HAVE KEY MAKE + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,54 ;43 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + + MOV D,TX_COUNT + CPI D,TX_SIZE-1 + BRSH L05F9 + + PUSH A + MOV A,R0 + RCALL TX_CHAR + CPI A,$1B + BRNE TX_CONT + RCALL TX_CHAR +TX_CONT: + POP A + +L05F9: + LDI D,4 ; SCAN TO NEXT LED / PHOTODIODE PAIR + ADD SCAN,D + + LDS D,LATCH5_SAV + SBRC D,7 + RJMP TURNED_ON + + LDI D,3 + OUT TCCR0,D ; PRESCALE=CK/64 + LDI D,-TK_DELAY_1 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI C,13*4 + CP SCAN,C + BRLO GO_L0617 + + ; KEEP VDD ON, TO AVOID THE LONG TK_DELAY_2 + ;LDS D,LATCH5_SAV + ;ANDI D,$BF ; BIT 6 = 0 VDD OFF + ;STS LATCH5_SAV,D + ;PHOTO D ; READY TO SLEEP FOR ANOTHER 0.25 SEC + + LDI D,0 + OUT TCCR0,D ; STOP TIMER SINCE COMPLETE SCAN DONE + ;RJMP T0_OVERFLOW_RET + + ;LDI D,$05 + ;OUT UBRR,D + ;LDI D,$18 + ;OUT UCR,D + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + ;OUT UDR,C + ;OUT UDR,D + OR C,D ; HAVE WE SOME ACTIVITY? + + LDS D,TURNON_COUNT + CPI D,4 + BRSH TURNON_BREAK ; WAITING FOR BREAK + CPI D,1 + BRSH TURNON_MAKE ; WAITING FOR MAKE +GO_T0_OVERFLOW_RET: + RJMP T0_OVERFLOW_RET ; ALREADY HAD MAKE, NOT TURNED ON YET + +TURNON_BREAK: + TST C ; HAD SOME ACTIVITY? + BREQ TURNON_SAVE ; NO, COUNT DOWN TO BREAK + LDI D,4+1 ; YES, RESTART COUNTDOWN TO BREAK + RJMP TURNON_SAVE +TURNON_MAKE: + TST C ; HAD SOME ACTIVITY? + BRNE TURNON_SAVE ; YES, COUNT DOWN TO MAKE + LDI D,3+1 ; NO, RESTART COUNTDOWN TO MAKE +TURNON_SAVE: + DEC D ; COUNT DOWN TO MAKE OR BREAK + STS TURNON_COUNT,D + BRNE GO_T0_OVERFLOW_RET ; NOT READY TO TRY TURNON YET + + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + CBI DDRD,2 ; D2 = TRI-STATE, VSWT ON + RJMP GO_SLEEP_ENTRY ; WE WILL NOW WAIT FOR TURNON COMMAND + +TURNED_ON: + LDI D,0 ; STOP TIMER, WE WILL REGAIN + OUT TCCR0,D ; CONTROL VIA NEXT CLOCKING INTERRUPT + STS ROW_INDEX,D + + LDI C,50*4 + CP SCAN,C + BRLO L0617 + + LDS D,DEBOUNCE ; COMPLETED ENTIRE SCAN, START NEW SCAN + TST D + BREQ L0617_RESET + DEC D + STS DEBOUNCE,D + BRNE L0617_RESET + + LDS D,ACTIVE_ZONE + TST D + BREQ L0617_RESET + + MOV D,TX_COUNT + CPI D,TX_SIZE + BRSH L0617_RESET + + PUSH A + LDI A,0 + RCALL TX_CHAR + POP A + +L0617_RESET: + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + ;LDIZ SCAN_TBL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$80 ; BIT 7 = PRESERVED, LCD ON/OFF STATUS + ORI D,$40 ; BIT 6 = 1 VDD ON + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + RJMP T0_OVERFLOW_RET + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP CLEAR_DISPLAY_LOOP + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_XPAGE: + A14_A18 A + RET + +; HOW MANY SECS/6553600 PER 4HZ INTERRUPT ? +; EACH TIME THROUGH ADD 1638400 SECS/6553600 = 1/4 SEC +; OSCILLATOR IS SLOW SO WE WILL ADD 1 PART IN 10000 +; HENCE EACH TIME THROUGH ADD 1638400+164 = 1638564 UNITS TO COUNT + +TIM2_OVF: + IN SR,SREG + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +;!! LDI A,$10 ; DIAGNOSTIC +;!! STS BUZZ_TIME,A ; SHORT BEEP + + LDS D,TIME_HSEC_64K + SUBI D,LOW(-1638564) + STS TIME_HSEC_64K,D + + LDS D,TIME_HSEC_256 + SBCI D,HIGH(-1638564) + STS TIME_HSEC_256,D + + LDS D,TIME_HSEC + SBCI D,HIGH(-1638564>>8) + CPI D,100 + BRSH TIM2_CARRY + STS TIME_HSEC,D + +TIM2_END: + OUT SREG,SR + SBRS FLAGS,6 ; IF WE TURNED OFF VIA COMMAND, + RETI ; START A NEW SCAN, OTHERWISE DONE + + LDI D,0 + STS SCAN_STATE,D ; WE WILL EXECUTE SCAN_START ROUTINE + RJMP T0_OVERFLOW ; GO AND TURN VDD ON + +GO_TX_CHAR: + RJMP TX_CHAR + +TIM2_CARRY: + LDI D,0 + STS TIME_HSEC,D + + LDS D,TIME_SECOND + INC D + CPI D,60 + BRLO TIM2_SECOND + + LDS D,TIME_MINUTE + INC D + CPI D,60 + BRLO TIM2_MINUTE + + LDS D,TIME_HOUR + INC D + CPI D,24 + BRLO TIM2_HOUR + + PUSH ZL + PUSH ZH + PUSH R0 + LDI ZL,LOW(MONTH_TABLE*2-1) + LDI ZH,HIGH(MONTH_TABLE*2-1) + LDS E,DATE_MONTH + ADD ZL,E + LDI E,0 + ADC ZH,E + LPM + MOV E,R0 + CPI E,28 + BRNE FEBRUARY_OK + LDS E,DATE_YEAR + ANDI E,3 + LDI E,28 + BRNE FEBRUARY_OK + LDI E,29 +FEBRUARY_OK: + POP R0 + POP ZH + POP ZL + + LDS D,DATE_DAY + CP D,E + BRLO TIM2_DAY + + LDS D,DATE_MONTH + CPI D,12 + BRLO TIM2_MONTH + + LDS D,DATE_YEAR + INC D + STS DATE_YEAR,D + CLR D +TIM2_MONTH: + INC D + STS DATE_MONTH,D + CLR D +TIM2_DAY: + INC D + STS DATE_DAY,D + CLR D +TIM2_HOUR: + STS TIME_HOUR,D + CLR D +TIM2_MINUTE: + STS TIME_MINUTE,D + CLR D +TIM2_SECOND: + STS TIME_SECOND,D + +TIM2_SEND: + MOV D,TX_COUNT + CPI D,TX_SIZE-7 + BRSH TIM2_SEND_SKIP + + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'T' + RCALL TX_CHAR +; LDS A,VCCL +; RCALL TX_CHAR +; LDS A,VCCH +; RCALL TX_CHAR +; LDS A,VEEL +; RCALL TX_CHAR +; LDS A,VEEH +; RCALL TX_CHAR +; LDI A,$0D +; RCALL TX_CHAR + LDS A,TIME_HOUR + RCALL GO_TX_CHAR + LDS A,TIME_MINUTE + RCALL GO_TX_CHAR + LDS A,TIME_SECOND + RCALL GO_TX_CHAR + LDS A,DATE_MONTH + RCALL GO_TX_CHAR + LDS A,DATE_DAY + RCALL GO_TX_CHAR + LDS A,DATE_YEAR + RCALL GO_TX_CHAR + POP A + +TIM2_SEND_SKIP: + RJMP TIM2_END + +; ----------------------------------------------------------------------------- + +MONTH_TABLE: + .DB 31,28,31,30,31,30,31,31,30,31,30,31 + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: +.INCLUDE "CHSET00.INC" +CHSET00_END: + +; ----------------------------------------------------------------------------- + +GET_CLEAR_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL CLEAR_FRAME_RECT + RJMP MAIN_LOOP + +GET_FRAME_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FRAME_RECT + RJMP MAIN_LOOP + +GET_CLEAR_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL CLEAR_HALFTONE_RECT + RJMP MAIN_LOOP + +GET_HALFTONE_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL HALFTONE_RECT + RJMP MAIN_LOOP + +NO_GOX: RET + +CLEAR_FRAME_RECT: + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS F,RECTNC_YY + STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +FRAME_RECT: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GOX + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GOX + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS F,RECTNC_YY + SUBI F,2 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_XX + STS RECT_XX,F + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +CLEAR_HALFTONE_RECT: +; LDS F,RECTNC_X +; STS RECT_X,F +; LDS F,RECTNC_Y +; STS RECT_Y,F +; LDS F,RECTNC_XX +; STS RECT_XX,F +; LDS F,RECTNC_YY +; STS RECT_YY,F + + LDI F,$02 + OR FLAGS,F + + RCALL DRAW_RECT + + LDI F,$FD + AND FLAGS,F + +HALFTONE_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LDI A,$55 + SBRS YH,0 + LDI A,$AA + MOV PATTERN,A + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP X03A3 +X039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +X03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ X03B0 + LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + TST XPIXEL + BREQ X03B0 +X03AD: LSR A + DEC XPIXEL + BRNE X03AD +X03B0: AND A,PATTERN + RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +X03B8: LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + BREQ X03D2 + AND A,PATTERN + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP X03B8 +X03C2: TST X_SIZE + BREQ X03D3 +X03C4: LSR A + DEC X_SIZE + BRNE X03C4 + COM A + TST XPIXEL + BREQ X03D2 + CLR B +X03CB: LSR A + ROR B + DEC XPIXEL + BRNE X03CB + AND A,PATTERN + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +X03D2: AND A,PATTERN + RCALL WR_DISP_MEM +X03D3: COM PATTERN + RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP X039A + RET + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/wpo15v1.asm b/src/avr/wpo15v1.asm new file mode 100644 index 00000000..c717da5e --- /dev/null +++ b/src/avr/wpo15v1.asm @@ -0,0 +1,2186 @@ +; WPO15V1.ASM + +; LOOK FOR BIGBODGE TO SEE CEC'S CHANGES TO FIX STARTUP PROBLEM +; AND TO SKIP VOLTAGE MEASURING + +; REVISED 17DEC01 TO SUPPORT NEW HARDWARE TYPE 3 FOR HYT1500 + +; REVISED 18DEC01 TO TRY A CONSERVATIVE 4.5 VOLT SHUTDOWN, LOW BATTERY +; THIS DOESN'T PROTECT AGAINST REBOOTING WHILE PRINTING, TOO BAD + +; REVISED 18DEC01 TO TRY AN AGGRESSIVE 5.5 VOLT SHUTDOWN, LOW BATTERY +; ALSO ENABLED THE 4.5 VOLT IMMEDIATE RESET, DUE TO UNRELIABLE OPERATION +; NOW TRYING 5.0 VOLT IMMEDIATE RESET, CEC SAYS IT WAS MARGINAL ANYWAY + +; NOW DISABLED THE IMMEDIATE RESET DUE TO TESTING RESULTS OF 08JAN02 +; NOT SURE IF THAT WAS REALLY THE PROBLEM - BUT WISH TO BE CONSERVATIVE + +; REVISED 01FEB02 FOR NEW 7.3728 MHZ XTAL, PREVIOUSLY 11.0592 MHZ, 2/3 +; LOOK FOR ;! TO SEE CHANGES FOR 7.3728 MHZ XTAL, ADDED COMMENTS ALSO + +; ----------------------------------------------------------------------------- + +.EQU LARGE =1 + +;IF LARGE +.INCLUDE "8535DEF.INC" +;ELSE +;.INCLUDE "4433DEF.INC" +;ENDIF + +; ----------------------------------------------------------------------------- +; API BUS TIMING CALCULATIONS: + +; 115200 BITS/SEC = 11520 BYTES/SEC = 86.8 US/BYTE + +; FOR MASTER API BUS TX, SEND 1 BYTE PER 9+12 BIT-TIMES, 24 TO BE SAFE +; SO THE CORRECT TX RATE = 86.8 * 2.4 = 200.8 US/BYTE = 4980 BYTES/SEC + +; A SUBTLE OPTIMISATION IS POSSIBLE WHEN THE PREVIOUS TRANSMITTED LSB IS 0, +; AS WE CAN THEN GUARANTEE THE 4800 BPS RECEIVERS WILL SEE FALSE START BIT: + +; FOR MASTER API BUS TX EVEN, SEND 1 BYTE PER 2+12 BIT-TIMES, 16 TO BE SAFE +; SO THE CORRECT TX RATE EVEN = 86.8 * 1.6 = 138.9 US/BYTE = 7199 BYTES/SEC + +; OLD: TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ = APPROX 185 US +; NEW: TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ = APPROX 278 US +; THUS ALL THE TIMEOUT VALUES BELOW HAVE BEEN DECREASED TO 2/3 ORIGINAL + +; NEW: THE EVEN/ODD TX RATE OPTIMISATION HAS BEEN DISABLED AS WE DON'T +; HAVE ENOUGH RESOLUTION WITH THE 7.3728 MHZ XTAL / 8 TO GENERATE 138.9 +; US/BYTE DELAY, BECAUSE MINIMUM UNIT IS NOW 278 US INSTEAD OF 185 US, +; THIS COULD BE IMPROVED LATER, BUT FOR NOW, WE GENERATE AN INTERRUPT +; EVERY 278 US, AND THE NEXT AVAILABLE TCK0 DIVIDER IS /1 SO THIS WOULD +; BECOME 34.8 US, THIS WOULD BE UNACCEPTABLE, SO REVISIT THE ISSUE LATER + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_TIMEOUT =16 ;!25 ; 25 * 0.185 MS = 4.6 MS +.EQU API_TIME_IDLE =8 ;!13 ; 13 * 0.185 MS = 2.4 MS +.EQU API_TIME_SLOW =8 ;!13 ; 25 * 0.185 MS = 2.4 MS +.EQU API_TIME_FAST =1 ;!2 ; 2 * 185 US = 370 US, NOW 1 * 278 US +.EQU API_RATE_SLOW =$5F ;!$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ;!$05 ; DIVISOR FOR 115200 BPS + +.EQU SPI_TIMEOUT =16 ;!25 ; 100 * 100 US = APPROX 10.0 MS + +;.def drem16uL =R0 ; remainder low +;.def drem16uH =R1 ; remainder high +;.def dres16uL =R2 ; result low DON'T use as general purpose +;.def dres16uH =R3 ; result high DON'T use as general purpose +;.def dd16uL =R2 ; dividend low +;.def dd16uH =R3 ; dividend high +;.def dv16uL =R4 ; divisor low +;.def dv16uH =R5 ; divisor high +; +;.DEF SPI_REMAIN =R6 +; +;.def mc16uL =R7 ;multiplicand low byte +;.def mc16uH =R8 ;multiplicand high byte +;.def mp16uL =R9 ;multiplier low byte +;.def mp16uH =R10 ;multiplier high byte +;.def m16u0 =R9 ;result byte 0 (LSB) +;.def m16u1 =R10 ;result byte 1 +;.def m16u2 =R11 ;result byte 2 +;.def m16u3 =R12 ;result byte 3 (MSB) +; +;.DEF RX_PTR =R13 +;.DEF RX_COUNT0 =R14 + +.DEF API_REMAIN =R1 +.DEF API_WATCHDOG =R2 +.DEF SPI_REMAIN =R3 +.DEF SPI_WATCHDOG =R4 +.DEF RX_PTR =R5 +.DEF RX_COUNT0 =R6 +.DEF RX_COUNT1 =R7 +.DEF TX_PTR =R8 +.DEF TX_COUNT0 =R9 +.DEF TX_COUNT1 =R10 + +.DEF SR =R15 +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R23 +.DEF G =R24 + +.DEF FLAGS =R20 +;.def counter =R20 ;loop counter + +.DEF ATOD =R21 ; SO YOU CAN USE SBCI, SUBI, CPI ETC + +.DEF API_STATE =R22 + +;.DEF TX_PTR =R25 +;.DEF API_WATCHDOG =R26 +;.DEF API_REMAIN =R27 +;.DEF SPI_WATCHDOG =R28 +;.DEF TX_COUNT0 =R29 + +.EQU TX_SIZE =$40 +.EQU RX_SIZE =$10 + + .DSEG + .ORG $60 + +VSWTS: .BYTE 1 ; RETAIN ORDERING % +VCHGS: .BYTE 1 +NEGVS: .BYTE 1 + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +TX_ADDRESS0: .BYTE 1 ; DEST FOR TX_COUNT0 BYTES AT HEAD +TX_ADDRESS1: .BYTE 1 ; DEST FOR TX_COUNT1 BYTES AT TAIL + +RX_ADDRESS0: .BYTE 1 ; SOURCE FOR RX_COUNT0 BYTES AT HEAD +RX_ADDRESS1: .BYTE 1 ; SOURCE FOR RX_COUNT1 BYTES AT TAIL + +RX_ADDRESS2: .BYTE 1 ; ALTERNATE VALUE FOR RX_ADDRESS1 + ; SCAN IS 1,2,1,3,1,4,1,5,1,6,1,7,1,8 + +TX_OVERRIDE: .BYTE 1 ; COUNTER TO TRANSMIT 1 TIME IN 16 +RX_OVERRIDE: .BYTE 1 ; COUNTER TO RECEIVE 1 TIME IN 16 + +TX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME TX DEVICE +RX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME RX DEVICE + +;ABSENT_COUNT: .BYTE 1 + +TURNOFF_COUNT: .BYTE 1 +WATCHDOG_COUNT: .BYTE 2 + +TX_LIMIT: .BYTE 9 ; MAX Z180 BYTES TO ACCEPT, PER DEVICE + +BATTERY_COUNT: .BYTE 2 ; COUNT 1024 ADC READINGS TO POWER DOWN + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +;LM385_COUNT: .BYTE 1 ; COUNT $10 ADC READINGS TO MISSING REF +VOLTAGE_VSWT: .BYTE 1 ; MOST RECENT ADC READING FROM REF + +HARDWARE_TYPE: .BYTE 1 ; COMES SOMEWHAT BEFORE RSEL HI COMMAND + +STACK_GUARD: .BYTE 1 ; DETECTS IF STACK COMES DOWN TO HERE + +; ----------------------------------------------------------------------------- + +; API_STATE DEFINITIONS +.EQU SPISIZE =0 ; SET IF EXPECTING SPI DATA SIZE CMD +.EQU SPIWAIT =1 ; SET IF SENDING SPI ADDRESS RESPONSE +.EQU SPIDATA =2 ; SET IF TRANSFERRING SPI DATA TX/RX +.EQU SPIDIRN =3 ; SET IF TX, BASED ON ADDRESS COMMAND +.EQU APISIZE =4 ; SET IF NEED TO SEND API DATA SIZE CMD +.EQU APIWAIT =5 ; SET IF WAITING FOR API DATA SIZE RESP +.EQU APIDATA =6 ; SET IF TRANSFERRING API DATA TX/RX +.EQU APIDIRN =7 ; SET IF TX, TOGGLED ON NULL TRANSFER + +; ----------------------------------------------------------------------------- + +;IF LARGE + +.EQU IRQ =6 +.EQU IRQ_PORT =PORTA +.EQU IRQ_DDR =DDRA + +.EQU PRG =3 +.EQU PRG_PORT =PORTB +.EQU PRG_DDR =DDRB + +.EQU OC1 =5 +.EQU OC1_PORT =PORTD +.EQU OC1_DDR =DDRD + +.EQU OCR1H =OCR1AH +.EQU OCR1L =OCR1AL + +.EQU COM10 =COM1A0 +.EQU COM11 =COM1A1 + +;ELSE +; +;.EQU IRQ =0 +;.EQU IRQ_PORT =PORTB +;.EQU IRQ_DDR =DDRB +; +;.EQU PRG =2 +;.EQU PRG_PORT =PORTC +;.EQU PRG_DDR =DDRC +; +;.EQU OC1 =1 +;.EQU OC1_PORT =PORTB +;.EQU OC1_DDR =DDRB +; +;.EQU USR =UCSRA +;.EQU UCR =UCSRB +; +;ENDIF + +; ----------------------------------------------------------------------------- + + .CSEG + + RJMP RESET_ENTRY + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER 0 OVERFLOW HANDLER + + .ORG SPIADDR + RJMP SPI_COMPLETE ; SPI TRANSFER COMPLETE HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + + .ORG ADCCaddr + RJMP ADC_COMPLETE + +; ----------------------------------------------------------------------------- + +RESET_ENTRY: + ; INITIALISE AVR +;IF LARGE + LDI A,HIGH(RAMEND) + OUT SPH,A +;ENDIF + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + ; INITIALISE STACK GUARD + LDI A,$5A + STS STACK_GUARD,A + + ; INITIALISE PORTS + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + LDI A,0 + OUT SPCR,A ; DISABLE SPI WHILE RESETTING Z180 + OUT UCR,A ; DISABLE UART WHILE RESETTING SLAVES + +;IF LARGE + LDI A,$FF + OUT DDRC,A ; PORTC CONFIGURED AS OUTPUT + + SBI PORTB,7 ; PB7/SCK CONFIGURED AS PULLED UP INPUT + SBI DDRB,6 ; PB6/MISO CONFIGURED AS OUTPUT + + SBI DDRA,7 ; A7 CONFIGURED AS OUTPUT FOR DTR1 + SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 + +; 18DEC01 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +; SBI PORTA,4 ; A4 PULLED UP TO DETECT MISSING LM385 +;ELSE +; SBI PORTB,5 ; PB5/SCK CONFIGURED AS PULLED UP INPUT +; SBI DDRB,4 ; PB4/MISO CONFIGURED AS OUTPUT +; +; SBI DDRD,5 ; D5 CONFIGURED AS OUTPUT FOR DTR1 +; SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 +; +; SBI PORTC,4 ; C4 PULLED UP TO DETECT MISSING LM385 +;ENDIF + + SBI PORTD,2 ; D2 CONFIGURED AS PULL UP FOR IBM CLK + SBI PORTD,3 ; D3 CONFIGURED AS PULL UP FOR IBM DATA + + SBI OC1_PORT,OC1 + SBI OC1_DDR,OC1 ; OUTPUT OC1 = 1, PWM TRANSISTOR OFF + + CBI IRQ_PORT,IRQ + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + CBI PORTD,7 + SBI DDRD,7 ; OUTPUT RSEL = 0 + + CBI PORTD,4 + SBI DDRD,4 ; OUTPUT RES = 0 + + ; HARD RESET API BUS DEVICES + CBI PRG_PORT,PRG + SBI PRG_DDR,PRG ; OUTPUT PRG = 0 + + CBI PORTD,1 + SBI DDRD,1 ; OUTPUT TXD = 0 + + LDI A,7 + RCALL PRG_RESET ; SPECIFIC RESET SPARE + + LDI A,6 + RCALL PRG_RESET ; SPECIFIC RESET M192 RECEIPT PRINTER + + LDI A,5 + RCALL PRG_RESET ; SPECIFIC RESET M192 LABEL PRINTER + + LDI A,4 + RCALL PRG_RESET ; SPECIFIC RESET MT102 RECEIPT PRINTER + + ;LDI A,3 + ;RCALL PRG_RESET ; SPECIFIC RESET SPARE + ; THE ABOVE SHOULD BE OK - WHY NOT ?? 16FEB01 + + ;LDI A,2 + ;RCALL PRG_RESET ; SPECIFIC RESET TOUCHSCREEN + + LDI A,1 + RCALL PRG_RESET ; SPECIFIC RESET CUSTOMER DISPLAY + + LDI A,0 + RCALL PRG_RESET ; REMOVE RESET PULSE + + ; LOADCELL HAS BEEN IN RESET UNTIL NOW, AND WILL START IN 10 MS + + ;SBI PORTD,1 ; OUTPUT TXD = 1 + + LDI A,API_RATE_SLOW ; 4800 BAUD + OUT UBRR,A ; SET BAUD RATE + LDI A,$18 + OUT UCR,A ; ENABLE TX AND RX (OUTPUTS TXD = 1) + + RCALL PRG_DELAY_280_MS ; DELAY FOR TOUCHSCREEN TO REENTER IDLE + + LDI A,$AA + OUT UDR,A ; SEND SLOW TURNON COMMAND + OUT UDR,A ; AND AGAIN FOR EXTRA SAFETY + + RCALL PRG_DELAY_20_MS ; DELAY TO ALLOW DEVICES TO INITIALISE + + ; ALLOW Z180 TO START + SBI PORTD,4 ; OUTPUT RES = 1 + ;CBI DDRD,4 ; OUTPUT RES = TRI-STATE + +; BIGBODGE FOR ANOTHER RESET PULSE!!!! +RCALL PRG_DELAY_20_MS +CBI PORTD,4 ; RES=0 +RCALL PRG_DELAY_20_MS +SBI PORTD,4 ; OUTPUT RES = 1 + + ; INITIALISE VARIABLES + CLR A + LDI ZL,VSWTS + CLR ZH + ST Z+,A + ST Z+,A + ST Z+,A + LDI ZL,TX_LIMIT + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A ; CAREFUL - Z WILL BE USED AGAIN BELOW + STS TURNOFF_COUNT,A + STS VOLTAGE_VSWT,A + + ;LDI A,LOW(1000) + STS WATCHDOG_COUNT,A + ;LDI A,HIGH(1000) ; 100 MS + STS WATCHDOG_COUNT+1,A + + LDI A,TX_SIZE + ST Z,A ; RX_LIMIT FOR 9TH (INTERNAL) DEVICE + + LDI A,LOW(1024) + STS BATTERY_COUNT,A + LDI A,HIGH(1024) + STS BATTERY_COUNT+1,A + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI A,$10 ; START COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,A + + CLR FLAGS + + CLR API_STATE + CLR API_REMAIN + + CLR TX_PTR + CLR TX_COUNT0 + CLR TX_COUNT1 + + CLR RX_PTR + CLR RX_COUNT0 + CLR RX_COUNT1 + +; LDI A,4 +; STS ABSENT_COUNT,A ; TOP UP ABSENT COUNTER FOR TX_ADDRESS + + ; START COMMUNICATIONS TASK + LDI A,2 + STS RX_ADDRESS2,A ; ALTERNATE VALUE FOR RX_ADDRESS1 + + LDI A,1 + STS TX_ADDRESS0,A + STS TX_ADDRESS1,A + STS RX_ADDRESS0,A + STS RX_ADDRESS1,A + STS TX_OVERRIDE,A + STS RX_OVERRIDE,A + STS HARDWARE_TYPE,A ; AS FOR OLD ALGORITHM WITH FLAGS,2 = 0 + + LDI A,0 + STS TX_STICKY,A + STS RX_STICKY,A + + LDI A,-API_TIMEOUT + MOV API_WATCHDOG,A ; SET UP TIME TO FIRST API BUS POLL + LDI A,-SPI_TIMEOUT + MOV SPI_WATCHDOG,A ; SET UP TIME TO FIRST SPI BUS POLL + + LDI A,$02 ; TCK0 = CK/8 + OUT TCCR0,A ; TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ + ; = APPROX 278 US + ;!TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ + ;! = APPROX 185 US +;IF LARGE + LDI A,$01 +;ELSE +; LDI A,$02 +;ENDIF + OUT TIMSK,A ; ENABLE TIMER 0 OVERFLOW INTERRUPTS + + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + IN A,SPSR + IN A,SPDR ; CLEAR SPI INTERRUPT PENDING FLAG + LDI A,$E8 + OUT SPCR,A ; SPI SLAVE, SAMPLE ON SCK FALLING EDGE + + ; START -5V GENERATOR TASK + LDI A,0 + OUT TCNT1H,A + OUT TCNT1L,A + OUT OCR1H,A + OUT OCR1L,A ; ASSUME NO LOAD TO BEGIN WITH + + LDI A,1< 0 + OR E,TX_COUNT0 + OR E,TX_COUNT1 + BRNE API_TRY_TX + +;API_TRY_RX: + LDS E,TX_OVERRIDE + DEC E + BREQ API_DIRECTION_TX ; FORCED TRANSMIT EVERY SO OFTEN + STS TX_OVERRIDE,E + RJMP API_DIRECTION_RX + +API_TRY_TX: + LDS E,RX_OVERRIDE + DEC E + BREQ BREQ_API_DIRECTION_RX ; FORCED RECEIVE EVERY SO OFTEN + STS RX_OVERRIDE,E + +API_DIRECTION_TX: + LDI E,$10 + STS TX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + ; SUSPEND TX OPERATIONS WHEN 9TH (INTERNAL) DEVICE ADDRESSED % + TST TX_COUNT0 ; ANY BYTES AT HEAD ? + LDS E,TX_ADDRESS0 + BRNE API_SUSPEND_TX0 ; YES, GO AND CHECK HEAD DEVICE + + TST TX_COUNT1 ; ANY BYTES AT TAIL ? + BREQ API_SUSPEND_TX1 ; NO, GO AND PERFORM TX OPERATION + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE TX_COUNT1 BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 + STS TX_ADDRESS0,E ; ADOPT TAIL DEVICE FOR BYTES AT HEAD + +API_SUSPEND_TX0: + CPI E,9 +BREQ_API_DIRECTION_RX: + BREQ API_DIRECTION_RX + +API_SUSPEND_TX1: + ; % + +; LDS E,ABSENT_COUNT +; TST E +; BRNE API_DEVICE_PRESENT +; +;;API_DEVICE_ABSENT: +; ADD TX_PTR,TX_COUNT0 ; SKIP TX_COUNT0 BYTES AT HEAD +; LDI E,TX_SIZE-1 +; AND TX_PTR,E +; +; CLR TX_COUNT0 ; ABANDON TX_COUNT0 DATA IN TX_BUF +; STS TX_STICKY,TX_COUNT0 ; DO NOT GO STICKY ON ABSENT DEVICE +; +; PUSH ZL +; PUSH ZH +; LDI ZL,TX_LIMIT-1 +; LDS ZH,TX_ADDRESS0 +; ADD ZL,ZH +; CLR ZH +; ;ST Z,TX_COUNT0 ; SAVE MAX BYTES TO ACCEPT, PER DEVICE +; LDI E,TX_SIZE +; ST Z,E ; SO THAT WE WILL GOBBLE UP DATA FOR ABSENT DEVICES +; POP ZH +; POP ZL +; +; LDI E,4 +; STS ABSENT_COUNT,E ; TOP UP ABSENT COUNTER FOR NEXT DEVICE +; +;API_DEVICE_PRESENT: + CBR API_STATE,1< 0 + DEC E + BRPL API_TX_ADDRESS_STICKY ; STAYING STICKY, ADOPT NEW DEVICE + + LDS E,TX_ADDRESS0 + INC E ; BUMP TX_ADDRESS BEFORE USING IT + CPI E,9 + BRLO API_TX_ADDRESS_SAVE + LDI E,1 + RJMP API_TX_ADDRESS_SAVE + +API_TX_ADDRESS_ADOPT: + LDI E,1 +API_TX_ADDRESS_STICKY: + STS TX_STICKY,E ; DECREMENT, OR TOP UP, STICKY COUNT + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 ; DEST FOR TX_COUNT1 BYTES AT HEAD +API_TX_ADDRESS_SAVE: + STS TX_ADDRESS0,E ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_TX_ADDRESS_SAME: + LDI E,1 + STS TX_STICKY,E ; TOP UP STICKY COUNT + + LDS E,TX_ADDRESS0 ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_DIRECTION_RX: + LDI E,$10 + STS RX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + SBR API_STATE,1< $10 + ;MOV E,ATOD + ;LSL ATOD ; $01 HALF SCALE -> $20 + ;ADD E,ATOD ; $01 HALF SCALE -> $30 HALF WIDTH + + LSR ATOD ; $40 HALF SCALE -> $20 + MOV E,ATOD + LSR ATOD ; $40 HALF SCALE -> $10 + ADD E,ATOD ; $40 HALF SCALE -> $30 HALF WIDTH + RJMP ADC_PULSE + +ADC_REFERENCE: + CBR FLAGS,1<<4 ; SAY NEXT RESULT WILL BE -5V GENERATOR + + ;STS VOLTAGE_VSWT,ATOD + ;RJMP ADC_DONE + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; SBRC FLAGS,5 ; CURRENT REFERENCE IS BANDGAP ? +; RJMP ADC_BANDGAP +; +; ; CURRENT REFERENCE IS LM385 (18DEC01 IT'S NOW A 100K/100K DIVIDER) +; CPI ATOD,$F8 ; IF =>$F8 ASSUME WE HAVE PULLUP ONLY +; BRLO ADC_LM385 +; +; LDS E,LM385_COUNT +; DEC E ; COUNT DOWN TO MISSING LM385 +; STS LM385_COUNT,E +; BRNE ADC_DONE ; KEEP TRYING LM385 +; +; SBR FLAGS,1<<5 ; SAY WE HAVE SWITCHED TO BANDGAP +;GO_ADC_DONE: +; RJMP ADC_DONE +; +;ADC_LM385: +; LDI E,$10 ; TOP UP COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,E +; +;; LSR ATOD ; LM385 VOLTAGE = APPROX 2*BANDGAP +; ; USE LM385Z-1.2 +; +;ADC_BANDGAP: + STS VOLTAGE_VSWT,ATOD + + ; 18DEC01 USE 5.5 VOLTS AS FOR THE ORIGINAL HYTECH 1000 SYSTEM + ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC + ;CPI ATOD,137 ; 256*0.5*4.5/4.2 + ;CPI ATOD,152 ; 256*0.5*5.0/4.2 + CPI ATOD,168 ; 256*0.5*5.5/4.2 + +; ;CPI ATOD,70 ; 256*1.22/4.5 +; ;CPI ATOD,63 ; 256*1.22/5.0 +; CPI ATOD,57 ; 256*1.22/5.5 + + LDI E,LOW(1024) + LDI F,HIGH(1024) + ; 18DEC01 FOR HYT1500 REVERSED THE SENSE DUE TO NEW 100K/100K DIVIDER + ;BRLO ADC_BATTERY_SAVE + BRSH ADC_BATTERY_SAVE + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 THIS IS NOW DONE FURTHER DOWN, AFTER LOW BATTERY TEST +;RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + + ; VSWT < 5.5 VOLTS, STABILISE READING FOR BATTERY LOW + LDS E,BATTERY_COUNT + LDS F,BATTERY_COUNT+1 + SUBI E,LOW(1) + SBCI F,HIGH(1) + BRNE ADC_BATTERY_SAVE ; COUNT 1024 LOW BATTERY READINGS + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<3 ; SHOW BATTERY MESSAGE AND POWER DOWN + +ADC_BATTERY_SAVE: + STS BATTERY_COUNT,E + STS BATTERY_COUNT+1,F + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 WE'LL ALSO COMMENT THE WHOLE THING OUT FOR NEATNESS +RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + +; ; 18DEC01 USE 5.0 VOLTS, MORE AGGRESSIVE THAN HYTECH 1000 SYSTEM +; ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC +; ;CPI ATOD,137 ; 256*0.5*4.5/4.2 +; CPI ATOD,152 ; 256*0.5*5.0/4.2 +; ;CPI ATOD,168 ; 256*0.5*5.5/4.2 +; BRSH ADC_DONE +; +;; ;CPI ATOD,90 ; 256*1.22/3.5 +;; ;CPI ATOD,79 ; 256*1.22/4.0 +;; CPI ATOD,70 ; 256*1.22/4.5 +;; BRLO ADC_DONE +; +; ; 18DEC01 VSWT < 5.0 VOLTS, RESET MAIN PROCESSOR IMMEDIATELY +; LDI E,$FF +; STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON +; +; LDI E,0 +; OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 +; +; CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM +; +; LDI E,$FF +; LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT + +ADC_PULSE: + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + +ADC_DONE: +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI E,$45 ; START MEASURING BANDGAP +; SBRS FLAGS,5 + LDI E,$04 ; START MEASURING LM385 + SBRS FLAGS,4 + LDI E,$05 ; START MEASURING -5V GENERATOR + OUT ADMUX,E + LDI E,$DE + OUT ADCSR,E ; ENABLE A/D, START, SINGLE CONVERSION + + OUT SREG,SR + RETI + +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 5 +; RCALL MULTIPLY +;DIAG_VOLTS_AT_A5: +; ;OUT PORTC,M16U1 ; res in byte 2(ignore ls,byte),volts pin 5 +; MOV A,B ; get saved VSWT +; SUB A,M16U1 ; voltage 47K = VSWT-Voltage at pin 35 +; MOV D,A ; which is 1/3 of total supply ie +V+(-V) +; ADD A,D +; ADD A,D ; TOTAL SUPPLY +; SUB A,B ; TOTAL SUPPLY-VSWT=NEG SUPPLY +;DIAG_NEG: +; ;OUT PORTC,A +; +; LDI A,4 +; OUT ADMUX,A ; NEXT TIME READ VCHG +;ADC_DONE: +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI + +;VSWT: ;OUT PORTC,ATOD ; count value for 2.5 V ref +; LDI A,$FF +; MOV DD16UH,A ; divide by full scale ie VSWT +; SUB DD16UL,DD16UL ; clear low reg +; SUB DV16UH,DV16UH ; clear high reg divisor +; MOV DV16UL,ATOD ; use ATOD value as divisor +; ;OUT PORTC,ATOD +; RCALL DIVIDE ; ***** NOTE AN FF RESULT IS NO INPUT ******* +; MOV MC16UH,DRES16UH ; load multiplicand high from result high +; MOV MC16UL,DRES16UL ; load multiplicand low from result low +; SUB MP16UH,MP16UH ; clear high byte in multiplier reg +; LDI A,25 +; MOV MP16UL,A ; mult by zener ref voltage (2.5V) +; RCALL MULTIPLY +;DIAG_VOLT_VSWT: +;xi: +; LDS A,VSWTS ; previous value of VSWT +; MOV B,MP16UL ; new value of VSWT +; ;RCALL SMOOTH +; STS VSWTS,B +; LDS B,VSWTS +; +; ;OUT PORTC,B;M16U1 ; VSWT IN 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; +; ;STS VSWTS,B ; SAVE NEW SMOOTHED VALUE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; MOV B,M16U1 ; save copy of VSWT for neg 5V routine +; MOV DD16UH,M16U1 +; SUB DD16UL,DD16UL +; LDI A,255 ; calculate the atod volts per division +; MOV DV16UL,A +; SUB DV16UH,DV16UH +; RCALL DIVIDE ; result to be found in dres high & low +; +; LDI A,3 +; OUT ADMUX,A ; NEXT TIME READ VCHG +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;VCHG: +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 37 (1/3 VCHG) +; RCALL MULTIPLY +; MOV A,M16U1 +; ADD M16U1,A ; B\C A3 IS 1/3 VCHG +; ADD M16U1,A +;DIAG_VOLT_VHG: +; ;OUT PORTC,M16U1 ; REUSULT 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; LDI A,5 +; OUT ADMUX,A ; NEXT TIME READ VSWT +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;;*************************************************************************** +;;* +;;* "div16u" - 16/16 Bit Unsigned Division +;;* +;;* This subroutine divides the two 16-bit numbers +;;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). +;;* The result is placed in "dres16uH:dres16uL" and the remainder in +;;* "drem16uH:drem16uL". +;;* +;;* Number of words :19 +;;* Number of cycles :235/251 (Min/Max) +;;* Low registers used :2 (drem16uL,drem16uH) +;;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, +;;* dcnt16u) +;;* +;;*************************************************************************** +;divide: +;div16u: clr drem16uL ;clear remainder Low byte +; sub drem16uH,drem16uH ;clear remainder High byte and carry +; ldi counter,17 ;init loop counter +;d16u_1: rol dd16uL ;shift left dividend +; rol dd16uH +; dec counter ;decrement counter +; brne d16u_2 ;if done +; ret ; return +;d16u_2: rol drem16uL ;shift dividend into remainder +; rol drem16uH +; sub drem16uL,dv16uL ;remainder = remainder - divisor +; sbc drem16uH,dv16uH ; +; brcc d16u_3 ;if result negative +; add drem16uL,dv16uL ; restore remainder +; adc drem16uH,dv16uH +; clc ; clear carry to be shifted into result +; rjmp d16u_1 ;else +;d16u_3: sec ; set carry to be shifted into result +; rjmp d16u_1 +; +;;********* 16 X 16 multiplication routine from app note avr200 ************* +;;* +;;* "mpy16u" - 16x16 Bit Unsigned Multiplication +;;* +;;* This subroutine multiplies the two 16-bit register variables +;;* mp16uH:mp16uL and mc16uH:mc16uL. +;;* The result is placed in m16u3:m16u2:m16u1:m16u0. +;;* +;;* Number of words :14 + return +;;* Number of cycles :153 + return +;;* Low registers used :None +;;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, +;;* m16u3,mcnt16u) +;;* +;;*************************************************************************** +;multiply: +;mpy16u: clr m16u3 ;clear high byte of result +; sub m16u2,m16u2 ;clear result byte 2 and carry +; clr m16u2 +; ldi counter,16 ;init loop counter +; lsr mp16uH +; ror mp16uL +; +;m16u_1: brcc noad8 ;if bit 0 of multiplier set +; add m16u2,mc16uL ;add multiplicand Low to byte 2 of res +; adc m16u3,mc16uH ;add multiplicand high to byte 3 of res +;noad8: ror m16u3 ;shift right result byte 3 +; ror m16u2 ;rotate right result byte 2 +; ror m16u1 ;rotate result byte 1 and multiplier High +; ror m16u0 ;rotate result byte 0 and multiplier Low +; dec counter ;decrement loop counter +; brne m16u_1 ;if not done, loop more +; ret +;;************************* Exponential smoothing routine ******************** +;;Receives : Previous value in A +;; : New value in B +;;Passes : Smoothed result back in B reg +;;Uses : d reg +; +;Smooth: +; mov d,a ; save a copy of previous value +; lsr a +; lsr a +; lsr b +; lsr b ; prev.ave - prev.ave + new.data +; sub d,a ; -------- -------- +; add b,d ; n n +; ret + +; ----------------------------------------------------------------------------- + +MESSAGE_0: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',0,128,$1B + .DB 'E','1' + +MESSAGE_1: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',240,64,$1B + .DB 'E','1' + +MESSAGE_2: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','0','0','0',0 + +MESSAGE_3: + .DB $1B,'S',16,13 + .DB 'W','P','O','3','0',' ','V','5' + +MESSAGE_4: + .DB $1B,'S',16,13 + .DB 'B','A','D',' ','C','O','M','M','A','N','D',0 + +MESSAGE_5: + .DB $1B,'S',16,13 + .DB 'B','A','T','T','E','R','Y',' ','L','O','W',0 + +MESSAGE_6: + .DB $1B,'M','0',0 + +MESSAGE_7: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','5','0','0',0 + +MESSAGE_8: + .DB $1B,'S',16,13 + .DB 'S','T','A','C','K',' ','O','V','E','R','F','L','O','W' + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4100 ; SELECT ADDRESS COMMAND + ; FSTRT = 0 FOR 1.1 MS R/C STARTUP DELAY + ;.DW $ACBE ; WRITE FUSE BITS COMMAND +; BIGBODGE (NOT REALLY - JUST IN CASE TYPE OF CHANGE) +; FSTRT = 1 FOR 16 MS R/C STARTUP DELAY + .DW $ACBF ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/wpov0.asm b/src/avr/wpov0.asm new file mode 100644 index 00000000..740fde64 --- /dev/null +++ b/src/avr/wpov0.asm @@ -0,0 +1,2116 @@ +; WPOV0.ASM + +; ----------------------------------------------------------------------------- + +.EQU LARGE =0 + +;IF LARGE +;.INCLUDE "8535DEFX.INC" +;ELSE +.INCLUDE "4433DEF.INC" +;ENDIF + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_TIMEOUT =25 ;50 ;100 ; 100 * 100 US = APPROX 10.0 MS +.EQU API_TIME_IDLE =13 ;25 ; 25 * 100 US = APPROX 2.5 MS +.EQU API_TIME_SLOW =13 ;25 ; 25 * 100 US = APPROX 2.5 MS +.EQU API_TIME_FAST =2 ;1 ;2 ; 2 * 100 US = APPROX 200 US +.EQU API_RATE_SLOW =$8F ;$11 ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ;$11 ; DIVISOR FOR 115200 BPS + +.EQU SPI_TIMEOUT =25 ;50 ;100 ; 100 * 100 US = APPROX 10.0 MS + +;.def drem16uL =R0 ; remainder low +;.def drem16uH =R1 ; remainder high +;.def dres16uL =R2 ; result low DON'T use as general purpose +;.def dres16uH =R3 ; result high DON'T use as general purpose +;.def dd16uL =R2 ; dividend low +;.def dd16uH =R3 ; dividend high +;.def dv16uL =R4 ; divisor low +;.def dv16uH =R5 ; divisor high +; +;.DEF SPI_REMAIN =R6 +; +;.def mc16uL =R7 ;multiplicand low byte +;.def mc16uH =R8 ;multiplicand high byte +;.def mp16uL =R9 ;multiplier low byte +;.def mp16uH =R10 ;multiplier high byte +;.def m16u0 =R9 ;result byte 0 (LSB) +;.def m16u1 =R10 ;result byte 1 +;.def m16u2 =R11 ;result byte 2 +;.def m16u3 =R12 ;result byte 3 (MSB) +; +;.DEF RX_PTR =R13 +;.DEF RX_COUNT0 =R14 + +.DEF API_REMAIN =R1 +.DEF API_WATCHDOG =R2 +.DEF SPI_REMAIN =R3 +.DEF SPI_WATCHDOG =R4 +.DEF RX_PTR =R5 +.DEF RX_COUNT0 =R6 +.DEF RX_COUNT1 =R7 +.DEF TX_PTR =R8 +.DEF TX_COUNT0 =R9 +.DEF TX_COUNT1 =R10 + +.DEF SR =R15 +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R23 +.DEF G =R24 + +.DEF FLAGS =R20 +;.def counter =R20 ;loop counter + +.DEF ATOD =R21 ; SO YOU CAN USE SBCI, SUBI, CPI ETC + +.DEF API_STATE =R22 + +;.DEF TX_PTR =R25 +;.DEF API_WATCHDOG =R26 +;.DEF API_REMAIN =R27 +;.DEF SPI_WATCHDOG =R28 +;.DEF TX_COUNT0 =R29 + +.EQU TX_SIZE =$40 +.EQU RX_SIZE =$10 + + .DSEG + .ORG $60 + +VSWTS: .BYTE 1 ; RETAIN ORDERING % +VCHGS: .BYTE 1 +NEGVS: .BYTE 1 + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +TX_ADDRESS0: .BYTE 1 ; DEST FOR TX_COUNT0 BYTES AT HEAD +TX_ADDRESS1: .BYTE 1 ; DEST FOR TX_COUNT1 BYTES AT TAIL + +RX_ADDRESS0: .BYTE 1 ; SOURCE FOR RX_COUNT0 BYTES AT HEAD +RX_ADDRESS1: .BYTE 1 ; SOURCE FOR RX_COUNT1 BYTES AT TAIL + +RX_ADDRESS2: .BYTE 1 ; ALTERNATE VALUE FOR RX_ADDRESS1 + ; SCAN IS 1,2,1,3,1,4,1,5,1,6,1,7,1,8 + +TX_OVERRIDE: .BYTE 1 ; COUNTER TO TRANSMIT 1 TIME IN 16 +RX_OVERRIDE: .BYTE 1 ; COUNTER TO RECEIVE 1 TIME IN 16 + +TX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME TX DEVICE +RX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME RX DEVICE + +;ABSENT_COUNT: .BYTE 1 + +TURNOFF_COUNT: .BYTE 1 +WATCHDOG_COUNT: .BYTE 2 + +TX_LIMIT: .BYTE 9 ; MAX Z180 BYTES TO ACCEPT, PER DEVICE + +BATTERY_COUNT: .BYTE 2 ; COUNT 1024 ADC READINGS TO POWER DOWN + +LM385_COUNT: .BYTE 1 ; COUNT $10 ADC READINGS TO MISSING REF +VOLTAGE_VSWT: .BYTE 1 ; MOST RECENT ADC READING FROM REF + +HARDWARE_TYPE: .BYTE 1 ; COMES SOMEWHAT BEFORE RSEL HI COMMAND + +STACK_GUARD: .BYTE 1 ; DETECTS IF STACK COMES DOWN TO HERE + +; ----------------------------------------------------------------------------- + +; API_STATE DEFINITIONS +.EQU SPISIZE =0 ; SET IF EXPECTING SPI DATA SIZE CMD +.EQU SPIWAIT =1 ; SET IF SENDING SPI ADDRESS RESPONSE +.EQU SPIDATA =2 ; SET IF TRANSFERRING SPI DATA TX/RX +.EQU SPIDIRN =3 ; SET IF TX, BASED ON ADDRESS COMMAND +.EQU APISIZE =4 ; SET IF NEED TO SEND API DATA SIZE CMD +.EQU APIWAIT =5 ; SET IF WAITING FOR API DATA SIZE RESP +.EQU APIDATA =6 ; SET IF TRANSFERRING API DATA TX/RX +.EQU APIDIRN =7 ; SET IF TX, TOGGLED ON NULL TRANSFER + +; ----------------------------------------------------------------------------- + +;IF LARGE +; +;.EQU IRQ =6 +;.EQU IRQ_PORT =PORTA +;.EQU IRQ_DDR =DDRA +; +;.EQU PRG =3 +;.EQU PRG_PORT =PORTB +;.EQU PRG_DDR =DDRB +; +;.EQU OC1 =5 +;.EQU OC1_PORT =PORTD +;.EQU OC1_DDR =DDRD +; +;.EQU OCR1H =OCR1AH +;.EQU OCR1L =OCR1AL +; +;.EQU COM10 =COM1A0 +;.EQU COM11 =COM1A1 +; +;ELSE + +.EQU IRQ =0 +.EQU IRQ_PORT =PORTB +.EQU IRQ_DDR =DDRB +; +.EQU PRG =2 +.EQU PRG_PORT =PORTC +.EQU PRG_DDR =DDRC + +.EQU OC1 =1 +.EQU OC1_PORT =PORTB +.EQU OC1_DDR =DDRB + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +;ENDIF + +; ----------------------------------------------------------------------------- + + .CSEG + + RJMP RESET_ENTRY + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER 0 OVERFLOW HANDLER + + .ORG SPIADDR + RJMP SPI_COMPLETE ; SPI TRANSFER COMPLETE HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + + .ORG ADCCaddr + RJMP ADC_COMPLETE + +; ----------------------------------------------------------------------------- + +RESET_ENTRY: + ; INITIALISE AVR +;IF LARGE +; LDI A,HIGH(RAMEND) +; OUT SPH,A +;ENDIF + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + ; INITIALISE STACK GUARD + LDI A,$5A + STS STACK_GUARD,A + + ; INITIALISE PORTS + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + LDI A,0 + OUT SPCR,A ; DISABLE SPI WHILE RESETTING Z180 + OUT UCR,A ; DISABLE UART WHILE RESETTING SLAVES + +;IF LARGE +; LDI A,$FF +; OUT DDRC,A ; PORTC CONFIGURED AS OUTPUT +; +; SBI PORTB,7 ; PB7/SCK CONFIGURED AS PULLED UP INPUT +; SBI DDRB,6 ; PB6/MISO CONFIGURED AS OUTPUT +; +; SBI DDRA,7 ; A7 CONFIGURED AS OUTPUT FOR DTR1 +; SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 +; +;; 18DEC01 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +;; SBI PORTA,4 ; A4 PULLED UP TO DETECT MISSING LM385 +;ELSE + SBI PORTB,5 ; PB5/SCK CONFIGURED AS PULLED UP INPUT + SBI DDRB,4 ; PB4/MISO CONFIGURED AS OUTPUT + + SBI DDRD,5 ; D5 CONFIGURED AS OUTPUT FOR DTR1 + SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 + + SBI PORTC,4 ; C4 PULLED UP TO DETECT MISSING LM385 +;ENDIF + + SBI PORTD,2 ; D2 CONFIGURED AS PULL UP FOR IBM CLK + SBI PORTD,3 ; D3 CONFIGURED AS PULL UP FOR IBM DATA + + SBI OC1_PORT,OC1 + SBI OC1_DDR,OC1 ; OUTPUT OC1 = 1, PWM TRANSISTOR OFF + + CBI IRQ_PORT,IRQ + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + CBI PORTD,7 + SBI DDRD,7 ; OUTPUT RSEL = 0 + + CBI PORTD,4 + SBI DDRD,4 ; OUTPUT RES = 0 + + ; HARD RESET API BUS DEVICES + CBI PRG_PORT,PRG + SBI PRG_DDR,PRG ; OUTPUT PRG = 0 + + CBI PORTD,1 + SBI DDRD,1 ; OUTPUT TXD = 0 + + LDI A,7 + RCALL PRG_RESET ; SPECIFIC RESET SPARE + + LDI A,6 + RCALL PRG_RESET ; SPECIFIC RESET M192 RECEIPT PRINTER + + LDI A,5 + RCALL PRG_RESET ; SPECIFIC RESET M192 LABEL PRINTER + + LDI A,4 + RCALL PRG_RESET ; SPECIFIC RESET MT102 RECEIPT PRINTER + + ;LDI A,3 + ;RCALL PRG_RESET ; SPECIFIC RESET SPARE + ; THE ABOVE SHOULD BE OK - WHY NOT ?? 16FEB01 + + ;LDI A,2 + ;RCALL PRG_RESET ; SPECIFIC RESET TOUCHSCREEN + + LDI A,1 + RCALL PRG_RESET ; SPECIFIC RESET CUSTOMER DISPLAY + + LDI A,0 + RCALL PRG_RESET ; REMOVE RESET PULSE + + ; LOADCELL HAS BEEN IN RESET UNTIL NOW, AND WILL START IN 10 MS + + ;SBI PORTD,1 ; OUTPUT TXD = 1 + + LDI A,API_RATE_SLOW ; 4800 BAUD + OUT UBRR,A ; SET BAUD RATE + LDI A,$18 + OUT UCR,A ; ENABLE TX AND RX (OUTPUTS TXD = 1) + + RCALL PRG_DELAY_280_MS ; DELAY FOR TOUCHSCREEN TO REENTER IDLE + + LDI A,$AA + OUT UDR,A ; SEND SLOW TURNON COMMAND + OUT UDR,A ; AND AGAIN FOR EXTRA SAFETY + + RCALL PRG_DELAY_20_MS ; DELAY TO ALLOW DEVICES TO INITIALISE + + ; ALLOW Z180 TO START + SBI PORTD,4 ; OUTPUT RES = 1 + ;CBI DDRD,4 ; OUTPUT RES = TRI-STATE + +; BIGBODGE FOR ANOTHER RESET PULSE!!!! (LARGE AVR ONLY, AT THE MOMENT) +;RCALL PRG_DELAY_20_MS +;CBI PORTD,4 ; RES=0 +;RCALL PRG_DELAY_20_MS +;SBI PORTD,4 ; OUTPUT RES = 1 + + ; INITIALISE VARIABLES + CLR A + LDI ZL,VSWTS + CLR ZH + ST Z+,A + ST Z+,A + ST Z+,A + LDI ZL,TX_LIMIT + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A ; CAREFUL - Z WILL BE USED AGAIN BELOW + STS TURNOFF_COUNT,A + STS VOLTAGE_VSWT,A + + ;LDI A,LOW(1000) + STS WATCHDOG_COUNT,A + ;LDI A,HIGH(1000) ; 100 MS + STS WATCHDOG_COUNT+1,A + + LDI A,TX_SIZE + ST Z,A ; RX_LIMIT FOR 9TH (INTERNAL) DEVICE + + LDI A,LOW(1024) + STS BATTERY_COUNT,A + LDI A,HIGH(1024) + STS BATTERY_COUNT+1,A + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION % + LDI A,$10 ; START COUNTDOWN TO MISSING LM385 + STS LM385_COUNT,A +; (BUT REMAINS FOR HYT1000) % + CLR FLAGS + + CLR API_STATE + CLR API_REMAIN + + CLR TX_PTR + CLR TX_COUNT0 + CLR TX_COUNT1 + + CLR RX_PTR + CLR RX_COUNT0 + CLR RX_COUNT1 + +; LDI A,4 +; STS ABSENT_COUNT,A ; TOP UP ABSENT COUNTER FOR TX_ADDRESS + + ; START COMMUNICATIONS TASK + LDI A,2 + STS RX_ADDRESS2,A ; ALTERNATE VALUE FOR RX_ADDRESS1 + + LDI A,1 + STS TX_ADDRESS0,A + STS TX_ADDRESS1,A + STS RX_ADDRESS0,A + STS RX_ADDRESS1,A + STS TX_OVERRIDE,A + STS RX_OVERRIDE,A + STS HARDWARE_TYPE,A ; AS FOR OLD ALGORITHM WITH FLAGS,2 = 0 + + LDI A,0 + STS TX_STICKY,A + STS RX_STICKY,A + + LDI A,-API_TIMEOUT + MOV API_WATCHDOG,A ; SET UP TIME TO FIRST API BUS POLL + LDI A,-SPI_TIMEOUT + MOV SPI_WATCHDOG,A ; SET UP TIME TO FIRST SPI BUS POLL + + LDI A,$02 ; TCK0 = CK/8 + OUT TCCR0,A ; TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ + ; = APPROX 278 US + ;!TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ + ;! = APPROX 185 US +;IF LARGE +; LDI A,$01 +;ELSE + LDI A,$02 +;ENDIF + OUT TIMSK,A ; ENABLE TIMER 0 OVERFLOW INTERRUPTS + + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + IN A,SPSR + IN A,SPDR ; CLEAR SPI INTERRUPT PENDING FLAG + LDI A,$E8 + OUT SPCR,A ; SPI SLAVE, SAMPLE ON SCK FALLING EDGE + + ; START -5V GENERATOR TASK + LDI A,0 + OUT TCNT1H,A + OUT TCNT1L,A + OUT OCR1H,A + OUT OCR1L,A ; ASSUME NO LOAD TO BEGIN WITH + + LDI A,1< 0 + OR E,TX_COUNT0 + OR E,TX_COUNT1 + BRNE API_TRY_TX + +;API_TRY_RX: + LDS E,TX_OVERRIDE + DEC E + BREQ API_DIRECTION_TX ; FORCED TRANSMIT EVERY SO OFTEN + STS TX_OVERRIDE,E + RJMP API_DIRECTION_RX + +API_TRY_TX: + LDS E,RX_OVERRIDE + DEC E + BREQ BREQ_API_DIRECTION_RX ; FORCED RECEIVE EVERY SO OFTEN + STS RX_OVERRIDE,E + +API_DIRECTION_TX: + LDI E,$10 + STS TX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + ; SUSPEND TX OPERATIONS WHEN 9TH (INTERNAL) DEVICE ADDRESSED % + TST TX_COUNT0 ; ANY BYTES AT HEAD ? + LDS E,TX_ADDRESS0 + BRNE API_SUSPEND_TX0 ; YES, GO AND CHECK HEAD DEVICE + + TST TX_COUNT1 ; ANY BYTES AT TAIL ? + BREQ API_SUSPEND_TX1 ; NO, GO AND PERFORM TX OPERATION + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE TX_COUNT1 BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 + STS TX_ADDRESS0,E ; ADOPT TAIL DEVICE FOR BYTES AT HEAD + +API_SUSPEND_TX0: + CPI E,9 +BREQ_API_DIRECTION_RX: + BREQ API_DIRECTION_RX + +API_SUSPEND_TX1: + ; % + +; LDS E,ABSENT_COUNT +; TST E +; BRNE API_DEVICE_PRESENT +; +;;API_DEVICE_ABSENT: +; ADD TX_PTR,TX_COUNT0 ; SKIP TX_COUNT0 BYTES AT HEAD +; LDI E,TX_SIZE-1 +; AND TX_PTR,E +; +; CLR TX_COUNT0 ; ABANDON TX_COUNT0 DATA IN TX_BUF +; STS TX_STICKY,TX_COUNT0 ; DO NOT GO STICKY ON ABSENT DEVICE +; +; PUSH ZL +; PUSH ZH +; LDI ZL,TX_LIMIT-1 +; LDS ZH,TX_ADDRESS0 +; ADD ZL,ZH +; CLR ZH +; ;ST Z,TX_COUNT0 ; SAVE MAX BYTES TO ACCEPT, PER DEVICE +; LDI E,TX_SIZE +; ST Z,E ; SO THAT WE WILL GOBBLE UP DATA FOR ABSENT DEVICES +; POP ZH +; POP ZL +; +; LDI E,4 +; STS ABSENT_COUNT,E ; TOP UP ABSENT COUNTER FOR NEXT DEVICE +; +;API_DEVICE_PRESENT: + CBR API_STATE,1< 0 + DEC E + BRPL API_TX_ADDRESS_STICKY ; STAYING STICKY, ADOPT NEW DEVICE + + LDS E,TX_ADDRESS0 + INC E ; BUMP TX_ADDRESS BEFORE USING IT + CPI E,9 + BRLO API_TX_ADDRESS_SAVE + LDI E,1 + RJMP API_TX_ADDRESS_SAVE + +API_TX_ADDRESS_ADOPT: + LDI E,1 +API_TX_ADDRESS_STICKY: + STS TX_STICKY,E ; DECREMENT, OR TOP UP, STICKY COUNT + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 ; DEST FOR TX_COUNT1 BYTES AT HEAD +API_TX_ADDRESS_SAVE: + STS TX_ADDRESS0,E ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_TX_ADDRESS_SAME: + LDI E,1 + STS TX_STICKY,E ; TOP UP STICKY COUNT + + LDS E,TX_ADDRESS0 ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_DIRECTION_RX: + LDI E,$10 + STS RX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + SBR API_STATE,1< $10 + ;MOV E,ATOD + ;LSL ATOD ; $01 HALF SCALE -> $20 + ;ADD E,ATOD ; $01 HALF SCALE -> $30 HALF WIDTH + + LSR ATOD ; $40 HALF SCALE -> $20 + MOV E,ATOD + LSR ATOD ; $40 HALF SCALE -> $10 + ADD E,ATOD ; $40 HALF SCALE -> $30 HALF WIDTH + RJMP ADC_PULSE + +ADC_REFERENCE: + CBR FLAGS,1<<4 ; SAY NEXT RESULT WILL BE -5V GENERATOR + + ;STS VOLTAGE_VSWT,ATOD + ;RJMP ADC_DONE + + SBRC FLAGS,5 ; CURRENT REFERENCE IS BANDGAP ? + RJMP ADC_BANDGAP + + ; CURRENT REFERENCE IS LM385 + CPI ATOD,$F8 ; IF =>$F8 ASSUME WE HAVE PULLUP ONLY + BRLO ADC_LM385 + + LDS E,LM385_COUNT + DEC E ; COUNT DOWN TO MISSING LM385 + STS LM385_COUNT,E + BRNE ADC_DONE ; KEEP TRYING LM385 + + SBR FLAGS,1<<5 ; SAY WE HAVE SWITCHED TO BANDGAP +GO_ADC_DONE: + RJMP ADC_DONE + +ADC_LM385: + LDI E,$10 ; TOP UP COUNTDOWN TO MISSING LM385 + STS LM385_COUNT,E + +; LSR ATOD ; LM385 VOLTAGE = APPROX 2*BANDGAP + ; USE LM385Z-1.2 + +ADC_BANDGAP: + STS VOLTAGE_VSWT,ATOD + + ;CPI ATOD,70 ; 256*1.22/4.5 + ;CPI ATOD,63 ; 256*1.22/5.0 + CPI ATOD,57 ; 256*1.22/5.5 + LDI E,LOW(1024) + LDI F,HIGH(1024) + BRLO ADC_BATTERY_SAVE + + ; VSWT < 5.5 VOLTS, STABILISE READING FOR BATTERY LOW + LDS E,BATTERY_COUNT + LDS F,BATTERY_COUNT+1 + SUBI E,LOW(1) + SBCI F,HIGH(1) + BRNE ADC_BATTERY_SAVE ; COUNT 1024 LOW BATTERY READINGS + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<3 ; SHOW BATTERY MESSAGE AND POWER DOWN + +ADC_BATTERY_SAVE: + STS BATTERY_COUNT,E + STS BATTERY_COUNT+1,F + + ;CPI ATOD,90 ; 256*1.22/3.5 + ;CPI ATOD,79 ; 256*1.22/4.0 + CPI ATOD,70 ; 256*1.22/4.5 + BRLO ADC_DONE + + ; VSWT < 4.5 VOLTS, RESET MAIN PROCESSOR IMMEDIATELY + LDI E,$FF + STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 + + CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM + + LDI E,$FF + LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT +ADC_PULSE: + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + +ADC_DONE: + LDI E,$45 ; START MEASURING BANDGAP + SBRS FLAGS,5 + LDI E,$04 ; START MEASURING LM385 + SBRS FLAGS,4 + LDI E,$05 ; START MEASURING -5V GENERATOR + OUT ADMUX,E + LDI E,$DE + OUT ADCSR,E ; ENABLE A/D, START, SINGLE CONVERSION + + OUT SREG,SR + RETI + +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 5 +; RCALL MULTIPLY +;DIAG_VOLTS_AT_A5: +; ;OUT PORTC,M16U1 ; res in byte 2(ignore ls,byte),volts pin 5 +; MOV A,B ; get saved VSWT +; SUB A,M16U1 ; voltage 47K = VSWT-Voltage at pin 35 +; MOV D,A ; which is 1/3 of total supply ie +V+(-V) +; ADD A,D +; ADD A,D ; TOTAL SUPPLY +; SUB A,B ; TOTAL SUPPLY-VSWT=NEG SUPPLY +;DIAG_NEG: +; ;OUT PORTC,A +; +; LDI A,4 +; OUT ADMUX,A ; NEXT TIME READ VCHG +;ADC_DONE: +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI + +;VSWT: ;OUT PORTC,ATOD ; count value for 2.5 V ref +; LDI A,$FF +; MOV DD16UH,A ; divide by full scale ie VSWT +; SUB DD16UL,DD16UL ; clear low reg +; SUB DV16UH,DV16UH ; clear high reg divisor +; MOV DV16UL,ATOD ; use ATOD value as divisor +; ;OUT PORTC,ATOD +; RCALL DIVIDE ; ***** NOTE AN FF RESULT IS NO INPUT ******* +; MOV MC16UH,DRES16UH ; load multiplicand high from result high +; MOV MC16UL,DRES16UL ; load multiplicand low from result low +; SUB MP16UH,MP16UH ; clear high byte in multiplier reg +; LDI A,25 +; MOV MP16UL,A ; mult by zener ref voltage (2.5V) +; RCALL MULTIPLY +;DIAG_VOLT_VSWT: +;xi: +; LDS A,VSWTS ; previous value of VSWT +; MOV B,MP16UL ; new value of VSWT +; ;RCALL SMOOTH +; STS VSWTS,B +; LDS B,VSWTS +; +; ;OUT PORTC,B;M16U1 ; VSWT IN 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; +; ;STS VSWTS,B ; SAVE NEW SMOOTHED VALUE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; MOV B,M16U1 ; save copy of VSWT for neg 5V routine +; MOV DD16UH,M16U1 +; SUB DD16UL,DD16UL +; LDI A,255 ; calculate the atod volts per division +; MOV DV16UL,A +; SUB DV16UH,DV16UH +; RCALL DIVIDE ; result to be found in dres high & low +; +; LDI A,3 +; OUT ADMUX,A ; NEXT TIME READ VCHG +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;VCHG: +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 37 (1/3 VCHG) +; RCALL MULTIPLY +; MOV A,M16U1 +; ADD M16U1,A ; B\C A3 IS 1/3 VCHG +; ADD M16U1,A +;DIAG_VOLT_VHG: +; ;OUT PORTC,M16U1 ; REUSULT 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; LDI A,5 +; OUT ADMUX,A ; NEXT TIME READ VSWT +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;;*************************************************************************** +;;* +;;* "div16u" - 16/16 Bit Unsigned Division +;;* +;;* This subroutine divides the two 16-bit numbers +;;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). +;;* The result is placed in "dres16uH:dres16uL" and the remainder in +;;* "drem16uH:drem16uL". +;;* +;;* Number of words :19 +;;* Number of cycles :235/251 (Min/Max) +;;* Low registers used :2 (drem16uL,drem16uH) +;;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, +;;* dcnt16u) +;;* +;;*************************************************************************** +;divide: +;div16u: clr drem16uL ;clear remainder Low byte +; sub drem16uH,drem16uH ;clear remainder High byte and carry +; ldi counter,17 ;init loop counter +;d16u_1: rol dd16uL ;shift left dividend +; rol dd16uH +; dec counter ;decrement counter +; brne d16u_2 ;if done +; ret ; return +;d16u_2: rol drem16uL ;shift dividend into remainder +; rol drem16uH +; sub drem16uL,dv16uL ;remainder = remainder - divisor +; sbc drem16uH,dv16uH ; +; brcc d16u_3 ;if result negative +; add drem16uL,dv16uL ; restore remainder +; adc drem16uH,dv16uH +; clc ; clear carry to be shifted into result +; rjmp d16u_1 ;else +;d16u_3: sec ; set carry to be shifted into result +; rjmp d16u_1 +; +;;********* 16 X 16 multiplication routine from app note avr200 ************* +;;* +;;* "mpy16u" - 16x16 Bit Unsigned Multiplication +;;* +;;* This subroutine multiplies the two 16-bit register variables +;;* mp16uH:mp16uL and mc16uH:mc16uL. +;;* The result is placed in m16u3:m16u2:m16u1:m16u0. +;;* +;;* Number of words :14 + return +;;* Number of cycles :153 + return +;;* Low registers used :None +;;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, +;;* m16u3,mcnt16u) +;;* +;;*************************************************************************** +;multiply: +;mpy16u: clr m16u3 ;clear high byte of result +; sub m16u2,m16u2 ;clear result byte 2 and carry +; clr m16u2 +; ldi counter,16 ;init loop counter +; lsr mp16uH +; ror mp16uL +; +;m16u_1: brcc noad8 ;if bit 0 of multiplier set +; add m16u2,mc16uL ;add multiplicand Low to byte 2 of res +; adc m16u3,mc16uH ;add multiplicand high to byte 3 of res +;noad8: ror m16u3 ;shift right result byte 3 +; ror m16u2 ;rotate right result byte 2 +; ror m16u1 ;rotate result byte 1 and multiplier High +; ror m16u0 ;rotate result byte 0 and multiplier Low +; dec counter ;decrement loop counter +; brne m16u_1 ;if not done, loop more +; ret +;;************************* Exponential smoothing routine ******************** +;;Receives : Previous value in A +;; : New value in B +;;Passes : Smoothed result back in B reg +;;Uses : d reg +; +;Smooth: +; mov d,a ; save a copy of previous value +; lsr a +; lsr a +; lsr b +; lsr b ; prev.ave - prev.ave + new.data +; sub d,a ; -------- -------- +; add b,d ; n n +; ret + +; ----------------------------------------------------------------------------- + +MESSAGE_0: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',0,128,$1B + .DB 'E','1' + +MESSAGE_1: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',240,64,$1B + .DB 'E','1' + +MESSAGE_2: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','0','0','0',0 + +MESSAGE_3: + .DB $1B,'S',16,13 + .DB 'W','P','O','3','0',' ','V','5' + +MESSAGE_4: + .DB $1B,'S',16,13 + .DB 'B','A','D',' ','C','O','M','M','A','N','D',0 + +MESSAGE_5: + .DB $1B,'S',16,13 + .DB 'B','A','T','T','E','R','Y',' ','L','O','W',0 + +MESSAGE_6: + .DB $1B,'M','0',0 + +MESSAGE_7: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','5','0','0',0 + +MESSAGE_8: + .DB $1B,'S',16,13 + .DB 'S','T','A','C','K',' ','O','V','E','R','F','L','O','W' + +; ----------------------------------------------------------------------------- + + ; BODEN = 0 ENABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 100 FOR 16K * 11MHZ STARTUP DELAY (NO R/C STARTUP DELAY) + + .ORG $1000 + + .DW $4100 ; SELECT ADDRESS COMMAND + .DW $ACB4 ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/wpov1.asm b/src/avr/wpov1.asm new file mode 100644 index 00000000..cc793ac3 --- /dev/null +++ b/src/avr/wpov1.asm @@ -0,0 +1,2116 @@ +; WPOV1.ASM + +; ----------------------------------------------------------------------------- + +.EQU LARGE =0 + +;IF LARGE +;.INCLUDE "8535DEFX.INC" +;ELSE +.INCLUDE "4433DEF.INC" +;ENDIF + +; ----------------------------------------------------------------------------- + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_TIMEOUT =25 ;50 ;100 ; 100 * 100 US = APPROX 10.0 MS +.EQU API_TIME_IDLE =13 ;25 ; 25 * 100 US = APPROX 2.5 MS +.EQU API_TIME_SLOW =13 ;25 ; 25 * 100 US = APPROX 2.5 MS +.EQU API_TIME_FAST =2 ;1 ;2 ; 2 * 100 US = APPROX 200 US +.EQU API_RATE_SLOW =$8F ;$11 ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$05 ;$11 ; DIVISOR FOR 115200 BPS + +.EQU SPI_TIMEOUT =25 ;50 ;100 ; 100 * 100 US = APPROX 10.0 MS + +;.def drem16uL =R0 ; remainder low +;.def drem16uH =R1 ; remainder high +;.def dres16uL =R2 ; result low DON'T use as general purpose +;.def dres16uH =R3 ; result high DON'T use as general purpose +;.def dd16uL =R2 ; dividend low +;.def dd16uH =R3 ; dividend high +;.def dv16uL =R4 ; divisor low +;.def dv16uH =R5 ; divisor high +; +;.DEF SPI_REMAIN =R6 +; +;.def mc16uL =R7 ;multiplicand low byte +;.def mc16uH =R8 ;multiplicand high byte +;.def mp16uL =R9 ;multiplier low byte +;.def mp16uH =R10 ;multiplier high byte +;.def m16u0 =R9 ;result byte 0 (LSB) +;.def m16u1 =R10 ;result byte 1 +;.def m16u2 =R11 ;result byte 2 +;.def m16u3 =R12 ;result byte 3 (MSB) +; +;.DEF RX_PTR =R13 +;.DEF RX_COUNT0 =R14 + +.DEF API_REMAIN =R1 +.DEF API_WATCHDOG =R2 +.DEF SPI_REMAIN =R3 +.DEF SPI_WATCHDOG =R4 +.DEF RX_PTR =R5 +.DEF RX_COUNT0 =R6 +.DEF RX_COUNT1 =R7 +.DEF TX_PTR =R8 +.DEF TX_COUNT0 =R9 +.DEF TX_COUNT1 =R10 + +.DEF SR =R15 +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R23 +.DEF G =R24 + +.DEF FLAGS =R20 +;.def counter =R20 ;loop counter + +.DEF ATOD =R21 ; SO YOU CAN USE SBCI, SUBI, CPI ETC + +.DEF API_STATE =R22 + +;.DEF TX_PTR =R25 +;.DEF API_WATCHDOG =R26 +;.DEF API_REMAIN =R27 +;.DEF SPI_WATCHDOG =R28 +;.DEF TX_COUNT0 =R29 + +.EQU TX_SIZE =$40 +.EQU RX_SIZE =$10 + + .DSEG + .ORG $60 + +VSWTS: .BYTE 1 ; RETAIN ORDERING % +VCHGS: .BYTE 1 +NEGVS: .BYTE 1 + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +TX_ADDRESS0: .BYTE 1 ; DEST FOR TX_COUNT0 BYTES AT HEAD +TX_ADDRESS1: .BYTE 1 ; DEST FOR TX_COUNT1 BYTES AT TAIL + +RX_ADDRESS0: .BYTE 1 ; SOURCE FOR RX_COUNT0 BYTES AT HEAD +RX_ADDRESS1: .BYTE 1 ; SOURCE FOR RX_COUNT1 BYTES AT TAIL + +RX_ADDRESS2: .BYTE 1 ; ALTERNATE VALUE FOR RX_ADDRESS1 + ; SCAN IS 1,2,1,3,1,4,1,5,1,6,1,7,1,8 + +TX_OVERRIDE: .BYTE 1 ; COUNTER TO TRANSMIT 1 TIME IN 16 +RX_OVERRIDE: .BYTE 1 ; COUNTER TO RECEIVE 1 TIME IN 16 + +TX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME TX DEVICE +RX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME RX DEVICE + +;ABSENT_COUNT: .BYTE 1 + +TURNOFF_COUNT: .BYTE 1 +WATCHDOG_COUNT: .BYTE 2 + +TX_LIMIT: .BYTE 9 ; MAX Z180 BYTES TO ACCEPT, PER DEVICE + +BATTERY_COUNT: .BYTE 2 ; COUNT 1024 ADC READINGS TO POWER DOWN + +LM385_COUNT: .BYTE 1 ; COUNT $10 ADC READINGS TO MISSING REF +VOLTAGE_VSWT: .BYTE 1 ; MOST RECENT ADC READING FROM REF + +HARDWARE_TYPE: .BYTE 1 ; COMES SOMEWHAT BEFORE RSEL HI COMMAND + +STACK_GUARD: .BYTE 1 ; DETECTS IF STACK COMES DOWN TO HERE + +; ----------------------------------------------------------------------------- + +; API_STATE DEFINITIONS +.EQU SPISIZE =0 ; SET IF EXPECTING SPI DATA SIZE CMD +.EQU SPIWAIT =1 ; SET IF SENDING SPI ADDRESS RESPONSE +.EQU SPIDATA =2 ; SET IF TRANSFERRING SPI DATA TX/RX +.EQU SPIDIRN =3 ; SET IF TX, BASED ON ADDRESS COMMAND +.EQU APISIZE =4 ; SET IF NEED TO SEND API DATA SIZE CMD +.EQU APIWAIT =5 ; SET IF WAITING FOR API DATA SIZE RESP +.EQU APIDATA =6 ; SET IF TRANSFERRING API DATA TX/RX +.EQU APIDIRN =7 ; SET IF TX, TOGGLED ON NULL TRANSFER + +; ----------------------------------------------------------------------------- + +;IF LARGE +; +;.EQU IRQ =6 +;.EQU IRQ_PORT =PORTA +;.EQU IRQ_DDR =DDRA +; +;.EQU PRG =3 +;.EQU PRG_PORT =PORTB +;.EQU PRG_DDR =DDRB +; +;.EQU OC1 =5 +;.EQU OC1_PORT =PORTD +;.EQU OC1_DDR =DDRD +; +;.EQU OCR1H =OCR1AH +;.EQU OCR1L =OCR1AL +; +;.EQU COM10 =COM1A0 +;.EQU COM11 =COM1A1 +; +;ELSE + +.EQU IRQ =0 +.EQU IRQ_PORT =PORTB +.EQU IRQ_DDR =DDRB +; +.EQU PRG =2 +.EQU PRG_PORT =PORTC +.EQU PRG_DDR =DDRC + +.EQU OC1 =1 +.EQU OC1_PORT =PORTB +.EQU OC1_DDR =DDRB + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +;ENDIF + +; ----------------------------------------------------------------------------- + + .CSEG + + RJMP RESET_ENTRY + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER 0 OVERFLOW HANDLER + + .ORG SPIADDR + RJMP SPI_COMPLETE ; SPI TRANSFER COMPLETE HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + + .ORG ADCCaddr + RJMP ADC_COMPLETE + +; ----------------------------------------------------------------------------- + +RESET_ENTRY: + ; INITIALISE AVR +;IF LARGE +; LDI A,HIGH(RAMEND) +; OUT SPH,A +;ENDIF + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + ; INITIALISE STACK GUARD + LDI A,$5A + STS STACK_GUARD,A + + ; INITIALISE PORTS + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + LDI A,0 + OUT SPCR,A ; DISABLE SPI WHILE RESETTING Z180 + OUT UCR,A ; DISABLE UART WHILE RESETTING SLAVES + +;IF LARGE +; LDI A,$FF +; OUT DDRC,A ; PORTC CONFIGURED AS OUTPUT +; +; SBI PORTB,7 ; PB7/SCK CONFIGURED AS PULLED UP INPUT +; SBI DDRB,6 ; PB6/MISO CONFIGURED AS OUTPUT +; +; SBI DDRA,7 ; A7 CONFIGURED AS OUTPUT FOR DTR1 +; SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 +; +;; 18DEC01 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +;; SBI PORTA,4 ; A4 PULLED UP TO DETECT MISSING LM385 +;ELSE + SBI PORTB,5 ; PB5/SCK CONFIGURED AS PULLED UP INPUT + SBI DDRB,4 ; PB4/MISO CONFIGURED AS OUTPUT + + SBI DDRD,5 ; D5 CONFIGURED AS OUTPUT FOR DTR1 + SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 + + SBI PORTC,4 ; C4 PULLED UP TO DETECT MISSING LM385 +;ENDIF + + SBI PORTD,2 ; D2 CONFIGURED AS PULL UP FOR IBM CLK + SBI PORTD,3 ; D3 CONFIGURED AS PULL UP FOR IBM DATA + + SBI OC1_PORT,OC1 + SBI OC1_DDR,OC1 ; OUTPUT OC1 = 1, PWM TRANSISTOR OFF + + CBI IRQ_PORT,IRQ + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + CBI PORTD,7 + SBI DDRD,7 ; OUTPUT RSEL = 0 + + CBI PORTD,4 + SBI DDRD,4 ; OUTPUT RES = 0 + + ; HARD RESET API BUS DEVICES + CBI PRG_PORT,PRG + SBI PRG_DDR,PRG ; OUTPUT PRG = 0 + + CBI PORTD,1 + SBI DDRD,1 ; OUTPUT TXD = 0 + + LDI A,7 + RCALL PRG_RESET ; SPECIFIC RESET SPARE + + LDI A,6 + RCALL PRG_RESET ; SPECIFIC RESET M192 RECEIPT PRINTER + + LDI A,5 + RCALL PRG_RESET ; SPECIFIC RESET M192 LABEL PRINTER + + LDI A,4 + RCALL PRG_RESET ; SPECIFIC RESET MT102 RECEIPT PRINTER + + ;LDI A,3 + ;RCALL PRG_RESET ; SPECIFIC RESET SPARE + ; THE ABOVE SHOULD BE OK - WHY NOT ?? 16FEB01 + + ;LDI A,2 + ;RCALL PRG_RESET ; SPECIFIC RESET TOUCHSCREEN + + LDI A,1 + RCALL PRG_RESET ; SPECIFIC RESET CUSTOMER DISPLAY + + LDI A,0 + RCALL PRG_RESET ; REMOVE RESET PULSE + + ; LOADCELL HAS BEEN IN RESET UNTIL NOW, AND WILL START IN 10 MS + + ;SBI PORTD,1 ; OUTPUT TXD = 1 + + LDI A,API_RATE_SLOW ; 4800 BAUD + OUT UBRR,A ; SET BAUD RATE + LDI A,$18 + OUT UCR,A ; ENABLE TX AND RX (OUTPUTS TXD = 1) + + RCALL PRG_DELAY_280_MS ; DELAY FOR TOUCHSCREEN TO REENTER IDLE + + LDI A,$AA + OUT UDR,A ; SEND SLOW TURNON COMMAND + OUT UDR,A ; AND AGAIN FOR EXTRA SAFETY + + RCALL PRG_DELAY_20_MS ; DELAY TO ALLOW DEVICES TO INITIALISE + + ; ALLOW Z180 TO START + SBI PORTD,4 ; OUTPUT RES = 1 + ;CBI DDRD,4 ; OUTPUT RES = TRI-STATE + +; BIGBODGE FOR ANOTHER RESET PULSE!!!! (LARGE AVR ONLY, AT THE MOMENT) +;RCALL PRG_DELAY_20_MS +;CBI PORTD,4 ; RES=0 +;RCALL PRG_DELAY_20_MS +;SBI PORTD,4 ; OUTPUT RES = 1 + + ; INITIALISE VARIABLES + CLR A + LDI ZL,VSWTS + CLR ZH + ST Z+,A + ST Z+,A + ST Z+,A + LDI ZL,TX_LIMIT + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A ; CAREFUL - Z WILL BE USED AGAIN BELOW + STS TURNOFF_COUNT,A + STS VOLTAGE_VSWT,A + + ;LDI A,LOW(1000) + STS WATCHDOG_COUNT,A + ;LDI A,HIGH(1000) ; 100 MS + STS WATCHDOG_COUNT+1,A + + LDI A,TX_SIZE + ST Z,A ; RX_LIMIT FOR 9TH (INTERNAL) DEVICE + + LDI A,LOW(1024) + STS BATTERY_COUNT,A + LDI A,HIGH(1024) + STS BATTERY_COUNT+1,A + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION % + LDI A,$10 ; START COUNTDOWN TO MISSING LM385 + STS LM385_COUNT,A +; (BUT REMAINS FOR HYT1000) % + CLR FLAGS + + CLR API_STATE + CLR API_REMAIN + + CLR TX_PTR + CLR TX_COUNT0 + CLR TX_COUNT1 + + CLR RX_PTR + CLR RX_COUNT0 + CLR RX_COUNT1 + +; LDI A,4 +; STS ABSENT_COUNT,A ; TOP UP ABSENT COUNTER FOR TX_ADDRESS + + ; START COMMUNICATIONS TASK + LDI A,2 + STS RX_ADDRESS2,A ; ALTERNATE VALUE FOR RX_ADDRESS1 + + LDI A,1 + STS TX_ADDRESS0,A + STS TX_ADDRESS1,A + STS RX_ADDRESS0,A + STS RX_ADDRESS1,A + STS TX_OVERRIDE,A + STS RX_OVERRIDE,A + STS HARDWARE_TYPE,A ; AS FOR OLD ALGORITHM WITH FLAGS,2 = 0 + + LDI A,0 + STS TX_STICKY,A + STS RX_STICKY,A + + LDI A,-API_TIMEOUT + MOV API_WATCHDOG,A ; SET UP TIME TO FIRST API BUS POLL + LDI A,-SPI_TIMEOUT + MOV SPI_WATCHDOG,A ; SET UP TIME TO FIRST SPI BUS POLL + + LDI A,$02 ; TCK0 = CK/8 + OUT TCCR0,A ; TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ + ; = APPROX 278 US + ;!TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ + ;! = APPROX 185 US +;IF LARGE +; LDI A,$01 +;ELSE + LDI A,$02 +;ENDIF + OUT TIMSK,A ; ENABLE TIMER 0 OVERFLOW INTERRUPTS + + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + IN A,SPSR + IN A,SPDR ; CLEAR SPI INTERRUPT PENDING FLAG + LDI A,$E8 + OUT SPCR,A ; SPI SLAVE, SAMPLE ON SCK FALLING EDGE + + ; START -5V GENERATOR TASK + LDI A,0 + OUT TCNT1H,A + OUT TCNT1L,A + OUT OCR1H,A + OUT OCR1L,A ; ASSUME NO LOAD TO BEGIN WITH + + LDI A,1< 0 + OR E,TX_COUNT0 + OR E,TX_COUNT1 + BRNE API_TRY_TX + +;API_TRY_RX: + LDS E,TX_OVERRIDE + DEC E + BREQ API_DIRECTION_TX ; FORCED TRANSMIT EVERY SO OFTEN + STS TX_OVERRIDE,E + RJMP API_DIRECTION_RX + +API_TRY_TX: + LDS E,RX_OVERRIDE + DEC E + BREQ BREQ_API_DIRECTION_RX ; FORCED RECEIVE EVERY SO OFTEN + STS RX_OVERRIDE,E + +API_DIRECTION_TX: + LDI E,$10 + STS TX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + ; SUSPEND TX OPERATIONS WHEN 9TH (INTERNAL) DEVICE ADDRESSED % + TST TX_COUNT0 ; ANY BYTES AT HEAD ? + LDS E,TX_ADDRESS0 + BRNE API_SUSPEND_TX0 ; YES, GO AND CHECK HEAD DEVICE + + TST TX_COUNT1 ; ANY BYTES AT TAIL ? + BREQ API_SUSPEND_TX1 ; NO, GO AND PERFORM TX OPERATION + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE TX_COUNT1 BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 + STS TX_ADDRESS0,E ; ADOPT TAIL DEVICE FOR BYTES AT HEAD + +API_SUSPEND_TX0: + CPI E,9 +BREQ_API_DIRECTION_RX: + BREQ API_DIRECTION_RX + +API_SUSPEND_TX1: + ; % + +; LDS E,ABSENT_COUNT +; TST E +; BRNE API_DEVICE_PRESENT +; +;;API_DEVICE_ABSENT: +; ADD TX_PTR,TX_COUNT0 ; SKIP TX_COUNT0 BYTES AT HEAD +; LDI E,TX_SIZE-1 +; AND TX_PTR,E +; +; CLR TX_COUNT0 ; ABANDON TX_COUNT0 DATA IN TX_BUF +; STS TX_STICKY,TX_COUNT0 ; DO NOT GO STICKY ON ABSENT DEVICE +; +; PUSH ZL +; PUSH ZH +; LDI ZL,TX_LIMIT-1 +; LDS ZH,TX_ADDRESS0 +; ADD ZL,ZH +; CLR ZH +; ;ST Z,TX_COUNT0 ; SAVE MAX BYTES TO ACCEPT, PER DEVICE +; LDI E,TX_SIZE +; ST Z,E ; SO THAT WE WILL GOBBLE UP DATA FOR ABSENT DEVICES +; POP ZH +; POP ZL +; +; LDI E,4 +; STS ABSENT_COUNT,E ; TOP UP ABSENT COUNTER FOR NEXT DEVICE +; +;API_DEVICE_PRESENT: + CBR API_STATE,1< 0 + DEC E + BRPL API_TX_ADDRESS_STICKY ; STAYING STICKY, ADOPT NEW DEVICE + + LDS E,TX_ADDRESS0 + INC E ; BUMP TX_ADDRESS BEFORE USING IT + CPI E,9 + BRLO API_TX_ADDRESS_SAVE + LDI E,1 + RJMP API_TX_ADDRESS_SAVE + +API_TX_ADDRESS_ADOPT: + LDI E,1 +API_TX_ADDRESS_STICKY: + STS TX_STICKY,E ; DECREMENT, OR TOP UP, STICKY COUNT + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 ; DEST FOR TX_COUNT1 BYTES AT HEAD +API_TX_ADDRESS_SAVE: + STS TX_ADDRESS0,E ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_TX_ADDRESS_SAME: + LDI E,1 + STS TX_STICKY,E ; TOP UP STICKY COUNT + + LDS E,TX_ADDRESS0 ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_DIRECTION_RX: + LDI E,$10 + STS RX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + SBR API_STATE,1< $10 + ;MOV E,ATOD + ;LSL ATOD ; $01 HALF SCALE -> $20 + ;ADD E,ATOD ; $01 HALF SCALE -> $30 HALF WIDTH + + LSR ATOD ; $40 HALF SCALE -> $20 + MOV E,ATOD + LSR ATOD ; $40 HALF SCALE -> $10 + ADD E,ATOD ; $40 HALF SCALE -> $30 HALF WIDTH + RJMP ADC_PULSE + +ADC_REFERENCE: + CBR FLAGS,1<<4 ; SAY NEXT RESULT WILL BE -5V GENERATOR + + ;STS VOLTAGE_VSWT,ATOD + ;RJMP ADC_DONE + + SBRC FLAGS,5 ; CURRENT REFERENCE IS BANDGAP ? + RJMP ADC_BANDGAP + + ; CURRENT REFERENCE IS LM385 + CPI ATOD,$F8 ; IF =>$F8 ASSUME WE HAVE PULLUP ONLY + BRLO ADC_LM385 + + LDS E,LM385_COUNT + DEC E ; COUNT DOWN TO MISSING LM385 + STS LM385_COUNT,E + BRNE ADC_DONE ; KEEP TRYING LM385 + + SBR FLAGS,1<<5 ; SAY WE HAVE SWITCHED TO BANDGAP +GO_ADC_DONE: + RJMP ADC_DONE + +ADC_LM385: + LDI E,$10 ; TOP UP COUNTDOWN TO MISSING LM385 + STS LM385_COUNT,E + +; LSR ATOD ; LM385 VOLTAGE = APPROX 2*BANDGAP + ; USE LM385Z-1.2 + +ADC_BANDGAP: + STS VOLTAGE_VSWT,ATOD + + ;CPI ATOD,70 ; 256*1.22/4.5 + ;CPI ATOD,63 ; 256*1.22/5.0 + CPI ATOD,57 ; 256*1.22/5.5 + LDI E,LOW(1024) + LDI F,HIGH(1024) + BRLO ADC_BATTERY_SAVE + + ; VSWT < 5.5 VOLTS, STABILISE READING FOR BATTERY LOW + LDS E,BATTERY_COUNT + LDS F,BATTERY_COUNT+1 + SUBI E,LOW(1) + SBCI F,HIGH(1) + BRNE ADC_BATTERY_SAVE ; COUNT 1024 LOW BATTERY READINGS + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<3 ; SHOW BATTERY MESSAGE AND POWER DOWN + +ADC_BATTERY_SAVE: + STS BATTERY_COUNT,E + STS BATTERY_COUNT+1,F + + ;CPI ATOD,90 ; 256*1.22/3.5 + ;CPI ATOD,79 ; 256*1.22/4.0 + CPI ATOD,70 ; 256*1.22/4.5 + BRLO ADC_DONE + + ; VSWT < 4.5 VOLTS, RESET MAIN PROCESSOR IMMEDIATELY + LDI E,$FF + STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 + + CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM + + LDI E,$FF + LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT +ADC_PULSE: + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + +ADC_DONE: + LDI E,$45 ; START MEASURING BANDGAP + SBRS FLAGS,5 + LDI E,$04 ; START MEASURING LM385 + SBRS FLAGS,4 + LDI E,$05 ; START MEASURING -5V GENERATOR + OUT ADMUX,E + LDI E,$DE + OUT ADCSR,E ; ENABLE A/D, START, SINGLE CONVERSION + + OUT SREG,SR + RETI + +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 5 +; RCALL MULTIPLY +;DIAG_VOLTS_AT_A5: +; ;OUT PORTC,M16U1 ; res in byte 2(ignore ls,byte),volts pin 5 +; MOV A,B ; get saved VSWT +; SUB A,M16U1 ; voltage 47K = VSWT-Voltage at pin 35 +; MOV D,A ; which is 1/3 of total supply ie +V+(-V) +; ADD A,D +; ADD A,D ; TOTAL SUPPLY +; SUB A,B ; TOTAL SUPPLY-VSWT=NEG SUPPLY +;DIAG_NEG: +; ;OUT PORTC,A +; +; LDI A,4 +; OUT ADMUX,A ; NEXT TIME READ VCHG +;ADC_DONE: +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI + +;VSWT: ;OUT PORTC,ATOD ; count value for 2.5 V ref +; LDI A,$FF +; MOV DD16UH,A ; divide by full scale ie VSWT +; SUB DD16UL,DD16UL ; clear low reg +; SUB DV16UH,DV16UH ; clear high reg divisor +; MOV DV16UL,ATOD ; use ATOD value as divisor +; ;OUT PORTC,ATOD +; RCALL DIVIDE ; ***** NOTE AN FF RESULT IS NO INPUT ******* +; MOV MC16UH,DRES16UH ; load multiplicand high from result high +; MOV MC16UL,DRES16UL ; load multiplicand low from result low +; SUB MP16UH,MP16UH ; clear high byte in multiplier reg +; LDI A,25 +; MOV MP16UL,A ; mult by zener ref voltage (2.5V) +; RCALL MULTIPLY +;DIAG_VOLT_VSWT: +;xi: +; LDS A,VSWTS ; previous value of VSWT +; MOV B,MP16UL ; new value of VSWT +; ;RCALL SMOOTH +; STS VSWTS,B +; LDS B,VSWTS +; +; ;OUT PORTC,B;M16U1 ; VSWT IN 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; +; ;STS VSWTS,B ; SAVE NEW SMOOTHED VALUE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; MOV B,M16U1 ; save copy of VSWT for neg 5V routine +; MOV DD16UH,M16U1 +; SUB DD16UL,DD16UL +; LDI A,255 ; calculate the atod volts per division +; MOV DV16UL,A +; SUB DV16UH,DV16UH +; RCALL DIVIDE ; result to be found in dres high & low +; +; LDI A,3 +; OUT ADMUX,A ; NEXT TIME READ VCHG +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;VCHG: +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 37 (1/3 VCHG) +; RCALL MULTIPLY +; MOV A,M16U1 +; ADD M16U1,A ; B\C A3 IS 1/3 VCHG +; ADD M16U1,A +;DIAG_VOLT_VHG: +; ;OUT PORTC,M16U1 ; REUSULT 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; LDI A,5 +; OUT ADMUX,A ; NEXT TIME READ VSWT +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;;*************************************************************************** +;;* +;;* "div16u" - 16/16 Bit Unsigned Division +;;* +;;* This subroutine divides the two 16-bit numbers +;;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). +;;* The result is placed in "dres16uH:dres16uL" and the remainder in +;;* "drem16uH:drem16uL". +;;* +;;* Number of words :19 +;;* Number of cycles :235/251 (Min/Max) +;;* Low registers used :2 (drem16uL,drem16uH) +;;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, +;;* dcnt16u) +;;* +;;*************************************************************************** +;divide: +;div16u: clr drem16uL ;clear remainder Low byte +; sub drem16uH,drem16uH ;clear remainder High byte and carry +; ldi counter,17 ;init loop counter +;d16u_1: rol dd16uL ;shift left dividend +; rol dd16uH +; dec counter ;decrement counter +; brne d16u_2 ;if done +; ret ; return +;d16u_2: rol drem16uL ;shift dividend into remainder +; rol drem16uH +; sub drem16uL,dv16uL ;remainder = remainder - divisor +; sbc drem16uH,dv16uH ; +; brcc d16u_3 ;if result negative +; add drem16uL,dv16uL ; restore remainder +; adc drem16uH,dv16uH +; clc ; clear carry to be shifted into result +; rjmp d16u_1 ;else +;d16u_3: sec ; set carry to be shifted into result +; rjmp d16u_1 +; +;;********* 16 X 16 multiplication routine from app note avr200 ************* +;;* +;;* "mpy16u" - 16x16 Bit Unsigned Multiplication +;;* +;;* This subroutine multiplies the two 16-bit register variables +;;* mp16uH:mp16uL and mc16uH:mc16uL. +;;* The result is placed in m16u3:m16u2:m16u1:m16u0. +;;* +;;* Number of words :14 + return +;;* Number of cycles :153 + return +;;* Low registers used :None +;;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, +;;* m16u3,mcnt16u) +;;* +;;*************************************************************************** +;multiply: +;mpy16u: clr m16u3 ;clear high byte of result +; sub m16u2,m16u2 ;clear result byte 2 and carry +; clr m16u2 +; ldi counter,16 ;init loop counter +; lsr mp16uH +; ror mp16uL +; +;m16u_1: brcc noad8 ;if bit 0 of multiplier set +; add m16u2,mc16uL ;add multiplicand Low to byte 2 of res +; adc m16u3,mc16uH ;add multiplicand high to byte 3 of res +;noad8: ror m16u3 ;shift right result byte 3 +; ror m16u2 ;rotate right result byte 2 +; ror m16u1 ;rotate result byte 1 and multiplier High +; ror m16u0 ;rotate result byte 0 and multiplier Low +; dec counter ;decrement loop counter +; brne m16u_1 ;if not done, loop more +; ret +;;************************* Exponential smoothing routine ******************** +;;Receives : Previous value in A +;; : New value in B +;;Passes : Smoothed result back in B reg +;;Uses : d reg +; +;Smooth: +; mov d,a ; save a copy of previous value +; lsr a +; lsr a +; lsr b +; lsr b ; prev.ave - prev.ave + new.data +; sub d,a ; -------- -------- +; add b,d ; n n +; ret + +; ----------------------------------------------------------------------------- + +MESSAGE_0: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',0,128,$1B + .DB 'E','1' + +MESSAGE_1: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',240,64,$1B + .DB 'E','1' + +MESSAGE_2: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','0','0','0',0 + +MESSAGE_3: + .DB $1B,'S',16,13 + .DB 'W','P','O','3','0',' ','V','5' + +MESSAGE_4: + .DB $1B,'S',16,13 + .DB 'B','A','D',' ','C','O','M','M','A','N','D',0 + +MESSAGE_5: + .DB $1B,'S',16,13 + .DB 'B','A','T','T','E','R','Y',' ','L','O','W',0 + +MESSAGE_6: + .DB $1B,'M','0',0 + +MESSAGE_7: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','5','0','0',0 + +MESSAGE_8: + .DB $1B,'S',16,13 + .DB 'S','T','A','C','K',' ','O','V','E','R','F','L','O','W' + +; ----------------------------------------------------------------------------- + + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 100 FOR 16K * 11MHZ STARTUP DELAY (NO R/C STARTUP DELAY) + + .ORG $1000 + + .DW $4100 ; SELECT ADDRESS COMMAND + .DW $ACBC ; WRITE FUSE BITS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/avr/wpov2.asm b/src/avr/wpov2.asm new file mode 100644 index 00000000..665c1456 --- /dev/null +++ b/src/avr/wpov2.asm @@ -0,0 +1,2198 @@ +; WPOV2.ASM +; COPIED FROM WPO15V1.ASM ON 20JUN02 + +; LOOK FOR BIGBODGE TO SEE CEC'S CHANGES TO FIX STARTUP PROBLEM +; AND TO SKIP VOLTAGE MEASURING + +; REVISED 17DEC01 TO SUPPORT NEW HARDWARE TYPE 3 FOR HYT1500 + +; REVISED 18DEC01 TO TRY A CONSERVATIVE 4.5 VOLT SHUTDOWN, LOW BATTERY +; THIS DOESN'T PROTECT AGAINST REBOOTING WHILE PRINTING, TOO BAD + +; REVISED 18DEC01 TO TRY AN AGGRESSIVE 5.5 VOLT SHUTDOWN, LOW BATTERY +; ALSO ENABLED THE 4.5 VOLT IMMEDIATE RESET, DUE TO UNRELIABLE OPERATION +; NOW TRYING 5.0 VOLT IMMEDIATE RESET, CEC SAYS IT WAS MARGINAL ANYWAY + +; NOW DISABLED THE IMMEDIATE RESET DUE TO TESTING RESULTS OF 08JAN02 +; NOT SURE IF THAT WAS REALLY THE PROBLEM - BUT WISH TO BE CONSERVATIVE + +; REVISED 01FEB02 FOR NEW 7.3728 MHZ XTAL, PREVIOUSLY 11.0592 MHZ, 2/3 +; LOOK FOR ;! TO SEE CHANGES FOR 7.3728 MHZ XTAL, ADDED COMMENTS ALSO + +; ----------------------------------------------------------------------------- + +.EQU LARGE =0 + +;IF LARGE +;.INCLUDE "8535DEF.INC" +;ELSE +.INCLUDE "4433DEF.INC" +;ENDIF + +; ----------------------------------------------------------------------------- +; API BUS TIMING CALCULATIONS: + +; 115200 BITS/SEC = 11520 BYTES/SEC = 86.8 US/BYTE + +; FOR MASTER API BUS TX, SEND 1 BYTE PER 9+12 BIT-TIMES, 24 TO BE SAFE +; SO THE CORRECT TX RATE = 86.8 * 2.4 = 200.8 US/BYTE = 4980 BYTES/SEC + +; A SUBTLE OPTIMISATION IS POSSIBLE WHEN THE PREVIOUS TRANSMITTED LSB IS 0, +; AS WE CAN THEN GUARANTEE THE 4800 BPS RECEIVERS WILL SEE FALSE START BIT: + +; FOR MASTER API BUS TX EVEN, SEND 1 BYTE PER 2+12 BIT-TIMES, 16 TO BE SAFE +; SO THE CORRECT TX RATE EVEN = 86.8 * 1.6 = 138.9 US/BYTE = 7199 BYTES/SEC + +; OLD: TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ = APPROX 185 US +; NEW: TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ = APPROX 278 US +; THUS ALL THE TIMEOUT VALUES BELOW HAVE BEEN DECREASED TO 2/3 ORIGINAL + +; NEW: THE EVEN/ODD TX RATE OPTIMISATION HAS BEEN DISABLED AS WE DON'T +; HAVE ENOUGH RESOLUTION WITH THE 7.3728 MHZ XTAL / 8 TO GENERATE 138.9 +; US/BYTE DELAY, BECAUSE MINIMUM UNIT IS NOW 278 US INSTEAD OF 185 US, +; THIS COULD BE IMPROVED LATER, BUT FOR NOW, WE GENERATE AN INTERRUPT +; EVERY 278 US, AND THE NEXT AVAILABLE TCK0 DIVIDER IS /1 SO THIS WOULD +; BECOME 34.8 US, THIS WOULD BE UNACCEPTABLE, SO REVISIT THE ISSUE LATER + +.EQU RAM =$60 ; START OF SRAM + +.EQU API_TIMEOUT =16 ;!25 ; 25 * 0.185 MS = 4.6 MS +.EQU API_TIME_IDLE =8 ;!13 ; 13 * 0.185 MS = 2.4 MS +.EQU API_TIME_SLOW =8 ;!13 ; 25 * 0.185 MS = 2.4 MS +.EQU API_TIME_FAST =1 ;!2 ; 2 * 185 US = 370 US, NOW 1 * 278 US +.EQU API_RATE_SLOW =$5F ;!$8F ; DIVISOR FOR 4800 BPS +.EQU API_RATE_FAST =$03 ;!$05 ; DIVISOR FOR 115200 BPS + +.EQU SPI_TIMEOUT =16 ;!25 ; 100 * 100 US = APPROX 10.0 MS + +;.def drem16uL =R0 ; remainder low +;.def drem16uH =R1 ; remainder high +;.def dres16uL =R2 ; result low DON'T use as general purpose +;.def dres16uH =R3 ; result high DON'T use as general purpose +;.def dd16uL =R2 ; dividend low +;.def dd16uH =R3 ; dividend high +;.def dv16uL =R4 ; divisor low +;.def dv16uH =R5 ; divisor high +; +;.DEF SPI_REMAIN =R6 +; +;.def mc16uL =R7 ;multiplicand low byte +;.def mc16uH =R8 ;multiplicand high byte +;.def mp16uL =R9 ;multiplier low byte +;.def mp16uH =R10 ;multiplier high byte +;.def m16u0 =R9 ;result byte 0 (LSB) +;.def m16u1 =R10 ;result byte 1 +;.def m16u2 =R11 ;result byte 2 +;.def m16u3 =R12 ;result byte 3 (MSB) +; +;.DEF RX_PTR =R13 +;.DEF RX_COUNT0 =R14 + +.DEF API_REMAIN =R1 +.DEF API_WATCHDOG =R2 +.DEF SPI_REMAIN =R3 +.DEF SPI_WATCHDOG =R4 +.DEF RX_PTR =R5 +.DEF RX_COUNT0 =R6 +.DEF RX_COUNT1 =R7 +.DEF TX_PTR =R8 +.DEF TX_COUNT0 =R9 +.DEF TX_COUNT1 =R10 + +.DEF SR =R15 +.DEF A =R16 ; GLOBAL REGISTERS +.DEF B =R17 +.DEF D =R18 +.DEF E =R19 +.DEF F =R23 +.DEF G =R24 + +.DEF FLAGS =R20 +;.def counter =R20 ;loop counter + +.DEF ATOD =R21 ; SO YOU CAN USE SBCI, SUBI, CPI ETC + +.DEF API_STATE =R22 + +;.DEF TX_PTR =R25 +;.DEF API_WATCHDOG =R26 +;.DEF API_REMAIN =R27 +;.DEF SPI_WATCHDOG =R28 +;.DEF TX_COUNT0 =R29 + +.EQU TX_SIZE =$40 +.EQU RX_SIZE =$10 + + .DSEG + .ORG $60 + +VSWTS: .BYTE 1 ; RETAIN ORDERING % +VCHGS: .BYTE 1 +NEGVS: .BYTE 1 + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +TX_ADDRESS0: .BYTE 1 ; DEST FOR TX_COUNT0 BYTES AT HEAD +TX_ADDRESS1: .BYTE 1 ; DEST FOR TX_COUNT1 BYTES AT TAIL + +RX_ADDRESS0: .BYTE 1 ; SOURCE FOR RX_COUNT0 BYTES AT HEAD +RX_ADDRESS1: .BYTE 1 ; SOURCE FOR RX_COUNT1 BYTES AT TAIL + +RX_ADDRESS2: .BYTE 1 ; ALTERNATE VALUE FOR RX_ADDRESS1 + ; SCAN IS 1,2,1,3,1,4,1,5,1,6,1,7,1,8 + +TX_OVERRIDE: .BYTE 1 ; COUNTER TO TRANSMIT 1 TIME IN 16 +RX_OVERRIDE: .BYTE 1 ; COUNTER TO RECEIVE 1 TIME IN 16 + +TX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME TX DEVICE +RX_STICKY: .BYTE 1 ; COUNTER TO STAY ON SAME RX DEVICE + +;ABSENT_COUNT: .BYTE 1 + +TURNOFF_COUNT: .BYTE 1 +WATCHDOG_COUNT: .BYTE 2 + +TX_LIMIT: .BYTE 9 ; MAX Z180 BYTES TO ACCEPT, PER DEVICE + +BATTERY_COUNT: .BYTE 2 ; COUNT 1024 ADC READINGS TO POWER DOWN + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +;LM385_COUNT: .BYTE 1 ; COUNT $10 ADC READINGS TO MISSING REF +VOLTAGE_VSWT: .BYTE 1 ; MOST RECENT ADC READING FROM REF + +HARDWARE_TYPE: .BYTE 1 ; COMES SOMEWHAT BEFORE RSEL HI COMMAND + +STACK_GUARD: .BYTE 1 ; DETECTS IF STACK COMES DOWN TO HERE + +; ----------------------------------------------------------------------------- + +; API_STATE DEFINITIONS +.EQU SPISIZE =0 ; SET IF EXPECTING SPI DATA SIZE CMD +.EQU SPIWAIT =1 ; SET IF SENDING SPI ADDRESS RESPONSE +.EQU SPIDATA =2 ; SET IF TRANSFERRING SPI DATA TX/RX +.EQU SPIDIRN =3 ; SET IF TX, BASED ON ADDRESS COMMAND +.EQU APISIZE =4 ; SET IF NEED TO SEND API DATA SIZE CMD +.EQU APIWAIT =5 ; SET IF WAITING FOR API DATA SIZE RESP +.EQU APIDATA =6 ; SET IF TRANSFERRING API DATA TX/RX +.EQU APIDIRN =7 ; SET IF TX, TOGGLED ON NULL TRANSFER + +; ----------------------------------------------------------------------------- + +;IF LARGE +; +;.EQU IRQ =6 +;.EQU IRQ_PORT =PORTA +;.EQU IRQ_DDR =DDRA +; +;.EQU PRG =3 +;.EQU PRG_PORT =PORTB +;.EQU PRG_DDR =DDRB +; +;.EQU OC1 =5 +;.EQU OC1_PORT =PORTD +;.EQU OC1_DDR =DDRD +; +;.EQU OCR1H =OCR1AH +;.EQU OCR1L =OCR1AL +; +;.EQU COM10 =COM1A0 +;.EQU COM11 =COM1A1 +; +;ELSE + +.EQU IRQ =0 +.EQU IRQ_PORT =PORTB +.EQU IRQ_DDR =DDRB + +.EQU PRG =2 +.EQU PRG_PORT =PORTC +.EQU PRG_DDR =DDRC + +.EQU OC1 =1 +.EQU OC1_PORT =PORTB +.EQU OC1_DDR =DDRB + +.EQU USR =UCSRA +.EQU UCR =UCSRB + +;ENDIF + +; ----------------------------------------------------------------------------- + + .CSEG + + RJMP RESET_ENTRY + + .ORG OVF0ADDR + RJMP T0_OVERFLOW ; TIMER 0 OVERFLOW HANDLER + + .ORG SPIADDR + RJMP SPI_COMPLETE ; SPI TRANSFER COMPLETE HANDLER + + .ORG URXCADDR + RJMP RX_COMPLETE ; UART RX COMPLETE HANDLER + + .ORG ADCCaddr + RJMP ADC_COMPLETE + +; ----------------------------------------------------------------------------- + +RESET_ENTRY: + ; INITIALISE AVR +;IF LARGE +; LDI A,HIGH(RAMEND) +; OUT SPH,A +;ENDIF + LDI A,LOW(RAMEND) + OUT SPL,A ; INIT STACK POINTER + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + ; INITIALISE STACK GUARD + LDI A,$5A + STS STACK_GUARD,A + + ; INITIALISE PORTS + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + LDI A,0 + OUT SPCR,A ; DISABLE SPI WHILE RESETTING Z180 + OUT UCR,A ; DISABLE UART WHILE RESETTING SLAVES + +;IF LARGE +; LDI A,$FF +; OUT DDRC,A ; PORTC CONFIGURED AS OUTPUT +; +; SBI PORTB,7 ; PB7/SCK CONFIGURED AS PULLED UP INPUT +; SBI DDRB,6 ; PB6/MISO CONFIGURED AS OUTPUT +; +; SBI DDRA,7 ; A7 CONFIGURED AS OUTPUT FOR DTR1 +; SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 +; +;; 18DEC01 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +;; SBI PORTA,4 ; A4 PULLED UP TO DETECT MISSING LM385 +;ELSE + SBI PORTB,5 ; PB5/SCK CONFIGURED AS PULLED UP INPUT + SBI DDRB,4 ; PB4/MISO CONFIGURED AS OUTPUT + + SBI DDRD,5 ; D5 CONFIGURED AS OUTPUT FOR DTR1 + SBI DDRD,6 ; D6 CONFIGURED AS OUTPUT FOR DTR0 + +; 20JUN02 NOT PULLED UP, DON'T WANT TO CORRUPT 100K/100K DIVIDER +; SBI PORTC,4 ; C4 PULLED UP TO DETECT MISSING LM385 +;ENDIF + + SBI PORTD,2 ; D2 CONFIGURED AS PULL UP FOR IBM CLK + SBI PORTD,3 ; D3 CONFIGURED AS PULL UP FOR IBM DATA + + SBI OC1_PORT,OC1 + SBI OC1_DDR,OC1 ; OUTPUT OC1 = 1, PWM TRANSISTOR OFF + + CBI IRQ_PORT,IRQ + CBI IRQ_DDR,IRQ ; OUTPUT IRQ = TRI-STATE + + CBI PORTD,7 + SBI DDRD,7 ; OUTPUT RSEL = 0 + + CBI PORTD,4 + SBI DDRD,4 ; OUTPUT RES = 0 + + ; HARD RESET API BUS DEVICES + CBI PRG_PORT,PRG + SBI PRG_DDR,PRG ; OUTPUT PRG = 0 + + CBI PORTD,1 + SBI DDRD,1 ; OUTPUT TXD = 0 + + LDI A,7 + RCALL PRG_RESET ; SPECIFIC RESET SPARE + + LDI A,6 + RCALL PRG_RESET ; SPECIFIC RESET M192 RECEIPT PRINTER + + LDI A,5 + RCALL PRG_RESET ; SPECIFIC RESET M192 LABEL PRINTER + + LDI A,4 + RCALL PRG_RESET ; SPECIFIC RESET MT102 RECEIPT PRINTER + + ;LDI A,3 + ;RCALL PRG_RESET ; SPECIFIC RESET SPARE + ; THE ABOVE SHOULD BE OK - WHY NOT ?? 16FEB01 + + ;LDI A,2 + ;RCALL PRG_RESET ; SPECIFIC RESET TOUCHSCREEN + + LDI A,1 + RCALL PRG_RESET ; SPECIFIC RESET CUSTOMER DISPLAY + + LDI A,0 + RCALL PRG_RESET ; REMOVE RESET PULSE + + ; LOADCELL HAS BEEN IN RESET UNTIL NOW, AND WILL START IN 10 MS + + ;SBI PORTD,1 ; OUTPUT TXD = 1 + + LDI A,API_RATE_SLOW ; 4800 BAUD + OUT UBRR,A ; SET BAUD RATE + LDI A,$18 + OUT UCR,A ; ENABLE TX AND RX (OUTPUTS TXD = 1) + + RCALL PRG_DELAY_280_MS ; DELAY FOR TOUCHSCREEN TO REENTER IDLE + + LDI A,$AA + OUT UDR,A ; SEND SLOW TURNON COMMAND + OUT UDR,A ; AND AGAIN FOR EXTRA SAFETY + + RCALL PRG_DELAY_20_MS ; DELAY TO ALLOW DEVICES TO INITIALISE + + ; ALLOW Z180 TO START + SBI PORTD,4 ; OUTPUT RES = 1 + ;CBI DDRD,4 ; OUTPUT RES = TRI-STATE + +; BIGBODGE FOR ANOTHER RESET PULSE!!!! +RCALL PRG_DELAY_20_MS +CBI PORTD,4 ; RES=0 +RCALL PRG_DELAY_20_MS +SBI PORTD,4 ; OUTPUT RES = 1 + + ; INITIALISE VARIABLES + CLR A + LDI ZL,VSWTS + CLR ZH + ST Z+,A + ST Z+,A + ST Z+,A + LDI ZL,TX_LIMIT + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A + ST Z+,A ; CAREFUL - Z WILL BE USED AGAIN BELOW + STS TURNOFF_COUNT,A + STS VOLTAGE_VSWT,A + + ;LDI A,LOW(1000) + STS WATCHDOG_COUNT,A + ;LDI A,HIGH(1000) ; 100 MS + STS WATCHDOG_COUNT+1,A + + LDI A,TX_SIZE + ST Z,A ; RX_LIMIT FOR 9TH (INTERNAL) DEVICE + + LDI A,LOW(1024) + STS BATTERY_COUNT,A + LDI A,HIGH(1024) + STS BATTERY_COUNT+1,A + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI A,$10 ; START COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,A + + CLR FLAGS + + CLR API_STATE + CLR API_REMAIN + + CLR TX_PTR + CLR TX_COUNT0 + CLR TX_COUNT1 + + CLR RX_PTR + CLR RX_COUNT0 + CLR RX_COUNT1 + +; LDI A,4 +; STS ABSENT_COUNT,A ; TOP UP ABSENT COUNTER FOR TX_ADDRESS + + ; START COMMUNICATIONS TASK + LDI A,2 + STS RX_ADDRESS2,A ; ALTERNATE VALUE FOR RX_ADDRESS1 + + LDI A,1 + STS TX_ADDRESS0,A + STS TX_ADDRESS1,A + STS RX_ADDRESS0,A + STS RX_ADDRESS1,A + STS TX_OVERRIDE,A + STS RX_OVERRIDE,A + STS HARDWARE_TYPE,A ; AS FOR OLD ALGORITHM WITH FLAGS,2 = 0 + + LDI A,0 + STS TX_STICKY,A + STS RX_STICKY,A + + LDI A,-API_TIMEOUT + MOV API_WATCHDOG,A ; SET UP TIME TO FIRST API BUS POLL + LDI A,-SPI_TIMEOUT + MOV SPI_WATCHDOG,A ; SET UP TIME TO FIRST SPI BUS POLL + + LDI A,$02 ; TCK0 = CK/8 + OUT TCCR0,A ; TCK0 ROLLOVER = 256 * 8 / 7.3728 MHZ + ; = APPROX 278 US + ;!TCK0 ROLLOVER = 256 * 8 / 11.0592 MHZ + ;! = APPROX 185 US +;IF LARGE +; LDI A,$01 +;ELSE + LDI A,$02 +;ENDIF + OUT TIMSK,A ; ENABLE TIMER 0 OVERFLOW INTERRUPTS + + ;LDI A,API_RATE_SLOW ; 4800 BAUD + ;OUT UBRR,A ; SET BAUD RATE + ;LDI A,$18 + ;OUT UCR,A ; ENABLE TX AND RX + + IN A,SPSR + IN A,SPDR ; CLEAR SPI INTERRUPT PENDING FLAG + LDI A,$E8 + OUT SPCR,A ; SPI SLAVE, SAMPLE ON SCK FALLING EDGE + + ; START -5V GENERATOR TASK + LDI A,0 + OUT TCNT1H,A + OUT TCNT1L,A + OUT OCR1H,A + OUT OCR1L,A ; ASSUME NO LOAD TO BEGIN WITH + + LDI A,1< 0 + OR E,TX_COUNT0 + OR E,TX_COUNT1 + BRNE API_TRY_TX + +;API_TRY_RX: + LDS E,TX_OVERRIDE + DEC E + BREQ API_DIRECTION_TX ; FORCED TRANSMIT EVERY SO OFTEN + STS TX_OVERRIDE,E + RJMP API_DIRECTION_RX + +API_TRY_TX: + LDS E,RX_OVERRIDE + DEC E + BREQ BREQ_API_DIRECTION_RX ; FORCED RECEIVE EVERY SO OFTEN + STS RX_OVERRIDE,E + +API_DIRECTION_TX: + LDI E,$10 + STS TX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + ; SUSPEND TX OPERATIONS WHEN 9TH (INTERNAL) DEVICE ADDRESSED % + TST TX_COUNT0 ; ANY BYTES AT HEAD ? + LDS E,TX_ADDRESS0 + BRNE API_SUSPEND_TX0 ; YES, GO AND CHECK HEAD DEVICE + + TST TX_COUNT1 ; ANY BYTES AT TAIL ? + BREQ API_SUSPEND_TX1 ; NO, GO AND PERFORM TX OPERATION + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE TX_COUNT1 BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 + STS TX_ADDRESS0,E ; ADOPT TAIL DEVICE FOR BYTES AT HEAD + +API_SUSPEND_TX0: + CPI E,9 +BREQ_API_DIRECTION_RX: + BREQ API_DIRECTION_RX + +API_SUSPEND_TX1: + ; % + +; LDS E,ABSENT_COUNT +; TST E +; BRNE API_DEVICE_PRESENT +; +;;API_DEVICE_ABSENT: +; ADD TX_PTR,TX_COUNT0 ; SKIP TX_COUNT0 BYTES AT HEAD +; LDI E,TX_SIZE-1 +; AND TX_PTR,E +; +; CLR TX_COUNT0 ; ABANDON TX_COUNT0 DATA IN TX_BUF +; STS TX_STICKY,TX_COUNT0 ; DO NOT GO STICKY ON ABSENT DEVICE +; +; PUSH ZL +; PUSH ZH +; LDI ZL,TX_LIMIT-1 +; LDS ZH,TX_ADDRESS0 +; ADD ZL,ZH +; CLR ZH +; ;ST Z,TX_COUNT0 ; SAVE MAX BYTES TO ACCEPT, PER DEVICE +; LDI E,TX_SIZE +; ST Z,E ; SO THAT WE WILL GOBBLE UP DATA FOR ABSENT DEVICES +; POP ZH +; POP ZL +; +; LDI E,4 +; STS ABSENT_COUNT,E ; TOP UP ABSENT COUNTER FOR NEXT DEVICE +; +;API_DEVICE_PRESENT: + CBR API_STATE,1< 0 + DEC E + BRPL API_TX_ADDRESS_STICKY ; STAYING STICKY, ADOPT NEW DEVICE + + LDS E,TX_ADDRESS0 + INC E ; BUMP TX_ADDRESS BEFORE USING IT + CPI E,9 + BRLO API_TX_ADDRESS_SAVE + LDI E,1 + RJMP API_TX_ADDRESS_SAVE + +API_TX_ADDRESS_ADOPT: + LDI E,1 +API_TX_ADDRESS_STICKY: + STS TX_STICKY,E ; DECREMENT, OR TOP UP, STICKY COUNT + + MOV TX_COUNT0,TX_COUNT1 + CLR TX_COUNT1 ; MOVE BYTES AT TAIL TO HEAD + + LDS E,TX_ADDRESS1 ; DEST FOR TX_COUNT1 BYTES AT HEAD +API_TX_ADDRESS_SAVE: + STS TX_ADDRESS0,E ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_TX_ADDRESS_SAME: + LDI E,1 + STS TX_STICKY,E ; TOP UP STICKY COUNT + + LDS E,TX_ADDRESS0 ; DEST FOR TX_COUNT0 BYTES AT HEAD + RJMP API_ADDRESS_SEND + +API_DIRECTION_RX: + LDI E,$10 + STS RX_OVERRIDE,E ; COUNTDOWN TO NEXT OVERRIDE + + SBR API_STATE,1< $10 + ;MOV E,ATOD + ;LSL ATOD ; $01 HALF SCALE -> $20 + ;ADD E,ATOD ; $01 HALF SCALE -> $30 HALF WIDTH + + LSR ATOD ; $40 HALF SCALE -> $20 + MOV E,ATOD + LSR ATOD ; $40 HALF SCALE -> $10 + ADD E,ATOD ; $40 HALF SCALE -> $30 HALF WIDTH + RJMP ADC_PULSE + +ADC_REFERENCE: + CBR FLAGS,1<<4 ; SAY NEXT RESULT WILL BE -5V GENERATOR + + ;STS VOLTAGE_VSWT,ATOD + ;RJMP ADC_DONE + +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; SBRC FLAGS,5 ; CURRENT REFERENCE IS BANDGAP ? +; RJMP ADC_BANDGAP +; +; ; CURRENT REFERENCE IS LM385 (18DEC01 IT'S NOW A 100K/100K DIVIDER) +; CPI ATOD,$F8 ; IF =>$F8 ASSUME WE HAVE PULLUP ONLY +; BRLO ADC_LM385 +; +; LDS E,LM385_COUNT +; DEC E ; COUNT DOWN TO MISSING LM385 +; STS LM385_COUNT,E +; BRNE ADC_DONE ; KEEP TRYING LM385 +; +; SBR FLAGS,1<<5 ; SAY WE HAVE SWITCHED TO BANDGAP +;GO_ADC_DONE: +; RJMP ADC_DONE +; +;ADC_LM385: +; LDI E,$10 ; TOP UP COUNTDOWN TO MISSING LM385 +; STS LM385_COUNT,E +; +;; LSR ATOD ; LM385 VOLTAGE = APPROX 2*BANDGAP +; ; USE LM385Z-1.2 +; +;ADC_BANDGAP: + STS VOLTAGE_VSWT,ATOD + + ; 18DEC01 USE 5.5 VOLTS AS FOR THE ORIGINAL HYTECH 1000 SYSTEM + ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC + ;CPI ATOD,137 ; 256*0.5*4.5/4.2 + ;CPI ATOD,152 ; 256*0.5*5.0/4.2 + CPI ATOD,168 ; 256*0.5*5.5/4.2 + +; ;CPI ATOD,70 ; 256*1.22/4.5 +; ;CPI ATOD,63 ; 256*1.22/5.0 +; CPI ATOD,57 ; 256*1.22/5.5 + + LDI E,LOW(1024) + LDI F,HIGH(1024) + ; 18DEC01 FOR HYT1500 REVERSED THE SENSE DUE TO NEW 100K/100K DIVIDER + ;BRLO ADC_BATTERY_SAVE + BRSH ADC_BATTERY_SAVE + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 THIS IS NOW DONE FURTHER DOWN, AFTER LOW BATTERY TEST +;RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + + ; VSWT < 5.5 VOLTS, STABILISE READING FOR BATTERY LOW + LDS E,BATTERY_COUNT + LDS F,BATTERY_COUNT+1 + SUBI E,LOW(1) + SBCI F,HIGH(1) + BRNE ADC_BATTERY_SAVE ; COUNT 1024 LOW BATTERY READINGS + + LDI E,0 + OUT SPCR,E ; DISABLE SPI WHILE SHOWING MESSAGE + CLR SPI_WATCHDOG ; ENSURE SPI REMAINS DISABLED + + SBR FLAGS,1<<3 ; SHOW BATTERY MESSAGE AND POWER DOWN + +ADC_BATTERY_SAVE: + STS BATTERY_COUNT,E + STS BATTERY_COUNT+1,F + +; BIGBODGE TO SKIP SHUT DOWN DUE TO VOLTAGE MEASURING +; 17DEC01 WE'LL ALSO COMMENT THE WHOLE THING OUT FOR NEATNESS +RJMP ADC_DONE ; SKIP VOLTAGE TEST FOR NOW + +; ; 18DEC01 USE 5.0 VOLTS, MORE AGGRESSIVE THAN HYTECH 1000 SYSTEM +; ; IT MUST BE A BIT > 4.2 VOLTS BECAUSE OTHERWISE AVR VCC = Z180 VCC +; ;CPI ATOD,137 ; 256*0.5*4.5/4.2 +; CPI ATOD,152 ; 256*0.5*5.0/4.2 +; ;CPI ATOD,168 ; 256*0.5*5.5/4.2 +; BRSH ADC_DONE +; +;; ;CPI ATOD,90 ; 256*1.22/3.5 +;; ;CPI ATOD,79 ; 256*1.22/4.0 +;; CPI ATOD,70 ; 256*1.22/4.5 +;; BRLO ADC_DONE +; +; ; 18DEC01 VSWT < 5.0 VOLTS, RESET MAIN PROCESSOR IMMEDIATELY +; LDI E,$FF +; STS TURNOFF_COUNT,E ; TIMEOUT TO RESET IF POWER STUCK ON +; +; LDI E,0 +; OUT SPCR,E ; DISABLE SPI WHILE RESETTING Z180 +; +; CBI PORTD,4 ; OUTPUT RES = 0 TO PROTECT RAM +; +; LDI E,$FF +; LDI F,$00 ; PWM TRANSISTOR ON, TO PULL DOWN VSWT + +ADC_PULSE: + OUT OCR1H,F + OUT OCR1L,E ; SET PULSE WIDTH FOR PWM TRANSISTOR + +ADC_DONE: +; 18DEC01 REMOVED FOR HYT1500 AS ONLY ONE POSSIBLE CONFIGURATION +; LDI E,$45 ; START MEASURING BANDGAP +; SBRS FLAGS,5 + LDI E,$04 ; START MEASURING LM385 + SBRS FLAGS,4 + LDI E,$05 ; START MEASURING -5V GENERATOR + OUT ADMUX,E + LDI E,$DE + OUT ADCSR,E ; ENABLE A/D, START, SINGLE CONVERSION + + OUT SREG,SR + RETI + +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 5 +; RCALL MULTIPLY +;DIAG_VOLTS_AT_A5: +; ;OUT PORTC,M16U1 ; res in byte 2(ignore ls,byte),volts pin 5 +; MOV A,B ; get saved VSWT +; SUB A,M16U1 ; voltage 47K = VSWT-Voltage at pin 35 +; MOV D,A ; which is 1/3 of total supply ie +V+(-V) +; ADD A,D +; ADD A,D ; TOTAL SUPPLY +; SUB A,B ; TOTAL SUPPLY-VSWT=NEG SUPPLY +;DIAG_NEG: +; ;OUT PORTC,A +; +; LDI A,4 +; OUT ADMUX,A ; NEXT TIME READ VCHG +;ADC_DONE: +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI + +;VSWT: ;OUT PORTC,ATOD ; count value for 2.5 V ref +; LDI A,$FF +; MOV DD16UH,A ; divide by full scale ie VSWT +; SUB DD16UL,DD16UL ; clear low reg +; SUB DV16UH,DV16UH ; clear high reg divisor +; MOV DV16UL,ATOD ; use ATOD value as divisor +; ;OUT PORTC,ATOD +; RCALL DIVIDE ; ***** NOTE AN FF RESULT IS NO INPUT ******* +; MOV MC16UH,DRES16UH ; load multiplicand high from result high +; MOV MC16UL,DRES16UL ; load multiplicand low from result low +; SUB MP16UH,MP16UH ; clear high byte in multiplier reg +; LDI A,25 +; MOV MP16UL,A ; mult by zener ref voltage (2.5V) +; RCALL MULTIPLY +;DIAG_VOLT_VSWT: +;xi: +; LDS A,VSWTS ; previous value of VSWT +; MOV B,MP16UL ; new value of VSWT +; ;RCALL SMOOTH +; STS VSWTS,B +; LDS B,VSWTS +; +; ;OUT PORTC,B;M16U1 ; VSWT IN 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; +; ;STS VSWTS,B ; SAVE NEW SMOOTHED VALUE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; MOV B,M16U1 ; save copy of VSWT for neg 5V routine +; MOV DD16UH,M16U1 +; SUB DD16UL,DD16UL +; LDI A,255 ; calculate the atod volts per division +; MOV DV16UL,A +; SUB DV16UH,DV16UH +; RCALL DIVIDE ; result to be found in dres high & low +; +; LDI A,3 +; OUT ADMUX,A ; NEXT TIME READ VCHG +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;VCHG: +; MOV MC16UH,DRES16UH ; X high from result of previous division in VSWT +; MOV MC16UL,DRES16UL ; X low from result of previous division in VSWT +; SUB MP16UH,MP16UH ; clear high +; MOV MP16UL,ATOD ; from ATOD count on pin 37 (1/3 VCHG) +; RCALL MULTIPLY +; MOV A,M16U1 +; ADD M16U1,A ; B\C A3 IS 1/3 VCHG +; ADD M16U1,A +;DIAG_VOLT_VHG: +; ;OUT PORTC,M16U1 ; REUSULT 2nd BYTE B/C YOU WANT IT FIXED SO THE REMAINDER IN THE +; ; LAST DIVISION IS WEIGHED CORRECTLY .... SEE CEC IF YOU CAN'T REMEMBER +; LDI A,5 +; OUT ADMUX,A ; NEXT TIME READ VSWT +; SBI ADCSR,ADSC ; START ANOTHER CONVERSION +; RETI +; +;;*************************************************************************** +;;* +;;* "div16u" - 16/16 Bit Unsigned Division +;;* +;;* This subroutine divides the two 16-bit numbers +;;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). +;;* The result is placed in "dres16uH:dres16uL" and the remainder in +;;* "drem16uH:drem16uL". +;;* +;;* Number of words :19 +;;* Number of cycles :235/251 (Min/Max) +;;* Low registers used :2 (drem16uL,drem16uH) +;;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, +;;* dcnt16u) +;;* +;;*************************************************************************** +;divide: +;div16u: clr drem16uL ;clear remainder Low byte +; sub drem16uH,drem16uH ;clear remainder High byte and carry +; ldi counter,17 ;init loop counter +;d16u_1: rol dd16uL ;shift left dividend +; rol dd16uH +; dec counter ;decrement counter +; brne d16u_2 ;if done +; ret ; return +;d16u_2: rol drem16uL ;shift dividend into remainder +; rol drem16uH +; sub drem16uL,dv16uL ;remainder = remainder - divisor +; sbc drem16uH,dv16uH ; +; brcc d16u_3 ;if result negative +; add drem16uL,dv16uL ; restore remainder +; adc drem16uH,dv16uH +; clc ; clear carry to be shifted into result +; rjmp d16u_1 ;else +;d16u_3: sec ; set carry to be shifted into result +; rjmp d16u_1 +; +;;********* 16 X 16 multiplication routine from app note avr200 ************* +;;* +;;* "mpy16u" - 16x16 Bit Unsigned Multiplication +;;* +;;* This subroutine multiplies the two 16-bit register variables +;;* mp16uH:mp16uL and mc16uH:mc16uL. +;;* The result is placed in m16u3:m16u2:m16u1:m16u0. +;;* +;;* Number of words :14 + return +;;* Number of cycles :153 + return +;;* Low registers used :None +;;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, +;;* m16u3,mcnt16u) +;;* +;;*************************************************************************** +;multiply: +;mpy16u: clr m16u3 ;clear high byte of result +; sub m16u2,m16u2 ;clear result byte 2 and carry +; clr m16u2 +; ldi counter,16 ;init loop counter +; lsr mp16uH +; ror mp16uL +; +;m16u_1: brcc noad8 ;if bit 0 of multiplier set +; add m16u2,mc16uL ;add multiplicand Low to byte 2 of res +; adc m16u3,mc16uH ;add multiplicand high to byte 3 of res +;noad8: ror m16u3 ;shift right result byte 3 +; ror m16u2 ;rotate right result byte 2 +; ror m16u1 ;rotate result byte 1 and multiplier High +; ror m16u0 ;rotate result byte 0 and multiplier Low +; dec counter ;decrement loop counter +; brne m16u_1 ;if not done, loop more +; ret +;;************************* Exponential smoothing routine ******************** +;;Receives : Previous value in A +;; : New value in B +;;Passes : Smoothed result back in B reg +;;Uses : d reg +; +;Smooth: +; mov d,a ; save a copy of previous value +; lsr a +; lsr a +; lsr b +; lsr b ; prev.ave - prev.ave + new.data +; sub d,a ; -------- -------- +; add b,d ; n n +; ret + +; ----------------------------------------------------------------------------- + +MESSAGE_0: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',0,128,$1B + .DB 'E','1' + +MESSAGE_1: + .DB $1B,'D','0',$1B,'G','0' + .DB $1B,'P','1',$1B,'E','0' + .DB $1B,'K' + .DB $1B,'0' + .DB $1B,'/','0',$1B + .DB 'S',0,0,$1B + .DB 'N',240,64,$1B + .DB 'E','1' + +MESSAGE_2: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','0','0','0',0 + +MESSAGE_3: + .DB $1B,'S',16,13 + .DB 'W','P','O','3','0',' ','V','5' + +MESSAGE_4: + .DB $1B,'S',16,13 + .DB 'B','A','D',' ','C','O','M','M','A','N','D',0 + +MESSAGE_5: + .DB $1B,'S',16,13 + .DB 'B','A','T','T','E','R','Y',' ','L','O','W',0 + +MESSAGE_6: + .DB $1B,'M','0',0 + +MESSAGE_7: + .DB $1B,'S',16,13 + .DB 'H','Y','T','E','C','H',' ','1','5','0','0',0 + +MESSAGE_8: + .DB $1B,'S',16,13 + .DB 'S','T','A','C','K',' ','O','V','E','R','F','L','O','W' + +; ----------------------------------------------------------------------------- + + .ORG $1000 + +;IF LARGE (THE ORIGINAL WPO15V1.HEX SETTINGS) +; .DW $4100 ; SELECT ADDRESS COMMAND +; ; FSTRT = 0 FOR 1.1 MS R/C STARTUP DELAY +; ;.DW $ACBE ; WRITE FUSE BITS COMMAND +;; BIGBODGE (NOT REALLY - JUST IN CASE TYPE OF CHANGE) +;; FSTRT = 1 FOR 16 MS R/C STARTUP DELAY +; .DW $ACBF ; WRITE FUSE BITS COMMAND +;ELSE + ; BODEN = 1 DISABLED + ; BODLEVEL = 1 FOR 2.7V + + ; CKSEL = 100 FOR 16K * 11MHZ STARTUP DELAY (NO R/C STARTUP DELAY) + + .DW $4100 ; SELECT ADDRESS COMMAND + .DW $ACBC ; WRITE FUSE BITS COMMAND +;ENDIF + +; ----------------------------------------------------------------------------- + diff --git a/src/bin/as-z80.exe b/src/bin/as-z80.exe index 632a28d56156ab272a7d3e22ecf13d12ee127930..912b5f73c0ced87ec20975ffd823cfe1e1182e42 100644 GIT binary patch delta 41676 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%0D~wfJbVyDpQcc1#B?Vg+@nHmy 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 delta 37115 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 diff --git a/src/bin/bd.exe b/src/bin/bd.exe index af80d7fee94f2d7924d961cbcec1a4ffa465b804..d284f670cffd04157ffa5f10faee1be27eeb6a78 100644 GIT binary patch delta 16574 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 delta 11759 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

    EW)7 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 SiUA}Jl0#D~UmlVrN&jEP6kHep diff --git a/src/bin/diff.exe b/src/bin/diff.exe deleted file mode 100644 index 8c84ded626a7c1e830b2c77761590230ea21abe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200768 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
    XrrQ!ns2Ssrh1}rQPtA~cmNBsAO0{ns2#2vyO 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 diff --git a/src/bin/fsck.exe b/src/bin/fsck.exe index 0354bae49c6426838ff49828c618794f7404dff1..30225ccb5f283831b5dd51c6bcffbfddd8b4ed5b 100644 GIT binary patch delta 20221 zcmdtKdwf*Y^*4Oxk}wGqW`G0&BoH7$Fn~$sl9`;DWC9rsnBatv8f8D&7NepjghEhMP_(E#HdM3+2Q>&LL1WJIU3(Iw?XS=0 z^S*z+`Fz&i`|QiwYp=ET+G}4XzwgjK^Hj`!hf03fxzJNwe%~m4&ZXreuyvlY+`zuS zSnfc)bAHeAIK=Dc{bP9o;)mw{eYu8xf41C;IDYJB%f}#Iwt2mma6CLcImhGXxDr(i zx3THvd~W!!ha00Bt%~Ki4rDwP&Fo%)*a$c!#jB>Nwn;auZqa&F+-&J#Rf>MCiW}5X zA;+ait?JBJTbYV8sve#`SvsZCSqBddH|`jY5smz%aopPZ+c&K9uj4p54!OWF+|d~I zWNW$?pFIH2aExf=&jkwSZ;m$o9OQDKhc(TTYSoj+9F9j8C}UZ!gZHa_36B_KZz;*- zxQiu|5ll=&P-H-`mhzrJ)r$ct*g6A2(|82eZk8;@OnoVpKa-4LL#DLFcqDjsb|F_L z-{#{u;i$f;W6ykV*5@uxo;#m1wBG8g_^6p1{YaZv$jLpxfD)fd{^Vwk^KxpA6Dy3% zS_zRyzT+;2$Vu7$`Cb>{>X~-~u7n$LJ(?LDLH2VXYo}JLyDG#>K2CJ&JA2|hVnUR_ zXErmuj6e?|-FG9>7o#+J8G)|r1TOp^2z)#Hp9sucOUPU|BD>>8WLJSAI@N*JHbvI@uFoBA<0!N0ycNpwG(p(q?@IH|-xR87Hvv=poI+{y#FU#6a~|(W zLUsNo#&P+N1B%kr;h(%oEN$NuN}w8E4%PoSapDvmJ~oBiG8jeqn?j`*yt+$h{K!qx z`H2&fjV!a`(x%pN(V9J|nTW=QPFNOkYOP<>zWObtdWJ)OMR ze#7AYr5e|)jgS0t)A1Oh3j)NzSSKV%>g480Gm@hM-LpWf=#4V6^IJ_TF=oT0>C4%8 zgiaO4Ny*3)V#U>Ht!1LShiL^=n+PbASM(_g=AM|;L*iHKRbm3AnpM|x)GSB(VAAwN z;&|Okv2>VVF^TkW%;fo#SmUVf^fLTRcaSSpOwP~{(R(JBck0B%=cv}IC?!#{LTOTZ>b4uF%5y(3jd1@zsddABOqB|!rlt@E z!*m*pQU2eTqy01v_aogiHD&x4sPNY`HrQwv+G*17rquJ(k)Ali$txii}Sy!h@!L-|$g?Te=2FuzzRr)3^|7OS^2Bt-Cygs2@ zDXS&XSbsz{Vn;*^smbc;$w|QP-9OvPrgK(I#%H#vlEbn3JVz}D=6lwlUo11asqAHX?iP~X>IUYk_^v6bZ%%xI!JJ8mr z0^z$Zv56x%Ssj0Z_vn|>Gc)U= zBGzeY#U?aXX^&W{D}(W+=F8+yKmDiX!0fH3=IO)DZ%1?1vJAa;%5fTIJ&3S7ZZ2R1 z{_$p>#b4Z92(oX<+=1{nnd@?xC-UT2COW}+hSb7u@SY*$x5L2!J0kPEHmJ5QG3>tN zksFgF``qA6lt&eQO(Inyg>QhP)Jh0w;vtqknmZ+Uz20tSPMFGntgJjMgS%y~mqOUH+LdNG}U$ z*whgig&y{x2P|b&`&c&grF5VyY8~fAk&6`r%X~qtT*5wegiwvTf*j*v{bKFl%0_H7 z7v+Pum^xd`I!lx%{?OT2bVe9xnP#nN<<9K%$gf6a)J7|i;G~cX=#RSx8-eIz2Ny&$ zTEba7v}esuErTD(7Q-@mE4&Ygk5$6Lf4!5;Q_JM_!?>yz%*WAM4Tp6?6mRhQP&?0SLJ6<}9H=2aYzigO+TTi99{E~Sq-`|01t*1EARS#D zKv!bvV43$hB%%s;E-DI0U`P)|V$Ko<#0;57ezJ#+$9od>WwjCGC*@#DehYYr4>^J= zUYW{2iKjm7T_7e7J8)l_^x6R4b>v$rr#Z-QUsf5-hA&dmf)$kJMC97HkIV17j6`x=u-Qm4Wq2 zk^_;jJ6+F}i>uNTL(WE2X-=)DijLNlDApNbLNZd7;kyR;-tFVX*l16}ms;LJRqDQ| z^``#=-K2bqUg6wxH8tM37m+brMg~>}WHf!W(ikvO-ytW_p(H(4CT(=hU%ps}ty!f{ zE$_!B&8POJor1Yh%lF|+IGWPxLR~RoSHBD6+pUGSuNFH+b5nPpi>s6qM%pf?wkmH* zwCy74A1<@np_5Vz^HlFi)rAY&{dVKRO0K8S%ERbrQ4EgoM}yRxg5 zE0&bPthN90+ei6Leh@nC{b7hAdPj7yVO#&No^9g%(v!C)&wYib>QYq#Y}C zqzRo`XFEvU{kiF#7mKOzi1>BqK#cI&G*R2M)`YQXdxZhTuZ3aJ2yu$gndV;5aP4VS z-F>FEOYRv`lzJ!0gY(B++=Gt0$}3+bO{l7rkKt1s2p6R%d%)P_N;wGSsH_st%J%q! zA1!!9m6{9&iM?UB(W3J4FNH4uZ&mm>cc>edJw2RYfQ z0mG7tfvxQ+b77E^-!yYv+kP~WcjR!K+>W(F?!q>#)r-8gEeJe{Wi2AbvWjYbe3BWZ zko$s1?nXV)eM!`baiP*4Pnq0z3-P^61jT_K`6Uz!&d1P7?T?X7>3D&%yEm!n!3P9ZIn zQg6LQZON6E-nv)4yi9uQ*4!Y?JE#}eR)oaGde*xKXhUvYGCjU);g^ut*!8AS5b@HV2Wbu7L8c>~6>=sXTUW*a_K26kzX+rfC zoz|-S86LSd7k$FSRWs@Wuz5sML~ZH-t>f6Z{t0)NaH*)gqO!`%fkU$N9Yobz18vm# zrpOb%SCpENh43Gbp^noy>8ZuZ6DdPDri-B_k-uXmVxlE^%cQp#-!hG=?OFEP22_cn z)Bq)v+;0;Ig_OD^b0O8){cWDUvi=_TpLwWuTx2#VsLSVc{wb4zZyl~5~5t5CG2cJ)f(Xi-5k9CmP}8IYN+Q!}(oY_q;p2v9csnL&v_e6pPj};_76;HOU2ww0z{pLh zl>dU&koYtyB0_h3T$OAf3bCC(9>fT`DkGOn9g%M;t9%-hQfp^6d2bQfc39KrAlzH} zTzbKu;E}Va-GEZ#SKTTMCGMWc>L}*tB-_%Ef3+ zbnI*xB7+;ynmVkJ(G5ep=wrQ4RjtJA1I?TI7wPq?z%s$n^f(Qnyeb?`y-a6|fwXdY zm-OS3+tq_tr1p|D^@mra4@;KKde_AXJqFT7!>f(Qw&1gKKr0N43b{`i9{4XTXG(gL zx$NMw()lWlcXFX5EPX+}uU~T9zDs>JM>=%-gX-pfX_3dR@u2WQ&s58*$%R}^{dYeO zjDyaO2{*MvWuZ39S@tXRH7}4*U;4c&{K|{?2<;iDlAERTo+=JQ&p+N zD8Fu)N2AN-Df6O+eN?6VzCA zM`gW8*HWr$)bUp}$|3quK8^gNe<(`1PglcV^T!LyXn%~LXalpv)NZPtK_SOq3lxb- zXTZHB$73kkhvuOQ9SC2oL*eY!Ze)rHClPA8`OZC4!-=lUZg9LBIl>H1IHF%1=#PvN z(g@cW#R4Q!eszkK(8I%U>)HsdsbeM0S#f!~R!ktt*^`zdtZXO2`6q1QH0Plv|S#+{UbHV0^e~6_zA# z`};0zOh#RV)vt+WRe8d%P?7xiFBQdABMdlp%!!tGp z>ieZ{R;&niKv zbi$vY>1-*U+&remHKloximgTMbK%~|$Kfu8o4jC9x#u{GAB7;5q}?RFAkM*sS9YOL z9T+RTvIU8l?KpF&zNm)m!%b(t02}wiBzwFvIH)A;qE|M(V_ zW8H3@)Q%ubQR7%d4#7KfWQkoIWNpQl_&BBioD zL0RE2h5rF96?vjKJn}4{t*PO={Q17Q9=RIk6CXAHESK1AOZJbcxAOsQ^P~tP>1$tn zxksiQ7Zyh$IH2~YVrBLx(~KD(b`N^w$AG$i&tPoLln$Xo1K-Ki;p6OZ$Gx;R86NF` zax^kFw2_zXx5^S)07)D9_JIWN0Nh{sml#h?B%YS_Wcgb(#Gnl$OL#q+L!ds@oa*5n z0h(6@HkF$`vZu}kmI`s+KGfOkYR$rz=xi>N&aBJ`GOzwU;aK8Ao>klZmSUj_*FFCC zRAcQ{@Mk&*M)Dv3*grrW!S&zT_jof_hz$!gc1b?NC!k8*wb4Vl!LFn2itEcVapk zwxuBsCD3qi>4Fe~;~*m{4(ns;NgR^2Dm`eV4Fa4!y;x|h5{HCigPC{hJHIlBZ*M-K z1rgzWsv`6qD(w}=EQU`SDjhU5eTD)tF*}@+9jdr0Rt|=i?6>M374p~{qIg+)m{`FiVMsJ3DYM}bG%XQ*Pt)}#9XoXg+(1R)wiDkMF@=yO00jmdu zPe9jILlc>c%)o%SdZ6<=t*;;y(BD=YDle^t(VhQ0c_Q z+R)NyS}QKrg_i1q;5=J(g*{iXaPl7-8XM3H?xVz2r?p}I=};}2=t97-R2u?@rCNTe zF0i%*90X6BOASMv%}Cc})bBCC)ws@LkQF!S`d7H9y(lg@GKW<%{=jH4h-x)jWV}RU zd-wBjBO^V|D7ptjv7w@@LDAi-=nPH$C~qYlBcpkaNK8nTdDb~MCbJNSY z;02c{??=m7lVRL(9v%A}Zs{@#2bzN<;V5F!WgIGA7_CuktiO99&K!lc+98%B?9wTL z&E=Q^+w{u&EKAvD{9#6rkzvX$Cef@2YwJ6E)M7WQ2*;&l?4`1BablTA-iuX@ru9+1 zl7PvO$MG>VsvTP44qYNMQf%s=O2|nAY@<@P^Mv6LE+ziZiS)&qLJg*wl)bi%;)8!( z`?)Ge)dS<8p*-VHVASx;L{3N-UZ7>DqDT^Ss9RZOQuxk5R=6nS0m(Q%Ao{CDY}%t3 z7k}KpPKZuoHsyy~Q$6odn(aCaH`*Y4o4Fx+TEZU>Ei(FV_G!Ib8c78P0Gq=73|(lE zK9GpT{CY3MJ?yF`3QKiLC_l7UtHgjelDK}2dVkr$OY5J|uyK*-yCANp0GXttl4n-A zY}h8VaWlsMU*!J(M(ibmb8ZlWRqb8)|4rr}g99T1hlwN+4WE!WR8T&$i8wim>ddeJ zlq4H?f)z)HgNKW+sOMqSsl;)UVs}!5(CY5co*u)4tuTc!(u!DTWWuPVmeTXyTD7h0 zVB+RkY7KGH`IFm%t!(+hahUdoH6;$Fn(~=nBsgtY>l8YN2#k7_*1broHx0!9pyzZD zCiXV<85;E}e+e(ShB5lY*2@#2`@BQ~U?fwLlxJrH!9vwu2RbA7?57bSm ze`o*=mGG^)(5U0LYJ2g~aGc1FoD+{lZW>U&BuD5_|C?L`UcCm|156vPYV?O+qAW;s5nkE<&CE+L>WpNSS2l=)9 z@g17bUcKTTR7!RJgoX$WTlh-X^wFL_33~=P@hx$O)<0LcJ6Q?L!hX0gZG~XN;oAZ* zwc%UF)32g&U{smR!Sk)*8I{=n?a^_DhdjtyQyYW>NXqvT@vc&Qoi8-*h~Wzpx8pn# z&ku4VUp{RJWQ)BoL1DOt&lLD1{MXylaKft(jX`J>yEiqQ=Xx_cLt`?J)Z)M*T%^;% zr>tdYvAxh`78^US>BB|c$@tP64vkeA>!))KHe$)~pi4`-5tyjN(BQH8LYRgl9;18! zZf6ZSW@U`SB%Ug<(kOfj9zTgT;$B_&!Q?a~j%OYd!BY*;I<`hD9M=V-C}N1atl{=cj$mz|iA)UHe3>`3*S!~6dDsT%Vu`y>7OGO8=HeQ zy72NzIyU)2V_CPE?}o~>hC}bp@g#>Es1bR)BWrCLJQ%!#!<4&ATP51VzaRs_e;wL0 zC>{^3)@`32)=q4m$amF^QjMKcrj5i2>$F_BP#03ch+KRNl{NkK`5f+dj)l!e{z|ZJ zVM}u3M}aI%p=woaJ&!ZJg^MEn{MU6$dG}x-20m6qKPRBKSLhA*{Q~Vpbk!A!F&w(0 zVJHH+?XQII(((Oud&AlZyjxedqb0VnBj5tYT2(b+%vk7(^oLW7{AyiYT;|uINrW^? zS@14hD7)DRDMqaPk-G77+|<){vv?))2g9KbO>gA4;gku{hDXq_aHJs(sd++pk?toa z44pmN%+7!25?BPMxYBSazDnGqV_MXed8@H=K+l&ZhIb!N-Z4&eCuVjBo7E}h}dIdC!`+~T{C|tvIr)x`LqYSvpi64X)U{+oV->V~oH<7u>arOmzLley!#eMbS zFR2ex_#ska{<1+Jx1!#z7@9heFrAoQIxxMocY5hy*lY;$ra-LX9>5h0)FKe4z^`== z7Dkp}hVUM(Ax!%}VGs6pN#YUy)TQyC6fHJADK_l&7`OymNa z4Tt=bbPFPv#MkMm*EOPJw*>E<*9FRejPu{FxaAkgT&#xVH6LiMHSCeeW@B82eK)~W zh~pZ*C6f$(_;0!xp&fX)61mwoR2|9ieIL2z8;pG8`z~_X_if}0-?hj^-$3M3(S3pT zv_emu(9zErEH(ec5v0Sn5N1uOK9oRd5ex4%`0m{_kc4jVT1+~LP;CM7bhJHz)UxZ6fM|aK#@q`u+3fS?W00fb3&iyxJHBi=S=fgK-1sf@EiBq~E zk9Zi#b%t-qx{tEboe$lRbw6c|bwUCif%s^bEy!ZWig0h0cX9nfMAg(rbi!I4SB4xI zo;DgJaVw7QqLPA-V})J$&&Q2)s5pGwNaKwjH_`zzbX{vV2EGaF7uSaM;o-waWU;eH zc7BnF>t1+bF?i4g{#o{;Gn3L1o7d$Z=Wyayp;G?QDJ)!Jf2=AZhqbQ+Ayyn59>tv> zE|2&tA&VDHu)@X3g>Rvv=p+=jX?}Y}l{_0wMY+aZU*Po5sE{8*BOLXFVp;WZRJ{tv zdE;J30#`FNn(uAX0w-20j0(A1hclT_DxnKaT~m8JMhj9^Hgvyocp0Vhm+SP$g8o-e zqB1+2svJI?YQ>c%7qaZaA?m;#>Eph7gUA++Ci7Q7gHGP|rZj)+jQF)^wx+fXx0%w4 zt!|Afr%?LU)&(s7$JU+{d~;fVZ1aRgE=AR1L>w^~4!zTNA65M1&YbvDH^aHcDbRCe z(zI>K)98~7Lu9s+^en_B4)EU@8b3$Q@fegzmD?QCo<{!Zf%0-!dAX;uygXEtZdU#( z%6!D1Qz5T9A^rEZ=^0PO5C>MlD*?dgK0vs-BIR^!Q^J2o>hNrt)W2<-`{!&Gu3m||)syf-uotNCVGZ?exZ6edMeIm z(p^8MXz;FN{aI*MB)+`tWhA7u?SsK0aH?HKF0b>aVX`l9;&ui{(ZaRy+f#*W={u97 zH;xGyY?r8g?-HuExzMPq;o4#3Z6DWg?RCZo%7lcu9heK0raK7cWR>&m{;{&Et`1k9 zy>#{Y*|e~OU42Ubt8VfvsvU>gk=yA_0Nen7dJ25cb{ghc;X4e5E;yu*>eADR+<&`Y z#ruLP;SI&4nEGDC5wA4UZ_Qwrf`5rDe3b-ODgWv((ThwIyU66y!unUJ=3c+)Cc0~^ zs$2GNq~Ro9GzgAtC17P|?q~h!3l9@Xqe3ZJxFh&a*S+jyt1^0fT~$|c!^O3OU0fFg zlGHfDuMDKsM9~TQECu`6|8RTESQzDCU5eN(^h^T-uU{N@YE@xvr(Yv-T{m7nOK%6V z^wI0rz&OUd(L1u@e_)>E-Z3o*25`8OZC=%_#WM<+Ao6AD2DPcrzvB9Nb>eYC0a0zqsr#ok4)~Di5A?(JhKaV#J%c5c##Ee#wXwCwCEbTb_ z2~2IJzwi7;zYki*yj1yehxExVe$5$Fhf!VN&H5`QSJF{Z1K0rnk3~xd(%y7rS1Iq~ zbdzfOJ>JAcp*`|;DV_K0b?YVoB1}zW%;_jI$4aO+F zc280~$tU{cM*8@kN_#gWHjo#+?DNIc-~c8mI@M_Mgc3-+7xSU+!oVHudd-5gN8Tdc zaqnaL;nwj?8OH8*slV)#%6I3n`TuVd3QuZi64Kiz1~RP?xD+Dx3YYZd!o~rx1CCqE zwD3+c5+ZRsrlO zN)y$QnELNB1FqygI;sP@mRi*!>H~|f>7D+7@imPqNIuQgVe;WK z@73eYl$;VJe{?HR-=f_n^x(0RUuSsr4dG%|Bxhu_qhXaVk6|N?R^23Ox6M3`s!I&7 zc6sDDDube4%;igsbyhJjAe1KR_`uceiFl&GhzJIZ{Odbnkq>7SFBgoO%OM>0Vpr`R zY)QVjfn2T9L~LttTujd@j7{(OW1->LLXr?7rG1^+c2o)mQgF;2$QRD5{c#O&;owp3 zjB7d(m}_?r?6|4Vov4bc$_$i1;Y$Y;-2Rp(2J6qO`#zX*qW=R;cc^p#*kfq#sYU~} zA2*@{{b#XHLyY@dH*NgYA=~h7$EO-m4~peaah*Ua!shnL@B(FJSNK3WdgHDL}Q|( zf~xY$ma!t9;5EME-`sMSsORR8AZR-gfZ7KYb24p0+Y{Dx#mJyKqsvT`%-#G~IZz;R?Z|rH5@O-jDb&KKFYN>;^m)l9o2k zR<%ew8#53-(Ksm`)xwLpX^8XyEnpB8uL3RsE&$Gjqz@Yxk4K595LOqU1hBS6vNmn3 z7Ae2~19Y_wN#GhG>RObjOd_fq^--e(HTIuHdH|4ykCsK6nWvj?)hzA2sJOWhcNQQ6 z21V(Y!PS~AS%uP2aN@$|6x{x2`L_!lSqq%IVB&UP4!dO!T(^_3#<)^5G^LYWa+x}6 zUgO|Z3VUQ#$b#nFm1lk*O4Y*0sII?dCUZDlkuQI!c;%U}d0A-nVCQGr--mzsSW2Pv z`}(PI_2^HxpS;l1^;3g`Km+WYr;QNG$B+yk+J`Ey_2T>2zpiNme(u+iio(MByA`|` zD264#^;>;2^`~<==>^{Q%at-cl!#V79y5Y85*tdTw5fw(d*+#EA_?}?9$LP}$k;~V zJ=xZV3Hg+Pfer^e7o;*yz9i=gd? zQ7=usZ-S0SM;w(L_ua99hNLhK;)3}SCPAeKFNf(7s1G;dmtbY0rIpuH?g`i`jm#wh#Js0f%MpVU7^g`BIf zkUzHlwa8*q2XiWgfx_*Rgn<=16Qd1`E#385p>=47tjYxOK%BFtknAKdpNL81)?kSp&>0SO_Z2Ns)d%rRV`Dtm zjAPN&ad_?(SHCfiYhF!HQNpEz_?Z>w)0Dx3#_xDI=0C%;=H#Cf9Y@pP75t7~7sMJ4 zxd$T&2){QR!mV_VZgeM(@3C&tuYAJAs)lPs=uZ8xSNMXqFoJCtZYR98AgB|EK8H^C z6;-P0Yl)m8uDNuu+5LT#obN##2mv|qj2w>086?xN4g}%ZJ^B16x(qM4<7c|{tXH4n zEr$DzN7qtZbLy?yOdM-0s;cs-R+f8RD2Q$iv7f%c1nJkoUZYNAMpae0*MSO^DC=Qm zhQ=A7948i;_=QsQ6b;2<^W-U1dhuf>7c2$uB4OWy+W|6wQb%*D`dpdxx8^BY``3yh z4K?Q`pNsZXiXN1}x#$CT>R&1iWvda@hvsXW@Vi3kPa!jX%b}U-r^}>-mZIR==urOs z{djWp{dlVmw3|NSy8`)PJlw{6^h!2LtW}qyy<(RaNu{#N=;&~wA`g%5El}=LSGN%k z+S#Rx?i65(X(c%;xONTT3V=Pwhu%}8i*&=m)<3#Vvae2#4jRsMayf=Zl|^@2^teyw z!j>>uNut4r+&y?Gv>ppz*nv5T7e48OvaT0*4;y9iYAA3HE|zSI{`f318uF%x=BAHK zebVjXq(s7i=D?naHJFYCE|p2U#VJ80<1rK|84eb@SXjiuViuOL(8EG{S*B!Evv3s) z*Rqhd%Swiqg|-Bvuc>6v?YEL)W8vd0e2Rq! zSokyxpJm~5EPS4Y?JPXZ!VVT5Wnni9PqOe73(v6dEDO)EFtLY47g#8>5R5ssZ-qt= zMV%L(oG@}A6H3J{QCc28ttm!4`@y_P8|fE5XR+Dl{}vekPiF}CKA1AA7s$k3zTZC% zdb9x_m}XOuWWBT3=^lCX-=tR_oUY#6BlSEuiM{I{d@wC>?BCdl0E}wL-5VIwKo8}m ztcQ}+<)2BnK9phX{CK21pf8sLebVlSZdvw6{CE-<1G-96AD>EleS?sMi6?f6Z`}BR z953d(wb&e9Behjkmdi`7Bg12VLt})gGxBpjmcD;zmU`!TDP#Za8Ku7&>C&&u#C7xD zWIVrR5BOu~02e%x?%Y2$_!N#f%H@|B{q#8gD&s-_$5ZdXIueU+#@WkT zy1vqt%RfSEx+6ZeCK5eSU`Jcn?a}W5=qj^v_%LV1zZ_wNmv?GgN;i*R%)86*-VgNQnK*TYHa2YYfdwFmG2vo3D_<(<+0c>#mSWdhirN5#=TIWH~x z3D-zzUI<5c;lZ4aU&hW~v*y;4+ZPm;tSNREde)S?OWX^WyNft(&6?8k%7x38-QHS&KgT9C8BSE8CSHKe5gIOQO z#mCtSqomjl{?~;a>W8y*!F3Kil11j)cU@dDU@jm9zyU7312+b681OXUQ9wOl6`&Yk z2FwN|19X7F(`W-Y2RI2h40syQ4DbUy0IKUkJe$&|T{r|lqW2WGFMu5uMg2wcNJgey8gFA6Uo?EIo&+`&^{98HL&Nrt6W~?ATYzF}i&(c@#mxXX0LuVAK;v>1yiX*41^5%- zDBujB2XG0{2T+4nBVZQ53RncF2J8adU!lT(fGPX`#UNhDQmfP|=PcE&8~vqsZU}7I zSiElQhAkU0A>$~|y>-Xt?RRdyW8+qT<+|;g*Zqi!0#s7DaeLk7JGZ)b6~2(IQQf0| zL1k2ZqzZ0;v}3apvwoA+mh)Ury5kmy*^%#9==hoASB~E~UUa6Biu`r?zs-Lo|F8L<=3mJl${$ydTrjKPmI7BnO@X&yR{@Z_ zIPQ5w$vG7{8*?7XIh=DO=dGM~b9!^W&C!|02TfB<`KE=YQqwxqCet0JI@9k=e=)sf zir^|B+5Ea$W6@hCT5hovS?;vlZMokPwoJF0t&6SY*0t76)<>=XWo@^)eyMALfp>jkQg)*=(C_J8hEfIol!I5!<&ml|93rW6!s*wr{rk?SefR zwy(+Cn%9{3Jipbk%lVqK$Jy`Pl28BJhu&zJvu)XqY*%(sc5!w|wkP|}oSiwRb3V#> z#Pp=;dDE+=qagKD5PQWmU>Y(R%t_`{^GtK5IorI*e4BZ>xyJlE^B>HI%rBd}%-!a{ znJ<{fTP9i3EjL>VEN)Ac<<6kxLCa&7-&y`>`Lm_da@KOuGGK|fW?7xq+pLw=&DQBjG=6#TNKJQ}QwLBxA!q4Du=FR*Msg4ZCJcr3)cN95F9FOP!KL5G=*Yn@b|2Y3b{?&XXe{4ZIBy1_jgOp1P zdhum9L;$>=Sq<>+_BI`f^kIiGR<#knZIB!6RmO2M3hpsnB+1z#3$+c@qVC@#oy<`n0Yn%*$| z)pXJHl}T+LZ%#9tAk7-{7IV=2i1~5zZz0VS=J(C#%zrn3Y1UejEjL+eESoLQTG}l~ zEbm(`ST0-oEQ6LRYpwM+)`<13+<)Yz*wStJwk5U|wqMvT+6HZT_GAi=3;R zdz}wDf9m|5^Cjn-&NI$Y`D61J<}b`8}&2G*PK9v3Q>?g7hWdAPvrR?{!2XhiJA^oPkCeid$liPf|`Azc~ zbCPAAmj$_9A<+y~G}{|1bNW?T76h_M`T0`$_vL`x*OL`;5HV zd2{o!^2~YvmG|qsj=bY}C-Y9_oyohLH-#_7K&$yx{91kk?+x->_-#x9kMiC8Nj}rz zb}VzOacp<&b~HI&aQwybSI2;3$T7`1$7y!jorTUC=T@iRS?_$n`H1s*XNU83=X=h- zIWIcDa^~ba@(c49<=>XSA>YS%@O}Q6g6Rd;g5?E2D!8*CSnyQAvjwjfoGkdT;6g#9 zV6cGOAH>-lSW}#}HtWY(cV_vsc4h6(`gPVDS)XQI%IeL!nl+F$n8jslvvt|ava7RK zWv|WNko|i0d)d9&{n>-rT#hzpdd_V*dvY3cnsfH$?9X{L=dql}bDqli92V|s&Opv! z&h0R4&zcUI&YNUY9<-?5{HXaobE0LYm7UWto>vA1^egr zUVEQ?5E`k=8%qp^sNNMmcVC1Re3t>CQhpUj@T8`3d>s z@-xBoW%)nPZ_EEvetSOsvovyj=4NGOmB3(C=dQ}#fXU7E&{JTJ)0>Q@G%FIl9QPQ< z&F5@pm$}2*Z9Qo{Wj$j(YdvS}v0kvs)=So2>s9N3bVY=2dmu*RR@C7w~W1 Pf@u9u=5O2ZBkunIYDK(6 delta 15598 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 diff --git a/src/bin/ihex2bin.exe b/src/bin/ihex2bin.exe index 0f3885e0818ee91a54838b15684d5d7bf9a154b6..c29e1e586af61651bfaad495cf226eb8f29ed495 100644 GIT binary patch delta 16777 zcmdUXdstIf*7wN;JZLZxK~X`2f|mg`kOUG=LO=r13fS$ z95dA(XQrL$v{LMK?9>@L9edLt4&bHZrP{HrZ;P$%92?tGuc*}X{q_l1JD2aT@1HNv zv-WlEwfA0ot+m(Q`@ri#)$2j^7MnucYM<-cQ1r=*mbAZI{t@1|JQn%8j4xhh5YIKd zCC6pPJ(sP>zhijkau(t;mU!Ip4gtRArru#4n#!)fHzB#YlrOyvq0irH$tf|@RDRU~K(3W^?vdNfNAT9v7h zrX&TWQEW{bA2Z9l>LD+xdISW7^mgHE#l%bs9m~CtA~d`Gmy51vtz6+{H_^ck%6kW^ID8#q@a)C6fcGdkqzXx-oQGt=kcsfP<6UsHwPwJM%_ELG&V)5E= zisJUGo1J}}z3_;zR;O3IFKpG#R2&iZ>Lw%oxo)=Npb#_4gmB)dIlhCr6yG#(Q39@SGr-y9P7VA!LdMGbWPB9n7pH8Dlt8qYyK(T$sLR=ON*jF{z68 zgtucRDh>%B#Z1;EDDx=JPC|+u>p5{q7%_U13Rz+1=(GuhdEyf??=($8HsaiaV6b*i zG|C0<=&5NM%#^doBBZ>re4L#9T-)*aNWYv8MYocoj$U1xMiRP4FP==Y{-$2S*8mBb zXv4u=s!qfIisbxphJ!+OY=TY=v~?&vFBhsMVRh^>c~F0gO^qd$3^37dcq_@Yp_MxB zcbL%jIOoWhq6QZV(@`H5F2+q&mX`_>#w7XHN4n3d*6Bj(Xzv=TaVeAGm!UgYu|5kcBq4 zk1MvX1O;}KS9p5$&&P52u+`58K?sPLp6K*97L6pWJ#nm$>|>PSz1xmPJ}TT-5|ZG2MF zkzA_GEpCKe;rj#m$?+~A#k*x4ahLI@#6ID}@kzS(b1Cg#)p?=Ce2<$q+uj$3O~_U> z3Uek*QErihdnaT~1)WVJ+$Ev~e5j}h4R5ufO^dpGN*7c`&3A@Y@o{Lke?s=KEtris zLf0OV@F&I3X2ejGo9`Fj8AVajI-N)%2Dh7n8zZ8xWr9DZ=yr-q@bVJ zqI_8rc21n->q6V6UjjoC@CtS#-)=%QQIz+Wg%$go1J24d9bcI#bD5|(Fg6poKB(n=- zrMO%yQG$}4|#!ND3U1v=$xThf?9s?gRkIut~g*zv0j@*Ui(3A;hCQUFE zqAj%Jgg?#%M({mhf%Hckkn1=@s}B03(@0X(wM|D{Ly7xh1cN@-_l^-Pipxjyw*6Rl z@!<@LYV!a^oNS;dapi0TU-nB@Q+;Xfq8vKa0 zN5%ruw@6eBVnNKPPI+0#;+9*&Yq7rJ<`y(()y80GM8nNpBz;efqFjpDfG$^GEzoEb z>|)N=}RaLL>wzDO1e|294S1Pq*wF`!K9L@;4sJnO5?ViT2 zG-NyaVU~vZokz8g{}%EsB{xl*(QchQTY(*J&6KyW+f7M+NGY0x-zPtT%*+&Lw(BBR zgdO1a$2NRbk7;^ixs81kJ2KF;`v>T^6t@fr74CVurOE~w`^)b_q(xzvWQjmO`rCzbp7 z3myFt+*iIyyt=7Zok#KNKCWN#s-e&-E=uA$^m7`n^#XOniK@HR{B#&%$<)fahLg5iLLc$WBi2aWOD)#O{kmOvjc71 zQrr?qPm?d`Rr6h;L{jPYY$r7(Qk;ua1+|TT2dNrmc^e@@^gEe%CV*5#E3q;X8!N%= zu^Ne`v3R7-x#vjV{R(ZOqY0>q$@(% zWND`coU|+89B{csLp&Cd>=NElSRz_t2SjhUD5Sm3Os~Z7st$CPlwvE}kQ~d{6Cm$e z?iZL0-|geC%JMxakRXe9$5$#|btT`RR(RKxiA!NpA?+1j8z(8e5uBuC$J8jrd=%Fx zcu{1Ks9^q9;Y}zLXOlGK>wcLV>~Ja0gA^~q7=2SF{swlLS5?%nG^nYjZ@f{ZV$3Yy zhjekUez9DN9*c;zOpt`jvnDGK-xS8p&Qn$ygk`g{l@A+)r)K93C%U|;s1@2Od@*~j z3Rz)>!KutQ3Tq9qN=v%%3&TteQPF_yNGM|O%NK;bhPz^Sg0MfDgq^KJp)fN&-Y47R z8j70=GrkrhUEN?Qx{HnF3vEpYywR$TmcsGPBU^GOG#4nUh!XEki^0}1FO{MKO&;uP zC9ZBcCK@EgZIEZ}9nZb@5bBidDDJ)ck%*{;Us--m32_WGo%lwQJX>_oevi1z2gQtg zNN%NVJPI1dPXYmgVfj4?y`x(cwiO#_+ao@8n!Z_)XBo$S6DCnJ#^pH*10ZfN53WB; zhigLf15GR8pLx{i&jtJ71%1o!Nl_p`!rQ3+ge<9Zg=x6N7fnRkpt?CVX)f^;_FH5s zyoOx9#}e-yS#M=nb@RB8JfsUX!%JME2L=Fw2=VkLLVUgPFfHEEL`cP_K)HV7Kx73> zNl>-)K<SLs{W{_&j7A({2kwWEy2Qv=Ohun<)xt0xE69mtmtl{cy^|`WzZg6d+!_ zj)pM5+95xr9?jwWfYE~v5L%b9t4oZZSQGO>q?DgYbYN3%Yaw#Hy&0K+(3(EkC;Krc zxvto`jEuSA?~<9|-12cwRxS-qBfU=E+mC&LzseWrpl>5RR6SGxu0bE~L5zYp3cGXtMmn;hHl^VvA+~B>HZzf!|)>bS06z+HE&Q`I=`;_py1chKxY?z+Bi;yV~aJ%8|nP+*}_ zef5K+WxMlzH>23;7(&vxP*Pw)uZ(f4{+ZqT(E=Ee1fxRD7Y*>0nvjabB{aWOttz_Y zze~-RYA`AuiN&-Z<;Q+9fXaUE3ykYhc*{*?`}xZLjvMM4ho9BlQRQPkU8m$fRTcH~ z$3TR%WIja6hs?*`d&qsmgKFkMn$6{I=<5>p$m2is!M9gGO!Dr|zqwGQW~Y*&rH3X3 z?&y`P<;pk011I(J&>zImL5k+*tNn|@X*EBe_AjD+;5;T&Npl-7Q7p}TtZi&SFFe@2 z?3g;BIp(iI6WR|7i`0HlSfpka(d_aTa1cCgF4ErYXhym&rGBFpuHr2gV^~q+Zsh{` zyYr*sLo;L~-H(js^MO{OM#0-;ZXbLdXq1N@rQ@9g{z!kmVSsn`Nwl`UR@an3IX8qKWh~5o8wY)ZG8jv9eu~RRtJ+JDE@$sjaSp!GxjU&d2`PiSSo* zo(gIu+%UJ1xV<&=YlV-XvoVlJM&<`QY)}(X;->?1)H10sk!U?|-DO6J>0k|ke7_4L z#uzih~cZNa>lZtn^%thBO<54I+Fp8Z6->43UE+#oQ_)F7V+g;CbAGdIhP{RJBM zV(WCbXcAswvmeVXq9uQhf0J5@03(D_Yqbh3+W%^OMkP;!tZe74mGw}$6i$R%RiQ>U zy2XPgSDvQK=Kn{lypXf!`!F}frn&$3CH`+KJZqY~3x=0>ko{!!8qV8bxn%Ca*9Xsj z8;LplfSgNc zBXKCsAK6M0{sOh%OcFd2hQQ;bqrfkp0v&%rY@i_CzewZXr1KZh#&6#G9;L?P+z&eK z@Aoa3a%_Rquk#mT#cPLc({B4ISis`+bNBIBtjkEv%297)tB1gADOzZ3KtcDe42*XR>@@HPSB}^x{hm_ zKz>g=avJTMqZGROB&xweSkmpwRTJ4@$4U`o@|>N7IMdbW#2s)UD~RqD%N!=lQ^vb> z+;#An9DVssbl{iqdL+72yErkvqhHn0t5NM^uKAqiYzdBP z17giBdQ(BH!8sr=Q8&$O?5{l@rjp5+$+*37=jMXlemOH^l7AC@ZaNx6-*AH9`#B#j zG$T2mhJx$lVEVO<|G@l0B44c`g2Z3sJ5#T6-^O>`RCRo%QLWc;jD*9<#sS^N5m;`> z2$tUa9VS(y1`EQn<;KXRIN6MMX`6O~Agln}?-sY5#D!TYZiX~X$9dnOO@;vUw{)Ps z`4VuXfJ^On4ZKYj2Rb^cJ5OF8nLk_yEfo#0ANuWNPJzb>@0p%D4QG{btn8pe7nq(2 z!6_a7c^Yhi%>}f-nx3JWQJ@YijHCmslfkgKRD+Rw>E}#gw_Zp{s!e9aBlyMWtTwk0V6GBlA5-`_r3sSjA8# zv#)OS3@7QS*2G^7{Zad7P}LWDDUdKG+;ATn<_$F@Q)(U)D4_2rCjD|r=jbbTt*w{F@XZeLxjG3Ym1BH3ZN^|naL zd(A(WjP)L{e=hA;r544aBj*6t6E4)i(0cl~^LlR8S*j##fXe)(z1BD)UaU%Tp5+(l zxNA^%^4`F$5&@Se{-eMgXyy69qckyiV`XPI$~s4*Z6aDDIWL`imh@o^JVAt*`CiKr zKe65_X`6yb7!M>B^(PheB^3<>Oj;jfWFsYKKW>mA7HpIR57jx47g_)fVO(l$fSlyG zjX0&n@%xy01KQ0^C;)c1vmXbSu%RzjXy43Keb0Qjab&%1EXA(TzUduD&k3F95AvnG z4cEvxHVE*;8JaByG0J*lf&8yLlQ+1s~IJotR|s!#nL< zh@7T-q|nc5ZkC5qYJLb^s~HGguDKEVzUF%9o0@B(b2a^;FL~$L@V!?Q7rZ*e;IQ%B zPvx~&<(U-muOwphJ-Fd#4s9fN*5k3@S&Qr?8NG+%pJO z$K1@pjd20f{M2Is(_f~e2$wcomu3Nbm51lQ0|oY9;@y|LkCF@r0-?3`Ew>dlkfKWa z*4v7FjihXWUAV1`EKn%R9=NUOF;bLlf8w?xa&s0MWykUc+2P?XTTmp)BdMXK4=Vg} zvZ5+PbIWO}7$vZ3ZDf*UDWb>~VVv(NY~M>OJNYHaYCd{9#%+z$BXsX3p_j}Tvn6RR zsDUD>tvdE{Kr_E8pb3ytrh^oDVci2w*8OkMA{T&k1SHWELo5_m_w$CW>SMq|{2?@(2ueG#H+=ZsR zSmCU9*u9fW#TjUXJ0X9hjJ}$nmr0r8Zx12Cb*U>Hq5GwSdo;PJxi$VAjDOE=AbZr%cyi6{1*clcYmeW&L=s+cro{N)C!^-} z$1@i(1X|pGMCf%+jw0_o)m3d4Nf=R3pz2WN2}=s*$nnz!y$Q%uYHwuon1WnM(V{~f z(rVv4e&sQO_^WvtdGF$Fy9BpIFQY#kkUoJdW16fH9&jIX(F^e+7#I{4nl8od02bfR z+|V|DjS{&|pbKr2aI;Gt>n|zEEh%xiOG^Ct$tLL^yvT&S8KvTtgTg(9NmDm}OjxoE zJ`ezR{M!kw&QJ-t?pes(Ao2n7!mEW7E1ozwxIlO)x)K^uiYJuVi4^fh;JiLV+I5BP zcjZ#@5_LYGc>5kQN^wcJDIRI)nhD}oviyECxgo_xD|9ny{)BjvPYqW#YI*A_=-c({dPo&u*Ej8C1gsWiHVY&iF|68*=qDlt^#x$DqSVE-?-z z9(?{XSm4<#9pz)d2tBH4akLOrq~5^T=ZwwT$19*GD2X2i15TfZUBwPcgwt@ zWnRr0f9%Oz%? zCM#OeB(V!alZeufAAEj~8GL^K^y?u6hZ|eUZ7=TRFwXjtIs41t0Og(F7DFe(S~)Jn zL-5IAxTzz2819A|b-F|6v0Gnum({3@Qk7MH6Wx?gwqZPG?gIB_U&+;Q-e{NjbP&zR zbB|&kcQbawSQ$q$?Gg*{kS}K{xa3__0b`c;`wj2%=z!?ot)K9EvBgK;a(1u12!)}& zdML~s`>9JrVYq9fYZJL^$?N0ELgiA?P?AnwebNimHd4^paP3``)y6bjJBT=pMI*Hi z+blsCLs~%7xkHjsGG2L0whanQAuF(jSTMN330H*Gi<47ix+%ki13xw;hPS=50b}yH7Q^t!bg#pFfC_Gm)J~Mi=#@C=kABN@x%NH z24isPPhPEZDSTo?Hh1uYXn~uN4P#kdDc=DzL0*tSm%OkEYfHx9o&E6=eR-G~r!h$X z@&@)3YPU3`F5#!@L0!r3P%8rJ4zG%*I&XhMlS_!=61^A|pLyQdruPdGa~l$wYN+@8k$I8}eN zUJ^>m{un)o7k>T}MwUC2Q%4JTmS_L?!g<^3;sz!BwTFD}7CmnZe=N`R;joR{ks%O? zpGLl`fyv>{Yf89P{cuijGHaO>Sg-KoI}Lokh;3^Ve3{M~JOib^Np_WxmX9W1AEB^C zorh<9a4Di?VnOI={f(Ju#YS>PvC2?H{f$&M66Gl3op{^QZuV^kFUZFMjhviF);{qF z5;dr-V3X@_7`##4PTg>fDwNR@X?w^UZ7Y|Hh^B@n`HOVcA{{#xh-{2pueO!5bW4?@ zfOG;KF&@9l>h`KY)9<`AIC`9kH)-(6hWNl=uvcODBL=^nTFdp~TMI9(-E)XLX9#5s z&2|L*pt*m!4RtlIUOS~5s0*}vI$h$oqwsDCg*lhS6zS?RdA1+(r5W~8Z7fXo;2@ZT z>j)cg*n}b1slNB)S;pxbz%i~R{@hCJlYCJu?k(`LbESi3bxp^;kuc-9BO;3sD!S64 z-VG!ln}8Q7HitW-^hPz{jD{oQ`lzM@Y?{^Czi!$UXRIPDD3eixy{f2R3XKBg`ZLNa zA5A!L^&?e}zo;L?Bgoy7(uW30FU>pqubzTHBMw2l$<3b9ZyCJKs8I}w2Z_Zm@$yGR zBy5KRbEKu6fgQ={jS8$x#-)1;9$ZWKQyslDP8;;qedPTQZ^6UoSU&O|YdqjB4i~ZC zj5t-s`#L+m(78vP;)m~*ZrZQ zkVwJO4PSwBJ-ffEdMVk?=L}d*c{3Y>-tR1@z0(@cdjE+Jx=<8{qSGjfMA3=RudAxV zL!NUJ?K*vdIX{p%FlT^7WKQHR5MP$GjKT*Dy2j()H7yS+8n1Zo#Cz<*xQ>D)PWt%mDWse14s)^-nEnB>4y zsNRA&fyBE|b{asf5vnStDVx^_k5?p<=(URY6hbI4pYkEPAFvXz46p>S5RebBtr5Pi zD2$c6lnCYRfSrKg8lm8>l@3hLkek!ah^bn(}1&p^MFf$ z0e~9SWA76lTUr zv^a4;agjfyQG`8!X6J~o6Cm7Km2Mz=2f0%47KI%3t431+=V-X0CE}t>vXcd`eoXzw z(c{S{R(&O6-Ed)7Rig5hpm3zhrqbi9>5217UO%Y zj<3|O2A=J|B)nBUDXJIU(Obx|_DuCe-%d~gamv+3=!soO2Hrdml)c-Lf8m9SHjt-Y z2$kmL)jurZEK>-hhDZPUX3`y`0zV8|j&hUYNCFOca@&%uu0d#r-SEoFtip__Bq3HSWe&b>fR}VQM(&oQK5> z*Sc?2yCpMeBp!Nu5NF`uaXjQxvq8MJw}r&J$NC79bS>K=2+8IxK@1|4aAlv;s|)i_ zPpUvE^hN!4Qc30Js2$Dq zKeB%05V@ZEbNW#45HTjLt9B30Uaf=`X(2-h^v@5EIaSMRx=WgwO7t zpV?gZU+htB*dC!;wnrr1g|gECsxEAg>caM@E^Lp0LF^Ht`vEHf%K%FN3jz56TV2>5 zA<0WmA>0nw2?*AO?GgK1#(t+ffusAGV!9)JoFW%*RMa`BP1wct^I9QWQj#kP__Y z@k4;CFG3CXvF)#{rWL+#U%@)cj(SP>(CjX&tNYIfmn-?{aM;~0af%o|(~-;3A;&s& zC+R_UGZWy;i)1pVxEu0Enzy<0Q7*CnOY|7h^TWu8d%hn6_%IOHRJVVxce^($4~+}< zlI^mXvu}anq)OOCxJ-~@?dI2^^N?ii6EBj4s1IMZSJDkPD42td(}!F;O^vcdyzo4F z{?QFA=X#Y@Ftw!n`^ZQ15Sz}9ep>rx&z1ZIih6vPwrV)ljJKo8s2XJ`s(w`z)m%wF zz6%r$)F^N>q$5=r&$q z62r%YI1H5U=F4HB94?eYmmDsU zLvo2Dr7V-f<#M=E4v8pADfj#2XssN2~%-F(}>`Tq1 zx&T8plV|2qQvn3)L&P5gs;lQMymL<8!sdChFZx!(F4DlU zASME(K}^n+;-5hW@wNEQ2C)b6Xv8+ef6ArCBi?}+mv+?sh{>5h zAMrzoO^6>xoQ(Jp#IcA6C@PK8Awe7)3h~W#{~1U%e(jF-t(wu(2bYGFcv2J;{={)> zQk?J96a}?tvVyuBunzDTU>o3hz;3`nz-hn*fD*VdfQf)v02{ysSPiHLYymtA*a>(W za1fA-b|PXm9K?wL3%~`a0c=QC*r?4&{1&hiup6)+Z~`C#E&-Gn>qtO6AQ_MeC;*hF zDDbD6#sA+=K+x|Sh?%OGx5``e^OfxVs|r^%vn6DD-Bia!e-onzbgbbdKPt)r;3Ld4ONzJKOi z%}I7Fax8IBdWzbQwI6SoWUv_u3`-2vhI&`RQmYztaMlU zvh;h?*QM8|FV0wzu|DG^;|kM#=0BT1Fn?{X&YWgVwa&I0tyxya>afnWj>=BWwr0=E zUYxx;`~K`lvbpSS*{@~4n|&nvgfF`XuHF{!oJNuU{A_c@`$D0!dtdjp0+$|`J?3xOTXn= zE6@Czd6xMT^H(49K68Tkm^sUQ&3wmPW+H4OZPRU5o5Qx)_J)nh#oranvsqzy$gs)4 z8J;veWq8@pZupzwnBgt*Nbkz{EF;#KV9YemF)lW4HJ&kEGG>@oVJ?2tv!)}a4^1J{IP(;9 zzPZA@&is4xAIzuCpPT#4QJMP86`2P!&t`s;`6ZSi(n1D5&$8IE%Cgz=JInuCzPD(t z6Cjcct#@13Sl3${ty`^6TYWEC-?5&wUbkwpW3ne_-^=`*Ilz3tl-O3-Hrjq`+iu%w zJ8KKswDtu1bo+Yy2D{(>JNrxao%Rm<`}Q;T@j0d(TTX4xFLHhZQG6ewcrNFMoH$38 zV;*$sZbzNt7mk1<=r~AtKvBy9;DXAK0u8&HgGJcj(n6W(L-i%) zxPD`K&a%VuvSp{`q~(Ss&YED=Ta&HRt!Y++)nv6;AG0=FH(R$@w_&Og+4}5h*=gB^ zY*V(cIQvoP;v3n!p^w4r{n8OAdtZ_W(@H?J$>~QRI{ME6~an{l2 zxK22*mZA#5fe3@vFb=YCx6g3D;X%VXaABL_w}z;6E#x>Sy*Pb!dSm*N(A(G3k3yQi zO&>@fo)McdAtNp0p^PmVzsYzmV@Jlz89OshX57e#gS_aC$;Ro%G^4?2GFps}8Jmrp zja!V{jMt43;Mg=Mw83OD6`LM4y=HpDwA=KqDQMbn>M>OuhGvg9>&?mL>E<-^BWBL* zH~-4~TQK$y=63U2=Aij+<`2ym%pSm}LKEIK z1Pwig!v_4t@b!}u<{yQgptc{ArZUtSR3E$oO9(?MTS+Z#a|_Md$HsPPbrCl7`M&Qnn6^K@uh;kc-)CO0 zbAOzB?z#7zd+xdC-e(SUNDp*K8f~J!C+)N69{O&cW^nr*l{X=)@)YXNv4+YYkkgGh zLatcf;Gjl+ebnuu(V|fl zRR=^(6nQEQxf0OGP7tMuDAppHDea@EY_?gHqUZ+`&{K^RmBRjBoFh}8qp0C0GbXZq zB6(gQIMTOnBu94RmrhYDXRNKd*MBcXb<2PSi;;0Ai6`W1^r-Fzq>tptZv31S)iL9N zXxAz-dLMvHv4dhC5s#05F$QJKOu+S0ZO@7yh8 zZJ&F9tx=|ne#btkoGv=R9#&39`Mh$bXfK;E#(?zBF|&euofK0)e4Xc+g$gEd%OdWT zIKn|*-{GI++xai8O*dKtilefcb|)pmWFqr@yZ?o<`UWNV?D?101tYC79fXm;osCb> zF8~#{S}q9SJ4Gr>M=I1lR2Gg@45Z>5snn2)K3b_3ae2@W#P{vr$Nn-QM-*h=Oqe9v z$9|SDS-Am|rR^l80^@wA_OYYKrb$p`r;p8@NR-DtA?Qv~-w}{q{2AnmefVO*`8?cF|-~4b}G%y@p9@jnnLPQtK4V z)1($sY4);~#1v%}$kqdSNkCS$v-c-17bf*yVooAyw1N`-Zfho$7W9&;{u=`ARu$jA zI(B5CAdYlDds&qwmd{})CZz`VLztgQg;waqFA;RY#1R%b!aPE8K9p%YSwJd&>qV>~ zZ6_%C+A>B(bR-eR)pu;0C8Y;91PYlr0W0*@pV(F+qyOOv!9AduLm%PVG`Q*QWwl85)K4~+m)NZzIe2M)CI0VM< zezlxe<(_j=E?$+5jILEHC^xfQofxurfTSVy5FxZRXGghCX5!Q*oowNRBs;;Z`>w*L zei2+#p2r~5Fo@Ud%l$17*)IVxUO?1;zAT_5BZY)fc~$K>C)+e3BjbRRD)Vr5xDjSB zT%=BRfhgI-4FKUOW6p4`?57hll)rOQ@vln@Ba4_G4`a0bj*XdU5f!nsCQcFex3jA! z=4XM==FuKEXM!HQ-pFmuHuTvhT{5K`TSdxrMOHB?^gA-q64MW9xDVsoWGTNFO*=3K z12KbKA##4bl6xGE4BD>m*d(Km^N|E*P6`w`+Qm88zSIIyGMheWn^^t^yMNM*;DQ7S zTJ{FM(06os7zk%IUirO~dUUjhdl{=lno{Zq0+MP`1>GG_f79=&rg-C?!%m7T%6t|reIb}-&@@k43JBF=EPYk}C4cS!& zbZ?PjLAf<|P*h6~NH|p{MR8?nB$-1z-@FI7mY0yYc;ilFym1GidhD;l)I!Au5Cs;|w)#`3Qtq-aDJh)PTjZq29IJtg1dQ zq0C}Sb{iHXFiamw-11Ewr1U4!oBFB1?cw_NYuL9?J_x*ZKdcTUz+i5obKBTUnG;2& ztUPOp=s?@ONE1(Db@;#$<_z7X;R7AmJtcRrAKmetcqo%Sl>K1pswwculbw_Y@EgEq zfOCK(;D5^&P0bMR%wkth-5aE^)}HFb`i_b~OgkmU5jo1*y(xz2ZXqqzQWy7C78Ksn z3WFuKoKY?Hgp8z(``{-H^6ClPlLOdy`uE#wpmIh}7!SzCtsKw5hWJLE1I;vqZnK$Ks0 z@i+$VDrGKJ^S+m&rthSxnkoETRUsHFw#}tvx2G($ifiseAN}Xnu7D#9%fu%1`1YWW zhgTKBc_<$UXNBUg+H5q$Q6kp$jg1J07AaADLfEJ3A-R>wcQ=ESF%)}15PwsT_f#h6X zWkbhMai6uzUl}SN4%;Z^DBU4Z4|B62CPZMagaT*F+#c>E`({qAKn_|AoapjkXh9J6 zhnz__yg*uRYSjhIFEFR9tXj0pEy(*034c6gyvikr=9h<32~A{jS(!U3Hrf`9h&>s! zM`ffP_CT38C2l68VgB4Mw0OOt;>6|)?dA1eNrG#|557nva)DLrdWN8 z)ag;7nKPmC3)U~=x9&u@(5B(AbYfKSvuZYBx_LZN4BYNQOpy|p$v}}tD)K*2#uaC>{0!By88EnN z5yNqrD0r>!dHpG6+;~!kQ7jik2;9c2mY~FN@F3rnaa-U^8Hu;9N+YG}zw^hIa>K+w zMpSTEiF9Ti6c7E^wzH4SoGc#2v+T@5@!U-I)0q}=WhR@TDZGvBzs(DqvBTJM&1?y( zY>TEic?NvAHzH%^$U~#}^~wBtIq{2=v!2pUSCCB>wjGbi4%fZHnzc)V3SyXXB<*Ux znL^?5IBKMPFLt|M3b)yXgH7L2O___-avyP#@l72Ntx6EBg&bsl757`{3tKn-#>uu4 zt>{O(yY-)&Q+I-_l$lPHy}77)H)=6ZxZQ`I&%jK6rD*X zg|%yGnux+tSshY{hwja!C9J3;6J=Kz)xkujRKYBiyFE;ylKETC&lJqkVfx+Svd+K6 zGk;)yKK#J@Qf!sGh!JlW6=Cd9`IXSZenv5Npi>lDI2Z_a4oRyE=B)@VR9KI%mxMMc zm<3~{)&*nbfw{QP&_n6#QVwJ6x|4qmFAzzup3bOkExH~X$ib)?=3qokclM36gM5VK zQ0ozN0o5o%wGjcqSUFQWRvHqDQWWKq^1;wXIcCHB(8){hq4|RKlInsL%)(*%942-t zzJ51YCF=b-p}Mxots=l;+bL7RF!iY(RNk zX5FTE9Jp_hi89AeMxeIX@juqWMXg1#$&sl7kurQwpU^_6g7R3e6o?xuv{jgStcihM zi~B6=ZL=IC36*TQFRD%C?^7s68?0wUFb5R zo>-S$sE+h>D(O89M}lA#Wz0C0*XPcTQp{D>ZJZ6Q&?}|a1q{7G&Ii`GVfQr({SmNTgOu^KP<%l%-IIQg%VJ+KbTrb-qvjXRum+i z0tv7>tDvGl%*d_;CL|Bfk_xP%OybDK^pxp&YiB?cE(*CYYs8*p8f7<}LJdT-9`)Z# zM|ZKX)kk_0I^U5(>~uLKj&=yg7`6!EH#^2QZu%Obb7+nNhunJQk35OG;E~7Ccgy*Z zBeYq{%b*Ol)V4x`9&NANc1i>>$YOV4fuc($tZj6yePpdmcon?dNTZbD z+P*Ug*+iRX|NpJ>7ZczFZ!GbM`pN2TxnzR}6SRjQDrzMo`sP)B$bvIMPWSK^-xkM1 z>Qtg&J#V%X<*Y1Bk${8^7M7E|?aRVUv4k|l6y2o&?~)SuP-FU=&bECE3?lIh$QE5NAyNF^V8tRHMrg$?s^ zJ`NjRrGTQdD7srQKX8?y7-KCE_Fv*ji@f}h3JnI48hhg{s4WClZh!I?RB$W7&9}3+ z;OYq~-yXgN^%y~^?N8i-B2hVPdiEdL|#Zs%5;aq+PzL{RtEkaR?Mpi zE5Zb8?Ib8aE<4e)I~^XSf9Rd##s4Msj5g$g5+y-v|q4CoD{9esgIVckMK&IB#)Xf!#m3lv|HZ z)-G>olt8|YkeBg!+@C*1f$o-iCD%-8f%nUKVHR8`2XrWvunSFEQE^nJ#8gH37=9Ts zWEdNXJ${_O74v^55xVk8Vc;atS3^_H^!+mbz_eh-9gc2i2%~ryzE8-@Xl?B!xh&6yc zd(}P3d-ju&<-omoATqiXSH>|DDB=JR`PY$t-Q<3|qN02mxp-eHA|bJl%#v%4cEzPs zUOkc9g%yJxl6Vp(ik8i=SHrI?DEnH5{$=gELD$b zA`>5^dEP$`VxSBAa_Nk_2s2*Qh&Cb)eWa+%^A4FIGYSlG3wZb|JV0bo#G(d&3-j4Z&uWq#^CXXMz>bRC<}P`w;T86;o&hy^ z$iSt~ABO;V8f~vSfVB-|_=d5XTr!g86s&0Mk}1|5=x9~?N7EhhLOXd4sQuoF>U!MZ)HIJ~1-^!scSjG{S?CK?%L1L{yj1AW>$19-kB^GZm+~Ld06OBjd!Cw zE(x>21u3uk3a=t-2y5Actm6GHylP4HC)x#F$pu}_8qt-3dAGAqVr?Kzff%Na3{Ng6 zgePJ1&ql^w#r%91o6zTV4^FK_Dm7b~z-X{Np`b z|CiA%mKb>h0bv<8>LcNKjyZ~B6-tW?ddfW25D7FQRxqPJ+B{lL)h0M%sM~ZNW72r-E}Dg>_E9XQ`p$=MP^6eKDf~khBzI) z;B=_;u;OiE9|aZqJBaO+t;4%A(+|U;zex+*i0x41!XHoDw0s~>*o42TP|tn|*22Vu zQZ)LGWk0#CJ1KnTAjdFtK#bU96`Wexx>BYSyPUjsfiHPTcxpuwo&?9ONM90VMk_S@ zKVAKQ!t6);UYGJyEg&IIP$i!U)VO}0cr_K7^#TIR)lM0Hct zP+VO*`_+9f$BocMAAQ(el?CGahs^8@I)H)@H*zS;QP2Rk&5=y`xZzI8-JKW3_aGc!``We3&kytJ zr+b&N?&@qYvQ5>ROwtdWw<6mPXaej6>;dct90VL)#-6C2n;4x=9}pa15TIDj&Uo`WCu+|aXIkOg~!*o%k0XBGA6wMKHhD`xPe?|K2(UJo};07bkupUzkW!oAx1}I z?feTP1$C>&QsLsUIDOpQ?Sq0h#$ldRw`uGI@{HW?=6)Uf)WfOb;BhwXVVk7xEhk&? z@VMFS@SA3he=XgiffId|IMHx1ho@gvJEkN&HmhN|)lPkf_i#D_QF;?63K`Lzy1Z|1 zC{+y~*Z%O#$wG|kjQr&$;pKf{!y-I6cYY(?8{XA(kd1vLEw&ZI$s0-Bs(oZqP;n?4 zr@C4QKdu|1gkL)ZlEV~Qo`2rk0`}DNkMxx%fm7tGy4|Faauya^yVo9$%+q%WhZ;RtxOO}} zxb)G)Xb0uCp1RKTh6aIC8a;UL+OhQD&mX=02D_fRi|LWR8_cY^-D}@L#MMkxL7wNQ z$cP^B(T&`g@H$g{jZ4As-lH-g*qLkR<(aDfgFC8(#^8?7EVv_78&@LP4rr~6x}&P7 zJF1GhBTy1|ge(P+2v7i|fMN8x0=QHebw@xkJmKsDEC9>9LULBP>fQFnwQ!}lTO0D}O<{p^gu zf?zgm7T4!lzJ7$nys8H_O0IkU)r|27%DxLgm+_zCeVS1EUA|LMgs+3-ExADQpSEa_ zHIp)qx+K1rIaB|+|Mq5r1w!T~7(Cl2-vHcg2{#0LZ9@UMD0sac>nI%X?r5m&DO}h1oq`zP7!l?S{e$ow>XtAd*2T47#E6k} zCWd_G2wn^0vk7jdw|?HZ^%NvQLOXeV=N6%#n<fDV%bd zq_OdK^H0q~(0Blllfg%Fj%9QqN6yw(+fT32cX06Vp4@ zNxgrcv+eidIEg6GmeHLOBmbR~nggKNdp{c6w&bHR;sks;ZU9hS0P^c{w*BJxMzMHM z!cO|z3qb=mGr7jdk&|^i`;?Qq4S73qm_4-}`55HOktZNGAs>refjk-csVAM(c;x$$ zPeATRJ`uSMISFtRk#9gQMZOXF70l)5$S)utrYJSlhXOf`dy&7q`rks^BbT345RntI z`#?GJyX|XqKlfxtQn2wWikfkrqGka+fcpS`z+-?NfW3f2fD?f8fWHB*18zsZ6u>lq z2`~rX0aO9}fOOEjfV>0nN5J0ziVGAq2`~d-1KfRqnn^81;eNn+z&5}$fIWa#z?*<> zz!?As_{RnO7xM1^jdOn1DHaVs+b9wFpLIz@NupPtO_Peoy`CZ!eLWhhQz2DC!e?bl z(I>(09Lj>Ef-muOdLYqaaNk88u)Chbmbm-e{!GwnI;MQ!k}+N;_)U5ak9ZmLeF zGwTX!6%bFC^72 z)4rrTqC2CL>y`TT`p5K5`seh&)4!wtQ2&Mgd%e^!&M?hjH{5AhWVqkpH*7KdmmzHU zmEnM)%W%RVH6|L%jFrZRj9ZLP7DGi{>A*i=gUk* zrY6&irms!O=1FFoxy1aKIb_~tK4$*ZeATS5OtrWy6(8xC*8j0S zZQEme&34vy(RS4)wyW$m`(5_1z1e=){-OQP_F;R1W4z-IhrvSJm{!*>Am`g^!54|^{+!CC-h(8d(Sn!#$Yk5F|0E@ZP;%(Y&d23 zLRe6RG1GY3sLTtF&r|2wpn=-F$Me{{=knU~dh<@_Y4R=kcjlMmi%g?UAycF2H>PZ} z(|o7-9`j=J67zC%y?LMcJ?Nv?e9C;reAe7&zF_9eI*Z9-vp6k9mc5o&p_kJz>^_*b z$eLpCJDEY_^ltj1<- z((Kmk#dbZcd0%r}lYs4-q0PcRDALZ?zM(y={gd`DT9GbEXV3*_>F&|3(ADX->vlnz zZ^F1f)ScC3>z(>L_4nu(>zC-4L#6xl@9B@}d-bREXY^ukn=ejPa~-TAn`7oL8JTKW}l~ zvZB1oya)1X@&Zu*Z}Q&BKbil1zTBiTSxvJ{t4*6t3Fe9B1?H9JYV#xJ2AJRh^A$4% zSCVX*WKmnDSu~bBi|yH|NuqfVLnV!raMGzY*_!>DR?Q(zho(n!OhfI)>49biHcfh- z&F-|XEbtYqDX1yfP(ZcfL_yn5!I%!}4nYIQbf=($3%X0XE4pEwRIkt{>QnS;eYQSV huhARyCcRCMv;1J}GwC9EEQuM&xm@||m~_#k{{z6wz+nIY diff --git a/src/bin/link-z80.exe b/src/bin/link-z80.exe index f6760bf1dfa41e57c23be60e0fe451bc106ab6ab..1462ae12c38edc6d3309792451e92e195b3cdba4 100644 GIT binary patch delta 33158 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≧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 delta 28832 zcmdVDeSA|z_CJ1annHk-6lkD8AE5<=0%?=^XYS0IGiT16IdkUB-1czuz!#ebY|rA`cbIR^tyJ7!7ri9n)4rhnG#T&CjRQZ8 zLHzT^*iWMn|Jga_Q#E^!`Sdo#C3i2eQJo#}kvlq6voB>Y&*uEU4sIwvgdf0haXiOu zmoqOnA`VB;A&<+I(|A|njedccYvx5gKTWxv=O&3e_$c+0Jl8P{0H_xwHYlcqChXw3 z-W~B{hflLFTW?3nPs4$dP{)bi@iD0qpY--MpU>5*Y_nVh5Z6$!R@^&6msPMfkK2-`cbU(u$>TUjlub7)kF$j@$>XF$ z4|1HVRaG4#75B2Lg4POXAz$UT^ax?rwW2B_cX<%JCx)XzQVja3 zV@e^6-ek($#j4K7*LILA;y%W!Dv)td+!#i`n;JeD_% zp_g&H3zh%NCK!? zWVp7x1R8X&T1FyRdfoX6a#67~*gsqW{CZahkE#ZL6U8cqKg6nbmtok62*KZGh&9q( zwl|QM;4bT}<{Bbq=W&y*flNb*RCR@TgQ3*ae-a#>LPN2q>@OwKE8?dk6BOXuwUMbq z7;d?zV)iIAW!H=vKbU0?bAvwd*->{z2PLlV0TNKKBFc_oZQ6h%glkJsIs$AQVi1+4*1 zUj9(9TpaS2+tLlj7F`@4X0VG@(Kqq4#RsGFX3h!BqxUyb8>;Kb1P?9UomnIkWxXZR z?|)+AVx+7|~Xd0Iq9c(^f{SDaq@VGI35Z~W-1BkcBEkm-G8Ma(5mk z6ja#W39;i@y?ixvr0^XZ2k9fk0l07m_vM7xsWMyylW?o_LT7Nw=W)mL^lBlX@2o_o zIC*0H1i40}H`dk~y^A?xa};F(0wN~`;~hb z2`+O2&~o;8A&e5mw&NI3+hQc82iLOUp*j0^2x(hr6qrfBK%MEES>;neNAyws66xw1 zs-h!o{Hi%=`?riwE;A#^p>9|W(i-W-J5&gxSisz-*bkzqGondGxlpKd7xf6N zl&w2pNDuGOpanEQjdxxkqH1~+j_7L6CZUT$QE##2tUX7qsv8Ne^L-g6L{q;XsQ|k0 zM(Px5O(H>|TC@9Aa+%|(%l6;7%&hN@r7m+W^~!!bs&r99G;<^URgzHTGSic@XIAr0 zTQ@;idacssZ)8f&LRej9dUB4@LKuM-OYg1rbBxslac!ZKpksKXyivA`G-7Nmp0$eL zXe~a+&?)`n;24ao({fhlpkIBywoqa(vmx}&-eh?+y==UdE{P`%Q-&G)0FAP%XRu>1 zCh+mii`O>2oOFTLrlV~Rd6u3=N_xi&Vd?jZuT7gikmRda@`&BjMh~U5Rlv9uD@&wx z;;88{(Q?J%Obo3U^f6ykr&Zo$hTzGnh|owOY~EUN#dMuBPnJHCtwS^%MXF-yA1fIj zgl?fsT_U|Hzj+D<46sTMv#u-2<^ZHn)>9(Au!3;|WMY;;AFpA#ZaO}w(uevu#1>OPPxP?Rr|3NsWnH3xvo|@A_a@u)y$)77qOZYOEYBv?+79a z$f!&*_%o*nMe1T{q}-;fIn*kh{~hZC5z63utkOUkxOy761$?Y0P8Al{`08o42u2dR z^C5#$0w&}{u{4*VQQM*d#gkbEjIM51O*f~hdzF}G>9$H*x$)`^-}zkl+&O7CA#6{*f|s&^5sm2h@-N zOgn?kF9E$w0yK47i78YvSiDz1p7Cy1Em^!!nk*sI)2mfFdzbi zk)RBN9mv+LXcDc$aF}JQ#L%>HBnr$}Ze1=Wr%j5yxQs|36W@B=a*gxU8yG2SaZOr! z1nC&*o6mec?+#%X5mh3Yn%+pWDU3;^qwJF#vPgq9^Nkb>Ve~Avtws~J_0&$8szkbV zF*Ok07J71xcw43(i|fOglbk1^frT)7GLw-dda^Xze#Smc&^9B#M0)8HHlG@@(3acM z;i~E2?HW84_Tg=o?mcM08;-<2N(@Be05us_1sYnu3W0=nm)KrLRs&(fUS<)a!`4br z&M?X>mhNPkDw{-^{$}U;^CIU4>ze#oS;!LnRVT`M=p)v|fVD{4Q7BfA*D~Xgl%Gl{ zG{A(QSz%il#ORbd7c#!f^ty}Ax@yjb*v)trtO|c_$@U zmyu|*bhXm^3O}RHxN6R@T4&^1?SWd|fm+I2SF&o6x1t&(leJcK%2jiU)jK8EOQKR@ za4sdNH7gQmZ80KfaVX;+XzA|a0OLlnE`>u!BfBe@&52KBjdW5SKZCzqKwVdP)4&~U znDnl%cq|_yZ5#W+yyk})VXH%~e+ZwFGr?nd_ol?|O>5iM2TaAjgHZbXI<{MdD)5F;#YzO+`YL&sT{EaWWNE=Gq zVU+r5enu{I)m)@%NBULs1WI~1#{hqM>#fc{dVc2zFwcQVW65cPc4b&$khwZ}nQZqg zCCh_($!$!MyDSVlt{8lHFu)Uic(^Sm1Nl(I4B8#;jqtOlda!iq4%Sb=*-rNF|M$1E zd>dyCcIR_{RvfYd{5|f^n@4$pxhv;&zQu!Pnv!nI30KXDkd5f+3FW3ykS068Ax&FY zbdFp-UTvFYW%ph=|FE1Nf_y*q#Y)$Ae)6qwInWGtZ9uQ5$&Ct%#O&R|I@~r|2K`TUhHRbbDKp1k(?KczT|2a z({qRUX}IGYu|inFN&emw-WSmUCRO ztXR&ekq|8B;IEL?vR#~VbDT~Vn^sp%D-)YmCQzGN@%)s2?5+mlvv0O6r5y>{?9bi0snLxc4N)N zLyd@{C6Y}LA)hu+as_uD{DDjZ+)sK>Zd`SoAN(3q0ADi&P`2Nn4;w>T%E_6LLuhX84)S6M5|~LtJo;O z>Qb4)2&TpaqrjE5s}^a_oKtx`5n4b-Al z_5l!#R4I=&?6a|QrTtVXj4EL#C|B~nBWS5!iS#iWAME`Z;ZQOS1Zb7s@aH>2+13{Y z!Ct0=zJU4Cug4t<&|{X#9WS?hpkK=oa?5=iWtz_TwS~?HAw)SiQ+AFF|FUzNYtEfO z*}bD1oK$+8G&&`i=|>6g$NmoV>-e3rl+m)Nd+`>^tqRv_!Cp~?Fv=dBUM~vLTgZ(-?==?PQp?B*8gvb<-T))we= zwA|@l!1<-*Ijh{~JF%A`{Y@ImW9hO=SJ`Mgu>uf0FqVy1(G-??YSJEe% zi)CE!SXBQ^csT}ZlI8_AY*34yoqS&zN}zzTN)sTY174H3V*wUSlx4sM z+0 zF*k1U?*q8bFkFJ=lwU4YGA_9LF^EjhP(sks(^S^sNRp{t*+=b(*}tKdns4&XEef4J zAG(^kY!}QR7!`ayZyuq3D;rgC$28EREmx&mg(x)XUh%GZ69&-MdGT6NoOkmWIf>Tc zf3O_}GTD<{B8?Ke=S^2r2E1~l&)14m%ErV}+A0;xZFxr$N_h%-!4jZfS~k&1FeTD2 z7DkU`d(G$TJOfE{nIk|8oQH5oE zcbMdexpt8NX@t=oMh?xkP;#Zy&k0auleUuXMLSrYhP8zTIx5|bCcWqVu3Am~Wddsl zn53u2GJ3?~A-kk_q(G<398RR$Ls@U&_(fB^qavWi&$(*OF)e=vh`rx|>sU1?7% z64g92UBU`cNhpTbVZp0}RNZ)L4T(BEWu|Oq`AY9{xdDY^fq!>G?u8KMUQm*Iq2~ml zhfUaXGSJQ`xg8i|f_5}(C?7|pKOernAu+yUq5>yivnr~X(Zbn>$_9sYGaD@QlTibI zeHbN*r73}YrhdqePl*y~L?EBM=bU{^KVSdQ2FkNa-32uMK*^SSLP?2Ysh#Dk;N=1< z4$Km#&M$J(c#&@CJda1;@O6F~e5DnvlNM_Kz&Qp=TJ+AF;4-sur^8x0>~XUbXb2MJ z(g`ocZJ|0m>DLx&2&U5gDX;yG0Mbxt!XY4C+V}oA-d$!^-H{-$lVG=&UfGE?oj!yS z#Ld%)1e3Ghje$34Jh6<8lb?c<2x# zvc#6uSF%kUQ5C-u?*UpCF;JB)o$~zKpxJUBJIW$4q_#TAIcv-62bCy8xy;NfYhPl^ z?Q3R`T*iE}PgW&5`&E12Otgi2-?#1QgMXD}!b&#K*xQ!`sQbgqG*(L6-hK!?GHe5Z zHik2%(UY@J6~ZV%=Qg(HKHLk;oRe`wF2x8Dl=oeic|EJP#Lw6Se_O58mVcKwPHs!k z5~y2i$J1q|C$=9A6k`$<+dBGD*A00A>*Yf5j)1)J??IEWo<-Qs^#g8Yz$y?Ro?B1? z4{qARg5k92xv=@NhjxB}nT17A^eh~uK=ky&ShhZCjw)b&(NdKDBI6JEj7sRZd)GV+ z6I(asrH|dLkk_=mFZF|U=i#yhTVC^(G<~H#gy{{c%{!8Av|h=JaZ;|5XQD}UWy#Pt zcix9t-xkUi78G_~0SLW{s~3$-qIoABKj`zh>#e{p?4l=*=%R3u!qrpj7>N24P@noB zesxC#>puy-r+zUYtj8=p>YZ9A>ZNw54C?UxTkG9n7)IH_#6EiXSW*|hI#*nD#~2&&;YzKhE(xs!%nThY zp$#vv@oFUH;4)J;Ib4j?MNCFlM_?a@i5Jov}?8_+@6pbwUZ_IrrM;v(P zs+p`xA9F`thl)gn0NV1Eq}>~2gzUVmFdXN&%G&}R`Z}%Y=$#>a_W!hYnDj6e_bR$c zw@jw@Gi!DqAWO%g@Qxu1PV_B_bjoY<*nVp>7GcUPmflXMDF#K&V1O+k$*OdWq%5bo zYUDGS0^NDE5OMN#Em^}j##XDO?PwKv8cC7#X%p~LB{`gOnXFNWnM|`Nn7)yoc#h=q zPCQXPU}F9~jZp;wuu5tE+N>6?amfeAed<2R`05e?tW!d;3n)4ZbP3Zz4r!z$J@>+Hg%zqIr%zybx!EV9@R>`>jSKmCAomMIF zuf#Sw7gKl@q=jj{J%l{MB;NwEs~nDo`{XMYy7p#n#zWKU%aH zCj&T-=j-IkV_`*K*YKnOievzEarQy1^6}gh-WzYT2D|x}6vo`&-k$0&Zk?UD-WS;9 z%WD=B-;ehDoJ@XcZEB!LBU@}peh=^W%O>TJ__DQ1!2qPMpCR#m3eSGx+r#*cQ(%bi z{r=jlRzLA&Na$9?7c$igrpPxS=l8YlUmZ1d*Vy#)*I?p%&Q{ph@4J)P@bg#yk2ImTZ%g`k=rTYm0t~y ziBy6UYGkaYUd1q|RL5xo_jK7satTm5Ai&14y(ZP^n$tEUNPvs|zrPa^#w~2}s zw-QaXhuYbNgaFC*lpQRQJTlwdmOZYTJ)9%QRTB=uXtQkZ_JeQlA#lrfLR)O(ZVyZb z-!$qNWcj+uAXxSUd!hm{I7+C_WFFURe42QAMU3K~Y2pP$Z={LCR!+<#bdf=v^BGPx zTw$wAK`dRAa5d9$1TeTVuq}fBLQq(3Nx>Qunl`M=ACSQA3t{pm1-6ny85eK=Gm|H; zma@fvtxaTG22NAI4U*vB3tq%L3b7~RskCPcVI5c(=?GVQjuKjW1r?3-=B?~kEL~Sj zZ{Ey)#a-7G)0+?m98MXxT$ykZZhC98(1wg`11uNxL+6WBv{K`YxlCnZhblFr8>qOY zgWS(UlpZ3kk#f8r;jRc`lQsfR#~@ru!3xgV6D7-Dm|j%WNF_K5r^p=^jwjk8Ap8Q` z?jGWJ52hQt`P1Wfa2LV%6LfHAHxPm;p@aaY{MHCY#Fp)GG~cO+j1ATlYiSB=$#o^p z5h}g@C!g(UAbw5mxh+*rZ zZXk8E@nlkmEoV^baP6+Y)b;#E>QLNY>Ux;q^hq6x`%7I zqa$6o0O2m`_FwadS++`yUmvr8I$VQ8v+fX!L>HFZ15O9#-6HSPIobO(i6|oPlfh3~ zPcD(h#17u~E_n6H4JA*NL5#|9F+5__(%zbM`D!7P{-W-X6Ck56$1m7(2${c+ug1&5 ze+UPUmp|OhPR>ef^8gW;O)`Ki*`z0MQ+82P^RQXG*nI!Y=!F68zb#f~)^!)bC;Wc; z5;_y3pOpS6^Aws~X37e$(MdYw2<*_zE$c2pOGRx;c6bK9at-uO8iZo+5x*&#CHtNV z)l7kX@Q-V{nVXmOqL zKd29D*ljr#kfSp&8)>Y2gow?8Sh}%f3c12y(U}Uvf%@ej>aU|^iu$jN;;D_Xeegs| zYY=|Vjo`=BT%yy0;hQokn!71)2=j2+q1*BP*d~jU;`fM$zXKs=8a8Btju%7^#EOtM*G4(;3A9S%vykv-5bmCP;=< z$Z0u;RzcZ1Ad`V^?6rKSlJy|~+!0JlF{fl0xgo0K#SKuk(~mMxcpX->6F_+bd@Y@- zKrNzOUW|MFJr9z-sXy7_o4?{XAA}!WWEEP5b*K`N!-brXGo>}+!uogxZXIl{A2E~R zEbHyxIGGLJO}IXdxk%}jufsQg&5$zoPz{icb_l7TL%{aW`dG$l@ZrXEw@Be^D1jMM zm@q>H{H8OSy5~rh^c#mr>JaDa*P)JZ7+k)7{Q*64ABO}pyVi&gJ{T|4W9hxVWq+4{ zGlYzu>xYm`qRyv-^w4X|SJ%i4Hxj_oRSh6Q&A@Wnu(upQm zE)!U0mj(Ic>Waipq-oznGkL#?$H@y+e9x9?r1|5vY8ADs#T@tK>q_nJ>q}$A&)n+k zAi94GG3xyX{c|5z)@4;Lx3qF=e_TylC(|_h*VgGwX-u)GGAunc;X+Y(o6-|l8N3jZ zz(CVZOZJcaT*n%4$p;wr5$sxl-+%v^T;^ZWBY(4`LvWbVg*y#O++8FI+Bo}EG8nrX zNX0WFOI>U$fVyDkT$hHDVpR82QsQgESSJi%tCBLaVXgvwOBR_dy^#kJ9Q1XjeR0XJAd zed0~@rQ_tCG0q@h5d)Md>LbXjrz?7vi|mUGEbI|z#SMwDbZ;$G)xM)Z>6Te=bOe^u z;z+kO!kgf+JjtwfTW=8m_pmJCFTnxHL%%2P;UE|1t8g3R3*e|b1LU4yQ1sQ&oibEF z9I@ZTXP>e_;`U!JZ2-iPyAn!*Rc{Yg{rP^@fWA2>YN`hE_k$!%1l2}1c#uu;TFTuyWs~$C5 z=*+m0$n>8hYwG?4br^hkm~>;mZeZ7g9Omi?I37?cc0U?liHpWakk0=4pWX93i=|d^bhe==50n{d&gT#w_IFss-7^$i{V3q{x(D*DC2g z6~5oN0Iv?wPGuqZ#EW7fjOt9m7sf2nr$}90_|6A&Bg)1`GI$L)%C<8&$YPWFkB{1)SuGUDQZPCI7#~N}yd0csQM1Au@ z$H2pMJnkJ}I$kqSINnGl)k>>$Jc8pY8@o2(gWKjxd@rRecN?ip`rCB{s_HRL>EIy1 z>fbp`9|XehfI4pFFjsS&t3_$HF3aOKey9KN)eb6rOZc&+C)9O576w}FdSocOT|GX# z5~g*CYmm>?5|_XEN-n;B-*{%>G3f;@&dAN%z#uwndr413{{KqR4zeb2JK0a|~xnNIF)nBqFluIv+1hMta z<@Ui=>3vF9E<9Gv`HU+;j!(OBM;?cke}NAQH1Wr*K6^rVAV~H^@%BI8%)cl;@#iQ_ z4%k*%DI8z;&M}|yz$)?GKTpg5h}Elfe5r3f#@aL)SAqfe4Jns2qX}iDBdY$ABcz&N z=sK=(o$oI1YkCrEx~cYwI9|IA9(A|n91W$%(t**mN*fZzzd!jkDF?f1^RM((qGL#@ z^cH;1gmqxKbZ@fQ)G$%;_;m4XLsS}Z*P}e)4L!UV1YF8h#@WNF71dm+^xiZkhQbWh z)*{swl{ccA_gGYmDy*f_tm#eD|DxmLB{uAKh3}LtvH;phm5+h%0=I3-JiOx1Bh)q) zXYItmIEH~aDxcN>;;lZd4v}kPf|@H8suCjH=IsF45=|rM$Z9wzV;u+2=ms%t->59g zxcB>owuD=NG|GZDCZmnYN?X!QWK1eV2AGD7`Y&#G&?uydR)`cLpV7vkR*IERjdhLz?<*^h382l|2a7wOE=dH# zT^$;)Lf@=8T6a7NuPr?|mlz1oh~}ZkuxR=c>IXLsd1gAVXkIR6?SGYDCSKaVUa>+i zuKw#E_+^hgYf;-WPVAR?+*Ad*5VJG*dod zrPA?%(3Cxu^*+ax@@iE;*+JvrfU*a<<6PzgBn0-+RoeMmT)#$a9K~RK zhJ(^%bcelEx)Kg@GfW{sBCdJSs2Dd@-2Y;x;+3dGXruX z63z?9>T$4E}z0NvRWaTkd14El9WQT)AV+wJ*q;QKxs(Cyd8NaS_%eZGSc`-5dQBgq=&&2 zA*8Z)sZPn&e{UaDCJjnL1+Nwiif|=biJ5Job5@B-P2&`qUeVfA7}*?45TQ`K?g74a zk-l{*ny%^7#Dh&!)l6S!ec%m!bMZ2yCit;Z{TCV0O956UOr;eKgJi=S7-n9)Lri-m(aBc3k6p(jZZNDcF%q0Bkw^lo8>_}3(H2^WCpw4f4OHS$*Mdy(pNA5i5#$djQbEr1!i68FtWgWM z^}62bt!Vi{BfKx%-+T8vbSY@IyQbH(jW0mc?gbag-K`#RiB8FS9L|<2%Ich%i`+$O z(+BH9+%;-p&IqMx&IpyG5W5;2LfsqnCYrAO=s%u0yz=s=@f!~o{5r^i&&pNt8BW}M zZ0Ycq1KbaC1IhKlB$peJ?;%EP$T@(;#1!0^5v`xsm@sh zqZr>hx{JCr^-luD6j+9EqY#Psc4y{orguT-x==Sd{cgyDUcvbbFi?Hd)pZKts_6s! z3NpTnm2l7X(f=AS)qeCHBksfad42Q`W90jb1LS`gzwEJpqBCqh-k6lIIg>ZsFPC4P3GpwuFQy5Wfl{QWRsrY)RRqYES$v1^kC)S0yBz&7m zbzzp^=?wu;BNe%g)GsLDcjOBV5y5su~IY9 zPeA0jRi1n$!y{t|qd8b!q4$|u96C>d+X{+dxeyH%f%$Jkzf5ho$16`*Hmm)$3C`9^ zlUn6b*2)z;0}Pve&;a5ejz%UeWp&*%)Q$)!yC6zp6*T22*Ibp)o$cPF^o1^6FMf1% zv0~|tCgYorhp;}-s2&TBD$Gs}Mw=$2P;KLCIj-2JT?{n;_lJ0n%e>Tyj`5pr{$G#p ze;eM<#<3Ms9$P=}Y1}q8cu!O2yCw!f6D275nqKUhDUxpd1 z`SMt_V&x9;+OdU*nijN9P$-aFe|*jm;4LnOqBOSN({$4ZMqbenFD^b6kwP|}d$rm< zU+Io?&sVwUN8z#&8+k!X3o6!6{rCDy`exI|6`K|a(O7GrJ~eSzKEC{K(T^P>_hcp1^uOCfU6jY1T z&x{#gfR?umsB|yrn&C3{19x2q9xr;%tnQEPEXD>+F>E6~E>|2}F0S}EL9u>W(~gga z^21kSHLER>eARIt%ie078;RnJpIjqj_TZ;68fwO4Ie|UdTUP0xQQ|*8eIw1!0UIO| zo2#r?hCU3$=5bq<^AjnXccr8BYO>GsI}bamqhGC-HFJ#IuD5P3B? zeH`p_ob@@{C4H=z^4Z4zRi^Z-()wA#=<6x@0SAddNR){D=dIL*w$FFRGNAHJ;j|&f zre0bX#lST5PM|ekOpf&6ug751u`xmEvuoJ?4uw)^wD{&1VfVI#$PZw1mwC{BAq6wI2{G>h9^ zzra%=8(Fl!fXEE8N`DSRW8OGnAQ@WMJTT;hW7pYNGD6H5GEU2GqB$0!1gBv;n8L^~ zEU(bGHel8XEy9I_LTnhq&;cY0dyyjbycT(tycixGgGgo2TevMX?XNPk2;x zKCNAzr8vpI=&r$maF6$yKH$CNbJ4&lS?M*)W@oM)UL198`WQ{!Kd{-8Spbf6ZZkFJ z9XZ9)ebayK5F86^tHw+~>CAhg`OB=4)Ty;(dkH689kDG}=p+{#j6Zxi!}&5$(iI^b zz=Tnn{#w8lER*zQhY;2S(H6A5c!r!VH@#b<^%!POIqfn0eG9U%#c&;0&vINAIKild z?3y3OA2_5zqZbztcvqXZ_siN$SqscN`eixmC~uZo?3Y(hS!rfZzpMu+E5ZDSepzI@ zdxx1Hp)7owK}~K&mXA?_{mMs`ZkDWE=vBEEtDyQns-&fnI*GCO4x-V~I@e=xZeMUr zn3sS{uN;tMXlv28^27ABQ-9H0O1qlXrsMZ2Gr}D|d(<-*dcZ;Cnp!B!4&jpx=(9|G za9QayjF@2DgU0l}tphTT*@tJDv9l?c{)0~{D?RoByjSul-*7_kpfL`;10Q2|rRgWP zk(>eWBn*a$dq!D>^mkMhq)JO|j@dr0OnLy7OvftS0~q)Z9{{|4rq<<{vKYAFz zHYH|4d8tpE08TZKC&O*5!zt=liNn7JN}(GbLeozmK_$)kK+O4S+@O`HwP<0ZZIxL4 z)eJ@6ed0@B-AvKtuf7_acOSl>u@BfXaz?I?-x`kCi-q9BOAny@r?2&ckK9A6j4*Zk z4pH|_WDLEcdCoh@r`<+VzQ^>7rtUlBU{8LJxcnRQvMtCy-BVhcTUu%@FD-Q!Bp7_3 z3X;idPbrgb1uuw2*s0scmzI{1Yc2s$zE80W8j6>2X+1v6taMi;gv0w3UhdP@Q8UN9 zr7rw^vN@(-NJzHr5LM@5XGnl#g9P`;CGU_jI2AhCdAu51^IEEQoU{<_$>D!Fc@kX3 zl3hl(L2QTHbIGeJ9ULdFI+vzsZWo_9cNazB-$o8mLF~MPON(DuEf@9QUK&r18&?l+ z4+D{tUFLa^Gu{zz>qWOEG>B2SN1Ss$!4!#lrf~ZZSFxRym`>DyiicCmidx zd93)CH<5lN3PcA!kmy8?Ej*6*XV{V$Tsz};(jxB!xF0>N0v22d{bNKm64e)d+5&V7 zO9ZK1_*sQH2}=EkhZ(O_j92-7UQHCT2F4t3jv?P95ckqWw=x_ST%9=cqP%#V0^UQutMN%=(+&1@` zg%iRlXkgdZu}lfW&suOA%U+^Y8UwWCKG-7<%k>M}aJJI)t%tzx?;5_SgS;F*WrHxN z>~Ro=d~-UCj*S;wS4OOjc3nxhFOurb$m6gwVmGe*_zYkhX$d>F`N|RGtsTDk%DaeV z^mLJQ9aJg-z}d~gbyVSc&!_k4FTILYW65`E3CyYVw)f_vG&{?sMHnpdb?M31mB+<- z)NcUr=y!&R^jdLm2|C?PojxDy$->IxU+`U7$v#Ia6UWisg#5kew=mEhrPDXx{@>O& z*5`70nXb6EtltWq1?P?E^p1k}aJM&ZzKqPJ*7<(pUFo;_Ged;z5V(}1u3H*uR9ck0 zN7-Tz5jZ#_h{dvVM$?t7E|f=TI4$GioG#sIP%>+(-j?0cr~uK!6D%|dJanh zQ`7HcVrLoRw_O$EpOkTB$|gZ|XeD-4+P-n7(G?ec|Ge4{$9ziS=pSuL5a}&jriD)g%PYtA7NgM zuo9v6oOtQSrIj7uf)?N9&(Pj>B!MkJ*%g_xDMXos3V1Z#}>;FHbcZ;FU2o@{@*#|Dirfj*J zhdZ2Mz^^o4D#+t&?L`f_)nf1En0Q(5?Pp?(Jk)+X!xFwWG<_lO5J_-FQ%_7} ze<)4;2B>%XECwjn^h6CO#LER`USbFj^}@2B=oy_R?|<^}w~SdH?GlGpE3itdq^kg= zLlAfpWxBR10jH4b{-ui522I6sd)-(1@oH2sJLc+W+L~ot zjf;}^Z^LcGNJhXChSEEn_GON%@sk1oK?*1I0YFr-IHJwM#DU`Gt0TnIS0jc||1^h` zd0r@OcnE;z($!2w=O8iVmqta-x8kS2R8{SBzzTGzGBr9M17AM%i) zv#)hE>+;QoD`*w+SR^ZEzySyhj2caS0wAk%_05%U=E4}n2TZ)%NC<+GkY+p5K{dSg{qw5Hk)(@}LT)|s?UwiT_7giSh* zetKT10>qnfD0%9s%EkgLJWqMc^73jo_+T9sLMS2WwOgn)Rj%2G8f!0aTQ z`jL7ExT7hpZ)Vt@d+s@JSVr^-%pLns3ELh{5}&>{(o7lX<*yF>1w%@stDGiNT~~d+<-)K_Z}Ik#G8b|!qs#CeM1A4PSkeBc{`{ISet7)zV;}Lx&~s&<@T}7 z<3p+Ym@Q|q*usHXeNBo&8W_(dR{c0Sfv{kCc>&R0gq;Z65b6*%BG?gDihulZW&~@_M_5lGoJHvV zkygR^){DVakVEpntb+4@VpI|Eb{o=L5Dp^z*HzFezVy>gyj48=Q*r{;0$wE|H9`bJ z6hZ<*5`qEY7BTtaOs!1IV!YcB)+21Yn7iAj;AcBeLMY2C9Qn3p7~VeZ5lAa-zU+4i z#=}V4UPg9>?-Lx@5TxB|+b3t(wo}}A3Yor78qXkVpfpV6k-k$xd;J&q3m24&jL=fb zf!2x)1ne>i8~ifG?9>nkZ4EDAG)d+U)3J{<2XbF3EKrr}FPWlc151lh7LEz;^*cc& z^X-I^*VJ8s095nkrPAL&-~EGwV z%yqb{9I8_3AMlUTY3T7qUjGh(JX)~e{l58XpRFBS!?lFnzlQQ-oW0-ywCXWOwg-Rl z4fj6EZKqHUC3*twf^$mjG^44k+;)-*z_(UbB7fvmt(f0PIA{x-AXuV+DYSvsc^^FL zvRlfbLNBOJ=MzK<>E)eBWGskus6wETc0V?NkC{S?JpN*w>6m>9RIeus2AiunB%xQD z4ucYxC4`G^$JvU~aw+!w?r#S0Q!=OmpkaSRKlf+Ge*`y5d|M`Zu5%T+qR4D|dX>Um9^Lq#3GHjs}|?BB6FTE&l5o&d_- zSt>p)l6nRLiqJ4~uF_p8B5Svx;*%AKkE-x5Mu4K>E>}jW`GjTn8Nnp=f_N-&iE$q3C zJ-4&xPWIfxo_pEzN%q{wp8MJJ0DB%}&zITrFnb)WzQ4rIrt=tPT_edeh5Eh z;-Roq{_>!vgNiXB6I!$6e;R`Yic3adzb7#a_+cUQ9om=6y|-`o=5u zmvg!M5dsjO^yG4%BM|h~E4kdmS8@;SaPVQ8foC4e<%%!lHZ>^1Lii1b;>-DqN`B6v zk+<`=tDL2IoNitoHxHo>;UK~hgf4`rvOI1Q!b*gL2t5dq<#}8Jf)!yU!XAWXgbsvm z1g-)$2*M-;E5bH}W`te@<@`LZ0AW5t9l|yQMbfH6KQ7^gLDBeBoNnHz00Bd_Urs5yLW`!W~3{jIt*YPy0FdhT&b9tM4v9^uwe4V8ttc zdg2s04oBP>OTL;0hK4)_ zU*>-vA|6yMJj6Hi{~pZm-QD>vzsC7-=6^D;WezcoG)*??OxdPeO!G}^Otq%>%%{x@ zvm3Hov)|1o5#YFkh|cSN&=n?^B)^dITFRR#@1(q+60e`CH|PuWv-HLK+x2$+M*U{J zNB@X^zy5jsHNC_pGW^c4*09mA-LT8B*YFoZyWyhYnqiF7s5j;qXBjJv zON_?Ug4Ekmx26@O&&}AC@k+)&GV(JAn}?c*n@5_*m}AW2%oEJo?6KJy*>kg<*$-y_ zDf^x5kFqaj56YR4Q5h-*kU4-ry-CW&Tol__1@{$Xa zA5Q*Ta%=M7l!%m^6z7bTD=8uR-+}Uay`cY-{xAB!>R;5i>(A+bz(MP;dZj^a7-vXE zAF>U%80H$v4OND_4EGq0rk+gwFtsc7LMoRwAZ=t?e40LOMp|)NMOszbooV-^ZA*J3 z?eVn6w7;b_r5#IqCoL?!DgDXJ=Q5izk7u6D{5rD}e7}C(j zWxSN(Y|oG~FPlbXeUo)HE5$s+eAzrCJ2|^Bdng)j&EZZ#U0^z=>xy(MbPwqMp!>V- zi0*UUPr9d)zfAsj@{eF+Y|5;Zc`0|K*i!CKc`N0Uloc7?hM}Jj6)DQ)Um~Jo{@(dM*6;8wbh69Ep2A^SwQER-(m}V?6&NSX?d=@lc zF=nU6r)7ef_oeLsGyj&>m6nx$Yq}@>K>GLTgW2Sb~52l|@Az9&B(OHRErmV$TYqQp8ZOQt<%x90xj?12!?bK)A zl07H8GJ8e#ec2nccVs`F{bKfa*~%PsPJT{#&RrOY$8+{UsQ!`jZ4TD~4GwM$)Q!@` zfb}=)%5@8L+jWoWPU=3={j7^fPD<7%Z%ckOxe+3^Amy%jUC2wM#a6q+LxLm_9r`GQBE&d%7-T zHpchBtl_|B~r^BlF$NZ!>?)3^&DL z_Rlq~G;K8PHoa>4$aKjRo@L3JmnEA2W`51wX8zoK&iuVO7EH^@UW|Vg_Yky~;+%?{$H2S4<~*O%lyfrYLlWL@j++M#=3z=M z)2-9Fow`3mpx)Jes{6N2l^l^gA=!|epFAhIGKsG#Oq6r=9N_&KSNhd}HVYyMHzeFpe`88J8M+jC^WJ>WoxtYFX;4R9EVj)P1Rk zQjeydN^MV-Qm>?{(-P7O(jH4YkajZdbXs@XwY0(M5$Q4M6VeUoCF%F1Ka~DVx-VUu zQJ8TsoG|Dv2G|4p0WH4o# za!oT#b4(>r!wXGIP1UB=rga#S2TWT`51V$H9y2{@dfIfr^pfeY>8PpIME_Hd*7^k9 zBpnG=7kb;HM_(bQ;mB9(!}W2g5hl*M`}}GCcFSU(D@69Gl=c*>alWz27?qlknv`lt z&4TislR7W8Ds^e<%2a#m#?-phZK*p`_oCiA(Nic-_Se{koYkiqVQ# zhS`gZJ<-f@HzL*pTFJL3n#Q-9eByUCW>$+v#Z79Df|)Hosz}lnD454IC~sw$B(YhU z9&623FnYzK(--2caT~ll+h==_=Ksvu_-G+PbV3?(&PyotkJ%eK3Bg(CD-ZNtvrsvi; z1V53~TPW`NBT3bua?dv-5PU~ce?8umizX8>0zWx=z>42kv>6ufV5iGUM%zqUTuMp zuPIzFB%rx?PCqe7D!(>V`S*xvJwH0pwsnsz5aI@CHowlL1X1-4%O&+36)IOht zkF4>eRPFQ3$Y!L2AQ~Tjh17;RK0=sKtY6+t5EV$K+bE(ay-Rs#-pb@`hT#%uJ^!;p zzP?bp^9mhPWWH~Jbd@~3tG`FFN4vW9T34lG#lMZ67>p9zTzs8a%~@bL0x=-;QDW~K zj)AZ_O04R?AvSO3FkbCA zY56`nG}Do$xN~4n!;wI=rf)Xs>O0C-O=O-g4_x-ghl_icOLgPL=f`CvpC{E@1CxDo zNzFHPwC5<&d&Y`CjWa609~9@0pA>v~kT6pn@}7>2==7fUOoIUBzh5X6pI$C_PsA8L z@nBZ!XeF(Xe;NfR+P)pRT-r&qG?7|5Gd|KzS{uzXweGpreGcjV=P|>&e<8{sGNvCP zV;$pfveVk90`t+K>C~%45&O?IoZ_aUujM`;!SE=>FvOMYAr_-g@uv6$U*}~q1Wn|L z>mAP$@=x$RictOuiX%X9IEUl-F3OSXEhhVFNu|W$q;^Fs`BTIBX9}gI;`8xKW@sRf z>qEu8>zmay<^3MI7EhD;eb5_ia<(`rflbpRt0{i$s1q1eo1_xrNJeA4BJ!$`K&q!F zpuMOyHi)_Y zMOP$as4I|zu7HPh6{IzXcSUQ`u1H06MS4V6B!9VNxkS5K-x*UoJ)8M18;J*yP%)h` zjfhh)QLqEh$?&a;nDwEA-N;0p1&9fqSh2;TyBOnal&|CHaNYiUCTfk8}uQ!XJuRF8OJm#<%x#&oC;N zOUtAAezjzyDI)s*RKa_?fX;FP$y|O|OB4Wg(xSD6uc)Th^{Sz?!-eJvA~a9JuwSzu z`P%3QQE&gV;qc(kvRo*=EZ&qjSFu-InfRCBP01ccPJMhLqK+7%*NRAXM@%10SUX~% z709`%BZjDjA~Lfh1`~}$vXDPm=sSQ8eT~Gb2B;cnVMt$u%JleP>3dR$xv!DbHIsbD zuT{L6R@9(k2o;53F|qT4c2{B4N;;{OYkbODm}6?9fAEnZXj+K51ytCo4aT6K77I z6$J9=uzXQ+falNXtCNTXlZup(KvMi675~Lxh^7T^Us(G#Ml4gcA;saGQHmBKAW@~^ z+f@ALgCVLwLh%6qt)lH)6;<5uQoSNXr9G;SYp)_E3PAO)g=mBjN5Z-`S-~)EmqzkE zF`@hmrc+G`WJ(%N1)PF+fR_|h!AVOff+9q00MkqYzEzbvcpZ^wn35bM%<|19ye!1x z&L56ibV&iG5yq}1CI5MW$g{ekl^X#*JcN3_O(cIBZJ{Ov5ODzkS`bhmt&Y}@4mv%K zaH3Gsjiwk|h>Gw|5;B~&Gw2-*09DTuM0u$$rBh}u_cK&03#5zZsWL@}o*p$mQhRiE zTZnDqog`$qk)7Vbdf;$7vRS9VXYci zF5MN)8}cun&sj~mLWrWv&XK@4D)hcL(3R8{LrOJ%MoJ*PK@8qCDx{1yz^enhkt_f zCMLSP+^>@E#S9dc93)OhX^Hd!%!V)!&Ph!ykOQfSCDOwfa7n3fTFRp%PZZiKD^|2O z*ShG!u9Q#s65j`NG^apzFHrf^C-DiF^dD)3!Kc7vZY&UKDYMCNo zWomrLxd&Amlb;|J9nIULSZ@&Gwjos#-aN?mRgD*7;X{P zK(9BV*Ya}T+>enl`!q5p(Ts*qSBNjn)My9|a>DLx@y(g@Z&gfy>s#ViN{iv&_?5nt zR(LE*iKX67QZw=Lgt(Mm51f|mYPM~=QfL!08#YBeOo{Y%!cf~d(pKS1inf(S_pD6C z1u-y-RXi;2owZ=pYLK`izge4}Ee_6F7$l$D_hHO>h0q>Q3Z0aJB)7yL-_TmYji5eQ zB$n-{86kAEkP^STKuVa1akT&oh$-i$`_&~OGbxh>F^KC08vkTzG~}h+bmRbWz@P+Z z5>k)lTT}QpwR36Lw;pEuxA17nNa-Qr$F_kO{_AN1^m-14tM20mJ1RzBZYhsACC-=7N*Rce z&cV@urmLmtDkh%s5klpJ6OcVLptZ!`&zr1-9=Cl#9v9^Qg~+<&@$Xa=vnSu4=~+I?8bnCOKl+~%a#R-`0wKa9{&5-z`SMLtwLNY zvO`W1Mi$En1%v^s@zEJWlo}et@Lh6c#j188?v3P|N!2$<)oDW9VZZbNIpxdr;(6hFL60oJHg5&oiQZZiRPhV4G3SQLE-G?0dQ7`8$_t;V%ut_hT}cy zUEp{la`+qI#b_6E{gDxT3c)o-HUo+H(@jZ1f}Yc0BiKUFnp#&-#@(8#hNp`RTS7e$ zlpG)v7nl&vTpZ4PnWQnJY)5sBtw7CP2x}KtgtcKhw{0{ppd?yO#0B#hh=akok$1ii z0a0+%eS;uff;C{8kAtO;8)mSlQNrp2qrt3frwEm5U=N#q)-=v8y2g$QU1PSP3KM)3%FqGO`oevC2s=WRm4oA8uF;r_I-UNDO8q z#~mU&%ulh^koTYYR(vL7N|5HXLu>fMb1Ne=!(L4oMOZMPG8XCRDChzb{tI%#O7w-b ztqf7ck#=EeDtw~@bO0JUfCWPX5Dv9%Gl#kC7U$EUhb%N2u^cpM3eX9-%_v&zDN1&}SY|(vGH7#czraR&kR2Op$Y7cREwYApCy86FExS}>D2|a|I#O6dMq=_vs>{&bCn?sf`A2zy-^nOHq)H!}6!PpstuEZCdQznuxzC#m3YDB((W2XoH zP1)ioBTBG2}#KnaH1&r|svt(if6C+h32w3TBcr$qg5G$H9DlCR5ILsOzq@5{ka6AP0pd0;kda7pLW~ zbeD!Wjkw005GQ|ZM z3LACXcH|I`5dPL)%;ilNJz72xS0L>r?FQuXfMOAUC4T!vT1U>@D;=E+>qZ)s^Qn88 zT$bPvlRa$WW6-DaNQ{uH3B}4=66Gx#VmTV;iJLt0w1jD4$Gef3w+y}FGoF`}pUxL6 zvy+sMd?nUorz&QPf6Tr?`P-RdNA{xN8H^?rN5b~z>mi8Kk!4&yK?aEP(Xwk6%1`D% zP6%L{*4J6{Z{y;HJO>T~<5X=;d6OH*Grp~f!wv6$2iv?0_N>4sbr26=8)?<5t3Lr8 zrcc9RQo;Hp2?OJs6pl69HIDm(>bWV6ifrp7?z<=k|AYeH2{f0knCJvyMbJb`f|14H zhP7mAP@}(sA~}Jq7}h6ARya(;{{by2Dv07JkY)pIc{$r2aQWvJNVgHcj%_aw7(7Ck zH8C)z*2Z$`#z_%M(vSX8MFmm>^9M=cg9FMyGQ>2HNS4F#VeB)d-9TMiGZm!C84m7l^p0c5ZxUm6?B%%e7v=HZ+i}MYr!1h02Jmry5M8*@PpU@D4 z)?Jn7S~SO!<5$cn8*;hPyp&sCWct*Wyc1Z8g?T$sXNRYG7rq2%W48FK1!+O*Hh;i( z#4luNwe9c7W>VprOZ~yB6_Ht_&l}$IU;`!e3%Pm-(-^ ztccPj8pf}uOJC6q(u*p6zO{c z3i(!DYM--q1jB3%v=9UlA8{OguoVp#x2(Z3ULcLdT2))4i7l^6tGhywZCzX<h;BThHDMF5Ei5C}8g8b~gIT!79J=3V zXl)@J;}q0G;L{rM0bhf?-sX;xiMv7qh zv_iJNRJg)-45r_wZTmqdynELXaxNI&smMX!q5M8!%wibmQ2wB<;cFBK@fqQyj8O3f zp=2;rj8m`+7Y`{ytF+vXwx85X_@CTcRDSnu!p&;-W(~KL|0$(<>g%APRyg`zB)n9q z?tgFk$^$vUD^O@1p%uD_%A`%1ziI%7wO!9uxg;~vfA$saoU?Jg6wBol)`7K z`~l%4kdT(_hsgPm{UmS)@z^)3+07cx!(UFRPC7{GKla}D{U1&b9LTw{R7IR$ zIgm3lF*1i%(qCt^5Ja_dH8Nf!V|(x0a6Kh`q#h?#q1aH4VGswBvPRd?kMd?BW5j5l zAtc6a$CqFxdf4{4PL-#9o#>{I@xX;Fls}A?(M;2)4=TJ+Jo`0$_NM<;SSn%kt z}UE5hp9wr-`+ zMJr;HvUF^3VK^_out2JXQ$*DIuvU(PGT0e5hKy>9n!iUAPmL5+9aIT9$pBkODb84q z5W|5>t?QkL&*f&Tpl0F^xh*8#_xPf36+u#+8wUwxDSx;TLz;=4kS4r9O;JUW#Q9LS zq|_v{ZJZ&T6Dk17*gg~bORw6r$1pCoGq8q_Dlt|0q1L3H?=aDJ4Tc+S5WYFHE_xin zc7}5GfgAm5ACp361qJ{f(k_ZFl&j_9vCd!Xg>Vlp#zcOZMh>|`JJfOvcq1-eQmNdP zz3>rg=Wh)paiDUHg^&;-Z{R`3KySp&zo=S}52j5?Wc+$7taq(Nv^ zSE#02_i!^zA&j&vRO{(vl#rHU)h!iDYxcfVx6D+k2q!NW-W+VE%MZ?*)Wg=4kucRH zpZZ0-vjA(IOnh)|#6hy|MUs6fn7-?BPEMMHzJ`msdM!v7=8*}#KF1zX^8?~w>gqqh zMETXQ01C`LtbeemRQ`a>;D4du071_7aZ`CGNikeZ3yFDW4*g1MA#o%j6x&P^p*=Hxq4MQJ5W8P_K^WJl*5ZOp%I;n)P4A<>m+1H&Ilcm zSwqV{B$$|+x+{d(fNt0cTvURIzaQQI4mE&~N1NEp!PQ_hjv;c@EhIIBBL&~W7$6F1 zgjix?^VC;WkD$aMVH}+k>W3C$p`?5$<#*`8VzQv{>js(dL469tyw3EwnL0NiowEt; zR6SI=ddhtGD?vgz1ZoILbmU-WCMZZ08nLXoptz4$AqOKwMpf44eN!)9`7{ zi+s%>BfKMQQ3vMo_a(~QOur(WopKv*#ZGepm|FJ}<>?R6m>W?j;cikcXDO99>Z#E% zx zDL6vahQ=V&3tj8$K4<#U+d^Z~4^?2hAI{Ne;8Rvmv^b{Fr040|E@{I#U5WV8>h_OS z=xe7lbymWX&Y(w4WP_V1$B@DEP7}w(AFqxiGp+wLB1Rnn<+6X%| z;fE7bkmyYB;HAX20aaVKR&|KIgd2)#yPzW{RL8bYwpFUPBox8OzltG1y5OmDWF4zi z^PQSt6h#c-E^S!VMHgOdeS~HD@Qy_6)7b&|0M#a81lzuS62TTpp&W>8;4j;*EXEvQ5${)T>Bj*otAL0N4!w5e_c+YlKYk8ZDqr)~$T@*e@hGm`(vnPQ0NS;(o{_kt0y*2WZSDpD8|ky zR7XbgYt&3QTN6^ii1fUJ%Buca7lSL3j&P=)Js+%I*pyiRDQAERl_@G}S)7M0%#HN3 zKUObey@Ol~e5{Ce4yUyhYjqF&7VQOe)gFn_?LV)gC^${ko8iqGw!eBuSUrLDYO1$1 z#n!iS9$>6clo5<+3q6tkaFU)~rKuj7{$pqoK^mnjxLFg*Xw+jCBNp~h_4qkn(oe=Z!g4x8!5xD^$uo7mOw+;0<|to_J4d0_I3%vA$HNA zZf65BP`lGRfHgj9=nECP{T9_Z_QRSnwT_7lcb9H|V3KA*q*pj96nEEMB6MsQ;k~mO zt`NwWz%8;@dX<=qAZA|mvFcJ?jYMoV#--ai3#LLCSN9V!$>2v|R!@ZNz`Nwgjs7cT zku?9$kxTx;$iMuTBj@}-MZWW2iuCvgB3}vKvt&=pcaP*-`>!&%5ULo?Q`B7|nzU6* zZ<-k0E9&gXa-pk4P@Bm)?1tsGX=%yCI^v*{Qyyv8z2Y4;!>c{ge*EfBe0@1b&+J1` zz)28_-2~5=UBa-C|56gOhWTiSE8J6`R z$r|g#WVUjnqFpv2i{3`SQm_FA@~FqYg{f0 z!)__a<-^b|1sU%zZYk6@J@>C)UQ!^7-cit_kN|F4;nc-QWhvmFncSe6E|<81H*w>MMMg#-wZ-RaDlMr2;`%$oIM{h*P{s*%aPKr|Bi}+lc2Cp3)qTF zrFJwGq;hYq+Zni_Sh^dHaB38arPc2w)k|^1u<95RIPxr4{cN4a9a$w)Dx}Y~INk{* z6Lg`el@*;aYeA~Qitbkot;pmk=NkRLo5nB)B~+&8TqQ&2T+QTi5a%4YY*|~JI__8( zA)7y($esrc8tLuh;_r%Y7_}YEDl1yHp;kw+SG8t#wm7C_0ga1Fx|8tDr~|Q$6LLMW zqDhaK+?bxa_yDPROQ|utcPjjJ94PI@++f@Esp%rNPVJlt9&aCeJ^%qDHHg`X%$5_L zM=fE1y{xPM7CE#`JXGpXKArumvMEYyhnQTJQS=n4)E+4!r#(yA%Vg@WwhK6{(}d2z zD33LfyG(+M>75=yDwa;-bq<{r+^1ZOj4s9?q4pu3jU`Wp~b8ja*JI6l#U#T3expi#b4uZ7(W(T>~|VjEW}2o#mH;eHaM@W`WPp z2}}uZ3=Jl5C+_)>_N5}bRQ?c$K%{1%z!x9Q@G&HAxqwXh!*g%||aU)8ksUyS-t7a)rofMNRlA`C)>aIx40h~vBE9NMJC&f(_ z#^7oQ)&UP#$Z7&9FtZDsPwR22e~!O2zABl&l)5!BdZ!XcxGktZ$U)VXm1xvncj*n} zRgJ5=bd(AS$dwm6K zz`g4)?~o|D^ctI&Zo?e(RR_U4Le+86gL|bc;(!_{`ZKFj%A@FctwF~5 z!7r|;hNH)}Bg(((q<<5oix4G6Slt#-2~7JhZn%oq7_=Lx$Z+E*>mFTW7|yz5Yo-Ok z5C#`RjVrsN4;#QU}mWt!zjkn*Ie)FrcTp|oe$Hqa}aeJai zOm`nOG5ou7WSo$TwKgyshxJ#)cW$4m0-MDjZci9RsE@vz5y#w7V(W?y)*ij4^T(9q zSSTSXhD5MJaYSx+^w) zVD#pfZXYDmtKt`Hw^*$Ada%EGO@*%b9(9$L?^db0aEn{85e6tVoQL9Fh>zoQ*J=bi z0ed%!53if0wB9SevM!ZG|5%rpMi7M;GdCeh0>lHf05xC`Z7u+MH;R+j=f%@5WrDc? zuoAH8UUAF%wdE%^ffl*{WAs;xB(Pnj>{67nbVAu_G(Zhfd6$H=1_=Y8DOWY)WaA>$ zvbG-OE$~{Z_WykTPlI@zdSa7kx^uP?(W*NQX`~%6*CW~qcnt6a;3>fKfR_NBo5UCI z%!`kb(~S%XFaXeQ7RUG&1*w{2N0&-LB8xU&0uU+Wd$mRUx&asrIOR>#!dn#~ZgAMU zpmy>uXk8DLMBR|9w!gheoy~WX=SVS4Q*$FHYA?@2D=wDLk5@)wYA>gAvB*c3;KgN# zZf9^O6$XW_o~Maa-6QuS;YVRPms)$-5Ws6j{U~CUj7_nQZGkvP8O z@4f;W-N9pgk0AmZ5q-uq8Vh8NG_2}+LA_~4C#o*d9c;(#i54CR%tB8Vo3F372;2b1 zt6{kdRq?os9U_7~x`nU-`wZOB>Q(1LILG$}2jRgtCHAZ(ZghS;wyd}cAos_5JR*(7 z(uCsyG6|9Vi*4!ys1)RqaD~CS_|KJrk#%s-v0KaONI7e+n4&1(Wiw`Z^>7#?10(sHyu;;sV?#7WWG-}y=&^= z52XlIm}|Mi6_qQ<`o3V$dOBdKZw>rlJrkH!e>U(9UV$Mi z0a<5|6^pF*BfqYwjFP{R1xT|TiqW)sw z7Tn)0O^t6Fk!w9cagJ_^CCO3PJ^!m>MI}fe8GT$NyhCnUqeO4Bn_~G6rL~(o+?1^X z6^Tvj@thDDfqzE+hC`qe57^(-BwEp;4 zOx!Wy3a(nt|G6nwHXX4qlDDb@>cxxuPYP`-Dk_h(iw8DmiPP5E&0GF^D_F}>TeA(t z#0n1LbJs2eZveVESi#wfEii&<2>-EeQYxy!v{WKm3djLC0GWWf08*T^1txIuc%%fG zV66r01nk)Y3%IUq+cg8YckBOX05vEAF$^m2N<`WUSPl3e4Ir}(25^pI8|+_3Dq4ZY zmr(x=z+u2~!25tRfU|)9tuTL!$5UGL2onLb0gi3rvb*zxd2luHw$Q_@ZH6#01#3fT zB<6b)ahe`lCp8bknKXS07u^-c13)~SEb)2J21n%Y)3q*uRXdVQ%1V3=QUC|^1TE3k zlLH*TvaE&RAS*Tgm>~(6Vw&M*!nKZuj-nK zT@BuZ)RXf+4CK77zJ#Ps9XJ60(q;%$@vR0pn`4Qy8TLwOop2h+C>5!w>Gzmg%img! zjSc>OK@l<&gy)}oHk7;;o?PKQH!Y!i9#7=^>lM#G7tUNBS~b}AwffocAG**F&Xt5? zfw@hE3Mf>XZahOkdEFnHMn$EbpKP(LVA)qz>)C&H&Ep* z4@&;@r}7qb%={@*oSj{JpNv;;c`%B&Wv*=`glIfY87->Ll}I}gM=N*6Ttym*4JDJb zsg+`T?z!h8akgXz(-9aWVT;d5;+-2OxJU*#aD~%%#*j4Fz{qLclr2C1GV=`09OQIl zqTmsuy7>A=kDV|KY#Qo_j-`e4OsPk|RL$#p<6|&9Z*K{%Y{+m4??v;y_lzWCq*>x~ z_f83tq7uBY=!K~$!3>#6vGfc!CVspN>BV1nMVnu*L;v_|s9qiF@rPHMTEpR9{EgCj zVJvRB0~4YQ(>Fa9(+h*%xN9}2izHnbsJ_ir6@wOLnfPfDblw!t+E+fj88-exlyJvs525krQ9%@)~^Q89!IucAxKg?66NgM<$0?PdKy^jwin>m8PLo zP?guNHK>_}?*b!>C1wI~cOnV@zEKcsHcwa1=@s{EP6$SC$GWK>Pj{5KOXiZXl7msY zo#f^U%+fvbXOfUoqQ`%$GSB=Dr+>y2GMly}7$P1!y{-9ssXZ)%{>=ZNw zL()OakVM=B{%{Hw{Ab9ckXYS*{KZ5Z!k=~f@tB}nGrBE$aqO3UWiW8$CHCOvTkecJ7Z8TuCAJ*BJqwY zJO@T;&u5fFuz~L(VXMLQ3RSI;H>I?c8cp2mr$&zsH6CnpQse|;{e;t@RcG0M>gu0B zGn}x8)l=wS`AC1dApTHgOC)tL$b3*Eb7#m28QISEW{aNc3?-uK>iNoZ=f#$43;FuA zdImXV33!6k%Q-Hm?M8b!%|SyC4RdIiN5iEwETAEIm@TK3(QqXVSJQAU4Sh7+K*LQm zB+tj>v~4upPQzLn){`)p)<{2g(r_0I$%VR{W~Jd1G~7eOr)c;z4WFmsUK+kc!vi#Y zgNCg%JWRtb8Xl+N2^zjn!_zdJe1=BdG(1Z~iH3x8+-<7an7Svq$#GXt8bZm~;)#d3 zld83dcW<#z`tnO?(P``=*?)55f3ZD|Y)P8g2V^+<>JN;=!b7+M0iS{-?TSA3ERaH9 zi1W5iR}OwD7HpkF&l)ytO^JWx3%c2bs)xLN+?YD@&{W*BH9^ULExxifP3OK=&S{IJ zEHSdxu)OjIyu8CrTZ!o+n;bPM36MmgT{t%UeJ0+YcB!!?xdc)2D@ux_uFtRcg|#$7 z@|DQn`?+|}wwcQQv*P31X5X;v#jCXfnsi)X??}Ysefs`2hMePqMdClVO$|;3vLeX} zw!n*q@wq@*(Er(#i~XN1N96f5F=d`FEkXq$oe_Q)dR*?kB*aKsxB6OMQglW`>>#`Oo&*M_bUw;~>g z_zA@05pP1Ah}epF5@J2#$%s$4dYCDQ_aG*Zp|>I4hS-PrKE!3Mo*;8S5_!lNM4W?| z_%E4=ceTT#1|06dW*)E$PzzWKC;(&vQUF@Oz}xV40j+@N0lNV^0owr^0ILB701v>S%`I3m~qW5D3@{*bUhJwz%x* z)ae)kLoS2}lnnuyJMtsUf z@NkWX`QKq*?%$8<$Itel-O$hPRWSHx5|2(#2%cG}U`iG!7(ZYKpb78<;90QhdJ$`K6wD0(2VgnC52(*kV5*S# zBj82AVZi%pE3T`_@?o)QEeJ)3Yh9m z&zoL19X6dbeQp|`X~=YDF3H@OS)ci6=AO)FGWTc3o2Q!Rm@~~)X5Rd;`7!fx^FPer zn7=pw%N%1_WGS=UVY$oFY9Zzg-HIAD%Ff!J z70%k7^@prKW$nxA%$j0NwPskS+h*J5+p=sP+hW^tTZQco+e5aUwr6c`*pArVwS8ne zYddH2+wZm4+aI?7&i;aZzx@q+m;FO~xBYATkM@51pk2vMV&}3JmSw%{&FtOmCbouc zVuOEVUu3)3ci1!R7i=%v&;HEDIN}|X9kU(t9ae|Ok?UCIsC3-rxYtqR;2mMduN}X4 z>~-vSyyf`Z@uTCigKnva=3G=FRE zGhZ=}uq0YCEFMdbWoDKo>kjZn%xcLxnDtH8>F$cdz}4{{f<4)US=6btRpzlk?crwq&rLw z8%A2>Sm{{f_#4J|(9!NV<~ZT_#?kAT;+*cB>ohtSIrE*B&aKX0JNG#M=6uEZrt^ri z+j-8(xW>7xF0ZS|RpHv~+U@#_tH<@TYl?f8d!f6`z0u9NdG{{&lkPvc+uVP5pLT!a zKIevcF<@mN8;^FwDT8E4G@de^G0n)#$y||nB6D}v6Ipw*p2~VU>-ns`SubVnvOZ&7 zVSCK>r0r>2tL+0DV;^OoXrF5ToBgo;WBZr(KKn&`DtjZF$F5=@W*=vtWlv*5RgOf5 z8AI}8(wZIr<>+!;a*V)Kd7Qb<<<2JOqt4*V&O^?3oQ19xt~PfksC&#)*uNGCs>Vn=#rr(KyXG%a~}1Yo z*iCkay~KW}{T_R*{R?}Y>k-$VUC+Dz=4y3yxIT1!?mF+1U2*R5?nL)gce>l_zS+IP zeYblvCPZ*Q>t+hT|Ccb*Q3fMu|E=*U<6h%i#VRgHKm&7n#?8_bpEL616-^2 zn|?Np$c)RJl{qidjH%k58OrR*RGI6|P39K!ZI(MNTPz=0=4RDo{fF&An_&MO6VnQj z`;0vc-O@M`pjRy9Y>gw}c*yan%=xkN zYi9%^wiLqkdsnxs-F?Q*tOmtUv9X3p@J8H*TMQ2yJ~Ny%+?262Bb;$DLvNg9OrXRY zK)l0Z@Z4WPPpE8opznUIM2Eym(gu?JKP?34rc0Q_X+n$7<;$-EK!|J@NK{W zg(2Or%COepGi-pM1`OK_+YPmbqY&8l4W|uf3?&&GGsYWlG%hd}8~crA=1u0UurT%J zM)OYd%jQpEn8l=jywwG-0U}O@+F2+8_ z?y)bkueR6OAF@Afe-Xyzko_pcuHXK%eI%=Ar?5_TFaKRzy2I|@xSQS2xLsk(lf(FfTW%upIN#xcft<78usai(#u(P#`>jV`QuON<4^65~qa z?a<_n#(?pDW3BN)<4)tRjJu70fMz@k-O!rmm`u=sqRiVe@5_7;E8lN2Kh4yce`o%i z*=t#530g$Ula@bPUbmct;?Bx4Wi80c%VJs?>c`GC7z|6Z3bIyatFrGlx~k0cA`&oOh{Q}l5HLGRg*(5d^?Oz8ktd&=rCNmi$f+5s zV&vyfW~lOL-KBZ}dG4AAJY?)s|k~P!_=UmBHXxp3i24h zeo}XZ%cv_z6@RyKCP~n+(-jQMqzX^5391;DIX4jf`xz!dsFkG+n8LD*f_-Y-sA1E* zD>r-5b$k~RLb^t{!j3T<8ieBhz9y3Q`*UIHX)Esc-j6oLEF=d3YLW{M*(l>K@XTOp zO09#GfBSPWOvAMGE7v{z0K+^)rT}LYuZubKq-;}E=Dt{lxon6+@-`{eqWkjiNU0pi zmycr+m%k&WzmjBv49OHFk_Liuo+JUZ2{~i(h5a##?0u(Q44FNIyZ| z+K0RtImIi%B&x=aL2f?kMLNx?Y(h>|)lfdoBa$Jr=@5lyZwo5d<4CW<)A2bf+rpI+ zR@@F84`GbYkIAhigxul-Ih0VC-)Wxiy9u#hhlj^gVz2fmrnyZ_A1j<1I?^9zXL>(& zl+B>U8J=Eyd`Hx?5J1&&Zy3{)N~ZcCj2fEi*$g?B#0K*_bH!yNgcHNk z6Q3vO4c<|nDFpM6!}^Kn-dG`ixJIVBA!H4|%YUYqsDL7nc`h`tHS=7@r%;jXvpIbJ zxm-T8Jwp99k^A!$NyTTMLq~h#l|i}UE3`=&s-Qygka6N;;Wll<{@c@Mkm5F|Do!%Zw%(j^>_${hbe_Vsf_ItG37P0J&<{l z&pt^Qqh8p6jQ-Q9^&&Xfb_zGEuV&^Hy>!Bn6_rt(wF{!>v*Iu$|0RAfd>McQ-41wC}CRjm<8|8Ozi z%|Ky13Ua13A{BWOb_%A>XU7B=uo0^QaV9hZ=c{urI6M?OP>`hB*FbECvf?!_P+3gmx#dJR008jz#2( z)wE6NIoOD{+g#>~rQ!Axg;+>SME6UQ`OI@}y31P9nA@x(766=?VQl^zYO32i6|ma= zO0$nB&7<(p#D!58lolPX5c@89B^d0zAxSyn86i7<3j2|;HU4G)&_swO`RSen7t<0! z44VzjXo=WI3#OI`m<3v!Mm@iv@4l&`EBRgSnVM#va7$&VSsYaMWV36)@=mFNkRjH8Z^BPH&bocpRbK+Ak) zS5Wmn#2`^yBHh7^NVbk>P1usSMmcw}H$bh5&+q20u#H#b)S81?F>HXEK-flC+#*b@ zf*NBTF%v$Dq}v-MmSGxu262}o0@+u!r+37WeX2U`wey+XoXAqECnI4UY=Afhrj{gJ zgFLzSH$uYv(TRQ{K~E|X@bpL`#;~6kzwDFt3exlUt3=5aRSmv@5b{dkc}hw94R}nn z69$M5fdLg5aEsf*_~AvTMG;Blh~I^`td7_XXD2D+Q?>dtd%Ylac^|Q8YG7$pn7Jhk zHC4A5ONpt%OHT`XB(b)S7;#vfourI!P-|vyC1{26s4oorIff7-{ciDtpQx!4|4+qr z+`E#G^AovHHwCYg)kl^1AkI!w#+MALdq9=X>~(wgqYze$&#A2u6Ici#++vQ%JO@!o zpBGyco{`VIitwci2SsQ!R6ip7}DV-4lNp5>mbn-aA3cqxc)Dh({AADU>JTZ&U7$MaF$C=~=B>9uyP zAI=Xzbb*<;?-f=(LD}$Ku_yTmrb&1Mv)+wai;6r`-aBzXd6M=cn345`bqTd9;PO%K6NHO0g|)Fv#y9f1s{O~o zj97JR?1%7$C9EeQJoY`opR8jK3x|`f?0lgs`JTuQu(&O|cIQ_v!Im=9PpV~yu;v(+ zZ}Q6cRw_W!T2K;O)llpkNW-(x0BcM6K)$7p^pq&v;wK}pt~yWwGey2}C5nQ8p7e=F z@90pLj1oUk09AXup2TK+92pW&4CNYk^V!Fct zF-SfY-zEMHno3ID1tqNHQ;O?HhU@1F#R=43BxxJ07oztxEGwR~cxjWQul~d(bWWUF zG9#X$i@Tt0Xe!{LCRY7A2!GSy0_Og>Wx3)z`zd5i3p>1?3QHl_$@=>KHTtefdi6g@(Do9fNXcFxoTub_H zPO^=;bNJ?PcmLsW!h@-C{Yhy1llZUHF*0tF@K&n+P*>_?b^vt4bD&5Vd-rIa3yi{F zo(;q$Lymmg_KOk}G!T`9TH{5f{6rusffU7v1sl|3<-V4-Hh`karVt1%lJmZSX!o$J)1*}znk?X*O8w2 z^Syc8_fcLK_x%9x)cL*z*eNsz>?94%mEtmp0Af&SjUbi@wP(0CX<6~oCO&H2C-)N6 zbp&-RALT_Ju#+@2l#lYz8c9QPK3l~%hCYD(DHz|7TGIFyNlIiPRV^9*77}5_lx#nl zww}(dHI0>j~X@N_j|xTl5jU!-#~4{WIHiDkgo*eOO@zM ztyQ9tk5VC(w^E}BUPzo9k9b5i*LOWMkV_)8hDdr45w=cE@DuVrB`$h( zgsiqVA+Suh5V?cKEf=H3=NkQCa6(BSPiNgVBapoCp0MJ$B;R$ZT^Qn9{V&Q?`H z6d|uL7%sg-US)hqd1A`--Rk-5LE%32IChuth&pc~7S44({w^7$ea-wiu1PKV8W1OROb{G~ z?_^cug{j81W1i8um~~ng^90}wAQJUqfZ2f0b;6s*Bw5-7;heEPq3kQ@Twye~1^bS( z^@s3T6igszk?@*ny6lAs!aq&hWLd1R)NJ&tAQ_w>VJ~pG0;RB52xKZlt-g##w5XlND^R^KE>4V^0M4)mUB?Bh48tFOcB?j*nZPRIQj<1 zH#zlHh0*`*#Swn9gTJsT>W=eXE1`AM-PS}J7DVNVBL+fmx{InLUs^$lvR^FVM>AT- zbM|VoU*5Y4#D{R05lO^`-pVV1$0#Kn;Id5vFxX^wL1BqpD;1k*ShX#KL~MwM4q~6C zUvsHAZ-EJdLR zewH#YK-w5DZB!Dkux`AN?3k(|5((N)g(BWtenMF4IGps}1csTsO~E?AS=yIuxiU1% zx-@qEEWE!V3X)$E(w)id5~093UiSCV!dB<(w4GRAAc~|-wZElcI+~o^Qaf2PZpI7Y zl!W_d#Likrx3rE#P2M>1&kS|3(YHkBK`*=)!OzovVNOg2T0TG3i)Kh96*UA{_EJ{3 zG$X}NBd<@mme`qAidgp1vSNfBK)M~5ebS%sQrr~C&NcBF$qIY7oMAS~>11`Jbzzgo z1&zKvl!kOw4RwT`k8R>ol2E`oNmxR_U6(K#h1LiqQg}!VuO&S}RRv*F2+mCQ$MX4j zAyPuCX2kG6rahwK7xi+-dJ7xBkLEw(xAv|%PM%cm4V3o=cd{9nJFxU>AiIlK4Tli~ zvb%l$#vVn9bMCT0w#s^HqdZWK=Y!!2Yu0e3Zw>+pt|w_j!h4vz;>`a9vslIT&&HJ< z%(ywomxfu#nf;+;uCb%9ALxB3M-Mh*2(ShatSt(VRPtrR6#-gQps18D?G9{Ff*bzV zMoDoWCpkCDOPtH_2*X_jW1Z1e`#~ZtzZWf(#Xx@d+(p(C;B#X{0E<2$U)sz2e+30H z-ulZ%8UKs*ly@zk-OcAHtU3Moe;br4&Rn6)ogTN~H~xoG_WQbTv448po;%pjQBaaf zey$=gFI-mebCrR4NRXw**Nm&>=ceww79a#evoRn0Z z9euO08s!Zs73I;0&fX!c@u$v&AgDoi-L3^Q4rUCB4^5^>F~R#fXipfcNP+sTEvcle z4l?l&WM)@jRA9;QUP&2U^$Y0M5^bt#h_3t+7g+>U@u*V8?#hhwe-^G&oIU{zaw}=I z57QOHy;x25F-(Ye#oU}TGmJ1Nree!XESp=dxJg^M%}U9)4n9XJRY{-GCaE;$H$5lD zMRk{tBf1_`_$wMaWPBUNL~NHev@<6-CpO0|-hh`u1P9+BMGZ3(nV7(wk=(^DsDES6?%5ONpd(D4 zT}Sdmr)FPa{e+xv7!=M*W#t>#XOL(KD1-MX=p7|I_9#!b8UGo$nJq+12fxHn=V-yS#!zNbEOhOK}xg z3(f*1B8$s^mqkN;5{Y=VlG#pVv+KSDSp_S+c3&~FLn`+~nVdB1bMKu9$~n-C;2d^) z4~aB3;Qx)P$SmuO7p5(~OK>kPrMHYgwi50l5Jher{2T?> z1Cwi`0;hMEIC^*axWIa%JP!Aaw2yJqpqH14h-y^xeAjt~C$|>Hz6;+d@j^)NK^zE# zO6@iMnzoasrS_-#HTf$^+dR9_udRwS8STM-O^=bLWc!o-njR-jL+!gsQ)GC`9cZHW zCn%zHrYJy}Dk=^sx#dde$(bTzWn_^MZfFn*JLCM7kT>2m_oCNpEEy#J=^PMwJ0W2j>ow;Wif6tBmROWo;k0|l=Zo)P zkhQ5OFo2?OBIt#<6FvAT3W(B*DUMLvB09#BbRf^jKEWX?NYjoumw9q~w zcezbg!wNOaN6V@|7XGq4J#Qz$Y6|6X-7;U6^;fd@w+4D`rm=jhH_~N__x(zeYiX@6 zUd$KAecZPzxB^}a4bI2C=?O>?HjS`(3M-`FKRU8)A;M}*xyQr2Oaky1`&Q#!&FlB0 z?78|U;)Fj%TtzUwZqL`@22VT5>-M8j`n2vvWVNIW-!VdJ=g(Dr;T=*-TG0@ZM_R~x z@GZc05^6XC4()j$hD|TSwyr0k9pA=vjK#&M?^d)UqfxLud?qdJvdLC zfQuW#UEjb0@xlP1a@8c+SLcPltV#%n*^0JML_NanPgYHqJ$ZijYK@;<mpWXrp&T;cu%)O(fXl>KD3?2ophpH#q?puLES? z&T+p&7s!oK_+fQ&WWSr|SkFj${W5zDDfII6erV>qM1>2)H;#udd|G# zrkmgI0&k;_$%O7edCN5yuEIvnBzZNI{JJ$sMPc%sN-g2UzT;NipF9K@mfwbif77IE z&?GjfX!Oc?23LcAqWNZxTD6>NjBgkf-MA8Uf6*;28S8>T7~Ey6m$WJPmSXs8`r2G| z&6`{xS}(%iRW%fNaYGV{M00Z zJ0*pN@v{=3wS(Panj}28c8nZS65d-I7fB`$zqSh())tr#hIzGw9|lSyiV!r#g|&$2 zMIef-?Xm-V%XL3UUljEyyTxCG2iNUY^^K0CD;@fvi!Bp!AGG$9$8X|93>bcD@{s$I z*wie%{@_M~XBD_Ppzwxr{KExaA-@NhD zOTGBc&3FXurpc^FSh^`a8Kc1CVc;JHGy_fo&H~N@z6M-hExf*I?r_RW4AOW&D!}Fu zE|kuepFDX|5Fd0I4y^e<%d7#YV6PtCL}oUUx1+5WkhDf9erS^Hz#8F+hmuM5mxtn0 z2qCcaJhGjDN#M)dNLXR4r7EajyuZkeus`N6;ErDb^lA;~=PkW*(KLVu^*}^(PgPh3tNksxEMbzSG!EqWZ z`BLb!pic?cN(Nnip3L3NMpx}Y!Mrryr>wTx6pmb=3y(hPvJinmOnnp4wbYTB zDfgInS@@0=i|q_%b{60sN|sAxFZ}%IgM-K#X_K(FY_y+r6}W>{oroj~utR#%Ek+|4 zDPhoxADM-R|As?575mXE3@#tzCqjOhT1rZB_Fe7z7ZhU`#(fY zcv1Wbg(BYxiua+Hmlsv6P%D_K@4SQZMfHg9 zFd!87@6mx^-!@KG)Fmw678iEMUZWq^jS|U|`tpBpFbQD?L$18-&>Y{a!om`EaUS(9 z;g|{G_gTu9R~bkoIHB={g?V8wgT8j!7hO3XB5REx{m=)-TpqiPcmYXh^GBITEAc#u zk}pB>#Z#Zt=W@aXE?>YHYU^j{;G{l}6IDSy&XkJLvQsyOxfSMk;$aXtWP=6Ccb;4; zNepE<^TV#WdOIo5GC>1F7k^Pas#5McZ9|DWw`ir4%(ybu=~6)J9VmO*3dZ zho)IHb<=bKO&8L12~9~9C8eyOsfVWPXj)2BFHJYow2Y+wlnPp@r0Eoz?xblAP501r zFHQH+bU#gBr0D^gzDCo7G(AkydYT@kX#-80Y1&59lQeCoDUrtOk1dj)g=2{3Mn&C< z!vl$kpacW=u{;)eWToY<_i<-NaD7U$e(4*2NAS3`GGXF5P{YOWx_1~nG?4-Hbu@}} zF8cMxEw24mc)oJnm<#0cy(1I%>Yw-zRBSl9ug)AC4)BEwl}Txj;F67~5OxyC?D7rS zPQNB`Pyugt$XT&+IGoaOTzK$#FC?6`r7pi^SPVSttge;j>5q! z{hEbX*{94Ck9|Yu=3AD9!dJFifhc*4B=7$PeUbg5e~avc3mO$WvKke__m7)XZtY>H z?_M(sP_oRfqE@5u(3phfN zuR~52yX#fA#eaR|H;L?2B-m409F9p039F+ zpaOKigismK0C)|s7qAmh23QAJ4sZip05u>9paOKh=yoyZUUV^s0R;I)zsLkDGD?C?~24$>h^Yy`{T-!YyV7w3On&N2=e%j5!90oDU50lNV& z0Nw_)06qnD0vO;A10(@702g3BUs_5)rAGy~cJp93xdt^yR`c|1TJ!Q$UZa{j+%{K%Z~tc*QUJ%Qb#5)R4= ze$T4eME~RILi+ynw)D@_zfHfIK2$SNqt&=H_iNT`9@Fre8qM>Xe`+pie$o_ZS7~=? zpVj_Jdq~@){aHIqH&!=A=hm&#ZO}cY<8^y=*K~}2uzrMofqtdFRKHRGSN(hX(~Ov6obbEG-Oe3yB=InAsyyUdy9HRgxRJI&9TUp4>D{Fb@Je8!w* z$+4`mlv>IxPg?d`p0m7Sska=nv{}wt{$aUb`P%ZUWr#K2nrNM5oodat=319o*I6sA z{yo-LtOu>{TAQsOS^r`E()z9Snzh#&X^XLqvW>T;+SIlgwtH@Jwufz-ZRNJz zw!OAmTa)dq?Vq-iV!}EqW4Da|2zZxQqF~)I5qwz;$kI`w$H$7}BH}R%tOs|*@n%*_F zn$DSiFfryon>)?XmN-j_#bsGzDYqQ8d}dK#MSE?}+TOM`+fIX>Z){4iG18u9SKEzt zyM2TGN&8;=8}?C-Ne-K1mLtni;CRrn!SSf0!tuD{_l{>B{+ArDIu1GBa(v`C<2diQ z=ty@OoDSzq=eAdaio8 z`Vn=7dbhe>{l5B)`hxlgb$t4y^fl?_>3>XrIlU?UT>AIvKc~wzF`7h8ie`o;TeDEJ zTJwlzreB+@^=S9%a`j6Lb%tic7Y4U6-jZNRvLstlEmJINi_Q{booxNW8f#0$cDQW$ zwhG%0+wX19+0yM9_9FWO_EP&s`-}Eh>}~dc+J`ve9CtewI)3Ni9D5yaU`baTqn+cN z)17miTbxfhfA6ewe(LK>&$VMI@_I$n_=3qvhMUnnl&1=)&>R_Xjf}DYpb+-wXbU5)qbq~T6QuTU zoqw9ns+*ykt;^G`(Ut3V>fY6Tq#LSF)KAh|^>g(F`o;SDp~+49!3MWMYs@lkHwKJ# z#{V|HXS`{gZ@S;~yy>XvhG~_#!W=MHS$0|WSoT|9vi!H@P0PEMX3GbbcFRS}4NEMx z?jGA}+ZLPO_N47I`Wl)PGeUQ-7}RRjbm6L)A>__onBjSEWCh-Uw%QC4G!0 zS<|UeXa{RoXdlu(inZ%?PTk*i&ALx@3*nwN>HYdjeYO7gkp|Z7-wR7SVtUWiY-%%| zH2rKEZPuG@@G}|aIp!?0+q}TM(ENh=fcZ7^LGxkrC~AYVEm;<~Wr5`p%O5Qt!poeq zoVRqq&xn>zOP9rBby+j4bF5j`KU()&k6KSzKedY1E-PajYD>1+Y)fpf!)CAAhS*2j zQ~h?UJ<~qlUSZ#5-*0cUx7tPfkMPP95^b_?{^cuZM@6i82e?;G?f7)-jXb=qpjj_hD#uVckK!gfI>s~-#RxNDh!NSWsWr`n3K&@aD>>fwOQEKCFT|8b!NZUTxPDsd9ug6*SycX z-~8h3y{VWB56^;uZyd2@&PYqJP%+-1IM?l$+D5ms1~7L_H&5^MQ)-(|Ac z;IA_*bD%Ay7OzEZ*V#>Wo81N91qQ=^hhCA5Q$FKjmE#+iTO0$R>JM0!__nTDvSIxL WOMKon>ozQTaP6uM(@IzTj`?3pGES=i diff --git a/src/bin/nroff.exe b/src/bin/nroff.exe index 60199e7624f65ea3fa82bb219ff1fdf87178fd3d..250afd09743ddf0679e7fd194696eb64d54c07a4 100644 GIT binary patch delta 46157 zcmbTf3wTu3)jxdZ21A%(0%Rb8009F80vZe;FpPwdKtLi1m_S5st(P&{iZFw=B~0QW z%Hc379&Oauw#*xBebu(MSfyStA(R0`D~c8??HeiD6DMla6oN+P|NHH8CJC+o@A_ zd+~mJ^{Qt+!TbJI>z--F`+KXef2LE!*FN(*y#IOQ+Gjq)d-<*34-m)hvFTTq6-&}m zi$fZ*I^w%aWw^mv6dpLvVv6%|V^S zVOBKAI^wF+Cz13Vk~W%eypq2HNouU;U8bGQxWfDA z`I0iduI<=Gl=VK?JYT9iSk|oNjF_EbFG0a3OQXF+yKThi`Ogs#qI|bqOK`V~NyNoK z+Z=%+lch*K18ozK7Ci~9j)$AIVn=^7^82K^BQat&SYn;+H zN826WqJ|2W;>|`0wbb1&IV{J&&emv?u%S&4M=q2;M znQ0+&%k(E8@{q9lrkde_r(T*b=^bARE>$P=n&ToXV66r3i@VG8Yu{ypv+;C+_Sex_ zVd+{3^gj+e8t~52zxXPV@Ej<0$`>{S2dEX@iuV<8UHxcHONH7lx1%2)Mf0p^a?H_r zYoT-qm8r#DjZdN9Wq%i?BbZVx=?`>@`elDNlR^cu|GFY@Ds)xA0y+W`#)$qji5?0{ z2xCHm{^KucyT;56cVwdVr_r5d`roqHOjrE9n4-^is^R7jX>0gziB@18j)?jKQkLEQn>4k48$Slu6 zoTIo?8TE3^Dc=2ywHveY!><5iln=Sd_Shf$gEQwZh%RjsRX>I2?~xiuZ!;{i7>M#Q z-X=-4KXR1FN4g8@n}V*GqX-Pm1d@1)5gtWW7kA@{G1u*?DNswhRWIxFr9}!}nx8F& z-RM@1`Ta^n7GJKvk96%XV^=vT zJmq?5w06}vUpZu8yi_YmX!tZ$ur`Kq$#%LhNcDMNpqp;NL#^mi?eFdaI8^DULayQ& z1Pa;no8q2oNiFS4q`k50pw=>OaX6KI1#XD9UoG-N})8MD%XGAE*ONKZMzG?rB-zMyr(e~g2U9}PM>2dxCnJr+UaxG9@KuE zJ=xZsS*ZOg`&}scn(?n%p=Rbzm@#n2D1$F}Yg;EA>4*6z`mA4DGI6Sa|MA3Y`#*;f zA8l>c{yfne5Nu?74L)+v@nYbyAkp!hy8g%46castvU^<5)rw{-pIuI zw?#pMvEV~(Q&`ZP%Cd|=B9x+U`bY>v+^NfGH~Y*c01rX)71L$%-9q{b_r63GVaWjpt@-{JNM! zphj7t4g=Jw(c6((rvLOCU_aziio4{RE-7q{KO1voE(@D_x3sISnZSymrMHqs!@>Xt z&jG948YXLnb{6v{D_6Z#$YOwqKuvenR%?7Ay3cc9$3`eXuvGSQxIhmeHNLfH*eVrW z+VR{p57m6g(Uya{WIu%V^W5yAkYq`z=thC@9N|6(q;tZQtQl;K6dYtWs{JqR8I{_UVOUV(vLr2S;d$mz6ZpgQmrGQ>cAQ`ph=8n~qzHjj`TH_acp z*{&d<9h)*@lBg0u@wL!SoOCC}SgW&<8M0qw*Axa?U((!D)5Dywx1JRpt$Nvix#kqZ zaJ5xGfsO>pQARn6_>MU^miX(P-k=Rbs#_p%+rd3WgfX)MUJ4F{q97+ioS(NDC`EN) zqbm%oEXQAzfkqa9Ifkd=Cef;wPsPi+`_`MBINDv&Y|QgA^cLT+_4rJS>_LAkqSr;f z>Z-40iu*YZzC~UEWq+gqzo zK#i9m7GAxT2PogMxI#^>PM+t>K zX=@OD-G>Q4C57K0hEI+u4314E5^H`_k}ZB(p)@@20ruW`Mrbf0t8!Ng&3>v+F-jPS zIePS(F*PJ76muR5jgkF^qVSj|ER2_#Qpg(buV4LPA`w5O8YXnoD2+Liidk55 z^v(&#K$H`TQ2rWK|Ls|&^!QsjdfRA?=E#U&WP z@n+0*hwtH7=8$V-YmAkI7`tqU=YT^D^`tf17fqpb7@1nxvUq&SHzaj^t_GYjJqgF2#>=7bvj2_r!92Lc#Le|YO zA_j-TkpdCw9a_e45#vNL1`Wi*WFssF@?3}o0#OPXyOZypk;kfxF^L=!fw^fJdYRIV zVa3s9XlKRE!KHfd=5(xhIl90`b6kzn9=mdAYOlPQ+L$p#uhTqPYPEj$%>0e2a;k0aL2${ES?OzfHpf*)MB9nm#tn zT&fF5uqZ+$&VYd-W+e%|%ibv0zo3Ln;}Z*XkP~yTgsZ2NJSPGBb;bukniMssv5-SE z_KU*8Cd4{&qFY#nFM}PNC;#s@V8M*>gP&zl&TbelVx;Wb@YgGB`)bn$+O_BAZm>SQ zOdIN-8s@r%DzPwqn@e?zSVfmoo*vJMib!dfuOtmwUK3C$#Ijd}%hMF^^Qa`|co3KyQ&r)c3l)0Gupt%YIKUK&L}NHO24 z`z$O8!)}C)1fG$c(ry@Q)_5HJ%JmWeYk}oa1~8RziCnIKg`S5&W;D6(lh$%9t^#~U znO~;AW9GYAi|vRa-r*P+F<&B>DURjQ4&)DnyN2(WLm1#7H|F37=P&7knY9>&ynHI& zCUi-3I)j)GYPw-O#~hr0j1j^N{$GUWGyA5N}m!_^kU6;%3bazq#-!UmDw6g-PL zXln4+yX1y-hISh!@Z$z+Wq&Ou2qszdCyk_-V>^@ZGiE}IKzrZYCR!4Qi8>6ty(&{o zEn-p;lcwC1)5wX%bR~rx`X=C3g?CEG2$d=9rMU*J$)?E9f=9;KzJ!->;lVPJf?0Gq z8KhM&!ldwqASqdTAxg{s2MG`yrf)=rdKeE>v&jIAV`_htT@k_nK80o|cxulT=7sxq zob0D>Mhe1kU;yGVjLUDk{x*s2amHBmV{eJ-RWC~~*VCV(6xqdG+UxN6H!nvYo>e%P z>jw-J+PVcP*4A6K+ZJSmDfXibwzT~MeLy#m@Z>-?woS$ovs{1dx1uK1E2N(j6$8;U zw4559@Axff_MIji%S<;K0ll(ZuQJl%OXNgr%(jxqcLg%{kbs{V3^TGGG$YTwyl+fV zf2(!lGA(D})Rf+7OIx>aoYTqL{mx~YvM?{75!Lml9njr%AJQ2y5Gu{fRK@i!Q~F9ovVS_q zS#W~tB_gGwGs=WUMyl<4_Und_ly)jYKbzBoRpev5UmhG(Z4qPp2$~DqDCS_Z27wl+ z2nH1>3Tv! zv~NpB2G~aU8`(7cVh+&|gk(SKl|0)Y6A^+*o?W{TQQeG)%F(lD*t1yMg`!jhVnJ$V z)2pNi&vMKGk*Hlfd=^0(Sp#$ef^@71`>R~p-RyZK7Is^C{Gg2y|JtrNDrE^-rR@z@eA5 zYnKcQi{57u2I4nifJBK-FT5umD$r@~K9*?>#MV0SMy zkbGhk@*%28P8j<6KWYD1lF^^m4xDD1?V5##sRCK2L8Jc)eMld_w)UE(X~IPN2~w2e z4$NkX7YW*dYsOlU|KT-bI4-SAC-F6PX?me(S1?^46NBQdIBV1nrSMOK+kHIX#4}%B7HeultXJD7Gk%j|*_ZLQ690Nov;ni+H&hy=D48dwMOGc1Q@04WR}?PW?Ba7QGqo z8L}Ru#T=ebEE`e5nt}_2OfraO@YSak?WY8#0SQAl&~yvCf=yVi|Lr}I0j|>N4E^fF zn%MK2y}0QXZD3hps*o0RLQQu9e3xF))|5>MbM5ML(Bug9&u=pIb`$s_CT#}9+LQrf zp=+#iqqIm2p)@?=?4Uxs*q5M6Eq59!i~U&QQiPLJfTT7)iy8$8EcvZrSVsaT9s5;4 zDPS@i^QgXvCJSiLAp|MNP7aJ{El|jMj?Y0VHoJ{YlAWgH2sgc9xeEJ9DYO%np$yBN zLb8HDpp>}Oig35^xGIII0)|U{r94f*kQ}8X9TY`Lj#8LupaD5bd6od77EwyFdz}UF z)v}au&GvDk5Ux?Q!_BASW<78*j)LWl4ImIBs4!g%Y*f;qkBbu(Zq zbt)oI=Vz2iwq*pSzoIoQA8oB&rnN4g)z@qpw_*wxs^)GpICju zQIhPp<*$hmFB%9JBz~A|0-%!XA4BehWy5U;2FQ8WpExU)>$_huw1u#9$71&{vyaXN zXrC<`?1+?TpRLFoOqLoMN~w;CC7_MGZVX#A_qvBiv8VosfhE-+^=!vdOw!N2%<vgBFbKTV%>`Q~_L7kS zo@i>ttZAew*~i#_%{|h5!Ag?RBPl@H$nL(xS*CSXOcbLRQt5Mshfq#AnAN2ZW}9Ql zwEn4idJMr%)GJgKOuIfN9OlPsUKJX7ke(-6EEZ6qjeX2NI%W48443^`s7eZNTbf*! zV?W|~tSgMwa|tLof*4kT025Ol15rM1YszzQf!-*V^TwinurZ^yy#s~|Ad)MJih3NO z30M*n6a9n?1OjAkBy2DdhRFCo3U>Y*wJuXUytIx&F=-L(QRcgPy+}j#T7c-cf)oQwp;G8HJ2cZo#m!ksuL4{je!zHV!RKBy zY@X5%!-l5GuF0z|6Otb*Zl8#vP%owJa3R-9l2U3&e#@$dM~DuCQsDfawDhrMtYdfX z&ZdK`o!M+aWm||l1bLQK9g*n@XT#{C3SLWx$v3VqF z@p6soE6>?B$mj<5Uca{H`fM)f%(gmBhnd)kg;IAlc4MQrXXx%hGq7`jq~-df1~cJ| zi!z~1|LY$_Pm2=VHVXE`(;gE0IMpyZji&qDO{gwZh#?N^JPfvZ$F-JXMjo$EGZ3iu zdTBl+xt3$I)QP?1J$`N6>MfRo+GDH7;`#FGk+AOeom!pOe;|SQi`FjEhJJsBI3{t; z_pi%)9m}2%=fO?Y)&jkQITo9)&?jwwKrHISJb|$Q(%YV7uKO%@Gryk^2G0f1RsyB5 z1R(AZ5VxZUv29>XcoDdD*wt1pa_M?v?gEj^JrdT1t#gbD76f390DK;uOu!KWP;^RR z4zmX!A>2o<2AN$}PAwRBM%iPX7rq6g8nx zhpAXtUFOcXw)D11)|_S9UAL9Z<%}(cxub2X6^e23Q$htMb*iK7W~5@T!&cmZ&6IdV z&*=rwY`2dio{6_#=FNflafhrMBS5a{kV3-(r(e<5-9Ci?k=rlh>-V?M;H&NS;#5|v zfBMUwy0oi*aJ`Wz_ep%}2WyPPVSN(4KYT^#hm${CFWy((aj$qc-BC4O4ED3JVjWaS z@ojLv3E}TaxgF<YWS25Ix~f_yGO{N?ULdbSM_2 zlzINd;{Fki8xg~haC4}{>~+1llwba$LWCh}e7CK|lFOV-aj@%>`Ba}B#cVe27m0*+ z&!#b9;EULImg%?sTnIMCU9x+v@#(^D7eloe4uzfi**z$l0mw_h+yuieL|TNT_EhVt zytLk5p)eP&`YwUM@H1;!oAX2ut=PP{lI>obv;oLMS~GmZf63l+>*yKPEA*GQgJCZ8 z3x6gk7t>pmecC9%4Bh7LXx6^mTqUZwHaKYk3N44eD%0IhuoN}{yRad`-og)x3;7fe zRaB+8+eL+ZDxyO2X5UM}F%HbrfBn&t71YaCz{i)sK>`x_!}gpYmU(gb(fKCM_yi+N znD~f3@Nl{7d5`5DJkiw%SnaMKSBFhhqD}e}kHSa5`GD-;yVo}!bCeAr>+0VbiuNQpNu6fBD;E`{^-Mk)r~yj zXr!g-+s(AOJ!z7@(M(H2(+xODzrjpfnuIIIAvlD|8vUmYtQb2a{ytlR&;t7(PF%%B zKTh6Khv3&MokPv-2n))hCmV^(6dq#Mez)`&S+ zySgT0Cg?H>rw3?p=vy?w#WG!g#FRm-9EC07PG=j4F73D$sTt8*R0?FW=!9g^NBb0I z4y^lRQ5cect4X(!&aRp2&) z-UPL3ET(W$i|J)Jj2EXLqLDE}-TGkJ&6l|2$v51Q{vM3~u~4f)1z00w3+w_phO@RL zJj1$YkyaNTw``A4+jQ}^;>bu^$P#YxsI+?S3Ln?xquXy5bI%Xn2or! zO6^Mn^`zQ~S%&Bhf>8qnFY19X_dx;YdQO;_d=*X{7eT}4idwhc}A59Qr6%$4uE7cmm&2R=4 zck5e$7By-9y0O`!J)sd~hx|E*YzN`X_{ExdS}`=^M%u=RtQM z?N#lax;?qV+nYSt(#u#qf#wNqCf}Wj$yN5_0N^F zeI`YSBbxtT^2mWpp$Vvg@Yb5;5gC2ip&xqy^Xa|_wh*Q-);i^J;VjPe@Hx+geu^?e z>yd9Prp9)|$^QokQH!GCG1@zAZx^BcsMf-^5!l<@cO z7cH>k;QX!HW7`cvRPS8KBc^rMX;6cP7}PMwSK1Bpck{S-oSHI5Z-> z2@d^D(57#_j|84pD^45kqohxQe(YaE@?awqWAB-=Xge0$@a5qK1p}pL;n;y(Vh@%CP>9P-~}LOC@W%Q^K)!RvcHwT?26fXnX`JJOm{`g-)xaBTOC?A(Jy5$Qg zp~3$K$a@1UK;s4K93fkkinv*m)d?jXn6HEyZ{$^& zUZuwU6{;~DScZsqqsP#) z?akm0!Dy2-qHQF7Z8==@h#fr?)=uxbENsjS&L|Z-gj9E;6EHFX4bZK)9;Pl(&L_!?+L`@jTDZwS$wn&k22d6Qqt8OGu zpgs83KLGCpv&%2lovQr{W0tNB0QbF8kM`9K3>56rphtWGZMkWj^L0O8zjd zBcyl(VYQC75%;ItOBJMW(!hQxyPW%`Yv#8@Svs}el; z&Qg>=%%hz88O4!&JaP88H&^vCsrk$R9O6a5Y<=HTsjTe5B*kuqaQ_ZZ)f-q=SZxdr zgd|-Cll1*{qW$_7N}F*oFf>xH1Xmha6bEjIDkyA2V(B$|l2zl(3}zr~zT>O`0{q1s zNYd_qVAuer7_nbJkZr6ILIRgg-O*za^p2ZgACscXFe%W0iZ1<02mve_Vf~~(ILY#7 zt?Tep+KK^~U2H7S zQ0NV?0%}M?*)siRM7XSD6NqM?^`T$(%kF~uI{&^>+R-L%MAUQ*qnAaTSHw*so)w>a zTs!_~c4p71Mb5-EU0F5O_$){)ET|`DYp%z#2Ave%ADm&p6w$RvoAcOsbk_RE=7~!% z|NYoxT$*{~vGPd}faX@~KnKTIbL)Ucwn7zck&kAT>(^`%Ols_YU0d|{<;ILnjf54w zQL(gj2&x|t#?V2!_Q>Ni1~6Z!L+zc%jaz@`A1?`WzCw|BHpcb}*i|zE>p2Q(U%q&^ zV1H39rC1jZt+xN4! z2mWhpm}kh9ijHV1dIcW6-qVA|y&lC)fbW?5p9L?4FfpL-3v#fwV!}4my|3b|XZ!CU zb>`uAPyJqsU~y}iJ`11}=29Ie8cVgcPk5}SXKQynu`EmqYoKFJDQ-b>#VK1wyHasl zEk5mYkmha3JgvAHY@3nbsifS!#m7h1d5*`%i?)97tGGF$uc&qfRsUL{<#bRVCs{o-diS>NGh z>Rr@D(d>WzZ2TBe73K%NMc>zfI%5>lPo?GlywHl*9Y5b7bhJTix&9vb80}luaAkF% zK`{s2S0!v3C_%r%B?ccdwTW)oltgYSRgmj-A_prB=zlO81<(sdL7oK=GpPXa1K{6R zOk3^*83ZvI$KvIB5UIFkh^LrJuqM@;wOzl+8_q3#&SW*%3}d+V%>tfU*!RvaW>_ce zL1*!YZraCdhqw_w}2p?&&~kY$^1iz}Ul+!prq(teHpjs7*nuJ{Sqn zB19UwJ7m;h;T_P8oGS5)=VLU0Q&MoU;rz*Ui#;1R;j#UTr%&w3)TH#qlY?}eiK`Qg zG0NW^Hqcvxcc^Yw311MNxYH4?7JGTre5(Lpc_ z0Ko&se8)!`C9I(#nA4fz&Bjv^;V2s;H-&L>34xeHFp?Dt0&D_-;bQbH$=;SGHp*-c zVlhl`Wq!7Sbh-ZJ?Sg?(Qu^3=KZ(Pcz7&ilR0abVGRQQnoMOeDC9wTWUz_LtQ5LOW zZ=s7aAoj}<(C*)Rd6=!`0_8epV09?oe!-LAD%`6>vQ$I=MJ|k09t>rQjlMSq;xmlK ziDlbhldKwy2%_1Vj$*bx#d4FygloC!Hnc_aJvk(=FHut4dl!-J7uHA6CpI5*1v7FT z>@S-`e_gA2G9yfY<@%Xw!4Si2!P+BA^Mx}d-&_dvS}`O^^s}2GMaTf|Krt-3NnZhgZlLR_J}F9Ck$2ys{vPI$S#~K zN3k2B-e4h!tzsi3h0{)#Sf)cNh|@;X0>}=Q>Ay9|?44`^_oNn}ZlVg8>u(0w3LI_$ zv>+rJWch>i1)ES}o)iR|%KMTPesAZ5gnr}FjGD=9jE}aJR(Q*QLL&SDpcHN};qJ$c z(?y3+d)rJvB$Zq8YY1Bj%1eT&+{=V2<+gAeX9t{JM4q5Y1PGx`dTLadkYp|2@ej$u7(ylY;g7S<1KRFNZhkZb6}= zt&-5*)buLu6??m3ef8yFZ|(X9avB~$qdi$DmZZ_qwhHEe>=%Lu=U1M|4SEbwjW+s! zvcrZa0;7n;^4CXOx-*f68&h~DRrHPc!~vofoVPXAA9HyXp2;{|W9ZTI7aEx!<-=5B zp5HpCw?sN_nGpIDOH?Q)$P>1Tkdg~s%Q_7Oik3+F|A2G7L&t0<{DMx=GC@7eKu<6I z`ULP3E2^Xk)HB#*|8}63LN@}tIiu>=tQG>4WZtMg%p2W{L&#+#drkk~7Ib6^z`mPJ zF`*SxaRNp!yH#t=OVfV)^Z@QhfX4S>{dz;t5hO#%83U|EJN5L$F+zxg^P+rHOY?0U zODHE#wb9Rv2y^TR#mqobW}s!N$LJ}>cr!R>CFjN?MgKD%|K1Q*n_MB`c7+g}lqlck z{6f2h^NT~|0T)K`a{c1X+KbN&3am$IDL5_4H|Z2_V>KQc*=OzDXGN|{;2Q4b8YNXP z145aJfRP@`NG@Gdab6XRSZ(UFa~ESz)||;*54Qc1lz7Xi)a;KGVdk6dm<~*vuEMO( zMuesW?iLQFn^7A~X*W{^qb2OBKRbCr5uj~2=EJusaHTj{3hn|gQSl&z)i80yJ!g^T zEkTZOQ6Zp>`E`0la@*UpeHkRdT%C4QXXqc?Bx+7F6-O)uSH*(WoGHj#TVXm@FsAdZ z+zzFRX+_)h>#_WdN-x*VxkjMCAyRShN&az~6kLj`t~07)!4H2u!nh5GQ>tPDv&~O4 zpmAe0gpJP)m9+|jZbJXhUJ5`x75?}y zu$%c4i;O#-%PQxd-EzI=dqNV}`x17>$kyEA&NBUxbz%%qz;Ok$v@^WS;CXIECj@=D zew`=>XG#YSz@*_6`Hok$*5@))iM3o$?ZJxc4WqTmzjKWhTZF+$&_TGau$~Se;m43_ zaKy07#^Y=&e>W-@G~*)`qT&B`EjCJK)SeADl1H+?s9F2P?}o2I*tiM>r#0>h37C(= ziU|B0b6Ji*(;Mu9-JJ;cU4R8I?;S29IasuzzxSJTUk!T+9$i5(>a*CRKN@frP33?kFXi0wLbqMa1_{zz~Wz z4r7W_eE6b)5O&d{D6}BySi8a4K`z%X-XN+Ft63PYcds{Uq*2e2mb~~kFgXuf*zT+=~H}WSu2N-4C z=b&=lwjA~v-co2W`VVwS!2-h$p>6D@ZFJjF+iao8x3M!x>KQ8xW4C^0Z6e`wgh@TN z#(Cc56+=MrMJ1rb;nbMp35edqh~SO}1}=a2@)^=_YCbqB%8=@WoBS@=;Ubw|PGKN^ z$~4zJ+qq3-5NYvj--$?XvCuZv8@{BR?4Qfl1WTiQV;^;Pao3hA4j1<X8&PKhG29> zr{ZNG%GPuK##_7d59whtTH2astP+6*JttuoY>$Pu&hr>{2uOiiJoJ;-3$YL@6v43& zzP>_uZrFYd2!pr2(ssl@VqDCw>{k(pPG{Y->@dG^-vrP=Qed3S7H#kwNFikgQfqva zVQu;Bh(oCla+sYmJJP6j7tONL%AJ>R5+XW*`m6wYB7jzU{RM0Ch)M`;w3Z_QC z$AEF+qU|Otdy)x?o7|E8d~%8Pi4Y-@jTrxL=+KvG?PLlZCJaolf8R`j2YW$Ztw~`g|s@_A3wdVap!}OQKTV9Pl zM|!U1V_D1fPlYr%aY3Ji1T(7>QRca_%JjF5EF2+Y7HQ=6E0F-N7vFL6vKcs!i)XKa zt+$|9_qkL#donUl37`o-^zIa6^G}{fGrR1dizrc;v`(o|uKh6lVtXghgyjuToWLG8_!l+_flN0EmEOAIDE#=s@d=8Zxz>xo=-32qE+xq{jW zmMms#7BRjO)(5Dh8#j*-*YXeja4NcP4=U6LEEC&r*7(><_j+@eVh?japv2zmn}@Oo zA`Dv({JpqA`}R<&gV4ov)*pgi2 z;wTzFu~fT3d*e?z>6A`-IpLT(V8uG7K+L=72lwG+gXRKvaH2>-muS_8$BJIN|M0Y_ zqJcR4i}j&k4?m&8z;}*Pt^II`6*yP^)YL+} zG|#b&0c>t4E1v%IJM63=(EqsI!z3#8mZ zWN&OsH&qn22m9)$eR;2YZC50>a(H5#>QINREL_!P`mRE5c1*-mY<6^r&5q!kR~fs0 z+&I*pe>2zGx_IA*Z{A?(XWU)bx8SYK7NlwWPpD>+w)pMo9&wwZSa>UOS9P|w>+NaQ zw@S6w-d-__ewlbB&d(Tw1D)sjt@|{nsePli_Khr@qrewJV85sp?V}$-^Jnjj z6C0>QPtM>@-jb7Z*{mHWOROhLwYN`h$T1qs*`tSvrXMus;I|C1X@k6U99(+WFTU0^ z46=@~etDEFPTrEtg6WQ^dDTjU#f~agibMjxQ;L9ZOovt2W2>)%r^EP6BJcgDK`I8C zyVAT#8b@oKK5s2lV<tIyf=n;;okT-td_~tQ0>Bk0~G&USc6Av_LQ6QC8l_ zWY`4E1g!Rh_eNyAg1SH~j>h1-gJW4w#k06l()y~l=e^7sy}7w!hZWZ=O>cM93CT>s5gqCc@IEZ3Y8<^^y4@&}J+ zvHsZknp3!N`_TJaMTOz_%dB9~iT5+Z-v!3HL=mMz7a@NSbr?C=lrGlG^t)##YwV#1 zLLl6ns8ua}R&kTFI4%nxGr0>}RB*ZY6g&60@!NO%U#Hoo0Zy+O1{Kf4{io%c(^Ac} zKo=F|XZfO*z{3Rj(2O__Xm9>)%%WCokm9W3OTWQ)jq5&X!k6Gqd@atWb)INdichMg zC(8p&#j&;J`aT0VR(y&{vEq&QkrqSXJ-Wip|AB7Ux>jh2Fz~85b|P;-(v%QU!~(ms?9lidu?wQ3bviEC{vnhEZ#Q zHu}Q}my>XtTO3Led2P$Nbg4LtvHt`}GaO5v1B3D5i0H}L+NKX@hDEEnt3lk{bp8oC zE&3Fi&Q%rP;x?*uH?jCl^o8sMpyl6MjdJZ_z72q5I;0BzI&XPjov3CLh zYbX^J#mEcYy&O9A|>_ldRGly0car;8>p#ANxhr=o5#+Lf2tMfZY)^ zV#7a%YunBYwj#LuOnKNT3h%pI)K#6OuQ$7B1-4;`2u<)3X1V@=0V6*9g+aA*@Qzdw zCT$dCq;V<9U0vSWtUD;a874j^hOa;!%!3659}f;hcS@nj@XI90$xjg#g$70KbF`oT zBY3$B)j`AKc4jI=IG&RQ14eX1me`+8H9XwBnI@(HE$Bng1qQI%G|0r)XQ3HgQL>~|lCCG0+x@?vS@_)gC zhQc)9*XaZ&1Ow2})C2Ri4Id5D#(X?5ECkoH{U{^@Us0p*){Ma+F0)a5;{zh2= z|EIS>A$L#T8Q<|W1PcS7h068y29{(cRLFv!WS{WljL;PZUj&@2ueAsuGzk|;a4>A7 zNy`U@NQlDpZn1|9pssTL+$4iw02!m_BO?JHR0kM;q8u=5fBxsV{-^POA21W*^MiY= z+M}Or9eZj!kl}7t;;lgX^Ef%={5_`6b`%TPe}|~_oHip~9`3jT7Wd#pFx#2%?%jaGkRcN4KUkd_N@d-OpL8U=IS*;x_N)<|h)9(O z_zDe!XO}zPRn=0Z{u^ysd(MbQ97Lza)~#)+_1p6RyP~3U+^KFdIn-?Vm3OTv-*(R_)>>e`Q^VG;PR z6W-_0sSzCAORVxfi{Q;_@h3O?9Fsv@$cKoINDd>HBl0mK6Brqb$QeY&F_MNzDl%@-J@DB$>r}V4@3Zkk=33bZyL?d!=0z63 zW%Z)=$!C`hS}c;C*tJ`broW|){5;!Mgo1^iPYpkdX0ucNp5N3G-9uqhAt`c~E#&ph z*oF9A^D6b7nAHIkoW8b2?y`oaszuq{?sG;qdgPBg;#-fGJVu# z2HMeacm27Lt=h6yK1|rkYAG?}L7+`|p9h214k8Du6M-D`QQ+Az+MV4Q;e_`UWaYoT z^CUjK2;otW7_%_G7LQo-hfdou+>l~WPi=f2Z^-WV@HMt7EQFlZnfl|DWBI0Te4cKq zgo^e9TjO5TsZX1N&xhuLdHP=`!RwI8$F8qo7Q6*4jVJLaOUwu#!8#4d~8!~=Zf;|mf)=`^?iAe#;!zFaIT!N1RZk13O!@hpFlD`sHf{1 z0#&|0RRuFw>i01W2|o@>(2pqwO{yNZ=6||U{~VO5wyN42^XyXnr@;XgdNn>4SQYm| zOQgx;N!SDsNKyxYK(s;V2qDW*QKKvMlxdPwP^RZ;$G+NVTR*K(^LLJL6CR5pNf`wU z+KrtjY|r66>tAy+zJ#Qxr{q5;eE*AEAff^Tzoz~xbHYgwsdo6z2ZvN9yl)v4k3^8f zCz*NW6zz?FjkOM(s&)J;!)1J8|3TX`kNrwdHMN;Nd7&d+)a&Uq)zLi3S`El6U|rk+3&rk-p7|A)ll9N^yFAQ&}REwsM7j$29GZt~J(EyR|pF@<-m_ zf`fdU$MZr`-0xA+BaSn1LzXZftE7;g*?ssb;O1~(4PD{Fk#mZ zpzu7nML|hFGo4keX@M_bMdi*Bo)=#Cyzs@jd!s+p^1t!rviaL4p>5~|`*T2;cCNrB z2M6)yV-O8^gryfP^v#fD?XhoWdW#0Z)(oYdYq5p;K?t{57U~VtwX@&Mw5@j+YNNWx z%(&5w=`A=sQhd5h-#ZhfF=~LfpUoXWj@lfzL8Mk6HI>z@9%Z#AT!I0wxcO{}_C8V8 z!{MKJi)zzeZCTZVAtS^Qw>Kt0NKQjkZmyeEdOe&iC3CUBaNC-9mWPjM;r!Bk9Nfg3<|!h2Rot7rRLz>)t!Btn2$KjSkvbf;zRhON%IKMvccWbLrb zpOq2%)WA?ZtSnH3;`*JllVa*La>DV&k@_343l*@VzOoewZ!0R8^)n_#B7FW|&@!vc zz)`0E*DQ9ouO)bO^^`LGjjIszwNwT33e+RB(u0F)XZu3-9T{;!(wEgKE6Q|*+7<&T z+-1f80qL>@({VQ}I5fg*IgbK$ZB2K-s*z3j&ot<@{HAJYHq@E8Yw39yW5C-X*wDzC zC^%EsPy$FAIsd`&)MW$Pe~$K4#Zx%nrR!gVgBY8h?|jUl<1Eoj|M3^qmiV)R!0-X=3)~#N98-dAp^gYEzLv5=)jU7Br|$JZhv$>Yg%6l}a3 zZ`_r_Gv-*2Cpu0-A2B=Pve%+Jw80n0hf^`YS5&I_%JBTumFh+LaCh#HT+N?*)IZ;P z)D9XVyDUYh8k>XapvC9JrBqM-$H-9ArbRNR(fL)`jkPbFZs)MsvBnkJ*8H`7iTw4v zEw<`;*Q?jqeb+c~Ir8hQ&7*OjSE^Nyy%Uctwc5|WGxmo4Md6DBaO$trIW{9cHnOBu zK=kB4vHuWC0HPlus&N0KTV3Od^T@8c!l|yd+prCAy`BGk3@HdKcPdCfaR~uyy5xU= zu1-%qwMA~IOI_2|{EfYOo)U6hvo`Ge`xdMEcN=^FCxC<{eeWUVJ>Oq(46M|p-f8#U z>BK*;`X+00CO@ZCtG@ouXXoD=8{A)XajDIYFQSn>v1b+Ho$eHffagVs2Olfmixt8r)_`>E;;C+rc|31uycI2B;P5&#&kwfnAh zhSu){2f@=FrJjq;I}qMHzP83Ag$DJo7-S8|=!r#&_7@FEk53XnslAL=!vL$YBY|s@ z+IK#QY!{>tz!ze>m3~T59xixvB%Gf5^T>}<#JGYzjR-CPAg0dXFl_$NV=HmJ%%K^O z3a~yZPrPU3iy|iO0cB1RHA@zx%6oT&*~126wIKCk$pQnSB(?TO3wUaIz5Sv{!D+ih z=++e&0UKS3_e4@+BMw6*hdy6T*p$62*BJUk)?y%%OfReSiyXi57IHJ z54jRDG%p(dMatS&0;CE-o3ryw-(D@ zykD%aTH=;4!Ep(KE$ zB-p^dSa5@EjA1e2&C-Mm9GZ{8?nHBq0+A)t>x>13FQzO^4Nk7M2c#_a3daA+gtr@P zVvZ}6me`WoQwzDrWu|fVequQYMqK!k0Q(S6SMtPqRN^hN=>Wh{wQ=IlypMfoGN+)*024c zhWr%ETC4q`7x8Z|Cs?gu=F2Y2(r{EvKv*=|`^+i>psblLEF+w@z-*V`nj+Ny0B64V zs6ZBauvgT%T%^Cjv)u*a)v4^$-fk`+OqF8lDe z$k`8u^A3Rm3tI`Hp*)eo+RLg?42I11bV}k^8WQkRta#3Ovffw8+AA zwheanrzt^dF{Ua1$sO@m>G zdEM6H>)JfB_JJ-GOhgtrmHx3s_6|hqVkA3$T0I<}XioePVrrbaizGJa>9dSBgt&LP zV-|p%8%1W%2p53OxUsts8w?1UII<8|2LTawl>1T3me`Y{k0`OycZ)s|mS{QVO2LPf z^0rj4m~#qO*pUONS@8Wx9rL8Rc_ckFTWt{o#I`V1Fdr66n3O}L#>k#T!o3uxvbqo} zouJ(p+hS9;xe~?QiBf0KT^DDw<*^qd&(1H^32fb|zz-~oE zCXG?HImIU*G2X%$K3#GcF35gz82`J_rOxwpdA9Q?OI%mixhP2LS87Y{dHJ*S=8LxG zk6pIAQe_`J6Oe+`nt|wU$OyVV_&FL?Z3hbs*{THPrglHUwi zjTQCVYWVeSc@d1?itgGSoq$P1%5ZV3`z3Y`#^~VKe9=FGKXS7(fe*L5r}){X$bIC! z@5pACJRASm2AT0MeMd$%UDm8D!ogAJj)hKTopX|H(n5P=X+LM=UP_QMC_Y`E{*5@$ zGD$5--4U*GMy|_niovH07S-myqm11= zYn+=03aV7dRDLZfP1SGCrRMK~45& zSZ>dfZ#pZjFci>ArJ{AVm*N$&C2;IuNveDS!@V8U$v5fv>y*^@BfJjM9{Gur3U9cu zk_XH#bb0DIY7)hrZ9iu>x`;>?!?CnFE~7Ik}e!Ickdu^q?3Fv}Z? zzTDz@VW#a1-+MKKYUd7@LbrNe2xd47PI<{&s;C;?exi~b|B*20wxm+u~ej1gwykKxcf460BxC|;)!LZ@o9ft8aEBONK_akhH zy9vz3p-((*Cn|l%YP^x@i*rvzrvIS~NpQ!=hh0lT=T(^X$C2Q_AO9+w=SCTkfgrxo z|6re_Iwr00@9vWn-p;foe(YxTlq3`5SNS7-lI~$rw*P@XN%t~oupeCjr>9ZnP9!A+ zCDqQvJ5`DZR;`UY<@HXf94XK|jcg>@HGm#7Z`cW|Z8iL5*Jbm*59prlEy1&LKc7Li z7p-MjZgN4`?Xy!u|BAR4uZ_4OO!YN0DF`LhB3u~9Vd=pX!~X<=dsLl4mwA3-XTLcu z!69?~LCc~_eG&Fosv^ODmbf0VzZyor!hyX0UG!>4mG3KM20iMS;s)T~2hbtuCyH5P zg0m}D>TVQO^{V39dH&$I3OyHv;O$ZR3Gm+#d}U&${?ET4ARo3@*}k1MCUkU7LQtX4 z8jE_BQADSVUbhxke?Y2b7OG!u&ZBg}^w9sjSCS4~2Vmi!sx@}XS7~X*l?G} zl08H{NxJ1j>AtT(gj09D*YInPWn9V;G-BP_Mr;K%yzj9TTcba0$V#;=;QOXj%ZDSQ zKP;5&!G1f2Ei6b_cBbMThZFVfbN2vX!(dB(%BpE})T&c6A8PpdU`zTK#-Z({cuvBb zjxJNXeBXGse}WWzmSkFC!@GkmbH}71<3!hr6$L9+lvS=+p%i6LPy9vIeevLx6?)f+ zhP)w`vEx%mlMgq*IKdx`?^I%IiLaplW~uKR3Pt)u4O@m-#;n?X!t53N1BY|*ffew} zPD5!-j<70SEO*#YtZPXG{UZ=*|;8FcjHAHQvH_;iRR zb2wx2VW&gPVrL>n*{Lx3p4i=xHPmv&=o`T2n&q!$1I9pj_$|(hRl!*@5&U4NWr~Y1 zTVIa%Q)eLM$)T1p!wrvmaI_jz|J>Z=kUt!QPhw}u4Id1(jD#n>p=+pRd}_8}A3paI z9FAtZwYy2S}mVI!!6lKN^XKPk>YXupM?VYyN0$OT)uy zmhWe|(N_78J#t%Wb;;bfRIn*D}>=J<+hxYq>1%Z)gY(QLVv- zN|c*EbU(V`BE&y*>%#VnB{Vj`Lzj9w9?=`nwU42c?-a*cYLFJqe1D)Hs{f)={Q|ot zzMnG7Q=bXxNa8bYkN_uk%e&4tocCJB52tq(DMKUmH$YzomNxRApS}K8L;f(!oNx(Z zEA>gDZ&M@nJj4;0A|OJb)<{^1^JG1dK#s`01qq24PJ;jgrcAFuN+31MVkQJ60at{7 z$t@q6vMxRW?!SmAK$ql9eHi?ERb}DC%<9gBmmLEUn1a_@7~XKw<-fgOG~6i~UT8L4 zJ%|%oz8%a7^;c_IJ)Pu60enmaV{boMf~mXNmS2Xm1uRP&ut*CP@5qX5PTx0;5VmR zhFi`yyq|8#sxr{YuDnF=-q(Mk!*a(bsNS5Z9+6wefK1gTXgpWcY_~-0%|V+gwe;QD zYFM6O$#a>zSwpyu)o?#jQrHnj1r0|sEMqtT+cGTwH6b0F6EMJ>mHFp7;tk8+|`aMc&*GTiAu<6!)=+C zU%O05v2)pwJ<75*+{?M%T}g8-y29w4%9Wcpf43B!E1HH))JlBQ9V-cL0n#8LQ&?+! z88(;F(Z*nQCWhKv^5m5K4Vr9_Np)V|)G%hWCG)$9Xo*S?*UIX&`lhv^{`)1cDc;X_ zxTe2)xRE*4*ur0&fkEBKO*Wnn7>k`h1siJE6wkXP!&yB-9~r~MkbiVPN2uyG_8tez zO<6dnS?cF5;nq*`-~MAOa}TOt8j>wkIuh(16anlYhHUbHgxs7}Sa+eoi6ST0w&*uQ zNNW8$n$1f?w`Mf-A7kmZ6l?<>!Cet-emY$NtdXXgbs$xV5Me(WJaEk$rr7t?S7x&l*yr#>5y)dl%YRj=)V zk$?ls7G(wze)Y`L%Ba0}G(0!flDAmc4+ZhhdI7(BCNh1wvZlNFWBb#QpVy)uEUwho zgHv{vTeiO)9PfDncKFx6*j;Hb-giC}0D$vBSR0eZS;mC9g^FsWvPRaVA4V|pLJ%OY z)gu1nlU0p-(VI`kE9TFy{ZRt5O$qcqHd|_UkPs)1zM#aWFDmt2WTpVdKgKkX#``Iw z7|w4J*q(XjnYerQr~nL_;2<3qv!pk~##x44%@nZUVki}NHcWFTF}_6b<=aaWi$r2K zz6gCC`bB^@jJ(WJFo!Gyqs*#AYZ_U%APF_Eqp4Tdp5{OUi`y&VyJUmO{f0*_v-}{; zW*TYOVr<7mSy_g!grs0DuEvbkj%_O=x3VX@GBJaN^ady@0n`1TFyj9~nQ(UiPCj%) zep4jUj;+X>)xp>X3Jx@Dye-gE$yYm`jkdgw9- z8GxfDG<@NRul`ogL?yTcczk=q#PODE!Ve6^l%{s+Uku0MVoR$2n}f7p;D)Pl;FLpr zh`KNnF1dlY&X9tZ-JFRn@R)qF3uY9s=Ae6|&_Er#fl|W3SW7vL#QaY&g$DM*ILJ>Z zQ#Ycwl~K+?e0I72PkZ0u-$b?TpPfF@LJBPi2wI?#LW@i?Gf5_yWLlu*A%$Q|(;`Aa zilrhTB#K@j_0TG9sB#NB9z_obNA!q-FN!ZHZ&bv3K&XI? zozL$dxcPk6-h1|Y)?Rz>wbxpE0%X=>p`hcyPnO#7c@(W&h#X|ZgiU>yrKX!1ybeX- zJ_X#nn&p|&kZlN6u}SM_R^j`rc!Ejx_jjF_`Up>`+(i1_p)c>Au>?99~A zwQDK0x?I86w4=ccqZTTzi)W3JEx#{msZlWRsI;Zl_|p^0MK!byMLZ7O7WK?cEOAn1 zw98##OLiLL0E4Bns5n~}DM=fT#l1xP@&{dqsY=qj#t3=#tfMqb%_(3I`@yd5n6q)9 zSL&rU5$q3jQXM~#^|;Fh&Zg`&F0y~td#PP$b0RF(C(7BuWcRK`NwO4j|aDmj+TY492{S*e_BkP%+~l;>H3|Bx|i=w?zulJqbiWp%hO7k&~syOz8Cz zHCSp601uX?&Nl!l;R!P(Zz^G@sdFEA6X5rb`8~-G^+ilNLIFzZ5lbQhn&2;LPrn=& zK!73x6a27^>4L^AO$qO#HE_FV;T?qhh}j?W_s0C)eJK#iLQ*qA0m`#8mIgXj*&vpl zVnm>U1d8c5h>6J;@oH;Rx(rjN3}PkSO!R_J?|_ZT4%j~?q#}OrAeP+)0hr70_#boR zA=s~|I^tMZ%^u7KhSMo2F|uV8e9yrp8B5!ea6KnKoeW$$;llz((If;6!Nn{>?VNX{WkfmZI zd(Ezsq22X)aVXKVekOPbLObu;%pQGK&rta-W3FM&6D_Rl00LZ{YeL>uSkC%;%8@Hp)JRXv> z`CESd@vj&4%*UGD>VP3E%M8D82;;0&5_JdREdta4mIGD+Rs+@pn%wHML(tb~k6IAZ z3eW%--Rh+wY@}KtvOB`0^&s9G_IZ=8*sk;_(cF8man&}L1RZ{@jKXE@Zjx%yq0>(W zJ|)^J2#Ji%E7%oU3aH30YOT?z_CKn|uuH}+Kwb8Xv5$n*>#~{6;qv~!htV$^cp8Od z8pZ>7Tu}~ZIbgFK9Y&WoI*jm*VWhf%nxXLe0MY>|fOx<~6gvkvEk}pZXjZ4%{ea1U zdEV$Sw)n0LV>N>RVHjIc0^Op_D>Q_Y5#Rv-aTr^C(P4yd3?r39-8Jx*16Bc61J(mJ z0$vB~^F@a-+M|<*(Et|!DT+GB2EA?$mP|+qhgG(M1JJws8?lu`pcT9`B92A4@&KX( zw6m_GoI!u(JJE>B=gD8kAyPlGPJp+T!q|a(=q-`f+T+14Ybh2H2}Kk`r=80H5gyeB z*>96%XX(t0gWGtXT}S8AN}h4%x4%`NdjxMzy6cxajCmK?Hwn_UT_x?OA%gg+Bv2K{>r*7- zaJXc|Rc4t(4YSP7er?-nlp{l6Hgf5u^hMVhd30g3wgnX$4`oX;H=7KLP4xo@6IqAK zoXlgcyr}w|EUy!tJC_t9r@G9^Mwm@Y)q_sfE9org2v+0jKb@>^g$q;>DhLF?K@?SL zNQsJZARL_BXwXt}U0=%6-aim1syu}ZB}gkZ(kwOovFYzipmZ>ZCTVdx^xUu(38h92 z0n6(0)7K(Zo#$e`15~K(bL2CQdWVbxQ0N-Rn7aIoKpaZQu9mmo6stq)ec}LiAD(ogl)bWBuet)h;oc8GePt zZZ@ZVuRbO*2R(l%u>t1vM)e1YjYvvfA4Q4R&3ac&#_QnVx+~;sfCW2@@JkHD;G8-m z+DJS^zkMmKB#IDBu5u&AQbT&gDs$;Ns)GnAGm_s2H6^U2Gj#O*qJ4t^qP$Vv;buMJ zz)7pe+^laly+d98Nmz8=fx~QrjJ+uOl8>K(inv0HoU03+00*F*|3U5VVcF?a0J#b0 zI7ZV8&uCPqc~}nnQhmh3GH$qHqMSq~%4uI4`vQdRNrsiOdcebOy6&<#05-~h|H{Z< z*eI)=WG4Tif<@8v-zvC6W`iA9Rp7j;g5Qjs2Q?J5RGI#aOC#4ztP5sl7Day0R;jyW z=6u}C9vbrwoxaFag0vrjUl^cD(`;-D9!y6={XX(A~%d zLrOi=ulbItEnemvMN+i|UI>UfsW=GeG0;!jMCc&1h&$YizUuB z5-l|}*ee_UI5CZxcrGF~XwgD*g?6cH94PUxFHsjPDxy)(C z(SLj{TWl_FR1fB|p60!6s+P+XdLER=a?F7?HIT((v)eT~nB4)h8@4!JRHLpO#;oie_03_d{C29=_|wq> zjEwdT6jHf3173ro=w0pkvLM}9D$x$CMa15+?EK`ixcm#%8K&HhJ_yYU|sISY}OH!Vvo9q4!+TbkwJLt(5mlyBT7^rN+`_PC|yDMZDtAB_cj zUV>AZ)D+|SLXHyczE_czwz=RCNT4IbFOGsl1ojSo+&>$H=880i%1~*fwMgrSAar}! z-G-w}|9%%K42Hn4F2e>G>_^5Ic~|P25YUdb88sDY$6ls-(rb^0`u)Bhv;$deY%3+x zMPn=NdwDBOFVXh=&DcsUwb!7owsO3DWMA8D@IdXBaBVjVT{?N61*X->(Th^XrK%W) zJ^?lw@>2}vmk_mnJ0Xe~V4#Y&k?0=3pfqx6$C-HAHZW%{YWcgUzhpk1035d416mS3 zkq|?hWeY5c;ti~Y_hNTS4ro7WKwPZspV5SYGfQnTx_p(r*%eF;zp9E@4X<2PLm*m1 zdpa%W|BfC@?M0BMfg+5*rREF~tG4Ea7@p$MXuFSZCaetj|6m&{UysYU?p&fxj@A*{ z`I|)zzB79FFi5a2UoRPBEbdU37befNZ0XEq0!MDkmKH;CyEvZ}g>`Ed#!n+=z6pdmUbhw-F7ZFQ zmDnoXT5h<+Pv}oWlIX?PE7vh|(C{D;Lxz9Z(01Vx_|p{t7ydE{h{8M`152(H_A%PV%%M zUzuw}EWRAkztUwy%)T7awUS$}zB`J!%*E@~j#12-Oe{C;mTKl`Hn{t8v{Mv4 z*?{>~>0htjF`5nSz4b$M{z67{w^ue$O zJNcnrz+?N(IPO$`edgbIqGh-@(2mbdUO7EQ@9g0aH5KoSGe5rg6k7&px9S$R$x zE@VS*HWV?i9|{&%OR$cEnM9@0+o+nL2=|&o7a%D%R0PZ0RJD+a-Kb3Um#Ni1r-rV< zDzX{U{Lc$nk0G(TQiA?yUCr&~f2`}=<+_;KZyd8;o(e**aOMO$wuDWL8D9GHo|dVfNBU(A`l62<{(8!0V%hV^TeBu>GZt!rdo zduM~WO4dG7v&Q56u)0w#91p(fs}I#X$1`s58e>p`_%meOb&lN+ZP`sD5JNKQ-Hj`u z>W=YjaM*b3;P|WFw8{)ZzXq;h`4K~&+_*uXVyq&~SWe2yZX>-pxC2)&waU-Z$Sx=BXG6)~ z>}NUt^{XK(A6gVSt38R3u@{E&v76jd0S@6Ef zQmh;SZQx35i~-yoRdXh=KB+F$Wh^xV=}dfTrCK_H4G4b(+%9cSz*UP!Q30_rWjOkT zjEm%Rz`tz5SO&Bgkc%vhQsRDmdpRVdI$xqah7{6QU)25!4WXBqMX>p3kALu&YGhe_ zyq(UWv5naZw4*o~zM{a+&G9zm1VFrwcoAm`r#{3SW5%jh0;L5 zoydzyw5jm1wMX{i2!B~77V{0!SP@t^@CywIGT8EaZe<${Qw$hIW4JN9)WJo}9wr)W z@77Rz0o%6Uu&sj8Pn2Yua=mmH@V-qj#-r~!fmFkBk^EG@*4hBXMfM{yBTB8%5t!N^ zMusK$#4ycVBHy+J=x40v3EF)ajhz zwDm#jRU;bm*Gwsawady@@UEdXWL<=1eRm3O?e=RZ(EqT2s9zMb8<%;g1D@dC~VhTbxR$)9&K_7-n8h{_;VLcuwaHPG5npnbQ%fG<0l{G9% zV(tG3XuTuqgc3H$yt7$dRKjd&WCn-H-c9Shl^7?w+pad3u%0P1P^w{a99v5h0>Y0XA?5^(Sr@DjI|KvVWnu(GkH1k&{sFdPEmdv81K@V3IIuyLvvrZX85Kw0hVL zF11pSJ{Ezk4g4I;USM`W%l!m!grHwvDHF5kSij_2SasFW`iD!Mv75`K1NH)WWFt@! zwGnu#lu1z=0r%(X@lrPMR^mW(EA5`Twc2oLGuN%l43{_s-AX&CZlzsJx6-`OtuzzB zI~uMrpjH}V@Q!esrj@aIS+7;6KN$DgTJxEdaPMVr`+!M9?t}|F(Oth*~RD(26hJ3qtJRJ4NK6X)*8&oli3pqgJS$TMvMPd$*jJ$IO8^`lfWJ|=L*fZmCIWXt@0(>uF*a)ADajM}%XKtDdAJ)z$4t`hoCipOsGM!kP zXM*zGv>85eL<`|VF^<0%$}_>d#ncl%tP)Kp*FbLoe=Gcj@Slf&Kl~@)KLCFj{EH^j zwWb;b$WkM?rpb4N-NiaBz!ae0f~L2QvU|;)Cc&_Uz@$z)#?qR`9%I#UNwYf-Gi`*T z_|RvpA(dEU;);oP<^W9--eD)q^s=kEbjw;{j@AeF#N%cYj5(3qBfR145owYQQ6a)qv*#TLF6kM*u$n zQqbm20QoU<*i?+b96&W76_q{<|7E~7z(K$}VxfC4}XU?yN8pdRoH zU^8GR;2!{!iUt9h03To+pd2s<`xb~nX#f_8B3d3K#8M9C!;^B2sTJ12i( zo|HAbB<)E%bDwhl2$5{E=k?pL&EM{_gC&h&pn=(J#To9 zdMxrJd6E3M{5N@%+{K&j?d{F*7I>F=o4oIO&wKm&cKY7)wfcVXF{QK8SIJbe6`NA3 z%ur@4L8V4{O4*>iq`aYQR}Lyi6cv-^%~Q|H3B<*9z%EFJX`{R9GPN z5)++WoxPknPP=oIbG&n+bE>n#S>>GPtajEp*EwHzzUBPTIn;H~bHekZ=V#9)d`>$} z9w6T==gMR8lI3!Re3!g1EH}ze$j{4L73+r4|f;3r@8047r7sFKa3%3bK5-kddlSa@&*jmd-5mp zH*%&o=zZ9`$9uth$=kl7-^E;l|GOTOW%NkJG;|7`JOV*-5}rZJQqDP40xlB&vwsRkHpK;%C?cDcVqAkVN z%XXt}kj-Xu+VX85<1QBf0r5|bTW9O;gpF3#l) zyA;<5*C^LmSIG60>kZdCu4dP6*M8RlSBvYgtJT$C%93&@=5uW9M)vJ*X5PHx!w`pzj@#Aws?ToZ_qF&AV+lIp8?5k(q~t4Olw##J-Pi)_TjEC5r_7V15?9=TF>|5=-?fku;MNw45k>W&gfw)3^9!Sh^I2^MaA3M%FWM`i9b}TvfVafS#=UV5h&OOf0 zoWDAYTota@T_3qFxKcp8Go_W%2I(R9qwdx2m)uF7-kzZz$y4AN>sjXsH+eqwXr7T+ zlkSr5l^+E4u9TmVH_Bhi7v(f>q4$7ypl`Wvy)RAarwqmXtyJb?{;nV*^fMFbA|`6Icrx6FH|_g-%`X7=0OkGyBSzj{0S6j03n*#rDcOtA;~SNLt%bQTK@!Ye|X z&_}#U{ImFtcvigDF&yhwrDMJNN^f&tw`mPCWunF$j^ku5mpjK_;7vljkRqfCeX#Up z2|0pkGc%6fcUL1YosmWuA(Ju zaEWEP#?oGG)UR#XMqBHG^Zj33TWvX-{2N%Bdh|Mpn~zS$ zd+a5yqd&mAvDAL_8oWQg#Ch};%1&**GSlian{u_NlId7yHu=UdQ!!;~&zSQD z>?}8%{K`+qjndi``gUswamD|D4H_}sh~%Sb}8Bq%^5?k9)~oLX3A%Y-9Ij)Mrzd49e_G zFE)kuD-kCHv3pf_4-;NhA_!>fGDgmSc9E&$hIl;QX7eM+pIYfq&EXcaPk-#|cszW- z+MJ(KZ0cA7Al12UP6FS$IodNB8KbNjh3(IADKdL&$B}PQ z*1hwYMW(H<`kv8pN6kyQW+)1_D9zUl)ovU$c2O$vAj)^gr381bPm<0+$9zGtnWacQ z109o)7CjEEwtJq@j*Pk_;(xxnS>MQ(;F^y|MAW;V107lpmkz)@3RZuA;fUuyL@XCvX( zTm!E(kQKDqOc~nP%&eK6sKOMmbxct}l-Ea!0^_8x$94vQx2CC1riMGfdf!lOedeeP zp#r?%TXpUvXV@`2)3sk^=2kOqv`XMuj)9Js$mYr}k9+psMW(=DwWP~qn~PxZHnptF z8p>E z%hraLx{>}z9$jS8yZ$L$s*US)uS=HSTo2xt^!W54?=r#OydXvU^Vsarx{(m*za6xF ziFdaC`4{oHYhRf?{MFTgL26}B#GMJQs~@dttyDY1o#@AIwAhR$x7jW)C^j8HWok)x zvmN~&_I6V`0x7j7{U>Lo{;;=)Nx`D9_c9i(i5Pg{TtNoWGLd?j3-iA9e%2tp@`ct zkf|p@DSvG?E8-Y{aovT6`q>cuF@sgj_2~F0AI+4e32nAqRK5#w)yahL{@jRj1EX$^ zxrjS`xOPo;K`0X#qkM#0EcgFmAZq#YE9uf~soIX`vq+7hw;7f!2BLgSv_Q$-W-ARJ z>M3ey2{_tpOTf@fAc>_IVXDctk{&!U=6W1;MQT}(>SleOw8o-G7v-2jPIN0rYdR8R zlX~;>Bp-xk4%Ft48yiY62u%?NH2fnTkCgPZ*(hfG0ZX!!_e>RgKCh|_-xtatMnKK*G$0&M0a0gH`LCBIyCvv`F*66xCe<5t-zJmtD=sCMCa zPdQ{@qN(0wLc?dN!rC^4goNuH7^M2b&(TfS??3X-d<^3phR^t5CQ8dd$yjAqtfu#DM4qHs))dR_v3_9 z3Ue?s0LFC0tSI6om?@B`P_PQoS+|U7x6gZ{5@- zY!7?$p$$yILFlfCGn2YSfWt)ER|*4v{ZP%BlW{rIOsW-I zGw{g3VJ!TrH6qCkhl3cA0txJ~BOTX3KEomJP7#BdQNC5XAypCyw^*B**zmR#Bp3_+ ztYaDr8r%qE8-aK*Mc??52t&-ShtY2KnMD9|WLl#hy|N>rN7FItOu;PGxjBTEctq*B z?$Cff?B&RgySCjak<~(+IW}4E`ZylP*czLx*w!(SwuhVG9yhh-&F0wUZ8kxTvZ4;m=!jz~#&xUSn2GRGcovu#cfCG>7t_tyOcjtDJ%l{6a`1~9nxnZxZN zvR1US%$uxSbyFdWCX_&3PxfYWY$>|WwQu_dC_u0@?B#HQ9zberbMLT?RCa5x=cT!* z=7YA5T+|izLTLYymopraY>HI&puj|qaE}erIcZvUAsb@~3`sQV@q=uX6{X10z;Gy6 zAF!eKUHgVMyd5ydDlyQV+K;A?B1pN~VxW}jLPl2@SXqw0 zCPu)o&6?3>gZrg(AiMqwAvZdLabw=31Z<> zh2nC3FqR^a;)a&ZQhDu18ufmy=F`e z$q6Mf4+XQrUPDp15+*E+mpP`OIW|zg=u|u&JE0mTbkZnovn3U?Saao3&Ks1c&Q$Hl z%q1aCkqJ}7$U-lQJr47tJ(Ormze1SJZu%SM=(f|)Doze3p`8K!E)akb!uIsd3o;uB z2SkHPNKA5sqMdUve4DAJRVS^mh*(`PwvZBjH5XGY5))>qqaPJoYko;725@XY=DLG- za4d7kHM2FwN%bO_TD?TrBO-2$p0q{^Iz&ulJuyaPa6~v# zAVPgZ%NQ;)P9nyjfmndS{J~-%&qXW{h*HSdoqYF>JXU3lN#u|S%uSb}mnq#CRvcZ1 zc8)kXxL`M@;uUdobb*bDaW!7M|AOJEee#mv*4_&;ipT-meuG;LJy;KhU*^-)pJxto z=C^<8$Fm0#k?hAbcR{YXUe^{DT&t|s9xj-X!Lel6_cTCg|)H&;f%v(X57n6H%bo@Ro_3frM0V^)hlf{x**E=RBs}HhWx%xl|XB zU@1Z+&VYfT%}f&dmc3D~e?bYE#%DzA$~GHIIC@Kk=f`2c7JdMvNl~*K3pq4{h8z~< z92rl~|m<#i2SSR@ogXPmkqBB~sSyDNRF`I{_Fe#%Fkz%`9A%7 ziF_w(u^fuXJJbe7EHV)+A&%uyAMyvoUBh>qO$>05+h*ek=P&7kxsS%No6m?l8(k8; zhe6B-bv-bi+iaYFj1j^N{$GUQp|hn;KMP_1IPg36vCN5mKr8zg*Gc-Cg4sli|0 zk{i|;+HJTJ9xzxN_I6={V3MLgY$QQUnS`G)6DorC$8RUlk~qa=3IT7Q%9N=^CKZ`9 z!!5bZoLCaBq@YdT2;8c8r(`yxGKIagz@RnRl7^)*=1@)oBlHcZP!HjOYBm~xF-+~b7`N$O*^gedl747POq3VlE~ka%(+8(XGgiCM1KJS8=$ZjpXYR18D|XgM`H-?8h_ z>{$somf2{RMnJDr=ov;je2JWBjoJ1h$#?iOcaeZ!7z{JAb|xZEKejt-$w0IDt#mDS z>GYJoX-m6m>3F-JwR`>PT4ZT{0VAs8we8T|TTjs$F&HY%&D4nFU8W{`xgV0wrBiD; z7}x~9^_!2x;|4c5QkcxQ-f=jYd>-`M$>eaSqfez`!Z5#%sivf726)-uzNx=>@(3!- zu$ND+dhQd6zi*iK^2MV=q_sk?0aEm7*n2t0QeZebqyF`J)yZhY`UYDP_TD3TlTw2bP;MI))xSEE_wV#z1&go@w!(q@@Y47#vm=7gtwznCS3d%~v;Plb{RXWn=p#fI>tnN6(&S&th#Cj8YNEf;5p$uTn%j z%W&MMYxT=U&Lv1QYk*Ebkd76xzsmKlgF)5E!lxN3mwYLF(9qU?ns%>BcXbO||UgQ`C(Fx|J;{Fd$!kO{()Bcuc!=`G}D8 zK8r9AyA}f^N^}v!HI^iHytqopD#|#tb8rYC!Agn%Rdp;CetOCVTq*{;`>28B6Qjt7 zRFj-A^e3UWh6mR7jqjo5TzZ=}{=K&|DyOSjKGpMv5 zuUI>nWF)+2TGxu{=Jq@-t85%!#br|~*e+pLvN)LF)7`DYVG0E1;02BCd0<#z3}{xZ z_c9VGu_LF=Dmm=0SQ|3in5pe6n`86|M&zH6m6)@FX~MZ?PGGR(DU$f9PKK_7*k2b( zD=WGH)G&d%f^SuZoJauKVT{o5=@5+d4f=4%f#Bq_TCxSYT%QOu8po8EMw&x$oBWr+7x zwb+qd8$Ga1Soqj!*d=VF;lLkv2JC^|;$)%lse09Y7l6X2>pe$; z@N+X_SP?Soqhisf=%VQ+hsm^GA1Lv18NELJ@4da2M>`}4$A%22pk03w)S@?Iy+hVz zw3x&5!OKQfvZladkx2&848Hoc;^Z4bsh@^}KYJFtf=#H<-}s|sfU9&mL%-UwCU(7I zEyU!efyXkRljc-zjYgdnrCP#2!K}$k!XM-;?X)_>eQwEHMuCdCE z(jqa0((s70gNm)PFF}=BZZ}jG`?1s!5htgBq&CYEfgrHtJ43LJ1STE(RX`~)na$$y zBuqBYphE~!l#?77(RL6W)^j~JQgO4>*d*DJkQ{N-8g0ihO&l;*$z3t0Z(t7R#1 z&GvJm5UyF;;p7urv~0E;&k%sg5TPRBT41A+t_6m}^ReM73{RSZG03S7<14Y-Q<-44 z2w##(VQ&CCAEw|1e(red#~!3`Seu!c%o^#>R36vrE8KZZwb(Y`$v$;5U@5Z$Jpx<3 zd=kl)4FBxMwU&yp=Js^0y<%>Evt|6sXOTT?$_K2e-*>4rE z$cUE)wi#S>irmTiN90Z{8*V!=K+Zc}Eruo}hTwVZHTcxFC>8nOi{U)L%z*|=xX8}1-VEM@&C3(C z2zw%n9DQD-;d(tl^cz5mfu%T7Y)^D(W&#yAXH9wy;QH|c#ybl>{eofhlyw<4G);Cb zylR3-ep^ZBWE6#ZDeHs_x!z=olo^uWy6T=$(qT{voZpj{KDLZkVFT`_nkn{NXtwfb z=3edBH4Buz+FxrfSiutP>p*ToObma{BCDr3cgwKz(u%E-MY%C-9!V{3u2DVZxm$)9 z-Qcti)Ye>)!v$TUt@eb&OmQ+!2D_Qx%Lswz0<@VxX)FPV9}2`tW&zvP zjENV4TZi2p<&sO+6LS|!F84@SS0Q52oh%5zTmhtyjew&BP&%bJm)V1m5b7saLlRw9 zPAwR-N7-|PJIx+&atoPgaE=1h+=nWnIY?@B_?Ws+QgbjSNyXFT&OHe#nx*)eL}R$8 zth&!Y@Cf+hO9(lQGigb8tPTV)Sk@ie2oD%bfRO9O56b*Cs?%Xm5vzFd5K88`AB6TG zP%)%Sn|1B*NjygYExW(lZg?)2Al_yx#gji{gSBY5R(tKV%Uj@Lb3KJQsO+rjo`zj# z)v?2J2#)iUjr|{^Z*C95gaWN1Lr^r1tuC z8N--h7+1Y;UtZ@?p41Ai_td~$W(tm_xm040Snth2Ty?TtVxcpD72bXb>1K#(y8qD>l1;-N(bxTw`msNkFsV0W zF5r-GI0X)<)M>$p%75W3eWv!{PQU2GNcl>e9f5T6R z=c^lL@inbBhp&oSLB83D{krx#J5dgHv%(ukP82?&(v7ro$BJ!+!H20>tggh)xVGZP zDdz3z+O0SG7I4OvVQ%Z#Y=&Z7_K2v!q)xSUT!&Qbby!Neu$dBT)N}g)G|T$~yQ z1ow7`A9u)lFapALU8dj&|H;R-tJY5=K;!xed_B9qkgtyQC8?}d|MWM#b!iuU{|X~9 z+%NHw@2@cuNAyc{|6s4^hvPq3C+`b?c&EHuepoY62K$+|5*<{SVq4&R6XEYoS+Bb1 zTC|Hc_=a<+mz+_{bYlwu_U1EMbc5S`C|%pLVcCpc5 z$)VC_-P)H+`Qe!ag%VJ=+ty99yZ zXV$WB&X*oqdGoR=wtH>T1|SP*&F~G*viF=idIq|K{pRjsm<#>lUkK$gy+zrl%>riV zHfPr}+COiukt!|?Oj(RV70_2c-T5F(VH2<$o@VwIer-0EqSQS5WL^w@biRo*HpvJRCN`=cJY4R2{{4Bc z9_wxftaj_|wV?zmX_Nloeee-*J|H{z?(>be*?fpU0ul_+n*iEoBMg5AODL{wMPl0Y zC8(vD(07LXMwVwvM!9|kildA2wRJz5Ei7yL(Kyl~*|n4P`|c4|H}i<2k(Q=!OQbF6 zO*82m5^3AebOX+$uTG?`NWzul5FEl}jsEi{R*W4IZ@(=;nAUsliC@S?f1B+PbqIca z(m6b_9igBsda{|w62e2w+7C95Phlx?4I}q~&6yV)ifAA#AgT4WpJSBpjMfRz*;hpZ zNxA+8@o}NA~qV{YM2Syzcy!16m!AJ9Lyy+|A0W)y9ZCMIT>rl9IRbbmoW!) z8HLmRv^exzG~uF8*Y8cpAXbiIi#XHS2Jx!x)f($Y^%XVwGg)*}vgm#NiZTZqUdf^` zBtNW6w~)^6x-6p5^H40=s`D9K2RvxvV7NhvrHpM<{Eod^*_I6UJiG|R3nwT|f$!i^ zu7MyWx{fQZ1dmps`TD${C7St|^gM>Jc0rEetSt`}noUEs zt)cOknLwAJlG|})BrWLjo1OqUPZ(T}jlx_<*Q%p|fUsOZ3QUL=m>b_&rS?w)^_2R_ z*@oy1fl&hmFZDo}`=NkyJvT&5o=Q88i=g2Pq!w;~n`6h2(95T@VC;Fl2&pu|c+|Z+ z6CB?ptS86&dMq(;g6Sgh>)-`|k&CAoF$}05O_H&S38SBtYL4A#ID<-h^vytvnl$g$ zaXHeS;3%@g`5nk&PFjd}Y|WY8x4A++E}mTaC&aVdg`R-)4d;pTfYYD$g!azXU3mhN zJlN95SUryB$*Ly2DHD@x*o%|jzr17GV1u=se)nqc-Z5zc#kTTnzc!E-R9{=b38gZNT#<|UgF{-?X81y&rKFVODa zW)PyfAA~$&T4$XGHE4)I4RbtYJuqK3K@AJw{?q3Dr|o!FBs{~NGt%bE|A2y^9Vl6oGwkuEj zwxP%{NPmYi30crCy>rDVj?Hkpf{B$Ug1O9q7~*s)M$&V4mb!@{;<%SYvTp(x^DLJ( z^vC(xG=$GP`4d}y-U!mJ{&CJop2OlV_P6s+m}n3F_+{?NT)BO&92(gLFziDf1#SA~ zACth7YUN48eU$V`(2xBDBo8(+G4`D)i*{nM4PPGi&KW2>qq;Xykz<=`GvCzgXC zwId^R-k6*Y?0OhrVJ|N}n1U;CeSyYDz~x^;IoZ!Vtk`C|_BpwAjV;eiV~_fyJ0-_o zO0W|~B~GRU+YSJSH1fCzbjDD{8!%S7G{;8uwSI#&BR6 zBHn`@L(7u00MN1B_(d6Lp7!@e+UIH(7c;}|njS(FE}{FjNg1D>B8A}wScuMrQDto; zKyub8Q@K%y-CFUD!RuSsy*OaUvm!7$me1ME(Lnh6H;OpE9rrR48`(djzAuA21Y==o zku;)hCVd^bT=d9}9tvwG@0t)YW(K%cI3-{Lv!fF*G6Cc%>)tXe=`(^WpxaRXA{lLq z#8}4MaF@|(qH)fj9L`_bTmm?KeK;PM1D~h~134wIT-(yP#JGdgoYYmvA)cHL_|`uF z?}XXq=WFtp8)RA>l(18Ag#4pBM7Lw0q8z+}R20GS5M;PLaJUbNZ8oChPjxedk&S1# zE*}~tH&HG)Li}RQETuXFnDdRY(msOITF`E~dv*vC3)cJeYe0#yNB&)`bInuHDjw4A3@P|_Yn3V7S z$%sKrF=9{rB*$1K1O=B)-O+0i^o^T9Ka--{Fe%UxmEHQo5CT{8e-5q5f5LN%iYU!Alk`eASMb=G#&i1zCT=X#_=V8HSnKh32QdG4n^A@GHv@83L6Lp=r$|{>$DL>fgmMJEEOK5EH;H&we8FDr_4{%% zdrvKLCa&wwt~1BxLSkV-^_Vrs{nWl}6bQincJp8x$JqY%LCtIhj(Fl3KAc^yUvi5usk!GR?cxV!7&A6C5?1s^#iq@} zQ2n3~h7QuTdmktq#C%bQ+B**zxBk9-pftq!3PoZ$7~3mhR~7o#aTL1+hG&$INXZFp-~Wya z@eFySvMag)y#kM3-|0c)UQfhHfbW?59pI%169fA000(P3CTv69dn(Vkwmrk{GA>!U z8XiIfQ?gH=3s4GknT`{UW!l;YUFHQA?S~Iu79xdp&@m?>P9eGSgr%}GQh8D>Iq9*H z<}JuP8F4b$Q5fgsM`tI0YNcMG54+jGT+)@eWQ3znY}S7m82YiGm=m1qS=bouUKxD} zPm;KzxM*QO&q0@q*6wpQ>8Z&ydfRd>+U>s>HCVh#xM=B|X3>82i`;C9qlSK7roKg8 z6wUtoFD7P5RhS?6mcHK#>WooHKb4mE%VINLKm6s@qN5FB%k}rb$7uhuMkQTR9o<)@ zY#Jy*zrrO3A2PLxu53&qPbgK8>$W4uxM~ANqX2rrD9Ez_GLs63mloRjlcIjhO(275 z3C6K_xgJ2OPj}%dQwi3j`ZL;HzseuUEq%^pb=VAJxc+DnPc7_z=U0X1Ny#&oVeejy z47!i6vEpV%-#O)Unl9RmUylgwAwY1t{`C(~g;$rDts@8E{STIQZ;;07kK!F0m&^f{ zb+EkQw1MV%Hv#fvyk*Up@SCa5hk(@BQs_s4v4>|0Rp_%=Gmq#|o6^o6iiGHMh%|F| z$f!f%9ncM&D)EaI;9M&>WeQ9+oIiO^_>0gxgoj5SPmk=$)TQ*tb05-iCT=S*B+G9K z8R*S{AF57PY2d)o8^Yp;6FE$EZ^tw2B?cupC0YcA`()QhT#r88_I>FfY?T3m2aNfS zjW$Y{gTvrqVTSu2JR=g0vN7S75H4gQ&}I`xvO;NuMGzP+M$ht`Eorh*X0Z{AVS+~% z}@lrO#Rx_gYG6+Kk!U`+PQ z5zy{_Xhw*w}`upe@Ux* zI3q-W3jK7gFvKuhu=a@hk<6KrZ!QD`518F1BuPIzNnAu^07tbLmTuD5f*@G4C#8d} zeF7YqWH?5Q^^niXedD2p{nM~F>C44lk@!z!d&5(Ty=9|QjUCHkY*E8sxcoPxLo#H8 z4pg<;s48|6cgjJBP}gflMPUP&nz{XjPQ^2PcviXo_Zy_WVr?8^kpNad3`nOk5E~Pv z{Q>Eq{Q>EiBXRPC>8dmII-o!ravPVVSfD;#PaR4~?J@zGIjhPV7jB*J?FD8&sX?ta`jz4!oX@0bIK zq;gAs4WW~uyd+r9y-cW5dXG9dJK(et@`NS{5JH>s$e0iz$y&Z+A0%e(z??RlppcRb zC3nbZ)8Ld5a7Fo$drEo>=PQV4Z%3@}2OP!yBawg|?0=Lc8lv)hxnZ zvAYM>SAP!n)vjMnPQwET)s6OKqgawgTgNJx12`iuD9y3_1UKk0L^ayj-{pi1PXtC0 ziRG`KwshWww1{&%o=FvZP1wt!rQp16Lj5t9SK*nA!!?E;{qn13rbqcmC^6SlHtH=& zSKR{ri4qm%1bI@ORHk{*wXD-nplFFn{~b8jH*^y1gkR7uEfeZt2D1AQ zbl(kHdw!bs)T4vA9|0Qw1nbuwgpME?B4-S+7VX5Nle0vK0}G>kQ%m!097`xCPqnd+ zjS6w>h+<|SDKpSAwOM+KG2RT$LGVrbM5O3%;_>edVYSH>5^h(B;G{(PPRuW2+F*XM zNgi-v6j$iqUZ=hA*bx6)C~XSNitW5HM}L5VJlzG&s$_ zNgPbqp*EP(PNoW@*I`%v@u`cS1GELleE3cXTp13Qg1f*=R6Gb_HcTA3=PYUNJ;)Ik z6#`n;6X})7ZEx4M%ODAf)oE94hW^2|Qgf22IASSWl?7{ZrU3bt;&iNF63(}BE0ijx z745Dk#_=;MeOyn>HG%?%Naf&D`1UkYUsxpCD7Nr@`IJYWD z68FlC-0*Gq@Wl6$=u%C=>O@5{wQ=rqY+fQs;Z4|#m@F4Zg`pk zHOVp6tA`OtgVr+cXju%N!%9Vx2o?jpABNkk{27O(Jnnj|&G9{m^RKGX`3q^$xw1ziFqD(Db_5(3^|%a=C44s&6dGbXvBDI0%jPG za|wacd81QHeR{+)`QlPwcH;hFAP>jdfLCZ>Aj*fwMySouq>S;WcYTk_LzE+;vdH-1 z)7jG(K7}=Uva@MEcdzFj<3OKG{mYoeNAdU%rFI}KnLNv0`~=t)xW6@M-01RT0f&z zKQkr|G~*)`((r$~78@lq>d%Cl$)m7$$uruoo*B6YVdE+koYuH2BrqR`A`L1(GMa-$8~&^}LH9+5<5uW~Erp|kpu4i$0%6r|dNvonl?R@k z(6=wq&zqLmphJ6kLJKa)b!&vPN!8u2e(XI(DbW-Nd2<&L-#-CEDBd`XDW~}GMFSCb z=}~NkElxVtRvSCW<@&d)r3zWi!g$@Z&Zv<_Jx5yd;@{xpJZz4=+&jTyqbWJBMjwRA zWH-@R(C*uv6VjF<3F5U{0s3;fFa2X*e|>7!zekwZlz*E9`Jd=9g0#h@D87Yp!kFCNhXr zT-$aa(pN0FMRkYHD;M@Y&ejCVqI_c?bzVvLEj1i2&PR}N^QFlqSlNUq)51D|Zk~-x zwQSreJH!?yn3R9jKCiO-mW(Kgrv&f~o4~5iK-+19mvw9NexH>gjIKNzaWfEQ>p6ep zt=;td^bi?s+MH&r5`hIhXTmPnE`_#E8XT(#nEds4=*O=Rv5*yta4d+guMnOawjTq+ z;H{^u6Y-B2m)Vv5DuF2H)$m*^%+>b<8c2$aliAV+uYnX&W*{}k#u(P7r?RJRSXAa? zP|kP9kD&Bq#@0%o9}^;CwX_E#I~0%CAFeklj-*J9s=Zt{CrQW2OSTwVDIx)JEpWPd zjwr;-(a!`R9ilE7fD|=Tz>TkH+^9N*Aa2v&$WX$Rz!&j;UX$R{S;L6Qt=_rZoUoP$?U=|>KzXqw`0+q7;NGIyX=MBgukbzO$;H!8Bogcfqvv$7F#%kiXhko zKJjc#(!Ijw_p@UAxkkin7e*vhUTW`2Y3LOgYF#L53ZzE=hXLclMaQ*f_B#_IPI4#g z<&#U2PZWv}M}RTNn7-o4|{i! zkU(Z_Jjy&rwoiZC$ikL6vq&SiUx@^G-T01^o6W#(E1rD@w%&?jA{TOax>qAaaX%Y! zgHKZlonC`Za11OXV-nbgiq?QaXlCM8FQ2(kOt)ZtmJG+%gMjIQL0jw2hEYDae5){e zH5hu!Mg8$gC+xQxIxCW!^8bJvtM}pB*MBGsv8-C2_=p&Gr%~mMfCJBQJm`LQA&eXH zh1!O192+JZ$agS#{YNyevp0lv;3zPQ! zRR4Xn?;pgf7WREq%zID(>;A(R^Ddy=SooDj24n_Goaq%tP-in>=slF8-kbl@pf0#VHcF(vk%+3ffD{IJ2(>l{%5tFFS+w2J6Oowlr1xHWR+f&I((DP z*i?~ELQSkk8V)+7s?JT%?tb^Be+;mIFIwBH-XV_wxhk3-BW0>KtkoN0Ql4n@{a>4* zCmY^|9s52o^o<+oK4Yx)^|GE)#=WfI5dFuON&r_hkYWgx(I5XdXJHD5K$!w{@ck&L zfEGzWJKCCZB?ZimJRDeJFxfE%uJAnGD3n=Ga@FOyF?7pJYA0B-n5|jF_)1tmpwb@P zJVIP6IPin%=(=5~P#<)eY`>XfPEZ~Vkk`&8|X*K*S- zo%C|TF}2T(bxe`WyXXh!!OMm`I2C6@CMRcNt@hwJ>9xBL&YCU_#Nl784~0GagbD-S zIZCz8gQaHRoYOX6Ii}szHh&Z`i(!M49=P4rbIW{DTa<~{+Ex)Z>yQ+=;n1WJQWqu* z97vbC41+^^_|O3%XZ_)6EbzeLadx7G@|dc%9`?EzafN%pWDzgTbtGdDn;Xpb>#f?X zBV%2RiM??)IMKi2HEr#Y9HmVQ9~rM4)P93!t9JNE@kBw&9YprVmh^;*!uDW){j@v( zk8aD%$(j6=V=b=b<{s`lx36?3y=GM=*8(IuN5fuk21yMEj_)Sf$=g;05FB_=Cj~8+$Z~5^BY}WSU zrRLcqwYQI7o!fU=qnC*ZKPWC#gN@j?#dn4z7x=6|6_@WXZBD};xP-uZZ!lP_KGm~*%kC}kgzW?5+44!5I zu{auo?+%V*J(Z8+N=f?@+OGF93;S~OWQR3Uribfv(-xlm{FPdH0xLj*Ofh}mjclmUpS)1|6Pv=}x)Wkv@YXMX@OYN!_kUS;0vB$7_NUEK zVdzgjGZ=L2Pnn_b0%KiLBvPqM$lFUD*R)LY>6_*yYwV>5LXbS!rj|V(agwt*E{m@k zle@4*h07%;*txG8zuoKqJj*f*aJqK{R6Gy&pA6TXG}X=WcT-V*Rv@+b?;*&kM8y82 zcJ#xni{J9HgyY2__^$ERPqOhzyJKI=`Lwgg+9M^$)w1K|ex~BsT7}+h0JoK#U{YI2 zS2kF>weG}_Ioj;MEWS*>@3TJ@S9btA6MYWEu2)LV_%KL~#2fKULN{7ZJ84{{iLJ#lA6)_#WWId&SOmtJxzqW$fb=KH29L(4vHx6RO-p5TQ3afcisW@v zaOqNc24la+%#lLJl55{kd^jRH+oEkeH76vk=B@^DbJO`p=(MOEP3NkLZ@G74<6=goH zUwIc9;DPZ8aDI|?9l*==D-Cdb%Z2#ZFH)mN4uu6T$BF>EBWT3ce;cW7IX%>j;7?DN zhx}4__YA44Hd|kp=%SU_*&!k{!A+P7{U-*DeD(`$*)eo`s)R`!1sQ2vN^)11_cph_ zD&Gu~FKgi|P_O30f`X3+2cplKf>Ys_Ns?2LA{7OPM6a=Ezx-QZ#(Go-4UgNI8yLdz zoNO2{(hb?NKfNiDjQ#0=MJqaUeTaO=*%{R-9g!4BB;q_No~8hf^>tm&;f(WOT@F&~ zzFex&qXEH&!?aQx8ew#;Ya6eYCL(q4=CZ@T{BuGoS4p8ReBGRZ`DHqmdV&v|mRlnlfhAc96|&Hi>=T}x5nW;MMc~5vT19}+BwQrH!LZQ@T0SsDLJHHn#U3(%y36%* zQw)LuWQ?AVjD$8D!T6JMz^uLb_wfT?FF>yxaNzTUyUf~spKKnNb19JFZdUv)fBHi> zIb{Derq50k^IM~cns#Z0vGUM5m}9}A@j#9}?!K=aQ%Kx>4_@KTIS$iGb#+c!#Jd_G z+sCXT;DTtjffZ+1GZCt4ys5|2wQ;yQz^EzwnblKBkefeU>!0>pRFnBIYMqK&Yij(n ze}{zpN05*q2@M}ynHo%G-4QS8h`ZA&G7 zj;gc~o!WNQ+SYn+fUqkotEyi?Nc(AL#!@S;8>w9l=K|OI>oNXbDsI3Pf})kx`UL}# zq2oes_+RnhEPNXXMTZ6_RO_6|8d_?C=~6&o2WVZLX_q}U05wIHW)>Xw><D;xv~|!vnHqy*!Gb=fA-Erp#FAk<)_m_ zO9$h>T<9x7q(4)VFX4fw18HmdIsdBK8F73wXRVV>sLfu=M$bnC`9)s(@i*GShvKpH z#xi?tcDYY?0FAFo@5X1v0aDPic1>&Cmiq1@6OnE0d>svIg#SA3eh8h~h@*S)RqkB~ zUZ<9Pa-GNa0Ei2E5YZ92kC7ROe2mD?85xJjX+(a;NE#yTi0ou!V01fPv699H7#eZl zf3RGu{w&YQ%!l#2su}s(Pd*!O{?wuE{%qnfUblqp5&qT`$ZuQ>m({J>C!b9i;*?~Z zMpYN5>Gx=(|B+*P4h4(LFtq z#d$=;_Mfs_j^INc4C<-PIe0_(V)$r94OTMt+D!cc3S#)$9+Upd@g~&sIIuN$p-O%A zIDG$e7fR^1EVvCW9*f73uQ9I|A+31{9=>>CXfEFI!r26yJAuO+AM!rq)87Oj*Likz zP^7HgSFShUBzsLwt9q>-54P+3ksbCvf>LH!3-9Hi=0J{BA21OjL?a;XK6`u-;roD| zNdlchpe6y8Hm0K3M5`OJv9hYV5^i^s|7=$g&Z^k;)0Ntc&o4ChbZOUrem!4reV#D} zXk#fW%U|k2fX3n__Q+yu0+H16Jmpii%2g^~KVkD_B7{+d!zt)jj$3tePMXKNw@mYW;SSZWfI0lJMYWt;l5bT4 zH&p9?Ln~21O<+Mdt^{o1xEU(JtiO(AeEUwR;3sXs6Q@G&0{`DfQ?(8Th;jwNpMaBSw_R!g5mTbH?{onkI@sJVqMEK3P=dZZ1 zAr%<-wLkt}=A=U)Qtk4585mX-cONh)9*rQ0Pcrj=#%a!T5VbNveKl5^wI zemt2&$pNNdQ5hVv)ysP8&$*}g(LiLN69nvA>;4pUhO8vsg+P-sh zMyvy?!T*9!3(gg^c;2nvvPK^tFFdCzgRh7cM+dqK9GHsi|4hie>xCsvVSd z?}>7)AU-i9`t#lJ!L-F5f!uubs5r!ZdI4$SiPKwZm~#h%}ia@ z>Mz0++*?!>b3;or@dcIE@Wc}cn8FiD6NYp1@lgo0*;?>SMKe~lMw!#-s0W?*{z;h_ zO5=ZUDnoy&i&E8p=H28_ujmQC+Ecy%GnaZ)y}jp#!&bA&bV;PHr|~Xj3962)Ig5Q1 z)iL~>EG&Yd{a;yY7cRRhQs(fyd5a~2{p}UQt)3Ob?ZHxfw*#K@n=@ZQ)%EZEqj7~| z{qp^Bo1b3t?Vw;DY8^K(gk%2u+Y|W!Pk`)w`T&XmY5<{bvjU}E-8|eHk)RbpyJbyx z<&6)alJ`v*H9(Q>k{X>QPM0S$=x5wRc z9{J@s)(@0+b(uA?+z4CMW%kH&9FGj)Oh6|NFV3rTxVA-54fdHD9bY9u83tSgD3)6z zK(XBFS#A%0Z^w#()^I#~dztIo{o4_~d18H?%M={)5(!n`d?yCB4a(?^H70pFPZ8weVU43JeJ4bH}a)Of<1$Lc8MlR7Nv$C+I}DeR0d+TDD~UY#Rf!a zYW;1Cd8Bil^;=27QKWcq{Yr@a21opTNs4d4NwMU>;n)+&#uXUKx3wO3Rn$WQn0Kgg z#n8_3#?myHcb!l|aDGCm$DJGr9(?;9uUjl(9iC8@#g_*0j9CEH%&bTu8+z4RL(hae z(|YS^nq^gr&Bx1{f>z}ryk8h?Q({Vpg>XomE)SLr4onP6q(tnE#a2OOAaQbBR#g|o zVGQRtE{XU+HLMzvQJrks88pq)7PvZW3}PASiPD7gAApXmwWGyGfyU*tw;JY}r!BHH zH88c->NjPxW1s-4xUJ#$>1#|xFP{x?`@}{pG z%38c%sBtQj%w}Y4btx;FMx`qYLVGz4mEi;iju|qHoA=?bFq#et2k(PE$L0;5mSa_( zBX#b^*~{{dHO~HhE|S8NOyPr$<-spilUn!?61;cgKl^cun~^XO#5Q<$_DkBzq&423 z_Dc$FW7={r7T&!j8<=#Vx3OQ+9Zbsc{-j^holF|){TY+6`OGSJASo`C)Y{|k)I=m$ zvo>ZAud}1$->Kn%VI#q<*dSUA?ocNfcqQzG%X4rvaTk!xb7$jOwTI6D+l$sR9By%V z4&H2?mm2)PM#r+XjgCg9diFCZfd4UKOtk4-AXme26@+=H7IJY=5Z^IiersUZ0&hUM zxJqA+rC?2CV1N?S8?7>f1Ma-`tMHKv#|Di%22Y4p?`<2XcxAnU^T$W(DR|R_m!K zs_Hc*^$Wd$@s;{TDCB9ai3||%Fu|+ibMzNaBM?4lt+D)TZdUN{nz&G*r)Qzw$QYuF zjJ;}Yo6QbVmARCbW6{&pIZ7!pD|4F)Mk|Z?-ZWY{HCmaA zqZWYy+ea)diYq%(@s7cWeEZxT00?9%1t|xOm}0qcw+Sm6 zwcGQJYuhJC!GY$l7d7db%7UyOPtgXsNR-cMz+L7Ooh$5bIpRrHy>DR=>e0inXe}cC`NFhvAs0Grw!LLPAFE`J zWF&mhZez1zryG~#q{6C8t!OG3tIQm`7i_Mpcx4-4419n3fIDk7fw^InZ>k@wOmh%s z^GmS-Y9Uhgj8(Em8VicRShY=kbAPujd@2hc@2g+Y^x0TtG!_y~gR_*0sSe>DE~W-X zq7?_qn~JiOnRAIO?zSV3tqC7k(pt5T6pE841(q?qHyH1ftF7PGv*wT1a#h*%P?qw& z>{Fl)3;o6$Q>#|$BhYkg=rlTR!CGy}Pwe{rCz~c`E7Q&Ieb7{utxU*&MxgC$u$+u? zfs1?e0Vk|i{P&4&tT~n7I6rrYb#53$5215^hfcq25h?!EY$cK4e@o!b zjH293yDB!RvBcge1#00Pn4^z?^<3i%#pl$Xjl0=5kb<3{bnW3*bw!S~;O#xqaJw|T zIMHzRRcs%5wlgOxO6%6I_9AiPu&rMm!P@|{BgFGP1mL2#71L1okMV+d!MQ&` zs(wFSxiCjW;I7x>WX7v+u22uDUHiYXg+I<} zT+m2KqX)nhUN9>joFjd9;{+wAIGw^eFp`;H&~jyRy`G?I5Gax5x-`4W<1`Rgs{0`o z5Pl-2@E@C?j8u*{bxcsQYYcQ@M}E9-`Tw8ju&D6}**9mZhr;byAX9Y+jpvr^wPmYrBNG#}waV6jMOQfXqgE*0+WN{FFm81Ocq*4glN_CCBs^FYw z3<-CI-C&&Bs{XP6zZBhQEym-F>iz_o10MV6z78D|HtZ zRj33G&Y07HOR&7x&U9c&7PMD;sDMsQQbr6CjX{<3^T|qePByB;fSYfiuC>*`giO>( zOd_XEKbovO;YdJ=@1|*XuCh7Q$GASf49r_DI9D2-Q&oNQ&EG9V=a#_g4OHO+l;1!T z!3jc>ggjxbvCFW$PDc|1Ihh!0Ib_L+@Hc3&K_(S?Lrc@lDN5#d6VV!72WhRUO>1ab z8yvWYKF-(x&%wHZ>cM8_)LMP|k4IuqH`C2PXXZHgJ|b`_z+?D>^D^wUqx4UYVQMHi zyyt0*P~7Jg@5|6|OExx@%e?fHZ2qL+?LV|I_f_?uhG2_U2i?{#v@QT2O3)G>6c6vu zF5dc8_6Za@zP45002!(GuA+!yw=9N0_t$uEq zRpEA=Itp4bDc*?N=YL+*v>{KqXdp_O^!X#3exIkz9Y(@jFIX4FFpjI#LITC}lzC=r zM$`Oh%GA}@z$X(4+FjdfA=L#Rc)oCLt77QwJwAAh=H&-AhFkKX&EO;1{COje6<{LH zMOR=da5dxrvbLz8rREhA%mkdSP$Gpy_{C$7M#fm@HMLAr@|TGPQ55^E5Ach}8fRBT z*7WTE*!pPWFV~@-dXGu{V_@2ja%J1wfr+l?71#4$d)n~Ng)4h@{HzoJ_MNad=1o_! zLUbabT9dDtHR%TtY<&K5fV|R<_`?s^G+WU%563DOEvmmQj@hOZdLQnU`t2md4nI9g zZ2Y`Rzl+QiU|jf0AdL-(jA6K-MX){g*kdv0yfMeWhJiUmhs|u#o8F(UjJSv?V8OS+ zRNPWRm;}Wq<_ll`b$;SBN$kPr>-M5w1iUG4hEg=2ECZtwRY_}_S+|gcny)gJ6lpeY z5_DE!A;AWd`%MqeP`)2xGmSJ~V?!q<$|@hOG^RoC*J4KN{1=)nC8~O}tKx+$q(^bm zKwx_Q6GlE>pMbj!aNz^13tAc*JK^NMP91vgRV6UO;N+Cl9rxH+%l4h73$ez{Jolp8e_A0}7)pF8Z!o*3OS!A1tajZV`StK!;!>6xemCzjJMZMraDxg>Nyb{?wK zZv7jW#8{B(Ti&371D9)^4SwF(Fm-7rmSBT@`fo5(hOf(n6R<6OodcE>ue@C8S|`dR)j1m|Z){m`-Ms0O5UN$KXy&NGKV(EM&X0V4$X=e5AFy#2UN0%(+ProS@gh)icZGMzEnq-tSL2zB}@YZtzfjY{K%uOnxr{|vBW zWlrIXzlYWjowq(GH8?oR-1>D3@##M!m@QaXJYM*gl$?tq{YtvFErgh}w5y>Ip(vq< zp<^au^%t33P4QXEfGh4YNFIufuO9RRHfL&F+Z+Ii7cxtq1_oE@r~Vm_!&yJ_ko1t} zwPxnIww(b7F&}70FlH@~S5m3}UkYkNsOhQ;lo2<2a8#sbcfNY)hQp~?Mq@7=Fgpe; z$P3u#w{9M|U|z_wH1?1Bi{=L}U0S6(0S%_XUrsPyz&F7AK))d91c07~xStQ#)Q$>6 zEa2KV05p>0IN43Y*m!*b31bLCR=>_dUJ6sP#Wt^@`Nj1;i^;#USOG3zuPn7zxl&!4 z25%8F93C6R$+gXl+<9I~gKHbN23;>W?*vmq<=4&gZX$PHaBjn^9Pc|4?|Qz2W00~L zp=xGrNn}xg%6%(iY00!|1ejP|?!)fD5LD)R!FB->VC|xY9E5yG$xpmzB;M1;Fc8c| zRxU!-gqfPigB&*vovoxfBmouJm@;d&QfNPkCPh2ZXFr&&R1Irq1Anm}UiSUithIF^ z{k_>r-Vg+EwrBsxX7x^Z@S9wPN}f{J=CqksPqHm*mO6*N$cX3F%|r5DT_j2PqAj2dt*{m@3a+;PdZ99J z&Z=n`_iZl%6>g+hH#)-Y7R#Y{PQ!*g491*BKeBh?-HGVVdORM--&=W2m(Eotn^#S1 zx^=FS!}l-dD(Mr6t8tm>GQ1YxZ#Mp>;V%b&nfOb?pJQ6npXVy2X;N*R*f-#BGyZl? zYnn4pxu<ItYq?`6pDm3qjyZlJ}KCULMKoMhQR=c&8nYT>Sa)w_~Yg!m;faTQ1$- zVZIE$r;X45>x+kb;yL$rO>g>Qo|0?Ed(3<#e>t^*bKNZ3M!hC}iDI)8%*oeH6uK%{8O)PY(606WF&Rc~x1&fu%V~CAw zaeiGSNiSBzhQKztJ<9i*9=TAtFoYFaAjeVddMc2U7XG$f{mZS+^UhBc#F2XIRL>YW zX5n0^=l&5sukM`ZWK`+(2aQF3TI>(l_Ndks*nM0u z;*8Ffa7Vh$T)eP*oD;2RBpo3?qRz{F=itw+A( z0ZAB^HQ}76O|mE3bZoIwsQjyG;1b1S{`Q-uB}ea86)e|Q7!_OL10BP>DuWvsZKVlr90m2Y=2gwa z!3O83C7Hlvi*hL`&7LU3C}_t*oQ34yS4zY0VZ+y?CmP;QX;{ECXE>r0hs%5zQklq%U{d(SEipW17D>S`bs!ST0TovQ6!l5$)Acqy2T+5UN|At_rk>7{lhGojs{s^Y`NATz}Wvuc* z)8S>xg-u^CQ|?+$?>qK$RPpy$2d>4a96hhF6k{t;qfdjdUPGAsNLe2o$1qOoNRh)xpHACok%x(;ShO?UbWL%y&kJ$@P$nD>0kUA#lUBubk6zS zj=(Tcb)rd{F1tjze1xnC4JF5?y;kAkt?3V!DA`j;BMeY=0Ji)tRmafjUX5RE+=o#U ze+T~de*`Y7)aO0jWL}|^4Acz~Yr1rWGG@sk^n9&yRj{af4+od8+P4w{vr1^f(DE`r zHlcbC2Ua5Ua>;aUg6=4$u_-t*QZ zhtP;Juu=DJo= z=%GFP!{Q=yvRm2n3u^qyT7e6%h9cn_;gmX(jw!9w>yezVf@rvv3AevR&guIK1|xFr zZ>bqToRu<=PIPZT+-6_+wEu_ss&fXP&%=7?9d)N1I@mK`?SfZZ8mPuvJdkGT`PN4R z>D&>dTIY*Ey@`G~_6?>ynDaEmt>|6x&1^qOCxj>BJsjAZ-6hqP9g$j7m`EkxI@Rjb zt*_gk$N>B107;pl?=FHWu!i~!ndm#zW<8xoYt2X#yK0zQCoqQ%?(I^KbYXWIEe6)t zH4?ny1f5<$quIfz;17_D&C=#nMut{w1bfy;$`v97)fW&l2!4iu!l+7;SLzy)S$rxB zSt`)Zq1)?l>jmQDfQE_(`8Uo8UA_?R4vFhHnknXmo!HF?{r4lZ8_F&YT#hLs9+tYa zz+RadLqf&7>ZarV$l#soPMM)kKf%RBh53_$J!|`5!p{WvrXd&fb5xHT{HP3xlf`yS zaUtsZhd%sQJ|WS0{*=FJ36N@v!qs#SS5y7KKPw;^0CifE#Kj%0iLYgcwPy3o(CP|D zYsM6}fx5iV1RJ8GkWvFBHOC-ciNCU$o<;YZY^MIM32B79W=Yzo&8~8`BtOz-N%o@6mOI%xMA&SW z$O)Szu{)cMbhaegWV0mZVY9K$mIOX*mU!uHmN=_zmUxD3mUwAxmN*D)mUzCxPBEJ$ zMkDf+mBq?o8T(a-~cfC)O2e~ z7EFO%?^|zV(Fwx63aJYVa23(qCB>V;{?HARorj7k8t$C9nnq6Aae3+1l`Oh5)8~CF zVJO`({@zu;qIHsI{O47}hT^Kz<xmrx99$FRbfzZVuDamMNbh`*(1KA*{_OHyk|aPFJ5tkA?m z=nL7k<7PNbj{H+~BIU4_2;dCTU3jY@0vn`-9)XW3yBZ%zbQS*mYp~D1_3^x%Bazj3 z56Pc4dpL+h0$KO6ccSa004%VAreT9F)ZVHcM)x4$^KQfG_~t}CXQaX4tAQuYalZDs zXk`zlrKZFmTKHpZ;qBOhh7cL$@RODer(1M$+~vqC^QRSRl=JD-T<1B%&RnOi>-Xx~ zZv8x*cK^L9B7F)`Rfin7L+6*(iPwAhizfIRv@bQ5WD1m|MyF*#8AGiX0%3Y;?6j8T zlMw|`S)r^SfSd5MwwyMbZe$4-HI6j-CbH`bs9l)o##1&8xHarP%=LEoaO}F>(F}eJfYJ>3~f@(7Q9w)OaDK1opD9%s{YS{Ii!lDSZ{1W zgP1LI9N#k&ti&KXc@#vBJ4-C09m%rE>HKgKs&r*$sV%LpBk5*jI8#Q3hjrRWx@+2l zP>K0HGJ;n_t+9tS3&2k*v`gQ7Pev&H`aQu?pl5_`5D(|h2rT|vSvMNl{%7(!LYicS z)?$F5rZ$yXS4PsUW4EmZ8i+LLKqhGu-mnrz(d`4XoC@ltg+6=@6`aT}K9!BwNrAJ{ zUVJcxnU4&S42It^*aGS#=NIv%BI#h3=Z`NZX)DUl8RIar-o2H2u7%C z(n92Y7+RQlNb@BYsVz-KW1)Jm3UL4^yGbJP1<|1^D3Op7+>2!qB9sw{on)3D_8DAgjn?yfm86!9%tS822WMbu6_kZK7O4L#^BZ{uRm=(IX)M`79?!?TlwEB&s z`DSJ45~#mv==e5bE|FCh)}nEAd~_1-D#?kU-ylaekE6Q=F73vV8Bz7f5h^=kU-ehP zeO)Re_Tn|hOUbbGN2GQ>CeuTJ=^$uF4%sl7Nixe{V-;SaKoTABSQmDqM4VyltGEFl z9(Un=1cTcM?pzo<2NEy{{gt!Znl_&9(2evbq7oIY zLwjBB5H7kEMDB4E?rVj^KQBZ5QFHboVC>p$?Hx})(23j<>Oi{3l3lXy2+V=>G{n6T z6m}A|@NOndf*MbtrH*8}`uu&!xp{;L%xo;ACxO`okwe?>1@cG)cYHX4``83p3rBDx zf3Vh1pgW`!1IA{Fg0L)ZdK84 z2dzian<_@`rVmFmR8&RxFX`pY#(W-bsR-p6KF}0j>jb4u{YCQ7!^>{1VP4 zK*y>SiUW{eGD`6XoVtL2|6;!){W(Be*U!S`T@zvTuE#71yo2N+LX|U6lI(>vl!y*d zT~U%`c?u<>lT_8qcs!IFP$J$$6`~|&O&^qG-CZI|q>)geMJW_gPpEQ~#2Gmc<#d$O zQT`9gJd|Y8F%)GjMcqdY#tsQ>_gYjjp+55%O&TM=T<=45WyQ%T=4qyZ2ZTp}vSu}8 znpI40$P`9I^+Nz-A)+$BH)2X+iS0|wU1AhdfQmtf=u=EZ+By2e#!Wk>F;0DCGdGi= z;EToS7J+_47^;2-LnQ#Z1Ns1l0`dTUz+6BnpbStB*b6uc_z7?oP=7E(H3zf1Y&X9$-442(Se3CSU_#E8ug$Nx)SA zg$IZQv;&BMK7e6>$$(P8I=~jdVL%8_189i11;+zA157|BU`mz?jbZ22EP{WFDsjvwf?5>wOizPki6{ ze)e7S)%qwbF5L-Ai{v_RT{)S1lpDxpayi^9+Bfj`-Jzf_o(-z_l&oZ(cEB-E{1MAWISRFGNv0v#*4-h zW2Ldm*kJ57ju^*{?~U`u72~E+Yebnbj!dPgGkAcJ++=PVw~%|8E92hgws5<+ueo2i zYuqiamSgxBzANwM0|wud@6TuOWBEz^yL^T_S?nujh!e!g;%srg_>#Cxd|g~6t`oP3 zmEw2e74fxMegno0|`qf|+6tFbA8%%n9ZUbCLPF zdBptDO!9F)k8gl4$2ZA0#pm~Z>HEfqM~kH?Vr|{ejpcgtqxe#O1;2&g&40x=agTQU z-J9I!+|}*|!u`TPArnKhOn6J!BYcZ>ZEeIZVvaaQoQj7lkcytToSS?ADv_9HEZML=$qy3q7UVGW|j>oH~>QCzn^iqA9z6k?< zKA>OGANCINj`ZevU@=`N9)|Unmh43ykOz9~2ewQE`+w zQw)kr#dpL5;xX~Octebk8cEG1R@x|Sm%fmWNvEVArJGVMXgx-5DYun7$dc@pd&&dl zEP0eXUVcJ;UM`Y@@(Ov4yj9*Ie}9}rJwS&@|v<*`Aqpj`9-;^+)?VO z&D0KRGLSo19j#7Mr>fJ{LUn<Ou8u^_2RvdRe`x-c{qY`?XAMxVBlV z)UIi@TDoVLXPW0ZPl;!l=UvZM&pyuy&pA(x=dLGG@1y7H6ZI!_zdl_L%+Ocs2laFM zCH<;?U9Zt=b;=v*b$QdhL%liPT<lf@u+x8{0)QFM;a`3 zl#}J&a=KhBFO&o2@^<-v98l&ehm`ZmCFMRfUS-uDs-~u>1J%cY@;BApYJ$dTW3_|Y zRZaHjo-9wk=Sj~TPtdd6v%&MJ=eXyVr@uZ*e@{Q4|EAaXrUGvz-Z#8+jhBF(cOjM% z%pRs@_BQ*OZE)1Bv@=APqTd$?xj4cq$!z7jxt8c1Bd&S zXO%+WWTEnkvQ$~AtWwq~<;oW26J@uuUpcHCRjw;d)K=;|b(y+O{aC%Bw$|Ee1GLfF zI_?!mt@mvA9>H18)L~rbk2R%LIUFCK<>BGY%Q2 zK|qboR%V7d*4z#hT{9c``uZ%Wr_H_{zG~lXAC*Q^Gk~B*Tz5|A`f@X&klH|KSMgr= z6n7h;gODRk6;=W-*Mt?~+v08rY*ueT6~Q>RXybLv!6H2*U)lMrGfI|WsJ%1Bh)aD)uiF5Ncg{Yc#S+@Qe! zM=7AJEmsPR%I}G?rA&V5CH#BJc9lRVC{aoTJ4^8r6mw`i4AxL$PVMq1r@9i(#6HJZD{|S01eh0_YMi7%l=L_&7GHNZ*Mlboa8O89y! zk8cdV19=|-vSTQ>@QtR1uQ}g9{iax;bp-ahJL%*Sv}>ForJ_=*fmf0Yb^7}04#!NC zw#iafGCwsdk$26gzh&mkdfdrU2C_0n^I}+Wv2=4i?z#Y$4zM)dbxRN|oq-`MBlS91 zI>3BShbh0GC}m{=crx$07zEB_z{twTxDK4D;mieCHt*UK1j}V$$jZpN4wefryUnGu zn`Qe6F~(tR2Qa!&$_C*ppjQDN~bH%B`J`GFGgzMuyw);t@Dwye9P$s(Wlg9@QE*81ah}u^j&8~q zPY@wZ@TLHNn&3Q$Zm>3&f+)KUrL4WZ9fzeW(zWL>Llc`bce#z3J4F7<>vGvv!d-d2 zID&YdCBjCD` zAk`Nfy$dxNh9kH#?)gG1Dk@?)={T-MkKtUT!AwP6Hz!MwLQHlsq2x$xE@U!DdnOq4 zeGQO3egCs=ca$Zk|(LZ0X6SJ%jPA{y%kI|8llE;(2t zm#&c@{k>mvc2$hvo14h?lbr6N?&h^sas~ZH^%!f0HZM2W?_ACgzg?z&m2yN@4HjNj z1^lGe{vGS080|=%yjoSo5QoEmHdXy2=8|N+#@3r2wn}Mhi+4EJuuzY6Pf8sP{z}Fm zrsA58YX+{FxMty+iz}0D*T9PwOtFT1y?3F$VFIdcM^-b}Vt}agVy(PgKeSn#*<#4k zlkJ(@--mL~wZ72YvvoQFCs?21JVu9ofT;6j8R>oIV1_-+9pa$#%|8dHcR3{MD2`^E zsgzfnwGbp9QJZx;F5z@xHk~^QbZck%e2ak<>S=tkUq{CzZ{n#x&t;*1!ayy+EWFfW zSfD3mRGd-m|F*W57suIGigN?I>~SK$3EazO<0{VORt;>O2(aY>Ff$m!Yn(fbA>2fiM^!c|46VnA zO2EYj_BO7hhCF4iigibslvYYzGcdkEDLr6SN` zNM%J1J=kbFOo82oom@f$-JegL=Gv@$jXvYUljGbvj1v8(cUz7Li>FQ*KqybtQ;eH* z`=raM(i$*?Z)=#cCFO77#2+H1wqnI9MtvRikTrkrF-Y<@LOR-NKS-;+mbqM4`+>2f zZqPJB+;pugq@+ckB7ME3$B-mrvb1o}TIizQQx%sOC_jjJ2~}~q^-BxIi(}O2r)52xf)=392iqMrR5bwC?~YMF)Z&> zEpI`D@^N6@cCG`U>yf)v%XLL4n**z|_F(1plA~3g3Ml_E z){E{4CG}^O#QsW=V9=c$9n{W9M}>B!vzMh9Y3YD=R~Vxi4R2RZ`CbfDzDjDa+!6lM zzcGFH{nwwC2I2e5#)OXvZ-^KhDGa(J{LR=GA~r`1G>tG-MkGg!jLeRBchLP2QUBzR z3^5P+Tg2svuOn6u)R`l1wxt}kPKkSQ;MUYv22PLfx@Ajjb=*^Nt#M-}-Vy#z+$)i# z)})&Q1OJjREAr*I`9oKy-*R))U_L%7_P4Q*#Fm5xhkQu4J1ahSVotw(LFf&HnQApwJVYz<~9Z-!o*rpgdZ_nG?s;*YOa`S5z`gX^i%emHA` zHe5h+j8ncMbkY=0i}E?4k;H4)D<2bTAl|8ZMJC=U`i4wx0i#VrWf}=M`pZP+EkZ-4 zG!oA~`bc7Ci?hS?f$|FRPS7jACRDo0NaMovSsS4oA4A{iq7R4CKX*}Um;|kd+9NSh zMK;NtI&Fq&9kX84TVH@-<1xnji)hb)+UYiDD1CoCz+A^rLHRz%FlLu0*6iqVi=!##)S+RkSW)plpD5NiEt%fsFaZ@<9H zbX}*m3Ln?&F3QT4(bUt48iVa=%Li<)=aSPjp?Z-HW2hHi^PL$$f6?jEDHYe0-J>zA z_0|^90K-~uZAGFs3ldz6WYcz4cl3(zRo(n@z3dBzI35+Qj2TUjUaPaNWi<{U@hTFH zM*6~dR&gV=S`+nM^L(UQV!8GA>%m0Fxj?gMqHkQQJ+-pVdK}=sxe?0AQS{%g)mvX< zXrybax*^sz$y$mk^cTRpj+HD0NCQjUhn&}0qOrq1Q#9Hg;shmPG+UwTp#g3pv_4c* z0F!W6Z+)Lrp&RwJaMM*0~@zV|ujEkT2oDUJcm2v!-W zp*hl(sOBpRSH_K^r@B0rUvQgApvB!oNj6<)2z=PmX4=m z;#&;k1gwr@G5ilqV@tdWsEqOSFBx?DWI7^yShE}J;Y5MBFVHbl>A>vuGg;SHc6qMQ zg%fMDk}(Dls!S6@_I+J-)?`+GdzUsmZvL;J$R8L*in>^b>AFjjupL5&=TBi7w>b*@ z9VkrelCt_HPu(r?$cP7`B8JF6K@8<(XLuv=8+h5p)aS8+)@Oih>tu~o(Lt4n{9j3(^)5UK6Oosp zG3pxF9sO-*o%L>(c&?M)A41=1^F-Em5izc|D^9djl&O|MTy<@i*=^Vu&eAmw|8d$G zqET6lRxL3c6s%6w63Jl>YowdeDZxd-05~y3f~SIMu>I^Djs6svVMDK-(^spX6ui;U>_a1%2QUCX7~Le$*6sCiRkZhbGNsw}$tzUcW&qZ7Q*DcholeI7m55_4P2 zfW+rwvR;p|H^+p16BBhg#$X;`whZ8g4&c)U49pr}DjP81cTf+fWzu&uot$hpi|s1R zV|q3IMZ^1?LNU$q^{Vo88&gYF<(F-AN;@6Q(_63njCA=|`bf8B64g&()SGbSI`zg} zVbuF~o|?zg^;3d;HfUu8&B|;duCOM~ucuF{8n0=ySsBz86fhxB@GJ3HeH;DyvNm_z z2H&3|6f!Kh;9~|sbJ9dVQ;T6nhwxJ%Wn55c1CTxhmUdA3@VxTHRW=9Ao8oA%&S?nj z5qW=`O#gJ*UMWtqXS);Wdza}um!WG+v}Za6dxblNPCn-vEy;?J&_i9GkR~!Mg183z z%~&p??cpoTfo2H5PAI4JmzQOxb{yyEM`xM+=AbgJ={$Y^EK}v7zqi#}Kj4};T6o!> z3W+e|audNCG7@Xa(B!dj^?`-lk$m&^fmmmxko6W`iMkrp{T1U?I*>R`%qz%D0##|h z;+q(*bSE$wy(t#T!1ug!pvPF7^$ymEKHD(!12=WZ-h91hWQM+!jUuKE%!>-Gl_RuP zQfsi0gU{AzE=LvZXh0wS{Yn)Kh&oi1sc_b1sb@XWpLLlT6z%cDeSogA<%b?uA$8h3 zt+XMa+in}k-S(ogYqBS{td5M^8k6TedOD_R@2BGU!mp!nD zE(!SeQu`(P+Gsi!O+^3LQ~X=$=u7mDfOCk4QvD@ZPEj<9)TMsiXLTvRQ%+=#qT~1(?$;7=K_vyG!z)HUUBGh`15yoFAEY%Q4uK#kq<$Vr< z2(5O9^-BS)WU;6LyA4?CflUIIpg}wVS2#?4>%x>LY~B?1a1O)YkfQeu4p;8CLFxcA zJZn()-G&aV^8TANZg&r$BQeV^+H2f5(~^tK3gF;y05u;z!;}Gf?-`)U&?|A5H*s_n zgX06cfNPO`f%^hnA$~cCJ1mGU-Y-BAMLBF!RP#sDDQ8?6Sf=-J?l=Wwka)&5ijFu# zKfC}`272rQeM42YU!pN*v@z^dB!JROit^Sa-^DQHFY)xw%fWeh7`CGS@ANU1x-P)| zvj9D$#}wCL`laGm=+q#TTc<3&L=UUVa+QwmtEf}X^(r-&Xl&p8C|Y#E(+W*fb7sKF z76&EB!f(o?PY`Du&ApJh!+ljryhJBoP=;UH6swUVi8y56i7>?)PZKVne>x@plJeW$ zO=dcaC<8CSiIBNVG=T1HgA2E4px}Lm7QZai3!l{ds_(zeFA` zyU(KC0CiVXHSCjLyJ`BU7rnBItaf3zJ$1 zbzPLpX4hLj<5p#T#*r1V^a<4oXTWEim{jNoT|VPfF+qtZv`ls0qzXYe)qSxVem0TA z>UJAj$~vpH6e+`iex~Uio6JFk0u5&s8NvZTNY4kHrXQh!9>MefP&rsN#bcy*5qDG} z{Us4C9wWMc!O`U}1c}i5Hae5IuQJ5$FCCr!i2$ApFRH_zgj6yS!yJIWTG-`}!~Im4 z5g-67zVyS>Kkj?FopasrK zHD~G63)CBMnduS}#@lLeU841>a?g31eU{oT&{?dgm=)<*(Zi}zc%F_pOZ69Mdaxlw zs9trY(L|GbG@W8{4ht@kkQ0ZfMRg6P(I$5!oosT32c;1T{!T}!O2~P7+~40(rTrY; zhr1ww6nYK|5ITI~TtkJPhC!P-0Bwecz}w)b4_>2n=L>1m`8CoMT*qS|Sq=o41R5Rvejq4v`=7aa&QC6%y zBL&a6xi+f;>hXg7;6ujYA!YR38P-JqVfy!P-JuM1*dHQdNXqX*c(5$ zmZlL*+(~+fNtxlLHd0-irTN(KBbqg)2|~jfafK=CZ(0xzr_RgF!2-FZgRh_0g4~MW>bQ)-WC+d7B)OkA>zLE291z9qiTRY zbJ5R6{fwX1b<*d;XwPY;Se_aP54;7v+^o>0G{{7_i-SO%(1$jfEjYEX3iZ&t#}egD zKh5u?)35{bL-p$wA5mx`rN=szU-^B14p&wWDeY^G8Os;XSJfHeR0glHNgCXII)FVA z?6>S^#UPr&9lrVqEsufxe_c1G*g(+@-#o=*XmxEVIxoPYL{u&cQj4`=?pYQ zp`$SYe?{p>etL($0z0T`V3#9vrt0qWeC2_lfr=V&nmuBnMr{Myk?+^kb;kP2XJ_c2 zDgB!I8WQLk3VU2Wqf8n?e@|&m2mN1^Ms!M7=p+7q6&@PAW|)Uhft?4Hky(4t4CvoD z*H4uB`IN?W&>A$W1NF!HHFf^eB!OU0jT!boum9H1>fc1^(RLa~VV2ZepM-mdO~YU5 z=`>2^cB-S)h5XvS{HO8g=ky$HJ@cP5vtID%>$B>xyW-JHxYlPqtCuo>!t%7928he3 zv3Hjo5T4Uthh;EAoj&Q)WdkM4uK@p~o*p1hV*t-nPOG(9&p{u0Cx}inVitW*hqcqY zzNZJpVjLK2U8PTcOV3}$N?Hyj za;-{ts&p1bqm8rz`{G?P(`l)ZII-F)zZgVAW7#5lz1@29A|w-hX1ptm&K=@1`U)as zu}@6rpQx5nU*m#%s=@6ewnYyyk+F`ef(WBUz4F`~tZL8pHj$_IP(l;|YHzA_X#7QHmI9w~8T+R{yBR6Ad|f|J%b? z0uh6;^cR|H{o#-n!SZ4Nfrif@BeO*ug|*HO{089X{poahifY)$i37dm3}`4Ftk)^7 zIR8M^@G-QG{+_5|=*WvPME4Q%F>S=hw=#m;*`A$M%ub$OTDi{JNSEPzOQs zLxcKB%gEYdDA5x}+rP#-vBWM<2W>}#k^((T7;VJw8pD-F0wTrGBgFm=X!|N?YxY}} zcZgC)lz(GjDPkn(8Ub*}hQzPCd;U z?AcK*`&tPdb=(C#YoErESmNnBJ@m7lAnR9rtIgEu@B(Tq&oh5h=^#dIHb}bECg`Ks zW9Fr=U{unus}&w&X^;*&&7-s(+ADKG6D)$5dxol-IwN#h%WH^!ScmOEFjOjR8MlEE z#D5Fc$!J8dZ2d&twn0zdJArru{}KA}G56=Q-3K&k?p%F@;b0i)6tZRt+=py&fmo9sf%UVLvX2ifqm+O+{PEEO4ZgkK*;<}1> z8*!Ec!8sxJQ|^eycc4ExCxaoP+2Gi}afdZNj~#U92!9xuW-r@{zo{{tMiA!!He_^0 zqJJYs_3$9i4i{G_)9isknla73iF1ZBsyP|epwS$>T==iZ7T`3yb^MJeNH3J*Zsr^aC9=8J3&flx(TC{Ge{{Ws93-bmiAUe?*u1UKW#Qd{XiRIKW*?p zyKQ+GdSo2r9O=IZ;@IfKqwe#ibpDvCjqiX?-y(?V8;y65BCP34|3R4+k}mg5N{RH9 z&bonPvy=LcIwvx{Qq9<|Z3eQKvU29J+5kprg5gPEc!D%~`bsZWhnB#L@DXU5XK?EZ zJ6N;f_SLifELHXze-EFv4|MCcB5b+NEQU15XSbob$4MCSXjbR{N z;^_WnFrlnMHP;$KqanKw;EDV2?Rzpk+=KWi9ip9*n9M>mgWH$R5Y=+4KDec+TITAp zaIp{p798~_&ZX=4O8y(xJG!uoKGPMPP9Z0;@+}_{tWq=VXqPywu!7CE_q$vdm2r{5 z0=lo4p1tP0P~+$lbrt?IealdG7ah<=cYK4<{H$*ym06u#V!Sq)odfCOK$qLBRb8%7pxBPl9U86J=et2zGkzOa>LJt^NiiiW)^c@J3 z7PMrnVKAXPsI!CC4d~zZN~bX$bV`TDOF}2&%X$1>WmBWrI~hhyF+PckE?|)6X=!!PPU)1aRBS%)d-s3PR|Zt z%M=SndjcU9V)(ihP^BN&(@^05SexO5-rN2n6qhz*Q3Li+CA?M6-Cs#d`Tyc9&(dp#U`W%Q)rp2}%p;IZg$T$yW zyG!Hrm=NLgyCe2IceL`!F?#HXZ+$BL{s>guW^8ANE4#v>lyyNLuwuRZVK9>VqzK*m zCB^0#%FD1ouvG-Ha9?SD4hcy%q*L2m{OY#)j6=9Xq!?1~b8dLu*uH2r8j-ncc_^3h z1;+t`{;$s|c2Mv5JctW>p3>p#w)H!Zk;_#28@OYjR4?~qNLL5b53+QPN|y(3fBz*d zKSy8v5}Ee|bLzgN+2`nUEN31ZKEa(=ajLem&BOlHFT1L#|Fi24odg)xSM0$e^cY@6 zv}^*Q>Y@I&08c!qQkyj%DwD2{LSJyzv@FcCtKk?&Zw~`Wb|E7>%sWoca*D#_!s?Wn zqf#B;rp&mSQbbaV2c_nTsTdgS&IUag$u!~^+W|!+#}qwLvW~J%J?%zS#vQG*PR6o4 z1*15RQ-&UGw@lH~Ih+!ERFgSICSo?SH6Tk*JTp~9GMR^SVwgvmhFV!Lj1MPxgsFOO z7E{hcSTdKhW>} zi9kJa#mhjscxZE%cn2MHP_#gvj}7dAbT_pdiuAk~9@wKitWrIZ4l4Jkcx)6Du@IVY z&~1c&B%Q22B5Td3{~qdT^-j~nIUek$mK$jHwAwk>u8o{BMqT5e+tsylsdt>fdJZ3q zT*bsIrj}+`)SPEl7>ii#i=Wi=LlffAU|w1g(W}Llpz8c!Byfcm2`tW$P}Xs@un=2B zCLWQ4a4A z8qYvCQjam&0ADxg4F(9s(1d_EGJ<3vtE{|)5Yo&xXQ;b9bH9i%^)-csu$4}$;*iyY z9gbDkR5un4u;Wy#jd$yJ&kU%l>~Khf>u(L@y4$s)U`xefws$fWlw#4x2m`~6Vd2h0 zd2vELe#^=$wq8=VtWvo+nn=3&in&F^hXpWtYQ$#X*;l$(AI} zSv}ce*E=ifEK~LVA_oo;Oh(G(s6(!Qnu9t>on@NdKb|HK`UC(>9#zd|AbW+;6V ziCBc5(7z%P>0m*qA1szDW6v}kP)F~JA^o?GPbjm|t(!@iak3bV(r16L9tkc=Tq^K}1SRm4h zaAhtci!l8{*%5{|7;<%y0B8-$2RFYlRFgG{&HN6S-~j1>*P5{bocTsoJN6*c-}j?? zC0sE89c)Dnwyl!^VWkJ7Ec%Xmzmz_L^Anu3nR&6pL^eCp0xb^u%%|cA|5-#(W$F`K zJo^HzO)NfFn=37!BA^2>h&E~W@5yoRWVu0AmxpQ5yBC}%U2>7RfoK#u@83Z6g!tj?Xol z)krsdLuU?<)q9}<6(01C2bW{}b-W(ChUu{&-rdQ`r-8NyXAck z8EH-IZo?LYXKK;HEr!L=!CoIy>Y75I<*Mw1fO-uaB;t2=i@4iv5}WL4?(o_ypc1zz zZ>V%nfCU>9v4!RF;_J%GDij*&n=^qqbeytZt0U^0|cp*$Vs1*PCpW|V}v2YF_4xJ;mLM`3~t z;S*aBjXsh-N6=cah(=Q7DV07+yuV}~#0c!>Qqw62fd|z_bEz^?4I*j}7GJ2MmD;v| z#wzd+h94+ zbUAwD6kQPo`;}>W!3sN0vb!<3)3(UBo}yJh0Q7BsJaCH1oL7Dd`Qj;>8YQ<|UKM2e zOs6IwgE4BmEm~9y!pT0NrYLzELhf@ZHD$MU`3iJ(C;lSgIy2@`rAMj0q3dC z(G0k{=tG12r)ctVXE)dqvH!JM4}qPm-iO(_74K4g!##TMBl?CZdQa-3*gQbU56YEe zpZX4lDKDtdFg)~Kb#o-7y|%a`s&I`ybF9mdIoQd2aEjp*_odovswf0YiRXhZrh|BP z1)BZs6~3_oZ=_q*L}QISV_CpSg2!l!>!*i^DNp}#PO72d0gmg_a&iL?KxEf!Wj6HiO6w|q4@^*QU&$xS!0 zyz#0yp-j5ml-o$8$^>c7FxJp&YpTS+USMF^dlTZh840T@hmonR65Nm?EEc(GG^^bf z5YzvmwkrfJmw$p|I&es>eOTnCQK$>orU^o=)TDZgO^CUP!wd-9HpJx1H_?&YwtSOs zq6wk}QnT2E=`zcdWSwf#S@U6q%{EC7CP=>=mPF&Oxud6kMP+s%E#HqbyH32k%bLW6N@DcU46t?W}+=*Tbaq1g{Y)z6WvN=Y)Lefn!Mvp4J9~q zz$6esqmYV2h-%ojiCUw6O<1Fbm}ni_lhqpa6QoNuq{D(p?`AMV|KY(!8cb3UCL6)e zc!)d6cfmw65qiW!;p{dwM4GovF|*OxhWuB11I@U?u2~vF2ZjJ^f(a95f~jG=N#5Ft z9gdG=@4ZY6nbsXQ*Y;$JhHVihxhZpfm}y&>N!A`A8YRnE6TOKw3Z0x_g0WPH>0{XT z2NSL7l`Nx7<+P%AK7FWHR_^F2FM}%PG$b}l*Xs1u^W}}Hn<8jK44 zJvf6hf{tLiip^YFh3k)cb*xXekdrLvRF7aep zxn!ARs<+HCAsBqHiCTK&B@1{&7-XWi_0|L9sxG(=xlU-dQdUI}cbyr>Oe+w7Qf3kn zy@4ZAlI7Mu1fTZ+!CVc2bVPkDL49l(bzpNx9Q5MMVK2^1P=yK{Z7DNx1m~c-XaQmBSDgux^lP z%*+IrPAwT`!d7%iw-{M}E8jBHM*27lA~=-PIB#QFuvz+Yn}+O7z>%Xoxwqx|+gOqgA;~$* z-}ca4b~oFe>GtO4GU*KaQ4XFb^Bp&D+iIpcy*@B?xXM`j&TC2mVVTLj&g=@7e>uSN z3$DQ&w#@f!HE%m^rjfm1#X^0c6`PO#Sv4%Hr^gu$M$`5q=_7I@`2+rofTiGZPT)GIJQq0@Gu9VDy7r z$GG4hV1kS(Z?7ePpJLuxOHw^g6H=$opLw#4+6Q6cmbgrweVd8yh@)}a(2f&iUBP+cAAqUB_&Ktx zbB&g`(79ILrW5FzZYK`K;aIvDTE6W=6aBJtz7LnmUUsvg6Kdr^-`;TL^A7Jc6Zip? zx0ZsD1-up4U34aE;OcGsY`BMQgcq5DQXM z@!kZd0XRslcK6Kp4L8%PJ==zx*+Q!k0P%a39T=?P=4}Jb zO@sF)FuNX&|N0uM@@5ZmsU4z&ejBKP!Kg$GpgXU*W_iH?&0>-Fb*6NNf@$a;)t|zc z2X+5?t)F>v!8|$m7UD~MC|a-Lmoe*16~KNSy8{3ajr^P7ad2uSzgRM>CZuR~s;1s&oTI^=U&-9q<#4w7Uu;f-)ocw9pq z%4HSJD6OE&228DiQwFqt=LBmof4#xXkSW2ph&32Rj0o$y84*6}wc@zsp>2etzwd}g z{?EDa;B$wb+mp0oW5~f1lCYZ7wLYb&g#N0dl+`}kUWM^BFn92`ZCx6LpXhSwwv84r zVG8u@G4^f@LxG+_f8B0ZyTk{4Q_NV((LPtZ7$;p`)neU9dfsMc_zoP(YcFJ3Hz8Ir zcOwUhWrxIi8v-bb&D+2ZNUB8StZIRLZHWOB_SP`q*fM8!R5?{)sMQl zOv-84A*(LPke9Tvoi*p7b~whE+ziPbM?~?6k;;@*RxJZE> zaN*lIXx_B~rT{W|B13A(%5S0w)8w8tEMX@K)0@a%%d}7dZwFY3+hLxa_F19{?v_w{ z5jHVP-KNqeey?SCRF%jl=Qb?CiiqWW34EWSP266Krk|;@XMd9cT2^`8hfR8Lt~_|Y zEC&qP0*;noPaz5}Ax|qiK0!;(%;RG>if5&)$-)bU44kICk6CJ-k$J*~dgRG){ApJx z(I>VY(MiI)+}Ss|6WyMVJ*jyDl47^CV*?b0at}@qcZ{6OVG9kXF?Zp}CIW-%Qzr}a zWt{D0$UQ)7g)y-@^qL~;qW>5 zV0nmo(BDCmwrjgrW8mkU2)lA3Fx>-Lcbwi!#N!AzID+HA!lNPC>Oqz;`gb)B*K+#r zH#MgCH)BU@-Ic^$^bqm?0haRs_$PtK5_C>Rdf(vup?L8FcApzl)PwWjE5#9Lc^>$$ z264W%S&fLbw%T_&Z^A1f;$-`0xZEV$_uvvM+dsu+h%B$O3z^h4Q0uE312`SzF#4u* z@IT6pHua$U8Uyis?0X__=pHdt4(!7D0380d3yC||_}mhl(=)w(MA~DtwVDQ*4hs0M`u60Z3^A{eVw_yc9#jSEx*ggayqPSp`Y*lyEA%2x zbvxKOZuB~$Z0ncY$pD}_s_||Czs_6CHzecb1*O=u#5*7&p{hrCQv^?|WGUtSf@Cr9 zenSvwBk`n;;c!shSV~u(p_|V%OcEexq{}^J7)N1}fSF@kaSh{iGj+Z%4u#}8hk;X= zU%SA65>Fqw{FwhpV2@`9jk=6Dj8Cfr2(K)~wp6O1)(I&>=3Zx0m)}w_zrtfp7TzPe z!=BxqD;N%u->l-yM-4VkD$1E{eBi)*&8Iv3jHeX`6`^$d5p(SDC=f2T<%2venL7|( z&Q8oX6l-25qPYeHn2f>tVjGBo(~g0->f-C=!yM_2NL&VH}cEb`g90g z!uGGUH-3m_M0sf2HF(F%Uy0`Bcee-Muu(2qLwWjLud{%@p$mL48R*5VRatnu2bBK? zoj=`!H)_z)I%wi}-3DN_S8dGJ%@@C+CwOm~!1hN(({eqn*s3e4S;2FgfE7oGaFYUpON$!1{6;dwxFsdoK<=uDw>5F`LI; z5Z=%65%0;G%_nA!6+G5Ce66gjw{B)C;y9rp4ZE137}?<4P2dy~G#3+NixvC4SJ zLGTD;IPZ7?;~cV4^@rd+53SyG04_IThiHP3xC`t&#Fs93A_F+wna@|S?USpYvWM3A zlL9;3ums_mk$vMC2-s~FPX~Y{XYp>+8n&I%3fNhQ^Q!Rdr&r;k$`aTc18}&erb|4- zoF|z^7b1zkk9cD34jnzrd6PKa=-KB@V-1b=CW2$JX%rgxP(tmx!8P>p@94YVA#!EP zH4{6`_#fY)tz(5!8cwP*ad?uMb5Mi$M5LVqGj}-ZQJ>0;G<%&(JD zC&P5=N0@r9V@iUfs+2Z@xY)V%;&LRo;aOEmuld+JO&}84P+!!XQ>;h98c%AVu$ED6 z3DSo+)c6WD4*jGCvzE^i^n@4|Tc7IO5xpttRicNQwR4T$ZY*CD@0;IxA)VtaM_S1ZCA z(`ar-V3)gtKGB68DsAD{DQ|Z8GO+#3mePBm0kKmkkV?#(@;lWpjPBS$@wF;F)0*hsAhCB{Lj(!1q{F64iwG%2pFmz+6W(vBEjfr$YyWc>+Z=?UKvoV>Lw$l@B^rcR=xNd^F zM5ni7j5=f)?8DyGvXLO*2QxDpp+ZSq@<7b$Y=}r#1VROE)Y6WL+aYg?k}Nq|2mQh( zgJf|Cup}W%9MB^`Ffn@S5z$hdO}4=uy+O%+d2ef z!X<>GQ|w(ZG&(>NyKuxs#@lt!UxeM%W<3a|($Px+@D+~jf*SOeUfq4XH0yUr=5FT@daVbuZwjn9E&#z7VEtTuwW=EDH3Rq!>_TW7u9zRIvQ7&` zOrRe_=T5N2d!*yow$cfhv|4CcH`uO zJ63m8ItYh6T=KfZ%J(Wuf^~?6&@u1Z2F-Y&u+Mn}{>g zp4R3H#~UgP$!VU}z}~7~uR^uDX`oI0~<1LvMhU+<+= zSLtTrOlvW$h2oJqo@@UKJh_=w8v1 zy;|kD$POQ4%d$2=#QMyPwVXTN`x;xrVzDpxnxKek^aMg_L>#C+IE|qnei%z zP--s&8U-M)pp>ZIR|Vf|LOOd*4F>fiRVx-lYrl)f{#P1$??nS!Iw2(13TnG$tpK0N zm%_Twg{d+WEu;3TgD(ZvmXLsOSm=_U>OLsALwxH5Y`DwQ1kP<>jmGPhQ0=MibprI~ z&xOLmsn*X0xYn>E)L+|hSYW=yxwp4n8<)iBm1}u((s~Nb&Q4*?2-Sj`O zv;UGQs)qrUdqgj;bmS9>J9K}Rr(Ck0RHFec0Uww1F~X9OZOf2VQrA{L+j zrJ%J&2Wt>k2Hs)Evp4cV`hie5_5KMLJgS5vhT;I4w$XjDVjhI=Lg>HDHG2{}7OS%G zjwkmZc7z^4W_E-glvz&&<)kVjLVvY^YMt|3#QXn*x=E5X0r9}Yxb26r-otRZ*AwZ; z_k^Sy-R%8WS3MbMa0n?ZWe zEZ`wdgJ;Kt+9r;Xjh&8hhqIa}P|j*w>fQe5*wa16Ch}DG5kdSCDi@An9u6>&J?u53 z|5KmTbv#LFCeIyBlBInq+1xY|< z^`zs{`ay6HkAc^2{Wy~jF5vapxL}tV!Arae;HMDCw31``|5JFOSiN->cI@yX7rcpa zzkk2K-ufr#QGZ0h=mw7Ju#*&3Hxe4t={nffErvu6!KfJ=Y5c1SyFE%vZ-E=ffNd1K zRUzEEf~&LMr*BH!n^0#tuCL2Df#WkL_3}&CNz>gU#M5Osmc`Mxh}GD%Xm7#`N0Zu< zRPE(-hIr-GcL4A{p?Yo$nX@;+D#ULYHey?Q#omN11Y2Lv?wl5`+cJE_Hnjr%??86E z^3FS-w(krTb&a}D6Ps}+iES{1Rxo#K*XbJgi*D{ye5Mowyep?RdYAjEF;kw($7 zZKtj=GQYKR7-DFgHs z(!B|InO?qWZ$j-ou>oZ5dpH(a7|z9RRO|C&_RWh8=4~Ml`gBAp7PiF@X&HOW8iCdZ zeg@)M7?Y^N=D7~B@CS&bcDx7zYhAVK)N9W|-P+<!g2#Sao)| zCEj9u{>dIszUgV0lp)zonH#p;MmB8mE`5Gp&+|_n+iHWG(7EvWdwR-OeW0&B87NOW zDfK+RtY>Qoc^g%9Z=LM)%ri+Hv^U_KRG%N%a>vrGe64g<>OsAc($!ThIw>F(_arvs zFqtJOuu9E-EK>SZdNTBde7u@c$`AMjhCm}Z{T<@tSPwuo>07z4FGxvepE_&c818;D zNIe!KeLR5IR2B=;XO?)nAm9r3N3xz41)Rozf`OI3f!Q;4GP?#zzquApui0Z+@Qb>3f!Q; z4GP?#zzquApui0Z+@Qb>3f!Q;4GP?#zzquApui0Z+@Qb>3j8w)jCYVn9pqOIQtu$Y zbufr?0?q=EGlFGEX=tQj2>buCd6jJOvagB5I!*^AtIcFYiaiL8cv|TY492Th>EI-s2|(*+CH&; zYTIYqZ#!T+X#33ex$O(vm-zb%CG3w7_U-?$oDfnrh>%O9*D%#c$o-uM`FZ@y+BaPH zGE(8X?YeNC1;3Rc+jXq|4;WagC1P?vy8q+rm?0c#iseW%zL6kHc{E49i&53Cm|%bZ zj}iVCE2yS$@-qHk(A4Oc@!uNqL)h>3=zqtrJ-PwEFUP#WIN|@Q&(4@o@_${U{@WC~ zxg?v6!S^llv8^fO?T~C>RMjyhA*5>;xtQ-{`6sxYA-P12&VSTJqxoX~h|t}-(cayf z@7z5u-}z+blbPMEuk!iM`spn1kgb?kIfI4$VFqU#$lZ$xH_)uZxox~QWXq>hW=u4o z)~MVEhDL?ohe+>#{Rz_hnyQj(3@G+Tka(XyvV$KTlN7Ao_y&`G1?=)<=8tZENQOqm z+D4~M&Yo3Tb;o^=F8|r>4{-m#OR4|#^WP%F_;G2d|4;G$morIKK9?DXH>6J>g%in~ ziKKWUSul|l6j$VxSK5k7X5^8Qc}P~5<^}Ia!X)zGB=YZ?;IV9ULEv;t$f|{HKWImbO zcRv>ybCEN5KFO|{mOb|I?5gCnIR)mpl%nj4vZ^N@*OE`5Fgaxo%OTnGrlr?hzg^h3ddnv^1d2A|JB z7S!N=SZ)!?ok=Q5c4gL-jGFAql=121XjWxb#svH(X?H~n7Lb(mqU^j8McHY|*_HFs z(7(#$?6mUi3jCXw27*;)r9GZf^aM$pLsGJ5gKq4LZi9Zoj#njLPxjNGF9R(@>U!Jy z;m`_}n^p)sWn)R%Fbq`EgtD>P*kq4Q=}(r;CMo!qmElrGit>s|%ByV^r8$l~TVBZ?8{CpT}-kDgTk zh@8rTlH#AC&z+l}pI2_{!$$hC=H!-?vo`m)qC96tK@};@E5|d@3R_W*qr5~zKO--{ zpcs&>TY1GLb7#)7m6wzh*$RqnKLQX3X)$iCr_)PwJ2Dnpty8y zWeVVMu`vKV%u!h|FE0q)|6mQc0$IFvj#k*_*ayfJrJ#N^En$ z19_yh2#-!Fb=aJXm)Rzyrlr|zjz=C{;aqa>eWI=OzDE{6ykxnp;*opA$L@44w&l27 zkKDE7PI0lzHb=ZW)i!R*r>mN+b9|za28dFf%UNEJN z52ije-Eoh$!qu8y`VT_xxQAt6{R@`FD42dG(x&KBQ&`tGMXi@C7lzh;m7pZS!gVz!ff zLh$=9KZ&V{goLqT)xv(?CMUR3;xlM;Hrg1^P6H2tHQB{h30ahv$>`I^%q+8CsN|PJ zF0c%3hWrGoGG`{4Q&2n&0%*=O_8hXD+)W-Lcaqc}rL=Ui>+TDmHdtWsUiM3HAy@lWc^KN-w#swHm@Aa4&M?}U@L z)PfCa*=E)7o+@ln!?vms9<@S>Ad>2Sc`*5HEcvZE^*Mn&r%wBK3;B1|-l&$p5JH}h z$II^r;PmZF2E)I_kY5iZub9XhJz0Ab`J*A`kLn|TH4J>$5Y}Xf+GL1~yMyeDj@}>5 z9f%%$FnYje2ICGj>x4R8R1*MH3dsW-pq! zICj{gjK#6T7fo6mJ7Uq~#jzt7O<5e9xJXE76> zizeS2YhN_w-q@@~;=Qrc3r5eHGbS$fp@PwlF>&VDwCuZ!!|k%*ElVzE5G+6T{_I?+KvfkB$_mO#vUBH+kIQz4yKO;1UR>(9xjCs1WKSGbQ&YsQ3l?No%}WoaM=cmPz91c1 zS9W??RqnVM3sPnC)<6Kbl(1O?pQIs)3E1EKnl|Z-A zO3bl$XD?cow&;OHi7M%>~V|+cc(17bKC;pcwmW^SYnQQFl|}- zlJdomK6vL{i*1iB5%06b{X^aK{<`V?b&){be!vBHjvIgX61OYvL3Ujdm-5h}^oM?t za(DWqC5zG*2NS7jHH%ZnWiOtVHtP0!`=2)*jWwf%lc#`Ktf8PlO7^(BQ`46^7c5x1 s$Q=6^1~aXyipzP@X}H4roZ3Hnka@iA<|jEmmqr#Q!sbHi5)R zl*?t5wxq?@*OCTXzLr+n^7>GL2ILWJ(FV$UO)Y(mH0`_Nq-|`|5^QR|-*2CDClf^b zzW2SgzHhxn*2e|3KbX9?{H}Y;7hZou z`91e7`P3yvMTHd_^kUESSjDG4IL`V1;G?l|7t8yH#@&nGPdsw%xcB4tz@y=D7vlFD zkJOI)2YIg>*MZ;qyY7gy?1`90LWWUS;5E*CW!cqETCZ_h!NdY&9Vjr2P8GZDT7-)k zcHzHTh4D^$@Xz@*I*~5<45632$U7c7UjL|q>s-ck6*~EIqs!QS4wGEQl#}N;Y3#Po zx{S3z`Q835NqlNW0*RHqx?ODR7{m;t+%Ohj^5Bx&6So`2%(DmyZ9}A@0e{tBwP93W zqOuvA?m}ES@loVk7d-0!ipK|hNG&~v&~;c$f{!wE8KnotXk~ojUo{%|{ zSiSxl9u>oQjO)YWLDKKzeDq}SNL`1=?}^Jo757dP$sY7an(y$KxVa z`6t5r;!AvW<8jrQDAq)*cCqYqLiraq{~LV#ya|t$z+O7^)Z>2&1!7izs=vev`6Big z{x&j_+Uqex!&Z1WY99r2%j=L8^Vi!ybzTR$LW3jtOEnG}jpO+OF;Ugo+L@?bdWn>@ z&tgfR8R}0p_8W-{tXO|)PeEmD*a{6*?lD6{R=7X4yTA+&qcm90$Px^A)#wThfYS{t zHsp>C1Y?8CORbPU0-)~jP}E*mCUCPCS+T)jY-sreD>Rt03j`o@tcew`o@9lF-Jzj< z)dhz2n_FM{zwRc`XK8`GQZ@e8m*mw7l>n#WDCr`U!{9=LOC%Z8>Uo?ia zZ4;7!wxk|ovlFcFpb%jYtwAeO^VS)GmhDJNHI^BP3M)K-3Vf(w&f`RkW@ZLc)V7Xj$V zQe&xMzj9o_=z3E9eogUs0>$IKAFnZN&NN^}^oS;UXgJjgjv*2Eq z*FO>~PwgLZ;J*tY!Mz~lC8K-;5-Pp{?_Vjy79>ng6cYMD!mKB|v#OI&|F1{r|K9-e zh1ef4&lvk)KCCqTY2*iGOY!GtTktEWY z3CIA92+HdR&k$B$y3&dbpcjWD_BqE?ujYngs?l#G3eoFiVL-IMtZ~*k(qtgj2;n9&JA;V};#P*--{(ES&zG8SJc#j~@Qsu*ki9V8 ziGgg#6n)xvcx#MEd=7}Dq?Tv02>Num1aqVssKpVL^rjk2dK_9s0}ntjU@lbw_RBQ( zhW(F{&l8Ey%R&7P6g*4~|0jZH=v@TQb;78i`H;eDt*R~6=ra<2ktlV-jh>ur1_?Yu zf|~YachwldP)YJ4h?!tf9B+v;Auj6M8I0IBE1?E);myp%Mj|Gz-xc$nV{rZp0mrRJ|dZyJe<+xZ)@`&6^Kyb>(}vIPlI`^PFF zd$Uz~3rJjVZx2gzyS#kGWIB?Xzg9q%wevS(Kka~$Xn^YSF40-7B8JSO#dvmk6D)>5 zt-JZ!;~Y@E#bCd)gpplPP$9LU06;?-rm{m(A?gH1CVGnbRg038LlHZI6&6aQ=I=#P zLEbKxH;iy{0m5E$=D&UWZP%_k0ILTb zC|_=H73YNYR2kzKn1iYL+fmI(@`891ey!4OJnQXJ?CnAyq6&F|*LQD?(ZO7)`A6`C z`q_l`rRLYEmxttq=|*xIwf#WrVnkJS-r4>*A}{|sxxyt#}ZV~K+8WfS5X8YROjsdjPRuy>gx*i zA`RL4jK;I2jc=&-N8;;=)CC%;@Ni|gxAo=3$5D4>tQSP@cZYgG_r9pT98MRQ>CDiP zRO1nYtD9cx0<-ZplEn1i7qK7yuyg=cqEUO9nyY|dr;Gj5>y8~UW4+lgOU^o#6P@U_ zqrV#&K@oR&7+PCb$mZe|t6S<1vKZyk0?W05N^t$sLM*E4?H2_&a2X^&C#G5Gj^aW zbXein9kH7Wb#r>Ga8EEi9C%_HiePwD#(K=y{*$y}eeG_XmrbVT zZ(;u>biRT_iB-yc_3<9&yGG|j(>f(zsj4VmF$<|P-(YRN?4=Iu#f+V%%2=ffQ9=~z zM-oNxO-%Z0M$nVlR|fmv1Of!w7A7B&WS^d#7wHK&HD9Dz65__UAK6m#DM*A=2M*(% za_B%00*X~2h-V0^P+ygiqlDe(oT`qnsvoPW+7AE}C$I|*7;(Jx&oV=HmzU9`F02`0 zyZL2TlL5(9dJAIf?VF^izk|w1R|p1aj>8`H)5k)381z=XoNDaF6tNr9gQ3JE2%CC) z1x&4?8|)|MFwJrR?-xljWJNs~TC{~kJm}}tBOarn9221B!WyMnYmR#*0%C=nP>>C9 zg0$xsYp8o6j+GQ13A9`Xd@$T(4EMk~RG6F%0V=XV7L<@k)M4%s3k_=Q3x<0h8fS4t zLNrUGQjG&p1xO7mbR-xWOx_2Ps8Au(f5c(>v&i)Q%7#&IUvV1Ik?{nv-hUx=UaLq3 z)S)}Ak_D-wSg)x81(x4IvXL4)6g75;6z3%W4h!qTKEaV{TDSfxI z(01mt!rRR-CxDUU$8vb2-deT%!w!NR?-~<&%ha^-TI+pC~Xkc2b&n%^WstZKy^K1d$L8aCz;?phV&7yS(JL>6#T!%utdHUFV zffectJhw-e*>8pqLynlS?$Hdbhm!A;dLk+lnH%g3m7s!j@du>=m;&!agDCiGJ*i9q znrL1NIW&}70lu8ZnPn0NxOA==+A8nhEwXPh*pf!vuM3?$OpR?dVHs}hAHhm*1KA;T zculx}HMr)mFyvw3&mu%uhPpeN(8MfQ?LRjpww!E8%y8=7VuiNoA(5PHg%4MTyUik2 zkRx5TFmn%>D6^F^m(BI3UN48uq*!{@^2^u~onZcNn8P77>RG=QIdL2n-tR-SdUN%jG&lnW$S-z824;;mR^*T*vt#2nwMeLqx$&3W+k345Yb?UWNU46{&}` z7*)$Z3MppQmNf6?mNsp&5FRxpUU|bR2O{eEB@k%Gj$2qu3_iU}UfzaT{ZQbU&Pq&z zy;uz8=dn+cM|N=lc)^s)8rTQ1;2GR~+=T_t?zdc(Ke9r-m7(Fv{ZQlZ4(xUhxhlKe zKQhC8$XFS+#dhC+*P(kLMzNa2&ZN6rpB5h}-o%0l<<+j3Kc|D$>n5d?rrId`6Dlo0nm%LQ}*!j0C6svAiED@d?Ch(~2; z=;`O@DS{y9wH~7Flj+;X={t~q7Kx})9i7@EX6H>tLU`0D{|>dem>M`iS&au_z6w719}Sij78E*{o=ZD7ii}Qi9j61;rDI z3M~>}<7|he4m0`PP*{-1pLv1FC$`5urakilYu7Uu3ZB>$ol!TXtN}^|GUZyK+E8y_ zJf>=Fv7$XuwkKHQZw%_@?1m0B+MJ0io#s&K8Ep;_VRO1_pf?b6G`-AdxI*eJ1F4>V z9xO~w{Sk6mH4?Q;q8xs`yK}royNoqg=djg9d{6I^J{Zkkme)+HdbBrH6`rSe2``N1 zpQrOvoy&DSIDF`xIiV%F54!h|AO)jrNqSnf#n3}wHYiA*Crv5wE<-ya_GM@v`Vkrv z&7GtI74;$fqKm+~!^S!9daMj^(;9)$4}!>tckQ;Rez9- z0_+La+0kvU{_>B049WB`AhZ?5{s(>7)XYq9v36hTkz!ZFSaeg+{c`AvNrmXz(tBjZ zVyG#^6Q$h?{FM+l;DQ=%iCO+un|caYcmuM+^WS}_qIu6oM#lQGXDC}OmI~kb1?#|~ zqK}$Bx9|sHw}8C+Hzz@caN=?*r7*AH33E(RFuxv{z0P;uIXreh&?W z2(lt2RnZb1t}d>^$m&KNsLJ}VzpBs`x6kxU#0$4E2hwtQWYs4~o>|b~9SO?KRzU5f;GZ+LEf; z67mbe^~F_@;)!59fmH3Us_{?U@1*&vBEHcyPgRX4mv(v;O2HuLMbBn06NMGFDd`L= zIcPQd?;fdW?qWAQPal&%J*#2XmYLULObvWul#_2vhc>e-tV#9uH40a}nFY<@Yr|+t zVm(}p?qE-*!<(ZvM=E+!b8K_}7QB<=guNXur>t&Xu?R^`BCq#aNuOYnZahq6Y*~-N zZg+sDfyQ%EjR%Yd*xSIKwMK)#t93DWk_?zFRAB@StBtX+mZci^8!{wPE9#8KajC{` zqj9Dc-V4USZr}%gt_co~+DpqJN9rP^!A@|IY9Ik5uEKD)!UrmA%Tl|?Tf1{&N#>aq zwJ_T6X3^@}N=#SdA&#MjFYvqJ(}S)CqIE`KZ5z>ofdW%8hdzv4q-1Ev)5jjEgRn}f z@X9(p5wjQS>jKZothpVwyUNh^gS{}ju~f7!80&0A+iyWD`IkLYP_H}o^QuEvhC2h# z>@nMz2KXq4BCN$N*#S84TumKJkDLv=vzKX_&CPK?f!@N|x5FLNPF%yviTnr-(B8BwUuT|37Nua)7^>#mtC z3wdNa;*QQV+Y(N;9(V0@GrZ9XZOqLU`}s0;T9{@;;0K2^0%BY zZy|rWfmMXJx+P$SH(Q~#Pe0GasZ5Y~*(EQdQ!HR8g$2Oa> zbyjHI)6akRDwozb*FC*UUK}JV_uut0=PEP&j1_Kjho3RiD*z$C6hz*MrS9q^5Vmf$ z>Zz*e++&BJwpO*W9T$M3sLk${zUr&0nRBcgb4gWf?FDznsb6F1wIp|llR9c*Qw(UqNQg;!Um`9e~+5jagy639Mh zNo}+Px5kk|-Y@}UoH$IddLUOE$sc{lcH-#65`x)!I1!||bMVQZj*%ha3N}|n#jv}! z!b~qAdNCiiXdkUGuuQTfrs@#4XP(&;+@ogKaaJocsu}bD&ARbat*0n(iUJ1?h$&Tpj}V^3wmhvzKVLg5bEM*)<%5X+o+wF|2iuBfjThZZb5xFJ0v`|=kf3hN_g z1|+?E8F=DLcz5QAbi+UW02ATX8h(NuVGToPbQWHxy>ES`w*Sx3rH1?pMwr^i1$_~SZAXPly8rSO3 z{-(zL!XEp{9Zkc(-U!0^)u#5XghZw zn&*z$@&w-ffnAt|hh`<=4AFn==Vo|s7OOmXcI*|i-CmH&q)8`dge%kQIy!y~Nk4J5 z?g^w}!6fo)Casnwz3hdhhE^@Fb(ms`8cN|owPzZ&&%uEw8B7DvLt=w!$289yz!^?r zQAieHakXz@>9CRcD#;WY%++v{Q^Q$Hu@jsFzXQD^;QO=K_S|}P8>MQ23IvW?6SG$@D#G&jJ^3@!hpjVEC+1J>!ANwR^G~2xqKM|oFt&2w zn#(nfAGRvW6vRj!up}br3mz1feF@5#I#vL?P#M(;H+evdKeUmYoi-W#Z z@J%kW;6_ujio*!DDcW(gq;pOvjGi1oliV0Sw4wT-@;o$4*v$oQqfyWiN{~Dg9wr-| zg|4{!P$B%X>GS_%>^gD0p%J5OvY18!`zAq;R!nJUBGeVyw833t(9Vz!Z&GdGP?9!m zOf_yacs#?Gou(`ia5DW0JjO-RBw@hYNHO%?(RvW-s*XS?V%-GuX`O^*INQ>Wxo z%W|nDxzyrZsy~5z7$kgm4-mj1vfmmN|b`{+yqkAjF0&;Lc5~H}%E>IO$>Gbm{U1 z@C9KLE{I7JCgX=_JnHj9oQI0Ls%iN(vge@#Q;+!k2{_0UTQ!hgAa$|1z?WtHPZIvv z84F&W$1&yZ0iv{VQG!scA8Bel5~iAUF8t}$mT4p#a`y?u68 z^KB0#pHdc1!mT~DGYPSOjrL@Ifd?D3+aFyz4QDs7DFs1z^eqyc(_iKVW(XChI;TY9 z_k!P%$Bh<5?OnM%LWe2vK@d7j$vnX#N?TJCEOny5u4sYkvgI)JDrYnZQDxvFe1C)p zz>NYrn-XQWx;h))$1;3D_R-thSpk?NxNDhXEh0ne&nMBj0t`>2miq>!)UG4FVF5CT{x|*XL zIy{iwl&Miz00oQ$PyNz)dCCq6tXh*f$3fOJs=?IT=c_Yq?7z2g@>lw=II`3)9n8)v z$YqeuD|R}sIP)XsfA7va05(wWaU2kNz+v>wb>3Hp92Pa5%5n z^10%DpbP;T@jhzWmS4fR3kUet=%P5Ujgx_-PH~>Oz zfmTW}uugD!BlGy`+3~P#L%u-#qoHmwX36mW11Q z`D-byIhUrxwi+bg25M@MUc=t_4trIHo~JHx>`m+@@NJj8 z{RMVx>>`k5>wFdNu}P2)b;T8^hYQvB8ujabqw(JQo}+$is&OlqgrlQA4|eDTnm7_= zjsttkyTBHuB(?>1X}CiOf8dl}KI?xeUhb@!SNuuH0~_z!tSYiPb1K|}F2 zUB6A2x0(74dqPN?t>0$L+Z_EiN8aY@x4C&udN(0?d!HuP=67k5TF`DzHEteDuFO`Vp^CE&~utmrwme#VS#NHuPdG8;zA>|}P% zPm##d%X4ek-9k7SK~D=jjI*-(rQ?i9A)B}0IHT{?n3_f1~Mpz;$QS3 z98N_TIK|x37d8zM?B8d#3xBO?xBfk8w_fbY`K*?CU5#qcPEX4h2(#pb33pPlNanHy z3f#lq%wI6uqA{u6Jo|>R^#U-=&5Q6DNey`fa|?hoDaB5y-P|8U<`3-D1JReg8}&H8 z?I(_WN2*_URKs3(a;Yv%9$uGfTt_CC=?Y3~o(%YMmP;!fAot0J>_2_D+V~0n-^BlE z*H#-<_`eSSw|%7A_#XZ*s;f4R;s2U&wQ&&ttFEgyeun=@eYLR>|K<(V#t-oSD*jg? zzZZEQ!2h|(dmsL9MBcCCf8zCkiT^1m(~bWdk^ge&!p1cHS1_%BA(y-sxTkp#@J^dH zZv3=qJ_IKePQ=qct!Ub`(*nhlnCo;t&cJ_3DIRA|#-r@4v(K3}W$L*r(1JAnzkz?l zHRi8i%o|=#Oc$-*InpjYPt%54LQQzsmBk`HHzy6>-B~D30>jyV6>HD1SbIjT80x^d zUPTWKu&bR_bf5*UzZgMNz&b%+;3*s}!|nJ`yz&PMTkRa&$6bnMQf9W*}BVT&1$9mfp@q60^y>frS~PpCQz7a0nZ;-LmEw zzThC%UA(M9oGu#tDpwiY-4kR_I69PLp(w=6x^k;6;7=+S2Pfg!1llqe8~2DvT?y|h zo`(TFxOTeM6Rh>{&?{V{;5W@RpYp)Eig{?SgToozjC{xgG53g%d0NN`f^dx~>wZt`g+=CiCdJ z%7W1{T^D?pR9$7r^LSoeQ-ZZqcpMzZuFX)FGX1s$)9a1b2lG zI(0;X(FoGno(R*~o`}(i3qMp_76oe;B|vyz^P^%!AeH@assP!V)Yf-QC`gJo6zWnw zI6<=_P#WDR9TfHOI0dl-Y0*PM@fx_RF_k1lq^c5r0M{an;vinGIHm&{E>bH%tz7XE za{;{9P#omR6&L3c76(0Y#iy7NSg24OM93AdGZ)n929FkxnAb*#Ne$+7zk5Li!Y0CK zMeTH8<-T@0!Y0CK0{8a)?#N7pO@vtr^E*n-mQu5&)Ep^Aj{vh4^F2zRhv8Gh;`@TMtGJTz&xa*EpONG(&5x z@Y*OYk^1viS>D9w5dIs71ioBg(9=iejtH(j$0{FD8h_u^`}-$!lq_;^zTAQ?3MxuVBVSDr3jI zWq>rFPdXTRXCkl;>9|d1GqcS)NjBU&z--%*zVtr(lNU4$O!BkEkBz;ZW42I z?pSR%Iuf)XKpGZG88BllSzkNvxiCX5R=CB4O>_SJ%#nmjdZ1pCBKFS!7K>k8RiI#~ z93RlYl2=(pH=@k3pP%z`^XohV+`QZH(3zpL%gY3^5SwF#I?+^8GHM?`S6XEM6I-UM z3^-SA9Q?NMbNg0gMTtdH;sJ@owv3oJ15dsr9vEAR5st6&#|{HeGqlBi9$C%MW-GQO z7~9+kJ$SPjY6267x4?%H-iu~zTYKUXUa7OK@iZKzLr}R;a_@DUDNcA+D_!x#6_-YO zdS)mz1FavY!W`RPZ@)c>jo`sdF>c|;qwPj=LTdh8^o<;O?Pk;A(NPd+{h5Te8iCeV z5Nh9oHcbreBg!qQU_%mdD zO^Zai3KRrdzQ$NGW07XYK+99)G6%z!e0YO|_az07g>YL;c)OzMEjnMkcpmaRtlk{{ zu7Z1wuzCSpY`o>jfw9V7Q)SDYvK1_Qm4Y9i%a>X5;>n!DtxjiDbqLP;jYjxn^a?A( zgsP-fQG6bY75p#hulS98$*31$C(Hu_5&M0Ra2So6i>x9aByH3_L&au(!R<5nRwXCL zIez2o03^PFkXAuXV(v*3M$;65fj*fW-^j$rR5e{*$~=x{``erIknVLMzrr%m`cuB} zo}QLpu`TnbQw$`h=Z09+{xHkpo}(dGp!G$`qbADM@5swu)Zt22r{-^#_QNAKf#JIi zcyK5)yc!@aaU+H_JrHq75{dT^*?$%AeqBEKFvJ=74=a z;GtT9%`jVMiJvhh9zv(8U>_8iSfw9`+MoG`pr3gIS>;xUYO9n|C-ujIdix%g2%$2g zE2IRUzRn4k7Xa0ds^9 z`#qAlA!$1x(EUN*GxUfmiT+GnqexM2*NuUez!9vCLGLpt2NxR>@j6APNPNnC(BXV} z^JQ;!DuLmqdt$5y$^q;hAlo!2dmXd?Nr3yZm!!iRU~4{5Z}%+ZNl(ghMdm-K>Lc+c z=AW+eJBZK8T@9rQ-*Q6X?>U7xvT*iU(gl6Q3D_NIc@QLbhSiP(=r1{(=CvPZDQvU{ zS|Z5d9QV)yAB+}9AMFJ|GBLvk5Vpjv8$BnpBjm?nM56x=1F;@loWlCY2{t8k?F+Qn z=(F|;nG@Eh<}+X5rr-@p;TKUgcj}U~f^O%w%pK!~ceJ%>WK} zrjC}w0}N(0NUq8sk9NqP0o(q}If#Ide4-E#2KGp5&gyF4#Vilu(Ir^lpC`(+{IMamo$qz?<^c!l2#~WajPpg zv|C>ew0?sPluFv!3=7v$aI@;IS;@)ya27Qqx~2g0(<5U5EnLIR_0(}>9}5N1(E>2Z zwfRs=n$6N7EG8um`c#KBPD^WG$h4>>S?c2p$%~))8p-L;taD+z>vPb&+nGn!Udf{P zYG%2komo7(nEkeT?dU=0XBJae_mWdc(oEC=fIFiW$U${nY%x{WYtNFpFd{b+?41I~ zmzjz(4(zXK*nad;#*>4MfRXt#FzoVj>XoW~E3eeH<@INHjdubrmR4**#CCy=(6SCL z0y5i~e1ORX4mL-@A51^Oc5FbpgTz#g1Q%kNRZ@-LspfupWqT1YGPld?CMUHXukl{g zqEYzrzi7SzDf`&wvW<$Asw3?0tJe-HLzz+*_FuymIG9|cQJl;4Kck%*?q_s44xr30 z5#QzIY)wLRc{vn?Bzq-+s)xM(le~61uV0r}PM?y>XN_%`E0z(8xa6<*n5)vv=l9F1lZSDEPqWA|9NLxSR#|E$Y$M zLj3O#{QXN^>Ppq013apN?-o=td%2YMWdlyK-kQ$*fm_yjGBS|f161F zvTEoxKV(CTorb**^x1BBFF$*4wQ=@+xJ?=Vi}C+&_`mu7YU8u`e+mC@c75=}9|Lyqi!vAmZe?Icp;Qt}~KZgH}_ z{=b6%Z{z=Y{QnF758{9NgVlynQQ&e{s6P*WycOdr##dDMCg`}riTz~}_ktkP!9~YJiRknaC*o3OLXUMoJ&erA9 zdz_?zB*9I5xY`Hx3Y&+xxY>g_4>KLM^Ad2j9=2SOxUU+p=z#I>ur*+`W&aJER`Aw( zfp4Q14wsLfyH+s7U1HX;*UmYVI_gU8!J+9vWpTqqgMGvpjBjw#tmOR!z33}(lk4SJ zK>hA;uUxN0Z*QCx(B-)44u@LoEc5*S05_F+sgjLj!xJ9Hx)V5F@{9~#?BU_cVLvdp zCw!SP(2)8^ce00Y$79T{>cjzFoVmkk7pO%z)fwE)yG}thTgrG~4ZtEAmlPD< zFoK(q^aXB?1u@VX1RL@K&Ccz?GR>anw_`*x@X9q%z#EPT}C%!%Ci{I4p;| z4_k7hQ{{fKL-ksv)YITX2Y{8KzRGSBXLiE9mAF?jd;p`n5;u&oqYhx_owW_(pf77X zV8*t{C0s4~(T(7n2AGk8@14OvhVWj}u(TW^g_x{2H=@p#!UMs|nX1eONeXtk2FtzriZy z9F;l>Z7OjYGo-`YqV`o!ldF6YOBz(4hKbX@NXNzN$S~FN=10AzSVwfD=>x#~Ojkal zoAv+=S8yx`0`{@jfC7~IFZ&&$VaX}gzYc9NfgNdPNr$#Y?B_RV1RT>#XTANbj*BlN z0zZ^D44<*o$&Swqyp4mzojE>UXrG6yaJ{!@;n(5kAv>M-)@P5$8)mHZq5{Z+Vf$BK zv-nFQly9#^PN>}gYFqfsIBzLaY$(_$2V1+y3q8{JGU?~kZ_4Z}Y zv+XcC_v?=c?k{QE5BtjM%$iPNRIhM`cJ>G6UybxlQ0YsR#bn zd-Kq=q)2fV_dt+mc&GFJdiw&MHCOg@r)+m#+3TfjNrtvz^mj1Shx>cOz0r7YUZxp2 zoFoTuLJl%%8vJ6v@CDWV@qQN3Hm_q)V=#{bC%NT!0O;?J+E3}Mxw0#rvO{@gUzD;X z*$)b7ztQH97PH8L(Hhz$mtXf4By+@mO+m{R#r?==FH$8HO3qppmm%JSY?;|$JhI)l z9<4T>!2cbOR2zT6e<#9*=VX5c1x~E1z>^E>IJfwB&BYy0edun(UV^&GD4JvVeFO54 zRm24YW+nSd$pBRd*FVum3N9$zZh}Q%u-^XudZ*2)q4|(jJVWwTC$2m7Rv|hv zgura@r|caktdCV5y`f*`3I*5L1X>;gEU~-c((PgJ0NhnP-qp~dC=jEz@dJT|){+X@ z3z5}@yPH+Ejk#<;|0jWtY+Nvb!>t;Bs<#}H*=xTDlwCLa|(rZ2-B&Q^B3`^RI&X?v5WJp^)ERiv-+jg|P}F;jbkZSm9xb z?Te&g6|-N_vGMy^@QlmIfwNW%cZE#+lS3o#7OOKcZ7m%Woi zj(tyBF}D6*lpW=H)C`JUG^S>`lUh_KBz=3`DC3@&cx9CRGbTBSr7@+bc?a|^PfU*A zOacv&Kt>G+bny;Ngf`*5~8%@E} z$Ta+wTs#Qh&cIV2Wsg%_4LqeW1D!DHt`-g%D`OhK&!av4DdZ5emdR*3xqR99U1<<% z=3o-}Qg9Oa@`z-^#C;O^@^O$1{oJ)cjV{fdH%dc2a%#plul3+nZpW?QfSt6@Rk)oF zta7Lj+rJVi>aUF}a`BA^8yCmhzkg2Jqqc`}J+9C|u^75)zI4?)L>UOD1=+->Kswu21vbJ zFwr^TJD6rW;8Zc3cis138F-U*3{F9Se9ZRPEtiO~dhB)I9f}Z+7JRmBYS7<`Q*K*ut>}h*WU0e`QI0E^G9v`XPz> z*k<;TKahrv9PR|evbY%SK3o;xG#6$S&X)hkGMd9~fO>^#L^y0fIBdY-uz`1Q7&J^o z3Wp6S4#SE0LVNAEbrb^@s2n5mm9E7cUux*nFZ&A8=qe-eK4(w9obm{B!Oukq@op!t-2sr4 zJskLB?#!1jA>zOYzv5u`TO%WtAsF2UP>&mav^eJ$?$5%Ngtz^RWX2xxc>D!^(s}>oaT; z(`P^m1h^qk4&NP}bwUzLX`ICYWg#g_aIDb`m1J?e61aW@J)rZS4zvaI1o8e~3y|z` zxtIg;M~VSu6r$_AF7(UMLWd*`_v4kop8(ndjV>kF^3R5{kccQo9Ss!#7oa_gkyA%- zztDAZt}c8~O4RL=OaTXgV@C1C6Xf2fx3D*0#S-givN+zr*wl%!O^m%~Y%EE;8u46p z*)eRX08Xm25TA8Z-7QuvAM~)H`uIA@hu(jBJM$Hb6ufzc>_#Zd7DjSWd?Twlx>~pe z%%YLC;k|@@kxzF~Vc%d%hNUi>U&lbLvZ)n60M>241&@eb%>sLUYI9oqK+V)~+mOR5 zt;Vz7F4J)oq3zsfjM%iaqo{x+4d-&+pt5E;*y?ljr~J+Thk1scYR)MNoT9)f3Y?jyZ>F@DY>}WxzJo4(mq>r^}S%C z39A$JJdANxd@rD2jZtrReob^&y18>j<=7!+z>nctu^)1ISrp%o{Py{cqD04yCVE-e zQ`C1k)1e-EJ$!GP<4ji+A7<|BRBkK$@3`&?eylioFyMTeF zaU@aN@`(#}i~d$B?jyC;BRKP^S__O$q6!~<9(3%*wAGOhuZ7PK#vvcHto4g5q7 z$nAy~LczhPT%|8z8ji`e}$5wNhaBpv-%slhjf z23XT#ZFHNo8SY%ONr5k-b}VMn;T~Fs1c{#r`8*N(RYgbPh&pCoDw$yp?C+>RR;!55 zpgh4eiG-4{)9dZWbt0qnFqoN|eUGaQF4=Gbs|1l;qZi$efY?GZ54mz! z2U>ZWK%wZR9i-n=3xsfM5m7H-j9tQ*_v;N`#`IM%2CnGL<6=y2HDl0>-UtHNtHd2^ zu=mS`9Go=p)ng$mvmRNjvmRL@S^Hr$KN5+rz>EDWg>>%l!&d}15n73VNX=(JQ0hq_ z#Oiw16NYdg6YJv}2xfx=W-j6k@YfE;KBfq#Jz|rgc2Y(e-L8=&YzOx-<4x)fCnC_i z5#oHf_`|Bc!?g&|9m1ZYpeZ0$5lN3j0i|R|xLJ#LZJ^aFf^rMM$YG*R1`_AR8vw-q z(+cUw(c=iJZ+=EOwUHTqt1@sjtB*(4+g_>EFYaBAXKzeC#jD+WtK>7L+<-fC^qae* zj$qm8RuNH)+G|DFz{QiV_4cRLP#AR!cBr%O^O598+k#UKm55Fy7P&|E`Z7Y+jwc6ItCLfxs_B?q@uj>Sl2$dWHXnCc@3 z>01zM%5C(pf-3++>StJfyvxV|`0Mg6Mu>4%DMM!IEqHc$7wYtO20E(o0JV$AtT~}J z?_qY7zr7Zbu&{M-9H~3~&GZ}sgx5^lTn5xRv({RKyIQO9WX)RC+k2Eb$&^;JQ!y1@ z^M3M+-)xWpf35; zfGON)l@d{$+QbvW;tR#7N?^JkESG+CORX?!zMVQ=#8V^(&{3Qw>D zODVH8f*>z|=P!3uC1ADjRcxK*IPM^EVt<^FIL(qG!ZtT1tMYQv>X{~;QoDVr*N03A z19Y3j!Kx{N?0N;jY^~EZ^H*wSz-r@@HLDAMPP5V~0v6Vp_>gb+X!Ys}+$%;)3@st9 zx$JikSM>%5?Au9`{dqKDSkZ(bY;owWX~f4h;K@HzeF?ynTkS0ow{)(QHkhRpPgX0* z*g>h3+DR@kk{?*=i66o6Q51{XFRT}izyN+gBo0v326zPGoKO;tC(qmn0GStD z(6Bu5zB~}i|1OAKiF^>t31VElKM%y59Egi3e8!+KE@H2A$}c7g?`Qe(@xi?EgP+%} z2(;b}j#6Eo+B4pizCsTRmATa*0o4WXxSee3QlHAmTbH8tA2$%F&urZb>f_=`fyJxX z@^6vmhg92`A+?iF19xbBP63gR0ILHHrgS+Ojh#*Nxdd{355@Nrqu_aW<#o=jX2eNK z6We1+gTS|oRluG6xFhZAat^%xabSt3|FWH_ZcoZyN_=~g8hVA(o>?TUEfX$WYf0(W zIf(C|hN)&1(dJ1ZhbQoLdV2<2UGXxEe z>pi3{wwS3dq~36u5@5C^$R4rxN;*#^LgN$bLh@YP!+^{M$#-K7R)jf=bw})T3)w5a z)VuckET`Wq)M_P~Zu1d2H*`b4oaIFMha|HGfD@2vm?Dq=b1 z|2DY(b+vkO(L6A>wiGhr{!>JBrPk0 zs6AgfVVY8VN(hG2e?O%Fn9svtpcH-JyIO|6*yyox}zC$&RJ3Mh1c zcTT#`)O1`gNYv}=KOPmS!qEifatEqI2~oHiW*enokIO5N>=b9sn~>J8Yi4+eHK!Re(=3;F{m4eV8Xr+eGQ0v* zumnByHLJ`G^D~1paBR7n0LRb<;OHe} z%nhPO_Uv9?<$&h@ZLPg*o|B0$!8YR3c!tV>mNU{!GcvOjwT!{=q(WoWWjX#;7?zKz zpi(N(2&`}I2H@-u(rNx;N@R(8n+NxSXMV%oTt94w7(<4U>?d;Qv4AP&p4{k@T7~IX zAQ4Rv;aM(3NQKY2#51SDEr)U2Yt(<;BE6>ceQnlf&H8RGto%tV9 z6Tko2`idi1oAGfa9O1!Q1!r^~!Fd|0uX#~-B1$X@mnLt5J&wM4si8{~Vew+ZWdesG z(9^LabjXd^Q(^rl(L&vlaH$-c!bP!1@u>?4gyy5N-|&`E4eOkX-+R$F(`27O&@n#u z&w+6YR9gic@dH!UfckMxBf-;^IN|`Djp+eL-eH);(Ij7L-WqW8HomL#3Gl5J{apso<;=fT93eA5Te_~Z@Ac+yy&Nn z8!26Q#}>6!ZICY$b2dE4VBh0mU8U9r!@iZ11Hk?5Wvi_w$|2TvSIkSnnV zd4(!Y6yPjK1HQI0Xu0+o4bL~AQ`IM1O4r{BzP z!K3j_B-76SlV+`b?s>RdO(e!h zVjARz@8Pqsq&zUarc*$2+%CPYS7>2wpXf%Pjz_QmCDJ z%hNa|-aCri+n*tF*aEewGvl;aA1Qy)C)5Cv`o(;~u2el2l%2QaRjPHmMd{eydV8mo zf~<}p5J`u+Blb6SRNPYsus^wtV2hn*u`?Sc$9YmIz7Xm0I%ZlWGmF1{36OSsrQRZL zz^<9Jx>&f)Dk?)#m!}yBYn+71x;$9_AVzXy(lN!HWQi#^WlvBxU1gi92t3h5Q@iAV zsc+4spYSkZ`uMBWv`5?mJap&%ex>fb^ww@Mf5 z!IHS}COn8wTlLB-)DePorACZ=bNP7Fx-Tq4IH6BRZ2 zCNf?R(cD<%7v&44Xnc6~0mpNP+5Pf;dx$gea5182eNinpECxkq%%w(S@ zFTwqeDCU+iIOYsODN(?IuYxOu)dMXQuZm#`lJgu4VLxQoY01P}IAfjCnL?elU7?Mm z?ZM}!GdS=CR8aBl&X{F2tFUmO6>%%Ni%S-UcOcwOS%Xc~y;1wEj|<1*{4^~n^)iNk z>%=LWOMEX`(j$?$20=c6auu$WKz?^@D~jxm*xz@GbUq2%kRCJ75VvzPbH}W zSl>&N__1zn*1AC^0LbzkdLxV|XzesAiv)Hl6Y(ig`6bUYR(PHX4$m{pKjmh`*mfx=ye6EC z3zLv1C=)A~emNTMF#R!jZ)AUkBb3Y#TaU?Yelg)C19B)0W;>~hpFE{v4DKZF8kuSs zZ*-JMBQ=7dLdq!vsJ`l+io)c1srh~gcAU+K&k1XK-J6uAVm@*KmXnvKEEH|t;(nte z6>>1MWhWD@J7hp&6r84qC2wNr%;IpxCTEat!qi#taE+9P`a)XhjU^aUr}IrVQiL&s zve%L-5s>KKrT4OXZ%=QDR$~0f7m?;&AvKi5)e;t%+rJ8*L%P4fIBfb9* z1oYxFM@jv!Ad=9S{N>Dh_%a=?i+u-;q>bl_dH`x|FcLUI;`3nLsR!VbfHj61qBf{q zO>giiHZa|IMA}2|W>O5*NEYyhEm1_4iX6xxksDTwyNi&uX5oai0_c28f zp_o;q2!f$ZxhK1hUzRR*jGw{#5Gi_aJy?;rxo5XaX&tD z55=D zCHr!uKKI}l_SJdikPwPtLs||A<>ZHkd2;ss8_;#I#@8h|4LexJ)(cka^ZKi(U6@z= z0eES%FmHMuxP$0m>aH*g+mfGX0 zx4#touQKtM&wy+>TUZj(1R5(GbYvdL7TP;YAVdmak9QUs7fD~0+s79Z>Cup>cfA>57A<0KnK?#ej~K5bFubnCED>KEhSnd)!#0(k z%~c(o?C`Ozmh6T((3$J72x~-H8Ra``Eg*VDoDWzOu%KK)Sr8Z;B@W~x4A6u*XX%((CSQ`v& zg-u#_$6Bhv>Hy$crH5q?D#8cDYa3t$S{saQO_n>_Rd>{Wrd}8|5?@F}cSq$7=%_Vv zc&+Yz|C5|4l*Wie>HN@IeAgOZf!WxuCKKe9fXW+ND=fG+#{wDB9{0lsg$q|LRLCUe zIlx2~m1Flu^fsmEy{+)URi(u40*zgGtw^4=F!bmfcdB8{`=}aI_^4kxd?aeWq>ExK z02Xc^`JNLI-iU<})`sm)L})FFfEMd?M0^Kpo7KXR2Cq&L>Ja0xwb&q61fLv#p1jhB zeDQu}zO{jwF+t}tZ)E0;?48N+7nr&1dSoug!=9}&XQrP;$* z)&%IaPr0hub(3;yY+2EJu%h?G>i|u!u6};MAOIi~`1u}8Y))U0cm@%G~8lC!DwR!pMP834h}jlv0|f z2D2###>vKtsI{r`5&N-R4pzjJzgJN;DmsUy=8N=57PX6P=`84wU%k5wAxnjntdpm& ziV}gFMi9x#>VyT?UyDX{&(9#7{gtv)3r4a@;1*Kg@^~xU=;;+S^w zba*S0Y^u=H0^WEM`jUUO}HrlD6uJu ztEKm5vJJ8m5)_4aCBBf>6jY1Vr>Zd4?5W^zWdJjhbJgTm8E#4)cQ;OrC-MmW`MZRv zwQ3Jj(+VWoFV+cVp~;As?l7^;-X*=E6ejGJNhgS3VqtQc8l~l**25aipNySE;m&`JgKGzo_GZ+wk0`ebGla9oUXu++H465 zd#}V-x?$yb`T@m=3NsOPcE?1Nmyw{dLYw;@hN9BurlVpG6|U?VCLv`l!WUVK$V4Jt zxke=2YM0*B5w?LypoXV*%Y?!-X!yA6DX_s z1_#bHQ;Kf&yvhiIs{KE$p4mU7#nMrC^BE6~{TFbWYAiQ2oW?RNjiu_!7g1fMv4Zg$ z>6z7Vp<01NN7WkU`a{RaOsZBS3K?ftQkaY<8Ma>QaF{U60*)D;?{7jwgQ9D%#05G{ zqsH#n?vw7r)sAWx(J^v#3(Z z9qb)Iei;0G2G=Ik%anPtLd@wAE4>&kjoLT$(F-Gi?rR^X`+^4M2{x|+?BXIiq`&JzTpdtxvj#1u&8 zgD#zC?EKybRU6}*ILG}gByXdW+Pvhs&ZGvHQ8ToWN$rEt-?EN5(Qd&Okfa)fw zwF*=|o*3&}Fcg$voPtI;f{|ev>#Yo>I$@EwEBA9M5a%qtl5osYf*ms9K$fmUQ6#5R zNYnGwipdJhnB4<@1xT$iB=LypQ|$S1+c5SeaCJGV2D24I>W|{muft65mc%dTVa8g z=YVjRILi}r^pJRpi!iwb&9U0}R1>E)47B;1+ zu{358OkWHsL3xuRX(YZMIH_y8H{3y%ERh#g0d@>jHkDzklAIZA#Xo*z+E#6R{KaZC!+Wy70+$o(c6mML z{7bd*(S6m%lD*YN3BpslP|&$E)PpNSU864&;-#Uo!FI5>gHumR9TZKRu8)M$c0^2h zZ6~)I;)h9qBkY;5ERA3fV7c8#UG<`d;gc0Ibbb0@DLKJNL`M&ns+pwTKKc;phtI2Md;)H`w70;)tt<-ME>gHr*G*jZ&di4; z8EaTLW&yuSIFH2VvE1*kW}Be>@UBE$m6yAlu6-^j2XZbWIW0Lzg_DqIEhwM~R-wIw z`r(vCI^gCp$5E$W9CiA|QKuZvG8Wule2$L}Hk1&76)XzCM<*Z`<+|=9XzUzv<%he_ z@NtomBsP};QhlZcR*Vk!IurWCZ1Q$mbf;>QH)BDF3DyB%f-ou>-shT? zy@f!v6H&i75%oL1N&Wf0Nxh_s@=fYjzDc<8ZO;--zg{^9?9??4@H1zl(ekBBcyy6F zGX+<|7pxY%b?_+fKF4ievZPrfE4zkflZ)0y{WJ@Wp3p{fd}qU z)*T*L6C1>eEi@pOi2<~)5Z-1tO9v|Ft@q>!IK#b@Cw?z-5-t9~1w>l%<%?EpyZjt%T{898?y>T5tZ zd)`e0R6>%r&G(9KOES4rge45HYrY;h1G%hR~p%5Tqu0J*%mpK&N9bSulhIF`%%@N=KNLzJ6|8LCwv9!X)+~hGkGX z*QMjTOqivNh8i4WL;#mnubQMR*_Dt6Q0`)VSuC3SkM(e%OCC3dy96xRws7NH4HD=I z^??EgE_8H&LokTM>H}T%w#Chu795*Lzm>GDk}r&IEkTkHS8=Uk^W336F}hVIF`G(6 ztPiq8Kq&nSAO;nPtSQq&bWF?pw8;#;jH*13)1sueOMnw@;Oxf|7}5{<1RnDZ>U=re zrDo1`xbJ&%d;`?Q_y!E2_(qPS#UhzBdiz{6l*z?MDJ`E&AO$fpFnoFU2|s8lkY>Rv zCp@sPU`F;e;2}{n0DL2XZzJ#>1n$BXCnPhe!t(LL~3 zKbp3MP3vaUdf2q-A{d;FVN@=D9p?XL?|ZkYC~S_hi9%PSh>&E#mm$^O%ZjV+V`tV24!x8M+48_ix+aLOEryW)a7^ui%^Pm(b>ZIC0=nk*^x+Rk1SS^jL!xjR z#Dc?hmq6~%6q;&%Hfwu!*we$@%kswb@KdF9D40I0;Zodh`-$Q*jj#-eZ0jVI;u09g1KQdJo z@w*ZFisa~VL|NK8I;SwKTSCD&$>3r-pK(^%2VmUh=_}al#+5-&wuQ@ajn4ra4tYK) zkb=zx?GFUmO#hY8L+*zoX!YYUVf@zbU$+4lRqlsl!-k`P9Zfil2UK!Otl>ja@wI&l zoX5_`w6>2OY2_GQ`kXLz9|YJ*#+5LHa92Cm;V>+&JJOrWV@)_)pfgp0UeF2yh4-V^ zGCd^2Hl(+>mTMhk;i98j??}253Q(q(&i@>oC~-Dwc*CFbr~3J4j39$pWyQT(d8X8 zI#I&?C;|B^^rD-X6d8&kW2~jouq5dteU(tevOxfuKH(pNaqc9}(?y1eeb9NAqpu*w z?NaNzFcNko(fGloPkj)m(;d^N!_|8<&mLyDxks(X6}3OCr8MPxaP<4uQ^i0;j86&m z%$3TWR#TvXr>1n+sUt>Vz2}RVhQjqcOn(urxLAHP8hWBVY=HAoz|IS|s?pSNIfis= z^@cle5QnbG)c_Z+$^9lC(Z`XY!xOtJ`UC!Qca&V-AY=`@tr;)hjeeVltc~8yU*ssc z&Op@qXa!!PaN~}-)N7M-p{axkA>FP_II7Sc#nch-vZf?Qry&(|LwsyE3zlWSi&Z~JMX^oQF{Apw zJUO9}&i!I1uRI^J9t$$q63`%Ou8xsbd-O1QKYHmotP;56TXvHM>jc*UVrp;=7WrYJ z>7T)y4%HcH>&`C&GwO?Q5Q5oq^21MxZNL7s*!BVb?*FXVHXeUB<9#XqY&QE>{iASp z4&=-66!X=YctJepR~2f7*$mWAf2;aN{vOBsQ~2A3zkkQy>-cNI-|z7E7XF&?cNl** zdy+#)P8sv1f2m&zIWIsw@9PU6A{J~vTapr&Kb~)wlG*Yk)@t~V+3)~5k*QZfOJZ#w zIGE3tm~A7uDQMFjxY7<*C0Ug;bLgVQEy%W9S0)n=Aa18G%#HkHDy^-@fm;-`40`7Y zBf`E4y`h55KvWavQPpA#%jblB4~!11ucZgDQe#ziEe}8eMH;IRh-(3b8@)j@>n1@V2j{tZ2j3=S);fkCl^YB8{q9^ zWH)U4WNF>tgHBIjRScU1)p!|$^eS~vr2g2cp9SpTXkfvKGiPN<&0OS8*_Q9MXu(|LBKPtpHo`(M>u)JiXvr+nCh?Y}un^^8I zJHwWH2@g<4#iqfmNVf4&=tdB`>5a)584=1agGn=sv8@M9Nz>(Z*eF0D^2wY_)2j)t6 z7beJYKnja#jB#XCIm}kUdr=!Yiox$vc@B0~9%;W4KI2Cg3=DS0Bgeoa<2DQ`o-^7E zA7HdCcLC9PATC7q9*z~;p1@xN{(1+oCONEsc6;LOyyvL3@Vsz**zHMQlZmH9B>n&T ze~A76f0nTMa3^g7=@yP1*r}Mti(aJ08!#KJP&uuIV#A(iXp8ww7cHzf!Ct=KN{n93qFmwX zZIoc!eoElk#_q2M7%Q`AL4s}I^K_k$zTmnDiPd@ z;4Ui|rB&!-6EQmx^ZZB*>VY*%nN`|;G?bXf{frXq*F5_<^N2HPc!MF;wd@8I;L?UE z`7W#!Gi*QxgF*jgCR@JYS&{ivOx7zVAb>X0jV~dCW$;cnLxI1>$?Y7L9ybUDv4zw7 zC^0z@J3^&vQL>ANhDK||ReOJv_g**nKGXrk~nKN|3S0z6>XxAW)<#yi>c zC#_Ha0m^#?D+#7e2l&vudocqXHQl0RF_^25$oUkFl6;Ahh)u%nS&5Q#Dro`xg4q<{ z+a#UWh!)neUF^;ffyj;2NZT@;6-Ixk#|3QpVcrGK&aU^5V{NIhxU7$?Prp!&Djv3~ zK=q)&%k|%vTELQnMrS9QkGSS~aq(lq+-&J$gBZ zpwH!PQR|2aNhm4nu&e>Rod#lD<|m%#>G z{}HTWumR9JS%Cnff|AeXU|<7Wp}+ZCs|hs9K@o09q`ZexevemU@x8Dob7cg9lCZ~x z#Om=E!sRZKmB4=)%3>_8$R+_0`PR2t!5p#9;C=^>fAU``nB4{sEBktYhhA)B)d0LY zs`QM+nmS@*ruI77b!@DIs#pP-SL_Tk3LwThm?+>$D&Qrn03ekhwg+vn!N+y<`h6?{ zmB*}0&MX^$>|69WgBNjRAZ?Rp;Fs>R$wn61WF%6;WciA6)&#fbH1<6%)C?aHbXfLS zAc4wc{rFfil7q2e=cvFFR951i=?7SAjxvZqar@8?i`~Ikdg@uUg9!Fh2N=PAicEyd z`|?SY8D}UvcMYoyO~J)gsWeVJJzxRoTw}QUd28;x3@A7a(#m__qyoqBCowzv=V0C* zDY-d^woK*ESLzK3Fm}RMDGI}U5P>@o^#8n?>Jj}#X|%HRRr;R;WLou3Tq?g@KQW&o zT@i8;Q@*oOf8ZA^F-XT1}`D!h6Zhh#z`gA}?BV~|;{=V2IX#C z#(a85Ezdd*gsYz=OtbK18GO_Zhd2g zJ1X=aC2HA$)QMVlP%S%nEeO}0RxOF}9UV5f4Bo*Q+#UW|R95wl<@%-52}&$ar}qP; z(R;8+(SFu{CldG%jKcC1R;eqJ!190moMl88f=r^jS%zbj!RqrqHzgS9^SVR^DO8w1 z_Jbr})30F|IS<+JJBFLuf$S~!01!g7Gx8gTCgjbge$J+T-sYECP1`DU`&F!s@G3+1 z`oQ}T20A?ARO-!E(bd}s>j>9Dk`lQF=20%JZriZBG4!JRZ3NpkK3ld`=t~l?CBnCL zB;BZaEC)rrd#IvKS276DJtwGpUI*Olv`pv~_U6L!_!~A0F^PH!`PL*_$6*+rMCQ*} zIdsuS18e(ks9tQgY2*}ozO5Ks<9A3=fa71~Co1(HGw3jMGieBB(h%J0Z=&{9Z(Xh% zSFo})&sMc{V%W2l2rG+_(=3EC=2vRqF3tO9crd@)ETd z*UGWW3hI|Ka4-PkM?lzU0K{!I)V?@+z=`^>8vKschteR|}c$2)(Fx(;szm4)h zB6Sy~9>cywW>B73YT1?y{ECwf{{0ja%fBB<{YNPMZL_H~kRvQ<^_);x%b_yrSY88Q zpcDBVKz20AqQN68D?`_BS;q@t=g|jPOkZKZi%hOXCgcthY~d^&c7=43pG?ECQXztE z0H9y9ygGspNHP*W$0?)Qn$9xD;n18~QtttemN=`oa~Ap|e>dgESzYF76RsvH!;-0-x;xgww4ogoheShv*&#JwbfmrWl$*{_OzGNkS1}C?Q{!; z0zKR5X^dy(1=92beArEY$Thp~R}$0?*|bcpCh$XlaA z&^mqzi6_QenTZsHg7m^e1@X`RT&gRxkcOSW zlT`5}0DZ=JpkuCo0hg^nfqsgk*}|otg}JO+5*$%x!~-|+Bb~q!z5Ep!-(_KfI=>FP zjv-~9b$^O734HP+9tI?5$$QzZ8-Bk1dDMVxXkZvS1UYflV&!PlBnaeWs zGw|qCe&QQ)7F%=(-D@f4*daiSgnSYZv-9Fmp+fLY1uoa0zl+Ks9&=PW$jFsDth5<) z+K->IOOs0ziHHMaF$a(1elestk3-exFv!I1%m?9o`lSPfKM~;A99Iir+Zuy^QvYmf z#Cv>`WfW6j{XBmW1+L(Myzl;*jRrx>Ac!mVygON|JCo^?FqV+CRrf*4#2DWW!DSof zTr;g+ROdg#;J{JkXX%BGDie9N%a^mBq*Ic7I1)Ibu|fLv zKpciLDgkA+8IO!g-TS1Kx_1YqCe|&Rr%s&zXZ}qdX6kY7N6GEqg{1mP2cN?uZkryK zb4NfvKxtm$X-3*PLY&w)5p?m+I3m#g6I9aoSVm`B*oLW~fS~Qreoyj~KMj`omY-8* zqVpa0YmNQGBsPq6z7tC4EUUK1L|CHdK`*QpC21OKBb)Np}}Z1yv8C z$i2d~bP72kAB|eUnA1rHK*u)dv^toy2})APlOg4qNthVYH6d zdOBK%fjxq3TAr{cxy(X~C8}l%5gqT78egP_k(`tq+5jLaw2eYY0*er;=~}5VLP4}Z zBB%^*ZDx|U^tfGqD3NpF5Z&x?-*7gZtevT3Ax)Be+i=En>fp7qhi3t2#UOM18-ol@ zhCqQPRTAAsfyMbpb~eZ={Jk^?0_+P5GXdI>bZztoY9%MA{ykuA^evodTcaTt>mw)) zI*#T!3QSyFd2>R^Jt;sVhTmFQ#6}f5S2r#~6<>8osQ;HA>}cvk?<33f^^kVV>jz^ zFbg=(dnfuOJ);P}XeWG~(;L~*G<<+W!G_)RyS#d;Y8v8{~C@95MIE*1q@uk!2ccw$lNHFj=iLles)6Y?I|^YCm4_&BQA|-_UeHd`vsjDgjtsVVLL1YW zOj#&_I{yS^mR&9MWGlH8x+V!ZvrZ$xokb;WOlzUXb_&rl`Y1eug~PuDJ;PZPrq0*# z3&-tbOwqzpB~uP^190s7qze`1~6E0mL$xo;6=j^Q~g|4JDLHH zsEoUwfy*seN)!dRvvjXF7?5#12kCYhRK_1hLrrkvE;Xq!2}^V0LHArE#l zNJ+Vi#t7|&cj0*+#h?us1@njDeNIhP(2a(hAo|$EWpw^!ET;$qgez3xtaotX&I}t?Hw6f!yJ@coT!8I zA#3a*Np^MIvYsY?Fz^lzqXmeNPB4YY3EJPzv&rj_D?gcvg}{a$5KF+ezd}#VB(TW# z_ZCg*%b!DW*yn2Fmg`%`QIz2BQ?gJlQ+90^?fvf&qRoCAx`u4y^>k8vx;x&q1mAHl&wg{H?anPkcF5K)mqTie z%@f0jxOzO5;WB1g@uM(2s$+%Q6Jz-d8@;%Hj2do(4EYOP@WqjPdomiwz=n#!)58(Y zI*bZ{L0k_;8|)RnfpkoUdyFUH(yEN}Xd%wgU>Sv}VUIdEPq{nM*B*6#F99Q8W);T< zZ{9G-iy6o+WAf>G??2sVHkRPwiB43zd(|D zW}cGL;pv%Y2>88;Vxu1dw&B^G+3*#sik3mM2Ub=vsN$26i1L0Wtl5u~J`DRrl*#aF zG*RxxrIOSR44Vm zMU=al6yOx!ZzjUC5#at?=yh~f)jFMwpi{hZQJH7ac+9^6QA?Hby^#rAnn3M&6W9hd8D|4tV}tyEF@cRs|NhJ! zfs&?r;)Esm)kIUP@s@-$YYI-}i3S~9W3y8NmkP)muW8NqSm2(h&^T4^mH5{PR;8UOZ@Z)7etef9uWn(uu7(b^V_%|$%8TW7~ z!qq(q-Vju4=U(}_(E+~2)h%&c##3r1Dr$$Nm|O* z!F;wK;+#KSPDo5Y>mIhlN+5qEgzuliY+E$aQU0q)Q<}?3+;&>3EN%h}S5{{-ZN@OG ziJr5bav3)z;`0;ngyE5R++4^PJX{G%x#=H`WVWrNlpekX4q$6cR;#17mh*JlA%ERo z{J*l#y^!_-1}pdN@D-YB)24zd_9~@UL_Ly z=VJCYE>iSJjgJx?DHoe@?i>a>!zMva3cw=aWUM08vvGc=7Rsn6?uSGU%LhLNzPGuF zzTF3LhPpb=4QQaodXyzf9BWPF%HNIa)je^R6MJ^jH>F0ujm?fS8IH)qaa7>6%D9O8vT$k!fO zc#c2f^q}sf{<6@S$-ApK(OuXgqDTL3pIwhi@_3(-U9r_?3)m>gZ)=Y%7^3po+qvO4 z>Ou-@*%pS%w^dFu5BRh5z_y8(W8o(D#xG34r!5zsf5Im=%vvxfJIhL8V6A!g6&uOdDR_0}f z=PyN)rpaZLu&8A#hY*sGr|?!2c`)woTRTBZ;ZUoe3hp_SWZfsL{CQUbT$sHE$fLTyy`XINPGGwvS!-N}Bt(ohaCL zN$YC0+g#O-+V^M^HEHfX<)bn=d+w)7PnkRpV-z!$RP-jOj`C(1il^}e`sS^v0`v5j zE425tdJzM>_48j1yytjB8`2c#sefxOH4FC6TWoF+WMRpYfrDDx9jjLFZAZSU8YIw4 zo!Tnbjz^`&Q-EPdu@o}sX_qIeYXsX4m(+L^-`X-UZzw!AjKrl*ics%$+VVbgCaw8} z(~eN(@`fR@mXgJWp&mSy^eX-5m(ndaJ|(qAUx8QOnt@WMX!pwZXr-cdV}2}BW)F|m zmSryqnc-!^MwhpuN`Ewm4JOz?8U^ZEQ=X``Yj3p0lGWpv!B26IjB~|8myx`)>CT0= z{$e3l&Ilw0Y*qRP=yD7~l-yh{Hi<@Nz#j34tEtFqhl?z%cdo`+nq|&ha?vj`a%_ms zT)+=0_o_RXUZuusDxy9P0Bd~_u$HFcq=0=0z*CFW=#SzRJf_yUdR1+EOOVECAT!ju zN=e;GjINR5?x;`II<`|xK&a4LCZX}$uUSuX&!SPX~Eu| z+kirBS&$_xj8j{4K~CqBDMa1JaP;yVMef!E{xeFTx zT`Q60$f|ao#Jj=yG{?v(ig<<1)^5%@f=`+rIuTHxuN{+8=-F^Nf&?8nW6(}41hJKA z776-I$VM%AAJmXfqB&d94I9#H^cGA(ipmM~D~^DDmD(YxANJLNg3Q^EJ~OjgG3i&e ztMePtZX3qkoLQ*cE8mOsmlV#Kix1hSdtes__$zp9s9!Dxg>Z$A$~RW&ub(kZpB7^? z_Sy>l1$??Yed{M_DZ!$-^A*WkRiSsxVS@nkCt1aeKCGogO6J;)q=MGftL|tgBG^)K z7a6_OrMSE5leD&)S62`YW{0++9cV?2>ge#TqRGL>!5AQd{Mhta!=RmgvtjUkHm^_jH%I|AZ)H`uhFM+90C{&uJ-=YjAB_b*Sqxn0CS+*x9XDC_JY<`?Z5_zQNd9! z&BQMCxFa~2qEjZ_-d>Ki69 z(CiGStk&AmW*C-YMB03)#9Po`aJ0ZIWJ7Obc?%6LO?VE-nhPm)f14`L!T@mD6$w{Y zkRBjr`sB%rU>Ji?n=+xlElD0*q2tgUi&B!(W2J6ZSl#bfMy*{=qB+5rIU-H$AJI{u z-dd-XA}wj2U74BIDqk`0F1s=*%}%NyQ)kmK z&A~`d+S@L@=t-OEaqi`d4=_gSPZfIQW@2s%jyA6Z_r+P9@nCVTe?z{%OrB|RIG?Jz zuy(vxJKOdb(eY<`xEy~rCaqRm1v!nUzOhW{zoVVfMYXhoHy9VhxSxWzhZ!HaN4q(W zlBZs8$QNN*!mAUnNk-Q&FT+_G_8Z49L#S7M8{^Hn16Ryqgd6jAsPgO@eFog4)Mzoi z5Tl$%>_*mFEUER$NDsMcDOxV4SLoj&_YZ4wY(A}1UE{Q2Ib)?#iK^7N2c1fb(Jp!> z$!UyAM}LJcr#-ReV6vG+LXBh$`*4c6KHFR`Qk^=lGh9liVDBfo_${r**}wZyWwy4= zKGug6I^ar-A6uoUEzedYS^R2?_;PFR;gO4gH!MAe5HO_{O*+kf(?_7q7 zBFfJG*991%m1f%@vew3yp&sc4`-1S;Rqb4T;)3LOjI~bE+}Ho`4My4Q?G>P;L`~VB zegiWE2Cr3&ASeCl2WftRn<5GX(UE#1Ea@OD9FJkBe}+=Dl=;Ea4%@~R^Eai(H`Q0> zC*KB=2IW7Ny9)gZBva?FKnT#W9yn!Or=X+Wk956$N!V~LLAv>Bl9ilD>r3RlK zFdd}=65wSuqHBcuG3xFjJb8*h_R|A{J_kCCk_=J`v0g+8HR5mr-@u^O71|pv7dKv} zm1YN09c@0O4c9=`B-%kH={HB~!1`N1$Pz?K#MJYXlw!zjdPi-&%v_cU3fWnjb3fYH zS?Yo$+-3m3_veW<1^rq%)&qv(9%^=5mG`yaWj{y-@Y;d<4h4H2jyd+d94t6)ckhb` zp;Dx&yCi>Kv3p-#X8yjHZJ`hB^qyRtzt5nBZ~K#2P_(vJf|YjL)7n`oW&2hHp{QRC znT~y-{#S*&!5$^QIu{QxDI0~`3sdV;7Ge)&^xqsv4QFjZ@_gY(s{%#aH&bCA+tUMQ zF{7Uz7}DBabwO+$&Uy+F_{N@MdlQx3+IP}49bH-*0=G9JR zq#qy*^aV#|a%q57;vmxZkN}H=0!L7y8e1T3rZJ$#ZkHZ!p_kU&=+lIkTJbfagaNzz z&#UUE70$T^6J=w1O_hFt)@7fO#w<0Pg%wjfXoIV@8~5Uh84yWqz+xbiUHv6D+k>(c zgq%G9MVZ)CJ7xuu$uYL3T2bo&s}L!V2OLBs#R{)EhXB)SF>uvAxtPSia(5^x(hIOa z&A{(D>4ow*_J8SZSZ)|A+t8Z}E~cdmZLCpacB%1+BsSyVe4r7aA|Qx>NazHplfP>$ zHX{1(`Y_ezJb+jpjMH}rv6Ad!Nwy&XoL(f<1A9}y00h8)j+xbkRRXP?V1+-!(%yr# zJ|7Q?{GKvY=&sL^zct;b#){To&7&&xv*;?YmaNQxL)EV{=lB7HqpwDP0G&Z+6d9N` z6?!fM@%~XDjvWDUE35Y0XK01u)PIIj)m9Pf3RQMh;5uFiqAK)gF-S41B+=4ND>o*zXYL^OwYMGeG{2s!nWut+59br7)pUHrF9s%bk`5z-mj%3h?c>)3c@gS8}#%EdRDt6xY z8a3unq`*Y|PdLWl3pn&Q0kIkr6k-3Wz3pl&S-H{ZUo(*03+CNvf0gZ#B(McS00epu zC@uOO=;LgrzZhL!qks1lmQuatZ>&YpZ>NySGV$X|N(J^6Mw*{irQsDt-^fd0GaFM{ zt9MGj#)W}63-7Oxlh)?J#*R%?^7qN#B^s*0W{KhT|eIEl=0j z`gys#TRXcpNsH0O$h<+%2OQHk3icbZOy&RCUN0J@?%K??rBFm+ComJx(oW!EX3mqL zwHF*3z`}Vp|BR8Oon=K}f&MX5zBy@SUTpV>`Q7f$wKu}ArZFAh)A`*u z>Ksfm7`A(QfNQ8(P{gJR-M~tY_L#WosP7>xWIe%L8{}ZnQ$wV25MAlR#sD4386U=@ z$lrr#ATwmjX{u=l3uGoKwRxZ69jlF!QKNeRrM)CC(^r5_oOBwHmO6bqf^uqJoH+JO zY_VNCh?&@9F%#%aFL;1V;$X&Ol>$6;Be97aiI-??Mn)%dxH1vYgWUqVL==2fKZA_E zjc%@wW7%Z=O!A>G_cPke`q^+m{ArDWt9egPb$4llyr*xd(icIJGre9+bT#-(^v^AD z+PHQm^{v(>kKujWmcP5AihzDFp8*YWeFOFEH>Tr=Nw<-Wolrl`1?(rTYI2|_7nwN5 z1IU+6GtQY9Xwgu6Kl23jupojsDj$ ztX_9Jv~YEIXkO=jJ6LQnxnrY1r-KJcws81^{G}1 zJaH_(YaB87N{gKv|rTYs{wPamsNL7E?^zfKgHiXLlLet&BHK25%}m zw8fayBCiIYG=V(gbQqY?QI)uZFPn*7(X`-=a4%V--)(?|*WeJ>xiqZwN&aJ?i}?Bs zUszVy5l!3y4K^^;S|_;M>ac;<5?kjh5_#JwuigI)NF(z8j_0LK?yDpo^491tLQkm0 zA|-j*M7c0H9)L9{s8zRqHC{-r(oTCw5)O*hHKC(kMWS^2QY;$2C@~?}E@xw_J+?~E z!}{t2clt^blqZ%D)^XlIS- z7(EveKt4?5JZ(|D%-w+*&{0w4)p2~%h7A9LvanW$OeqvZS$|K$p~X6F}Aa zZM+oYvh(v-jqE-5gR7tdl*#IR63y7;%o_cTOwPK8;Fi#gj-$CkVy97iY-|&qB-((H z;bJZu_iBUc8DZ^=f%hOxkj4CiO{t5QC}*@Ta7>Oidbse|2azU8CR0xR5?ND_=4PZ} z0(oK)+i~nS8%r5hv~=v`e6*yUiK2c8jM!h+5zYlcuzLV+BxM0kv9DWGgyf)55N^<> z7PHsOCJYn>3JI=bMQx6iWx4pt*NqPO6AKRs>uxdwj~_?vpL8I5T!wKpxcHf43C=kfO}{+_|# zR{TAQzs>m5N*+5AE_wU}o;sd7p1pYX;@O91AD(dD`1ol&V|d2!jN=)P2oW?JETJQo zz=TN+?!#Xkf3C$S+ar<~cMG+4^gD046#^K~!v;{1NE?x_i%04T;}-t&M)03;?$poX zsP};~)M5_22Q25}6=fy*W03bpKJ~{#fCVWi@s=jM@4(*y{56+4rXFls>{y0^ZzasV zFsfLB%ZeZAqfe96&lvVMk4m{^R60P9)>(b^sYCsYdQ^J!c8tnVIZ$>UfVl>Lv+-Ai zzY_c{#oulC`xgFy=N#ZU2hVIgv+>NtGZRl2o-RC{cslVE@f7hC@D$GP7mlAG%4@>k zQ}}z9%1-o4sROMa)er0&tsT_|XdBY-u=DzjEqSgQe+(p8@A#Og9CoT$H2d6dDcRTy zkqYrU*df$nvO$)3Nvp5esC9S1koPpQz?LMe#O1t5d0$OsMUDQiY#-&q60FSC*vWXD zLj}t+n4w(NpPU6^6T~TF9XaW2U0)AgBA&h)@blP|oSRGZ&jscOP&M@K$G}7+6gfSZ z_QWBXS;z3UM)Q2U#-02!3RB$p(DAX8K4#+MLwvkIA5-x00X}|9ADQ^*!N+s-k=n8Y z55p4)%|?Hs&~6k;Y{VsMEJ+!^My-Dfx))|5nGCU-0jY@L0GX-rMwFh{sED88-|FpD z%Bl*8)#CJXhJIr7(@#I2(+|#32SC|?Pm;pHXLs1X*OJ0|rC);q!$P9Hzais1O3jv+ z4OhD-vy~*HO8*t~UToP=@@oR(XgN0{;yCloiTFh|dJ0VOz!S@v#!I00UVRDn%viR$ zuoTUR0kHwoZrs7kHoWy}FsD10~QY9|>pWqLo^g<;y%H z2VZT+MaRByMmD|buI-t4f_42jFxn7zDqqteQkrJ1c?+yh>auGO6o7UPO!_E8!Hz9dEh$1<}(fs zJeJM471d{B(UtRZFvfa;0<9a0ChTlRFJogW^qk-(&{MzswG$|e!!r)>(D<9H^7_N6ktSAs+q&%Fov2(Np-InDHlxAnK#<(ZI&D(QeS1}L%qU#fL#Z+}r= zr=^FXmIIX(7JJlo!97&>a=}sF*rIMTGP_$T4;}3&6&jS}K>rFOO=~Y>a@5wpq2SZh zMKKkO$0YA?HBP3x3*ShjAtks>C^jV8f2ZM9Gz9zx7pZ3*bw4&4;AU1I3L&;h-BZ$D z^D3d4DUu++IQ|jF=M|V29Rf6$3iM@vWjm{e-c0O&KqIQ$8GO7+>ci+3Ffb>-%+5Ds zc5^nvDCZ5^|5e$AKQje*p6J;8A$S0>hmBbp{eh1bU=L>lp5Qp7d=kO0&~E6 zQToA02#JJx&teRf$MeZAtZUtLyqcbP^O)dZnv!agqkxR!Cb3xSiu@C$%-;u11>mjQ z57wIHg?iOGrtRHWy$bBTNcu z0HLs6lvf9mS739YEFBr|+iCnqgGj(947M3YC;YQ`A&_Cxi;+rD^l7w+d@THYB=J_v zHGLsGar%t;v_Y9A6qD-%XK?PtQsbMLE4;28)DWIel^GLZlKHhWZ*RMqd>c~vNp_)M z32NhG+;D4nfhcFFOPpfo0w$+7#^FPVEXYIzg0R`PX$wU4E-1_FjIeOJverSi9#Gp~ z2Fjv28ChvAfj$ZfD7ImujqaORp=d&F;7V_{8mC)|?{8vp;vn(OwX$3-3hf7kwkmIg zzr8}RD!EnqLm#km!l{rYmSzT$!lcGn5r#mfRDfygP2pA9;f-SW#_%d(O~W#0(m0g8 z`i@mhZ3v1W*lOgY8jD2DQ3IBuyj;hO@sIDN-x+#|c5! z051a$xcs1?zxlGojYqMm4lBK3$c-9LL&yXB)`CO0+!{u$%7KDIh1I>%=3@vCp3SYB z5Ip|AGwQ5=&Psu&L#JCa&9n zuUHtkhH)!4ok2PleF!N~kgDg(ZdG@{gP|_Umz9;t#OOb>ym43bG5(Sp4N=rhHz=9GP4?N!*u{&HE(p9w??*(q`T$oq0y)wP z?foSSAUMA$;^_rD2HWTM3Vjn&HD3lYvKVP!xNvH3OdbEKw1t0XSi%4#B77s~Gj0 z7-qJjd`jUGeOecoO{sARL=HzE$G}HEmU9GkdX6E8$mKiBLWiVAI_R)Qor{Y1;jOsX z_^8vfpHc+dbJ4xUkw5GNX>{)c;glk8BOH7v@NbJA#LsAGc)bLM?AB)i5Rf>^TA`PM zZ9(hdr3%W%>pMN&RJ<`=)o+)tSM@RS>t#}-ji1}MLz;= zSVMn@L^RP0;GYqk;x+xAbD}&+dd+r_?6pyo)y(Mc37hvGqn0B!x*eY_TL=?iKBJGJ zaK#xs`z^*@Q&kXJnhK7ifH>l%Pb-73nVniOj_d8B9=2K(fqy?U%XKeSDf>%(agE0LL%g9JV*eLOghk>E@g%+NYR$v{WiBY$`ahysSa`ug`k2cqOfNQHON zMnbZxCrgb#!3)sTNDsM^CSc<^Tj}YGbtj)N* zg?BqH^O|UJWHsAOcvOK_S`Va ztQ3?-cB2VN#vIl!m!Jm`m+O~TJV#IVm+Pd=Tf_aWlEH$I?sq<1QK zJAtA0BE|^}^v&`7ozJ{T!f>SfUP!_J>XW`XPHVXBx$=z-hZ}` z>e=XU)E>d&ZI;KHvW?%PzsBNmI6qX3?wSXcZYozqWCRLrva5# z8}Dx~mapjVw96^ziWx>`e>;E8H^%h0C&}pu%|-W68#JXSUpbMlobGRTD&s98R1?V6 z>FOBLVS!#nJRcKdtzegMJrC_~$MorM7e?inrT-PhAqU&q!Qb&|+eT`;RvU{vWUkR1 zi%?Ei#UlM%*oR^(aJ((X*tsAq8loy!iN;25%+IACn-9yR=TN(!G#wjGltf9>a{xbDvL0dt) z)EiAXl_l6j=7S^zb!zRm)ObU!8?Qj-9OS|Qn-p&;+ra3GmF*_V)_w~H&j%ztB>|pl z6Equ0iuEC4gSH^1RVKa>xrSnK@tLE*TxFRBm5eeAy0*XAsmd8pvb_)3NP2HytPW+? zO=4-x+0W@eJBBSH*%A5Fyyt8QYoJ}UujSTO-C%pd8T8xUGV%-llSI0Ld4NbOMEEO6 zR9Mg&uoXi5$QU`?5C+O8GG=uuPN6H>{lysY!&#a6Tc~wAm8aO-)oHDGv8mGt zWJt@m@4~Y)c?W)p7OrS-p@@hx$XXF`HbE7TNp@8E70!k;)QGjIYHOx}>%>SVqxO=w zOxmi{XbW80=lKshwcFtzE$(gmRMOtk9*N(#R{+tv1-hZgW_t-B3)jM-VxQ)ORToY+ z#*|HMgF@h@C984Sg!}FF4zLy4(g}il=>$>1F(;=wn7b~Aj$H>2e->G47Y5#)QukcR z&=>`d+Qlh_aHG`LV?`sim15U(dyoT(QYg{GFanz(YIPHYFnbm7DmrRo;fF;41Jfl_ zxK%Z8TJH$lv>KZo^*G?_1rvoL@?oJ5bw5D}uUkuQ2a{0lT%R09oA)_tqYaG8rDMQw=? zzL~!Z+7dB*GY<5@H62dWkAZQi)EGuB;FlxL!9+@WN3t+VxLF9JgqsET&7$(n=B25E zYUVbTOG9lYc(63sE1!GH^dBJ05VF z@3J8C0oTa=lBW0PD75b|MfE<=8P}OG8BylHG zo7TgO0%!3lYdC`@6O^0qa6wVwIn+!>)A>{xRZUe5D#E7hQ6#3hQ8r0Ejw64NDG5t3 z0c18xQ5_=%+Dd<0}(?$t?GN~r5+x_Qot+?(Y?G{0EPc4s49ZG*& zNmtu5-L-K$ZBmD408jFgq6zoRLql}XwYjYtpq10rFXsSQmnOn+B~ zd&9W4ufXKQB|%tl)N(1xeM`x(stM$xlGU)eO+I*hu`z&imD+8Cf|iyK`g0Prr)@}B zrVib-5fguvdq8T;0C}<|$z7Nr_4&hd07M{CH&+-q9Iox1y0WPxjK3iX5^ZR{%X_D! z8`q7V7c6aLGaI1;ho@XLBq1BzGxEf@2pA%G#RPr?_d3LEM3peJ9}z*2q{b%+KY+CE zq!4kQ3_pTd|D`E>PxI0gK^?*rPOqOn)E2Byw>2R|NoP}0d+YFLW8A~9fPG9|Q;Biy zsDv4jWr=A!=KCNj@yIR)ErMS~{lUYZj`;@24%twt!i=DV=}M0<2#mW)aU2nccumz1^MRQkQ&nK){(2 zYu$zL&V{v@Vw?)uI1E=plOIy>N$N7ugsfwuU?$Vl)=FLAoU{(h(t)jSUhP2_q&5Xd zp@L36*s}=ZsXcJheXX>--5zP2#nv{+(Tc@zF|6Fgn}MFQ0io?9$?-6F0IaTT>9=43 zHz8t1NBcBy4CQ*G*n*xrmZ#qsDYj`!gK6gI`7hYptsok1M| z6qroKM#}o!`_^|tm=?L!nM|%$aQp?yAZ&`<>I3v0A@BM(fU|*|E}-+tSDW9XNq~3D#d)$szs~~F-LESM^+YKlDfjRP9k&&0Iee? zXBD<2=!y`vTZvmlkVODP?ps9#yms!oOF8j->#z}#Q$YC`=Eo{m5l3~AF$I*u!h8gj z2hm?bd##f&zd;B;$S}V_3_l2Yj?1CM!;0&?T1Tke_X)AoRkr})B7WVsFbrGNjxj7L z!a87>7?x2aP8?G>g5kFa!$<%;B&Zy*G!F|A3&YDsVc6peJHjQ|WG~MtRDx4!C;Tu{ z#uyXMsIWO)X=V{`|9_uN!M&+Oe(W0;{hzTYm*mrS*5Xer^2=4HMHm~5dSW7T7RREu zW>zMef_)JqM}MHDeKOHks1g_~;o7cneUJ253t}K=HMMmvMtW-!8KqE!GA(k3>yKbl zANc_%gx%UAv7v+L4g5fb>-BK`fv~cNN(dB(>yL%&Pk`+yX!RB1KIuQ~f$aU%FQv_Y z1e6TJw1u_+!__5JzUOqo(a07ei0aEu7{!^9-@5RSLQLE;4=)!}va#4zXoK?jC0r>X zJx=rx?1Pb`wLvsorpDNEzrt(`QKb?7PzPPo=68^?zfF=tZ{nq4km#%QcpKge>tL=R zTqlK|!-v-A{(S9IQs@~A;%l;eacA+&ZXp{MNx^X@wp)r3^BH*e1BmXc=2Q;feuGI zpcM;%!rdW-9-@srWJEY52>;RGJ*Az1EO=NS<2g3QbA&OU!yzZec=W=xf)wf^=;8JY zW&xljM6e1cNugii3E7VdnFlzVVr@X$oWu~bN2~3E%O7`X5dMBBtLKCpc=`ce8*qJ2 zkRIK%lpegd*Yq5KN(?uQw^z=ZAj?w96E4H-x zE+k{8t@gGDhKw5mapU^H8DnN3W?UT@G_DAoH7*Yf7?%eAW?URNZA=WDGR6n`jj@4~ zMq1!=BPGyhBn3WOVZ2JLI^B%{GY5!H=7?*ddbW&XAukni5OvNom>>Fyt7)#$QJU19 zXyT^YcC~e=w!IR%SdE=31AC*TfP-14P0q#?^WtB?tiah+^RTA7Ka+2))=zb@qhw)d zTjguL-s*~gY2Lt6U_xHXEHd@X>wqnco({o>Q)kLfYGdskP+H^M%il=a!j(ts=0hcY zfK<{STxRKx`b!Q%8$Av8O67q=hfpJj&Gawmo5wS?+K847h;il{QP@>q=2_!fFTkhEeu zl|ic1Jk67Xl9F4<`rZVWmM};L+>|H!Q)D3X`VcY5g|*p=*s>Ez!=CJ_DxO&LYZ0qCd}Ksm3wx?56TCmPfNy9hK9HW8NLsda$X z(a~HX^zVkY`X@+61QM3wG~2Yd$gOtEgJ4I= ztmHJVTZT?qaaA(C@+{u?dA#v~WFIya@cojok_cxowegKqVeC6>b2{Q#fUB&_A~99jR$XHqQOA za}J(Av5`$NvOx6$et;xBx)?OeZ~?nA+MKeZ7>!J7O3AOsG7fb>?CS;yKk`xu<8N(F z3};5j)V~0dfEXrNb869D^2J4KWvK`{$jgD)m+TI34P;9Gmfa9v8bf{XR#L!zd-G!Z z;(6^-<6nRx_hEj{TY9xsjor3st$e4d=gS^dzX-P6`dB%qObR`VbcNVRgtp_wx`IO8 zn`^wt0!hg=9OyFsM}J$fQm^hUHlD)CQDvQad`SH;uI^20cq@pM#-lrF*$#CnzVxo> zT3Y?|yJe^#XR3NSX?|0b;{MlL6?gE>;%F733u|M_Olt@>d}zJ~YuF+ycv2$xEn6|P zd$>u;L{>Sq;864;ya(S5GQ(LvaSLp~LPCFR28K)*v<~h!>Y4j@+$+Vk_TdMd;T1wS zJG?>+ugD3P@zVub7M<7zB`Np>=V)8q|LNUWt4(HSXwPbr`%O8ke*vWBX~nRcaqq6{ zg^#1zs*$I~0=aD;CFzgvCcA_TN*@*^E@UrCb)S>7wE_3v(B5S(GyGj4{9R}GyJC1| z_`5jV#>{-x`A>nq;y69?7HlTd7hB%E1)t!!uirU=xWw>`9+I?Aj=?xPJXy!D{sd}- z4U+qBQm7yJ_UlN%ZR*_U^6^RFL@7wiC_;%iEw-j`#!S3nSZrqp3bUw07-pROc7Kth zgM}fqOtTm^ zL9J}Qx?kT;aZ=+6AQ1LskG^c00Y?pQgT4oL>%P70#9js=wK=6IUl!-J*QFK}ZgP|wp9OE6rz|V2(NmEcIK&8{WaOTYCm%_A zijq!6QX05_FCE5|IPe}X0E!~CfjUIaVSp2I^mGE8-musb)W9`ES}wDY;zz}?@1Sgq zP%j0RNbMA`-=URex|3;mDNc8C3{R;s39*IqX|PC*WEv{HnDH2pR=K8devpv&V#a3r z#IxCYHqld=jF3jWc`51#Rum1d%8Du@GZE&+3k7;BE4)?uSkxuGm^=>w>Yi&*!!>w= zMQ8F{>v@CqoJ~*VD#Xmfo0pPYZ$;4{$4UB3*!R=U73CNU6Va$Gnc}^az-#=8n8hTo zw+e@?s;cxYNN$A$k^^bHjPJ8DR%lthz(z|PKiaY!_ksFLu@%_-8a6lXF6r?X>A7#? zrEofMF+bhl?yBo|@7wgbyKAFJDgOy6aE2LU0B2|EH|4%o9b_Au3aMbPJGqZ={jY5} z1=L2Lw!87Uwaxg9@ySkml~(JjkwQ%S;DPkmrQYjuXnjh0+lNWo4=A-UhP}?lt9BR% z+wVK{9UwEZ$n>_wlC;4|+e;YKw}O339&>6e{Hc6df5rCJ`&NVcuKB6-Pn zR^_;t=>z0=Z2s;AEGV2orEo%N`TGEm?E(?~O2gY6&STRyd@IISjkxc_tdQJc?mO3ugLPCK5H*VX&gI;<2F=3>_n)Q4t;j}t z4&f5cfj@Bt=fL-bJ;#XCHYOxkZy1TN5Uut^Vf`_A4Ve35yawXGt#U!P%h6aCMLtqE zDzv_^((N9QukZI{2y$^@eU8-lTU6{;ayDJcoA$*lkG`g#Zp9s8#v5= zn#N&17Ow4KFpnRGx!@=TVE^y_v-~`^Im(GIfChlK0v@kd5xia_g#%Ml<0DG$qhASpk?Q{YaA;ci0OSz=K?4iNCbMGqU<|i9Bbm!1ng8?T1>ih#3<+vI$VE0dd1P4d5ihy#AX(ewv#VlJUSE-+7$i?cXDe{bE%56~U zAviprevKu3cQIBW<@prXPeuQR@V|>cd|tylcn{ z$aJxY-mV7oDrc8*Ssv|Rv^fO*PS%9k+8io;Cxh}zZ4SY=lL2|LSAUxlKLB5JqR&Xz z<`7If=|>&1vz7Rlh{vEy#Zj#9J#U&-0nz6kq~oXQbo^9+ws7(ZN*P8iHL4>H6+tl68CCUIi%j8l~ zW6e2K2u?b@gX8{Vz2-Zp*2n9epqik5R4E;b6t`2tg4R30z_ydsf|fzUqA;rtzco8) zRLBz}vzJ6>|DN74T-+V&k_#&Y<#fckWL3l&VFRa)g~`~_bMuZPC?0+a7W!9!TANuV zG*x5nv+(ROrx@@4r3eO8u(F_(a)rN$2l%g|=k{&{n(u5shDQs%gBDCQ50C~`9@|2p z2uQA?5X&Zq>~gXpE1}ZJrp7v_fi*8p!FE}+)u&*8mu4hGi=7aY=wzsdIf{J+zqpLf z$(Ga6Rfq`{vBN%N!NB|I0HA45>nOmXUAxL>yv}+Uc(V=pVf5Hf>8g4 zKL)4RmNZXlwl|GyN?o$pJ-GIBz{1KdXl0;?u+OfC=ZO`NwqQ+RzN#K2s%1d|=)k)r z{`7BA6wY1(LZVhwNM@QM6?&YT(&~~?);g=K5!sIp8%x?=TP?~a_f3k+D^DQ(X}z-} zWk%`1QT1Khz@Nbbz;L8igleGx_B%=@c(w?R$v`|b{GEYs4HDXHH8w^&vtAIqMv^eA zDWx=IZrHb02p!$9CwPTz8ExmsHoKZ8Hi^rMA*+RXdM~wncP7n0Lis2F?_uo)faGup z*56KVXs^`xa{?Q_5^MMgw<>r?OkLdADi>NO-cD+%=Xpo$9QKa5IF4kOHJ*?s!sZCx z5!1-@$W-3G)yTjJHABR~GaNnoOaND$InV(%4WjFERUzGQe!jFWMTeO zj*j~gaf@;$(R{1Xzy7<8z6OoH)M_;RBC&o!qm68SbvoY0T9?^QGK7LdtjvPeC30Fp zYd95q^Ce0Q04t#cjLc&Q(fACkt5;jjLX;`~I7-&D@zc_S`H$@)bDC&UXcB&WT%kh} z1-f8x@6HFne7apYpVlfam~ZaKt;wy9j7F zL$ykcC-EBzt;Ck#t6Yw-aPD&C^e}?xTnNRh zx;x--#QZyOK-;UEkk^A0L_&9B3i*oMj1QfcFk(z3OIC$unahj0{0Pdm^wlZenSAtB|6&!(J~!M!SO;m zw^4A2qf%t3Txg+E+uhdVa5oVql~gTAwUfyp&%kAiI|=D-5f_)XiVNrav9Q#gR0k)l zovaS#ZOG=5ND>LRYr=mDNV=UwlkE+IyAZZ^e8b>AJb5aj;p^dTni3Fy!MM6gatAkx z2Ie zu(C$aKzg4$<};FtuEo`aPSjYVzxN9oCpCHl^&LDu#`Fz%bHscNrhs~U>mEdCjs9CC zr0s)*=P@}^y+t5P*Aj2FSovw zv?>%Fk6wvtYIOf^0n{Cka<1klOCipL-W=wrE334#x(BE91J_n*eYzWOz%*uy2fWWM zfq7MW96=0QKE++7|MK54hFcvK`qjU-Fzb`+{d3WBa8x_MCVBO4JZPA2NHWskR#0$v zz*4YJg<)4*Ld?0}u7(&BY z8oKpIjY)~&25%3dj!h4xLe-RK#&1w!thQIvvDj9M5DXd)s&{WeA+#s3?gWQc+6Yk_h|3=iCl ziAu@)iWIm#xcoER$`;s>G^NdH}Pb1zz4{V*5#pMN0e2Mn%Y`;3}+D2T9?Wf|~ z-f8ilgw3!yM-z6m%^236k_C1Hj-$4x>{+naoRB}5ei;*OTGLWKu4O5RhxS!{1IuSD zfpruhiKRR?e3GR!;llRZ_wB*NuLzF$bX{?egg(T;#4aHLZ4|+Z{iG~NEJnsUWK!Ol zG8my*L6TUWF@)csd;+h34ASe`cU<-T4Q4%_~E(&k^Fd}>) zBf|F;n_gKu5R~zleV~mQ6^=7pyHc+5pMWMeBfl-+vTvjFtVCirA^T9h1$?Q_pyd=a z#{!{8XV3}?y2=6_r_P|26r{7XM+MP<4vn;6tJWEd#AKnqmRl(Z=#WaJ-s;>39KfMg z3M`!qiU>`g9zK9!D7%ksK`;Y)(fArT1-KmqYxF*V$a`rYK&|bz4@fkm`M>YJ4M0%W zE?^C~@Yn?;1*?dT)Xai`GFY=MG$aq#X3(2dZRi3vLF?P5_)PsKC&1#K~ zgeenQiw-msw7~=V%ls2s?QvOwA1)KF0P&fgx@G_I8#egHbBRJqI1Wg)2T|*JS?v97 z_8xkjc@ja-=TQcES)m*jlEgl@re&pWdGB~rbS6oygPSkOLn*w_3#If5{Lst)+KT=D zgh?S8A?`p`7!u3D9M~?YD-NS&t!WfDiQ>^QBNn~~;n9`HZENB9-7p!5aMhuJezrd` z3z~yerLoY5^QY5^-N9h&EQ-6V-5v+)bvr^(fv3$4oq8Ocx@JeqjKTXtZ3nJ~F!F*N zs>rS$v-84nAa+~RP|vIA&KI0MMpbO6ieRMup^%A)7ezI(hX@}LHmOknOaRovaakQR zfqq#l0kCjf$A#n#3kgl5(Cq`T`=K)=)2DAZ0+C-KPCCrS)Pnvd#N^Q7-04?^-v;mM zm;mfRF{rhn(cytJ5sNm;B4r_dBNDcQ*fNZpNJs-?C`C-4x?%_XRfbF2b_o|`WmOpl z`%j6FZ^!Ivvk;4H-^s$ltinQjabY2}Ce+Xs51K-Paz=2|gW{B#09A?+g@rT7!p}&= z3crix`vTg82Cv1aEp3?%$q*cr6pE;NJ41!U`J7_Khn?f zF}t(cf-{2ID27dE=!YB+^`3#VP-~y1B`XCiS3706i!=e4ibknqg9gOZ46?#nGj8W~iEVI6?u zBnu7r!ne(owbiHKoTQKm+u|dI(e3JmZ7EN+!18U&q?D#5I7#U5R}+U`X`AqrESQDV z;i9Kxp`DdC(>jUuIR%vgRa@CcWGc73F_8)ag8-VI1t|ucWk}jeeY&%7`d>L5?F%JK zFIcijUoR)IWkE{mEHJ2Ed#yM}DW91mm$QWz$3jY=sSQm)*we~ljZ9rh_#V^*w%H&p zfizljPPh3|+O7i=Ff2IQQx-NYxf$0yYGCwNQa3F4Pz|{4W!KHhYN%E zi0S9B;7F&;K(EN!u4v01W^cy7tvH=1n_% z!*H^m46<#Lg}#9X@tC;nCvn_fH1kjd{q>1WyZGg&*jfLVLpdTJKll~UI`K4Bl8uD+ z6wxd!%d{m9*+RtEWhwzixn&9Ogo4|@NNW2~w6%;;kXS700hRb*CHP#nDVofRuwN@} zGnxH+|0PX9+zRZwk^--0f%t&s2PBXMKf`Vol=hx5F2C&G ztyJ2{htiQ_ac~BP5gGXoyozy=gyT_(3{EgG-#mK{bfqNr8ZCe@&#`z38HYDi4=&UWGjMX!tY8E1|q)- z+%)jxdT;X&#(0MXqLFD}2Yv$<*#sDV{-*6fC>uj*HogEGQP{qYeTVjax$j`_z5ee` z9K(Ur%8`Q+V**%FpC|0|USLAJ2AQ{~32_(3O$84KP1=zLtRVgsQdFrpmLV$+=njSL zzD&ZR7&@cZ7?152XZQ<4Uy#sC&+;bEX>6ibaJut|rv%u3hr<_`j z1re&0bPDz;NIx7s@n@B6eXbw4Yq$XeyNi0PB)~$r35C9gMwDzNRZ!_;E&G_df&*E& zJBcFT1>1oEren)MqJbgs0~S_@Bq7-yV3;$EWY;924t~OdTXKhOphSd_he|TlPFX~F zAm!fiAg#>;XE2%eNCyLYkxR<2NFz5Z$71)o13?&IQL$4# zM8VMlavCC{{_N&6MDSP&{sjSe(-G24CJMV59Ykb0Q{QfZ?GkpQD0G#NrLHK(H}HD( zAY=`4!P~S=KHf6AikPezOkCTm!r0d7apF!FC;NXe?QXy+>(i~b$`L`fnzG3$FTIcIet&2NGH47# zKrjgd4dX?up)AW1MhfpY#X%C=ijliA4fSZbmf8?mpjtpINwv|3X-#lSrM*`KyMiQWNPE}XvTR+_v&bq^F+;Awv`h9C6*eyG^_G7<^;G^%{+Lzu-=4Zi5E9*b>np9~9m;0y{ z3=(KV84-oByM_G_j5xshps4rXH53NXpxMR<_U08yM?lCyH0b@VHTT=E7#ox6r(w13XCc{zNI5w9o+Z%LEg% zB&a&1pBtCDW~V8MObU`^`n!-z>3w8n5I5Qs;RwBOk-?&eSLhqmy-qta!5SID&|q3g z8k_SIgITwO&#+reD16wW7t{Fr<5RlyiDmLqi+&7b?G`Eks1ul07JL)+M(tJ}FI|$; zWa9)YGys%g^)v0}XM%6tNxKUK_HLV)n8yT$p`$S0Ob27Zcdr58fy6n2Ii$fPZ%KS6 zq+EH(zj)>GrST^|Xit0^LmrE2FiVP;x*`h$f%fMqPc&6Nk;t)@HZ4uzggmOsH@DC- zV-H@tmhm%CB_R{x#lgX=5wNRt3~t#-$UPb0xvUe1h8{X`V8lVJL<5)HN0i_J`=i{&v{?3*Lv#A9Rrth?|?H5o%JI$l(%vLa1HnP`yPKe%P%t|ohD=o^H<@( z{Dijcb4TnNvs1{JBn+P)yn)5$d9 z@}`r#0AZRO`Z_1G{C{on9}NwJJs>27+H}M)5X_Sw{R@Zrvz0?jM!do<-7xLBUIVVu ztHPDAZE-Qq)FF*v#uG?5b)_3a3<~fpA01u@0-;RIywDYh0$eH#!4tHC(986Sa6yMv zj89A_s^dv&Jd{OV2;jMLHz=n*X&4SC_KnCN0JyQ+yl}%$^77a59q>3Fcl;&r<9nZg zNkbV6l!cNvr3pRQds@)(HAcZf-1KAm@LYRvE3P|$T^>4)1iM$vNDp@T0gPzUyA%3h zcuQOUp?IYuHIbcv>c=#kc6YpkdJw7E1AUVf>P4G>>LwZ3P>WG^Db8h-wjFDGH6>0o z4ceUBJK8#Ez}b5ePHQCk7r_+20A@qH;D!};FroekApy8>Ox}6af5CEQe6R_n3Hc#g zz}X**67(Z+p&(xeQW$J_6?FqD3tdEp z0x-f8NhKDz8&X|r1Rd9!%9sSx?&}68TiCK=i{b}8q6*zUXfR{4%eEP-E^3Q zRS6SA`%|~*a9%j0?Q5{Tejek;bws*}P=}QANWqnJ!BJucy`_s<>YENHB5|Mg#Jk#O z=e%@Dw1>$Y-gdRu=T$;hiF_;b#C7yq$t||rFcLsQ)twU0`yqdb@o8vc%f{066uZbJK z;*iiUb;~i>)b0JcAwLC&n8$}hy;p*uB42#l4#e=k9AOpZ%K`?IKOs8=`&((nxELY7 zwJ&Z~1o5a3{9qDPBsA#_=6^Om3mKt{vxz>%q8=SQDD))=Ng>Er#03s0}c(;9oD=oyDXCY8c+07Y1vp`{~NSl6~N-_n11#bixmN zxm$4hqN*i#KUxWO0EqKia^EU#k>lWMDYhLa+9xHp7s(Ts>2Rs!k97L)i^%PX?dFrM z6B9S3`DHj?*0Uu()FUvQYf291WH;?dG<~q-b!4Fm;{X>YWFQySewwjOKPN0rY=b`E z{DfJi155i*5?OdWt&O2ifLVze0HSMQdLiHquE)Jbeq4A;YX)%O{5aCu{*FmWS1|-A zqPnpEEnJ2$8MFZ?C_)_r|AD?G)KLT`A`o9m@LKdX2(C5_AxQtF^C7kWG(4~w9+Lbs z&kA_x<(<$Vq)NoGMDnyOO@opi>O^J-gW-43QEYpFSwiA@XkWz7#kHXc7(Qui$)4JR zvfG#Rj0=5P65QJk4|diox3$EE(Mm|lAgCJD))VP;c8CmvgIGF}!hVT( zZF2^YHZ+fgCan$KL1quzz>r8?xeclFI{uE|4J0}RMba;L(Pu>XF?-ahD@Zi}bmL%Q zMBB;M)W9i=07coY%}{)qoe;;;l(wb}ZZ{8JvDg1m+m8u51Go+H3L0+0h`^$FqyOT- zq6CZoLUf8f7@%}ZdM1hK5_X67x8bswgkARF*Q;3522j&dSI!`^4R~D}+;KA&1(*jG z$170~qHY8AExM#*2c9@nRDB~7;F1mK?j}x0jbp{dQpd>MgwHWn`pClFzO z%^o~@6N{B_bXO0)<9iTtfE9^2G2MwuY?BLCs-T_KH(@6-cq=4omixC^53=fkLm_K`TB@CK7ln309S_wkPPHft#;78Ve=4=oJJzMx#lEca?mFmT^L7<&A~2QXk1jvRNT zOvH)I^wcRe#AV}=8l~e@U*sMiNf1Jt^G@2AUWnOT+1t2sNc|g~CHPo$iDVr_=4Q;dHVC6iz2ah;TX? z9tx+^#UkN!x@aVvevtjrO#|U{x_Ka+{wez*y{LQAraq}}%;)}N*?%Dff@NbyM;_g_OSi>{z!E2H+6PReUM$Q5zM*=RZ z8O;Lpk$}E6gIT~RDFCKV-^gm)y*-%FbXec}B)#=$LOEn0lJR;f<4MgC`tT(+vsudi zm_AgPzdtlJs3GH+a?cR`+<5;$GF3qHluazczEwz$6U+9X1DLtADL5~b6nw5X_GP(; z+gGj!J|#}#MgR%>5m-PW4)lW<#x*lpSr1Yol$E*y@DMd|+E?BU)(h~;0knWA?Sbp+ zEDlbDN^R|Oi_>(}@qBk)EbJ`UuVLRx9n?mTD&Rgr1+mboc#P!SKoUIpPC z+}V8qiySf)b7VJlNSD7A2aN$53`wQlSvb%;TSzpI^H0a^Ez)aV>(qqyyaeTb<0~NX zPt6v32TqNHcGRS}tk4lX7y()M8Quyx12m5CSw^3syYv-;lk`wOqT5Zx)s;42ow}F8 zu;ak^0U>eZ&!PB~IO6YM=e&sxfG)kvj{T@NrUt1;7uUoGuoeL|1mB@uIb(X^7GAoM zmdu)@6$fdI(q+AWe~zHYZX}_J*>ptC)G@*M=}+2c!T3KQeeP+TQ#{$e^dy)-_TVf~ zcx>{Jx_VXHqycT3&8SS(^6j-ft6K8kL{M5)Hs1E*4e-r>2TvKE2k`{V^WUq23EC#- z2k3*`_r+oMrk%teq7`bA1Bmy`JRuG8W)xHs`~;L0O~0kcX2Ab}(gbyT?%{4F2@obx z*>v|GvFQeU2$*7^KFaFB7SS{B;*;*iAr&(keFL8pqt0z#d6EWs4YT+&aH|+Psg;FF z<3(m%c?xlaOfanNyK-fg;2IE@U{k;Xb}uORvkd4`)LpsBFt0%i0*FbhcRx&a{d%odIQ+iEGX*6}HHGg=;`0;+>QmT6+!eLj#lgWZ@l$j#4;(AJ{|-J-Od z?dsuR_uMt5(>lY=FQ0|`El4Z;dzx1??0SiM@O}J!L1F!P9b1otp3Rr!gbu={3|PJF zdL>c)3~&^u@HWgE>`kCKeUaVMA62XTnG< zWnd=mOkMd9x>qFE7>P#5XK_-r;{?Vr)+nIJ9vmO)6?siV`;flnf|jXiXQR)SxqQpq zVYsrwpVTsUKxhk;VG8ZgS1l}T;|jxSJ#<{fvHKBt3&6#pHORL;_fd)i^xGqXhVe`k zb8q8VvX?~Yb?N{mfkZFun1&&7JonK!L55?mJx0cbdeC!AoQO$q{H$}yB!eJbb3C$S zrXm!J%Mp+UY}Nddmd+skd`>?f)6ZdhFl(Qt&K*&T~ScSOnSTkF3g10*+@F zaTh|7%aLEo|1jn*t(0?~04?B8Hq6;9u8~)Zg*?$&h`=zCh!Mp$2-aWAyh+SFFtuj@ zt7BX4n=O|B@GW!GItJ2uxb$>KA3UQ50HlT3k6;y7oOU`TO z8O(05MI%cO4Q34X^TeDG6_c$tDNQ0f3-cSQULupO2#oB~(hj0*FkUe7CgB`3OxtDC ziJMt35)+&_U0`x$lc9T27nzj%i%1|#_@oBcYv-O81#yMAq12BXY(+s`5;O3@V^a8g zA`}1V(1kP`_M*R-7eBc_ZU0=Ba1_`Axrc~v*2-kZfse4Lr}>i+zt(;Q62M!RYUwx`jot2j9h51$oo-brzJ}BC8;JcZsU$aVHab-25GfJ}MKay;I;qz9$5%k(&5pnhf?blinL&~Z;R_7##yHD({&APnG06Oyu#8~ym7Y>g{BF0!4)a}57> z`_aFV_A^?OKY#mqGk<3LCHx?aqot9w4I9!KclpxPEqjkI7n_-qMIXc~M|x(3{*FE) zDj1vtjMOd`3&vLoj=JI)+)`P4(t4c1fN^qMS@=Y_Eu6ef$iz|B)=?AnFA3j{%{C7i zvN!M%AHO{@`^LlFy!yk!{vq3jg|Yh#skhR2z|F*zeiWs@bfW&C@GY25w_~dSY1m7N z!FJj-yp*WlDZDpyThqZX4#I1eT9dL2@6CFvAhG@E=klkSc(!+mI*Ldt2 zqoCII?gW}6f)TsL2(=j4nZ@Rfy?Ks|Mm&heOmWVJ`bn|a_s&`MOqPWvUBlx*X1K~_ zIHvaXFrtnNQw}s>TD0v!ATJinFv3lUuq?G}x_9_!l@-gM9xS;QX-Ydt4IJ~D@lt$YFatVVVC6-`OEa4e#{)Idb$$!l2J&;kLfN_fq%3vI zp5qg)iVFxA5V`=eXr9vx79n~CoV_>z5fy9ChkaVe_7bLJR?9G_*_hsh5ft3ajvvsN zeux&89yGB-eP|WI^gd1EmhBNf9~xAQ)9}(CSrUfsV?0Jq&+(~`B#sOn12?3#2mHx- zsrMz0^c{oT0}BMuS~#8UZqsS?52q995l$xtL^z#T9N~1@3x?Baml95=JySTHHe}$m zv0uV?;Iy${qNu=WW52YVgVV--38$YqU%F;a>@5a?7zAPvh(RC*ffxj05Qsq_27wp^ zVi1TyAO?XL1Y!_~K_CW!7zAPvh(RC*ffxj05Qsq_27wp^Vi1TyAO?XL1Y!_~K_CW! z7zAPvh(RC*ffxj05Qsq_27wp^Vi1TyAO?XL1Y!_~K_CW!|5ga#%uwtv27wp^Vi1Ty zAO?XL1Y!_~K_CW!7zAPvh(RC*ffxk-Qz0Kc#Ye8qX?^S4c$1 zG&r3L$X-q*>M2KfjmPgDOYvN8ZZw`g)I)@}n2)2{gHZ90@~!j3w+YEQs7~Ksvhy!vr^z@!(RtKd%}MQ{1x!CC;V^0?}VQ{;ZH-k$Xs4#tuD(in^0C$R#)a5$rVI<5QUpsmRr_nq6dCB!B}VX zm1WbDe&JkYi@4Hp?s52xpK*xF-u+x-Mt;VGk(@doKcyM@$eP|V3M_cdD1ghzw;%vN zMf6Sq6d%6Qj7p?~E3n{)Je5Vrt|Vh7*H{8)Dd94_%*%d}+>2m1yp>pHa&YvLWtD#1Wj8%EYYNN|o z>z?W{)*HRX0-sRiUs!BhWGpo3F_<8W}iTYj*|7%g-UGTpZ^}QDUV3eOQ;?XGoRQOLurDvFG zTvvPQ@m&_>_rgB_{>WbeUWP^aeejPw!#_64Pnbd-G@h&RETV6C9)z2T_cRrraI^8g3D57~=HY#`dOTMT_XJ!e{HO7(!IRe@F5E`A zTKJFRDc9l~+@o-(;p!2drNaePc&@^85uO|IJPMbk#|4IPFTo8k;6_D?i)S-j0PkDz zJPfx2@2BznPyZWRG@et#nc=3u+2LlwMgFL-;>1=&-J zO2_hohZky`ymOJ@bPIgF(_7~f1ZO2*-pJQF8ZwhhJ$}%)jl9=c30lDGD)$RcWLED& zZk{Tn?J6S~HE?=ab^`K|zB~DeQ)loKoo=VsQOn!?<+ZK~eu}HY>GnA@lk+@YzRrXC zyWAk@>R1DKN4du@P(D5<%0_j(zOlRyt)-e)xoVxf+fj!)=1jAfPM$iE+S=fyYP+f0 zU0~xK?n>V7@YnLWjP^bo?EiL1S}Dd@Tzo=eQjeapUdg>v`dpBj*0*2(0RsnJIQXI= zLx){_$))`8%SMb$zkJl_E3O%yaMZDb&YHOg4#N_ zr~X>6Pw+2nSk$<9*6cZR%jTW``*ll}F1tRk{D!6#D{s81xuvyjRr~L5UVY20x2^g8 z+S~8A^AC63z3!eruHSI)eH-t8;K5A~J^aX{e|qfkC!YNCQ=6aO^32v}|MJ)8o`2!R zZ6AI7$)}%v{zb6k%g~XpzW(RYZ@xYD-S@{&oILfzq4)ps!H0*>|NY0)Fv9xp052H} zJ+1YbnVDR^tHSH?VF2^RE}tKRBWKJQzQFIMJq$)jx!2)sq%ua^y-uHxFK`N&4j8YM z&T@Y>8w-y5dW8bG7VbX}jBU3S%kHZd+Dvb0-p30x% zay#iQ4L0HIXm*>_|ba% z%$_n%CzqGlv76(0+RAaVc{TI!2ZF4A5&mR|fxVtghKCIQ$cw#|oAYzE_{TuZjV2t5 z*U7cD&T4dJc_Yw-&v~ui>8@}h{sfoTSs{4Pfo_k$JL~F&MlR3qt{^D0AXi;|t&_ls z4I%!fdiYvT#R4DiScvvhUyAT!AOl{-S2xjH1x_EjvBHT#;i#k(NZ@f*vP|&JUkf}! zu^rxOss=Z~Q|EBGd8gOwA@YeE@AWJI+NgKcJGml61W!{e@P6mgEP z(I+_TkY=)bp`+GSNf>DX<$=2T>K&*TL$siW*mKB~8)_WbQuEWxij36?EXSyS zBrmCIoqkp~!uUcPz-}cEJ_;-T5AOk>6S3tSqYW z=XqU);EHhERStKavpnD7&93+6I~uR@yRY)sX8WrPo%PcygsGl|6TtMqUl9mw%Foh} z&1J*U`!{%g4>!>%OaTuf8xwG$)9$JFV{?Hp(O=?nS9%(_e8AjM?Hun}l+6J%dR5BI zN@~1ULeZ@9Jje9`LNA&!t*}sR4tcpktjkeeZo;(u?8#HRLJG8UrM^#c2K6~6H=%Wx z+ael(&hr9&F(i6s{PV*_N(4I6fhzP#c9gq`D68#U zCW)?dxx2$z&f0U%{&BhiL64izI`TtZ<*YsDj2ppTKGt}Ot0Xv8)p}5zyPB`}xImy% zQiK4(OE8kgVlE-{;mOJNs5Nvp#-TmCXc8VATPW#CizhwH*;GP!9b0cQDKh?Oj;van z&8>!`_aEsAmpN`WXS-626Z?%pAO?XL1Y!_~K_CW!7zAPvh(RC*ffxk-w?V+8%;u)w zmHof1TCw`XAn-p1fdQ)6eE1&&eyrda1pb#nVB3H!&LzonA{8Yj_I?fs*3Y5 znHa*H3!NmaV&WLELg~BPRm-{kb>&XT<;hQSf#TeP!pYO7mgP*FT2wG?3ODl10E&2y zzjPlHIYPcj8V(!>Ke=>hwswY5IPpUxe}qLz%fe1NTg0Aaf)4=B?<1eR7Gl(NAEdkx z1~9#@s5m4aVDcqIhYSsh0^t5bW=rBbQS-nDWrcE2Wg}0@Vqle%T7g)%98VpzT%$6h zv=E|0$S)uY4@i;Vl@$!V2sdIHp#spol4JRX8W#z_JWe0uC_~AB$->UeCYj4|xJLnvJG%qPJ6^$67McX<6|Qs#DoEewKR<&#~+#XxEbY?Iicm{PP+6!qGlap8Z7n7PC z=@bDkK^Td5S2d(C&J2uM!N~;82ovQpEFFe1-Q5eG%O@d6PD)3@|Fg$&ZUz$eb{c2$woR+>kVXNDxH=9umU;*~pmP_d|UW=IY8 z`KwsFDKFApuJkr$Ku$>M%RMN&98x3F=BRPjQuQQwWw@#`ATDOpkJ^+Wg0XurSMTu= zNKtMAgA^KQ-idKZAPG&6MF=LX zC59Fw`PEWRXZ0h`Pi9?9=!n!Mm=Zxnjl*3Hyj1QKpxh4C1csYPlZlN73E*K>10rcpi!~P=XMlhWr}P zY`y}iNO;P$-#kz#AZWUs4Xop_1~m{0rQBHkT)aKIC}&dM)sLnYS}t)a34- zSo{!`jM7cur)KAiO(B(Ri|EV8nH9dy3AGputf~x*YIg=(ZN*AS>o~=Yz=dUTHtyp2 z0*23cDIr5>Qa=Lr49oG3DvZ$1rAX|zYY4g$zTkN_wSa_})?havj3vb?Kg7<}(5iqM zCR7o8{EVU;e)PorqASF_iXwS2-7$WOYk{-D<%8Zl4%7K zcs{xnOv^Ar(MXZeu|PgNMV8>g^CJC6K_cx3#S^sFQ46gxpu5N;!%>SR5Q>ZyV|nPV zIO?Uj$nz5<@&)vSfL?*x4bSrlkEkOCI6_8@OBbt=d$sFh)+N%Oy$ z7eRzpNzIO|Ru<{Q3?vd?&wxuN*Gmis=$%lRz!)7RQr)A*@}na3HQou}5%PN!H3Bdk z&)W-f^Cr(EaEhy-B@$rwI-$M=-BU3Fk+)*s5Fo{2g-npJG!lh%Nw+2SH)a-Dh_Q4b zzr}pvj6A7M;*xBM1Y`rpp-PhXJXNARsv~PCXb^D)g<_C|D%r>^$bqJhP?1T!LTfXr z5ScL37Epj2>VFh~_T{^L6&U{xx0CixohXpX5a2KXi0TH$UI03pXMIX5xrz5Jz=B;4 z=K^YFZc(m@A$9az0lN6-bN z@CXW6RB+}SDBE%;LvA2Rkb{_qL_YyJc*IRc1t}t-WRW~T$)Z*wpf#UVUZGS7?U)8y zJsUiJEO9lorqK!{=ErC#p3m{HTF|;eQ`J7L5aZV;032A1DKhF`$xoQf*3?eg)xrXD z7-7QFQLROM9MS4Th7_sF1r=r~pA3=aqxAu6B0-##w4vez?IJ*fmp<2dDn;C~P=X!p z-#TFznXm-CNWMfvc1B?PAqvTaP9Zc2q5bQxW-Fi>FB#QtKj=|ctuG62nI3PoHIwUx zSXiMd7eE%FZRTZ=P`g_HB`Q*z73XXji!!(Jv%CPb6s zoxR~6DQ0lihcg4twO60or8ilJC00~^CLL&rVBu?^J3L$>d8j+E5J;p9ZLzr-ogqi5X0b4C}VNPN=Nt6^*;!VeC0X8KoodVM~8;)~)9tA<}$|hEFHv206f>stQXc?XaQl>P+`t!BMSgPGZHAU>(KC z0J9@Gxd4;>{4p@?d2|i+f}`32(hr;u0t5qSW(7wegqJG>YOAMM;s*vR5gTDbOSBTm zbRX?3BJ&SNEzp11Gg3OXf~5QCTwNY5CTN4ihd7JUBI*Y^yrNbhN}}uVD51#rT~xLiaS{9-V+o83MD^)ziq4iizyu={wVdWtzgY#&^Yt?03N* zVBIhF8Ah1|e7q4b(QfL{Opv?;SAxIK!5|bx1a}rI@nC+rTxxU%cnzI=BSMk$Krew0 zC@o(EYfm|8Y6@8L=(qrV$FfUNB=VoZPFn9px`0x#-ifqdLgJVdkv?u@t-*f2YiG&M z6^W~+gnX!ea1uXB+*z=3zp|>@o0XqAwu;MxpX2q z$Ld4*AUx`1Kv!IeenGrxB9>sC#ikyS<%o!GqwIh6JAWnqkPjM{LH)*_c%k5^Kjg&1 zcsa{ed>3bUt3s3AY8g!H`FZKl%0URwWciOt}nqY92jMX%s3s5Z}d z_zg6#0cR0Ebzh1I{=i}$FWAheC;`SdT$)4@H3jZ;wZn_O7mZt2tp!c1t)d5YUQxas zv=4i7MY;KQ%5R)d$M{_7zH#;G6*Ji%h1V^h6_MUze=!KeAP|FqC|6qwKtyC~(i%^z z7O^`c8zr`HVjFNlXe5$}ZGGx%9Rh7Ek-myBIGzn-%A;i^V1+wz02q;?h^%wSR2T}4 ziqe^1)Q8BT$qwIDV#7-KZ&F2(3wS2N6s)jKm;N`QEhh>WCv zw45^ennT)sV1*)144uSmY@iof|ECcbh)^&x;u}EMR?&H9+D1}QVhtnwaR)X+Op3wy zg^=HNs2O1%p6L{z-d|(RQ{W0{kFK1aA$QrXyeC_+!f?(%Yk%q=M}ZI$@VnAjv3L z6UB%k{nsUvL{TCDu>WE(5Z73?IN6py%4#mkPVVT=ex76JPCO+eK8q zYY;FMh)6%xmr?d+mPMUoQMY=WT?bZBS5AOoRGfJjyQ9u5M?Mzkupv-!2smqq_|w3m zsRWM+9WxKWh>mXp-_Hq7eKheLl^w>BUpxs<8`6I#MjJ4%xGw~1B&HLE31AXqr$XnAiBXDUsZOuU z2VBb5I44i@o>hPe2mNF!0E+?eC>{L=;6~>;d=>0eB4H=+VQ3)YKbAd;cs_K`c*G9x zi~>(|RAhWg@huiMQ1Nxi5|$2mSS(bLvT`T3^rQpREe-NLD-8=fBTWQ{68y#O9Nw-> z<}kn{Ki)8BY5YWu^>fb2&OClSZntqg&pfJ=g%$Oo6Is)^`jxVylEGdPn;j9RSk$Me z96Q_huh!N2>vbibnsgSvi>FImTalum;WQk@a=-!D!qYCktH0~Z*eqak3>qBbWXr*3 z7jbY%m#9D>yff!4Lus9BR}=z?YP=XH`dfPDmEBn+XT?Un7)jFweatoVJyAG(ovX4E z6B?+QGDU+TW46AGDm+U*hwaTRY;PXIJWxLBYq5;T8BE z`-?%~--UoArstR>9htDFB&Mf4iB=OO^&|&@`T*7%8k3j7&4Xiu7thEa%shs3u;?%b zyGWdoaM4l8EF4I57UshFcu-O}L@u3F8TkItOJdANiP;ZAixvSfE>wERgp8Cm5n;p= z|FtxveHKYWb^qnOy2~91H$~!~JD;<8YmxY8YVKu@LtS$U#}N;c>LI=p?(6h(g*jaj zBHfFfVF-pB&~u#%@~jHc@zX2*#rVjb^n75!h^bjb zwCf}FAjDeXsdi&lUDE><&vY&MyKpI#0^*Tos7a|F_ifOq~aG?|;i*pm97ahn{gX_#%I4 zk(aJ#JYJ)tbbS%u=sUUCUkn1j6#`ez9nX=&3Ut=L(XeVK{yY2I*&&l)SMQhpt>Di7 z*FFAnuIpbM_uKwO=Wqkp^)DVX;kW#Yr00Jt!2U0eN4SM_%A#=$s1niiqhxoHcE*ew zLri^9w#~?iO?_Z<7j8XV^k3(r~8%+%~wo;VAAZJOz4( zn*wKslf&_FDR30$DC$Pf_wn2V_bA*QZ~-_9AA@=aAg?AE9sMR8wil9C+`s>4hsE{( z%HKQ(U=GLN8EJYU1JKc4IH9E@iTo)_Vn zh361FWq1z7^UeMk7kF;MliF|xoW!gUOcI;)DDUtfTKDum!3D^ zN#C2`==%yd%I6liE8y;t{2TD3`fh}y@*aevc+bF5{a%No@9)CV_rU-P!ACv_^AC=P z8w>}yZlmw?cQM`x-t@ON>b)KB1WWq+UDW%{QSYmx-ci@i__s#A-xl>w{Y(8sZC?e) zC*4Lvsq@e9U^aIy7l{xTpUA4T5gE<9q49>{(uW5=6kj&nFFu$5@h}ZFE^AqUJvSl# z_WRzuj~73m^}GCMF(^xVKK&cxXG`(7ApRToetPc^?z4M?_s%+h{>wJ76w}cG)8Cu> z9?zA%H~&55+3^n?{NV5@j#Dg))J%**eH;6WK_CW!7zAPvh(RC*ffxj05cto9!06Ro z6y1>9SdmSzacM?vvCY~DtHyX|e zHwA7s+l zI}Vq&7UjW>hnosF7j8b>61d;N-2t}|?ghBl;68>s373p^kA_pjO@XU|TL{+-cMsg7 zaJ%3>fIAL%!5#73FgPRJRd93Ryl^+d{dfGu`r?02Uo6FK3N8Uw)ak+n?wgyPU$1k8jx$NeKNAM$C6p3T+Mw;~)Qy9T1!$z2C%Ic^SpDP%Wt(06Vq%Y}sW z%*(yPYAIflG6gCqxIU0#6pQA8aF1bpp;Mqj>||En33fsqg-n7xx7L}%j!ba{tPG)2 z4CJ_hf|uJLUxNEgNNc9ZlTViY$Kz@h?qM#k*6*vKvc|*o z3Yx`npT>25FY-hZafM<%$z~GO8}Kjg9s-ujP{`1sbs#l#aC`xzz^obEi*ZwO@*VZ0 zne47c+HKK(q|7F$;Z!jliOUhZwPF@t&Prv_n8}td2H|$ZO@ZBh=~^G;)Q4hFA=v^l zr)#Br2>nz140jFdgv#7S6;3ADLnPKif942axm|Y(h_ynpr_S@GgzG`2oSlS|ojV*Y z8W&$6)Xs1>K);Y%Lai(88UZh|QDvv@28T-&1Ky~kk_*mKRXA^E(Mi0EjORu z%PH5WIu%QH9kMw!Cyo&Y7Opp|Bc@{xj!1XTzt`hS94;Zx<1Ivw)H(?&UzN0;)P0-17Lv)wvM(Y&1iMnaJV%;T%QHBQ$PZ*vyykx#>pJZKk_S8%z(Iwwd;r-Y|V+>TT|C9&R3Mo@ln4i_K-`DznerXkKQ% z(|nKlS@Yk_Z=1g|e{1F}y)3Dg3oV%zoyBUgTLxM$v0iS~SZ!9jwan_WUTY0lTdixX zf3U8%K56~P`i1qhb%5<++bEmdX0h3A*V&qEEw;OD8*C5SHruw_-mx9E{b=KOjyr;O zT`V6Vm&^0yRr1C1+vMBjhvXr7vO=w}DC~-2MU7&iBA{qi+^%>=@w(zY#l^}g%CA(% zRAJQv>etnrW~^qO#-&-TY1XXKtkc}5c}nw~=4H*RnnRjTG##2#ny{vic8J!XE!NJ{ zR%z?CjoOXcC$)RDA83zgd+5H`U8-NJ-=_am-^(z-Fw`*IkYUgnvJAO~8HQN~hoRcg zWVqR|(eNk3X2V|%uNbZ}K4Ls#{N8xlm|*H>8fmha@=Y^M6{c%VHv_Iuo8C0NZ~Daa zrRgV=%zT0QaQVdo8 zPPtk6j`F1PGF2aqQRC6vsTrc1s$Zpl*zlyG&L|kuOh(g2^XumQmLAq|){kv;@g>QW zQvk(3$X}8lm-C8gioJ?sihar?)i~Arsw8!`I#)eeov)s*o}n&P&rv(nPPI#2r@mJ0 zS2wDcs+X%*s$10U>RZ&mSKp~#r{18xU;U8!PwFStPph9*Kd-(}GgNaa3BKn+<{t+c zwY<0dB02TkSh-Q2C7&#>kUu1U4yC^?KOpar$1D0O1}TgRn_`NhKru^Erl?Z*6pe}- z6gMh3Pby}6C)}uw!(Grh(k-Ay^l=@xu=jxuCG|ec@1WkpeL35+# z_nId)uWJ&tyjG<(Yp0>_*J$t6{zxI@UFdnk4dDar^9BY+zfz@YiwBBHCvEFQb z!1`zFHtXxwzhiFxVC`iaX1mg+u}!cQ+8nkT+d^Bw)@)mg`T4l*FSfn5gSO9YA=^)+ zL|e~sOVHoc+au&-p{!KaDjSv8D_fK| zD{oicjh=r>xlOrC`I_=A<=>Sd$&+OH={X3RSaem1?zWjp`27-KzDfjjB_sICT&8 zMe5;dwYor^qA9=(dsZ_*dztoD?K+H(&oM4+x;u5x=w8ts(hb(@^;hfX=v(x+>tE3C z(eKm$L;r>TD8@mYVWy$XP;c-X?lo*Od|>$0kYMa()Edo3uW^y_4&yz>KN+_h-!O)Z z|1=&mo-qDsoP|FB+%yiDc7ypL^B~K3%L|q-EhDV6tn;kvtoK@78kDz#l*qF$^{ z)%>7M(_OB!VpO-I4R7fFq5DMljqZdlNuR7ohO5OsrQBRfpK_`4Cgm;4yOcYX|G;b; zuF7R_tXJIxsNJi2R`sH4x9T0$_o^RN3F@KhQR?yPslXoB0aN@@y$QHsr~07!OLdZF zAaKNR&1j8XGZPruqgkYB(cG-LL-T-UGjQ?_%`2MynlCi})Wm6fYSXkAX-8+HRomUrN z^YtFxle!n#jQvFSrS6ojhdxz*p*|gbc9njney+Yszd*lC->hGwzfb>X{d4-4(0?DI z|GwAXU|3~Xi@AHR;SsEwTMaK7{$_X^>*fsO9Q58Y%-}oGcc-yJ4gwyxnkSfD=H=#_ z%#WIPn~#|FmKsaDUq^()!V?3 zebfrgbWI)B!{eG1?eiD~pXh?XXqW28=$Gp6)Zedv2C#S&W4OOzm|+|++I(Y^@j>Gj z$@(8`6D>n&}TyDg7d-o~naq3u#zx-G+|vYBjIwgTHMTZOIO=EwTp zZoAF)kd1o+?E}8h%1!dAa*w=0zEs{M-zndVRpFrgpYosNJrpU5e!vmDB2Q7IxCZOO z0>vW5GQ|o-yW%#*dd2;UKPx^{9Kq^!QZYiQ1&*jxE>JF0-m2W7d{Ftg@&)Bfzzq8_ z`oBuom{(6kQ4f==m zKj?b`)>j**gQ}=EEHqqiSYcRgxYO_;MqkkIwc)g3m~o`>A>%W~ouDq_8Fg``NomrX zCV<9RVp?a~YT9Xf)pP(9#>b{3rf*Ft<}1xAv%x$IRGY_q9afRwgKFDie$o6gsDnf1 zewHjto@JV4w#8w&&eCLQv8+KqZm>LHdBn2Q@($LG1Z#h`ViZ{`t#w!{mRna_@3g*% zb>c(ox7Oaa3vKgkZmbOLw!3UkV`X^P#%&{hDfH*$edN4+0@nQ+`3>^Nu>yqT7b%7- zu276q=oQ(DiCFiG6|)uP=+!$Fe?+f7tk|x23-ntM_&=<;KsiV`T&Yx=FuqHH|GmoP zz-xD5d_SvvS^2K=i1N5Htn95C1Wa#H<*2SvEd(ZChcW)D>RZ)Msv)3a=BaDdH>z(} zzoPzBeOx_4lcSlcnXg%)c?Ny=iDra0Lwl8Wmi9XBjoSM_@qMa2sqKliUa!m1%>ZV+ zR(GTBX5AXyW4ae~A7gGL>WAw`>Bs4F_2s}B@9DqNf2%(Us&IrsZ?G70Kn=PLKEn-$ zTMT!g&mK4Y#qg@(d#v|kj8@~-#!_RAaiOurxX$>VvBMZ=N(1Gs1kJq!bm2PFBc>Nj z$4sX{6JBgiHyh29&2!BQ%r zj8+a(T@AcatGYyeIWYb#^=QpinnF#frd(64sn;}WZqTe^^W`zXdz)sD<~_|}(Az&~ zIBhTOQ0*w~bnP`-r*@h4CSdio+P`RD#=a$}J*AbQ59GS>x|uqkZl$hOcZY60;Qxhg zvc3>AW)WLwAJIRr-vR9OcZRFgfPTKA1oLJA*4pb0Er#1ckw0VD3w-^(A<;OR6kHEO zGJ{94d8PS5^IPTujCUI-q5ak*+dx~1?F(xAQRuVcalQOTc?xjti&*h?D_>Q?sp8cJ;1aufwz^#1puQfo@+;~i>J=Kd z-mgzJ_BUQ=9BN!(YBR0DKHwqj1h$)AF}-7Y7c|@uOM%5@*<|^Pqvq8J$amB z1aON=F&XQ{ChP-y0%H{EOR>UN=xcyy|DxXs+U#}xJ9-yp=@P?A!|yOhpEYbZ>^B@V zdkXC%Ew5VMvYfEQTa&G0ta6Oc*;a?uV_jyw(R!=(DeDW?z1BCZ z2d# awAQY^kY1f9D+}hJQ7h;4 z4%Uv=W$M&Avo0GnULkP9TwSGZJ}^W8Blk(&F3_-tbk~^Yo3A&oHV*?|VJz^T$@V+j zAFyY6()J7>v&Z%k@Z8t7A8cWQk35b@5pJM-sC+SYAnz+aSJb0rcPJlFK8Y3PRqQN2 z2DO`_8mhWdRfm?XRo$a{5N&%I7%x+;Q4=NW*66erZ3*}WD!oPjjXnYVftiN6hU>Ar z+hE)T>i#w3XU3ygt^1e;m@YD9nyO5TfCF}8|NsBBcdpM>Rd*OZp|L~=5SYlN1~`@o z83u9f``T+?PK-e)f}{wD7;Fq-8X#z-Q7WWPD2NO&V<R_=%j!JDyGmzrXb}u zfkAGQVw$EFS}v(%5Eu%5&bHHkpkLw3fyqoJYwh29-}iY}&Y`zI#DCm>%AeuS^LH^3 zm;3?26TwvYZ9{N9csSI*+*oS7Z}c_i z!MHo&@B`*7>nCV!Ym}oqt((>z>rwk@bhZq-t+0P;SK3wN=w zol5p{iL=Q$;`|%0OOxr)ZKmuG;l|}`SuQKk-b#5)#@z3_x~tIK*=_}DyONCZk-HPW z`;&Xajj5t29WPgn>JO?#eWg0pJ=N74&dG4eDHEaGA9-uw+eYsUO~_5JFDjt?BLBz! zTF(Do=(Y=O(x6~mFeR8Dtb}8mg9|~g@S$)>=!egSW#J(7x+pP+Ou3fad@OOECwo2l zObb$?_bzy10?BeAD!xW+6t6PP?`jA2Dr32M!u*Mgbqw7toV8TZ?o>x; z0`WS0w2B?xE>4TTiD8;YYci9mc$cZzNoGDyWAfLCh91!S=|l7!JCRwBcSfPB#m-!35xKY4`Ov9%cEN=g z=(+}zd*?-*Tnnju0w?d61Kn)5jK;AB?{8E8V67QmoU^^%+waBvIIe!!Z>Jr;7UYmp z$I<}Tgj>QRFmPM=4eT%^F)A@RQ3xF_O4Ps)$7z+AtLl`P$y{|4y@i2W&Bv$S;S`_M zIwCGe)zkEJsP_dDPbE#@5`7tMV6|R@a<}Oh@ud!^Z<;ZaX6Nny_BtPvhkBTqW`8rw zjGNhJjyb{<^dME{5}Lu4^sTMtJ+mAA#9(Mow{mfyYU`KQU#uegcXph7wA%T#)98He zoOjxz-FQqUWD(uL+j5nxh2FNx&qx+6@}j&3$7PY6beLc?Eccwdjx4&>-G)LQMN^(2 zQOt};-~+XnDLF%CO2Zq5atiZE4bOTd-h18_ZzsEW*}LI&^)vkqew+V|Zv;5!T#LIN zdoWtf*{Ib@CZ`+lX_x3kWReTxYN#5abR}V*d^J`Ts40G-3Ji zasd=y3zZy(4AXh`3*2RNNBg)DIOAS-`>2uX&phcYl;B1072NL&p6tW;f4Sen)4k|l z^*jCB+@pLqNDul1{qeu-$WQFRrv>C0^Ny_KT}T#LE?eZ#staKXDLUY(3>s`<=SJzi z9Do1T1DbGvR`Pw!$#CKjRjyOu6yfw$PBlce!)bDwomQvAiQ)5cnJe?<7<%jiIf-7Z zkm)XA0?Pj9`&DuYD_kk7Y0B2J(mLj%UN*=ba+lnL9yHMw9g;_3vQzRbC!v)alZ)~) zJ!mJCe23JK>ZZBrZU(m~{b`iqs7H=Fg30M5b>BfvQ&p*-nn+8|a|XYg$;%)0Lwd5+ zO?JBZ_88VT$&SUl#4`C>I@yy|t364!E8zD=d8za2y?B@%#)`Vc>iKsm&Qwm)trj(+ z4u`524PuAbCH8O+(Zo%}A+m3?I7RQ&0#UV-f-j2>(J5}?VKFULOCu3yXqj4nEsHiP zTg%Z#;AtlPg^x?;<80%!R_-S%P@*NMPz~MmX1#%XiM>$=bxLp1+fk%WZYWCWBFfDQ zGsDWX`de96+{#YgmfZhye+TaG!2KQgzjol6JWV9OLEmF#Au%8}LlwTZU{)a?iC9=N b^Y!F^2U8e*Y~5qghv$6z_mSl##j*bYCeLqK diff --git a/src/bin/pkzipc.exe b/src/bin/pkzipc.exe new file mode 100644 index 0000000000000000000000000000000000000000..09883b9e9a16ea5cf129e2b2e42e958b85c3c49d GIT binary patch literal 258048 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

    mu#^5| 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 delta 48691 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 diff --git a/src/font/large.psd b/src/font/large.psd new file mode 100644 index 0000000000000000000000000000000000000000..d2f7656a5149b6e47f8d2f0a60b9d3ea24a92591 GIT binary patch literal 64357 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 literal 0 HcmV?d00001 diff --git a/src/font/lcd0.cmd b/src/font/lcd0.cmd new file mode 100644 index 0000000000000000000000000000000000000000..b01407f111b4201684555922b2bcda44dda185c9 GIT binary patch literal 12700 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 literal 0 HcmV?d00001 diff --git a/src/font/n.bat b/src/font/n.bat new file mode 100644 index 00000000..754176fc --- /dev/null +++ b/src/font/n.bat @@ -0,0 +1,27 @@ +bmp2txt set01.bmp +bmp2txt set02.bmp +bmp2txt set03.bmp +bmp2txt set04.bmp +bmp2txt set05.bmp +bmp2txt set06.bmp + +txt2chs set01.txt 1 3 +txt2chs set02.txt 1 3 +txt2chs set03.txt 1 4 +txt2chs set04.txt 2 5 +txt2chs set05.txt 2 7 +txt2chs set06.txt 1 3 + +chs2cmd set01.chs 1 +chs2cmd set02.chs 2 +chs2cmd set03.chs 3 +chs2cmd set04.chs 4 +chs2cmd set05.chs 5 +chs2cmd set06.chs 6 + +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd+set06.cmd lcd0.cmd +copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd lcd1.cmd + +copy lcd0.cmd ..\..\bin\font +copy lcd1.cmd ..\..\bin\font + diff --git a/src/font/set01.bmp b/src/font/set01.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c49ae7a6b180c702df08afc3f9b7533240e18483 GIT binary patch literal 26580 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 literal 0 HcmV?d00001 diff --git a/src/font/set01.txt b/src/font/set01.txt new file mode 100644 index 00000000..2b3e6462 --- /dev/null +++ b/src/font/set01.txt @@ -0,0 +1,1056 @@ +at 15,17 size 2,10 + +## +## +## +## +## + +##__ + + +at 21,17 size 4,10 +## ## +## ## +## ## + + + + +________ + + +at 30,17 size 7,10 + + ## ## + ## ## + ########## + ## ## +########## + ## ## +__##__##______ + + +at 41,17 size 6,10 + ## + ## + ######## +## ## + #### + #### + ## ## +########____ + ## + ## +at 51,17 size 10,10 + + #### ## +## ## ## +## ## ## + #### ## #### + ## ## ## + ## ## ## +____##______####____ + + +at 65,17 size 7,10 + + #### +## ## +## ## + #### ## +## ## ## +## ## +__######__##__ + + +at 76,17 size 2,10 +## +## +## + + + + +____ + + +at 82,17 size 4,10 + ## + ## +## +## +## +## +## +##______ + ## + ## +at 90,17 size 4,10 +## + ## + ## + ## + ## + ## + ## +____##__ + ## +## +at 99,17 size 6,10 + ## +## ## ## + ###### +## ## ## + ## + + +____________ + + +at 108,17 size 8,10 + + ## + ## + ## +############## + ## + ## +______##________ + + +at 120,17 size 3,10 + + + + + + + ## +__##__ +## + +at 127,17 size 4,10 + + + + +###### + + +________ + + +at 135,17 size 2,10 + + + + + + +## +##__ + + +at 141,17 size 5,10 + ## + ## + ## + ## + ## + ## + ## +##________ +## + +at 151,17 size 6,10 + + ###### +## ## +## ## +## ## +## ## +## ## +__######____ + + +at 160,17 size 6,10 + + ## +###### + ## + ## + ## + ## +##########__ + + +at 170,17 size 6,10 + + ###### +## ## + ## + ## + ## + ## +##########__ + + +at 180,17 size 6,10 + + ###### +## ## + ## + #### + ## +## ## +__######____ + + +at 190,17 size 6,10 + + ## + #### + ## ## +## ## +########## + ## +______##____ + + +at 200,17 size 6,10 + +########## +## +######## + ## + ## +## ## +__######____ + + +at 210,17 size 6,10 + + #### + ## +## +######## +## ## +## ## +__######____ + + +at 220,17 size 6,10 + +########## + ## + ## + ## + ## + ## +__##________ + + +at 230,17 size 6,10 + + ###### +## ## +## ## + ###### +## ## +## ## +__######____ + + +at 239,17 size 6,10 + + ###### +## ## +## ## + ######## + ## + ## +__####______ + + +at 250,17 size 2,10 + + + +## +## + +## +##__ + + +at 257,17 size 3,10 + + + + ## + ## + + ## +__##__ +## + +at 265,17 size 7,10 + + + #### + #### +#### + #### + #### +______________ + + +at 277,17 size 7,10 + + + +############ + +############ + +______________ + + +at 289,17 size 7,10 + + +#### + #### + #### + #### +#### +______________ + + +at 300,17 size 5,10 + +###### + ## + ## + ## + ## + +__##______ + + +at 7,41 size 9,10 + + ########## + ## ## +## ###### ## +## ## ## ## +## ## ## ## +## ## ## ## +##____####__##____ + ## + ######## +at 20,41 size 8,10 + + ## + ## ## + ## ## + ## ## + ########## + ## ## +##__________##__ + + +at 31,41 size 6,10 + +###### +## ## +## ## +######## +## ## +## ## +########____ + + +at 41,41 size 7,10 + + ###### + ## ## +## +## +## + ## ## +____######____ + + +at 52,41 size 7,10 + +######## +## ## +## ## +## ## +## ## +## ## +########______ + + +at 63,41 size 5,10 + +######## +## +## +######## +## +## +########__ + + +at 73,41 size 6,10 + +########## +## +## +######## +## +## +##__________ + + +at 82,41 size 7,10 + + ###### + ## ## +## +## ###### +## ## + ## ## +____########__ + + +at 93,41 size 7,10 + +## ## +## ## +## ## +############ +## ## +## ## +##________##__ + + +at 104,41 size 4,10 + +###### + ## + ## + ## + ## + ## +######__ + + +at 111,41 size 5,10 + + #### + ## + ## + ## + ## + ## +######____ + + +at 120,41 size 7,10 + +## ## +## ## +## ## +###### +## ## +## ## +##________##__ + + +at 131,41 size 6,10 + +## +## +## +## +## +## +##########__ + + +at 140,41 size 8,10 + +#### #### +#### #### +## ## ## ## +## ## ## ## +## ## ## +## ## ## +##__________##__ + + +at 152,41 size 6,10 + +## ## +#### ## +## ## ## +## ## ## +## #### +## ## +##______##__ + + +at 163,41 size 8,10 + + ###### + ## ## +## ## +## ## +## ## + ## ## +____######______ + + +at 174,41 size 6,10 + +######## +## ## +## ## +## ## +######## +## +##__________ + + +at 184,41 size 8,10 + + ###### + ## ## +## ## +## ## +## ## + ## ## +____######______ + ## + #### +at 195,41 size 7,10 + +######## +## ## +## ## +######## +## ## +## ## +##________##__ + + +at 205,41 size 6,10 + + ###### +## ## +## + ###### + ## +## ## +__######____ + + +at 215,41 size 8,10 + +############## + ## + ## + ## + ## + ## +______##________ + + +at 225,41 size 7,10 + +## ## +## ## +## ## +## ## +## ## +## ## +__########____ + + +at 235,41 size 8,10 + +## ## + ## ## + ## ## + ## ## + ## ## + ## ## +______##________ + + +at 247,41 size 10,10 + +## ## ## +## ## ## + ## ## ## ## + ## ## ## ## + ## ## ## ## + ## ## +____##______##______ + + +at 260,41 size 6,10 + +## ## +## ## + ## ## + ## + ## ## +## ## +##______##__ + + +at 269,41 size 8,10 + +## ## + ## ## + ## ## + ## + ## + ## +______##________ + + +at 280,41 size 6,10 + +########## + ## + ## + ## + ## +## +##########__ + + +at 290,41 size 4,10 +###### +## +## +## +## +## +## +##______ +## +###### +at 297,41 size 5,10 +## +## + ## + ## + ## + ## + ## +______##__ + ## + +at 307,41 size 4,10 +###### + ## + ## + ## + ## + ## + ## +____##__ + ## +###### +at 315,41 size 7,10 + + #### + ## ## +## ## + + + +______________ + + +at 325,41 size 7,10 + + + + + + + +______________ + +############ +at 8,65 size 3,10 +## + ## + + + + + +______ + + +at 17,65 size 6,10 + + + + ###### + ## + ######## +## ## +__########__ + + +at 26,65 size 6,10 +## +## +## +######## +## ## +## ## +## ## +########____ + + +at 36,65 size 5,10 + + + + ###### +## +## +## +__######__ + + +at 45,65 size 6,10 + ## + ## + ## + ######## +## ## +## ## +## ## +__########__ + + +at 55,65 size 6,10 + + + + ###### +## ## +########## +## +__########__ + + +at 63,65 size 5,10 + #### + ## + ## +######## + ## + ## + ## +__##______ + + +at 71,65 size 6,10 + + + + ######## +## ## +## ## +## ## +__########__ + ## + ###### +at 81,65 size 6,10 +## +## +## +######## +## ## +## ## +## ## +##______##__ + + +at 91,65 size 2,10 + +## + +## +## +## +## +##__ + + +at 96,65 size 3,10 + + ## + +#### + ## + ## + ## +__##__ + ## +## +at 104,65 size 6,10 +## +## +## +## ## +## ## +###### +## ## +##______##__ + + +at 113,65 size 2,10 +## +## +## +## +## +## +## +##__ + + +at 120,65 size 10,10 + + + +######## ###### +## ## ## +## ## ## +## ## ## +##______##______##__ + + +at 133,65 size 6,10 + + + +######## +## ## +## ## +## ## +##______##__ + + +at 143,65 size 6,10 + + + + ###### +## ## +## ## +## ## +__######____ + + +at 152,65 size 6,10 + + + +######## +## ## +## ## +## ## +########____ +## +## +at 162,65 size 6,10 + + + + ######## +## ## +## ## +## ## +__########__ + ## + ## +at 172,65 size 4,10 + + + +## ## +#### +## +## +##______ + + +at 180,65 size 5,10 + + + + ###### +## + #### + ## +######____ + + +at 187,65 size 5,10 + + ## + ## +######## + ## + ## + ## +____####__ + + +at 196,65 size 6,10 + + + +## ## +## ## +## ## +## ## +__########__ + + +at 206,65 size 5,10 + + + +## ## +## ## +## ## + #### +__####____ + + +at 215,65 size 6,10 + + + +## ## +## ## ## +## ## ## + ## ## +__##__##____ + + +at 227,65 size 6,10 + + + +## ## + ## ## + ## + ## ## +##______##__ + + +at 236,65 size 5,10 + + + +## ## +## ## +## ## + #### +____##____ + ## + ## +at 246,65 size 5,10 + + + +######## + ## + ## +## +########__ + + +at 254,65 size 6,10 + #### + ## + ## + ## + ## +#### + ## +____##______ + ## + #### +at 265,65 size 2,10 +## +## +## +## +## +## +## +##__ +## +## +at 271,65 size 6,10 +#### + ## + ## + ## + ## + #### + ## +____##______ + ## +#### +at 282,65 size 7,10 + + + + ## ## +## #### ## +## ## + +______________ + + +at 293,65 size 7,10 + + ###### + ## ## +######## + ## +######## + ## ## +____######____ + + +at 303,65 size 6,10 + + + ## + ######## +## +## +## +__########__ + ## + diff --git a/src/font/set02.bmp b/src/font/set02.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0c7e2e80152f5cd479a9c2cc6025a049f12b93f7 GIT binary patch literal 29048 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 literal 0 HcmV?d00001 diff --git a/src/font/set02.cmd b/src/font/set02.cmd new file mode 100644 index 0000000000000000000000000000000000000000..160af2d0f1ba2b104a34d9cfdc81375082264549 GIT binary patch literal 1607 zcmds0O^6&t6z-{??w;L_X)z%kR-_T}=b*GM$Ve6$mjqUEF_1kN5K=XVh+z{NgtZTi zv=Sodo>tU7miBksnD#Zje7ohX!;Hy`MfxpQO*w=jjSP zLXXik`UYL6AJC8KC-frynqHwl)9dsmy+t_-*&KV2&9kT3vuuSOVaHg`-eMcNP_p1sKESOd=3a zDUsk4{MZmkz~ilSE5>bM7*6p+C4<&t!epm{2LceTobmlIjN^X4C~DVIfUvaY(i4?{ z7}@M*1Wcw~rqO0vd(w+~FK$kv2(w0wBFrL!8d(I)MoA)svRME{+?FDX(lM1By-=_K zUtpmMRO?2f5Rp6fC7U|V6jLe*NRTu*sKgOmK@Ub~LE}LdVT^1;IjTmbMg$;$ zFi7#{@b?QBPMyMrlb5c4{^9yb%z`Qiiwm+eFhaK5W}~|rZQ7K2*ebs5?xZ=(RuF8> z+GUnyNj*F8w9@K$alCl7n0Mx#rkEue2)8q2xZe(mXQzx|a;8GD7!{s;QS|$99EQGc zYj#xlsz4J9d#l5aFFR8x5hcc+ml(o)nr=F-B82p|P z24NxT*=k^WTL5kU5e__oDNJ^SQ(?1EEr~9{WVq}|Xk$D(;Nt@4#uqZ74&6|KK}ge@ z{2yb0GE4AXHF^!4Ask$ztcQCM!|DczEE#tt-`?IndeoNCP{gvOL?DF0zXJLPw>zoO o<;W0p^LAiO!5lC>3IlT0!R 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 a+zE7U=jnTwcGtNR=-kfJ_pYON2mA*Tu{aO_ literal 0 HcmV?d00001 diff --git a/src/font/set03.chs b/src/font/set03.chs new file mode 100644 index 0000000000000000000000000000000000000000..05c355bed2da64c06d018a031562c958073d49dd GIT binary patch literal 1826 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 literal 0 HcmV?d00001 diff --git a/src/font/set05.cmd b/src/font/set05.cmd new file mode 100644 index 0000000000000000000000000000000000000000..c365d83ab395fa2922d0558fa3a515dd7ef7f405 GIT binary patch literal 3528 zcmds3&5Inz6@S}3(>)*6)3fW{xSgGBTe*dV&>Q5X9R`gY6r;=e_Fr+QcG0 zr(V-tU0wD1z2EP>SGE52=SJSvg%_W{bZLA0!i9?$x3^z<>9Sq7nwDqz*0S}KwPrnS zUA8}uJY%h!nZNfotZ!Idi(BtnA6R!SZPo2B+uyXmhgx2>e`x>G{=ojL{i(fC`Br7O z@{`K%Du1awtT@##R=27btFKhwseV}fd)0F`otK?!&U?<#`NVnTcZS&`fa(;0Hi#w^_@f0bUSHVD3xbP26^p#DMi*6Bxm3Z z9DB)H1xP|Mkay1S!#>=B0r;|_D)_g3Rmg$)PIL4ZcG_JB_88n_Fbd2S!MzCfc4YU8 zf}1HEMoT}V%WkE%s~lVEm82a)PrN2M%BBc|bHPq9Jd#?b@(rC2-VNR3O5Z8nKY?w=t7y10n zhR1H-jiZ!vDYJUtIyreNSZT%LcAsMM`(`^J}e39 zle{Ggu?M=9wDFs?r7K&qBV&YA$wC);IuA-cav;fKk^v0F(nQNl5BlMYP{d}2gj;BV zQl%%Hr==e_r%;6|r!1jGB|3x+Aw#H?cnl_M6~Bgz>_{}pV4~0p#AAY4pZG1u)j)-0 z8d_zG9-M=5wa<_WFbz9nx8F|Fw0xhC_Rm(r@Tc0AK6F8&bP*vNNrC90pSVRF7Xl=Nn;#%Ks6TaW-pw9zx6avB9h>$Fc#dMBC|$0;Ni=TM*i_ksiVzh!6eBo* zLpXvQ?!q5oB!+}sDq~8Ui6v8uPCZR(As?!xH}uBQ*3s7C?&0nMw$a<8w}(WL5#mEf zI?AG>=;P=xx)~irBb4F$!}qatQSnNNSL8z@A03Vy&ISGNARik2M|(~%jnTeI8;Sx> zPT7QdR{w_{a!J7+oFfd1&(Jqo!~o}na-cDD4HhZ%q_5!(iewR}v`{^1;^aR{;$nHE zK4CD6z-c5-o+?dIODG5f>6B57K^?>~#daCx1c-|%P1}a#kxV15d3mKb_~s2+Ue7SO z?uqhhxlmr@r;4%k^H>Ga6TWaUEj{503}c1+L!@HzL3J>hqBsqZ0AISMC@uP7@S;*+ zDr;G`94uM0Qj6bcZ^`p1KeK0^(_SD=!Ar5!M5YpS%w9mdf`bsD2&&*f`z|V(>`n6r zMsho;V@VONU^3uwiY{SZT3)hLsQYfeqS7cBvxHG$egSz#<}kdd-Ns&5;s&>j!xQ<4 zO7o;}n)0cJSSxP9xS258W>cYNa}{tg5Fu^y%f<^%_mKBg%9Sa-Mg#7(1GT}&p3#7T zP2Z-upFZ1Dp**hlmp9JgW|`-F)^I`lNy>nqN8<;82%a`x+%~SAzLn<~fW=WP3ag9( zy!qxFOxDTtX*f=og8MKn1$d%ZUesp#JZ<*g%{=)6@w{c$`tH zL{D<1%B`LNc@jTU{+wX@xBmkutp zPN@{nZ|e}6*&(jm6dYk7mlk!B#!~0>)D#2RM5PzcDgsk{o_;unF|uY(FebBTO}UQt z^k8AE1z1cZGP^c&YOzCVG-RlHs)C-Fq_~JOekvWDqv2sYak^}eU16ge!%S+d6TYqe jY$J#<(JA`zj>bh;I5q-5v-N{!vQnn~lk%+m+T{NRN_irk literal 0 HcmV?d00001 diff --git a/src/font/set05.txt b/src/font/set05.txt new file mode 100644 index 00000000..1739a518 --- /dev/null +++ b/src/font/set05.txt @@ -0,0 +1,2145 @@ +at 32,42 size 3,21 + +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### + + +#### +####__ + + + + +at 48,42 size 7,21 +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### + + + + + + + + + + +______________ + + + + +at 66,42 size 15,21 + + ## ## + ## ## + ## ## + ## ## + ## ## + ########################## + ## ## + ## ## + ## ## + ## ## +########################## + ## ## + ## ## + ## ## + ## ## +____##________##______________ + + + + +at 90,42 size 12,21 + ## + ## + ## + ############ + ################## +###### ## ## +#### ## +#### ## +###### ## + ############## + ############ + ## ###### + ## #### + ## #### +#### ## ###### +#################### +__##############________ + ## + ## + ## + ## +at 113,42 size 21,21 + + ######## #### + ############ #### +###### ###### #### +#### #### #### +#### #### #### +#### #### #### +###### ###### #### + ############ #### ######## + ######## #### ############ + #### ###### ###### + #### #### #### + #### #### #### + #### #### #### + #### ###### ###### + #### ############ +__________####______________########______ + + + + +at 144,42 size 17,21 + + ########## + ############## + ###### ###### + #### #### + #### #### + #### #### + ########## #### + ########## #### + #### #### #### +#### ###### #### +#### ######## +#### ###### +#### ######## +######## ############ + ################ ###### +______##########__________######__ + + + + +at 168,42 size 3,21 +#### +#### +#### +#### +#### +#### + + + + + + + + + + +______ + + + + +at 182,42 size 7,21 + ###### + #### + #### + #### + #### + #### +###### +#### +#### +#### +#### +#### +#### +#### +###### + #### +__####________ + #### + #### + #### + ###### +at 200,42 size 7,21 +###### + #### + #### + ###### + #### + #### + ###### + #### + #### + #### + #### + #### + #### + #### + ###### + #### +______####____ + ###### + #### + #### +###### +at 216,42 size 12,21 + ## + ## +#### ## #### + ###### ## ###### + ########## + ########## + ###### ## ###### +#### ## #### + ## + ## + + + + + + +________________________ + + + + +at 239,42 size 15,21 + + + + #### + #### + #### + #### + #### + #### +############################ +############################ + #### + #### + #### + #### + #### +____________####______________ + + + + +at 265,42 size 6,21 + + + + + + + + + + + + + + + ###### + #### +__######____ + #### + #### +#### +#### +at 281,42 size 8,21 + + + + + + + + + +############## +############## + + + + + +________________ + + + + +at 299,42 size 4,21 + + + + + + + + + + + + + + +###### +###### +######__ + + + + +at 312,42 size 11,21 + #### + #### + #### + ###### + #### + #### + #### + #### + ###### + #### + #### + #### + #### + #### + #### + #### +__######______________ + #### + #### +#### + +at 331,42 size 12,21 + + ########## + ############## + ###### ###### + #### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### #### + ###### ###### + ############## +______##########________ + + + + +at 354,42 size 9,21 + + #### + #### +########## +########## + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### +################ +################__ + + + + +at 375,42 size 11,21 + + ############ +################ +## ###### + #### + #### + #### + #### + #### + #### + ###### + ###### + ###### + ###### +###### +#################### +####################__ + + + + +at 397,42 size 11,21 + + ############## +################## +## ###### + #### + #### + #### + ######## + ######## + #### + #### + #### + #### + #### +## #### +################## +__############________ + + + + +at 418,42 size 13,21 + + #### + ###### + ######## + ########## + ###### #### + ###### #### + ###### #### + ###### #### +###### #### +######################## +######################## + #### + #### + #### + #### +________________####______ + + + + +at 440,42 size 11,21 + + ################## + ################## + #### + #### + #### + #### + ############## + ################ + ###### + #### + #### + #### + #### +## #### +################## +__############________ + + + + +at 461,42 size 12,21 + + ########## + ############ + ###### + #### + #### +#### +#### ########## +#################### +###### ###### +#### #### +#### #### +#### #### + #### #### + ###### #### + ############## +______##########________ + + + + +at 484,42 size 12,21 + +###################### +###################### + #### + #### + #### + ###### + #### + #### + #### + #### + ###### + #### + #### + #### + #### +__######________________ + + + + +at 504,42 size 12,21 + + ########## + ################## +###### ###### +#### #### +#### #### +###### #### + ######## ###### + ########## + #### ######## +#### ###### +#### #### +#### #### +#### #### +###### #### + ################## +______##########________ + + + + +at 526,42 size 12,21 + + ########## + ############## + #### ###### +#### #### +#### #### +#### #### +#### #### +###### ###### + #################### + ########## #### + #### + #### + #### + ###### + ############ +____##########__________ + + + + +at 551,42 size 4,21 + + + + + +###### +###### +###### + + + + + + +###### +###### +######__ + + + + +at 568,42 size 6,21 + + + + + + ###### + ###### + ###### + + + + + + + ###### + #### +__######____ + #### + #### +#### +#### +at 585,42 size 13,21 + + + + + #### + ######## + ######## + ######## + ######## +######## +######## + ######## + ######## + ######## + ######## + #### +__________________________ + + + + +at 611,42 size 14,21 + + + + + + + +########################## +########################## + + + +########################## +########################## + + +____________________________ + + + + +at 637,42 size 13,21 + + + + +#### +######## + ######## + ######## + ######## + ######## + ######## + ######## + ######## + ######## +######## +#### +__________________________ + + + + +at 662,42 size 10,21 + + ############ +################ +## ###### + #### + #### + #### + #### + ###### + ###### + #### + #### + #### + + + #### +______####__________ + + + + +at 16,94 size 19,21 + + ############ + #################### + ###### ######## + ###### #### + ###### ############## #### + #### ################ #### +###### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +###### ###### ###### ###### + #### ######################## + ###### ######## ############ +____######____________________________ + ######## + ################## + ############## + +at 44,94 size 16,21 + + ###### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + ###### ###### + ###################### + ###################### + #### #### + #### #### + #### #### +####______________________####__ + + + + +at 68,94 size 13,21 + +################## +#################### +#### ###### +#### #### +#### #### +#### #### +################## +###################### +#### #### +#### #### +#### #### +#### #### +#### #### +#### ###### +###################### +##################________ + + + + +at 90,94 size 14,21 + + ############ + #################### + ###### ###### + ###### ## + #### +#### +#### +#### +#### +#### +#### + #### + ###### ## + ###### ###### + #################### +________##############______ + + + + +at 114,94 size 15,21 + +################## +###################### +#### ######## +#### ###### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### ###### +#### ######## +###################### +##################____________ + + + + +at 139,94 size 12,21 + +###################### +###################### +#### +#### +#### +#### +###################### +###################### +#### +#### +#### +#### +#### +#### +###################### +######################__ + + + + +at 161,94 size 12,21 + +###################### +###################### +#### +#### +#### +#### +#################### +#################### +#### +#### +#### +#### +#### +#### +#### +####____________________ + + + + +at 180,94 size 15,21 + + ############## + ###################### + ###### ###### + ###### ## + #### +#### +#### +#### +#### ############ +#### ############ +#### #### + #### #### + ###### #### + ###### #### + ###################### +__________############________ + + + + +at 206,94 size 14,21 + +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +########################## +########################## +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +####__________________####__ + + + + +at 230,94 size 7,21 + +############ +############ + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### +############ +############__ + + + + +at 245,94 size 9,21 + + ############ + ############ + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + ###### +############## +############______ + + + + +at 265,94 size 14,21 + +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +############ +###### #### +#### ###### +#### ###### +#### ###### +#### ###### +#### ###### +####________________######__ + + + + +at 288,94 size 11,21 + +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#################### +####################__ + + + + +at 308,94 size 16,21 + +###### ###### +######## ######## +######## ######## +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### #### #### #### +#### ###### #### +#### ###### #### +#### ## #### +#### #### +#### #### +#### #### +####______________________####__ + + + + +at 334,94 size 13,21 + +######## #### +######## #### +########## #### +#### #### #### +#### ###### #### +#### #### #### +#### ###### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### ######## +#### ######## +#### ###### +####______________######__ + + + + +at 357,94 size 16,21 + + ############ + ################## + ###### ###### + ###### ###### + #### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### #### + ###### ###### + ###### ###### + ################## +__________############__________ + + + + +at 383,94 size 11,21 + +############## +################## +#### ###### +#### #### +#### #### +#### #### +#### #### +#### #### +################ +############## +#### +#### +#### +#### +#### +####__________________ + + + + +at 403,94 size 16,21 + + ############ + ################## + ###### ###### + ###### ###### + #### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### #### + ###### ###### + ###### ###### + ################## +__________##########____________ + #### + ###### + ############ + ########## +at 429,94 size 14,21 + +################ +################## +#### ###### +#### #### +#### #### +#### #### +#### #### +#### #### +################ +############## +#### #### +#### ###### +#### ###### +#### ###### +#### ###### +####________________######__ + + + + +at 451,94 size 14,21 + + ############## + ###################### + #### ###### +#### ## +#### +#### + ###### + ################ + ################ + ######## + #### + #### +## #### +###### ###### +###################### +____################________ + + + + +at 473,94 size 15,21 + +############################ +############################ + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### +____________####______________ + + + + +at 497,94 size 13,21 + +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +###### ###### + ###### ###### + ################ +______############________ + + + + +at 518,94 size 16,21 + +#### #### + #### #### + #### #### + #### #### + #### #### + #### #### + ###### ###### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + ########## +____________######______________ + + + + +at 542,94 size 21,21 + +#### #### #### +#### ###### #### + #### ######## #### + #### ######## #### + #### ######## #### + ###### ## #### #### + #### #### #### #### + #### #### #### #### + #### #### #### #### + #### ## #### #### + #### #### #### #### + #### #### #### #### + #### #### #### #### + ###### ###### + ###### ###### +________######____________######__________ + + + + +at 572,94 size 14,21 + +###### ###### + #### #### + #### #### + ###### ###### + #### #### + #### #### + ########## + ###### + ###### + #### #### + #### #### + #### #### + ###### ###### + #### #### + #### #### +######______________######__ + + + + +at 593,94 size 15,21 + +###### ###### + #### #### + #### #### + ###### ###### + #### #### + #### #### + ############ + ######## + #### + #### + #### + #### + #### + #### + #### +____________####______________ + + + + +at 616,94 size 14,21 + +########################## +########################## + ###### + ###### + ###### + ###### + #### + #### + #### + #### + ###### + ###### + ###### +###### +########################## +##########################__ + + + + +at 640,94 size 7,21 +############ +############ +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +####__________ +#### +#### +############ +############ +at 656,94 size 11,21 +#### + #### + #### + ###### + #### + #### + #### + #### + ###### + #### + #### + #### + #### + #### + #### + #### +____________######____ + #### + #### + #### + +at 675,94 size 7,21 +############ +############ + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### + #### +________####__ + #### + #### +############ +############ +at 693,94 size 15,21 + + #### + ######## + ######## + #### #### + #### #### + ###### ###### + #### #### + #### #### +#### #### + + + + + + +______________________________ + + + + +at 716,94 size 12,21 + + + + + + + + + + + + + + + + +________________________ + + +###################### + +at 18,146 size 6,22 +###### + ###### + #### + #### + + + + + + + + + + + + + +____________ + + + + +at 37,146 size 11,22 + + + + + + + ############## + ################ + ## ###### + #### + ############## + ################## +######## #### +#### #### +#### #### +###### ###### + ################## +____########____####__ + + + + +at 59,146 size 12,22 + +#### +#### +#### +#### +#### +#### ######## +#################### +###### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### ###### +#### ###### +################## +####__##########________ + + + + +at 79,146 size 10,22 + + + + + + + ########## + ############## + ###### ## +###### +#### +#### +#### +#### +###### + #### ## + ################ +______##########____ + + + + +at 98,146 size 12,22 + + #### + #### + #### + #### + #### + ########## #### + ################## + ###### #### +###### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### ###### + #################### +______########____####__ + + + + +at 120,146 size 12,22 + + + + + + + ########## + ################ + ###### #### +###### #### +#### #### +###################### +###################### +#### +#### + ###### ## + ################## +______##############____ + + + + +at 141,146 size 8,22 + + ######## + ########## + ###### + #### + #### +############ +############ + #### + #### + #### + #### + #### + #### + #### + #### + #### +__####__________ + + + + +at 156,146 size 12,22 + + + + + + + ########## #### + ################## + ###### #### +###### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### ###### + #################### +______########____####__ + #### + ## #### + ################## + ############## +at 178,146 size 11,22 + +#### +#### +#### +#### +#### +#### ######## +################## +###### ###### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +####____________####__ + + + + +at 200,146 size 3,22 + + +#### +#### + + +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +####__ + + + + +at 212,146 size 7,22 + + + #### + #### + + + ########## + ########## + #### + #### + #### + #### + #### + #### + #### + #### + #### +________####__ + #### + ###### +########## +######## +at 229,146 size 12,22 + +#### +#### +#### +#### +#### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +############ +###### ###### +#### ###### +#### ###### +#### ###### +####____________######__ + + + + +at 250,146 size 3,22 + +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +####__ + + + + +at 264,146 size 19,22 + + + + + + +#### ######## ########## +################## ############## +###### ########## ###### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +#### #### #### +####____________####____________####__ + + + + +at 293,146 size 11,22 + + + + + + +#### ######## +################## +###### ###### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +####____________####__ + + + + +at 314,146 size 12,22 + + + + + + + ########## + ############## + ###### ###### +###### ###### +#### #### +#### #### +#### #### +#### #### +###### ###### + ###### ###### + ############## +______##########________ + + + + +at 336,146 size 12,22 + + + + + + +#### ######## +#################### +###### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### ###### +#### ###### +################## +####__##########________ +#### +#### +#### +#### +at 356,146 size 12,22 + + + + + + + ########## #### + ################## + ###### #### +###### #### +#### #### +#### #### +#### #### +#### #### +#### #### + #### ###### + #################### +______##########__####__ + #### + #### + #### + #### +at 378,146 size 8,22 + + + + + + +#### ###### +############## +###### +#### +#### +#### +#### +#### +#### +#### +#### +####____________ + + + + +at 395,146 size 10,22 + + + + + + + ############ + ################ +#### ## +#### +###### + ############ + ########## + ###### + #### +## #### +################ +__############______ + + + + +at 414,146 size 9,22 + + + + #### + #### + #### +################ +################ + #### + #### + #### + #### + #### + #### + #### + ###### + ############ +______##########__ + + + + +at 431,146 size 11,22 + + + + + + +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +#### #### +###### ###### + ################## +____########____####__ + + + + +at 452,146 size 12,22 + + + + + + +#### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + ###### + ###### +________######__________ + + + + +at 473,146 size 17,22 + + + + + + +#### #### #### +#### #### #### + #### ######## #### + #### ######## #### + #### ## ## #### + #### #### #### #### + #### #### #### ## + #### ## ## #### + #### ## ######## + ######## ######## + #### #### +______####____________####________ + + + + +at 498,146 size 12,22 + + + + + + +###### ###### + ###### #### + #### #### + #### #### + ########## + ###### + ###### + ########## + #### #### + #### #### + #### #### +######__________######__ + + + + +at 519,146 size 12,22 + + + + + + +#### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + #### #### + ###### + ###### +________####____________ + #### + #### + #### + ###### +at 540,146 size 11,22 + + + + + + +#################### +#################### + ###### + ###### + ###### + ###### + ###### + ###### + ###### +###### +#################### +####################__ + + + + +at 560,146 size 11,22 + + ######## + ########## + ###### + #### + #### + #### + #### + #### + #### + #### +######## +######## + #### + #### + #### + #### +________####__________ + #### + ###### + ########## + ######## +at 584,146 size 3,22 + +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +#### +####__ +#### +#### +#### +#### +at 600,146 size 11,22 + +######## +########## + ###### + #### + #### + #### + #### + #### + #### + #### + ######## + ######## + #### + #### + #### + #### +________####__________ + #### + ###### +########## +######## +at 621,146 size 15,22 + + + + + + + + + ######## #### + ############ #### + #### ###### #### +#### ###### #### +#### ############ +#### ######## + + + +______________________________ + + + + +at 647,146 size 14,22 + + + ############ + ################## + ######## #### + ###### + #### +###################### +###################### + #### +#################### +#################### + #### + ###### + ######## #### + ################## + ############ +____________________________ + + + + +at 676,146 size 10,22 + + + + #### + #### + #### + ########## + ############## + ###### ## +###### +#### +#### +#### +#### +###### + #### ## + ################ +______##########____ + #### + #### + #### + diff --git a/src/font/set06.bmp b/src/font/set06.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e995ee456702111a47dbc99f4e4abc5ab8a10956 GIT binary patch literal 20024 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 G0{<5ZU8o-b literal 0 HcmV?d00001 diff --git a/src/fsutil/bd.exe b/src/fsutil/bd.exe index af80d7fee94f2d7924d961cbcec1a4ffa465b804..d284f670cffd04157ffa5f10faee1be27eeb6a78 100644 GIT binary patch delta 16574 zcmdUWdstLQw(sr-xY5RL6ciN&6^!pRb_3n)-q0wGn22eDHljQqr7(nApG_NreC&AG;+i4#p5@;iF-(OXuG3Pty ze&4p%<>z)W%wkOp zv$pBYyjw**%t*}$O)SIgWGp10zxfjonE<=Vr!$(yx1N0BcPnPh@)XV8dXt8kE;ndW z3~3sM9ftDV43i>1t(_HXP0%m~&C`>|kDBXWyVZ}PjXMw!)H~(BX(nZ#i$ikvP!@^r z_&L$_+%>EHtC6R#MDQvAnar#5TC+Wivmza z>oJ=B0qtY)KQ~p+U3JyTlq$)0F^qWB(A2hVuGjpAlTlJoT|BDyn%~67BJ@E%>c5hA zm?mVACT``SD%yl+v<%~)CzY_JUMFdJ0z(&%veA~;V{W%RW18+oxz|lFsu(aT`83Kh za8Ys@q+)$3@S~`Y_RM;<^$ZiuIay6B?;-t)JP8?)Sw}i^(9VX)T>pJ%8xrb=5p3Qa zZ^+jYW{f0tAETo%cplI3 z{PC!}wP+JNI(;cAdvK`i58fW~xis48#SyBide4)b`9ow-);+4D47m8*O;wfR3GJmy z!7`fXW0bEkAF?sYD(@csoa|2Qo6Hyrn5H(rRz2xWJ^=FB*MRU6$n)y|fKSZ%+N9FJ zrOQr6NKpOhteWIVC}7-bk`0kqmu_Inq{{TfAg`cG^ThL{qN8|$+>t2*e@x_Oo7*Cy^Yp>Hv?UJ?W*|(jHNBI$^&Fw+$ zS5Vuh@uuvS+sC{f*8?K9m$dGP$l}<-apbFRKL%yeNF9Ey)KycxvZEEba?jYY0aEJI zyOp;gE){!rL`Xjs!epP`6U-uI%HAIou)guiHOxhY<=7z;Bv48sO@jIau`Nw(*Yi6; zSKYrXAH1GM3Xe!%w?|^c3#pR6$vJ=weXkf%{raXhK_|wkVtZO(e#7;8RIU4{x5h*`s`c3{SaqTKN@S1j$kd8Ccme zmBU)D- zmS>L3OZfqc^dF*-8^_JQqv;n=L+F4ueRo`{)|RmU!Z?d2`(-Q_sW;>@xmCfS3aqjg zlZIG|c$A5B*(H-Hsp?oJUGk~k>6m_RqgB3d!USs}gwgUr%SXYaw}=#UH=Ly_EdCI_ z+Rw7Osh%lpDn#WA#F)zoMcNn;J@itjN!# zn6-z-%bh9Pb&Ihu7Ea7|lcj*EX7=nu;$l7Ry%>0dE;ig1D(NdPRk5PLWV4!tHbeo8 zkX(JiZEVmL3BRZ&-KxBcOv63n zO1{{wc8He>iJ*EJ3|-kWLDr;>W(mfwn7W9ZlA4lCKEzHohExdu15yw1Nm>O)xKrm& zBIInl|D8hAiDLLC`p2^M+eFfSSL*Efq)OeJ;aDk)q%3Mv|MntDM;2dpO9|88uJO<9 zZ)b%Oz*-q))g-A)dY??e+30GOho?=@Vj}KJ%Sc#`DpEvLRsYy>+CZ*Ko4b%;R+E;Z z4C1>|JX+Y{IZRhMQHaCc$~I6XPGc&>PJP2oCn4y|Y9a$3NnnltDHz0?J>@}xl~1K5 z1(vr?CnJvNgz=J#?(5G3h#`Ho~ z)(sRH3>x8n(b2?Q!4S&IL($Zm#P$%<%9P4vS(&^4Y5{^o8uJL4&QbY{4; z#pmSsX{lLD!RCtk8xIMin)-#2p{7IMsVc-}G0lFPe9aN!>r1}Vgx-D~AHi*ra-~^b zJ#D$>@cuUtCcZES-3dpf(_)8N722S~)91+3reD^!&61O5JUnq;x|3n2I+>|}M*%MY zUICl~Y?gmLW3u+q*>c;A!zO5J2m_$Sx! zsV>8@juUtM2^ABLBbqQN;KfQ6LX7hJyTQLKva?v!me|}5|0oBK<$yiyD^;xs z`C~O~ta!Rm`s`mdm(#1j;@RKI;$xpJ--#+_2(s?X>B zQYNMCp{4{*eBw&>M#h;FVXefgMq%CT#$xTFIsv%sO*f7UyInJZT_Qi${~WYaoGD zGUV6iOpPPEWli-SY?oioDbk+(MxHZw0f}noo}F;^8z-ap$2N~Ca;lmZ6Jla zls|H}#c8_gWXhIFbL!ETr`+2lt=I-8o5yQ!#L2vQa-d~68F*#72^Oo#qbB)DtB!CP(Uyz38$=3jA@VzH zsZy7JxYL#_+#o^!tS+adEK{B##ub?#D5L)Hh-Fx-U9%XX8=>zv5`>*Zrw~1ly`E|^ zA6Xx2Qeyz6>l$n&D}+R;*wJ*%AFpd~DIVWEvc)-}xky7b{-N2Uu+MFV)(kayVc?g! zyJ-9jhNUL$00wB+@#5QCQKl6V#J4vf5mO7lX8A=exDjgl=rY`bozQ!3Z)A@XjhbmA zW8=vHa9BPIg-8wCuSw`1-J)@8zJ*0LEw9ppC5w0m8gJWZUy+D>9k@%O0|s3h~~E4s7R%e1wM+aY$Bv zg$)XWHs0DOcY=*r+hBAD-GM!5T`sJnYsCO0kkwtNvfbHg!k5H9i;vJogO_o_03=SZ zD%&%Y0(95?SnNz(z)d90>i(i;kp@2Kt7uu(%J5x;gemW&bpX+TRAj=OkMuJ2@LY)J zMKDX*+<@@qowQ-!JaGccx6D(%%!i8Jy%x+q%(s!b3{wSzU-}ZtO@2Oew)SO<{9)!p zBy!9fHyoNSJiM&*O+&j}Gp~Otv0w>j<1zS|BL57GR*f*(I|$)Xk`c5fUX{06GIG(3 zGx7Uup*HK4~I4t70##AMZD*Mp3o@3@;{{rx#eCe0{!E3ZaB0;KpTE&dI1)Pw0DI$FuCgplJkrD=vTyt`<< zY$|`VYr@k)E;d9Pkm<-)mVg@AwAsEsHHp}NWa~#%eXK)ToUXTgaELI3V=1rZ5AiA> z9ck~;am}Pi7$((|?jf~9ErRjHsy;;6igsz>@q9iR!cg~>czty3MDcq1mgK0J91p&B zNcxWtpz0oCH+M8#e+zlFqZ+OsM;xsM|B%^?t&vn1LtC(g>H0E`*uV{0qg})n#neg0 z{=!Vy=^nRo1+z!&HnNA4R>YeK-$&d@2&z9l1!LSx#PGCu12RUfc=^+;sZ(!z1Gg=B z>S}t*#rIT;YUzI+c5-TVPC7Mm-wiJ~OjNi>iPJ_6Jqt0*olIKD@HQ$wo^8F0e3oy5 zJtOrJkK#gV$U!{{O0MY0RE2CRQy*ui2lf$)h6Pj1mbR5Ya82$YhH}^wb*aiXExYYa z0WWpD3EpA4&VDEOkR#eu|GZmkAl1?~tJ`l{!r?W*f45V%2j!@ZEm0%+$EPnIOw~iKMCy<$u?)U4K|3iN4~tjl(^QL{ zq^{?-7NdSeb%5Fv#EWU__pi9^xQy{AH$YfLQ=7-1?N-KP@^K!JOFAcO%T08;M_D$S z>U&UZWE#Www@P~VK4Gzk1##~Gn3gv8e9~SA~cUdq1a|j z@8#=pO0mVihqMoSp+p5Q9s1_gWK>FRAK9hY*oxYWhMN%`w&N{}JW4UJ5boy%>4bE} z5VFt{gI$0!wc#d3J4t!MNNW0%g4C~zRs`#CoVA>o9PrD$PO$ZdbATO>Y%hX_3ci@Z z;)4-0u=PwME%z|^4#t!5bj2wBPI_329gb{GAwxa(GTE4$5ipT+2+X5FDlnBxH^t7u zSwA+kUo}eauRo>-4WS*HLUbK0>6Jz(EiOK#f>Zqe3s03`$jou#UuKth7?EE9nca&`ZkvXy*;#;79NNa zPRc3ikAZZcVx>j;;F4%sFD+t&OV|K7j{#M&;!Op46pmVOSkbehDy%>gpQQN)tdbhCItv_`S1 z{>KX#Ax>PSze#h%txyx|%di4A8q`l{mb%gO{emF6f{M13L>5IzU*F!NmAYxgS>2(< z371Mk#fhbEWl{!6$ErSRP~))_>~zP7+7K@# z-tI(R&(GH~1M=_ry@>Xg<%Kl?QdbxS@#H9TgkeLg5;;LOG+$5gL@~sZB?v zs4(aTy*P#>#FyVP{$9nPxGw){F}i-~avy3<>UobAV4<@ZYqUY=9&1DN*oW&17Mc7r zeR?mGHe{p1hk2Qz3l$4~?uD=pTiaN139AP4g4^|KjA1|?R2wZ4OS#P zr9fG^`Z1Zp|3twdf}HCWCW$;rF+$895{rB~{Yu$G;&4(hwv{A;MfzYCNk~YTLr;(! z!_bq@0#C3gF;tWsTw(}rHwBAW%jMUlm&=kaBQyUv-_>SCh z)}6x=E?4fuIR-g%EHddjxX7jn^-o36Pz^0)gTuNO>U;6g&_&1&pMleT*N}q*5hlu} z;U*#0|6eVIsAnGa%ZD03%A-x}SpnxcEKL?e*h5l7IMVPfjfBY&WTjZ5V2ky))*dxJ zI>dN7C)L#2!8S?xP%dsafyHDy5!Vhfp~I#$hIy0e&1V|&3F(4e>Y(dGS7f5hhe;hE zltZFYMWd?5r(Gr7#1*Mu&vk9q1-Bbi*PvR$`r{kIWZ2?Ww&}BNuZi0R8R;+5X1#y5 z_~T?%nC8=j3er};;o>%yF+Sx+R!wyP3XBNf z8-#Zr={Q$l+8o0bB-XN09CzHG6TY&~C}c{#Z$My}h6^eT67K8TG}x4e;7Eifse4_+ zS*CYZdvN5eBh@%i4HdF1#I~BEg;B=NDmJxWH-rkilksIR9!$`f>L)V|Ho}swfKyLo zLl~>ZkikRn5T@Zo$)xOsD_B7pTuL}hrl(x;n8a_v>BQ?04y*M3>vEBlh@Q4_|WoN7yFfcH;^0|ny@vj(PSdnTBM3AIw zQpc$KspCJ{SngbPVXz4hXF1}y_?RM6O!BV~P;D)13*lQ5%HAC41O>zPmi8`MCFT>J|v z>jvuc7+m#shO8#;T42+HmgL6I1T&VrG2I*Psvs3oC4xAsFn- z491`S3hgCy)e(*{9=xWbCuI@K^mnj@E9A+Y&KyQ!`a-CO`~VHNKds^>00;| zjyt(!7T3G^uA#cUn-VQ;L5nR`80M^Z#4`Tt!3BiY2f_XYY*06=BoQ6C1~H$ovj%Tj zP66>!nz;5nQx;V~<-uh=_9P-+f=+dvm+mo%*Rk9$p^>;&0rWA_r=j^+m6t+4VTr;U zOAX{W`+S43iL4sc)pzkZ(uXDV6cJ+XE2Bv4ih8?hY-&Toa%^%*WO7OG$#tIivtm!2*fu~JOb?^W#rIWgD*K#Rq`;B8PxM(L8hMTv6Th8~k7&Hivl8SJDr$8ssY_gEfXz!ad-PPJR!2^-et59a zQrNB+dz?gbLk&RNYO7$wIIqf2FG|mC!=YcuW$5A$5RX@nHn8&AqT|4!On4$G z^LQCjfFtv_Xo<0rs34zq`5uCU93`Ynt`uO3X>}4tzycSr8PLZNuntJ0i)63E$wJgm zwO1tzY%5_}(3M?@VAWvAfh`iJf_b&;!#d+2!|h9;+!%&Bztp>JGL zH36}2=lkX7OUzT~J&`kf<@8_FCvl-o^n2L&UYN>X1o-dDg8rhpYgJ=3x5A*4_WK}Zc*RCp#5gWK!Hs`ReKX;ispXlNOSs8y-q{1R;gtR(TE8h;ltzkxEqtzi zcTb=E8+U3=v_*G)ds=fdt&iskt7}J#k;k`;yw#|?{$g6Vhcp4(oLpz^VVvo;lF<@b zo*F~Qhu$EUs_>nC-zh2RqoOMY8S=!^d$ZYUC&c;0Mg3TJ9=MC(-57P6NyaIIHEK-M^+{cMWJ!2R=oAZX|*27G>9?l+7ZP?L!09AeDC>Li#j- z!ADDxZtAJ#g}No}7q$1{0>1X(ch{aDRMY=$ca6NDY`PZFkIKv$q#ZCXMN|n`1K0rY z1L^>cfM3?gN6Ly5qvX7bj6;BKz?m9(($a+iSb#9uZ-Ighhg_Wyp%O0{%EYx1oIJo> zXh{ui(FBFTJKl+PkauEhk7EY#PAvLJ%y_UP`c4enL`=)1qVUQ38*|V~h!sl`wc(ih z8?%I1uIHY1!GEHT+jOu|@H6h_fprg47&P;sE47poxWe& zcPv23C$G@R6Ss|G4<6h3S>xgN#Ea%IPW_{=;zre=m>OIE89d6|Y zxiiF`cQJ=6F>T70gb2pVazbBiBHrx`5y2hbOxOSm2(Niey03ybUvvcqVOz8$UtB{r z_>x2z(>S6ePmN4XANXU*(Go0qOhUM%zg>R_l>$Nvj#h;{@vPP#*8szTVd}TUH60UX z+g*{(clEmxHPO9t3QFKXltk2U0x;K~)%Jfn;n={Zy6#{}1ju8E!=nwLf!5DTuE@Y? zcn65Xcmzh=O>NLd{AAeJKFuxhAhGf#);tjrde|PCudeI}?M+8#OlVCybYKfE4$7p{ z?L91x;MsvAWHsV4c=&wVr~Xro$NZ(yEaCEq)8$e}p#7Z5Gvc%~{2le?&F#2|8L+&k z>(yNszf#3s)$+cjQ#_)FH>uGy2q_sP@_$Gojlecs0Ooq(Xm!m>VsXqLw4L^6H@5k& z+RpgzYCP}%Cm#ACD+yU=kQIxpkHWvGu8ER7|0ddXgaY%wqw)Mf5|JSh{}lURO9Gxn zni@awuWxxw)7bC74|lMO(-T{U71>TwoFiIdNpd*s`fsXN)_??((JO>Q+trrUTJ$!( zC06Xz+IobeEd@GIk=(KlZ#a?R|04VcxWg-JT8`X*@k8k1&_Weo9a0wwvGmG4Wm1Xh z+%)M^EIqKK?dw-CaqmetaRhwrg_a`Kax8bDx<&8TFIqHkN@`zOUGx3rhwNT)cYxkV z&&HO66QcRvLRcJX(nr`~$omNYLsHgBq`fv|m#d%Pc7W9MyS>w+8Qw$^?=d4&{bY|7 zQ7cJ9D8{HKrPEEH`A4>rTx7(QksQcH@-2X2GyAHE9)!Z@4@aVRGW)MA&DCUgulw&6 zbkAC<22Z1yDCkNO_aZL^3FkVhpu5*m1&xR(Xo3ie?;S)h1NH)T0iFTu05k&X)=>pb zyHpA09>664^AJ_gtGu@rvkjGPyF?iejYh?R0lA=6=L3S$Vel|Ff)Co^1 zFE5Ll$0$2P%Z!avpu4+bmS2^xu1L`$ieEXQoRnSs9P6K&kRKvp--aWiAuBkoyqucN zxS2@5!wOD|TEWukVAXl<3uEIhG{Y%DNIxNJ34b1u11s(0h@}k4E&(m7a3*SaQ%dDi zE6qAkEbA-hXlF)bOJz3w+)z1%J~Dc`k`F{rZF|TfE+rlg#H~!22t5vK$GC%>sKVkg zKJ@}gC}~l*w2E!GL5#p{({JrJ2A{S}Nj(e(M_)*jy=l4Fqs7$eankUxltlI`siQr@ z8V`2&7v7_($7`9j!k;~6kW&9KqXK|?1E3ljcosFp?5BlYAs>-LHM?*|wZgd6uVk&T{ll1-b z3i9YfezZDCo8K+}tooPnL)D`TR-RdtuWj#=AFj#0ks;IC+L;nm_b z={d+l5)KEr9!ozrk-VQUib;go9nyPuyu&8X%)9llC$D1+K8>eLsX8jZ|G*fn>!|$C z2c~KHZrS+Y^vQqUcdG|KI}6t!+mpk873rJy81j4+580PLm>SsMfi9IlQz}hRpO@(1 z2R@(BKk)ey@uqrf=Hk&;bVBLlb#ki8mMH>SldFr)n()y11$jUNbC4KSL{WH#-hr(6 zFUKXJrS1Bb#qD~z|3Uk#ThDdELr-^Z;pk8^h;XPGWJc5sLfZb-YxYguzi~~9et%r^ zGrF-~ZHfNX4C|el0iZvVX8(kp@9O5()GSd0wQ}X5VKYlTPbg$3J^Z{U!s(T-HGW#BO?tfbQ{D@&^#=_~S zBp>m*{b?`s>WBB-aMGT8ZtNfbQa~Hn<7A2fvjHgp25{*=oXknUTY!ClX8`qpN8`kV#H+8B_bY&_|je{Gam5)#1jzLAx=TO6!BKXg@}KQ z*oydZ#Oa6!8D<2NhJ=a?)875B{GnDeksKHjunhqj1No8j$FDF)kH+uctzAU|YfLJs z*rUOC);s?@*q^_@)i8QG`PbjjFAob4|1x}fa#CPqqJ~*AO2a$=*bHa}`~vU-;59%e z;50x1^aI$@8YU571{48S0UihJ1ndJG0ek}J1u($vM4J@EGXdFv`GBQ>H2{C2#=-m) ziJt@Z0p0+d0GtN=18@bvfL0S=5@0T1FmMs1MegON^j{H=^Ptz=1>o0k9 zjj&;D@#;s`Y*<^sFmWW$^~mP+wU0jXqqUFtJ*#WiuYQ0O38cicwszC{M;~!*E!f}M zp*8H+oE)YJ9KZ~-<_z;<^9r+Me%kyS^C9y^^MHADra3b^bAIOInGKoGXTFwsIP>qB z7c=`Zb@SrqeKGIKJiWzgy<&}IE;HY;z>G)p(N2}vS$9~5#$KM^79FzFD{A2t! z{t5nn@xSE{@^A9(d`jNbyod8%&6D$A&Oe)fF`qFr^na#0v(cPtt~S47Za1sul+5bP zP^O%DBJ*12v-5s4@0EF{=KXcvxp~*-eLGKM8D^Pl$+gV4++$f`dCaoSB3hocd}^6* zt+WQ#TC1`)WNpvdoArmRce0LW{XI*cJvw_?_WJB6vgPdm%s!g^x9qdoSF;DR<8l&m zCg)7cvE;aNN^?9p59e&jc_L?5&Ko(Waz4+|+eX+jY}K}{wtCw^+i}}xHjO>Oo@}3E zFR)kGe`1&HKexYN|C9Z={ghpwJ2KaqyD)csZe1Yv_1t5*{kdt}G|tX7b5C;LaXLqw z!|0glusRkv7CY8DM8_MBHpe-~MTedr&L{Ab_zZpyZ{h8HA-|a4mH)f^SM!hOzn}kk z{`vgAd^MkOGE6t7HNl*2zT2E-&NVyDC1#&_qxmQ1dUMeHr1?4XUbA9;GV>>vz|SmC zT3RhHTHdxCwH&v6Wci!r3(J?5Z!9-0$<`UxyRGxBd#wv>r8cka5!)u)Pi@V%XKj0I zf3&sR-nV^h`ynFLr%6m7jD1UMO+I$Sb%`nMW z(JAH`W}Ep}<}2p>Ox{v#DY1sFs&!meUY0w{leI4EPucHekIR{wQ=ik6)0%T2=gpiy z=X{*=Wln!ioNcnL!1hbqZ*8C2uGtt6nr5E~Lf6_i*_$vSftT%nw*S@s5BopuSM9@c zQ*x)|&dtrj>^zYBNbc5LF*lU^%iLe*_T>I6_iAom?)BVJTr&3r7vf&x-s0Zp&U0Fa z$uZF}$Fan*0y6!$quKFu$FCf}b3_~_ek`BLr}NYK+59s8C;Y$hyZGJwUVb0{GXE-n zfIq}*^VmS1A>%&yEn%Xb!?)o4w$PO@fL=U6S)Tx-77ZQWo! zlyx%euUTJYozGITE@dTUa}e=LEZxAGY;X34?2Xy}?5){Hvb(cSWS`9bC_5K2zAERT zoDDe}bNo3^gQ1sm`f?&UgE@>%Z)0r+o5{Aqw#v2!au>dfC~ z9?1MKvnMm0`Bi4ty!G??=8drY#f1v2qh5A zHk-|c98=EHoaNxvnjHLj`niuc>D#bb%SoTyH7U)KZkcYGZDD$%^_>vh#TK_^sb#sP u(t<7dTlVKY>||oQ#Q@!c+)Cl`^_81yAFN!rN${`VQ2D@`xf|C!!2ECH5C(Su delta 11759 zcmdUVeRxw<*6+zjA%&C%Xrb8DrjTm22ubtZ6p`cW0Jr3lrR(ej}(S6(b5!+S8*se-j=;k>`S(;`04-1|KD z{&({{Yk#c0_S$Q&wfEXs04&vaf0ijl$v$e+oHiJrYVm zen+Sw$^kqhVo??b6l_fCW^{y@$#q}{0WaDLH z7^WVWwQ=m6bmSUl2E#NHgqu_-C`lE+(VSs~JlSkzAH(DbPsp_D0fs37E7DCXw8(Q4 z^k*4n_=&9aNwb3YZVaL&aU&AKtzP(AcBA#B#5grYq1W|4H%6Yda(Qq$kSi@nb^~-I z7YgJz*jAE(`T&GmC*ZoD8<<(^?p^)h3Wj-ZEE)y?gszuq-!6YBN!TsZJgKRj)!X4_ z%0*2!!*GYxjh&lj`3-yBjHp!+gwk)=hsr#RLn?jm2-`I27ShEdrk2qzEF))_U>;wl zD)+ld&!ZTOJEV&Dyqs{Y=V?ujAMJh*;V5C!APUIDN+^;qR`Vswa_~pfB|5UoFRy2q zIA-(Rl(?0Q%dsS7AZ8sI%tZ$q5p&fqgRP!eKbCOwZ`&(eoOsIwLi-S%h1%cOA>2Bt zO14*Mm^6EOAGl>pP)nqEfG-;;_xBRg9?D4-`@nx{ukh)l*>dz5Gg-fow5=Fvd)41Z zste5bvmE42qkayp<(C1y2<>Q_(8)Vi~7VeXUyw%N@DMdu>Y^ z+W4fBSIB(ol+La?Ip4*b8+ZOY1Q34OKcFlh}aJ>q*Rh}qiTMaHQLWd)Sph=sI?dw$iR z3fv%GRDjgWPy%;8lUFwG?gT

    mu#^5| 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 delta 48691 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 diff --git a/src/fsutil/ucp.map b/src/fsutil/ucp.map index 43e53cfb..44d8238b 100644 --- a/src/fsutil/ucp.map +++ b/src/fsutil/ucp.map @@ -1,13 +1,13 @@ ucp - Timestamp is 3e6cd0f0 (Tue Mar 11 04:52:48 2003) + Timestamp is 3ebb8562 (Fri May 09 20:39:30 2003) Preferred load address is 00400000 Start Length Name Class - 0001:00000000 000197f7H .text CODE - 0002:00000000 00000696H .rdata DATA - 0002:00000696 00000000H .edata DATA + 0001:00000000 0001aa8fH .text CODE + 0002:00000000 000006d0H .rdata DATA + 0002:000006d0 00000000H .edata DATA 0003:00000000 00000104H .CRT$XCA DATA 0003:00000104 00000104H .CRT$XCZ DATA 0003:00000208 00000104H .CRT$XIA DATA @@ -18,725 +18,758 @@ 0003:00000724 00000104H .CRT$XPZ DATA 0003:00000828 00000104H .CRT$XTA DATA 0003:0000092c 00000104H .CRT$XTZ DATA - 0003:00000a30 000026eeH .data DATA - 0003:00003120 000076a4H .bss DATA + 0003:00000a30 00004f6fH .data DATA + 0003:000059a0 00006c04H .bss DATA 0004:00000000 00000014H .idata$2 DATA 0004:00000014 00000014H .idata$3 DATA - 0004:00000028 00000138H .idata$4 DATA - 0004:00000160 00000138H .idata$5 DATA - 0004:00000298 00000559H .idata$6 DATA + 0004:00000028 00000144H .idata$4 DATA + 0004:0000016c 00000144H .idata$5 DATA + 0004:000002b0 0000059dH .idata$6 DATA Address Publics by Value Rva+Base Lib:Object - 0001:000008a0 _pse 004018a0 f ucp.obj - 0001:000008e6 _dohelp 004018e6 f ucp.obj - 0001:0000092d _eq 0040192d f ucp.obj - 0001:00000947 _execute 00401947 f ucp.obj - 0001:00000ea9 _usage 00401ea9 f ucp.obj - 0001:00000ec7 _main 00401ec7 f ucp.obj - 0001:000019e0 _ldir 004029e0 f ucpsub.obj - 0001:00001a21 _devdir 00402a21 f ucpsub.obj - 0001:00001a9c _prot 00402a9c f ucpsub.obj - 0001:00001aae _dols 00402aae f ucpsub.obj - 0001:0000206e _xls 0040306e f ucpsub.obj - 0001:00002164 _xchmod 00403164 f ucpsub.obj - 0001:000021e4 _xumask 004031e4 f ucpsub.obj - 0001:00002265 _xmknod 00403265 f ucpsub.obj - 0001:00002399 _xmkdir 00403399 f ucpsub.obj - 0001:000023e0 _xget 004033e0 f ucpsub.obj - 0001:0000258b _xput 0040358b f ucpsub.obj - 0001:00002722 _xtype 00403722 f ucpsub.obj - 0001:000027c0 _xdump 004037c0 f ucpsub.obj - 0001:00002a7e _xunlink 00403a7e f ucpsub.obj - 0001:00002b64 _xrmdir 00403b64 f ucpsub.obj - 0001:00002d68 _xdf 00403d68 f ucpsub.obj - 0001:00002e27 _xalign 00403e27 f ucpsub.obj - 0001:00002f1c _xualign 00403f1c f ucpsub.obj - 0001:00003560 _wd_read 00404560 f devhd.obj - 0001:00003597 _wd_write 00404597 f devhd.obj - 0001:000035ce _setup 004045ce f devhd.obj - 0001:0000372b _chkstat 0040472b f devhd.obj - 0001:00003771 _wd_open 00404771 f devhd.obj - 0001:00003810 _bread 00404810 f devio.obj - 0001:00003947 _bfree 00404947 f devio.obj - 0001:000039fe _zerobuf 004049fe f devio.obj - 0001:00003a85 _bufsync 00404a85 f devio.obj - 0001:00003af9 _bfind 00404af9 f devio.obj - 0001:00003b51 _freebuf 00404b51 f devio.obj - 0001:00003c93 _bufdump 00404c93 f devio.obj - 0001:00003d7a _validdev 00404d7a f devio.obj - 0001:00003e05 _bdreadwrite 00404e05 f devio.obj - 0001:00003e83 _cdreadwrite 00404e83 f devio.obj - 0001:00003ee9 _d_openclose 00404ee9 f devio.obj - 0001:00003f49 _d_ioctl 00404f49 f devio.obj - 0001:00003f9f _d_init 00404f9f f devio.obj - 0001:00003ffe _ok 00404ffe f devio.obj - 0001:00004005 _ok_rdwr 00405005 f devio.obj - 0001:0000400c _nogood 0040500c f devio.obj - 0001:00004014 _nogood_ioctl 00405014 f devio.obj - 0001:0000401c _insq 0040501c f devio.obj - 0001:0000408e _remq 0040508e f devio.obj - 0001:000040fc _uninsq 004050fc f devio.obj - 0001:0000416f _clrq 0040516f f devio.obj - 0001:000043f0 _mem_read 004053f0 f devmisc.obj - 0001:00004451 _mem_write 00405451 f devmisc.obj - 0001:000044b4 _null_write 004054b4 f devmisc.obj - 0001:000044be _lpr_open 004054be f devmisc.obj - 0001:000044cc _lpr_close 004054cc f devmisc.obj - 0001:000044e5 _lpr_write 004054e5 f devmisc.obj - 0001:0000454b _mt_read 0040554b f devmisc.obj - 0001:00004553 _mt_write 00405553 f devmisc.obj - 0001:0000455b _mt_open 0040555b f devmisc.obj - 0001:00004563 _mt_close 00405563 f devmisc.obj - 0001:000045d0 _tty_read 004055d0 f devtty.obj - 0001:00004783 _tty_write 00405783 f devtty.obj - 0001:00004900 _tty_open 00405900 f devtty.obj - 0001:00004997 _tty_close 00405997 f devtty.obj - 0001:000049fb _tty_ioctl 004059fb f devtty.obj - 0001:00004b99 _tty_inproc 00405b99 f devtty.obj - 0001:00004f41 _tty_inproc_dummy 00405f41 f devtty.obj - 0001:00004f46 _echo 00405f46 f devtty.obj - 0001:000051e0 _findfs 004061e0 f filesys.obj - 0001:0000522c _getfs 0040622c f filesys.obj - 0001:00005281 _wr_inode 00406281 f filesys.obj - 0001:00005354 _i_ref 00406354 f filesys.obj - 0001:000053b2 _i_deref 004063b2 f filesys.obj - 0001:00005489 _i_free 00406489 f filesys.obj - 0001:00005522 __namei 00406522 f filesys.obj - 0001:000056f9 _namei 004066f9 f filesys.obj - 0001:00005a57 _srch_dir 00406a57 f filesys.obj - 0001:00005b87 _srch_mt 00406b87 f filesys.obj - 0001:00005be7 _i_open 00406be7 f filesys.obj - 0001:00005e80 _ch_link 00406e80 f filesys.obj - 0001:00006029 _filename 00407029 f filesys.obj - 0001:000060d0 _namecomp 004070d0 f filesys.obj - 0001:00006156 _newfile 00407156 f filesys.obj - 0001:00006232 _doclose 00407232 f filesys.obj - 0001:000062d3 _i_alloc 004072d3 f filesys.obj - 0001:000063d8 _blk_alloc 004073d8 f filesys.obj - 0001:00006512 _blk_free 00407512 f filesys.obj - 0001:000065c0 _oft_alloc 004075c0 f filesys.obj - 0001:00006630 _oft_deref 00407630 f filesys.obj - 0001:00006688 _uf_alloc 00407688 f filesys.obj - 0001:000066e0 _isdevice 004076e0 f filesys.obj - 0001:00006727 _freeblk 00407727 f filesys.obj - 0001:000067c8 _f_trunc 004077c8 f filesys.obj - 0001:00006881 _bmap 00407881 f filesys.obj - 0001:00006ae1 _validblk 00407ae1 f filesys.obj - 0001:00006b60 _getinode 00407b60 f filesys.obj - 0001:00006c3c _getperm 00407c3c f filesys.obj - 0001:00006cdc _setftim 00407cdc f filesys.obj - 0001:00006d46 _fmount 00407d46 f filesys.obj - 0001:00006efe _magic 00407efe f filesys.obj - 0001:00006f28 _i_sync 00407f28 f filesys.obj - 0001:00006f9d _fs_sync 00407f9d f filesys.obj - 0001:00007d40 _scsiop 00408d40 f hdasm.obj - 0001:00007e60 _fs_init 00408e60 f machdep.obj - 0001:00007e81 _valadr 00408e81 f machdep.obj - 0001:00007e8b _addtick 00408e8b f machdep.obj - 0001:00007ee9 _incrtick 00408ee9 f machdep.obj - 0001:00007f28 _calltrap 00408f28 f machdep.obj - 0001:00007fae _sttime 00408fae f machdep.obj - 0001:00007fc6 _panic 00408fc6 f machdep.obj - 0001:00008014 _warning 00409014 f machdep.obj - 0001:00008048 _idump 00409048 f machdep.obj - 0001:000082b0 _abort 004092b0 f main.obj - 0001:000082ce _rdtime 004092ce f main.obj - 0001:00008370 _init2 00409370 f process.obj - 0001:00008591 _psleep 00409591 f process.obj - 0001:0000860d _wakeup 0040960d f process.obj - 0001:00008658 _getproc 00409658 f process.obj - 0001:000086b1 _newproc 004096b1 f process.obj - 0001:000087f1 _ptab_alloc 004097f1 f process.obj - 0001:000088a6 _clkint2 004098a6 f process.obj - 0001:000089ea _unix2 004099ea f process.obj - 0001:00008a72 _chksigs 00409a72 f process.obj - 0001:00008b30 _sgrpsig 00409b30 f process.obj - 0001:00008b7c _ssig 00409b7c f process.obj - 0001:00008bf3 _sendsig 00409bf3 f process.obj - 0001:00008c47 _dowait 00409c47 f process.obj - 0001:00008fa0 _sys_NONE 00409fa0 f scall1.obj - 0001:00008fb2 _sys_sync 00409fb2 f scall1.obj - 0001:00008fc3 _sys_utime 00409fc3 f scall1.obj - 0001:000090e4 _sys_close 0040a0e4 f scall1.obj - 0001:000090f7 _truncateto0 0040a0f7 f scall1.obj - 0001:00009170 _sys_open 0040a170 f scall1.obj - 0001:000094a9 _sys_link 0040a4a9 f scall1.obj - 0001:000095f4 _sys_symlink 0040a5f4 f scall1.obj - 0001:000096e2 _sys_unlink 0040a6e2 f scall1.obj - 0001:000097fc _sys_readwrite 0040a7fc f scall1.obj - 0001:00009892 _sys_lseek 0040a892 f scall1.obj - 0001:00009970 _sys_chdir 0040a970 f scall1.obj - 0001:000099ff _sys_chroot 0040a9ff f scall1.obj - 0001:00009a3d _sys_mknod 0040aa3d f scall1.obj - 0001:00009b18 _sys_access 0040ab18 f scall1.obj - 0001:00009bff _sys_chmod 0040abff f scall1.obj - 0001:00009ce3 _sys_chown 0040ace3 f scall1.obj - 0001:00009d0a _stcpy 0040ad0a f scall1.obj - 0001:00009da7 _sys_statfstat 0040ada7 f scall1.obj - 0001:00009e3a _sys_falign 0040ae3a f scall1.obj - 0001:00009ea4 _sys_dup 0040aea4 f scall1.obj - 0001:00009f2f _sys_dup2 0040af2f f scall1.obj - 0001:00009fdb _sys_getfsys 0040afdb f scall1.obj - 0001:0000a036 _sys_ioctl 0040b036 f scall1.obj - 0001:0000a0c9 _sys_mountumount 0040b0c9 f scall1.obj - 0001:0000a32c _sys_time 0040b32c f scall1.obj - 0001:0000a364 _exit0 0040b364 f scall1.obj - 0001:0000a375 _n_creat 0040b375 f scall1.obj - 0001:0000a531 _readwritei 0040b531 f scall1.obj - 0001:0000aa5b _rwsetup 0040ba5b f scall1.obj - 0001:0000ab08 _getfsys 0040bb08 f scall1.obj - 0001:0000b410 _findprocess 0040c410 f scall2.obj - 0001:0000b475 _filldesc 0040c475 f scall2.obj - 0001:0000b4ab _sys_pipe 0040c4ab f scall2.obj - 0001:0000b642 _sys_stime 0040c642 f scall2.obj - 0001:0000b691 _sys_times 0040c691 f scall2.obj - 0001:0000b6e0 _sys_brk 0040c6e0 f scall2.obj - 0001:0000b71c _sys_sbrk 0040c71c f scall2.obj - 0001:0000b762 _sys_waitpid 0040c762 f scall2.obj - 0001:0000b7dd _sys__exit 0040c7dd f scall2.obj - 0001:0000b7f5 _doexit 0040c7f5 f scall2.obj - 0001:0000b929 _sys_fork 0040c929 f scall2.obj - 0001:0000b92e _sys_pause 0040c92e f scall2.obj - 0001:0000b94a _sys_signal 0040c94a f scall2.obj - 0001:0000ba03 _sys_kill 0040ca03 f scall2.obj - 0001:0000ba67 _sys_alarm 0040ca67 f scall2.obj - 0001:0000ba8b _sys_reboot 0040ca8b f scall2.obj - 0001:0000bade _sys_getset 0040cade f scall2.obj - 0001:0000bf10 _bitmap_align 0040cf10 f xip.obj - 0001:0000c62a _bitmap_ualign 0040d62a f xip.obj - 0001:0000c752 _bitmap_examine 0040d752 f xip.obj - 0001:0000c977 _bitmap_align_chase 0040d977 f xip.obj - 0001:0000cae2 _bitmap_align_bmap 0040dae2 f xip.obj - 0001:0000cd68 _bitmap_align_reverse 0040dd68 f xip.obj - 0001:0000ce53 _bitmap_align_recurse 0040de53 f xip.obj - 0001:0000d2d7 _bitmap_search 0040e2d7 f xip.obj - 0001:0000d469 _bitmap_reserve 0040e469 f xip.obj - 0001:0000d656 _bitmap_find 0040e656 f xip.obj - 0001:0000d895 _bitmap_get 0040e895 f xip.obj - 0001:0000d966 _bitmap_set 0040e966 f xip.obj - 0001:0000e010 _bzero 0040f010 f utils.obj - 0001:0000e036 _bfill 0040f036 f utils.obj - 0001:0000e05e _bcopy 0040f05e f utils.obj - 0001:0000e091 _int_min 0040f091 f utils.obj - 0001:0000e0b2 _int_max 0040f0b2 f utils.obj - 0001:0000e110 _xfs_init 0040f110 f xfs.obj - 0001:0000e27e _xfs_end 0040f27e f xfs.obj - 0001:0000e2c5 _UZIXopen 0040f2c5 f xfs.obj - 0001:0000e2ea _UZIXclose 0040f2ea f xfs.obj - 0001:0000e2fc _UZIXcreat 0040f2fc f xfs.obj - 0001:0000e321 _UZIXlink 0040f321 f xfs.obj - 0001:0000e33c _UZIXsymlink 0040f33c f xfs.obj - 0001:0000e357 _UZIXunlink 0040f357 f xfs.obj - 0001:0000e369 _UZIXread 0040f369 f xfs.obj - 0001:0000e394 _UZIXwrite 0040f394 f xfs.obj - 0001:0000e3bf _UZIXlseek 0040f3bf f xfs.obj - 0001:0000e3ee _UZIXchdir 0040f3ee f xfs.obj - 0001:0000e400 _UZIXmknod 0040f400 f xfs.obj - 0001:0000e424 _UZIXsync 0040f424 f xfs.obj - 0001:0000e42e _UZIXaccess 0040f42e f xfs.obj - 0001:0000e449 _UZIXchmod 0040f449 f xfs.obj - 0001:0000e464 _UZIXchown 0040f464 f xfs.obj - 0001:0000e488 _UZIXstat 0040f488 f xfs.obj - 0001:0000e4aa _UZIXfstat 0040f4aa f xfs.obj - 0001:0000e4cc _UZIXfalign 0040f4cc f xfs.obj - 0001:0000e4e7 _UZIXdup 0040f4e7 f xfs.obj - 0001:0000e4f9 _UZIXdup2 0040f4f9 f xfs.obj - 0001:0000e514 _UZIXumask 0040f514 f xfs.obj - 0001:0000e530 _UZIXgetfsys 0040f530 f xfs.obj - 0001:0000e550 _UZIXioctl 0040f550 f xfs.obj - 0001:0000e574 _UZIXmount 0040f574 f xfs.obj - 0001:0000e59f _UZIXumount 0040f59f f xfs.obj - 0001:0000e5b8 _UZIXtime 0040f5b8 f xfs.obj - 0001:0000e6f8 ___initstdio 0040f6f8 f LIBC:_file.obj - 0001:0000e79d ___endstdio 0040f79d f LIBC:_file.obj - 0001:0000e7b1 _fgets 0040f7b1 f LIBC:fgets.obj - 0001:0000e808 _fflush 0040f808 f LIBC:fflush.obj - 0001:0000e843 __flush 0040f843 f LIBC:fflush.obj - 0001:0000e89f __flushall 0040f89f f LIBC:fflush.obj - 0001:0000e915 _fprintf 0040f915 f LIBC:fprintf.obj - 0001:0000e947 _printf 0040f947 f LIBC:printf.obj - 0001:0000e980 _strcpy 0040f980 f LIBC:strcat.obj - 0001:0000e990 _strcat 0040f990 f LIBC:strcat.obj - 0001:0000ea70 __cinit 0040fa70 f LIBC:crt0dat.obj - 0001:0000ea9d _exit 0040fa9d f LIBC:crt0dat.obj - 0001:0000eaae __exit 0040faae f LIBC:crt0dat.obj - 0001:0000eabf __cexit 0040fabf f LIBC:crt0dat.obj - 0001:0000eace __c_exit 0040face f LIBC:crt0dat.obj - 0001:0000eb90 _system 0040fb90 f LIBC:system.obj - 0001:0000ec40 _strchr 0040fc40 f LIBC:strchr.obj - 0001:0000ec46 ___from_strstr_to_strchr 0040fc46 f LIBC:strchr.obj - 0001:0000ecfc _sscanf 0040fcfc f LIBC:sscanf.obj - 0001:0000ed30 _fputs 0040fd30 f LIBC:fputs.obj - 0001:0000ed73 __flsbuf 0040fd73 f LIBC:_flsbuf.obj - 0001:0000ee90 _strlen 0040fe90 f LIBC:strlen.obj - 0001:0000ef0b __isctype 0040ff0b f LIBC:isctype.obj - 0001:0000ef80 __fsopen 0040ff80 f LIBC:fopen.obj - 0001:0000efa0 _fopen 0040ffa0 f LIBC:fopen.obj - 0001:0000efb3 _sprintf 0040ffb3 f LIBC:sprintf.obj - 0001:0000f010 _strncat 00410010 f LIBC:strncat.obj - 0001:0000f133 _fclose 00410133 f LIBC:fclose.obj - 0001:0000f189 _fread 00410189 f LIBC:fread.obj - 0001:0000f271 _fwrite 00410271 f LIBC:fwrite.obj - 0001:0000f37b _atol 0041037b f LIBC:atox.obj - 0001:0000f406 _atoi 00410406 f LIBC:atox.obj - 0001:0000f411 __atoi64 00410411 f LIBC:atox.obj - 0001:0000f4cb __fputchar 004104cb f LIBC:fputchar.obj - 0001:0000f4fa _putchar 004104fa f LIBC:fputchar.obj - 0001:0000f505 _localtime 00410505 f LIBC:localtim.obj - 0001:0000f665 _time 00410665 f LIBC:time.obj - 0001:0000f741 _mainCRTStartup 00410741 f LIBC:crt0.obj - 0001:0000f820 __amsg_exit 00410820 f LIBC:crt0.obj - 0001:0000f869 __ioinit 00410869 f LIBC:ioinit.obj - 0001:0000fa14 __ioterm 00410a14 f LIBC:ioinit.obj - 0001:0000fa37 _calloc 00410a37 f LIBC:calloc.obj - 0001:0000fab4 __fcloseall 00410ab4 f LIBC:closeall.obj - 0001:0000fb0c __filbuf 00410b0c f LIBC:_filbuf.obj - 0001:0000fbe5 __commit 00410be5 f LIBC:commit.obj - 0001:0000fc3c __write 00410c3c f LIBC:write.obj - 0001:0000fc3c _write 00410c3c f LIBC:write.obj - 0001:0000fde9 __stbuf 00410de9 f LIBC:_sftbuf.obj - 0001:0000fe76 __ftbuf 00410e76 f LIBC:_sftbuf.obj - 0001:0000feb3 __output 00410eb3 f LIBC:output.obj - 0001:000106bd __spawnvpe 004116bd f LIBC:spawnvpe.obj - 0001:00010820 __spawnve 00411820 f LIBC:spawnve.obj - 0001:000109ba __access 004119ba f LIBC:access.obj - 0001:000109fe _getenv 004119fe f LIBC:getenv.obj - 0001:00010a7b __input 00411a7b f LIBC:input.obj - 0001:0001152c _lseek 0041252c f LIBC:lseek.obj - 0001:0001152c __lseek 0041252c f LIBC:lseek.obj - 0001:000115c6 __getbuf 004125c6 f LIBC:_getbuf.obj - 0001:0001160a __isatty 0041260a f LIBC:isatty.obj - 0001:0001160a _isatty 0041260a f LIBC:isatty.obj - 0001:00011630 ___crtGetStringTypeA 00412630 f LIBC:a_str.obj - 0001:00011779 __openfile 00412779 f LIBC:_open.obj - 0001:000118e9 __getstream 004128e9 f LIBC:stream.obj - 0001:00011961 _free 00412961 f LIBC:free.obj - 0001:00011990 __close 00412990 f LIBC:close.obj - 0001:00011a43 __freebuf 00412a43 f LIBC:_freebuf.obj - 0001:00011a6e __read 00412a6e f LIBC:read.obj - 0001:00011a6e _read 00412a6e f LIBC:read.obj - 0001:00011c70 _memcpy 00412c70 f LIBC:memcpy.obj - 0001:00011fb0 __allmul 00412fb0 f LIBC:llmul.obj - 0001:00011fe4 ___tzset 00412fe4 f LIBC:tzset.obj - 0001:00011ff9 __tzset 00412ff9 f LIBC:tzset.obj - 0001:00012257 __isindst 00413257 f LIBC:tzset.obj - 0001:00012543 _gmtime 00413543 f LIBC:gmtime.obj - 0001:0001263c ___loctotime_t 0041363c f LIBC:dtoxtime.obj - 0001:000126fe __XcptFilter 004136fe f LIBC:winxfltr.obj - 0001:00012882 __setenvp 00413882 f LIBC:stdenvp.obj - 0001:0001293b __setargv 0041393b f LIBC:stdargv.obj - 0001:00012b88 ___crtGetEnvironmentStringsA 00413b88 f LIBC:a_env.obj - 0001:00012cba __heap_init 00413cba f LIBC:heapinit.obj - 0001:00012cf6 __heap_term 00413cf6 f LIBC:heapinit.obj - 0001:00012d6c __global_unwind2 00413d6c f LIBC:exsup.obj - 0001:00012dae __local_unwind2 00413dae f LIBC:exsup.obj - 0001:00012e06 __NLG_Return2 00413e06 f LIBC:exsup.obj - 0001:00012e16 __abnormal_termination 00413e16 f LIBC:exsup.obj - 0001:00012e39 __NLG_Notify1 00413e39 f LIBC:exsup.obj - 0001:00012e42 __NLG_Notify 00413e42 f LIBC:exsup.obj - 0001:00012e55 __NLG_Dispatch 00413e55 f LIBC:exsup.obj - 0001:00012e64 __except_handler3 00413e64 f LIBC:exsup3.obj - 0001:00012f21 __seh_longjmp_unwind@4 00413f21 f LIBC:exsup3.obj - 0001:00012f3c __FF_MSGBANNER 00413f3c f LIBC:crt0msg.obj - 0001:00012f75 __NMSG_WRITE 00413f75 f LIBC:crt0msg.obj - 0001:000130c8 __GET_RTERRMSG 004140c8 f LIBC:crt0msg.obj - 0001:000130f9 _malloc 004140f9 f LIBC:malloc.obj - 0001:0001310b __nh_malloc 0041410b f LIBC:malloc.obj - 0001:00013137 __heap_alloc 00414137 f LIBC:malloc.obj - 0001:00013170 _memset 00414170 f LIBC:memset.obj - 0001:000131c8 ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z 004141c8 f LIBC:handler.obj - 0001:000131d8 ?_query_new_handler@@YAP6AHI@ZXZ 004141d8 f LIBC:handler.obj - 0001:000131de __callnewh 004141de f LIBC:handler.obj - 0001:000131f9 __get_sbh_threshold 004141f9 f LIBC:sbheap.obj - 0001:000131ff __set_sbh_threshold 004141ff f LIBC:sbheap.obj - 0001:00013216 ___sbh_heap_init 00414216 f LIBC:sbheap.obj - 0001:00013254 ___sbh_find_block 00414254 f LIBC:sbheap.obj - 0001:0001327f ___sbh_free_block 0041427f f LIBC:sbheap.obj - 0001:000135aa ___sbh_alloc_block 004145aa f LIBC:sbheap.obj - 0001:000138b3 ___sbh_alloc_new_region 004148b3 f LIBC:sbheap.obj - 0001:00013964 ___sbh_alloc_new_group 00414964 f LIBC:sbheap.obj - 0001:00013a5f ___sbh_resize_block 00414a5f f LIBC:sbheap.obj - 0001:00013d55 ___sbh_heapmin 00414d55 f LIBC:sbheap.obj - 0001:00013e26 ___sbh_heap_check 00414e26 f LIBC:sbheap.obj - 0001:00014155 __alloc_osfhnd 00415155 f LIBC:osfinfo.obj - 0001:000141ea __set_osfhnd 004151ea f LIBC:osfinfo.obj - 0001:00014261 __free_osfhnd 00415261 f LIBC:osfinfo.obj - 0001:000142db __get_osfhandle 004152db f LIBC:osfinfo.obj - 0001:00014318 __open_osfhandle 00415318 f LIBC:osfinfo.obj - 0001:000143b5 __dosmaperr 004153b5 f LIBC:dosmap.obj - 0001:0001441c _wctomb 0041541c f LIBC:wctomb.obj - 0001:00014490 __aulldiv 00415490 f LIBC:ulldiv.obj - 0001:00014500 __aullrem 00415500 f LIBC:ullrem.obj - 0001:00014575 __mbsrchr 00415575 f LIBC:mbsrchr.obj - 0001:000145d5 __getpath 004155d5 f LIBC:getpath.obj - 0001:00014649 __mbschr 00415649 f LIBC:mbschr.obj - 0001:000146bc __dospawn 004156bc f LIBC:dospawn.obj - 0001:0001489b __cenvarg 0041589b f LIBC:cenvarg.obj - 0001:00014a9f __mbsnbicoll 00415a9f f LIBC:mbsnbico.obj - 0001:00014ade ___wtomb_environ 00415ade f LIBC:wtombenv.obj - 0001:00014b4c _mbtowc 00415b4c f LIBC:mbtowc.obj - 0001:00014c14 _isalpha 00415c14 f LIBC:_ctype.obj - 0001:00014c42 _isupper 00415c42 f LIBC:_ctype.obj - 0001:00014c6a _islower 00415c6a f LIBC:_ctype.obj - 0001:00014c92 _isdigit 00415c92 f LIBC:_ctype.obj - 0001:00014cba _isxdigit 00415cba f LIBC:_ctype.obj - 0001:00014ce7 _isspace 00415ce7 f LIBC:_ctype.obj - 0001:00014d0f _ispunct 00415d0f f LIBC:_ctype.obj - 0001:00014d37 _isalnum 00415d37 f LIBC:_ctype.obj - 0001:00014d65 _isprint 00415d65 f LIBC:_ctype.obj - 0001:00014d93 _isgraph 00415d93 f LIBC:_ctype.obj - 0001:00014dc1 _iscntrl 00415dc1 f LIBC:_ctype.obj - 0001:00014de9 ___isascii 00415de9 f LIBC:_ctype.obj - 0001:00014df6 ___toascii 00415df6 f LIBC:_ctype.obj - 0001:00014dfe ___iscsymf 00415dfe f LIBC:_ctype.obj - 0001:00014e3b ___iscsym 00415e3b f LIBC:_ctype.obj - 0001:00014e80 __allshl 00415e80 f LIBC:llshl.obj - 0001:00014e9f _ungetc 00415e9f f LIBC:ungetc.obj - 0001:00014f10 __chkstk 00415f10 f LIBC:chkstk.obj - 0001:00014f10 __alloca_probe 00415f10 f LIBC:chkstk.obj - 0001:00014f3f __open 00415f3f f LIBC:open.obj - 0001:00014f3f _open 00415f3f f LIBC:open.obj - 0001:00014f56 __sopen 00415f56 f LIBC:open.obj - 0001:00015210 _strncpy 00416210 f LIBC:strncpy.obj - 0001:00015310 _strcmp 00416310 f LIBC:strcmp.obj - 0001:00015394 __setmbcp 00416394 f LIBC:mbctype.obj - 0001:00015758 __getmbcp 00416758 f LIBC:mbctype.obj - 0001:00015768 ___initmbctable 00416768 f LIBC:mbctype.obj - 0001:00015784 ___crtMessageBoxA 00416784 f LIBC:crtmbox.obj - 0001:00015810 _memmove 00416810 f LIBC:memmove.obj - 0001:00015b45 __fptrap 00416b45 f LIBC:crt0fp.obj - 0001:00015b50 _strrchr 00416b50 f LIBC:strrchr.obj - 0001:00015b77 ___crtCompareStringA 00416b77 f LIBC:a_cmp.obj - 0001:00015e1f ___crtsetenv 00416e1f f LIBC:setenv.obj - 0001:00016065 __chsize 00417065 f LIBC:chsize.obj - 0001:000161ab ___crtLCMapStringA 004171ab f LIBC:a_map.obj - 0001:000163fa _realloc 004173fa f LIBC:realloc.obj - 0001:0001651a __strdup 0041751a f LIBC:strdup.obj - 0001:00016545 __setmode 00417545 f LIBC:setmode.obj - 0001:000165c0 _ExitProcess@4 004175c0 f kernel32:KERNEL32.dll - 0001:000165c6 _TerminateProcess@8 004175c6 f kernel32:KERNEL32.dll - 0001:000165cc _GetCurrentProcess@0 004175cc f kernel32:KERNEL32.dll - 0001:000165d2 _GetTimeZoneInformation@4 004175d2 f kernel32:KERNEL32.dll - 0001:000165d8 _GetSystemTime@4 004175d8 f kernel32:KERNEL32.dll - 0001:000165de _GetLocalTime@4 004175de f kernel32:KERNEL32.dll - 0001:000165e4 _GetCommandLineA@0 004175e4 f kernel32:KERNEL32.dll - 0001:000165ea _GetVersion@0 004175ea f kernel32:KERNEL32.dll - 0001:000165f0 _SetHandleCount@4 004175f0 f kernel32:KERNEL32.dll - 0001:000165f6 _GetStdHandle@4 004175f6 f kernel32:KERNEL32.dll - 0001:000165fc _GetFileType@4 004175fc f kernel32:KERNEL32.dll - 0001:00016602 _GetStartupInfoA@4 00417602 f kernel32:KERNEL32.dll - 0001:00016608 _HeapAlloc@12 00417608 f kernel32:KERNEL32.dll - 0001:0001660e _GetLastError@0 0041760e f kernel32:KERNEL32.dll - 0001:00016614 _FlushFileBuffers@4 00417614 f kernel32:KERNEL32.dll - 0001:0001661a _WriteFile@20 0041761a f kernel32:KERNEL32.dll - 0001:00016620 _GetFileAttributesA@4 00417620 f kernel32:KERNEL32.dll - 0001:00016626 _SetFilePointer@16 00417626 f kernel32:KERNEL32.dll - 0001:0001662c _MultiByteToWideChar@24 0041762c f kernel32:KERNEL32.dll - 0001:00016632 _GetStringTypeA@20 00417632 f kernel32:KERNEL32.dll - 0001:00016638 _GetStringTypeW@16 00417638 f kernel32:KERNEL32.dll - 0001:0001663e _HeapFree@12 0041763e f kernel32:KERNEL32.dll - 0001:00016644 _CloseHandle@4 00417644 f kernel32:KERNEL32.dll - 0001:0001664a _ReadFile@20 0041764a f kernel32:KERNEL32.dll - 0001:00016650 _WideCharToMultiByte@32 00417650 f kernel32:KERNEL32.dll - 0001:00016656 _UnhandledExceptionFilter@4 00417656 f kernel32:KERNEL32.dll - 0001:0001665c _GetModuleFileNameA@12 0041765c f kernel32:KERNEL32.dll - 0001:00016662 _FreeEnvironmentStringsA@4 00417662 f kernel32:KERNEL32.dll - 0001:00016668 _FreeEnvironmentStringsW@4 00417668 f kernel32:KERNEL32.dll - 0001:0001666e _GetEnvironmentStrings@0 0041766e f kernel32:KERNEL32.dll - 0001:00016674 _GetEnvironmentStringsW@0 00417674 f kernel32:KERNEL32.dll - 0001:0001667a _HeapDestroy@4 0041767a f kernel32:KERNEL32.dll - 0001:00016680 _HeapCreate@12 00417680 f kernel32:KERNEL32.dll - 0001:00016686 _VirtualFree@12 00417686 f kernel32:KERNEL32.dll - 0001:0001668c _RtlUnwind@16 0041768c f kernel32:KERNEL32.dll - 0001:00016692 _VirtualAlloc@16 00417692 f kernel32:KERNEL32.dll - 0001:00016698 _HeapReAlloc@16 00417698 f kernel32:KERNEL32.dll - 0001:0001669e _IsBadWritePtr@8 0041769e f kernel32:KERNEL32.dll - 0001:000166a4 _SetStdHandle@8 004176a4 f kernel32:KERNEL32.dll - 0001:000166aa _GetExitCodeProcess@8 004176aa f kernel32:KERNEL32.dll - 0001:000166b0 _WaitForSingleObject@8 004176b0 f kernel32:KERNEL32.dll - 0001:000166b6 _CreateProcessA@40 004176b6 f kernel32:KERNEL32.dll - 0001:000166bc _CreateFileA@28 004176bc f kernel32:KERNEL32.dll - 0001:000166c2 _GetCPInfo@8 004176c2 f kernel32:KERNEL32.dll - 0001:000166c8 _GetACP@0 004176c8 f kernel32:KERNEL32.dll - 0001:000166ce _GetOEMCP@0 004176ce f kernel32:KERNEL32.dll - 0001:000166d4 _GetProcAddress@8 004176d4 f kernel32:KERNEL32.dll - 0001:000166da _LoadLibraryA@4 004176da f kernel32:KERNEL32.dll - 0001:000166e0 _CompareStringA@24 004176e0 f kernel32:KERNEL32.dll - 0001:000166e6 _CompareStringW@24 004176e6 f kernel32:KERNEL32.dll - 0001:000166ec _SetEnvironmentVariableA@8 004176ec f kernel32:KERNEL32.dll - 0001:000166f2 _SetEndOfFile@4 004176f2 f kernel32:KERNEL32.dll - 0001:000166f8 _LCMapStringA@24 004176f8 f kernel32:KERNEL32.dll - 0001:000166fe _LCMapStringW@24 004176fe f kernel32:KERNEL32.dll - 0001:00016710 __stricmp 00417710 f LIBC:stricmp.obj - 0001:00016710 _stricmp 00417710 f LIBC:stricmp.obj - 0001:00016710 __strcmpi 00417710 f LIBC:stricmp.obj - 0001:0001679c _chdir 0041779c f LIBC:chdir.obj - 0001:0001679c __chdir 0041779c f LIBC:chdir.obj - 0001:00016830 _memicmp 00417830 f LIBC:memicmp.obj - 0001:00016830 __memicmp 00417830 f LIBC:memicmp.obj - 0001:000168cd __fileno 004178cd f LIBC:fileno.obj - 0001:000168cd _fileno 004178cd f LIBC:fileno.obj - 0001:000168d5 __tolower 004178d5 f LIBC:tolower.obj - 0001:000168dd _tolower 004178dd f LIBC:tolower.obj - 0001:000169a8 __mbctoupper 004179a8 f LIBC:mbtoupr.obj - 0001:00016a24 _GetCurrentDirectoryA@8 00417a24 f kernel32:KERNEL32.dll - 0001:00016a2a _SetCurrentDirectoryA@4 00417a2a f kernel32:KERNEL32.dll - 0002:0000001c ??_C@_07OOMJ@cmd?4exe?$AA@ 0041b01c LIBC:system.obj - 0002:00000024 ??_C@_0M@IPJP@command?4com?$AA@ 0041b024 LIBC:system.obj - 0002:00000030 ??_C@_02JMK@?1c?$AA@ 0041b030 LIBC:system.obj - 0002:00000034 ??_C@_07KFDO@COMSPEC?$AA@ 0041b034 LIBC:system.obj - 0002:0000004c ___lookuptable 0041b04c LIBC:output.obj - 0002:000000a8 ??_C@_1O@POHA@?$AA?$CI?$AAn?$AAu?$AAl?$AAl?$AA?$CJ?$AA?$AA@ 0041b0a8 LIBC:output.obj - 0002:000000b8 ??_C@_06ONKE@?$CInull?$CJ?$AA@ 0041b0b8 LIBC:output.obj - 0002:000000c0 ??_C@_01PCFE@?2?$AA@ 0041b0c0 LIBC:spawnvpe.obj - 0002:000000c4 ??_C@_04LNMG@PATH?$AA@ 0041b0c4 LIBC:spawnvpe.obj - 0002:000000cc ??_C@_04GGNP@?4com?$AA@ 0041b0cc LIBC:spawnve.obj - 0002:000000d4 ??_C@_04NFOM@?4exe?$AA@ 0041b0d4 LIBC:spawnve.obj - 0002:000000dc ??_C@_04KBDN@?4bat?$AA@ 0041b0dc LIBC:spawnve.obj - 0002:000000e4 ??_C@_04LFKF@?4cmd?$AA@ 0041b0e4 LIBC:spawnve.obj - 0002:000000ec ??_C@_02OFKN@?4?2?$AA@ 0041b0ec LIBC:spawnve.obj - 0002:000000f0 ??_C@_01A@?$AA?$AA@ 0041b0f0 LIBC:a_str.obj - 0002:000000f4 ??_C@_13A@?$AA?$AA?$AA?$AA@ 0041b0f4 LIBC:a_str.obj - 0002:00000104 ___dnames 0041b104 LIBC:timeset.obj - 0002:0000011c ___mnames 0041b11c LIBC:timeset.obj - 0002:00000144 ??_C@_02JHIA@TZ?$AA@ 0041b144 LIBC:tzset.obj - 0002:00000148 ??_C@_0P@GGKG@runtime?5error?5?$AA@ 0041b148 LIBC:crt0msg.obj - 0002:00000158 ??_C@_02PIMC@?$AN?6?$AA@ 0041b158 LIBC:crt0msg.obj - 0002:0000015c ??_C@_0O@DELO@TLOSS?5error?$AN?6?$AA@ 0041b15c LIBC:crt0msg.obj - 0002:0000016c ??_C@_0N@OMLL@SING?5error?$AN?6?$AA@ 0041b16c LIBC:crt0msg.obj - 0002:0000017c ??_C@_0P@OJAK@DOMAIN?5error?$AN?6?$AA@ 0041b17c LIBC:crt0msg.obj - 0002:0000018c ??_C@_0CF@EANP@R6028?$AN?6?9?5unable?5to?5initialize?5he@ 0041b18c LIBC:crt0msg.obj - 0002:000001b4 ??_C@_0DF@ECGN@R6027?$AN?6?9?5not?5enough?5space?5for?5lo@ 0041b1b4 LIBC:crt0msg.obj - 0002:000001ec ??_C@_0DF@FKAC@R6026?$AN?6?9?5not?5enough?5space?5for?5st@ 0041b1ec LIBC:crt0msg.obj - 0002:00000224 ??_C@_0CG@DPMN@R6025?$AN?6?9?5pure?5virtual?5function?5c@ 0041b224 LIBC:crt0msg.obj - 0002:0000024c ??_C@_0DF@CKIP@R6024?$AN?6?9?5not?5enough?5space?5for?5_o@ 0041b24c LIBC:crt0msg.obj - 0002:00000284 ??_C@_0CJ@GGOE@R6019?$AN?6?9?5unable?5to?5open?5console?5@ 0041b284 LIBC:crt0msg.obj - 0002:000002b0 ??_C@_0CB@LBOB@R6018?$AN?6?9?5unexpected?5heap?5error?$AN?6@ 0041b2b0 LIBC:crt0msg.obj - 0002:000002d4 ??_C@_0CN@FPEG@R6017?$AN?6?9?5unexpected?5multithread?5@ 0041b2d4 LIBC:crt0msg.obj - 0002:00000304 ??_C@_0CM@OBIC@R6016?$AN?6?9?5not?5enough?5space?5for?5th@ 0041b304 LIBC:crt0msg.obj - 0002:00000330 ??_C@_0CB@HPAL@?$AN?6abnormal?5program?5termination?$AN?6@ 0041b330 LIBC:crt0msg.obj - 0002:00000354 ??_C@_0CM@JOOB@R6009?$AN?6?9?5not?5enough?5space?5for?5en@ 0041b354 LIBC:crt0msg.obj - 0002:00000380 ??_C@_0CK@OIBL@R6008?$AN?6?9?5not?5enough?5space?5for?5ar@ 0041b380 LIBC:crt0msg.obj - 0002:000003ac ??_C@_0CF@LKPB@R6002?$AN?6?9?5floating?5point?5not?5load@ 0041b3ac LIBC:crt0msg.obj - 0002:000003d4 ??_C@_0CF@JPDF@Microsoft?5Visual?5C?$CL?$CL?5Runtime?5Lib@ 0041b3d4 LIBC:crt0msg.obj - 0002:000003fc ??_C@_02JJJH@?6?6?$AA@ 0041b3fc LIBC:crt0msg.obj - 0002:00000400 ??_C@_0BK@DEOK@Runtime?5Error?$CB?6?6Program?3?5?$AA@ 0041b400 LIBC:crt0msg.obj - 0002:0000041c ??_C@_03NAME@?4?4?4?$AA@ 0041b41c LIBC:crt0msg.obj - 0002:00000420 ??_C@_0BH@NNCD@?$DMprogram?5name?5unknown?$DO?$AA@ 0041b420 LIBC:crt0msg.obj - 0002:00000438 ??_C@_0BD@NJFP@GetLastActivePopup?$AA@ 0041b438 LIBC:crtmbox.obj - 0002:0000044c ??_C@_0BA@GILI@GetActiveWindow?$AA@ 0041b44c LIBC:crtmbox.obj - 0002:0000045c ??_C@_0M@PKCK@MessageBoxA?$AA@ 0041b45c LIBC:crtmbox.obj - 0002:00000468 ??_C@_0L@HKL@user32?4dll?$AA@ 0041b468 LIBC:crtmbox.obj - 0003:00000000 ___xc_a 0041c000 LIBC:crt0init.obj - 0003:00000104 ___xc_z 0041c104 LIBC:crt0init.obj - 0003:00000208 ___xi_a 0041c208 LIBC:crt0init.obj - 0003:00000418 ___xi_z 0041c418 LIBC:crt0init.obj - 0003:0000051c ___xp_a 0041c51c LIBC:crt0init.obj - 0003:00000724 ___xp_z 0041c724 LIBC:crt0init.obj - 0003:00000828 ___xt_a 0041c828 LIBC:crt0init.obj - 0003:0000092c ___xt_z 0041c92c LIBC:crt0init.obj - 0003:00000a30 _in 0041ca30 ucp.obj - 0003:00000a34 _rdev 0041ca34 ucp.obj - 0003:00000a38 _syserror 0041ca38 ucp.obj - 0003:00000a3c _help 0041ca3c ucp.obj - 0003:000016c4 _cmdblk 0041d6c4 devhd.obj - 0003:000016cc _busid 0041d6cc devhd.obj - 0003:00001708 _dev_tab 0041d708 devio.obj - 0003:00001898 _tty_default 0041d898 devtty.obj - 0003:000018a8 _tty_vector 0041d8a8 devtty.obj - 0003:000018d0 _ttyinq 0041d8d0 devtty.obj - 0003:00001a00 _baddevmsg 0041da00 filesys.obj - 0003:00001d4c _UZIX 0041dd4c main.obj - 0003:00001d5c _HOST 0041dd5c main.obj - 0003:00001ec8 _stringerr 0041dec8 xfs.obj - 0003:00002450 __iob 0041e450 LIBC:_file.obj - 0003:000026d0 __pctype 0041e6d0 LIBC:ctype.obj - 0003:000026d4 __pwctype 0041e6d4 LIBC:ctype.obj - 0003:000026d8 __ctype 0041e6d8 LIBC:ctype.obj - 0003:000028dc ___mb_cur_max 0041e8dc LIBC:nlsdata1.obj - 0003:000028e0 ___decimal_point 0041e8e0 LIBC:nlsdata1.obj - 0003:000028e4 ___decimal_point_length 0041e8e4 LIBC:nlsdata1.obj - 0003:000028f0 __aexit_rtn 0041e8f0 LIBC:crt0.obj - 0003:000028f4 ___app_type 0041e8f4 LIBC:crt0.obj - 0003:000028f8 ___badioinfo 0041e8f8 LIBC:ioinit.obj - 0003:00002900 ___nullstring 0041e900 LIBC:output.obj - 0003:00002904 ___wnullstring 0041e904 LIBC:output.obj - 0003:00002930 __timezone 0041e930 LIBC:timeset.obj - 0003:00002934 __daylight 0041e934 LIBC:timeset.obj - 0003:00002938 __dstbias 0041e938 LIBC:timeset.obj - 0003:000029bc __tzname 0041e9bc LIBC:timeset.obj - 0003:000029e8 __XcptActTab 0041e9e8 LIBC:winxfltr.obj - 0003:00002a60 __First_FPE_Indx 0041ea60 LIBC:winxfltr.obj - 0003:00002a64 __Num_FPE 0041ea64 LIBC:winxfltr.obj - 0003:00002a68 __XcptActTabCount 0041ea68 LIBC:winxfltr.obj - 0003:00002a6c __fpecode 0041ea6c LIBC:winxfltr.obj - 0003:00002a70 __amblksiz 0041ea70 LIBC:heapinit.obj - 0003:00002a74 __NLG_Destination 0041ea74 LIBC:exsup.obj - 0003:00002b20 ___sbh_threshold 0041eb20 LIBC:sbheap.obj - 0003:00002c90 __cfltcvt_tab 0041ec90 LIBC:cmiscdat.obj - 0003:00002cb0 __p_overlay 0041ecb0 LIBC:dospawn.obj - 0003:00002cc0 __lpdays 0041ecc0 LIBC:days.obj - 0003:00002cf4 __days 0041ecf4 LIBC:days.obj - 0003:00003120 _f_pause 0041f120 ucp.obj - 0003:00003121 _unix_locked_out 0041f121 - 0003:00003122 _swapblk 0041f122 - 0003:00003124 _hd_offset 0041f124 devhd.obj - 0003:00003128 _hd_sector 0041f128 devhd.obj - 0003:0000312c _dptr 0041f12c devhd.obj - 0003:00003130 _dlen 0041f130 devhd.obj - 0003:00003134 _cptr 0041f134 devhd.obj - 0003:00003139 _dirty_mask 0041f139 - 0003:0000313a _inint 0041f13a - 0003:0000313c _initproc 0041f13c - 0003:00003140 _bufclock 0041f140 devio.obj - 0003:00003148 _swapcnt 0041f148 - 0003:0000314d _traceon 0041f14d - 0003:0000314e _sec 0041f14e - 0003:00003159 _total 0041f159 - 0003:0000315a _waitno 0041f15a - 0003:00003164 _tod 0041f164 - 0003:00003174 _runticks 0041f174 - 0003:00003176 _root_dev 0041f176 - 0003:00003188 __cflush 0041f188 LIBC:_file.obj - 0003:0000318c _errno 0041f18c LIBC:crt0dat.obj - 0003:00003190 __doserrno 0041f190 LIBC:crt0dat.obj - 0003:00003194 __umaskval 0041f194 LIBC:crt0dat.obj - 0003:00003198 __osver 0041f198 LIBC:crt0dat.obj - 0003:0000319c __winver 0041f19c LIBC:crt0dat.obj - 0003:000031a0 __winmajor 0041f1a0 LIBC:crt0dat.obj - 0003:000031a4 __winminor 0041f1a4 LIBC:crt0dat.obj - 0003:000031a8 ___argc 0041f1a8 LIBC:crt0dat.obj - 0003:000031ac ___argv 0041f1ac LIBC:crt0dat.obj - 0003:000031b0 ___wargv 0041f1b0 LIBC:crt0dat.obj - 0003:000031b4 __environ 0041f1b4 LIBC:crt0dat.obj - 0003:000031b8 ___initenv 0041f1b8 LIBC:crt0dat.obj - 0003:000031bc __wenviron 0041f1bc LIBC:crt0dat.obj - 0003:000031c0 ___winitenv 0041f1c0 LIBC:crt0dat.obj - 0003:000031c4 __pgmptr 0041f1c4 LIBC:crt0dat.obj - 0003:000031c8 __wpgmptr 0041f1c8 LIBC:crt0dat.obj - 0003:000031cc __exitflag 0041f1cc LIBC:crt0dat.obj - 0003:000031d0 __C_Termination_Done 0041f1d0 LIBC:crt0dat.obj - 0003:000031d4 __C_Exit_Done 0041f1d4 LIBC:crt0dat.obj - 0003:000031f0 __aenvptr 0041f1f0 LIBC:crt0.obj - 0003:000031f4 __wenvptr 0041f1f4 LIBC:crt0.obj - 0003:000031f8 ___error_mode 0041f1f8 LIBC:crt0.obj - 0003:000031fc __stdbuf 0041f1fc LIBC:_sftbuf.obj - 0003:000032c4 _swapbase 0041f2c4 - 0003:000032ec __pxcptinfoptrs 0041f2ec LIBC:winxfltr.obj - 0003:000033f8 __adbgmsg 0041f3f8 LIBC:crt0msg.obj - 0003:000033fc ?_pnhHeap@@3P6AHI@ZA 0041f3fc LIBC:handler.obj - 0003:00003400 __newmode 0041f400 LIBC:_newmode.obj - 0003:00003404 ___lc_handle 0041f404 LIBC:nlsdata2.obj - 0003:0000341c ___lc_codepage 0041f41c LIBC:nlsdata2.obj - 0003:00003420 ___lc_collate_cp 0041f420 LIBC:nlsdata2.obj - 0003:00003424 __commode 0041f424 LIBC:ncommode.obj - 0003:0000343c __fmode 0041f43c LIBC:txtmode.obj - 0003:00003444 _ticks 0041f444 - 0003:00003448 _root_ino 0041f448 - 0003:0000344c _ncalls 0041f44c - 0003:00003450 _ibuf 0041f450 - 0003:0000345c _osBank 0041f45c - 0003:00003460 _bufpool 0041f460 - 0003:00005d50 _disp_tab 00421d50 - 0003:00005d54 _buf_flsh 00421d54 - 0003:00005d58 _buf_hits 00421d58 - 0003:00005d5c _buf_miss 00421d5c - 0003:00005d60 _fs_tab 00421d60 - 0003:00005de0 _of_tab 00421de0 - 0003:00005f60 _i_tab 00421f60 - 0003:00006b40 _ub 00422b40 - 0003:00007b40 _ptab 00423b40 - 0003:00007c80 _kbuf 00423c80 - 0003:00007cc0 _recv_bufs 00423cc0 - 0003:000089c0 _stopflag 004249c0 - 0003:00008a00 _flshflag 00424a00 - 0003:00008a40 _tty_data 00424a40 - 0003:00008ae0 _cwd 00424ae0 - 0003:00008b80 _line 00424b80 - 0003:00009024 ___mbcodepage 00425024 - 0003:000090a0 ___mbulinfo 004250a0 - 0003:000090ac ___ismbcodepage 004250ac - 0003:000090c0 __mbcasemap 004250c0 - 0003:000091c0 __mbctype 004251c0 - 0003:000092c4 ___mblcid 004252c4 - 0003:000092c8 ___sbh_sizeHeaderList 004252c8 - 0003:000092d8 ___sbh_indGroupDefer 004252d8 - 0003:000092dc ___sbh_pHeaderScan 004252dc - 0003:000092e0 ___sbh_pHeaderDefer 004252e0 - 0003:000092e4 ___sbh_cntHeaderList 004252e4 - 0003:000092e8 ___sbh_pHeaderList 004252e8 - 0003:000092ec __crtheap 004252ec - 0003:00009300 ___pioinfo 00425300 - 0003:0000943c __nhandle 0042543c - 0003:00009440 __acmdln 00425440 - 0003:0000944c ___env_initialized 0042544c - 0003:0000945c ___mbctype_initialized 0042545c - 0003:00009460 ___onexitend 00425460 - 0003:00009464 ___onexitbegin 00425464 - 0003:00009468 __FPinit 00425468 - 0003:0000946c ___piob 0042546c - 0003:000097c0 __bufin 004257c0 - 0003:0000a7c0 __nstream 004267c0 - 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 00427000 kernel32:KERNEL32.dll - 0004:00000014 __NULL_IMPORT_DESCRIPTOR 00427014 kernel32:KERNEL32.dll - 0004:00000160 __imp__FreeEnvironmentStringsW@4 00427160 kernel32:KERNEL32.dll - 0004:00000164 __imp__TerminateProcess@8 00427164 kernel32:KERNEL32.dll - 0004:00000168 __imp__GetCurrentProcess@0 00427168 kernel32:KERNEL32.dll - 0004:0000016c __imp__GetTimeZoneInformation@4 0042716c kernel32:KERNEL32.dll - 0004:00000170 __imp__GetSystemTime@4 00427170 kernel32:KERNEL32.dll - 0004:00000174 __imp__GetLocalTime@4 00427174 kernel32:KERNEL32.dll - 0004:00000178 __imp__GetCommandLineA@0 00427178 kernel32:KERNEL32.dll - 0004:0000017c __imp__GetVersion@0 0042717c kernel32:KERNEL32.dll - 0004:00000180 __imp__SetHandleCount@4 00427180 kernel32:KERNEL32.dll - 0004:00000184 __imp__GetStdHandle@4 00427184 kernel32:KERNEL32.dll - 0004:00000188 __imp__GetFileType@4 00427188 kernel32:KERNEL32.dll - 0004:0000018c __imp__GetStartupInfoA@4 0042718c kernel32:KERNEL32.dll - 0004:00000190 __imp__HeapAlloc@12 00427190 kernel32:KERNEL32.dll - 0004:00000194 __imp__GetLastError@0 00427194 kernel32:KERNEL32.dll - 0004:00000198 __imp__FlushFileBuffers@4 00427198 kernel32:KERNEL32.dll - 0004:0000019c __imp__WriteFile@20 0042719c kernel32:KERNEL32.dll - 0004:000001a0 __imp__GetFileAttributesA@4 004271a0 kernel32:KERNEL32.dll - 0004:000001a4 __imp__SetFilePointer@16 004271a4 kernel32:KERNEL32.dll - 0004:000001a8 __imp__MultiByteToWideChar@24 004271a8 kernel32:KERNEL32.dll - 0004:000001ac __imp__GetStringTypeA@20 004271ac kernel32:KERNEL32.dll - 0004:000001b0 __imp__GetStringTypeW@16 004271b0 kernel32:KERNEL32.dll - 0004:000001b4 __imp__HeapFree@12 004271b4 kernel32:KERNEL32.dll - 0004:000001b8 __imp__CloseHandle@4 004271b8 kernel32:KERNEL32.dll - 0004:000001bc __imp__ReadFile@20 004271bc kernel32:KERNEL32.dll - 0004:000001c0 __imp__WideCharToMultiByte@32 004271c0 kernel32:KERNEL32.dll - 0004:000001c4 __imp__UnhandledExceptionFilter@4 004271c4 kernel32:KERNEL32.dll - 0004:000001c8 __imp__GetModuleFileNameA@12 004271c8 kernel32:KERNEL32.dll - 0004:000001cc __imp__FreeEnvironmentStringsA@4 004271cc kernel32:KERNEL32.dll - 0004:000001d0 __imp__ExitProcess@4 004271d0 kernel32:KERNEL32.dll - 0004:000001d4 __imp__GetEnvironmentStrings@0 004271d4 kernel32:KERNEL32.dll - 0004:000001d8 __imp__GetEnvironmentStringsW@0 004271d8 kernel32:KERNEL32.dll - 0004:000001dc __imp__HeapDestroy@4 004271dc kernel32:KERNEL32.dll - 0004:000001e0 __imp__HeapCreate@12 004271e0 kernel32:KERNEL32.dll - 0004:000001e4 __imp__VirtualFree@12 004271e4 kernel32:KERNEL32.dll - 0004:000001e8 __imp__RtlUnwind@16 004271e8 kernel32:KERNEL32.dll - 0004:000001ec __imp__VirtualAlloc@16 004271ec kernel32:KERNEL32.dll - 0004:000001f0 __imp__HeapReAlloc@16 004271f0 kernel32:KERNEL32.dll - 0004:000001f4 __imp__IsBadWritePtr@8 004271f4 kernel32:KERNEL32.dll - 0004:000001f8 __imp__SetStdHandle@8 004271f8 kernel32:KERNEL32.dll - 0004:000001fc __imp__GetExitCodeProcess@8 004271fc kernel32:KERNEL32.dll - 0004:00000200 __imp__WaitForSingleObject@8 00427200 kernel32:KERNEL32.dll - 0004:00000204 __imp__CreateProcessA@40 00427204 kernel32:KERNEL32.dll - 0004:00000208 __imp__CreateFileA@28 00427208 kernel32:KERNEL32.dll - 0004:0000020c __imp__GetCPInfo@8 0042720c kernel32:KERNEL32.dll - 0004:00000210 __imp__GetACP@0 00427210 kernel32:KERNEL32.dll - 0004:00000214 __imp__GetOEMCP@0 00427214 kernel32:KERNEL32.dll - 0004:00000218 __imp__GetProcAddress@8 00427218 kernel32:KERNEL32.dll - 0004:0000021c __imp__LoadLibraryA@4 0042721c kernel32:KERNEL32.dll - 0004:00000220 __imp__CompareStringA@24 00427220 kernel32:KERNEL32.dll - 0004:00000224 __imp__CompareStringW@24 00427224 kernel32:KERNEL32.dll - 0004:00000228 __imp__SetEnvironmentVariableA@8 00427228 kernel32:KERNEL32.dll - 0004:0000022c __imp__SetEndOfFile@4 0042722c kernel32:KERNEL32.dll - 0004:00000230 __imp__LCMapStringA@24 00427230 kernel32:KERNEL32.dll - 0004:00000234 __imp__LCMapStringW@24 00427234 kernel32:KERNEL32.dll - 0004:00000238 __imp__GetCurrentDirectoryA@8 00427238 kernel32:KERNEL32.dll - 0004:0000023c __imp__SetCurrentDirectoryA@4 0042723c kernel32:KERNEL32.dll - 0004:00000240 \177KERNEL32_NULL_THUNK_DATA 00427240 kernel32:KERNEL32.dll + 0001:000008c0 _pse 004018c0 f ucp.obj + 0001:00000906 _dohelp 00401906 f ucp.obj + 0001:0000094d _eq 0040194d f ucp.obj + 0001:00000967 _execute 00401967 f ucp.obj + 0001:00000f45 _usage 00401f45 f ucp.obj + 0001:00000f63 _main 00401f63 f ucp.obj + 0001:00001aa0 _ldir 00402aa0 f ucpsub.obj + 0001:00001ae1 _devdir 00402ae1 f ucpsub.obj + 0001:00001b5c _prot 00402b5c f ucpsub.obj + 0001:00001b6e _dols 00402b6e f ucpsub.obj + 0001:0000212e _xls 0040312e f ucpsub.obj + 0001:00002224 _xchmod 00403224 f ucpsub.obj + 0001:000022a4 _xchown 004032a4 f ucpsub.obj + 0001:00002344 _xchgrp 00403344 f ucpsub.obj + 0001:000023e4 _xumask 004033e4 f ucpsub.obj + 0001:00002465 _xmknod 00403465 f ucpsub.obj + 0001:00002599 _xmkdir 00403599 f ucpsub.obj + 0001:000025e0 _xget 004035e0 f ucpsub.obj + 0001:0000278b _xput 0040378b f ucpsub.obj + 0001:00002922 _xtype 00403922 f ucpsub.obj + 0001:000029c0 _xdump 004039c0 f ucpsub.obj + 0001:00002c7e _xunlink 00403c7e f ucpsub.obj + 0001:00002d64 _xrmdir 00403d64 f ucpsub.obj + 0001:00002f68 _xdf 00403f68 f ucpsub.obj + 0001:00003027 _xalign 00404027 f ucpsub.obj + 0001:0000311c _xualign 0040411c f ucpsub.obj + 0001:000037b0 _wd_read 004047b0 f devhd.obj + 0001:000037e7 _wd_write 004047e7 f devhd.obj + 0001:0000381e _setup 0040481e f devhd.obj + 0001:0000397b _chkstat 0040497b f devhd.obj + 0001:000039c1 _wd_open 004049c1 f devhd.obj + 0001:00003a50 _bread 00404a50 f devio.obj + 0001:00003b87 _bfree 00404b87 f devio.obj + 0001:00003c3e _zerobuf 00404c3e f devio.obj + 0001:00003cc5 _bufsync 00404cc5 f devio.obj + 0001:00003d39 _bfind 00404d39 f devio.obj + 0001:00003d91 _freebuf 00404d91 f devio.obj + 0001:00003ed3 _bufdump 00404ed3 f devio.obj + 0001:00003fba _validdev 00404fba f devio.obj + 0001:00004045 _bdreadwrite 00405045 f devio.obj + 0001:000040c3 _cdreadwrite 004050c3 f devio.obj + 0001:00004129 _d_openclose 00405129 f devio.obj + 0001:00004189 _d_ioctl 00405189 f devio.obj + 0001:000041df _d_init 004051df f devio.obj + 0001:0000423e _ok 0040523e f devio.obj + 0001:00004245 _ok_rdwr 00405245 f devio.obj + 0001:0000424c _nogood 0040524c f devio.obj + 0001:00004254 _nogood_ioctl 00405254 f devio.obj + 0001:0000425c _insq 0040525c f devio.obj + 0001:000042ce _remq 004052ce f devio.obj + 0001:0000433c _uninsq 0040533c f devio.obj + 0001:000043af _clrq 004053af f devio.obj + 0001:00004640 _mem_read 00405640 f devmisc.obj + 0001:000046a1 _mem_write 004056a1 f devmisc.obj + 0001:00004704 _null_write 00405704 f devmisc.obj + 0001:0000470e _lpr_open 0040570e f devmisc.obj + 0001:0000471c _lpr_close 0040571c f devmisc.obj + 0001:00004735 _lpr_write 00405735 f devmisc.obj + 0001:0000479b _mt_read 0040579b f devmisc.obj + 0001:000047a3 _mt_write 004057a3 f devmisc.obj + 0001:000047ab _mt_open 004057ab f devmisc.obj + 0001:000047b3 _mt_close 004057b3 f devmisc.obj + 0001:00004820 _tty_read 00405820 f devtty.obj + 0001:000049d3 _tty_write 004059d3 f devtty.obj + 0001:00004b50 _tty_open 00405b50 f devtty.obj + 0001:00004be7 _tty_close 00405be7 f devtty.obj + 0001:00004c4b _tty_ioctl 00405c4b f devtty.obj + 0001:00004de9 _tty_inproc 00405de9 f devtty.obj + 0001:00005191 _tty_inproc_dummy 00406191 f devtty.obj + 0001:00005196 _echo 00406196 f devtty.obj + 0001:00005430 _findfs 00406430 f filesys.obj + 0001:0000547c _getfs 0040647c f filesys.obj + 0001:000054d1 _wr_inode 004064d1 f filesys.obj + 0001:000055a4 _i_ref 004065a4 f filesys.obj + 0001:00005602 _i_deref 00406602 f filesys.obj + 0001:000056d9 _i_free 004066d9 f filesys.obj + 0001:00005772 __namei 00406772 f filesys.obj + 0001:00005949 _namei 00406949 f filesys.obj + 0001:00005ca7 _srch_dir 00406ca7 f filesys.obj + 0001:00005dd7 _srch_mt 00406dd7 f filesys.obj + 0001:00005e37 _i_open 00406e37 f filesys.obj + 0001:000060fe _ch_link 004070fe f filesys.obj + 0001:000062a7 _filename 004072a7 f filesys.obj + 0001:0000634e _namecomp 0040734e f filesys.obj + 0001:000063d4 _newfile 004073d4 f filesys.obj + 0001:000064b0 _doclose 004074b0 f filesys.obj + 0001:00006551 _i_alloc 00407551 f filesys.obj + 0001:00006656 _blk_alloc 00407656 f filesys.obj + 0001:00006790 _blk_free 00407790 f filesys.obj + 0001:0000683e _oft_alloc 0040783e f filesys.obj + 0001:000068ae _oft_deref 004078ae f filesys.obj + 0001:00006906 _uf_alloc 00407906 f filesys.obj + 0001:0000695e _isdevice 0040795e f filesys.obj + 0001:000069a5 _freeblk 004079a5 f filesys.obj + 0001:00006a46 _f_trunc 00407a46 f filesys.obj + 0001:00006aff _bmap 00407aff f filesys.obj + 0001:00006d5f _validblk 00407d5f f filesys.obj + 0001:00006dde _getinode 00407dde f filesys.obj + 0001:00006eba _getperm 00407eba f filesys.obj + 0001:00006f5a _setftim 00407f5a f filesys.obj + 0001:00006fc4 _fmount 00407fc4 f filesys.obj + 0001:0000717c _magic 0040817c f filesys.obj + 0001:000071a6 _i_sync 004081a6 f filesys.obj + 0001:0000721b _fs_sync 0040821b f filesys.obj + 0001:00007a50 _scsiop 00408a50 f hdasm.obj + 0001:00007b70 _fs_init 00408b70 f machdep.obj + 0001:00007b91 _valadr 00408b91 f machdep.obj + 0001:00007b9b _addtick 00408b9b f machdep.obj + 0001:00007bf9 _incrtick 00408bf9 f machdep.obj + 0001:00007c38 _calltrap 00408c38 f machdep.obj + 0001:00007cbe _sttime 00408cbe f machdep.obj + 0001:00007cd6 _panic 00408cd6 f machdep.obj + 0001:00007d24 _warning 00408d24 f machdep.obj + 0001:00007d58 _idump 00408d58 f machdep.obj + 0001:00007ff0 _abort 00408ff0 f main.obj + 0001:0000800e _rdtime 0040900e f main.obj + 0001:000080b0 _init2 004090b0 f process.obj + 0001:000082d1 _psleep 004092d1 f process.obj + 0001:0000834d _wakeup 0040934d f process.obj + 0001:00008398 _getproc 00409398 f process.obj + 0001:000083f1 _newproc 004093f1 f process.obj + 0001:00008537 _ptab_alloc 00409537 f process.obj + 0001:000085ec _clkint2 004095ec f process.obj + 0001:00008730 _unix2 00409730 f process.obj + 0001:000087b8 _chksigs 004097b8 f process.obj + 0001:00008862 _sgrpsig 00409862 f process.obj + 0001:000088ae _ssig 004098ae f process.obj + 0001:00008925 _sendsig 00409925 f process.obj + 0001:00008979 _dowait 00409979 f process.obj + 0001:00008cf0 _sys_NONE 00409cf0 f scall1.obj + 0001:00008d02 _sys_sync 00409d02 f scall1.obj + 0001:00008d13 _sys_utime 00409d13 f scall1.obj + 0001:00008e34 _sys_close 00409e34 f scall1.obj + 0001:00008e47 _truncateto0 00409e47 f scall1.obj + 0001:00008ec0 _sys_open 00409ec0 f scall1.obj + 0001:000091f9 _sys_link 0040a1f9 f scall1.obj + 0001:00009344 _sys_symlink 0040a344 f scall1.obj + 0001:00009432 _sys_unlink 0040a432 f scall1.obj + 0001:0000954c _sys_readwrite 0040a54c f scall1.obj + 0001:000095e2 _sys_lseek 0040a5e2 f scall1.obj + 0001:000096c0 _sys_chdir 0040a6c0 f scall1.obj + 0001:0000974f _sys_chroot 0040a74f f scall1.obj + 0001:0000978d _sys_mknod 0040a78d f scall1.obj + 0001:00009868 _sys_access 0040a868 f scall1.obj + 0001:0000994f _sys_chmod 0040a94f f scall1.obj + 0001:00009a33 _sys_chown 0040aa33 f scall1.obj + 0001:00009a5a _stcpy 0040aa5a f scall1.obj + 0001:00009af7 _sys_statfstat 0040aaf7 f scall1.obj + 0001:00009b8a _sys_falign 0040ab8a f scall1.obj + 0001:00009bf4 _sys_dup 0040abf4 f scall1.obj + 0001:00009c7f _sys_dup2 0040ac7f f scall1.obj + 0001:00009d2b _sys_getfsys 0040ad2b f scall1.obj + 0001:00009d86 _sys_ioctl 0040ad86 f scall1.obj + 0001:00009e19 _sys_mountumount 0040ae19 f scall1.obj + 0001:0000a07c _sys_time 0040b07c f scall1.obj + 0001:0000a0b4 _exit0 0040b0b4 f scall1.obj + 0001:0000a0c5 _n_creat 0040b0c5 f scall1.obj + 0001:0000a281 _readwritei 0040b281 f scall1.obj + 0001:0000a7ab _rwsetup 0040b7ab f scall1.obj + 0001:0000a858 _getfsys 0040b858 f scall1.obj + 0001:0000b160 _findprocess 0040c160 f scall2.obj + 0001:0000b1c5 _filldesc 0040c1c5 f scall2.obj + 0001:0000b1fb _sys_pipe 0040c1fb f scall2.obj + 0001:0000b392 _sys_stime 0040c392 f scall2.obj + 0001:0000b3e1 _sys_times 0040c3e1 f scall2.obj + 0001:0000b430 _sys_brk 0040c430 f scall2.obj + 0001:0000b46c _sys_sbrk 0040c46c f scall2.obj + 0001:0000b4b2 _sys_waitpid 0040c4b2 f scall2.obj + 0001:0000b52d _sys__exit 0040c52d f scall2.obj + 0001:0000b545 _doexit 0040c545 f scall2.obj + 0001:0000b67e _sys_fork 0040c67e f scall2.obj + 0001:0000b683 _sys_pause 0040c683 f scall2.obj + 0001:0000b69f _sys_signal 0040c69f f scall2.obj + 0001:0000b758 _sys_kill 0040c758 f scall2.obj + 0001:0000b7bc _sys_alarm 0040c7bc f scall2.obj + 0001:0000b7e0 _sys_reboot 0040c7e0 f scall2.obj + 0001:0000b833 _sys_getset 0040c833 f scall2.obj + 0001:0000bcb0 _bitmap_align 0040ccb0 f xip.obj + 0001:0000c368 _bitmap_ualign 0040d368 f xip.obj + 0001:0000c490 _bitmap_examine 0040d490 f xip.obj + 0001:0000c6b5 _bitmap_align_chase 0040d6b5 f xip.obj + 0001:0000c7ca _bitmap_align_bmap 0040d7ca f xip.obj + 0001:0000ca50 _bitmap_align_reverse 0040da50 f xip.obj + 0001:0000cb3b _bitmap_align_recurse 0040db3b f xip.obj + 0001:0000cf5e _bitmap_search 0040df5e f xip.obj + 0001:0000d0f0 _bitmap_reserve 0040e0f0 f xip.obj + 0001:0000d2dd _bitmap_find 0040e2dd f xip.obj + 0001:0000d51c _bitmap_get 0040e51c f xip.obj + 0001:0000d5ed _bitmap_set 0040e5ed f xip.obj + 0001:0000dda0 _bzero 0040eda0 f utils.obj + 0001:0000ddc6 _bfill 0040edc6 f utils.obj + 0001:0000ddee _bcopy 0040edee f utils.obj + 0001:0000de21 _int_min 0040ee21 f utils.obj + 0001:0000de42 _int_max 0040ee42 f utils.obj + 0001:0000dea0 _xfs_init 0040eea0 f xfs.obj + 0001:0000e00e _xfs_end 0040f00e f xfs.obj + 0001:0000e055 _UZIXopen 0040f055 f xfs.obj + 0001:0000e07a _UZIXclose 0040f07a f xfs.obj + 0001:0000e08c _UZIXcreat 0040f08c f xfs.obj + 0001:0000e0b1 _UZIXlink 0040f0b1 f xfs.obj + 0001:0000e0cc _UZIXsymlink 0040f0cc f xfs.obj + 0001:0000e0e7 _UZIXunlink 0040f0e7 f xfs.obj + 0001:0000e0f9 _UZIXread 0040f0f9 f xfs.obj + 0001:0000e124 _UZIXwrite 0040f124 f xfs.obj + 0001:0000e14f _UZIXlseek 0040f14f f xfs.obj + 0001:0000e17e _UZIXchdir 0040f17e f xfs.obj + 0001:0000e190 _UZIXmknod 0040f190 f xfs.obj + 0001:0000e1b4 _UZIXsync 0040f1b4 f xfs.obj + 0001:0000e1be _UZIXaccess 0040f1be f xfs.obj + 0001:0000e1d9 _UZIXchmod 0040f1d9 f xfs.obj + 0001:0000e1f4 _UZIXchown 0040f1f4 f xfs.obj + 0001:0000e218 _UZIXstat 0040f218 f xfs.obj + 0001:0000e23a _UZIXfstat 0040f23a f xfs.obj + 0001:0000e25c _UZIXfalign 0040f25c f xfs.obj + 0001:0000e277 _UZIXdup 0040f277 f xfs.obj + 0001:0000e289 _UZIXdup2 0040f289 f xfs.obj + 0001:0000e2a4 _UZIXumask 0040f2a4 f xfs.obj + 0001:0000e2c0 _UZIXgetfsys 0040f2c0 f xfs.obj + 0001:0000e2e0 _UZIXioctl 0040f2e0 f xfs.obj + 0001:0000e304 _UZIXmount 0040f304 f xfs.obj + 0001:0000e32f _UZIXumount 0040f32f f xfs.obj + 0001:0000e348 _UZIXtime 0040f348 f xfs.obj + 0001:0000e488 ___initstdio 0040f488 f LIBC:_file.obj + 0001:0000e52d ___endstdio 0040f52d f LIBC:_file.obj + 0001:0000e541 _fgets 0040f541 f LIBC:fgets.obj + 0001:0000e598 _fflush 0040f598 f LIBC:fflush.obj + 0001:0000e5d3 __flush 0040f5d3 f LIBC:fflush.obj + 0001:0000e62f __flushall 0040f62f f LIBC:fflush.obj + 0001:0000e6a5 _fprintf 0040f6a5 f LIBC:fprintf.obj + 0001:0000e6d7 _printf 0040f6d7 f LIBC:printf.obj + 0001:0000e710 _strcpy 0040f710 f LIBC:strcat.obj + 0001:0000e720 _strcat 0040f720 f LIBC:strcat.obj + 0001:0000e800 __cinit 0040f800 f LIBC:crt0dat.obj + 0001:0000e82d _exit 0040f82d f LIBC:crt0dat.obj + 0001:0000e83e __exit 0040f83e f LIBC:crt0dat.obj + 0001:0000e84f __cexit 0040f84f f LIBC:crt0dat.obj + 0001:0000e85e __c_exit 0040f85e f LIBC:crt0dat.obj + 0001:0000e920 _system 0040f920 f LIBC:system.obj + 0001:0000e9d0 _strchr 0040f9d0 f LIBC:strchr.obj + 0001:0000e9d6 ___from_strstr_to_strchr 0040f9d6 f LIBC:strchr.obj + 0001:0000ea8c _sscanf 0040fa8c f LIBC:sscanf.obj + 0001:0000eac0 _fputs 0040fac0 f LIBC:fputs.obj + 0001:0000eb03 __flsbuf 0040fb03 f LIBC:_flsbuf.obj + 0001:0000ec20 _strlen 0040fc20 f LIBC:strlen.obj + 0001:0000ec9b __isctype 0040fc9b f LIBC:isctype.obj + 0001:0000ed10 __fsopen 0040fd10 f LIBC:fopen.obj + 0001:0000ed30 _fopen 0040fd30 f LIBC:fopen.obj + 0001:0000ed43 _sprintf 0040fd43 f LIBC:sprintf.obj + 0001:0000eda0 _strncat 0040fda0 f LIBC:strncat.obj + 0001:0000eec3 _fclose 0040fec3 f LIBC:fclose.obj + 0001:0000ef19 _fread 0040ff19 f LIBC:fread.obj + 0001:0000f001 _fwrite 00410001 f LIBC:fwrite.obj + 0001:0000f10b _atol 0041010b f LIBC:atox.obj + 0001:0000f196 _atoi 00410196 f LIBC:atox.obj + 0001:0000f1a1 __atoi64 004101a1 f LIBC:atox.obj + 0001:0000f25b __fputchar 0041025b f LIBC:fputchar.obj + 0001:0000f28a _putchar 0041028a f LIBC:fputchar.obj + 0001:0000f295 _localtime 00410295 f LIBC:localtim.obj + 0001:0000f3f5 _time 004103f5 f LIBC:time.obj + 0001:0000f4d1 _mainCRTStartup 004104d1 f LIBC:crt0.obj + 0001:0000f5b0 __amsg_exit 004105b0 f LIBC:crt0.obj + 0001:0000f5f9 __ioinit 004105f9 f LIBC:ioinit.obj + 0001:0000f7a4 __ioterm 004107a4 f LIBC:ioinit.obj + 0001:0000f7c7 _calloc 004107c7 f LIBC:calloc.obj + 0001:0000f878 __fcloseall 00410878 f LIBC:closeall.obj + 0001:0000f8d0 __filbuf 004108d0 f LIBC:_filbuf.obj + 0001:0000f9a9 __commit 004109a9 f LIBC:commit.obj + 0001:0000fa00 _write 00410a00 f LIBC:write.obj + 0001:0000fa00 __write 00410a00 f LIBC:write.obj + 0001:0000fbad __stbuf 00410bad f LIBC:_sftbuf.obj + 0001:0000fc3a __ftbuf 00410c3a f LIBC:_sftbuf.obj + 0001:0000fc77 __output 00410c77 f LIBC:output.obj + 0001:00010481 __spawnvpe 00411481 f LIBC:spawnvpe.obj + 0001:000105e4 __spawnve 004115e4 f LIBC:spawnve.obj + 0001:0001077e __access 0041177e f LIBC:access.obj + 0001:000107c2 _getenv 004117c2 f LIBC:getenv.obj + 0001:0001083f __input 0041183f f LIBC:input.obj + 0001:000112f0 _lseek 004122f0 f LIBC:lseek.obj + 0001:000112f0 __lseek 004122f0 f LIBC:lseek.obj + 0001:0001138a __getbuf 0041238a f LIBC:_getbuf.obj + 0001:000113ce _isatty 004123ce f LIBC:isatty.obj + 0001:000113ce __isatty 004123ce f LIBC:isatty.obj + 0001:000113f4 ___crtGetStringTypeA 004123f4 f LIBC:a_str.obj + 0001:0001153d __openfile 0041253d f LIBC:_open.obj + 0001:000116ad __getstream 004126ad f LIBC:stream.obj + 0001:00011725 _free 00412725 f LIBC:free.obj + 0001:0001178e __close 0041278e f LIBC:close.obj + 0001:00011841 __freebuf 00412841 f LIBC:_freebuf.obj + 0001:0001186c __read 0041286c f LIBC:read.obj + 0001:0001186c _read 0041286c f LIBC:read.obj + 0001:00011a70 _memcpy 00412a70 f LIBC:memcpy.obj + 0001:00011db0 __allmul 00412db0 f LIBC:llmul.obj + 0001:00011de4 ___tzset 00412de4 f LIBC:tzset.obj + 0001:00011df9 __tzset 00412df9 f LIBC:tzset.obj + 0001:00012057 __isindst 00413057 f LIBC:tzset.obj + 0001:00012343 _gmtime 00413343 f LIBC:gmtime.obj + 0001:0001243c ___loctotime_t 0041343c f LIBC:dtoxtime.obj + 0001:000124fe __XcptFilter 004134fe f LIBC:winxfltr.obj + 0001:00012682 __setenvp 00413682 f LIBC:stdenvp.obj + 0001:0001273b __setargv 0041373b f LIBC:stdargv.obj + 0001:00012988 ___crtGetEnvironmentStringsA 00413988 f LIBC:a_env.obj + 0001:00012aba __GetLinkerVersion 00413aba f LIBC:heapinit.obj + 0001:00012ae7 ___heap_select 00413ae7 f LIBC:heapinit.obj + 0001:00012c2f __heap_init 00413c2f f LIBC:heapinit.obj + 0001:00012c8c __heap_term 00413c8c f LIBC:heapinit.obj + 0001:00012d34 __global_unwind2 00413d34 f LIBC:exsup.obj + 0001:00012d76 __local_unwind2 00413d76 f LIBC:exsup.obj + 0001:00012dce __NLG_Return2 00413dce f LIBC:exsup.obj + 0001:00012dde __abnormal_termination 00413dde f LIBC:exsup.obj + 0001:00012e01 __NLG_Notify1 00413e01 f LIBC:exsup.obj + 0001:00012e0a __NLG_Notify 00413e0a f LIBC:exsup.obj + 0001:00012e1d __NLG_Dispatch 00413e1d f LIBC:exsup.obj + 0001:00012e2c __except_handler3 00413e2c f LIBC:exsup3.obj + 0001:00012ee9 __seh_longjmp_unwind@4 00413ee9 f LIBC:exsup3.obj + 0001:00012f04 __FF_MSGBANNER 00413f04 f LIBC:crt0msg.obj + 0001:00012f3d __NMSG_WRITE 00413f3d f LIBC:crt0msg.obj + 0001:00013090 __GET_RTERRMSG 00414090 f LIBC:crt0msg.obj + 0001:000130c1 _malloc 004140c1 f LIBC:malloc.obj + 0001:000130d3 __nh_malloc 004140d3 f LIBC:malloc.obj + 0001:000130ff __heap_alloc 004140ff f LIBC:malloc.obj + 0001:00013180 _memset 00414180 f LIBC:memset.obj + 0001:000131d8 ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z 004141d8 f LIBC:handler.obj + 0001:000131e8 ?_query_new_handler@@YAP6AHI@ZXZ 004141e8 f LIBC:handler.obj + 0001:000131ee __callnewh 004141ee f LIBC:handler.obj + 0001:00013209 __get_sbh_threshold 00414209 f LIBC:sbheap.obj + 0001:00013228 __set_sbh_threshold 00414228 f LIBC:sbheap.obj + 0001:000132db ___sbh_heap_init 004142db f LIBC:sbheap.obj + 0001:00013323 ___sbh_find_block 00414323 f LIBC:sbheap.obj + 0001:0001334e ___sbh_free_block 0041434e f LIBC:sbheap.obj + 0001:00013677 ___sbh_alloc_block 00414677 f LIBC:sbheap.obj + 0001:00013980 ___sbh_alloc_new_region 00414980 f LIBC:sbheap.obj + 0001:00013a31 ___sbh_alloc_new_group 00414a31 f LIBC:sbheap.obj + 0001:00013b2c ___sbh_resize_block 00414b2c f LIBC:sbheap.obj + 0001:00013e22 ___sbh_heapmin 00414e22 f LIBC:sbheap.obj + 0001:00013ef3 ___sbh_heap_check 00414ef3 f LIBC:sbheap.obj + 0001:00014222 __get_old_sbh_threshold 00415222 f LIBC:sbheap.obj + 0001:00014228 __set_old_sbh_threshold 00415228 f LIBC:sbheap.obj + 0001:00014244 ___old_sbh_new_region 00415244 f LIBC:sbheap.obj + 0001:00014388 ___old_sbh_release_region 00415388 f LIBC:sbheap.obj + 0001:000143de ___old_sbh_decommit_pages 004153de f LIBC:sbheap.obj + 0001:000144a0 ___old_sbh_find_block 004154a0 f LIBC:sbheap.obj + 0001:000144f7 ___old_sbh_free_block 004154f7 f LIBC:sbheap.obj + 0001:0001453c ___old_sbh_alloc_block 0041553c f LIBC:sbheap.obj + 0001:00014744 ___old_sbh_alloc_block_from_page 00415744 f LIBC:sbheap.obj + 0001:00014868 ___old_sbh_resize_block 00415868 f LIBC:sbheap.obj + 0001:00014911 ___old_sbh_heap_check 00415911 f LIBC:sbheap.obj + 0001:00014a6f __alloc_osfhnd 00415a6f f LIBC:osfinfo.obj + 0001:00014b04 __set_osfhnd 00415b04 f LIBC:osfinfo.obj + 0001:00014b7b __free_osfhnd 00415b7b f LIBC:osfinfo.obj + 0001:00014bf5 __get_osfhandle 00415bf5 f LIBC:osfinfo.obj + 0001:00014c32 __open_osfhandle 00415c32 f LIBC:osfinfo.obj + 0001:00014ccf __dosmaperr 00415ccf f LIBC:dosmap.obj + 0001:00014d36 _wctomb 00415d36 f LIBC:wctomb.obj + 0001:00014da0 __aulldiv 00415da0 f LIBC:ulldiv.obj + 0001:00014e10 __aullrem 00415e10 f LIBC:ullrem.obj + 0001:00014e85 __mbsrchr 00415e85 f LIBC:mbsrchr.obj + 0001:00014ee5 __getpath 00415ee5 f LIBC:getpath.obj + 0001:00014f59 __mbschr 00415f59 f LIBC:mbschr.obj + 0001:00014fcc __dospawn 00415fcc f LIBC:dospawn.obj + 0001:000151ab __cenvarg 004161ab f LIBC:cenvarg.obj + 0001:000153af __mbsnbicoll 004163af f LIBC:mbsnbico.obj + 0001:000153ee ___wtomb_environ 004163ee f LIBC:wtombenv.obj + 0001:0001545c _mbtowc 0041645c f LIBC:mbtowc.obj + 0001:00015524 _isalpha 00416524 f LIBC:_ctype.obj + 0001:00015552 _isupper 00416552 f LIBC:_ctype.obj + 0001:0001557a _islower 0041657a f LIBC:_ctype.obj + 0001:000155a2 _isdigit 004165a2 f LIBC:_ctype.obj + 0001:000155ca _isxdigit 004165ca f LIBC:_ctype.obj + 0001:000155f7 _isspace 004165f7 f LIBC:_ctype.obj + 0001:0001561f _ispunct 0041661f f LIBC:_ctype.obj + 0001:00015647 _isalnum 00416647 f LIBC:_ctype.obj + 0001:00015675 _isprint 00416675 f LIBC:_ctype.obj + 0001:000156a3 _isgraph 004166a3 f LIBC:_ctype.obj + 0001:000156d1 _iscntrl 004166d1 f LIBC:_ctype.obj + 0001:000156f9 ___isascii 004166f9 f LIBC:_ctype.obj + 0001:00015706 ___toascii 00416706 f LIBC:_ctype.obj + 0001:0001570e ___iscsymf 0041670e f LIBC:_ctype.obj + 0001:0001574b ___iscsym 0041674b f LIBC:_ctype.obj + 0001:00015790 __allshl 00416790 f LIBC:llshl.obj + 0001:000157af _ungetc 004167af f LIBC:ungetc.obj + 0001:00015820 __alloca_probe 00416820 f LIBC:chkstk.obj + 0001:00015820 __chkstk 00416820 f LIBC:chkstk.obj + 0001:0001584f __open 0041684f f LIBC:open.obj + 0001:0001584f _open 0041684f f LIBC:open.obj + 0001:00015866 __sopen 00416866 f LIBC:open.obj + 0001:00015b20 _strncpy 00416b20 f LIBC:strncpy.obj + 0001:00015c20 _strcmp 00416c20 f LIBC:strcmp.obj + 0001:00015ca4 __setmbcp 00416ca4 f LIBC:mbctype.obj + 0001:00016068 __getmbcp 00417068 f LIBC:mbctype.obj + 0001:00016078 ___initmbctable 00417078 f LIBC:mbctype.obj + 0001:00016094 _strtol 00417094 f LIBC:strtol.obj + 0001:000162b3 _strtoul 004172b3 f LIBC:strtol.obj + 0001:000162d0 _strstr 004172d0 f LIBC:strstr.obj + 0001:00016350 _strncmp 00417350 f LIBC:strncmp.obj + 0001:00016388 ___crtMessageBoxA 00417388 f LIBC:crtmbox.obj + 0001:00016420 _memmove 00417420 f LIBC:memmove.obj + 0001:00016755 __fptrap 00417755 f LIBC:crt0fp.obj + 0001:00016760 _strrchr 00417760 f LIBC:strrchr.obj + 0001:00016787 ___crtCompareStringA 00417787 f LIBC:a_cmp.obj + 0001:00016a2f ___crtsetenv 00417a2f f LIBC:setenv.obj + 0001:00016c75 __chsize 00417c75 f LIBC:chsize.obj + 0001:00016dbb ___crtLCMapStringA 00417dbb f LIBC:a_map.obj + 0001:0001700a __toupper 0041800a f LIBC:toupper.obj + 0001:00017012 _toupper 00418012 f LIBC:toupper.obj + 0001:000170de _realloc 004180de f LIBC:realloc.obj + 0001:0001737e __strdup 0041837e f LIBC:strdup.obj + 0001:000173a9 __setmode 004183a9 f LIBC:setmode.obj + 0001:00017420 _ExitProcess@4 00418420 f kernel32:KERNEL32.dll + 0001:00017426 _TerminateProcess@8 00418426 f kernel32:KERNEL32.dll + 0001:0001742c _GetCurrentProcess@0 0041842c f kernel32:KERNEL32.dll + 0001:00017432 _GetTimeZoneInformation@4 00418432 f kernel32:KERNEL32.dll + 0001:00017438 _GetSystemTime@4 00418438 f kernel32:KERNEL32.dll + 0001:0001743e _GetLocalTime@4 0041843e f kernel32:KERNEL32.dll + 0001:00017444 _GetCommandLineA@0 00418444 f kernel32:KERNEL32.dll + 0001:0001744a _GetVersion@0 0041844a f kernel32:KERNEL32.dll + 0001:00017450 _SetHandleCount@4 00418450 f kernel32:KERNEL32.dll + 0001:00017456 _GetStdHandle@4 00418456 f kernel32:KERNEL32.dll + 0001:0001745c _GetFileType@4 0041845c f kernel32:KERNEL32.dll + 0001:00017462 _GetStartupInfoA@4 00418462 f kernel32:KERNEL32.dll + 0001:00017468 _HeapAlloc@12 00418468 f kernel32:KERNEL32.dll + 0001:0001746e _GetLastError@0 0041846e f kernel32:KERNEL32.dll + 0001:00017474 _FlushFileBuffers@4 00418474 f kernel32:KERNEL32.dll + 0001:0001747a _WriteFile@20 0041847a f kernel32:KERNEL32.dll + 0001:00017480 _GetFileAttributesA@4 00418480 f kernel32:KERNEL32.dll + 0001:00017486 _SetFilePointer@16 00418486 f kernel32:KERNEL32.dll + 0001:0001748c _MultiByteToWideChar@24 0041848c f kernel32:KERNEL32.dll + 0001:00017492 _GetStringTypeA@20 00418492 f kernel32:KERNEL32.dll + 0001:00017498 _GetStringTypeW@16 00418498 f kernel32:KERNEL32.dll + 0001:0001749e _HeapFree@12 0041849e f kernel32:KERNEL32.dll + 0001:000174a4 _CloseHandle@4 004184a4 f kernel32:KERNEL32.dll + 0001:000174aa _ReadFile@20 004184aa f kernel32:KERNEL32.dll + 0001:000174b0 _WideCharToMultiByte@32 004184b0 f kernel32:KERNEL32.dll + 0001:000174b6 _UnhandledExceptionFilter@4 004184b6 f kernel32:KERNEL32.dll + 0001:000174bc _GetModuleFileNameA@12 004184bc f kernel32:KERNEL32.dll + 0001:000174c2 _FreeEnvironmentStringsA@4 004184c2 f kernel32:KERNEL32.dll + 0001:000174c8 _FreeEnvironmentStringsW@4 004184c8 f kernel32:KERNEL32.dll + 0001:000174ce _GetEnvironmentStrings@0 004184ce f kernel32:KERNEL32.dll + 0001:000174d4 _GetEnvironmentStringsW@0 004184d4 f kernel32:KERNEL32.dll + 0001:000174da _GetModuleHandleA@4 004184da f kernel32:KERNEL32.dll + 0001:000174e0 _GetEnvironmentVariableA@12 004184e0 f kernel32:KERNEL32.dll + 0001:000174e6 _GetVersionExA@4 004184e6 f kernel32:KERNEL32.dll + 0001:000174ec _HeapDestroy@4 004184ec f kernel32:KERNEL32.dll + 0001:000174f2 _HeapCreate@12 004184f2 f kernel32:KERNEL32.dll + 0001:000174f8 _VirtualFree@12 004184f8 f kernel32:KERNEL32.dll + 0001:000174fe _RtlUnwind@16 004184fe f kernel32:KERNEL32.dll + 0001:00017504 _VirtualAlloc@16 00418504 f kernel32:KERNEL32.dll + 0001:0001750a _HeapReAlloc@16 0041850a f kernel32:KERNEL32.dll + 0001:00017510 _IsBadWritePtr@8 00418510 f kernel32:KERNEL32.dll + 0001:00017516 _SetStdHandle@8 00418516 f kernel32:KERNEL32.dll + 0001:0001751c _GetExitCodeProcess@8 0041851c f kernel32:KERNEL32.dll + 0001:00017522 _WaitForSingleObject@8 00418522 f kernel32:KERNEL32.dll + 0001:00017528 _CreateProcessA@40 00418528 f kernel32:KERNEL32.dll + 0001:0001752e _CreateFileA@28 0041852e f kernel32:KERNEL32.dll + 0001:00017534 _GetCPInfo@8 00418534 f kernel32:KERNEL32.dll + 0001:0001753a _GetACP@0 0041853a f kernel32:KERNEL32.dll + 0001:00017540 _GetOEMCP@0 00418540 f kernel32:KERNEL32.dll + 0001:00017546 _GetProcAddress@8 00418546 f kernel32:KERNEL32.dll + 0001:0001754c _LoadLibraryA@4 0041854c f kernel32:KERNEL32.dll + 0001:00017552 _CompareStringA@24 00418552 f kernel32:KERNEL32.dll + 0001:00017558 _CompareStringW@24 00418558 f kernel32:KERNEL32.dll + 0001:0001755e _SetEnvironmentVariableA@8 0041855e f kernel32:KERNEL32.dll + 0001:00017564 _SetEndOfFile@4 00418564 f kernel32:KERNEL32.dll + 0001:0001756a _LCMapStringA@24 0041856a f kernel32:KERNEL32.dll + 0001:00017570 _LCMapStringW@24 00418570 f kernel32:KERNEL32.dll + 0001:00017580 __stricmp 00418580 f LIBC:stricmp.obj + 0001:00017580 __strcmpi 00418580 f LIBC:stricmp.obj + 0001:00017580 _stricmp 00418580 f LIBC:stricmp.obj + 0001:0001760c _chdir 0041860c f LIBC:chdir.obj + 0001:0001760c __chdir 0041860c f LIBC:chdir.obj + 0001:000176a0 _memicmp 004186a0 f LIBC:memicmp.obj + 0001:000176a0 __memicmp 004186a0 f LIBC:memicmp.obj + 0001:0001773d _fileno 0041873d f LIBC:fileno.obj + 0001:0001773d __fileno 0041873d f LIBC:fileno.obj + 0001:00017745 __tolower 00418745 f LIBC:tolower.obj + 0001:0001774d _tolower 0041874d f LIBC:tolower.obj + 0001:00017818 __mbctoupper 00418818 f LIBC:mbtoupr.obj + 0001:00017894 _GetCurrentDirectoryA@8 00418894 f kernel32:KERNEL32.dll + 0001:0001789a _SetCurrentDirectoryA@4 0041889a f kernel32:KERNEL32.dll + 0002:0000001c ??_C@_07OOMJ@cmd?4exe?$AA@ 0041c01c LIBC:system.obj + 0002:00000024 ??_C@_0M@IPJP@command?4com?$AA@ 0041c024 LIBC:system.obj + 0002:00000030 ??_C@_02JMK@?1c?$AA@ 0041c030 LIBC:system.obj + 0002:00000034 ??_C@_07KFDO@COMSPEC?$AA@ 0041c034 LIBC:system.obj + 0002:0000004c ___lookuptable 0041c04c LIBC:output.obj + 0002:000000a8 ??_C@_1O@POHA@?$AA?$CI?$AAn?$AAu?$AAl?$AAl?$AA?$CJ?$AA?$AA@ 0041c0a8 LIBC:output.obj + 0002:000000b8 ??_C@_06ONKE@?$CInull?$CJ?$AA@ 0041c0b8 LIBC:output.obj + 0002:000000c0 ??_C@_01PCFE@?2?$AA@ 0041c0c0 LIBC:spawnvpe.obj + 0002:000000c4 ??_C@_04LNMG@PATH?$AA@ 0041c0c4 LIBC:spawnvpe.obj + 0002:000000cc ??_C@_04GGNP@?4com?$AA@ 0041c0cc LIBC:spawnve.obj + 0002:000000d4 ??_C@_04NFOM@?4exe?$AA@ 0041c0d4 LIBC:spawnve.obj + 0002:000000dc ??_C@_04KBDN@?4bat?$AA@ 0041c0dc LIBC:spawnve.obj + 0002:000000e4 ??_C@_04LFKF@?4cmd?$AA@ 0041c0e4 LIBC:spawnve.obj + 0002:000000ec ??_C@_02OFKN@?4?2?$AA@ 0041c0ec LIBC:spawnve.obj + 0002:000000f0 ??_C@_01A@?$AA?$AA@ 0041c0f0 LIBC:a_str.obj + 0002:000000f4 ??_C@_13A@?$AA?$AA?$AA?$AA@ 0041c0f4 LIBC:a_str.obj + 0002:00000104 ___dnames 0041c104 LIBC:timeset.obj + 0002:0000011c ___mnames 0041c11c LIBC:timeset.obj + 0002:00000144 ??_C@_02JHIA@TZ?$AA@ 0041c144 LIBC:tzset.obj + 0002:00000148 ??_C@_0BH@PHHF@__GLOBAL_HEAP_SELECTED?$AA@ 0041c148 LIBC:heapinit.obj + 0002:00000160 ??_C@_0BF@BBGL@__MSVCRT_HEAP_SELECT?$AA@ 0041c160 LIBC:heapinit.obj + 0002:00000178 ??_C@_0P@GGKG@runtime?5error?5?$AA@ 0041c178 LIBC:crt0msg.obj + 0002:00000188 ??_C@_02PIMC@?$AN?6?$AA@ 0041c188 LIBC:crt0msg.obj + 0002:0000018c ??_C@_0O@DELO@TLOSS?5error?$AN?6?$AA@ 0041c18c LIBC:crt0msg.obj + 0002:0000019c ??_C@_0N@OMLL@SING?5error?$AN?6?$AA@ 0041c19c LIBC:crt0msg.obj + 0002:000001ac ??_C@_0P@OJAK@DOMAIN?5error?$AN?6?$AA@ 0041c1ac LIBC:crt0msg.obj + 0002:000001bc ??_C@_0CF@EANP@R6028?$AN?6?9?5unable?5to?5initialize?5he@ 0041c1bc LIBC:crt0msg.obj + 0002:000001e4 ??_C@_0DF@ECGN@R6027?$AN?6?9?5not?5enough?5space?5for?5lo@ 0041c1e4 LIBC:crt0msg.obj + 0002:0000021c ??_C@_0DF@FKAC@R6026?$AN?6?9?5not?5enough?5space?5for?5st@ 0041c21c LIBC:crt0msg.obj + 0002:00000254 ??_C@_0CG@DPMN@R6025?$AN?6?9?5pure?5virtual?5function?5c@ 0041c254 LIBC:crt0msg.obj + 0002:0000027c ??_C@_0DF@CKIP@R6024?$AN?6?9?5not?5enough?5space?5for?5_o@ 0041c27c LIBC:crt0msg.obj + 0002:000002b4 ??_C@_0CJ@GGOE@R6019?$AN?6?9?5unable?5to?5open?5console?5@ 0041c2b4 LIBC:crt0msg.obj + 0002:000002e0 ??_C@_0CB@LBOB@R6018?$AN?6?9?5unexpected?5heap?5error?$AN?6@ 0041c2e0 LIBC:crt0msg.obj + 0002:00000304 ??_C@_0CN@FPEG@R6017?$AN?6?9?5unexpected?5multithread?5@ 0041c304 LIBC:crt0msg.obj + 0002:00000334 ??_C@_0CM@OBIC@R6016?$AN?6?9?5not?5enough?5space?5for?5th@ 0041c334 LIBC:crt0msg.obj + 0002:00000360 ??_C@_0CB@HPAL@?$AN?6abnormal?5program?5termination?$AN?6@ 0041c360 LIBC:crt0msg.obj + 0002:00000384 ??_C@_0CM@JOOB@R6009?$AN?6?9?5not?5enough?5space?5for?5en@ 0041c384 LIBC:crt0msg.obj + 0002:000003b0 ??_C@_0CK@OIBL@R6008?$AN?6?9?5not?5enough?5space?5for?5ar@ 0041c3b0 LIBC:crt0msg.obj + 0002:000003dc ??_C@_0CF@LKPB@R6002?$AN?6?9?5floating?5point?5not?5load@ 0041c3dc LIBC:crt0msg.obj + 0002:00000404 ??_C@_0CF@JPDF@Microsoft?5Visual?5C?$CL?$CL?5Runtime?5Lib@ 0041c404 LIBC:crt0msg.obj + 0002:0000042c ??_C@_02JJJH@?6?6?$AA@ 0041c42c LIBC:crt0msg.obj + 0002:00000430 ??_C@_0BK@DEOK@Runtime?5Error?$CB?6?6Program?3?5?$AA@ 0041c430 LIBC:crt0msg.obj + 0002:0000044c ??_C@_03NAME@?4?4?4?$AA@ 0041c44c LIBC:crt0msg.obj + 0002:00000450 ??_C@_0BH@NNCD@?$DMprogram?5name?5unknown?$DO?$AA@ 0041c450 LIBC:crt0msg.obj + 0002:00000468 ??_C@_0BD@NJFP@GetLastActivePopup?$AA@ 0041c468 LIBC:crtmbox.obj + 0002:0000047c ??_C@_0BA@GILI@GetActiveWindow?$AA@ 0041c47c LIBC:crtmbox.obj + 0002:0000048c ??_C@_0M@PKCK@MessageBoxA?$AA@ 0041c48c LIBC:crtmbox.obj + 0002:00000498 ??_C@_0L@HKL@user32?4dll?$AA@ 0041c498 LIBC:crtmbox.obj + 0003:00000000 ___xc_a 0041d000 LIBC:crt0init.obj + 0003:00000104 ___xc_z 0041d104 LIBC:crt0init.obj + 0003:00000208 ___xi_a 0041d208 LIBC:crt0init.obj + 0003:00000418 ___xi_z 0041d418 LIBC:crt0init.obj + 0003:0000051c ___xp_a 0041d51c LIBC:crt0init.obj + 0003:00000724 ___xp_z 0041d724 LIBC:crt0init.obj + 0003:00000828 ___xt_a 0041d828 LIBC:crt0init.obj + 0003:0000092c ___xt_z 0041d92c LIBC:crt0init.obj + 0003:00000a30 _in 0041da30 ucp.obj + 0003:00000a34 _rdev 0041da34 ucp.obj + 0003:00000a38 _syserror 0041da38 ucp.obj + 0003:00000a3c _help 0041da3c ucp.obj + 0003:0000177c _cmdblk 0041e77c devhd.obj + 0003:00001784 _busid 0041e784 devhd.obj + 0003:000017c0 _dev_tab 0041e7c0 devio.obj + 0003:00001978 _tty_default 0041e978 devtty.obj + 0003:00001988 _tty_vector 0041e988 devtty.obj + 0003:000019b0 _ttyinq 0041e9b0 devtty.obj + 0003:00001ae0 _baddevmsg 0041eae0 filesys.obj + 0003:00001e84 _UZIX 0041ee84 main.obj + 0003:00001e94 _HOST 0041ee94 main.obj + 0003:000020ac _stringerr 0041f0ac xfs.obj + 0003:00002638 __iob 0041f638 LIBC:_file.obj + 0003:000028c0 __pctype 0041f8c0 LIBC:ctype.obj + 0003:000028c4 __pwctype 0041f8c4 LIBC:ctype.obj + 0003:000028c8 __ctype 0041f8c8 LIBC:ctype.obj + 0003:00002acc ___mb_cur_max 0041facc LIBC:nlsdata1.obj + 0003:00002ad0 ___decimal_point 0041fad0 LIBC:nlsdata1.obj + 0003:00002ad4 ___decimal_point_length 0041fad4 LIBC:nlsdata1.obj + 0003:00002ae0 __aexit_rtn 0041fae0 LIBC:crt0.obj + 0003:00002ae4 ___app_type 0041fae4 LIBC:crt0.obj + 0003:00002ae8 ___badioinfo 0041fae8 LIBC:ioinit.obj + 0003:00002af0 ___nullstring 0041faf0 LIBC:output.obj + 0003:00002af4 ___wnullstring 0041faf4 LIBC:output.obj + 0003:00002b20 __timezone 0041fb20 LIBC:timeset.obj + 0003:00002b24 __daylight 0041fb24 LIBC:timeset.obj + 0003:00002b28 __dstbias 0041fb28 LIBC:timeset.obj + 0003:00002bac __tzname 0041fbac LIBC:timeset.obj + 0003:00002bd8 __XcptActTab 0041fbd8 LIBC:winxfltr.obj + 0003:00002c50 __First_FPE_Indx 0041fc50 LIBC:winxfltr.obj + 0003:00002c54 __Num_FPE 0041fc54 LIBC:winxfltr.obj + 0003:00002c58 __XcptActTabCount 0041fc58 LIBC:winxfltr.obj + 0003:00002c5c __fpecode 0041fc5c LIBC:winxfltr.obj + 0003:00002c60 __amblksiz 0041fc60 LIBC:heapinit.obj + 0003:00002c64 __NLG_Destination 0041fc64 LIBC:exsup.obj + 0003:00002d10 ___old_small_block_heap 0041fd10 LIBC:sbheap.obj + 0003:00004d34 ___old_sbh_threshold 00421d34 LIBC:sbheap.obj + 0003:00004ea0 __cfltcvt_tab 00421ea0 LIBC:cmiscdat.obj + 0003:00004ec0 __p_overlay 00421ec0 LIBC:dospawn.obj + 0003:00004ed0 __lpdays 00421ed0 LIBC:days.obj + 0003:00004f04 __days 00421f04 LIBC:days.obj + 0003:000059a0 _f_pause 004229a0 ucp.obj + 0003:000059a1 _unix_locked_out 004229a1 + 0003:000059a2 _swapblk 004229a2 + 0003:000059a4 _hd_offset 004229a4 devhd.obj + 0003:000059a8 _hd_sector 004229a8 devhd.obj + 0003:000059ac _dptr 004229ac devhd.obj + 0003:000059b0 _dlen 004229b0 devhd.obj + 0003:000059b4 _cptr 004229b4 devhd.obj + 0003:000059b9 _dirty_mask 004229b9 + 0003:000059ba _inint 004229ba + 0003:000059bc _initproc 004229bc + 0003:000059c0 _bufclock 004229c0 devio.obj + 0003:000059c8 _swapcnt 004229c8 + 0003:000059cd _traceon 004229cd + 0003:000059ce _sec 004229ce + 0003:000059d9 _total 004229d9 + 0003:000059da _waitno 004229da + 0003:000059e4 _tod 004229e4 + 0003:000059f4 _runticks 004229f4 + 0003:000059f6 _root_dev 004229f6 + 0003:00005a08 __cflush 00422a08 LIBC:_file.obj + 0003:00005a0c _errno 00422a0c LIBC:crt0dat.obj + 0003:00005a10 __doserrno 00422a10 LIBC:crt0dat.obj + 0003:00005a14 __umaskval 00422a14 LIBC:crt0dat.obj + 0003:00005a18 __osver 00422a18 LIBC:crt0dat.obj + 0003:00005a1c __winver 00422a1c LIBC:crt0dat.obj + 0003:00005a20 __winmajor 00422a20 LIBC:crt0dat.obj + 0003:00005a24 __winminor 00422a24 LIBC:crt0dat.obj + 0003:00005a28 ___argc 00422a28 LIBC:crt0dat.obj + 0003:00005a2c ___argv 00422a2c LIBC:crt0dat.obj + 0003:00005a30 ___wargv 00422a30 LIBC:crt0dat.obj + 0003:00005a34 __environ 00422a34 LIBC:crt0dat.obj + 0003:00005a38 ___initenv 00422a38 LIBC:crt0dat.obj + 0003:00005a3c __wenviron 00422a3c LIBC:crt0dat.obj + 0003:00005a40 ___winitenv 00422a40 LIBC:crt0dat.obj + 0003:00005a44 __pgmptr 00422a44 LIBC:crt0dat.obj + 0003:00005a48 __wpgmptr 00422a48 LIBC:crt0dat.obj + 0003:00005a4c __exitflag 00422a4c LIBC:crt0dat.obj + 0003:00005a50 __C_Termination_Done 00422a50 LIBC:crt0dat.obj + 0003:00005a54 __C_Exit_Done 00422a54 LIBC:crt0dat.obj + 0003:00005a70 __aenvptr 00422a70 LIBC:crt0.obj + 0003:00005a74 __wenvptr 00422a74 LIBC:crt0.obj + 0003:00005a78 ___error_mode 00422a78 LIBC:crt0.obj + 0003:00005a7c __stdbuf 00422a7c LIBC:_sftbuf.obj + 0003:00005b44 _swapbase 00422b44 + 0003:00005b6c __pxcptinfoptrs 00422b6c LIBC:winxfltr.obj + 0003:00005c78 __adbgmsg 00422c78 LIBC:crt0msg.obj + 0003:00005c7c ?_pnhHeap@@3P6AHI@ZA 00422c7c LIBC:handler.obj + 0003:00005c80 __newmode 00422c80 LIBC:_newmode.obj + 0003:00005c88 ___lc_handle 00422c88 LIBC:nlsdata2.obj + 0003:00005ca0 ___lc_codepage 00422ca0 LIBC:nlsdata2.obj + 0003:00005ca4 ___lc_collate_cp 00422ca4 LIBC:nlsdata2.obj + 0003:00005ca8 __commode 00422ca8 LIBC:ncommode.obj + 0003:00005cc0 __fmode 00422cc0 LIBC:txtmode.obj + 0003:00005cc8 _ticks 00422cc8 + 0003:00005ccc _root_ino 00422ccc + 0003:00005cd0 _ibuf 00422cd0 + 0003:00005cdc _ncalls 00422cdc + 0003:00005ce0 _bufpool 00422ce0 + 0003:00007158 _osBank 00424158 + 0003:0000715c _disp_tab 0042415c + 0003:00007160 _fs_tab 00424160 + 0003:000071cc _buf_flsh 004241cc + 0003:000071d0 _buf_hits 004241d0 + 0003:000071d4 _buf_miss 004241d4 + 0003:000071e0 _of_tab 004241e0 + 0003:00007360 _i_tab 00424360 + 0003:00007f40 _ub 00424f40 + 0003:00008f40 _ptab 00425f40 + 0003:00009080 _kbuf 00426080 + 0003:000090c0 _recv_bufs 004260c0 + 0003:00009dc0 _stopflag 00426dc0 + 0003:00009e00 _flshflag 00426e00 + 0003:00009e40 _tty_data 00426e40 + 0003:00009ee0 _cwd 00426ee0 + 0003:00009f80 _line 00426f80 + 0003:0000ade4 ___mbcodepage 00427de4 + 0003:0000ae60 ___mbulinfo 00427e60 + 0003:0000ae6c ___ismbcodepage 00427e6c + 0003:0000ae80 __mbcasemap 00427e80 + 0003:0000af80 __mbctype 00427f80 + 0003:0000b084 ___mblcid 00428084 + 0003:0000b088 ___sbh_sizeHeaderList 00428088 + 0003:0000b09c ___sbh_indGroupDefer 0042809c + 0003:0000b0a0 ___sbh_pHeaderScan 004280a0 + 0003:0000b0a4 ___sbh_initialized 004280a4 + 0003:0000b0a8 ___sbh_pHeaderDefer 004280a8 + 0003:0000b0ac ___sbh_cntHeaderList 004280ac + 0003:0000b0b0 ___sbh_pHeaderList 004280b0 + 0003:0000b0b4 ___sbh_threshold 004280b4 + 0003:0000b0b8 __crtheap 004280b8 + 0003:0000b0c8 ___active_heap 004280c8 + 0003:0000b0e0 ___pioinfo 004280e0 + 0003:0000b21c __nhandle 0042821c + 0003:0000b220 __acmdln 00428220 + 0003:0000b22c ___env_initialized 0042822c + 0003:0000b23c ___mbctype_initialized 0042823c + 0003:0000b240 ___onexitend 00428240 + 0003:0000b244 ___onexitbegin 00428244 + 0003:0000b248 __FPinit 00428248 + 0003:0000b24c ___piob 0042824c + 0003:0000b5a0 __bufin 004285a0 + 0003:0000c5a0 __nstream 004295a0 + 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 0042a000 kernel32:KERNEL32.dll + 0004:00000014 __NULL_IMPORT_DESCRIPTOR 0042a014 kernel32:KERNEL32.dll + 0004:0000016c __imp__GetEnvironmentStringsW@0 0042a16c kernel32:KERNEL32.dll + 0004:00000170 __imp__TerminateProcess@8 0042a170 kernel32:KERNEL32.dll + 0004:00000174 __imp__GetCurrentProcess@0 0042a174 kernel32:KERNEL32.dll + 0004:00000178 __imp__GetTimeZoneInformation@4 0042a178 kernel32:KERNEL32.dll + 0004:0000017c __imp__GetSystemTime@4 0042a17c kernel32:KERNEL32.dll + 0004:00000180 __imp__GetLocalTime@4 0042a180 kernel32:KERNEL32.dll + 0004:00000184 __imp__GetCommandLineA@0 0042a184 kernel32:KERNEL32.dll + 0004:00000188 __imp__GetVersion@0 0042a188 kernel32:KERNEL32.dll + 0004:0000018c __imp__SetHandleCount@4 0042a18c kernel32:KERNEL32.dll + 0004:00000190 __imp__GetStdHandle@4 0042a190 kernel32:KERNEL32.dll + 0004:00000194 __imp__GetFileType@4 0042a194 kernel32:KERNEL32.dll + 0004:00000198 __imp__GetStartupInfoA@4 0042a198 kernel32:KERNEL32.dll + 0004:0000019c __imp__HeapAlloc@12 0042a19c kernel32:KERNEL32.dll + 0004:000001a0 __imp__GetLastError@0 0042a1a0 kernel32:KERNEL32.dll + 0004:000001a4 __imp__FlushFileBuffers@4 0042a1a4 kernel32:KERNEL32.dll + 0004:000001a8 __imp__WriteFile@20 0042a1a8 kernel32:KERNEL32.dll + 0004:000001ac __imp__GetFileAttributesA@4 0042a1ac kernel32:KERNEL32.dll + 0004:000001b0 __imp__SetFilePointer@16 0042a1b0 kernel32:KERNEL32.dll + 0004:000001b4 __imp__MultiByteToWideChar@24 0042a1b4 kernel32:KERNEL32.dll + 0004:000001b8 __imp__GetStringTypeA@20 0042a1b8 kernel32:KERNEL32.dll + 0004:000001bc __imp__GetStringTypeW@16 0042a1bc kernel32:KERNEL32.dll + 0004:000001c0 __imp__HeapFree@12 0042a1c0 kernel32:KERNEL32.dll + 0004:000001c4 __imp__CloseHandle@4 0042a1c4 kernel32:KERNEL32.dll + 0004:000001c8 __imp__ReadFile@20 0042a1c8 kernel32:KERNEL32.dll + 0004:000001cc __imp__WideCharToMultiByte@32 0042a1cc kernel32:KERNEL32.dll + 0004:000001d0 __imp__UnhandledExceptionFilter@4 0042a1d0 kernel32:KERNEL32.dll + 0004:000001d4 __imp__GetModuleFileNameA@12 0042a1d4 kernel32:KERNEL32.dll + 0004:000001d8 __imp__FreeEnvironmentStringsA@4 0042a1d8 kernel32:KERNEL32.dll + 0004:000001dc __imp__FreeEnvironmentStringsW@4 0042a1dc kernel32:KERNEL32.dll + 0004:000001e0 __imp__GetEnvironmentStrings@0 0042a1e0 kernel32:KERNEL32.dll + 0004:000001e4 __imp__ExitProcess@4 0042a1e4 kernel32:KERNEL32.dll + 0004:000001e8 __imp__GetModuleHandleA@4 0042a1e8 kernel32:KERNEL32.dll + 0004:000001ec __imp__GetEnvironmentVariableA@12 0042a1ec kernel32:KERNEL32.dll + 0004:000001f0 __imp__GetVersionExA@4 0042a1f0 kernel32:KERNEL32.dll + 0004:000001f4 __imp__HeapDestroy@4 0042a1f4 kernel32:KERNEL32.dll + 0004:000001f8 __imp__HeapCreate@12 0042a1f8 kernel32:KERNEL32.dll + 0004:000001fc __imp__VirtualFree@12 0042a1fc kernel32:KERNEL32.dll + 0004:00000200 __imp__RtlUnwind@16 0042a200 kernel32:KERNEL32.dll + 0004:00000204 __imp__VirtualAlloc@16 0042a204 kernel32:KERNEL32.dll + 0004:00000208 __imp__HeapReAlloc@16 0042a208 kernel32:KERNEL32.dll + 0004:0000020c __imp__IsBadWritePtr@8 0042a20c kernel32:KERNEL32.dll + 0004:00000210 __imp__SetStdHandle@8 0042a210 kernel32:KERNEL32.dll + 0004:00000214 __imp__GetExitCodeProcess@8 0042a214 kernel32:KERNEL32.dll + 0004:00000218 __imp__WaitForSingleObject@8 0042a218 kernel32:KERNEL32.dll + 0004:0000021c __imp__CreateProcessA@40 0042a21c kernel32:KERNEL32.dll + 0004:00000220 __imp__CreateFileA@28 0042a220 kernel32:KERNEL32.dll + 0004:00000224 __imp__GetCPInfo@8 0042a224 kernel32:KERNEL32.dll + 0004:00000228 __imp__GetACP@0 0042a228 kernel32:KERNEL32.dll + 0004:0000022c __imp__GetOEMCP@0 0042a22c kernel32:KERNEL32.dll + 0004:00000230 __imp__GetProcAddress@8 0042a230 kernel32:KERNEL32.dll + 0004:00000234 __imp__LoadLibraryA@4 0042a234 kernel32:KERNEL32.dll + 0004:00000238 __imp__CompareStringA@24 0042a238 kernel32:KERNEL32.dll + 0004:0000023c __imp__CompareStringW@24 0042a23c kernel32:KERNEL32.dll + 0004:00000240 __imp__SetEnvironmentVariableA@8 0042a240 kernel32:KERNEL32.dll + 0004:00000244 __imp__SetEndOfFile@4 0042a244 kernel32:KERNEL32.dll + 0004:00000248 __imp__LCMapStringA@24 0042a248 kernel32:KERNEL32.dll + 0004:0000024c __imp__LCMapStringW@24 0042a24c kernel32:KERNEL32.dll + 0004:00000250 __imp__GetCurrentDirectoryA@8 0042a250 kernel32:KERNEL32.dll + 0004:00000254 __imp__SetCurrentDirectoryA@4 0042a254 kernel32:KERNEL32.dll + 0004:00000258 \177KERNEL32_NULL_THUNK_DATA 0042a258 kernel32:KERNEL32.dll - entry point at 0001:0000f741 + entry point at 0001:0000f4d1 diff --git a/src/fsutil/ucpsub.c b/src/fsutil/ucpsub.c index c3b90ddc..a5ddbbeb 100644 --- a/src/fsutil/ucpsub.c +++ b/src/fsutil/ucpsub.c @@ -64,7 +64,11 @@ extern uchar *syserror; int xls(char *option, char *path); -int xchmod(char *path, char *modes); +int xchmod(char *modes, char *path); /* Nick reversed argument order */ +#if 1 /* Nick */ +int xchown(char *uidno, char *path); +int xchgrp(char *gidno, char *path); +#endif int xumask(char *masks); int xmknod(char *path, char *modes, char *devs, char *devs1); int xmkdir(char *path); @@ -232,7 +236,7 @@ int xls(option, thepath) /* just to make syntax equal to Solaris, Linux, etc */ int xchmod(modes, path) - char *path, *modes; + char *modes, *path; /* Nick reversed argument order */ { int mode = -1; @@ -250,6 +254,50 @@ int xchmod(modes, path) return 0; } +#if 1 /* Nick */ +int xchown(char *uidno, char *path) + { + int uid = -1; + struct stat statbuf; + + sscanf(uidno, "%d", &uid); + if (uid == -1) + { + PF("chown: bad uid\n"); + pse(); + return (-1); + } + if (UZIXstat(path, &statbuf) || UZIXchown(path, uid, statbuf.st_gid)) + { + PF("_chown: error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return 0; + } + +int xchgrp(char *gidno, char *path) + { + int gid = -1; + struct stat statbuf; + + sscanf(gidno, "%d", &gid); + if (gid == -1) + { + PF("chgrp: bad gid\n"); + pse(); + return (-1); + } + if (UZIXstat(path, &statbuf) || UZIXchown(path, statbuf.st_uid, gid)) + { + PF("_chgrp: error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return 0; +} +#endif + int xumask(masks) char *masks; { diff --git a/src/fsutil/utils.rel b/src/fsutil/utils.rel index 2aaadffb..1e9626ab 100644 --- a/src/fsutil/utils.rel +++ b/src/fsutil/utils.rel @@ -1,10 +1,10 @@ XL4 H 2 areas A global symbols M utils -S ?CL64180L_4_06_L00 Ref00000000 -S ?LEAVE_DIRECT_L09 Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 S ?ENT_PARM_DIRECT_L09 Ref00000000 S ?SS_CMP_L02 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 S .__.ABS. Def00000000 A _DEFAULT size 0 flags 0 A CODE size C5 flags 0 @@ -16,7 +16,7 @@ S int_max Def000000AF T 00 00 00 00 R 00 00 01 00 T 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 02 00 +R 00 00 01 00 02 05 01 00 T 03 00 00 00 R 00 00 01 00 T 03 00 00 00 @@ -34,18 +34,18 @@ R 00 00 01 00 T 27 00 00 00 R 00 00 01 00 T 27 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 01 00 +R 00 00 01 00 02 05 00 00 T 2A 00 00 00 R 00 00 01 00 T 2A 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 02 00 +R 00 00 01 00 02 05 01 00 T 2D 00 00 00 R 00 00 01 00 T 2D 00 00 00 R 00 00 01 00 -T 2D 00 00 00 DD 6E 08 DD 66 09 2B DD 75 08 DD +T 2D 00 00 00 DD 6E 0A DD 66 0B 2B DD 75 0A DD R 00 00 01 00 -T 38 00 00 00 74 09 23 7D B4 28 14 +T 38 00 00 00 74 0B 23 7D B4 28 14 R 00 00 01 00 T 3F 00 00 00 R 00 00 01 00 @@ -56,18 +56,18 @@ R 00 00 01 00 T 53 00 00 00 R 00 00 01 00 T 53 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 01 00 +R 00 00 01 00 02 05 00 00 T 56 00 00 00 R 00 00 01 00 T 56 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 02 00 +R 00 00 01 00 02 05 01 00 T 59 00 00 00 R 00 00 01 00 T 59 00 00 00 R 00 00 01 00 -T 59 00 00 00 DD 6E 08 DD 66 09 2B DD 75 08 DD +T 59 00 00 00 DD 6E 0A DD 66 0B 2B DD 75 0A DD R 00 00 01 00 -T 64 00 00 00 74 09 23 7D B4 28 20 +T 64 00 00 00 74 0B 23 7D B4 28 20 R 00 00 01 00 T 6B 00 00 00 R 00 00 01 00 @@ -80,13 +80,13 @@ R 00 00 01 00 T 8B 00 00 00 R 00 00 01 00 T 8B 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 01 00 +R 00 00 01 00 02 05 00 00 T 8E 00 00 00 R 00 00 01 00 T 8E 00 00 00 CD 00 00 00 00 4B 42 DD 6E 04 DD -R 00 00 01 00 02 05 02 00 +R 00 00 01 00 02 05 01 00 T 97 00 00 00 66 05 CD 00 00 00 00 30 08 DD 6E -R 00 00 01 00 02 07 03 00 +R 00 00 01 00 02 07 02 00 T A0 00 00 00 04 DD 66 05 18 06 R 00 00 01 00 T A6 00 00 00 @@ -96,11 +96,11 @@ R 00 00 01 00 T AC 00 00 00 R 00 00 01 00 T AC 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 01 00 +R 00 00 01 00 02 05 00 00 T AF 00 00 00 R 00 00 01 00 T AF 00 00 00 CD 00 00 00 00 EB CD 00 00 00 00 -R 00 00 01 00 02 05 02 00 02 0B 03 00 +R 00 00 01 00 02 05 01 00 02 0B 02 00 T B6 00 00 00 30 04 69 60 18 06 R 00 00 01 00 T BC 00 00 00 @@ -110,4 +110,4 @@ R 00 00 01 00 T C2 00 00 00 R 00 00 01 00 T C2 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 01 00 +R 00 00 01 00 02 05 00 00 diff --git a/src/gboot/build.ban b/src/gboot/build.ban new file mode 100644 index 00000000..fd61bc88 --- /dev/null +++ b/src/gboot/build.ban @@ -0,0 +1,35 @@ +copy ..\gboot.asm +copy ..\io64180.inc +copy ..\diag.inc +copy ..\copyr.inc +copy ..\clears.inc +as-z80 -l -o gboot +@if errorlevel 1 goto failure +link-z80 -f gboot +@if errorlevel 1 goto failure +ihex2bin gboot.i86 ..\..\..\bin\boot.bin +4dos /c crcd ..\..\..\bin\boot.bin +bin2c ..\..\..\bin\boot.bin ..\..\fsutil\boot.c + +copy ..\uzboot.asm +as-z80 -l -o uzboot +@if errorlevel 1 goto failure +copy ..\uzfile.asm +as-z80 -l -o uzfile +@if errorlevel 1 goto failure +copy ..\uzmain.asm +as-z80 -l -o uzmain +@if errorlevel 1 goto failure +copy ..\uzdata.asm +as-z80 -l -o uzdata +@if errorlevel 1 goto failure +link-z80 -f uzboot +@if errorlevel 1 goto failure +ihex2bin uzboot.i86 ..\..\..\bin\uzboot.ldr + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/gboot/gboot.asm$ b/src/gboot/gboot.asm$ deleted file mode 100644 index 29c12958..00000000 --- a/src/gboot/gboot.asm$ +++ /dev/null @@ -1,793 +0,0 @@ -; gboot.asm -; Generic Hytech boot loader program to occupy 4 sectors at start of each disk - -$ io64180.inc - -LDFILE equ 0f037h ; BOOTLDR.BIN entry point - -SUPERBLOCK equ 4 ; starting position of filesystem -SMOUNTED equ 12742 ; random number to specify mounted fs -ROOTINODE equ 1 ; inode number of / for all mounted fs - -BUFSIZE equ 200h ; how many bytes per disk block -BUFSIZELOG equ 9 ; shift count representing the above - -SIZEOF_DINODE_T equ 64 ; how many bytes per disk inode -DINODESPERBLOCK equ 8 ; how many disk inodes per disk block -DINODESPERBLOCKLOG equ 3 ; shift count representing the above - -DIRECTBLOCKS equ 18 -INDIRECTBLOCKS equ 1 ; MUST BE 1! -DINDIRECTBLOCKS equ 1 ; MUST BE 1! - -SIZEOF_DIRECT_T equ 16 ; how many bytes per directory entry -DIRNAMELEN equ 14 ; how many bytes of these are dir name - -REGION_LOG equ 14 -REGION_BYTES equ (1<> 14) & 1 - defb ((800h-(final-start)) >> 14) & 2 - defb ((0c00h-(final-start)) >> 14) & 3 - defb 0,0,0,0,0,0,0,0,0,0,0,0 - -entry: - call gmess - defb 'loading /boot/kernel.bin',0dh,0ah,0 - - ld de,SUPERBLOCK - ld hl,block - call block_read - - ld hl,(block) - ld de,SMOUNTED - or a - sbc hl,de - jr nz,black_magic - - ld hl,(block+2) - ld (reserv),hl - ld hl,(block+4) - ld (isize),hl - ld hl,(block+6) - ld (fsize),hl - - ld de,ROOTINODE - ld hl,name_boot - call dir_search ; returns de = the found inode - jr nz,bad_file - - ld hl,name_kernel_bin - call dir_search ; returns de = the found inode - jr nz,bad_file - - call file_scan - - call virtual_init ; modifies CBR (can't call EPROM now) - - ld bc,8080h ; initial spot in virt memory table - ld hl,region_list+2 ; -> block no. of 2nd found region - jr translate_loope - -translate_loop: - add hl,de ; restore hl value from comparison - - call block_to_bbr ; calculates a from word at hl (bumped) - ld (bc),a ; a = required bbr value to access page - inc bc - -translate_loope: - ld de,(region_ptr) ; indicates end of region list - or a - sbc hl,de ; see if we've gone past the end - jr c,translate_loop - - ld hl,region_list ; there is at least one entry - call block_to_bbr ; a = required bbr value for init code - -kazumi: ; please preserve a for entering kernel at label runsys! - ld sp,parameters-parameters_end ; stack just under copied params - - ld hl,parameters ; pre-initialised parameter block - ld de,parameters-parameters_end ; to fit neatly at top of memory - ld bc,parameters_end-parameters ; size in bytes to copy - ldir ; copy parameter block for kernel init - - .if 1 ; so as not to corrupt CBR when jumping to the loaded program - ld hl,runsys ; start of small stub program below - ld de,8100h ; -> just after virtual memory table - push de - ld c,runsys_end-runsys ; size of small stub program (b=0) - ldir ; copy stub program - ret ; enter stub program (jp 8100h) - .else - ld e,30h-8 - out0 (CBR),e ; window onto runsys (CBAR = 80h) - jp runsys+8000h ; run the remaining startup from window - .endif - -runsys: ld e,84h - out0 (CBAR),e ; CA0 = 16k, bank area = 16k, CA1 = 32k - - out0 (BBR),a ; bank area = logical 4000 = abs c:0000 - jp 4000h ; execute file from the 1st loaded page - .if 1 ; so as not to corrupt CBR when jumping to the loaded program -runsys_end: - .endif - -black_magic: - call gmess - defb 'bad magic: ',0 - add hl,de - jr reboot_ahexw - -bad_file: - call gmess - defb 'file not found',0dh,0ah,0 - jr reboot_plain - -; ----------------------------------------------------------------------------- -; had some kind of fatal error, the entry points are to save code space - -reboot_ahexw: - call ahexw - -reboot_acrlf: - call acrlf - -reboot_plain: - ; try not to surprise the user unnecessarily - call gmess - defb 'doing a clean boot',0dh,0ah,0 - - ; before rebooting, prepare to clobber CP/M drive A: directory - ld hl,block - ld de,block+1 - ld bc,BUFSIZE-1 - ld (hl),0aah ; clobbering pattern - ldir ; initialise temporary buffer - - ; perform the clobbering (this ensures a clean boot from EPROM) - ld de,304h - ld l,c - ld h,b ; ld hl,0 ; e:hl -> destination 4:0000 - - ld b,4 ; clobber until just before 4:0800 -clobber_loop: - push bc - - ld iy,block ; copy from d:iy -> destination - ld bc,BUFSIZE ; bytes to copy - call copyr ; copy them, one byte at a time - - pop bc - djnz clobber_loop - - ; ready to reboot, by instructing the WPO chip on motherboard - ld a,0aah - out0 (TRDR),A ; command byte to reboot the system - ld a,13h - out0 (CNTR),A ; TE=1, divisor = 3, start transmission - - ; wait for the reboot to occur, or else we're rather stuck - jr $ - -; ----------------------------------------------------------------------------- - -gmess: call amess - defb 'gboot: ',0 - jp amess - -rsel1: - .if 1 ; temporary only - ld de,2 ; save eprom serial no to 2:fc81 - call copy_serial_no - .endif - ld a,81h - out0 (TRDR),A ; command byte to set RSEL=1 - ld a,13h - out0 (CNTR),A ; TE=1, divisor = 3, start transmission - - sub a - dec a - jr nz,$-1 - dec a - jr nz,$-1 - dec a - jr nz,$-1 - dec a - jr nz,$-1 ; delay for command to be processed - .if 1 ; temporary only - ld de,200h ; restore eprom serial no from 2:fc81 -copy_serial_no: - ld hl,0fc81h - push hl - pop iy - ld bc,5 - jp copyr - .else - ret - .endif - -virtual_init: - call gmess - defb 'starting operating system',0dh,0ah,0 - - call rsel1 - - ld a,80h - out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k - - ld a,4-8 ;0 also works, see bstartup.s01 at label init - out0 (CBR),a ; window onto 0:8000, virt memory table - - ld hl,08000h - ld de,08001h - ld bc,0ffh - ld (hl),l ; 0 - ldir ; zero out the virtual memory table - ret - -; ----------------------------------------------------------------------------- - -file_scan: - ld hl,region_list - ld (region_ptr),hl - - ld hl,inode - call inode_read ; read inode of the target file - - call bmap_setup ; prepare counters to walk the file - call bmap_remain ; get hl = valid bytes in first block - ; and decrement the file size remaining - ld a,l - or h ; any bytes in file? - jr z,bad_file_size ; no, abort proceedings - -file_scan_loop: - call bmap_block ; get de = block no. of current block - ; and increment the block position - ld a,e - or d - jr z,bad_file_block -; ld l,e -; ld h,d -; call ahexw - - ld a,e - and PAGE_BLOCKS-1 ; check it starts on a page boundary - jr nz,bad_alignment - - ld hl,(region_ptr) - ld (hl),e - inc hl - ld (hl),d ; stash away the starting block no. - inc hl - ld (region_ptr),hl ; for the current region (bumped) - - ld b,REGION_BLOCKS-1 - -file_region_loop: - push bc - push de - - call bmap_remain ; get hl = valid bytes in current block - ; and decrement the file size remaining - ld a,l - or h - jr z,file_region_final - - call bmap_block ; get de = block no. of current block - ; and increment the block position - ld a,e - or d - jr z,bad_file_block -; ld a,' ' -; call abyte -; ld l,e -; ld h,d -; call ahexw - - ex de,hl ; hl = the actual block no. from file - pop de - inc de ; de = expected, contiguous block no. - - or a - sbc hl,de - jr nz,bad_alignment - - pop bc - djnz file_region_loop -; call acrlf - - call bmap_remain ; get hl = valid bytes in current block - ; and decrement the file size remaining - ld a,l - or h ; anything left to read? - jr nz,file_scan_loop ; yes (scan is limited by file size) - ret ; last region is = REGION_BLOCKS blocks - -file_region_final: -; call acrlf - pop hl ; last region is < REGION_BLOCKS blocks - pop hl ; clean up saved variables, and done - ret - -bad_file_size: - call gmess - defb 'null file',0dh,0ah,0 - jp reboot_plain - -bad_file_block: - call gmess - defb 'hole in file',0dh,0ah,0 - jp reboot_plain - -bad_alignment: - call gmess - defb 'not aligned',0dh,0ah,0 - jp reboot_plain - -; ----------------------------------------------------------------------------- - -dir_search: - ld (dir_name),hl - - ld hl,inode - call inode_read ; read inode of the dir to be searched - - call bmap_setup ; prepare counters to walk the file - jr dir_search_loope - -dir_search_loop: - push hl ; h = count of entries in current block - call bmap_block ; get de = block no. of current block - ; and increment the block position - ld a,e - or d - jr z,bad_dir_block - - ld hl,block - push hl - call block_read - pop hl - pop bc ; b = count of entries in current block - -dir_search_entry_loop: - push hl - inc hl - inc hl - - ld de,(dir_name) - ld c,DIRNAMELEN - -dir_search_compare_loop: - ld a,(de) - cp (hl) - jr nz,dir_search_compare_bad - or a - jr z,dir_search_compare_good - - inc hl - inc de - dec c - jr nz,dir_search_compare_loop - -dir_search_compare_good: - pop hl - ld e,(hl) - inc hl - ld d,(hl) - ret - -dir_search_compare_bad: - pop hl - ld de,SIZEOF_DIRECT_T - add hl,de - djnz dir_search_entry_loop - -dir_search_loope: - call bmap_remain ; get hl = valid bytes in current block - ; and decrement the file size remaining - add hl,hl - add hl,hl - add hl,hl - add hl,hl ; assumes SIZEOF_DIRECT_T = 16!! - - ld a,h ; a = valid bytes / SIZEOF_DIRECT_T - or a - jr nz,dir_search_loop - - ret - -bad_dir_block: - call gmess - defb 'hole in directory',0dh,0ah,0 - jp reboot_plain - -; ----------------------------------------------------------------------------- - -bmap_setup: - ld hl,(inode+8) - ld (size_remain),hl - ld hl,(inode+10) - ld (size_remain+2),hl - - ld hl,inode+24 - ld (direct_ptr),hl - ld hl,indirect_block+BUFSIZE - ld (indirect_ptr),hl - ld hl,dindirect_block+BUFSIZE - ld (dindirect_ptr),hl - ret - -bmap_remain: - ld hl,(size_remain) - ld de,(size_remain+2) - - ld bc,BUFSIZE - or a - sbc hl,bc - ex de,hl - ld b,0 ; ld bc,0 - sbc hl,bc - ex de,hl - jr c,bmap_remain_final - - ld (size_remain),hl - ld (size_remain+2),de - - ld hl,BUFSIZE - ret ; return a complete block of size hl - -bmap_remain_final: - ld hl,(size_remain) - ld (size_remain),bc ; 0 - ;ld (size_remain+2),bc ; 0 - ret ; return a partial block of size hl - -bmap_block: - ld hl,(direct_ptr) - ld de,inode+24+DIRECTBLOCKS*2 - or a - sbc hl,de - jr nc,bmap_indirect - - ld hl,(direct_ptr) - ld e,(hl) - inc hl - ld d,(hl) - inc hl - ld (direct_ptr),hl - ret - -bmap_indirect: - ld hl,(indirect_ptr) - ld de,indirect_block+BUFSIZE - or a - sbc hl,de - jr c,bmap_indirect_already - - ld hl,(direct_ptr) - ld e,(hl) - inc hl - ld d,(hl) - inc hl - ld (direct_ptr),hl - - ld hl,indirect_block - ld (indirect_ptr),hl - call block_read - -bmap_indirect_already: - ld hl,(direct_ptr) - ld de,inode+24+DIRECTBLOCKS*2+INDIRECTBLOCKS*2+1 ; fudge! - or a - sbc hl,de - jr nc,bmap_dindirect - - ld hl,(indirect_ptr) - ld e,(hl) - inc hl - ld d,(hl) - inc hl - ld (indirect_ptr),hl - ret - -bmap_dindirect: - ld hl,(dindirect_ptr) - ld de,dindirect_block+BUFSIZE - or a - sbc hl,de - jr c,bmap_dindirect_already - - ld hl,(indirect_ptr) - ld e,(hl) - inc hl - ld d,(hl) - inc hl - ld (indirect_ptr),hl - - ld hl,dindirect_block - ld (dindirect_ptr),hl - call block_read - -bmap_dindirect_already: - ld hl,(dindirect_ptr) - ld e,(hl) - inc hl - ld d,(hl) - inc hl - ld (dindirect_ptr),hl - ret - -; ----------------------------------------------------------------------------- -; enter with hl -> buffer, de = inode number - -inode_read: - push hl - - ld a,e - and DINODESPERBLOCK-1 ; find inode position within disk block - - ld b,DINODESPERBLOCKLOG ; shift count to find which disk block -inode_shift: - srl d - rr e - djnz inode_shift ; leaves de = block (relative to itab) - - ld hl,(isize) - scf - sbc hl,de ; check if block is beyond end of table - jr c,bad_inode - - ld hl,(reserv) - add hl,de - ex de,hl ; adjust block for start of inode table - - ld hl,block - push af - push hl - call block_read - pop hl - pop de ; d = inode position within block - - ld bc,SIZEOF_DINODE_T - ld e,c - mlt de - add hl,de - pop de ; de -> user's buffer for disk inode - ldir ; copy it, freeing up block buffer - ret - -bad_inode: - call gmess - defb 'bad inode: ',0 - add a,'0' - call abyte - call amess - defb ', ',0 - ex de,hl - jp reboot_ahexw - -; ----------------------------------------------------------------------------- -; enter with hl -> buffer, de = block number - -block_read: - push hl - call block_xlate ; a:hl -> data in ramdrive - - push hl - pop iy - ld d,a ; d:iy -> data in ramdrive - - pop hl - ld e,3 ; e:hl -> user's buffer in seg 3: - jp copyr ; copy BUFSIZE bytes from d:iy to e:hl - -block_write: - push hl - call block_xlate ; a:hl -> data in ramdrive - - pop iy - ld d,3 ; d:iy -> user's buffer in seg 3: - - ld e,a ; e:hl -> data in ramdrive - jp copyr ; copy BUFSIZE bytes from d:iy to e:hl - -block_xlate: - ld hl,HD0_SIZE - scf - sbc hl,de ; check whether block no is in range - jr c,bad_block - - ld bc,BUFSIZE ; bytes to be copied for 1 block - - ld hl,HD0_START - add hl,de ; hl = block index (from start of ram) - - ld a,h - ld h,l - ld l,c ;0 ; a:hl = block index * 100h - - add hl,hl - adc a,a ; a:hl = block index * BUFSIZE (200h!!) - ret - -block_to_bbr: - ld a,(hl) - inc hl - ld d,(hl) ; d:a = block no. from start of disk - inc hl - - srl d - rra - srl d - rra - srl d - rra ; a = block / 8 (PAGE_BLOCKS = 8!!) - - add a,HD0_START/PAGE_BLOCKS-4 - ret - -bad_block: - call gmess - defb 'bad block: ',0 - ex de,hl - jp reboot_ahexw - -; ----------------------------------------------------------------------------- - -initial_boot: - ld hl,UZINAM - call LDFILE ; copy entire KERNEL.BIN data to c:0000 - ret z ; halt if the file could not be found - - call gmess - defb 'loading A:KERNEL.BIN',0dh,0ah,0 - - ld a,'1' - ld (argument_1+7),a ; so kernel will use /dev/hd1 as root - -loop: ld de,(LDMAX) - or a - sbc hl,de ; did we load an entire extent? - jr nz,done ; no, assume the file is fully loaded - - add hl,de ; restore hl = LDMAX - ld (LDPTR),hl ; load from where we finished last time - - ld a,l - or h ; did we wrap around to a new segment? - jr nz,cont - - ld hl,LDSEG - inc (hl) ; yes, need to advance segment counter - -cont: ld hl,4000h - add hl,de - ld (LDMAX),hl ; advance LDMAX to load 4000h bytes - - ld hl,LDEXT - inc (hl) ; advance extent counter to next extent - - ld hl,UZINAM - call LDFILE ; copy more CMX.BIN data to LDSEG:LDPTR - jr nz,loop - - .if 1 ; virtual memory - ld hl,LDEXT - dec (hl) ; account for extent that wasn't found - .endif - -done: - .if 1 ; virtual memory - call virtual_init ; modifies CBR (can't call EPROM now) - - ld a,(LDEXT) - ld b,a ; how many extents were loaded ? (-1) - - ld hl,8080h ; initial spot in virt memory table - ld a,0c0h ; bbr value to access 2nd loaded page - -virtual_loop: - ld (hl),a ; map 16kbytes into virt memory space - inc hl - add a,4 - djnz virtual_loop - .else - call rsel1 ; select RAM for segments 0: and 1: - - ld a,80h - out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k - .endif - - ld a,0c0h-4 ; bbr value to access 1st loaded page - jp kazumi - -; ----------------------------------------------------------------------------- - -$ diag.inc -$ copyr.inc -$ clears.inc - -; ----------------------------------------------------------------------------- - -parameters: defw 2 ; argc - defw arguments-parameters_end ; argv - defw environment-parameters_end ; envp -arguments: defw argument_0-parameters_end - defw argument_1-parameters_end - defw 0 ; terminates the argument list -argument_0: defb '/boot/kernel.bin',0 -argument_1: defb 'root=hd0',0 -environment: defw environment_0-parameters_end - defw 0 ; termninates the environment list -environment_0: defb 'SN=00000',0 -parameters_end: ; this will equal address 0 after parameters are copied - -name_boot: defb 'boot',0 -name_kernel_bin: defb 'kernel.bin',0 - - ; note: defb 1 is very important here, because if UZINAM ends - ; up on a 32 byte boundary, the KERNEL.BIN filename (extent 0) - ; may be seen by the initial_boot routine, preventing the - ; proper loading of /boot/kernel after formatting the ramdrive -UZINAM: defb 1,'KERNEL BIN' ; LDNAM -LDEXT: defb 0 ; LDEXT -LDSEG: defb 0ch ; LDSEG -LDPTR: defw 0 ; LDPTR -LDMAX: defw 4000h ; LDMAX - -; ----------------------------------------------------------------------------- - -final: ; initialised code and data ends here - -reserv: -isize equ reserv+2 -fsize equ isize+2 - -dir_name equ fsize+2 -size_remain equ dir_name+2 - -direct_ptr equ size_remain+4 -indirect_ptr equ direct_ptr+2 -dindirect_ptr equ indirect_ptr+2 - -inode equ dindirect_ptr+2 -block equ inode+SIZEOF_DINODE_T - -indirect_block equ block+BUFSIZE -dindirect_block equ indirect_block+BUFSIZE - -region_ptr equ dindirect_block+BUFSIZE -region_list equ region_ptr+2 - -; ----------------------------------------------------------------------------- - - END diff --git a/src/gboot/gboot.map b/src/gboot/gboot.map deleted file mode 100644 index 9e67d797..00000000 --- a/src/gboot/gboot.map +++ /dev/null @@ -1,39 +0,0 @@ -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------- ---- ---- ------- ----- ------------ -. .ABS. 00000000 00000000 = 0. bytes (ABS,OVR) - - Value Global Value Global Value Global - ----- ------ ----- ------ ----- ------ - 00000000 e__DEFAUL | 00000000 l__DEFAUL | 00000000 s__DEFAUL - 00000000 s_RCODE | 00000000 .__.ABS. | 00000728 e_RCODE - 00000728 l_RCODE -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------- ---- ---- ------- ----- ------------ -_DEFAULT 00000000 00000000 = 0. bytes (REL,CON) - - Value Global Value Global Value Global - ----- ------ ----- ------ ----- ------ -Hexadecimal [32-Bits] - -Area Addr Size Decimal Bytes (Attributes) --------------------- ---- ---- ------- ----- ------------ -RCODE 00000000 00000728 = 1832. bytes (REL,CON) - - Value Global Value Global Value Global - ----- ------ ----- ------ ----- ------ - 0000059E abyte | 000005AB acrlf | 000005B4 ahexw - 000005B9 ahexb | 000005C2 ahexn | 000005CC amess - 000005DB copyr | 000006A3 clears - -Files Linked [ module(s) ] - -gboot [ ] - - -User Base Address Definitions - -_DEFAULT=0 diff --git a/src/gboot/gboot.rel b/src/gboot/gboot.rel deleted file mode 100644 index b7dfd70d..00000000 --- a/src/gboot/gboot.rel +++ /dev/null @@ -1,651 +0,0 @@ -XL4 -H 2 areas 9 global symbols -S .__.ABS. Def00000000 -A _DEFAULT size 0 flags 0 -A RCODE size 728 flags 0 -S ahexb Def000005B9 -S acrlf Def000005AB -S ahexn Def000005C2 -S abyte Def0000059E -S amess Def000005CC -S ahexw Def000005B4 -S copyr Def000005DB -S clears Def000006A3 -T 00 00 00 00 58 58 58 58 59 59 4D 4D 44 44 48 -R 00 00 01 00 -T 0B 00 00 00 48 4D 4D 53 53 31 00 80 CD -R 00 00 01 00 -T 14 00 00 00 A3 06 00 00 CD AB 05 00 00 CD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 1A 00 00 00 FD 04 00 00 18 22 00 00 00 42 4F -R 00 00 01 00 00 04 01 00 -T 23 00 00 00 4F 54 20 20 20 20 42 49 4E 00 00 -R 00 00 01 00 -T 2E 00 00 00 00 0F 00 01 00 00 00 00 00 00 00 -R 00 00 01 00 -T 39 00 00 00 00 00 00 00 00 00 00 -R 00 00 01 00 -T 40 00 00 00 -R 00 00 01 00 -T 40 00 00 00 CD D2 01 00 00 6C 6F 61 64 69 6E -R 00 00 01 00 00 05 01 00 -T 49 00 00 00 67 20 2F 62 6F 6F 74 2F 6B 65 72 -R 00 00 01 00 -T 54 00 00 00 6E 65 6C 2E 62 69 6E 0D 0A 00 CD -R 00 00 01 00 -T 5F 00 00 00 2C 02 00 00 11 04 00 21 -R 00 00 01 00 00 04 01 00 -T 65 00 00 00 7A 07 00 00 CD AB 04 00 00 2A -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 6B 00 00 00 7A 07 00 00 11 C6 31 B7 ED 52 C2 -R 00 00 01 00 00 04 01 00 -T 74 00 00 00 79 01 00 00 2A 7C 07 00 00 22 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 7A 00 00 00 28 07 00 00 2A 7E 07 00 00 22 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 80 00 00 00 2A 07 00 00 2A 80 07 00 00 22 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 86 00 00 00 2C 07 00 00 11 01 00 21 -R 00 00 01 00 00 04 01 00 -T 8C 00 00 00 06 07 00 00 CD 70 02 00 00 20 7B -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 93 00 00 00 21 0B 07 00 00 CD 70 02 00 00 20 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 9A 00 00 00 73 CD 99 03 00 00 21 94 0D 00 00 -R 00 00 01 00 00 06 01 00 00 0B 01 00 -T A1 00 00 00 01 14 00 CD 22 03 00 00 38 7B CD -R 00 00 01 00 00 08 01 00 -T AA 00 00 00 40 01 00 00 CD 5D 01 00 00 3E F8 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T B1 00 00 00 ED 39 38 CD 51 02 00 00 21 00 80 -R 00 00 01 00 00 08 01 00 -T BA 00 00 00 CD 22 03 00 00 3E FC ED 39 38 CD -R 00 00 01 00 00 05 01 00 -T C3 00 00 00 59 02 00 00 EB CD 22 03 00 00 CD -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T CA 00 00 00 62 02 00 00 D4 3F 02 00 00 CD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T D0 00 00 00 99 02 00 00 CD 0C 02 00 00 01 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T D6 00 00 00 80 80 21 AA 0D 00 00 18 06 -R 00 00 01 00 00 07 01 00 -T DD 00 00 00 -R 00 00 01 00 -T DD 00 00 00 19 CD DA 04 00 00 02 03 -R 00 00 01 00 00 06 01 00 -T E3 00 00 00 -R 00 00 01 00 -T E3 00 00 00 ED 5B A8 0D 00 00 B7 ED 52 38 F1 -R 00 00 01 00 00 06 01 00 -T EC 00 00 00 -R 00 00 01 00 -T EC 00 00 00 31 CD FF 21 D3 06 00 00 11 CD FF -R 00 00 01 00 00 08 01 00 -T F5 00 00 00 01 33 00 ED B0 21 3A 01 00 00 ED -R 00 00 01 00 00 0A 01 00 -T FE 00 00 00 5B A4 0D 00 00 D5 0E 06 ED B0 2A -R 00 00 01 00 00 05 01 00 -T 07 01 00 00 A0 0D 00 00 ED 5B A6 0D 00 00 C9 -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 0E 01 00 00 -R 00 00 01 00 -T 0E 01 00 00 CD D2 01 00 00 66 69 6C 65 20 6E -R 00 00 01 00 00 05 01 00 -T 17 01 00 00 6F 74 20 66 6F 75 6E 64 0D 0A 00 -R 00 00 01 00 -T 22 01 00 00 18 6B -R 00 00 01 00 -T 24 01 00 00 -R 00 00 01 00 -T 24 01 00 00 CD D2 01 00 00 66 69 6C 65 20 74 -R 00 00 01 00 00 05 01 00 -T 2D 01 00 00 6F 6F 20 73 68 6F 72 74 0D 0A 00 -R 00 00 01 00 -T 38 01 00 00 18 55 -R 00 00 01 00 -T 3A 01 00 00 -R 00 00 01 00 -T 3A 01 00 00 3E 84 ED 39 3A E9 -R 00 00 01 00 -T 40 01 00 00 -R 00 00 01 00 -T 40 01 00 00 -R 00 00 01 00 -T 40 01 00 00 2A 94 0D 00 00 11 C9 A6 B7 ED 52 -R 00 00 01 00 00 05 01 00 -T 49 01 00 00 C8 CD D2 01 00 00 62 61 64 20 65 -R 00 00 01 00 00 06 01 00 -T 52 01 00 00 5F 6D 61 67 69 63 3A 20 00 18 2B -R 00 00 01 00 -T 5D 01 00 00 -R 00 00 01 00 -T 5D 01 00 00 2A 96 0D 00 00 11 03 00 B7 ED 52 -R 00 00 01 00 00 05 01 00 -T 66 01 00 00 C8 CD D2 01 00 00 62 61 64 20 65 -R 00 00 01 00 00 06 01 00 -T 6F 01 00 00 5F 66 6F 72 6D 61 74 3A 20 00 -R 00 00 01 00 -T 79 01 00 00 -R 00 00 01 00 -T 79 01 00 00 CD D2 01 00 00 62 61 64 20 6D 61 -R 00 00 01 00 00 05 01 00 -T 82 01 00 00 67 69 63 3A 20 00 -R 00 00 01 00 -T 88 01 00 00 -R 00 00 01 00 -T 88 01 00 00 19 -R 00 00 01 00 -T 89 01 00 00 -R 00 00 01 00 -T 89 01 00 00 CD B4 05 00 00 -R 00 00 01 00 00 05 01 00 -T 8C 01 00 00 -R 00 00 01 00 -T 8C 01 00 00 CD AB 05 00 00 -R 00 00 01 00 00 05 01 00 -T 8F 01 00 00 -R 00 00 01 00 -T 8F 01 00 00 CD D2 01 00 00 64 6F 69 6E 67 20 -R 00 00 01 00 00 05 01 00 -T 98 01 00 00 61 20 63 6C 65 61 6E 20 62 6F 6F -R 00 00 01 00 -T A3 01 00 00 74 0D 0A 00 21 7A 07 00 00 11 -R 00 00 01 00 00 09 01 00 -T AB 01 00 00 7B 07 00 00 01 FF 01 36 AA ED B0 -R 00 00 01 00 00 04 01 00 -T B4 01 00 00 11 00 00 06 04 -R 00 00 01 00 -T B9 01 00 00 -R 00 00 01 00 -T B9 01 00 00 C5 D5 21 7A 07 00 00 CD -R 00 00 01 00 00 07 01 00 -T BF 01 00 00 B9 04 00 00 D1 C1 13 10 F3 3E AA -R 00 00 01 00 00 04 01 00 -T C8 01 00 00 ED 39 0B 3E 13 ED 39 0A 18 FE CD -R 00 00 01 00 -T D3 01 00 00 CC 05 00 00 67 62 6F 6F 74 3A 20 -R 00 00 01 00 00 04 01 00 -T DC 01 00 00 00 C3 CC 05 00 00 -R 00 00 01 00 00 06 01 00 -T E0 01 00 00 -R 00 00 01 00 -T E0 01 00 00 11 02 00 CD 00 02 00 00 3E 81 ED -R 00 00 01 00 00 08 01 00 -T E9 01 00 00 39 0B 3E 13 ED 39 0A 97 3D 20 FD -R 00 00 01 00 -T F4 01 00 00 3D 20 FD 3D 20 FD 3D 20 FD 11 -R 00 00 01 00 -T FE 01 00 00 00 02 -R 00 00 01 00 -T 00 02 00 00 -R 00 00 01 00 -T 00 02 00 00 21 81 FC E5 FD E1 01 05 00 C3 -R 00 00 01 00 -T 0A 02 00 00 DB 05 00 00 -R 00 00 01 00 00 04 01 00 -T 0C 02 00 00 -R 00 00 01 00 -T 0C 02 00 00 CD D2 01 00 00 73 74 61 72 74 69 -R 00 00 01 00 00 05 01 00 -T 15 02 00 00 6E 67 20 6F 70 65 72 61 74 69 6E -R 00 00 01 00 -T 20 02 00 00 67 20 73 79 73 74 65 6D 0D 0A 00 -R 00 00 01 00 -T 2B 02 00 00 C9 -R 00 00 01 00 -T 2C 02 00 00 -R 00 00 01 00 -T 2C 02 00 00 CD E0 01 00 00 3E 80 ED 39 3A 3E -R 00 00 01 00 00 05 01 00 -T 35 02 00 00 FC ED 39 38 11 01 80 01 FF 00 -R 00 00 01 00 -T 3F 02 00 00 -R 00 00 01 00 -T 3F 02 00 00 6B 62 2B 36 00 79 B0 C8 ED B0 C9 -R 00 00 01 00 -T 4A 02 00 00 -R 00 00 01 00 -T 4A 02 00 00 B7 ED 52 D0 19 EB C9 -R 00 00 01 00 -T 51 02 00 00 -R 00 00 01 00 -T 51 02 00 00 2A 9C 0D 00 00 11 14 00 18 11 -R 00 00 01 00 00 05 01 00 -T 59 02 00 00 -R 00 00 01 00 -T 59 02 00 00 2A A2 0D 00 00 ED 5B 9E 0D 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T 60 02 00 00 18 08 -R 00 00 01 00 -T 62 02 00 00 -R 00 00 01 00 -T 62 02 00 00 2A A6 0D 00 00 ED 5B A2 0D 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T 69 02 00 00 13 -R 00 00 01 00 -T 6A 02 00 00 -R 00 00 01 00 -T 6A 02 00 00 B7 ED 52 4D 44 C9 -R 00 00 01 00 -T 70 02 00 00 -R 00 00 01 00 -T 70 02 00 00 22 2E 07 00 00 CD 99 03 00 00 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 76 02 00 00 -R 00 00 01 00 -T 76 02 00 00 01 10 00 21 7A 0D 00 00 CD -R 00 00 01 00 00 08 01 00 -T 7D 02 00 00 22 03 00 00 D8 23 ED 5B -R 00 00 01 00 00 04 01 00 -T 83 02 00 00 2E 07 00 00 06 0E -R 00 00 01 00 00 04 01 00 -T 87 02 00 00 -R 00 00 01 00 -T 87 02 00 00 23 1A BE 20 EA B7 28 05 13 10 F5 -R 00 00 01 00 -T 92 02 00 00 1A B7 -R 00 00 01 00 -T 94 02 00 00 -R 00 00 01 00 -T 94 02 00 00 ED 5B 7A 0D 00 00 C9 -R 00 00 01 00 00 06 01 00 -T 99 02 00 00 -R 00 00 01 00 -T 99 02 00 00 21 AA 0D 00 00 22 A8 0D 00 00 CD -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T A0 02 00 00 A5 03 00 00 CD C4 03 00 00 7D B4 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T A7 02 00 00 28 3E -R 00 00 01 00 -T A9 02 00 00 -R 00 00 01 00 -T A9 02 00 00 CD EC 03 00 00 7B B2 28 49 7B E6 -R 00 00 01 00 00 05 01 00 -T B2 02 00 00 07 20 59 2A A8 0D 00 00 73 23 72 -R 00 00 01 00 00 08 01 00 -T BB 02 00 00 23 22 A8 0D 00 00 06 1F -R 00 00 01 00 00 06 01 00 -T C1 02 00 00 -R 00 00 01 00 -T C1 02 00 00 C5 D5 CD C4 03 00 00 7D B4 28 1A -R 00 00 01 00 00 07 01 00 -T CA 02 00 00 CD EC 03 00 00 7B B2 28 28 EB D1 -R 00 00 01 00 00 05 01 00 -T D3 02 00 00 13 B7 ED 52 20 35 C1 10 E5 CD -R 00 00 01 00 -T DD 02 00 00 C4 03 00 00 7D B4 20 C6 C9 -R 00 00 01 00 00 04 01 00 -T E4 02 00 00 -R 00 00 01 00 -T E4 02 00 00 E1 E1 C9 -R 00 00 01 00 -T E7 02 00 00 -R 00 00 01 00 -T E7 02 00 00 CD D2 01 00 00 6E 75 6C 6C 20 66 -R 00 00 01 00 00 05 01 00 -T F0 02 00 00 69 6C 65 0D 0A 00 C3 8F 01 00 00 -R 00 00 01 00 00 0B 01 00 -T F9 02 00 00 -R 00 00 01 00 -T F9 02 00 00 CD D2 01 00 00 68 6F 6C 65 20 69 -R 00 00 01 00 00 05 01 00 -T 02 03 00 00 6E 20 66 69 6C 65 0D 0A 00 C3 -R 00 00 01 00 -T 0C 03 00 00 8F 01 00 00 -R 00 00 01 00 00 04 01 00 -T 0E 03 00 00 -R 00 00 01 00 -T 0E 03 00 00 CD D2 01 00 00 6E 6F 74 20 61 6C -R 00 00 01 00 00 05 01 00 -T 17 03 00 00 69 67 6E 65 64 0D 0A 00 C3 -R 00 00 01 00 -T 20 03 00 00 8F 01 00 00 -R 00 00 01 00 00 04 01 00 -T 22 03 00 00 -R 00 00 01 00 -T 22 03 00 00 E5 C5 ED 43 8E 0D 00 00 22 -R 00 00 01 00 00 08 01 00 -T 29 03 00 00 90 0D 00 00 21 00 00 22 -R 00 00 01 00 00 04 01 00 -T 2F 03 00 00 92 0D 00 00 2A 8A 0D 00 00 7D B4 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 36 03 00 00 20 1A -R 00 00 01 00 -T 38 03 00 00 -R 00 00 01 00 -T 38 03 00 00 CD C4 03 00 00 7D B4 28 4F 22 -R 00 00 01 00 00 05 01 00 -T 40 03 00 00 8A 0D 00 00 CD EC 03 00 00 7B B2 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 47 03 00 00 28 B0 21 7A 07 00 00 22 -R 00 00 01 00 00 07 01 00 -T 4D 03 00 00 8C 0D 00 00 CD AB 04 00 00 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 52 03 00 00 -R 00 00 01 00 -T 52 03 00 00 2A 8A 0D 00 00 ED 5B 8E 0D 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T 59 03 00 00 CD 4A 02 00 00 2A 8A 0D 00 00 B7 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 60 03 00 00 ED 52 22 8A 0D 00 00 2A -R 00 00 01 00 00 07 01 00 -T 66 03 00 00 8E 0D 00 00 B7 ED 52 22 -R 00 00 01 00 00 04 01 00 -T 6C 03 00 00 8E 0D 00 00 2A 92 0D 00 00 19 22 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 73 03 00 00 92 0D 00 00 4B 42 ED 5B -R 00 00 01 00 00 04 01 00 -T 79 03 00 00 90 0D 00 00 2A 8C 0D 00 00 ED B0 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 80 03 00 00 22 8C 0D 00 00 ED 53 90 0D 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T 87 03 00 00 2A 8E 0D 00 00 7D B4 20 AA -R 00 00 01 00 00 05 01 00 -T 8E 03 00 00 -R 00 00 01 00 -T 8E 03 00 00 2A 92 0D 00 00 4D 44 D1 B7 ED 52 -R 00 00 01 00 00 05 01 00 -T 97 03 00 00 E1 C9 -R 00 00 01 00 -T 99 03 00 00 -R 00 00 01 00 -T 99 03 00 00 21 3A 07 00 00 CD 5F 04 00 00 21 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T A0 03 00 00 00 00 22 8A 0D 00 00 -R 00 00 01 00 00 07 01 00 -T A5 03 00 00 -R 00 00 01 00 -T A5 03 00 00 2A 42 07 00 00 22 30 07 00 00 2A -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T AC 03 00 00 44 07 00 00 22 32 07 00 00 21 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T B2 03 00 00 52 07 00 00 22 34 07 00 00 21 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T B8 03 00 00 7A 0B 00 00 22 36 07 00 00 21 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T BE 03 00 00 7A 0D 00 00 22 38 07 00 00 C9 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T C4 03 00 00 -R 00 00 01 00 -T C4 03 00 00 2A 30 07 00 00 ED 5B 32 07 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T CB 03 00 00 01 00 02 B7 ED 42 EB 06 00 ED 42 -R 00 00 01 00 -T D6 03 00 00 EB 38 0B 22 30 07 00 00 ED 53 -R 00 00 01 00 00 08 01 00 -T DE 03 00 00 32 07 00 00 21 00 02 C9 -R 00 00 01 00 00 04 01 00 -T E4 03 00 00 -R 00 00 01 00 -T E4 03 00 00 2A 30 07 00 00 ED 43 30 07 00 00 -R 00 00 01 00 00 05 01 00 00 0B 01 00 -T EB 03 00 00 C9 -R 00 00 01 00 -T EC 03 00 00 -R 00 00 01 00 -T EC 03 00 00 2A 34 07 00 00 11 76 07 00 00 B7 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T F3 03 00 00 ED 52 30 0B 2A 34 07 00 00 5E 23 -R 00 00 01 00 00 09 01 00 -T FC 03 00 00 56 23 22 34 07 00 00 C9 -R 00 00 01 00 00 07 01 00 -T 02 04 00 00 -R 00 00 01 00 -T 02 04 00 00 2A 36 07 00 00 11 7A 0B 00 00 B7 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 09 04 00 00 ED 52 38 13 2A 34 07 00 00 5E 23 -R 00 00 01 00 00 09 01 00 -T 12 04 00 00 56 23 22 34 07 00 00 21 -R 00 00 01 00 00 07 01 00 -T 18 04 00 00 7A 09 00 00 22 36 07 00 00 CD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 1E 04 00 00 AB 04 00 00 -R 00 00 01 00 00 04 01 00 -T 20 04 00 00 -R 00 00 01 00 -T 20 04 00 00 2A 34 07 00 00 11 79 07 00 00 B7 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 27 04 00 00 ED 52 30 0B 2A 36 07 00 00 5E 23 -R 00 00 01 00 00 09 01 00 -T 30 04 00 00 56 23 22 36 07 00 00 C9 -R 00 00 01 00 00 07 01 00 -T 36 04 00 00 -R 00 00 01 00 -T 36 04 00 00 2A 38 07 00 00 11 7A 0D 00 00 B7 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 3D 04 00 00 ED 52 38 13 2A 36 07 00 00 5E 23 -R 00 00 01 00 00 09 01 00 -T 46 04 00 00 56 23 22 36 07 00 00 21 -R 00 00 01 00 00 07 01 00 -T 4C 04 00 00 7A 0B 00 00 22 38 07 00 00 CD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 52 04 00 00 AB 04 00 00 -R 00 00 01 00 00 04 01 00 -T 54 04 00 00 -R 00 00 01 00 -T 54 04 00 00 2A 38 07 00 00 5E 23 56 23 22 -R 00 00 01 00 00 05 01 00 -T 5C 04 00 00 38 07 00 00 C9 -R 00 00 01 00 00 04 01 00 -T 5F 04 00 00 -R 00 00 01 00 -T 5F 04 00 00 E5 7B E6 07 06 03 -R 00 00 01 00 -T 65 04 00 00 -R 00 00 01 00 -T 65 04 00 00 CB 3A CB 1B 10 FA 2A 2A 07 00 00 -R 00 00 01 00 00 0B 01 00 -T 6E 04 00 00 37 ED 52 38 1A 2A 28 07 00 00 19 -R 00 00 01 00 00 0A 01 00 -T 77 04 00 00 EB 21 7A 07 00 00 F5 E5 CD -R 00 00 01 00 00 06 01 00 -T 7E 04 00 00 AB 04 00 00 E1 D1 01 40 00 59 ED -R 00 00 01 00 00 04 01 00 -T 87 04 00 00 5C 19 D1 ED B0 C9 -R 00 00 01 00 -T 8D 04 00 00 -R 00 00 01 00 -T 8D 04 00 00 CD D2 01 00 00 62 61 64 20 69 6E -R 00 00 01 00 00 05 01 00 -T 96 04 00 00 6F 64 65 3A 20 00 C6 30 CD -R 00 00 01 00 -T 9F 04 00 00 9E 05 00 00 CD CC 05 00 00 2C 20 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T A6 04 00 00 00 EB C3 89 01 00 00 -R 00 00 01 00 00 07 01 00 -T AB 04 00 00 -R 00 00 01 00 -T AB 04 00 00 E5 CD C5 04 00 00 E5 FD E1 57 E1 -R 00 00 01 00 00 06 01 00 -T B4 04 00 00 1E 03 C3 DB 05 00 00 -R 00 00 01 00 00 07 01 00 -T B9 04 00 00 -R 00 00 01 00 -T B9 04 00 00 E5 CD C5 04 00 00 FD E1 16 03 5F -R 00 00 01 00 00 06 01 00 -T C2 04 00 00 C3 DB 05 00 00 -R 00 00 01 00 00 05 01 00 -T C5 04 00 00 -R 00 00 01 00 -T C5 04 00 00 21 00 06 37 ED 52 38 1D 01 00 02 -R 00 00 01 00 -T D0 04 00 00 21 00 02 19 7C 65 69 29 8F C9 -R 00 00 01 00 -T DA 04 00 00 -R 00 00 01 00 -T DA 04 00 00 7E 23 56 23 CB 3A 1F CB 3A 1F CB -R 00 00 01 00 -T E5 04 00 00 3A 1F C6 3C C9 -R 00 00 01 00 -T EA 04 00 00 -R 00 00 01 00 -T EA 04 00 00 CD D2 01 00 00 62 61 64 20 62 6C -R 00 00 01 00 00 05 01 00 -T F3 04 00 00 6F 63 6B 3A 20 00 EB C3 -R 00 00 01 00 -T FB 04 00 00 89 01 00 00 -R 00 00 01 00 00 04 01 00 -T FD 04 00 00 -R 00 00 01 00 -T FD 04 00 00 21 16 07 00 00 CD 37 F0 C8 CD -R 00 00 01 00 00 05 01 00 -T 05 05 00 00 D2 01 00 00 6C 6F 61 64 69 6E 67 -R 00 00 01 00 00 04 01 00 -T 0E 05 00 00 20 41 3A 4B 45 52 4E 45 4C 2E 42 -R 00 00 01 00 -T 19 05 00 00 49 4E 0D 0A 00 3E 31 32 -R 00 00 01 00 -T 21 05 00 00 F7 06 00 00 ED 5B 26 07 00 00 B7 -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 28 05 00 00 ED 52 20 23 19 22 24 07 00 00 7D -R 00 00 01 00 00 0A 01 00 -T 31 05 00 00 B4 20 04 21 23 07 00 00 34 21 -R 00 00 01 00 00 08 01 00 -T 39 05 00 00 00 40 19 22 26 07 00 00 21 -R 00 00 01 00 00 08 01 00 -T 40 05 00 00 22 07 00 00 34 21 16 07 00 00 CD -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 47 05 00 00 37 F0 20 D8 21 22 07 00 00 35 -R 00 00 01 00 00 09 01 00 -T 4F 05 00 00 -R 00 00 01 00 -T 4F 05 00 00 CD 2C 02 00 00 FD 21 00 00 21 -R 00 00 01 00 00 05 01 00 -T 57 05 00 00 94 0D 00 00 11 03 0C 01 14 00 CD -R 00 00 01 00 00 04 01 00 -T 60 05 00 00 DB 05 00 00 CD 40 01 00 00 CD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 66 05 00 00 5D 01 00 00 CD 51 02 00 00 D5 FD -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 6D 05 00 00 E1 11 00 0C 6B 63 CD DB 05 00 00 -R 00 00 01 00 00 0B 01 00 -T 76 05 00 00 D5 CD 59 02 00 00 21 00 C0 19 D1 -R 00 00 01 00 00 06 01 00 -T 7F 05 00 00 CD DB 05 00 00 CD 62 02 00 00 D4 -R 00 00 01 00 00 05 01 00 00 0A 01 00 -T 86 05 00 00 3F 02 00 00 CD 0C 02 00 00 3A -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 8C 05 00 00 22 07 00 00 3C 47 21 80 80 3E BC -R 00 00 01 00 00 04 01 00 -T 95 05 00 00 -R 00 00 01 00 -T 95 05 00 00 77 23 C6 04 10 FA C3 EC 00 00 00 -R 00 00 01 00 00 0B 01 00 -T 9E 05 00 00 -R 00 00 01 00 -T 9E 05 00 00 F5 ED 38 05 E6 02 28 F9 F1 ED 39 -R 00 00 01 00 -T A9 05 00 00 07 C9 -R 00 00 01 00 -T AB 05 00 00 -R 00 00 01 00 -T AB 05 00 00 3E 0D CD 9E 05 00 00 3E 0A 18 EA -R 00 00 01 00 00 07 01 00 -T B4 05 00 00 -R 00 00 01 00 -T B4 05 00 00 7C CD B9 05 00 00 7D -R 00 00 01 00 00 06 01 00 -T B9 05 00 00 -R 00 00 01 00 -T B9 05 00 00 F5 0F 0F 0F 0F CD C2 05 00 00 F1 -R 00 00 01 00 00 0A 01 00 -T C2 05 00 00 -R 00 00 01 00 -T C2 05 00 00 E6 0F C6 90 27 CE 40 27 18 D2 -R 00 00 01 00 -T CC 05 00 00 -R 00 00 01 00 -T CC 05 00 00 E3 F5 7E 23 B7 28 05 CD -R 00 00 01 00 -T D4 05 00 00 9E 05 00 00 18 F6 F1 E3 C9 -R 00 00 01 00 00 04 01 00 -T DB 05 00 00 -R 00 00 01 00 -T DB 05 00 00 7B FE 04 D2 59 06 00 00 79 E6 1F -R 00 00 01 00 00 08 01 00 -T E4 05 00 00 C5 4F 06 00 CD 2B 06 00 00 0C 0D -R 00 00 01 00 00 09 01 00 -T ED 05 00 00 28 11 ED 38 30 EE 50 ED 39 30 FD -R 00 00 01 00 -T F8 05 00 00 09 DC 55 06 00 00 09 DC -R 00 00 01 00 00 06 01 00 -T FE 05 00 00 57 06 00 00 -R 00 00 01 00 00 04 01 00 -T 00 06 00 00 -R 00 00 01 00 -T 00 06 00 00 C1 3E 05 CB 38 CB 19 3D 20 F9 18 -R 00 00 01 00 -T 0B 06 00 00 1A C5 01 20 00 ED 09 26 ED 38 30 -R 00 00 01 00 -T 16 06 00 00 EE 50 ED 39 30 FD 09 DC -R 00 00 01 00 -T 1E 06 00 00 55 06 00 00 09 DC 57 06 00 00 C1 -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 25 06 00 00 0B 78 B1 20 E2 C9 -R 00 00 01 00 -T 2B 06 00 00 -R 00 00 01 00 -T 2B 06 00 00 ED 09 26 ED 01 27 18 05 3E 01 ED -R 00 00 01 00 -T 36 06 00 00 39 26 E5 FD E5 ED 29 23 ED 21 24 -R 00 00 01 00 -T 41 06 00 00 ED 19 25 E1 ED 29 20 ED 21 21 ED -R 00 00 01 00 -T 4C 06 00 00 11 22 E1 3E 02 ED 39 31 C9 14 C9 -R 00 00 01 00 -T 57 06 00 00 1C C9 C5 AF ED 39 26 ED 39 27 3E -R 00 00 01 00 -T 62 06 00 00 04 CB 38 CB 19 3D 20 F9 78 B1 28 -R 00 00 01 00 -T 6D 06 00 00 0D C5 01 10 00 CD 83 06 00 00 C1 -R 00 00 01 00 00 0A 01 00 -T 76 06 00 00 0B 78 B1 20 F3 C1 47 79 E6 0F 28 -R 00 00 01 00 -T 81 06 00 00 20 4F ED 30 26 CC 33 06 00 00 FD -R 00 00 01 00 00 0A 01 00 -T 8A 06 00 00 09 DC 55 06 00 00 09 DC -R 00 00 01 00 00 06 01 00 -T 90 06 00 00 57 06 00 00 41 0E 01 ED 38 30 EE -R 00 00 01 00 00 04 01 00 -T 99 06 00 00 50 ED 39 30 ED 09 26 10 F8 -R 00 00 01 00 -T A2 06 00 00 -R 00 00 01 00 -T A2 06 00 00 C9 -R 00 00 01 00 -T A3 06 00 00 -R 00 00 01 00 -T A3 06 00 00 3E 74 ED 39 00 ED 39 01 3E 22 ED -R 00 00 01 00 -T AE 06 00 00 39 02 ED 39 03 97 ED 39 04 ED 39 -R 00 00 01 00 -T B9 06 00 00 05 ED 30 08 ED 30 09 ED 39 27 ED -R 00 00 01 00 -T C4 06 00 00 39 2F ED 39 29 ED 39 2A ED 39 2B -R 00 00 01 00 -T CF 06 00 00 ED 39 2C C9 02 00 D3 FF F3 FF -R 00 00 01 00 -T D9 06 00 00 D9 FF EA FF 00 00 2F 62 6F 6F 74 -R 00 00 01 00 -T E4 06 00 00 2F 6B 65 72 6E 65 6C 2E 62 69 6E -R 00 00 01 00 -T EF 06 00 00 00 72 6F 6F 74 3D 68 64 30 00 -R 00 00 01 00 -T F9 06 00 00 F7 FF 00 00 53 4E 3D 30 30 30 30 -R 00 00 01 00 -T 04 07 00 00 30 00 -R 00 00 01 00 -T 06 07 00 00 -R 00 00 01 00 -T 06 07 00 00 62 6F 6F 74 00 6B 65 72 6E 65 6C -R 00 00 01 00 -T 11 07 00 00 2E 62 69 6E 00 01 4B 45 52 4E 45 -R 00 00 01 00 -T 1C 07 00 00 4C 20 20 42 49 4E 00 0C 00 00 -R 00 00 01 00 -T 26 07 00 00 00 40 -R 00 00 01 00 -T 28 07 00 00 -R 00 00 01 00 -T 28 07 00 00 -R 00 00 01 00 diff --git a/src/gboot/n.bat b/src/gboot/n.bat index 2a922e15..a9e801e6 100644 --- a/src/gboot/n.bat +++ b/src/gboot/n.bat @@ -1,25 +1,8 @@ -as-z80 -l -o gboot -@if errorlevel 1 goto failure -link-z80 -f gboot -@if errorlevel 1 goto failure - -ihex2bin gboot.i86 ..\..\bin\boot.bin -4dos /c crcd ..\..\bin\boot.bin -bin2c ..\..\bin\boot.bin ..\fsutil\boot.c - -copy checksum.dat \nlddl -copy checksum.dat \nlddl\crc.dat -copy ..\..\bin\boot.bin \nlddl -set country=NLD -crc -copy \nlddl\checksum ..\..\bin - -copy \nlddl\checksum \\darkstar\public\dos622\nlddl -copy \nlddl\boot.bin \\darkstar\public\dos622\nlddl - -@echo SUCCESS -@goto done -:failure -@echo FAILURE -:done +md build +cd build +copy ..\gboot.lnk +copy ..\uzboot.lnk +copy ..\build.ban n.bat +call n +cd .. diff --git a/src/gboot/uzboot.asm b/src/gboot/uzboot.asm new file mode 100644 index 00000000..99c710f6 --- /dev/null +++ b/src/gboot/uzboot.asm @@ -0,0 +1,67 @@ +; uzboot.asm by Nick, based on c0k.asm for UZI180 (creates a kernel executable) + +; ----------------------------------------------------------------------------- + +$ io64180.inc + +E_MAGIC equ 0a6c9h +E_FORMAT_KERNEL equ 3 +E_STACK_SIZE equ 1000h + +; ----------------------------------------------------------------------------- + + module _uzboot + + extern init + + extern e_RCODE ; e_hsize + extern s_ICODE ; e_idata + extern s_UDATA0 ; e_udata + extern s_CSTACK ; e_stack + extern e_CSTACK ; e_break + +; ----------------------------------------------------------------------------- +; forward definitions of segments, to set the linkage order (c0k must be first) + + rseg RCODE + rseg ICODE +; rseg TEMP +; rseg DATA0 +; rseg WCSTR + rseg CONST + rseg CSTR + rseg IDATA0(NUL) + rseg CDATA0 + rseg ECSTR(NUL) + rseg CCSTR + rseg CODE(NUL) ; needs to be at end for banked model + rseg UDATA0 + rseg CSTACK + +; ----------------------------------------------------------------------------- + + rseg _DEFAULT ; means header is discarded at loading + + defw E_MAGIC ; e_magic + defw E_FORMAT_KERNEL ; e_format + defd 12345678h ; e_size + defw e_RCODE+14h ; e_hsize (14h = l__DEFAULT) + defw s_ICODE ; e_idata + defw init ; e_entry + defw s_UDATA0 ; e_udata + defw s_CSTACK ; e_stack + defw e_CSTACK ; e_break + +; ----------------------------------------------------------------------------- + +$ diag.inc ; this will select RCODE segment +$ copyr.inc ; this will select RCODE segment + +; ----------------------------------------------------------------------------- + + rseg CSTACK + defs E_STACK_SIZE ; the default stack size is set here + +; ----------------------------------------------------------------------------- + + END diff --git a/src/gboot/uzboot.lnk b/src/gboot/uzboot.lnk new file mode 100644 index 00000000..6fc150b2 --- /dev/null +++ b/src/gboot/uzboot.lnk @@ -0,0 +1,12 @@ +-m +-u +-i +-o uzboot +-bl RCODE=0 +-bl ICODE=0x8100 +-bl CODE=0x804000,0x10000 +-bc CODE=0x4000 +uzboot +uzfile +uzmain +uzdata diff --git a/src/gboot/uzdata.asm b/src/gboot/uzdata.asm new file mode 100644 index 00000000..7f4bac37 --- /dev/null +++ b/src/gboot/uzdata.asm @@ -0,0 +1,22 @@ +; uzdata.asm by Nick, gunzipper, stub program providing label to access zdata + +; ----------------------------------------------------------------------------- + +$ io64180.inc + +; ----------------------------------------------------------------------------- + + module _uzdata + + public zdata + + rseg CODE + +; ----------------------------------------------------------------------------- + +zdata:: + ; the actual data is provided by concatenating it to the executable + +; ----------------------------------------------------------------------------- + + END diff --git a/src/gboot/uzfile.asm b/src/gboot/uzfile.asm new file mode 100644 index 00000000..16c12e9c --- /dev/null +++ b/src/gboot/uzfile.asm @@ -0,0 +1,1255 @@ +; uzfile.asm by Nick, gunzipper, based on zipfile.inc from Hytech EPROM 5.529+ + +; ----------------------------------------------------------------------------- + +$ io64180.inc + + module _uzfile + + public uzfgo + public gzhbuf + public gztbuf + extern abyte + extern ahexb + extern ahexw + extern acrlf + extern bomb + extern copyr + extern uzmess + + rseg RCODE + +; ----------------------------------------------------------------------------- + +bad_format: + call uzmess + db 'not in gzip format',0dh,0ah,0 + jp bomb + +uzfgo: ; file is deflated, inflate + ;in0 d,(BBR) + ;push de + + ;ld e,0 + ;call winehl ; e:hl -> input data + ;push hl + ;pop iy + ;out0 (BBR),e ; BBR:iy -> input data + + ld (outptr),hl + ld hl,outseg + ld (hl),e ; save absolute address -> output buffer for calls to copyr + + ld hl,virtbr + ld (hl),d ; save virtual base address to use when incrementing virtbr:ix + push iy + pop ix ; now reading the input data from (ix) instead of (iy) + + ld l,d + ld h,80h + ld a,(hl) ; translate BBR value via virtual memory table for actual use + out0 (BBR),a ; prepare to read the input data directly from (ix) + + sub a ; inflation_routine + ld (lblock),a ; last block flag + ld (dbits),a ; dead bits in low dbuf + call nxtix ; initialise dbuf + + ld iy,gzhbuf + ld b,10 + call pread + + ld hl,(gzhbuf) + ld de,8b1fh + or a + sbc hl,de ; ensure magic number is gzip + jr nz,bad_format + + ld hl,(gzhbuf+2) + ld de,8 + or a + sbc hl,de ; ensure compression method = 8 and no header options are present + jr nz,bad_format + + ld iy,outbuf ; non-repeated data will be stored temporarily at (iy) + +uzf0: ld a,(lblock) + dec a + .if 0 + jp z,uzfret + .else + jr z,uzfret ; inflate_done + .endif + + .if 0 + call acrlf + + ld a,(virtbr) + call ahexb + ld a,':' + call abyte + push ix + pop hl + call ahexw + + ld a,'=' + call abyte + + extern zdata + ld hl,LWRD zdata+10 + ld a,BYTE3 zdata+10 + add hl,hl + add hl,hl + rra + rr h + rr l + rra + rr h + rr l + ex de,hl + ld c,a ; c:de -> absolute start of compressed data + + push ix + pop hl + ld a,(virtbr) + add hl,hl + add hl,hl + rra + rr h + rr l + rra + rr h + rr l ; a:hl -> absolute position in compressed data + + or a + sbc hl,de + sbc a,c ; a:hl = absolute offset within compressed data + call ahexb + call ahexw + + ld a,' ' + call abyte + ld a,16 + ld hl,dbits + sub (hl) + call ahexb + ld a,' ' + call abyte + call peek + ld a,c + and 7 + call ahexb + call acrlf + .endif + + ld a,1 + call bits ; get_bit + ld (lblock),a + + call tbl ; read_tables + ;jr nz,uzfret ; bad table + +uzf1: + .if 0 + ld a,'a' + call abyte + .endif + + ;ld bc,wdog ; rwdog + ;in0 (c) + + ld hl,plit ; lit_parse_table + ld de,llit ; lit_bitlen_table + call parse ; returns de = item + dec d + .if 0 + jp z,uzf2 + .else + jr z,uzf2 + .endif + + ld (iy),e + inc iy + .if 0 + ld a,e + call ahexb + call acrlf + .endif + .if 0 + ld a,'b' + call abyte + .endif + + .if 1 + ld hl,plit ; lit_parse_table + ld de,llit ; lit_bitlen_table + call parse ; returns de = item + dec d + jr z,uzf2 + + ld (iy),e + inc iy + .if 0 + ld a,e + call ahexb + call acrlf + .endif + .if 0 + ld a,'c' + call abyte + .endif + + ld hl,plit ; lit_parse_table + ld de,llit ; lit_bitlen_table + call parse ; returns de = item + dec d + jr z,uzf2 + + ld (iy),e + inc iy + .if 0 + ld a,e + call ahexb + call acrlf + .endif + .if 0 + ld a,'d' + call abyte + .endif + + ld hl,plit ; lit_parse_table + ld de,llit ; lit_bitlen_table + call parse ; returns de = item + dec d + jr z,uzf2 + + ld (iy),e + inc iy + .if 0 + ld a,e + call ahexb + call acrlf + .endif + .if 0 + ld a,'e' + call abyte + .endif + + push iy + pop hl + ld de,outbuf+100h + or a + sbc hl,de + jr c,uzf1 ; output buffer still has room + .if 0 + ld a,'f' + call abyte + .endif + + inc h ; hl now = iy - outbuf (byte count) + call oflsh + .endif + jr uzf1 + +uzfret: ; enter with z = success, nz = failure + .if 0 + ld a,'g' + call abyte + .endif + + ;ld bc,(zdbuf+16h) ; uncompressed size, if success + ;pop de + ;out0 (BBR),d + push iy + pop hl + ld de,outbuf + or a + sbc hl,de + call nz,oflsh ; leaves outptr/seg valid for possible checking by our caller + + ld iy,gztbuf + ld b,8 + call pread ; retrieve crc/size, our caller is responsible for checking them + + ld hl,outseg + ld e,(hl) + ld hl,(outptr) ; so our caller can calculate the actual decompressed size + ret + +uzf2: + .if 0 + ld a,'h' + call abyte + .endif + + ld a,e + or a + .if 1 + jp z,uzf0 + .else + jr z,uzf0 ; new_table + .endif + + ex de,hl ; hl = basic length code + + cp 9 + jr c,uzf4 ; length 3-10 = hl+2, no extra bits + cp 1dh + jr c,uzf3 ; length 11-258, 1-5 extra bits + + ld hl,258 ; length 258 = hl, no extra bits + jr uzf5 + +uzf3: sub 5 ; a = 4-17h extra bits/4 + rrca + rrca + and 7 + ld b,a ; b = 1-5 extra bits + + ld a,l + dec a ; no need to sub 5 + and 3 ; 4 possible lengths for current b + or 4 + ld l,a ; hl = 4-7 for algorithm + + ld a,b + add hl,hl ; hl = base length, value 0-0e0h + djnz $-1 + + ex de,hl + call bitsb ; hl = 1-5 extra bits, value 0-1fh + add hl,de ; hl = 8-0ffh for lengths 11-258 + + inc hl +uzf4: inc hl + inc hl +uzf5: push hl + .if 0 + ld a,'i' + call abyte + .endif + + ld hl,pdist ; dist_parse_table + ld de,ldist ; dist_bitlen_table + call parse ; returns de = item + + ;ld a,e + ex de,hl + ld a,l + cp 4 + jr c,uzf6 ; de = distance 0-3, no extra bits + + ;ex de,hl ; hl = basic distance code + + rrca + and 0fh + dec a + ld b,a ; b = 1-0bh extra bits + + ld a,l + and 1 ; 2 possible distances for current b + or 2 + ld l,a ; hl = 2-3 for algorithm + + ld a,b + add hl,hl ; hl = base distance, value 0-6000h + djnz $-1 + + ex de,hl + call bitsw ; hl = 0-0bh extra bits, value 0-1fffh + add hl,de ; de = distance 4-7fffh + + ;ex de,hl +uzf6: ;inc de ; real distance + inc hl + push hl + .if 0 + ld a,'j' + call abyte + .endif + + push iy + pop hl + ld de,outbuf + sub a ;or a + sbc hl,de ; got anything in output buffer? + ld c,l + ld b,h ; zf, bc indicate how many bytes waiting + + ld iy,outbuf-4000h + ld d,a ;ld d,0 + + ld hl,outseg + ld e,(hl) + ld hl,(outptr) + + call nz,copyr ; flush anything still in output buffer + .if 0 + ld a,'k' + call abyte + .endif + + ;push iy + ;pop hl + ;push hl + ;or a + ;sbc hl,de + ;pop de + ;pop bc + ;ldir + ;push de + ;pop iy + ; e:hl = output location + ; can't use outptr/seg until e:hl has been saved back + .if 0 + ex (sp),hl + call ahexw + ex (sp),hl + ld a,',' + call abyte + .endif + pop bc ; bc = distance code + push hl + or a + sbc hl,bc ; go backwards as specified by distance code + ex (sp),hl ; restore e:hl = output location + pop iy + ld a,e + sbc a,0 + ld d,a ; d:iy = output location - distance code + + .if 0 + ex (sp),hl + call ahexw + ex (sp),hl + call acrlf + .endif + pop bc ; bc = length code + call copyr ; append bc bytes from d:iy to output buffer + + ld (outptr),hl + ld hl,outseg + ld (hl),e + + ld iy,outbuf ; restart output buffer + + .if 0 + ld a,(zfprog) + or a + jp z,uzf1 ; skip progress callouts if disabled + + push ix + pop hl + in0 a,(BBR) + rlca + rlca + rlca + rlca + add a,h ; minor absehl + call uzprog ; a = index = source address / 100h + .endif + jp uzf1 + +; ----------------------------------------------------------------------------- + +tbl: ld a,2 + call bits ; get_bits + dec a ; 1 = default tables + jr nz,tbldyn + + ld hl,llit ; lit_bitlen_table + ld de,llit+1 ; lit_bitlen_table+1 + ld bc,90h + ld (hl),8 + ldir ; 90h * bit length 8 + ld c,70h + ld (hl),9 + ldir ; 70h * bit length 9 + ld c,18h + ld (hl),7 + ldir ; 18h * bit length 7 + ld c,8-1 + ld (hl),8 ; 8 * bit length 8 + ldir + + ld hl,ldist ; dist_bitlen_table + ld de,ldist+1 + ld bc,20h-1 + ld (hl),5 + ldir ; 20h * bit length 5 + + ld hl,120h + ld (nlit),hl ; num_lit_codes = 120h + dec h + ld (ndist),hl ; num_dist_codes = 20h + jp tblmak ; make_parse_tables + +tbldyn: dec a ; 2 = dynamic tables + ;ret nz ; else bad table + jp nz,bad_block + + ld a,5 + call bitsb ; get_bits + ld bc,101h + add hl,bc + ld (nlit),hl ; num_lit_codes + + ld a,5 + call bitsb + inc hl + ld (ndist),hl ; num_dist_codes + + ld hl,ltbl ; bitlen_bitlens + ld bc,13h + call zfill ; initialise bitlen bitlen table + + ld a,4 + call bits ; get_bits + add a,4 + ld b,a ; count of bitlen bitlens + ld de,lxlat ; bitlen_order +tbl0: push bc + + ld a,(de) + inc de + ld c,a + ld b,0 + ld hl,ltbl ; bitlen_bitlens + add hl,bc + + ld a,3 + call bits ; get_bits + ld (hl),a + + pop bc + djnz tbl0 + + ld bc,13h + ld de,ltbl ; bitlen_bitlens + ld hl,ptbl ; bitlen_parse_table + call make ; make_parse_table + + ld de,llit ; lit_bitlen_table + ld hl,(nlit) ; num_lit_codes + ld bc,(ndist) ; num_dist_codes + add hl,bc + add hl,de + ld (lend),hl ; termination loop counter +tbl1: ex de,hl + push hl + + ld hl,ptbl ; bitlen_parse_table + ld de,ltbl ; bitlen_bitlens + call parse + + ld a,e + cp 10h + jr c,tbl5 ; single bitlen + jr z,tbl4 ; 10h = repeated bitlen * 3-6 + cp 11h + jr z,tbl2 ; 11h = repeated zeros * 3-10 + + ld a,7 ; 12h = repeated zeros * 11-138 + call bits ; get_bits + add a,11 + jr tbl3 + +tbl2: ld a,3 ; 11h = repeated zeros * 3-10 + call bits ; get_bits + add a,3 +tbl3: ld c,a + + pop hl + call zfill + jr tbl6 + +tbl4: ld a,2 ; 10h = repeated bitlen * 3-6 + call bits ; get_bits + add a,3 + ld c,a + + pop hl + dec hl + call hlfill + jr tbl6 + +tbl5: pop hl + ld (hl),e ; single bitlen + +tbl6: inc hl + ld e,l + ld d,h + + ld bc,(lend) ; termination loop counter + or a + sbc hl,bc + jr c,tbl1 + + ld bc,(ndist) + ld hl,ldist-1 + add hl,bc + ex de,hl + ld hl,(lend) + dec hl + lddr ; move dist_bitlen_table to proper spot + +tblmak: ld bc,(nlit) ; num_lit_codes + ld de,llit ; lit_bitlen_table + ld hl,plit ; lit_parse_table + lit_parse_tree + call make ; make_parse_table + + ld bc,(ndist) ; num_dist_codes + ld de,ldist ; dist_bitlen_table + ld hl,pdist ; dist_parse_table + dist_parse_tree + ;call make + ;ret + +; call with: +; bc = items +; de -> bitlen table, 1 byte per item +; hl -> parse table, 100h words +; parse tree is at hl+200h + +make: ld a,c + or b + ret z + + ld (nmake),bc ; count of items + ld (lmake),de ; pointer to bitlen table + ld (pmake),hl ; pointer to parse table + tree + + ; scan entries counting each bit length 0-15 to lcount + + ld hl,lcount ; bitlen_counts + ld bc,10h*2 + call zfill + + ld de,(lmake) ; pointer to bitlen table + ld bc,(nmake) ; count of items +make0: push bc + + ld a,(de) + inc de + + ld c,a + ld b,0 + ld hl,lcount ; bitlen_counts + add hl,bc + add hl,bc + inc (hl) + jr nz,$+4 + inc hl + inc (hl) + + pop bc + dec bc + ld a,c + or b + jr nz,make0 + + ; assign each bit length 1-15 a starting code to cmake + + ld de,0 + ld bc,2 +make1: push bc + + ld hl,cmake ; current_codes + add hl,bc + ld (hl),e + inc hl + ld (hl),d + + ld hl,lcount ; bitlen_counts + add hl,bc + ld c,(hl) + inc hl + ld b,(hl) + + ex de,hl + add hl,bc + add hl,hl + ex de,hl + + pop bc + inc c + inc c + ld a,c + cp 20h + jr c,make1 + + ld a,e + or d + jr z,make15 + + ; table is not full, allowed if sum lcount <= 1 + + ld hl,lcount+2 ; ignore bit length 0 + ld de,0 + ld a,15 ; bit lengths 1-15 +make14: ld c,(hl) + inc hl + ld b,(hl) + inc hl + ex de,hl + add hl,bc + ex de,hl + dec a + jr nz,make14 + ld hl,1 + or a + sbc hl,de + ;ret c ; bad table if 1 < sum lcount + jp c,bad_table + +make15: ; scan entries assigning codes to hmake from cmake + + ld de,(lmake) ; pointer to bitlen table + ld bc,(nmake) ; count of items + ld hl,hmake ; huffman_table +make2: push bc + + ld a,(de) + inc de + or a + ld bc,0 + jr z,make3 + + push hl + ld c,a + ld hl,cmake ; current_codes + add hl,bc + add hl,bc + + ld c,(hl) + inc (hl) + inc hl + ld b,(hl) + jr nz,$+3 + inc (hl) + pop hl + +make3: ld (hl),c + inc hl + ld (hl),b + inc hl + + pop bc + dec bc + ld a,c + or b + jr nz,make2 + + ; scan entries bit reversing each code in hmake + + ld de,(lmake) ; pointer to bitlen table + ld bc,(nmake) ; count of items + ld hl,hmake ; huffman_table +make4: push bc + + ld a,(de) + inc de + + push de + push hl + + ld e,(hl) + inc hl + ld d,(hl) + + or a + jr z,make6 + + ld hl,0 + ld b,a +make5: rr d + rr e + adc hl,hl + djnz make5 + ex de,hl + +make6: pop hl + ld (hl),e + inc hl + ld (hl),d + inc hl + pop de + + pop bc + dec bc + ld a,c + or b + jr nz,make4 + + ; construct parse table and tree + + ld hl,(pmake) ; pointer to parse table + tree + ld bc,100h*2 + call zfill + inc hl + ld (trptr),hl ; tree ptr + + ld de,0 ; index to lmake +make7: ld hl,hmake + add hl,de + add hl,de + ld c,(hl) + inc hl + ld b,(hl) + + ld hl,(lmake) ; pointer to bitlen table + add hl,de + ld a,(hl) + or a + jr z,make13 + cp 9 + jr nc,make10 + + ld b,a + ld hl,1 +make8: add hl,hl + djnz make8 ; b = 0 for <= 8 bit huffman code + ld (pinc),hl ; parse table increment + +make9: ld hl,(pmake) ; pointer to parse table + tree + add hl,bc + add hl,bc ; huffman code + + ld (hl),e + inc hl + ld (hl),d + + ld hl,(pinc) ; parse table increment + add hl,bc + ld c,l + ld b,h + + ld a,b + or a + jr z,make9 + jr make13 + +make10: push de + push af + + ld a,b + ld b,0 + ld hl,(pmake) ; pointer to parse table + tree + add hl,bc + add hl,bc ; huffman code, lo 8 bits + ld c,a ; huffman code, hi 8 bits + + pop af + sub 8 + ld b,a + +make11: ld e,(hl) + inc hl + ld d,(hl) + + ld a,e + or d + jr nz,make12 ; existing branch + + ld de,(trptr) ; tree ptr + ld (hl),d + dec hl + ld (hl),e + + push de +; rept 4 +; ld (de),a +; inc de +; endm + ld (de),a + inc de + ld (de),a + inc de + ld (de),a + inc de + ld (de),a + inc de + ld (trptr),de ; tree ptr + pop de + +make12: ex de,hl + + rr c + jr nc,$+4 + inc hl + inc hl + + djnz make11 + + pop de + ld (hl),e + inc hl + ld (hl),d + +make13: inc de + + ld hl,(nmake) + or a + sbc hl,de + jr nz,make7 + + ret ; z for caller of tbl + +bad_block: + call uzmess + db 'invalid table type',0dh,0ah,0 + jp bomb + +bad_table: + call uzmess + db 'file has bad table',0dh,0ah,0 + jp bomb + +; ----------------------------------------------------------------------------- +; enter with: +; a = bits to read (1-10h) + +; returns: +; de = preserved +; hl = value + +bitsw: cp 9 + jr c,bitsb + + sub 8 + ld h,a ; h = eventual bits in h + call peek + .if 0 + inc ix ; shortcut to flush 8 bits + .else + call nxtix + .endif + ld l,c ; l = bits 0-7 of result + + ld a,h + call bits + ld h,a ; h = bits 8-n of result + ret ; result in hl + +bitsb: call bits + ld l,a + ld h,b ; 0 + ret + +; enter with: +; a = bits to read (1-8) + +; returns: +; de = preserved +; a = value + +bits: push hl + ld l,a + call peek + call flush + ld a,c + ld c,l + ld hl,bmask-1 + add hl,bc + and (hl) + pop hl + ret ; result in hl and a + +; ----------------------------------------------------------------------------- +; enter with: +; hl -> parse table +; de -> bitlen table + +; returns: +; de = next item from input + +parse: call peek ; a = index for parse table lookup + add hl,bc + add hl,bc + ld a,(hl) + inc hl + ld h,(hl) + ld l,a ; hl = parse table entry + ex de,hl ; de = parse table entry, hl -> bitlens + + .if 0 + bit 4,d + .else + bit 7,d + .endif + jr z,parse2 ; parse from table + ; parse from tree + .if 0 + inc ix ; shortcut to flush 8 bits + .else + call nxtix + .endif + call peek ; c = bit buffer for tree lookup + + ld a,(dbits) + +parse0: rr c + jr nc,$+4 + inc de + inc de + + inc a + cp 8 ; dbits = 8? + jr c,parse1 ; no, bit buffer ok + + .if 0 + inc ix ; shortcut to flush 8 bits + ld c,(ix) ; refresh bit buffer + .else + call nxtix + ld a,(dbuf) + ld c,a + .endif + + sub a ; new byte, no dead bits + +parse1: ex de,hl + ld e,(hl) + inc hl + ld d,(hl) + + .if 0 + bit 4,d + .else + bit 7,d + .endif + jr nz,parse0 + + ld (dbits),a + ret + +parse2: add hl,de + ld l,(hl) ; l = bitlen table entry + ;call flush + ;ret + +; enter with: +; l = bits to kill +; BBR:ix -> input data +; dbuf = 8 bits from input +; dbits = dead bits 0-7 + +; returns: +; bc = preserved +; de = preserved +; hl = preserved +; BBR:ix = advanced +; dbuf = updated +; dbits = advanced + +flush: ld a,(dbits) + add a,l + ld (dbits),a + sub 8 + ret c + ld (dbits),a + +nxtix: ld a,(ix) + ld (dbuf),a + ;push bc + ;ld bc,1 + ;add ix,bc + ;pop bc + ;ret nc ; still in same window + inc ix + push ix + ex (sp),hl + bit 7,h + pop hl + ret z ; still in same window (ix < 8000h) + + .if 0 + ld a,(zfprog) + or a ; progress callouts enabled? + jr z,skprog ; skip if not + + in0 a,(BBR) + push af + push bc + push de + push hl + push iy + + add a,0fh+1 + rlca + rlca + rlca + rlca ; convert window to segment + ld h,a + ld l,0 ; absolute 0:hl -> new source data + call uzprog ; call boot1 + + pop iy + pop hl + pop de + pop bc + pop af + jr dnprog + .endif + +skprog: ;in0 a,(BBR) +dnprog: ;inc a + push hl + ld hl,virtbr + inc (hl) + ld l,(hl) + ld h,80h + ld a,(hl) ; translate BBR value via virtual memory table for actual use + pop hl + out0 (BBR),a ; wrapped into new window + + ;ld ix,0f000h ; BBR:ix -> new source data + ld ix,4000h + ret + +; ----------------------------------------------------------------------------- + +; enter with: +; BBR:ix -> input data +; dbuf = 8 bits from input +; dbits = dead bits 0-7 + +; returns: +; bc = next 8 bits (b = 0) +; de = preserved +; hl = preserved + +peek: ld bc,(dbuf) ; b = dbits + ld a,b + or a + ret z + ld a,(ix) +peeklp: rra + rr c + djnz peeklp + ret + +; ----------------------------------------------------------------------------- + +zfill: sub a +afill: ld (hl),a + dec bc +hlfill: ld e,l + ld d,h + inc de + ldir + ret + +; ----------------------------------------------------------------------------- + +pread: ; plain_read + ld hl,dbits + ld a,(hl) ; see if we were already byte aligned + or a + jr z,preade + ld (hl),0 ; no, we need to flush up to 7 bits + +preadl: call nxtix ; refresh bit buffer, then advance ix +preade: ld a,(dbuf) ; enter here with a valid bit buffer + + ld (iy),a ; save in output (no shifting needed) + inc iy + + djnz preadl ; copy up to 100h bytes + jp nxtix ; refresh bit buffer for our caller + +oflsh: ; output_flush + ld c,l + ld b,h ; bc now = iy - outbuf (byte count) + + ld iy,outbuf-4000h ; because IDATA0 is phys 4000, log 8000 + ld d,0 + + ld hl,outseg + ld e,(hl) + ld hl,(outptr) + + call copyr ; flush output buffer to output + + ld (outptr),hl + ld hl,outseg + ld (hl),e + + ld iy,outbuf ; restart output buffer + ret + +; ----------------------------------------------------------------------------- + + rseg IDATA0 +bmask: defs 8 + rseg CDATA0 + defb 1,3,7,0fh,1fh,3fh,7fh,0ffh + + rseg IDATA0 +lxlat: defs 19 + rseg CDATA0 + defb 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 + +; ----------------------------------------------------------------------------- + + rseg UDATA0 + +; tbl data + +nlit: defs 2 ; num_lit_codes +ndist: defs 2 ; num_dist_codes +lend: defs 2 ; llit + nlit + ndist, loop terminator + +; make data + +nmake: defs 2 ; count of items +lmake: defs 2 ; pointer to bitlen table +pmake: defs 2 ; pointer to parse table + tree +trptr: defs 2 ; tree ptr +pinc: defs 2 ; parse table increment + +; peek + flush data + +; retain ordering % +dbuf: defs 1 +dbits: defs 1 ; dead bits in low dbuf +; % + +; uzfile data + +lblock: defs 1 ; last_block_flag + +virtbr: defs 1 ; virtual base register before xlat +gzhbuf: defs 10 ; gzip header (no extra fields allowed) +gztbuf: defs 8 ; gzip trailer (crc-32, orig size-32) + +outptr: defs 2 ; absolute output offset +outseg: defs 1 ; absolute output segment +outbuf: defs 103h ; minimises the need to call copyr + ; outbuf should be 100h, but we allow an extra 3 bytes, due to + ; the main loop for decompressing non-repeated data, which is + ; unrolled 4 times (we test against outbuf+100h every 4 chars) + +; buffers + +ltbl: defs 13h ; bitlen_bitlens +lcount: defs 10h*2 ; bitlen_counts +cmake: defs 10h*2 ; current_codes +hmake: defs 120h*2 ; huffman_table + +; llit must be followed by ldist because we unpack lit bitlens and +; dist bitlens together, then move dist bitlens to start at ldist + +; retain ordering % +llit: defs 120h ; lit_bitlen_table +ldist: defs 20h ; dist_bitlen_table +; % + +ptbl: defs 100h*2 ; bitlen_parse_table +plit: defs (100h+240h)*2 ; lit_parse_table + lit_parse_tree +pdist: defs (100h+40h)*2 ; dist_parse_table + dist_parse_tree + +;ztop: defs 1 ; must be < 0e000h + +; ----------------------------------------------------------------------------- + + \ No newline at end of file diff --git a/src/gboot/uzmain.asm b/src/gboot/uzmain.asm new file mode 100644 index 00000000..e5642f82 --- /dev/null +++ b/src/gboot/uzmain.asm @@ -0,0 +1,233 @@ +; uzmain.asm by Nick, gunzipper, main program and error handling routines + +; ----------------------------------------------------------------------------- + +$ io64180.inc + +BUFSIZE equ 200h ; how many bytes per disk block +BUFSIZELOG equ 9 ; shift count representing the above + +HD0_START equ 512 +HD0_SIZE equ 1536 + +; ----------------------------------------------------------------------------- + + module _uzmain + + public init + public bomb + public uzmess + extern abyte + extern ahexb + extern ahexw + extern acrlf + extern amess + extern copyr + extern uzfgo + extern gztbuf + extern zdata + + extern s_CODE + extern e_CODE + + rseg ICODE + +; ----------------------------------------------------------------------------- + +init:: +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc + + call uzmess + defb 'unzipping root filesystem',0dh,0ah,0 + + ld hl,0 + ld iy,LWRD zdata + defb 11h ; ld de, + defb 4 ; e:hl -> destination, absolute 4:0000 (CP/M A: and B:) + defb BYTE3 zdata ; d:iy -> source, virtual zdata (gzipped input) + + call uzfgo ; we return here only if successful + + ld a,e + sub 4 + ld e,a + ld d,0 ; de:hl = 32-bit actual size unpacked + .if 0 + push hl + ex de,hl + call ahexw + ex de,hl + call ahexw + ld a,' ' + call abyte + ld hl,(gztbuf+6) + call ahexw + ld hl,(gztbuf+4) + call ahexw + call acrlf + pop hl + .endif + + ld bc,(gztbuf+4) + or a + sbc hl,bc + jr nz,bad_size ; check low order 16 bits of size + + ld hl,(gztbuf+6) + ;or a + sbc hl,de + jr nz,bad_size ; check high order 16 bits of size + + .if 0 ; intentionally corrupt inode 20 so that fsck won't run + jr poox +poo: + defw 0c1h + defw 0c0h +poox: + ld iy,poo-4000h + ld hl,0f18h + ld de,4 + ld bc,poox-poo + call copyr + .endif + + .if 0 ; check for accidental corruption of inode 18 + ; dump block 7 + ld a,40h-4 + out0 (BBR),a + ld hl,4e00h + ld c,20h +dline: + ld b,10h +ditem: + ld a,(hl) + inc hl + call ahexb + ld a,' ' + call abyte + djnz ditem + call acrlf + dec c + jr nz,dline + .endif + + call uzmess + defb 'starting kernel via reboot',0dh,0ah,0 + + ld hl,0 + ; wait for last character to be sent @ 9600 +reboot_delay: + dec hl + ld a,l + or h + jr nz,reboot_delay + + jr success ; reboot and run ramdrive boot sector + +bad_size: + call uzmess + db 'bad uncompressed size',0dh,0ah,0 + ;jr bomb + +bomb:: + ; try not to surprise the user unnecessarily + call uzmess + defb 'doing a clean boot',0dh,0ah,0 + + ; before rebooting, prepare to clobber CP/M drive A: directory + ld hl,block + ld de,block+1 + ld bc,BUFSIZE-1 + ld (hl),0aah ; clobbering pattern + ldir ; initialise temporary buffer + + ; perform the clobbering (this ensures a clean boot from EPROM) + .if 1 + ld de,0 + ld b,4 +clobber_loop: + push bc + push de + + ld hl,block + call block_write + + pop de + pop bc + inc de + djnz clobber_loop + .else + ld de,304h + ld l,c + ld h,b ; ld hl,0 ; e:hl -> destination 4:0000 + + ld b,4 ; clobber until just before 4:0800 +clobber_loop: + push bc + + ld iy,block ; copy from d:iy -> destination + ld bc,BUFSIZE ; bytes to copy + call copyr ; copy them, one byte at a time + + pop bc + djnz clobber_loop + .endif + +success: + ; ready to reboot, by instructing the WPO chip on motherboard + ld a,0aah + out0 (TRDR),A ; command byte to reboot the system + ld a,13h + out0 (CNTR),A ; TE=1, divisor = 3, start transmission + + ; wait for the reboot to occur, or else we're rather stuck + jr $ + +block_write: + push hl + call block_xlate ; a:hl -> data in ramdrive + + pop iy + ld d,3 ; d:iy -> user's buffer in seg 3: + + ld e,a ; e:hl -> data in ramdrive + jp copyr ; copy BUFSIZE bytes from d:iy to e:hl + +block_xlate: + ;ld hl,HD0_SIZE + ;scf + ;sbc hl,de ; check whether block no is in range + ;jr c,bad_block + + ld bc,BUFSIZE ; bytes to be copied for 1 block + + ld hl,HD0_START + add hl,de ; hl = block index (from start of ram) + + ld a,h + ld h,l + ld l,c ;0 ; a:hl = block index * 100h + + add hl,hl + adc a,a ; a:hl = block index * BUFSIZE (200h!!) + ret + +; ----------------------------------------------------------------------------- + +uzmess:: + call amess + defb 'uzboot: ',0 + jp amess + +; ----------------------------------------------------------------------------- + + rseg UDATA0 + +block: defs BUFSIZE ; temporary buffer for clobbering disc + +; ----------------------------------------------------------------------------- + + END diff --git a/src/gui/0000.scr b/src/gui/0000.scr new file mode 100644 index 0000000000000000000000000000000000000000..cea4476da2fb5b82b6388aa96eff49bb1bf2b887 GIT binary patch literal 262 zcmZ9_Jr06E5Cz~ju0YEXwl^^g@dQZWA0`S$TOunGg*A&5b{^eDh$K!m^JV5uJpspG z1puQBGb)7e03YNA%-Fg&zqOGYfEdkt6Rk00Bb#>gOY|{z6N?cgKZ1Z|_Lwzn5j@!D zhsk?e-QQW8=eV(h{czcJ3#BeuDXRwY`6_kEeT2o6*WUq&)J@K-G}ZjDU7nDrJikkX YN@>2D9;ZA~x-P04B3UZ^%9`?l56nL%3IG5A literal 0 HcmV?d00001 diff --git a/src/gui/0001.scr b/src/gui/0001.scr new file mode 100644 index 0000000000000000000000000000000000000000..a9efc69b82edbe201455f1c36c5139dba337745b GIT binary patch literal 345 zcmZ9_y>7xV6o%pNoET8clDU(w0GVuTwJVE+gz)18ZlD=DpjIFTHn{Vih^9n%vLC-b zKE2}&Ps;&Jg@V%eiv$!q7Ry<{7?S`AICdbWWz@4sITPLlf#54$ud(-j9zN1mcFpnh)xb<<#vt{@8k;(+uxt+B$BX_vAAax) DO7bN- literal 0 HcmV?d00001 diff --git a/src/gui/0001.tmp b/src/gui/0001.tmp new file mode 100644 index 00000000..e69de29b diff --git a/src/gui/0002.scr b/src/gui/0002.scr new file mode 100644 index 0000000000000000000000000000000000000000..bb846eea7adb6ca400430bd3f49737fcf1946896 GIT binary patch literal 719 zcmYk&%}&BV7=__8MdH6!jnNom8r?S9iV7^9P=P2d0%GEhNP`H1DMggq@)Eo;kHnI% zn@*qPo#}iUFjNuq$AL1nL95OQ4h&N-&>GTGriL<R*{6R;W$(CkI z+hR+*m$q$IKr5*^I@qx)igr6E&S2Nl2JKPW9%ssXOcVQ?-@c_eX7wfQfGzD)+M%Vv zdrYJqv88=Tv)Izc(vGeA3BD6a-kosLeSV4Y9(7+wXT1*MVccr*n{_6t_V zMRVBioTArn4Ps=GLmn5n#1&keBf~q`sMgAU1EnCiDWKx{54a7gWe+;=@mQ|cJs+N9 vXYzO|-uPCvp(#$L literal 0 HcmV?d00001 diff --git a/src/gui/0003.scr b/src/gui/0003.scr new file mode 100644 index 0000000000000000000000000000000000000000..43d8958ebb76eb3850de4b8de269a642d7cd26c4 GIT binary patch literal 760 zcmaixJ8l9|5CmuT5s;Jl2w1lH`V)|}O+bi*PvT>6IgJ08vD_om!vsidKyQ^wPY-yR z+J&8cVDA2SaW}sh-xe-3um>Lh-xAzi;mTsL{w8jS$NNVClS?1P!=7lzC=`yOVM$kjMwMK z|Fiu)bt^OUc-GpL@vQapYLj?)LF3|i*|`|sBrG+wl$I*d8zMbsq&s>6s{MqM_bI*h1Q)D;7&!-!f( zT{WOOjHpf2H3O={h}uS7H=sIIiP#s3pkQ;VvKy?^VW7Hc1s>6s{ zL>(DW9Y)kL>bU{cVMMK>UK&sxM$|g$odMNhL~Wv88BiTY)HdqA0o7qdO;Jw`s174) z7xm15>M){)Jcc(7s174)jCx@}br?~LsM`iqhY_`mx?@0f7*VUJy9QK;5w(uGXFzor zQJbg-22_U;wT*gcKy?^VQ`92^s>6udMNNi-JoO*;C(fSpm>>6hC)esQ=A0K%Zw;sp zBWf9S%Yf=IqE=C_4X6$yY8^EjP#s3pChCa+)nP4vLFrtR2ujB7> pE_e0#%cswOfL|Z;%$*v)S-=1I*FSWwwac~6s`!TXCm)?Xe*$ZfGM@kd literal 0 HcmV?d00001 diff --git a/src/gui/Copy (2) of wnd.c b/src/gui/Copy (2) of wnd.c new file mode 100644 index 00000000..da577936 --- /dev/null +++ b/src/gui/Copy (2) of wnd.c @@ -0,0 +1,1138 @@ +/************************************************ + * Graphical User Interface driver (GUI) * + * By J.W. Morsink for Retail Vision B.V. * + ************************************************/ + +#include +#include "..\libc\malloc-l.h" +#undef NULL +#define NULL 0 + +/*void *malloc(size_t size) + { + void *ptr; + + ptr = (void *)sbrk(size); + return (ptr == (void *)-1) ? NULL : ptr; + } + +void free(void *ptr) + { + } + +*/ +#define JOOST_DEBUG +/*#define STR_DEBUG*/ +/*#define MALLOC_DEBUG + +/************************************************ + * Global variables for GUI * + ************************************************/ + +struct Global_GUI* global; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(){ + struct sgttyb temp; + char init[]={0x1B,'K'}; + + global->lcd=open("/dev/lcd0",O_RDWR); + gtty(global->lcd,&temp); + temp.sg_flags=RAW | UNBUFF; + stty(global->lcd,&temp); + + write(global->lcd,init,2); +} + +void GraphicsClose(){ + close(global->lcd); +} + +void Move(int x, int y){ + unsigned char cmd[]={0x1B,'S',0,0}; + cmd[2]=(unsigned char) (x); + cmd[3]=(unsigned char) (y); + write(global->lcd,cmd,4); +} + +void ClearRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'C',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void DrawRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'N',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'R',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'F',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void GrayRect(int sx,int sy){ + unsigned char cmd[]={0x1B,'h',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void Text(char *s){ + int c=strlen(s); + write(global->lcd,s,c); +} + +void TouchRegion(int msg, int x, int y, int sx, int sy){ + char touch[]={0x1B,'Z',0,0,0,0,0}; + touch[2]=(unsigned char) (msg); + touch[3]=(unsigned char) (x); + touch[4]=(unsigned char) (y); + touch[5]=(unsigned char) (sx); + touch[6]=(unsigned char) (sy); + write(global->lcd,touch,7); +#ifdef JOOST_DEBUG + printf("Touch: %x,%x,%x,%x,%x\n",msg,x,y,sx,sy); fflush(stdout); +#endif +} + +void ClearScreen(){ + Move(0,0); + ClearRect(0,0x80); + TouchRegion(0,0,0,0,0x80); +} + +void EnableScreen(unsigned char c){ + char cmd[]={0x1B,'E',0}; + cmd[2]=c; + write(global->lcd,cmd,3); +} + +void grSetFont(int f){ + char cmd[]={0x1B,0}; + cmd[1]=f & 0xff; + write(global->lcd,cmd,2); +} + +/************************************************ + * Fonts * + ************************************************/ + +struct Font* fontSearch(int f){ + struct Font* current=global->firstfont; + while(current!=NULL && current->id!=f) + current=current->nextfont; + return current; +} + +void setCurrentFont(int f){ + if(fontSearch(f)!=NULL){ + grSetFont(f); + global->currentfont=fontSearch(f); + } +} + +void loadFont(int id,int (*sw)(char*),int (*sh)(char*),int sizedata, void* data){ + struct Font* font=(struct Font*) malloc(sizeof(struct Font)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",font); fflush(stdout); +#endif + font->id=id; + font->stringwidth=sw; + font->stringheight=sh; + font->nextfont=NULL; + font->sizefontdata=sizedata; + font->fontdata=data; + if(global->firstfont==NULL){ + global->firstfont=font; + global->currentfont=font; + } + else + { + struct Font* current=global->firstfont; + while(current->nextfont!=NULL) + current=current->nextfont; + current->nextfont=font; + } +} + +int stringwidth(char *str,int extra){ + int w=0,i=0; + while(str[i]!=0x00){ + switch(str[i]){ + case 'i': + case 'I': + case '!': + w+=2; + break; + case 'l': + w+=3; + break; + case ',': + case '1': + case '.': + w+=4; + break; + case 'r': + case 'k': + case 'j': + w+=5; + break; + default: + w+=6; + } + i++; + w+=extra; + } + return w; +} + +int stringheight(char ch, int extra){ + if(ch<0x80) return 7+extra; + if(ch>=0xcc && ch<=0xdf) return 1+extra; +} + +int stringheight01(char* ch){ + return stringheight(ch[0],0); +} + +int stringheight2(char* ch){ + return stringheight(ch[0],5); +} + +int stringwidth0(char *str){ + return stringwidth(str,0); +} + +int stringwidth1(char *str){ + return stringwidth(str,2); +} + +int stringwidth2(char *str){ + return stringwidth(str,3); +} +/************************************************ + * Components * + ************************************************/ + +struct Component* Component_new(int x,int y,int sx,int sy){ + struct Component* this=(struct Component*) (malloc(sizeof(struct Component))); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",this); fflush(stdout); +#endif + + this->id=(++global->id); + this->x=x; + this->y=y; + this->sizex=sx; + this->sizey=sy; + this->state=0; + this->order=0; + this->font=0; + this->msg=0; + this->parent=NULL; + this->next_sibling=NULL; + this->first_child=NULL; + this->handler=NULL; + this->paint=NULL; + this->add=NULL; + this->sizexds=0; + this->xds=NULL; + this->label=NULL; + this->label2=NULL; + return this; +} + +void Component_setlabel(struct Component* this, char* s){ + int i=0; + while(s[i]!=0 && ilabel[i]=s[i]; + i++; + } + this->label[i]=0; +} + +void Component_add(struct Component* this, struct Component* comp){ + struct Component* current=this->first_child; + if(this->first_child==NULL){ + this->first_child=comp; + comp->next_sibling=NULL; + } + else + { + while(current->next_sibling!=NULL){ + current=current->next_sibling; + } + current->next_sibling=comp; + comp->next_sibling=NULL; + } + comp->parent=this; +} + +void Component_paint(struct Component* this){ + struct Component* current=this->first_child; + EnableScreen(0); + while(current!=NULL){ + current->paint(current); + current=current->next_sibling; + } + EnableScreen(1); +} + +void Component_findXY(struct Component* this, int* x, int* y){ + struct Component* current=this; + do{ + *x+=current->x; + *y+=current->y; + current=current->parent; + } while(current!=NULL); +} + +struct Component* Component_find(struct Component* this, int msg){ + struct Component* current=this->first_child; +#ifdef JOOST_DEBUG + printf("Find %x in %x:\n",msg, this->id); fflush(stdout); +#endif + while(current!=NULL){ +#ifdef JOOST_DEBUG + printf("Comp_find: %x, %x\n",msg, current->msg); fflush(stdout); +#endif + if(current->msg==msg) + return current; + current=current->next_sibling; + } + return NULL; +} + +struct Component* Component_delete(struct Component* this){ + struct Component* current=this->first_child; + int id=this->id; + if(this!=NULL){ +#ifdef JOOST_DEBUG + printf("Deleting component: %d\n",id); fflush(stdout); +#endif + while(current!=NULL){ + current=Component_delete(current); + } + if(this->parent!=NULL){ + if(this==this->parent->first_child) + this->parent->first_child=this->parent->first_child->next_sibling; + else{ + current=this->parent->first_child; + while(this!=current->next_sibling && current->next_sibling!=NULL) + current=current->next_sibling; + if(current->next_sibling!=NULL) + current->next_sibling=current->next_sibling->next_sibling; + } + } + current=this->next_sibling; + if(this->sizexds==sizeof(struct StringTableXDS)) + { + struct Component* par=this->parent; + struct StringTableXDS* stx=(struct StringTableXDS*) this->xds; + +#ifdef STR_DEBUG + printf("Stringtable @ %x freed!\n",stx->stringtabledata); fflush(stdout); +#endif + +#ifdef MALLOC_DEBUG + printf("free: %x\n",stx->stringtabledata); fflush(stdout); +#endif + free(stx->stringtabledata); +#ifdef MALLOC_DEBUG + printf("free: %x\n",stx->stringtable); fflush(stdout); +#endif + free(stx->stringtable); + + while((par!=NULL) && (par->sizexds!=sizeof(struct StringTableXDS))) + par=par->parent; + if(par!=NULL) + { + stx=(struct StringTableXDS*) par->xds; + global->stringtabledata=stx->stringtabledata; + global->stringtable=stx->stringtable; + } + } + if(this->sizexds>0){ +#ifdef MALLOC_DEBUG + printf("free: %x\n",this->xds); fflush(stdout); +#endif + free(this->xds); + } + if((this->state & STRING_FROMTABLE)==0 && this->label!=NULL){ +#ifdef MALLOC_DEBUG + printf("free: %x\n",this->label); fflush(stdout); +#endif + free(this->label); + } +#ifdef MALLOC_DEBUG + printf("free: %x\n",this); fflush(stdout); +#endif + + free(this); +#ifdef JOOST_DEBUG + printf("Deleted component: %d\n",id); fflush(stdout); +#endif + } + return current; +} + +void Component_delete_children(struct Component* this){ + struct Component* current=this->first_child; + while(current!=NULL) + current=Component_delete(current); +} + +void Component_changestate_children(struct Component* this, int andmask, int ormask, int xormask){ + struct Component* current=this->first_child; + while(current!=NULL){ + current->state&=(0xffff-andmask); + current->state|=ormask; + current->state^=xormask; + current=current->next_sibling; + } + fflush(stdout); +} + +void Component_linkstringtable(struct Component* this){ + struct Component* child=this->first_child; +#ifdef STR_DEBUG + printf("%d: %x -> %x\n",this->id,this->label-1,global->stringtable[(int) (this->label)-1]); fflush(stdout); +#endif + if(((int)(this->label))<0x1000 && ((int)(this->label))>0) + this->label=global->stringtable[(int) (this->label)-1]; + if(((int)(this->label2))<0x1000 && ((int)(this->label2))>0) + this->label2=global->stringtable[(int) (this->label2)-1]; + while(child!=NULL){ + Component_linkstringtable(child); + child=child->next_sibling; + } + +} + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param){ + struct Component* current,current2; + int x=0,y=0; +#ifdef JOOST_DEBUG + printf("Message in window %d, Msg: %x, Param: %x\n",this->id,msg,param); fflush(stdout); +#endif + switch(msg){ + case KEY_PRESSED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)) + current->handler(current,msg,param); + current=current->next_sibling; + } + break; + case KEY_RELEASED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)) + current->handler(current,msg,param); + current->handler(current,KEY_TYPED,param); + current=current->next_sibling; + } + break; + case KEY_TYPED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)){ + current->handler(current,msg,param); + if((current->state & STATE_ACTION)!=0 && current->msg==param){ + struct ActionXDS* act=(struct ActionXDS*) (current->xds); +#ifdef JOOST_DEBUG + printf("Before actionhandler...\n"); +#endif + act->actionhandler(current); + if((act->action & 0xff00)==0){ + current=NULL; + } +#ifdef JOOST_DEBUG + printf("After actionhandler...\n"); +#endif + } + } + if(current!=NULL) + current=current->next_sibling; + } + break; + case WND_REDRAW: + this->paint(this); + break; + case WND_CLOSE: + this->state=this->state & (0xffff-(STATE_VISIBLE | STATE_ENABLED)); + Component_findXY(this,&x,&y); + TouchRegion(0,x,y,this->sizex,this->sizey); + this->parent->handler(this->parent,WND_REDRAW,0); + break; + case WND_DESTROY: + current=this->parent; + Component_delete(this); + current->handler(current,WND_REDRAW,0); + break; + case WND_BROADCAST: + current=this->first_child; + while(current!=NULL){ + if(current!=(struct Component*) (param) && (current->state & STATE_FOCUS)!=0) + current->handler(current,CMP_BROADCAST,param); + current=current->next_sibling; + } + break; + case APP_QUIT: + if(this->parent==NULL) + global->willquit=1; + else if((this->state & STATE_APPLICATION)==0) + this->parent->handler(this->parent,APP_QUIT,param); + else{ + current=this->parent; + current->state|=STATE_VISIBLE | STATE_ENABLED; + Component_changestate_children(current,0,STATE_VISIBLE,0); + this->handler(this,WND_DESTROY,0); + } + break; + } +} + +void Window_paint(struct Component* this){ + int x=0,y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + + EnableScreen(0); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion(0,x,y,this->sizex,this->sizey); + Move(x,y+global->currentfont->stringheight(this->label)+4); + DrawRectNC(this->sizex,this->sizey-global->currentfont->stringheight(this->label)-4); + Move(x,y); + FillRect(this->sizex,global->currentfont->stringheight(this->label)+5); + Move(x+2,y+2); + Text(this->label); + Component_paint(this); + } +} + +void Root_paint(struct Component* this){ + EnableScreen(0); + Move(0,0); + ClearRect(0,0x80); + GrayRect(0,0x80); + TouchRegion(0,0,0,0,0x80); + + Component_paint(this); +/* EnableScreen(0); + Window_paint(this); + EnableScreen(1);*/ +} + +void Window_add(struct Component* this, struct Component* comp){ + Component_add(this,comp); +} + +struct Component* Window_new(int x,int y,int sx,int sy){ + struct Component* this=Component_new(x,y,sx,sy); + this->handler=Window_handler; + this->paint=Window_paint; + this->add=Window_add; + return this; +} + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->parent->handler(this->parent, CMP_ACTION, param); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void Button_drawtext(struct Component* this, int x, int y){ + if((this->state & STYLE_MULTILINE)!=0){ + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-2*global->currentfont->stringheight(this->label))/2); + Text(this->label); + Move(x+(this->sizex-global->currentfont->stringwidth(this->label2))/2,y+(this->sizey)/2+1); + Text(this->label2); + } else { + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-global->currentfont->stringheight(this->label))/2+1); + Text(this->label); + } +#ifdef STR_DEBUG + printf("Drawtext (%d): ""%s"" @ %x\n",this->id,this->label,this->label); fflush(stdout); +#endif +} + +void Button_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & (STATE_ENABLED | STYLE_INVERTED))!=0 && (this->state & (STATE_ENABLED | STYLE_INVERTED))!=(STATE_ENABLED | STYLE_INVERTED) ) + FillRectNC(this->sizex,this->sizey); + else + DrawRectNC(this->sizex,this->sizey); + Button_drawtext(this,x,y); + } +} + +void Button_add(struct Component* this, struct Component* comp){ + return; +} + +struct Component* Button_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE; + this->msg=msg; + this->handler=Button_handler; + this->paint=Button_paint; + this->add=Button_add; + + return this; +} + +/*void Numpad(struct Component* this, int x, int y){ + int i; + char s[2]={0,0}; + struct Component* button; + for(i=0; i<9; i++){ + s[0]=0x31+(char) i; + button=Button_new(x+(i%3)*0x18,y+0x30-(i/3)*0x18,0x16,0x16,i+0x31); + Component_setlabel(button,s); + button->state|=STATE_CASTING; + this->add(this,button); + } + button=Button_new(x+0x18,y+0x48,0x16,0x16,0x30); + Component_setlabel(button,"0"); + button->state|=STATE_CASTING; + this->add(this,button); + + button=Button_new(x+0x30,y+0x48,0x16,0x16,0x08); + Component_setlabel(button,"CE"); + button->state|=STATE_CASTING; + this->add(this,button); +}*/ + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->state^=STATE_CHECKED; + this->parent->handler(this->parent, CMP_STATECHANGE, param); + this->handler(this, WND_REDRAW, 0); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void ToggleButton_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + if((this->state & STATE_ENABLED)!=0 && (this->state & STATE_CHECKED)!=0){ + FillRectNC(this->sizex,this->sizey); + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + }else{ + DrawRectNC(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + } + Button_drawtext(this,x,y); + } +} + +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE | STATE_CHECKED; + this->msg=msg; + this->handler=ToggleButton_handler; + this->paint=ToggleButton_paint; + this->add=Button_add; + + return this; +} + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==CMP_ACTION && param==0xff){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_OK, this->msg); + } + if(msg==CMP_ACTION && param==0xfe){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_CANCEL, this->msg); + + } +} + +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* ok; + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_VISIBLE; + this->msg=msg; + this->handler=Dialog_handler; + this->paint=Window_paint; + this->add=Window_add; + + ok=Button_new(sx-0x30,sy-0x1c,0x28,0x14,0xff); + ok->label=(char*) malloc(3); + Component_setlabel(ok,"OK"); + this->add(this,ok); + + ok=Button_new(sx-0x30,sy-0x38,0x28,0x14,0xfe); /*Cancel*/ + ok->label=(char*) malloc(7); + Component_setlabel(ok,"Cancel"); + this->add(this,ok); + + return this; +} + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param){ + Button_handler(this,msg,param); + if(msg==CMP_BROADCAST && (this->state & STATE_FOCUS)!=0){ +#ifdef JOOST_DEBUG + printf("strlen = %d->",strlen(this->label)); fflush(stdout); +#endif + if(param==0x08){ + if(strlen(this->label)!=0) + this->label[strlen(this->label)-1]=0; + }else{ + this->label[strlen(this->label)+1]=0; + this->label[strlen(this->label)]=(char) param; + } +#ifdef JOOST_DEBUG + printf("%d\n",strlen(this->label)); fflush(stdout); +#endif + this->handler(this,WND_REDRAW,0); + } +} + +void Display_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + char pwd[64]; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & STYLE_INVERTED)==0) + FillRectNC(this->sizex,this->sizey); + else + DrawRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2); + if(this->state & STYLE_PASSWORD){ + int i; + for(i=0; ilabel); i++) + pwd[i]='*'; + pwd[i]=0; + Text(pwd); + }else + Text(this->label); + +/* Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + + FillRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2); + Text(this->label); + TouchRegion((this->state&STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); +*/ + } +} + +struct Component* Display_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Button_new(x,y,sx,sy,msg); + this->state|=STATE_FOCUS; + Component_setlabel(this,""); + this->paint=Display_paint; + this->handler=Display_handler; + return this; +} + +/************************************************ + * Labels * + ************************************************/ +void Label_handler(struct Component* this, int msg, int param){ + return; +} + +void Label_paint(struct Component* this){ + int x=0, y=0; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Button_drawtext(this,x,y); + } +} + +struct Component* Label_new(int x, int y, int sx, int sy,char* l){ + struct Component* comp=Component_new(x,y,sx,sy); + comp->label=l; + comp->state=STATE_VISIBLE; + comp->handler=Label_handler; + comp->paint=Label_paint; + comp->add=Button_add; + return comp; +} + /************************************************ + * Implementation * + ************************************************/ +/* +void ScreenDialog_handler(struct Component* this, int msg, int param){ + char cmd[]={0x1B,'V',0}; + Dialog_handler(this,msg,param); + if(msg==CMP_ACTION){ + if(param=='U') + cmd[2]=0; + else if(param=='D') + cmd[2]=1; + else + return; + write(global->lcd,cmd,3); + } +} + +struct Component* ScreenDialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* button; + struct Component* this=Dialog_new(x,y,sx,sy,msg); + + button=Button_new(0x04,0x10,0x20,0x14,'U'); + Component_setlabel(button,"Up"); + this->add(this,button); + + button=Button_new(0x04,0x28,0x20,0x14,'D'); + Component_setlabel(button,"Down"); + this->add(this,button); + + this->handler=ScreenDialog_handler; + + return this; +} +*/ +void rootWindow_handler(struct Component* this, int msg, int param){ + struct Component* dummy; + Window_handler(this,msg,param); +} + + +void screenbuilder(struct Component* root, char* filename){ + struct Component* subw; + struct ActionXDS* action; + int mode; + int fh,rd; + char buf[SIZE_SCRBLD_RECORD]; + long l; + int xs,ys; + xs=0x2b; + ys=0x1a; + buf[0]=0; + fh=open(filename,O_RDONLY); + do{ + char comp=0; + if(buf[0]=='s'){ /* Change size */ + xs=*((int*)(buf+0x1)); + ys=*((int*)(buf+0x3)); + } + + if(buf[0]=='B' || buf[0]=='M'){ /* Button, Multi-line button */ + subw=Button_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + if(buf[0]=='M') subw->state|=STYLE_MULTILINE; + comp=1; + } + if(buf[0]=='T'){ /* Toggle-button */ + subw=ToggleButton_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='D'){ /* Display button */ + subw=Display_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='L'){ /* Label */ + subw=Label_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf+0x12); + comp=1; + } + if(buf[0]=='A'){ + struct ActionXDS a; + root->xds=&a; + a.action=*((int*)(buf+0x6)); + a.wParam=*((int*)(buf+0x8)); + a.lParam=*((long*)(buf+0xa)); + root_actionhandler(root); + } + + if(buf[0]=='S'){ + struct StringTableXDS* stx; + read_stringtable(fh,buf); + root->xds=(void*) malloc(sizeof(struct StringTableXDS)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",root->xds); fflush(stdout); +#endif + + stx=(struct StringTableXDS*) root->xds; + root->sizexds=sizeof(struct StringTableXDS); + stx->stringtable=global->stringtable; + stx->stringtabledata=global->stringtabledata; +#ifdef STR_DEBUG + printf("Stringtable created @ %x\n",stx->stringtabledata); fflush(stdout); +#endif + comp=0; + } + if(comp!=0){ + if((buf[6] | buf[7])!=0){ + subw->state|=STATE_ACTION; + subw->sizexds=sizeof(struct ActionXDS); + subw->xds=(void*) malloc(sizeof(struct ActionXDS)); +#ifdef MALLOC_DEBUG + printf("malloc Action: %x\n",subw->xds); fflush(stdout); +#endif + + action=(struct ActionXDS*) (subw->xds); + action->actionhandler=root_actionhandler; + action->action=*((int*)(buf+0x6)); + action->wParam=*((int*)(buf+0x8)); + action->lParam=*((long*)(buf+0xa)); + } + if((buf[0x0e] | buf[0x0f])!=0) + subw->state=*((int*)(buf+0x0e)); + subw->font=*((int*)(buf+0x10)); + + subw->label=(char*) (*((int*) (buf+0x12)) & 0x0fff); + if(subw->label==NULL) { + subw->label=(char*) malloc(LABEL_LENGTH); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",subw->label); fflush(stdout); +#endif + subw->label[0]=0; + } + else + subw->state|=STRING_FROMTABLE; + + if((*((int*) (buf+0x12)) &0xf000)>0x1000) + subw->label2=(char*)((*((int*) (buf+0x12)) & 0x0fff)+1); + + root->add(root,subw); + } + + rd=read(fh,buf,SIZE_SCRBLD_RECORD); + } while(rd==SIZE_SCRBLD_RECORD); + close(fh); + Component_linkstringtable(root); + root->paint(root); +} + +void root_actionhandler(struct Component* this){ + struct ActionXDS *act; + struct Component* subw; + char filename[]={'0','0','0','0','.','s','c','r',0}; + + act=(struct ActionXDS*) (this->xds); +#ifdef JOOST_DEBUG + printf("0x%x: (0x%x, 0x%x, 0x%lx)",act, act->action, act->wParam, act->lParam); +#endif + if(act->action==0x0001){ /*QUIT*/ + this->handler(this,APP_QUIT,0); + } + if((act->action & 0xfffe)==0x0002){ /*Open Screen*/ + Component_changestate_children(this->parent,STATE_VISIBLE,0,0); + subw=Window_new(0,0,this->parent->sizex,this->parent->sizey); + subw->state=STATE_VISIBLE | STATE_ENABLED; + if((act->action & 1)!=0) + subw->state|=STATE_APPLICATION; + subw->handler=rootWindow_handler; + subw->paint=Root_paint; + filename[0]=(char) ((act->lParam) &0xff); + filename[1]=(char) ((act->lParam>>8) &0xff); + filename[2]=(char) ((act->lParam>>16) &0xff); + filename[3]=(char) ((act->lParam>>24) &0xff); + screenbuilder(subw,filename); + this->parent->add(this->parent,subw); + } + if(act->action==0x0004) { /* Open MessageBox */ + /*Component_changestate_children(this->parent,0,0,0);*/ + struct Component* label; + int i; + subw=Dialog_new(0x05,0x05,this->parent->sizex-0x0a,this->parent->sizey-0x0a,1); + subw->state=STATE_VISIBLE | STATE_ENABLED | STYLE_SELFDESTRUCT; + subw->font=0x0030; + for(i=0; i<(act->wParam>>12)&0x0f; i++){ + label=Label_new(0x08,0x14+i*0x0c,(subw->sizex & 0xff)-0x10,0x10,global->stringtable[(act->wParam&0xfff)+i-1]); + label->font=0x0030; + subw->add(subw,label); + } + Component_setlabel(subw,"Message Box"); + Component_find(subw,0xff)->font=0x0030; + Component_delete(Component_find(subw,0xfe)); + this->parent->add(this->parent,subw); + this->parent->handler(this->parent,WND_REDRAW,0); + } +#ifdef JOOST_DEBUG + printf("Before external handler...\n"); fflush(stdout); +#endif + if(global->actionhandler!=NULL) + global->actionhandler(this); + +#ifdef JOOST_DEBUG + printf("After external handler...\n"); fflush(stdout); +#endif +} + +void read_stringtable(int fh,char* buf){ + int siz,bsiz; + int i=0,j=0; + char **ptrs; + char *rawdata; + + siz=*((int*) (buf+0x01)); + bsiz=*((int*) (buf+0x03)); +#ifdef STR_DEBUG + printf("%d %d\n",siz,bsiz); +#endif + + ptrs=(char**) malloc(sizeof(char*)*siz); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",ptrs); fflush(stdout); +#endif + + rawdata=(char*) malloc(bsiz); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",rawdata); fflush(stdout); +#endif + + read(fh,rawdata,bsiz); + while(istringtabledata=rawdata; + global->stringtable=ptrs; +#ifdef STR_DEBUG + for(i=0; i""%s""\n",i,global->stringtable[i],global->stringtable[i]); + fflush(stdout); +#endif + +} + +struct Global_GUI* gui_globals(){ + return global; +} + + +void GUIinit(void){ + global=(struct Global_GUI*) malloc(sizeof(struct Global_GUI)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",global); fflush(stdout); +#endif + + global->id=0; + global->willquit=0; + global->currentfont=NULL; + global->firstfont=NULL; + global->stringtable=NULL; + global->stringtabledata=NULL; + global->actionhandler=NULL; + GraphicsOpen(); + loadFont(0x0030,stringwidth0,stringheight01,0,NULL); + loadFont(0x0031,stringwidth1,stringheight01,0,NULL); + loadFont(0x0032,stringwidth2,stringheight2,0,NULL); + global->root=Window_new(0x0,0x0,0x00,0x80); + global->root->state=STATE_VISIBLE; + global->root->handler=rootWindow_handler; + global->root->paint=Root_paint; +} + +void GUIunit(void){ + Component_delete(global->root); + ClearScreen(); + GraphicsClose(); +} + +void GUIgo(char* scr){ + char buf,obuf; + screenbuilder(global->root,scr); + + while(read(global->lcd,&buf,1)==1); + + while(!global->willquit){ + if(read(global->lcd,&buf,1)==1){ + if(buf!=0) + global->root->handler(global->root,KEY_PRESSED,buf); + else + global->root->handler(global->root,KEY_RELEASED,obuf); + obuf=buf; + } + } +} + +/*void main(void){ + GUIinit(); + GUIgo(); + GUIunit(); +}*/ + diff --git a/src/gui/Copy of wnd.c b/src/gui/Copy of wnd.c new file mode 100644 index 00000000..d2397708 --- /dev/null +++ b/src/gui/Copy of wnd.c @@ -0,0 +1,941 @@ +/************************************************ + * Graphical User Interface driver (GUI) * + * By J.W. Morsink for Retail Vision B.V. * + ************************************************/ + +#include + +#define JOOST_DEBUG + +/************************************************ + * Global variables for GUI * + ************************************************/ +struct Global_GUI { + int id; + int lcd; + int willquit; + char *stringtabledata; + char **stringtable; + struct Font* currentfont; + struct Font* firstfont; + struct Component* root; +}; + +struct Global_GUI* global; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(){ + struct sgttyb temp; + char init[]={0x1B,'K'}; + + global->lcd=open("/dev/lcd0",O_RDWR); + gtty(global->lcd,&temp); + temp.sg_flags=RAW | UNBUFF; + stty(global->lcd,&temp); + + write(global->lcd,init,2); +} + +void GraphicsClose(){ + close(global->lcd); +} + +void Move(int x, int y){ + unsigned char cmd[]={0x1B,'S',0,0}; + cmd[2]=(unsigned char) (x); + cmd[3]=(unsigned char) (y); + write(global->lcd,cmd,4); +} + +void ClearRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'C',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void DrawRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'N',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'R',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'F',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void Text(char *s){ + int c=strlen(s); + write(global->lcd,s,c); +} + +void TouchRegion(int msg, int x, int y, int sx, int sy){ + char touch[]={0x1B,'Z',0,0,0,0,0}; + touch[2]=(unsigned char) (msg); + touch[3]=(unsigned char) (x); + touch[4]=(unsigned char) (y); + touch[5]=(unsigned char) (sx); + touch[6]=(unsigned char) (sy); + write(global->lcd,touch,7); +#ifdef JOOST_DEBUG + printf("Touch: %x,%x,%x,%x,%x\n",msg,x,y,sx,sy); fflush(stdout); +#endif +} + +void ClearScreen(){ + Move(0,0); + ClearRect(0,0x80); + TouchRegion(0,0,0,0,0x80); +} + +void EnableScreen(unsigned char c){ + char cmd[]={0x1B,'E',0}; + cmd[2]=c; + write(global->lcd,cmd,3); +} + +void grSetFont(int f){ + char cmd[]={0x1B,0}; + cmd[1]=f & 0xff; + write(global->lcd,cmd,2); +} + +/************************************************ + * Fonts * + ************************************************/ + +struct Font* fontSearch(int f){ + struct Font* current=global->firstfont; + while(current!=NULL && current->id!=f) + current=current->nextfont; + return current; +} + +void setCurrentFont(int f){ + if(fontSearch(f)!=NULL){ + grSetFont(f); + global->currentfont=fontSearch(f); + } +} + +void loadFont(int id,int (*sw)(char*),int (*sh)(char*),int sizedata, void* data){ + struct Font* font=(struct Font*) malloc(sizeof(struct Font)); + font->id=id; + font->stringwidth=sw; + font->stringheight=sh; + font->nextfont=NULL; + font->sizefontdata=sizedata; + font->fontdata=data; + if(global->firstfont==NULL){ + global->firstfont=font; + global->currentfont=font; + } + else + { + struct Font* current=global->firstfont; + while(current->nextfont!=NULL) + current=current->nextfont; + current->nextfont=font; + } +} + +int stringwidth(char *str,int extra){ + int w=0,i=0; + while(str[i]!=0x00){ + switch(str[i]){ + case 'i': + case 'I': + case '!': + w+=2; + break; + case 'l': + w+=3; + break; + case ',': + case '1': + case '.': + w+=4; + break; + case 'r': + case 'k': + case 'j': + w+=5; + break; + default: + w+=6; + } + i++; + w+=extra; + } + return w; +} + +int stringheight(char ch, int extra){ + if(ch<0x80) return 7+extra; + if(ch>=0xcc && ch<=0xdf) return 1+extra; +} + +int stringheight01(char* ch){ + return stringheight(ch[0],0); +} + +int stringheight2(char* ch){ + return stringheight(ch[0],5); +} + +int stringwidth0(char *str){ + return stringwidth(str,0); +} + +int stringwidth1(char *str){ + return stringwidth(str,2); +} + +int stringwidth2(char *str){ + return stringwidth(str,3); +} +/************************************************ + * Components * + ************************************************/ + +struct Component* Component_new(int x,int y,int sx,int sy){ + struct Component* this=(struct Component*) (malloc(sizeof(struct Component))); + this->id=(++global->id); + this->x=x; + this->y=y; + this->sizex=sx; + this->sizey=sy; + this->state=0; + this->order=0; + this->font=0; + this->msg=0; + this->parent=NULL; + this->next_sibling=NULL; + this->first_child=NULL; + this->handler=NULL; + this->paint=NULL; + this->add=NULL; + this->sizexds=0; + this->xds=NULL; + this->label[0]=0; + this->label[LABEL_LENGTH]=0; + return this; +} + +void Component_setlabel(struct Component* this, char* s){ + int i=0; + while(s[i]!=0 && ilabel[i]=s[i]; + i++; + } + this->label[i]=0; +} + +void Component_add(struct Component* this, struct Component* comp){ + struct Component* current=this->first_child; + if(this->first_child==NULL){ + this->first_child=comp; + comp->next_sibling=NULL; + } + else + { + while(current->next_sibling!=NULL){ + current=current->next_sibling; + } + current->next_sibling=comp; + comp->next_sibling=NULL; + } + comp->parent=this; +} + +void Component_paint(struct Component* this){ + struct Component* current=this->first_child; + while(current!=NULL){ + current->paint(current); + current=current->next_sibling; + } +} + +void Component_findXY(struct Component* this, int* x, int* y){ + struct Component* current=this; + do{ + *x+=current->x; + *y+=current->y; + current=current->parent; + } while(current!=NULL); +} + +struct Component* Component_find(struct Component* this, int msg){ + struct Component* current=this->first_child; +#ifdef JOOST_DEBUG + printf("Find %x in %x:\n",msg, this->id); fflush(stdout); +#endif + while(current!=NULL){ +#ifdef JOOST_DEBUG + printf("Comp_find: %x, %x\n",msg, current->msg); fflush(stdout); +#endif + if(current->msg==msg) + return current; + current=current->next_sibling; + } + return NULL; +} + +struct Component* Component_delete(struct Component* this){ + struct Component* current=this->first_child; + int id=this->id; + if(this!=NULL){ +#ifdef JOOST_DEBUG + printf("Deleting component: %d\n",id); fflush(stdout); +#endif + while(current!=NULL){ + current=Component_delete(current); + } + if(this->parent!=NULL){ + if(this==this->parent->first_child) + this->parent->first_child=this->parent->first_child->next_sibling; + else{ + current=this->parent->first_child; + while(this!=current->next_sibling && current->next_sibling!=NULL) + current=current->next_sibling; + if(current->next_sibling!=NULL) + current->next_sibling=current->next_sibling->next_sibling; + } + } + current=this->next_sibling; + if(this->sizexds>0) + free(this->xds); + free(this); +#ifdef JOOST_DEBUG + printf("Deleted component: %d\n",id); fflush(stdout); +#endif + } + return current; +} + +void Component_delete_children(struct Component* this){ + struct Component* current=this->first_child; + while(current!=NULL) + current=Component_delete(current); +} + +void Component_changestate_children(struct Component* this, int andmask, int ormask, int xormask){ + struct Component* current=this->first_child; + while(current!=NULL){ + current->state&=(0xffff-andmask); + current->state|=ormask; + current->state^=xormask; + current=current->next_sibling; + } + fflush(stdout); +} + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param){ + struct Component* current,current2; + int x=0,y=0; +#ifdef JOOST_DEBUG + printf("Message in window %d, Msg: %x, Param: %x\n",this->id,msg,param); fflush(stdout); +#endif + switch(msg){ + case KEY_TYPED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)){ + current->handler(current,msg,param); + if((current->state & STATE_ACTION)!=0 && current->msg==param){ + struct ActionXDS* act=(struct ActionXDS*) (current->xds); +#ifdef JOOST_DEBUG + printf("Before actionhandler...\n"); +#endif + act->actionhandler(current); + if((act->action & 0xff00)==0){ + current=NULL; + } +#ifdef JOOST_DEBUG + printf("After actionhandler...\n"); +#endif + } + } + if(current!=NULL) + current=current->next_sibling; + } + break; + case WND_REDRAW: + this->paint(this); + break; + case WND_CLOSE: + this->state=this->state & (0xffff-(STATE_VISIBLE | STATE_ENABLED)); + Component_findXY(this,&x,&y); + TouchRegion(0,x,y,this->sizex,this->sizey); + this->parent->handler(this->parent,WND_REDRAW,0); + break; + case WND_DESTROY: + current=this->parent; + Component_delete(this); + current->handler(current,WND_REDRAW,0); + break; + case WND_BROADCAST: + current=this->first_child; + while(current!=NULL){ + if(current!=(struct Component*) (param) && (current->state & STATE_FOCUS)!=0) + current->handler(current,CMP_BROADCAST,param); + current=current->next_sibling; + } + break; + case APP_QUIT: + if(this->parent==NULL) + global->willquit=1; + else if((this->state & STATE_APPLICATION)==0) + this->parent->handler(this->parent,APP_QUIT,param); + else{ + current=this->parent; + current->state|=STATE_VISIBLE | STATE_ENABLED; + Component_changestate_children(current,0,STATE_VISIBLE,0); + this->handler(this,WND_DESTROY,0); + } + break; + } +} + +void Window_paint(struct Component* this){ + int x=0,y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion(0,x,y,this->sizex,this->sizey); + Move(x,y+global->currentfont->stringheight(this->label)+4); + DrawRect(this->sizex,this->sizey-global->currentfont->stringheight(this->label)-4); + Move(x,y); + FillRect(this->sizex,global->currentfont->stringheight(this->label)+5); + Move(x+2,y+2); + Text(this->label); + Component_paint(this); + } +} + +void Root_paint(struct Component* this){ + Move(0,0); + ClearRect(0,0x80); + TouchRegion(0,0,0,0,0x80); + + Component_paint(this); +/* EnableScreen(0); + Window_paint(this); + EnableScreen(1);*/ +} + +void Window_add(struct Component* this, struct Component* comp){ + Component_add(this,comp); +} + +struct Component* Window_new(int x,int y,int sx,int sy){ + struct Component* this=Component_new(x,y,sx,sy); + this->handler=Window_handler; + this->paint=Window_paint; + this->add=Window_add; + return this; +} + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->parent->handler(this->parent, CMP_ACTION, param); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void Button_drawtext(struct Component* this, int x, int y){ + if((this->state & STYLE_MULTILINE)!=0){ + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-2*global->currentfont->stringheight(this->label))/2); + Text(this->label); + Move(x+(this->sizex-global->currentfont->stringwidth(this->label+LABEL_LENGTH/2))/2,y+(this->sizey)/2+1); + Text((this->label)+0x0a); + } else { + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-global->currentfont->stringheight(this->label))/2+1); + Text(this->label); + } +} + +void Button_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & (STATE_ENABLED | STYLE_INVERTED))!=0 && (this->state & (STATE_ENABLED | STYLE_INVERTED))!=(STATE_ENABLED | STYLE_INVERTED) ) + FillRectNC(this->sizex,this->sizey); + else + DrawRect(this->sizex,this->sizey); + Button_drawtext(this,x,y); + } +} + +void Button_add(struct Component* this, struct Component* comp){ + return; +} + +struct Component* Button_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE; + this->msg=msg; + this->handler=Button_handler; + this->paint=Button_paint; + this->add=Button_add; + + return this; +} + +void Numpad(struct Component* this, int x, int y){ + int i; + char s[2]={0,0}; + struct Component* button; + for(i=0; i<9; i++){ + s[0]=0x31+(char) i; + button=Button_new(x+(i%3)*0x18,y+0x30-(i/3)*0x18,0x16,0x16,i+0x31); + Component_setlabel(button,s); + button->state|=STATE_CASTING; + this->add(this,button); + } + button=Button_new(x+0x18,y+0x48,0x16,0x16,0x30); + Component_setlabel(button,"0"); + button->state|=STATE_CASTING; + this->add(this,button); + + button=Button_new(x+0x30,y+0x48,0x16,0x16,0x08); + Component_setlabel(button,"CE"); + button->state|=STATE_CASTING; + this->add(this,button); +} + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->state^=STATE_CHECKED; + this->parent->handler(this->parent, CMP_STATECHANGE, param); + this->handler(this, WND_REDRAW, 0); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void ToggleButton_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + if((this->state & STATE_ENABLED)!=0 && (this->state & STATE_CHECKED)!=0){ + FillRectNC(this->sizex,this->sizey); + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + }else{ + DrawRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + } + Button_drawtext(this,x,y); + } +} + +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE | STATE_CHECKED; + this->msg=msg; + this->handler=ToggleButton_handler; + this->paint=ToggleButton_paint; + this->add=Button_add; + + return this; +} + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==CMP_ACTION && param==0xff){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_OK, this->msg); + } + if(msg==CMP_ACTION && param==0xfe){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_CANCEL, this->msg); + + } +} + +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* ok; + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_VISIBLE; + this->msg=msg; + this->handler=Dialog_handler; + this->paint=Window_paint; + this->add=Window_add; + + ok=Button_new(sx-0x30,sy-0x1c,0x28,0x14,0xff); + Component_setlabel(ok,"OK"); + this->add(this,ok); + + ok=Button_new(sx-0x30,sy-0x38,0x28,0x14,0xfe); /*Cancel*/ + Component_setlabel(ok,"Cancel"); + this->add(this,ok); + + return this; +} + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param){ + Button_handler(this,msg,param); + if(msg==CMP_BROADCAST && (this->state & STATE_FOCUS)!=0){ +#ifdef JOOST_DEBUG + printf("strlen = %d->",strlen(this->label)); fflush(stdout); +#endif + if(param==0x08){ + if(strlen(this->label)!=0) + this->label[strlen(this->label)-1]=0; + }else{ + this->label[strlen(this->label)+1]=0; + this->label[strlen(this->label)]=(char) param; + } +#ifdef JOOST_DEBUG + printf("%d\n",strlen(this->label)); fflush(stdout); +#endif + this->handler(this,WND_REDRAW,0); + } +} + +void Display_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & STYLE_INVERTED)==0) + FillRectNC(this->sizex,this->sizey); + else + DrawRect(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2); + Text(this->label); + +/* Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + + FillRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2); + Text(this->label); + TouchRegion((this->state&STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); +*/ + } +} + +struct Component* Display_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Button_new(x,y,sx,sy,msg); + this->state|=STATE_FOCUS; + Component_setlabel(this,""); + this->paint=Display_paint; + this->handler=Display_handler; + return this; +} + +/************************************************ + * Labels * + ************************************************/ +void Label_handler(struct Component* this, int msg, int param){ + return; +} + +void Label_paint(struct Component* this){ + int x=0, y=0; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Button_drawtext(this,x,y); + } +} + +struct Component* Label_new(int x, int y, int sx, int sy,char* l){ + struct Component* comp=Component_new(x,y,sx,sy); + Component_setlabel(comp,l); + comp->state=STATE_VISIBLE; + comp->handler=Label_handler; + comp->paint=Label_paint; + comp->add=Button_add; + return comp; +} +/************************************************ + * Implementation * + ************************************************/ +/* +void ScreenDialog_handler(struct Component* this, int msg, int param){ + char cmd[]={0x1B,'V',0}; + Dialog_handler(this,msg,param); + if(msg==CMP_ACTION){ + if(param=='U') + cmd[2]=0; + else if(param=='D') + cmd[2]=1; + else + return; + write(global->lcd,cmd,3); + } +} + +struct Component* ScreenDialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* button; + struct Component* this=Dialog_new(x,y,sx,sy,msg); + + button=Button_new(0x04,0x10,0x20,0x14,'U'); + Component_setlabel(button,"Up"); + this->add(this,button); + + button=Button_new(0x04,0x28,0x20,0x14,'D'); + Component_setlabel(button,"Down"); + this->add(this,button); + + this->handler=ScreenDialog_handler; + + return this; +} +*/ +void rootWindow_handler(struct Component* this, int msg, int param){ + struct Component* dummy; + Window_handler(this,msg,param); +} + + +void screenbuilder(struct Component* root, char* filename){ + struct Component* subw; + struct ActionXDS* action; + int mode; + int fh,rd; + char buf[SIZE_SCRBLD_RECORD]; + long l; + int xs,ys; + xs=0x2b; + ys=0x1a; + buf[0]=0; + fh=open(filename,O_RDONLY); + do{ + char comp=0; + if(buf[0]=='s'){ /* Change size */ + xs=*((int*)(buf+0x1)); + ys=*((int*)(buf+0x3)); + } + + if(buf[0]=='B' || buf[0]=='M'){ /* Button, Multi-line button */ + subw=Button_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + if(buf[0]=='M') subw->state|=STYLE_MULTILINE; + comp=1; + } + if(buf[0]=='T'){ /* Toggle-button */ + subw=ToggleButton_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='D'){ /* Display button */ + subw=Display_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='L'){ /* Label */ + subw=Label_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf+0x12); + comp=1; + } + if(comp!=0){ + if((buf[6] | buf[7])!=0){ + subw->state|=STATE_ACTION; + subw->sizexds=sizeof(struct ActionXDS); + subw->xds=(void*) malloc(sizeof(struct ActionXDS)); + action=(struct ActionXDS*) (subw->xds); + action->actionhandler=root_actionhandler; + action->action=*((int*)(buf+0x6)); + action->wParam=*((int*)(buf+0x8)); + action->lParam=*((long*)(buf+0xa)); + } + if((buf[0x0e] | buf[0x0f])!=0) + subw->state=*((int*)(buf+0x0e)); + subw->font=*((int*)(buf+0x10)); + for(rd=0; rd<20; rd++) + subw->label[rd]=buf[rd+0x12]; + root->add(root,subw); + } + + rd=read(fh,buf,SIZE_SCRBLD_RECORD); + } while(rd==SIZE_SCRBLD_RECORD); + close(fh); + root->paint(root); +} + +void root_actionhandler(struct Component* this){ + struct ActionXDS *act; + struct Component* subw; + char filename[]={'0','0','0','0','.','s','c','r',0}; + + act=(struct ActionXDS*) (this->xds); + + if(act->action==0x0001){ /*QUIT*/ + this->handler(this,APP_QUIT,0); + } + if((act->action & 0xfffe)==0x0002){ /*Open Screen*/ + Component_changestate_children(this->parent,STATE_VISIBLE,0,0); + subw=Window_new(0,0,this->parent->sizex,this->parent->sizey); + subw->state=STATE_VISIBLE | STATE_ENABLED; + if((act->action & 1)!=0) + subw->state|=STATE_APPLICATION; + subw->handler=rootWindow_handler; + subw->paint=Root_paint; + filename[0]=(char) ((act->lParam) &0xff); + filename[1]=(char) ((act->lParam>>8) &0xff); + filename[2]=(char) ((act->lParam>>16) &0xff); + filename[3]=(char) ((act->lParam>>24) &0xff); + screenbuilder(subw,filename); + this->parent->add(this->parent,subw); + } + if(act->action==0x0004) { /* Open MessageBox */ + /*Component_changestate_children(this->parent,0,0,0);*/ + struct Component* label; + int i; + subw=Dialog_new(0x05,0x05,this->parent->sizex-0x0a,this->parent->sizey-0x0a,1); + subw->state=STATE_VISIBLE | STATE_ENABLED | STYLE_SELFDESTRUCT; + subw->font=0x0030; + for(i=0; i<(act->wParam>>12)&0x0f; i++){ + label=Label_new(0x08,0x14+i*0x0c,(subw->sizex & 0xff)-0x10,0x10,global->stringtable[(act->wParam&0xfff)+i]); + label->font=0x0030; + subw->add(subw,label); + } + Component_setlabel(subw,"Message Box"); + Component_find(subw,0xff)->font=0x0030; + Component_delete(Component_find(subw,0xfe)); + this->parent->add(this->parent,subw); + this->parent->handler(this->parent,WND_REDRAW,0); + } +} + +void read_stringtable(){ + int siz,bsiz; + int i=0,j=0; + char buf[12]; + char **ptrs; + char *rawdata; + int fh=open("strings.txt",O_RDONLY); + read(fh,buf,12); + siz=(buf[0]-0x30)*10000+(buf[1]-0x30)*1000+(buf[2]-0x30)*100+(buf[3]-0x30)*10+(buf[4]-0x30); + bsiz=(buf[5]-0x30)*10000+(buf[6]-0x30)*1000+(buf[7]-0x30)*100+(buf[8]-0x30)*10+(buf[9]-0x30); + + ptrs=(char**) malloc(sizeof(char*)*siz); + rawdata=(char*) malloc(bsiz); + read(fh,rawdata,bsiz); + while(istringtabledata=rawdata; + global->stringtable=ptrs; + +} + +void GUIinit(void){ + global=(struct Global_GUI*) malloc(sizeof(struct Global_GUI)); + global->id=0; + global->willquit=0; + global->currentfont=NULL; + global->firstfont=NULL; + GraphicsOpen(); + loadFont(0x0030,stringwidth0,stringheight01,0,NULL); + loadFont(0x0031,stringwidth1,stringheight01,0,NULL); + loadFont(0x0032,stringwidth2,stringheight2,0,NULL); + read_stringtable(); + global->root=Window_new(0x0,0x0,0x00,0x80); + global->root->state=STATE_VISIBLE; + global->root->handler=rootWindow_handler; + global->root->paint=Root_paint; + Component_setlabel(global->root,"Test-window"); + +} + +void GUIunit(void){ + Component_delete(global->root); + ClearScreen(); + GraphicsClose(); +} + +void GUIgo(void){ + char buf; + screenbuilder(global->root,"0000.scr"); + + while(read(global->lcd,&buf,1)==1); + + while(!global->willquit){ + if(read(global->lcd,&buf,1)==1) + global->root->handler(global->root,KEY_TYPED,buf); + } +} + +void main(void){ + GUIinit(); + GUIgo(); + GUIunit(); +} + diff --git a/src/gui/Copy of wnd.h b/src/gui/Copy of wnd.h new file mode 100644 index 00000000..13fe89d1 --- /dev/null +++ b/src/gui/Copy of wnd.h @@ -0,0 +1,180 @@ +#ifndef JOOST_WND_H +#define JOOST_WND_H +#include +#include +#include +#include +#include +#include + +#define FONT_HEIGHT global->currentfont->stringheight +#define FONT_WIDTH(x) global->currentfont->stringwidth(x) +#define LABEL_LENGTH 0x14 +#define SIZE_SCRBLD_RECORD 0x12+LABEL_LENGTH + + +#define STATE_VISIBLE 0x0001 +#define STATE_ENABLED 0x0002 +#define STATE_CHECKED 0x0004 +#define STATE_FOCUS 0x0008 +#define STATE_CASTING 0x0010 +#define STATE_ACTION 0x0020 +#define STYLE_MULTILINE 0x0040 +#define STYLE_INVERTED 0x0080 +#define STYLE_SELFDESTRUCT 0x2000 +#define STATE_APPLICATION 0x4000 +#define STATE_DUMMY 0x8000 + +#define KEY_TYPED 0x0001 +#define WND_OPEN 0x0101 +#define WND_CLOSE 0x0102 +#define WND_REDRAW 0x0103 +#define WND_BROADCAST 0x0104 +#define WND_DESTROY 0x0105 +#define CMP_ACTION 0x0201 +#define CMP_STATECHANGE 0x0202 +#define CMP_BROADCAST 0x0203 +#define DLG_OK 0x0301 +#define DLG_CANCEL 0x0302 +#define APP_QUIT 0x0401 + +struct Font; +struct Component; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(); +void GraphicsClose(); +void Move(int x, int y); +void ClearRect(int sx, int sy); +void DrawRect(int sx, int sy); +void FillRect(int sx, int sy); +void FillRectNC(int sx, int sy); +void Text(char *s); +void TouchRegion(int msg, int x, int y, int sx, int sy); +void ClearScreen(); +void EnableScreen(unsigned char c); +void grSetFont(int f); + +/************************************************ + * Fonts * + ************************************************/ + +struct Font { + int id; + int (*stringwidth)(char*); + int (*stringheight)(char*); + struct Font* nextfont; + int sizefontdata; + void* fontdata; +}; + +struct Font* fontSearch(int f); +void setCurrentFont(int f); +void loadFont(int id,int (*sw)(char*),int (*sh)(char*),int sizedata, void* data); + + +/************************************************ + * Components * + ************************************************/ + +struct Component { + int id; + int x,y; + int sizex,sizey; + int state; + int order; + int font; + char msg; + struct Component* parent; + struct Component *next_sibling; + struct Component *first_child; + void (*handler) (struct Component*, int, int); + void (*paint) (struct Component*); + void (*add) (struct Component*, struct Component*); + char label[LABEL_LENGTH+1]; + int sizexds; + void *xds; +}; + +struct ActionXDS { + void (*actionhandler)(struct Component*); + int action; + int wParam; + long lParam; +}; + +struct Component* Component_new(int x,int y,int sx,int sy); +void Component_setlabel(struct Component* this, char* s); +void Component_add(struct Component* this, struct Component* comp); +void Component_paint(struct Component* this); +void Component_findXY(struct Component* this, int* x, int* y); +struct Component* Component_find(struct Component* this, int msg); +struct Component* Component_delete(struct Component* this); +void Component_delete_children(struct Component* this); +void Component_changestate_children(struct Component* this, int andmask, int ormask, int xormask); + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param); +void Window_paint(struct Component* this); +void Root_paint(struct Component* this); +void Window_add(struct Component* this, struct Component* comp); +struct Component* Window_new(int x,int y,int sx,int sy); + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param); +void Button_drawtext(struct Component* this, int x, int y); +void Button_paint(struct Component* this); +void Button_add(struct Component* this, struct Component* comp); +struct Component* Button_new(int x, int y, int sx, int sy, int msg); +void Numpad(struct Component* this, int x, int y); + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param); +void ToggleButton_paint(struct Component* this); +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param); +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param); +void Display_paint(struct Component* this); +struct Component* Display_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Labels * + ************************************************/ +void Label_handler(struct Component* this, int msg, int param); +void Label_paint(struct Component* this); +struct Component* Label_new(int x, int y, int sx, int sy,char* l); + +/************************************************ + * Implementation * + ************************************************/ +void rootWindow_handler(struct Component* this, int msg, int param); +void root_actionhandler(struct Component*); +void screenbuilder(struct Component* root, char* filename); +void read_stringtable(); +void GUIinit(); +void GUIgo(); +void GUIunit(); + +#endif \ No newline at end of file diff --git a/src/gui/cl64180.r01 b/src/gui/cl64180.r01 new file mode 100644 index 0000000000000000000000000000000000000000..19dd6c159c5f94b672c5cc145c769973845656e8 GIT binary patch literal 100922 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 literal 0 HcmV?d00001 diff --git a/src/gui/grlogin.map b/src/gui/grlogin.map new file mode 100644 index 00000000..8f8c2e6c --- /dev/null +++ b/src/gui/grlogin.map @@ -0,0 +1,272 @@ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +. .ABS. 00000000 00000000 = 0. bytes (ABS,OVR) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR + 00000000 .__.ABS. | 00000000 ?CL64180L | 00000000 ?CL64180B + 00000014 e__DEFAUL | 00000014 l__DEFAUL | 00000034 l_CONST + 000000A0 l_CSTR | 00000158 l_CDATA0 | 00000158 l_IDATA0 + 00000381 l_RCODE | 000003B3 l_UDATA0 | 00001000 l_CSTACK + 00004000 s_CODE | 00008100 s_RCODE | 00008481 e_RCODE + 00008481 s_CONST | 000084B5 s_CSTR | 000084B5 e_CONST + 00008555 e_CSTR | 00008555 s_IDATA0 | 00008555 s_CDATA0 + 000086AD s_UDATA0 | 000086AD e_CCSTR | 000086AD e_ECSTR + 000086AD s_CCSTR | 000086AD e_CDATA0 | 000086AD s_ECSTR + 000086AD e_IDATA0 | 00008A60 e_UDATA0 | 00008A60 s_CSTACK + 00009A60 e_CSTACK | 0000C00E l_CODE | 0001000E e_CODE +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +_DEFAULT 00000000 00000014 = 20. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +RCODE 00008100 00000381 = 897. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008100 __init | 0000811F ?BANK_LEA | 00008125 ?BANK_FAS + 0000812A ?S_MUL_L0 | 00008140 ?C_V_SWIT | 00008152 ?ENT_PARM + 0000815E ?BANK_CAL | 0000816B ?S_V_SWIT | 00008188 ?ENT_AUTO + 0000819C ?V_SWITCH | 000081A6 ?SS_CMP_L | 000081B8 ?SS_DIV_L + 000081D4 ?UL_RSHAS | 000081E2 ?SL_RSH_L | 000081F0 ?UL_RSH_L + 0000820B ?BANK_LEA | 00008217 ?SS_RSH_L | 00008221 ?L_LSH_L0 + 00008239 ?S_DIVMOD | 0000824F ?L_END_AS | 00008258 ?L_XOR_L0 + 00008276 ?L_ORASG_ | 0000828F ?LEAVE_DI | 00008296 ?L_ADDASG + 000082AF ?S_S_SWIT | 000082C3 ?S_SWITCH | 000082D1 ?S_FIND_S + 000082ED ?L_NEG_L0 | 000082FF ?US_MOD_L | 00008308 ?US_DIV_L + 00008316 ?L_MULASG | 00008326 ?L_MUL_L0 | 000083AA ?S_MULASG + 000083B4 ?L_END_MU | 000083BD ?UL_DIVAS | 000083CD ?UL_MOD_L + 000083F2 ?UL_DIV_L | 0000841A ?L_DIVMOD | 00008472 ?L_NOT_L0 +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CONST 00008481 00000034 = 52. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTR 000084B5 000000A0 = 160. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +IDATA0 00008555 00000158 = 344. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008555 __IO_list | 00008557 stdin | 0000856F stdout + 00008587 stderr | 000085A5 _path_pas | 000085A7 __sys_err + 000085A9 __sys_ner | 000085AB __on_exit | 000085AD __ctype +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CDATA0 00008555 00000158 = 344. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +ECSTR 000086AD 00000000 = 0. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CCSTR 000086AD 00000000 = 0. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CODE 00004000 0000C00E = 49166. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 000045C1 GraphicsO | 0000464F GraphicsC | 00004664 Move + 000046A3 ClearRect | 000046E6 DrawRectN | 0000472B FillRect + 00004770 FillRectN | 000047B5 GrayRect | 000047FA Text + 00004827 TouchRegi | 0000487E ClearScre | 000048BB EnableScr + 000048F9 grSetFont | 00004936 fontSearc | 00004966 setCurren + 000049F4 loadFont | 00004A9B stringwid | 00004B14 stringhei + 00004B31 stringhei | 00004B44 stringhei | 00004B4D stringwid + 00004B5E stringwid | 00004B67 stringwid | 00004B70 Component + 00004C1A Component | 00004C67 Component | 00004CC5 Component + 00004D0B Component | 00004D4F Component | 00004D87 Component + 00004F58 Component | 00004F77 Component | 00004FE0 Component + 00005093 Window_ha | 00005360 Window_pa | 000054ED Root_pain + 00005524 Window_ad | 00005532 Window_ne | 00005584 Button_ha + 0000563B Button_dr | 000056F7 Button_pa | 000057F0 Button_ad + 000057F6 Button_ne | 00005848 ToggleBut | 000058E4 ToggleBut + 000059D0 ToggleBut | 00005A22 Dialog_ha | 00005ADB Dialog_ne + 00005BCA Display_h | 00005C4B Display_p | 00005D97 Display_n + 00005DF1 Label_han | 00005DF7 Label_pai | 00005E58 Label_new + 00005EB1 rootWindo | 00005ECF screenbui | 000062A9 root_acti + 000065E1 read_stri | 000066B6 gui_globa | 000066BC GUIinit + 000067E3 GUIunit | 00006808 GUIgo | 000068BD login + 000069CC login_act | 00006AC5 main | 00006AFA setgid + 00006B14 unix | 00006B2E strrchr | 00006B96 fflush + 00006DA9 chdir | 00006DBE _write | 00006DDD setuid + 00006DF7 lseek | 00006E24 __stdio_c | 00006E8F __stdio_i + 00006ECD setenv | 00007149 unsetenv | 000071E9 close + 000071FE strlen | 00007235 strcmp | 000072D6 perror + 00007313 execv | 00007326 ioctl | 00007351 isatty + 0000738C fstat | 000073A3 free | 00007483 getpwnam + 000074E5 setpwent | 0000752A endpwent | 00007549 getpwent + 00007567 strcpy | 0000758E __getpwen | 00007816 crypt + 00007AC3 open | 00007AEE malloc | 00007D1A exit + 00007D4A _read | 00007D69 memcmp | 00007DD6 execve + 00007DF5 strerror | 00007FB2 memset | 00014000 memcpy + 000140CE on_exit | 00014147 atexit | 0001415A printf + 00014189 unix_long | 000141A3 strchr | 000141DE _exit + 00014279 strtoul | 000143D0 toupper | 000143F5 tolower + 0001441A atoi | 00014430 __longtoa | 000145C4 itoa + 000147AD vfprintf | 00014D08 ltoa | 00014D6B sbrk + 00014D80 strcat | 00014DA0 fputc | 00014EB2 ultoa + 00014F07 strtol +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +UDATA0 000086AD 000003B3 = 947. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 000086AD _argc | 000086AF _argv | 000086B1 environ + 000086B3 errno | 000086B5 __cleanup | 000086B8 global + 000089D8 __malloc_ | 000089DC __malloc_ | 00008A2E __on_exit +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTACK 00008A60 00001000 = 4096. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + +Files Linked [ module(s) ] + +..\..\lib\c0b.rel [ _c0b ] +wnd [ wnd ] +login [ login ] + + +Libraries Linked [ object file ] + +..\..\lib\libsysb.lib [ relsysb\setgid.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strrchr.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\chdir.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libiar.lib [ reliar\SMUL.rel ] +..\..\lib\libsysb.lib [ relsysb\setuid.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libcb.lib [ relcb\setenv.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libcb.lib [ relcb\strcmp.rel ] +..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] +..\..\lib\libcb.lib [ relcb\perror.rel ] +..\..\lib\libcb.lib [ relcb\execv.rel ] +..\..\lib\libsysb.lib [ relsysb\ioctl.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libcb.lib [ relcb\getpwnam.rel ] +..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\setpwent.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\SVSWITCH.rel ] +..\..\lib\libcb.lib [ relcb\getpwent.rel ] +..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] +..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] +..\..\lib\libiar.lib [ reliar\SSCMP.rel ] +..\..\lib\libcb.lib [ relcb\crypt.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] +..\..\lib\libiar.lib [ reliar\SSDIV.rel ] +..\..\lib\libiar.lib [ reliar\ULRSHASG.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] +..\..\lib\libiar.lib [ reliar\SLRSH.rel ] +..\..\lib\libiar.lib [ reliar\ULRSH.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] +..\..\lib\libiar.lib [ reliar\SSRSH.rel ] +..\..\lib\libiar.lib [ reliar\LLSH.rel ] +..\..\lib\libcb.lib [ relcb\memcmp.rel ] +..\..\lib\libsysb.lib [ relsysb\execve.rel ] +..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] +..\..\lib\libcb.lib [ relcb\error.rel ] +..\..\lib\libiar.lib [ reliar\LENDASG.rel ] +..\..\lib\libcb.lib [ relcb\memset.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libiar.lib [ reliar\LXOR.rel ] +..\..\lib\libcb.lib [ relcb\printf.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libiar.lib [ reliar\LORASG.rel ] +..\..\lib\libcb.lib [ relcb\strchr.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libiar.lib [ reliar\LADDASG.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] +..\..\lib\libiar.lib [ reliar\SSSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SSWITCHEND.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libiar.lib [ reliar\SFINDSIGN.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] +..\..\lib\libiar.lib [ reliar\LNEG.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] +..\..\lib\libiar.lib [ reliar\USMOD.rel ] +..\..\lib\libiar.lib [ reliar\USDIV.rel ] +..\..\lib\libiar.lib [ reliar\LMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LMUL.rel ] +..\..\lib\libiar.lib [ reliar\SMULASG.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] +..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] +..\..\lib\libiar.lib [ reliar\ULMOD.rel ] +..\..\lib\libiar.lib [ reliar\ULDIV.rel ] +..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] +..\..\lib\libiar.lib [ reliar\LNOT.rel ] + + +User Base Address Definitions + +l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/gui/hello.map b/src/gui/hello.map new file mode 100644 index 00000000..44a45a1b --- /dev/null +++ b/src/gui/hello.map @@ -0,0 +1 @@ +Error[e12]: Unable to open file 'hello' diff --git a/src/gui/login.c b/src/gui/login.c new file mode 100644 index 00000000..598cf056 --- /dev/null +++ b/src/gui/login.c @@ -0,0 +1,93 @@ +/* login.c + * descripton: login into a user account + * author: Alistair Riddoch + * modification: David Murn + * Added password entry + * modification: Shane Kerr + * More work on password entry + */ + +/* todo: add a timeout for serial and network logins */ +/* ??? need a signal mechanism (i.e. alarm() and SIGALRM) */ +/* real getpass() ! */ + +#include +#include +#include +#include +#include +#include + +void login(pwd, argv) + struct passwd *pwd; + char **argv; +{ + char pname[64]; + char *bname; + +#if 1 /* addition by Nick, please see linux manpage passwd.5 */ + if (!*pwd->pw_shell) + { + pwd->pw_shell = "/bin/sh"; + } +#endif + +/* chown("/dev/tty",pwd->pw_uid,pwd->pw_gid); */ + pname[0] = '-'; + if ((bname = strrchr(pwd->pw_shell, '/')) != NULL) + bname++; + else bname = pwd->pw_shell; + strcpy(pname+1, bname); + argv[0] = pname; + argv[1] = NULL; + /* we must set first GID, because we're still root + if UID is set first and we aren't logging as root, + we won't have permission to change our GID */ + setgid(pwd->pw_gid); + setuid(pwd->pw_uid); + chdir(pwd->pw_dir); + setenv("HOME", pwd->pw_dir, 1); + setenv("USER", pwd->pw_name, 1); + execv(pwd->pw_shell, argv); + perror(pwd->pw_shell); + exit(1); +} + +void login_actionhandler(struct Component* this){ + char lbuf[20], *pbuf, salt[3], *s; + struct passwd *pwd; + int n; + struct ActionXDS *act; + struct Component* disp=this; + + act=(struct ActionXDS*) (this->xds); + if(act->action==0x0101){ + lbuf[0]=disp->label[0]; + lbuf[1]=disp->label[1]; + lbuf[2]=0; + disp->label[0]=0; + pwd = getpwnam(lbuf); + pbuf=disp->label+2; + if (pwd != NULL) { + salt[0] = pwd->pw_passwd[0]; + salt[1] = pwd->pw_passwd[1]; + salt[2] = 0; + s = crypt(pbuf, salt); + if (!strcmp(s, pwd->pw_passwd)){ + ClearScreen(); + login(pwd, NULL); + } + } + disp->paint(disp); + } +} + +void main(int argc, char** argv) +{ + GUIinit(); + gui_globals()->actionhandler=login_actionhandler; + GUIgo("/wnd/logn.scr"); + GUIunit(); +} + + diff --git a/src/gui/login.map b/src/gui/login.map new file mode 100644 index 00000000..297c5c7d --- /dev/null +++ b/src/gui/login.map @@ -0,0 +1,283 @@ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +. .ABS. 00000000 00000000 = 0. bytes (ABS,OVR) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR + 00000000 .__.ABS. | 00000000 ?CL64180L | 00000000 ?CL64180B + 00000014 e__DEFAUL | 00000014 l__DEFAUL | 0000002F l_CONST + 00000148 l_CSTR | 00000170 l_CDATA0 | 00000170 l_IDATA0 + 000003B5 l_UDATA0 | 00000430 l_RCODE | 00001000 l_CSTACK + 00004000 s_CODE | 00008100 s_RCODE | 00008530 e_RCODE + 00008530 s_CONST | 0000855F s_CSTR | 0000855F e_CONST + 000086A7 e_CSTR | 000086A7 s_IDATA0 | 000086A7 s_CDATA0 + 00008817 s_UDATA0 | 00008817 e_CCSTR | 00008817 e_ECSTR + 00008817 s_CCSTR | 00008817 e_CDATA0 | 00008817 s_ECSTR + 00008817 e_IDATA0 | 00008BCC e_UDATA0 | 00008BCC s_CSTACK + 00009BCC e_CSTACK | 0000C27F l_CODE | 0001027F e_CODE +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +_DEFAULT 00000000 00000014 = 20. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +RCODE 00008100 00000430 = 1072. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008100 __init | 0000811F ?L_MUL_L0 | 000081A3 ?BANK_LEA + 000081A9 ?BANK_FAS | 000081AE ?S_MUL_L0 | 000081C4 ?C_V_SWIT + 000081D6 ?L_ADDASG | 000081EF ?ENT_PARM | 000081FB ?BANK_CAL + 00008208 ?S_S_SWIT | 0000821C ?S_V_SWIT | 00008239 ?S_SWITCH + 00008247 ?SL_MOD_L | 0000827A ?ENT_AUTO | 0000828E ?V_SWITCH + 00008298 ?SL_DIV_L | 000082C8 ?SS_CMP_L | 000082DA ?L_INC_L0 + 000082E2 ?US_MOD_L | 000082EB ?SS_DIV_L | 00008307 ?UL_RSHAS + 00008315 ?US_DIV_L | 00008323 ?SL_RSH_L | 00008331 ?UL_RSH_L + 0000834C ?L_DIVMOD | 000083A4 ?BANK_LEA | 000083B0 ?SS_RSH_L + 000083BA ?L_LSH_L0 | 000083D2 ?S_DIVMOD | 000083E8 ?S_MULASG + 000083F2 ?L_END_AS | 000083FB ?L_NOT_L0 | 0000840A ?L_XOR_L0 + 00008428 ?L_ORASG_ | 00008441 ?LEAVE_DI | 00008448 ?L_FIND_S + 0000848C ?UL_DIVAS | 0000849C ?UL_MOD_L | 000084C1 ?S_FIND_S + 000084DD ?UL_DIV_L | 00008505 ?L_NEG_L0 | 00008517 ?L_MULASG + 00008527 ?L_END_MU +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CONST 00008530 0000002F = 47. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTR 0000855F 00000148 = 328. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +IDATA0 000086A7 00000170 = 368. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 000086BF __IO_list | 000086C1 stdin | 000086D9 stdout + 000086F1 stderr | 0000870F _path_pas | 00008711 __sys_err + 00008713 __sys_ner | 00008715 __on_exit | 00008717 __ctype +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CDATA0 000086A7 00000170 = 368. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +ECSTR 00008817 00000000 = 0. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CCSTR 00008817 00000000 = 0. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CODE 00004000 0000C27F = 49791. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 0000472B GraphicsO | 000047C7 GraphicsC | 000047DF Move + 0000481E ClearRect | 00004861 DrawRectN | 000048A6 FillRect + 000048EB FillRectN | 00004930 GrayRect | 00004975 Text + 000049A1 TouchRegi | 000049F8 ClearScre | 00004A35 EnableScr + 00004A73 grSetFont | 00004AB0 fontSearc | 00004AE0 setCurren + 00004B7C loadFont | 00004C23 stringwid | 00004C9C stringhei + 00004CB9 stringhei | 00004CCC stringhei | 00004CD5 stringwid + 00004CE6 stringwid | 00004CEF stringwid | 00004CF8 Component + 00004DA2 Component | 00004DEF Component | 00004E4D Component + 00004E93 Component | 00004ED7 Component | 00004F0F Component + 000050E0 Component | 000050FF Component | 00005168 Component + 0000521B Window_ha | 00005485 Window_pa | 00005611 Root_pain + 00005648 Window_ad | 00005656 Window_ne | 000056A8 Button_ha + 0000575F Button_dr | 0000582D Button_pa | 00005900 Button_ad + 00005906 Button_ne | 00005958 ToggleBut | 000059F1 ToggleBut + 00005ADD ToggleBut | 00005B2F Dialog_ha | 00005BE8 Dialog_ne + 00005CD7 Display_h | 00005D55 Display_p | 00005E72 Display_n + 00005ECC Label_han | 00005ED2 Label_pai | 00005F33 Label_new + 00005F8C Transacti | 000065CA rootWindo | 000065E8 screenbui + 000069B0 root_acti | 00006CE5 read_stri | 00006DBA gui_globa + 00006DC0 GUIinit | 00006EF0 GUIunit | 00006F15 GUIgo + 00006F94 login | 000070BD login_act | 00007213 main + 0000727A setgid | 00007294 unix | 000072AE sprintf + 000072F2 strrchr | 0000735A fflush | 0000756D chdir + 00007582 _write | 000075A1 setuid | 000075BB printf + 000075EA lseek | 00007617 __stdio_c | 00007682 __stdio_i + 000076C0 setenv | 0000793C unsetenv | 000079DC close + 000079F1 strlen | 00007A28 strcmp | 00007AC9 perror + 00007B06 execv | 00007B19 ioctl | 00007B44 isatty + 00007B7F fstat | 00007B96 free | 00007C76 getpwnam + 00007CD8 setpwent | 00007D1D endpwent | 00007D3C getpwent + 00007D5A strcpy | 00014000 __getpwen | 00014288 atoi + 0001441E vfprintf | 00014979 ltoa | 000149DC atol + 000149F2 __longtoa | 00014B86 itoa | 00014BEF crypt + 00014E9C fputs | 00014EFA open | 00014F25 malloc + 00015151 exit | 00015181 _read | 000151A0 memcmp + 0001520D execve | 0001522C strerror | 000153E9 memset + 00015429 memcpy | 000154F7 on_exit | 00015570 atexit + 00015583 strcat | 000155A3 unix_long | 000155BD strchr + 000155F8 _exit | 00015693 strtoul | 000157EA fputc + 000158FC toupper | 00015921 tolower | 00015946 ultoa + 0001599B strtol | 00015A43 sbrk +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +UDATA0 00008817 000003B5 = 949. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008817 _argc | 00008819 _argv | 0000881B environ + 0000881D errno | 0000881F __cleanup | 00008822 global + 00008824 trans | 00008B44 __malloc_ | 00008B48 __malloc_ + 00008B9A __on_exit +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTACK 00008BCC 00001000 = 4096. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + +Files Linked [ module(s) ] + +..\..\lib\c0b.rel [ _c0b ] +wnd [ wnd ] +login [ login ] + + +Libraries Linked [ object file ] + +..\..\lib\libsysb.lib [ relsysb\setgid.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] +..\..\lib\libcb.lib [ relcb\sprintf.rel ] +..\..\lib\libiar.lib [ reliar\LMUL.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strrchr.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\chdir.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libiar.lib [ reliar\SMUL.rel ] +..\..\lib\libsysb.lib [ relsysb\setuid.rel ] +..\..\lib\libcb.lib [ relcb\printf.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libcb.lib [ relcb\setenv.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libcb.lib [ relcb\strcmp.rel ] +..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] +..\..\lib\libcb.lib [ relcb\perror.rel ] +..\..\lib\libcb.lib [ relcb\execv.rel ] +..\..\lib\libsysb.lib [ relsysb\ioctl.rel ] +..\..\lib\libiar.lib [ reliar\LADDASG.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libcb.lib [ relcb\getpwnam.rel ] +..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\setpwent.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\SSSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SVSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SSWITCHEND.rel ] +..\..\lib\libiar.lib [ reliar\SLMOD.rel ] +..\..\lib\libcb.lib [ relcb\getpwent.rel ] +..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] +..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] +..\..\lib\libiar.lib [ reliar\SLDIV.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] +..\..\lib\libcb.lib [ relcb\atol.rel ] +..\..\lib\libiar.lib [ reliar\SSCMP.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] +..\..\lib\libiar.lib [ reliar\LINC.rel ] +..\..\lib\libcb.lib [ relcb\crypt.rel ] +..\..\lib\libcb.lib [ relcb\fputs.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] +..\..\lib\libiar.lib [ reliar\USMOD.rel ] +..\..\lib\libiar.lib [ reliar\SSDIV.rel ] +..\..\lib\libiar.lib [ reliar\ULRSHASG.rel ] +..\..\lib\libiar.lib [ reliar\USDIV.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] +..\..\lib\libiar.lib [ reliar\SLRSH.rel ] +..\..\lib\libiar.lib [ reliar\ULRSH.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] +..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] +..\..\lib\libiar.lib [ reliar\SSRSH.rel ] +..\..\lib\libiar.lib [ reliar\LLSH.rel ] +..\..\lib\libcb.lib [ relcb\memcmp.rel ] +..\..\lib\libsysb.lib [ relsysb\execve.rel ] +..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] +..\..\lib\libcb.lib [ relcb\error.rel ] +..\..\lib\libiar.lib [ reliar\SMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LENDASG.rel ] +..\..\lib\libiar.lib [ reliar\LNOT.rel ] +..\..\lib\libcb.lib [ relcb\memset.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libiar.lib [ reliar\LXOR.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libiar.lib [ reliar\LORASG.rel ] +..\..\lib\libcb.lib [ relcb\strchr.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] +..\..\lib\libiar.lib [ reliar\LFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] +..\..\lib\libiar.lib [ reliar\ULMOD.rel ] +..\..\lib\libiar.lib [ reliar\SFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIV.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] +..\..\lib\libiar.lib [ reliar\LNEG.rel ] +..\..\lib\libiar.lib [ reliar\LMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] + + +User Base Address Definitions + +l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/gui/login.rel b/src/gui/login.rel new file mode 100644 index 00000000..ca893803 --- /dev/null +++ b/src/gui/login.rel @@ -0,0 +1,231 @@ +XL4 +H 3 areas 1B global symbols +M login +S setgid Ref00000000 +S GUIunit Ref00000000 +S ?BANK_FAST_LEAVE_L08 Ref00000000 +S ClearScreen Ref00000000 +S strrchr Ref00000000 +S gui_globals Ref00000000 +S chdir Ref00000000 +S setuid Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S setenv Ref00000000 +S strcmp Ref00000000 +S perror Ref00000000 +S execv Ref00000000 +S GUIgo Ref00000000 +S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S getpwnam Ref00000000 +S strcpy Ref00000000 +S ?ENT_AUTO_DIRECT_L09 Ref00000000 +S crypt Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S GUIinit Ref00000000 +S exit Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 23D flags 0 +S login_actionhandler Def0000010F +S login Def00000000 +S main Def00000208 +A CSTR size 20 flags 0 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 FD E5 DD E5 C5 21 C0 FF 39 F9 D5 +R 00 00 01 00 +T 0B 00 00 00 DD E1 21 0C 00 19 7E 23 66 6F AF +R 00 00 01 00 +T 16 00 00 00 B6 20 08 +R 00 00 01 00 +T 19 00 00 00 +R 00 00 01 00 +T 19 00 00 00 DD 36 0C 00 00 00 00 DD 36 0D +R 00 00 01 00 09 07 02 00 +T 20 00 00 00 00 00 00 00 +R 00 00 01 00 89 04 02 00 +T 21 00 00 00 +R 00 00 01 00 +T 21 00 00 00 21 00 00 39 36 2D 01 2F 00 DD 5E +R 00 00 01 00 +T 2C 00 00 00 0C DD 56 0D 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 04 00 +T 33 00 00 00 00 00 00 00 CD 00 00 00 00 E5 FD +R 00 00 01 00 02 04 04 00 02 09 0F 00 +T 3A 00 00 00 E1 7D B4 28 04 +R 00 00 01 00 +T 3F 00 00 00 +R 00 00 01 00 +T 3F 00 00 00 FD 23 18 09 +R 00 00 01 00 +T 43 00 00 00 +R 00 00 01 00 +T 43 00 00 00 DD 6E 0C DD 66 0D E5 FD E1 +R 00 00 01 00 +T 4C 00 00 00 +R 00 00 01 00 +T 4C 00 00 00 FD E5 C1 21 00 00 39 11 01 00 19 +R 00 00 01 00 +T 57 00 00 00 EB 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 11 00 02 0B 11 00 +T 5D 00 00 00 CD 00 00 00 00 21 00 00 39 E5 21 +R 00 00 01 00 02 05 0F 00 +T 66 00 00 00 42 00 39 7E 23 66 6F C1 71 23 70 +R 00 00 01 00 +T 71 00 00 00 21 40 00 39 47 23 66 68 23 23 AF +R 00 00 01 00 +T 7C 00 00 00 77 23 77 DD 5E 06 DD 56 07 3E +R 00 00 01 00 +T 86 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 00 00 02 09 00 00 +T 8B 00 00 00 00 00 00 00 DD 5E 04 DD 56 05 3E +R 00 00 01 00 02 04 0F 00 +T 94 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 99 00 00 00 00 00 00 00 DD 5E 0A DD 56 0B 3E +R 00 00 01 00 02 04 0F 00 +T A2 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 06 00 02 09 06 00 +T A7 00 00 00 00 00 00 00 21 01 00 E5 DD 4E 0A +R 00 00 01 00 02 04 0F 00 +T B0 00 00 00 DD 46 0B 11 08 00 00 00 3E +R 00 00 01 00 00 08 02 00 +T B7 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 09 00 02 09 09 00 +T BC 00 00 00 00 00 00 00 F1 21 01 00 E5 DD 4E +R 00 00 01 00 02 04 0F 00 +T C5 00 00 00 00 DD 46 01 11 0D 00 00 00 3E +R 00 00 01 00 00 09 02 00 +T CD 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 09 00 02 09 09 00 +T D2 00 00 00 00 00 00 00 F1 21 40 00 39 4E 23 +R 00 00 01 00 02 04 0F 00 +T DB 00 00 00 46 DD 5E 0C DD 56 0D 3E +R 00 00 01 00 +T E3 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0C 00 02 09 0C 00 +T E8 00 00 00 00 00 00 00 DD 5E 0C DD 56 0D 3E +R 00 00 01 00 02 04 0F 00 +T F1 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +T F6 00 00 00 00 00 00 00 11 01 00 3E +R 00 00 01 00 02 04 0F 00 +T FC 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 16 00 02 09 16 00 +T 01 01 00 00 00 00 00 00 21 42 00 39 F9 DD E1 +R 00 00 01 00 02 04 0F 00 +T 0A 01 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 02 00 +T 0F 01 00 00 +R 00 00 01 00 +T 0F 01 00 00 CD 00 00 00 00 E0 FF FD E5 DD 6E +R 00 00 01 00 02 05 12 00 +T 18 01 00 00 02 DD 66 03 E5 FD E1 21 26 00 DD +R 00 00 01 00 +T 23 01 00 00 4E 02 DD 46 03 09 46 23 66 68 23 +R 00 00 01 00 +T 2E 01 00 00 23 23 46 23 66 68 01 01 01 A7 ED +R 00 00 01 00 +T 39 01 00 00 42 C2 03 02 00 00 +R 00 00 01 00 00 06 01 00 +T 3D 01 00 00 +R 00 00 01 00 +T 3D 01 00 00 FD 6E 20 FD 66 21 46 DD 70 EC FD +R 00 00 01 00 +T 48 01 00 00 6E 20 FD 66 21 23 46 DD 70 ED DD +R 00 00 01 00 +T 53 01 00 00 36 EE 00 FD 6E 20 FD 66 21 36 00 +R 00 00 01 00 +T 5E 01 00 00 21 0E 00 39 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 10 00 +T 66 01 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 10 00 02 09 0F 00 +T 6D 01 00 00 E0 DD 74 E1 FD 4E 20 FD 46 21 03 +R 00 00 01 00 +T 78 01 00 00 03 DD 71 EA DD 70 EB 7D B4 28 71 +R 00 00 01 00 +T 83 01 00 00 +R 00 00 01 00 +T 83 01 00 00 23 23 7E 23 66 6F 46 DD 70 E2 DD +R 00 00 01 00 +T 8E 01 00 00 6E E0 DD 66 E1 23 23 46 23 66 68 +R 00 00 01 00 +T 99 01 00 00 23 46 DD 70 E3 DD 36 E4 00 21 +R 00 00 01 00 +T A3 01 00 00 04 00 39 4D 44 DD 5E EA DD 56 EB +R 00 00 01 00 +T AE 01 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 13 00 02 0A 13 00 +T B4 01 00 00 00 00 00 00 DD 75 E8 DD 74 E9 DD +R 00 00 01 00 02 04 0F 00 +T BD 01 00 00 4E E0 DD 46 E1 03 03 69 60 4E 23 +R 00 00 01 00 +T C8 01 00 00 46 DD 5E E8 DD 56 E9 3E +R 00 00 01 00 +T D0 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0A 00 02 09 0A 00 +T D5 01 00 00 00 00 00 00 7D B4 20 19 +R 00 00 01 00 02 04 0F 00 +T DB 01 00 00 +R 00 00 01 00 +T DB 01 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 03 00 02 0A 03 00 +T E1 01 00 00 00 00 00 00 01 00 00 DD 5E E0 DD +R 00 00 01 00 02 04 0F 00 +T EA 01 00 00 56 E1 3E 00 00 00 00 21 +R 00 00 01 00 29 07 01 00 +T EF 01 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 0F 00 +T F4 01 00 00 +R 00 00 01 00 +T F4 01 00 00 +R 00 00 01 00 +T F4 01 00 00 FD E5 D1 FD 7E 1C FD 6E 1A FD 66 +R 00 00 01 00 +T FF 01 00 00 1B CD 00 00 00 00 +R 00 00 01 00 02 06 0F 00 +T 03 02 00 00 +R 00 00 01 00 +T 03 02 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 08 00 +T 08 02 00 00 +R 00 00 01 00 +T 08 02 00 00 CD 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 0E 00 2B 0A 15 00 +T 0E 02 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 15 00 02 09 0F 00 +T 14 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 05 00 02 09 05 00 +T 19 02 00 00 00 00 00 00 01 10 00 09 36 +R 00 00 01 00 02 04 0F 00 +T 20 02 00 00 0F 01 00 00 23 36 0F 01 00 00 23 +R 00 00 01 00 09 04 01 00 89 0A 01 00 +T 25 02 00 00 36 0F 01 00 00 11 12 00 00 00 3E +R 00 00 01 00 29 05 01 00 00 0A 02 00 +T 2B 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0D 00 02 09 0D 00 +T 30 02 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 0F 00 2B 09 01 00 +T 35 02 00 00 00 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 02 04 01 00 02 09 0F 00 +T 3B 02 00 00 00 00 00 00 +R 00 00 01 00 02 04 08 00 +T 00 00 00 00 +R 00 00 02 00 +T 00 00 00 00 2F 62 69 6E 2F 73 68 00 +R 00 00 02 00 +T 08 00 00 00 +R 00 00 02 00 +T 08 00 00 00 48 4F 4D 45 00 +R 00 00 02 00 +T 0D 00 00 00 +R 00 00 02 00 +T 0D 00 00 00 55 53 45 52 00 +R 00 00 02 00 +T 12 00 00 00 +R 00 00 02 00 +T 12 00 00 00 2F 77 6E 64 2F 6C 6F 67 6E 2E 73 +R 00 00 02 00 +T 1D 00 00 00 63 72 00 +R 00 00 02 00 diff --git a/src/gui/m.bat b/src/gui/m.bat new file mode 100644 index 00000000..b5bd020f --- /dev/null +++ b/src/gui/m.bat @@ -0,0 +1,27 @@ +iccz80 -S -w -mb -v1 -z9 -A -I..\..\include\ wnd +@if errorlevel 1 goto failure +del wnd.r01 +as-z80 -l -o wnd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z9 -A -I..\..\include\ login +@if errorlevel 1 goto failure +del login.r01 +as-z80 -l -o login.s01 +@if errorlevel 1 goto failure + +link-z80 -f wnd +@if errorlevel 1 goto failure +ihex2bin -l grlogin.i86 ..\..\bin\banked\grlogin +@if errorlevel 1 goto failure + +cd ..\..\bin +call appinst.bat +cd ..\src\gui + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/gui/p.bat b/src/gui/p.bat new file mode 100644 index 00000000..43e20c84 --- /dev/null +++ b/src/gui/p.bat @@ -0,0 +1,2 @@ +@echo off +set path=c:\iar\z80\bin;%path% diff --git a/src/gui/t.bat b/src/gui/t.bat new file mode 100644 index 00000000..f7e61fb0 --- /dev/null +++ b/src/gui/t.bat @@ -0,0 +1,33 @@ +iccz80 -S -w -mb -v1 -z9 -A -I..\..\include\ wnd +@if errorlevel 1 goto failure +del wnd.r01 +as-z80 -l -o wnd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z9 -A -I..\..\include\ trans +@if errorlevel 1 goto failure +del trans.r01 +as-z80 -l -o trans.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z9 -A -I..\..\include\ test +@if errorlevel 1 goto failure +del test.r01 +as-z80 -l -o test.s01 +@if errorlevel 1 goto failure + +link-z80 -f test +@if errorlevel 1 goto failure +ihex2bin -l test.i86 ..\..\bin\banked\test +@if errorlevel 1 goto failure + +cd ..\..\bin +call appinst.bat +cd ..\src\gui + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/gui/test.c b/src/gui/test.c new file mode 100644 index 00000000..2ef63cbe --- /dev/null +++ b/src/gui/test.c @@ -0,0 +1,10 @@ +#include +#include + +void main(void){ + GUIinit(); + Transaction_init(); + gui_globals()->actionhandler=Transaction_handler; + GUIgo("/wnd/0000.scr"); /* Nick added /wnd/ */ + GUIunit(); +} \ No newline at end of file diff --git a/src/gui/test.lnk b/src/gui/test.lnk new file mode 100644 index 00000000..e1e593e3 --- /dev/null +++ b/src/gui/test.lnk @@ -0,0 +1,15 @@ +-k ..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o test +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\lib\c0b.rel +wnd +trans +test diff --git a/src/gui/test.map b/src/gui/test.map new file mode 100644 index 00000000..6cb50e55 --- /dev/null +++ b/src/gui/test.map @@ -0,0 +1,248 @@ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +. .ABS. 00000000 00000000 = 0. bytes (ABS,OVR) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR + 00000000 .__.ABS. | 00000000 ?CL64180L | 00000000 ?CL64180B + 00000014 e__DEFAUL | 00000014 l__DEFAUL | 00000034 l_CONST + 000000E3 l_CSTR | 00000166 l_CDATA0 | 00000166 l_IDATA0 + 00000247 l_UDATA0 | 000003AF l_RCODE | 00001000 l_CSTACK + 00004000 s_CODE | 00008100 s_RCODE | 000084AF e_RCODE + 000084AF s_CONST | 000084E3 s_CSTR | 000084E3 e_CONST + 000085C6 e_CSTR | 000085C6 s_IDATA0 | 000085C6 s_CDATA0 + 0000872C s_UDATA0 | 0000872C e_CCSTR | 0000872C e_ECSTR + 0000872C s_CCSTR | 0000872C e_CDATA0 | 0000872C s_ECSTR + 0000872C e_IDATA0 | 00008973 e_UDATA0 | 00008973 s_CSTACK + 00009973 e_CSTACK | 0000C141 l_CODE | 00010141 e_CODE +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +_DEFAULT 00000000 00000014 = 20. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +RCODE 00008100 000003AF = 943. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008100 __init | 0000811F ?L_MUL_L0 | 000081A3 ?BANK_LEA + 000081A9 ?BANK_FAS | 000081AE ?S_MUL_L0 | 000081C4 ?C_V_SWIT + 000081D6 ?L_ADDASG | 000081EF ?ENT_PARM | 000081FB ?BANK_CAL + 00008208 ?S_S_SWIT | 0000821C ?S_V_SWIT | 00008239 ?S_SWITCH + 00008247 ?SL_MOD_L | 0000827A ?ENT_AUTO | 0000828E ?V_SWITCH + 00008298 ?SL_DIV_L | 000082C8 ?SS_CMP_L | 000082DA ?L_INC_L0 + 000082E2 ?US_MOD_L | 000082EB ?SS_DIV_L | 00008307 ?US_DIV_L + 00008315 ?SL_RSH_L | 00008323 ?L_DIVMOD | 0000837B ?BANK_LEA + 00008387 ?SS_RSH_L | 00008391 ?S_DIVMOD | 000083A7 ?S_MULASG + 000083B1 ?L_NOT_L0 | 000083C0 ?LEAVE_DI | 000083C7 ?L_FIND_S + 0000840B ?UL_DIVAS | 0000841B ?UL_MOD_L | 00008440 ?S_FIND_S + 0000845C ?UL_DIV_L | 00008484 ?L_NEG_L0 | 00008496 ?L_END_MU + 0000849F ?L_MULASG +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CONST 000084AF 00000034 = 52. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTR 000084E3 000000E3 = 227. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +IDATA0 000085C6 00000166 = 358. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 000085DE __IO_list | 000085E0 stdin | 000085F8 stdout + 00008610 stderr | 0000862A __on_exit | 0000862C __ctype +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CDATA0 000085C6 00000166 = 358. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +ECSTR 0000872C 00000000 = 0. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CCSTR 0000872C 00000000 = 0. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CODE 00004000 0000C141 = 49473. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00004640 GraphicsO | 000046CE GraphicsC | 000046E3 Move + 00004722 ClearRect | 00004765 DrawRectN | 000047AA FillRect + 000047EF FillRectN | 00004834 GrayRect | 00004879 Text + 000048A6 TouchRegi | 000048FD ClearScre | 0000493A EnableScr + 00004978 grSetFont | 000049B5 fontSearc | 000049E5 setCurren + 00004A73 loadFont | 00004B1A stringwid | 00004B93 stringhei + 00004BB0 stringhei | 00004BC3 stringhei | 00004BCC stringwid + 00004BDD stringwid | 00004BE6 stringwid | 00004BEF Component + 00004C99 Component | 00004CE6 Component | 00004D44 Component + 00004D8A Component | 00004DCE Component | 00004E06 Component + 00004FD7 Component | 00004FF6 Component | 0000505F Component + 00005112 Window_ha | 000053DF Window_pa | 0000556C Root_pain + 000055A3 Window_ad | 000055B1 Window_ne | 00005603 Button_ha + 000056BA Button_dr | 00005776 Button_pa | 0000586F Button_ad + 00005875 Button_ne | 000058C7 ToggleBut | 00005963 ToggleBut + 00005A4F ToggleBut | 00005AA1 Dialog_ha | 00005B5A Dialog_ne + 00005C49 Display_h | 00005CCA Display_p | 00005E16 Display_n + 00005E70 Label_han | 00005E76 Label_pai | 00005ED7 Label_new + 00005F30 rootWindo | 00005F4E screenbui | 00006328 root_acti + 00006660 read_stri | 00006735 gui_globa | 0000673B GUIinit + 00006862 GUIunit | 00006887 GUIgo | 0000693C Transacti + 000069B1 Transacti | 00006FD3 main | 00007011 sprintf + 00007055 fflush | 00007268 _write | 00007287 lseek + 000072B4 __stdio_c | 0000731F __stdio_i | 0000735D close + 00007372 strlen | 000073A9 ioctl | 000073D4 isatty + 0000740F fstat | 00007426 free | 00007506 strcpy + 0000752D atoi | 000076C3 vfprintf | 00007C1E ltoa + 00007C81 atol | 00007C97 __longtoa | 00007E2B itoa + 00007E94 open | 00014000 malloc | 0001422C exit + 0001425C _read | 0001427B unix | 00014295 memcpy + 00014363 on_exit | 000143DC atexit | 000143EF strcat + 0001440F unix_long | 00014429 _exit | 0001443E fputc + 00014550 ultoa | 000145A5 strtol | 0001464D sbrk + 000146E8 strtoul | 0001483F toupper | 00014864 tolower +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +UDATA0 0000872C 00000247 = 583. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 0000872C _argc | 0000872E _argv | 00008730 environ + 00008732 errno | 00008734 __cleanup | 00008737 global + 00008739 trans | 0000893B __malloc_ | 0000893F __malloc_ + 00008941 __on_exit +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTACK 00008973 00001000 = 4096. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + +Files Linked [ module(s) ] + +..\..\lib\c0b.rel [ _c0b ] +wnd [ wnd ] +trans [ trans ] +test [ test ] + + +Libraries Linked [ object file ] + +..\..\lib\libcb.lib [ relcb\sprintf.rel ] +..\..\lib\libiar.lib [ reliar\LMUL.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libiar.lib [ reliar\SMUL.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] +..\..\lib\libsysb.lib [ relsysb\ioctl.rel ] +..\..\lib\libiar.lib [ reliar\LADDASG.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\SSSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SVSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SSWITCHEND.rel ] +..\..\lib\libiar.lib [ reliar\SLMOD.rel ] +..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] +..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] +..\..\lib\libiar.lib [ reliar\SLDIV.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] +..\..\lib\libcb.lib [ relcb\atol.rel ] +..\..\lib\libiar.lib [ reliar\SSCMP.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] +..\..\lib\libiar.lib [ reliar\LINC.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] +..\..\lib\libiar.lib [ reliar\USMOD.rel ] +..\..\lib\libiar.lib [ reliar\SSDIV.rel ] +..\..\lib\libiar.lib [ reliar\USDIV.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] +..\..\lib\libiar.lib [ reliar\SLRSH.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] +..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] +..\..\lib\libiar.lib [ reliar\SSRSH.rel ] +..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] +..\..\lib\libiar.lib [ reliar\SMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LNOT.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] +..\..\lib\libiar.lib [ reliar\LFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] +..\..\lib\libiar.lib [ reliar\ULMOD.rel ] +..\..\lib\libiar.lib [ reliar\SFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIV.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] +..\..\lib\libiar.lib [ reliar\LNEG.rel ] +..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] +..\..\lib\libiar.lib [ reliar\LMULASG.rel ] + + +User Base Address Definitions + +l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/gui/test.rel b/src/gui/test.rel new file mode 100644 index 00000000..3862ba0b --- /dev/null +++ b/src/gui/test.rel @@ -0,0 +1,47 @@ +XL4 +H 3 areas B global symbols +M test +S GUIunit Ref00000000 +S ?BANK_FAST_LEAVE_L08 Ref00000000 +S gui_globals Ref00000000 +S GUIgo Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S Transaction_handler Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S Transaction_init Ref00000000 +S GUIinit Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 3E flags 0 +S main Def00000000 +A CSTR size E flags 0 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 C5 D5 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 08 00 +T 05 00 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 08 00 02 09 04 00 +T 0B 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 10 00 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 04 00 2B 09 02 00 +T 15 00 00 00 00 00 00 00 CD 00 00 00 00 01 +R 00 00 01 00 02 04 02 00 02 09 04 00 +T 1B 00 00 00 10 00 09 36 00 00 00 00 23 36 +R 00 00 01 00 0B 08 05 00 +T 22 00 00 00 00 00 00 00 23 36 00 00 00 00 11 +R 00 00 01 00 8B 04 05 00 2B 0A 05 00 +T 27 00 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 03 00 +T 2C 00 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 03 00 02 09 04 00 +T 32 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 00 00 02 09 00 00 +T 37 00 00 00 00 00 00 00 D1 C1 C3 00 00 00 00 +R 00 00 01 00 02 04 04 00 02 0B 01 00 +T 00 00 00 00 +R 00 00 02 00 +T 00 00 00 00 2F 77 6E 64 2F 30 30 30 30 2E 73 +R 00 00 02 00 +T 0B 00 00 00 63 72 00 +R 00 00 02 00 diff --git a/src/gui/trans.c b/src/gui/trans.c new file mode 100644 index 00000000..c41491a0 --- /dev/null +++ b/src/gui/trans.c @@ -0,0 +1,124 @@ +#include +#include +#include "..\libc\malloc-l.h" +#undef NULL +#define NULL 0 + +/************************************************ + * Transactions * + ************************************************/ + +struct Global_Trans* trans; + +void Transaction_init(){ + trans=(struct Global_Trans*) malloc(sizeof(struct Global_Trans)); + trans->first=(struct Transaction*) malloc(sizeof(struct Transaction)); + trans->first->next=NULL; + trans->first->barcode[0]=0; + trans->first->stuks=0; + trans->first->prijs=0; +} + +void Transaction_handler(struct Component* this){ + struct ActionXDS *act; + + act=(struct ActionXDS*) (this->xds); + + if(trans==NULL){ + Transaction_init(); + } + + if(act->action==0x1000) /* Transaction module init*/ + { + trans->barcode=act->lParam & 0xff; + trans->stuks=(act->lParam>>8) & 0xff; + trans->prijs=(act->lParam>>16) & 0xff; + Component_setlabel(Component_find(this,trans->barcode),"Barcode"); + Component_setlabel(Component_find(this,trans->stuks),"Stuks"); + Component_setlabel(Component_find(this,trans->prijs),"Prijs"); + } + + if(act->action>=0x1010 && act->action<=0x1012){ + struct Component* display; + struct Transaction* tr=trans->first; + while(tr->next!=NULL) + tr=tr->next; + display=Component_find(this->parent,act->wParam); + Component_setlabel(this, display->label); + Component_setlabel(display,""); + display->paint(display); + switch(act->action){ + case 0x1010: + strcpy(tr->barcode,this->label); + break; + case 0x1011: + tr->stuks=atoi(this->label); + break; + case 0x1012: + tr->prijs=atol(this->label); + break; + } + this->paint(this); + } + + if(act->action==0x101e){ + int prn,i; + struct sgttyb temp; + struct Transaction* tr; + long totaal=0; + char s[80]; + + tr=trans->first; + + prn=open("/dev/printer",O_WRONLY); + gtty(prn,&temp); + temp.sg_flags=RAW | UNBUFF; + stty(prn,&temp); + while(tr!=NULL){ + if(tr->stuks!=0){ + if(tr->stuks==1) + sprintf(s,"%13s Verkoopartikel \x7c%7ld,%02ld\r\n",tr->barcode,tr->prijs/100,tr->prijs%100); + else + sprintf(s,"%13s Verkoopartikel\r\n%4dx @ \x7c %7ld,%02ld \x7c%7ld,%02ld\r\n",tr->barcode,tr->stuks,tr->prijs/100,tr->prijs%100,(tr->stuks*tr->prijs)/100,(tr->stuks*tr->prijs)%100); + totaal+=tr->stuks*tr->prijs; + write(prn,s,strlen(s)); + } + tr=tr->next; + } + sprintf(s,"\r\n%13sTotaal:%10s\x7c%7ld,%02ld\r\n\r\n\r\n","","",totaal/100,totaal%100); + write(prn,s,strlen(s)); + close(prn); + tr=trans->first; + while(tr!=NULL){ + free(tr); + tr=tr->next; + } + trans->first=(struct Transaction*) malloc(sizeof(struct Transaction)); + trans->first->next=NULL; + trans->first->barcode[0]=0; + trans->first->stuks=0; + trans->first->prijs=0; + + } + + if(act->action==0x101f){ + struct Transaction* tr=trans->first; + while(tr->next!=NULL) + tr=tr->next; + trans->barcode=act->lParam & 0xff; + trans->stuks=(act->lParam>>8) & 0xff; + trans->prijs=(act->lParam>>16) & 0xff; + Component_setlabel(Component_find(this->parent,trans->barcode),"Barcode"); + Component_setlabel(Component_find(this->parent,trans->stuks),"Stuks"); + Component_setlabel(Component_find(this->parent,trans->prijs),"Prijs"); + this->parent->paint(this->parent); + tr->next=(struct Transaction*) malloc(sizeof(struct Transaction)); + tr=tr->next; + tr->next=NULL; + tr->barcode[0]=0; + tr->stuks=0; + tr->prijs=0; + } + +} + diff --git a/src/gui/trans.h b/src/gui/trans.h new file mode 100644 index 00000000..b4833438 --- /dev/null +++ b/src/gui/trans.h @@ -0,0 +1,16 @@ +#include +struct Transaction{ + char barcode[14]; + int stuks; + long prijs; + struct Transaction* next; +}; + +struct Global_Trans{ + int barcode,stuks,prijs; + struct Transaction* first; +}; + +void Transaction_init(); +void Transaction_handler(struct Component* this); + diff --git a/src/gui/trans.rel b/src/gui/trans.rel new file mode 100644 index 00000000..0fc49de1 --- /dev/null +++ b/src/gui/trans.rel @@ -0,0 +1,638 @@ +XL4 +H 4 areas 1D global symbols +M trans +S ?L_MUL_L03 Ref00000000 +S sprintf Ref00000000 +S ?BANK_FAST_LEAVE_L08 Ref00000000 +S _write Ref00000000 +S Component_find Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S close Ref00000000 +S strlen Ref00000000 +S ioctl Ref00000000 +S ?L_ADDASG_L03 Ref00000000 +S free Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S strcpy Ref00000000 +S ?S_S_SWITCH_L06 Ref00000000 +S ?SL_MOD_L03 Ref00000000 +S ?ENT_AUTO_DIRECT_L09 Ref00000000 +S atoi Ref00000000 +S ?SL_DIV_L03 Ref00000000 +S atol Ref00000000 +S ?SS_CMP_L02 Ref00000000 +S open Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S ?SL_RSH_L03 Ref00000000 +S malloc Ref00000000 +S Component_setlabel Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 697 flags 0 +S Transaction_handler Def00000075 +S Transaction_init Def00000000 +A CSTR size A8 flags 0 +A UDATA0 size 2 flags 0 +S trans Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 C5 D5 11 08 00 CD 6D 00 00 00 22 +R 00 00 01 00 00 0A 01 00 +T 09 00 00 00 00 00 00 00 01 06 00 09 E5 CD +R 00 00 01 00 00 04 03 00 +T 11 00 00 00 6A 00 00 00 4D 44 E1 71 23 70 21 +R 00 00 01 00 00 04 01 00 +T 1A 00 00 00 06 00 ED 4B 00 00 00 00 09 56 23 +R 00 00 01 00 00 08 03 00 +T 23 00 00 00 66 6A 11 14 00 19 AF 77 23 77 21 +R 00 00 01 00 +T 2E 00 00 00 06 00 ED 4B 00 00 00 00 09 7E 23 +R 00 00 01 00 00 08 03 00 +T 37 00 00 00 66 6F 72 21 06 00 ED 4B +R 00 00 01 00 +T 3F 00 00 00 00 00 00 00 09 56 23 66 6A 11 +R 00 00 01 00 00 04 03 00 +T 47 00 00 00 0E 00 19 AF 77 23 77 21 06 00 ED +R 00 00 01 00 +T 52 00 00 00 4B 00 00 00 00 09 46 23 66 68 01 +R 00 00 01 00 00 05 03 00 +T 5B 00 00 00 10 00 09 77 23 77 23 77 23 77 D1 +R 00 00 01 00 +T 66 00 00 00 C1 C3 00 00 00 00 +R 00 00 01 00 02 06 02 00 +T 6A 00 00 00 +R 00 00 01 00 +T 6A 00 00 00 11 16 00 +R 00 00 01 00 +T 6D 00 00 00 +R 00 00 01 00 +T 6D 00 00 00 3E 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 05 17 00 02 0A 17 00 +T 73 00 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 75 00 00 00 +R 00 00 01 00 +T 75 00 00 00 CD 00 00 00 00 9E FF FD E5 21 +R 00 00 01 00 02 05 0F 00 +T 7D 00 00 00 26 00 DD 4E 02 DD 46 03 09 46 DD +R 00 00 01 00 +T 88 00 00 00 70 9E 23 66 DD 74 9F 2A +R 00 00 01 00 +T 90 00 00 00 00 00 00 00 7D B4 20 08 +R 00 00 01 00 00 04 03 00 +T 96 00 00 00 +R 00 00 01 00 +T 96 00 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 9C 00 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 9E 00 00 00 +R 00 00 01 00 +T 9E 00 00 00 68 DD 66 9F 23 23 23 3E 10 23 AE +R 00 00 01 00 +T A9 00 00 00 2B B6 20 64 +R 00 00 01 00 +T AD 00 00 00 +R 00 00 01 00 +T AD 00 00 00 21 07 00 48 DD 46 9F 09 6E 67 E5 +R 00 00 01 00 +T B8 00 00 00 2A 00 00 00 00 C1 71 23 70 2A +R 00 00 01 00 00 05 03 00 +T C0 00 00 00 00 00 00 00 23 23 E5 CD +R 00 00 01 00 00 04 03 00 +T C6 00 00 00 D7 05 00 00 E1 71 23 70 21 04 00 +R 00 00 01 00 00 04 01 00 +T CF 00 00 00 ED 4B 00 00 00 00 09 E5 21 07 00 +R 00 00 01 00 00 06 03 00 +T D8 00 00 00 DD 5E 9E DD 56 9F 19 5E 23 56 23 +R 00 00 01 00 +T E3 00 00 00 4E 23 46 EB 3E 10 CD EB 05 00 00 +R 00 00 01 00 00 0B 01 00 +T EC 00 00 00 E1 71 23 70 2A 00 00 00 00 4E 23 +R 00 00 01 00 00 09 03 00 +T F5 00 00 00 46 DD 5E 02 DD 56 03 CD +R 00 00 01 00 +T FD 00 00 00 12 06 00 00 DD 5E 02 DD 56 03 CD +R 00 00 01 00 00 04 01 00 +T 06 01 00 00 F2 05 00 00 DD 5E 02 DD 56 03 CD +R 00 00 01 00 00 04 01 00 +T 0F 01 00 00 2F 06 00 00 +R 00 00 01 00 00 04 01 00 +T 11 01 00 00 +R 00 00 01 00 +T 11 01 00 00 DD 6E 9E DD 66 9F 23 23 23 46 23 +R 00 00 01 00 +T 1C 01 00 00 66 68 01 10 90 3E 80 AC 67 ED 42 +R 00 00 01 00 +T 27 01 00 00 DA 56 02 00 00 DD 6E 9E DD 66 9F +R 00 00 01 00 00 05 01 00 +T 30 01 00 00 23 23 23 4E 23 46 21 12 10 CD +R 00 00 01 00 +T 3A 01 00 00 00 00 00 00 DA 56 02 00 00 +R 00 00 01 00 02 04 13 00 00 09 01 00 +T 3F 01 00 00 +R 00 00 01 00 +T 3F 01 00 00 +R 00 00 01 00 +T 3F 01 00 00 +R 00 00 01 00 +T 3F 01 00 00 21 06 00 ED 4B 00 00 00 00 09 46 +R 00 00 01 00 00 09 03 00 +T 48 01 00 00 23 66 68 +R 00 00 01 00 +T 4B 01 00 00 +R 00 00 01 00 +T 4B 01 00 00 DD 75 A2 DD 74 A3 +R 00 00 01 00 +T 51 01 00 00 +R 00 00 01 00 +T 51 01 00 00 21 14 00 DD 4E A2 DD 46 A3 09 7E +R 00 00 01 00 +T 5C 01 00 00 23 B6 28 0A +R 00 00 01 00 +T 60 01 00 00 +R 00 00 01 00 +T 60 01 00 00 21 14 00 09 56 23 66 6A 18 E1 +R 00 00 01 00 +T 6A 01 00 00 +R 00 00 01 00 +T 6A 01 00 00 21 05 00 DD 4E 9E DD 46 9F 09 4E +R 00 00 01 00 +T 75 01 00 00 23 46 21 11 00 DD 5E 02 DD 56 03 +R 00 00 01 00 +T 80 01 00 00 19 5E 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 04 00 +T 87 01 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 04 00 02 09 0B 00 +T 8E 01 00 00 A0 DD 74 A1 01 20 00 09 4E 23 46 +R 00 00 01 00 +T 99 01 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 +R 00 00 01 00 2B 0B 18 00 +T A1 01 00 00 21 00 00 00 00 CD 00 00 00 00 01 +R 00 00 01 00 02 05 18 00 02 0A 0B 00 +T A8 01 00 00 14 00 00 00 DD 5E A0 DD 56 A1 3E +R 00 00 01 00 00 04 02 00 +T B1 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 18 00 02 09 18 00 +T B6 01 00 00 00 00 00 00 DD 5E A0 4B DD 56 A1 +R 00 00 01 00 02 04 0B 00 +T BF 01 00 00 CD 43 06 00 00 DD 6E 9E DD 66 9F +R 00 00 01 00 00 05 01 00 +T C8 01 00 00 23 23 23 5E 23 56 CD 00 00 00 00 +R 00 00 01 00 02 0B 0D 00 +T D1 01 00 00 10 10 03 00 4C 02 00 00 +R 00 00 01 00 00 08 01 00 +T D7 01 00 00 DD 01 00 00 FA 01 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T DB 01 00 00 1F 02 00 00 +R 00 00 01 00 00 04 01 00 +T DD 01 00 00 +R 00 00 01 00 +T DD 01 00 00 21 20 00 DD 4E 02 DD 46 03 09 4E +R 00 00 01 00 +T E8 01 00 00 23 46 DD 5E A2 DD 56 A3 3E +R 00 00 01 00 +T F1 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0C 00 02 09 0C 00 +T F6 01 00 00 00 00 00 00 18 52 +R 00 00 01 00 02 04 0B 00 +T FA 01 00 00 +R 00 00 01 00 +T FA 01 00 00 21 0E 00 DD 4E A2 DD 46 A3 09 E5 +R 00 00 01 00 +T 05 02 00 00 21 20 00 DD 4E 02 DD 46 03 09 5E +R 00 00 01 00 +T 10 02 00 00 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 10 00 +T 15 02 00 00 00 00 00 00 CD 00 00 00 00 4D 44 +R 00 00 01 00 02 04 10 00 02 09 0B 00 +T 1C 02 00 00 E1 18 2A +R 00 00 01 00 +T 1F 02 00 00 +R 00 00 01 00 +T 1F 02 00 00 21 20 00 DD 4E 02 DD 46 03 09 5E +R 00 00 01 00 +T 2A 02 00 00 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 12 00 +T 2F 02 00 00 00 00 00 00 CD 00 00 00 00 7C 07 +R 00 00 01 00 02 04 12 00 02 09 0B 00 +T 36 02 00 00 9F 4F 41 E5 21 10 00 DD 5E A2 DD +R 00 00 01 00 +T 41 02 00 00 56 A3 19 D1 73 23 72 23 +R 00 00 01 00 +T 49 02 00 00 +R 00 00 01 00 +T 49 02 00 00 71 23 70 +R 00 00 01 00 +T 4C 02 00 00 +R 00 00 01 00 +T 4C 02 00 00 DD 5E 02 4B DD 56 03 CD +R 00 00 01 00 +T 54 02 00 00 43 06 00 00 +R 00 00 01 00 00 04 01 00 +T 56 02 00 00 +R 00 00 01 00 +T 56 02 00 00 DD 6E 9E DD 66 9F 23 23 23 46 23 +R 00 00 01 00 +T 61 02 00 00 66 68 01 1E 10 A7 ED 42 C2 +R 00 00 01 00 +T 6A 02 00 00 B3 04 00 00 +R 00 00 01 00 00 04 01 00 +T 6C 02 00 00 +R 00 00 01 00 +T 6C 02 00 00 AF DD 77 AC DD 77 AD DD 77 AE DD +R 00 00 01 00 +T 77 02 00 00 77 AF 21 06 00 ED 4B 00 00 00 00 +R 00 00 01 00 00 0B 03 00 +T 80 02 00 00 09 46 23 66 68 E5 FD E1 21 01 00 +R 00 00 01 00 +T 8B 02 00 00 E5 21 15 00 00 00 E5 3E +R 00 00 01 00 00 06 02 00 +T 91 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 14 00 02 09 14 00 +T 96 02 00 00 00 00 00 00 F1 F1 DD 75 A0 DD 74 +R 00 00 01 00 02 04 0B 00 +T 9F 02 00 00 A1 21 08 00 39 E5 21 00 00 E5 DD +R 00 00 01 00 +T AA 02 00 00 6E A0 DD 66 A1 E5 3E 00 00 00 00 +R 00 00 01 00 2B 0B 08 00 +T B2 02 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 0B 00 +T B9 02 00 00 F1 F1 DD 36 A8 60 DD 36 A9 00 21 +R 00 00 01 00 +T C4 02 00 00 08 00 39 E5 21 01 00 E5 DD 6E A0 +R 00 00 01 00 +T CF 02 00 00 DD 66 A1 E5 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 08 00 +T D6 02 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 0B 00 +T DD 02 00 00 F1 +R 00 00 01 00 +T DE 02 00 00 +R 00 00 01 00 +T DE 02 00 00 FD E5 E1 7D B4 CA C8 03 00 00 +R 00 00 01 00 00 0A 01 00 +T E6 02 00 00 +R 00 00 01 00 +T E6 02 00 00 FD 7E 0E FD B6 0F CA BC 03 00 00 +R 00 00 01 00 00 0B 01 00 +T EF 02 00 00 +R 00 00 01 00 +T EF 02 00 00 3E 01 FD AE 0E FD B6 0F 20 29 +R 00 00 01 00 +T F9 02 00 00 +R 00 00 01 00 +T F9 02 00 00 6F 67 E5 2E 64 E5 CD 5A 06 00 00 +R 00 00 01 00 00 0B 01 00 +T 02 03 00 00 C5 E5 6F 67 E5 2E 64 E5 CD +R 00 00 01 00 +T 0B 03 00 00 69 06 00 00 C5 E5 FD E5 21 +R 00 00 01 00 00 04 01 00 +T 12 03 00 00 22 00 00 00 E5 21 20 00 39 E5 CD +R 00 00 01 00 00 04 02 00 +T 1B 03 00 00 52 06 00 00 21 0E 00 18 68 +R 00 00 01 00 00 04 01 00 +T 22 03 00 00 +R 00 00 01 00 +T 22 03 00 00 21 00 00 E5 2E 64 E5 FD 6E 0E FD +R 00 00 01 00 +T 2D 03 00 00 66 0F 7C 07 9F 4F 41 C5 E5 CD +R 00 00 01 00 +T 37 03 00 00 78 06 00 00 CD 00 00 00 00 C5 E5 +R 00 00 01 00 00 04 01 00 02 09 0E 00 +T 3E 03 00 00 21 00 00 E5 2E 64 E5 FD 6E 0E FD +R 00 00 01 00 +T 49 03 00 00 66 0F 7C 07 9F 4F 41 C5 E5 CD +R 00 00 01 00 +T 53 03 00 00 78 06 00 00 CD 00 00 00 00 C5 E5 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T 5A 03 00 00 21 00 00 E5 2E 64 E5 CD +R 00 00 01 00 +T 62 03 00 00 5A 06 00 00 C5 E5 21 00 00 E5 2E +R 00 00 01 00 00 04 01 00 +T 6B 03 00 00 64 E5 CD 69 06 00 00 C5 E5 FD 6E +R 00 00 01 00 00 07 01 00 +T 74 03 00 00 0E FD 66 0F E5 FD E5 21 +R 00 00 01 00 +T 7C 03 00 00 45 00 00 00 E5 21 2A 00 39 E5 CD +R 00 00 01 00 00 04 02 00 +T 85 03 00 00 52 06 00 00 21 18 00 +R 00 00 01 00 00 04 01 00 +T 8A 03 00 00 +R 00 00 01 00 +T 8A 03 00 00 39 F9 +R 00 00 01 00 +T 8C 03 00 00 +R 00 00 01 00 +T 8C 03 00 00 21 10 00 39 E5 FD 5E 0E FD 56 0F +R 00 00 01 00 +T 97 03 00 00 7A 07 9F 4F 41 C5 D5 CD +R 00 00 01 00 +T 9F 03 00 00 78 06 00 00 EB E1 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 0B 09 00 +T A6 03 00 00 21 14 00 39 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 07 00 +T AE 03 00 00 00 00 00 00 CD 00 00 00 00 E5 21 +R 00 00 01 00 02 04 07 00 02 09 0B 00 +T B5 03 00 00 16 00 39 CD 87 06 00 00 F1 +R 00 00 01 00 00 08 01 00 +T BC 03 00 00 +R 00 00 01 00 +T BC 03 00 00 FD 6E 14 FD 66 15 E5 FD E1 C3 +R 00 00 01 00 +T C6 03 00 00 DE 02 00 00 +R 00 00 01 00 00 04 01 00 +T C8 03 00 00 +R 00 00 01 00 +T C8 03 00 00 6F 67 E5 2E 64 E5 DD 4E AE DD 46 +R 00 00 01 00 +T D3 03 00 00 AF DD 6E AC DD 66 AD CD +R 00 00 01 00 +T DB 03 00 00 00 00 00 00 C5 E5 6F 67 E5 2E 64 +R 00 00 01 00 02 04 0E 00 +T E4 03 00 00 E5 DD 4E AE DD 46 AF DD 6E AC DD +R 00 00 01 00 +T EF 03 00 00 66 AD CD 00 00 00 00 C5 E5 21 +R 00 00 01 00 02 07 11 00 +T F7 03 00 00 14 00 00 00 E5 E5 21 85 00 00 00 +R 00 00 01 00 00 04 02 00 00 0B 02 00 +T FE 03 00 00 E5 21 22 00 39 E5 CD 52 06 00 00 +R 00 00 01 00 00 0B 01 00 +T 07 04 00 00 21 10 00 39 F9 21 14 00 39 EB 3E +R 00 00 01 00 +T 12 04 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 17 04 00 00 00 00 00 00 E5 21 16 00 39 CD +R 00 00 01 00 02 04 0B 00 +T 1F 04 00 00 87 06 00 00 F1 DD 5E A0 DD 56 A1 +R 00 00 01 00 00 04 01 00 +T 28 04 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 06 00 02 0A 06 00 +T 2E 04 00 00 00 00 00 00 21 06 00 ED 4B +R 00 00 01 00 02 04 0B 00 +T 35 04 00 00 00 00 00 00 09 46 23 66 68 +R 00 00 01 00 00 04 03 00 +T 3C 04 00 00 +R 00 00 01 00 +T 3C 04 00 00 E5 FD E1 +R 00 00 01 00 +T 3F 04 00 00 +R 00 00 01 00 +T 3F 04 00 00 7D B4 28 13 +R 00 00 01 00 +T 43 04 00 00 +R 00 00 01 00 +T 43 04 00 00 FD E5 D1 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 0A 00 +T 49 04 00 00 00 00 00 00 CD 00 00 00 00 FD 6E +R 00 00 01 00 02 04 0A 00 02 09 0B 00 +T 50 04 00 00 14 FD 66 15 18 E6 +R 00 00 01 00 +T 56 04 00 00 +R 00 00 01 00 +T 56 04 00 00 21 06 00 ED 4B 00 00 00 00 09 E5 +R 00 00 01 00 00 09 03 00 +T 5F 04 00 00 CD 6A 00 00 00 EB E1 73 23 72 21 +R 00 00 01 00 00 05 01 00 +T 68 04 00 00 06 00 ED 4B 00 00 00 00 09 56 23 +R 00 00 01 00 00 08 03 00 +T 71 04 00 00 66 6A 11 14 00 19 AF 77 23 77 21 +R 00 00 01 00 +T 7C 04 00 00 06 00 ED 4B 00 00 00 00 09 7E 23 +R 00 00 01 00 00 08 03 00 +T 85 04 00 00 66 6F 72 21 06 00 ED 4B +R 00 00 01 00 +T 8D 04 00 00 00 00 00 00 09 56 23 66 6A 11 +R 00 00 01 00 00 04 03 00 +T 95 04 00 00 0E 00 19 AF 77 23 77 21 06 00 ED +R 00 00 01 00 +T A0 04 00 00 4B 00 00 00 00 09 46 23 66 68 01 +R 00 00 01 00 00 05 03 00 +T A9 04 00 00 10 00 09 77 23 77 23 77 23 77 +R 00 00 01 00 +T B3 04 00 00 +R 00 00 01 00 +T B3 04 00 00 DD 6E 9E DD 66 9F 23 23 23 46 23 +R 00 00 01 00 +T BE 04 00 00 66 68 01 1F 10 A7 ED 42 C2 +R 00 00 01 00 +T C7 04 00 00 D2 05 00 00 +R 00 00 01 00 00 04 01 00 +T C9 04 00 00 +R 00 00 01 00 +T C9 04 00 00 21 06 00 ED 4B 00 00 00 00 09 46 +R 00 00 01 00 00 09 03 00 +T D2 04 00 00 23 66 68 +R 00 00 01 00 +T D5 04 00 00 +R 00 00 01 00 +T D5 04 00 00 DD 75 A0 DD 74 A1 +R 00 00 01 00 +T DB 04 00 00 +R 00 00 01 00 +T DB 04 00 00 21 14 00 DD 4E A0 DD 46 A1 09 7E +R 00 00 01 00 +T E6 04 00 00 23 B6 28 0A +R 00 00 01 00 +T EA 04 00 00 +R 00 00 01 00 +T EA 04 00 00 21 14 00 09 56 23 66 6A 18 E1 +R 00 00 01 00 +T F4 04 00 00 +R 00 00 01 00 +T F4 04 00 00 21 07 00 DD 4E 9E DD 46 9F 09 6E +R 00 00 01 00 +T FF 04 00 00 67 E5 2A 00 00 00 00 C1 71 23 70 +R 00 00 01 00 00 07 03 00 +T 08 05 00 00 2A 00 00 00 00 23 23 E5 CD +R 00 00 01 00 00 05 03 00 +T 0F 05 00 00 D7 05 00 00 E1 71 23 70 21 04 00 +R 00 00 01 00 00 04 01 00 +T 18 05 00 00 ED 4B 00 00 00 00 09 E5 21 07 00 +R 00 00 01 00 00 06 03 00 +T 21 05 00 00 DD 5E 9E DD 56 9F 19 5E 23 56 23 +R 00 00 01 00 +T 2C 05 00 00 4E 23 46 EB 3E 10 CD EB 05 00 00 +R 00 00 01 00 00 0B 01 00 +T 35 05 00 00 E1 71 23 70 2A 00 00 00 00 4E 23 +R 00 00 01 00 00 09 03 00 +T 3E 05 00 00 46 21 11 00 DD 5E 02 DD 56 03 19 +R 00 00 01 00 +T 49 05 00 00 5E 23 56 CD 12 06 00 00 21 11 00 +R 00 00 01 00 00 08 01 00 +T 52 05 00 00 DD 5E 02 DD 56 03 19 5E 23 56 CD +R 00 00 01 00 +T 5D 05 00 00 F2 05 00 00 21 11 00 DD 5E 02 DD +R 00 00 01 00 00 04 01 00 +T 66 05 00 00 56 03 19 5E 23 56 CD 2F 06 00 00 +R 00 00 01 00 00 0B 01 00 +T 6F 05 00 00 21 11 00 DD 4E 02 DD 46 03 09 5E +R 00 00 01 00 +T 7A 05 00 00 23 56 21 11 00 09 46 23 66 68 01 +R 00 00 01 00 +T 85 05 00 00 1A 00 CD 47 06 00 00 21 14 00 DD +R 00 00 01 00 00 07 01 00 +T 8E 05 00 00 4E A0 DD 46 A1 09 E5 CD +R 00 00 01 00 +T 96 05 00 00 6A 00 00 00 EB E1 73 23 72 21 +R 00 00 01 00 00 04 01 00 +T 9E 05 00 00 14 00 09 56 23 66 6A DD 75 A0 DD +R 00 00 01 00 +T A9 05 00 00 74 A1 01 14 00 09 AF 77 23 77 DD +R 00 00 01 00 +T B4 05 00 00 6E A0 DD 66 A1 70 21 0E 00 DD 4E +R 00 00 01 00 +T BF 05 00 00 A0 DD 46 A1 09 77 23 77 21 10 00 +R 00 00 01 00 +T CA 05 00 00 09 77 23 77 23 77 23 77 +R 00 00 01 00 +T D2 05 00 00 +R 00 00 01 00 +T D2 05 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 05 00 +T D7 05 00 00 +R 00 00 01 00 +T D7 05 00 00 21 07 00 DD 4E 9E DD 46 9F 09 5E +R 00 00 01 00 +T E2 05 00 00 23 56 23 4E 23 46 EB 3E 08 +R 00 00 01 00 +T EB 05 00 00 +R 00 00 01 00 +T EB 05 00 00 CD 00 00 00 00 06 00 4D C9 +R 00 00 01 00 02 05 16 00 +T F2 05 00 00 +R 00 00 01 00 +T F2 05 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 04 00 02 0A 04 00 +T F8 05 00 00 00 00 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 02 04 0B 00 2B 0A 18 00 +T FE 05 00 00 00 00 00 00 01 08 00 00 00 CD +R 00 00 01 00 02 04 18 00 00 09 02 00 +T 04 06 00 00 00 00 00 00 21 04 00 ED 5B +R 00 00 01 00 02 04 0B 00 +T 0B 06 00 00 00 00 00 00 19 4E 23 46 C9 +R 00 00 01 00 00 04 03 00 +T 12 06 00 00 +R 00 00 01 00 +T 12 06 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 04 00 02 0A 04 00 +T 18 06 00 00 00 00 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 02 04 0B 00 2B 0A 18 00 +T 1E 06 00 00 00 00 00 00 01 00 00 00 00 CD +R 00 00 01 00 02 04 18 00 00 09 02 00 +T 24 06 00 00 00 00 00 00 2A 00 00 00 00 23 23 +R 00 00 01 00 02 04 0B 00 00 09 03 00 +T 2B 06 00 00 4E 23 46 C9 +R 00 00 01 00 +T 2F 06 00 00 +R 00 00 01 00 +T 2F 06 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 04 00 02 0A 04 00 +T 35 06 00 00 00 00 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 02 04 0B 00 2B 0A 18 00 +T 3B 06 00 00 00 00 00 00 01 0E 00 00 00 C3 +R 00 00 01 00 02 04 18 00 00 09 02 00 +T 41 06 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 43 06 00 00 +R 00 00 01 00 +T 43 06 00 00 42 21 1A 00 +R 00 00 01 00 +T 47 06 00 00 +R 00 00 01 00 +T 47 06 00 00 09 4E 23 46 23 7E 69 60 C3 +R 00 00 01 00 +T 50 06 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 52 06 00 00 +R 00 00 01 00 +T 52 06 00 00 3E 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 05 01 00 02 0A 01 00 +T 58 06 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 5A 06 00 00 +R 00 00 01 00 +T 5A 06 00 00 FD 4E 12 FD 46 13 FD 6E 10 FD 66 +R 00 00 01 00 +T 65 06 00 00 11 C3 00 00 00 00 +R 00 00 01 00 02 06 0E 00 +T 69 06 00 00 +R 00 00 01 00 +T 69 06 00 00 FD 4E 12 FD 46 13 FD 6E 10 FD 66 +R 00 00 01 00 +T 74 06 00 00 11 C3 00 00 00 00 +R 00 00 01 00 02 06 11 00 +T 78 06 00 00 +R 00 00 01 00 +T 78 06 00 00 FD 4E 12 FD 46 13 FD 6E 10 FD 66 +R 00 00 01 00 +T 83 06 00 00 11 C3 00 00 00 00 +R 00 00 01 00 02 06 00 00 +T 87 06 00 00 +R 00 00 01 00 +T 87 06 00 00 4D 44 DD 5E A0 DD 56 A1 3E +R 00 00 01 00 +T 90 06 00 00 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 04 03 00 02 09 03 00 +T 95 06 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 00 00 00 00 +R 00 00 02 00 +T 00 00 00 00 42 61 72 63 6F 64 65 00 +R 00 00 02 00 +T 08 00 00 00 +R 00 00 02 00 +T 08 00 00 00 53 74 75 6B 73 00 +R 00 00 02 00 +T 0E 00 00 00 +R 00 00 02 00 +T 0E 00 00 00 50 72 69 6A 73 00 +R 00 00 02 00 +T 14 00 00 00 +R 00 00 02 00 +T 14 00 00 00 00 +R 00 00 02 00 +T 15 00 00 00 +R 00 00 02 00 +T 15 00 00 00 2F 64 65 76 2F 70 72 69 6E 74 65 +R 00 00 02 00 +T 20 00 00 00 72 00 +R 00 00 02 00 +T 22 00 00 00 +R 00 00 02 00 +T 22 00 00 00 25 31 33 73 20 56 65 72 6B 6F 6F +R 00 00 02 00 +T 2D 00 00 00 70 61 72 74 69 6B 65 6C 20 20 7C +R 00 00 02 00 +T 38 00 00 00 25 37 6C 64 2C 25 30 32 6C 64 0D +R 00 00 02 00 +T 43 00 00 00 0A 00 +R 00 00 02 00 +T 45 00 00 00 +R 00 00 02 00 +T 45 00 00 00 25 31 33 73 20 56 65 72 6B 6F 6F +R 00 00 02 00 +T 50 00 00 00 70 61 72 74 69 6B 65 6C 0D 0A 25 +R 00 00 02 00 +T 5B 00 00 00 34 64 78 20 40 20 7C 20 25 37 6C +R 00 00 02 00 +T 66 00 00 00 64 2C 25 30 32 6C 64 20 20 20 20 +R 00 00 02 00 +T 71 00 00 00 20 20 20 20 20 20 7C 25 37 6C 64 +R 00 00 02 00 +T 7C 00 00 00 2C 25 30 32 6C 64 0D 0A 00 +R 00 00 02 00 +T 85 00 00 00 +R 00 00 02 00 +T 85 00 00 00 0D 0A 25 31 33 73 54 6F 74 61 61 +R 00 00 02 00 +T 90 00 00 00 6C 3A 25 31 30 73 7C 25 37 6C 64 +R 00 00 02 00 +T 9B 00 00 00 2C 25 30 32 6C 64 0D 0A 0D 0A 0D +R 00 00 02 00 +T A6 00 00 00 0A 00 +R 00 00 02 00 +T 00 00 00 00 +R 00 00 03 00 +T 00 00 00 00 +R 00 00 03 00 diff --git a/src/gui/wnd.c b/src/gui/wnd.c new file mode 100644 index 00000000..bb795a9b --- /dev/null +++ b/src/gui/wnd.c @@ -0,0 +1,1141 @@ +/************************************************ + * Graphical User Interface driver (GUI) * + * By J.W. Morsink for Retail Vision B.V. * + ************************************************/ + +#include +#include "..\libc\malloc-l.h" +#undef NULL +#define NULL 0 + +/*void *malloc(size_t size) + { + void *ptr; + + ptr = (void *)sbrk(size); + return (ptr == (void *)-1) ? NULL : ptr; + } + +void free(void *ptr) + { + } + +*/ +/*#define JOOST_DEBUG +/*#define STR_DEBUG*/ +/*#define MALLOC_DEBUG + +/************************************************ + * Global variables for GUI * + ************************************************/ + +struct Global_GUI* global; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(){ + struct sgttyb temp; + char init[]={0x1B,'K'}; + + global->lcd=open("/dev/lcd0",O_RDWR); + gtty(global->lcd,&temp); + temp.sg_flags=RAW | UNBUFF; + stty(global->lcd,&temp); + + write(global->lcd,init,2); +} + +void GraphicsClose(){ + close(global->lcd); +} + +void Move(int x, int y){ + unsigned char cmd[]={0x1B,'S',0,0}; + cmd[2]=(unsigned char) (x); + cmd[3]=(unsigned char) (y); + write(global->lcd,cmd,4); +} + +void ClearRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'C',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void DrawRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'N',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'R',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void FillRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'F',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void GrayRect(int sx,int sy){ + unsigned char cmd[]={0x1B,'h',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(global->lcd,cmd,4); +} + +void Text(char *s){ + int c=strlen(s); + write(global->lcd,s,c); +} + +void TouchRegion(int msg, int x, int y, int sx, int sy){ + char touch[]={0x1B,'Z',0,0,0,0,0}; + touch[2]=(unsigned char) (msg); + touch[3]=(unsigned char) (x); + touch[4]=(unsigned char) (y); + touch[5]=(unsigned char) (sx); + touch[6]=(unsigned char) (sy); + write(global->lcd,touch,7); +#ifdef JOOST_DEBUG + printf("Touch: %x,%x,%x,%x,%x\n",msg,x,y,sx,sy); fflush(stdout); +#endif +} + +void ClearScreen(){ + Move(0,0); + ClearRect(0,0x80); + TouchRegion(0,0,0,0,0x80); +} + +void EnableScreen(unsigned char c){ + char cmd[]={0x1B,'E',0}; + cmd[2]=c; + write(global->lcd,cmd,3); +} + +void grSetFont(int f){ + char cmd[]={0x1B,0}; + cmd[1]=f & 0xff; + write(global->lcd,cmd,2); +} + +/************************************************ + * Fonts * + ************************************************/ + +struct Font* fontSearch(int f){ + struct Font* current=global->firstfont; + while(current!=NULL && current->id!=f) + current=current->nextfont; + return current; +} + +void setCurrentFont(int f){ + if(fontSearch(f)!=NULL){ + grSetFont(f); + global->currentfont=fontSearch(f); + } +} + +void loadFont(int id,int (*sw)(char*),int (*sh)(char*),int sizedata, void* data){ + struct Font* font=(struct Font*) malloc(sizeof(struct Font)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",font); fflush(stdout); +#endif + font->id=id; + font->stringwidth=sw; + font->stringheight=sh; + font->nextfont=NULL; + font->sizefontdata=sizedata; + font->fontdata=data; + if(global->firstfont==NULL){ + global->firstfont=font; + global->currentfont=font; + } + else + { + struct Font* current=global->firstfont; + while(current->nextfont!=NULL) + current=current->nextfont; + current->nextfont=font; + } +} + +int stringwidth(char *str,int extra){ + int w=0,i=0; + while(str[i]!=0x00){ + switch(str[i]){ + case 'i': + case 'I': + case '!': + w+=2; + break; + case 'l': + w+=3; + break; + case ',': + case '1': + case '.': + w+=4; + break; + case 'r': + case 'k': + case 'j': + w+=5; + break; + default: + w+=6; + } + i++; + w+=extra; + } + return w; +} + +int stringheight(char ch, int extra){ + if(ch<0x80) return 7+extra; + if(ch>=0xcc && ch<=0xdf) return 1+extra; +} + +int stringheight01(char* ch){ + return stringheight(ch[0],0); +} + +int stringheight2(char* ch){ + return stringheight(ch[0],5); +} + +int stringwidth0(char *str){ + return stringwidth(str,0); +} + +int stringwidth1(char *str){ + return stringwidth(str,2); +} + +int stringwidth2(char *str){ + return stringwidth(str,3); +} +/************************************************ + * Components * + ************************************************/ + +struct Component* Component_new(int x,int y,int sx,int sy){ + struct Component* this=(struct Component*) (malloc(sizeof(struct Component))); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",this); fflush(stdout); +#endif + + this->id=(++global->id); + this->x=x; + this->y=y; + this->sizex=sx; + this->sizey=sy; + this->state=0; + this->order=0; + this->font=0; + this->msg=0; + this->parent=NULL; + this->next_sibling=NULL; + this->first_child=NULL; + this->handler=NULL; + this->paint=NULL; + this->add=NULL; + this->sizexds=0; + this->xds=NULL; + this->label=NULL; + this->label2=NULL; + return this; +} + +void Component_setlabel(struct Component* this, char* s){ + int i=0; + while(s[i]!=0 && ilabel[i]=s[i]; + i++; + } + this->label[i]=0; +} + +void Component_add(struct Component* this, struct Component* comp){ + struct Component* current=this->first_child; + if(this->first_child==NULL){ + this->first_child=comp; + comp->next_sibling=NULL; + } + else + { + while(current->next_sibling!=NULL){ + current=current->next_sibling; + } + current->next_sibling=comp; + comp->next_sibling=NULL; + } + comp->parent=this; +} + +void Component_paint(struct Component* this){ + struct Component* current=this->first_child; + EnableScreen(0); + while(current!=NULL){ + current->paint(current); + current=current->next_sibling; + } + EnableScreen(1); +} + +void Component_findXY(struct Component* this, int* x, int* y){ + struct Component* current=this; + do{ + *x+=current->x; + *y+=current->y; + current=current->parent; + } while(current!=NULL); +} + +struct Component* Component_find(struct Component* this, int msg){ + struct Component* current=this->first_child; +#ifdef JOOST_DEBUG + printf("Find %x in %x:\n",msg, this->id); fflush(stdout); +#endif + while(current!=NULL){ +#ifdef JOOST_DEBUG + printf("Comp_find: %x, %x\n",msg, current->msg); fflush(stdout); +#endif + if(current->msg==msg) + return current; + current=current->next_sibling; + } + return NULL; +} + +struct Component* Component_delete(struct Component* this){ + struct Component* current=this->first_child; + int id=this->id; + if(this!=NULL){ +#ifdef JOOST_DEBUG + printf("Deleting component: %d\n",id); fflush(stdout); +#endif + while(current!=NULL){ + current=Component_delete(current); + } + if(this->parent!=NULL){ + if(this==this->parent->first_child) + this->parent->first_child=this->parent->first_child->next_sibling; + else{ + current=this->parent->first_child; + while(this!=current->next_sibling && current->next_sibling!=NULL) + current=current->next_sibling; + if(current->next_sibling!=NULL) + current->next_sibling=current->next_sibling->next_sibling; + } + } + current=this->next_sibling; + if(this->sizexds==sizeof(struct StringTableXDS)) + { + struct Component* par=this->parent; + struct StringTableXDS* stx=(struct StringTableXDS*) this->xds; + +#ifdef STR_DEBUG + printf("Stringtable @ %x freed!\n",stx->stringtabledata); fflush(stdout); +#endif + +#ifdef MALLOC_DEBUG + printf("free: %x\n",stx->stringtabledata); fflush(stdout); +#endif + free(stx->stringtabledata); +#ifdef MALLOC_DEBUG + printf("free: %x\n",stx->stringtable); fflush(stdout); +#endif + free(stx->stringtable); + + while((par!=NULL) && (par->sizexds!=sizeof(struct StringTableXDS))) + par=par->parent; + if(par!=NULL) + { + stx=(struct StringTableXDS*) par->xds; + global->stringtabledata=stx->stringtabledata; + global->stringtable=stx->stringtable; + } + } + if(this->sizexds>0){ +#ifdef MALLOC_DEBUG + printf("free: %x\n",this->xds); fflush(stdout); +#endif + free(this->xds); + } + if((this->state & STRING_FROMTABLE)==0 && this->label!=NULL){ +#ifdef MALLOC_DEBUG + printf("free: %x\n",this->label); fflush(stdout); +#endif + free(this->label); + } +#ifdef MALLOC_DEBUG + printf("free: %x\n",this); fflush(stdout); +#endif + + free(this); +#ifdef JOOST_DEBUG + printf("Deleted component: %d\n",id); fflush(stdout); +#endif + } + return current; +} + +void Component_delete_children(struct Component* this){ + struct Component* current=this->first_child; + while(current!=NULL) + current=Component_delete(current); +} + +void Component_changestate_children(struct Component* this, int andmask, int ormask, int xormask){ + struct Component* current=this->first_child; + while(current!=NULL){ + current->state&=(0xffff-andmask); + current->state|=ormask; + current->state^=xormask; + current=current->next_sibling; + } + fflush(stdout); +} + +void Component_linkstringtable(struct Component* this){ + struct Component* child=this->first_child; +#ifdef STR_DEBUG + printf("%d: %x -> %x\n",this->id,this->label-1,global->stringtable[(int) (this->label)-1]); fflush(stdout); +#endif + if(((int)(this->label))<0x1000 && ((int)(this->label))>0) + this->label=global->stringtable[(int) (this->label)-1]; + if(((int)(this->label2))<0x1000 && ((int)(this->label2))>0) + this->label2=global->stringtable[(int) (this->label2)-1]; + while(child!=NULL){ + Component_linkstringtable(child); + child=child->next_sibling; + } + +} + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param){ + struct Component* current,current2; + int x=0,y=0; +#ifdef JOOST_DEBUG + printf("Message in window %d, Msg: %x, Param: %x\n",this->id,msg,param); fflush(stdout); +#endif + switch(msg){ + case KEY_PRESSED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)) + current->handler(current,msg,param); + current=current->next_sibling; + } + break; + case KEY_RELEASED: + current=this->first_child; + while(current!=NULL) { + if((current->state & STATE_VISIBLE)!=0){ + current->handler(current,msg,param); + current->handler(current,KEY_TYPED,param); + if((current->state & (STATE_ACTION | STATE_ENABLED))==(STATE_ACTION | STATE_ENABLED) && current->msg==param) + current=NULL; + } + if(current!=NULL) + current=current->next_sibling; + } + break; + case KEY_TYPED: + current=this; + if((current->state & STATE_VISIBLE)==(STATE_VISIBLE)){ + + if((current->state & STATE_ACTION)!=0 && current->msg==param){ + struct ActionXDS* act=(struct ActionXDS*) (current->xds); +#ifdef JOOST_DEBUG + printf("Before actionhandler...\n"); +#endif + act->actionhandler(current); + if((act->action & 0xff00)==0){ + current=NULL; + } +#ifdef JOOST_DEBUG + printf("After actionhandler...\n"); +#endif + } + } + if(current!=NULL) + current=current->next_sibling; + + break; + case WND_REDRAW: + this->paint(this); + break; + case WND_CLOSE: + this->state=this->state & (0xffff-(STATE_VISIBLE | STATE_ENABLED)); + Component_findXY(this,&x,&y); + TouchRegion(0,x,y,this->sizex,this->sizey); + this->parent->handler(this->parent,WND_REDRAW,0); + break; + case WND_DESTROY: + current=this->parent; + Component_delete(this); + current->handler(current,WND_REDRAW,0); + break; + case WND_BROADCAST: + current=this->first_child; + while(current!=NULL){ + if(current!=(struct Component*) (param) && (current->state & STATE_FOCUS)!=0) + current->handler(current,CMP_BROADCAST,param); + current=current->next_sibling; + } + break; + case APP_QUIT: + if(this->parent==NULL) + global->willquit=1; + else if((this->state & STATE_APPLICATION)==0) + this->parent->handler(this->parent,APP_QUIT,param); + else{ + current=this->parent; + current->state|=STATE_VISIBLE | STATE_ENABLED; + Component_changestate_children(current,0,STATE_VISIBLE,0); + this->handler(this,WND_DESTROY,0); + } + break; + } +} + +void Window_paint(struct Component* this){ + int x=0,y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + + EnableScreen(0); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion(0,x,y,this->sizex,this->sizey); + Move(x,y+global->currentfont->stringheight(this->label)+4); + DrawRectNC(this->sizex,this->sizey-global->currentfont->stringheight(this->label)-4); + Move(x,y); + FillRect(this->sizex,global->currentfont->stringheight(this->label)+5); + Move(x+2,y+14); /* Nick 2); */ + Text(this->label); + Component_paint(this); + } +} + +void Root_paint(struct Component* this){ + EnableScreen(0); + Move(0,0); + ClearRect(0,0x80); + GrayRect(0,0x80); + TouchRegion(0,0,0,0,0x80); + + Component_paint(this); +/* EnableScreen(0); + Window_paint(this); + EnableScreen(1);*/ +} + +void Window_add(struct Component* this, struct Component* comp){ + Component_add(this,comp); +} + +struct Component* Window_new(int x,int y,int sx,int sy){ + struct Component* this=Component_new(x,y,sx,sy); + this->handler=Window_handler; + this->paint=Window_paint; + this->add=Window_add; + return this; +} + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->parent->handler(this->parent, CMP_ACTION, param); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void Button_drawtext(struct Component* this, int x, int y){ + if((this->state & STYLE_MULTILINE)!=0){ + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-2*global->currentfont->stringheight(this->label))/2+12); /* Nick +7 */ + Text(this->label); + Move(x+(this->sizex-global->currentfont->stringwidth(this->label2))/2,y+(this->sizey)/2+10); /* Nick 1); */ + Text(this->label2); + } else { + Move(x+(this->sizex-global->currentfont->stringwidth(this->label))/2,y+(this->sizey-global->currentfont->stringheight(this->label))/2+13); /* Nick 1); */ + Text(this->label); + } +#ifdef STR_DEBUG + printf("Drawtext (%d): ""%s"" @ %x\n",this->id,this->label,this->label); fflush(stdout); +#endif +} + +void Button_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & (STATE_ENABLED | STYLE_INVERTED))!=0 && (this->state & (STATE_ENABLED | STYLE_INVERTED))!=(STATE_ENABLED | STYLE_INVERTED) ) + FillRectNC(this->sizex,this->sizey); + else + DrawRectNC(this->sizex,this->sizey); + Button_drawtext(this,x,y); + } +} + +void Button_add(struct Component* this, struct Component* comp){ + return; +} + +struct Component* Button_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE; + this->msg=msg; + this->handler=Button_handler; + this->paint=Button_paint; + this->add=Button_add; + + return this; +} + +/*void Numpad(struct Component* this, int x, int y){ + int i; + char s[2]={0,0}; + struct Component* button; + for(i=0; i<9; i++){ + s[0]=0x31+(char) i; + button=Button_new(x+(i%3)*0x18,y+0x30-(i/3)*0x18,0x16,0x16,i+0x31); + Component_setlabel(button,s); + button->state|=STATE_CASTING; + this->add(this,button); + } + button=Button_new(x+0x18,y+0x48,0x16,0x16,0x30); + Component_setlabel(button,"0"); + button->state|=STATE_CASTING; + this->add(this,button); + + button=Button_new(x+0x30,y+0x48,0x16,0x16,0x08); + Component_setlabel(button,"CE"); + button->state|=STATE_CASTING; + this->add(this,button); +}*/ + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->state^=STATE_CHECKED; + this->parent->handler(this->parent, CMP_STATECHANGE, param); + this->handler(this, WND_REDRAW, 0); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void ToggleButton_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + if((this->state & STATE_ENABLED)!=0 && (this->state & STATE_CHECKED)!=0){ + FillRectNC(this->sizex,this->sizey); + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + }else{ + DrawRectNC(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + } + Button_drawtext(this,x,y); + } +} + +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_ENABLED | STATE_VISIBLE | STATE_CHECKED; + this->msg=msg; + this->handler=ToggleButton_handler; + this->paint=ToggleButton_paint; + this->add=Button_add; + + return this; +} + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==CMP_ACTION && param==0xff){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_OK, this->msg); + } + if(msg==CMP_ACTION && param==0xfe){ + if((this->state & STYLE_SELFDESTRUCT)!=0) + this->handler(this,WND_DESTROY,0); + else + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_CANCEL, this->msg); + + } +} + +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* ok; + struct Component* this=Component_new(x,y,sx,sy); + this->state|=STATE_VISIBLE; + this->msg=msg; + this->handler=Dialog_handler; + this->paint=Window_paint; + this->add=Window_add; + + ok=Button_new(sx-0x30,sy-0x1c,0x28,0x14,0xff); + ok->label=(char*) malloc(3); + Component_setlabel(ok,"OK"); + this->add(this,ok); + + ok=Button_new(sx-0x30,sy-0x38,0x28,0x14,0xfe); /*Cancel*/ + ok->label=(char*) malloc(7); + Component_setlabel(ok,"Cancel"); + this->add(this,ok); + + return this; +} + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param){ + Button_handler(this,msg,param); + if(msg==CMP_BROADCAST && (this->state & STATE_FOCUS)!=0){ +#ifdef JOOST_DEBUG + printf("strlen = %d->",strlen(this->label)); fflush(stdout); +#endif + if(param==0x08){ + if(strlen(this->label)!=0) + this->label[strlen(this->label)-1]=0; + }else{ + this->label[strlen(this->label)+1]=0; + this->label[strlen(this->label)]=(char) param; + } +#ifdef JOOST_DEBUG + printf("%d\n",strlen(this->label)); fflush(stdout); +#endif + this->handler(this,WND_REDRAW,0); + } +} + +void Display_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + char pwd[64]; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + + if( (this->state & STYLE_INVERTED)==0) + FillRectNC(this->sizex,this->sizey); + else + DrawRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2+7); + if(this->state & STYLE_PASSWORD){ + int i; + for(i=0; ilabel); i++) + pwd[i]='*'; + pwd[i]=0; + Text(pwd); + }else + Text(this->label); + +/* Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + + FillRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-global->currentfont->stringheight(this->label))/2+12); /x Nick +7 x/ + Text(this->label); + TouchRegion((this->state&STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); +*/ + } +} + +struct Component* Display_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Button_new(x,y,sx,sy,msg); + this->state|=STATE_FOCUS; + Component_setlabel(this,""); + this->paint=Display_paint; + this->handler=Display_handler; + return this; +} + +/************************************************ + * Labels * + ************************************************/ +void Label_handler(struct Component* this, int msg, int param){ + return; +} + +void Label_paint(struct Component* this){ + int x=0, y=0; + if(global->currentfont->id!=this->font) + setCurrentFont(this->font); + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Button_drawtext(this,x,y); + } +} + +struct Component* Label_new(int x, int y, int sx, int sy,char* l){ + struct Component* comp=Component_new(x,y,sx,sy); + comp->label=l; + comp->state=STATE_VISIBLE; + comp->handler=Label_handler; + comp->paint=Label_paint; + comp->add=Button_add; + return comp; +} + /************************************************ + * Implementation * + ************************************************/ +/* +void ScreenDialog_handler(struct Component* this, int msg, int param){ + char cmd[]={0x1B,'V',0}; + Dialog_handler(this,msg,param); + if(msg==CMP_ACTION){ + if(param=='U') + cmd[2]=0; + else if(param=='D') + cmd[2]=1; + else + return; + write(global->lcd,cmd,3); + } +} + +struct Component* ScreenDialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* button; + struct Component* this=Dialog_new(x,y,sx,sy,msg); + + button=Button_new(0x04,0x10,0x20,0x14,'U'); + Component_setlabel(button,"Up"); + this->add(this,button); + + button=Button_new(0x04,0x28,0x20,0x14,'D'); + Component_setlabel(button,"Down"); + this->add(this,button); + + this->handler=ScreenDialog_handler; + + return this; +} +*/ +void rootWindow_handler(struct Component* this, int msg, int param){ + struct Component* dummy; + Window_handler(this,msg,param); +} + + +void screenbuilder(struct Component* root, char* filename){ + struct Component* subw; + struct ActionXDS* action; + int mode; + int fh,rd; + char buf[SIZE_SCRBLD_RECORD]; + long l; + int xs,ys; + xs=0x2b; + ys=0x1a; + buf[0]=0; + fh=open(filename,O_RDONLY); + do{ + char comp=0; + if(buf[0]=='s'){ /* Change size */ + xs=*((int*)(buf+0x1)); + ys=*((int*)(buf+0x3)); + } + + if(buf[0]=='B' || buf[0]=='M'){ /* Button, Multi-line button */ + subw=Button_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + if(buf[0]=='M') subw->state|=STYLE_MULTILINE; + comp=1; + } + if(buf[0]=='T'){ /* Toggle-button */ + subw=ToggleButton_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='D'){ /* Display button */ + subw=Display_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf[5]); + comp=1; + } + if(buf[0]=='L'){ /* Label */ + subw=Label_new(buf[1]*xs,buf[2]*ys,buf[3]*xs-3,buf[4]*ys-3,buf+0x12); + comp=1; + } + if(buf[0]=='A'){ + struct ActionXDS a; + root->xds=&a; + a.action=*((int*)(buf+0x6)); + a.wParam=*((int*)(buf+0x8)); + a.lParam=*((long*)(buf+0xa)); + root_actionhandler(root); + } + + if(buf[0]=='S'){ + struct StringTableXDS* stx; + read_stringtable(fh,buf); + root->xds=(void*) malloc(sizeof(struct StringTableXDS)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",root->xds); fflush(stdout); +#endif + + stx=(struct StringTableXDS*) root->xds; + root->sizexds=sizeof(struct StringTableXDS); + stx->stringtable=global->stringtable; + stx->stringtabledata=global->stringtabledata; +#ifdef STR_DEBUG + printf("Stringtable created @ %x\n",stx->stringtabledata); fflush(stdout); +#endif + comp=0; + } + if(comp!=0){ + if((buf[6] | buf[7])!=0){ + subw->state|=STATE_ACTION; + subw->sizexds=sizeof(struct ActionXDS); + subw->xds=(void*) malloc(sizeof(struct ActionXDS)); +#ifdef MALLOC_DEBUG + printf("malloc Action: %x\n",subw->xds); fflush(stdout); +#endif + + action=(struct ActionXDS*) (subw->xds); + action->actionhandler=root_actionhandler; + action->action=*((int*)(buf+0x6)); + action->wParam=*((int*)(buf+0x8)); + action->lParam=*((long*)(buf+0xa)); + } + if((buf[0x0e] | buf[0x0f])!=0) + subw->state=*((int*)(buf+0x0e)); + subw->font=*((int*)(buf+0x10)); + + subw->label=(char*) (*((int*) (buf+0x12)) & 0x0fff); + if(subw->label==NULL) { + subw->label=(char*) malloc(LABEL_LENGTH); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",subw->label); fflush(stdout); +#endif + subw->label[0]=0; + } + else + subw->state|=STRING_FROMTABLE; + + if((*((int*) (buf+0x12)) &0xf000)>0x1000) + subw->label2=(char*)((*((int*) (buf+0x12)) & 0x0fff)+1); + + root->add(root,subw); + } + + rd=read(fh,buf,SIZE_SCRBLD_RECORD); + } while(rd==SIZE_SCRBLD_RECORD); + close(fh); + Component_linkstringtable(root); + root->paint(root); +} + +void root_actionhandler(struct Component* this){ + struct ActionXDS *act; + struct Component* subw; + char filename[]={'/','w','n','d','/','0','0','0','0','.','s','c','r',0}; /* Nick added /wnd/ */ + + act=(struct ActionXDS*) (this->xds); +#ifdef JOOST_DEBUG + printf("0x%x: (0x%x, 0x%x, 0x%lx)",act, act->action, act->wParam, act->lParam); +#endif + if(act->action==0x0001){ /*QUIT*/ + this->handler(this,APP_QUIT,0); + } + if((act->action & 0xfffe)==0x0002){ /*Open Screen*/ + Component_changestate_children(this->parent,STATE_VISIBLE,0,0); + subw=Window_new(0,0,this->parent->sizex,this->parent->sizey); + subw->state=STATE_VISIBLE | STATE_ENABLED; + if((act->action & 1)!=0) + subw->state|=STATE_APPLICATION; + subw->handler=rootWindow_handler; + subw->paint=Root_paint; + filename[5]=(char) ((act->lParam) &0xff); /* Nick 5 formerly 0 */ + filename[6]=(char) ((act->lParam>>8) &0xff); /* Nick 6 formerly 1 */ + filename[7]=(char) ((act->lParam>>16) &0xff); /* Nick 7 formerly 2 */ + filename[8]=(char) ((act->lParam>>24) &0xff); /* Nick 8 formerly 3 */ + screenbuilder(subw,filename); + this->parent->add(this->parent,subw); + } + if(act->action==0x0004) { /* Open MessageBox */ + /*Component_changestate_children(this->parent,0,0,0);*/ + struct Component* label; + int i; + subw=Dialog_new(0x05,0x05,this->parent->sizex-0x0a,this->parent->sizey-0x0a,1); + subw->state=STATE_VISIBLE | STATE_ENABLED | STYLE_SELFDESTRUCT; + subw->font=0x0030; + for(i=0; i<(act->wParam>>12)&0x0f; i++){ + label=Label_new(0x08,0x14+i*0x0c,(subw->sizex & 0xff)-0x10,0x10,global->stringtable[(act->wParam&0xfff)+i-1]); + label->font=0x0030; + subw->add(subw,label); + } + Component_setlabel(subw,"Message Box"); + Component_find(subw,0xff)->font=0x0030; + Component_delete(Component_find(subw,0xfe)); + this->parent->add(this->parent,subw); + this->parent->handler(this->parent,WND_REDRAW,0); + } +#ifdef JOOST_DEBUG + printf("Before external handler...\n"); fflush(stdout); +#endif + if(global->actionhandler!=NULL) + global->actionhandler(this); + +#ifdef JOOST_DEBUG + printf("After external handler...\n"); fflush(stdout); +#endif +} + +void read_stringtable(int fh,char* buf){ + int siz,bsiz; + int i=0,j=0; + char **ptrs; + char *rawdata; + + siz=*((int*) (buf+0x01)); + bsiz=*((int*) (buf+0x03)); +#ifdef STR_DEBUG + printf("%d %d\n",siz,bsiz); +#endif + + ptrs=(char**) malloc(sizeof(char*)*siz); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",ptrs); fflush(stdout); +#endif + + rawdata=(char*) malloc(bsiz); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",rawdata); fflush(stdout); +#endif + + read(fh,rawdata,bsiz); + while(istringtabledata=rawdata; + global->stringtable=ptrs; +#ifdef STR_DEBUG + for(i=0; i""%s""\n",i,global->stringtable[i],global->stringtable[i]); + fflush(stdout); +#endif + +} + +struct Global_GUI* gui_globals(){ + return global; +} + + +void GUIinit(void){ + global=(struct Global_GUI*) malloc(sizeof(struct Global_GUI)); +#ifdef MALLOC_DEBUG + printf("malloc: %x\n",global); fflush(stdout); +#endif + + global->id=0; + global->willquit=0; + global->currentfont=NULL; + global->firstfont=NULL; + global->stringtable=NULL; + global->stringtabledata=NULL; + global->actionhandler=NULL; + GraphicsOpen(); + loadFont(0x0030,stringwidth0,stringheight01,0,NULL); + loadFont(0x0031,stringwidth1,stringheight01,0,NULL); + loadFont(0x0032,stringwidth2,stringheight2,0,NULL); + global->root=Window_new(0x0,0x0,0x00,0x80); + global->root->state=STATE_VISIBLE; + global->root->handler=rootWindow_handler; + global->root->paint=Root_paint; +} + +void GUIunit(void){ + Component_delete(global->root); + ClearScreen(); + GraphicsClose(); +} + +void GUIgo(char* scr){ + char buf,obuf; + screenbuilder(global->root,scr); + + while(read(global->lcd,&buf,1)==1); + + while(!global->willquit){ + if(read(global->lcd,&buf,1)==1){ + if(buf!=0) + global->root->handler(global->root,KEY_PRESSED,buf); + else + global->root->handler(global->root,KEY_RELEASED,obuf); + obuf=buf; + } + } +} + +/*void main(void){ + GUIinit(); + GUIgo(); + GUIunit(); +}*/ + diff --git a/src/gui/wnd.cbackup b/src/gui/wnd.cbackup new file mode 100644 index 00000000..d7f96dac --- /dev/null +++ b/src/gui/wnd.cbackup @@ -0,0 +1,658 @@ +#include +#include +#include +#include +#include +#include + +/*#define JOOST_DEBUG*/ + +#define FONT_HEIGHT 7 +#define FONT_WIDTH 6 + +#define STATE_VISIBLE 0x0001 +#define STATE_ENABLED 0x0002 +#define STATE_CHECKED 0x0004 +#define STATE_FOCUS 0x0008 +#define STATE_CASTING 0x0010 +#define STATE_ACTION 0x0020 + +#define KEY_TYPED 0x0001 +#define WND_OPEN 0x0101 +#define WND_CLOSE 0x0102 +#define WND_REDRAW 0x0103 +#define WND_BROADCAST 0x0104 +#define CMP_ACTION 0x0201 +#define CMP_STATECHANGE 0x0202 +#define CMP_BROADCAST 0x0203 +#define DLG_OK 0x0301 +#define DLG_CANCEL 0x0302 + +int id=0; +int lcd; +int willquit; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(){ + struct sgttyb temp; + char init[]={0x1B,'K'}; + + lcd=open("/dev/lcd0",O_RDWR); + gtty(lcd,&temp); + temp.sg_flags=RAW | UNBUFF; + stty(lcd,&temp); + + write(lcd,init,2); +} + +void Move(int x, int y){ + unsigned char cmd[]={0x1B,'S',0,0}; + cmd[2]=(unsigned char) (x); + cmd[3]=(unsigned char) (y); + write(lcd,cmd,4); +} + +void ClearRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'C',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(lcd,cmd,4); +} + +void DrawRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'N',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(lcd,cmd,4); +} + +void FillRect(int sx, int sy){ + unsigned char cmd[]={0x1B,'R',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(lcd,cmd,4); +} + +void FillRectNC(int sx, int sy){ + unsigned char cmd[]={0x1B,'F',0,0}; + cmd[2]=(unsigned char) (sx); + cmd[3]=(unsigned char) (sy); + write(lcd,cmd,4); +} + +void Text(char *s){ + int c=strlen(s); + write(lcd,s,c); +} + +void TouchRegion(int msg, int x, int y, int sx, int sy){ + char touch[]={0x1B,'Z',0,0,0,0,0}; + touch[2]=(unsigned char) (msg); + touch[3]=(unsigned char) (x); + touch[4]=(unsigned char) (y); + touch[5]=(unsigned char) (sx); + touch[6]=(unsigned char) (sy); + write(lcd,touch,7); +#ifdef JOOST_DEBUG + printf("Touch: %x,%x,%x,%x,%x\n",msg,x,y,sx,sy); fflush(stdout); +#endif +} + +void ClearScreen(){ + Move(0,0); + ClearRect(0,0x80); + TouchRegion(0,0,0,0,0x80); +} + +void EnableScreen(unsigned char c){ + char cmd[]={0x1B,'E',0}; + cmd[2]=c; + write(lcd,cmd,3); +} + +/************************************************ + * Components * + ************************************************/ + +struct Component { + int id; + int x,y; + int sizex,sizey; + int state; + int order; + char msg; + struct Component* parent; + struct Component *next_sibling; + struct Component *first_child; + void (*handler) (struct Component*, int, int); + void (*paint) (struct Component*); + void (*add) (struct Component*, struct Component*); + char label[20]; + int sizexds; + void *xds; +}; + +struct ActionXDS { + void (*actionhandler)(struct Component*, int); + int action; + int wParam; + long lParam; +}; + +struct Component* root; + +struct Component* Component_new(int x,int y,int sx,int sy){ + struct Component* this=(struct Component*) (malloc(sizeof(struct Component))); + this->id=(++id); + this->x=x; + this->y=y; + this->sizex=sx; + this->sizey=sy; + this->state=0; + this->order=0; + this->msg=0; + this->parent=NULL; + this->next_sibling=NULL; + this->first_child=NULL; + this->handler=NULL; + this->paint=NULL; + this->add=NULL; + this->sizexds=0; + this->xds=NULL; + this->label[0]=0; + return this; +} + +void Component_setlabel(struct Component* this, char* s){ + int i=0; + while(s[i]!=0 && i<20){ + this->label[i]=s[i]; + i++; + } + this->label[i]=0; +} + +void Component_add(struct Component* this, struct Component* comp){ + struct Component* current=this->first_child; + if(this->first_child==NULL){ + this->first_child=comp; + comp->next_sibling=NULL; + } + else + { + while(current->next_sibling!=NULL){ + current=current->next_sibling; + } + current->next_sibling=comp; + comp->next_sibling=NULL; + } + comp->parent=this; +} +void Component_paint(struct Component* this){ + struct Component* current=this->first_child; + while(current!=NULL){ + current->paint(current); + current=current->next_sibling; + } +} + + +void Component_findXY(struct Component* this, int* x, int* y){ + struct Component* current=this; + do{ + *x+=current->x; + *y+=current->y; + current=current->parent; + } while(current!=NULL); +} + +struct Component* Component_find(struct Component* this, int msg){ + struct Component* current=this->first_child; +#ifdef JOOST_DEBUG + printf("Find %x in %x:\n",msg, this->id); fflush(stdout); +#endif + while(current!=NULL){ +#ifdef JOOST_DEBUG + printf("Comp_find: %x, %x\n",msg, current->msg); fflush(stdout); +#endif + if(current->msg==msg) + return current; + current=current->next_sibling; + } + return NULL; +} + +struct Component* Component_delete(struct Component* this){ + struct Component* current=this->first_child; + int id=this->id; + if(this!=NULL){ +#ifdef JOOST_DEBUG + printf("Deleting component: %d\n",id); fflush(stdout); +#endif + while(current!=NULL){ + current=Component_delete(current); + } + if(this->parent!=NULL){ + if(this==this->parent->first_child) + this->parent->first_child=this->parent->first_child->next_sibling; + else{ + current=this->parent->first_child; + while(this!=current->next_sibling && current->next_sibling!=NULL) + current=current->next_sibling; + if(current->next_sibling!=NULL) + current->next_sibling=current->next_sibling->next_sibling; + } + } + current=this->next_sibling; + if(this->sizexds>0) + free(this->xds); + free(this); +#ifdef JOOST_DEBUG + printf("Deleted component: %d\n",id); fflush(stdout); +#endif + } + return current; +} + + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param){ + struct Component* current; + int x=0,y=0; +#ifdef JOOST_DEBUG + printf("Message in window %d, Msg: %x, Param: %x\n",this->id,msg,param); fflush(stdout); +#endif + switch(msg){ + case KEY_TYPED: + current=this->first_child; + while(current!=NULL) { + current->handler(current,msg,param); + current=current->next_sibling; + } + break; + case WND_REDRAW: + this->paint(this); + break; + case WND_CLOSE: + Component_findXY(this,&x,&y); + TouchRegion(0,x,y,this->sizex,this->sizey); + this->parent->handler(this->parent,WND_REDRAW,0); + break; + case WND_BROADCAST: + current=this->first_child; + while(current!=NULL){ + if(current!=(struct Component*) (param) && (current->state & STATE_FOCUS)!=0) + current->handler(current,CMP_BROADCAST,param); + current=current->next_sibling; + } + break; + } +} + +void Window_paint(struct Component* this){ + int x=0,y=0; + struct Component* current; + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + TouchRegion(0,x,y,this->sizex,this->sizey); + Move(x,y+FONT_HEIGHT+4); + DrawRect(this->sizex,this->sizey-FONT_HEIGHT-4); + Move(x,y); + FillRect(this->sizex, FONT_HEIGHT+5); + Move(x+2,y+2); + Text(this->label); + Component_paint(this); + } +} + +void Root_paint(struct Component* this){ + Move(0,0); + ClearRect(0,0x80); + Component_paint(this); +/* EnableScreen(0); + Window_paint(this); + EnableScreen(1);*/ +} + +void Window_add(struct Component* this, struct Component* comp){ + Component_add(this,comp); +} + +struct Component* Window_new(int x,int y,int sx,int sy){ + struct Component* this=Component_new(x,y,sx,sy); + this->handler=Window_handler; + this->paint=Window_paint; + this->add=Window_add; + return this; +} + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->parent->handler(this->parent, CMP_ACTION, param); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void Button_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + if((this->state & STATE_ENABLED)!=0){ + FillRectNC(this->sizex,this->sizey); + Move(x+(this->sizex-FONT_WIDTH*strlen(this->label))/2,y+(this->sizey-FONT_HEIGHT)/2); + Text(this->label); + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + }else{ + DrawRect(this->sizex,this->sizey); + Move(x+(this->sizex-FONT_WIDTH*strlen(this->label))/2,y+(this->sizey-FONT_HEIGHT)/2); + Text(this->label); + TouchRegion(0,x,y,this->sizex,this->sizey); + } + } +} + +void Button_add(struct Component* this, struct Component* comp){ + +} + +struct Component* Button_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state=this->state | STATE_ENABLED | STATE_VISIBLE; + this->msg=msg; + this->handler=Button_handler; + this->paint=Button_paint; + this->add=Button_add; + + return this; +} + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==KEY_TYPED && this->msg==param && (this->state & (STATE_VISIBLE | STATE_ENABLED))!=0){ + this->state^=STATE_CHECKED; + this->parent->handler(this->parent, CMP_STATECHANGE, param); + this->handler(this, WND_REDRAW, 0); + if((this->state & STATE_CASTING)!=0) + this->parent->handler(this->parent, WND_BROADCAST, this->msg); + } + if(msg==CMP_ACTION) + this->parent->handler(this->parent, CMP_ACTION, param); +} + +void ToggleButton_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + Move(x,y); + ClearRect(this->sizex,this->sizey); + if((this->state & STATE_ENABLED)!=0 && (this->state & STATE_CHECKED)!=0){ + FillRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-FONT_HEIGHT)/2); + Text(this->label); + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + }else{ + DrawRect(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-FONT_HEIGHT)/2); + Text(this->label); + TouchRegion((this->state & STATE_ENABLED)?this->msg:0,x,y,this->sizex,this->sizey); + } + } +} + +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Component_new(x,y,sx,sy); + this->state=this->state | STATE_ENABLED | STATE_VISIBLE | STATE_CHECKED; + this->msg=msg; + this->handler=ToggleButton_handler; + this->paint=ToggleButton_paint; + this->add=Button_add; + + return this; +} + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param){ + Window_handler(this,msg,param); + if(msg==CMP_ACTION && param=='O'){ + this->state=this->state & (0xffff-(STATE_VISIBLE | STATE_ENABLED)); + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_OK, this->msg); + } + if(msg==CMP_ACTION && param=='C'){ + this->state=this->state & (0xffff-(STATE_VISIBLE | STATE_ENABLED)); + this->handler(this,WND_CLOSE,0); + this->parent->handler(this->parent, DLG_CANCEL, this->msg); + } +} + +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* ok; + struct Component* this=Component_new(x,y,sx,sy); + this->state=this->state | STATE_VISIBLE; + this->msg=msg; + this->handler=Dialog_handler; + this->paint=Window_paint; + this->add=Window_add; + + ok=Button_new(sx-0x30,sy-0x1c,0x28,0x14,'O'); + Component_setlabel(ok,"OK"); + this->add(this,ok); + + ok=Button_new(sx-0x30,sy-0x38,0x28,0x14,'C'); /*Cancel*/ + Component_setlabel(ok,"Cancel"); + this->add(this,ok); + + return this; +} + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param){ + Button_handler(this,msg,param); + if(msg==CMP_BROADCAST && (this->state & STATE_FOCUS)!=0){ +#ifdef JOOST_DEBUG + printf("strlen = %d->",strlen(this->label)); fflush(stdout); +#endif + if(param==0x08){ + if(strlen(this->label)!=0) + this->label[strlen(this->label)-1]=0; + }else{ + this->label[strlen(this->label)+1]=0; + this->label[strlen(this->label)]=(char) param; + } +#ifdef JOOST_DEBUG + printf("%d\n",strlen(this->label)); fflush(stdout); +#endif + this->handler(this,WND_REDRAW,0); + } +} + +void Display_paint(struct Component* this){ + int x=0, y=0; + struct Component* current; + if((this->state & STATE_VISIBLE)!=0){ + Component_findXY(this,&x,&y); + + Move(x,y); + ClearRect(this->sizex,this->sizey); + + FillRectNC(this->sizex,this->sizey); + Move(x+2,y+(this->sizey-FONT_HEIGHT)/2); + Text(this->label); + if((this->state & STATE_ENABLED)!=0) + TouchRegion(this->msg,x,y,this->sizex,this->sizey); + } +} + +struct Component* Display_new(int x, int y, int sx, int sy, int msg){ + struct Component* this=Button_new(x,y,sx,sy,msg); + this->state|=STATE_FOCUS; + Component_setlabel(this,""); + this->paint=Display_paint; + this->handler=Display_handler; + return this; +} + +/************************************************ + * Implementation * + ************************************************/ + +void ScreenDialog_handler(struct Component* this, int msg, int param){ + char cmd[]={0x1B,'V',0}; + Dialog_handler(this,msg,param); + if(msg==CMP_ACTION){ + if(param=='U') + cmd[2]=0; + else if(param=='D') + cmd[2]=1; + else + return; + write(lcd,cmd,3); + } +} + +struct Component* ScreenDialog_new(int x, int y, int sx, int sy, int msg){ + struct Component* button; + struct Component* this=Dialog_new(x,y,sx,sy,msg); + + button=Button_new(0x04,0x10,0x20,0x14,'U'); + Component_setlabel(button,"Up"); + this->add(this,button); + + button=Button_new(0x04,0x28,0x20,0x14,'D'); + Component_setlabel(button,"Down"); + this->add(this,button); + + this->handler=ScreenDialog_handler; + + return this; +} + +void rootWindow_handler(struct Component* this, int msg, int param){ + struct Component* dummy; + Window_handler(this,msg,param); + if(msg==DLG_OK && param=='!') + willquit=1; + if(msg==DLG_CANCEL && param=='!'){ + Component_delete(Component_find(this,'!')); + Component_find(this,'Q')->state|=STATE_ENABLED; + this->handler(this,WND_REDRAW,0); + } + + if((msg==DLG_CANCEL || msg==DLG_OK) && param=='#'){ + Component_delete(Component_find(this,'#')); + Component_find(this,'S')->state|=STATE_ENABLED; + this->handler(this,WND_REDRAW,0); + } + + if(msg==CMP_ACTION && param=='Q'){ + dummy=Dialog_new(0x02,0x02,0xfc,0x7c,'!'); + dummy->state=dummy->state | STATE_VISIBLE; + Component_setlabel(dummy,"Really quit?"); + this->add(root,dummy); + Component_find(this,'Q')->state&=0xffff-STATE_ENABLED; + this->handler(this,WND_REDRAW,0); + } + + if(msg==CMP_ACTION && param=='S'){ + dummy=ScreenDialog_new(0x02,0x02,0xfc,0x7c,'#'); + dummy->state=dummy->state | STATE_VISIBLE; + Component_setlabel(dummy,"Screen contrast"); + + this->add(root,dummy); + Component_find(this,'S')->state&=0xffff-STATE_ENABLED; + this->handler(this,WND_REDRAW,0); + } +} + +void Numpad(struct Component* this, int x, int y){ + int i; + char s[2]={0,0}; + struct Component* button; + for(i=0; i<9; i++){ + s[0]=0x31+(char) i; + button=Button_new(x+(i%3)*0x18,y+0x30-(i/3)*0x18,0x16,0x16,i+0x31); + Component_setlabel(button,s); + button->state|=STATE_CASTING; + this->add(this,button); + } + button=Button_new(x+0x18,y+0x48,0x16,0x16,0x30); + Component_setlabel(button,"0"); + button->state|=STATE_CASTING; + this->add(this,button); + + button=Button_new(x+0x30,y+0x48,0x16,0x16,0x08); + Component_setlabel(button,"CE"); + button->state|=STATE_CASTING; + this->add(this,button); +} + +void main(void){ + struct Component* subw; + char buf; + willquit=0; + GraphicsOpen(); + root=Window_new(0x0,0x0,0x00,0x80); + root->state=STATE_VISIBLE; + root->handler=rootWindow_handler; + root->paint=Root_paint; + Component_setlabel(root,"Test-window"); + + subw=Button_new(0xc0,0x60,0x30,0x18,'Q'); + Component_setlabel(subw,"Quit"); + root->add(root,subw); + + subw=ToggleButton_new(0xc0,0x40,0x30,0x18,'T'); + Component_setlabel(subw," Toggle!"); + root->add(root,subw); + + subw=Button_new(0xc0,0x20,0x30,0x18,'S'); + Component_setlabel(subw,"Screen"); + root->add(root,subw); + + subw=Display_new(0x10,0x02,0x46,0x18,'@'); + root->add(root,subw); + + Numpad(root,0x10,0x1f); + + root->paint(root); + + while(read(lcd,&buf,1)==1); + + while(!willquit){ + if(read(lcd,&buf,1)==1) + root->handler(root,KEY_TYPED,buf); + } + + Component_delete(root); + ClearScreen(); +} \ No newline at end of file diff --git a/src/gui/wnd.h b/src/gui/wnd.h new file mode 100644 index 00000000..dcf45c3d --- /dev/null +++ b/src/gui/wnd.h @@ -0,0 +1,201 @@ +#ifndef JOOST_WND_H +#define JOOST_WND_H +#include +#include +#include +#include +#include +#include + +#define FONT_HEIGHT global->currentfont->stringheight +#define FONT_WIDTH(x) global->currentfont->stringwidth(x) +#define LABEL_LENGTH 0x14 +#define SIZE_SCRBLD_RECORD 0x14 + + +#define STATE_VISIBLE 0x0001 +#define STATE_ENABLED 0x0002 +#define STATE_CHECKED 0x0004 +#define STATE_FOCUS 0x0008 +#define STATE_CASTING 0x0010 +#define STATE_ACTION 0x0020 +#define STYLE_MULTILINE 0x0040 +#define STYLE_INVERTED 0x0080 +#define STYLE_PASSWORD 0x0100 +#define STYLE_SELFDESTRUCT 0x1000 +#define STATE_APPLICATION 0x2000 +#define STRING_FROMTABLE 0x4000 +#define STATE_DUMMY 0x8000 + +#define KEY_PRESSED 0x0001 +#define KEY_RELEASED 0x0002 +#define KEY_TYPED 0x0003 +#define WND_OPEN 0x0101 +#define WND_CLOSE 0x0102 +#define WND_REDRAW 0x0103 +#define WND_BROADCAST 0x0104 +#define WND_DESTROY 0x0105 +#define CMP_ACTION 0x0201 +#define CMP_STATECHANGE 0x0202 +#define CMP_BROADCAST 0x0203 +#define DLG_OK 0x0301 +#define DLG_CANCEL 0x0302 +#define APP_QUIT 0x0401 + +struct Global_GUI { + int id; + int lcd; + int willquit; + char *stringtabledata; + char **stringtable; + struct Font* currentfont; + struct Font* firstfont; + struct Component* root; + void (*actionhandler) (struct Component*); +}; + +/************************************************ + * Graphics * + ************************************************/ + +void GraphicsOpen(); +void GraphicsClose(); +void Move(int x, int y); +void ClearRect(int sx, int sy); +void DrawRect(int sx, int sy); +void FillRect(int sx, int sy); +void FillRectNC(int sx, int sy); +void GrayRect(int sx, int sy); +void Text(char *s); +void TouchRegion(int msg, int x, int y, int sx, int sy); +void ClearScreen(); +void EnableScreen(unsigned char c); +void grSetFont(int f); + +/************************************************ + * Fonts * + ************************************************/ + +struct Font { + int id; + int (*stringwidth)(char*); + int (*stringheight)(char*); + struct Font* nextfont; + int sizefontdata; + void* fontdata; +}; + +struct Font* fontSearch(int f); +void setCurrentFont(int f); +void loadFont(int id,int (*sw)(char*),int (*sh)(char*),int sizedata, void* data); + + +/************************************************ + * Components * + ************************************************/ + +struct Component { + int id; + int x,y; + int sizex,sizey; + int state; + int order; + int font; + char msg; + struct Component* parent; + struct Component *next_sibling; + struct Component *first_child; + void (*handler) (struct Component*, int, int); + void (*paint) (struct Component*); + void (*add) (struct Component*, struct Component*); + char* label; + char* label2; + int sizexds; + void *xds; +}; + +struct ActionXDS { + void (*actionhandler)(struct Component*); + int action; + int wParam; + long lParam; +}; + +struct StringTableXDS { + char *stringtabledata; + char **stringtable; +}; + +struct Component* Component_new(int x,int y,int sx,int sy); +void Component_setlabel(struct Component* this, char* s); +void Component_add(struct Component* this, struct Component* comp); +void Component_paint(struct Component* this); +void Component_findXY(struct Component* this, int* x, int* y); +struct Component* Component_find(struct Component* this, int msg); +struct Component* Component_delete(struct Component* this); +void Component_delete_children(struct Component* this); +void Component_changestate_children(struct Component* this, int andmask, int ormask, int xormask); +void Component_linkstringtable(struct Component* this); + +/************************************************ + * Windows * + ************************************************/ + +void Window_handler (struct Component* this, int msg, int param); +void Window_paint(struct Component* this); +void Root_paint(struct Component* this); +void Window_add(struct Component* this, struct Component* comp); +struct Component* Window_new(int x,int y,int sx,int sy); + +/************************************************ + * Buttons * + ************************************************/ + +void Button_handler(struct Component* this, int msg, int param); +void Button_drawtext(struct Component* this, int x, int y); +void Button_paint(struct Component* this); +void Button_add(struct Component* this, struct Component* comp); +struct Component* Button_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Toggle-buttons * + ************************************************/ + +void ToggleButton_handler(struct Component* this, int msg, int param); +void ToggleButton_paint(struct Component* this); +struct Component* ToggleButton_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Dialogs * + ************************************************/ + +void Dialog_handler(struct Component* this, int msg, int param); +struct Component* Dialog_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Displays * + ************************************************/ +void Display_handler(struct Component* this, int msg, int param); +void Display_paint(struct Component* this); +struct Component* Display_new(int x, int y, int sx, int sy, int msg); + +/************************************************ + * Labels * + ************************************************/ +void Label_handler(struct Component* this, int msg, int param); +void Label_paint(struct Component* this); +struct Component* Label_new(int x, int y, int sx, int sy,char* l); + +/************************************************ + * Implementation * + ************************************************/ +void rootWindow_handler(struct Component* this, int msg, int param); +void root_actionhandler(struct Component*); +void screenbuilder(struct Component* root, char* filename); +void read_stringtable(int fh,char* buf); +struct Global_GUI* gui_globals(); +void GUIinit(); +void GUIgo(char* scr); +void GUIunit(); + +#endif \ No newline at end of file diff --git a/src/gui/wnd.ihx b/src/gui/wnd.ihx new file mode 100644 index 00000000..be61cb6f --- /dev/null +++ b/src/gui/wnd.ihx @@ -0,0 +1,1068 @@ +:020000040000FA +:10810000C30381ED73A6C3114AC7CDF9BFCD458125 +:10811000DD210000DD39DD6E04DD66052212C5DDDE +:108120004E02DD4603ED4310C5DD5E00DD5601ED78 +:10813000530EC5CD3AABEBD52A16C57DB4C44481E8 +:10814000D1C319C0E9214AC7110EC5CD6E8111A056 +:10815000C321A0C30132C2CD6381114AC721A0C38C +:1081600001A0C3AFED42C54D44E1C8EDB0C9AFE5D4 +:10817000ED52E1C8121318F77BF5ED3804E602283A +:10818000F9F1ED3906C93E0DCD79813E0A18EAEBC9 +:108190007CCD95817DF50F0F0F0FCD9E81F1E60F00 +:1081A000C69027CE402718D1E3F57E23B72805CD0A +:1081B000798118F6F1E3C90405C8CB2ACB1B10FA64 +:1081C000C9F5E5CD2C827B2F5F7A2F57E1F1C9F5F8 +:1081D000C5E5AFCD1082F5CD2C82F1B72803131879 +:1081E000067B2F5F7A2F57E1C1F1C9F5E5CD2C82CF +:1081F000EBE1F1C9F5E5C53E01CD1082F5CD2C824C +:10820000F1EBB72007AF935F3E009A57C1E1F1C988 +:10821000CB782809AF914F3E0098473E01CB7AC8F2 +:10822000F5AF935F3E009A57F1EE01C92100003E81 +:1082300011CB13CB123DC8CB15CB14ED4230F20954 +:1082400018EFF5C5E5784251676BED4CED6CED5CD0 +:1082500079858257E1C1F1C9C5E5F57CEE80677883 +:10826000EE8047F1A7ED42E1C1C95E2356CD4282BF +:10827000722B73C9B7C8CB28CB19CB1CCB1D3D20A3 +:10828000F5C9E3D5DDE5DD210000DD39DD5609DD89 +:108290007409DD5E08DD7508D5C5F5DD6E0462ED97 +:1082A0006CDD5605ED5C1959DD5607ED5C19DD5E98 +:1082B0000650ED5C19E5DD5E04DD56FEED5CDD6E1D +:1082C00005DD6607ED6C19DD4606ED4C09E5DD5E62 +:1082D00004DD5607ED5CDD6E05DD6606ED6CAF195D +:1082E00017F5DD5E04DD5606ED5C4A0600AF0917A2 +:1082F00055C14CE10984C1814D47EBF1D1D1DDE19C +:10830000D133333333C9EBE3F5DDE5DD210000DDA7 +:1083100039C5D5DD5609DD7409DD5E08DD7508CD8A +:10832000FA83E1C1CD5A84DDE1F1D13333C9EBE306 +:10833000F5DDE5DD210000DD39C5D5DD5609DD744B +:1083400009DD5E08DD7508AFCDB683CDFA83E1C1E6 +:10835000B7CC5A84C45284DDE1F1D13333C9EBE3A5 +:10836000F5DDE5DD210000DD39C5D5DD5609DD741B +:1083700009DD5E08DD7508CDFA83DDF9DDE1F1D1B7 +:108380003333C9EBE3F5DDE5DD210000DD39C5D58B +:10839000DD5609DD7409DD5E08DD75083E01CDB6E8 +:1083A00083CDFA83B72006CD5A84CD5284DDF9DD22 +:1083B000E1F1D13333C9CB7A2818424BDD6607DDB2 +:1083C0006E06CD5A84CD52845059DD7407DD750692 +:1083D0003E01DDCBFF7EC8F5DD46FFDD4EFEDD66EE +:1083E000FDDD6EFCCD5A84CD5284DD70FFDD71FE63 +:1083F000DD74FDDD75FCF1EE01C9F5210000010021 +:1084000000DD36F82118021937DDCBFC16DDCBFD77 +:1084100016DDCBFE16DDCBFF16DD35F8282ECB1191 +:10842000CB10CB15CB14ED5238DD201078DD96073C +:1084300038D5200879DD960638CD180479DD960602 +:108440004F78DD9E074730C12BA718BDF1E5606965 +:10845000C1C92CC024C00CC004C9F57D2F6F7C2F6E +:1084600067792F4F782F47F1C9F5AF956F3E009C84 +:10847000673E00994F3E009847F1C9C5D55E235627 +:10848000234E2346EBCD8282C39B84C5D55E235603 +:10849000234E2346EBCD0683C39B84EB702B712BBD +:1084A000722B73C9F57E83775F237E8A7757237E8D +:1084B00089774F237E8877472B2B2BF1C9E3F5D59E +:1084C0007B96235F7A9E23577B96237A9E23C3D184 +:1084D000843004EB2329195E2356EBD1F1E3C9E381 +:1084E000F5C54E2346237BEDB12002232309C30E9D +:1084F00085E3F5C54E23462378B1280D0B7B9623E3 +:1085000020F57A9620F12323230909C30E85090952 +:108510007E23666FC1F1E3C9E1C5D5DDE5DD21004C +:1085200000DD39E9E1C5D5DDE5DD210000DD395E9D +:10853000235623EB39F9EBE9DDF9DDE1D1C1C9DDE2 +:10854000F9DDE1D13333C9E9CD2485F8FF210600F7 +:1085500039EB2123C1010200EDB02A18C52323E520 +:108560000303C50150C1C5CD89C0F1F14D44E1718E +:10857000237021000039E5210000E52A18C52323D6 +:108580004E2346C5CD3BC0F1F1F1DD36FC60DD3652 +:10859000FD0021000039E5210100E52A18C523234B +:1085A0004E2346C5CD3BC0F1F1F1210200E52E0876 +:1085B000394D442A18C523235E2356CD09C1F1C382 +:1085C0003885D52A18C523235E2356CD09C0D1C9C5 +:1085D000CD2485FCFF21000039EB2125C1010400D9 +:1085E000EDB0DD4602DD70FEDD4604DD70FF2104E6 +:1085F00000E52B2BC3B0854DC3B2852A18C52323B4 +:108600005E23C3BA85CD09C1F1C33885CD2485FC6D +:10861000FF21000039EB2129C1010400EDB0DD4646 +:1086200002DD70FEDD4604DD70FF210400E52B2B2A +:10863000C3B0854DC3F8852A18C5C3B68523C300CA +:108640008623C3BA85CD09C1F1C33885CD2485FC05 +:10865000FF21000039EB212DC1010400EDB0DD4602 +:1086600002DD70FEDD4604DD70FF210400E52B2BEA +:10867000C3B0854DC3F8852A18C5C33A8623C3B84D +:108680008523C30286CD09C1F1C33885CD2485FC7D +:10869000FF21000039EB2131C1010400EDB0DD46BE +:1086A00002DD70FEDD4604DD70FF210400E52B2BAA +:1086B000C3B0854DC3F8852A18C5C33A8623C37E47 +:1086C0008623C3BA85CD09C1F1C33885CD2485FC85 +:1086D000FF21000039EB2135C1010400EDB0DD467A +:1086E00002DD70FEDD4604DD70FF210400E52B2B6A +:1086F000C3B0854DC3F8852A18C5C33A8623C37E07 +:108700008623C3C286CD09C1F1C33885C5FDE5DD29 +:10871000E5D5DDE1CD4EB6E5DDE5C12A18C523235B +:108720005E2356CD09C1F1DDE1FDE1C1C9CD24854E +:10873000F8FF21000039EB2139C1010700EDB0DD60 +:108740004602DD70FADD4604DD70FBDD4608DD70B3 +:10875000FCDD460ADD70FDDD460CDD70FE21070004 +:10876000E52E02C3B0854DC3F8852A18C5C33A86E5 +:1087700023C37E8623C3C286CD09C1F1C33885C514 +:10878000D5CD9487E56CE5E54D44EBCD2D87E1E152 +:10879000E1D1C1C90100005950CDD08501800058F8 +:1087A00050CD0C86218000C9CD2485FCFF2100001E +:1087B00039EB2140C1010300EDB0DD4602DD70FE62 +:1087C000210300E52BC3B0854DC3F8852A18C5C326 +:1087D0003A8623C37E8623C3C286CD09C1F1C3383E +:1087E00085CD2485FEFF21000039EB2143C1010224 +:1087F00000EDB0DD4602DD70FF210200E5C3B0856B +:108800004DC3F8852A18C5C33A8623C37E8623C381 +:10881000C286CD09C1F1C33885CD24850000210C65 +:1088200000ED4B18C50946236668EB7BB228166B32 +:108830006246236668DD4E02DD4603ED42280621CE +:1088400006001918E1EBC33885C5DDE5D5DDE1CDBE +:1088500019887DB4281BDDE5D1CDE187210A00ED23 +:108860004B18C509E5DDE5D1CD19884D44E17123EB +:1088700070DDE1C1C9CD2485FCFFFDE5110C00CD03 +:108880000489DD4E0271DD46032370DD6E04FD7543 +:1088900002DD6605FD7403DD6E08FD7504DD660905 +:1088A000FD7405AFFD7706FD7707DD6E0AFD7508DF +:1088B000DD660BFD7409DD6E0CFD750ADD660DFDD0 +:1088C000740B210C00ED4B18C5097E23B6210C005A +:1088D000ED4B18C5092010FDE5C1712370210A0078 +:1088E000ED4B18C509181246236668EB21060019DE +:1088F0007E23B62106001920EEFDE5C1712370FD2F +:10890000E1C33885CDE3B2E5FDE1C9FDE5DDE5C5AF +:10891000D5DD210000FD210000FDE5210200394EDA +:108920002346E1097EB72850FDE5E1095ECDDF84ED +:108930000A00212C2E3149696A6B6C726689618943 +:10894000578961896189528952895C895C895C890E +:1089500052890102001812010300180D01040018C9 +:10896000080105001803010600DD09210200394E47 +:108970002346DD09FD2318A1DDE5E1F1F1DDE1FD8F +:10898000E1C9CD18857BFE80300621070009180C4F +:10899000FECC38083EDFBB3803696023C33885CD81 +:1089A00018850100001A5FCD8289C33885CD1885EE +:1089B000010500C3A589C5D5010000CD0B89F1C112 +:1089C000C9C5D5010200CD0B89F1C1C9C5D50103C7 +:1089D00000CD0B89F1C1C9CD24850000FDE511252D +:1089E00000CD04892A18C55E235613722B73FDE54A +:1089F000E1732372DD6E02FD7502DD6603FD740313 +:108A0000FD7104FD7005DD6E08FD7506DD6609FD6E +:108A10007407DD6E0AFD7508DD660BFD7409AFFD98 +:108A2000770AFD770BFD770CFD770DFD770EFD774F +:108A30000FFD7710FD7711FD7712FD7713FD771489 +:108A4000FD7715FD7716FD7717FD7718FD7719FD72 +:108A5000771AFD771BFD771CFD7721FD7722FD77C7 +:108A600023FD7724FD771DFD771EFD771FFD772001 +:108A7000FDE5E1FDE1C33885CD24850000FDE5DDA0 +:108A80006E02DD6603E5FDE1110000DD6E04DD66CA +:108A900005197EB728210114806B6278AC67ED421E +:108AA0003015FD6E1DFD661E19E5DD6E04DD6605E3 +:108AB0001946E1701318D4FD6E1DFD661E193600AF +:108AC000FDE1C33885CD24850000FDE55950211511 +:108AD00000DD4E02DD4603097E23666FE5FDE121E0 +:108AE0001500097E23B62009211500097323721889 +:108AF00019FD7E13FDB614280BFD6E13FD6614E5FB +:108B0000FDE118EDFD7313FD721421130019772395 +:108B10007721110019DD4E0271DD46032370FDE15E +:108B2000C33885C5FDE5DDE52115001946236668D6 +:108B3000E5DDE17DB42814DDE5D1DD6E19DD661AD1 +:108B4000CD4785DD6E13DD661418E5DDE1FDE1C17D +:108B5000C9CD24850000FDE5DD6E02DD6603E5FD7F +:108B6000E1DD6E04DD66057EFD860277237EFD8EE7 +:108B70000377DD6E08DD66097EFD860477237EFDC2 +:108B80008E0577FD6E11FD6612E5FDE17DB420D105 +:108B9000FDE1C33885CD24850000211500DD4E029E +:108BA000DD46030946236668EB7BB2281B211000D3 +:108BB000194E0600DD6E04DD6605A7ED422003EBCD +:108BC00018082113001918DC6F67C33885CD248578 +:108BD000F8FFFDE5DD6E02DD6603E5FDE1FD6E15E6 +:108BE000DD75F8FD6616DD74F9FDE5E17DB4CA8634 +:108BF0008DDD7EF8DDB6F92811DD5EF8DD56F9CDA4 +:108C0000CD8BDD75F8DD74F918E7FD7E11FDB61228 +:108C1000CA9C8CFD6E11FD66120115000946236683 +:108C200068FDE5C1A7ED42FD6E11FD66120115005C +:108C3000092009E5FD6E11FD66121850462366688D +:108C4000DD75F8DD74F9211300DD4EF8DD46F90914 +:108C500046236668FDE5C1A7ED422819211300DD12 +:108C60004EF8DD46F9097E23B6280A21130009567D +:108C700023666A18CB211300DD4EF8DD46F9097E24 +:108C800023B6281821130009E5211300094623669D +:108C900068011300094E2346E1712370FD6E13DD58 +:108CA00075F8FD6614DD74F93E04FDAE21FDB622B3 +:108CB000C2528DFD6E11DD75FCFD6612DD74FDFD89 +:108CC0006E23DD75FEFD6624DD74FF5E2356CD77D1 +:108CD000AFDD6EFEDD66FF23235E2356CD77AFDD6D +:108CE0007EFCDDB6FD2820212100DD4EFCDD46FDA9 +:108CF000093E04AE23B6280F2111000956DD72FC8F +:108D00002366DD74FD18D8DD7EFCDDB6FD28432129 +:108D10002300DD4EFCDD46FD0946DD70FE2366DDE9 +:108D200074FF210600ED4B18C509E5DD6EFEDD661A +:108D3000FF5E2356E1732372210800ED4B18C5092D +:108D4000E5DD4EFEDD46FF030369604E2346E1711B +:108D50002370FD4E21FD4622210000CD58823009AE +:108D6000FD5E23FD5624CD77AFFDCB0B762011FDA4 +:108D70007E1DFDB61E2809FD5E1DFD561ECD77AF7A +:108D8000FDE5D1CD77AFDD6EF8DD66F9FDE1C338E5 +:108D900085C5FDE5DDE52115001946236668E5DD9D +:108DA000E17DB42808DDE5D1CDCD8B18F1DDE1FD05 +:108DB000E1C1C9CD24850000FDE5211500DD5E027D +:108DC000DD5603195623666AE5FDE17DB4283D2191 +:108DD0000A00FDE5C109DD7E04DD56052F5F7A2F0F +:108DE000577EA377237EA277210A00097EDDB6088D +:108DF00077237EDDB60977210A00097EDDAE0A778A +:108E0000237EDDAE0B772113000918B811DCC4CD29 +:108E100084ACFDE1C33885C5FDE5DDE5D5DDE121A7 +:108E200015001946236668E5FDE1211D001946235A +:108E300066680100903E80AC67ED42302EDD4E1D2D +:108E4000DD461E210000CD58823020DD6E1DDD661E +:108E50001E29E5210800ED4B18C5094E2346E109FE +:108E60002B2B46DD701D2366DD741EDD6E1FDD6657 +:108E7000200100903E80AC67ED42302EDD4E1FDDBC +:108E80004620210000CD58823020DD6E1FDD662097 +:108E900029E5210800ED4B18C5094E2346E1092BB1 +:108EA0002B46DD701F2366DD7420FDE5E17DB428CF +:108EB00011FDE5D1CD178EFD6E13FD6614E5FDE1C4 +:108EC00018E8DDE1FDE1C1C9CD2485D2FFFDE5AFA4 +:108ED000DD77F9DD77FADD77FBDD77FC5950CDF1F1 +:108EE000840600010002010301040105010104F3ED +:108EF000906C9002902B90798F8A8FFD8E211500B7 +:108F0000DD4E02DD46030946236668E5FDE17DB4DA +:108F10002864FDCB0A46284FDD6E08DD6609E5DDD5 +:108F20004E04DD4605CD3191E1FDCB0A6E2838FDBA +:108F30004E100600DD6E08DD6609A7ED422028FD13 +:108F40006E23DD75FDFD6624DD74FEFDE5D146234F +:108F50006668CD4785DD6EFDDD66FE23232366AFA3 +:108F6000B42004FD210000FDE5E17DB428A0FD6EE4 +:108F700013FD66141895C3F390DD5E024BDD5603B6 +:108F800042211900CD2991C3F390210A00DD4E0240 +:108F9000DD4603097EE6FC77212B0039E52B2B4DBE +:108FA00044DD5E02DD5603CD518BE1210800DD4E2C +:108FB00002DD4603095E2356D5210600095E2356CD +:108FC000D5DD6EFBDD66FCE5DD4EF9DD46FA110010 +:108FD00000CD2D87E1E1E1210000E52E11DD5E02EB +:108FE000DD5603195E2356211100DD4E02DD4603D6 +:108FF00009462366680117000946236668010301D4 +:109000001826211100DD4E02DD4603095623666A4B +:10901000E5FDE15950CDCD8B210000E5010301FDB7 +:10902000E5D1FD6E17FD6618C3EF90211500DD4EEA +:1090300002DD46030946236668E5FDE17DB4282983 +:10904000DD6E08DD6609FDE5C1ED422814FDCB0AA1 +:109050005E280EDD6E08DD6609E5010302CD319163 +:10906000E1FD6E13FD661418D0C3F390211100DDED +:109070004E02DD4603097E23B6200E210400ED4B8F +:1090800018C50936012377186A210A000923CB6E17 +:109090002025DD6E08DD6609E52111005950195EB5 +:1090A000235621110009462366680117000946234B +:1090B00066680101041838211100095623666AE523 +:1090C000FDE1110A00197EF603776A62E523E54A9D +:1090D00042FDE5D1CDB38DE1E1210000E5DD5E0289 +:1090E0004BDD5603422E170946236668010501CD64 +:1090F0004785E1FDE1C338852346211100DD5E028D +:10910000DD5603195E2356CD958BEB0178C1CD78E2 +:109110008A211100DD4E02DD4603095E235621112E +:109120000009462366680119000946236668C3479B +:1091300085FDE5D1FD6E17FD6618C34785C5DDE5E4 +:10914000F5F5D5DDE121020039AF7723772B2B2B05 +:10915000772377210A00ED4B18C5097E23666F46F9 +:10916000236668E5210E00194E2346E1A7ED42284B +:1091700003CD6092DDCB0A46CA1B9221000039E57F +:10918000CD5692E121000039CD2192E5DD6E06DD5C +:109190006607E5210400394E2346C5234E234611B8 +:1091A0000000CD2D87E1E1E1DD5E1DDD561E210AC7 +:1091B00000ED4B18C509CDAC92E5210200394E23D4 +:1091C00046E109010400094D4421020039CD4192D4 +:1091D000CDAC924D44DD6E08DD6609A7ED4201FC81 +:1091E000FF094D44CDC192210000394E234623CDC5 +:1091F000419246236668CDB092010500094D44DDD9 +:109200005E06DD5607CD8C86210000394E234603CD +:109210000323CDCA92DDE5D1CD238BE1E1DDE1C1B0 +:10922000C94E2346235E2356CDD085DD4E08DD464C +:1092300009DD5E06DD5607CD0C86DD6E08DD6609AC +:10924000C95E2356CDD085DD5E1DDD561E210A0088 +:10925000ED4B18C509C923234D44DDE5D1C3518B1E +:10926000DD5E0EDD560FC34988210A00ED4B18C59F +:109270000946236668232346236668CD47854D4407 +:10928000DD6E06DD6607A7ED42EB010200CDCF8162 +:10929000FDE5E119EBC9CD47854D44DD6E08DD667E +:1092A00009A7ED42EB010200CDCF81C97E23666F95 +:1092B0000104000946236668C34785DD4E08DD4684 +:1092C00009DD5E06DD5607C34C865E23561313CDBB +:1092D000D085DD5E1DDD561EC30C87CD1885CD946F +:1092E00087E56CE5E54D44EBCD2D87E1E1E1DD5E01 +:1092F00002DD5603CD238BC33885C5D5CDC58AE1A4 +:10930000E1C9DDE5C5D5210A00394E2346C52B2B21 +:109310002B4E2346C5210600394E2346CDD789F171 +:10932000F1E5DDE10117000936C823368EDD361977 +:109330003DDD361A91DD361BFADD361C92DDE5E1A6 +:10934000F1F1DDE1C9CD1885FDE5D5FDE1DD6E0862 +:10935000DD6609E5CDC88EE13E01DDAE04DDB60572 +:109360002054FD4E1047DD6E08DD6609ED422046B3 +:10937000FD7E0AE603283FDD6E08DD6609E5FD5E39 +:1093800011FD5612FD6E11FD66120E17CDE393E12D +:10939000FDCB0A662820FD4E100600C5FD5E11FDBE +:1093A0005612FD6E11FD66120E17094623666801FE +:1093B0000401CD4785E1210102DD4E04DD4605A70C +:1093C000ED42200BDD6E08DD6609E5CDD493E1FDAD +:1093D000E1C33885FD5E11FD5612FD6E11FD66126A +:1093E0000117000946236668010102C34785FDE5B0 +:1093F000DDE5D5DDE1C5FDE1210A0019CB76DD5EB5 +:109400001DDD561E210A00ED4B18C5097E23666F2F +:109410000104000946236668CA9E94CD4785294DFC +:1094200044DD6E08DD6609A7ED42EB010200CDCFF9 +:1094300081210600394623666819E5DD5E1DDD568B +:109440001E210A00ED4B18C5097E23666F23237E7B +:1094500023666FCD4785EBDD6E06DD6607A7ED520F +:10946000EB010200CDCF81FDE5E119EBC1CDCF923B +:10947000DD5E08DD5609010200CDCF8121060039ED +:1094800046236668194D4403C5DD5E1FDD5620CDB9 +:109490006992C1CDD085DD5E1FDD56201823CD96A3 +:1094A000922106003946236668194D4403C5DD5EE6 +:1094B0001DDD561ECD6992C1CDD085DD5E1DDD5608 +:1094C0001ECD0C87DDE1FDE1C9C5DDE5F5F5D5DD96 +:1094D000E121020039AF7723772B2B2B77237721DC +:1094E0000A00ED4B18C5097E23666F46236668E5C2 +:1094F000210E00194E2346E1A7ED422803CD6092CC +:10950000DDCB0A46285E21000039E5CD5692E121E7 +:10951000000039CD2192E5DD6E06DD6607E5210408 +:1095200000394E2346C5234E2346DDCB0A4E28077D +:10953000DD5E1016001803110000CD2D87E1E1E17A +:10954000DD7E0AE682280EDD7E0AE682EE822805AE +:10955000CD6A951803CDBB92210000394E2346C534 +:10956000CD7995E1E1E1DDE1C1C9DD4E08DD4609D6 +:10957000DD5E06DD5607C3CC86234E2346DDE5D1EE +:10958000C3EE93C5D5E1E1C9CD24850000FDE5DD3D +:109590006E0ADD660BE5DD6E08DD6609E5CDCE956C +:1095A000F1F1E5FDE1010A00097EF60377DD460CE5 +:1095B000FD7010FD361745FD361893FD3619C9FDAF +:1095C000361A94FD361B83FD361C95C3708ADD5E0A +:1095D00002DD5603C3D789CD2485FCFFFDE52104B8 +:1095E0000039EB2145C1010200EDB0AFDD77FCDDB4 +:1095F00077FD010980DD6EFCDD66FD78AC67ED422C +:10960000D28896DD7EFCC631DD77FE213100DD4E4D +:10961000FCDD46FD09E5211600E5E5010300DD5E00 +:10962000FCDD56FDCDCF810E18CD4282DD6E08DD0A +:109630006609A7ED520E3009E50E03DD5EFCDD562E +:10964000FDCDF4810E18CD4282DD6E04DD66051974 +:10965000EBC1CD8895F1F1F1E5FDE1210400394D33 +:1096600044FDE5D1CD1097FDE5DD5E024BDD5603EF +:1096700042211B000946236668C1CD4785DD34FCC5 +:109680002003DD34FDC3F295213000E52E16E5E51B +:109690002E48DD4E08DD4609094D44211800DD5EE7 +:1096A00004DD5605CD2A97F1F1F1E5FDE1015AC13E +:1096B000CD0F97FDE5DD5E024BDD560342211B0019 +:1096C000097E23666FC1CD4785210800E52E16E58A +:1096D000E52E48DD4E08DD4609094D44213000DD08 +:1096E0005E04DD5605CD2A97F1F1F1E5FDE1015C5F +:1096F000C1CD0F97FDE5DD5E024BDD560342211B18 +:10970000000946236668C1CD4785FDE1C33885EB76 +:10971000CD788AFDCB0AE6C9DD4E0ADD460B094D40 +:109720004421D0FFDD5E08DD560919EBC38895CDD5 +:109730001885FDE5D5FDE1DD6E08DD6609E5CDC8DE +:109740008EE13E01DDAE04DDB6052078FD4E10470A +:10975000DD6E08DD6609ED42206AFD7E0AE603281B +:1097600063FD7E0AEE04FD770ADD6E08DD6609E51D +:10977000FD5E11FD5612FD6E11FD66120E170946B3 +:10978000236668010202CD4785E1210000E501035F +:1097900001FDE5D1FD6E17FD6618CD4785E1FDCBD6 +:1097A0000A662820FD4E100600C5FD5E11FD56120A +:1097B000FD6E11FD66120E1709462366680104014D +:1097C000CD4785E1210102DD4E04DD4605A7ED42CE +:1097D000200BDD6E08DD6609E5CDD493E1FDE1C324 +:1097E0003885C5DDE5F5F5D5DDE121020039AF7736 +:1097F00023772B2B2B772377210A00ED4B18C509F4 +:109800007E23666F46236668E5210E00194E2346C7 +:10981000E1A7ED422803CD6092DDCB0A46CAB0989D +:1098200021000039E5CD5692E1210000394E234652 +:10983000235E2356CDD085DD4E08DD4609DD5E066C +:10984000DD5607CD0C86DDCB0A4E2825DDCB0A562A +:10985000281FCD6A95DD6E08DD6609E5DD6E06DD43 +:109860006607E5210400394E2346C5234E234618DA +:1098700023CDBB92DD6E08DD6609E5DD6E06DD6693 +:1098800007E5210400394E2346C5234E2346DDCB90 +:109890000A4E2807DD5E1016001803110000CD2DBA +:1098A00087E1E1E1210000394E2346C5CD7995E1FC +:1098B000E1E1DDE1C1C9CD24850000FDE5DD6E0AF1 +:1098C000DD660BE5DD6E08DD6609E5CDCE95F1F1CF +:1098D000E5FDE1010A00097EF60777DD460CFD7023 +:1098E00010FD36172FFD361897FD3619E2FD361A92 +:1098F00097FD361B83FD361C95C3708ACD1885FDF8 +:10990000E5D5FDE1DD6E08DD6609E5CDC88EE12116 +:109910000102DD4E04DD4605A7ED4220463EFFDD97 +:10992000AE08DDB609203CFDCB0B66E52805010538 +:10993000011803010201FDE5D1FD6E17FD6618CD8A +:109940004785E1FD4E100600C5FD5E11FD5612FD76 +:109950006E11FD66120E170946236668010103CDDC +:109960004785E1210102DD4E04DD4605A7ED4220D9 +:10997000463EFEDDAE08DDB609203CFDCB0B66E5BC +:1099800028050105011803010201FDE5D1FD6E174F +:10999000FD6618CD4785E1FD4E100600C5FD5E1140 +:1099A000FD5612FD6E11FD66120E170946236668FC +:1099B000010203CD4785E1FDE1C33885CD2485FE55 +:1099C000FFFDE5DD6E0ADD660BE5DD6E08DD66098F +:1099D000E5CDCE95F1F1E5FDE1010A0009CBC6DD4B +:1099E000460CFD7010FD3617FCFD361898FD361933 +:1099F0003DFD361A91FD361BFAFD361C9221FF0003 +:109A0000E52E14E52E28E521E4FFCD1897F1F1F1BC +:109A1000DD75FEDD74FF011D0009E5110300CDE3D6 +:109A2000B24D44E1712370015FC1CD609A21FE0007 +:109A3000E52E14E52E28E521C8FFCD1897F1F1F1A8 +:109A4000DD75FEDD74FF011D0009E5110700CDE3A2 +:109A5000B24D44E17123700162C1CD609AC3708A36 +:109A6000DD5EFEDD56FFCD788ADD4EFEDD46FFFD74 +:109A7000E5D1FD6E1BFD661CCD4785C9CD1885FD62 +:109A8000E5D5FDE1DD6E08DD6609E5CD4593E12113 +:109A90000302DD4E04DD4605A7ED422046FDCB0A5C +:109AA0005E28403E08DDAE08DDB609FD5E1DFD56B0 +:109AB0001E200FCD4EB67DB42815CDE89A2B36006A +:109AC000180DCDEE9A233600CDE89ADD46087021B8 +:109AD0000000E5010301FDE5D1FD6E17FD6618CD1F +:109AE0004785E1FDE1C33885FD5E1DFD561ECD4E67 +:109AF000B6FD4E1DFD461E09C9C5DDE5F5F5D5DDF2 +:109B0000E121020039AF7723772B2B2B77237721A5 +:109B10000A00ED4B18C5097E23666F46236668E58B +:109B2000210E00194E2346E1A7ED422803CD609295 +:109B3000DDCB0A46CAB99B21000039E5CD5692E13A +:109B400021000039CD2192E5DD6E06DD6607E521B5 +:109B50000400394E2346C5234E2346DDCB0A4E284A +:109B600007DD5E1016001803110000CD2D87E1E11E +:109B7000E1DDCB0A7EDD4E08DD4609DD5E06DD5601 +:109B8000072005CDCC861803CD4C86DD5E1DDD5645 +:109B90001E210A00ED4B18C5094623666801040022 +:109BA0000946236668CD969268603946236668192F +:109BB0004D4421020039CDCA92E1E1DDE1C1C9DDA8 +:109BC000E5C5D5210C00394E2346C52B2B2B4E2342 +:109BD00046C52B2B2B4E2346C5210800394E234664 +:109BE000CD8895F1F1F1E5DDE1010A0009CBDE0157 +:109BF00069C1DDE5D1CD788ADD3619F9DD361A9AED +:109C0000DD36177CDD36189AC33D93C5D5E1E1C931 +:109C1000C5DDE5F5F5D5DDE121020039AF77237724 +:109C20002B2B2B772377210A00ED4B18C5097E23B8 +:109C3000666F46236668E5210E00194E2346E1A7AC +:109C4000ED422803CD6092DDCB0A462815210000A5 +:109C500039E5CD5692E1210000394E2346C5CD7934 +:109C600095E1E1E1DDE1C1C9CD24850000FDE5DD3F +:109C70006E0ADD660BE5DD6E08DD6609E5CDCE9585 +:109C8000F1F1E5FDE1011D0009DD4E0C71DD460D30 +:109C90002370FD360A01FD360B00FD36170BFD362D +:109CA000189CFD361910FD361A9CFD361B83FD36B7 +:109CB0001C95C3708ACD24859EFFFDE5212300DD20 +:109CC0004E02DD46030946DD709E2366DD749F2A41 +:109CD0001AC57DB42066110800CDE3B2221AC50171 +:109CE000060009E5111600CDE3B24D44E171237081 +:109CF000210600ED4B1AC5095623666A1114001996 +:109D0000AF772377210600ED4B1AC5097E23666FD6 +:109D100072210600ED4B1AC5095623666A110E0022 +:109D200019AF772377210600ED4B1AC50946236644 +:109D3000680110000977237723772377DD6E9EDD96 +:109D4000669F23233E1023AE2BB6204B210600DD59 +:109D50004E9EDD469F096E67E52A1AC5C1712370C4 +:109D60002A1AC52323E5CD2FA2E171237021040017 +:109D7000ED4B1AC509E5210600DD5E9EDD569F19F3 +:109D80005E2356234E2346EB3E10CD43A2E1CDE5A4 +:109D9000A1CD22A2CDF890DD6E9EDD669F232346E5 +:109DA0002366680110903E80AC67ED42DAC39EDD09 +:109DB0006E9EDD669F23234E2346211210CD5882CE +:109DC000DAC39E210600ED4B1AC50946236668DDFD +:109DD00075A2DD74A3211400DD4EA2DD46A3097E29 +:109DE00023B6280A211400095623666A18E12104C3 +:109DF00000DD4E9EDD469F094E2346211100DD5EAB +:109E000002DD5603195E2356CD958BDD75A0DD74FA +:109E1000A1011D00094E2346DD5E02DD5603CD780B +:109E20008A0169C1DD5EA0DD56A1CD788ADD5EA024 +:109E30004BDD56A142211900CD2991DD6E9EDD66D4 +:109E40009F23235E2356CDBD8410100300B59E557D +:109E50009E6D9E8D9E211D00DD4E02DD4603094E46 +:109E60002346DD5EA2DD56A3CD31B61848210E0093 +:109E7000DD4EA2DD46A309E5211D00DD4E02DD46D3 +:109E800003095E2356CD18AC4D44E11825211D0071 +:109E9000DD4E02DD4603095E2356CD29AC7C079FCB +:109EA0004F41E5211000DD5EA2DD56A319D17323D9 +:109EB0007223712370DD5E024BDD560342211900CF +:109EC000CD2991DD6E9EDD669F23234623666801C2 +:109ED0001E10A7ED42C2FFA0AFDD77ACDD77ADDD90 +:109EE00077AEDD77AF210600ED4B1AC50946236634 +:109EF00068E5FDE1210100E5217EC1E5CD89C0F1E4 +:109F0000F1DD75A0DD74A121080039E5210000E52F +:109F1000DD6EA0DD66A1E5CD3BC0F1F1F1DD36A837 +:109F200060DD36A90021080039E5210100E5DD6E7C +:109F3000A0DD66A1E5CD3BC0F1F1F1FDE5E17DB429 +:109F4000CA20A0FD7E0EFDB60FCA14A03E01FDAED4 +:109F50000EFDB60F20296F67E52E64E5CD4AA2C538 +:109F6000E56F67E52E64E5CD59A2C5E5FDE5218BDA +:109F7000C1E521200039E5CD57B5210E0018682133 +:109F80000000E52E64E5FD6E0EFD660F7C079F4F19 +:109F900041C5E5CD68A2CD8383C5E5210000E52E4E +:109FA00064E5FD6E0EFD660F7C079F4F41C5E5CD54 +:109FB00068A2CD2E83C5E5210000E52E64E5CD4ADB +:109FC000A2C5E5210000E52E64E5CD59A2C5E5FD59 +:109FD0006E0EFD660FE5FDE521AEC1E5212A0039D3 +:109FE000E5CD57B521180039F921100039E5FD5E9E +:109FF0000EFD560F7A079F4F41C5D5CD68A2EBE104 +:10A00000CDA48421140039EBCD4EB6E521160039DC +:10A01000CDDAA1F1FD6E14FD6615E5FDE1C33B9FB0 +:10A020006F67E52E64E5DD4EAEDD46AFDD6EACDD7F +:10A0300066ADCD8383C5E56F67E52E64E5DD4EAE85 +:10A04000DD46AFDD6EACDD66ADCD2E83C5E52169A5 +:10A05000C1E5E521EEC1E521220039E5CD57B52165 +:10A06000100039F921140039EBCD4EB6E521160068 +:10A0700039CDDAA1F1DD5EA0DD56A1CD09C0210602 +:10A0800000ED4B1AC50946236668E5FDE17DB4285D +:10A090000EFDE5D1CD77AFFD6E14FD661518EB21F1 +:10A0A0000600ED4B1AC509E5111600CDE3B2EBE150 +:10A0B000732372210600ED4B1AC5095623666A11F7 +:10A0C000140019AF772377210600ED4B1AC5097EDE +:10A0D00023666F72210600ED4B1AC5095623666A86 +:10A0E000110E0019AF772377210600ED4B1AC50931 +:10A0F000462366680110000977237723772377DDED +:10A100006E9EDD669F232346236668011F10A7ED20 +:10A1100042C2D5A1210600ED4B1AC5094623666847 +:10A12000DD75A0DD74A1211400DD4EA0DD46A1097E +:10A130007E23B6280A211400095623666A18E121F5 +:10A140000600DD4E9EDD469F096E67E52A1AC5C1F1 +:10A150007123702A1AC52323E5CD2FA2E171237044 +:10A16000210400ED4B1AC509E5210600DD5E9EDDE8 +:10A17000569F195E2356234E2346EB3E10CD43A235 +:10A18000E1CDE5A1CD22A2CDF890211400DD4EA0B5 +:10A19000DD46A109E5111600CDE3B2EBE1732372B0 +:10A1A000211400095623666ADD75A0DD74A101142F +:10A1B0000009AF772377DD6EA0DD66A170210E0068 +:10A1C000DD4EA0DD46A10977237721100009772312 +:10A1D0007723772377FDE1C338854D44DD5EA0DD2D +:10A1E00056A1C309C17123702A1AC54E23462111F5 +:10A1F00000DD5E02DD5603195E2356CD958BEB0123 +:10A200006AC1CD788A2A1AC523234E23462111001C +:10A21000DD5E02DD5603195E2356CD958BEB017290 +:10A22000C1C9CD788A210400ED5B1AC5194EC92138 +:10A230000600DD4E9EDD469F095E2356234E2346D3 +:10A24000EB3E08CD748206004DC9FD4E12FD46134B +:10A25000FD6E10FD6611C38383FD4E12FD4613FD96 +:10A260006E10FD6611C32E83FD4E12FD4613FD6E6A +:10A2700010FD6611C38282C5D5210600394E2346E2 +:10A28000C5210400394E2346CDC88EE1E1E1C9CD98 +:10A290002485CEFFFDE5DD36D800210000E5C5CDE3 +:10A2A00089C0F1F1DD75D4DD74D5DD36F02BDD36F6 +:10A2B000F100DD36F21ADD36F300DD36F400DD7E26 +:10A2C000D8FE732018DD6ED9DD66DADD75F0DD7439 +:10A2D000F1DD6EDBDD66DCDD75F2DD74F3DD7ED88D +:10A2E000FE422807DD7ED8FE4D2037DD4EDD06001C +:10A2F000C5CDBCA5D5DD4EDBDD5EF0DD56F1CDC5AF +:10A30000A5D5CDD9A5D5CDCCA5C1CD8895F1F1F1F7 +:10A31000E5FDE1DD7ED8FE4D2004FDCB0AF6DD36FD +:10A32000F401DD7ED8FE54202CDD4EDD0600C5CDC7 +:10A33000BCA5D5DD4EDBDD5EF0DD56F1CDC5A5D586 +:10A34000CDD9A5D5CDCCA5C1CDB698F1F1F1E5FD1E +:10A35000E1DD36F401DD7ED8FE44202CDD4EDD0645 +:10A3600000C5CDBCA5D5DD4EDBDD5EF0DD56F1CD03 +:10A37000C5A5D5CDD9A5D5CDCCA5C1CDBF9BF1F176 +:10A38000F1E5FDE1DD36F401DD7ED8FE4C202F2124 +:10A390000C003901120009E5CDBCA5D5DD4EDBDD91 +:10A3A0005EF0DD56F1CDC5A5D5CDD9A5D5CDCCA5D1 +:10A3B000C1CD689CF1F1F1E5FDE1DD36F401DD7E12 +:10A3C000D8FE41204C212300DD4E02DD460309E585 +:10A3D000212B0039EBE1732372DD6EDEDD66DFDDFC +:10A3E00075F7DD74F8DD6EE0DD66E1DD75F9DD74CD +:10A3F000FA211600394E2346235E2356DD71FBDD1C +:10A4000070FCDD73FDDD72FEDD5E02DD5603CDE521 +:10A41000A5DD7ED8FE53206C210C00394D44DD5E55 +:10A42000D4DD56D5CDDAA8212300DD4E02DD46036A +:10A4300009E5110400CDE3B2EBE17323722123009F +:10A440000956DD72F52366DD74F621210009360414 +:10A450002336006ADD66F62323E5210800ED4B185C +:10A46000C5095E2356E1732372210600ED4B18C522 +:10A470000946236668E5DD6EF5DD66F6C171237079 +:10A48000DD36F400AFDDB6F4CA7DA5DD7EDEDDB6D7 +:10A49000DF2865FDCB0AEEFD36210AFD36220011CC +:10A4A0000A00CDE3B2FD7523FD7424FD6E23DD7536 +:10A4B000D0FD6624DD74D136E52336A5DD6ED0DD12 +:10A4C00066D12323DD4EDE71DD46DF2370210400DB +:10A4D000DD4ED0DD46D109DD5EE073DD56E123724D +:10A4E00021060009E5211800395E2356234E234634 +:10A4F000E173237223712370DD7EE6DDB6E7280C5D +:10A50000DD6EE6FD750ADD66E7FD740BDD6EE8FDC8 +:10A51000750EDD66E9FD740FDD6EEAFD751DDD7EED +:10A52000EBE60FFD771EFD7E1DFDB61E20161114F5 +:10A5300000CDE3B2FD751DFD741EFD6E1DFD661E92 +:10A5400036001804FDCB0BF6DD7EEB2E004DE6F059 +:10A55000472610ED423010DD6EEADD7EEBE60F6738 +:10A5600023FD751FFD7420FDE5DD5E024BDD560306 +:10A5700042211B000946236668C1CD47852114008E +:10A58000E52E0E394D44DD5ED4DD56D5CDAFC0F19C +:10A590003E14ADB4CABAA2DD5ED4DD56D5CD09C035 +:10A5A000DD5E02DD5603CD178EDD5E024BDD560308 +:10A5B00042211900CD2991FDE1C33885DD4EDCDD56 +:10A5C0005EF2DD56F3CD42821B1B1BC9DD5ED95006 +:10A5D000DD4EF0DD46F1C34282DD4EDADD5EF2DDB6 +:10A5E00056F3C34282CD2485EEFFFDE5DD6E02DD2C +:10A5F0006603E5FDE121060039EB2147C1010900B1 +:10A60000EDB0FD6E23DD75EEFD6624DD74EF2323D2 +:10A610003E01AE23B62011C5010104FDE5D1FD6E5A +:10A6200017FD6618CD4785E1DD6EEEDD66EF23236D +:10A6300046236668CB853E02ADB4C23EA76F67E590 +:10A64000E5010100FD5E11FD5612CDB38DE1E1FD86 +:10A650006E11FD6612010800094E2346C5FD6E11FC +:10A66000FD6612010600094E2346C501000059503F +:10A67000CD0293F1F1DD75F0DD74F1010A000936C8 +:10A68000032370DD6EEEDD66EF2323CB46280C69D5 +:10A6900060DD4EF0DD46F10923CBEE211700DD4EE3 +:10A6A000F0DD46F10936772336A22119000936DBA1 +:10A6B000233692210600DD5EEEDD56EF195EEBDDFE +:10A6C00075F2210600DD4EEEDD46EF095E235623CE +:10A6D0004E2346EB3E08CD7482DD75F3210600DD86 +:10A6E0004EEEDD46EF095E2356234E2346EB3E1029 +:10A6F000CD7482DD75F4210600DD4EEEDD46EF09F6 +:10A700005E2356234E2346EB3E18CD7482DD75F54D +:10A71000210600394D44DD5EF0DD56F1CD8FA2DD1E +:10A720004EF0DD46F1C5FD5E11FD5612FD6E11FDC8 +:10A730006612011B000946236668C1CD4785DD6EA0 +:10A74000EEDD66EF23233E04AE23B6C2CFA821017F +:10A7500000E5FD6E11FD66120108000946236668DA +:10A7600001F6FF09E5FD6E11FD66120106000946BE +:10A7700023666801F6FF09E50105005950CDBC9933 +:10A78000F1F1F1DD75F0DD74F1010A000936032302 +:10A790003610210E00DD4EF0DD46F109363023364D +:10A7A00000AFDD77FDDD77FE210400DD4EEEDD46F6 +:10A7B000EF095E2356060CCDB7814B42DD6EFDDD01 +:10A7C00066FECD588230043E011801AFE60FCA6222 +:10A7D000A8210400DD4EEEDD46EF0946237E68E643 +:10A7E0000F67DD4EFDDD46FE0929E5210800ED5B22 +:10A7F00018C5195E2356E1192B2B5E2356D521105F +:10A8000000E52E06DD5EF0DD56F1196E260001F042 +:10A81000FF09E5DD6EFDDD66FE29294D44290901AC +:10A820001400094D44110800CD689CF1F1F1DD756B +:10A83000FBDD74FC010E000936302370DD4EFBDDBC +:10A8400046FCC5DD5EF04BDD56F142211B0009469A +:10A85000236668C1CD4785DD34FD2003DD34FEC3AA +:10A86000A8A70111C2DD5EF0DD56F1CD788A01FFA7 +:10A8700000DD5EF0DD56F1CD958B010E000936301E +:10A8800023700EFEDD5EF0DD56F1CD958BEBCDCD68 +:10A890008BDD4EF0DD46F1C5FD5E11FD5612FD6EFD +:10A8A00011FD6612011B000946236668C1CD47856C +:10A8B000210000E5FD5E11FD5612FD6E11FD6612D0 +:10A8C0000117000946236668010301CD4785E1FDB4 +:10A8D000E5D1CDB59CFDE1C33885CD2485F8FFFDDC +:10A8E000E5030ADD77FE030ADD77FF0369604EDDCD +:10A8F00071FC2346DD70FDDD6EFE6729EBCDE3B212 +:10A90000DD75FADD74FB5950CD0489C54D44DD5E1B +:10A9100002DD5603CDAFC0F1110000AFDD77F8DDE9 +:10A9200077F9DD4EFCDD46FD6B62CD58823035CDCA +:10A93000A0A9303023DD75F8DD74F92B29DD4EFA3E +:10A94000DD46FB09E5FDE5E1194D44E1712370FDAC +:10A95000E5E1197EB728031318F56B6213FDE5C115 +:10A96000097718BECDA0A9301329DD4EFADD46FBCC +:10A9700009E5FDE5E1194D44E1712370210600ED83 +:10A980004B18C509FDE5C1712370210800ED4B1876 +:10A99000C509DD4EFA71DD46FB2370FDE1C3388544 +:10A9A000DD4EFEDD46FFDD6EF8DD66F9C35882C57B +:10A9B000D5111000CDE3B22218C5210000221AC51E +:10A9C0002A18C5AF772377210400ED4B18C5097706 +:10A9D0002377210A00ED4B18C509772377210C0056 +:10A9E000ED4B18C509772377210800ED4B18C509F1 +:10A9F000772377210600ED4B18C509772377CD48DB +:10AA000085210000E5E5219F89E501B68911300027 +:10AA1000CD7588E1E1E1210000E5E5219F89E501AF +:10AA2000C189113100CD7588E1E1E1210000E5E542 +:10AA300021AD89E501CC89113200CD7588E1E1E1D4 +:10AA4000210E00ED4B18C509E5118000D55AD54BF4 +:10AA500042CD0293F1F14D44E1712370210E00EDDE +:10AA60004B18C5095623666A110A0019360123726C +:10AA7000210E00ED4B18C5095623666A11170019FF +:10AA800036772336A2210E00ED4B18C50946236602 +:10AA9000680119000936DB233692D1C1C9C5D52119 +:10AAA0000E00ED4B18C5095E2356CDCD8BCD7F87AB +:10AAB000CDC285D1C1C9CD2485FEFF011DC2210EA5 +:10AAC00000ED5B18C5195E2356CD8FA2210100E56C +:10AAD0002339CD2DABF13E01ADB428F0210400EDBA +:10AAE0004B18C5097E23B62041210100E52339CD4D +:10AAF0002DABF13E01ADB420E3DDB6FE28DE4F06FE +:10AB000000C5210E00ED5B18C5195E2356210E000D +:10AB1000ED4B18C5094623666801170009462366F0 +:10AB200068010100CD4785E118B2C338854D442A3C +:10AB300018C523235E2356C3AFC0CDAFA9CDB6AA97 +:10AB4000C39DAACD2485FCFF2AA8C32BDD75FCDD9F +:10AB500074FD21FFFF22A8C32100002216C5DDCB12 +:10AB6000FD7E2043DD6EFCDD66FD2929011CC50943 +:10AB700046236668DD75FEDD74FFDD6EFCDD66FD77 +:10AB80002929011EC5094E2346DD5E02DD5603DD7F +:10AB90006EFEDD66FFCD4785DD6EFCDD66FD2BDDDF +:10ABA00075FCDD74FD18B7C33885CD18852AA8C398 +:10ABB000CB7C200E010A802AA8C33E80AC67ED4200 +:10ABC000380B210C002214C521FFFF183C2143AB98 +:10ABD0002216C5DD7E02DDB603282B2AA8C329294B +:10ABE000011CC509DD4E02DD46037123702AA8C38E +:10ABF0002929011EC509DD4E04DD46057123702A91 +:10AC0000A8C32322A8C3210000C33885CD1885011D +:10AC10000000CDAAABC33885CD1885210A00E50117 +:10AC20000000CD85B6F1C33885CD1885210A00E531 +:10AC3000010000CD85B6F1C33F85CD1885160021F2 +:10AC4000AAC3197EE604280EDD7E02EE206FDD7EAB +:10AC500003EE00671806DD6E02DD6603C33885CD9E +:10AC60001885160021AAC3197EE602280EDD7E0291 +:10AC7000EE206FDD7E03EE00671806DD6E02DD66F6 +:10AC800003C33885CD2485F8FFAFDD77FEDD77FF80 +:10AC9000DD7E02DDB603206411C4C4CD84AC7DB476 +:10ACA000201411DCC4CD84AC7DB4200A11F4C4CDD1 +:10ACB00084AC7DB4280621FFFFC376AE2AC2C4DD72 +:10ACC0007502DD7403DD7E02DDB6032829DD5E0238 +:10ACD000DD5603CD84AC7DB4280621FFFFC376AEDC +:10ACE000211600DD4E02DD4603095623666ADD7536 +:10ACF00002DD740318CF210000C376AE210C00DD05 +:10AD00004E02DD4603097EE680CAD1AD210600DD94 +:10AD10004E02DD4603095E23560A6F030A67A7ED5C +:10AD200052DD75FADD74FB7DB4CACFAD210600DDBE +:10AD30004E02DD46030946236668DD75F8DD74F9C9 +:10AD4000DD6EFADD66FBE5DD4EF8DD46F9210A0031 +:10AD5000DD5E02DD5603195E2356CD09C1F1DD75B6 +:10AD6000FCDD74FD4D44210000CD5882301E2100D1 +:10AD700000397EDD86FC77237EDD8EFD77210200A3 +:10AD8000397EDD96FC77237EDD9EFD77DD4EFCDD92 +:10AD900046FD210000CD588238A6DD7EFCDDA6FDF3 +:10ADA0003C20092A14C53E04ADB42894DD7EFADDAA +:10ADB000B6FB281B210C00DD4E02DD4603097EF6A2 +:10ADC0000077237EF60277DD36FEFFDD36FFFF18C3 +:10ADD00065210C00DD4E02DD4603097EE640285663 +:10ADE000DD6E02DD66034E2346DD6E02DD66032363 +:10ADF000235623666AA7ED42DD75FADD74FB4D44E8 +:10AE0000210000CD5882302E210100E5DD4EFADD13 +:10AE100046FBA7210000ED427C079F4F41C5E5217D +:10AE20000A00DD4E02DD4603095E2356CD61C0F106 +:10AE3000F1F1CB782800210C00DD4E02DD4603093C +:10AE40007EE63F77237EE6FA7769602323E52104D7 +:10AE500000DD4E02DD460309E521060009562366A2 +:10AE60006AE56960C1712370E1712370E17123703B +:10AE7000DD6EFEDD66FFC33885CD2485FEFFCDED9A +:10AE8000B5210C000946236668DD75FEDD74FF7D83 +:10AE9000E6402813DD5E04DD5605CD84AC7DB42884 +:10AEA0000621FFFFC374AFDD7EFEE6206FDD7EFF6F +:10AEB000E603673E20ADB4280621FFFFC374AF212F +:10AEC0000800DD4E04DD4605095E23560A6F030ABD +:10AED00067A7ED523813DD5E04DD5605CD84AC7DE9 +:10AEE000B4280621FFFFC374AFDD6E04DD66054E96 +:10AEF000234603702B710B6960DD460270210C0044 +:10AF0000DD4E04DD4605097EF68077237EF6007768 +:10AF10003E0ADDAE02DDB6032007DD7EFEE601203F +:10AF200007DD7EFEE6022812DD5E04DD5605CD84D7 +:10AF3000AC7DB4280521FFFF183ADD7EFEE603282C +:10AF400018210400DD4E04DD460509E5210600094F +:10AF50004E2346E17123701816210400DD4E04DDF6 +:10AF6000460509E5210800094E2346E1712370DDFD +:10AF70006E022600C33885CD2485FCFF21FCFFDD51 +:10AF80004E02DD460309DD75FEDD74FF23237E23BB +:10AF9000B6280621FFFFC354B02A48C5DD75FCDD85 +:10AFA00074FDDD4EFCDD46FDDD6EFEDD66FFA7EDCA +:10AFB000423817DD6EFCDD66FD232346236668DD1F +:10AFC0004EFEDD46FFA7ED423053DD6EFCDD66FD33 +:10AFD00023234E2346DD6EFCDD66FDA7ED423829B6 +:10AFE000DD4EFEDD46FFDD6EFCDD66FDA7ED423881 +:10AFF00016DD6EFCDD66FD23234E2346DD6EFEDD91 +:10B0000066FFA7ED4230021814DD6EFCDD66FD23FD +:10B010002346236668DD75FCDD74FD1885DD6EFE54 +:10B02000DD66FF2323E5DD4EFCDD46FD030369609D +:10B030004E2346E1712370DD6EFCDD66FD2323DDCA +:10B040004EFEDD46FF712370DD6EFCDD66FD22489D +:10B05000C5210000C33885CD2485E2FF21000039D9 +:10B060004D44DD5E02DD5603CD29C07DA43C28128F +:10B07000DD7EE6E6006FDD7EE7E6F0673E20ACB5FC +:10B0800028052100001803210100C33885CD24853F +:10B09000D6FFDD6E08DD6609DD75F8DD74F9210087 +:10B0A0000039DD75FADD74FB212C0039DD75FCDD1E +:10B0B00074FD213800397ED60A77DD4E0ADD460B55 +:10B0C000212400CD58823811010280DD6E0ADD6630 +:10B0D0000B3E80AC67ED423003C310B2DD6EFCDD89 +:10B0E00066FD23237EE60047237EE680B02831AF4D +:10B0F000DDB60C282BDD6EF8DD66F923DD75F8DD95 +:10B1000074F92B362DDD4E04DD4605DD6E02DD665D +:10B1100003CD6984DD7502DD7403DD7104DD700526 +:10B12000DD6EFCDD66FD23237E23B62002184EDD96 +:10B130006E0ADD660B7C079F4F41C5E5DD4E04DDE1 +:10B140004605DD6E02DD6603CD5E83E5DD6EFADD6C +:10B1500066FB23DD75FADD74FB2BC171212C0039F0 +:10B16000DD5E0ADD560B7A079F4F41CD8B84DD6E85 +:10B17000FCDD66FD23237E23B620B41830DD5E029D +:10B18000DD5603DD4E0ADD460BCDEB81DD6EFADDCB +:10B1900066FB23DD75FADD74FB2B73DD5E02DD5685 +:10B1A00003CDC181DD6EFCDD66FD732372DD6EFCB7 +:10B1B000DD66FD7E23B620C5210000394D44DD6EDD +:10B1C000FADD66FBA7ED42DD75FFAFDDB6FF284077 +:10B1D000DD6EFADD66FB2BDD75FADD74FB46DD7096 +:10B1E000FE78FE0A300ADD7EFEC630DD77FE1809E5 +:10B1F000DD7EFEDD860EDD77FEDD6EF8DD66F92391 +:10B20000DD75F8DD74F92BDD46FE70DD35FF18BA0B +:10B21000DD6EF8DD66F93600DD6E08DD6609C338DF +:10B2200085CD2485FEFFDD36FE41DDCB097E281667 +:10B23000DD36FE61DD4E08DD4609A7210000ED4246 +:10B24000DD7508DD7409DD6EFEE50E01C5DD6E08F5 +:10B25000DD6609E5DD6E04DD6605E53E0ADDAE0866 +:10B26000DDB609200DDD5E02DD56037A079F4F41F2 +:10B270001809DD5E02DD5603010000CD8DB0F1F14D +:10B28000F1F1C33885CD2485FEFFDD36FE41DDCBEF +:10B290000B7E2816DD36FE61DD4E0ADD460BA7214A +:10B2A0000000ED42DD750ADD740BDD6EFEE53E0A41 +:10B2B000DDAE0ADDB60B20043E011801AF4FC5DD3F +:10B2C0006E0ADD660BE5DD6E08DD6609E5DD4E0420 +:10B2D000DD4605DD5E02DD5603CD8DB0F1F1F1F105 +:10B2E000C33885CD2485FAFFDD6E02DD6603232396 +:10B2F00023CB3CCB1DCB3CCB1D23DD75FEDD74FF8A +:10B300002A48C5DD75FCDD74FD7DB42011DD36FCF9 +:10B3100044DD36FDC52144C52246C52248C5DD6E43 +:10B32000FCDD66FD232346236668DD75FADD74FBCC +:10B33000DD6EFADD66FB232346236668DD4EFADD0B +:10B3400046FBA7ED42CAD3B3DD6EFADD66FB4623AA +:10B3500066682929DD4EFADD46FB09E503036960CD +:10B360004E2346E1A7ED42206ADD6EFADD66FB233F +:10B370002346236668ED4B48C5A7ED422015DD6ED8 +:10B38000FADD66FB2323462366682323462366688B +:10B390002248C5DD6EFADD66FB23237E23666F4EF1 +:10B3A0002346DD6EFADD66FB7E8177237E8877DDBE +:10B3B0006EFADD66FB2323E5DD4EFADD46FB030373 +:10B3C00069604E2346030369604E2346E171237092 +:10B3D000C330B3DD6EFADD66FB46236668DD4EFEE4 +:10B3E000DD46FFA7ED42DA91B4DD6EFADD66FB467D +:10B3F000236668DD4EFEDD46FFA7ED42201CDD6EB4 +:10B40000FCDD66FD2323E5DD4EFADD46FB03036923 +:10B41000604E2346E17123701856DD6EFEDD66FF37 +:10B420002929DD4EFADD46FB092248C5DD6EFCDD2B +:10B4300066FD2323ED5B48C57323722A48C5232389 +:10B44000E5030369604E2346E1712370DD6EFADD8A +:10B4500066FB46236668DD4EFEDD46FFA7ED42E54E +:10B460002A48C5D1732372DD6EFADD66FB71237045 +:10B47000DD6EFCDD66FD2248C5DD6EFADD66FB2370 +:10B4800023AF772377210400DD4EFADD46FB091850 +:10B49000222A48C5DD4EFADD46FBA7ED42204511C4 +:10B4A0000004CDC9C0DD75FADD74FB7DA43C200627 +:10B4B000210000C33885DD6EFADD66FB36002336D9 +:10B4C00001DD6EFADD66FB2323AF772377210400CD +:10B4D000DD4EFADD46FB09EBCD77AF2A48C5DD75B9 +:10B4E000FADD74FBDD6EFADD66FBDD75FCDD74FDF7 +:10B4F000DD6EFADD66FB232346236668DD75FADD23 +:10B5000074FBC330B3CD2485FCFFDD6E02DD660322 +:10B51000DD75FCDD74FDDD71FEDD70FFDD6E08DDC7 +:10B5200066092BDD7508DD7409237DB42820DD6EE6 +:10B53000FEDD66FF23DD75FEDD74FF2B46DD6EFC50 +:10B54000DD66FD23DD75FCDD74FD2B7018CEDD6E30 +:10B5500002DD6603C33885CD2485FCFF210E00394A +:10B5600001020009DD75FCDD74FDDD4E08DD4609D4 +:10B57000ED43AAC4E5DD4E0ADD460B11AAC4CDC6D3 +:10B58000BAF1DD75FEDD74FF2AAAC43600DD6EFE59 +:10B59000DD66FFC33885CD2485FEFF2AC2C4DD7574 +:10B5A000FEDD74FF11DCC4CD84AC11F4C4CD84ACD9 +:10B5B000DD7EFEDDB6FF2832DD5EFEDD56FFCD848A +:10B5C000AC210A00DD4EFEDD46FF095E2356CD09A3 +:10B5D000C0210A000936FF2336FF21160009562331 +:10B5E000666ADD75FEDD74FF18C6C33885D52A0C82 +:10B5F000C57DB420021822210000220CC5110100D3 +:10B60000CD57B07DB4280C21E8C47EF60177237EA7 +:10B61000F600771196B5CD0CACD1C9CD1885D5CD36 +:10B620004EB6D119EBCD31B6DD6E02DD6603C338FF +:10B6300085CD18855950CD4EB623E5DD4E04DD4647 +:10B6400005DD5E02DD5603CD05B5F1C33885CD2499 +:10B6500085FEFFDD6E02DD6603DD75FEDD74FFDD58 +:10B660006EFEDD66FFAFB6280ADD34FE2003DD3452 +:10B67000FF18ECDD4E02DD4603DD6EFEDD66FFA742 +:10B68000ED42C33885CD2485F8FFAFDD77FCDD774B +:10B69000FDDD6E02DD6603DD75FEDD74FFDD6EFE31 +:10B6A000DD66FF4E060021AAC3097EE610280ADDEA +:10B6B00034FE2003DD34FF18E4DD6EFEDD66FF7E20 +:10B6C000FE2D2012DD34FC2003DD34FDDD34FE20B0 +:10B6D00003DD34FF1813DD6EFEDD66FF7EFE2B20DA +:10B6E00008DD34FE2003DD34FFDD6E08DD6609E58C +:10B6F000DD4E04DD4605DD5EFEDD56FFCDAEB7F165 +:10B70000DD75F8DD74F9DD71FADD70FBDD7EFCDDE1 +:10B71000B6FD2805CD6984180CDD4EFADD46FBDD4B +:10B720006EF8DD66F9C33F85CD2485FEFFDD36FE6C +:10B73000FFDD36FFFFDD5E02160021AAC3197EE69B +:10B7400008280FDD4E02060021D0FF09DD75FEDD61 +:10B7500074FFDD4E02060021AAC3097EE604280F0D +:10B76000DD4E02060021A9FF09DD75FEDD74FFDD57 +:10B770004E02060021AAC3097EE602280FDD4E0212 +:10B78000060021B0FF09DD75FEDD74FFDD4E04DD2E +:10B790004605DD6EFEDD66FFCD58823808DD36FEDB +:10B7A000FFDD36FFFFDD6EFEDD66FFC33885CD248D +:10B7B00085FAFF110280DD6E08DD66093E80AC6708 +:10B7C000ED52380EDD4E08DD4609212400CD5882A9 +:10B7D0003007AFDD7708DD7709DD6E02DD66034EE9 +:10B7E000060021AAC3097EE610280ADD34022003E0 +:10B7F000DD340318E4DD6E02DD66037EFE2B200AD5 +:10B80000DD34022003DD3403186DDD7E08DDB6096A +:10B810002065DD6E02DD66037EFE30205ADD6E029D +:10B82000DD6603237EEE20FE582017DD360810DD8E +:10B83000360900210800397EC60277237ECE0077C4 +:10B840001835DD6E02DD6603237EEE20FE422017F2 +:10B85000DD360802DD360900210800397EC6027790 +:10B86000237ECE00771810DD360808DD360900DDAE +:10B8700034022003DD3403DD7E08DDB6092008DD57 +:10B8800036080ADD360900AFDD77FADD77FBDD77B4 +:10B89000FCDD77FDDD4E08DD4609DD6E02DD660369 +:10B8A0005ECD28B7DD75FEDD74FF7DA43C282E211A +:10B8B000000039DD5E08DD56097A079F4F41CD7BD8 +:10B8C0008421000039DD5EFEDD56FF7A079F4F417F +:10B8D000CDA484DD34022003DD340318B7DD7E04FB +:10B8E000DDB6052811DD6E02DD6603E5DD6E04DDE3 +:10B8F0006605C1712370DD4EFCDD46FDDD6EFADDAF +:10B9000066FBC33F85CD2485FEFFDD36FE41DDCBE2 +:10B910000B7E2816DD36FE61DD4E0ADD460BA721C3 +:10B920000000ED42DD750ADD740BDD6EFEE50E00F4 +:10B93000C5DD6E0ADD660BE5DD6E08DD6609E5DD59 +:10B940004E04DD4605DD5E02DD5603CD8DB0F1F11E +:10B95000F1F1C33885CD2485FAFFAFDD77FBDD77C4 +:10B96000FC5950CD4EB6DD75FDDD74FEDD6E04DD97 +:10B9700066057EFE2D2014DD6E04DD660523DD7573 +:10B9800004DD74052B46DD700A180EAFDDB60A28FB +:10B9900008DD34FD2003DD34FEDD7E10DDA6113C24 +:10B9A000281DDD4EFDDD46FEDD6E10DD6611CD5835 +:10B9B00082300CDD6E10DD6611DD75FDDD74FEDD9F +:10B9C0004EFDDD46FEDD6E0EDD660FCD5882300C7D +:10B9D000DD6EFDDD66FEDD750EDD740FDD6E0EDDE8 +:10B9E000660FDD75FBDD74FC211400397EDD96FDEC +:10B9F00077237EDD9EFE77DD7E0EDDB60F2009DD2E +:10BA00007EFDDDB6FECABDBADD7E08DDB609203496 +:10BA1000DD7E0EDDB60F282CDD7EFDDDB6FE280FA7 +:10BA2000AFDDB60A2809DD7E0CFE3020021823DDCA +:10BA3000460CDD70FADD6E0EDD660F2BDD750EDD5A +:10BA4000740F184EDD7EFDDDB6FE2833AFDDB60A7D +:10BA5000280CDD460ADD70FADD360A001812DD6EAC +:10BA600004DD660523DD7504DD74052B46DD70FA03 +:10BA7000DD6EFDDD66FE2BDD75FDDD74FE1813DD6C +:10BA8000460CDD70FADD6E0EDD660F2BDD750EDD0A +:10BA9000740FDD4E02DD4603DD5EFA1600CD79AE91 +:10BAA000DD7EFAFE0A20133E01DDAE12DDB6132064 +:10BAB00009DD5E02DD5603CD84ACC3F7B9DD6EFB54 +:10BAC000DD66FCC33885CD2485A2FFAFDD77B0DD10 +:10BAD00077B1210C00DD5E02DD5603197EE6034FCF +:10BAE000237EE60047DD71FDDD70FE210C00197E2E +:10BAF000E6FC77237EE6FF77DD6E04DD6605AFB6F4 +:10BB0000CAA8BFDD6E04DD66057EFE25C265BF3EA8 +:10BB100002DDAEFDDDB6FE2009DD5E02DD5603CDA1 +:10BB200084ACAFDD77A4DD77A5DD36B300DD36B2BA +:10BB300020DD36ACFFDD36ADFFAFDD77AADD77ABBC +:10BB4000DD36A8FFDD36A9FFDD36AE0ADD36AF00F3 +:10BB5000211B0039DD75B5DD74B6DD36B400AFDD0F +:10BB600077A6DD77A7AFDD77A2DD77A3DD340420EC +:10BB700003DD3405DD6E04DD66057EFE30380BDD49 +:10BB80006E04DD66053E39BE3002186521000039BD +:10BB9000010A00CD6A82DD6E04DD66054E060021D5 +:10BBA000D0FF094D44210000397E8177237E8877BC +:10BBB000DD7EAADDB6AB280EDD6EA2DD66A3DD75E7 +:10BBC000A8DD74A91821DD7EA2DDB6A3200DDD7EDF +:10BBD000B2FE202006DD36B230188ADD6EA2DD66A8 +:10BBE000A3DD75ACDD74ADDD34042003DD34051850 +:10BBF00083DD6E04DD66055ECDDF84140000202148 +:10BC0000232A2B2D2E5862636468696C6F707375DC +:10BC10007861BF78BD80BDF4BE53BD49BDD4BCE9D9 +:10BC2000BCDFBCE9BCB1BE3FBD6EBDC9BC4BBC56A0 +:10BC3000BC6ABC63BC93BE56BC3BBCDD6E04DD6617 +:10BC4000052BDD7504DD7405C365BFDD36A401DD9C +:10BC500036A500C365BBDD6E04DD660546DD70B349 +:10BC6000C365BBDD36B401C365BB216600397EC642 +:10BC70000277237ECE00772B6E672B2B46236668D8 +:10BC8000DD75A2DD74A3DD7EAADDB6AB280EDD6E08 +:10BC9000A2DD66A3DD75A8DD74A9182ADD6EA2DD1C +:10BCA00066A3DD75ACDD74ADCB7C281ADD36A4014E +:10BCB000DD36A500DD4EA2DD46A3A7210000ED4242 +:10BCC000DD75ACDD74ADC365BBDD36AA01DD36AB19 +:10BCD00000C365BBDD36A601DD36A700C365BBAF7B +:10BCE000DD77A6DD77A7C365BB210A00E5211D002E +:10BCF00039E5DD7EA6DDB6A7281D216A00397EC69E +:10BD00000477237ECE00772B6E6701FCFF095E234C +:10BD100056234E2346181A216A00397EC60277231D +:10BD20007ECE00772B6E672B2B5E23567A079F4FB4 +:10BD300041CD85B2F1F1DD75B5DD74B6C318BFDD57 +:10BD400036AE02DD36AF001837DD36AE08DD36AF71 +:10BD500000182DAFDD77A6DD77A7DD36B230DD36F2 +:10BD6000AC05DD36AD00DD36A808DD36A900DD36D0 +:10BD7000AE10DD36AF001808DD36AEF0DD36AFFFB1 +:10BD8000DD7EA6DDB6A7281E216600397EC60477B3 +:10BD9000237ECE00772B6E6701FCFF095E235623BE +:10BDA0004E2346EB1819216600397EC60277237EA2 +:10BDB000CE00772B6E672B2B46236668010000DDD3 +:10BDC00075B9DD74BADD71BBDD70BCDD5EAEDD560C +:10BDD000AFD5211D003901040009E5DD4EBBDD466C +:10BDE000BCDD5EB9DD56BACD05B9F1F1DD75B5DD65 +:10BDF00074B6DD36B726DD36B8C2AFDDB6B4CA904C +:10BE0000BE3E02DDAEAEDDB6AF200ADD36B727DDC1 +:10BE100036B8C218493E08DDAEAEDDB6AF2018DD3B +:10BE20007EB9DDB6BADDB6BBDDB6BC2808DD36B7F7 +:10BE30002ADD36B8C218273E10DDAEAEDDB6AF2023 +:10BE40000ADD36B72CDD36B8C218133E0FDDAEAEB4 +:10BE5000DDA6AF3C2008DD36B72FDD36B8C2DD6E7B +:10BE6000B7DD66B8AFB62828DD36B200DD4EB7DDE7 +:10BE700046B8211B00395D54CD31B6DD4EB5DD46E7 +:10BE8000B6211B00395D54CD1BB6DD75B5DD74B62A +:10BE9000C318BFDD6E04DD6605234E0600DD71A20A +:10BEA000DD70A379B02808DD34042003DD340518E3 +:10BEB0001C216600397EC60277237ECE00772B6E6A +:10BEC000672B2B46236668DD75A2DD74A3DD46A2D1 +:10BED000DD6EB5DD66B670DD6EB5DD66B6233600A7 +:10BEE000AFDDB6B4280CDD6EB5DD66B646DD70B2EA +:10BEF0001822181C216600397EC60277237ECE00E8 +:10BF0000772B6E672B2B46236668DD75B5DD74B61F +:10BF1000DD36B220DD36B300DD6EFDDD66FEE5DD2B +:10BF20006EA8DD66A9E5DD6EACDD66ADE5DD6EB261 +:10BF3000E5DD6EB3E5DD6EA4DD66A5E5DD4EB5DDC0 +:10BF400046B6DD5E02DD5603CD55B9EB210C003956 +:10BF5000F9EB4D44210E00397E8177237E887718D6 +:10BF60000218021838DD4E02DD4603DD6E04DD6680 +:10BF7000055E1600CD79AEDD34B02003DD34B1DDD1 +:10BF80006E04DD66057EFE0A20133E01DDAEFDDD9A +:10BF9000B6FE2009DD5E02DD5603CD84ACDD34043F +:10BFA0002003DD3405C3F8BA210C00DD4E02DD4666 +:10BFB00003097EDDB6FD77237EDDB6FE773E02DD2A +:10BFC000AEFDDDB6FE2009DD5E02DD5603CD84AC9C +:10BFD0003E01DDAEFDDDB6FE2016210400DD4E0281 +:10BFE000DD460309E5210600094E2346E171237071 +:10BFF000DD6EB0DD66B1C33885CD1885D521020070 +:10C00000E5CDD9C0F1F1C33885CD1885D52106001D +:10C01000E5CDD9C0F1F1C33885CD1885D5210B0008 +:10C02000E5CDD9C0F1F1C33885CD1885C5D5210D31 +:10C0300000E5CDD9C0F1F1F1C33885CD1885DD6EAD +:10C040000CDD660DE5DD6E0ADD660BE5DD6E08DDF7 +:10C050006609E5210F00E5CDD9C0F1F1F1F1C33852 +:10C0600085CD1885DD6E0CDD660DE5DD6E0ADD66BD +:10C070000BE5DD6E08DD6609E5D5211900E5CDF19A +:10C08000C0F1F1F1F1F1C33F85CD1885DD6E0CDD16 +:10C09000660DE5DD6E0ADD660BE5DD6E08DD660921 +:10C0A000E5211400E5CDD9C0F1F1F1F1C33885CD1A +:10C0B0001885DD6E08DD6609E5C5D5211700E5CDDB +:10C0C000D9C0F1F1F1F1C33885CD1885D52118001B +:10C0D000E5CDD9C0F1F1C3388521020039C5D55E5F +:10C0E0002356234D44F730062214C521FFFFD1C14A +:10C0F000C921020039D55E2356234D44F73008226A +:10C1000014C521FFFF4D44D1C9CD1885DD6E08DD72 +:10C110006609E5C5D5212400E5CDD9C0F1F1F1F1DD +:10C12000C338851B4B1B5300001B4300001B4E00F4 +:10C13000001B5200001B4600001B5A0000000000BC +:10C140001B45001B000000303030302E736372003E +:10C150002F6465762F6C6364300030004345004FD8 +:10C160004B0043616E63656C0000426172636F64F3 +:10C1700065005374756B73005072696A73002F64A5 +:10C1800065762F7072696E74657200253133732085 +:10C190005665726B6F6F70617274696B656C20208D +:10C1A0007C25376C642C2530326C640D0A002531F7 +:10C1B0003373205665726B6F6F70617274696B6553 +:10C1C0006C0D0A253464782040207C2025376C646F +:10C1D0002C2530326C64202020202020202020209C +:10C1E0007C25376C642C2530326C640D0A000D0AF6 +:10C1F00025313373546F7461616C3A253130737C2F +:10C2000025376C642C2530326C640D0A0D0A0D0A3A +:10C21000004D65737361676520426F780030303080 +:10C22000302E7363720000306200300030780030CE +:10C2300058004AC74AC74AC700000000010101016F +:10C24000010101010111111111110101010101018E +:10C250000101010101010101010101011020202062 +:10C26000202020202020202020202020484848482E +:10C270004848484848482020202020202042424268 +:10C2800042424202020202020202020202020202CE +:10C290000202020202020220202020202044444404 +:10C2A000444444040404040404040404040404048E +:10C2B00004040404040404202020200100000000E1 +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C34000FFFF0000FFFFFFFF2000000000000000D3 +:10C350000000000000004AC54AC54AC54AC54AC691 +:10C3600000001000000000000000000000004AC6AD +:10C370004AC64AC64AC64AC701002000000000005B +:10C3800000000000000002C502C502C502C504C5C8 +:10C390000200220000000000000000000000010078 +:00000001FF diff --git a/src/gui/wnd.lnk b/src/gui/wnd.lnk new file mode 100644 index 00000000..5db953de --- /dev/null +++ b/src/gui/wnd.lnk @@ -0,0 +1,14 @@ +-k ..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o grlogin +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\lib\c0b.rel +wnd +login diff --git a/src/gui/wnd.map b/src/gui/wnd.map new file mode 100644 index 00000000..b5732b9f --- /dev/null +++ b/src/gui/wnd.map @@ -0,0 +1,283 @@ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +. .ABS. 00000000 00000000 = 0. bytes (ABS,OVR) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR + 00000000 .__.ABS. | 00000000 ?CL64180L | 00000000 ?CL64180B + 00000014 e__DEFAUL | 00000014 l__DEFAUL | 0000002F l_CONST + 00000153 l_CSTR | 00000170 l_CDATA0 | 00000170 l_IDATA0 + 000003B5 l_UDATA0 | 00000430 l_RCODE | 00001000 l_CSTACK + 00004000 s_CODE | 00008100 s_RCODE | 00008530 e_RCODE + 00008530 s_CONST | 0000855F s_CSTR | 0000855F e_CONST + 000086B2 e_CSTR | 000086B2 s_IDATA0 | 000086B2 s_CDATA0 + 00008822 s_UDATA0 | 00008822 e_CCSTR | 00008822 e_ECSTR + 00008822 s_CCSTR | 00008822 e_CDATA0 | 00008822 s_ECSTR + 00008822 e_IDATA0 | 00008BD7 e_UDATA0 | 00008BD7 s_CSTACK + 00009BD7 e_CSTACK | 0000C257 l_CODE | 00010257 e_CODE +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +_DEFAULT 00000000 00000014 = 20. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +RCODE 00008100 00000430 = 1072. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008100 __init | 0000811F ?L_MUL_L0 | 000081A3 ?BANK_LEA + 000081A9 ?BANK_FAS | 000081AE ?S_MUL_L0 | 000081C4 ?C_V_SWIT + 000081D6 ?L_ADDASG | 000081EF ?ENT_PARM | 000081FB ?BANK_CAL + 00008208 ?S_S_SWIT | 0000821C ?S_V_SWIT | 00008239 ?S_SWITCH + 00008247 ?SL_MOD_L | 0000827A ?ENT_AUTO | 0000828E ?V_SWITCH + 00008298 ?SL_DIV_L | 000082C8 ?SS_CMP_L | 000082DA ?L_INC_L0 + 000082E2 ?US_MOD_L | 000082EB ?SS_DIV_L | 00008307 ?UL_RSHAS + 00008315 ?US_DIV_L | 00008323 ?SL_RSH_L | 00008331 ?UL_RSH_L + 0000834C ?L_DIVMOD | 000083A4 ?BANK_LEA | 000083B0 ?SS_RSH_L + 000083BA ?L_LSH_L0 | 000083D2 ?S_DIVMOD | 000083E8 ?S_MULASG + 000083F2 ?L_END_AS | 000083FB ?L_NOT_L0 | 0000840A ?L_XOR_L0 + 00008428 ?L_ORASG_ | 00008441 ?LEAVE_DI | 00008448 ?L_FIND_S + 0000848C ?UL_DIVAS | 0000849C ?UL_MOD_L | 000084C1 ?S_FIND_S + 000084DD ?UL_DIV_L | 00008505 ?L_NEG_L0 | 00008517 ?L_MULASG + 00008527 ?L_END_MU +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CONST 00008530 0000002F = 47. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTR 0000855F 00000153 = 339. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +IDATA0 000086B2 00000170 = 368. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 000086CA __IO_list | 000086CC stdin | 000086E4 stdout + 000086FC stderr | 0000871A _path_pas | 0000871C __sys_err + 0000871E __sys_ner | 00008720 __on_exit | 00008722 __ctype +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CDATA0 000086B2 00000170 = 368. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +ECSTR 00008822 00000000 = 0. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CCSTR 00008822 00000000 = 0. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CODE 00004000 0000C257 = 49751. bytes (NUL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00004736 GraphicsO | 000047D2 GraphicsC | 000047EA Move + 00004829 ClearRect | 0000486C DrawRectN | 000048B1 FillRect + 000048F6 FillRectN | 0000493B GrayRect | 00004980 Text + 000049AC TouchRegi | 00004A03 ClearScre | 00004A40 EnableScr + 00004A7E grSetFont | 00004ABB fontSearc | 00004AEB setCurren + 00004B87 loadFont | 00004C2E stringwid | 00004CA7 stringhei + 00004CC4 stringhei | 00004CD7 stringhei | 00004CE0 stringwid + 00004CF1 stringwid | 00004CFA stringwid | 00004D03 Component + 00004DAD Component | 00004DFA Component | 00004E58 Component + 00004E9E Component | 00004EE2 Component | 00004F1A Component + 000050EB Component | 0000510A Component | 00005173 Component + 00005226 Window_ha | 00005490 Window_pa | 0000561C Root_pain + 00005653 Window_ad | 00005661 Window_ne | 000056B3 Button_ha + 0000576A Button_dr | 00005838 Button_pa | 0000590B Button_ad + 00005911 Button_ne | 00005963 ToggleBut | 000059FC ToggleBut + 00005AE8 ToggleBut | 00005B3A Dialog_ha | 00005BF3 Dialog_ne + 00005CE2 Display_h | 00005D60 Display_p | 00005E7D Display_n + 00005ED7 Label_han | 00005EDD Label_pai | 00005F3E Label_new + 00005F97 Transacti | 000065D5 rootWindo | 000065F3 screenbui + 000069BB root_acti | 00006CF0 read_stri | 00006DC5 gui_globa + 00006DCB GUIinit | 00006EFB GUIunit | 00006F20 GUIgo + 00006F9F login | 000070C8 login_act | 0000723B main + 000072A2 setgid | 000072BC unix | 000072D6 sprintf + 0000731A strrchr | 00007382 fflush | 00007595 chdir + 000075AA _write | 000075C9 setuid | 000075E3 printf + 00007612 lseek | 0000763F __stdio_c | 000076AA __stdio_i + 000076E8 setenv | 00007964 unsetenv | 00007A04 close + 00007A19 strlen | 00007A50 strcmp | 00007AF1 perror + 00007B2E execv | 00007B41 ioctl | 00007B6C isatty + 00007BA7 fstat | 00007BBE free | 00007C9E getpwnam + 00007D00 setpwent | 00007D45 endpwent | 00007D64 getpwent + 00007D82 strcpy | 00014000 __getpwen | 00014288 atoi + 0001441E vfprintf | 00014979 ltoa | 000149DC atol + 000149F2 __longtoa | 00014B86 itoa | 00014BEF crypt + 00014E9C fputs | 00014EFA open | 00014F25 malloc + 00015151 exit | 00015181 _read | 000151A0 memcmp + 0001520D execve | 0001522C strerror | 000153E9 memset + 00015429 memcpy | 000154F7 on_exit | 00015570 atexit + 00015583 strcat | 000155A3 unix_long | 000155BD strchr + 000155F8 _exit | 00015693 strtoul | 000157EA fputc + 000158FC toupper | 00015921 tolower | 00015946 ultoa + 0001599B strtol | 00015A43 sbrk +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +UDATA0 00008822 000003B5 = 949. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + 00008822 _argc | 00008824 _argv | 00008826 environ + 00008828 errno | 0000882A __cleanup | 0000882D global + 0000882F trans | 00008B4F __malloc_ | 00008B53 __malloc_ + 00008BA5 __on_exit +Hexadecimal [32-Bits] + +Area Addr Size Decimal Bytes (Attributes) +-------------------- ---- ---- ------- ----- ------------ +CSTACK 00008BD7 00001000 = 4096. bytes (REL,CON) + + Value Global Value Global Value Global + ----- ------ ----- ------ ----- ------ + +Files Linked [ module(s) ] + +..\..\lib\c0b.rel [ _c0b ] +wnd [ wnd ] +login [ login ] + + +Libraries Linked [ object file ] + +..\..\lib\libsysb.lib [ relsysb\setgid.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] +..\..\lib\libcb.lib [ relcb\sprintf.rel ] +..\..\lib\libiar.lib [ reliar\LMUL.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strrchr.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\chdir.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libiar.lib [ reliar\SMUL.rel ] +..\..\lib\libsysb.lib [ relsysb\setuid.rel ] +..\..\lib\libcb.lib [ relcb\printf.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libcb.lib [ relcb\setenv.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libcb.lib [ relcb\strcmp.rel ] +..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] +..\..\lib\libcb.lib [ relcb\perror.rel ] +..\..\lib\libcb.lib [ relcb\execv.rel ] +..\..\lib\libsysb.lib [ relsysb\ioctl.rel ] +..\..\lib\libiar.lib [ reliar\LADDASG.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libcb.lib [ relcb\getpwnam.rel ] +..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\setpwent.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\SSSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SVSWITCH.rel ] +..\..\lib\libiar.lib [ reliar\SSWITCHEND.rel ] +..\..\lib\libiar.lib [ reliar\SLMOD.rel ] +..\..\lib\libcb.lib [ relcb\getpwent.rel ] +..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] +..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] +..\..\lib\libiar.lib [ reliar\SLDIV.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] +..\..\lib\libcb.lib [ relcb\atol.rel ] +..\..\lib\libiar.lib [ reliar\SSCMP.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] +..\..\lib\libiar.lib [ reliar\LINC.rel ] +..\..\lib\libcb.lib [ relcb\crypt.rel ] +..\..\lib\libcb.lib [ relcb\fputs.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] +..\..\lib\libiar.lib [ reliar\USMOD.rel ] +..\..\lib\libiar.lib [ reliar\SSDIV.rel ] +..\..\lib\libiar.lib [ reliar\ULRSHASG.rel ] +..\..\lib\libiar.lib [ reliar\USDIV.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] +..\..\lib\libiar.lib [ reliar\SLRSH.rel ] +..\..\lib\libiar.lib [ reliar\ULRSH.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] +..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] +..\..\lib\libiar.lib [ reliar\SSRSH.rel ] +..\..\lib\libiar.lib [ reliar\LLSH.rel ] +..\..\lib\libcb.lib [ relcb\memcmp.rel ] +..\..\lib\libsysb.lib [ relsysb\execve.rel ] +..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] +..\..\lib\libcb.lib [ relcb\error.rel ] +..\..\lib\libiar.lib [ reliar\SMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LENDASG.rel ] +..\..\lib\libiar.lib [ reliar\LNOT.rel ] +..\..\lib\libcb.lib [ relcb\memset.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libiar.lib [ reliar\LXOR.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libiar.lib [ reliar\LORASG.rel ] +..\..\lib\libcb.lib [ relcb\strchr.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] +..\..\lib\libiar.lib [ reliar\LFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] +..\..\lib\libiar.lib [ reliar\ULMOD.rel ] +..\..\lib\libiar.lib [ reliar\SFINDSIGN.rel ] +..\..\lib\libiar.lib [ reliar\ULDIV.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] +..\..\lib\libiar.lib [ reliar\LNEG.rel ] +..\..\lib\libiar.lib [ reliar\LMULASG.rel ] +..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] + + +User Base Address Definitions + +l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/gui/wnd.rel b/src/gui/wnd.rel new file mode 100644 index 00000000..cec1bfdc --- /dev/null +++ b/src/gui/wnd.rel @@ -0,0 +1,3437 @@ +XL4 +H 5 areas 57 global symbols +M wnd +S ?BANK_FAST_LEAVE_L08 Ref00000000 +S fflush Ref00000000 +S _write Ref00000000 +S ?S_MUL_L02 Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S close Ref00000000 +S strlen Ref00000000 +S ?C_V_SWITCH_L06 Ref00000000 +S ioctl Ref00000000 +S free Ref00000000 +S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S stdout Ref00000000 +S ?S_V_SWITCH_L06 Ref00000000 +S ?ENT_AUTO_DIRECT_L09 Ref00000000 +S ?SS_CMP_L02 Ref00000000 +S open Ref00000000 +S ?SS_DIV_L02 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S ?SL_RSH_L03 Ref00000000 +S malloc Ref00000000 +S _read Ref00000000 +S ?SS_RSH_L02 Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 22FC flags 0 +S Window_new Def00000F71 +S stringheight2 Def00000583 +S GraphicsOpen Def00000000 +S Component_findXY Def0000074A +S Text Def00000239 +S GUIunit Def00002222 +S Button_new Def00001235 +S setCurrentFont Def000003A5 +S ToggleButton_new Def0000140F +S ClearScreen Def000002BD +S gui_globals Def000020F5 +S Component_delete_children Def00000997 +S Component_paint Def00000704 +S stringheight Def00000553 +S Window_paint Def00000D9F +S Component_find Def0000078E +S Window_handler Def00000AD2 +S FillRect Def0000016A +S loadFont Def00000433 +S Button_paint Def00001136 +S rootWindow_handler Def000018F0 +S ToggleButton_paint Def00001323 +S Dialog_new Def0000151A +S Button_handler Def00000FC3 +S read_stringtable Def00002020 +S ToggleButton_handler Def00001287 +S GUIgo Def00002247 +S Component_add Def000006A6 +S grSetFont Def00000338 +S Display_new Def000017D6 +S Window_add Def00000F63 +S GrayRect Def000001F4 +S Component_changestate_children Def000009B6 +S Button_add Def0000122F +S Component_delete Def000007C6 +S FillRectNC Def000001AF +S stringwidth0 Def0000058C +S screenbuilder Def0000190E +S TouchRegion Def00000266 +S GraphicsClose Def0000008E +S EnableScreen Def000002FA +S stringwidth1 Def0000059D +S stringwidth2 Def000005A6 +S Label_new Def00001897 +S fontSearch Def00000375 +S DrawRectNC Def00000125 +S Dialog_handler Def00001461 +S Button_drawtext Def0000107A +S stringheight01 Def00000570 +S Display_paint Def0000168A +S Display_handler Def00001609 +S ClearRect Def000000E2 +S stringwidth Def000004DA +S Move Def000000A3 +S GUIinit Def000020FB +S Label_paint Def00001836 +S Component_new Def000005AF +S Label_handler Def00001830 +S Component_setlabel Def00000659 +S root_actionhandler Def00001CE8 +S Root_paint Def00000F2C +S Component_linkstringtable Def00000A1F +A CSTR size 21 flags 0 +A CONST size 34 flags 0 +A UDATA0 size 2 flags 0 +S global Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 F8 FF 21 06 00 39 +R 00 00 01 00 02 05 0E 00 +T 09 00 00 00 EB 21 00 00 00 00 01 02 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 12 00 00 00 2A 00 00 00 00 23 23 E5 03 03 C5 +R 00 00 01 00 00 05 04 00 +T 1B 00 00 00 01 00 00 00 00 C5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 10 00 +T 21 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 10 00 02 0A 0B 00 +T 28 00 00 00 F1 4D 44 E1 71 23 70 21 00 00 39 +R 00 00 01 00 +T 33 00 00 00 E5 21 00 00 E5 2A 00 00 00 00 23 +R 00 00 01 00 00 0A 04 00 +T 3C 00 00 00 23 4E 23 46 C5 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 08 00 +T 44 00 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 0B 00 +T 4B 00 00 00 F1 DD 36 FC 60 DD 36 FD 00 21 +R 00 00 01 00 +T 55 00 00 00 00 00 39 E5 21 01 00 E5 2A +R 00 00 01 00 +T 5E 00 00 00 00 00 00 00 23 23 4E 23 46 C5 3E +R 00 00 01 00 00 04 04 00 +T 67 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 6C 00 00 00 00 00 00 00 F1 F1 F1 21 02 00 E5 +R 00 00 01 00 02 04 0B 00 +T 75 00 00 00 2E 08 +R 00 00 01 00 +T 77 00 00 00 +R 00 00 01 00 +T 77 00 00 00 39 4D +R 00 00 01 00 +T 79 00 00 00 +R 00 00 01 00 +T 79 00 00 00 44 2A 00 00 00 00 +R 00 00 01 00 00 06 04 00 +T 7D 00 00 00 +R 00 00 01 00 +T 7D 00 00 00 23 23 +R 00 00 01 00 +T 7F 00 00 00 +R 00 00 01 00 +T 7F 00 00 00 5E 23 +R 00 00 01 00 +T 81 00 00 00 +R 00 00 01 00 +T 81 00 00 00 56 3E 00 00 00 00 +R 00 00 01 00 2B 06 02 00 +T 84 00 00 00 +R 00 00 01 00 +T 84 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 02 00 02 0A 0B 00 +T 8B 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T 8E 00 00 00 +R 00 00 01 00 +T 8E 00 00 00 D5 2A 00 00 00 00 23 23 5E 23 56 +R 00 00 01 00 00 06 04 00 +T 97 00 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 05 00 02 0A 05 00 +T 9D 00 00 00 00 00 00 00 D1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 00 00 +T A3 00 00 00 +R 00 00 01 00 +T A3 00 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T AC 00 00 00 EB 21 02 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T B5 00 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T C0 00 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T C8 00 00 00 77 00 00 00 4D +R 00 00 01 00 00 04 01 00 +T CB 00 00 00 +R 00 00 01 00 +T CB 00 00 00 C3 79 00 00 00 2A 00 00 00 00 23 +R 00 00 01 00 00 05 01 00 00 0A 04 00 +T D2 00 00 00 23 +R 00 00 01 00 +T D3 00 00 00 +R 00 00 01 00 +T D3 00 00 00 5E 23 +R 00 00 01 00 +T D5 00 00 00 +R 00 00 01 00 +T D5 00 00 00 56 3E 00 00 00 00 +R 00 00 01 00 2B 06 02 00 +T D8 00 00 00 +R 00 00 01 00 +T D8 00 00 00 C3 84 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T DF 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T E2 00 00 00 +R 00 00 01 00 +T E2 00 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T EB 00 00 00 EB 21 06 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T F4 00 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T FF 00 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T 07 01 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 0E 01 00 00 00 00 00 00 +R 00 00 01 00 00 04 04 00 +T 10 01 00 00 +R 00 00 01 00 +T 10 01 00 00 C3 7D 00 00 00 23 C3 D3 00 00 00 +R 00 00 01 00 00 05 01 00 00 0B 01 00 +T 17 01 00 00 23 56 3E 00 00 00 00 +R 00 00 01 00 2B 07 02 00 +T 1B 01 00 00 +R 00 00 01 00 +T 1B 01 00 00 C3 84 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T 22 01 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T 25 01 00 00 +R 00 00 01 00 +T 25 01 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T 2E 01 00 00 EB 21 0A 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 37 01 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T 42 01 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T 4A 01 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 51 01 00 00 00 00 00 00 C3 10 01 00 00 23 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T 57 01 00 00 +R 00 00 01 00 +T 57 01 00 00 C3 7F 00 00 00 23 C3 D5 00 00 00 +R 00 00 01 00 00 05 01 00 00 0B 01 00 +T 5E 01 00 00 3E 00 00 00 00 C3 1B 01 00 00 CD +R 00 00 01 00 2B 05 02 00 00 0A 01 00 +T 64 01 00 00 00 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 04 00 +T 6A 01 00 00 +R 00 00 01 00 +T 6A 01 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T 73 01 00 00 EB 21 0E 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 7C 01 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T 87 01 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T 8F 01 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 96 01 00 00 00 00 00 00 C3 10 01 00 00 23 C3 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T 9D 01 00 00 57 01 00 00 23 +R 00 00 01 00 00 04 01 00 +T A0 01 00 00 +R 00 00 01 00 +T A0 01 00 00 C3 81 00 00 00 3E 00 00 00 00 C3 +R 00 00 01 00 00 05 01 00 2B 0A 02 00 +T A6 01 00 00 D8 00 00 00 CD 00 00 00 00 F1 C3 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T AD 01 00 00 00 00 00 00 +R 00 00 01 00 02 04 04 00 +T AF 01 00 00 +R 00 00 01 00 +T AF 01 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T B8 01 00 00 EB 21 12 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T C1 01 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T CC 01 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T D4 01 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T DB 01 00 00 00 00 00 00 C3 10 01 00 00 23 C3 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T E2 01 00 00 57 01 00 00 23 C3 A0 01 00 00 3E +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T E9 01 00 00 00 00 00 00 +R 00 00 01 00 2B 04 02 00 +T EA 01 00 00 +R 00 00 01 00 +T EA 01 00 00 C3 84 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T F1 01 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T F4 01 00 00 +R 00 00 01 00 +T F4 01 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T FD 01 00 00 EB 21 16 00 00 00 01 04 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 06 02 00 00 DD 46 02 DD 70 FE DD 46 04 DD 70 +R 00 00 01 00 +T 11 02 00 00 FF 21 04 00 E5 2B 2B C3 +R 00 00 01 00 +T 19 02 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 20 02 00 00 00 00 00 00 C3 10 01 00 00 23 C3 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T 27 02 00 00 57 01 00 00 23 C3 A0 01 00 00 3E +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 2E 02 00 00 00 00 00 00 C3 EA 01 00 00 CD +R 00 00 01 00 2B 04 02 00 00 09 01 00 +T 33 02 00 00 00 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 04 00 +T 39 02 00 00 +R 00 00 01 00 +T 39 02 00 00 C5 FD E5 DD E5 D5 DD E1 3E +R 00 00 01 00 +T 42 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 06 00 02 09 06 00 +T 47 02 00 00 00 00 00 00 E5 DD E5 C1 2A +R 00 00 01 00 02 04 0B 00 +T 4E 02 00 00 00 00 00 00 23 23 5E 23 56 3E +R 00 00 01 00 00 04 04 00 +T 56 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 02 00 02 09 02 00 +T 5B 02 00 00 00 00 00 00 F1 +R 00 00 01 00 02 04 0B 00 +T 5E 02 00 00 +R 00 00 01 00 +T 5E 02 00 00 DD E1 FD E1 C1 C3 00 00 00 00 +R 00 00 01 00 02 0A 00 00 +T 66 02 00 00 +R 00 00 01 00 +T 66 02 00 00 CD 00 00 00 00 F8 FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T 6F 02 00 00 EB 21 1A 00 00 00 01 07 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 78 02 00 00 DD 46 02 DD 70 FA DD 46 04 DD 70 +R 00 00 01 00 +T 83 02 00 00 FB DD 46 0A DD 70 FC DD 46 0C DD +R 00 00 01 00 +T 8E 02 00 00 70 FD DD 46 0E DD 70 FE 21 07 00 +R 00 00 01 00 +T 99 02 00 00 E5 2E 02 C3 77 00 00 00 4D C3 +R 00 00 01 00 00 08 01 00 +T A1 02 00 00 CB 00 00 00 2A 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 00 09 04 00 +T A7 02 00 00 10 01 00 00 23 C3 57 01 00 00 23 +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T AE 02 00 00 C3 A0 01 00 00 3E 00 00 00 00 C3 +R 00 00 01 00 00 05 01 00 2B 0A 02 00 +T B4 02 00 00 EA 01 00 00 CD 00 00 00 00 F1 C3 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T BB 02 00 00 00 00 00 00 +R 00 00 01 00 02 04 04 00 +T BD 02 00 00 +R 00 00 01 00 +T BD 02 00 00 C5 D5 CD D7 02 00 00 CD +R 00 00 01 00 00 07 01 00 +T C3 02 00 00 00 00 00 00 21 80 00 E5 6C E5 E5 +R 00 00 01 00 02 04 0B 00 +T CC 02 00 00 CD EF 02 00 00 E1 E1 E1 D1 C1 C3 +R 00 00 01 00 00 05 01 00 +T D5 02 00 00 00 00 00 00 +R 00 00 01 00 02 04 00 00 +T D7 02 00 00 +R 00 00 01 00 +T D7 02 00 00 01 00 00 59 50 3E A3 00 00 00 21 +R 00 00 01 00 29 0A 01 00 +T DF 02 00 00 A3 00 00 00 CD 00 00 00 00 01 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T E5 02 00 00 80 00 58 50 3E E2 00 00 00 21 +R 00 00 01 00 29 09 01 00 +T EC 02 00 00 E2 00 00 00 C9 +R 00 00 01 00 00 04 01 00 +T EF 02 00 00 +R 00 00 01 00 +T EF 02 00 00 4D 44 EB +R 00 00 01 00 +T F2 02 00 00 +R 00 00 01 00 +T F2 02 00 00 3E 66 02 00 00 21 66 02 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T F8 02 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T FA 02 00 00 +R 00 00 01 00 +T FA 02 00 00 CD 00 00 00 00 FC FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T 03 03 00 00 EB 21 21 00 00 00 01 03 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 0C 03 00 00 DD 46 02 DD 70 FE 21 03 00 E5 2B +R 00 00 01 00 +T 17 03 00 00 C3 77 00 00 00 4D C3 CB 00 00 00 +R 00 00 01 00 00 05 01 00 00 0B 01 00 +T 1E 03 00 00 2A 00 00 00 00 C3 10 01 00 00 23 +R 00 00 01 00 00 05 04 00 00 0A 01 00 +T 25 03 00 00 C3 57 01 00 00 23 C3 A0 01 00 00 +R 00 00 01 00 00 05 01 00 00 0B 01 00 +T 2C 03 00 00 3E 00 00 00 00 C3 EA 01 00 00 CD +R 00 00 01 00 2B 05 02 00 00 0A 01 00 +T 32 03 00 00 00 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 04 00 +T 38 03 00 00 +R 00 00 01 00 +T 38 03 00 00 CD 00 00 00 00 FE FF 21 00 00 39 +R 00 00 01 00 02 05 0E 00 +T 41 03 00 00 EB 21 24 00 00 00 01 02 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 4A 03 00 00 DD 46 02 DD 70 FF 21 02 00 E5 C3 +R 00 00 01 00 +T 55 03 00 00 77 00 00 00 4D C3 CB 00 00 00 2A +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 5C 03 00 00 00 00 00 00 C3 10 01 00 00 23 C3 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T 63 03 00 00 57 01 00 00 23 C3 A0 01 00 00 3E +R 00 00 01 00 00 04 01 00 00 0A 01 00 +T 6A 03 00 00 00 00 00 00 C3 EA 01 00 00 CD +R 00 00 01 00 2B 04 02 00 00 09 01 00 +T 6F 03 00 00 00 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 04 00 +T 75 03 00 00 +R 00 00 01 00 +T 75 03 00 00 CD 00 00 00 00 00 00 21 0C 00 ED +R 00 00 01 00 02 05 0E 00 +T 7E 03 00 00 4B 00 00 00 00 09 +R 00 00 01 00 00 05 04 00 +T 82 03 00 00 +R 00 00 01 00 +T 82 03 00 00 46 23 66 68 EB +R 00 00 01 00 +T 87 03 00 00 +R 00 00 01 00 +T 87 03 00 00 7B B2 28 16 6B 62 46 23 66 68 DD +R 00 00 01 00 +T 92 03 00 00 4E 02 DD 46 03 ED 42 28 06 +R 00 00 01 00 +T 9B 03 00 00 +R 00 00 01 00 +T 9B 03 00 00 +R 00 00 01 00 +T 9B 03 00 00 +R 00 00 01 00 +T 9B 03 00 00 21 08 00 19 18 E1 +R 00 00 01 00 +T A1 03 00 00 +R 00 00 01 00 +T A1 03 00 00 EB C3 00 00 00 00 +R 00 00 01 00 02 06 04 00 +T A5 03 00 00 +R 00 00 01 00 +T A5 03 00 00 CD 00 00 00 00 3E 75 03 00 00 21 +R 00 00 01 00 02 05 0A 00 29 0A 01 00 +T AB 03 00 00 75 03 00 00 CD 22 04 00 00 28 29 +R 00 00 01 00 00 04 01 00 00 09 01 00 +T B2 03 00 00 +R 00 00 01 00 +T B2 03 00 00 DD 5E 02 DD 56 03 3E 38 03 00 00 +R 00 00 01 00 29 0B 01 00 +T BA 03 00 00 21 38 03 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T C1 03 00 00 0A 00 ED 4B 00 00 00 00 09 E5 DD +R 00 00 01 00 00 08 04 00 +T CA 03 00 00 5E 02 DD 56 03 3E 75 03 00 00 21 +R 00 00 01 00 29 0A 01 00 +T D2 03 00 00 75 03 00 00 CD 2D 04 00 00 E1 71 +R 00 00 01 00 00 04 01 00 00 09 01 00 +T D9 03 00 00 23 70 +R 00 00 01 00 +T DB 03 00 00 +R 00 00 01 00 +T DB 03 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T DE 03 00 00 +R 00 00 01 00 +T DE 03 00 00 ED 4B 00 00 00 00 09 46 23 66 68 +R 00 00 01 00 00 06 04 00 +T E7 03 00 00 +R 00 00 01 00 +T E7 03 00 00 23 23 4E 23 46 23 7E 69 60 CD +R 00 00 01 00 +T F1 03 00 00 00 00 00 00 4D 44 FD 6E 06 FD 66 +R 00 00 01 00 02 04 0B 00 +T FA 03 00 00 07 A7 ED 42 EB 01 02 00 CD +R 00 00 01 00 +T 03 04 00 00 00 00 00 00 DD 6E 04 DD 66 05 19 +R 00 00 01 00 02 04 11 00 +T 0C 04 00 00 EB 3E A3 00 00 00 21 A3 00 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 12 04 00 00 C9 +R 00 00 01 00 +T 13 04 00 00 +R 00 00 01 00 +T 13 04 00 00 CD 00 00 00 00 4D 44 FD 6E 08 FD +R 00 00 01 00 02 05 0B 00 +T 1C 04 00 00 66 09 A7 ED 42 C9 +R 00 00 01 00 +T 22 04 00 00 +R 00 00 01 00 +T 22 04 00 00 CD 00 00 00 00 7D B4 C9 +R 00 00 01 00 02 05 0B 00 +T 28 04 00 00 +R 00 00 01 00 +T 28 04 00 00 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 05 14 00 02 0A 14 00 +T 2D 04 00 00 +R 00 00 01 00 +T 2D 04 00 00 CD 00 00 00 00 4D 44 C9 +R 00 00 01 00 02 05 0B 00 +T 33 04 00 00 +R 00 00 01 00 +T 33 04 00 00 CD 00 00 00 00 FC FF FD E5 11 +R 00 00 01 00 02 05 0E 00 +T 3B 04 00 00 0E 00 CD CE 04 00 00 DD 4E 02 71 +R 00 00 01 00 00 07 01 00 +T 44 04 00 00 DD 46 03 23 70 DD 46 0C DD 6E 0A +R 00 00 01 00 +T 4F 04 00 00 FD 75 02 DD 66 0B FD 74 03 FD 70 +R 00 00 01 00 +T 5A 04 00 00 04 DD 46 10 DD 6E 0E FD 75 05 DD +R 00 00 01 00 +T 65 04 00 00 66 0F FD 74 06 FD 70 07 AF FD 77 +R 00 00 01 00 +T 70 04 00 00 08 FD 77 09 DD 6E 12 FD 75 0A DD +R 00 00 01 00 +T 7B 04 00 00 66 13 FD 74 0B DD 6E 14 FD 75 0C +R 00 00 01 00 +T 86 04 00 00 DD 66 15 FD 74 0D 21 0C 00 ED 4B +R 00 00 01 00 +T 91 04 00 00 00 00 00 00 09 7E 23 B6 21 0C 00 +R 00 00 01 00 00 04 04 00 +T 9A 04 00 00 ED 4B 00 00 00 00 09 20 10 +R 00 00 01 00 00 06 04 00 +T A1 04 00 00 +R 00 00 01 00 +T A1 04 00 00 FD E5 C1 71 23 70 21 0A 00 ED 4B +R 00 00 01 00 +T AC 04 00 00 00 00 00 00 09 18 12 +R 00 00 01 00 00 04 04 00 +T B1 04 00 00 +R 00 00 01 00 +T B1 04 00 00 46 23 66 68 EB +R 00 00 01 00 +T B6 04 00 00 +R 00 00 01 00 +T B6 04 00 00 21 08 00 19 7E 23 B6 21 08 00 19 +R 00 00 01 00 +T C1 04 00 00 20 EE +R 00 00 01 00 +T C3 04 00 00 +R 00 00 01 00 +T C3 04 00 00 +R 00 00 01 00 +T C3 04 00 00 FD E5 C1 71 23 70 +R 00 00 01 00 +T C9 04 00 00 +R 00 00 01 00 +T C9 04 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T CE 04 00 00 +R 00 00 01 00 +T CE 04 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 14 00 02 0A 14 00 +T D4 04 00 00 00 00 00 00 E5 FD E1 C9 +R 00 00 01 00 02 04 0B 00 +T DA 04 00 00 +R 00 00 01 00 +T DA 04 00 00 FD E5 DD E5 C5 D5 DD 21 00 00 FD +R 00 00 01 00 +T E5 04 00 00 21 00 00 +R 00 00 01 00 +T E8 04 00 00 +R 00 00 01 00 +T E8 04 00 00 FD E5 21 02 00 39 4E 23 46 E1 09 +R 00 00 01 00 +T F3 04 00 00 7E B7 28 50 +R 00 00 01 00 +T F7 04 00 00 +R 00 00 01 00 +T F7 04 00 00 FD E5 E1 09 5E CD 00 00 00 00 +R 00 00 01 00 02 0A 07 00 +T FF 04 00 00 0A 00 21 2C 2E 31 49 69 6A 6B 6C +R 00 00 01 00 +T 0A 05 00 00 72 35 05 00 00 30 05 00 00 +R 00 00 01 00 00 05 01 00 00 09 01 00 +T 0F 05 00 00 26 05 00 00 30 05 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 13 05 00 00 30 05 00 00 21 05 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 17 05 00 00 21 05 00 00 2B 05 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 1B 05 00 00 2B 05 00 00 2B 05 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 1F 05 00 00 21 05 00 00 +R 00 00 01 00 00 04 01 00 +T 21 05 00 00 +R 00 00 01 00 +T 21 05 00 00 01 02 00 18 12 +R 00 00 01 00 +T 26 05 00 00 +R 00 00 01 00 +T 26 05 00 00 01 03 00 18 0D +R 00 00 01 00 +T 2B 05 00 00 +R 00 00 01 00 +T 2B 05 00 00 01 04 00 18 08 +R 00 00 01 00 +T 30 05 00 00 +R 00 00 01 00 +T 30 05 00 00 01 05 00 18 03 +R 00 00 01 00 +T 35 05 00 00 +R 00 00 01 00 +T 35 05 00 00 01 06 00 +R 00 00 01 00 +T 38 05 00 00 +R 00 00 01 00 +T 38 05 00 00 DD 09 +R 00 00 01 00 +T 3A 05 00 00 +R 00 00 01 00 +T 3A 05 00 00 21 02 00 39 4E 23 46 DD 09 FD 23 +R 00 00 01 00 +T 45 05 00 00 18 A1 +R 00 00 01 00 +T 47 05 00 00 +R 00 00 01 00 +T 47 05 00 00 DD E5 E1 F1 F1 DD E1 FD E1 C3 +R 00 00 01 00 +T 51 05 00 00 00 00 00 00 +R 00 00 01 00 02 04 00 00 +T 53 05 00 00 +R 00 00 01 00 +T 53 05 00 00 CD 00 00 00 00 7B FE 80 30 06 +R 00 00 01 00 02 05 0A 00 +T 5B 05 00 00 +R 00 00 01 00 +T 5B 05 00 00 21 07 00 09 18 0C +R 00 00 01 00 +T 61 05 00 00 +R 00 00 01 00 +T 61 05 00 00 FE CC 38 08 3E DF BB 38 03 +R 00 00 01 00 +T 6A 05 00 00 +R 00 00 01 00 +T 6A 05 00 00 +R 00 00 01 00 +T 6A 05 00 00 +R 00 00 01 00 +T 6A 05 00 00 69 60 23 +R 00 00 01 00 +T 6D 05 00 00 +R 00 00 01 00 +T 6D 05 00 00 +R 00 00 01 00 +T 6D 05 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T 70 05 00 00 +R 00 00 01 00 +T 70 05 00 00 CD 00 00 00 00 01 00 00 +R 00 00 01 00 02 05 0A 00 +T 76 05 00 00 +R 00 00 01 00 +T 76 05 00 00 1A 5F 3E 53 05 00 00 21 +R 00 00 01 00 29 07 01 00 +T 7B 05 00 00 53 05 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 81 05 00 00 00 00 00 00 +R 00 00 01 00 02 04 04 00 +T 83 05 00 00 +R 00 00 01 00 +T 83 05 00 00 CD 00 00 00 00 01 05 00 C3 +R 00 00 01 00 02 05 0A 00 +T 8A 05 00 00 76 05 00 00 +R 00 00 01 00 00 04 01 00 +T 8C 05 00 00 +R 00 00 01 00 +T 8C 05 00 00 CD 00 00 00 00 01 00 00 +R 00 00 01 00 02 05 0A 00 +T 92 05 00 00 +R 00 00 01 00 +T 92 05 00 00 3E DA 04 00 00 21 DA 04 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 98 05 00 00 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 09 04 00 +T 9D 05 00 00 +R 00 00 01 00 +T 9D 05 00 00 CD 00 00 00 00 01 02 00 C3 +R 00 00 01 00 02 05 0A 00 +T A4 05 00 00 92 05 00 00 +R 00 00 01 00 00 04 01 00 +T A6 05 00 00 +R 00 00 01 00 +T A6 05 00 00 CD 00 00 00 00 01 03 00 C3 +R 00 00 01 00 02 05 0A 00 +T AD 05 00 00 92 05 00 00 +R 00 00 01 00 00 04 01 00 +T AF 05 00 00 +R 00 00 01 00 +T AF 05 00 00 CD 00 00 00 00 00 00 FD E5 11 +R 00 00 01 00 02 05 0E 00 +T B7 05 00 00 28 00 CD CE 04 00 00 2A +R 00 00 01 00 00 07 01 00 +T BD 05 00 00 00 00 00 00 5E 23 56 13 72 2B 73 +R 00 00 01 00 00 04 04 00 +T C6 05 00 00 FD E5 E1 73 23 72 DD 6E 02 FD 75 +R 00 00 01 00 +T D1 05 00 00 02 DD 66 03 FD 74 03 FD 71 04 FD +R 00 00 01 00 +T DC 05 00 00 70 05 DD 6E 0A FD 75 06 DD 66 0B +R 00 00 01 00 +T E7 05 00 00 FD 74 07 DD 6E 0C FD 75 08 DD 66 +R 00 00 01 00 +T F2 05 00 00 0D FD 74 09 AF FD 77 0A FD 77 0B +R 00 00 01 00 +T FD 05 00 00 FD 77 0C FD 77 0D FD 77 0E FD 77 +R 00 00 01 00 +T 08 06 00 00 0F FD 77 10 FD 77 11 FD 77 12 FD +R 00 00 01 00 +T 13 06 00 00 77 13 FD 77 14 FD 77 15 FD 77 16 +R 00 00 01 00 +T 1E 06 00 00 FD 77 17 FD 77 18 FD 77 19 FD 77 +R 00 00 01 00 +T 29 06 00 00 1A FD 77 1B FD 77 1C FD 77 1D FD +R 00 00 01 00 +T 34 06 00 00 77 1E FD 77 1F FD 77 24 FD 77 25 +R 00 00 01 00 +T 3F 06 00 00 FD 77 26 FD 77 27 FD 77 20 FD 77 +R 00 00 01 00 +T 4A 06 00 00 21 FD 77 22 FD 77 23 +R 00 00 01 00 +T 51 06 00 00 +R 00 00 01 00 +T 51 06 00 00 FD E5 E1 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 0A 04 00 +T 59 06 00 00 +R 00 00 01 00 +T 59 06 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 62 06 00 00 02 DD 66 03 E5 FD E1 11 00 00 +R 00 00 01 00 +T 6C 06 00 00 +R 00 00 01 00 +T 6C 06 00 00 DD 6E 04 DD 66 05 19 7E B7 28 21 +R 00 00 01 00 +T 77 06 00 00 01 14 80 6B 62 78 AC 67 ED 42 30 +R 00 00 01 00 +T 82 06 00 00 15 +R 00 00 01 00 +T 83 06 00 00 +R 00 00 01 00 +T 83 06 00 00 +R 00 00 01 00 +T 83 06 00 00 +R 00 00 01 00 +T 83 06 00 00 FD 6E 20 FD 66 21 19 E5 DD 6E 04 +R 00 00 01 00 +T 8E 06 00 00 DD 66 05 19 46 E1 70 13 18 D4 +R 00 00 01 00 +T 98 06 00 00 +R 00 00 01 00 +T 98 06 00 00 FD 6E 20 FD 66 21 19 36 00 FD E1 +R 00 00 01 00 +T A3 06 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T A6 06 00 00 +R 00 00 01 00 +T A6 06 00 00 CD 00 00 00 00 00 00 FD E5 59 50 +R 00 00 01 00 02 05 0E 00 +T AF 06 00 00 21 15 00 DD 4E 02 DD 46 03 09 7E +R 00 00 01 00 +T BA 06 00 00 23 66 6F E5 FD E1 21 15 00 09 7E +R 00 00 01 00 +T C5 06 00 00 23 B6 20 09 +R 00 00 01 00 +T C9 06 00 00 +R 00 00 01 00 +T C9 06 00 00 21 15 00 09 73 23 72 18 19 +R 00 00 01 00 +T D2 06 00 00 +R 00 00 01 00 +T D2 06 00 00 +R 00 00 01 00 +T D2 06 00 00 FD 7E 13 FD B6 14 28 0B +R 00 00 01 00 +T DA 06 00 00 +R 00 00 01 00 +T DA 06 00 00 FD 6E 13 FD 66 14 E5 FD E1 18 ED +R 00 00 01 00 +T E5 06 00 00 +R 00 00 01 00 +T E5 06 00 00 FD 73 13 FD 72 14 +R 00 00 01 00 +T EB 06 00 00 +R 00 00 01 00 +T EB 06 00 00 21 13 00 19 77 23 77 +R 00 00 01 00 +T F2 06 00 00 +R 00 00 01 00 +T F2 06 00 00 21 11 00 19 DD 4E 02 71 DD 46 03 +R 00 00 01 00 +T FD 06 00 00 23 70 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 09 04 00 +T 04 07 00 00 +R 00 00 01 00 +T 04 07 00 00 C5 FD E5 DD E5 21 15 00 19 46 23 +R 00 00 01 00 +T 0F 07 00 00 66 68 E5 DD E1 CD 40 07 00 00 +R 00 00 01 00 00 0A 01 00 +T 17 07 00 00 +R 00 00 01 00 +T 17 07 00 00 DD E5 E1 7D B4 28 1A +R 00 00 01 00 +T 1E 07 00 00 +R 00 00 01 00 +T 1E 07 00 00 DD E5 D1 DD 7E 1C DD 6E 1A DD 66 +R 00 00 01 00 +T 29 07 00 00 1B CD 00 00 00 00 DD 6E 13 DD 66 +R 00 00 01 00 02 06 0B 00 +T 32 07 00 00 14 E5 DD E1 18 DF +R 00 00 01 00 +T 38 07 00 00 +R 00 00 01 00 +T 38 07 00 00 1E 01 CD 42 07 00 00 C3 +R 00 00 01 00 00 07 01 00 +T 3E 07 00 00 5E 02 00 00 +R 00 00 01 00 00 04 01 00 +T 40 07 00 00 +R 00 00 01 00 +T 40 07 00 00 1E 00 +R 00 00 01 00 +T 42 07 00 00 +R 00 00 01 00 +T 42 07 00 00 3E FA 02 00 00 21 FA 02 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 48 07 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 4A 07 00 00 +R 00 00 01 00 +T 4A 07 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 53 07 00 00 02 DD 66 03 E5 FD E1 +R 00 00 01 00 +T 5A 07 00 00 +R 00 00 01 00 +T 5A 07 00 00 DD 6E 04 DD 66 05 7E FD 86 02 77 +R 00 00 01 00 +T 65 07 00 00 23 7E FD 8E 03 77 DD 6E 0A DD 66 +R 00 00 01 00 +T 70 07 00 00 0B 7E FD 86 04 77 23 7E FD 8E 05 +R 00 00 01 00 +T 7B 07 00 00 77 FD 6E 11 FD 66 12 E5 FD E1 7D +R 00 00 01 00 +T 86 07 00 00 B4 20 D1 +R 00 00 01 00 +T 89 07 00 00 +R 00 00 01 00 +T 89 07 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 8E 07 00 00 +R 00 00 01 00 +T 8E 07 00 00 CD 00 00 00 00 00 00 21 15 00 DD +R 00 00 01 00 02 05 0E 00 +T 97 07 00 00 4E 02 DD 46 03 09 +R 00 00 01 00 +T 9D 07 00 00 +R 00 00 01 00 +T 9D 07 00 00 46 23 66 68 EB +R 00 00 01 00 +T A2 07 00 00 +R 00 00 01 00 +T A2 07 00 00 7B B2 28 1B +R 00 00 01 00 +T A6 07 00 00 +R 00 00 01 00 +T A6 07 00 00 21 10 00 19 4E 06 00 DD 6E 04 DD +R 00 00 01 00 +T B1 07 00 00 66 05 A7 ED 42 20 03 +R 00 00 01 00 +T B8 07 00 00 +R 00 00 01 00 +T B8 07 00 00 EB 18 08 +R 00 00 01 00 +T BB 07 00 00 +R 00 00 01 00 +T BB 07 00 00 21 13 00 19 18 DC +R 00 00 01 00 +T C1 07 00 00 +R 00 00 01 00 +T C1 07 00 00 6F 67 +R 00 00 01 00 +T C3 07 00 00 +R 00 00 01 00 +T C3 07 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T C6 07 00 00 +R 00 00 01 00 +T C6 07 00 00 CD 00 00 00 00 F8 FF FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T CF 07 00 00 02 DD 66 03 E5 FD E1 FD 6E 15 DD +R 00 00 01 00 +T DA 07 00 00 75 F8 FD 66 16 DD 74 F9 FD E5 E1 +R 00 00 01 00 +T E5 07 00 00 7D B4 CA 79 09 00 00 +R 00 00 01 00 00 07 01 00 +T EA 07 00 00 +R 00 00 01 00 +T EA 07 00 00 +R 00 00 01 00 +T EA 07 00 00 DD 7E F8 DD B6 F9 28 11 +R 00 00 01 00 +T F2 07 00 00 +R 00 00 01 00 +T F2 07 00 00 DD 5E F8 DD 56 F9 CD 8F 09 00 00 +R 00 00 01 00 00 0B 01 00 +T FB 07 00 00 DD 75 F8 DD 74 F9 18 E7 +R 00 00 01 00 +T 03 08 00 00 +R 00 00 01 00 +T 03 08 00 00 FD 7E 11 FD B6 12 CA 95 08 00 00 +R 00 00 01 00 00 0B 01 00 +T 0C 08 00 00 +R 00 00 01 00 +T 0C 08 00 00 FD 6E 11 FD 66 12 01 15 00 09 46 +R 00 00 01 00 +T 17 08 00 00 23 66 68 FD E5 C1 A7 ED 42 FD 6E +R 00 00 01 00 +T 22 08 00 00 11 FD 66 12 01 15 00 09 20 09 +R 00 00 01 00 +T 2C 08 00 00 +R 00 00 01 00 +T 2C 08 00 00 E5 FD 6E 11 FD 66 12 18 50 +R 00 00 01 00 +T 35 08 00 00 +R 00 00 01 00 +T 35 08 00 00 46 23 66 68 +R 00 00 01 00 +T 39 08 00 00 +R 00 00 01 00 +T 39 08 00 00 DD 75 F8 DD 74 F9 +R 00 00 01 00 +T 3F 08 00 00 +R 00 00 01 00 +T 3F 08 00 00 21 13 00 DD 4E F8 DD 46 F9 09 46 +R 00 00 01 00 +T 4A 08 00 00 23 66 68 FD E5 C1 A7 ED 42 28 19 +R 00 00 01 00 +T 55 08 00 00 21 13 00 DD 4E F8 DD 46 F9 09 7E +R 00 00 01 00 +T 60 08 00 00 23 B6 28 0A +R 00 00 01 00 +T 64 08 00 00 +R 00 00 01 00 +T 64 08 00 00 +R 00 00 01 00 +T 64 08 00 00 +R 00 00 01 00 +T 64 08 00 00 21 13 00 09 56 23 66 6A 18 CB +R 00 00 01 00 +T 6E 08 00 00 +R 00 00 01 00 +T 6E 08 00 00 21 13 00 DD 4E F8 DD 46 F9 09 7E +R 00 00 01 00 +T 79 08 00 00 23 B6 28 18 +R 00 00 01 00 +T 7D 08 00 00 +R 00 00 01 00 +T 7D 08 00 00 21 13 00 09 E5 21 13 00 +R 00 00 01 00 +T 85 08 00 00 +R 00 00 01 00 +T 85 08 00 00 09 46 23 66 68 01 13 00 09 4E 23 +R 00 00 01 00 +T 90 08 00 00 46 E1 71 23 70 +R 00 00 01 00 +T 95 08 00 00 +R 00 00 01 00 +T 95 08 00 00 +R 00 00 01 00 +T 95 08 00 00 +R 00 00 01 00 +T 95 08 00 00 FD 6E 13 DD 75 F8 FD 66 14 DD 74 +R 00 00 01 00 +T A0 08 00 00 F9 3E 04 FD AE 24 FD B6 25 C2 +R 00 00 01 00 +T AA 08 00 00 45 09 00 00 +R 00 00 01 00 00 04 01 00 +T AC 08 00 00 +R 00 00 01 00 +T AC 08 00 00 FD 6E 11 DD 75 FC FD 66 12 DD 74 +R 00 00 01 00 +T B7 08 00 00 FD FD 6E 26 DD 75 FE FD 66 27 DD +R 00 00 01 00 +T C2 08 00 00 74 FF CD 84 09 00 00 DD 6E FE DD +R 00 00 01 00 00 07 01 00 +T CB 08 00 00 66 FF 23 23 CD 84 09 00 00 +R 00 00 01 00 00 09 01 00 +T D2 08 00 00 +R 00 00 01 00 +T D2 08 00 00 DD 7E FC DD B6 FD 28 20 21 24 00 +R 00 00 01 00 +T DD 08 00 00 DD 4E FC DD 46 FD 09 3E 04 AE 23 +R 00 00 01 00 +T E8 08 00 00 B6 28 0F +R 00 00 01 00 +T EB 08 00 00 +R 00 00 01 00 +T EB 08 00 00 +R 00 00 01 00 +T EB 08 00 00 +R 00 00 01 00 +T EB 08 00 00 21 11 00 09 56 DD 72 FC 23 66 DD +R 00 00 01 00 +T F6 08 00 00 74 FD 18 D8 +R 00 00 01 00 +T FA 08 00 00 +R 00 00 01 00 +T FA 08 00 00 DD 7E FC DD B6 FD 28 43 +R 00 00 01 00 +T 02 09 00 00 +R 00 00 01 00 +T 02 09 00 00 21 26 00 DD 4E FC DD 46 FD 09 46 +R 00 00 01 00 +T 0D 09 00 00 DD 70 FE 23 66 DD 74 FF 21 06 00 +R 00 00 01 00 +T 18 09 00 00 ED 4B 00 00 00 00 09 E5 DD 6E FE +R 00 00 01 00 00 06 04 00 +T 21 09 00 00 DD 66 FF 5E 23 56 E1 73 23 72 21 +R 00 00 01 00 +T 2C 09 00 00 08 00 ED 4B 00 00 00 00 09 E5 DD +R 00 00 01 00 00 08 04 00 +T 35 09 00 00 4E FE DD 46 FF 03 03 69 60 4E 23 +R 00 00 01 00 +T 40 09 00 00 46 E1 71 23 70 +R 00 00 01 00 +T 45 09 00 00 +R 00 00 01 00 +T 45 09 00 00 +R 00 00 01 00 +T 45 09 00 00 FD 4E 24 FD 46 25 21 00 00 CD +R 00 00 01 00 +T 4F 09 00 00 00 00 00 00 30 09 +R 00 00 01 00 02 04 0F 00 +T 53 09 00 00 +R 00 00 01 00 +T 53 09 00 00 FD 5E 26 FD 56 27 CD 87 09 00 00 +R 00 00 01 00 00 0B 01 00 +T 5C 09 00 00 +R 00 00 01 00 +T 5C 09 00 00 FD CB 0B 76 20 11 FD 7E 20 FD B6 +R 00 00 01 00 +T 67 09 00 00 21 28 09 +R 00 00 01 00 +T 6A 09 00 00 +R 00 00 01 00 +T 6A 09 00 00 +R 00 00 01 00 +T 6A 09 00 00 +R 00 00 01 00 +T 6A 09 00 00 FD 5E 20 FD 56 21 CD 87 09 00 00 +R 00 00 01 00 00 0B 01 00 +T 73 09 00 00 +R 00 00 01 00 +T 73 09 00 00 FD E5 D1 CD 87 09 00 00 +R 00 00 01 00 00 08 01 00 +T 79 09 00 00 +R 00 00 01 00 +T 79 09 00 00 DD 6E F8 DD 66 F9 FD E1 C3 +R 00 00 01 00 +T 82 09 00 00 00 00 00 00 +R 00 00 01 00 02 04 04 00 +T 84 09 00 00 +R 00 00 01 00 +T 84 09 00 00 5E 23 56 +R 00 00 01 00 +T 87 09 00 00 +R 00 00 01 00 +T 87 09 00 00 3E 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 05 09 00 02 0A 09 00 +T 8D 09 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 8F 09 00 00 +R 00 00 01 00 +T 8F 09 00 00 3E C6 07 00 00 21 C6 07 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 95 09 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 97 09 00 00 +R 00 00 01 00 +T 97 09 00 00 C5 FD E5 DD E5 21 15 00 19 46 23 +R 00 00 01 00 +T A2 09 00 00 66 68 +R 00 00 01 00 +T A4 09 00 00 +R 00 00 01 00 +T A4 09 00 00 E5 DD E1 +R 00 00 01 00 +T A7 09 00 00 +R 00 00 01 00 +T A7 09 00 00 7D B4 28 08 +R 00 00 01 00 +T AB 09 00 00 +R 00 00 01 00 +T AB 09 00 00 DD E5 D1 CD 8F 09 00 00 18 F1 +R 00 00 01 00 00 08 01 00 +T B3 09 00 00 +R 00 00 01 00 +T B3 09 00 00 C3 5E 02 00 00 +R 00 00 01 00 00 05 01 00 +T B6 09 00 00 +R 00 00 01 00 +T B6 09 00 00 CD 00 00 00 00 00 00 FD E5 21 +R 00 00 01 00 02 05 0E 00 +T BE 09 00 00 15 00 DD 5E 02 DD 56 03 19 +R 00 00 01 00 +T C7 09 00 00 +R 00 00 01 00 +T C7 09 00 00 56 23 66 6A E5 FD E1 +R 00 00 01 00 +T CE 09 00 00 +R 00 00 01 00 +T CE 09 00 00 7D B4 28 3D +R 00 00 01 00 +T D2 09 00 00 +R 00 00 01 00 +T D2 09 00 00 21 0A 00 FD E5 C1 09 DD 7E 04 DD +R 00 00 01 00 +T DD 09 00 00 56 05 2F 5F 7A 2F 57 7E A3 77 23 +R 00 00 01 00 +T E8 09 00 00 7E A2 77 21 0A 00 09 7E DD B6 0A +R 00 00 01 00 +T F3 09 00 00 77 23 7E DD B6 0B 77 21 0A 00 09 +R 00 00 01 00 +T FE 09 00 00 7E DD AE 0C 77 23 7E DD AE 0D 77 +R 00 00 01 00 +T 09 0A 00 00 21 13 00 09 18 B8 +R 00 00 01 00 +T 0F 0A 00 00 +R 00 00 01 00 +T 0F 0A 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 0C 00 2B 0A 01 00 +T 15 0A 00 00 00 00 00 00 CD 00 00 00 00 FD E1 +R 00 00 01 00 02 04 01 00 02 09 0B 00 +T 1C 0A 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T 1F 0A 00 00 +R 00 00 01 00 +T 1F 0A 00 00 C5 FD E5 DD E5 D5 DD E1 21 15 00 +R 00 00 01 00 +T 2A 0A 00 00 19 46 23 66 68 E5 FD E1 21 20 00 +R 00 00 01 00 +T 35 0A 00 00 19 46 23 66 68 01 00 90 3E 80 AC +R 00 00 01 00 +T 40 0A 00 00 67 ED 42 30 2E DD 4E 20 DD 46 21 +R 00 00 01 00 +T 4B 0A 00 00 21 00 00 CD 00 00 00 00 30 20 +R 00 00 01 00 02 08 0F 00 +T 53 0A 00 00 +R 00 00 01 00 +T 53 0A 00 00 +R 00 00 01 00 +T 53 0A 00 00 +R 00 00 01 00 +T 53 0A 00 00 DD 6E 20 DD 66 21 29 E5 21 08 00 +R 00 00 01 00 +T 5E 0A 00 00 ED 4B 00 00 00 00 09 4E 23 46 E1 +R 00 00 01 00 00 06 04 00 +T 67 0A 00 00 09 2B 2B 46 DD 70 20 23 66 DD 74 +R 00 00 01 00 +T 72 0A 00 00 21 +R 00 00 01 00 +T 73 0A 00 00 +R 00 00 01 00 +T 73 0A 00 00 DD 6E 22 DD 66 23 01 00 90 3E 80 +R 00 00 01 00 +T 7E 0A 00 00 AC 67 ED 42 30 2E DD 4E 22 DD 46 +R 00 00 01 00 +T 89 0A 00 00 23 21 00 00 CD 00 00 00 00 30 20 +R 00 00 01 00 02 09 0F 00 +T 92 0A 00 00 +R 00 00 01 00 +T 92 0A 00 00 +R 00 00 01 00 +T 92 0A 00 00 +R 00 00 01 00 +T 92 0A 00 00 DD 6E 22 DD 66 23 29 E5 21 08 00 +R 00 00 01 00 +T 9D 0A 00 00 ED 4B 00 00 00 00 09 4E 23 46 E1 +R 00 00 01 00 00 06 04 00 +T A6 0A 00 00 09 2B 2B 46 DD 70 22 23 66 DD 74 +R 00 00 01 00 +T B1 0A 00 00 23 +R 00 00 01 00 +T B2 0A 00 00 +R 00 00 01 00 +T B2 0A 00 00 +R 00 00 01 00 +T B2 0A 00 00 FD E5 E1 7D B4 28 16 +R 00 00 01 00 +T B9 0A 00 00 +R 00 00 01 00 +T B9 0A 00 00 FD E5 D1 3E 1F 0A 00 00 21 +R 00 00 01 00 29 08 01 00 +T BF 0A 00 00 1F 0A 00 00 CD 00 00 00 00 FD 6E +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T C6 0A 00 00 13 FD 66 14 E5 FD E1 18 E3 +R 00 00 01 00 +T CF 0A 00 00 +R 00 00 01 00 +T CF 0A 00 00 C3 5E 02 00 00 +R 00 00 01 00 00 05 01 00 +T D2 0A 00 00 +R 00 00 01 00 +T D2 0A 00 00 CD 00 00 00 00 D0 FF FD E5 AF DD +R 00 00 01 00 02 05 0E 00 +T DB 0A 00 00 77 FA DD 77 FB DD 77 FC DD 77 FD +R 00 00 01 00 +T E6 0A 00 00 59 50 CD 00 00 00 00 08 00 01 00 +R 00 00 01 00 02 07 0D 00 +T EF 0A 00 00 02 00 03 00 02 01 03 01 04 01 +R 00 00 01 00 +T F9 0A 00 00 05 01 01 04 6B 0D 00 00 +R 00 00 01 00 00 08 01 00 +T FF 0A 00 00 D9 0C 00 00 6C 0C 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 03 0B 00 00 98 0C 00 00 E0 0B 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 07 0B 00 00 F1 0B 00 00 A5 0B 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 0B 0B 00 00 40 0B 00 00 0F 0B 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 0F 0B 00 00 +R 00 00 01 00 +T 0F 0B 00 00 21 15 00 DD 4E 02 DD 46 03 09 46 +R 00 00 01 00 +T 1A 0B 00 00 23 66 68 +R 00 00 01 00 +T 1D 0B 00 00 +R 00 00 01 00 +T 1D 0B 00 00 E5 FD E1 +R 00 00 01 00 +T 20 0B 00 00 +R 00 00 01 00 +T 20 0B 00 00 7D B4 28 19 +R 00 00 01 00 +T 24 0B 00 00 +R 00 00 01 00 +T 24 0B 00 00 FD CB 0A 46 28 0B +R 00 00 01 00 +T 2A 0B 00 00 +R 00 00 01 00 +T 2A 0B 00 00 DD 6E 0A DD 66 0B E5 CD +R 00 00 01 00 +T 32 0B 00 00 70 0D 00 00 E1 +R 00 00 01 00 00 04 01 00 +T 35 0B 00 00 +R 00 00 01 00 +T 35 0B 00 00 FD 6E 13 FD 66 14 18 E0 +R 00 00 01 00 +T 3D 0B 00 00 +R 00 00 01 00 +T 3D 0B 00 00 C3 6B 0D 00 00 +R 00 00 01 00 00 05 01 00 +T 40 0B 00 00 +R 00 00 01 00 +T 40 0B 00 00 21 15 00 DD 4E 02 DD 46 03 09 46 +R 00 00 01 00 +T 4B 0B 00 00 23 66 68 +R 00 00 01 00 +T 4E 0B 00 00 +R 00 00 01 00 +T 4E 0B 00 00 E5 FD E1 +R 00 00 01 00 +T 51 0B 00 00 +R 00 00 01 00 +T 51 0B 00 00 7D B4 28 4D +R 00 00 01 00 +T 55 0B 00 00 +R 00 00 01 00 +T 55 0B 00 00 FD CB 0A 46 28 38 +R 00 00 01 00 +T 5B 0B 00 00 +R 00 00 01 00 +T 5B 0B 00 00 DD 6E 0A DD 66 0B E5 CD +R 00 00 01 00 +T 63 0B 00 00 70 0D 00 00 E1 DD 6E 0A DD 66 0B +R 00 00 01 00 00 04 01 00 +T 6C 0B 00 00 E5 01 03 00 CD 76 0D 00 00 E1 FD +R 00 00 01 00 00 09 01 00 +T 75 0B 00 00 7E 0A E6 22 6F 26 00 3E 22 AD 20 +R 00 00 01 00 +T 80 0B 00 00 12 FD 4E 10 44 DD 6E 0A DD 66 0B +R 00 00 01 00 +T 8B 0B 00 00 ED 42 20 04 +R 00 00 01 00 +T 8F 0B 00 00 +R 00 00 01 00 +T 8F 0B 00 00 +R 00 00 01 00 +T 8F 0B 00 00 +R 00 00 01 00 +T 8F 0B 00 00 FD 21 00 00 +R 00 00 01 00 +T 93 0B 00 00 +R 00 00 01 00 +T 93 0B 00 00 +R 00 00 01 00 +T 93 0B 00 00 FD E5 E1 7D B4 28 B7 +R 00 00 01 00 +T 9A 0B 00 00 +R 00 00 01 00 +T 9A 0B 00 00 FD 6E 13 FD 66 14 18 AC +R 00 00 01 00 +T A2 0B 00 00 +R 00 00 01 00 +T A2 0B 00 00 +R 00 00 01 00 +T A2 0B 00 00 C3 6B 0D 00 00 +R 00 00 01 00 00 05 01 00 +T A5 0B 00 00 +R 00 00 01 00 +T A5 0B 00 00 DD 6E 02 DD 66 03 E5 FD E1 21 +R 00 00 01 00 +T AF 0B 00 00 0A 00 DD 4E 02 DD 46 03 09 CB 46 +R 00 00 01 00 +T BA 0B 00 00 28 21 +R 00 00 01 00 +T BC 0B 00 00 +R 00 00 01 00 +T BC 0B 00 00 FD CB 0A 6E 28 1B FD 4E 10 47 DD +R 00 00 01 00 +T C7 0B 00 00 6E 0A DD 66 0B A7 ED 42 20 0C +R 00 00 01 00 +T D1 0B 00 00 +R 00 00 01 00 +T D1 0B 00 00 +R 00 00 01 00 +T D1 0B 00 00 +R 00 00 01 00 +T D1 0B 00 00 FD 6E 26 FD 66 27 FD E5 D1 CD +R 00 00 01 00 +T DB 0B 00 00 95 0D 00 00 +R 00 00 01 00 00 04 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 +R 00 00 01 00 +T DD 0B 00 00 C3 6B 0D 00 00 +R 00 00 01 00 00 05 01 00 +T E0 0B 00 00 +R 00 00 01 00 +T E0 0B 00 00 DD 5E 02 4B DD 56 03 42 21 1A 00 +R 00 00 01 00 +T EB 0B 00 00 CD 94 0D 00 00 C3 6B 0D 00 00 +R 00 00 01 00 00 05 01 00 00 0A 01 00 +T F1 0B 00 00 +R 00 00 01 00 +T F1 0B 00 00 21 0A 00 DD 4E 02 DD 46 03 09 7E +R 00 00 01 00 +T FC 0B 00 00 E6 FC 77 21 2E 00 39 E5 2B 2B 4D +R 00 00 01 00 +T 07 0C 00 00 44 DD 5E 02 DD 56 03 CD +R 00 00 01 00 +T 0F 0C 00 00 8C 0D 00 00 E1 21 08 00 DD 4E 02 +R 00 00 01 00 00 04 01 00 +T 18 0C 00 00 DD 46 03 09 5E 23 56 D5 21 06 00 +R 00 00 01 00 +T 23 0C 00 00 09 5E 23 56 D5 DD 6E FC DD 66 FD +R 00 00 01 00 +T 2E 0C 00 00 E5 DD 4E FA DD 46 FB 11 00 00 CD +R 00 00 01 00 +T 39 0C 00 00 F2 02 00 00 E1 E1 E1 21 00 00 E5 +R 00 00 01 00 00 04 01 00 +T 42 0C 00 00 2E 11 DD 5E 02 DD 56 03 19 5E 23 +R 00 00 01 00 +T 4D 0C 00 00 56 21 11 00 DD 4E 02 DD 46 03 09 +R 00 00 01 00 +T 58 0C 00 00 46 23 66 68 01 17 00 09 4E 23 46 +R 00 00 01 00 +T 63 0C 00 00 23 7E 69 60 01 03 01 18 29 +R 00 00 01 00 +T 6C 0C 00 00 +R 00 00 01 00 +T 6C 0C 00 00 21 11 00 DD 4E 02 DD 46 03 09 56 +R 00 00 01 00 +T 77 0C 00 00 23 66 6A E5 FD E1 59 50 CD +R 00 00 01 00 +T 80 0C 00 00 8F 09 00 00 21 00 00 E5 01 03 01 +R 00 00 01 00 00 04 01 00 +T 89 0C 00 00 FD E5 D1 FD 7E 19 FD 6E 17 FD 66 +R 00 00 01 00 +T 94 0C 00 00 18 +R 00 00 01 00 +T 95 0C 00 00 +R 00 00 01 00 +T 95 0C 00 00 C3 67 0D 00 00 +R 00 00 01 00 00 05 01 00 +T 98 0C 00 00 +R 00 00 01 00 +T 98 0C 00 00 21 15 00 DD 4E 02 DD 46 03 09 46 +R 00 00 01 00 +T A3 0C 00 00 23 66 68 +R 00 00 01 00 +T A6 0C 00 00 +R 00 00 01 00 +T A6 0C 00 00 E5 FD E1 +R 00 00 01 00 +T A9 0C 00 00 +R 00 00 01 00 +T A9 0C 00 00 7D B4 28 29 +R 00 00 01 00 +T AD 0C 00 00 +R 00 00 01 00 +T AD 0C 00 00 DD 6E 0A DD 66 0B FD E5 C1 ED 42 +R 00 00 01 00 +T B8 0C 00 00 28 14 FD CB 0A 5E 28 0E +R 00 00 01 00 +T C0 0C 00 00 +R 00 00 01 00 +T C0 0C 00 00 +R 00 00 01 00 +T C0 0C 00 00 +R 00 00 01 00 +T C0 0C 00 00 DD 6E 0A DD 66 0B E5 01 03 02 CD +R 00 00 01 00 +T CB 0C 00 00 76 0D 00 00 E1 +R 00 00 01 00 00 04 01 00 +T CE 0C 00 00 +R 00 00 01 00 +T CE 0C 00 00 FD 6E 13 FD 66 14 18 D0 +R 00 00 01 00 +T D6 0C 00 00 +R 00 00 01 00 +T D6 0C 00 00 C3 6B 0D 00 00 +R 00 00 01 00 00 05 01 00 +T D9 0C 00 00 +R 00 00 01 00 +T D9 0C 00 00 21 11 00 DD 4E 02 DD 46 03 09 7E +R 00 00 01 00 +T E4 0C 00 00 23 B6 20 0E +R 00 00 01 00 +T E8 0C 00 00 +R 00 00 01 00 +T E8 0C 00 00 21 04 00 ED 4B 00 00 00 00 09 36 +R 00 00 01 00 00 09 04 00 +T F1 0C 00 00 01 23 77 18 75 +R 00 00 01 00 +T F6 0C 00 00 +R 00 00 01 00 +T F6 0C 00 00 21 0A 00 09 23 CB 6E 20 28 +R 00 00 01 00 +T FF 0C 00 00 +R 00 00 01 00 +T FF 0C 00 00 DD 6E 0A DD 66 0B E5 21 11 00 59 +R 00 00 01 00 +T 0A 0D 00 00 50 19 5E 23 56 21 11 00 09 46 23 +R 00 00 01 00 +T 15 0D 00 00 66 68 01 17 00 09 4E 23 46 23 7E +R 00 00 01 00 +T 20 0D 00 00 69 60 01 01 04 18 40 +R 00 00 01 00 +T 27 0D 00 00 +R 00 00 01 00 +T 27 0D 00 00 21 11 00 09 56 23 66 6A E5 FD E1 +R 00 00 01 00 +T 32 0D 00 00 11 0A 00 19 7E F6 03 77 6A 62 E5 +R 00 00 01 00 +T 3D 0D 00 00 23 E5 4A 42 FD E5 D1 3E +R 00 00 01 00 +T 45 0D 00 00 B6 09 00 00 21 B6 09 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 4A 0D 00 00 00 00 00 00 E1 E1 21 00 00 E5 DD +R 00 00 01 00 02 04 0B 00 +T 53 0D 00 00 5E 02 4B DD 56 03 42 2E 17 09 4E +R 00 00 01 00 +T 5E 0D 00 00 23 46 23 7E 69 60 01 05 01 +R 00 00 01 00 +T 67 0D 00 00 +R 00 00 01 00 +T 67 0D 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 02 05 0B 00 +T 6B 0D 00 00 +R 00 00 01 00 +T 6B 0D 00 00 +R 00 00 01 00 +T 6B 0D 00 00 +R 00 00 01 00 +T 6B 0D 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 70 0D 00 00 +R 00 00 01 00 +T 70 0D 00 00 DD 4E 04 DD 46 05 +R 00 00 01 00 +T 76 0D 00 00 +R 00 00 01 00 +T 76 0D 00 00 FD E5 D1 FD 7E 19 FD 6E 17 FD 66 +R 00 00 01 00 +T 81 0D 00 00 18 C3 00 00 00 00 +R 00 00 01 00 02 06 0B 00 +T 85 0D 00 00 +R 00 00 01 00 +T 85 0D 00 00 23 23 +R 00 00 01 00 +T 87 0D 00 00 +R 00 00 01 00 +T 87 0D 00 00 4D 44 DD E5 D1 +R 00 00 01 00 +T 8C 0D 00 00 +R 00 00 01 00 +T 8C 0D 00 00 3E 4A 07 00 00 21 4A 07 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 92 0D 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 94 0D 00 00 +R 00 00 01 00 +T 94 0D 00 00 09 +R 00 00 01 00 +T 95 0D 00 00 +R 00 00 01 00 +T 95 0D 00 00 4E 23 46 23 7E 69 60 C3 +R 00 00 01 00 +T 9D 0D 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 9F 0D 00 00 +R 00 00 01 00 +T 9F 0D 00 00 CD 00 00 00 00 FC FF FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T A8 0D 00 00 02 DD 66 03 E5 FD E1 AF DD 77 FE +R 00 00 01 00 +T B3 0D 00 00 DD 77 FF DD 77 FC DD 77 FD 21 +R 00 00 01 00 +T BD 0D 00 00 0A 00 ED 4B 00 00 00 00 09 7E 23 +R 00 00 01 00 00 08 04 00 +T C6 0D 00 00 66 6F 46 23 66 68 FD 4E 0E FD 46 +R 00 00 01 00 +T D1 0D 00 00 0F A7 ED 42 28 09 +R 00 00 01 00 +T D7 0D 00 00 +R 00 00 01 00 +T D7 0D 00 00 FD 5E 0E FD 56 0F CD 24 0F 00 00 +R 00 00 01 00 00 0B 01 00 +T E0 0D 00 00 +R 00 00 01 00 +T E0 0D 00 00 FD CB 0A 46 CA DC 0E 00 00 +R 00 00 01 00 00 09 01 00 +T E7 0D 00 00 +R 00 00 01 00 +T E7 0D 00 00 21 02 00 39 E5 23 23 4D 44 FD E5 +R 00 00 01 00 +T F2 0D 00 00 D1 CD 8C 0D 00 00 E1 CD +R 00 00 01 00 00 06 01 00 +T F8 0D 00 00 40 07 00 00 DD 4E FC DD 46 FD DD +R 00 00 01 00 00 04 01 00 +T 01 0E 00 00 5E FE DD 56 FF 3E A3 00 00 00 21 +R 00 00 01 00 29 0A 01 00 +T 09 0E 00 00 A3 00 00 00 CD 00 00 00 00 FD 4E +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 10 0E 00 00 08 FD 46 09 FD 5E 06 FD 56 07 3E +R 00 00 01 00 +T 1B 0E 00 00 E2 00 00 00 21 E2 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 20 0E 00 00 00 00 00 00 FD 6E 08 FD 66 09 E5 +R 00 00 01 00 02 04 0B 00 +T 29 0E 00 00 FD 6E 06 FD 66 07 E5 DD 6E FC DD +R 00 00 01 00 +T 34 0E 00 00 66 FD E5 DD 4E FE DD 46 FF 11 +R 00 00 01 00 +T 3E 0E 00 00 00 00 CD F2 02 00 00 E1 E1 E1 FD +R 00 00 01 00 00 07 01 00 +T 47 0E 00 00 5E 20 FD 56 21 21 0A 00 ED 4B +R 00 00 01 00 +T 51 0E 00 00 00 00 00 00 09 7E 23 66 6F CD +R 00 00 01 00 00 04 04 00 +T 59 0E 00 00 E1 0E 00 00 DD 4E FC DD 46 FD 09 +R 00 00 01 00 00 04 01 00 +T 62 0E 00 00 11 04 00 19 4D 44 CD EF 0E 00 00 +R 00 00 01 00 00 0B 01 00 +T 6B 0E 00 00 7E 23 66 6F 01 05 00 09 4E 23 46 +R 00 00 01 00 +T 76 0E 00 00 23 7E 69 60 CD 13 04 00 00 01 +R 00 00 01 00 00 09 01 00 +T 7E 0E 00 00 FC FF 09 4D 44 FD 5E 06 FD 56 07 +R 00 00 01 00 +T 89 0E 00 00 3E 25 01 00 00 21 25 01 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 8F 0E 00 00 00 00 00 00 DD 4E FC DD 46 FD CD +R 00 00 01 00 02 04 0B 00 +T 98 0E 00 00 EF 0E 00 00 46 23 66 68 CD +R 00 00 01 00 00 04 01 00 +T 9F 0E 00 00 E1 0E 00 00 01 05 00 09 4D 44 FD +R 00 00 01 00 00 04 01 00 +T A8 0E 00 00 5E 06 FD 56 07 3E 6A 01 00 00 21 +R 00 00 01 00 29 0A 01 00 +T B0 0E 00 00 6A 01 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T B6 0E 00 00 0E 00 DD 4E FC DD 46 FD 09 4D 44 +R 00 00 01 00 +T C1 0E 00 00 DD 5E FE DD 56 FF 13 13 3E +R 00 00 01 00 +T CA 0E 00 00 A3 00 00 00 21 A3 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T CF 0E 00 00 0C 0F 00 00 FD E5 D1 3E +R 00 00 01 00 00 04 01 00 +T D5 0E 00 00 04 07 00 00 21 04 07 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T DA 0E 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T DC 0E 00 00 +R 00 00 01 00 +T DC 0E 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T E1 0E 00 00 +R 00 00 01 00 +T E1 0E 00 00 01 05 00 09 4E 23 46 23 7E 69 60 +R 00 00 01 00 +T EC 0E 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T EF 0E 00 00 +R 00 00 01 00 +T EF 0E 00 00 DD 5E FE DD 56 FF 3E A3 00 00 00 +R 00 00 01 00 29 0B 01 00 +T F7 0E 00 00 21 A3 00 00 00 CD 00 00 00 00 FD +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T FE 0E 00 00 5E 20 FD 56 21 21 0A 00 ED 4B +R 00 00 01 00 +T 08 0F 00 00 00 00 00 00 09 C9 +R 00 00 01 00 00 04 04 00 +T 0C 0F 00 00 +R 00 00 01 00 +T 0C 0F 00 00 CD 00 00 00 00 FD 5E 20 FD 56 21 +R 00 00 01 00 02 05 0B 00 +T 15 0F 00 00 3E 39 02 00 00 21 39 02 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 1B 0F 00 00 00 00 00 00 C9 +R 00 00 01 00 02 04 0B 00 +T 1E 0F 00 00 +R 00 00 01 00 +T 1E 0F 00 00 DD 5E 0E DD 56 0F +R 00 00 01 00 +T 24 0F 00 00 +R 00 00 01 00 +T 24 0F 00 00 3E A5 03 00 00 21 A5 03 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 2A 0F 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 2C 0F 00 00 +R 00 00 01 00 +T 2C 0F 00 00 CD 00 00 00 00 CD 40 07 00 00 CD +R 00 00 01 00 02 05 0A 00 00 0A 01 00 +T 33 0F 00 00 D7 02 00 00 CD 00 00 00 00 01 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 39 0F 00 00 80 00 58 50 3E F4 01 00 00 21 +R 00 00 01 00 29 09 01 00 +T 40 0F 00 00 F4 01 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 46 0F 00 00 80 00 E5 6C E5 E5 CD EF 02 00 00 +R 00 00 01 00 00 0B 01 00 +T 4F 0F 00 00 E1 E1 E1 DD 5E 02 DD 56 03 3E +R 00 00 01 00 +T 59 0F 00 00 04 07 00 00 21 04 07 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 5E 0F 00 00 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 09 04 00 +T 63 0F 00 00 +R 00 00 01 00 +T 63 0F 00 00 CD 00 00 00 00 3E A6 06 00 00 21 +R 00 00 01 00 02 05 0A 00 29 0A 01 00 +T 69 0F 00 00 A6 06 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 6F 0F 00 00 00 00 00 00 +R 00 00 01 00 02 04 04 00 +T 71 0F 00 00 +R 00 00 01 00 +T 71 0F 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 7A 0F 00 00 0C DD 66 0D E5 DD 6E 0A DD 66 0B +R 00 00 01 00 +T 85 0F 00 00 E5 CD B5 0F 00 00 F1 F1 E5 FD E1 +R 00 00 01 00 00 06 01 00 +T 8E 0F 00 00 01 17 00 09 36 D2 0A 00 00 23 36 +R 00 00 01 00 09 09 01 00 +T 96 0F 00 00 D2 0A 00 00 23 36 D2 0A 00 00 FD +R 00 00 01 00 89 04 01 00 29 0A 01 00 +T 9B 0F 00 00 36 1A 9F 0D 00 00 FD 36 1B +R 00 00 01 00 09 06 01 00 +T A1 0F 00 00 9F 0D 00 00 FD 36 1C 9F 0D 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T A6 0F 00 00 FD 36 1D 63 0F 00 00 FD 36 1E +R 00 00 01 00 09 07 01 00 +T AD 0F 00 00 63 0F 00 00 FD 36 1F 63 0F 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T B2 0F 00 00 C3 51 06 00 00 +R 00 00 01 00 00 05 01 00 +T B5 0F 00 00 +R 00 00 01 00 +T B5 0F 00 00 DD 5E 02 DD 56 03 3E AF 05 00 00 +R 00 00 01 00 29 0B 01 00 +T BD 0F 00 00 21 AF 05 00 00 C3 00 00 00 00 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T C3 0F 00 00 +R 00 00 01 00 +T C3 0F 00 00 CD 00 00 00 00 FD E5 D5 FD E1 DD +R 00 00 01 00 02 05 0A 00 +T CC 0F 00 00 6E 0A DD 66 0B E5 3E D2 0A 00 00 +R 00 00 01 00 29 0B 01 00 +T D4 0F 00 00 21 D2 0A 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T DB 0F 00 00 3E 03 DD AE 04 DD B6 05 20 3E FD +R 00 00 01 00 +T E6 0F 00 00 4E 10 47 DD 6E 0A DD 66 0B ED 42 +R 00 00 01 00 +T F1 0F 00 00 20 30 FD 7E 0A E6 03 28 29 +R 00 00 01 00 +T FA 0F 00 00 +R 00 00 01 00 +T FA 0F 00 00 +R 00 00 01 00 +T FA 0F 00 00 +R 00 00 01 00 +T FA 0F 00 00 DD 6E 0A DD 66 0B E5 FD 5E 11 FD +R 00 00 01 00 +T 05 10 00 00 56 12 FD 6E 11 FD 66 12 0E 17 CD +R 00 00 01 00 +T 10 10 00 00 50 10 00 00 E1 FD CB 0A 66 28 0A +R 00 00 01 00 00 04 01 00 +T 19 10 00 00 +R 00 00 01 00 +T 19 10 00 00 FD 4E 10 06 00 C5 CD 5E 10 00 00 +R 00 00 01 00 00 0B 01 00 +T 22 10 00 00 E1 +R 00 00 01 00 +T 23 10 00 00 +R 00 00 01 00 +T 23 10 00 00 +R 00 00 01 00 +T 23 10 00 00 21 01 02 DD 4E 04 DD 46 05 A7 ED +R 00 00 01 00 +T 2E 10 00 00 42 20 0B +R 00 00 01 00 +T 31 10 00 00 +R 00 00 01 00 +T 31 10 00 00 DD 6E 0A DD 66 0B E5 CD +R 00 00 01 00 +T 39 10 00 00 41 10 00 00 E1 +R 00 00 01 00 00 04 01 00 +T 3C 10 00 00 +R 00 00 01 00 +T 3C 10 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 41 10 00 00 +R 00 00 01 00 +T 41 10 00 00 FD 5E 11 FD 56 12 FD 6E 11 FD 66 +R 00 00 01 00 +T 4C 10 00 00 12 01 17 00 +R 00 00 01 00 +T 50 10 00 00 +R 00 00 01 00 +T 50 10 00 00 09 4E 23 46 23 7E 69 60 01 01 02 +R 00 00 01 00 +T 5B 10 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T 5E 10 00 00 +R 00 00 01 00 +T 5E 10 00 00 FD 5E 11 FD 56 12 FD 6E 11 FD 66 +R 00 00 01 00 +T 69 10 00 00 12 0E 17 09 4E 23 46 23 7E 69 60 +R 00 00 01 00 +T 74 10 00 00 01 04 01 C3 00 00 00 00 +R 00 00 01 00 02 08 0B 00 +T 7A 10 00 00 +R 00 00 01 00 +T 7A 10 00 00 CD 00 00 00 00 FD E5 D5 FD E1 21 +R 00 00 01 00 02 05 0A 00 +T 83 10 00 00 0A 00 19 CB 76 FD 5E 20 FD 56 21 +R 00 00 01 00 +T 8E 10 00 00 21 0A 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T 97 10 00 00 23 66 6F 01 05 00 09 4E 23 46 23 +R 00 00 01 00 +T A2 10 00 00 7E 69 60 28 53 +R 00 00 01 00 +T A7 10 00 00 +R 00 00 01 00 +T A7 10 00 00 CD 00 00 00 00 29 4D 44 FD 6E 08 +R 00 00 01 00 02 05 0B 00 +T B0 10 00 00 FD 66 09 A7 ED 42 CD 27 11 00 00 +R 00 00 01 00 00 0B 01 00 +T B9 10 00 00 0E 0C 09 E5 FD 5E 20 FD 56 21 21 +R 00 00 01 00 +T C4 10 00 00 0A 00 ED 4B 00 00 00 00 09 7E 23 +R 00 00 01 00 00 08 04 00 +T CD 10 00 00 66 6F CD E7 03 00 00 C1 CD +R 00 00 01 00 00 07 01 00 +T D4 10 00 00 0C 0F 00 00 FD 5E 08 FD 56 09 CD +R 00 00 01 00 00 04 01 00 +T DD 10 00 00 28 11 00 00 0E 0A 09 E5 FD 5E 22 +R 00 00 01 00 00 04 01 00 +T E6 10 00 00 FD 56 23 69 60 CD DE 03 00 00 C1 +R 00 00 01 00 00 0A 01 00 +T EF 10 00 00 CD 00 00 00 00 FD 5E 22 FD 56 23 +R 00 00 01 00 02 05 0B 00 +T F8 10 00 00 18 20 +R 00 00 01 00 +T FA 10 00 00 +R 00 00 01 00 +T FA 10 00 00 CD 13 04 00 00 CD 27 11 00 00 0E +R 00 00 01 00 00 05 01 00 00 0A 01 00 +T 01 11 00 00 0D 09 E5 FD 5E 20 FD 56 21 21 +R 00 00 01 00 +T 0B 11 00 00 0A 00 CD DE 03 00 00 C1 CD +R 00 00 01 00 00 07 01 00 +T 12 11 00 00 00 00 00 00 FD 5E 20 FD 56 21 +R 00 00 01 00 02 04 0B 00 +T 1A 11 00 00 +R 00 00 01 00 +T 1A 11 00 00 3E 39 02 00 00 21 39 02 00 00 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 1F 11 00 00 +R 00 00 01 00 +T 1F 11 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T 22 11 00 00 +R 00 00 01 00 +T 22 11 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 27 11 00 00 +R 00 00 01 00 +T 27 11 00 00 EB +R 00 00 01 00 +T 28 11 00 00 +R 00 00 01 00 +T 28 11 00 00 01 02 00 CD 00 00 00 00 DD 6E 0A +R 00 00 01 00 02 08 11 00 +T 31 11 00 00 DD 66 0B 19 C9 +R 00 00 01 00 +T 36 11 00 00 +R 00 00 01 00 +T 36 11 00 00 C5 DD E5 F5 F5 D5 DD E1 21 02 00 +R 00 00 01 00 +T 41 11 00 00 39 AF 77 23 77 2B 2B 2B 77 23 77 +R 00 00 01 00 +T 4C 11 00 00 21 0A 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T 55 11 00 00 23 66 6F 46 23 66 68 E5 21 0E 00 +R 00 00 01 00 +T 60 11 00 00 19 4E 23 46 E1 A7 ED 42 28 03 +R 00 00 01 00 +T 6A 11 00 00 +R 00 00 01 00 +T 6A 11 00 00 CD 1E 0F 00 00 +R 00 00 01 00 00 05 01 00 +T 6D 11 00 00 +R 00 00 01 00 +T 6D 11 00 00 DD CB 0A 46 CA 06 12 00 00 +R 00 00 01 00 00 09 01 00 +T 74 11 00 00 +R 00 00 01 00 +T 74 11 00 00 21 00 00 39 E5 CD 85 0D 00 00 E1 +R 00 00 01 00 00 0A 01 00 +T 7D 11 00 00 21 00 00 39 CD 0E 12 00 00 CD +R 00 00 01 00 00 09 01 00 +T 85 11 00 00 00 00 00 00 DD 6E 08 DD 66 09 E5 +R 00 00 01 00 02 04 0B 00 +T 8E 11 00 00 DD 6E 06 DD 66 07 E5 21 04 00 39 +R 00 00 01 00 +T 99 11 00 00 4E 23 46 C5 23 4E 23 46 DD CB 0A +R 00 00 01 00 +T A4 11 00 00 4E 28 07 DD 5E 10 16 00 18 03 +R 00 00 01 00 +T AE 11 00 00 +R 00 00 01 00 +T AE 11 00 00 11 00 00 +R 00 00 01 00 +T B1 11 00 00 +R 00 00 01 00 +T B1 11 00 00 CD F2 02 00 00 E1 E1 E1 DD 7E 0A +R 00 00 01 00 00 05 01 00 +T BA 11 00 00 E6 82 28 1C DD 7E 0A E6 82 EE 82 +R 00 00 01 00 +T C5 11 00 00 28 13 +R 00 00 01 00 +T C7 11 00 00 +R 00 00 01 00 +T C7 11 00 00 +R 00 00 01 00 +T C7 11 00 00 +R 00 00 01 00 +T C7 11 00 00 DD 4E 08 DD 46 09 DD 5E 06 DD 56 +R 00 00 01 00 +T D2 11 00 00 07 3E AF 01 00 00 21 AF 01 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T D8 11 00 00 18 11 +R 00 00 01 00 +T DA 11 00 00 +R 00 00 01 00 +T DA 11 00 00 DD 4E 08 DD 46 09 DD 5E 06 DD 56 +R 00 00 01 00 +T E5 11 00 00 07 3E 25 01 00 00 21 25 01 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T EB 11 00 00 +R 00 00 01 00 +T EB 11 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T EE 11 00 00 +R 00 00 01 00 +T EE 11 00 00 21 00 00 39 4E 23 46 C5 23 4E 23 +R 00 00 01 00 +T F9 11 00 00 46 DD E5 D1 3E 7A 10 00 00 21 +R 00 00 01 00 29 09 01 00 +T 00 12 00 00 7A 10 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 06 12 00 00 +R 00 00 01 00 +T 06 12 00 00 E1 E1 DD E1 C1 C3 00 00 00 00 +R 00 00 01 00 02 0A 00 00 +T 0E 12 00 00 +R 00 00 01 00 +T 0E 12 00 00 4E 23 46 23 +R 00 00 01 00 +T 12 12 00 00 +R 00 00 01 00 +T 12 12 00 00 5E 23 56 3E A3 00 00 00 21 +R 00 00 01 00 29 08 01 00 +T 18 12 00 00 A3 00 00 00 CD 00 00 00 00 DD 4E +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 1F 12 00 00 08 DD 46 09 DD 5E 06 DD 56 07 3E +R 00 00 01 00 +T 2A 12 00 00 E2 00 00 00 21 E2 00 00 00 C9 +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 2F 12 00 00 +R 00 00 01 00 +T 2F 12 00 00 CD 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 0A 00 02 0A 04 00 +T 35 12 00 00 +R 00 00 01 00 +T 35 12 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 3E 12 00 00 0C DD 66 0D E5 DD 6E 0A DD 66 0B +R 00 00 01 00 +T 49 12 00 00 E5 CD B5 0F 00 00 F1 F1 E5 FD E1 +R 00 00 01 00 00 06 01 00 +T 52 12 00 00 01 0A 00 09 7E F6 03 77 DD 46 0E +R 00 00 01 00 +T 5D 12 00 00 FD 70 10 FD 36 17 C3 0F 00 00 FD +R 00 00 01 00 09 0A 01 00 +T 65 12 00 00 36 18 C3 0F 00 00 FD 36 19 +R 00 00 01 00 89 06 01 00 +T 6B 12 00 00 C3 0F 00 00 FD 36 1A 36 11 00 00 +R 00 00 01 00 29 04 01 00 09 0B 01 00 +T 70 12 00 00 FD 36 1B 36 11 00 00 FD 36 1C +R 00 00 01 00 89 07 01 00 +T 77 12 00 00 36 11 00 00 FD 36 1D 2F 12 00 00 +R 00 00 01 00 29 04 01 00 09 0B 01 00 +T 7C 12 00 00 FD 36 1E 2F 12 00 00 FD 36 1F +R 00 00 01 00 89 07 01 00 +T 83 12 00 00 2F 12 00 00 C3 51 06 00 00 +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 87 12 00 00 +R 00 00 01 00 +T 87 12 00 00 CD 00 00 00 00 FD E5 D5 FD E1 DD +R 00 00 01 00 02 05 0A 00 +T 90 12 00 00 6E 0A DD 66 0B E5 3E D2 0A 00 00 +R 00 00 01 00 29 0B 01 00 +T 98 12 00 00 21 D2 0A 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T 9F 12 00 00 3E 03 DD AE 04 DD B6 05 20 5C FD +R 00 00 01 00 +T AA 12 00 00 4E 10 47 DD 6E 0A DD 66 0B ED 42 +R 00 00 01 00 +T B5 12 00 00 20 4E FD 7E 0A E6 03 28 47 +R 00 00 01 00 +T BE 12 00 00 +R 00 00 01 00 +T BE 12 00 00 +R 00 00 01 00 +T BE 12 00 00 +R 00 00 01 00 +T BE 12 00 00 FD 7E 0A EE 04 FD 77 0A DD 6E 0A +R 00 00 01 00 +T C9 12 00 00 DD 66 0B E5 FD 5E 11 FD 56 12 FD +R 00 00 01 00 +T D4 12 00 00 6E 11 FD 66 12 0E 17 09 4E 23 46 +R 00 00 01 00 +T DF 12 00 00 23 7E 69 60 01 02 02 CD +R 00 00 01 00 +T E7 12 00 00 00 00 00 00 E1 21 00 00 E5 01 +R 00 00 01 00 02 04 0B 00 +T EF 12 00 00 03 01 CD 76 0D 00 00 E1 FD CB 0A +R 00 00 01 00 00 07 01 00 +T F8 12 00 00 66 28 0A +R 00 00 01 00 +T FB 12 00 00 +R 00 00 01 00 +T FB 12 00 00 FD 4E 10 06 00 C5 CD 5E 10 00 00 +R 00 00 01 00 00 0B 01 00 +T 04 13 00 00 E1 +R 00 00 01 00 +T 05 13 00 00 +R 00 00 01 00 +T 05 13 00 00 +R 00 00 01 00 +T 05 13 00 00 21 01 02 DD 4E 04 DD 46 05 A7 ED +R 00 00 01 00 +T 10 13 00 00 42 20 0B +R 00 00 01 00 +T 13 13 00 00 +R 00 00 01 00 +T 13 13 00 00 DD 6E 0A DD 66 0B E5 CD +R 00 00 01 00 +T 1B 13 00 00 41 10 00 00 E1 +R 00 00 01 00 00 04 01 00 +T 1E 13 00 00 +R 00 00 01 00 +T 1E 13 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 23 13 00 00 +R 00 00 01 00 +T 23 13 00 00 C5 DD E5 F5 F5 D5 DD E1 21 02 00 +R 00 00 01 00 +T 2E 13 00 00 39 AF 77 23 77 2B 2B 2B 77 23 77 +R 00 00 01 00 +T 39 13 00 00 21 0A 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T 42 13 00 00 23 66 6F 46 23 66 68 E5 21 0E 00 +R 00 00 01 00 +T 4D 13 00 00 19 4E 23 46 E1 A7 ED 42 28 03 +R 00 00 01 00 +T 57 13 00 00 +R 00 00 01 00 +T 57 13 00 00 CD 1E 0F 00 00 +R 00 00 01 00 00 05 01 00 +T 5A 13 00 00 +R 00 00 01 00 +T 5A 13 00 00 DD CB 0A 46 CA 0C 14 00 00 +R 00 00 01 00 00 09 01 00 +T 61 13 00 00 +R 00 00 01 00 +T 61 13 00 00 21 00 00 39 E5 CD 85 0D 00 00 E1 +R 00 00 01 00 00 0A 01 00 +T 6A 13 00 00 21 00 00 39 CD 0E 12 00 00 CD +R 00 00 01 00 00 09 01 00 +T 72 13 00 00 00 00 00 00 DD CB 0A 4E 28 36 DD +R 00 00 01 00 02 04 0B 00 +T 7B 13 00 00 CB 0A 56 28 30 +R 00 00 01 00 +T 80 13 00 00 +R 00 00 01 00 +T 80 13 00 00 +R 00 00 01 00 +T 80 13 00 00 +R 00 00 01 00 +T 80 13 00 00 DD 4E 08 DD 46 09 DD 5E 06 DD 56 +R 00 00 01 00 +T 8B 13 00 00 07 3E AF 01 00 00 21 AF 01 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 91 13 00 00 CD 00 00 00 00 DD 6E 08 DD 66 09 +R 00 00 01 00 02 05 0B 00 +T 9A 13 00 00 E5 DD 6E 06 DD 66 07 E5 21 04 00 +R 00 00 01 00 +T A5 13 00 00 39 4E 23 46 C5 23 4E 23 46 18 34 +R 00 00 01 00 +T B0 13 00 00 +R 00 00 01 00 +T B0 13 00 00 DD 4E 08 DD 46 09 DD 5E 06 DD 56 +R 00 00 01 00 +T BB 13 00 00 07 3E 25 01 00 00 21 25 01 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T C1 13 00 00 CD 00 00 00 00 DD 6E 08 DD 66 09 +R 00 00 01 00 02 05 0B 00 +T CA 13 00 00 E5 DD 6E 06 DD 66 07 E5 21 04 00 +R 00 00 01 00 +T D5 13 00 00 39 4E 23 46 C5 23 4E 23 46 DD CB +R 00 00 01 00 +T E0 13 00 00 0A 4E 28 07 +R 00 00 01 00 +T E4 13 00 00 +R 00 00 01 00 +T E4 13 00 00 DD 5E 10 16 00 18 03 +R 00 00 01 00 +T EB 13 00 00 +R 00 00 01 00 +T EB 13 00 00 11 00 00 +R 00 00 01 00 +T EE 13 00 00 +R 00 00 01 00 +T EE 13 00 00 CD F2 02 00 00 E1 E1 E1 +R 00 00 01 00 00 05 01 00 +T F4 13 00 00 +R 00 00 01 00 +T F4 13 00 00 21 00 00 39 4E 23 46 C5 23 4E 23 +R 00 00 01 00 +T FF 13 00 00 46 DD E5 D1 3E 7A 10 00 00 21 +R 00 00 01 00 29 09 01 00 +T 06 14 00 00 7A 10 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 0C 14 00 00 +R 00 00 01 00 +T 0C 14 00 00 C3 06 12 00 00 +R 00 00 01 00 00 05 01 00 +T 0F 14 00 00 +R 00 00 01 00 +T 0F 14 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 18 14 00 00 0C DD 66 0D E5 DD 6E 0A DD 66 0B +R 00 00 01 00 +T 23 14 00 00 E5 CD B5 0F 00 00 F1 F1 E5 FD E1 +R 00 00 01 00 00 06 01 00 +T 2C 14 00 00 01 0A 00 09 7E F6 07 77 DD 46 0E +R 00 00 01 00 +T 37 14 00 00 FD 70 10 FD 36 17 87 12 00 00 FD +R 00 00 01 00 09 0A 01 00 +T 3F 14 00 00 36 18 87 12 00 00 FD 36 19 +R 00 00 01 00 89 06 01 00 +T 45 14 00 00 87 12 00 00 FD 36 1A 23 13 00 00 +R 00 00 01 00 29 04 01 00 09 0B 01 00 +T 4A 14 00 00 FD 36 1B 23 13 00 00 FD 36 1C +R 00 00 01 00 89 07 01 00 +T 51 14 00 00 23 13 00 00 FD 36 1D 2F 12 00 00 +R 00 00 01 00 29 04 01 00 09 0B 01 00 +T 56 14 00 00 FD 36 1E 2F 12 00 00 FD 36 1F +R 00 00 01 00 89 07 01 00 +T 5D 14 00 00 2F 12 00 00 C3 51 06 00 00 +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 61 14 00 00 +R 00 00 01 00 +T 61 14 00 00 CD 00 00 00 00 FD E5 D5 FD E1 DD +R 00 00 01 00 02 05 0A 00 +T 6A 14 00 00 6E 0A DD 66 0B E5 3E D2 0A 00 00 +R 00 00 01 00 29 0B 01 00 +T 72 14 00 00 21 D2 0A 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T 79 14 00 00 21 01 02 DD 4E 04 DD 46 05 A7 ED +R 00 00 01 00 +T 84 14 00 00 42 20 40 3E FF DD AE 0A DD B6 0B +R 00 00 01 00 +T 8F 14 00 00 20 36 +R 00 00 01 00 +T 91 14 00 00 +R 00 00 01 00 +T 91 14 00 00 +R 00 00 01 00 +T 91 14 00 00 +R 00 00 01 00 +T 91 14 00 00 FD CB 0B 66 E5 28 05 +R 00 00 01 00 +T 98 14 00 00 +R 00 00 01 00 +T 98 14 00 00 01 05 01 18 03 +R 00 00 01 00 +T 9D 14 00 00 +R 00 00 01 00 +T 9D 14 00 00 01 02 01 +R 00 00 01 00 +T A0 14 00 00 +R 00 00 01 00 +T A0 14 00 00 CD 76 0D 00 00 E1 +R 00 00 01 00 00 05 01 00 +T A4 14 00 00 +R 00 00 01 00 +T A4 14 00 00 FD 4E 10 06 00 C5 FD 5E 11 FD 56 +R 00 00 01 00 +T AF 14 00 00 12 FD 6E 11 FD 66 12 0E 17 09 4E +R 00 00 01 00 +T BA 14 00 00 23 46 23 7E 69 60 01 01 03 CD +R 00 00 01 00 +T C4 14 00 00 00 00 00 00 E1 +R 00 00 01 00 02 04 0B 00 +T C7 14 00 00 +R 00 00 01 00 +T C7 14 00 00 21 01 02 DD 4E 04 DD 46 05 A7 ED +R 00 00 01 00 +T D2 14 00 00 42 20 40 3E FE DD AE 0A DD B6 0B +R 00 00 01 00 +T DD 14 00 00 20 36 +R 00 00 01 00 +T DF 14 00 00 +R 00 00 01 00 +T DF 14 00 00 +R 00 00 01 00 +T DF 14 00 00 +R 00 00 01 00 +T DF 14 00 00 FD CB 0B 66 E5 28 05 +R 00 00 01 00 +T E6 14 00 00 +R 00 00 01 00 +T E6 14 00 00 01 05 01 18 03 +R 00 00 01 00 +T EB 14 00 00 +R 00 00 01 00 +T EB 14 00 00 01 02 01 +R 00 00 01 00 +T EE 14 00 00 +R 00 00 01 00 +T EE 14 00 00 CD 76 0D 00 00 E1 +R 00 00 01 00 00 05 01 00 +T F2 14 00 00 +R 00 00 01 00 +T F2 14 00 00 FD 4E 10 06 00 C5 FD 5E 11 FD 56 +R 00 00 01 00 +T FD 14 00 00 12 FD 6E 11 FD 66 12 0E 17 09 4E +R 00 00 01 00 +T 08 15 00 00 23 46 23 7E 69 60 01 02 03 CD +R 00 00 01 00 +T 12 15 00 00 00 00 00 00 E1 +R 00 00 01 00 02 04 0B 00 +T 15 15 00 00 +R 00 00 01 00 +T 15 15 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 1A 15 00 00 +R 00 00 01 00 +T 1A 15 00 00 CD 00 00 00 00 FE FF FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T 23 15 00 00 0C DD 66 0D E5 DD 6E 0A DD 66 0B +R 00 00 01 00 +T 2E 15 00 00 E5 CD B5 0F 00 00 F1 F1 E5 FD E1 +R 00 00 01 00 00 06 01 00 +T 37 15 00 00 01 0A 00 09 CB C6 DD 46 0E FD 70 +R 00 00 01 00 +T 42 15 00 00 10 FD 36 17 61 14 00 00 FD 36 18 +R 00 00 01 00 09 08 01 00 +T 4A 15 00 00 61 14 00 00 FD 36 19 61 14 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T 4F 15 00 00 FD 36 1A 9F 0D 00 00 FD 36 1B +R 00 00 01 00 09 07 01 00 +T 56 15 00 00 9F 0D 00 00 FD 36 1C 9F 0D 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T 5B 15 00 00 FD 36 1D 63 0F 00 00 FD 36 1E +R 00 00 01 00 09 07 01 00 +T 62 15 00 00 63 0F 00 00 FD 36 1F 63 0F 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T 67 15 00 00 21 FF 00 E5 2E 14 E5 2E 28 E5 21 +R 00 00 01 00 +T 72 15 00 00 E4 FF CD CC 15 00 00 F1 F1 F1 DD +R 00 00 01 00 00 07 01 00 +T 7B 15 00 00 75 FE DD 74 FF 01 20 00 09 E5 11 +R 00 00 01 00 +T 86 15 00 00 03 00 CD 28 04 00 00 E1 71 23 70 +R 00 00 01 00 00 07 01 00 +T 8F 15 00 00 01 0A 00 00 00 CD E8 15 00 00 CD +R 00 00 01 00 00 05 02 00 00 0A 01 00 +T 96 15 00 00 00 00 00 00 21 FE 00 E5 2E 14 E5 +R 00 00 01 00 02 04 0B 00 +T 9F 15 00 00 2E 28 E5 21 C8 FF CD CC 15 00 00 +R 00 00 01 00 00 0B 01 00 +T A8 15 00 00 F1 F1 F1 DD 75 FE DD 74 FF 01 +R 00 00 01 00 +T B2 15 00 00 20 00 09 E5 11 07 00 CD +R 00 00 01 00 +T BA 15 00 00 28 04 00 00 E1 71 23 70 01 +R 00 00 01 00 00 04 01 00 +T C1 15 00 00 0D 00 00 00 CD E8 15 00 00 CD +R 00 00 01 00 00 04 02 00 00 09 01 00 +T C7 15 00 00 00 00 00 00 C3 51 06 00 00 +R 00 00 01 00 02 04 0B 00 00 09 01 00 +T CC 15 00 00 +R 00 00 01 00 +T CC 15 00 00 DD 4E 0C DD 46 0D 09 4D 44 21 +R 00 00 01 00 +T D6 15 00 00 D0 FF DD 5E 0A DD 56 0B 19 EB +R 00 00 01 00 +T E0 15 00 00 +R 00 00 01 00 +T E0 15 00 00 3E 35 12 00 00 21 35 12 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T E6 15 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T E8 15 00 00 +R 00 00 01 00 +T E8 15 00 00 DD 5E FE DD 56 FF 3E 59 06 00 00 +R 00 00 01 00 29 0B 01 00 +T F0 15 00 00 21 59 06 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T F7 15 00 00 4E FE DD 46 FF FD E5 D1 FD 7E 1F +R 00 00 01 00 +T 02 16 00 00 FD 6E 1D FD 66 1E C9 +R 00 00 01 00 +T 09 16 00 00 +R 00 00 01 00 +T 09 16 00 00 CD 00 00 00 00 FD E5 D5 FD E1 DD +R 00 00 01 00 02 05 0A 00 +T 12 16 00 00 6E 0A DD 66 0B E5 3E C3 0F 00 00 +R 00 00 01 00 29 0B 01 00 +T 1A 16 00 00 21 C3 0F 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T 21 16 00 00 21 03 02 DD 4E 04 DD 46 05 A7 ED +R 00 00 01 00 +T 2C 16 00 00 42 20 40 FD CB 0A 5E 28 3A +R 00 00 01 00 +T 35 16 00 00 +R 00 00 01 00 +T 35 16 00 00 +R 00 00 01 00 +T 35 16 00 00 +R 00 00 01 00 +T 35 16 00 00 3E 08 DD AE 0A DD B6 0B FD 5E 20 +R 00 00 01 00 +T 40 16 00 00 FD 56 21 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 06 00 +T 46 16 00 00 00 00 00 00 20 0D +R 00 00 01 00 02 04 06 00 +T 4A 16 00 00 +R 00 00 01 00 +T 4A 16 00 00 CD 22 04 00 00 28 15 +R 00 00 01 00 00 05 01 00 +T 4F 16 00 00 +R 00 00 01 00 +T 4F 16 00 00 CD 74 16 00 00 2B 36 00 +R 00 00 01 00 00 05 01 00 +T 55 16 00 00 +R 00 00 01 00 +T 55 16 00 00 18 0D +R 00 00 01 00 +T 57 16 00 00 +R 00 00 01 00 +T 57 16 00 00 CD 7F 16 00 00 23 36 00 CD +R 00 00 01 00 00 05 01 00 +T 5E 16 00 00 74 16 00 00 DD 46 0A 70 +R 00 00 01 00 00 04 01 00 +T 64 16 00 00 +R 00 00 01 00 +T 64 16 00 00 21 00 00 E5 01 03 01 CD +R 00 00 01 00 +T 6C 16 00 00 76 0D 00 00 E1 +R 00 00 01 00 00 04 01 00 +T 6F 16 00 00 +R 00 00 01 00 +T 6F 16 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 74 16 00 00 +R 00 00 01 00 +T 74 16 00 00 FD 5E 20 FD 56 21 3E 00 00 00 00 +R 00 00 01 00 2B 0B 06 00 +T 7C 16 00 00 21 00 00 00 00 +R 00 00 01 00 02 05 06 00 +T 7F 16 00 00 +R 00 00 01 00 +T 7F 16 00 00 CD 00 00 00 00 FD 4E 20 FD 46 21 +R 00 00 01 00 02 05 0B 00 +T 88 16 00 00 09 C9 +R 00 00 01 00 +T 8A 16 00 00 +R 00 00 01 00 +T 8A 16 00 00 C5 FD E5 DD E5 21 B8 FF 39 F9 D5 +R 00 00 01 00 +T 95 16 00 00 DD E1 AF 77 23 77 23 77 23 77 21 +R 00 00 01 00 +T A0 16 00 00 0A 00 ED 4B 00 00 00 00 09 7E 23 +R 00 00 01 00 00 08 04 00 +T A9 16 00 00 66 6F 46 23 66 68 E5 21 0E 00 19 +R 00 00 01 00 +T B4 16 00 00 4E 23 46 E1 A7 ED 42 28 03 +R 00 00 01 00 +T BD 16 00 00 +R 00 00 01 00 +T BD 16 00 00 CD 1E 0F 00 00 +R 00 00 01 00 00 05 01 00 +T C0 16 00 00 +R 00 00 01 00 +T C0 16 00 00 DD CB 0A 46 CA CE 17 00 00 +R 00 00 01 00 00 09 01 00 +T C7 16 00 00 +R 00 00 01 00 +T C7 16 00 00 21 02 00 39 E5 2B 2B CD +R 00 00 01 00 +T CF 16 00 00 87 0D 00 00 E1 21 02 00 39 4E 23 +R 00 00 01 00 00 04 01 00 +T D8 16 00 00 46 2B 2B 2B CD 12 12 00 00 CD +R 00 00 01 00 00 09 01 00 +T E0 16 00 00 00 00 00 00 DD 6E 08 DD 66 09 E5 +R 00 00 01 00 02 04 0B 00 +T E9 16 00 00 DD 6E 06 DD 66 07 E5 21 06 00 39 +R 00 00 01 00 +T F4 16 00 00 4E 23 46 C5 2B 2B 2B 4E 23 46 DD +R 00 00 01 00 +T FF 16 00 00 CB 0A 4E 28 07 DD 5E 10 16 00 18 +R 00 00 01 00 +T 0A 17 00 00 03 +R 00 00 01 00 +T 0B 17 00 00 +R 00 00 01 00 +T 0B 17 00 00 11 00 00 +R 00 00 01 00 +T 0E 17 00 00 +R 00 00 01 00 +T 0E 17 00 00 CD F2 02 00 00 E1 E1 E1 DD CB 0A +R 00 00 01 00 00 05 01 00 +T 17 17 00 00 7E DD 4E 08 DD 46 09 DD 5E 06 DD +R 00 00 01 00 +T 22 17 00 00 56 07 20 07 +R 00 00 01 00 +T 26 17 00 00 +R 00 00 01 00 +T 26 17 00 00 3E AF 01 00 00 21 AF 01 00 00 18 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 2C 17 00 00 05 +R 00 00 01 00 +T 2D 17 00 00 +R 00 00 01 00 +T 2D 17 00 00 3E 25 01 00 00 21 25 01 00 00 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 32 17 00 00 +R 00 00 01 00 +T 32 17 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T 35 17 00 00 +R 00 00 01 00 +T 35 17 00 00 DD 5E 20 DD 56 21 21 0A 00 ED 4B +R 00 00 01 00 +T 40 17 00 00 00 00 00 00 09 46 23 66 68 01 +R 00 00 01 00 00 04 04 00 +T 48 17 00 00 05 00 09 4E 23 46 23 7E 69 60 CD +R 00 00 01 00 +T 53 17 00 00 2D 04 00 00 DD 6E 08 DD 66 09 A7 +R 00 00 01 00 00 04 01 00 +T 5C 17 00 00 ED 42 EB 01 02 00 CD 00 00 00 00 +R 00 00 01 00 02 0B 11 00 +T 65 17 00 00 69 60 39 46 23 66 68 19 01 07 00 +R 00 00 01 00 +T 70 17 00 00 09 4D 44 21 00 00 39 5E 23 56 13 +R 00 00 01 00 +T 7B 17 00 00 13 3E A3 00 00 00 21 A3 00 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 81 17 00 00 CD 00 00 00 00 DD CB 0B 46 28 36 +R 00 00 01 00 02 05 0B 00 +T 8A 17 00 00 +R 00 00 01 00 +T 8A 17 00 00 FD 21 00 00 +R 00 00 01 00 +T 8E 17 00 00 +R 00 00 01 00 +T 8E 17 00 00 DD 5E 20 DD 56 21 3E 00 00 00 00 +R 00 00 01 00 2B 0B 06 00 +T 96 17 00 00 21 00 00 00 00 CD 2D 04 00 00 FD +R 00 00 01 00 02 05 06 00 00 0A 01 00 +T 9D 17 00 00 E5 E1 A7 ED 42 21 06 00 30 0B +R 00 00 01 00 +T A7 17 00 00 +R 00 00 01 00 +T A7 17 00 00 39 FD E5 C1 09 36 2A FD 23 18 DC +R 00 00 01 00 +T B2 17 00 00 +R 00 00 01 00 +T B2 17 00 00 39 FD E5 C1 09 36 00 21 06 00 39 +R 00 00 01 00 +T BD 17 00 00 EB 18 06 +R 00 00 01 00 +T C0 17 00 00 +R 00 00 01 00 +T C0 17 00 00 DD 5E 20 DD 56 21 +R 00 00 01 00 +T C6 17 00 00 +R 00 00 01 00 +T C6 17 00 00 3E 39 02 00 00 21 39 02 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T CC 17 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T CE 17 00 00 +R 00 00 01 00 +T CE 17 00 00 +R 00 00 01 00 +T CE 17 00 00 21 48 00 39 F9 C3 5E 02 00 00 +R 00 00 01 00 00 0A 01 00 +T D6 17 00 00 +R 00 00 01 00 +T D6 17 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T DF 17 00 00 0E DD 66 0F E5 DD 6E 0C DD 66 0D +R 00 00 01 00 +T EA 17 00 00 E5 DD 6E 0A DD 66 0B E5 DD 5E 02 +R 00 00 01 00 +T F5 17 00 00 DD 56 03 CD E0 15 00 00 F1 F1 F1 +R 00 00 01 00 00 08 01 00 +T FE 17 00 00 E5 FD E1 01 0A 00 09 CB DE 01 +R 00 00 01 00 +T 08 18 00 00 14 00 00 00 FD E5 D1 3E +R 00 00 01 00 00 04 02 00 +T 0E 18 00 00 59 06 00 00 21 59 06 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 13 18 00 00 00 00 00 00 FD 36 1A 8A 16 00 00 +R 00 00 01 00 02 04 0B 00 09 0B 01 00 +T 19 18 00 00 FD 36 1B 8A 16 00 00 FD 36 1C +R 00 00 01 00 89 07 01 00 +T 20 18 00 00 8A 16 00 00 FD 36 17 09 16 00 00 +R 00 00 01 00 29 04 01 00 09 0B 01 00 +T 25 18 00 00 FD 36 18 09 16 00 00 FD 36 19 +R 00 00 01 00 89 07 01 00 +T 2C 18 00 00 09 16 00 00 C3 51 06 00 00 +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 30 18 00 00 +R 00 00 01 00 +T 30 18 00 00 CD 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 0A 00 02 0A 04 00 +T 36 18 00 00 +R 00 00 01 00 +T 36 18 00 00 C5 DD E5 F5 F5 D5 DD E1 21 02 00 +R 00 00 01 00 +T 41 18 00 00 39 AF 77 23 77 2B 2B 2B 77 23 77 +R 00 00 01 00 +T 4C 18 00 00 21 0A 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T 55 18 00 00 23 66 6F 46 23 66 68 E5 21 0E 00 +R 00 00 01 00 +T 60 18 00 00 19 4E 23 46 E1 A7 ED 42 28 03 +R 00 00 01 00 +T 6A 18 00 00 +R 00 00 01 00 +T 6A 18 00 00 CD 1E 0F 00 00 +R 00 00 01 00 00 05 01 00 +T 6D 18 00 00 +R 00 00 01 00 +T 6D 18 00 00 DD CB 0A 46 28 21 +R 00 00 01 00 +T 73 18 00 00 +R 00 00 01 00 +T 73 18 00 00 21 00 00 39 E5 CD 85 0D 00 00 E1 +R 00 00 01 00 00 0A 01 00 +T 7C 18 00 00 21 00 00 39 4E 23 46 C5 23 4E 23 +R 00 00 01 00 +T 87 18 00 00 46 DD E5 D1 3E 7A 10 00 00 21 +R 00 00 01 00 29 09 01 00 +T 8E 18 00 00 7A 10 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 94 18 00 00 +R 00 00 01 00 +T 94 18 00 00 C3 06 12 00 00 +R 00 00 01 00 00 05 01 00 +T 97 18 00 00 +R 00 00 01 00 +T 97 18 00 00 CD 00 00 00 00 00 00 FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T A0 18 00 00 0C DD 66 0D E5 DD 6E 0A DD 66 0B +R 00 00 01 00 +T AB 18 00 00 E5 CD B5 0F 00 00 F1 F1 E5 FD E1 +R 00 00 01 00 00 06 01 00 +T B4 18 00 00 01 20 00 09 DD 4E 0E 71 DD 46 0F +R 00 00 01 00 +T BF 18 00 00 23 70 FD 36 0A 01 FD 36 0B 00 FD +R 00 00 01 00 +T CA 18 00 00 36 17 30 18 00 00 FD 36 18 +R 00 00 01 00 09 06 01 00 +T D0 18 00 00 30 18 00 00 FD 36 19 30 18 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T D5 18 00 00 FD 36 1A 36 18 00 00 FD 36 1B +R 00 00 01 00 09 07 01 00 +T DC 18 00 00 36 18 00 00 FD 36 1C 36 18 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T E1 18 00 00 FD 36 1D 2F 12 00 00 FD 36 1E +R 00 00 01 00 09 07 01 00 +T E8 18 00 00 2F 12 00 00 FD 36 1F 2F 12 00 00 +R 00 00 01 00 89 04 01 00 29 0B 01 00 +T ED 18 00 00 C3 51 06 00 00 +R 00 00 01 00 00 05 01 00 +T F0 18 00 00 +R 00 00 01 00 +T F0 18 00 00 CD 00 00 00 00 00 00 DD 6E 0A DD +R 00 00 01 00 02 05 0E 00 +T F9 18 00 00 66 0B E5 DD 5E 02 DD 56 03 3E +R 00 00 01 00 +T 03 19 00 00 D2 0A 00 00 21 D2 0A 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 08 19 00 00 00 00 00 00 E1 C3 00 00 00 00 +R 00 00 01 00 02 04 0B 00 02 0A 04 00 +T 0E 19 00 00 +R 00 00 01 00 +T 0E 19 00 00 CD 00 00 00 00 CE FF FD E5 DD 36 +R 00 00 01 00 02 05 0E 00 +T 17 19 00 00 D8 00 21 00 00 E5 C5 3E +R 00 00 01 00 +T 1F 19 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 10 00 02 09 10 00 +T 24 19 00 00 00 00 00 00 F1 F1 DD 75 D4 DD 74 +R 00 00 01 00 02 04 0B 00 +T 2D 19 00 00 D5 DD 36 F0 2B DD 36 F1 00 DD 36 +R 00 00 01 00 +T 38 19 00 00 F2 1A DD 36 F3 00 +R 00 00 01 00 +T 3E 19 00 00 +R 00 00 01 00 +T 3E 19 00 00 DD 36 F4 00 DD 7E D8 FE 73 20 18 +R 00 00 01 00 +T 49 19 00 00 +R 00 00 01 00 +T 49 19 00 00 DD 6E D9 DD 66 DA DD 75 F0 DD 74 +R 00 00 01 00 +T 54 19 00 00 F1 DD 6E DB DD 66 DC DD 75 F2 DD +R 00 00 01 00 +T 5F 19 00 00 74 F3 +R 00 00 01 00 +T 61 19 00 00 +R 00 00 01 00 +T 61 19 00 00 DD 7E D8 FE 42 28 07 DD 7E D8 FE +R 00 00 01 00 +T 6C 19 00 00 4D 20 4F +R 00 00 01 00 +T 6F 19 00 00 +R 00 00 01 00 +T 6F 19 00 00 +R 00 00 01 00 +T 6F 19 00 00 +R 00 00 01 00 +T 6F 19 00 00 DD 4E DD 06 00 C5 CD D8 1C 00 00 +R 00 00 01 00 00 0B 01 00 +T 78 19 00 00 D5 DD 4E DB DD 5E F0 DD 56 F1 CD +R 00 00 01 00 +T 83 19 00 00 E1 1C 00 00 D5 DD 4E DA DD 5E F2 +R 00 00 01 00 00 04 01 00 +T 8C 19 00 00 DD 56 F3 CD 00 00 00 00 D5 DD 5E +R 00 00 01 00 02 08 03 00 +T 95 19 00 00 D9 50 DD 4E F0 DD 46 F1 CD +R 00 00 01 00 +T 9E 19 00 00 00 00 00 00 3E 35 12 00 00 21 +R 00 00 01 00 02 04 03 00 29 09 01 00 +T A3 19 00 00 35 12 00 00 C1 CD 00 00 00 00 F1 +R 00 00 01 00 00 04 01 00 02 0A 0B 00 +T AA 19 00 00 F1 F1 E5 FD E1 DD 7E D8 FE 4D 20 +R 00 00 01 00 +T B5 19 00 00 04 +R 00 00 01 00 +T B6 19 00 00 +R 00 00 01 00 +T B6 19 00 00 FD CB 0A F6 +R 00 00 01 00 +T BA 19 00 00 +R 00 00 01 00 +T BA 19 00 00 DD 36 F4 01 +R 00 00 01 00 +T BE 19 00 00 +R 00 00 01 00 +T BE 19 00 00 DD 7E D8 FE 54 20 44 +R 00 00 01 00 +T C5 19 00 00 +R 00 00 01 00 +T C5 19 00 00 DD 4E DD 06 00 C5 CD D8 1C 00 00 +R 00 00 01 00 00 0B 01 00 +T CE 19 00 00 D5 DD 4E DB DD 5E F0 DD 56 F1 CD +R 00 00 01 00 +T D9 19 00 00 E1 1C 00 00 D5 DD 4E DA DD 5E F2 +R 00 00 01 00 00 04 01 00 +T E2 19 00 00 DD 56 F3 CD 00 00 00 00 D5 DD 5E +R 00 00 01 00 02 08 03 00 +T EB 19 00 00 D9 50 DD 4E F0 DD 46 F1 CD +R 00 00 01 00 +T F4 19 00 00 00 00 00 00 3E 0F 14 00 00 21 +R 00 00 01 00 02 04 03 00 29 09 01 00 +T F9 19 00 00 0F 14 00 00 C1 CD 00 00 00 00 F1 +R 00 00 01 00 00 04 01 00 02 0A 0B 00 +T 00 1A 00 00 F1 F1 E5 FD E1 DD 36 F4 01 +R 00 00 01 00 +T 09 1A 00 00 +R 00 00 01 00 +T 09 1A 00 00 DD 7E D8 FE 44 20 44 +R 00 00 01 00 +T 10 1A 00 00 +R 00 00 01 00 +T 10 1A 00 00 DD 4E DD 06 00 C5 CD D8 1C 00 00 +R 00 00 01 00 00 0B 01 00 +T 19 1A 00 00 D5 DD 4E DB DD 5E F0 DD 56 F1 CD +R 00 00 01 00 +T 24 1A 00 00 E1 1C 00 00 D5 DD 4E DA DD 5E F2 +R 00 00 01 00 00 04 01 00 +T 2D 1A 00 00 DD 56 F3 CD 00 00 00 00 D5 DD 5E +R 00 00 01 00 02 08 03 00 +T 36 1A 00 00 D9 50 DD 4E F0 DD 46 F1 CD +R 00 00 01 00 +T 3F 1A 00 00 00 00 00 00 3E D6 17 00 00 21 +R 00 00 01 00 02 04 03 00 29 09 01 00 +T 44 1A 00 00 D6 17 00 00 C1 CD 00 00 00 00 F1 +R 00 00 01 00 00 04 01 00 02 0A 0B 00 +T 4B 1A 00 00 F1 F1 E5 FD E1 DD 36 F4 01 +R 00 00 01 00 +T 54 1A 00 00 +R 00 00 01 00 +T 54 1A 00 00 DD 7E D8 FE 4C 20 47 +R 00 00 01 00 +T 5B 1A 00 00 +R 00 00 01 00 +T 5B 1A 00 00 21 0C 00 39 01 12 00 09 E5 CD +R 00 00 01 00 +T 65 1A 00 00 D8 1C 00 00 D5 DD 4E DB DD 5E F0 +R 00 00 01 00 00 04 01 00 +T 6E 1A 00 00 DD 56 F1 CD E1 1C 00 00 D5 DD 4E +R 00 00 01 00 00 08 01 00 +T 77 1A 00 00 DA DD 5E F2 DD 56 F3 CD +R 00 00 01 00 +T 7F 1A 00 00 00 00 00 00 D5 DD 5E D9 50 DD 4E +R 00 00 01 00 02 04 03 00 +T 88 1A 00 00 F0 DD 46 F1 CD 00 00 00 00 3E +R 00 00 01 00 02 09 03 00 +T 90 1A 00 00 97 18 00 00 21 97 18 00 00 C1 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 96 1A 00 00 00 00 00 00 F1 F1 F1 E5 FD E1 DD +R 00 00 01 00 02 04 0B 00 +T 9F 1A 00 00 36 F4 01 +R 00 00 01 00 +T A2 1A 00 00 +R 00 00 01 00 +T A2 1A 00 00 DD 7E D8 FE 41 20 51 +R 00 00 01 00 +T A9 1A 00 00 +R 00 00 01 00 +T A9 1A 00 00 21 26 00 DD 4E 02 DD 46 03 09 E5 +R 00 00 01 00 +T B4 1A 00 00 21 2B 00 39 EB E1 73 23 72 DD 6E +R 00 00 01 00 +T BF 1A 00 00 DE DD 66 DF DD 75 F8 DD 74 F9 DD +R 00 00 01 00 +T CA 1A 00 00 6E E0 DD 66 E1 DD 75 FA DD 74 FB +R 00 00 01 00 +T D5 1A 00 00 21 16 00 39 4E 23 46 23 5E 23 56 +R 00 00 01 00 +T E0 1A 00 00 DD 71 FC DD 70 FD DD 73 FE DD 72 +R 00 00 01 00 +T EB 1A 00 00 FF DD 5E 02 DD 56 03 3E +R 00 00 01 00 +T F3 1A 00 00 E8 1C 00 00 21 E8 1C 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T F8 1A 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T FA 1A 00 00 +R 00 00 01 00 +T FA 1A 00 00 DD 7E D8 FE 53 20 71 +R 00 00 01 00 +T 01 1B 00 00 +R 00 00 01 00 +T 01 1B 00 00 21 0C 00 39 4D 44 DD 5E D4 DD 56 +R 00 00 01 00 +T 0C 1B 00 00 D5 3E 20 20 00 00 21 20 20 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 12 1B 00 00 CD 00 00 00 00 21 26 00 DD 4E 02 +R 00 00 01 00 02 05 0B 00 +T 1B 1B 00 00 DD 46 03 09 E5 11 04 00 CD +R 00 00 01 00 +T 24 1B 00 00 D0 1C 00 00 EB E1 73 23 72 21 +R 00 00 01 00 00 04 01 00 +T 2C 1B 00 00 26 00 09 56 DD 72 F5 23 66 DD 74 +R 00 00 01 00 +T 37 1B 00 00 F6 21 24 00 09 36 04 23 36 00 6A +R 00 00 01 00 +T 42 1B 00 00 DD 66 F6 23 23 E5 21 08 00 ED 4B +R 00 00 01 00 +T 4D 1B 00 00 00 00 00 00 09 5E 23 56 E1 73 23 +R 00 00 01 00 00 04 04 00 +T 56 1B 00 00 72 21 06 00 ED 4B 00 00 00 00 09 +R 00 00 01 00 00 0A 04 00 +T 5F 1B 00 00 46 23 66 68 E5 DD 6E F5 DD 66 F6 +R 00 00 01 00 +T 6A 1B 00 00 C1 71 23 70 DD 36 F4 00 +R 00 00 01 00 +T 72 1B 00 00 +R 00 00 01 00 +T 72 1B 00 00 AF DD B6 F4 CA 72 1C 00 00 +R 00 00 01 00 00 09 01 00 +T 79 1B 00 00 +R 00 00 01 00 +T 79 1B 00 00 DD 7E DE DD B6 DF 28 69 +R 00 00 01 00 +T 81 1B 00 00 +R 00 00 01 00 +T 81 1B 00 00 FD CB 0A EE FD 36 24 0B FD 36 25 +R 00 00 01 00 +T 8C 1B 00 00 00 11 0B 00 CD D0 1C 00 00 FD 75 +R 00 00 01 00 00 09 01 00 +T 95 1B 00 00 26 FD 74 27 FD 6E 26 DD 75 D0 FD +R 00 00 01 00 +T A0 1B 00 00 66 27 DD 74 D1 36 E8 1C 00 00 23 +R 00 00 01 00 09 0A 01 00 +T A8 1B 00 00 36 E8 1C 00 00 23 36 E8 1C 00 00 +R 00 00 01 00 89 05 01 00 29 0B 01 00 +T AD 1B 00 00 DD 6E D0 DD 66 D1 23 23 23 DD 4E +R 00 00 01 00 +T B8 1B 00 00 DE 71 DD 46 DF 23 70 21 05 00 DD +R 00 00 01 00 +T C3 1B 00 00 4E D0 DD 46 D1 09 DD 5E E0 73 DD +R 00 00 01 00 +T CE 1B 00 00 56 E1 23 72 21 07 00 09 E5 21 +R 00 00 01 00 +T D8 1B 00 00 18 00 39 5E 23 56 23 4E 23 46 E1 +R 00 00 01 00 +T E3 1B 00 00 73 23 72 23 71 23 70 +R 00 00 01 00 +T EA 1B 00 00 +R 00 00 01 00 +T EA 1B 00 00 DD 7E E6 DD B6 E7 28 0C +R 00 00 01 00 +T F2 1B 00 00 +R 00 00 01 00 +T F2 1B 00 00 DD 6E E6 FD 75 0A DD 66 E7 FD 74 +R 00 00 01 00 +T FD 1B 00 00 0B +R 00 00 01 00 +T FE 1B 00 00 +R 00 00 01 00 +T FE 1B 00 00 DD 6E E8 FD 75 0E DD 66 E9 FD 74 +R 00 00 01 00 +T 09 1C 00 00 0F DD 6E EA FD 75 20 DD 7E EB E6 +R 00 00 01 00 +T 14 1C 00 00 0F FD 77 21 FD 7E 20 FD B6 21 20 +R 00 00 01 00 +T 1F 1C 00 00 16 +R 00 00 01 00 +T 20 1C 00 00 +R 00 00 01 00 +T 20 1C 00 00 11 14 00 CD D0 1C 00 00 FD 75 20 +R 00 00 01 00 00 08 01 00 +T 29 1C 00 00 FD 74 21 FD 6E 20 FD 66 21 36 00 +R 00 00 01 00 +T 34 1C 00 00 18 04 +R 00 00 01 00 +T 36 1C 00 00 +R 00 00 01 00 +T 36 1C 00 00 FD CB 0B F6 +R 00 00 01 00 +T 3A 1C 00 00 +R 00 00 01 00 +T 3A 1C 00 00 DD 7E EB 2E 00 4D E6 F0 47 26 10 +R 00 00 01 00 +T 45 1C 00 00 ED 42 30 10 +R 00 00 01 00 +T 49 1C 00 00 +R 00 00 01 00 +T 49 1C 00 00 DD 6E EA DD 7E EB E6 0F 67 23 FD +R 00 00 01 00 +T 54 1C 00 00 75 22 FD 74 23 +R 00 00 01 00 +T 59 1C 00 00 +R 00 00 01 00 +T 59 1C 00 00 FD E5 DD 5E 02 4B DD 56 03 42 21 +R 00 00 01 00 +T 64 1C 00 00 1D 00 09 4E 23 46 23 7E 69 60 C1 +R 00 00 01 00 +T 6F 1C 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 0B 00 +T 72 1C 00 00 +R 00 00 01 00 +T 72 1C 00 00 21 14 00 E5 2E 0E 39 4D 44 DD 5E +R 00 00 01 00 +T 7D 1C 00 00 D4 DD 56 D5 CD C8 1C 00 00 F1 3E +R 00 00 01 00 00 09 01 00 +T 86 1C 00 00 14 AD B4 CA 3E 19 00 00 +R 00 00 01 00 00 08 01 00 +T 8C 1C 00 00 +R 00 00 01 00 +T 8C 1C 00 00 DD 5E D4 DD 56 D5 3E 00 00 00 00 +R 00 00 01 00 2B 0B 05 00 +T 94 1C 00 00 21 00 00 00 00 CD 00 00 00 00 DD +R 00 00 01 00 02 05 05 00 02 0A 0B 00 +T 9B 1C 00 00 5E 02 DD 56 03 3E 1F 0A 00 00 21 +R 00 00 01 00 29 0A 01 00 +T A3 1C 00 00 1F 0A 00 00 CD 00 00 00 00 DD 5E +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T AA 1C 00 00 02 4B DD 56 03 42 21 1A 00 09 4E +R 00 00 01 00 +T B5 1C 00 00 23 46 23 7E 69 60 C3 1F 11 00 00 +R 00 00 01 00 00 0B 01 00 +T BE 1C 00 00 +R 00 00 01 00 +T BE 1C 00 00 4D 44 2A 00 00 00 00 23 23 5E 23 +R 00 00 01 00 00 07 04 00 +T C7 1C 00 00 56 +R 00 00 01 00 +T C8 1C 00 00 +R 00 00 01 00 +T C8 1C 00 00 3E 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 05 15 00 02 0A 15 00 +T CE 1C 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T D0 1C 00 00 +R 00 00 01 00 +T D0 1C 00 00 3E 00 00 00 00 21 00 00 00 00 C3 +R 00 00 01 00 2B 05 14 00 02 0A 14 00 +T D6 1C 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T D8 1C 00 00 +R 00 00 01 00 +T D8 1C 00 00 DD 4E DC DD 5E F2 DD 56 F3 +R 00 00 01 00 +T E1 1C 00 00 +R 00 00 01 00 +T E1 1C 00 00 CD 00 00 00 00 1B 1B 1B C9 +R 00 00 01 00 02 05 03 00 +T E8 1C 00 00 +R 00 00 01 00 +T E8 1C 00 00 CD 00 00 00 00 EA FF FD E5 DD 6E +R 00 00 01 00 02 05 0E 00 +T F1 1C 00 00 02 DD 66 03 E5 FD E1 21 06 00 39 +R 00 00 01 00 +T FC 1C 00 00 EB 21 26 00 00 00 01 0E 00 ED B0 +R 00 00 01 00 00 06 03 00 +T 05 1D 00 00 FD 6E 26 DD 75 EA FD 66 27 DD 74 +R 00 00 01 00 +T 10 1D 00 00 EB 23 23 23 3E 01 AE 23 B6 20 08 +R 00 00 01 00 +T 1B 1D 00 00 +R 00 00 01 00 +T 1B 1D 00 00 C5 01 01 04 CD 76 0D 00 00 E1 +R 00 00 01 00 00 09 01 00 +T 23 1D 00 00 +R 00 00 01 00 +T 23 1D 00 00 DD 6E EA DD 66 EB 23 23 23 46 23 +R 00 00 01 00 +T 2E 1D 00 00 66 68 CB 85 3E 02 AD B4 C2 +R 00 00 01 00 +T 37 1D 00 00 53 1E 00 00 +R 00 00 01 00 00 04 01 00 +T 39 1D 00 00 +R 00 00 01 00 +T 39 1D 00 00 6F 67 E5 E5 01 01 00 FD 5E 11 FD +R 00 00 01 00 +T 44 1D 00 00 56 12 3E B6 09 00 00 21 +R 00 00 01 00 29 07 01 00 +T 49 1D 00 00 B6 09 00 00 CD 00 00 00 00 E1 E1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 50 1D 00 00 FD 6E 11 FD 66 12 01 08 00 09 4E +R 00 00 01 00 +T 5B 1D 00 00 23 46 C5 FD 6E 11 FD 66 12 01 +R 00 00 01 00 +T 65 1D 00 00 06 00 09 4E 23 46 C5 01 00 00 59 +R 00 00 01 00 +T 70 1D 00 00 50 3E 71 0F 00 00 21 71 0F 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 76 1D 00 00 CD 00 00 00 00 F1 F1 DD 75 EC DD +R 00 00 01 00 02 05 0B 00 +T 7F 1D 00 00 74 ED 01 0A 00 09 36 03 23 70 DD +R 00 00 01 00 +T 8A 1D 00 00 6E EA DD 66 EB 23 23 23 CB 46 28 +R 00 00 01 00 +T 95 1D 00 00 0C +R 00 00 01 00 +T 96 1D 00 00 +R 00 00 01 00 +T 96 1D 00 00 69 60 DD 4E EC DD 46 ED 09 23 CB +R 00 00 01 00 +T A1 1D 00 00 EE +R 00 00 01 00 +T A2 1D 00 00 +R 00 00 01 00 +T A2 1D 00 00 21 17 00 DD 4E EC DD 46 ED 09 36 +R 00 00 01 00 +T AD 1D 00 00 F0 18 00 00 23 36 F0 18 00 00 23 +R 00 00 01 00 09 04 01 00 89 0A 01 00 +T B2 1D 00 00 36 F0 18 00 00 21 1A 00 09 36 +R 00 00 01 00 29 05 01 00 +T B9 1D 00 00 2C 0F 00 00 23 36 2C 0F 00 00 23 +R 00 00 01 00 09 04 01 00 89 0A 01 00 +T BE 1D 00 00 36 2C 0F 00 00 21 07 00 DD 5E EA +R 00 00 01 00 29 05 01 00 +T C6 1D 00 00 DD 56 EB 19 5E EB DD 75 F3 21 +R 00 00 01 00 +T D0 1D 00 00 07 00 DD 4E EA DD 46 EB 09 5E 23 +R 00 00 01 00 +T DB 1D 00 00 56 23 4E 23 46 EB 3E 08 CD +R 00 00 01 00 +T E4 1D 00 00 00 00 00 00 DD 75 F4 21 07 00 DD +R 00 00 01 00 02 04 13 00 +T ED 1D 00 00 4E EA DD 46 EB 09 5E 23 56 23 4E +R 00 00 01 00 +T F8 1D 00 00 23 46 EB 3E 10 CD 00 00 00 00 DD +R 00 00 01 00 02 0A 13 00 +T 01 1E 00 00 75 F5 21 07 00 DD 4E EA DD 46 EB +R 00 00 01 00 +T 0C 1E 00 00 09 5E 23 56 23 4E 23 46 EB 3E 18 +R 00 00 01 00 +T 17 1E 00 00 CD 00 00 00 00 DD 75 F6 21 06 00 +R 00 00 01 00 02 05 13 00 +T 20 1E 00 00 39 4D 44 DD 5E EC DD 56 ED 3E +R 00 00 01 00 +T 2A 1E 00 00 0E 19 00 00 21 0E 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 2F 1E 00 00 00 00 00 00 DD 4E EC DD 46 ED C5 +R 00 00 01 00 02 04 0B 00 +T 38 1E 00 00 FD 5E 11 FD 56 12 FD 6E 11 FD 66 +R 00 00 01 00 +T 43 1E 00 00 12 01 1D 00 09 4E 23 46 23 7E 69 +R 00 00 01 00 +T 4E 1E 00 00 60 C1 CD 00 00 00 00 +R 00 00 01 00 02 07 0B 00 +T 53 1E 00 00 +R 00 00 01 00 +T 53 1E 00 00 DD 6E EA DD 66 EB 23 23 23 3E 04 +R 00 00 01 00 +T 5E 1E 00 00 AE 23 B6 C2 F1 1F 00 00 +R 00 00 01 00 00 08 01 00 +T 64 1E 00 00 +R 00 00 01 00 +T 64 1E 00 00 21 01 00 E5 FD 6E 11 FD 66 12 01 +R 00 00 01 00 +T 6F 1E 00 00 08 00 09 46 23 66 68 01 F6 FF 09 +R 00 00 01 00 +T 7A 1E 00 00 E5 FD 6E 11 FD 66 12 01 06 00 09 +R 00 00 01 00 +T 85 1E 00 00 46 23 66 68 01 F6 FF 09 E5 01 +R 00 00 01 00 +T 8F 1E 00 00 05 00 59 50 3E 1A 15 00 00 21 +R 00 00 01 00 29 09 01 00 +T 96 1E 00 00 1A 15 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 9D 1E 00 00 F1 DD 75 EC DD 74 ED 01 0A 00 09 +R 00 00 01 00 +T A8 1E 00 00 36 03 23 36 10 21 0E 00 DD 4E EC +R 00 00 01 00 +T B3 1E 00 00 DD 46 ED 09 36 30 23 36 00 AF DD +R 00 00 01 00 +T BE 1E 00 00 77 FE DD 77 FF +R 00 00 01 00 +T C3 1E 00 00 +R 00 00 01 00 +T C3 1E 00 00 21 05 00 DD 4E EA DD 46 EB 09 5E +R 00 00 01 00 +T CE 1E 00 00 23 56 06 0C CD 00 00 00 00 4B 42 +R 00 00 01 00 02 09 16 00 +T D7 1E 00 00 DD 6E FE DD 66 FF CD 00 00 00 00 +R 00 00 01 00 02 0B 0F 00 +T E0 1E 00 00 30 04 3E 01 18 01 +R 00 00 01 00 +T E6 1E 00 00 +R 00 00 01 00 +T E6 1E 00 00 AF +R 00 00 01 00 +T E7 1E 00 00 +R 00 00 01 00 +T E7 1E 00 00 E6 0F CA 85 1F 00 00 +R 00 00 01 00 00 07 01 00 +T EC 1E 00 00 +R 00 00 01 00 +T EC 1E 00 00 21 05 00 DD 4E EA DD 46 EB 09 46 +R 00 00 01 00 +T F7 1E 00 00 23 7E 68 E6 0F 67 DD 4E FE DD 46 +R 00 00 01 00 +T 02 1F 00 00 FF 09 29 E5 21 08 00 ED 5B +R 00 00 01 00 +T 0B 1F 00 00 00 00 00 00 19 5E 23 56 E1 19 2B +R 00 00 01 00 00 04 04 00 +T 14 1F 00 00 2B 5E 23 56 D5 21 10 00 E5 2E 06 +R 00 00 01 00 +T 1F 1F 00 00 DD 5E EC DD 56 ED 19 6E 26 00 01 +R 00 00 01 00 +T 2A 1F 00 00 F0 FF 09 E5 DD 6E FE DD 66 FF 29 +R 00 00 01 00 +T 35 1F 00 00 29 4D 44 29 09 01 14 00 09 4D 44 +R 00 00 01 00 +T 40 1F 00 00 11 08 00 3E 97 18 00 00 21 +R 00 00 01 00 29 08 01 00 +T 46 1F 00 00 97 18 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 4D 1F 00 00 F1 DD 75 FC DD 74 FD 01 0E 00 09 +R 00 00 01 00 +T 58 1F 00 00 36 30 23 70 DD 4E FC DD 46 FD C5 +R 00 00 01 00 +T 63 1F 00 00 DD 5E EC 4B DD 56 ED 42 21 1D 00 +R 00 00 01 00 +T 6E 1F 00 00 09 4E 23 46 23 7E 69 60 C1 CD +R 00 00 01 00 +T 78 1F 00 00 00 00 00 00 DD 34 FE 20 03 DD 34 +R 00 00 01 00 02 04 0B 00 +T 81 1F 00 00 FF +R 00 00 01 00 +T 82 1F 00 00 +R 00 00 01 00 +T 82 1F 00 00 C3 C3 1E 00 00 +R 00 00 01 00 00 05 01 00 +T 85 1F 00 00 +R 00 00 01 00 +T 85 1F 00 00 01 15 00 00 00 DD 5E EC DD 56 ED +R 00 00 01 00 00 05 02 00 +T 8E 1F 00 00 3E 59 06 00 00 21 59 06 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 94 1F 00 00 00 00 00 00 01 FF 00 CD +R 00 00 01 00 02 04 0B 00 +T 9A 1F 00 00 12 20 00 00 01 0E 00 09 36 30 23 +R 00 00 01 00 00 04 01 00 +T A3 1F 00 00 70 0E FE CD 12 20 00 00 EB CD +R 00 00 01 00 00 08 01 00 +T AB 1F 00 00 8F 09 00 00 DD 4E EC DD 46 ED C5 +R 00 00 01 00 00 04 01 00 +T B4 1F 00 00 FD 5E 11 FD 56 12 FD 6E 11 FD 66 +R 00 00 01 00 +T BF 1F 00 00 12 01 1D 00 09 4E 23 46 23 7E 69 +R 00 00 01 00 +T CA 1F 00 00 60 C1 CD 00 00 00 00 21 00 00 E5 +R 00 00 01 00 02 07 0B 00 +T D3 1F 00 00 FD 5E 11 FD 56 12 FD 6E 11 FD 66 +R 00 00 01 00 +T DE 1F 00 00 12 01 17 00 09 4E 23 46 23 7E 69 +R 00 00 01 00 +T E9 1F 00 00 60 01 03 01 CD 00 00 00 00 E1 +R 00 00 01 00 02 09 0B 00 +T F1 1F 00 00 +R 00 00 01 00 +T F1 1F 00 00 21 10 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T FA 1F 00 00 23 B6 23 B6 28 0D +R 00 00 01 00 +T 00 20 00 00 +R 00 00 01 00 +T 00 20 00 00 FD E5 D1 21 10 00 ED 4B +R 00 00 01 00 +T 08 20 00 00 00 00 00 00 CD 94 0D 00 00 +R 00 00 01 00 00 04 04 00 00 09 01 00 +T 0D 20 00 00 +R 00 00 01 00 +T 0D 20 00 00 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 07 04 00 +T 12 20 00 00 +R 00 00 01 00 +T 12 20 00 00 DD 5E EC DD 56 ED 3E 8E 07 00 00 +R 00 00 01 00 29 0B 01 00 +T 1A 20 00 00 21 8E 07 00 00 C3 00 00 00 00 +R 00 00 01 00 00 05 01 00 02 0A 0B 00 +T 20 20 00 00 +R 00 00 01 00 +T 20 20 00 00 CD 00 00 00 00 F8 FF FD E5 03 0A +R 00 00 01 00 02 05 0E 00 +T 29 20 00 00 DD 77 FE 03 0A DD 77 FF 03 69 60 +R 00 00 01 00 +T 34 20 00 00 4E DD 71 FC 23 46 DD 70 FD DD 6E +R 00 00 01 00 +T 3F 20 00 00 FE 67 29 EB CD D0 1C 00 00 DD 75 +R 00 00 01 00 00 09 01 00 +T 48 20 00 00 FA DD 74 FB 59 50 CD CE 04 00 00 +R 00 00 01 00 00 0B 01 00 +T 51 20 00 00 C5 4D 44 DD 5E 02 DD 56 03 CD +R 00 00 01 00 +T 5B 20 00 00 C8 1C 00 00 F1 11 00 00 AF DD 77 +R 00 00 01 00 00 04 01 00 +T 64 20 00 00 F8 DD 77 F9 +R 00 00 01 00 +T 68 20 00 00 +R 00 00 01 00 +T 68 20 00 00 DD 4E FC DD 46 FD 6B 62 CD +R 00 00 01 00 +T 71 20 00 00 00 00 00 00 30 35 CD E6 20 00 00 +R 00 00 01 00 02 04 0F 00 00 0B 01 00 +T 78 20 00 00 30 30 +R 00 00 01 00 +T 7A 20 00 00 +R 00 00 01 00 +T 7A 20 00 00 +R 00 00 01 00 +T 7A 20 00 00 +R 00 00 01 00 +T 7A 20 00 00 23 DD 75 F8 DD 74 F9 2B 29 DD 4E +R 00 00 01 00 +T 85 20 00 00 FA DD 46 FB 09 E5 FD E5 E1 19 4D +R 00 00 01 00 +T 90 20 00 00 44 E1 71 23 70 +R 00 00 01 00 +T 95 20 00 00 +R 00 00 01 00 +T 95 20 00 00 FD E5 E1 19 7E B7 28 03 +R 00 00 01 00 +T 9D 20 00 00 +R 00 00 01 00 +T 9D 20 00 00 13 18 F5 +R 00 00 01 00 +T A0 20 00 00 +R 00 00 01 00 +T A0 20 00 00 6B 62 13 FD E5 C1 09 77 18 BE +R 00 00 01 00 +T AA 20 00 00 +R 00 00 01 00 +T AA 20 00 00 CD E6 20 00 00 30 13 +R 00 00 01 00 00 05 01 00 +T AF 20 00 00 +R 00 00 01 00 +T AF 20 00 00 29 DD 4E FA DD 46 FB 09 E5 FD E5 +R 00 00 01 00 +T BA 20 00 00 E1 19 4D 44 E1 71 23 70 +R 00 00 01 00 +T C2 20 00 00 +R 00 00 01 00 +T C2 20 00 00 21 06 00 ED 4B 00 00 00 00 09 FD +R 00 00 01 00 00 09 04 00 +T CB 20 00 00 E5 C1 71 23 70 21 08 00 ED 4B +R 00 00 01 00 +T D5 20 00 00 00 00 00 00 09 DD 4E FA 71 DD 46 +R 00 00 01 00 00 04 04 00 +T DE 20 00 00 FB 23 70 FD E1 C3 00 00 00 00 +R 00 00 01 00 02 0A 04 00 +T E6 20 00 00 +R 00 00 01 00 +T E6 20 00 00 DD 4E FE DD 46 FF DD 6E F8 DD 66 +R 00 00 01 00 +T F1 20 00 00 F9 C3 00 00 00 00 +R 00 00 01 00 02 06 0F 00 +T F5 20 00 00 +R 00 00 01 00 +T F5 20 00 00 2A 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 00 05 04 00 02 0A 00 00 +T FB 20 00 00 +R 00 00 01 00 +T FB 20 00 00 C5 D5 11 13 00 CD D0 1C 00 00 22 +R 00 00 01 00 00 0A 01 00 +T 04 21 00 00 00 00 00 00 AF 77 23 77 21 04 00 +R 00 00 01 00 00 04 04 00 +T 0D 21 00 00 ED 4B 00 00 00 00 09 77 23 77 21 +R 00 00 01 00 00 06 04 00 +T 16 21 00 00 0A 00 ED 4B 00 00 00 00 09 77 23 +R 00 00 01 00 00 08 04 00 +T 1F 21 00 00 77 21 0C 00 ED 4B 00 00 00 00 09 +R 00 00 01 00 00 0A 04 00 +T 28 21 00 00 77 23 77 21 08 00 ED 4B +R 00 00 01 00 +T 30 21 00 00 00 00 00 00 09 77 23 77 21 06 00 +R 00 00 01 00 00 04 04 00 +T 39 21 00 00 ED 4B 00 00 00 00 09 77 23 77 21 +R 00 00 01 00 00 06 04 00 +T 42 21 00 00 10 00 ED 4B 00 00 00 00 09 77 23 +R 00 00 01 00 00 08 04 00 +T 4B 21 00 00 77 23 77 3E 00 00 00 00 21 +R 00 00 01 00 29 08 01 00 +T 51 21 00 00 00 00 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 57 21 00 00 00 00 E5 E5 0E 70 05 00 00 C5 21 +R 00 00 01 00 29 09 01 00 +T 5F 21 00 00 70 05 00 00 E5 0E 8C 05 00 00 C5 +R 00 00 01 00 00 04 01 00 29 0A 01 00 +T 65 21 00 00 21 8C 05 00 00 E5 11 30 00 CD +R 00 00 01 00 00 05 01 00 +T 6D 21 00 00 1A 22 00 00 21 0C 00 39 F9 21 +R 00 00 01 00 00 04 01 00 +T 75 21 00 00 00 00 E5 E5 0E 70 05 00 00 C5 21 +R 00 00 01 00 29 09 01 00 +T 7D 21 00 00 70 05 00 00 E5 0E 9D 05 00 00 C5 +R 00 00 01 00 00 04 01 00 29 0A 01 00 +T 83 21 00 00 21 9D 05 00 00 E5 11 31 00 CD +R 00 00 01 00 00 05 01 00 +T 8B 21 00 00 1A 22 00 00 21 0C 00 39 F9 21 +R 00 00 01 00 00 04 01 00 +T 93 21 00 00 00 00 E5 E5 0E 83 05 00 00 C5 21 +R 00 00 01 00 29 09 01 00 +T 9B 21 00 00 83 05 00 00 E5 0E A6 05 00 00 C5 +R 00 00 01 00 00 04 01 00 29 0A 01 00 +T A1 21 00 00 21 A6 05 00 00 E5 11 32 00 CD +R 00 00 01 00 00 05 01 00 +T A9 21 00 00 1A 22 00 00 21 0C 00 39 F9 21 +R 00 00 01 00 00 04 01 00 +T B1 21 00 00 0E 00 ED 4B 00 00 00 00 09 E5 11 +R 00 00 01 00 00 08 04 00 +T BA 21 00 00 80 00 D5 5A D5 4B 42 3E +R 00 00 01 00 +T C2 21 00 00 71 0F 00 00 21 71 0F 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T C7 21 00 00 00 00 00 00 F1 F1 4D 44 E1 71 23 +R 00 00 01 00 02 04 0B 00 +T D0 21 00 00 70 21 0E 00 ED 4B 00 00 00 00 09 +R 00 00 01 00 00 0A 04 00 +T D9 21 00 00 56 23 66 6A 11 0A 00 19 36 01 23 +R 00 00 01 00 +T E4 21 00 00 72 21 0E 00 ED 4B 00 00 00 00 09 +R 00 00 01 00 00 0A 04 00 +T ED 21 00 00 56 23 66 6A 11 17 00 19 36 +R 00 00 01 00 +T F6 21 00 00 F0 18 00 00 23 36 F0 18 00 00 23 +R 00 00 01 00 09 04 01 00 89 0A 01 00 +T FB 21 00 00 36 F0 18 00 00 21 0E 00 ED 4B +R 00 00 01 00 29 05 01 00 +T 02 22 00 00 00 00 00 00 09 46 23 66 68 01 +R 00 00 01 00 00 04 04 00 +T 0A 22 00 00 1A 00 09 36 2C 0F 00 00 23 36 +R 00 00 01 00 09 08 01 00 +T 11 22 00 00 2C 0F 00 00 23 36 2C 0F 00 00 D1 +R 00 00 01 00 89 04 01 00 29 0A 01 00 +T 16 22 00 00 C1 C3 00 00 00 00 +R 00 00 01 00 02 06 00 00 +T 1A 22 00 00 +R 00 00 01 00 +T 1A 22 00 00 3E 33 04 00 00 21 33 04 00 00 C3 +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 20 22 00 00 00 00 00 00 +R 00 00 01 00 02 04 0B 00 +T 22 22 00 00 +R 00 00 01 00 +T 22 22 00 00 C5 D5 21 0E 00 ED 4B 00 00 00 00 +R 00 00 01 00 00 0B 04 00 +T 2B 22 00 00 09 5E 23 56 CD 8F 09 00 00 3E +R 00 00 01 00 00 09 01 00 +T 33 22 00 00 BD 02 00 00 21 BD 02 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 38 22 00 00 00 00 00 00 3E 8E 00 00 00 21 +R 00 00 01 00 02 04 0B 00 29 09 01 00 +T 3D 22 00 00 8E 00 00 00 CD 00 00 00 00 D1 C1 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 44 22 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 00 00 +T 47 22 00 00 +R 00 00 01 00 +T 47 22 00 00 CD 00 00 00 00 FE FF DD 4E 02 DD +R 00 00 01 00 02 05 0E 00 +T 50 22 00 00 46 03 21 0E 00 ED 5B 00 00 00 00 +R 00 00 01 00 00 0B 04 00 +T 59 22 00 00 19 5E 23 56 3E 0E 19 00 00 21 +R 00 00 01 00 29 09 01 00 +T 60 22 00 00 0E 19 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 0B 00 +T 65 22 00 00 +R 00 00 01 00 +T 65 22 00 00 21 01 00 E5 23 39 CD BE 1C 00 00 +R 00 00 01 00 00 0B 01 00 +T 6E 22 00 00 F1 3E 01 AD B4 28 F0 +R 00 00 01 00 +T 75 22 00 00 +R 00 00 01 00 +T 75 22 00 00 +R 00 00 01 00 +T 75 22 00 00 +R 00 00 01 00 +T 75 22 00 00 21 04 00 ED 4B 00 00 00 00 09 7E +R 00 00 01 00 00 09 04 00 +T 7E 22 00 00 23 B6 20 77 +R 00 00 01 00 +T 82 22 00 00 +R 00 00 01 00 +T 82 22 00 00 21 01 00 E5 23 39 CD BE 1C 00 00 +R 00 00 01 00 00 0B 01 00 +T 8B 22 00 00 F1 3E 01 AD B4 20 E3 +R 00 00 01 00 +T 92 22 00 00 +R 00 00 01 00 +T 92 22 00 00 DD B6 FE 28 2B +R 00 00 01 00 +T 97 22 00 00 +R 00 00 01 00 +T 97 22 00 00 4F 06 00 C5 21 0E 00 ED 5B +R 00 00 01 00 +T A0 22 00 00 00 00 00 00 19 5E 23 56 21 0E 00 +R 00 00 01 00 00 04 04 00 +T A9 22 00 00 ED 4B 00 00 00 00 09 46 23 66 68 +R 00 00 01 00 00 06 04 00 +T B2 22 00 00 01 17 00 09 4E 23 46 23 7E 69 60 +R 00 00 01 00 +T BD 22 00 00 01 01 00 18 2A +R 00 00 01 00 +T C2 22 00 00 +R 00 00 01 00 +T C2 22 00 00 DD 4E FF 47 C5 21 0E 00 ED 5B +R 00 00 01 00 +T CC 22 00 00 00 00 00 00 19 5E 23 56 21 0E 00 +R 00 00 01 00 00 04 04 00 +T D5 22 00 00 ED 4B 00 00 00 00 09 46 23 66 68 +R 00 00 01 00 00 06 04 00 +T DE 22 00 00 01 17 00 09 4E 23 46 23 7E 69 60 +R 00 00 01 00 +T E9 22 00 00 01 02 00 +R 00 00 01 00 +T EC 22 00 00 +R 00 00 01 00 +T EC 22 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 02 05 0B 00 +T F0 22 00 00 +R 00 00 01 00 +T F0 22 00 00 DD 46 FE DD 70 FF +R 00 00 01 00 +T F6 22 00 00 +R 00 00 01 00 +T F6 22 00 00 C3 75 22 00 00 +R 00 00 01 00 00 05 01 00 +T F9 22 00 00 +R 00 00 01 00 +T F9 22 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 04 00 +T 00 00 00 00 +R 00 00 02 00 +T 00 00 00 00 2F 64 65 76 2F 6C 63 64 30 00 +R 00 00 02 00 +T 0A 00 00 00 +R 00 00 02 00 +T 0A 00 00 00 4F 4B 00 +R 00 00 02 00 +T 0D 00 00 00 +R 00 00 02 00 +T 0D 00 00 00 43 61 6E 63 65 6C 00 +R 00 00 02 00 +T 14 00 00 00 +R 00 00 02 00 +T 14 00 00 00 00 +R 00 00 02 00 +T 15 00 00 00 +R 00 00 02 00 +T 15 00 00 00 4D 65 73 73 61 67 65 20 42 6F 78 +R 00 00 02 00 +T 20 00 00 00 00 +R 00 00 02 00 +T 00 00 00 00 +R 00 00 03 00 +T 00 00 00 00 1B 4B +R 00 00 03 00 +T 02 00 00 00 +R 00 00 03 00 +T 02 00 00 00 1B 53 00 00 +R 00 00 03 00 +T 06 00 00 00 +R 00 00 03 00 +T 06 00 00 00 1B 43 00 00 +R 00 00 03 00 +T 0A 00 00 00 +R 00 00 03 00 +T 0A 00 00 00 1B 4E 00 00 +R 00 00 03 00 +T 0E 00 00 00 +R 00 00 03 00 +T 0E 00 00 00 1B 52 00 00 +R 00 00 03 00 +T 12 00 00 00 +R 00 00 03 00 +T 12 00 00 00 1B 46 00 00 +R 00 00 03 00 +T 16 00 00 00 +R 00 00 03 00 +T 16 00 00 00 1B 68 00 00 +R 00 00 03 00 +T 1A 00 00 00 +R 00 00 03 00 +T 1A 00 00 00 1B 5A 00 00 00 00 00 +R 00 00 03 00 +T 21 00 00 00 +R 00 00 03 00 +T 21 00 00 00 1B 45 00 +R 00 00 03 00 +T 24 00 00 00 +R 00 00 03 00 +T 24 00 00 00 1B 00 +R 00 00 03 00 +T 26 00 00 00 +R 00 00 03 00 +T 26 00 00 00 2F 77 6E 64 2F 30 30 30 30 2E 73 +R 00 00 03 00 +T 31 00 00 00 63 72 00 +R 00 00 03 00 +T 00 00 00 00 +R 00 00 04 00 +T 00 00 00 00 +R 00 00 04 00 diff --git a/src/gui/wnd.xcl b/src/gui/wnd.xcl new file mode 100644 index 00000000..86b193b4 --- /dev/null +++ b/src/gui/wnd.xcl @@ -0,0 +1,13 @@ +-cz80 +-Z(CODE)RCODE,CODE,ZVECT,CONST,CSTR,CDATA0,CCSTR=8100 +-Z(DATA)DATA0,IDATA0,UDATA0,ECSTR,WCSTR,TEMP,CSTACK+200 +..\libc\cstartup +wnd +login +..\libc\libc +..\libc\syscalls\syscalls +cl64180 +-x +-l wnd.map +-FINTEL-EXTENDED -Y1 +-o wnd.ihx diff --git a/src/gui/wnd.xls b/src/gui/wnd.xls new file mode 100644 index 0000000000000000000000000000000000000000..c3438cef683447a424da09ef2da503e1a872e55f GIT binary patch literal 15872 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 R@Kx74uD|;4Cps^-{{fDfkiq}} literal 0 HcmV?d00001 diff --git a/src/gui/wnd.zip b/src/gui/wnd.zip new file mode 100644 index 0000000000000000000000000000000000000000..205d545ec6a6bf523035aad2333f78c1b01ba539 GIT binary patch literal 9882 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 WL%+=e7#PCaNB6BDP*VK$?SBBneJz6k literal 0 HcmV?d00001 diff --git a/src/init/init.c b/src/init/init.c index 90016bb2..46726c79 100644 --- a/src/init/init.c +++ b/src/init/init.c @@ -21,6 +21,7 @@ #include #include /* Nick */ #include +#include /* Nick */ #include static firsttime = 1; @@ -40,45 +41,126 @@ struct exec_struct tty_list[NUM_TTYS] = }; void process_inittab(void) -{ + { FILE *fdm; - char cmd[128], *p; /* [64], *p; */ - static char *_argv[3]; /* [2] = { 0, 0 }; */ + char cmd[128], *p; + char silent; + int i, argc; + char *argv[18]; int pid; - if ((fdm = fopen("/etc/inittab", "r")) != NULL) { - while (!feof(fdm)) { - if (fgets(cmd, sizeof(cmd)-1, fdm)==NULL) break; - if (cmd[0] != '#') { - if (NULL != (p = strchr(cmd, '\n'))) *p=0; - if (cmd[0] > ' ') { - printf("init: executing %s\n", cmd); - pid = fork(); - if (pid==-1) { - printf("init: can't execute %s\n", cmd); - continue; - } - if (pid==0) { - _argv[0] = cmd; - _argv[1] = NULL; - execve(_argv[0], _argv, environ); - if (errno == ESHELL) - { - _argv[0] = _PATH_BSHELL; - _argv[1] = cmd; - _argv[2] = NULL; - execve(_argv[0], _argv, environ); - } - printf("init: can't execute %s\n", cmd); - exit(1); - } - wait(&pid); + printf("Processing /etc/inittab\n"); + fflush(stdout); + + fdm = fopen("/etc/inittab", "r"); + if (fdm == NULL) + { + perror("can't open /etc/inittab"); + return; + } + + while (feof(fdm) == 0) + { + if (fgets(cmd, sizeof(cmd)-1, fdm) == NULL) + { + break; + } +/* printf("@@@ %s", cmd); */ + /* check for comment lines */ + p = cmd; + while (isspace(*p)) + { + p++; + } + + if (*p == '#') + { + continue; + } + + /* check for silent lines */ + silent = 0; + if (*p == '@') + { + silent = 1; + p++; + } + + /* convert line into arguments */ + argc = 0; + while (argc < 16) + { + while (isspace(*p)) + { + p++; + } + if (*p == 0) + { + break; + } + argv[1 + argc++] = p; + while (*p && isspace(*p) == 0) + { + p++; } + if (*p == 0) + { + break; + } + *p = 0; + } + + /* got a command to execute? */ + if (argc < 1) + { + continue; + } + + /* pacify the user, unless silent */ + if (silent == 0) + { + printf("%s", argv[1]); + for (i = 1; i < argc; i++) + { + printf(" %s", argv[1 + i]); + } + printf("\n"); + fflush(stdout); } + + /* fork and execute the program */ + pid = fork(); + if (pid == -1) + { + if (silent == 0) + { + perror("can't fork"); + } + continue; + } + + if (pid == 0) + { + argv[1 + argc] = NULL; + execve(argv[1], argv + 1, environ); + if (errno == ESHELL) + { + argv[0] = _PATH_BSHELL; + execve(argv[0], argv, environ); + } + if (silent == 0) + { + perror("can't execute"); + } + _exit(1); /* don't close handles in this case!!!!! */ + } + + /* wait for child to complete */ + wait(&pid); } - fclose(fdm); + + fclose(fdm); } -} int determine_tty(int pid) { @@ -92,7 +174,7 @@ int determine_tty(int pid) } void generate_mtab(void) -{ + { #if 1 /* Nick, new getfsys() convention */ filesys_t fsys; #else @@ -105,11 +187,11 @@ void generate_mtab(void) #else char mtabline[] = "/dev/fdX\t/\trw\n"; #endif - char *s = "failed"; FILE *fdm; #if 1 /* Nick */ - printf("init: creating /etc/mtab: "); + printf("Generating /etc/mtab\n"); + fflush(stdout); #else printf("Updating /etc/mtab: "); #endif @@ -127,66 +209,94 @@ void generate_mtab(void) { j = MINOR(fsys->s_dev); #endif - unlink("/etc/mtab"); + if (unlink("/etc/mtab") < 0) + { + perror("can't unlink /etc/mtab"); + break; + } mtabline[7] = j + '0'; - if ((fdm = fopen("/etc/mtab", "w")) != NULL) + if ((fdm = fopen("/etc/mtab", "w")) == NULL) { - if (fputs(mtabline, fdm) != EOF) - s = "ok"; - fclose(fdm); + perror("can't create /etc/mtab"); + break; } + if (fputs(mtabline, fdm) == EOF) + { + perror("can't write /etc/mtab"); + break; + } + fclose(fdm); break; } } - printf("%s\n", s); -} + } #if 1 /* Nick, we want mtab preserved over bootup */ #define PLENGTH 40 -void process_mtab(void) +void process_fstab(void) { int r; - FILE *mtb; + FILE *fdf, *fdm; char line[PLENGTH]; char mf1[PLENGTH], mf2[PLENGTH], mf3[PLENGTH]; - if ((mtb = fopen("/etc/mtab", "r")) == NULL) + printf("Processing /etc/fstab\n"); + fflush(stdout); + + if ((fdf = fopen("/etc/fstab", "r")) == NULL) { -#if 1 - generate_mtab(); -#else - printf("init: can't open /etc/mtab\n"); -#endif + perror("can't open /etc/fstab"); return; } - while (!feof(mtb)) + + while (feof(fdf) == 0) { - if (fgets(line, PLENGTH, mtb)) + if (fgets(line, PLENGTH, fdf) == NULL) { - mf1[0] = mf2[0] = mf3[0] = '\0'; - r = sscanf(line, "%s%s%s", mf1, mf2, mf3); - if (r > 1 && strcmp(mf2, "/")) - { - if (r > 2) - { - r = !strcmp(mf3, "ro"); - } - else - { - r = 0; /* default to read/write */ - } - r = mount(mf1, mf2, r); - if (r < 0) - { - fprintf(stderr, - "init: failed to mount %s on %s\n", - mf1, mf2); - } - } + break; + } + + mf1[0] = mf2[0] = mf3[0] = '\0'; + r = sscanf(line, "%s%s%s", mf1, mf2, mf3); + if (r < 2 || strcmp(mf2, "/") == 0) + { + continue; + } + + if (r > 2) + { + r = !strcmp(mf3, "ro"); + } + else + { + r = 0; /* default to read/write */ + } + r = mount(mf1, mf2, r); + if (r < 0) + { + perror("mount failed"); + continue; } + + fdm = fopen("/etc/mtab", "a"); + if (fdm == NULL) + { + perror("can't open /etc/mtab"); + continue; + } + + sprintf(line,"%s\t%s\tr%c\n", mf1, mf2, r ? 'o' : 'w'); + if (fputs(line, fdm) == EOF) + { + perror("can't write /etc/mtab"); + continue; + } + + fclose(fdm); } - fclose(mtb); + + fclose(fdf); } #endif @@ -224,13 +334,10 @@ int spawn_tty(unsigned num, char **argv) dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (firsttime) { -#if 1 /* Nick, we want mtab preserved over bootup */ - process_mtab(); -#else generate_mtab(); -#endif + process_fstab(); process_inittab(); - printf("Spawning tty #%d (%s): ok\n", num, p->tty_name); + printf("\nSpawning tty #%d (%s): ok\n", num, p->tty_name); } setenv("TTY", p->tty_name, 1); setenv("TERM", @@ -344,6 +451,7 @@ VOID main(int argc, char *argv[]) time_t mytimet; #if 1 /* Nick */ struct tm *tmbuf; + char *tmptr; #endif #endif @@ -360,7 +468,7 @@ VOID main(int argc, char *argv[]) #if 1 /* Nick */ /* reopen_console(); */ - printf("Date/time: "); + printf("Time/date: "); fflush(stdout); time(&mytimet); @@ -370,7 +478,17 @@ VOID main(int argc, char *argv[]) } tmbuf = localtime(&mytimet); +#if 1 + tmptr = asctime(tmbuf); + tmptr[3] = 0; /* terminate day of week */ + tmptr[7] = 0; /* terminate month */ + tmptr[10] = 0; /* terminate day of month */ + tmptr[19] = 0; /* terminate time of day */ + printf("%s %s %s %s %s", + tmptr + 11, tmptr, tmptr + 8, tmptr + 4, tmptr + 20); +#else printf("%s", asctime(tmbuf)); /* has embedded newline */ +#endif fflush(stdout); if (tmbuf->tm_year < 103) /* 2003 */ @@ -378,7 +496,7 @@ VOID main(int argc, char *argv[]) for (;;) #endif { - printf("Enter date/time (hh:mm[:ss] dd/mm/yyyy): "); + printf("Enter time/date (hh:mm[:ss] dd/mm/yyyy): "); fflush(stdout); read(0, buf, 39); p=strchr(buf, '\n'); @@ -387,7 +505,7 @@ VOID main(int argc, char *argv[]) *p=0; if (!conv_time(buf, p+1, &tt)) { - printf("Bad date/time format\n"); + printf("Bad time/date format\n"); #if 1 /* Nick */ } else @@ -399,8 +517,19 @@ VOID main(int argc, char *argv[]) } else { - printf("New date/time: %s", ctime(&mytimet)); +#if 1 + tmptr = ctime(&mytimet); + tmptr[3] = 0; /* terminate day of week */ + tmptr[7] = 0; /* terminate month */ + tmptr[10] = 0; /* terminate day of month */ + tmptr[19] = 0; /* terminate time of day */ + printf("New time/date: %s %s %s %s %s", + tmptr + 11, tmptr, tmptr + 8, tmptr + 4, + tmptr + 20); +#else + printf("New time/date: %s", ctime(&mytimet)); /* has embedded newline */ +#endif } } } diff --git a/src/kernel/build.ban b/src/kernel/build.ban index a1368824..e0f7b879 100644 --- a/src/kernel/build.ban +++ b/src/kernel/build.ban @@ -69,91 +69,91 @@ rem build uzi copy ..\uzi\asmdef.inc copy ..\uzi\z180.inc -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\main +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\main @if errorlevel 1 goto failure del main.r01 as-z80 -l -o main.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\data +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\data @if errorlevel 1 goto failure del data.r01 as-z80 -l -o data.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devflop +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\devflop @if errorlevel 1 goto failure del devflop.r01 as-z80 -l -o devflop.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devhd +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\devhd @if errorlevel 1 goto failure del devhd.r01 as-z80 -l -o devhd.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devio +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\devio @if errorlevel 1 goto failure del devio.r01 as-z80 -l -o devio.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devmisc +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\devmisc @if errorlevel 1 goto failure del devmisc.r01 as-z80 -l -o devmisc.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devtty +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\devtty @if errorlevel 1 goto failure del devtty.r01 as-z80 -l -o devtty.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\filesys +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\filesys @if errorlevel 1 goto failure del filesys.r01 as-z80 -l -o filesys.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\machdep +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\machdep @if errorlevel 1 goto failure del machdep.r01 as-z80 -l -o machdep.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\process +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\process @if errorlevel 1 goto failure del process.r01 as-z80 -l -o process.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall1 +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\scall1 @if errorlevel 1 goto failure del scall1.r01 as-z80 -l -o scall1.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall2 +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\scall2 @if errorlevel 1 goto failure del scall2.r01 as-z80 -l -o scall2.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall3 +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\scall3 @if errorlevel 1 goto failure del scall3.r01 as-z80 -l -o scall3.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\systrace +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\systrace @if errorlevel 1 goto failure del systrace.r01 as-z80 -l -o systrace.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\xip +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=2 ..\uzi\xip @if errorlevel 1 goto failure del xip.r01 as-z80 -l -o xip.s01 @@ -185,73 +185,79 @@ copy ..\libc\_exit.asm _exit.s01 as-z80 -l -o _exit.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\kprintf +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\dprintf +@if errorlevel 1 goto failure +del dprintf.r01 +as-z80 -l -o dprintf.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\kprintf @if errorlevel 1 goto failure del kprintf.r01 as-z80 -l -o kprintf.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\vfprintf +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\vfprintf @if errorlevel 1 goto failure del vfprintf.r01 as-z80 -l -o vfprintf.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\itoa +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\itoa @if errorlevel 1 goto failure del itoa.r01 as-z80 -l -o itoa.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\ltoa +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\ltoa @if errorlevel 1 goto failure del ltoa.r01 as-z80 -l -o ltoa.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\ultoa +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\ultoa @if errorlevel 1 goto failure del ultoa.r01 as-z80 -l -o ultoa.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strlen +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\strlen @if errorlevel 1 goto failure del strlen.r01 as-z80 -l -o strlen.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strcat +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\strcat @if errorlevel 1 goto failure del strcat.r01 as-z80 -l -o strcat.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strcpy +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\strcpy @if errorlevel 1 goto failure del strcpy.r01 as-z80 -l -o strcpy.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strncmp +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\strncmp @if errorlevel 1 goto failure del strncmp.r01 as-z80 -l -o strncmp.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\memcpy +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\memcpy @if errorlevel 1 goto failure del memcpy.r01 as-z80 -l -o memcpy.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\abort +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\abort @if errorlevel 1 goto failure del abort.r01 as-z80 -l -o abort.s01 @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\exit +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -DDEBUG=2 ..\libc\exit @if errorlevel 1 goto failure del exit.r01 as-z80 -l -o exit.s01 @@ -264,13 +270,13 @@ link-z80 -f kernel ihex2bin -l kernel.i86 ..\..\..\bin\kernel.bin @if errorlevel 1 goto failure -copy ..\..\..\bin\kernel.bin \nlddl -set country=NLD -crc -copy \nlddl\checksum ..\..\..\bin +rem copy ..\..\..\bin\kernel.bin \nlddl +rem set country=NLD +rem crc +rem copy \nlddl\checksum ..\..\..\bin -copy \nlddl\checksum \\darkstar\public\dos622\nlddl -copy \nlddl\kernel.bin \\darkstar\public\dos622\nlddl +rem copy \nlddl\checksum \\darkstar\public\dos622\nlddl +rem copy \nlddl\kernel.bin \\darkstar\public\dos622\nlddl @echo SUCCESS @goto done diff --git a/src/kernel/cmx/apibus.asm b/src/kernel/cmx/apibus.asm index 53a0e924..3708d158 100644 --- a/src/kernel/cmx/apibus.asm +++ b/src/kernel/cmx/apibus.asm @@ -68,6 +68,7 @@ _apibus_setup:: public _apibus_priority _apibus_priority:: +if 0 ; 08apr03 patch to avoid BAD COMMAND error on TPG hardware ; enter with e = priority value to be set ; upper nibble is priority (1-7), lower nibble is device (1-8) @@ -99,6 +100,7 @@ set_priority: pop de pop bc +endif jp ?BANK_FAST_LEAVE_L08 ; ----------------------------------------------------------------------------- diff --git a/src/kernel/cmx/copyr.asm b/src/kernel/cmx/copyr.asm index 7b1af16d..ea8fc2d6 100644 --- a/src/kernel/cmx/copyr.asm +++ b/src/kernel/cmx/copyr.asm @@ -11,7 +11,7 @@ BITELOG equ 5 PBITE equ 16 PBITELOG equ 4 - extern abyte, ahexw, ahexn, acrlf + extern abyte, ahexn, ahexb, ahexw, acrlf ; copy routine ; ------------ @@ -93,6 +93,65 @@ copyr: call acrlf pop hl + .endif + .if 0 ; disk block monitor + ld a,e + cp 4 + jr nz,nowrm + push bc + push hl + ld bc,0e00h + or a + sbc hl,bc + pop hl + pop bc + jr nz,nowrm + ; e:hl -> 4:0e00, disk block 7 + call nomon + +mon: + push bc + push hl + in0 a,(BBR) + push af + ld a,40h-4 + out0 (BBR),a + ld hl,4e00h ; bbr:hl -> 4:0e00, disk block 7 + ld c,20h +dline: + ld b,10h +ditem: + ld a,(hl) + inc hl + call ahexb + ld a,' ' + call abyte + djnz ditem + call acrlf + dec c + jr nz,dline + pop af + out0 (BBR),a + pop hl + pop bc + ret + +nowrm: + ld a,d + cp 4 + jr nz,nomon + push bc + push hl + push iy + pop hl + ld bc,0e00h + or a + sbc hl,bc + pop hl + pop bc + call z,mon ; if d:iy -> 4:0e00, disk block 7 + +nomon: .endif ld a,e cp 4 diff --git a/src/kernel/cmx/diag.asm b/src/kernel/cmx/diag.asm index c741e491..b8c7f0f4 100644 --- a/src/kernel/cmx/diag.asm +++ b/src/kernel/cmx/diag.asm @@ -24,6 +24,10 @@ _abyte:: public abyte abyte:: + .if 1 + ei ; a bit naughty but avoids inadvertent BAD COMMAND when line is busy + .endif + .if 0 ; 0=enable abytes, 1=disable abytes (doesn't affect the code size) ret .else diff --git a/src/kernel/kernel.lnk b/src/kernel/kernel.lnk index 7a7a699f..2a389ec1 100644 --- a/src/kernel/kernel.lnk +++ b/src/kernel/kernel.lnk @@ -38,6 +38,7 @@ flopasm utils systrace xip +dprintf kprintf vfprintf itoa diff --git a/src/kernel/libc/vendor.h b/src/kernel/libc/VENDOR.H similarity index 79% rename from src/kernel/libc/vendor.h rename to src/kernel/libc/VENDOR.H index 7c5b7c44..ac96c04e 100644 --- a/src/kernel/libc/vendor.h +++ b/src/kernel/libc/VENDOR.H @@ -2,10 +2,13 @@ #ifndef UTIL /* ensures we don't do anything when compiling utils under MSVC */ +#define dprintf _dprintf #define kprintf _kprintf +#define ub _ub #if 1 /* Nick, see kprintf.c */ int kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +int dprintf(char debuglevel, char *fmt, ...); #else void kprintf(char *, ...); /* ensures IAR won't try to pass register params */ #endif diff --git a/src/kernel/libc/dprintf.c b/src/kernel/libc/dprintf.c new file mode 100644 index 00000000..ea99c9a2 --- /dev/null +++ b/src/kernel/libc/dprintf.c @@ -0,0 +1,59 @@ +/* dprintf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +/* #include "printf.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include +#if 1 +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#include +#include +#include + +#include "unix.h" /* Nick for udata.u_debugme */ +#include "config.h" /* Nick for udata.u_debugme */ +#include "extern.h" /* Nick for udata.u_debugme */ + +int dprintf(char debuglevel, char *fmt, ...) +{ +#ifdef DEBUG + va_list ptr; + int rv; + + if (udata.u_debugme < debuglevel) + { + return 0; + } + + va_strt(ptr, fmt); +#if 1 /* Nick */ + rv = vfprintf(NULL, fmt, ptr); +#else + rv = vfprintf(stdout, fmt, ptr); +#endif + va_end(ptr); + return rv; +#else + return 0; +#endif +} + diff --git a/src/kernel/libc/dprintf.h b/src/kernel/libc/dprintf.h new file mode 100644 index 00000000..20e582c6 --- /dev/null +++ b/src/kernel/libc/dprintf.h @@ -0,0 +1,9 @@ +/* dprintf.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __DPRINTF_H +#define __DPRINTF_H + +int dprintf(char *fmt, ...); + +#endif /* __DPRINTF_H */ + diff --git a/src/kernel/uzi/config.h b/src/kernel/uzi/config.h index 9e0ee5a9..6eb8a699 100644 --- a/src/kernel/uzi/config.h +++ b/src/kernel/uzi/config.h @@ -79,7 +79,7 @@ extern devsw_t dev_tab[]; /* Nick */ #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ #define SWAPDEV 3 /* Device for swapping. */ -#define NBUFS 20 /*10*/ /* Number of block buffers */ +#define NBUFS 10 /* DEBUGGING 20 */ /*10*/ /* Number of block buffers */ #if 1 /* Nick UZIX compatibility */ diff --git a/src/kernel/uzi/devhd.c b/src/kernel/uzi/devhd.c index a542b882..de95395d 100644 --- a/src/kernel/uzi/devhd.c +++ b/src/kernel/uzi/devhd.c @@ -73,9 +73,8 @@ int wd_read(uchar minor, uchar rawflag) int setup(); /* kputchar(minor + '0'); */ -#if DEBUG > 1 - kputchar('<'); - kputchar(8); +#if DEBUG >= 2 + dprintf(2, "<\x08"); #endif #ifdef APIBUS @@ -89,9 +88,8 @@ int wd_read(uchar minor, uchar rawflag) chkstat (scsiop(), 1); -#if DEBUG > 1 - kputchar(' '); - kputchar(8); +#if DEBUG >= 2 + dprintf(2, " \x08"); #endif return 0; /* success.. formerly count of bytes read */ @@ -103,9 +101,8 @@ int wd_write(uchar minor, uchar rawflag) int setup(); /* kputchar(minor + '0'); */ -#if DEBUG > 1 - kputchar('>'); - kputchar(8); +#if DEBUG >= 2 + dprintf(2, ">\x08"); #endif #ifdef APIBUS @@ -118,9 +115,8 @@ int wd_write(uchar minor, uchar rawflag) chkstat (scsiop(), 0); -#if DEBUG > 1 - kputchar(' '); - kputchar(8); +#if DEBUG >= 2 + dprintf(2, " \x08"); #endif return 0; /* success.. formerly count of bytes written */ diff --git a/src/kernel/uzi/devio.c b/src/kernel/uzi/devio.c index 703bf291..3c25b575 100644 --- a/src/kernel/uzi/devio.c +++ b/src/kernel/uzi/devio.c @@ -82,7 +82,7 @@ bufptr freebuf(uchar waitfor); uint bufclock = 0; /* Time-stamp counter for LRU */ -#if DEBUG > 0 +#if DEBUG uint buf_hits; /* buffer pool hits */ uint buf_miss; /* buffer pool misses */ uint buf_flsh; /* buffer pool flushes */ @@ -93,18 +93,22 @@ void *bread(dev_t dev, blkno_t blk, uchar rewrite) { register bufptr bp = bufpool; +#if DEBUG >= 3 + dprintf(3, "bread(%u, %u, %u) starting\n", dev, blk, rewrite); +#endif + #if 1 /* Nick */ if (bp = bfind(dev, blk)) { if (bp->bf_busy) panic("want busy block %d, device %d", blk, dev); -#if DEBUG > 0 +#if DEBUG ++buf_hits; #endif -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("chit 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("chit 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif goto Done; @@ -115,7 +119,7 @@ void *bread(dev_t dev, blkno_t blk, uchar rewrite) if (bp->bf_dev == dev && bp->bf_blk == blk) { if (bp->bf_busy) /* ??? */ panic("want busy block %d at dev %d",blk,dev); -#if DEBUG > 0 +#if DEBUG ++buf_hits; #endif goto Done; @@ -123,7 +127,7 @@ void *bread(dev_t dev, blkno_t blk, uchar rewrite) ++bp; } #endif -#if DEBUG > 0 +#if DEBUG ++buf_miss; #endif /* block not found in pool - allocate free buffer for them */ @@ -137,33 +141,44 @@ void *bread(dev_t dev, blkno_t blk, uchar rewrite) if (bdread(bp) < 0) { /* device can define the error */ if (udata.u_error == 0) udata.u_error = EIO; -Err: return NULL; +Err: +#if DEBUG >= 3 + dprintf(3, "bread() returning NULL, error %u\n", udata.u_error); +#endif + return NULL; } -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("read 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("read 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif } Done: if (rewrite > 1) /* we need really zeroed block */ { bzero(bp->bf_data, BUFSIZE); -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("zero 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("zero 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif } bp->bf_busy++; /* was always zero */ bp->bf_time = ++bufclock; /* Time stamp it */ +#if DEBUG >= 3 + dprintf(3, "bread() returning %u, success\n", bp - bufpool); +#endif return (bp->bf_data); } /* free not needed now buffer */ int bfree(bufptr bp, uchar dirty) { +#if DEBUG >= 3 + dprintf(3, "bfree(%u, %u) starting\n", bp - bufpool, dirty); +#endif + bp->bf_dirty |= dirty; bp->bf_busy = 0; if (bp->bf_dirty && bp->bf_dev == NULLDEV) @@ -174,29 +189,35 @@ int bfree(bufptr bp, uchar dirty) #else if (bp->bf_dirty >= 2 && !dirty_mask) { /* Extra dirty */ #endif -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("wri2 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("wri2 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif if (bdwrite(bp) < 0) { udata.u_error = EIO; +#if DEBUG >= 3 + dprintf(3, "bfree() returning -1, error %u\n", udata.u_error); +#endif return (-1); } bp->bf_prio = bp->bf_dirty = 0; } -#if DEBUG > 10 +#if DEBUG >= 5 else { if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("free 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("free 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } } #endif if (!bp->bf_prio) wakeup(bufpool); +#if DEBUG >= 3 + dprintf(3, "bfree() returning 0, success\n"); +#endif return 0; } @@ -207,7 +228,13 @@ int bfree(bufptr bp, uchar dirty) void *zerobuf(uchar waitfor) { static int blk = 0; - register bufptr bp = freebuf(waitfor); + register bufptr bp; /* = freebuf(waitfor); Nick see below */ + +#if DEBUG >= 3 + dprintf(3, "zerobuf(%u) starting\n", waitfor); +#endif + + bp = freebuf(waitfor); /* Nick see above */ if (bp) { bp->bf_dev = NULLDEV; @@ -215,8 +242,14 @@ void *zerobuf(uchar waitfor) bp->bf_busy = 1; bp->bf_time = ++bufclock; bzero(bp->bf_data, BUFSIZE); +#if DEBUG >= 3 + dprintf(3, "zerobuf() returning %d, found\n", bp - bufpool); +#endif return bp->bf_data; } +#if DEBUG >= 3 + dprintf(3, "zerobuf() returning NULL, not found\n", bp - bufpool); +#endif return NULL; } @@ -225,6 +258,10 @@ void bufsync(void) { register bufptr bp = bufpool; +#if DEBUG >= 3 + dprintf(3, "bufsync() starting\n"); +#endif + #if 0 /* dirty_mask logic is now handled by i_sync() and wr_inode() */ dirty_mask = 0; @@ -233,10 +270,10 @@ void bufsync(void) if (bp->bf_dev != NULLDEV && bp->bf_dirty && !bp->bf_prio) { -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("sync 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("sync 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif if (!bdwrite(bp)) @@ -244,6 +281,9 @@ void bufsync(void) } ++bp; } +#if DEBUG >= 3 + dprintf(3, "bufsync() returning\n"); +#endif } #if 1 /* Nick */ @@ -251,22 +291,22 @@ bufptr bfind(int dev, blkno_t blk) { register bufptr bp; -#if DEBUG > 1 - kprintf("bfind(%u, %u) starting\n", dev, blk); +#if DEBUG >= 3 + dprintf(3, "bfind(%u, %u) starting\n", dev, blk); #endif for (bp=bufpool; bp < bufpool+NBUFS; ++bp) { if (bp->bf_dev == dev && bp->bf_blk == blk) { -#if DEBUG > 1 - kprintf("bfind() returning %d, found\n", bp - bufpool); +#if DEBUG >= 3 + dprintf(3, "bfind() returning %d, found\n", bp - bufpool); #endif return (bp); } } -#if DEBUG > 1 - kprintf("bfind() returning NULL, not found\n"); +#if DEBUG >= 3 + dprintf(3, "bfind() returning NULL, not found\n"); #endif return (NULL); } @@ -283,6 +323,10 @@ bufptr freebuf(uchar waitfor) register bufptr oldest = NULL; register uint oldtime = 0; +#if DEBUG >= 3 + dprintf(3, "freebuf(%u) starting\n", waitfor); +#endif + /* Try to find a non-busy buffer and * write out the data if it is dirty */ @@ -316,13 +360,13 @@ bufptr freebuf(uchar waitfor) if (oldest->bf_dev == NULLDEV) panic("attempt to write-back zerobuf"); #endif -#if DEBUG > 0 +#if DEBUG ++buf_flsh; #endif -#if DEBUG > 10 +#if DEBUG >= 5 if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("wri1 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("wri1 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } #endif if (bdwrite(oldest) < 0) { @@ -331,19 +375,22 @@ Err: return NULL; } oldest->bf_dirty = 0; } -#if DEBUG > 10 +#if DEBUG >= 5 else { if (bp->bf_dev == 0 && bp->bf_blk == 222) { - kprintf("toss 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + dprintf(5, ("toss 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); } } +#endif +#if DEBUG >= 3 + dprintf(3, "freebuf() returning %d, found\n", oldest - bufpool); #endif return oldest; } -#if DEBUG > 0 +#if DEBUG /* dump buffers info for debug */ void bufdump(void) { diff --git a/src/kernel/uzi/devtty.c b/src/kernel/uzi/devtty.c index 0513ec19..17d55f15 100644 --- a/src/kernel/uzi/devtty.c +++ b/src/kernel/uzi/devtty.c @@ -86,8 +86,8 @@ int tty_read(uchar minor, uchar rawflag) char c; int remq(); -#if DEBUG > 1 - kprintf("tty_read(%d, %d) starting\n", minor, rawflag); +#if DEBUG >= 2 + dprintf(2, "tty_read(%d, %d) starting\n", minor, rawflag); #endif /* Minor == 0 means that it is the controlling tty of the process */ @@ -98,8 +98,8 @@ int tty_read(uchar minor, uchar rawflag) if ((minor < 1) || (minor > NTTYS+1)) { udata.u_error = ENODEV; -#if DEBUG > 1 - kprintf("tty_read() returning -1, error %d\n", udata.u_error); +#if DEBUG >= 2 + dprintf(2, "tty_read() returning -1, error %d\n", udata.u_error); #endif return (-1); } @@ -127,8 +127,8 @@ int tty_read(uchar minor, uchar rawflag) /* In unbuffered mode, don't wait when no input */ if (tty_data[minor].t_flags & UNBUFF) { -#if DEBUG > 1 - kprintf("tty_read() returning %d, success\n", nread); +#if DEBUG >= 2 + dprintf(2, "tty_read() returning %d, success\n", nread); #endif return(nread); } @@ -137,8 +137,8 @@ int tty_read(uchar minor, uchar rawflag) psleep (&ttyinq[minor]); if (udata.u_cursig || udata.u_ptab->p_pending) { /* messy */ udata.u_error = EINTR; -#if DEBUG > 1 - kprintf("tty_read() returning -1, error %d\n", udata.u_error); +#if DEBUG >= 2 + dprintf(2, "tty_read() returning -1, error %d\n", udata.u_error); #endif return (-1); } @@ -149,8 +149,8 @@ int tty_read(uchar minor, uchar rawflag) #endif if ((nread++ == 0) && (c == tty_data[minor].t_eof)) /* ^D */ { -#if DEBUG > 1 - kprintf("tty_read() returning 0, eof\n"); +#if DEBUG >= 2 + dprintf(2, "tty_read() returning 0, eof\n"); #endif return(0); } @@ -170,8 +170,8 @@ int tty_read(uchar minor, uchar rawflag) #endif ++udata.u_base; } -#if DEBUG > 1 - kprintf("tty_read() returning %d, success\n", nread); +#if DEBUG >= 2 + dprintf(2, "tty_read() returning %d, success\n", nread); #endif return(nread); } @@ -369,7 +369,7 @@ void tty_inproc(int minor, char c) { if ((mode & RAW) == 0) /* if mode == COOKED or CBREAK */ { -#ifdef DEBUG +#if DEBUG if (c == 0x1a) /* ^Z */ { idump(); /* (For debugging) */ diff --git a/src/kernel/uzi/extern.h b/src/kernel/uzi/extern.h index 649c4de3..3fbfbc94 100644 --- a/src/kernel/uzi/extern.h +++ b/src/kernel/uzi/extern.h @@ -84,7 +84,7 @@ extern blkno_t swapblk; extern uint16 waitno; /* Serial number of processes entering wait state */ #ifdef DEBUG -extern char traceon; /* Nick flag to enable/disable tracing via keyboard */ +extern char traceon; /* Nick to enable/disable tracing via keyboard */ #endif #if 1 /* Nick UZIX compatible */ @@ -125,6 +125,7 @@ extern char traceon; /* Nick flag to enable/disable tracing via keyboard */ #ifdef UTIL /* Nick */ #define kprintf printf +#define dprintf /* parameters will be evaluated, to no effect */ #define kputchar putchar #define _putc putchar #define uput(sptr, uptr, nbytes) (bcopy((sptr), (uptr), (nbytes))) diff --git a/src/kernel/uzi/filesys.c b/src/kernel/uzi/filesys.c index 1beaec05..efd385a2 100644 --- a/src/kernel/uzi/filesys.c +++ b/src/kernel/uzi/filesys.c @@ -105,8 +105,8 @@ int wr_inode(inoptr ino) { dinode_t *buf; -#if DEBUG > 1 - kprintf("wr_inode(%u) starting\n", ino - i_tab); +#if DEBUG >= 3 + dprintf(3, "wr_inode(%u) starting\n", ino - i_tab); #endif magic(ino, "wr_inode"); @@ -116,8 +116,8 @@ int wr_inode(inoptr ino) ino->c_num), 0)) == NULL) { Err: -#if DEBUG > 1 - kprintf("wr_inode() returning -1, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "wr_inode() returning -1, error %u\n", udata.u_error); #endif return -1; } @@ -132,8 +132,8 @@ Err: goto Err; } ino->c_dirty = 0; /* unmark modif flag */ -#if DEBUG > 1 - kprintf("wr_inode() returning 0, success\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "wr_inode() returning 0, success\n", udata.u_error); #endif return 0; } @@ -142,15 +142,15 @@ Err: */ void i_ref(inoptr ino) { -#if DEBUG > 1 - kprintf("i_ref(%u) starting\n", ino - i_tab); +#if DEBUG >= 4 + dprintf(4, "i_ref(%u) starting\n", ino - i_tab); #endif magic(ino, "i_ref"); if (++ino->c_refs >= 12 * ITABSIZE) /* Arbitrary limit */ panic(refstoinode, "too many", ino - i_tab); -#if DEBUG > 1 - kprintf("i_ref() returning, refs %u\n", ino->c_refs); +#if DEBUG >= 4 + dprintf(4, "i_ref() returning, refs %u\n", ino->c_refs); #endif } @@ -160,8 +160,8 @@ void i_ref(inoptr ino) */ void i_deref(inoptr ino) { -#if DEBUG > 1 - kprintf("i_deref(%u) starting\n", ino - i_tab); +#if DEBUG >= 4 + dprintf(4, "i_deref(%u) starting\n", ino - i_tab); #endif magic(ino, "i_deref"); @@ -184,8 +184,8 @@ void i_deref(inoptr ino) if (ino->c_dirty) wr_inode(ino); } -#if DEBUG > 1 - kprintf("i_deref() returning, refs %u\n", ino->c_refs); +#if DEBUG >= 4 + dprintf(4, "i_deref() returning, refs %u\n", ino->c_refs); #endif } @@ -197,8 +197,8 @@ void i_free(dev_t devno, ino_t ino) { register fsptr dev = getfs(devno); -#if DEBUG > 1 - kprintf("i_free(%u, %u) starting\n", devno, ino); +#if DEBUG >= 4 + dprintf(4, "i_free(%u, %u) starting\n", devno, ino); #endif if (ino <= ROOTINODE || ino >= devinodes(dev)) @@ -211,16 +211,16 @@ void i_free(dev_t devno, ino_t ino) if (bitmap_set(devno, ino, 0, dev->s_bitmap_inode, dev->s_bitmap_block) != 1) { -#if DEBUG > 1 - kprintf("i_free() returning, error\n"); +#if DEBUG >= 4 + dprintf(4, "i_free() returning, error\n"); #endif return; /* always an i/o error (or very bad !!) */ } ++dev->s_tinode; #if 0 /* remove support for the original UZI filesystem */ -#if DEBUG > 1 - kprintf("i_free() returning, success\n"); +#if DEBUG >= 4 + dprintf(4, "i_free() returning, success\n"); #endif return; /* crude way to skip inode list processing */ } @@ -232,8 +232,8 @@ void i_free(dev_t devno, ino_t ino) if (dev->s_ninode < FSFREEINODES) dev->s_inode[dev->s_ninode++] = ino; #endif -#if DEBUG > 1 - kprintf("i_free() returning, success\n"); +#if DEBUG >= 4 + dprintf(4, "i_free() returning, success\n"); #endif } @@ -540,10 +540,13 @@ inoptr i_open(dev_t devno, ino_t ino) dinode_t *buf; inoptr ip, nindex; uchar i, newn, mode0; +#if 1 /* Nick free bitmap */ + uchar refs0; +#endif static inoptr nexti = i_tab; /* rover ptr */ -#if DEBUG > 1 - kprintf("i_open(%u, %u) starting\n", devno, ino); +#if DEBUG >= 3 + dprintf(3, "i_open(%u, %u) starting\n", devno, ino); #endif if ((dev = findfs(devno)) == NULL) @@ -554,9 +557,9 @@ inoptr i_open(dev_t devno, ino_t ino) goto Err; /* errno is already set by i_alloc */ ++newn; } -/* kprintf("ino = %u\n", ino); */ -/* kprintf("dev -> %u\n", dev - fs_tab); */ -/* kprintf("devinodes(dev) = %u\n", devinodes(dev)); */ +/* dprintf(2, "ino = %u\n", ino); */ +/* dprintf(2, "dev -> %u\n", dev - fs_tab); */ +/* dprintf(2, "devinodes(dev) = %u\n", devinodes(dev)); */ if (ino < ROOTINODE || ino >= devinodes(dev)) { warning(badinomsg, "i_open", ino); goto Err; @@ -565,28 +568,28 @@ inoptr i_open(dev_t devno, ino_t ino) nindex = NULL; i = 0; ip = nexti; -/* kprintf("{ "); */ +/* dprintf(2, "{ "); */ while (i != ITABSIZE) { nexti = ip; if (++ip >= i_tab + ITABSIZE) ip = i_tab; -/* kprintf("%u ", ip - i_tab); */ +/* dprintf(2, "%u ", ip - i_tab); */ if (ip->c_refs == 0) nindex = ip; /* candidate for discarding */ if (ip->c_dev == devno && ip->c_num == ino) { nindex = ip; -/* kprintf("} "); */ +/* dprintf(2, "} "); */ goto found; /* really found */ } ++i; } -/* kprintf("} "); */ +/* dprintf(2, "} "); */ /* Not already in table - take last candidate */ if (nindex == NULL) { /* No unrefed slots in inode table */ udata.u_error = ENFILE; goto Err; } -/* kprintf("reading(%u, %u) ", inodeblock(dev, ino), inodeoffset(ino)); */ +/* dprintf(2, "reading(%u, %u) ", inodeblock(dev, ino), inodeoffset(ino)); */ /* discard oldest? inode from table and read the inode from disk */ buf = (dinode_t *)bread(devno, inodeblock(dev, ino), 0); if (buf == NULL) goto Err; @@ -598,25 +601,37 @@ inoptr i_open(dev_t devno, ino_t ino) nindex->c_num = ino; nindex->c_ro = dev->s_ronly; found: -/* kprintf("found(%u, 0%o) ", nindex->c_node.i_nlink, nindex->c_node.i_mode); */ +/* dprintf(2, "found(%u, 0%o) ", nindex->c_node.i_nlink, nindex->c_node.i_mode); */ mode0 = (getmode(nindex) == 0); +#if 1 /* Nick free bitmap */ + /* need to check for the special case of working on an erased file */ + refs0 = (nindex->c_refs == 0) && (nindex->c_node.i_nlink == 0); +#endif if (newn) { /* RO fs can't do i_alloc()! */ /* newly allocated disk inode must be clean */ +#if 1 /* Nick free bitmap */ + if (!refs0 || !mode0) +#else if (nindex->c_node.i_nlink || !mode0) +#endif goto badino; } /* and vice versa */ +#if 1 /* Nick free bitmap */ + else if (refs0 || mode0) +#else else if (nindex->c_node.i_nlink == 0 || mode0) +#endif goto badino; i_ref(nindex); /* yet one ref */ -#if DEBUG > 1 - kprintf("i_open() returning %u, success\n", nindex - i_tab); +#if DEBUG >= 3 + dprintf(3, "i_open() returning %u, success\n", nindex - i_tab); #endif return nindex; badino: warning(badinomsg, "i_open (disk)", ino); /* nindex - i_tab); */ Err: -#if DEBUG > 1 - kprintf("i_open() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "i_open() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -637,8 +652,8 @@ int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) direct_t curentry; int i; -#if DEBUG > 1 - kprintf("ch_link(%u, \"%s\", \"%s\", %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "ch_link(%u, \"%s\", \"%s\", %u) starting\n", wd - i_tab, oldname, newname, nindex - i_tab); #endif @@ -693,8 +708,8 @@ int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) if (udata.u_error) { Err: -#if DEBUG > 1 - kprintf("ch_link() returning 0, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "ch_link() returning 0, error %u\n", udata.u_error); #endif return 0; } @@ -704,8 +719,8 @@ Err: wd->c_node.i_size += BUFSIZE; } setftim(wd, A_TIME | M_TIME | C_TIME); /* And sets c_dirty */ -#if DEBUG > 1 - kprintf("ch_link() returning 1, success\n"); +#if DEBUG >= 3 + dprintf(3, "ch_link() returning 1, success\n"); #endif return 1; } @@ -763,8 +778,8 @@ int namecomp(uchar *n1, uchar *n2) { uchar n = DIRNAMELEN; -#if DEBUG > 2 - kprintf("namecomp(\"%s\", \"%s\") starting\n", n1, n2); +#if DEBUG >= 5 + dprintf(5, "namecomp(\"%s\", \"%s\") starting\n", n1, n2); #endif while (*n1 && *n1 != '/') { @@ -772,22 +787,22 @@ int namecomp(uchar *n1, uchar *n2) goto NotEq; if (--n == 0) { -#if DEBUG > 2 - kprintf("namecomp() returning -1, error\n"); +#if DEBUG >= 5 + dprintf(5, "namecomp() returning -1, error\n"); #endif return (-1); /* first name too long - ignore this */ } } if (*n2 == '\0' || *n2 == '/') { -#if DEBUG > 2 - kprintf("namecomp() returning -1, match\n"); +#if DEBUG >= 5 + dprintf(5, "namecomp() returning -1, match\n"); #endif return 1; /* names matched */ } NotEq: -#if DEBUG > 2 - kprintf("namecomp() returning 0, no match\n"); +#if DEBUG >= 5 + dprintf(5, "namecomp() returning 0, no match\n"); #endif return 0; } @@ -806,21 +821,21 @@ inoptr newfile(inoptr pino, char *name) { register inoptr nindex; -#if DEBUG > 1 - kprintf("newfile(%u, \"%s\") starting\n", pino - i_tab, name); +#if DEBUG >= 3 + dprintf(3, "newfile(%u, \"%s\") starting\n", pino - i_tab, name); #endif if ((getperm(pino) & S_IOWRITE) == 0) { udata.u_error = EPERM; -#if DEBUG > 1 - kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "newfile() returning NULL, error %u\n", udata.u_error); #endif return 0; } if ((nindex = i_open(pino->c_dev, NULLINO)) == NULL) { -#if DEBUG > 1 - kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "newfile() returning NULL, error %u\n", udata.u_error); #endif goto Ret; /* can't create new inode */ } @@ -839,14 +854,14 @@ inoptr newfile(inoptr pino, char *name) #endif i_deref(nindex); /* can't enter new file to directory */ nindex = NULL; -#if DEBUG > 1 - kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "newfile() returning NULL, error %u\n", udata.u_error); #endif } -#if DEBUG > 1 +#if DEBUG >= 3 else { - kprintf("newfile() returning %u, success\n", nindex - i_tab); + dprintf(3, "newfile() returning %u, success\n", nindex - i_tab); } #endif Ret: i_deref(pino); @@ -859,14 +874,14 @@ int doclose(uchar fd) register inoptr ino = getinode(fd); uchar oftindex; -#if DEBUG > 1 - kprintf("doclose(%u) starting\n", (unsigned int)fd); +#if DEBUG >= 3 + dprintf(3, "doclose(%u) starting\n", (unsigned int)fd); #endif if (ino == NULL) { -#if DEBUG > 1 - kprintf("doclose() returning -1, error\n"); +#if DEBUG >= 3 + dprintf(3, "doclose() returning -1, error\n"); #endif return (-1); } @@ -877,8 +892,8 @@ int doclose(uchar fd) d_close(DEVNUM(ino)); udata.u_files[fd] = -1; oft_deref(oftindex); -#if DEBUG > 1 - kprintf("doclose() returning 0, success\n"); +#if DEBUG >= 3 + dprintf(3, "doclose() returning 0, success\n"); #endif return 0; } @@ -894,8 +909,8 @@ ino_t i_alloc(dev_t devno) dinode_t *buf, *bp; fsptr dev = getfs(devno); -#if DEBUG > 1 - kprintf("i_alloc(%u) starting\n", devno); +#if DEBUG >= 4 + dprintf(4, "i_alloc(%u) starting\n", devno); #endif if (dev->s_ronly) { @@ -937,8 +952,8 @@ found_inode: if (ino <= ROOTINODE || ino >= devinodes(dev)) goto Corrupt; --dev->s_tinode; -#if DEBUG > 1 - kprintf("i_alloc() returning %u, success\n", ino); +#if DEBUG >= 4 + dprintf(4, "i_alloc() returning %u, success\n", ino); #endif return ino; #if 0 /* remove support for the original UZI filesystem */ @@ -949,7 +964,7 @@ found_inode: sys_sync(); /* Make on-disk inodes consistent */ k = 0; blk = 0; -/* kprintf("[ "); */ +/* dprintf(2, "[ "); */ while (blk != dev->s_isize) { if ((bp = buf = (dinode_t *)bread(devno, blk+dev->s_reserv, 0)) == NULL) goto Err; @@ -957,7 +972,7 @@ found_inode: while (j != DINODESPERBLOCK) { if (bp->i_mode == 0 && bp->i_nlink == 0) /* { */ -/* kprintf("%d ", blockinodes(blk) + j); */ +/* dprintf(2, "%d ", blockinodes(blk) + j); */ dev->s_inode[k++] = blockinodes(blk) + j; /* } */ if (k == FSFREEINODES) { @@ -973,7 +988,7 @@ found_inode: break; } Done: -/* kprintf("] "); */ +/* dprintf(2, "] "); */ if (k == 0) { /* no free inodes on disk */ if (dev->s_tinode) goto Corrupt; @@ -987,8 +1002,8 @@ Corrupt:warning(badfsmsg, "i_alloc", devno); dev->s_mounted = ~SMOUNTED; /* mark device as bad */ Err: udata.u_error = ENOSPC; Err1: -#if DEBUG > 1 - kprintf("i_alloc() returning NULLINO, error %u\n", udata.u_error); +#if DEBUG >= 4 + dprintf(4, "i_alloc() returning NULLINO, error %u\n", udata.u_error); #endif return NULLINO; } @@ -1011,8 +1026,8 @@ blkno_t blk_alloc(dev_t devno, uchar dirty) /* Nick dirty */ register fsptr dev = getfs(devno); /* int i; */ -#if DEBUG > 1 - kprintf("blk_alloc(%u, %u) starting\n", devno, (unsigned)dirty); +#if DEBUG >= 4 + dprintf(4, "blk_alloc(%u, %u) starting\n", devno, (unsigned)dirty); #endif if (dev->s_ronly) { @@ -1043,17 +1058,17 @@ blkno_t blk_alloc(dev_t devno, uchar dirty) /* Nick dirty */ goto Corrupt; #else nf = dev->s_nfree; -/* kprintf("nf = %u\n", nf); */ +/* dprintf(2, "nf = %u\n", nf); */ if (nf <= 0 || nf > FSFREEBLOCKS) /* { */ -/* kprintf("nf out of range\n"); */ +/* dprintf(2, "nf out of range\n"); */ goto Corrupt; /* } */ #endif if (0 == (newno = dev->s_free[--dev->s_nfree])) { if (dev->s_tfree != 0) /* { */ -/* kprintf("dev->s_tfree != 0\n"); */ +/* dprintf(2, "dev->s_tfree != 0\n"); */ goto Corrupt; /* } */ ++dev->s_nfree; @@ -1063,15 +1078,15 @@ blkno_t blk_alloc(dev_t devno, uchar dirty) /* Nick dirty */ if (dev->s_nfree == 0) { if ((buf = bread(devno, newno, 0)) == NULL) goto Err; -/* kprintf("buf[0] = %u\n", ((blkno_t *)buf)[0]); */ +/* dprintf(2, "buf[0] = %u\n", ((blkno_t *)buf)[0]); */ dev->s_nfree = ((blkno_t *)buf)[0]; bcopy(((blkno_t *)buf)+1,dev->s_free,sizeof(dev->s_free)); -/* kprintf("< "); */ +/* dprintf(2, "< "); */ /* for (i = 0; i < dev->s_nfree; i++) */ /* { */ -/* kprintf("%u ", dev->s_free[i]); */ +/* dprintf(2, "%u ", dev->s_free[i]); */ /* } */ -/* kprintf("> "); */ +/* dprintf(2, "> "); */ if (brelse((bufptr)buf) < 0) goto Err; } @@ -1082,7 +1097,7 @@ found_block: validblk(devno, newno); if (dev->s_tfree == 0) /* { */ -/* kprintf("dev->s_tfree == 0\n"); */ +/* dprintf(2, "dev->s_tfree == 0\n"); */ goto Corrupt; /* } */ --dev->s_tfree; @@ -1095,8 +1110,8 @@ found_block: if (bawrite((bufptr)buf) < 0) /* write back */ #endif goto Err; -#if DEBUG > 1 - kprintf("blk_alloc() returning %u, success\n", newno); +#if DEBUG >= 4 + dprintf(4, "blk_alloc() returning %u, success\n", newno); #endif return newno; @@ -1104,8 +1119,8 @@ Corrupt:warning(badfsmsg, "blk_alloc", devno); dev->s_mounted = ~SMOUNTED; Err: udata.u_error = ENOSPC; Err1: -#if DEBUG > 1 - kprintf("blk_alloc() returning 0, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "blk_alloc() returning 0, error %u\n", udata.u_error); #endif return 0; } @@ -1123,15 +1138,15 @@ void blk_free(dev_t devno, blkno_t blk) #endif register fsptr dev = getfs(devno); -#if DEBUG > 1 - kprintf("blk_free(%u, %u) starting\n", devno, blk); +#if DEBUG >= 4 + dprintf(4, "blk_free(%u, %u) starting\n", devno, blk); #endif if (dev->s_ronly || blk == 0) { End: -#if DEBUG > 1 - kprintf("blk_free() returning, error\n"); +#if DEBUG >= 4 + dprintf(4, "blk_free() returning, error\n"); #endif return; } @@ -1157,8 +1172,8 @@ End: ++dev->s_tfree; #if 0 /* remove support for the original UZI filesystem */ -#if DEBUG > 1 - kprintf("blk_free() returning, success\n"); +#if DEBUG >= 4 + dprintf(4, "blk_free() returning, success\n"); #endif return; /* crude way to skip free list processing */ } @@ -1179,8 +1194,8 @@ End: ++dev->s_tfree; dev->s_free[dev->s_nfree++] = blk; #endif -#if DEBUG > 1 - kprintf("blk_free() returning, success\n"); +#if DEBUG >= 4 + dprintf(4, "blk_free() returning, success\n"); #endif } @@ -1191,16 +1206,16 @@ uchar oft_alloc(void) register ofptr op = of_tab; uchar j = 0; -#if DEBUG > 1 - kprintf("oft_alloc() starting\n"); +#if DEBUG >= 4 + dprintf(4, "oft_alloc() starting\n"); #endif while (j != OFTSIZE) { if (op->o_refs == 0) { bzero(op, sizeof(oft_t)); /* zero out all fields */ op->o_refs++; -#if DEBUG > 1 - kprintf("oft_alloc() returning %u, success\n", (unsigned int)j); +#if DEBUG >= 4 + dprintf(4, "oft_alloc() returning %u, success\n", (unsigned int)j); #endif return j; } @@ -1208,8 +1223,8 @@ uchar oft_alloc(void) ++j; } udata.u_error = ENFILE; -#if DEBUG > 1 - kprintf("oft_alloc() returning -1, error %u\n", udata.u_error); +#if DEBUG >= 4 + dprintf(4, "oft_alloc() returning -1, error %u\n", udata.u_error); #endif return (-1); } @@ -1221,16 +1236,16 @@ void oft_deref(uchar of) { register ofptr op = of_tab + of; -#if DEBUG > 1 - kprintf("oft_deref(%u) starting\n", (unsigned int)of); +#if DEBUG >= 4 + dprintf(4, "oft_deref(%u) starting\n", (unsigned int)of); #endif if (--op->o_refs == 0 && op->o_inode != NULL) { i_deref(op->o_inode); op->o_inode = NULL; } -#if DEBUG > 1 - kprintf("oft_deref() returning, refs %u\n", op->o_refs); +#if DEBUG >= 4 + dprintf(4, "oft_deref() returning, refs %u\n", op->o_refs); #endif } @@ -1241,15 +1256,15 @@ uchar uf_alloc(void) register uchar j = 0; register uchar *p = udata.u_files; -#if DEBUG > 1 - kprintf("uf_alloc() starting\n"); +#if DEBUG >= 4 + dprintf(4, "uf_alloc() starting\n"); #endif while (j != UFTSIZE) { if (freefileentry(*p)) { -#if DEBUG > 1 - kprintf("uf_alloc() returning %u, success\n", (unsigned int)j); +#if DEBUG >= 4 + dprintf(4, "uf_alloc() returning %u, success\n", (unsigned int)j); #endif return j; } @@ -1257,8 +1272,8 @@ uchar uf_alloc(void) ++j; } udata.u_error = ENFILE; -#if DEBUG > 1 - kprintf("uf_alloc() returning -1, error %u\n", udata.u_error); +#if DEBUG >= 4 + dprintf(4, "uf_alloc() returning -1, error %u\n", udata.u_error); #endif return (-1); } @@ -1280,8 +1295,8 @@ uchar isdevice(inoptr ino) */ void freeblk(dev_t dev, blkno_t blk, uchar level) { -#if DEBUG > 2 - kprintf("freeblk(%u, %u, %u) starting\n", dev, blk, (unsigned int)level); +#if DEBUG >= 3 + dprintf(3, "freeblk(%u, %u, %u) starting\n", dev, blk, (unsigned int)level); #endif if (blk != 0) { @@ -1298,14 +1313,14 @@ void freeblk(dev_t dev, blkno_t blk, uchar level) } } blk_free(dev, blk); -#if DEBUG > 2 - kprintf("freeblk() returning, success\n"); +#if DEBUG >= 3 + dprintf(3, "freeblk() returning, success\n"); #endif } -#if DEBUG > 2 +#if DEBUG >= 3 else { - kprintf("freeblk() returning, error\n"); + dprintf(3, "freeblk() returning, error\n"); } #endif } @@ -1320,8 +1335,8 @@ void f_trunc(inoptr ino) blkno_t *blk = ip->i_addr; register uchar j; -#if DEBUG > 1 - kprintf("f_trunc(%u) starting\n", ino - i_tab); +#if DEBUG >= 3 + dprintf(3, "f_trunc(%u) starting\n", ino - i_tab); #endif /* First deallocate the double indirect blocks */ @@ -1337,8 +1352,8 @@ void f_trunc(inoptr ino) bzero(ip->i_addr, sizeof(blkno_t)*TOTALREFBLOCKS); ino->c_dirty = 1; ip->i_size = 0; -#if DEBUG > 1 - kprintf("f_trunc() returning\n"); +#if DEBUG >= 3 + dprintf(3, "f_trunc() returning\n"); #endif } @@ -1354,15 +1369,15 @@ blkno_t bmap(inoptr ip, blkno_t bn, uchar rdflg) register uint i, j, sh; register blkno_t *bp, nb; -#if DEBUG > 1 - kprintf("bmap(%u, %u, %u) starting\n", ip - i_tab, bn, (unsigned int)rdflg); -/* kprintf("xx %u %u\n", i_tab[38].c_node.i_addr[3], udata.u_page); */ +#if DEBUG >= 3 + dprintf(3, "bmap(%u, %u, %u) starting\n", ip - i_tab, bn, (unsigned int)rdflg); +/* dprintf(2, "xx %u %u\n", i_tab[38].c_node.i_addr[3], udata.u_page); */ #endif if (isdevice(ip)) /* block devices */ { -#if DEBUG > 1 - kprintf("bmap() returning %u, direct\n", bn); +#if DEBUG >= 3 + dprintf(3, "bmap() returning %u, direct\n", bn); #endif return bn; /* map directly */ } @@ -1406,8 +1421,8 @@ blkno_t bmap(inoptr ip, blkno_t bn, uchar rdflg) if ((bp = (blkno_t *)bread(dev, nb, 0)) == NULL) { Err: -#if DEBUG > 1 - kprintf("bmap() returning NULLBLK, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "bmap() returning NULLBLK, error %u\n", udata.u_error); #endif return NULLBLK; } @@ -1435,8 +1450,8 @@ Err: ++j; } Ok: -#if DEBUG > 1 - kprintf("bmap() returning %u, success\n", nb); +#if DEBUG >= 3 + dprintf(3, "bmap() returning %u, success\n", nb); #endif return nb; } @@ -1546,11 +1561,11 @@ Ok: fp->s_mounted = ~SMOUNTED; register int i; for (i = SUPERBLOCK; i < 0x400; ++i) { - kprintf("reading sector 0x%x\n", i); + dprintf(2, "reading sector 0x%x\n", i); buf = bread(dev, i, 0); if (*(int *)buf == SMOUNTED) { - kprintf("formatted at sector 0x%x\n", i - SUPERBLOCK); + dprintf(2, "formatted at sector 0x%x\n", i - SUPERBLOCK); panic("stop"); } brelse((bufptr)buf); diff --git a/src/kernel/uzi/hdconf.h b/src/kernel/uzi/hdconf.h index be331703..fae005f3 100644 --- a/src/kernel/uzi/hdconf.h +++ b/src/kernel/uzi/hdconf.h @@ -54,7 +54,7 @@ #define HD0_Start 0 /* sentinel value indicating the ramdrive */ #define HD0_Size 0x600 /* define a harddrive of size 768 kbytes */ -#define HD1_Start 0x39 /*0x239 /*0x259 /*0x2bb /* just after HYTDISK.DAT finishes */ +#define HD1_Start 0x59 /*0x239 /*0x259 /*0x2bb /* just after HYTDISK.DAT finishes */ #define HD1_Size 0x2000 /* define a harddrive of size 4 Mbytes */ #else #define HD0_Start 3000 /* 1st Drive Start. CP/M uses first 3000 "tracks" */ diff --git a/src/kernel/uzi/machdep.c b/src/kernel/uzi/machdep.c index 1a327888..a66309c4 100644 --- a/src/kernel/uzi/machdep.c +++ b/src/kernel/uzi/machdep.c @@ -176,7 +176,7 @@ void kputs(s) #endif #endif -#if DEBUG > 0 +#if DEBUG >= 1 /* _idump() dumps state of all inodes */ static void _idump(void) diff --git a/src/kernel/uzi/main.c b/src/kernel/uzi/main.c index eb3c2860..229c500f 100644 --- a/src/kernel/uzi/main.c +++ b/src/kernel/uzi/main.c @@ -1,6 +1,6 @@ /* main.c for uzi180 by Nick - initialises CMX and then starts UZI as a task */ -#define POLLED /* causes console I/O to be output via abyte() */ +/* #define POLLED */ /* causes console I/O to be output via abyte() */ #include "vendor.h" /* Nick, must come first */ #include @@ -429,12 +429,12 @@ int scsiop(void) return 0; #endif -#if DEBUG > 1 - kprintf("scsiop: %c %u+%u,%u -> 0x%x\n", cmdblk[1], - (unsigned int)hd_sector, - (unsigned int)hd_offset, - (unsigned int)cmdblk[7], - (unsigned int)dptr); +#if DEBUG >= 2 + dprintf(2, "scsiop: %c %u+%u,%u -> 0x%x\n", cmdblk[1], + (unsigned int)hd_sector, + (unsigned int)hd_offset, + (unsigned int)cmdblk[7], + (unsigned int)dptr); #endif /* check for special hd_offset indicating the ramdrive is wanted */ @@ -447,11 +447,11 @@ int scsiop(void) switch(cmdblk[1]) { case 'R': -/* kprintf("R %08lx -> %08lx, %04x\n", hd_sector, hd_offset, j); */ +/* dprintf(2, "R %08lx -> %08lx, %04x\n", hd_sector, hd_offset, j); */ copyr(hd_sector, hd_offset, j); break; case 'W': -/* kprintf("W %08lx -> %08lx, %04x\n", hd_offset, hd_sector, j); */ +/* dprintf(2, "W %08lx -> %08lx, %04x\n", hd_offset, hd_sector, j); */ copyr(hd_offset, hd_sector, j); break; } diff --git a/src/kernel/uzi/process.c b/src/kernel/uzi/process.c index 5ed822ff..98c7887c 100644 --- a/src/kernel/uzi/process.c +++ b/src/kernel/uzi/process.c @@ -72,7 +72,7 @@ init2() /* User's file table */ for (j=udata.u_files; j < (udata.u_files+UFTSIZE); ++j) - *j = -1; + *j = -1; /* please see freefileentry() macro in unix.h */ /* abyte('c'); */ ei_absolute(); /* Nick */ @@ -277,6 +277,9 @@ ptptr p; { register char *j; +/* abyte('['); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + /* Note that ptab_alloc clears most of the entry */ di_absolute(); /* Nick */ /* p_swap is replaced by p_page for UZI180 Banked memory access. It is @@ -317,10 +320,22 @@ ptptr p; p->p_priority = MAXTICKS; #endif +/* abyte('\\'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ +/* di_absolute(); */ + for (j=udata.u_files; j < (udata.u_files+UFTSIZE); ++j) +#if 1 /* Nick, to sidestep signed vs unsigned char issues */ + if (freefileentry(*j) == 0) +#else if (*j >= 0) +#endif ++of_tab[*j].o_refs; ei_absolute(); /* Nick */ + +/* abyte(']'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + } @@ -335,6 +350,9 @@ ptab_alloc() register ptptr pp; static int nextpid = 0; +/* abyte('('); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + di_absolute(); /* Nick */ for (p=ptab; p < ptab+PTABSIZE; ++p) { @@ -342,6 +360,14 @@ ptab_alloc() goto found; } ei_absolute(); /* Nick */ + +#if DEBUG >= 2 /* Nick */ + dprintf(2, "process table full\n"); +#endif + +/* abyte('*'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + return (NULL); found: @@ -364,6 +390,14 @@ nogood: p->p_status = P_FORKING; ei_absolute(); /* Nick */ + +#if DEBUG >= 2 /* Nick */ + dprintf(2, "process %d starting\n", p->p_pid); +#endif + +/* abyte(')'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + return (p); } @@ -457,7 +491,7 @@ unix2() ei_absolute(); /* Nick */ /* abyte('1'); */ -#if DEBUG > 0 && !defined(UTIL) +#if DEBUG && !defined(UTIL) if (traceon) { #if 1 @@ -476,7 +510,7 @@ unix2() udata.u_retval = (*disp_tab[udata.u_callno])(); /* abyte('3'); */ -#if DEBUG > 0 && !defined(UTIL) +#if DEBUG && !defined(UTIL) if (traceon) { #if 1 @@ -535,8 +569,8 @@ chksigs() if (udata.u_sigvec[j] == SIG_DFL) { ei_absolute(); /* Nick */ -#ifdef DEBUG - kprintf("process terminated by signal %d: ", j); /* Nick %d */ +#if DEBUG >= 2 + dprintf(2, "process terminated by signal %d: ", j); /* Nick %d */ #endif doexit (0, j); } diff --git a/src/kernel/uzi/scall1.c b/src/kernel/uzi/scall1.c index c6414fed..467b352a 100644 --- a/src/kernel/uzi/scall1.c +++ b/src/kernel/uzi/scall1.c @@ -949,12 +949,12 @@ inoptr n_creat(char *name, bool_t new, mode_t mode) #if 1 char fname[15]; #endif -#if DEBUG > 1 +#if DEBUG >= 3 char *buf; buf = tmpbuf(); ugets(name, buf, 512); - kprintf("n_creat(\"%s\", %d, 0%o)\n", buf, new, mode); + dprintf(3, "n_creat(\"%s\", %d, 0%o)\n", buf, new, mode); brelse((bufptr)buf); #endif @@ -1023,16 +1023,16 @@ inoptr n_creat(char *name, bool_t new, mode_t mode) #else goto Err; #endif -#if DEBUG > 1 - kprintf("n_creat() returning %u, success\n", ino - i_tab); +#if DEBUG >= 3 + dprintf(3, "n_creat() returning %u, success\n", ino - i_tab); #endif return ino; Err1: i_deref(parent); Err: if (ino) i_deref(ino); -#if DEBUG > 1 - kprintf("n_creat() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "n_creat() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -1049,14 +1049,14 @@ void readwritei(char write, inoptr ino) dev_t dev = ino->c_dev; bool_t ispipe = 0; -#if DEBUG > 1 - kprintf("readwritei(%u, %u) starting\n", (unsigned int)write, ino - i_tab); +#if DEBUG >= 3 + dprintf(3, "readwritei(%u, %u) starting\n", (unsigned int)write, ino - i_tab); #endif if (write && ino->c_ro) { UERR = EROFS; -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1065,8 +1065,8 @@ void readwritei(char write, inoptr ino) UCNT = write ? cdwrite(DEVNUM(ino)) : cdread(DEVNUM(ino)); if ((int)UCNT != -1) addoff(&UOFFS, UCNT); -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; case S_IFLNK: /* sym link */ @@ -1081,8 +1081,8 @@ void readwritei(char write, inoptr ino) /* See if offset is beyond end of file */ if ((unsigned long)UOFFS >= (unsigned long)ISIZE(ino)) { UCNT = 0; -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1102,8 +1102,8 @@ void readwritei(char write, inoptr ino) UCNT = -1; UERR = EPIPE; ssig(udata.u_ptab, SIGPIPE); -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1151,8 +1151,8 @@ loop: while (todo) { * it's not really an error. it just means EOF... */ if (UERR == EFAULT) UERR = 0; -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1172,8 +1172,8 @@ loop: while (todo) { bp = bread(dev, pblk, (amount == BUFSIZE)); if (bp == NULL) { -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1191,8 +1191,8 @@ loop: while (todo) { #endif if (bfree((bufptr)bp, 2) < 0) { -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1211,8 +1211,8 @@ loop: while (todo) { #endif if (brelse((bufptr)bp) < 0) { -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1240,16 +1240,16 @@ loop: while (todo) { ino->c_dirty = 1; } } -#if DEBUG > 1 - kprintf("readwritei() returning, success\n"); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, success\n"); #endif return; default: error: UERR = ENODEV; if (!write) UCNT = -1; -#if DEBUG > 1 - kprintf("readwritei() returning, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "readwritei() returning, error %u\n", udata.u_error); #endif return; } @@ -1261,16 +1261,16 @@ inoptr rwsetup(uchar fd, void *base, uint cnt, uchar rdflag) register inoptr ino; register ofptr oftp; -#if DEBUG > 1 - kprintf("rwsetup(%u, 0x%x, %u, %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "rwsetup(%u, 0x%x, %u, %u) starting\n", (unsigned int)fd, base, cnt, (unsigned int)rdflag); #endif if ((ino = getinode(fd)) == NULL) /* check fd */ { Err1: -#if DEBUG > 1 - kprintf("rwsetup() returning NULL, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "rwsetup() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -1287,8 +1287,8 @@ Err1: #if 1 /* Nick */ udata.u_sysio = 0; /* transfer is to be done on behalf of user */ #endif -#if DEBUG > 1 - kprintf("rwsetup() returning %u, success\n", ino - i_tab); +#if DEBUG >= 3 + dprintf(3, "rwsetup() returning %u, success\n", ino - i_tab); #endif return ino; } @@ -1322,7 +1322,7 @@ int pdat(struct s_pdata *ubuf) { bcopy(tmpbuf->u_name, ubuf->u_name, DIRNAMELEN); ubuf->u_insys = tmpbuf->u_insys; ubuf->u_callno = tmpbuf->u_callno; -#if DEBUG > 1 +#if DEBUG ubuf->u_traceme = tmpbuf->u_traceme; #else ubuf->u_traceme = 0; diff --git a/src/kernel/uzi/scall2.c b/src/kernel/uzi/scall2.c index 3635a151..33c691f8 100644 --- a/src/kernel/uzi/scall2.c +++ b/src/kernel/uzi/scall2.c @@ -318,15 +318,19 @@ int16 val2; register int16 j; register ptptr p; -#if DEBUG > 1 - kprintf ("process %d exiting\n", udata.u_ptab->p_pid); +#if DEBUG >= 2 + dprintf(2, "process %d exiting\n", udata.u_ptab->p_pid); #endif di(); for (j=0; j < UFTSIZE; ++j) { +#if 1 /* Nick, to sidestep signed vs unsigned char issues */ + if (freefileentry(udata.u_files[j]) == 0) +#else if (udata.u_files[j] >= 0) /* Portable equivalent of == -1 */ +#endif doclose (j); } @@ -347,7 +351,7 @@ int16 val2; /* See if we have any children. Set child's parents to our parent */ for (p=ptab; p < ptab+PTABSIZE; ++p) { - if (p->p_status && p->p_pptr == udata.u_ptab && p != udata.u_ptab) + if (p->p_status && p->p_pptr == udata.u_ptab && p != udata.u_ptab) p->p_pptr = udata.u_ptab->p_pptr; } ei(); @@ -597,13 +601,21 @@ int sys_getset(void) udata.u_mask = parm1 & S_UMASK; return old; case SET_TRACE: -#if DEBUG > 1 - if (parm1 < 0) traceon = 1; - else if (parm1 > 0) udata.u_traceme = 1; - else if (udata.u_traceme) udata.u_traceme = 0; - else traceon = 0; +#if DEBUG + old = udata.u_traceme; + udata.u_traceme = parm1; + return old; +#else + goto Ok; #endif + case SET_DEBUG: +#if DEBUG + old = udata.u_debugme; + udata.u_debugme = parm1; + return old; +#else goto Ok; +#endif } UERR = EPERM; Err: return (-1); diff --git a/src/kernel/uzi/systrace.c b/src/kernel/uzi/systrace.c index ffae234e..68c3e7df 100644 --- a/src/kernel/uzi/systrace.c +++ b/src/kernel/uzi/systrace.c @@ -180,6 +180,9 @@ void systrace_entry(void) unsigned int value; unsigned char type; +/* abyte('{'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + /* kprintf("word at 0x83f8 = 0x%x\n", ugetw(0x83f8)); */ kprintf ("\tpid %d, call %d", @@ -219,6 +222,9 @@ void systrace_exit(void) { register unsigned char type; +/* abyte('}'); */ +/* ahexw(*(int *)(0xc931 + 0x9a)); */ + kprintf ("\t\tpid %d, call %d, ret ", udata.u_ptab->p_pid, udata.u_callno); diff --git a/src/kernel/uzi/unix.h b/src/kernel/uzi/unix.h index d75b5c50..4ec9c3d3 100644 --- a/src/kernel/uzi/unix.h +++ b/src/kernel/uzi/unix.h @@ -709,7 +709,8 @@ typedef struct u_data { uzitime_t u_cstime; char u_page; /* Process' MMU Base Address */ inoptr u_root; /* Index into inode table of chroot target */ - char u_traceme; /* added by Nick, used only when DEBUG > 1 */ + char u_traceme; /* added by Nick, used only ifdef DEBUG */ + char u_debugme; /* added by Nick, used only ifdef DEBUG */ #if 1 char u_files[UFTSIZE]; /* Process file table: indices into open file table. */ @@ -962,6 +963,7 @@ typedef struct s_kdata { #define SET_PRIO 9 /* set process priority */ #define SET_UMASK 10 /* get/set umask */ #define SET_TRACE 11 /* set trace flag */ +#define SET_DEBUG 12 /* set debug flag */ #endif diff --git a/src/kernel/uzi/vendor.h b/src/kernel/uzi/vendor.h index 1884199c..32434c4f 100644 --- a/src/kernel/uzi/vendor.h +++ b/src/kernel/uzi/vendor.h @@ -18,6 +18,7 @@ #define di_absolute _di_absolute #define doexec _doexec #define dofork _dofork +#define dprintf _dprintf #define dptr _dptr #define dTbl _dTbl #define ei _ei @@ -64,6 +65,7 @@ #if 1 /* Nick, see kprintf.c */ int kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +int dprintf(char debuglevel, char *fmt, ...); #else void kprintf(char *, ...); /* ensures IAR won't try to pass register params */ #endif diff --git a/src/kernel/uzi/xip.c b/src/kernel/uzi/xip.c index 1f4e3eff..af25ba8c 100644 --- a/src/kernel/uzi/xip.c +++ b/src/kernel/uzi/xip.c @@ -34,6 +34,11 @@ #include "filesys.h" /* prototypes added by Nick */ #include "xip.h" /* prototypes added by Nick */ +#if 0 +#undef DEBUG +#define DEBUG 3 /* TEMPORARY! */ +#endif + #ifdef UTIL /* rather a hack indeed */ #define EISALIGN 42 /* 42 File is already aligned */ #define ENOALIGN 43 /* 43 File is not aligned */ @@ -63,8 +68,8 @@ int bitmap_align(inoptr ino, off_t size) inoptr other; int flag, exclude, indirection; -#if DEBUG > 2 - kprintf("bitmap_align(%u, %ld) starting\n", ino - i_tab, size); +#if DEBUG >= 3 + dprintf(3, "bitmap_align(%u, %ld) starting\n", ino - i_tab, size); #endif /* return 0; */ @@ -75,8 +80,8 @@ int bitmap_align(inoptr ino, off_t size) if (dev->s_bitmap_immov >= dev->s_bitmap_final) { udata.u_error = ENOLCKFS; /* not a locking filesystem */ -#if DEBUG > 2 - kprintf("bitmap_align() returning -1 a\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_align() returning -1 a\n"); #endif return -1; } @@ -90,8 +95,8 @@ int bitmap_align(inoptr ino, off_t size) if ((ino->c_node.i_mode & S_IFMT) != S_IFREG) { udata.u_error = ENOREGALIGN; /* file not regular or aligned */ -#if DEBUG > 2 - kprintf("bitmap_ualign() returning -1 b\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_ualign() returning -1 b\n"); #endif return -1; } @@ -101,8 +106,8 @@ int bitmap_align(inoptr ino, off_t size) if (regions > (BUFSIZE / sizeof(blkno_t))) { udata.u_error = ENOSPC; /* size specified is too large */ -#if DEBUG > 2 - kprintf("bitmap_align() returning -1 c\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_align() returning -1 c\n"); #endif return -1; } @@ -149,7 +154,7 @@ int bitmap_align(inoptr ino, off_t size) } #if DEBUG > 1 - kprintf("processing my inode %d\n", ino->c_num); + dprintf(2, "processing my inode %d\n", ino->c_num); #endif /* move the file's data into unoccupied blocks of each region */ @@ -235,13 +240,15 @@ int bitmap_align(inoptr ino, off_t size) } #if DEBUG > 1 - kprintf("processing other inode %d\n", other->c_num); + dprintf(2, "processing other inode %d\n", other->c_num); #endif +#if 0 /* don't bother, since the S_IFMT bits will be invalid anyway */ if (other->c_node.i_mode == 0) { i_deref(other); continue; /* inode bitmap is bad, try to continue */ } +#endif /* check mode */ flag = other->c_node.i_mode & S_IFMT; @@ -282,7 +289,7 @@ int bitmap_align(inoptr ino, off_t size) indirection = 2; } blk = other->c_node.i_addr[i]; - if (blk == 3840) kprintf("bad @ %d,%d 0x%04x\n", other->c_num, i, &other->c_node.i_addr[i]); +/* if (blk == 3840) dprintf(3, "bad @ %d,%d 0x%04x\n", other->c_num, i, &other->c_node.i_addr[i]); */ if (blk) { pos = bitmap_align_recurse(dev, /*pos,*/ @@ -342,8 +349,8 @@ bitmap_align_error: dev->s_bitmap_final); } -#if DEBUG > 2 - kprintf("bitmap_align() returning -1 d\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_align() returning -1 d\n"); #endif return -1; } @@ -352,8 +359,8 @@ bitmap_align_error: ino->c_dirty = 1; i_sync(); /* flushing inodes */ -#if DEBUG > 2 - kprintf("bitmap_align() returning 0, success\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_align() returning 0, success\n"); #endif return 0; /* successfully aligned the file */ } @@ -365,8 +372,8 @@ int bitmap_ualign(inoptr ino, off_t size) fsptr dev; dev_t devno; -#if DEBUG > 2 - kprintf("bitmap_ualign(%u, %ld) starting\n", ino - i_tab, size); +#if DEBUG >= 3 + dprintf(3, "bitmap_ualign(%u, %ld) starting\n", ino - i_tab, size); #endif /* prepare to access the given inode */ @@ -377,8 +384,8 @@ int bitmap_ualign(inoptr ino, off_t size) region = bitmap_examine(dev, ino, size, ®ions, &blocks); if (region == NULL) { -#if DEBUG > 2 - kprintf("bitmap_ualign() returning -1 a\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_ualign() returning -1 a\n"); #endif return -1; /* error code has been setup by bitmap_examine() */ } @@ -397,8 +404,8 @@ int bitmap_ualign(inoptr ino, off_t size) { /* disk i/o error, or corrupt filesystem */ /* udata.u_error = ENXIO */; -#if DEBUG > 2 - kprintf("bitmap_ualign() returning -1 f\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_ualign() returning -1 f\n"); #endif return -1; } @@ -415,8 +422,8 @@ int bitmap_ualign(inoptr ino, off_t size) ino->c_dirty = 1; i_sync(); /* flushing inodes */ -#if DEBUG > 2 - kprintf("bitmap_ualign() returning 0\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_ualign() returning 0\n"); #endif return 0; } @@ -428,11 +435,16 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, blkno_t blk, pos, /*inc,*/ newno; blkno_t *region, regions, blocks; +#if DEBUG >= 3 + dprintf(3, "bitmap_examine(%d, %d, %ld, 0x%x, 0x%x) starting\n", + dev - fs_tab, ino - i_tab, size, regioncount, blockcount); +#endif + if (dev->s_bitmap_immov >= dev->s_bitmap_final) { udata.u_error = ENOLCKFS; /* not a locking filesystem */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL a\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -441,16 +453,16 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, if ((ino->c_node.i_mode & S_IFMT) == S_IFREG) { udata.u_error = ENOALIGN; /* file is not aligned */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL b\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u\n", udata.u_error); #endif return NULL; } if ((ino->c_node.i_mode & S_IFMT) != S_IFALIGN) { udata.u_error = ENOREGALIGN; /* file not regular or aligned */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL c\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -460,8 +472,8 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, if (regions > (BUFSIZE / sizeof(blkno_t))) { udata.u_error = ENOSPC; /* size specified is too large */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL c\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u\n", udata.u_error); #endif return NULL; } @@ -484,8 +496,8 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, if ((blk & (PAGE_BLOCKS-1)) || blk == NULLBLK) { udata.u_error = ENOALIGN; /* alignment bad */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL d\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u a\n", udata.u_error); #endif return NULL; } @@ -500,8 +512,8 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, if (newno != blk) /*|| newno == NULLBLK)*/ { udata.u_error = ENOALIGN; /* alignment bad */ -#if DEBUG > 2 - kprintf("bitmap_examine() returning NULL e\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning NULL, error %u b\n", udata.u_error); #endif return NULL; } @@ -511,6 +523,9 @@ blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, *regioncount = regions; *blockcount = blocks; +#if DEBUG >= 3 + dprintf(3, "bitmap_examine() returning 0x%x (%d, %d)\n", region, regions, blocks); +#endif return region; } @@ -521,12 +536,17 @@ blkno_t bitmap_align_chase(fsptr dev, inoptr ino, blkno_t blk, blkno_t pos, int i, occupied; bufptr buf, other; +#if DEBUG >= 3 + dprintf(3, "bitmap_align_chase(%d, %d, %d, %d, 0x%x, %d, %d) starting\n", + dev - fs_tab, ino - i_tab, blk, pos, region, regions, blocks); +#endif + /* check we have been passed a valid block number */ if (blk < (dev->s_reserv + dev->s_isize) || blk >= dev->s_fsize) { udata.u_error = ECORRUPTFS; -#if DEBUG > 0 - kprintf("bitmap_align_chase() 1 ino = %d, blk = %d, pos = %d\n", +#if DEBUG + dprintf(1, "bitmap_align_chase() 1 ino = %d, blk = %d, pos = %d\n", ino->c_num, blk, pos); #endif return (blkno_t)-1; /* filesystem is corrupt */ @@ -548,9 +568,12 @@ blkno_t bitmap_align_chase(fsptr dev, inoptr ino, blkno_t blk, blkno_t pos, blk >= dev->s_fsize) { udata.u_error = ECORRUPTFS; -#if DEBUG > 0 - kprintf("bitmap_align_chase() 2 ino = %d, blk = %d, pos = %d\n", +#if DEBUG + dprintf(1, "bitmap_align_chase() 2 ino = %d, blk = %d, pos = %d\n", ino->c_num, blk, pos); +#endif +#if DEBUG >= 3 + dprintf(3, "bitmap_align_chase() returning -1, error %u\n", udata.u_error); #endif return (blkno_t)-1; /* filesystem is corrupt */ } @@ -559,6 +582,9 @@ blkno_t bitmap_align_chase(fsptr dev, inoptr ino, blkno_t blk, blkno_t pos, pos = bitmap_align_reverse(blk, region, regions, blocks); if (pos == (blkno_t)-1) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_chase() returning %d, ok\n", blk); +#endif return blk; /* success, return the just-freed block */ } @@ -573,8 +599,8 @@ blkno_t bitmap_align_bmap(inoptr ino, blkno_t newno, blkno_t pos) blkno_t blk; bufptr buf, other; -#if DEBUG > 2 - kprintf("bitmap_align_bmap(%u, %u) starting\n", ino - i_tab, pos); +#if DEBUG >= 3 + dprintf(3, "bitmap_align_bmap(%u, %u) starting\n", ino - i_tab, pos); #endif devno = ino->c_dev; @@ -639,8 +665,8 @@ blkno_t bitmap_align_bmap(inoptr ino, blkno_t newno, blkno_t pos) if (buf == NULL) { Err: -#if DEBUG > 2 - kprintf("bitmap_align_bmap() returning -1, error %u\n", udata.u_error); +#if DEBUG >= 3 + dprintf(3, "bitmap_align_bmap() returning -1, error %u\n", udata.u_error); #endif return (blkno_t)-1; } @@ -665,29 +691,29 @@ Ok: goto Err; } -#if DEBUG > 2 - kprintf("getting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); +#if DEBUG >= 2 + dprintf(2, "getting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); #endif /* really move the block by manipulating cache entries */ other = (bufptr)bfind(devno, newno); /* hanging around in cache? */ if (other) { -/* kprintf("bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ +/* dprintf(3, "bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ other->bf_blk = blk; /* swap, for minimal overhead */ other->bf_dirty = 0; /* try to avoid writing back */ } /* revise the original cache entry to show the new block */ buf->bf_blk = newno; /* original value is in variable blk */ -/* kprintf("bufpool entry %d = block %d, dirty 1\n", buf - bufpool, newno); */ +/* dprintf(3, "bufpool entry %d = block %d, dirty 1\n", buf - bufpool, newno); */ if (bawrite(buf) < 0) /* dirty, but delay writing for the moment */ { goto Err; } -#if DEBUG > 2 - kprintf("bitmap_align_bmap() returning %u, success\n", blk); +#if DEBUG >= 3 + dprintf(3, "bitmap_align_bmap() returning %u, success\n", blk); #endif return blk; } @@ -698,8 +724,8 @@ blkno_t bitmap_align_reverse(blkno_t blk, blkno_t i, k; blkno_t pos; -#if DEBUG > 2 - kprintf("bitmap_align_reverse(%u) starting\n", blk); +#if DEBUG > 3 + dprintf(4, "bitmap_align_reverse(%u) starting\n", blk); #endif /* perform a reverse lookup of blk via the region list */ @@ -714,8 +740,8 @@ blkno_t bitmap_align_reverse(blkno_t blk, { /* yes, return the computed logical pos in file */ pos += blk - region[i]; -#if DEBUG > 2 - kprintf("bitmap_align_reverse() returning %u, found\n", pos); +#if DEBUG > 3 + dprintf(4, "bitmap_align_reverse() returning %u, found\n", pos); #endif return pos; } @@ -725,8 +751,8 @@ blkno_t bitmap_align_reverse(blkno_t blk, } /* the given blk was not found in any region of the list */ -#if DEBUG > 2 - kprintf("bitmap_align_reverse() returning -1, not found\n"); +#if DEBUG > 3 + dprintf(4, "bitmap_align_reverse() returning -1, not found\n"); #endif return -1; } @@ -745,15 +771,25 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, char tempdirty; blkno_t pos, chase; +#if DEBUG > 3 + dprintf(4, "bitmap_align_recurse" + "(%d, %d, %d, 0x%x, 0x%x, %d, 0x%x, %d, %d) starting\n", + dev - fs_tab, ino - i_tab, exclude, parent, dirty, indirection, + region, regions, blocks); +#endif + /* check we have been passed a valid block number */ blk = *parent; if (blk < (dev->s_reserv + dev->s_isize) || blk >= dev->s_fsize) { /* filesystem is corrupt, invalid block */ udata.u_error = ECORRUPTFS; -#if DEBUG > 0 - kprintf("bitmap_align_recurse() ino = %d, blk = %d, ind = %d, par = 0x%04x\n", +#if DEBUG + dprintf(1, "bitmap_align_recurse() ino = %d, blk = %d, ind = %d, par = 0x%04x\n", ino->c_num, blk, indirection, parent); +#endif +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); #endif return (blkno_t)-1; } @@ -785,6 +821,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, if (moveable == 0 && indirection == 0) { /* no action is needed (no move and not indirect) */ +#if DEBUG > 3 + dprintf(4, "bitmap_align_recurse() returning -1, no action, ok\n"); +#endif return (blkno_t)-1; } @@ -793,6 +832,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, buf = (bufptr)bread(devno, blk, 0); if (buf == NULL) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error reading the block itself */ } @@ -816,7 +858,7 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, for (i = 0; i < BUFSIZE / sizeof(blkno_t); i++) { newno = ((blkno_t *)buf)[i]; - if (newno == 3840) kprintf("bad # %d,%d 0x%04x\n", buf->bf_blk, i, &((blkno_t *)buf)[i]); +/* if (newno == 3840) dprintf(3, "bad # %d,%d 0x%04x\n", buf->bf_blk, i, &((blkno_t *)buf)[i]); */ if (newno) { if (exclude == 2) /* it's the target file */ @@ -826,6 +868,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, if (bfree(buf, buf->bf_dirty) < 0) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error */ } @@ -838,6 +883,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, buf = (bufptr)bread(devno, blk, 0); if (buf == NULL) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error */ } @@ -863,6 +911,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, { if (bfree(buf, buf->bf_dirty) < 0) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error */ } } @@ -876,12 +927,18 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, buf = (bufptr)bread(devno, blk, 0); if (buf == NULL) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error */ } } if (newno == (blkno_t)-1) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; } @@ -891,6 +948,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, dev->s_bitmap_immov) != 1) { /* i/o error, or corrupt filesystem */ +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; } } @@ -909,6 +969,9 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, newno >= dev->s_fsize) { udata.u_error = ENOSPC; /* may overwrite ENXIO !! */ +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; } @@ -918,37 +981,49 @@ blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, /* inform parent that its allocation entries were changed */ *dirty = 1; -#if DEBUG > 2 - kprintf("putting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); +#if DEBUG >= 2 + dprintf(2, "putting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); #endif /* really move the block by manipulating cache entries */ other = (bufptr)bfind(devno, newno); /* hanging around in cache? */ if (other) { -/* kprintf("bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ +/* dprintf(3, "bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ other->bf_blk = blk; /* swap, for minimal overhead */ other->bf_dirty = 0; /* try to avoid writing back */ } /* revise the original cache entry to show the new block */ -/* kprintf("bufpool entry %d = block %d, dirty 2\n", buf - bufpool, newno); */ +/* dprintf(3, "bufpool entry %d = block %d, dirty 2\n", buf - bufpool, newno); */ buf->bf_blk = newno; /* original value is in variable blk */ if (bfree(buf, 2) < 0) /* very dirty, write back immediately */ { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error writing back */ } +#if DEBUG > 3 + dprintf(4, "bitmap_align_recurse() returning %d, moved, ok\n", chase); +#endif return chase; /* indicate which spot was just freed */ } else { if (bfree(buf, buf->bf_dirty) < 0) { +#if DEBUG >= 3 + dprintf(3, "bitmap_align_recurse() returning -1, error %u\n", udata.u_error); +#endif return (blkno_t)-1; /* disk i/o error writing back */ } } +#if DEBUG > 3 + dprintf(4, "bitmap_align_recurse() returning -1, ok\n"); +#endif return (blkno_t)-1; /* successfully traversed the block and its children */ } @@ -958,8 +1033,8 @@ blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) blkno_t i, j, lm, blk; unsigned long bits, mask; /* assumes REGION_BLOCKS <= 32 */ -#if DEBUG > 2 - kprintf("bitmap_search(%u, %d, %u, %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "bitmap_search(%u, %d, %u, %u) starting\n", devno, size, start, final); #endif @@ -1004,8 +1079,8 @@ blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_search() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_search() returning -1, i/o error\n"); #endif return (blkno_t)-1; /* should indicate i/o error */ } @@ -1027,14 +1102,14 @@ blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) /* don't write it back, our caller will */ if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_search() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_search() returning -1, i/o error\n"); #endif return (blkno_t)-1; } -#if DEBUG > 2 - kprintf("bitmap_search() returning %u, success\n", blk); +#if DEBUG >= 3 + dprintf(3, "bitmap_search() returning %u, success\n", blk); #endif return blk; } @@ -1045,8 +1120,8 @@ blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) /* nothing found this time, release block and loop */ if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_search() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_search() returning -1, i/o error\n"); #endif return (blkno_t)-1; } @@ -1056,8 +1131,8 @@ blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) } /* no '0' string found within the bitmap limits */ -#if DEBUG > 2 - kprintf("bitmap_search() returning -1, bitmap full\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_search() returning -1, bitmap full\n"); #endif return (blkno_t)-1; /* not an error, bitmap was really full */ } @@ -1068,8 +1143,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, blkno_t i, j, lm; char *buf, *p, mask; -#if DEBUG > 2 - kprintf("bitmap_reserve(%u, %u, %d, %d, %u, %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve(%u, %u, %d, %d, %u, %u) starting\n", devno, blk, size, flag, start, final); #endif @@ -1077,8 +1152,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, j = start + (blk >> 3); if (j >= final) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, out of range\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, out of range\n"); #endif return -1; /* block out of range, very bad */ } @@ -1087,8 +1162,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } @@ -1109,8 +1184,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, /* gone past the end of the current bitmap block */ if (j >= final) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, out of range\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, out of range\n"); #endif return -1; /* out of range */ } @@ -1118,8 +1193,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, /* need to flush the modifications done so far */ if (bawrite((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, i/o error\n"); #endif return -1; /* i/o error */ } @@ -1128,8 +1203,8 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, i/o error\n"); #endif return -1; /* i/o error */ } @@ -1156,14 +1231,14 @@ int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, /* ready to write back the modified bitmap block */ if (bawrite((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_reserve() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } -#if DEBUG > 2 - kprintf("bitmap_reserve() returning 0, success\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_reserve() returning 0, success\n"); #endif return 0; } @@ -1175,8 +1250,8 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, char *buf, *p, mask; blkno_t i, j, lm; -#if DEBUG > 2 - kprintf("bitmap_find(%u, %u, %d, %d, %u, %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "bitmap_find(%u, %u, %d, %d, %u, %u) starting\n", devno, blk, flag, toggle, start, final); #endif @@ -1197,8 +1272,8 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_find() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning -1, i/o error\n"); #endif return (blkno_t)-1; /* should indicate i/o error */ } @@ -1231,8 +1306,8 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, *p ^= 1 << i; if (bawrite((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_find() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning -1, i/o error\n"); #endif return (blkno_t)-1; /* i/o */ } @@ -1241,15 +1316,15 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, { if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_find() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning -1, i/o error\n"); #endif return (blkno_t)-1; /* i/o */ } } -#if DEBUG > 2 - kprintf("bitmap_find() returning %u, success\n", blk); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning %u, success\n", blk); #endif return blk; } @@ -1260,8 +1335,8 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, /* nothing found this time, release block and loop */ if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_find() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning -1, i/o error\n"); #endif return (blkno_t)-1; } @@ -1272,8 +1347,8 @@ blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, /* no 'flag' bit found within the bitmap limits */ blk = (j - start) << 3; -#if DEBUG > 2 - kprintf("bitmap_find() returning %u, bitmap full\n", blk); +#if DEBUG >= 3 + dprintf(3, "bitmap_find() returning %u, bitmap full\n", blk); #endif return blk; /* not an error, bitmap was really full */ } @@ -1283,16 +1358,16 @@ int bitmap_get(dev_t devno, blkno_t blk, blkno_t start, blkno_t final) blkno_t i, j; char *buf, *p; -#if DEBUG > 2 - kprintf("bitmap_get(%u, %u, %u, %u) starting\n", devno, blk, start, final); +#if DEBUG >= 3 + dprintf(3, "bitmap_get(%u, %u, %u, %u) starting\n", devno, blk, start, final); #endif /* calculate byte position within bitmap for this block */ j = start + (blk >> 3); if (j >= final) { -#if DEBUG > 2 - kprintf("bitmap_get() returning -1, out of range\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_get() returning -1, out of range\n"); #endif return -1; /* block out of range, very bad */ } @@ -1302,8 +1377,8 @@ int bitmap_get(dev_t devno, blkno_t blk, blkno_t start, blkno_t final) buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_get() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_get() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } @@ -1314,14 +1389,14 @@ int bitmap_get(dev_t devno, blkno_t blk, blkno_t start, blkno_t final) if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_get() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_get() returning -1, i/o error\n"); #endif return -1; } -#if DEBUG > 2 - kprintf("bitmap_get() returning %d, success\n", i); +#if DEBUG >= 3 + dprintf(3, "bitmap_get() returning %d, success\n", i); #endif return i; } @@ -1332,8 +1407,8 @@ int bitmap_set(dev_t devno, blkno_t blk, int flag, blkno_t i, j; char *buf, *p, mask; -#if DEBUG > 2 - kprintf("bitmap_set(%u, %u, %d, %u, %u) starting\n", +#if DEBUG >= 3 + dprintf(3, "bitmap_set(%u, %u, %d, %u, %u) starting\n", devno, blk, flag, start, final); #endif @@ -1341,8 +1416,8 @@ int bitmap_set(dev_t devno, blkno_t blk, int flag, j = start + (blk >> 3); if (j >= final) { -#if DEBUG > 2 - kprintf("bitmap_set() returning -1, out of range\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_set() returning -1, out of range\n"); #endif return -1; /* block out of range, very bad */ } @@ -1352,8 +1427,8 @@ int bitmap_set(dev_t devno, blkno_t blk, int flag, buf = bread(devno, j >> BUFSIZELOG, 0); if (buf == NULL) { -#if DEBUG > 2 - kprintf("bitmap_set() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_set() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } @@ -1369,8 +1444,8 @@ int bitmap_set(dev_t devno, blkno_t blk, int flag, *p ^= mask; if (bawrite((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_set() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_set() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } @@ -1379,15 +1454,15 @@ int bitmap_set(dev_t devno, blkno_t blk, int flag, { if (brelse((bufptr)buf) < 0) { -#if DEBUG > 2 - kprintf("bitmap_set() returning -1, i/o error\n"); +#if DEBUG >= 3 + dprintf(3, "bitmap_set() returning -1, i/o error\n"); #endif return -1; /* should indicate i/o error */ } } -#if DEBUG > 2 - kprintf("bitmap_set() returning %d, success\n", j); +#if DEBUG >= 3 + dprintf(3, "bitmap_set() returning %d, success\n", j); #endif return j; } diff --git a/src/libiar/n.bat b/src/libiar/n.bat index 97a07cd8..d06db476 100644 --- a/src/libiar/n.bat +++ b/src/libiar/n.bat @@ -1,3 +1,4 @@ +md build cd build copy ..\build.ban n.bat call n diff --git a/src/libsys/build-b.ban b/src/libsys/build-b.ban index e834b895..403ff840 100644 --- a/src/libsys/build-b.ban +++ b/src/libsys/build-b.ban @@ -346,6 +346,13 @@ as-z80 -l -o systrace.s01 @if errorlevel 1 goto failure copy systrace.rel ..\..\..\lib\relsysb +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sysdebug ..\sysdebug +@if errorlevel 1 goto failure +del sysdebug.r01 +as-z80 -l -o sysdebug.s01 +@if errorlevel 1 goto failure +copy sysdebug.rel ..\..\..\lib\relsysb + iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_time ..\time @if errorlevel 1 goto failure del time.r01 diff --git a/src/libsys/build-l.ban b/src/libsys/build-l.ban index da32baa5..32d2d4e6 100644 --- a/src/libsys/build-l.ban +++ b/src/libsys/build-l.ban @@ -346,6 +346,13 @@ as-z80 -l -o systrace.s01 @if errorlevel 1 goto failure copy systrace.rel ..\..\..\lib\relsysl +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sysdebug ..\sysdebug +@if errorlevel 1 goto failure +del sysdebug.r01 +as-z80 -l -o sysdebug.s01 +@if errorlevel 1 goto failure +copy sysdebug.rel ..\..\..\lib\relsysl + iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_time ..\time @if errorlevel 1 goto failure del time.r01 diff --git a/src/libsys/libsysb.lib b/src/libsys/libsysb.lib index 6c982515..503b75f4 100644 --- a/src/libsys/libsysb.lib +++ b/src/libsys/libsysb.lib @@ -47,6 +47,7 @@ relsysb\symlink.rel relsysb\sync.rel relsysb\sys0b.rel relsysb\sys1b.rel +relsysb\sysdebug.rel relsysb\systrace.rel relsysb\time.rel relsysb\times.rel diff --git a/src/libsys/libsysl.lib b/src/libsys/libsysl.lib index 1cb0d327..e77395d9 100644 --- a/src/libsys/libsysl.lib +++ b/src/libsys/libsysl.lib @@ -47,6 +47,7 @@ relsysl\symlink.rel relsysl\sync.rel relsysl\sys0l.rel relsysl\sys1l.rel +relsysl\sysdebug.rel relsysl\systrace.rel relsysl\time.rel relsysl\times.rel diff --git a/src/libsys/syscalls.h b/src/libsys/syscalls.h index d9914c1f..c4aa93b2 100644 --- a/src/libsys/syscalls.h +++ b/src/libsys/syscalls.h @@ -77,6 +77,7 @@ #define L_setprio #define L_umask #define L_systrace +#define L_sysdebug /* Nick */ #endif #endif diff --git a/src/libsys/sysdebug.c b/src/libsys/sysdebug.c new file mode 100644 index 00000000..723b00be --- /dev/null +++ b/src/libsys/sysdebug.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX sysdebug(int onoff); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_sysdebug +#ifndef HI_TECH_C +UNIX sysdebug(int onoff) + { +#if 0 + return unix_set(SET_DEBUG, onoff); +#else + return unix(7, SET_DEBUG, onoff); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __setset"); + asm(" global _sysdebug"); + asm(" signat _sysdebug,4154"); + asm("_sysdebug:"); + asm(" push de"); + asm(" ld de," __str1(SET_DEBUG)); + asm(" jp __setset"); +#endif +#endif + + diff --git a/src/link-z80/link-z80.exe b/src/link-z80/link-z80.exe deleted file mode 100644 index f6760bf1dfa41e57c23be60e0fe451bc106ab6ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106545 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 LF}k{V9``>0Qgqci diff --git a/src/link-z80/link-z80.map b/src/link-z80/link-z80.map deleted file mode 100644 index 18e3cb58..00000000 --- a/src/link-z80/link-z80.map +++ /dev/null @@ -1,520 +0,0 @@ - link-z80 - - Timestamp is 3e663ef6 (Thu Mar 06 05:16:22 2003) - - Preferred load address is 00400000 - - Start Length Name Class - 0001:00000000 000112f3H .text CODE - 0002:00000000 000005ccH .rdata DATA - 0002:000005cc 00000000H .edata DATA - 0003:00000000 00000104H .CRT$XCA DATA - 0003:00000104 00000104H .CRT$XCZ DATA - 0003:00000208 00000104H .CRT$XIA DATA - 0003:0000030c 00000109H .CRT$XIC DATA - 0003:00000418 00000104H .CRT$XIZ DATA - 0003:0000051c 00000104H .CRT$XPA DATA - 0003:00000620 00000104H .CRT$XPX DATA - 0003:00000724 00000104H .CRT$XPZ DATA - 0003:00000828 00000104H .CRT$XTA DATA - 0003:0000092c 00000104H .CRT$XTZ DATA - 0003:00000a30 000023ddH .data DATA - 0003:00002e10 00001f34H .bss DATA - 0004:00000000 00000014H .idata$2 DATA - 0004:00000014 00000014H .idata$3 DATA - 0004:00000028 000000fcH .idata$4 DATA - 0004:00000124 000000fcH .idata$5 DATA - 0004:00000220 00000444H .idata$6 DATA - - Address Publics by Value Rva+Base Lib:Object - - 0001:00000350 _newarea 00401350 f lkarea.obj - 0001:00000466 _lkparea 00401466 f lkarea.obj - 0001:00000593 _lnkarea 00401593 f lkarea.obj - 0001:000007b5 _lnksect 004017b5 f lkarea.obj - 0001:00000ce0 _eval 00401ce0 f lkeval.obj - 0001:00000d68 _expr 00401d68 f lkeval.obj - 0001:00000faa _term 00401faa f lkeval.obj - 0001:0000131a _digit 0040231a f lkeval.obj - 0001:000013cf _oprio 004023cf f lkeval.obj - 0001:00001620 _newhead 00402620 f lkhead.obj - 0001:00001720 _module 00402720 f lkhead.obj - 0001:000017d0 _getid 004027d0 f lklex.obj - 0001:0000183c _getfid 0040283c f lklex.obj - 0001:0000188f _getnb 0040288f f lklex.obj - 0001:000018b0 _skip 004028b0 f lklex.obj - 0001:000018ea _get 004028ea f lklex.obj - 0001:00001918 _unget 00402918 f lklex.obj - 0001:00001930 _getmap 00402930 f lklex.obj - 0001:00001a80 _getline 00402a80 f lklex.obj - 0001:00001cc0 _more 00402cc0 f lklex.obj - 0001:00001cfd _endline 00402cfd f lklex.obj - 0001:00001e90 _addpath 00402e90 f lklibr.obj - 0001:00001f21 _addlib 00402f21 f lklibr.obj - 0001:00001f83 _addfile 00402f83 f lklibr.obj - 0001:000021a7 _search 004031a7 f lklibr.obj - 0001:00002228 _fndsym 00403228 f lklibr.obj - 0001:000026df _library 004036df f lklibr.obj - 0001:0000271c _loadfile 0040371c f lklibr.obj - 0001:00002a20 _newpag 00403a20 f lklist.obj - 0001:00002a62 _dgt 00403a62 f lklist.obj - 0001:00002aaf _slew 00403aaf f lklist.obj - 0001:000030cb _lstarea 004040cb f lklist.obj - 0001:0000361a _lkulist 0040461a f lklist.obj - 0001:0000374f _lkalist 0040474f f lklist.obj - 0001:00003a53 _lkglist 00404a53 f lklist.obj - 0001:00004430 _main 00405430 f lkmain.obj - 0001:000047a1 _lkexit 004057a1 f lkmain.obj - 0001:00004831 _link 00405831 f lkmain.obj - 0001:00004aea _map 00405aea f lkmain.obj - 0001:00004df3 _parse 00405df3 f lkmain.obj - 0001:000053bc _doparse 004063bc f lkmain.obj - 0001:0000546b _bassav 0040646b f lkmain.obj - 0001:000054fd _setbas 004064fd f lkmain.obj - 0001:00005828 _gblsav 00406828 f lkmain.obj - 0001:000058ba _setgbl 004068ba f lkmain.obj - 0001:000059d8 _afile 004069d8 f lkmain.obj - 0001:00005bbc _fndidx 00406bbc f lkmain.obj - 0001:00005c32 _usage 00406c32 f lkmain.obj - 0001:000062b0 _lkout 004072b0 f lkout.obj - 0001:000062f2 _ixx 004072f2 f lkout.obj - 0001:000064a2 _iflush 004074a2 f lkout.obj - 0001:00006617 _sxx 00407617 f lkout.obj - 0001:000067e1 _sflush 004077e1 f lkout.obj - 0001:00006ac0 _reloc 00407ac0 f lkrloc.obj - 0001:00006b50 _relt 00407b50 f lkrloc.obj - 0001:00006ba3 _relr 00407ba3 f lkrloc.obj - 0001:000071d1 _relp 004081d1 f lkrloc.obj - 0001:000073d5 _rele 004083d5 f lkrloc.obj - 0001:00007400 _evword 00408400 f lkrloc.obj - 0001:00007446 _adb_1b 00408446 f lkrloc.obj - 0001:0000746c _adb_2b 0040846c f lkrloc.obj - 0001:00007522 _adb_3b 00408522 f lkrloc.obj - 0001:00007632 _adb_4b 00408632 f lkrloc.obj - 0001:0000779b _adb_xb 0040879b f lkrloc.obj - 0001:000078d2 _adb_lo 004088d2 f lkrloc.obj - 0001:0000794e _adb_hi 0040894e f lkrloc.obj - 0001:000079ca _adb_byte3 004089ca f lkrloc.obj - 0001:00007a46 _adb_byte4 00408a46 f lkrloc.obj - 0001:00007ac2 _adw_xb 00408ac2 f lkrloc.obj - 0001:00007b31 _relerr 00408b31 f lkrloc.obj - 0001:00007b63 _errdmp 00408b63 f lkrloc.obj - 0001:00007ce8 _prntval 00408ce8 f lkrloc.obj - 0001:00007da7 _relerp 00408da7 f lkrloc.obj - 0001:00007dd9 _erpdmp 00408dd9 f lkrloc.obj - 0001:00008360 _syminit 00409360 f lksym.obj - 0001:0000838c _newsym 0040938c f lksym.obj - 0001:0000855a _lkpsym 0040955a f lksym.obj - 0001:00008601 _symval 00409601 f lksym.obj - 0001:0000862d _symdef 0040962d f lksym.obj - 0001:000086a4 _symmod 004096a4 f lksym.obj - 0001:00008760 _symeq 00409760 f lksym.obj - 0001:00008805 _hash 00409805 f lksym.obj - 0001:00008866 _strsto 00409866 f lksym.obj - 0001:000088e5 _new 004098e5 f lksym.obj - 0001:00008aa2 _fprintf 00409aa2 f LIBC:fprintf.obj - 0001:00008ad4 ___initstdio 00409ad4 f LIBC:_file.obj - 0001:00008b79 ___endstdio 00409b79 f LIBC:_file.obj - 0001:00008b90 _strcpy 00409b90 f LIBC:strcat.obj - 0001:00008ba0 _strcat 00409ba0 f LIBC:strcat.obj - 0001:00008c80 _strlen 00409c80 f LIBC:strlen.obj - 0001:00008cfb _fclose 00409cfb f LIBC:fclose.obj - 0001:00008d51 _fgets 00409d51 f LIBC:fgets.obj - 0001:00008da8 _free 00409da8 f LIBC:free.obj - 0001:00008dd7 __fsopen 00409dd7 f LIBC:fopen.obj - 0001:00008df7 _fopen 00409df7 f LIBC:fopen.obj - 0001:00008e0a _sprintf 00409e0a f LIBC:sprintf.obj - 0001:00008e5c _malloc 00409e5c f LIBC:malloc.obj - 0001:00008e6e __nh_malloc 00409e6e f LIBC:malloc.obj - 0001:00008e9a __heap_alloc 00409e9a f LIBC:malloc.obj - 0001:00008ee0 _strchr 00409ee0 f LIBC:strchr.obj - 0001:00008ee6 ___from_strstr_to_strchr 00409ee6 f LIBC:strchr.obj - 0001:00008fa0 _strncmp 00409fa0 f LIBC:strncmp.obj - 0001:00008fd8 _sscanf 00409fd8 f LIBC:sscanf.obj - 0001:00009010 _strcmp 0040a010 f LIBC:strcmp.obj - 0001:00009094 __flsbuf 0040a094 f LIBC:_flsbuf.obj - 0001:000091b0 _strncpy 0040a1b0 f LIBC:strncpy.obj - 0001:000092ae __cinit 0040a2ae f LIBC:crt0dat.obj - 0001:000092db _exit 0040a2db f LIBC:crt0dat.obj - 0001:000092ec __exit 0040a2ec f LIBC:crt0dat.obj - 0001:000092fd __cexit 0040a2fd f LIBC:crt0dat.obj - 0001:0000930c __c_exit 0040a30c f LIBC:crt0dat.obj - 0001:000093d0 _strrchr 0040a3d0 f LIBC:strrchr.obj - 0001:000093f7 _mainCRTStartup 0040a3f7 f LIBC:crt0.obj - 0001:000094d6 __amsg_exit 0040a4d6 f LIBC:crt0.obj - 0001:0000951f __stbuf 0040a51f f LIBC:_sftbuf.obj - 0001:000095ac __ftbuf 0040a5ac f LIBC:_sftbuf.obj - 0001:000095e9 __output 0040a5e9 f LIBC:output.obj - 0001:00009df3 __ioinit 0040adf3 f LIBC:ioinit.obj - 0001:00009f9e __ioterm 0040af9e f LIBC:ioinit.obj - 0001:00009fc1 _calloc 0040afc1 f LIBC:calloc.obj - 0001:0000a03e __fcloseall 0040b03e f LIBC:closeall.obj - 0001:0000a096 _fflush 0040b096 f LIBC:fflush.obj - 0001:0000a0d1 __flush 0040b0d1 f LIBC:fflush.obj - 0001:0000a12d __flushall 0040b12d f LIBC:fflush.obj - 0001:0000a1a3 __close 0040b1a3 f LIBC:close.obj - 0001:0000a256 __freebuf 0040b256 f LIBC:_freebuf.obj - 0001:0000a281 __filbuf 0040b281 f LIBC:_filbuf.obj - 0001:0000a35a __heap_init 0040b35a f LIBC:heapinit.obj - 0001:0000a396 __heap_term 0040b396 f LIBC:heapinit.obj - 0001:0000a40b __get_sbh_threshold 0040b40b f LIBC:sbheap.obj - 0001:0000a411 __set_sbh_threshold 0040b411 f LIBC:sbheap.obj - 0001:0000a428 ___sbh_heap_init 0040b428 f LIBC:sbheap.obj - 0001:0000a466 ___sbh_find_block 0040b466 f LIBC:sbheap.obj - 0001:0000a491 ___sbh_free_block 0040b491 f LIBC:sbheap.obj - 0001:0000a7bc ___sbh_alloc_block 0040b7bc f LIBC:sbheap.obj - 0001:0000aac5 ___sbh_alloc_new_region 0040bac5 f LIBC:sbheap.obj - 0001:0000ab76 ___sbh_alloc_new_group 0040bb76 f LIBC:sbheap.obj - 0001:0000ac71 ___sbh_resize_block 0040bc71 f LIBC:sbheap.obj - 0001:0000af67 ___sbh_heapmin 0040bf67 f LIBC:sbheap.obj - 0001:0000b038 ___sbh_heap_check 0040c038 f LIBC:sbheap.obj - 0001:0000b367 __openfile 0040c367 f LIBC:_open.obj - 0001:0000b4d7 __getstream 0040c4d7 f LIBC:stream.obj - 0001:0000b54f ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z 0040c54f f LIBC:handler.obj - 0001:0000b55f ?_query_new_handler@@YAP6AHI@ZXZ 0040c55f f LIBC:handler.obj - 0001:0000b565 __callnewh 0040c565 f LIBC:handler.obj - 0001:0000b580 __input 0040c580 f LIBC:input.obj - 0001:0000c031 __lseek 0040d031 f LIBC:lseek.obj - 0001:0000c0cb __write 0040d0cb f LIBC:write.obj - 0001:0000c278 __getbuf 0040d278 f LIBC:_getbuf.obj - 0001:0000c2bc __isatty 0040d2bc f LIBC:isatty.obj - 0001:0000c2e2 __XcptFilter 0040d2e2 f LIBC:winxfltr.obj - 0001:0000c466 __setenvp 0040d466 f LIBC:stdenvp.obj - 0001:0000c51f __setargv 0040d51f f LIBC:stdargv.obj - 0001:0000c76c ___crtGetEnvironmentStringsA 0040d76c f LIBC:a_env.obj - 0001:0000c8a0 __global_unwind2 0040d8a0 f LIBC:exsup.obj - 0001:0000c8e2 __local_unwind2 0040d8e2 f LIBC:exsup.obj - 0001:0000c93a __NLG_Return2 0040d93a f LIBC:exsup.obj - 0001:0000c94a __abnormal_termination 0040d94a f LIBC:exsup.obj - 0001:0000c96d __NLG_Notify1 0040d96d f LIBC:exsup.obj - 0001:0000c976 __NLG_Notify 0040d976 f LIBC:exsup.obj - 0001:0000c989 __NLG_Dispatch 0040d989 f LIBC:exsup.obj - 0001:0000c998 __except_handler3 0040d998 f LIBC:exsup3.obj - 0001:0000ca55 __seh_longjmp_unwind@4 0040da55 f LIBC:exsup3.obj - 0001:0000ca70 __FF_MSGBANNER 0040da70 f LIBC:crt0msg.obj - 0001:0000caa9 __NMSG_WRITE 0040daa9 f LIBC:crt0msg.obj - 0001:0000cbfc __GET_RTERRMSG 0040dbfc f LIBC:crt0msg.obj - 0001:0000cc2d _wctomb 0040dc2d f LIBC:wctomb.obj - 0001:0000cca0 __aulldiv 0040dca0 f LIBC:ulldiv.obj - 0001:0000cd10 __aullrem 0040dd10 f LIBC:ullrem.obj - 0001:0000cd90 _memset 0040dd90 f LIBC:memset.obj - 0001:0000cde8 __commit 0040dde8 f LIBC:commit.obj - 0001:0000ce3f __dosmaperr 0040de3f f LIBC:dosmap.obj - 0001:0000cea6 __alloc_osfhnd 0040dea6 f LIBC:osfinfo.obj - 0001:0000cf3b __set_osfhnd 0040df3b f LIBC:osfinfo.obj - 0001:0000cfb2 __free_osfhnd 0040dfb2 f LIBC:osfinfo.obj - 0001:0000d02c __get_osfhandle 0040e02c f LIBC:osfinfo.obj - 0001:0000d069 __open_osfhandle 0040e069 f LIBC:osfinfo.obj - 0001:0000d106 __read 0040e106 f LIBC:read.obj - 0001:0000d300 _memmove 0040e300 f LIBC:memmove.obj - 0001:0000d635 __open 0040e635 f LIBC:open.obj - 0001:0000d64c __sopen 0040e64c f LIBC:open.obj - 0001:0000d905 _mbtowc 0040e905 f LIBC:mbtowc.obj - 0001:0000d9cd _isalpha 0040e9cd f LIBC:_ctype.obj - 0001:0000d9fb _isupper 0040e9fb f LIBC:_ctype.obj - 0001:0000da23 _islower 0040ea23 f LIBC:_ctype.obj - 0001:0000da4b _isdigit 0040ea4b f LIBC:_ctype.obj - 0001:0000da73 _isxdigit 0040ea73 f LIBC:_ctype.obj - 0001:0000daa0 _isspace 0040eaa0 f LIBC:_ctype.obj - 0001:0000dac8 _ispunct 0040eac8 f LIBC:_ctype.obj - 0001:0000daf0 _isalnum 0040eaf0 f LIBC:_ctype.obj - 0001:0000db1e _isprint 0040eb1e f LIBC:_ctype.obj - 0001:0000db4c _isgraph 0040eb4c f LIBC:_ctype.obj - 0001:0000db7a _iscntrl 0040eb7a f LIBC:_ctype.obj - 0001:0000dba2 ___isascii 0040eba2 f LIBC:_ctype.obj - 0001:0000dbaf ___toascii 0040ebaf f LIBC:_ctype.obj - 0001:0000dbb7 ___iscsymf 0040ebb7 f LIBC:_ctype.obj - 0001:0000dbf4 ___iscsym 0040ebf4 f LIBC:_ctype.obj - 0001:0000dc31 __isctype 0040ec31 f LIBC:isctype.obj - 0001:0000dcb0 __allmul 0040ecb0 f LIBC:llmul.obj - 0001:0000dcf0 __allshl 0040ecf0 f LIBC:llshl.obj - 0001:0000dd0f _ungetc 0040ed0f f LIBC:ungetc.obj - 0001:0000dd7d __setmbcp 0040ed7d f LIBC:mbctype.obj - 0001:0000e141 __getmbcp 0040f141 f LIBC:mbctype.obj - 0001:0000e151 ___initmbctable 0040f151 f LIBC:mbctype.obj - 0001:0000e170 _memcpy 0040f170 f LIBC:memcpy.obj - 0001:0000e4a5 ___crtMessageBoxA 0040f4a5 f LIBC:crtmbox.obj - 0001:0000e52e __fptrap 0040f52e f LIBC:crt0fp.obj - 0001:0000e537 __chsize 0040f537 f LIBC:chsize.obj - 0001:0000e67d ___crtGetStringTypeA 0040f67d f LIBC:a_str.obj - 0001:0000e7c6 ___crtLCMapStringA 0040f7c6 f LIBC:a_map.obj - 0001:0000ea15 __setmode 0040fa15 f LIBC:setmode.obj - 0001:0000ea90 __chkstk 0040fa90 f LIBC:chkstk.obj - 0001:0000ea90 __alloca_probe 0040fa90 f LIBC:chkstk.obj - 0001:0000eac0 _HeapFree@12 0040fac0 f kernel32:KERNEL32.dll - 0001:0000eac6 _HeapAlloc@12 0040fac6 f kernel32:KERNEL32.dll - 0001:0000eacc _ExitProcess@4 0040facc f kernel32:KERNEL32.dll - 0001:0000ead2 _TerminateProcess@8 0040fad2 f kernel32:KERNEL32.dll - 0001:0000ead8 _GetCurrentProcess@0 0040fad8 f kernel32:KERNEL32.dll - 0001:0000eade _GetCommandLineA@0 0040fade f kernel32:KERNEL32.dll - 0001:0000eae4 _GetVersion@0 0040fae4 f kernel32:KERNEL32.dll - 0001:0000eaea _SetHandleCount@4 0040faea f kernel32:KERNEL32.dll - 0001:0000eaf0 _GetStdHandle@4 0040faf0 f kernel32:KERNEL32.dll - 0001:0000eaf6 _GetFileType@4 0040faf6 f kernel32:KERNEL32.dll - 0001:0000eafc _GetStartupInfoA@4 0040fafc f kernel32:KERNEL32.dll - 0001:0000eb02 _GetLastError@0 0040fb02 f kernel32:KERNEL32.dll - 0001:0000eb08 _CloseHandle@4 0040fb08 f kernel32:KERNEL32.dll - 0001:0000eb0e _HeapDestroy@4 0040fb0e f kernel32:KERNEL32.dll - 0001:0000eb14 _HeapCreate@12 0040fb14 f kernel32:KERNEL32.dll - 0001:0000eb1a _VirtualFree@12 0040fb1a f kernel32:KERNEL32.dll - 0001:0000eb20 _VirtualAlloc@16 0040fb20 f kernel32:KERNEL32.dll - 0001:0000eb26 _HeapReAlloc@16 0040fb26 f kernel32:KERNEL32.dll - 0001:0000eb2c _IsBadWritePtr@8 0040fb2c f kernel32:KERNEL32.dll - 0001:0000eb32 _SetFilePointer@16 0040fb32 f kernel32:KERNEL32.dll - 0001:0000eb38 _WriteFile@20 0040fb38 f kernel32:KERNEL32.dll - 0001:0000eb3e _UnhandledExceptionFilter@4 0040fb3e f kernel32:KERNEL32.dll - 0001:0000eb44 _GetModuleFileNameA@12 0040fb44 f kernel32:KERNEL32.dll - 0001:0000eb4a _FreeEnvironmentStringsA@4 0040fb4a f kernel32:KERNEL32.dll - 0001:0000eb50 _FreeEnvironmentStringsW@4 0040fb50 f kernel32:KERNEL32.dll - 0001:0000eb56 _WideCharToMultiByte@32 0040fb56 f kernel32:KERNEL32.dll - 0001:0000eb5c _GetEnvironmentStrings@0 0040fb5c f kernel32:KERNEL32.dll - 0001:0000eb62 _GetEnvironmentStringsW@0 0040fb62 f kernel32:KERNEL32.dll - 0001:0000eb68 _RtlUnwind@16 0040fb68 f kernel32:KERNEL32.dll - 0001:0000eb6e _FlushFileBuffers@4 0040fb6e f kernel32:KERNEL32.dll - 0001:0000eb74 _SetStdHandle@8 0040fb74 f kernel32:KERNEL32.dll - 0001:0000eb7a _ReadFile@20 0040fb7a f kernel32:KERNEL32.dll - 0001:0000eb80 _CreateFileA@28 0040fb80 f kernel32:KERNEL32.dll - 0001:0000eb86 _MultiByteToWideChar@24 0040fb86 f kernel32:KERNEL32.dll - 0001:0000eb8c _GetCPInfo@8 0040fb8c f kernel32:KERNEL32.dll - 0001:0000eb92 _GetACP@0 0040fb92 f kernel32:KERNEL32.dll - 0001:0000eb98 _GetOEMCP@0 0040fb98 f kernel32:KERNEL32.dll - 0001:0000eb9e _GetProcAddress@8 0040fb9e f kernel32:KERNEL32.dll - 0001:0000eba4 _LoadLibraryA@4 0040fba4 f kernel32:KERNEL32.dll - 0001:0000ebaa _SetEndOfFile@4 0040fbaa f kernel32:KERNEL32.dll - 0001:0000ebb0 _GetStringTypeA@20 0040fbb0 f kernel32:KERNEL32.dll - 0001:0000ebb6 _GetStringTypeW@16 0040fbb6 f kernel32:KERNEL32.dll - 0001:0000ebbc _LCMapStringA@24 0040fbbc f kernel32:KERNEL32.dll - 0001:0000ebc2 _LCMapStringW@24 0040fbc2 f kernel32:KERNEL32.dll - 0002:0000002c ___lookuptable 0041302c LIBC:output.obj - 0002:00000088 ??_C@_1O@POHA@?$AA?$CI?$AAn?$AAu?$AAl?$AAl?$AA?$CJ?$AA?$AA@ 00413088 LIBC:output.obj - 0002:00000098 ??_C@_06ONKE@?$CInull?$CJ?$AA@ 00413098 LIBC:output.obj - 0002:000000a0 ??_C@_0P@GGKG@runtime?5error?5?$AA@ 004130a0 LIBC:crt0msg.obj - 0002:000000b0 ??_C@_02PIMC@?$AN?6?$AA@ 004130b0 LIBC:crt0msg.obj - 0002:000000b4 ??_C@_0O@DELO@TLOSS?5error?$AN?6?$AA@ 004130b4 LIBC:crt0msg.obj - 0002:000000c4 ??_C@_0N@OMLL@SING?5error?$AN?6?$AA@ 004130c4 LIBC:crt0msg.obj - 0002:000000d4 ??_C@_0P@OJAK@DOMAIN?5error?$AN?6?$AA@ 004130d4 LIBC:crt0msg.obj - 0002:000000e4 ??_C@_0CF@EANP@R6028?$AN?6?9?5unable?5to?5initialize?5he@ 004130e4 LIBC:crt0msg.obj - 0002:0000010c ??_C@_0DF@ECGN@R6027?$AN?6?9?5not?5enough?5space?5for?5lo@ 0041310c LIBC:crt0msg.obj - 0002:00000144 ??_C@_0DF@FKAC@R6026?$AN?6?9?5not?5enough?5space?5for?5st@ 00413144 LIBC:crt0msg.obj - 0002:0000017c ??_C@_0CG@DPMN@R6025?$AN?6?9?5pure?5virtual?5function?5c@ 0041317c LIBC:crt0msg.obj - 0002:000001a4 ??_C@_0DF@CKIP@R6024?$AN?6?9?5not?5enough?5space?5for?5_o@ 004131a4 LIBC:crt0msg.obj - 0002:000001dc ??_C@_0CJ@GGOE@R6019?$AN?6?9?5unable?5to?5open?5console?5@ 004131dc LIBC:crt0msg.obj - 0002:00000208 ??_C@_0CB@LBOB@R6018?$AN?6?9?5unexpected?5heap?5error?$AN?6@ 00413208 LIBC:crt0msg.obj - 0002:0000022c ??_C@_0CN@FPEG@R6017?$AN?6?9?5unexpected?5multithread?5@ 0041322c LIBC:crt0msg.obj - 0002:0000025c ??_C@_0CM@OBIC@R6016?$AN?6?9?5not?5enough?5space?5for?5th@ 0041325c LIBC:crt0msg.obj - 0002:00000288 ??_C@_0CB@HPAL@?$AN?6abnormal?5program?5termination?$AN?6@ 00413288 LIBC:crt0msg.obj - 0002:000002ac ??_C@_0CM@JOOB@R6009?$AN?6?9?5not?5enough?5space?5for?5en@ 004132ac LIBC:crt0msg.obj - 0002:000002d8 ??_C@_0CK@OIBL@R6008?$AN?6?9?5not?5enough?5space?5for?5ar@ 004132d8 LIBC:crt0msg.obj - 0002:00000304 ??_C@_0CF@LKPB@R6002?$AN?6?9?5floating?5point?5not?5load@ 00413304 LIBC:crt0msg.obj - 0002:0000032c ??_C@_0CF@JPDF@Microsoft?5Visual?5C?$CL?$CL?5Runtime?5Lib@ 0041332c LIBC:crt0msg.obj - 0002:00000354 ??_C@_02JJJH@?6?6?$AA@ 00413354 LIBC:crt0msg.obj - 0002:00000358 ??_C@_0BK@DEOK@Runtime?5Error?$CB?6?6Program?3?5?$AA@ 00413358 LIBC:crt0msg.obj - 0002:00000374 ??_C@_03NAME@?4?4?4?$AA@ 00413374 LIBC:crt0msg.obj - 0002:00000378 ??_C@_0BH@NNCD@?$DMprogram?5name?5unknown?$DO?$AA@ 00413378 LIBC:crt0msg.obj - 0002:00000390 ??_C@_0BD@NJFP@GetLastActivePopup?$AA@ 00413390 LIBC:crtmbox.obj - 0002:000003a4 ??_C@_0BA@GILI@GetActiveWindow?$AA@ 004133a4 LIBC:crtmbox.obj - 0002:000003b4 ??_C@_0M@PKCK@MessageBoxA?$AA@ 004133b4 LIBC:crtmbox.obj - 0002:000003c0 ??_C@_0L@HKL@user32?4dll?$AA@ 004133c0 LIBC:crtmbox.obj - 0002:000003cc ??_C@_01A@?$AA?$AA@ 004133cc LIBC:a_str.obj - 0002:000003d0 ??_C@_13A@?$AA?$AA?$AA?$AA@ 004133d0 LIBC:a_str.obj - 0003:00000000 ___xc_a 00414000 LIBC:crt0init.obj - 0003:00000104 ___xc_z 00414104 LIBC:crt0init.obj - 0003:00000208 ___xi_a 00414208 LIBC:crt0init.obj - 0003:00000418 ___xi_z 00414418 LIBC:crt0init.obj - 0003:0000051c ___xp_a 0041451c LIBC:crt0init.obj - 0003:00000724 ___xp_z 00414724 LIBC:crt0init.obj - 0003:00000828 ___xt_a 00414828 LIBC:crt0init.obj - 0003:0000092c ___xt_z 0041492c LIBC:crt0init.obj - 0003:00000b14 __abs_ 00414b14 lkdata.obj - 0003:00000b18 _rtaflg 00414b18 lkdata.obj - 0003:00000b1c _ctype 00414b1c lkdata.obj - 0003:00000b9c _ccase 00414b9c lkdata.obj - 0003:00001370 _usetxt 00415370 lkmain.obj - 0003:00001d7c _errmsg 00415d7c lkrloc.obj - 0003:000022d0 __iob 004162d0 LIBC:_file.obj - 0003:00002550 __aexit_rtn 00416550 LIBC:crt0.obj - 0003:00002554 ___app_type 00416554 LIBC:crt0.obj - 0003:00002558 ___nullstring 00416558 LIBC:output.obj - 0003:0000255c ___wnullstring 0041655c LIBC:output.obj - 0003:00002560 ___badioinfo 00416560 LIBC:ioinit.obj - 0003:00002568 __amblksiz 00416568 LIBC:heapinit.obj - 0003:0000256c ___sbh_threshold 0041656c LIBC:sbheap.obj - 0003:00002580 __XcptActTab 00416580 LIBC:winxfltr.obj - 0003:000025f8 __First_FPE_Indx 004165f8 LIBC:winxfltr.obj - 0003:000025fc __Num_FPE 004165fc LIBC:winxfltr.obj - 0003:00002600 __XcptActTabCount 00416600 LIBC:winxfltr.obj - 0003:00002604 __fpecode 00416604 LIBC:winxfltr.obj - 0003:00002608 __NLG_Destination 00416608 LIBC:exsup.obj - 0003:000026a8 __cfltcvt_tab 004166a8 LIBC:cmiscdat.obj - 0003:000026c0 __pctype 004166c0 LIBC:ctype.obj - 0003:000026c4 __pwctype 004166c4 LIBC:ctype.obj - 0003:000026c8 __ctype 004166c8 LIBC:ctype.obj - 0003:00002a40 ___mb_cur_max 00416a40 LIBC:nlsdata1.obj - 0003:00002a44 ___decimal_point 00416a44 LIBC:nlsdata1.obj - 0003:00002a48 ___decimal_point_length 00416a48 LIBC:nlsdata1.obj - 0003:00002e10 _rtadr0 00416e10 lkdata.obj - 0003:00002e14 _rtadr1 00416e14 lkdata.obj - 0003:00002e18 _rtadr2 00416e18 lkdata.obj - 0003:00002e1c _obj_flag 00416e1c lkdata.obj - 0003:00002e20 _uflag 00416e20 - 0003:00002e44 _hilo 00416e44 - 0003:00002e48 __cflush 00416e48 LIBC:_file.obj - 0003:00002e4c _errno 00416e4c LIBC:crt0dat.obj - 0003:00002e50 __doserrno 00416e50 LIBC:crt0dat.obj - 0003:00002e54 __umaskval 00416e54 LIBC:crt0dat.obj - 0003:00002e58 __osver 00416e58 LIBC:crt0dat.obj - 0003:00002e5c __winver 00416e5c LIBC:crt0dat.obj - 0003:00002e60 __winmajor 00416e60 LIBC:crt0dat.obj - 0003:00002e64 __winminor 00416e64 LIBC:crt0dat.obj - 0003:00002e68 ___argc 00416e68 LIBC:crt0dat.obj - 0003:00002e6c ___argv 00416e6c LIBC:crt0dat.obj - 0003:00002e70 ___wargv 00416e70 LIBC:crt0dat.obj - 0003:00002e74 __environ 00416e74 LIBC:crt0dat.obj - 0003:00002e78 ___initenv 00416e78 LIBC:crt0dat.obj - 0003:00002e7c __wenviron 00416e7c LIBC:crt0dat.obj - 0003:00002e80 ___winitenv 00416e80 LIBC:crt0dat.obj - 0003:00002e84 __pgmptr 00416e84 LIBC:crt0dat.obj - 0003:00002e88 __wpgmptr 00416e88 LIBC:crt0dat.obj - 0003:00002e8c __exitflag 00416e8c LIBC:crt0dat.obj - 0003:00002e90 __C_Termination_Done 00416e90 LIBC:crt0dat.obj - 0003:00002e94 __C_Exit_Done 00416e94 LIBC:crt0dat.obj - 0003:00002e98 __aenvptr 00416e98 LIBC:crt0.obj - 0003:00002e9c __wenvptr 00416e9c LIBC:crt0.obj - 0003:00002ea0 ___error_mode 00416ea0 LIBC:crt0.obj - 0003:00002ea4 __stdbuf 00416ea4 LIBC:_sftbuf.obj - 0003:00002eac __newmode 00416eac LIBC:_newmode.obj - 0003:00002eb0 ?_pnhHeap@@3P6AHI@ZA 00416eb0 LIBC:handler.obj - 0003:00002eb4 __pxcptinfoptrs 00416eb4 LIBC:winxfltr.obj - 0003:00002fc0 __adbgmsg 00416fc0 LIBC:crt0msg.obj - 0003:00002fc4 __commode 00416fc4 LIBC:ncommode.obj - 0003:00002fd8 ___lc_handle 00416fd8 LIBC:nlsdata2.obj - 0003:00002ff0 ___lc_codepage 00416ff0 LIBC:nlsdata2.obj - 0003:00002ff4 ___lc_collate_cp 00416ff4 LIBC:nlsdata2.obj - 0003:00002ff8 __fmode 00416ff8 LIBC:txtmode.obj - 0003:00003004 _rtcnt 00417004 - 0003:00003008 _lbfhead 00417008 - 0003:0000300c _cfp 0041700c - 0003:00003010 _bsp 00417010 - 0003:00003014 _axp 00417014 - 0003:00003018 _lbnhead 00417018 - 0003:0000301c _gcntr 0041701c - 0003:00003020 _rtbuf 00417020 - 0003:00003070 _filep 00417070 - 0003:00003074 _gsp 00417074 - 0003:00003078 _globlp 00417078 - 0003:0000307c _lfp 0041707c - 0003:00003080 _rtflg 00417080 - 0003:000030c0 _symhash 004170c0 - 0003:000031c0 _mfp 004171c0 - 0003:000031c4 _a_mask 004171c4 - 0003:000031c8 _line 004171c8 - 0003:000031cc _lop 004171cc - 0003:000031d0 _ofp 004171d0 - 0003:000031d4 _headp 004171d4 - 0003:000031d8 _zflag 004171d8 - 0003:000031dc _rfp 004171dc - 0003:000031e0 _rtval 004171e0 - 0003:00003220 _oflag 00417220 - 0003:00003224 _sfp 00417224 - 0003:00003228 _areap 00417228 - 0003:0000322c _tfp 0041722c - 0003:00003230 _sdp 00417230 - 0003:0000323c _page 0041723c - 0003:00003240 _pass 00417240 - 0003:00003244 _ap 00417244 - 0003:00003248 _outfp 00417248 - 0003:0000324c _wflag 0041724c - 0003:00003250 _hp 00417250 - 0003:00003254 _ip 00417254 - 0003:00003258 _rp 00417258 - 0003:0000325c _a_bytes 0041725c - 0003:00003260 _ib 00417260 - 0003:00003328 _gline 00417328 - 0003:0000332c _pflag 0041732c - 0003:00003330 _s_mask 00417330 - 0003:00003334 _basep 00417334 - 0003:00003338 _lbphead 00417338 - 0003:0000333c _xflag 0041733c - 0003:00003340 _rb 00417340 - 0003:00003408 _startp 00417408 - 0003:0000340c _radix 0041740c - 0003:00003410 _mflag 00417410 - 0003:00003414 _linkp 00417414 - 0003:00003418 _objflg 00417418 - 0003:0000341c _lkerr 0041741c - 0003:00003420 _rerr 00417420 - 0003:00003434 _v_mask 00417434 - 0003:000035a4 ___mbcodepage 004175a4 - 0003:00003620 ___mbulinfo 00417620 - 0003:0000362c ___ismbcodepage 0041762c - 0003:00003640 __mbcasemap 00417640 - 0003:00003740 __mbctype 00417740 - 0003:00003844 ___mblcid 00417844 - 0003:00003848 ___sbh_sizeHeaderList 00417848 - 0003:00003858 ___sbh_indGroupDefer 00417858 - 0003:0000385c ___sbh_pHeaderScan 0041785c - 0003:00003860 ___sbh_pHeaderDefer 00417860 - 0003:00003864 ___sbh_cntHeaderList 00417864 - 0003:00003868 ___sbh_pHeaderList 00417868 - 0003:0000386c __crtheap 0041786c - 0003:00003880 ___pioinfo 00417880 - 0003:000039bc __nhandle 004179bc - 0003:000039c0 __acmdln 004179c0 - 0003:000039cc ___env_initialized 004179cc - 0003:000039dc ___mbctype_initialized 004179dc - 0003:000039e0 ___onexitend 004179e0 - 0003:000039e4 ___onexitbegin 004179e4 - 0003:000039e8 __FPinit 004179e8 - 0003:000039ec ___piob 004179ec - 0003:00003d40 __bufin 00417d40 - 0003:00004d40 __nstream 00418d40 - 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 00419000 kernel32:KERNEL32.dll - 0004:00000014 __NULL_IMPORT_DESCRIPTOR 00419014 kernel32:KERNEL32.dll - 0004:00000124 __imp__GetModuleFileNameA@12 00419124 kernel32:KERNEL32.dll - 0004:00000128 __imp__HeapAlloc@12 00419128 kernel32:KERNEL32.dll - 0004:0000012c __imp__ExitProcess@4 0041912c kernel32:KERNEL32.dll - 0004:00000130 __imp__TerminateProcess@8 00419130 kernel32:KERNEL32.dll - 0004:00000134 __imp__GetCurrentProcess@0 00419134 kernel32:KERNEL32.dll - 0004:00000138 __imp__GetCommandLineA@0 00419138 kernel32:KERNEL32.dll - 0004:0000013c __imp__GetVersion@0 0041913c kernel32:KERNEL32.dll - 0004:00000140 __imp__SetHandleCount@4 00419140 kernel32:KERNEL32.dll - 0004:00000144 __imp__GetStdHandle@4 00419144 kernel32:KERNEL32.dll - 0004:00000148 __imp__GetFileType@4 00419148 kernel32:KERNEL32.dll - 0004:0000014c __imp__GetStartupInfoA@4 0041914c kernel32:KERNEL32.dll - 0004:00000150 __imp__GetLastError@0 00419150 kernel32:KERNEL32.dll - 0004:00000154 __imp__CloseHandle@4 00419154 kernel32:KERNEL32.dll - 0004:00000158 __imp__HeapDestroy@4 00419158 kernel32:KERNEL32.dll - 0004:0000015c __imp__HeapCreate@12 0041915c kernel32:KERNEL32.dll - 0004:00000160 __imp__VirtualFree@12 00419160 kernel32:KERNEL32.dll - 0004:00000164 __imp__VirtualAlloc@16 00419164 kernel32:KERNEL32.dll - 0004:00000168 __imp__HeapReAlloc@16 00419168 kernel32:KERNEL32.dll - 0004:0000016c __imp__IsBadWritePtr@8 0041916c kernel32:KERNEL32.dll - 0004:00000170 __imp__SetFilePointer@16 00419170 kernel32:KERNEL32.dll - 0004:00000174 __imp__WriteFile@20 00419174 kernel32:KERNEL32.dll - 0004:00000178 __imp__UnhandledExceptionFilter@4 00419178 kernel32:KERNEL32.dll - 0004:0000017c __imp__HeapFree@12 0041917c kernel32:KERNEL32.dll - 0004:00000180 __imp__FreeEnvironmentStringsA@4 00419180 kernel32:KERNEL32.dll - 0004:00000184 __imp__FreeEnvironmentStringsW@4 00419184 kernel32:KERNEL32.dll - 0004:00000188 __imp__WideCharToMultiByte@32 00419188 kernel32:KERNEL32.dll - 0004:0000018c __imp__GetEnvironmentStrings@0 0041918c kernel32:KERNEL32.dll - 0004:00000190 __imp__GetEnvironmentStringsW@0 00419190 kernel32:KERNEL32.dll - 0004:00000194 __imp__RtlUnwind@16 00419194 kernel32:KERNEL32.dll - 0004:00000198 __imp__FlushFileBuffers@4 00419198 kernel32:KERNEL32.dll - 0004:0000019c __imp__SetStdHandle@8 0041919c kernel32:KERNEL32.dll - 0004:000001a0 __imp__ReadFile@20 004191a0 kernel32:KERNEL32.dll - 0004:000001a4 __imp__CreateFileA@28 004191a4 kernel32:KERNEL32.dll - 0004:000001a8 __imp__MultiByteToWideChar@24 004191a8 kernel32:KERNEL32.dll - 0004:000001ac __imp__GetCPInfo@8 004191ac kernel32:KERNEL32.dll - 0004:000001b0 __imp__GetACP@0 004191b0 kernel32:KERNEL32.dll - 0004:000001b4 __imp__GetOEMCP@0 004191b4 kernel32:KERNEL32.dll - 0004:000001b8 __imp__GetProcAddress@8 004191b8 kernel32:KERNEL32.dll - 0004:000001bc __imp__LoadLibraryA@4 004191bc kernel32:KERNEL32.dll - 0004:000001c0 __imp__SetEndOfFile@4 004191c0 kernel32:KERNEL32.dll - 0004:000001c4 __imp__GetStringTypeA@20 004191c4 kernel32:KERNEL32.dll - 0004:000001c8 __imp__GetStringTypeW@16 004191c8 kernel32:KERNEL32.dll - 0004:000001cc __imp__LCMapStringA@24 004191cc kernel32:KERNEL32.dll - 0004:000001d0 __imp__LCMapStringW@24 004191d0 kernel32:KERNEL32.dll - 0004:000001d4 \177KERNEL32_NULL_THUNK_DATA 004191d4 kernel32:KERNEL32.dll - - entry point at 0001:000093f7 - diff --git a/src/mkfont/bmp2txt.cpp b/src/mkfont/bmp2txt.cpp new file mode 100644 index 00000000..26122008 --- /dev/null +++ b/src/mkfont/bmp2txt.cpp @@ -0,0 +1,313 @@ +// bmp2txt.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#pragma hdrstop +#include "hymb.h" +#include "hyfs.h" +#include "hyfile.h" +#include "hyimage.h" + +int main(int argc, char **argv); +int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn); + +// ---------------------------------------------------------------------------- + +BMPTAG btIn; +char *pszInFileName; + +FILETAG ftOut; +char *pszOutFileName; +char szOutFileName[512]; + +// ---------------------------------------------------------------------------- + +int main(int argc, char **argv) + { + int i; + + if (argc > 1) + { + pszInFileName = argv[1]; + } + + if (argc > 2) + { + pszOutFileName = argv[2]; + } + + if (pszInFileName == NULL) + { + printf("usage: bmp2txt infile.bmp [outfile.txt]\n"); + exit(1); + } + + if (pszOutFileName == NULL) + { + pszOutFileName = szOutFileName; + strcpy(pszOutFileName, pszInFileName); + + i = strlen(pszOutFileName); + while (i--) + { + if (pszOutFileName[i] == '\\') + { + break; /* no extension, so don't strip it */ + } + if (pszOutFileName[i] == '.') + { + pszOutFileName[i] = 0; /* strip dot and extension */ + break; /* ready to concatenate our extension */ + } + } + + strcat(pszOutFileName, ".txt"); + } + + if (!strcmp(pszInFileName, pszOutFileName)) + { + printf("Input and output filenames identical\n"); + exit(1); + } + + // read the input bmp file entirely to a malloc'd block + if (fiBmpReadIn(&btIn, pszInFileName) == FALSE) + { + printf("Could not read %s\n", pszInFileName); + exit(1); + } + + printf("Loaded %s, 0x%08x samples\n", pszInFileName, + btIn.iSampleAppend); + + // prepare an output buffer for character set data + FileAllocate(&ftOut, 0x100000); // 64 kbytes + + // search for characters and write character set files + if (fiProcess(&ftOut, &btIn) == FALSE) + { + exit(1); + } + + // ready to write the output we found + FileWriteOut(&ftOut, pszOutFileName); + + // all done my friend + BmpFree(&btIn); + FileFree(&ftOut); + + return 0; + } + +// ---------------------------------------------------------------------------- + +int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn) + { + int m, x, y, t; + int i, j, k, l; + int n, o, p, q /*, u*/; + int r, s; + int cx, cy; + int iCurrent, iState, iSample, iOffset; + int *piTotal, *piRow, *piColumn; + MBHANDLE mbhTotal, mbhRow, mbhColumn; + char *pc; + + cx = pbtIn->pbih->biWidth; + cy = pbtIn->pbih->biHeight; + +#if 0 + if (pbtIn->iChannels != 1) + { + printf("fiProcess: Channels %d (must be 1)\n", + pbtIn->iChannels); + return FALSE; + } +#endif + + // prepare to find total of black values per pixel row + MBAlloc(&mbhTotal, cy * sizeof(int)); + piTotal = (int *)mbhTotal.pcBase; + + // prepare to find row indices of the character lines + MBAlloc(&mbhRow, (cy + 1) * sizeof(int)); + piRow = (int *)mbhRow.pcBase; + + // find blackness of each row and divide into character lines + r = 0; + iState = 0; + iCurrent = cy * pbtIn->iSamplesLine; + for (y = cy - 1; y >= 0; y--) + { + iCurrent -= pbtIn->iSamplesLine; + iSample = iCurrent; + + t = 0; + for (x = 0; x < cx; x++) + { + for (m = 0; m < pbtIn->iChannels; m++) + { + t += pbtIn->pucSample[iSample++] ^ 0xff; + } + } + + piTotal[y] = t; // total of dark pixels for row + + m = (t != 0); // 0 = all white, 1 = something found + if (iState != m) + { + iState = m; + piRow[r++] = y + 1; // record change of state + } + } + + if (iState) + { + piRow[r++] = y + 1; // record change of state to white + } + + // prepare to find column indices of individual characters + MBAlloc(&mbhColumn, (cx + 1) * sizeof(int)); + piColumn = (int *)mbhColumn.pcBase; + + // loop through the character lines found + pc = pftOut->pcBase; + for (i = 0; i < r; i += 2) + { + j = piRow[i + 1]; // start line of region + k = piRow[i]; // line after end of region + + // optional feature to find baseline ignoring descenders + t = 0; + for (y = j; y < k; y++) + { + t += piTotal[y]; // total black counts for region + } + + l = j; // assume line after bottom is baseline + t = t * 2 / (3 * (k - j)); // 2/3 of the average black count + for (y = j; y < k; y++) + { + if (piTotal[y] >= t) // is line blacker than this? + { + l = y; // found the line after baseline + break; + } + } + + // find blackness of each column and divide into characters + s = 0; + iState = 0; + iCurrent = j * pbtIn->iSamplesLine; + iOffset = pbtIn->iSamplesLine - pbtIn->iChannels; + for (x = 0; x < cx; x++) + { + iSample = iCurrent; + iCurrent += pbtIn->iChannels; + + t = 0; + for (y = j; y < k; y++) + { + for (m = 0; m < pbtIn->iChannels; m++) + { + t += pbtIn->pucSample[iSample++] ^ + 0xff; + } + iSample += iOffset; + } + + m = (t != 0); // 0 = all white, 1 = something found + if (iState != m) + { + iState = m; + piColumn[s++] = x; // record change of state + } + } + + if (iState) + { + piColumn[s++] = x; // record change of state to white + } + + // loop through the individual characters found + for (n = 0; n < s; n += 2) + { + o = piColumn[n]; // start column of character + p = piColumn[n + 1]; // column after end of character + + pc += sprintf(pc, "at %d,%d size %d,%d\r\n", + o, cy - j, p + 1 - o, k - j); + + iCurrent = k * pbtIn->iSamplesLine; + iOffset = o * pbtIn->iChannels; + for (y = k - 1; y >= j; y--) + { + iCurrent -= pbtIn->iSamplesLine; + iSample = iCurrent + iOffset; + + q = (y == l) ? '_' : ' '; + /*u = '|';*/ + for (x = o; x < p; x++) + { + t = 0; + for (m = 0; m < pbtIn->iChannels; m++) + { + if + ((pbtIn->pucSample[iSample++] + ^ 0xff) >= 0x80) + { + t = 1; + } + } + if (t) + { + *pc++ = '#'; + *pc++ = '#'; + } + else + { + *pc++ = q; /*u;*/ + *pc++ = q; + } + /*u = q;*/ + } + + *pc++ = q; + *pc++ = q; + *pc++ = '\r'; + *pc++ = '\n'; + } + +#if 0 + /*u = '|';*/ + for (x = o; x < p; x++) + { + *pc++ = ' '; /*u;*/ + *pc++ = ' '; + /*u = ' ';*/ + } + + *pc++ = ' '; + *pc++ = ' '; + *pc++ = '\r'; + *pc++ = '\n'; +#endif + } + + } + + MBFree(&mbhColumn); + MBFree(&mbhRow); + MBFree(&mbhTotal); + + pftOut->pcAppend = pc; + + return TRUE; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/bmp2txt.exe b/src/mkfont/bmp2txt.exe new file mode 100644 index 0000000000000000000000000000000000000000..fdf4e30050f580e98b18b432dbccd4ec8800aaf7 GIT binary patch literal 98350 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� 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 +#include +#include +#include +#include +#pragma hdrstop +#include "hymb.h" +#include "hyfs.h" +#include "hyfile.h" + +int main(int argc, char **argv); +int fiProcess(FILETAG *ftOut, FILETAG *ftIn, int iICS, int iILS); +int iCompare(const void *pvLeft, const void *pvRight); +int iUpdateCRC(char *pcBase, int iCount, int iCRC); + +// ---------------------------------------------------------------------------- + +FILETAG ftIn; +char *pszInFileName; + +FILETAG ftOut; +char *pszOutFileName; +char szOutFileName[512]; + +// ---------------------------------------------------------------------------- + +int main(int argc, char **argv) + { + int i, iSetNo; + + if (argc > 1) + { + pszInFileName = argv[1]; + } + + iSetNo = 0; + if (argc > 2) + { + iSetNo = atoi(argv[2]); + if (iSetNo < 1 || iSetNo > 0xff) + { + pszOutFileName = argv[2]; + if (argc > 3) + { + iSetNo = atoi(argv[3]); + } + } + } + + if (pszInFileName == NULL) + { + printf("usage: chs2cmd infile.txt [outfile.cmd] [setno]\n"); + exit(1); + } + + if (pszOutFileName == NULL) + { + pszOutFileName = szOutFileName; + strcpy(pszOutFileName, pszInFileName); + + i = strlen(pszOutFileName); + while (i--) + { + if (pszOutFileName[i] == '\\') + { + break; /* no extension, so don't strip it */ + } + if (pszOutFileName[i] == '.') + { + pszOutFileName[i] = 0; /* strip dot and extension */ + break; /* ready to concatenate our extension */ + } + } + + strcat(pszOutFileName, ".cmd"); + } + + if (!strcmp(pszInFileName, pszOutFileName)) + { + printf("Input and output filenames identical\n"); + exit(1); + } + + // read the input bmp file entirely to a malloc'd block + FileReadIn(&ftIn, pszInFileName); + + // create output buffer with esc plus character set data + FileCopyPadded(&ftOut, &ftIn, 5, 0); + ftOut.pcBase[0] = 0x1b; + ftOut.pcBase[1] = '.'; + ftOut.pcBase[2] = iSetNo + '0'; + *(short *)&ftOut.pcBase[3] = ftIn.pcAppend - ftIn.pcBase; + + // ready to write the output we found + FileWriteOut(&ftOut, pszOutFileName); + + // all done my friend + FileFree(&ftIn); + FileFree(&ftOut); + + return 0; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/chs2cmd.exe b/src/mkfont/chs2cmd.exe new file mode 100644 index 0000000000000000000000000000000000000000..f355dbb73fb02aab667664572506b3c07440ef26 GIT binary patch literal 73774 zcmeFa4_p<;xi`M&oCOy+c#aB+2`0ygNesrKfJ%-g2jL(Z(W3}R6x0MLQlkcT{nLs$ zWFci)H?e=--nKVw<2CKIZQkCrO|8ve5DTbj;=iUQ@wTM3>C!a`MhmEf{e7R=a}Z6^ z+xNZq_xrrR`<}yRc6Mi;d1mIBnP;AP=9!`3fjyjq<2WA9G&$}deERv=^Y1^p5k30W z7e;f>$NXmULEDnwOkP>Nq0Y0VcJt?J*FWreX#J*5n?=uqm7ZE@lV`&wPwuip&%>K5 zDrdyU$EJi(S1i4p=lR?}C5GLCw8q3K?E4#uF8Hg{|2c6g{AFoRB~FIFFa2AIY3%zu ziHY!UcRrPv0)NGZhpGw3jU^8FIc|w9isPDJyf+-z&5gFj*`hh_X@u;tLeuVo?}mGh zzJ1m^zKJgM3;UeUX2l_l=*B)M9VKS|ut$L$=dp2jT5q5JOtW!1ibDA&e>%jchGtB* zaZVKFvwkzg%IzW|Pks{*D%aB?A71$9;kb1(YAe=@>p5-^Bw}?ZSd?Yt&j*6cu)w%2 zrHE;TLm>0vg?~PT%-CQ7c2S*BcZ(+17nH%(R&Lz<5XY4XfCCK}ocj}S3lJOmMJN!V zK!gGj3PdOnp+JNJ5eh^o5TQVX0uc)Q7f|3e`t|$(OWB@7@p$aSLbqo+y(P!t@k1=n zdPJ<{dg8D^>?xy&=O|)`!eZ$2Xe=Jzr(}PoH^Yg?0hFxgE`qaDvR^Xv6nkhC9;+#g zBe)+CNROT4STX)jcoeDU<@17EFW7cDRlifs=au*h)5mrC2Z-8;uNs?(18 zIQ?}O!&PI`PmIRfd`il>n!XHtol*3$?qeUPCQ_Oed+9r%yFq^Wu%O1%=W_i5`$TC5 z)uKVwKPc-qyf>W`(=7-`!JzAvG4ho)lHKqy6b?T^1o`p|X|&49>L?oQuycmpc)7X) zg$m_!5KVP0pHLZeyA|5hiW+RB8aRh*;6e@dQb_~V+ws(&`q(sqpoXi7Vgc3F6uO6n zy4864>ag9cCbE|Wwizl2+L~rXG-un@#701*CK9f_1XHC19HClUsJ?AwVCD8>_Q6{* z-?cu{Th%|8wf`T`!O*`{Kf2DdgG3S@)Jswegyq%yiGoM121OtE4T$@xPv*<@nIYaa3C*$ssU%}m=)-Pf$Gx)^B{w9erg6c&}d|SpSvNydB=cj z{BV8~KP|sxg87Jbm47_H1k}&H9HR_n2CbgFO0;sLp10G$!r;qxrrI5Tx5J+hsIH(K z_OKiTQ0{ABDSxM8s85Z%hUgN|yDc&RC-M?j=+jv~L{C1w)wnrCyD>^Yxc2HiNII&r z_Ha9PTnV=$rAcJCscjl9+}EJx^U2fzTEV&H`nxPqIHUVn=FeM*X!QCAseRQkD>VPP zfPRuiIKBQs(alnS$$~_7W3-}kEA%f|-z+QYQ|6=6TYJ8a z+NhMx7odz|ylhY{7_{hd`!J-NmBc=r@%j*qYPTws&SF>@lUZ$kbD5EaB|B!lqr7*q z^1o<(1CGclD2oMpMSCJ=LCLl#JX{fBxFR#JRYZT>!eQ|`tCwtIL1Chn5e3mxY^ipz zXRElO?zAY32PAeB4WJN;o1m8qp)a&IeLBORPKHZR7dVw{{(3TBD;@Pa`7l7iR8|iC{S3TN(Tx~%3%Sjv6wrj}EpodwQkGwbA*!b-6qGNp$um|OLjd^# z5~614yhfE3z@p_Syt(htb0?LPMh(IIv6q@Kz zL}?V+iFv%k2EwCiphE(vsn~~`<_7j1`TSp`fW_B|{yt}_?UNG;;u(i!kD8>=O!5uZ z^({W(RF?DAT#z~v2F31j8WhA(6zVVXJzV{0G-{{M-93Xkq!GoM?s{|!htYLr3pC%* zX!JXk1$=c7pVf95LBwcgFzhti6+5uXa|wHa(3$Oi_Y>IJ&;SSc+UoEymFouyzDVd? z;QpfppG0NDMxbe0XplEI+_zA7AaP@Ivc|4Gpx3V>WKM9p5HgnepDbiF6%bDfGj=N{ zLWw>bV(>R2oV?=G5T5%75&kbW_J0BR_5A@NE(jRVAIAzOJQ=uR7`;cd5fd-QQ6Izn zgH;BGxHYY?UI2xph(yK43yqP{LBwAdE_Nl!KsboU>^>W~xn zSE+XS5aB+F(4&O=2ynN_ZFXb#$l{l%J5vOsMtdd&$vD+S+4z$FHY%LxYO!TEwu)Zs zQ@WtqUNDD-b~%pAy=M9$l{L(QY2EPCD%4s)a+4#LpwsYQ7Dh zTq{2R9iNch+p+dTwNjjVIty@8fQ<#*77nlxj6Uw#CjxZzQ|hSgB{jCSS@V5dHYbfi zGQmuoH#wUNn2B@Y$vab=T%o!qB|(`#4h{7SgzZd8kmt`k?&EB`T&@G7YQRnAgC?b=27RjWX|MaZ7Cu|6}78)mA z2j(o4hwfHC5ToRwREekW^moEIoHcy0J~);kh}&x=-XeEn;VH&z{6A}J@{Usi;|=-a zyVZ8d-hXCodD-fA6qDCCVj3uIUmhw}QW#~pSU<3^{{3PpVv75^f~CJ7#>0xX{!@!K zP0Kr8!+lHbt%)rHhLl3}BmHN9M9)idbdCE+eM|j-75nFCdN&n3uK$esTlpl{|F&UQ ze@k^JWy^i=Cnxn+s6iH{x3*wJm8h5HD}3$U{cp+dIz%D$MDwVHi=-=RS6jCL@fn^Q z-ck9FjI|ul>q)3>qdTcw` zS$`+viwVF5jPhlncG|`7n<@XJImO4Roi9+N+{4#8r{dWw%TQ?zd)dJp_$ z@}EQ4SvU?KQ%>+p5>=i#4+-wVGN z{w4UA;19qbfIkR-P~$aJn{)I!2EvpuslrdgJqy=Lxcx%;+9U0IsJ0{Dt(u2IP{!-1 z0aAovHF4&kwlixmME{g)^pF4e;`axUujh8;V)nlUDj%Qf+3ORvlmHR|8=$s5c34Rj%1o#Q?-SFM; zo$#IT1^5Dd9zK74yIAx|1HQR%`EY9pceq{h9H{+>c3|JA?T9u&-2h{SUDs}A<{I#4 z;-xwbfYQ=-3}e1~+ii^PkQr1{YpFCo3&Tw$mdoqrXe;dZkQerLM}e0U+m#0#QldBW zHGFTouUP+gSbrg*m{Hy?57?!nuMlzq{-K#LF_fUM2GjYP`Bt>QLK(?xC@9yM|>75xQ7E?x8B6zlmdr>_pN8Rx79B8bOhK z8V4++8nfE-9LYwdm>Tw?UARDnf<^$E^KJ|frBXK&0{~Ay*>YM*bfa^qT@CNj&WIB4 z#8=z9g5#(XFVL&*-p9j-r1vbyf}*02CF|b?Y^hv1$muVqqI)MU0k(a)kks@qK|0%) zixhgwogAlE-GN8l-%N9_2VwhC@CcZhN$||f1cG|x&!mdO0u?IG?SNDL=T$+CQ3|>P z%k^haYA_!a1(v$?8br(Ummrm0jM8Zh%UI92&v9He72ZsI8sZ!=t6`v5!ayJ3r8ERZ za-k&_np@rasx;P8;1m#|(oUdwF>a>pm z?zOAS+tXXY4Z&TxV(~WcOlMzSyjz@BtWQR{f>rS!$W=+4d^;ys30!G;J6NW(&j*N6 z0o_E!5d_xPa6TVA4Na@oJJb7GZe7^;jv`%Br1MI>)75w>8pExiH~pjmHAk;19Zx@* zRdn99`z*qPS3Nt&1+Q*@bhPW0_LiU%{YLI~8TRy6*DH-3)A89hz{>-p6#sG8m%oh! zm~wN{0aVayDn+j;MQ45?^$TQ*m~~8OR!)t*pq36*n6f^$kn@~DH>E7`rq(HUNT&FEdk(Th zi^LhhtJR_>cy*&VHh2~M@M#J!_*m%qCzf{5-SdR?;^}FksQYG13BgBg8Pe#53jr4d z-Fr47LMb|Ktq4FI*MauF+-zG=oT&NF(?|xP0{WwXYPl67U?I|sjHsdv4m*3M!Y7gr zeBSkBGFn+4sB~%HKzEl1R=J)u@ZxIRPT_ivtMPmI1hu!oZIrR$*VKdgyQ<$mm?lU( zRX~+`O{v1H)LD+50=bMg*)BF4%3*rRVtK114bwo~~YWDns zs9AZIYL3{RefZqFpD5uU2=qJwnSIK`e%!yWoR7GAJKTXm~G(v|@r>-^)p(LqKNYO8_V(>|;r084iA)1v9eV zEybfDZQ9Gf0--?R68&2rlBhF?vdH=dS0fQw)}vgF-^B~a)JUGVoCaXy$4HZpu%9v* zjL0KM)#*PCF3lP9Qrk`p^gNFctMyr(v9)0}yC?+ba-zd$Tu5!}d6FgT6_5<6N5Sj! z4+cSdFhfo(Yw@4%@c%W9$0o!%P>*Z&8%BNzg3^dyRKad!vUa%{Er>WzsTfnG7M!nA z1S1N*B7|DKX9~3kx)so4H4fO1gCd3sn8N#rDK)YwwKy41AL~j^y^F$KueN^6n5w_T z-hbI@d^8Lo=>N(RcI)3GKm8=dh&MN#e00K2EWGQ+^q;{>RqgG6n<%YbF?h9Cy+Zj) z4*4(8?Dul@F`?Escua%+YDZkBgtv3(YQLoYEPtuiYo!-q&dpqtO(18wq{w)@!N})7Nen z;}GgW^PnNoBfC?jbE(p$zILZHHpGOAYdrb{#6onV5Y7KrCVXI;o@IshwPX17weurV zr0IVKI;4>6&vIh6Tz`q%MRixp2DI&FmFma=o~}TSJ|0p6WQo#Uv$TTq%Ym4M>$LfU z)N1E4)a|&D7%GY>T{5Ks{RJx)jm3*2OZiABRlU=i`7q}-jl*UmL$UM>TsuT^{~MWEI8k z^^p>-CZVadTpD$dL*F){y&d(V)Q)`=Q-cN7DD<<^edn-p0`;ZIP(CS{6sLbc)f|ox zYHrfM(g(JZe&pbDV0~&LB~kb>a;pcr(fOpO+WFV?lfP=E$V2K!Z39vAd$+25(>fl~ zB;N~qiPS+Ia*Qdrc@{KW_PmB9r_0;*XTWTN^GN~7iBUawpg>GI#!^+ww>4bm(7U!d zty$CcOFr9Jp>`FknUrH2mfHtT^yL=Yg5~1qVC4|kTrk+||G36(!~`op2Adg#P^A^b z)-YA&a&)S}089>UronYM8O5<5X?Ok7A3MeGJQC6n(Ha!`CwE*Io=!}9Ab0<}humCY z|GVlLitVpRNpM(i?>bJcMil9*_O3$(lz4i!vv=zWDcwaMbDoXKa|fr7#jMuwIhx0+(JcxCoy;d= z05fqNFd(0sMJjQZ)QF`eSdxAP z2~lNNSk+L0%Wyd5^}r@&Cb`&OhRxiu57h&2NmhIS63a!cm zZCg~V=K~3ihkF&K3+jv_k|T~owU|DqVTfV9MgOvkAjL$5>47Xj@Go8m9hfYTZZll5FiXGUchQ_~7KJ)Feo_?;w07o@&z>^)#MnRSqpk(V8>J+Ddaa zd)w*~XtOLe;B2@;ja55JZcQ+BG&rb)l`|AFg-ny2?JiM=n5iYtREjRC#aJW3Qsh$KA)8X>lye%^b(AT5!vc5hV<&M^72B&*1w{O_cPK`>6D62D(U`0)?q&eP(N7&b zj0Av)CWulVW)o_e({PYqD5$G>N5LiK0oa*1$&>;wD+C4MC$7uCY(V}Kign4=L|i6S z8o;F8c9pNWPm!GWmwSJ|)vo@Y3|&qD2PO2riI6wFZ;KCM@>Cz;y^jczPrmA@OMZow z{@AGx`rn)^qU1{)JQ;=wlV=*YYWH`uXcqarRc?xBC4U4Z2P#2b#4Ag!cV1m2C`++y zq3V>u?(-5S3EsC|jSa|zR1Xar8nlS z8A|DM%g;1Z>sokKpL-}j#{$TA2Y2LfQjENgA7UZ$b|{B76k=>_ahh+kAae_B>B205 zcoXaOY9b96jSseU+tn@xnA)W+8FPNQmY=XZpwFF#l4H0ZcAD`tO1x22r>(sFu#mup z3mZ~^Q07zh_EBtD%O#&r7?DR|F>-;bI?tCUK+aU8SfvIGNEoFhKTB&QZO)ODDDj@PHs=|mJK4J z_Al_I9qQZOGX$1+9at2=jQ6}}q*4IYjgh}3p#LBYkjDFz?)GrHcoxUtKLGq_eJ+jN zGfnRRR7@z;-^ORDdcPZHA~|k(uF0(PTnJPqu~O!^RkwTvN|8Y^LEXKF+DzTKCpTQ) zIjR-3C3i~Ez!d2cDbKY0+_*PY>5?=-{YoR?P5&SwAz!IOQ?lZIC-#t?@X>Vh1_pCU zT>`wXOYxy>YCOnfZPSsRQ77JAX!NTEm(-P)c{Mf_!{Y)Lv28>AQhDgUU0^fi-hNkO zJlK@FnD;Igr1i4tsZX^Az#FFwFbr+yTyPwv?EI89&AAHPkV~3Ns_laFljDq;+Ojb3 z3BhW+S@#5!nmFV_GAS+ud_T`dtP1PFFY++I=9C>ga#g=5C_4mKBeQEnNq1hr_`RTf zk%y%g408aXz%tD$T}8{1XkH$|_>HTdHq;iZkK>vVBE`K5Vg=RLPkk8U9ezc5Vs`MutwTRXvWwPntz0rX*58~{wo7PQ4qC7+CJ`5JrNP&dm($WU)YjMv z*3-N+M{>k$=NXSxkDdB!|H;WP&7@6zrZJb#Gt)3XX~&^LRez^#nUK01X3TEvHMRZK zr5^pn5L`C6$cw?{R@Y>)eN3fn(DlSxlnU!?SJN`QINtJJbUo?E8@h(Y@b1HC+!|eT zUnzWbE$>|`Ncmucb+?A*b96p!iH*(pduYZ_rCD>LkpjN>35cf{KN&IUFB5=L!R)_` zS0AN8hAr>Z*KGyN^2_zak3bW(9wxlbHj`hbEtxqen@sdrtCn5TlCLUdZb%B0zRazZ z3JREQDX-iw;OQ+Dq%|!|M)BYl%?0CVE*-_!O%B$N8=gxU^T1rHYI!zg0rsP34fHGo5n&se1J9-1LliA@ zP6K9)(fbFrHR%|nZb($b=nw#2Mn9@%4VXTZvC6<)J#_;mcx`IVADIwfo|4A8Ti9Da!k8M}Z|DJsEO%GcITEa<) z{SpUjI6n`4gKd!&! zNpCI9@}JjUK8ywD#UHzNzl~Bd3X@_hR4`Z5Ov3NKgvI$DVu~ z^d7w2L|~(_z)&xXV;4bR!edZ8N&FDvgORMZVZ$b09$?e`DzmYPGSw_kzU+4GeiM*= zZ7x^SZ}8G^nfR;g$u_)a?Sw@JKhxFp96r=u??<)YbTvIgK!=F`=EzqC*X}A5NtMok z3ui^Un!buyxpDyd2Fe9ikZK+;SN3w+E&)q}4r~y)8h=6ks|V*1eLPCx?Qk`bu7otV;vL|!Bzw9JqGZ8SdW`>U zjQ=zfK8Hij#rXBCTHe*vMWx50$=~Y*FQNXQHNn;N6Zp``%FskYvhk_?uHAMuLQ7oKQ|7ov7 zTC4hXZw@b&Ku$IN-Pqeg@AR@6+qHW=z(RYfI!MT$4zAv`qgk?b5p%$#$TI z$0TM$&qr@6EHQse+~?mAevoi`d!<|C`Siv~QTxcpZaVu)-bcQXs6_9j7i_00ne>9b zrle_KrkifGC+J{+l9!-iyLG8k+2zLWYx?`Yx`5F1lk&%I*LMyro^oQbUvWcXfYj3P zF%6rYf5Kv^MBnii)7L^8aTV7`Ie>Jgwop(;buQ$4@zKypg*MKr9mX9YtqUX^ zTGcfSQCY*`isoG$N3 zGNs#VY+APG0a^$-7Z63SFp7R?`O>K6I$5cgdRZaGShCG=JsCg{n|-L?y+DL3R*!nK z-CLu)*$K7S_V*qY=NKRCcS$qV-WSkUxQ6#kVg?`8dT4K48BIF#5UWUSQ%0vADhIpM zas`3yqZ3-FfP~b1ciUyBmfMv?N?q51F*bK_GS@Jd2-4}}sar@B%qXh5JfEH(ST(ry zXTZctnJB!R$V+Wgq88Jt&e~a3cL~}PNuaOVnc5-iNo@l#UU51Oc`t+Y)!n1Iu=MdB z+j&#gT7GL{Ar{iVLJcgnsYI%RwY=OJ!oWmYmaewTS|{Z}YvI;*C1Kg?#SY?NUAj8T z+rD!mAxkL4e(|7QGmP$b;A+4DA8MaY!COC2d(y%(+sleACidij)(ZQWb}I}IdhSGG zHqz7q`B4~cMaz#mv6HFZ2TRDt-+>~AuC8@bA5t%>?Wz6p2T5&1j<)xlj%{w)YeLIh zKj^NHLsO%FpxMO_Q6&ie-ImlJz~0tCXaNFlOPmy=Um7UZZ+a7qtq6Ob&Zd*0Vbqb^1hZgJdQ+KC4WWIR2=DExbIMsJ3|89& z<0Eg^&8<_~l!auX-wbn$wZb&Vv^*Y?nxH*Sy+;{sWat^Nn?moNrslhwO9gG^M1hSu zWem$T^%Pc}t^=p01(LJ|N<(VK@VbDOL^z#=&hQ9dqGoB|BF5nT2vfS+Nt%br8b6_V zg15bHlx@tk<-8Fiuje@}TTpCZ9zCxE*wG)nmlI(Sre(Oj7wd9bk{aKU(lB;b*~)`n zSexYJ8U5am>Xzd8pcDle(tu#=%qnua9{U!Olfd3?M7a)JbTAB(Q2Vm>h~Vw7+okd2 zy?&u?YfE%vtKsUIm538_`EM+9YNvl}gF%=R9t8#m2Q z8P#T}7mc4_zsu2U{HvBc-b!}}>9WJ=s6x%-wLIYqM_jPhN^QHIMj#O6@nYA3SS+3d z)`Qwp7rNU9oZf;2ZD(iF*0DI@mD<&8x4FPiY4jQE>M9YYW!N>D(X^wsNaM$NJL+Pw z%Pe7+`I5IoTF~N8z*#GY_xQF{Z|~MSLa@Dc3F)m$`rK$~lrK0hniDT8IaJh#K>Hj) zaikU`AR`F>L_q&wxH0AP9@?NSwD?X5>{hZ886$R>{&VVLw|p7H{5;agl{(xdPJK&T zfZ=#v`w|ZBn9>BMe2mFjfbB&ZFQ)%e4{fol>DrUjf4vu6@?rSFEJ$gscu7ApxnN*& zLGNTNZ8BWmbSWA#12!emBcvEeCm2WB#$r0!7T{glSCN8FsY{9KA@9OL*KW3O@t?=R zcE}4Bb6<{q$=Qwz-Z$$<2j@-Tqz$eE;zVJAab7*D7Ij0I1K`fDk*Fm|FozuA#AT*m z{}p2st%Bn%$K{54o%l3r<=TA*i7aCqt`HvvHN-o53@|_}*C9#_tum(8d~95XeDOEP z6c-?4ybt-J2Xe-rA=J<&g4`V=xAupr3zI!T&jiV#=MRZ!t1xl68WRyFUyYKS@;ZUk z_&p@2$yaTz#y*r5XUM^R6%4Zir^4Q0ok3=`mgE&bfT6D@4&v!JQS3chpQvRlN#=R-j; zoRA1_%$cu^2zrcyQszH7B8X%zR*)LOJXNZ&*V1xBpsFuN2>8@K zsxQ$vhRh=qw_|2sUDnP{>BMs=byi{!H7hcr^av)t0(H0Ppn&8bl+ zHZ2e&f@QU{U8r@m0bC+Q>AP+MZ8LL`SGw5}eNVeMcHVr^wy;>=_#4b|SnApgUE^Oy zSHL|5@u$%ddP}_*l}xhI!(14nf9(w5)cJ&A?yX{05$sQqQq@cS!TaWmw-xDUPQk>d zy;O;2;1vX3V$Rl+U&9OJ+ET~Ib8nT7l$op$`XDBOQe_gMQ*K#X-We4@NzoCw)uH*8 z_Rxk)-#U@wUfBp(w!K&!+FsmC28K#z8p72fY!KRUWCJESwEI^GbK3%7gV_Wr68L5) zu~9y?7uKWRizuO>ANn0i5QYa^(D=s##U=U#mWnKL@)c&6xVC&B875kaA+-RTVhM%C z@?_``u|~`zL&8Q^Q0B;;JnXiDb8nM!TLLy;@XBrCG#nY4>N;?;@3Cx0Hph!j z(*~>0=oWYL_>b|1EnrUS}VC@OCbb5ajuc92OGAqFdZP*MYbD0}pjIcB5u3Zi0;>II`Sf;k2X~S$G^#HSL{# zc8)Rqo#5Ox67PfBkBT%M$}DLr*2wiqVtjDB?KUl7lX&%z;ZSgv0=9-QBusLB{g6_W zbizHpRXz_NxE!#AEkDv^BaNg#6V%8udpysTv({&rev7EQ+2N)&MMNs zf7}`}xj1q&rLeGw4jZKa%KRPlq@(fS)=#6?mMUu?V3ucEeDpqyT3Z#u?ehx#@!nE^6 zBU)uR)6s8s<*5#`N}1hK0R4weoYB`NNO36TH&IH+hqtJm>KkOn@^09SMdQ2FI7I+_ zb3VV&FSqmFp`9 z$jnZ$#Rl{roIC$2SRZyt^`5uK+RBf00=6~OoVbF3v$GG)K!AI#R)S~ zaR$!SrHFTG8CzB7&lN1ZlzgYW6NZ-3*lHV^NzMJap!<;8T={dsXs>uOicp~=qA*yn zRjBdw-LQkFj3hU%bWm3~vz7~zb?CaiaQTaF%!x*9=mp|9DNb{E=)-07}lFTIWPx58uz!29erf;7Is6zdRBo!Uz5nEiS|DJsaNLFK0aW+R^Pf`^Bq>|%A zS^)_VrDi;7?4>0TXCxm49iY7+a3g|mRK&atf zvUevdmw51qyX5)Lz~IUzO|GWP9rPqT_KLP_vZZ6kJgIN##J<=vw&6Uf?{KggR$Ly? z(d!mz{gyqS%ush;C{{1Dz31?LgQ8qb$p8&!2HRTTK!)+546PMn!xhTa)kqS&*0ctN zw9J37&|~&LNH8uGzW?Vw2o|oxU?8PdP)R_0nUd&#MW7D`b@R4Pvtk1J?+}E^oS~F; zZ;it-Q2h)rl;~w+slT|jrgb25bu+{It9EEKSwKlZe`)xmx{<~H7y;&i6x7Lr3FzNK zNVVHz3k6iKVQ|~W5a#J?4LWL}u>>_-020h%Dl}edpqr&3jFJ2dJe;kdv6Ft%BBj7c zxgbPJ^-x>4!`n=hlt!sR${qcind^BO=c;wkXP4Z4Yun{0)v3`yZpppojl(ve|(&_EQZBlv8{Xubb%E#C$G)BowogVp^ zi3BoOx)QxsZO8b8;hfczFsLwxz5_9UnF{VI*n1A#M&+MFr<<$hJNw#XF^$f7+9X#% zp8@iN&z6dla*UfOl#|Bwwb{kd0exI3O0vfdKuX*GXIf~uPuv=|Q(@&}$ zkAIR2L++>l)t86$oL4|gapC-NGNyo9Yn zD$0KI%9I570(@ux+c0B(o1@Ixq(FyY(M!tR`yX>PUIZQX`&>;1`8IJpHT-_JtMMIt zt4oEHA!RhW2H+_|u5@xKA3E(-KXlq?Z}~RssEjCtj>*Io>SLjn#zZZRD%O{wo0Zae z8NpT}R)l&XOgo{xTbi_}$%JXoE_X?wP=6DeJt%rG!t5-CV4<{niq5CK@W1(WI09^C2d%(U^d( zv2h-|_kSxcsd1#6<)KlSJ7N@muFvO`#rS|efk;Dx&xXy-gq;%@jG6JAzVirDDM5#VoEqj5H8ZpR)!U z54my@#T8e#QUsQ5&$1X-BdNk_?5p+>4x&|x>Q4rysJ%46O&BZSBjULdsGs%^6=I0bU;8i97Y zMxgH`&6en{><$4O7aG1sAgbk-JmYxq>fJ~sMau;Vb|WfyHC2j6ID%lA4zYUoZp`3B zvqqV{q`02^B3^0`S1P3hucnDOv*3t7M$^EJWIO(i`Rd{G7cd>f{vaG`2aD@TRI31IF(u`T*y2fEK zGI}IvmCA3K(g`-bm>q|Del%HGb;&(*yan#M*{U>v+6rFjQf&f;X{Zda10f$4}C1V*N-7CLq z7wKY15FxlN1}9&pXZZ)V-qGhzuvt^aZHNIUfsL9m2AG5I+WX$R`AGj;4mvFb;z@1rbSMqQ88G5-PYj7=%G~gN9o?sKt$X|#ER(uNcxJGCZGpMEJ#;&YR*?d; z2f7oXP(6d&4=^c&?s0*2b?kzf}=bA z>Bn%6|FV3+q)SxZNbkVSE)DO}Jt|W2RCb-pDe`QR(C{9SKssE$b~VW=3kK(&5ohC` zl@I5h74N`3B!9tKPy{6+=q!Sw5p>%4M)_K+#0!Ryu3cO3vE>btM>QhJ7K5&33{E_d zE?`5;BR1TpvJ6Jdm~UG~<;^|LP{y@H(`zi0*?%ivy%r^)fL_Vac9|{f?a1uTmT26N zFt=Me+>-4;A(C3EaI^pc;vbBk!ZdjG+Ll8-ryyZ!3&G#lwyT}=#NaC_E`%w}pKiyc z6wq4qr?-Ce6SUqjbqF)!#UHffndwLFS!izKMSjtu{u653YP#4U+$ziGllD|YEou`Q zdg%RbdNkQsc-{HbF7@(tf_F!H_$H^Onhf$(|UZvcNc zKKFR=SOT{N?jO2uf{^20f??Ru9R@etH$hOJe&0kW{f7WJ3wIjsHMqlYFTp(z_beRl zDL99F3jUM#O)yHBRADzc`@!Su05biY!3Af9C=DrCwLz0|<307~$1Viep%;#yshk({d`<{?IF1i|v>Fwmf zGmr?g(!^R^Lc3so*GIIN)%-f<=fvkB1TeWF1&}p9Sl+zqgBDh<$6dP&;l&^S2x@4o zzFd!gNc^t;11xCCxK1nhuw_gmPPhI9AFc!0CNz-VL#{7>ji8#D7S?Bca1G_fA8Q#a zAZWC`$NxzCu8tC6_f0(}PH$OmvoyfithwUt+=iPU2V1^+900-|LgT|W``@y&gISz( znzmBgVbwm!*S3L@ol*1bmTEGvk7}=XP{9tIMcP->5cB=-m+qsof8Qtqf*mH7?fIC> zAjeoG6nyhZ15kURSl<+hm;= zC&+rd=*$;sS$vS^p>{ermOXh$Bkc#r(0fUZuM|b4_Cu?M3eD)Uk7~gvfjTfA-*7%5 z3Z(L%FNVPvk#0m+7*Cz1^%W|1b7Rzb%n&|YIB}`P|4~O1eR(jM%)x>FqKnwV#73yM zZQCT+!@tBpvk!XkQ{Mv1y!d1F7?#)t>Y zp)IDPXHQ>3^AHRsdn>khIJ($Mr0<3@j=|vi-Wy@6=@efGt^#oK;WdyvHOjI|9fN}; z;&`j+-7Q~_qD-3i_&^&Yx$lr&bX!p#iUMxqPr;`tlJjL}g8;7@i$YY92eNA?$^#E< zO9p#iF`^F(I1O<+Rnk^ zz2;**8M&9@mh8};kF{471QhnF7F6@kgQX@OM$aKdy!d%FvlZ{v16V_pm~Y~64?&87 zYTXK`K283r2f3vQliw<8! zHy-L;>)N~DgR4x3=yXfyDmtfi6`jU-H43kuus5uG*mlI8j;d_ZTQIvgEP2?Sk@ZO9UW zHYI@=UN5*F{|iDe;9&KEt-#a*7$Laprs0*=2Qk6RvC=5)y?1c&zGeXj4YmJ4kf}#4 zL&}}6ks6YPU~lmf6oS@QNkDa&8EKX#5S7k>p{5OnI-NTqH901b{_F#V;70TEV3f95!Za;A@!x^(E8@%L(IOuK_wbZdybUzyjG}mI zsjT`0STZtIkaY?dcfBO+rC3rJO){lq(#MQY6yO6(iX*i1iLwCiw-OPv!oR=#)Z{HxNU=lsAcD} z>d%T*P(+=zav)t%2rnvKfXcEcQfOJEPaP8Ms6O&AB@ zZV<533yZLiaScY(SeZa(5WF z76^_v4ZZCzQR*M8%?&DhvBm33>Tturr?EPD-b_=P9ohk7x0k|1S?5G|z9{5N;|gJ4 zEfm7g+EG~3XC|H{GL2G_)6!d4e-T1y+{-mN#g>PbAWOVT+3N@rok}$vva;S(D+3dN!$*zQ3u_TlAN5J5qD!N5gNx3;*YvDRc2&>uwiErmQ_tfCYN}V=?FzL=Reg!Th31S z8$VArsgL8XhVeCa{SgFX^H|rbsdnC9mx{?HI&F=TjMa^91hyY*(NNVPWxZdbA0}cs zN@=p>n%);fj*2HBJNj5)QLJ$JL`9`?*&PwHFd)Th|Qcv+VgCdp^&e2ifx__H1R( z!|d6`p0BazarQjTo@dzeEPHn2$u?!Z%m@PmwL^WK+IiSCq%XG%O+3F4GhYo?tRKQv zDX{c7Mm9EB!Q4vwRK@zU6iW9aBFKqNonrml2qEdUoi2X6uFr=g=W@E(*IDDklPQX? z-$O{oHYm*eiu>AvCAhlBi5{qw>0%6y-FEm*w-FbtG`UXyd2m+zpXea8lwH!8zF+$! zAuH-R8`e;`0?Z87IMlZCDIKZp;@$b;#MyFB2b>o?M1+dtrwUR0!BBN2BZ(Nu0Y!5NN6IR z78u=guLX|?j><>}p=d$yN)Ucir#OymOt3ILF{K~@bYpjjLi~$upe-rTqtDiN7zUJa z{a9iMEKo3F_q)Yt_U_j2rHh2lKn(Q$;nUdEy=Z7yxznx}?*3vI6@d|+LkFTMQydGG z6!lz;=$r9M9V^Tn{aAKDj_i38U}PmEdd^i z4cuP_Fxs+#p`l!lTX)_NKM$>j^kCnid~s5XFKS*aR{RBS+&}Elmf1p0-;tXZ6>BZs zuw;|m%h|F`x7y$yi}*EBr8tot>i0DAtjVM2UdnLbVYccdQ|5sFG_^p_?NnYINxft% z!ui}Zo~>4~_M|-{Yyias?~9dqCvVtOt~TR8g5WIc0Pccwba~sbL*$Z=0Su$2g`0;J z8fh2j#fx!R{F{Dv&sXrd2>WhzNr3PL=f+}t&+oPy0-9EBFxABklzG-CIF2Zw-6m9%9!S@cS>==dNWpv>KGMkB!PF)g|a#i zi5KlpF|gc3z9>J6IWG6?^~PCsL)uExtCM~w|#e+wkqaOZ^vn9LMv>V8ZGK&fF{){NB19cS>3kcCQkCcr{$gpgYIzzss1wz7?HS<=RnDdW8@ zZLd&Wr^0brm_Q(Fz5A#U-$2*y`=Emx6Fd^6B~Wv0)l{z4(NW%hjprMoN`~`oH>VQ& zGN)1(GpAB@!m>fck5C{&fd~a66o^nDLV*YcA{2;FAVPr%1tJuPP#{8q2n8Y(h)^Ix zfd~a66o^nDLV*YcA{2;FAVPr%1tJuPP#{8q2n8Y(h)^Ixfd~a66o^nDLV^EVDF7SA z$S*>H2n8Y(h)^Ixfd~cuV+u6CcrO9b*{T^~Xb+B2;D;j`X761-j!*T`p{Qs&VCCi< z(Ok6M&HMfSDEi^f^Z)^S?wlJ~HA>*-q@|Sva4O5=p<|Amu&#O?ejK-D%Xa((K;X=l zAixvwN1xoC+$K)qHsWs@CE@PeByHS?*R^XGE?Kr9d&$~-e|BJPp?`@#XQe-v!V3zE zb5^Vz8BXbHrA^|7hbujmwY8gTJscMw%W*50EGsOuLgo;!rVx_0La{U&Dh9kH+1h;9k=&9VaS^9jn zr*6yohblc)$a~}FZ5u`;TrY0eyy;rH*`JxNPOSJl=`tzZ7OA$3tjWkBW1_)Pq3H*c!kzCrxldXYSjNL3sz*UT(Rcdg!=w^Rc0=1p~*L5GUU zts5R10UM%G<@PO=4~dl(j561#$Ps;JGWtl!F$D9lv{Bq3R@YXpuK{Q27T4|~MQ+J`r6x}MHytUjOGK9!q5!Ofc>hr0v>uWzR5nx@IzG<_FPE{K>BfCwX_iWj`VUx(Z0YWM&D=c~zY}Ll0MAU!-co#>yGucG0tXvm~+)gqL|%*Hwy}HkZ+M3pWEHYB_QA%et7`RtF1)VIh&=86-?J&g>Qz#Gc|4Q_G>AZ zFde*SYTa~C+IEWaJh(%wtQ!U(Tr02vv1rpsY-~$n>NO~i%RvzBYkU?W!c$VaL9ARR zi6b#>qcEfjXGm~4o44!;tgpb{z(~l45c=t5r0UZy!VVAqA0yts`J9hyhV#W_Gs=)} zv$p8iH{FJIjnIU|Hd?lR4qb*2n8Y(h)^Ixfd~a66o^nDLV*YcA{2;FAVPr%1tJuPP#{8q z2n8Y(h)^Ixfd~a66o^nDLV*YcA{2;FAVPuvn7V*ILi#NH zo8XJ^Z-ze)elq+7_}k(0@aaJKrRRLy7vZ0SKM21Yz6t+0{0FyuxYeY@uES)YVIb>{compN|cu5igL z5VA!X4@d1r4%srF`W3YW{U2ZYSDCoWg0&^}0Vf<0jeKff@~K}?9QDm`9O0$3Ot^9I4W~P$bSqz#mjIM-v~!|z5+K5?z^Gyz3{1g&%jZB{|ZNNzl5Xmy$(n5 zzk{RrBoKw@6Zu6b5TQVX0uc&CC=j7QgaQ!?L?{rU!2ka!aHq#MThC z18`Mv|JA<;Ev`|tp7Y}tLEKjN5H6JCzH46@x`eMX9K`k0-E%ooZ7ojtg#*83%f~H> z*&A^KAonlqeMP19^*#1QC;d3?C`-Bd;fHZ#aLI;EmD!wV1FquA+B)2K$Z@yRSHb2A zX=7zRKsEw^OSu+C$L^NmbRj}xDAa%L!oTA6wHxT(L)?8g0;3;y;eChYpIccc)^6Ux z{WJTr&H-}VtM+2+&P7(d7sFpx!MTIBMRg0-SFi(t0kM|*pZ20n)vQ<*{_PJ{ZlOCG zQ6$__$ZmsqMR5TRHFD86)GUOE z6Fxm0>V=2xg_WX3FC3-ZBti#4u!UlU707Xk^i9-TxnoNu7qDX2ht?>*J_KcYm9=z$&~v|{_v{=f zNM;h;GJgTR-%Ib*eX=VmYN@Mnhir7tGjxq2u--%vbnhX%LXqQs#N}<2>Z++^3#6(l zbQ+GUp}JE@fG%vLmUz{+B&T5g7K?1a(mL`RCEH0UM$qPFE@$KBx=?@P?)R@)>R%GR zJ24}4Vw5t-=927m#*`6;TTfX0n<|!7S>M;jPvk8^fd~a66o^nDLV*YcA{2;FAVPuv zPbuK$xK+q7WoG%zoiiI}erx6rX8vgAb2AUj{PoPg%)C4^cGkpMx6HbGR>rKnSr5!w zH|vpETW2-S(q?^U)(>VqJL{*jUYyl7>-Aah%xX@5Exk8=UdFnNLm5xZ1ws$@32oTp zPFt9^B&|4Yb=ptTUPx<8JCXLgwBM)cX||a$Ge^(7Y38jnGiQ2{_cvz#bmrSLKbU#< zto&KhEM?aA^gZeSl>WW+XVUklKb!vB^sDKK8Oa%*jFgN!Gp1*xWn^T`&3G)MIb(Om zo{X<&T*-*a^km+VIXyEiGb3|(=9e=6XXf*n2Qy#FY|T8J*_HWP=JCv%W_xC*%)WE> z^x4~HKR^5M>spk%pH?8AuEtooK=orAQ6OE1FTSMs5RUgVU4lITRqVL6p5lyZ1rr?Q3l$J3eZ(lj_TW+>47pU4+y#2s;8ybu+lfovhWN-q1$P#G>ikX16FE~#tkj(V)h)Jye78GQ`HtLNAd1c6>af&O5m zuJP$XgS)5zDD1oBj_Bug6^Xys0_VAb?o+bC)=_^>_PSzJKA1k|86(XBmaWV zqhHYtbPLU)_vjz=6@5$nSYy_bdD&K$!@g%1*kyK`-Dj1oE^o}+@d*AYKcQ>k5m6#h zm{Q3wnJfLANN2bjr>YL8DAQw$26w?TPzmb7*6@9Z;UMUNGvFe)9%jRR@Ho5(Z^NhX zIeZQM%r<5((=lh53(S*R-&f72W`*f*HL{vn)2#$6&#Hy)p?{ERb34MGV8_|HcBS16 zhvO8y9Phw+_!)kI0|+4>k|;8ZtRu%r0jVGceTR0XlFp|OsKEkQE#8!O`kLbvC#eZn;}WrKr^^ zNByjd)eWU5IzjtRdoKvI)s+~cD=`Jcf)!v3$N~q!51B)=BH7HCB82JgTRYshd5{j<-|no%Ru(NSEzLb}ifqTbSc8 zJRZm6Id~5~h#%ro97wv8-b9ixGMbDh2_%`UCA&zO)=pIL}1@)_XR>d#5rq8C1&Vf;2B1iypL9)(2V{gso48s9wKP z;X3GrS#XbD!}i0&Fc0R#(@;O;yL<$E1bhU11bhU11bhU11gZ&y^@UZtGsDnl0P1b8 g5yCw)=T7l_86WMLKJ~L1u?e34fA!icE+)$O58R6%UH||9 literal 0 HcmV?d00001 diff --git a/src/mkfont/hyfile.cpp b/src/mkfont/hyfile.cpp new file mode 100644 index 00000000..f39efc35 --- /dev/null +++ b/src/mkfont/hyfile.cpp @@ -0,0 +1,307 @@ +// hyfile.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#pragma hdrstop +#include "hymb.h" +#include "hyfs.h" +#include "hyfile.h" + +// ---------------------------------------------------------------------------- + +int fiFileAllocate(FILETAG *pft, int iSize) + { + // zero the entire file tag item data area, avoiding leaks + memset(pft, 0, sizeof(FILETAG)); + + // allocate via the lower level wrapper, relying on the fact + // that the FILETAG structure is compatible with MBHANDLE !! + if (fiMBAlloc((MBHANDLE *) pft, iSize) == 0) + { + return FALSE; // indicates failure to allocate block + } + + // set position to start and file to null + pft->pcPosition = pft->pcBase; + pft->pcAppend = pft->pcBase; + + // say it is now allocated + return TRUE; + } + +int fiFileFree(FILETAG *pft) + { + // free via the lower level wrapper, relying on the fact + // that the FILETAG structure is compatible with MBHANDLE !! + if (fiMBFree((MBHANDLE *) pft) == 0) + { + return FALSE; // indicates failure to free block + } + + // zero the entire file tag item data area, avoiding leaks + memset(pft, 0, sizeof(FILETAG)); + + return TRUE; // indicates block freed and tag item zeroed + } + +// ---------------------------------------------------------------------------- + +int fiFileWriteOut(FILETAG *pft, char *pszName) + { + int iSize; + FSHANDLE fsh; + + // attempt to create or truncate file for writing + if (fiFSCreate(&fsh, pszName) == FALSE) + { + return FALSE; // probably directory not found + } + + // attempt to write the exact amount of data + iSize = iFileSize(pft); + if (iFSWrite(&fsh, pft->pcBase, iSize) != iSize) + { + fiFSClose(&fsh); + return FALSE; + } + + fiFSClose(&fsh); + return TRUE; // says we wrote the file + } + +int fiFileReadIn(FILETAG *pft, char *pszName) + { + int iSize; + FSHANDLE fsh; + + // zero the entire file tag item data area, avoiding leaks + memset(pft, 0, sizeof(FILETAG)); + + // attempt to open file for reading, get size + if (fiFSOpen(&fsh, pszName) == FALSE) + { + return FALSE; // probably file not found + } + iSize = filelength(fsh.iHandle); // assume can get size + +#if 0 + // sanity check for file much too large + if (iSize > 0x100000) // 1 megabyte + { + fiFSClose(&fsh); + return FALSE; + } +#endif + + // allocate heap to hold entire file + // note: simpler than the array or pool implementation, + // because the original limit, position, append info lost + if (fiFileAllocate(pft, iSize) == FALSE) + { + fiFSClose(&fsh); + return FALSE; + } + + // attempt read the exact amount of data + if (iFSRead(&fsh, pft->pcBase, iSize) != iSize) + { + fiFileFree(pft); + fiFSClose(&fsh); + return FALSE; + } + + fiFSClose(&fsh); + + // set position to start and length to length read + pft->pcPosition = pft->pcBase; + pft->pcAppend = pft->pcBase + iSize; + + return TRUE; // says we read the file + } + +// ---------------------------------------------------------------------------- + +int fiFileCopy(FILETAG *pft, FILETAG *pftIn) + { + int i, iSize; + + // zero the entire file tag item data area, avoiding leaks + memset(pft, 0, sizeof(FILETAG)); + + // allocate via the lower level wrapper, relying on the fact + // that the FILETAG structure is compatible with MBHANDLE !! + iSize = iFileSize(pftIn); + if (fiMBAlloc((MBHANDLE *) pft, iSize) == FALSE) + { + return FALSE; // indicates failure to allocate block + } + + // calculate the required adjustment, before clobbering pft! + i = pft->pcBase - pftIn->pcBase; + + // copy the entire file tag item data area, avoiding leaks + memcpy(pft, pftIn, iSize); + + // apply the required adjustment to all fields of filetag + pft->pcBase += i; + //pft->pcLimit += i; + pft->pcPosition += i; + pft->pcAppend += i; + + // another slight adjustment because the copy trims to size + pft->pcLimit = pft->pcAppend; + return TRUE; // indicates copied and new tag item filled out + } + +int fiFileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight) + { + int i, iSize; + + // zero the entire file tag item data area, avoiding leaks + memset(pft, 0, sizeof(FILETAG)); + + // allocate via the lower level wrapper, relying on the fact + // that the FILETAG structure is compatible with MBHANDLE !! + iSize = iFileSize(pftIn); + if (fiMBAlloc((MBHANDLE *) pft, iLeft + iSize + iRight) == FALSE) + { + return FALSE; // indicates failure to allocate block + } + + // calculate the required adjustment, before clobbering pft! + i = pft->pcBase - pftIn->pcBase; + + // copy the entire file tag item data area, avoiding leaks + memcpy(pft, pftIn, sizeof(FILETAG)); + + // apply the required adjustment to all fields of filetag + pft->pcBase += i; + //pft->pcLimit += i; + pft->pcPosition += iLeft + i; + pft->pcAppend += iLeft + i + iRight; + + // another slight adjustment because the copy trims to size + pft->pcLimit = pft->pcAppend; + + // copy the actual data, with padding as specified by caller + memset(pft->pcBase, 0, iLeft); + memcpy(pft->pcBase + iLeft, pftIn->pcBase, iSize); + memset(pft->pcBase + iLeft + iSize, 0, iRight); + + return TRUE; // indicates copied and new tag item filled out + } + +// ---------------------------------------------------------------------------- + +int fiFilePutLine(FILETAG *pft, char *pszLine) + { + int iTemp; + + // calculate length once + iTemp = 0; + if (pszLine != NULL) + { + iTemp = strlen(pszLine); + } + + // do not go past end of memory + if ((pft->pcPosition + iTemp + 2) > pft->pcLimit) + { + return FALSE; + } + + // copy line and crlf terminator out to heap + if (pszLine != NULL) + { + memcpy(pft->pcPosition, pszLine, iTemp); + } + memcpy(pft->pcPosition + iTemp, "\r\n", 2); + pft->pcPosition += iTemp + 2; + + // set file length possibly truncating + pft->pcAppend = pft->pcPosition; + + // say we stored a line + return TRUE; + } + +int fiFileGetLine(FILETAG *pft, char *pszLine, int iLimit, int *piCount) + { + int i; + + // indicate eof to caller + if (pft->pcPosition >= pft->pcAppend) + { + // if caller requested the length of the result, return null + if (piCount != NULL) + { + *piCount = 0; + } + + // the return value from the function indicates eof or not + return FALSE; + } + + for (i = 0; i < iLimit; i++) + { + // terminate the loop for eof + if (pft->pcPosition >= pft->pcAppend) + { + break; + } + + // terminate the loop for lf by itself + if (*pft->pcPosition == 0x0a) + { + (pft->pcPosition)++; + break; + } + + // terminate the loop for cr optionally skipping lf + if (*pft->pcPosition == 0x0d) + { + (pft->pcPosition)++; + if (*pft->pcPosition == 0x0a) + { + pft->pcPosition++; + } + break; + } + + // copy character to caller buffer + if (pszLine != NULL) + { + pszLine[i] = *pft->pcPosition; // formerly ++ + } + pft->pcPosition++; + } + + // null terminate string for caller + if (pszLine != NULL) + { + // see hyprintf.cpp, but i decided to do this differently here!! + //// sentinel is not always placed, so use the length instead !! + //// callers wishing to bodgy can use count-1 and poke their own 0 + //if (i < iCount) + // { + pszLine[i] = 0; + // } + } + + // if caller requested the length of the result, return it + if (piCount != NULL) + { + *piCount = i; + } + + // the return value from the function indicates eof or not + return TRUE; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hyfile.h b/src/mkfont/hyfile.h new file mode 100644 index 00000000..0d8a1ddc --- /dev/null +++ b/src/mkfont/hyfile.h @@ -0,0 +1,125 @@ +// hyfile.h + +#ifndef _INC_HYFILE +#define _INC_HYFILE + +// ---------------------------------------------------------------------------- + +typedef struct +{ + char *pcBase; // also the handle for the malloc'd buffer + char *pcLimit; // offset just after end of malloc'd buffer + char *pcPosition; // offset of the next char to be clobbered + char *pcAppend; // offset just after end of valid char data +} FILETAG; + +// ---------------------------------------------------------------------------- + +int fiFileAllocate(FILETAG *pft, int iSize); +int fiFileFree(FILETAG *pft); + +int fiFileWriteOut(FILETAG *pft, char *pszName); +int fiFileReadIn(FILETAG *pft, char *pszName); + +int fiFileCopy(FILETAG *pft, FILETAG *pftIn); +int fiFileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight); + +int fiFilePutLine(FILETAG *pft, char *pszLine); +int fiFileGetLine(FILETAG *pft, char *pszLine, int iLimit, int *piCount); + +// ---------------------------------------------------------------------------- + +inline int iFileSize(FILETAG *pft) + { + // return size in bytes, for use by FileReadIn etc family + return pft->pcAppend - pft->pcBase; // note: the trimmed size + } + +// ---------------------------------------------------------------------------- +// handy functions for the client, not important to the interface: + +#ifdef _INC_STDIO +inline void FileAllocate(FILETAG *pft, int iSize) + { + if (fiFileAllocate(pft, iSize) == FALSE) + { + printf("FileAllocate: Could not allocate %08x bytes\n", iSize); + exit(1); + } + +#ifdef DEBUG + printf("FileAllocate: " + "Allocated file %08x, %08x bytes\n", pft, iSize); +#endif + } + +inline void FileFree(FILETAG *pft) + { + if (fiFileFree(pft) == FALSE) + { + printf("FileFree: Could not free file %08x\n", pft); + exit(1); + } + +#ifdef DEBUG + printf("FileFree: Freed file %08x\n", pft); +#endif + } + +inline void FileReadIn(FILETAG *pft, char *pszName) + { + if (fiFileReadIn(pft, pszName) == FALSE) + { + printf("FileReadIn: Could not read %s\n", pszName); + exit(1); + } + + printf( +#ifdef DEBUG + "FileReadIn: " +#endif + "Loaded %s, 0x%08x bytes\n", + pszName, pft->pcAppend - pft->pcBase); + } + +inline void FileWriteOut(FILETAG *pft, char *pszName) + { + if (fiFileWriteOut(pft, pszName) == FALSE) + { + printf("FileWriteOut: Could not write %s\n", pszName); + exit(1); + } + + printf( +#ifdef DEBUG + "FileWriteOut: " +#endif + "Created %s, 0x%08x bytes\n", + pszName, pft->pcAppend - pft->pcBase); + } + +inline void FileCopy(FILETAG *pft, FILETAG *pftIn) + { + if (fiFileCopy(pft, pftIn) == FALSE) + { + printf("FileCopy: Could not copy 0x%08x bytes\n", + pftIn->pcAppend - pftIn->pcBase); + exit(1); + } + } + +inline void FileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight) + { + if (fiFileCopyPadded(pft, pftIn, iLeft, iRight) == FALSE) + { + printf("FileCopyPadded: Could not copy 0x%08x bytes\n", + (pftIn->pcAppend - pftIn->pcBase) + iLeft + iRight); + exit(1); + } + } +#endif + +// ---------------------------------------------------------------------------- + +#endif + diff --git a/src/mkfont/hyfs.cpp b/src/mkfont/hyfs.cpp new file mode 100644 index 00000000..ebdf991f --- /dev/null +++ b/src/mkfont/hyfs.cpp @@ -0,0 +1,137 @@ +// hyfs.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#pragma hdrstop +#include "hyfs.h" + +// ---------------------------------------------------------------------------- + +void FSEntrySetup(void) + { + // for future expansion, including GetModuleFileName + } + +void FSExitCleanup(void) + { + // for future expansion + } + +// ---------------------------------------------------------------------------- + +int fiFSOpen(FSHANDLE *pfsh, char *pszName) + { + // clear filestreamtag, although we should also free name and error if + // not null, so calling convention needs to be revised (zero it for now) + memset(pfsh, 0, sizeof(FSHANDLE)); + + // set up fields to print a report on closure + //pfsh->iMode = 0; + //pfsh->iCount = 0; + + // attempt to open file or device for reading + pfsh->pszName = pszName; + pfsh->iHandle = open(pszName, O_RDONLY | O_BINARY); + if (pfsh->iHandle < 0) + { + pfsh->iError = IDS_ERROR_FS_OPEN; + return FALSE; + } + + // indicate successful operation + //pfsh->iError = 0; + return TRUE; + } + +int fiFSCreate(FSHANDLE *pfsh, char *pszName) + { + // clear filestreamtag, although we should also free name and error if + // not null, so calling convention needs to be revised (zero it for now) + memset(pfsh, 0, sizeof(FSHANDLE)); + + // set up fields to print a report on closure + pfsh->iMode = 1; + //pfsh->iCount = 0; + + // attempt to create file or open device for writing + pfsh->pszName = pszName; + pfsh->iHandle = open(pszName, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + S_IREAD | S_IWRITE); + if (pfsh->iHandle < 0) + { + pfsh->iError = IDS_ERROR_FS_CREATE; + return FALSE; + } + + // indicate successful operation + //pfsh->iError = 0; + return TRUE; + } + +int fiFSClose(FSHANDLE *pfsh) + { + int i; + + // attempt to close file, noting success + i = close(pfsh->iHandle); + if (i < 0) // check msdn + { + pfsh->iError = IDS_ERROR_FS_CLOSE; + return FALSE; + } + pfsh->iHandle = -1; // for no good reason + + // indicate successful operation + pfsh->iError = 0; + return TRUE; + } + +// ---------------------------------------------------------------------------- + +int iFSRead(FSHANDLE *pfsh, char *pcOut, int iLimit) + { + int i; + + // attempt to open file or device for reading + i = read(pfsh->iHandle, pcOut, iLimit); + if (i < 0) // check msdn + { + pfsh->iError = IDS_ERROR_FS_READ; + return 0; + } + + // maintain fields to print a report on closure + pfsh->iCount += i; + + // indicate successful operation + pfsh->iError = 0; + return i; + } + +int iFSWrite(FSHANDLE *pfsh, char *pcIn, int iLimit) + { + int i; + + // attempt to open file or device for reading + i = write(pfsh->iHandle, pcIn, iLimit); + if (i < 0) // check msdn + { + pfsh->iError = IDS_ERROR_FS_WRITE; + return 0; + } + + // maintain fields to print a report on closure + pfsh->iCount += i; + + // indicate successful operation + pfsh->iError = 0; + return i; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hyfs.h b/src/mkfont/hyfs.h new file mode 100644 index 00000000..cb85160a --- /dev/null +++ b/src/mkfont/hyfs.h @@ -0,0 +1,121 @@ +// hyfs.h + +#define _INC_HYFS + +// ---------------------------------------------------------------------------- + +#define IDS_ERROR_FS_OPEN 12000 +#define IDS_ERROR_FS_CREATE 12001 +#define IDS_ERROR_FS_CLOSE 12002 +#define IDS_ERROR_FS_READ 12003 +#define IDS_ERROR_FS_WRITE 12004 + +// ---------------------------------------------------------------------------- + +typedef struct + { + int iHandle; + char *pszName; + + int iMode; + int iCount; + + int iError; + char *pszError; + } FSHANDLE; + +// ---------------------------------------------------------------------------- + +void FSEntrySetup(void); +void FSExitCleanup(void); + +int fiFSOpen(FSHANDLE *pfsh, char *pszName); +int fiFSCreate(FSHANDLE *pfsh, char *pszName); +int fiFSClose(FSHANDLE *pfsh); + +int iFSRead(FSHANDLE *pfsh, char *pcOut, int iLimit); +int iFSWrite(FSHANDLE *pfsh, char *pcIn, int iLimit); + +// ---------------------------------------------------------------------------- + +inline void FSOpen(FSHANDLE *pfsh, char *pszName) + { + if (fiFSOpen(pfsh, pszName) == 0) + { + printf("FSOpen: " + "Could not open file %s for reading, exiting\n", pszName); + exit(1); + } + + printf("FSOpen: " + "Handle %08x file %s opened, read mode\n", pfsh, pszName); + } + +inline void FSCreate(FSHANDLE *pfsh, char *pszName) + { + if (fiFSCreate(pfsh, pszName) == 0) + { + printf("FSCreate: " + "Could not create or truncate file %s, exiting\n", pszName); + exit(1); + } + + printf("FSCreate: " + "Handle %08x file %s opened, write mode\n", pfsh, pszName); + } + +inline void FSClose(FSHANDLE *pfsh) + { + if (fiFSClose(pfsh) == 0) + { + printf("FSClose: " + "Could not close handle %08x, exiting\n", pfsh); + exit(1); + } + + printf("FSClose: " + "Handle %08x file %s closed, %s mode\n", + pfsh, pfsh->pszName, pfsh->iMode ? "write" : "read"); + + printf("Loaded file %s, size %d bytes\n", + pfsh->pszName, pfsh->iCount); + } + +inline void FSRead(FSHANDLE *pfsh, char *pcOut, int iLimit) + { + int iCount; + + iCount = iFSRead(pfsh, pcOut, iLimit); + if (iCount != iLimit) + { + printf("FSRead: " + "End of file, handle %08x, request %d, return %d\n", + pfsh, iLimit, iCount); + exit(1); + } + + printf("FSRead: " + "Handle %08x file %s read, request %d, return %d\n", + pfsh, pfsh->pszName, iLimit, iCount); + } + +inline void FSWrite(FSHANDLE *pfsh, char *pcIn, int iLimit) + { + int iCount; + + iCount = iFSWrite(pfsh, pcIn, iLimit); + if (iCount != iLimit) + { + printf("FSWrite: " + "Disk full, handle %08x, request %d, return %d\n", + pfsh, iLimit, iCount); + exit(1); + } + + printf("FSWrite: " + "Handle %08x file %s written, request %d, return %d\n", + pfsh, pfsh->pszName, iLimit, iCount); + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hyimage.cpp b/src/mkfont/hyimage.cpp new file mode 100644 index 00000000..dfc111fc --- /dev/null +++ b/src/mkfont/hyimage.cpp @@ -0,0 +1,1230 @@ +// hyimage.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#pragma hdrstop +#include "hyfile.h" +#include "hyimage.h" + +// ---------------------------------------------------------------------------- + +BITMAPFILEHEADER bfhDefault = + { + 0x4D42, // bfType = 'BM' + 0, // bfSize + 0, // bfReserved1 + 0, // bfReserved2 + 0, // bfOffBits + }; + +/* +BITMAPINFOHEADER bihDefault = + { + 0x46465952, // iFileId = 'RIFF' + 0, // iFileSize + 0x45564157, // iTypeId = 'BMPE' + 0x20746d66, // iFormatId = 'fmt_' + 0x10, // iFormatSize + 1, // siFormatTag + 2, // siChannels + 44100, // iPixelRate + 176400, // iByteRate + 4, // siAlignment + 16, // siBitsPixel + 0x61746164, // iDataId = 'data' + 0 // iDataSize + }; +*/ + +// ---------------------------------------------------------------------------- + +int fiBmpAllocate(BMPTAG *pbt, BITMAPINFOHEADER *pbihIn, + int cxPixels, int cyPixels) + { + int iPalette; + int iBitsPixel, iBitsLine; + int iPixelsLine, iBytes; + + // fill important bmptag fields from the user's bmp header + pbt->iChannels = max(1, pbihIn->biBitCount / 8); + pbt->iBitsChannel = pbihIn->biBitCount / pbt->iChannels; + + // calculate overall image size and required storage + iBitsPixel = pbt->iChannels * pbt->iBitsChannel; + iBitsLine = (cxPixels * iBitsPixel + 0x1f) & 0xffffffe0; + + pbt->iSamplesLine = iBitsLine / pbt->iBitsChannel; + + iBytes = cyPixels * (iBitsLine / 8); + + iPalette = 0; + if (pbt->iChannels == 1) + { + iPalette = sizeof(RGBQUAD) << pbt->iBitsChannel; + } + + // allocate and initialise memory block for header + data + if (fiFileAllocate(&pbt->ft, sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER) + + iPalette + iBytes) == FALSE) + { + return FALSE; + } + + memset(pbt->ft.pcBase, 0, pbt->ft.pcLimit - pbt->ft.pcBase); + + // fill bmptag fields which refer to the allocated memory block + pbt->pbfh = (BITMAPFILEHEADER *) (pbt->ft.pcBase); + pbt->pbih = (BITMAPINFOHEADER *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER)); + pbt->prgbq = (RGBQUAD *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + pbt->pucSample = (unsigned char *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + if (pbt->iChannels == 1) + { + pbt->pucSample += sizeof(RGBQUAD) << pbt->iBitsChannel; + } + + // initialise bitmap header within the allocated block + memcpy(pbt->pbfh, &bfhDefault, sizeof(BITMAPFILEHEADER)); + pbt->pbfh->bfOffBits = (char *) (pbt->pucSample) - pbt->ft.pcBase; + pbt->pbfh->bfSize = pbt->pbfh->bfOffBits + iBytes; + + memcpy(pbt->pbih, pbihIn, sizeof(BITMAPINFOHEADER)); + pbt->pbih->biWidth = cxPixels; + pbt->pbih->biHeight = cyPixels; + + // initialise the remainder of the bmptag for client + pbt->iSampleBase = 0; + pbt->iSampleLimit = pbt->pbih->biHeight * pbt->iSamplesLine; + pbt->iSamplePosition = 0; + pbt->iSampleAppend = 0; + + //pbt->rPixelWindow.left = 0; + //pbt->rPixelWindow.right = pbt->pbih->biWidth; + //pbt->rPixelWindow.bottom = 0; + //pbt->rPixelWindow.top = pbt->pbih->biHeight; + + //pbt->rPixelSurface.left = 0; + //pbt->rPixelSurface.right = iBitsLine / iBitsPixel; + //pbt->rPixelSurface.bottom = 0; + //pbt->rPixelSurface.top = pbt->pbih->biHeight; + + // say we met with success + return TRUE; + } + +// ---------------------------------------------------------------------------- + +int fiBmpReadIn(BMPTAG *pbt, char *pszFileName) + { + int iBitsPixel, iBitsLine, iPixelsLine; + + // attempt to read the client's requested file fully + if (fiFileReadIn(&pbt->ft, pszFileName) == FALSE) + { + return FALSE; + } + + // fill bmptag fields which refer to the allocated memory block + pbt->pbfh = (BITMAPFILEHEADER *) (pbt->ft.pcBase); + pbt->pbih = (BITMAPINFOHEADER *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER)); + pbt->prgbq = (RGBQUAD *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + + // check the file format in place before using header fields + if ((pbt->pbih->biPlanes != 1) || + ((pbt->pbih->biBitCount != 1) && + (pbt->pbih->biBitCount != 8) && + (pbt->pbih->biBitCount != 24) && + (pbt->pbih->biBitCount != 32))) + { + printf("fiBmpReadIn: Invalid BMP file %s\n", pszFileName); + FileFree(&pbt->ft); + return FALSE; + } +// printf("%d %d\n", pbt->pbih->biWidth, pbt->pbih->biHeight); + + // fill important bmptag fields from the user's bmp header + pbt->iChannels = max(1, pbt->pbih->biBitCount / 8); + pbt->iBitsChannel = pbt->pbih->biBitCount / pbt->iChannels; +// printf("%d %d\n", pbt->iChannels, pbt->iBitsChannel); + + pbt->pucSample = (unsigned char *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + if (pbt->iChannels == 1) + { + pbt->pucSample += sizeof(RGBQUAD) << pbt->iBitsChannel; + } + + iBitsPixel = pbt->iChannels * pbt->iBitsChannel; + iBitsLine = (pbt->pbih->biWidth * iBitsPixel + 0x1f) & 0xffffffe0; + + pbt->iSamplesLine = iBitsLine / pbt->iBitsChannel; + + // initialise the remainder of the bmptag for client + pbt->iSampleBase = 0; + pbt->iSamplePosition = 0; + pbt->iSampleAppend = pbt->pbih->biHeight * pbt->iSamplesLine; + pbt->iSampleLimit = pbt->iSampleAppend; + + //pbt->rPixelWindow.left = 0; + //pbt->rPixelWindow.right = pbt->pbih->biWidth; + //pbt->rPixelWindow.bottom = 0; + //pbt->rPixelWindow.top = pbt->pbih->biHeight; + + //pbt->rPixelSurface.left = 0; + //pbt->rPixelSurface.right = iBitsLine / iBitsPixel; + //pbt->rPixelSurface.bottom = 0; + //pbt->rPixelSurface.top = pbt->pbih->biHeight; + + // say we met with success + return TRUE; + } + +// ---------------------------------------------------------------------------- + +int fiBmpWriteOut(BMPTAG *pbt, char *pszFileName) + { + int i, j, k; + int iBitsPixel, iBitsLine; + int iBytesLine, iBytes; + + // update bmp file and info header lengths from length generated + iBitsPixel = pbt->iChannels * pbt->iBitsChannel; + iBitsLine = (pbt->pbih->biWidth * iBitsPixel + 0x1f) & 0xffffffe0; + + iBytesLine = iBitsLine / 8; + iBytes = pbt->pbih->biHeight * iBytesLine; + + pbt->pbfh->bfOffBits = (char *) (pbt->pucSample) - pbt->ft.pcBase; + pbt->pbfh->bfSize = pbt->pbfh->bfOffBits + iBytes; + + // refresh palette within file data if any palette is required + if (pbt->iChannels == 1) + { + j = 0; + k = 1 << pbt->iBitsChannel; + for (i = 0; i < k; i++) + { + ((int *) (pbt->prgbq))[i] = j; + j += 0x00010101; + } + } + + // update bmp info header information for client selected format + pbt->pbih->biPlanes = 1; // the red baron + pbt->pbih->biBitCount = pbt->iChannels * pbt->iBitsChannel; + + // update length in output filetag then write out + pbt->ft.pcAppend = (char *) (pbt->pucSample) + iBytes; + return fiFileWriteOut(&pbt->ft, pszFileName); + } + +// ---------------------------------------------------------------------------- + +void BmpFree(BMPTAG *pbt) + { + FileFree(&pbt->ft); + } + +// ---------------------------------------------------------------------------- + +int fiBmpCopy(BMPTAG *pbt, BMPTAG *pbtIn) + { + // copy the tag item, which will then be modified + memcpy(pbt, pbtIn, sizeof(BMPTAG)); + + // redirect the new tag item to a new malloc'd buffer + pbt->ft.pcBase = (char *) malloc(pbt->ft.pcLimit - pbt->ft.pcBase); + if (pbt->ft.pcBase == NULL) + { + printf("fiBmpCopy: " + "Could not allocate copy buffer of %08x bytes\n", + pbt->ft.pcLimit - pbt->ft.pcBase); + return FALSE; + } + + // copy the original sample data into the new malloc'd buffer + memcpy(pbt->ft.pcBase, pbtIn->ft.pcBase, + pbtIn->ft.pcLimit - pbtIn->ft.pcBase); + + // fill bmptag fields which refer to the allocated memory block + pbt->pbfh = (BITMAPFILEHEADER *) (pbt->ft.pcBase); + pbt->pbih = (BITMAPINFOHEADER *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER)); + pbt->prgbq = (RGBQUAD *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + pbt->pucSample = (unsigned char *) (pbt->ft.pcBase + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER)); + if (pbt->iChannels == 1) + { + pbt->pucSample += sizeof(RGBQUAD) << pbt->iBitsChannel; + } + + // sneakily nudge the remaining fields of the new tag item + pbt->ft.pcLimit += pbt->ft.pcBase - pbtIn->ft.pcBase; + pbt->ft.pcPosition += pbt->ft.pcBase - pbtIn->ft.pcBase; + pbt->ft.pcAppend += pbt->ft.pcBase - pbtIn->ft.pcBase; + + // say we met with success + return TRUE; + } + +// ---------------------------------------------------------------------------- + +int fiLinearExpand2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxFactor, int cyFactor) + { + int i, j, k, l, m, x, y, t; + int cxIn, cyIn, cxOut, cyOut; + int cxCentre, cyCentre; + int cxLeftFraction, cxRightFraction; + int cyTopFraction, cyBottomFraction; + int iLine, iPixel, iSample; + int *pi, *piThis, *piPrev, *piTemp; + int iThis[4], iPrev[4], iNormal; + + cxIn = pbtIn->pbih->biWidth; + cyIn = pbtIn->pbih->biHeight; + + cxOut = cxIn * cxFactor; + cyOut = cyIn * cyFactor; + + if (fiBmpAllocate(pbtOut, pbtIn->pbih, cxOut, cyOut) == FALSE) + { + printf("fiLinearExpand2D: " + "Failed to allocate output buffer of %08x pixels\n", + cxOut * cyOut); + return FALSE; + } + + pi = (int *) malloc(cxOut * pbtIn->iChannels * 2 * sizeof(int)); + if (pi == NULL) + { + printf("fiLinearExpand2D: " + "Failed to allocate temporary buffer of %08x samples\n", + cxOut * pbtIn->iChannels * 2); + BmpFree(pbtOut); + return FALSE; + } + + piThis = pi; + piPrev = pi + cxOut * pbtIn->iChannels; + + cxCentre = cxFactor / 2; + cyCentre = cyFactor / 2; + + cyBottomFraction = cyCentre; + cyTopFraction = cyFactor; + memset(piThis, 0, cxOut * pbtIn->iChannels * sizeof(int)); + + iNormal = cxFactor * cyFactor; + + i = 0; + iLine = 0; + for (y = 0; y <= cyIn; y++) + { + iPixel = iLine; + iLine += pbtIn->iSamplesLine; + + piTemp = piPrev; + piPrev = piThis; + piThis = piTemp; + + if (y < cyIn) + { + cxLeftFraction = cxCentre; + cxRightFraction = cxFactor; + memset(iThis, 0, pbtIn->iChannels * sizeof(int)); + + t = 0; + iSample = iPixel; + for (x = 0; x <= cxIn; x++) + { + memcpy(iPrev, iThis, pbtIn->iChannels * sizeof(int)); + + if (x < cxIn) + { + for (m = 0; m < pbtIn->iChannels; m++) + { + iThis[m] = pbtIn->pucSample[iSample++]; + } + } + else + { + cxRightFraction = cxCentre; + memset(iThis, 0, pbtIn->iChannels * sizeof(int)); + } + + for (k = cxLeftFraction; k < cxRightFraction; k++) + { + for (m = 0; m < pbtIn->iChannels; m++) + { + piThis[t++] = + k * iThis[m] + (cxFactor - k) * iPrev[m]; + } + } + + cxLeftFraction = 0; + } + } + else + { + cyTopFraction = cyCentre; + memset(piThis, 0, cxOut * pbtIn->iChannels * sizeof(int)); + } + + for (l = cyBottomFraction; l < cyTopFraction; l++) + { + j = i; + i += pbtOut->iSamplesLine; + + t = 0; + for (x = 0; x < cxOut; x++) + { + +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiLinearExpand2D: " + "Overflowed output buffer at sample %08x\n", j); + free(pi); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + for (m = 0; m < pbtIn->iChannels; m++) + { + pbtOut->pucSample[j++] = + (l * piThis[t] + (cyFactor - l) * piPrev[t]) / + iNormal; + + t++; + } + + } + } + + cyBottomFraction = 0; + } + + free(pi); + +#if 1 + if (i < pbtOut->iSampleLimit) + { + printf("fiLinearExpand2D: " + "Partially filled output buffer to sample %08x\n", i); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = i; + return TRUE; + } + +// ---------------------------------------------------------------------------- + +int fiLinearShrink2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxFactor, int cyFactor) + { + int i, j, k, l, m, x, y, t, u; + int cxIn, cyIn, cxOut, cyOut; + int iLine, iPixel, iSample; + int *pi, iNormal; + + cxIn = pbtIn->pbih->biWidth; + cyIn = pbtIn->pbih->biHeight; + + cxOut = cxIn / cxFactor; + cyOut = cyIn / cyFactor; + + if (fiBmpAllocate(pbtOut, pbtIn->pbih, cxOut, cyOut) == FALSE) + { + printf("fiLinearShrink2D: " + "Failed to allocate output buffer of %08x samples\n", + cxOut * cyOut * pbtIn->iChannels); + return FALSE; + } + + pi = (int *) malloc(cxOut * pbtIn->iChannels * sizeof(int)); + if (pi == NULL) + { + printf("fiLinearShrink2D: " + "Failed to allocate temporary buffer of %08x pixels\n", + cxOut); + BmpFree(pbtOut); + return FALSE; + } + + iNormal = cxFactor * cyFactor; + + i = 0; + iLine = 0; + for (y = 0; y < cyOut; y++) + { + j = i; + i += pbtOut->iSamplesLine; + + memset(pi, 0, cxOut * pbtIn->iChannels * sizeof(int)); + + for (l = 0; l < cyFactor; l++) + { + iPixel = iLine; + iLine += pbtIn->iSamplesLine; + + t = 0; + iSample = iPixel; + for (x = 0; x < cxOut; x++) + { + for (k = 0; k < cxFactor; k++) + { + u = t; + for (m = 0; m < pbtIn->iChannels; m++) + { + pi[u++] += pbtIn->pucSample[iSample++]; + } + } + + t += pbtIn->iChannels; + } + } + + t = 0; + for (x = 0; x < cxOut; x++) + { +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiLinearShrink2D: " + "Overflowed output buffer at sample %08x\n", j); + free(pi); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + for (m = 0; m < pbtIn->iChannels; m++) + { + pbtOut->pucSample[j++] = pi[t++] / iNormal; + } + } + } + + free(pi); + +#if 1 + if (i < pbtOut->iSampleLimit) + { + printf("fiLinearShrink2D: " + "Partially filled output buffer to sample %08x\n", i); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = i; + return TRUE; + } + +// ---------------------------------------------------------------------------- + +#if 1 +int fiSincInterpolate2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxInterpolate, int cyInterpolate) + { + BMPTAG btFilter; + int i, j, k, l, m, x, y, t, u; + int iThis, iShift, iNormal; + int cxSize, cySize; + int cxPixelsIn, cyPixelsIn; + int cxPixelsOut, cyPixelsOut; + int cxFraction, cyFraction; + int cxLeft, cyBottom; + int cxCentre, cyCentre; + int cxLeftClipped, cxRightClipped; + int cxLeftFraction, cxRightFraction; + int cyBottomClipped, cyTopClipped; + int cyBottomFraction, cyTopFraction; + int cxLeftSample, cxRightSample; + int cxCoefficient, cyCoefficient; + int cxCoefficientSave, cyCoefficientSave; + int cxCoefficientStep, cyCoefficientStep; + int fiCoefficientStep; + + cxSize = cxInterpolate * FILTER_OVERLAP; + cySize = cyInterpolate * FILTER_OVERLAP; + + cxPixelsIn = pbtIn->pbih->biWidth; + cyPixelsIn = pbtIn->pbih->biHeight; + + cxPixelsOut = cxPixelsIn * cxInterpolate; + cyPixelsOut = cyPixelsIn * cyInterpolate; + + if (fiBmpAllocate(pbtOut, pbtIn->pbih, + cxPixelsOut, cyPixelsOut) == FALSE) + { + printf("fiSincInterpolate2D: " + "Failed to allocate output buffer of %08x samples\n", + cxPixelsOut * cyPixelsOut * pbtIn->iChannels); + return FALSE; + } + + if (fiMakeSincFilter2D(&btFilter, pbtIn, cxSize, cySize, + FILTER_CUTOFF, FILTER_CUTOFF) == FALSE) + { + BmpFree(pbtOut); + return FALSE; + } + + fiBmpWriteOut(&btFilter, "filtint.bmp"); + printf("Created filtint.bmp, 0x%08x samples\n", btFilter.iSampleAppend); + +#if 0 + iShift = 0; + for (x = cxInterpolate; x < cxSize; x <<= 1) + { + iShift++; + } + for (y = cyInterpolate; y < cySize; y <<= 1) + { + iShift++; + } + printf("shift %d\n", iShift); +#endif + + i = 0; + iNormal = 0; + for (y = 0; y < cySize; y++) + { + j = i; + i += btFilter.iSamplesLine; + + for (x = 0; x < cxSize; x++) + { + iNormal += (int) (btFilter.pucSample[j]) - 0x30; + j += btFilter.iChannels; // only 1st channel ! + } + } +#if 0 + printf("normal %d\n", iNormal); + iNormal >>= iShift; +#endif + iNormal = (iNormal << 8) / (cxInterpolate * cyInterpolate); + + if (iNormal == 0) + { + printf("fiSincInterpolate2D: " + "Inadequate precision to normalise filter response\n"); + BmpFree(&btFilter); + BmpFree(pbtOut); + return FALSE; + } + + cxCentre = FILTER_OVERLAP / 2; + cyCentre = FILTER_OVERLAP / 2; + + cxCoefficientStep = cxInterpolate * btFilter.iChannels; + cyCoefficientStep = cyInterpolate * btFilter.iSamplesLine; + + fiCoefficientStep = (btFilter.iChannels >= pbtIn->iChannels); + + cyBottomFraction = cyInterpolate / 2; + cyTopFraction = cyInterpolate; + + i = 0; + for (y = 0; y <= cyPixelsIn; y++) + { + if (y >= cyPixelsIn) + { + cyTopFraction = cyInterpolate / 2; + } + + cyBottom = y - cyCentre; + + cyBottomClipped = max(cyBottom, 0) * pbtIn->iSamplesLine; + cyTopClipped = min(cyBottom + FILTER_OVERLAP, cyPixelsIn) * + pbtIn->iSamplesLine; + + // the (cyInterpolate - 1) term below is completed when we also + // subtract iFraction, making (cyInterpolate - cyFraction - 1). + // same algorithm applies to cxCoefficientSave inside the loop. + + // this reversal is necessary because the window moves in the + // opposite direction, from the viewpoint of the coefficients, + // than our normal viewpoint which is relative to input data. + + cyCoefficientSave = (cyInterpolate - 1) + + max(0, -cyBottom) * cyInterpolate; + + for (cyFraction = cyBottomFraction; cyFraction < cyTopFraction; + cyFraction++) + { + j = i; + i += pbtOut->iSamplesLine; + + // fraction here ensures that we move through the + // available coefficients for smooth interpolation, + // compensation for clipping is done using quantised + // values especially to avoid disturbing this effect + cyCoefficient = (cyCoefficientSave - cyFraction) * + btFilter.iSamplesLine; + + cxLeftFraction = cxInterpolate / 2; + cxRightFraction = cxInterpolate; + + for (x = 0; x <= cxPixelsIn; x++) + { + if (x >= cxPixelsIn) + { + cxRightFraction = cxInterpolate / 2; + } + + cxLeft = x - cxCentre; + + cxLeftClipped = max(cxLeft, 0) * pbtIn->iChannels; + cxRightClipped = min(cxLeft + FILTER_OVERLAP, cxPixelsIn) * + pbtIn->iChannels; + + cxCoefficientSave = (cxInterpolate - 1) + + max(0, -cxLeft) * cxInterpolate; + + for (cxFraction = cxLeftFraction; + cxFraction < cxRightFraction; cxFraction++) + { +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiSincInterpolate2D: " + "Overflowed output buffer at sample %08x\n", j); + BmpFree(&btFilter); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + cxLeftSample = cxLeftClipped; + cxRightSample = cxRightClipped; + + // fraction here ensures that we move through the + // available coefficients for smooth interpolation, + // compensation for clipping is done using quantised + // values especially to avoid disturbing this effect + cxCoefficient = (cxCoefficientSave - cxFraction) * + btFilter.iChannels; + + for (m = 0; m < pbtIn->iChannels; m++) + { + iThis = 0; + + t = cyCoefficient + cxCoefficient; + + for (k = cyBottomClipped; k < cyTopClipped; + k += pbtIn->iSamplesLine) + { + u = t; + t += cyCoefficientStep; + + for (l = cxLeftSample; l < cxRightSample; + l += pbtIn->iChannels) + { + iThis += (pbtIn->pucSample[k + l] * + ((int) + (btFilter.pucSample[u]) - + 0x30)); //>> iShift; + u += cxCoefficientStep; + } + } + + cxLeftSample++; + cxRightSample++; + cxCoefficient += fiCoefficientStep; + + iThis = (iThis << 8) / iNormal; + if (iThis > 0xff) + { + iThis = 0xff; + } + if (iThis < 0) + { + iThis = 0; + } + pbtOut->pucSample[j++] = iThis; + } + } + + cxLeftFraction = 0; + } + } + + cyBottomFraction = 0; + } + + BmpFree(&btFilter); + +#if 0 //1 + if (j < pbtOut->iSampleLimit) + { + printf("fiSincInterpolate2D: " + "Partially filled output buffer to sample %08x\n", j); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = j; + return TRUE; + } +#endif + +// ---------------------------------------------------------------------------- + +#if 0 +int fiSincDecimate2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxDecimate, int cyDecimate) + { + BMPTAG btFilter; + int i, j, k, l, m, x, y, t, u; + int cxSize, cySize, iThis; + int iShift, iNormal; + int fiCoefficientStep; + int cxPixelsIn, cyPixelsIn; + int cxPixelsOut, cyPixelsOut; + int iCoefficient, iCentre, iLeft; + int iLeftClipped, iRightClipped; + + cxSize = cxDecimate * FILTER_OVERLAP; + cySize = cyDecimate * FILTER_OVERLAP; + + cxPixelsIn = pbtIn->pbih->biWidth; + cyPixelsIn = pbtIn->pbih->biHeight; + + cxPixelsOut = cxPixelsIn / cxDecimate; + cyPixelsOut = cyPixelsIn / cyDecimate; + + if (fiBmpAllocate(pbtOut, pbtIn->pbih, + cxPixelsOut, cyPixelsOut) == FALSE) + { + printf("fiSincDecimate2D: " + "Failed to allocate output buffer of %08x samples\n", + cxPixelsOut * cyPixelsOut * pbtIn->iChannels); + return FALSE; + } + + if (fiMakeSincFilter2D(&btFilter, pbtIn, cxSize, cySize, + FILTER_CUTOFF, FILTER_CUTOFF) == FALSE) + { + BmpFree(pbtOut); + return FALSE; + } + + fiBmpWriteOut(&btFilter, "filtdec.bmp"); + printf("Created filtdec.bmp, 0x%08x samples\n", btFilter.iSampleAppend); + + iShift = 0; + for (i = 1; i < iSize; i <<= 1) + { + iShift++; + } + + iNormal = 0; + for (i = 0; i < iSize; i++) + { + iNormal += btFilter.pucSample[i * btFilter.iChannels]; + } + iNormal >>= iShift; + + iCentre = iSize / 2; + fiCoefficientStep = (btFilter.iChannels >= pbtIn->iChannels); + + j = 0; + for (i = 0; i < iPixelsIn; i += iDecimate) + { +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiSincDecimate2D: " + "Overflowed output buffer at sample %08x\n", j); + BmpFree(&btFilter); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + iLeft = i - iCentre; + + iLeftClipped = max(iLeft, 0) * pbtIn->iChannels; + iRightClipped = min(iLeft + iSize, pbtIn->iSampleAppend) * + pbtIn->iChannels; + + iCoefficient = max(0, -iLeft) * btFilter.iChannels; + + for (m = 0; m < pbtIn->iChannels; m++) + { + iThis = 0; + + l = iCoefficient; + iCoefficient += fiCoefficientStep; + + for (k = iLeftClipped++; k < iRightClipped; + k += pbtIn->iChannels) + { + iThis += (pbtIn->pucSample[k] * btFilter.pucSample[l]) >> + iShift; + l += btFilter.iChannels; + } + + iRightClipped++; + + iThis /= iNormal; + if (iThis > 0xff) + { + iThis = 0xff; + } + if (iThis < 0) + { + iThis = 0; + } + + pbtOut->pucSample[j++] = iThis; + } + } + + BmpFree(&btFilter); + +#if 1 + if (j < pbtOut->iSampleLimit) + { + printf("fiSincDecimate2D: " + "Partially filled output buffer to sample %08x\n", j); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = j; + return TRUE; + } +#endif + +// ---------------------------------------------------------------------------- + +#if 0 +int fiSincResample2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxInterpolate, int cyInterpolate, + int cxDecimate, int cyDecimate) + { + BMPTAG btFilter; + int i, j, k, l, m, x, y, t, u; + int cxSize, cySize; + int cxSizeQuantised, cySizeQuantised; + int iShift, iNormal, iThis; + int iCoefficientStep, fiCoefficientStep; + int cxPixelsIn, cyPixelsIn; + int cxPixelsQuantised, cyPixelsQuantised; + int iCoefficient; + int iIntermediate, iInteger, iFraction; + int iLeftQuantised, iCentreQuantised; + int iLeftClipped, iRightClipped; + + // I think it is best to quantise the input data window size once, + // at the beginning, so all convolutions are done with the same width, + // avoiding normalisation issues. Therefore one coefficient will + // always skipped, on either side of the coefficient bank depending + // on the interpolation status, but it will be of low amplitude. + // + // window_size_quantised = window_size / output_rate + // = max(t, t * input_rate / output_rate) + + cxSizeQuantised = max(FILTER_OVERLAP, + (FILTER_OVERLAP * cxDecimate) / cxInterpolate); + cySizeQuantised = max(FILTER_OVERLAP, + (FILTER_OVERLAP * cyDecimate) / cyInterpolate); + + // So how many possible interpolation states are there? The + // interpolation has to be reset each time the base coefficient + // pointer overflows to a value => the input data rate unit + // (output_rate intermediate units). Thus, the base coefficient + // pointer is the state counter for the interpolation and it + // can have values 0 thru output_rate-1. + // + // Having calculated window_size_quantised we can then multiply + // by the number of possible interpolation states, thus: + // + // window_size_coefficient = window_size_quantised * output_rate + // = max(t * output_rate, t * input_rate) + // + // Note: The second derivation undoes the beneficial effect of + // the quantisation, meaning the window is now slightly larger + // than necessary, but this is necessary, because otherwise our + // use of s * t to set the cutoff would introduce a freq. error. + + cxSize = FILTER_OVERLAP * max(cxInterpolate, cxDecimate); + cySize = FILTER_OVERLAP * max(cyInterpolate, cyDecimate); + + cxPixelsIn = pbtIn->pbih->biWidth; + cyPixelsIn = pbtIn->pbih->biHeight; + + cxPixelsQuantised = (cxPixelsIn * cxInterpolate) / cxDecimate; + cyPixelsQuantised = (cyPixelsIn * cyInterpolate) / cyDecimate; + + if (fiBmpAllocate(pbtOut, pbtIn->pbih, + cxPixelsQuantised, cyPixelsQuantised) == FALSE) + { + printf("fiSincResample2D: " + "Failed to allocate output buffer of %08x samples\n", + cxPixelsQuantised * cyPixelsQuantised * pbtIn->iChannels); + return FALSE; + } + + if (fiMakeSincFilter2D(&btFilter, pbtIn, cxSize, cySize, + FILTER_CUTOFF, FILTER_CUTOFF) == FALSE) + { + BmpFree(pbtOut); + return FALSE; + } + + if (iInterpolate > iDecimate) + { + fiBmpWriteOut(&btFilter, "filtint.bmp"); + printf("Created filtint.bmp, 0x%08x samples\n", btFilter.iSampleAppend); + } + else + + { + fiBmpWriteOut(&btFilter, "filtdec.bmp"); + printf("Created filtdec.bmp, 0x%08x samples\n", btFilter.iSampleAppend); + } + + iShift = 0; + for (i = 1; i < iSizeQuantised; i <<= 1) + { + iShift++; + } + + iNormal = 0; + for (i = 0; i < iSizeQuantised; i++) + { + iNormal += btFilter.pucSample[i * iInterpolate * btFilter.iChannels]; + } + iNormal >>= iShift; + + // centre should also be compensated for the rounding down of + // (iPixelsIn * iInterpolate) / iDecimate, so must convert back + iCentreQuantised = iSizeQuantised / 2; + + iCoefficientStep = iInterpolate * btFilter.iChannels; + fiCoefficientStep = (btFilter.iChannels >= pbtIn->iChannels); + + j = 0; + iIntermediate = 0; + for (i = 0; i < iPixelsQuantised; i++) + { +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiSincResample2D: " + "Overflowed output buffer at sample %08x\n", j); + BmpFree(&btFilter); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + // integer and fraction variables are used for clarity, + // and could be optimised with modulo arithmetic, but + // there is little point optimising this part of the + // loop since we are doing vector multiplication later + iInteger = iIntermediate / iInterpolate; + iFraction = iIntermediate % iInterpolate; + iIntermediate += iDecimate; + + // left side of window is recalculated each time through, + // to avoid issues with the rounding of negative numbers + iLeftQuantised = iInteger - iCentreQuantised; + + // input data window size is constant, so the quantised + // value calculated in the beginning is used for clipping + iLeftClipped = max(iLeftQuantised, 0) * pbtIn->iChannels; + iRightClipped = min(iLeftQuantised + iSizeQuantised, iPixelsIn) * + pbtIn->iChannels; + + // fraction here ensures that we move through the + // available coefficients for smooth interpolation, the + // compensation for clipping is done using quantised + // values especially to avoid disturbing this effect + iCoefficient = ((iInterpolate - iFraction - 1) + + max(0, -iLeftQuantised) * iInterpolate) * + btFilter.iChannels; + + for (m = 0; m < pbtIn->iChannels; m++) + { + iThis = 0; + + l = iCoefficient; + iCoefficient += fiCoefficientStep; + + for (k = iLeftClipped++; k < iRightClipped; + k += pbtIn->iChannels) + { + iThis += (pbtIn->pucSample[k] * btFilter.pucSample[l]) >> + iShift; + l += iCoefficientStep; + } + + iRightClipped++; + + iThis /= iNormal; + if (iThis > 0xff) + { + iThis = 0xff; + } + if (iThis < 0) + { + iThis = 0; + } + + pbtOut->pucSample[j++] = iThis; + } + } + + BmpFree(&btFilter); + +#if 1 + if (j < pbtOut->iSampleLimit) + { + printf("fiSincResample2D: " + "Partially filled output buffer to sample %08x\n", j); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = j; + return TRUE; + } +#endif + +// ---------------------------------------------------------------------------- + +int fiMakeSincFilter2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxSize, int cySize, int cxCutoff, int cyCutoff) + { + BITMAPINFOHEADER bih; + int i, j, m, x, y, iThis; + float fxScale, fyScale; + float fxCentre, fyCentre; + float fxWindow, fyWindow; + float fxThis, fyThis; + + // the sinc filter will have the same file format as the input data, + // except that channels is set to 1 because the same filter will be + // used on all colour channels, and bits per sample is set to 8 + // to reduce the number of combinations to be handled when filtering. + // + // note: the sinc filter will adopt the same sample rate as the input, + // which is not exactly correct if overall interpolation will be used. + + memcpy(&bih, pbtIn->pbih, sizeof(BITMAPINFOHEADER)); + + bih.biBitCount = 8; + + if (fiBmpAllocate(pbtOut, &bih, cxSize, cySize) == FALSE) + { + printf("fiMakeSincFilter2D: " + "Failed to allocate output buffer of %08x samples\n", + cxSize, cySize); + return FALSE; + } + + fxCentre = (cxSize - 1) / 2.0; + fyCentre = (cySize - 1) / 2.0; + + fxScale = (6.283185307 * cxCutoff) / cxSize; + fyScale = (6.283185307 * cyCutoff) / cySize; + + i = 0; + for (y = 0; y < cySize; y++) + { + j = i; + i += pbtOut->iSamplesLine; + + fyWindow = 1 - min(y + 1, cySize - y) / fyCentre; + fyWindow = 1 - fyWindow * fyWindow; + + fyThis = fyScale * (y - fyCentre); + if (fyThis) + { + fyThis = sin(fyThis) / fyThis; + } + else + { + fyThis = 1; + } + + for (x = 0; x < cxSize; x++) + { + fxWindow = 1 - min(x + 1, cxSize - x) / fxCentre; + fxWindow = 1 - fxWindow * fxWindow; + + fxThis = fxScale * (x - fxCentre); + if (fxThis) + { + fxThis = sin(fxThis) / fxThis; + } + else + { + fxThis = 1; + } + + // the filter gain is fixed here, but will later be adjusted by + // normalisation (only the caller knows the interpolation in use) + iThis = fxThis * fyThis * fxWindow * fyWindow * 0xcf + 0x30; + +#if 1 + if (j >= pbtOut->iSampleLimit) + { + printf("fiMakeSincFilter2D: " + "Overflowed output buffer at sample %08x\n", j); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + //for (m = 0; m < pbtOut->iChannels; m++) // always 1 for now + { + pbtOut->pucSample[j++] = iThis; + } + } + } + +#if 1 + if (j < pbtOut->iSampleLimit) + { + printf("fiMakeSincFilter2D: " + "Partially filled output buffer to sample %08x\n", j); + BmpFree(pbtOut); + return FALSE; // should never happen + } +#endif + + pbtOut->iSampleAppend = j; + return TRUE; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hyimage.h b/src/mkfont/hyimage.h new file mode 100644 index 00000000..645f57cc --- /dev/null +++ b/src/mkfont/hyimage.h @@ -0,0 +1,104 @@ +// hyimage.h + +// ---------------------------------------------------------------------------- + +#define FILTER_CUTOFF 2 // cutoff/overlap should be 1/2 for nyquist frequency +#define FILTER_OVERLAP 4 // history size, in slow-samples, for interp/decimate + +// ---------------------------------------------------------------------------- + +/* +typedef struct tagBITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; + +typedef struct tagBITMAPINFOHEADER{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; + +typedef struct tagRGBQUAD { + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; +} RGBQUAD; +typedef RGBQUAD FAR* LPRGBQUAD; + +typedef struct tagRECT +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; +*/ + +typedef struct + { + FILETAG ft; // ft.pcBase points to WAV_FILE_HEADER followed by data + + BITMAPFILEHEADER *pbfh; // easier than (BITMAPINFOHEADER *) ft.pcBase + BITMAPINFOHEADER *pbih; // easier than (BITMAPINFOHEADER *) (ft.pcBase+x) + RGBQUAD *prgbq; // easier than (RGBQUAD *) (ft.pcBase+y), base of palette + unsigned char *pucSample; // points after BITMAPINFOHEADER and palette + + int iChannels; // max(biBitCount / 8, 1), because usoft is so very lame + int iBitsChannel; // always biBitcount / iChannels, because usoft is lame + int iSamplesLine; // generally in bytes, this offset includes wasted part + + int iSampleBase; // usually 0 unless client wants to do advanced looping + int iSampleLimit; // iSampleAppend or larger if block is of arbitrary size + int iSamplePosition; // for general use, initialised to 0 for client + int iSampleAppend; // calculated for client, pbih->biHeight * iSamplesLine + + int iBackground; // dc bias per channel, to be removed for calculations + int cxHot, cyHot; // reference point on image for client use, or centre + + //RECT rPixelWindow; // set up from the exact pixel image size via pbih + //RECT rPixelSurface; // same as rPixelWindow, except rRight includes waste + } BMPTAG; + +// ---------------------------------------------------------------------------- + +int fiBmpAllocate(BMPTAG *pbt, BITMAPINFOHEADER *pbihIn, + int cxPixels, int cyPixels); +int fiBmpReadIn(BMPTAG *pbt, char *pszFileName); +int fiBmpWriteOut(BMPTAG *pbt, char *pszFileName); +void BmpFree(BMPTAG *pbt); +int fiBmpCopy(BMPTAG *pbt, BMPTAG *pbtIn); + +int fiLinearExpand2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxFactor, int cyFactor); + +int fiLinearShrink2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxFactor, int cyFactor); + +int fiSincInterpolate2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxInterpolate, int cyInterpolate); + +int fiSincDecimate2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxDecimate, int cyDecimate); + +int fiSincResample2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxInterpolate, int cyInterpolate, + int cxDecimate, int cyDecimate); + +int fiMakeSincFilter2D(BMPTAG *pbtOut, BMPTAG *pbtIn, + int cxSize, int cySize, int cxCutoff, int cyCutoff); + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hymb.cpp b/src/mkfont/hymb.cpp new file mode 100644 index 00000000..bd465734 --- /dev/null +++ b/src/mkfont/hymb.cpp @@ -0,0 +1,117 @@ +// hymb.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#pragma hdrstop +#include "hymb.h" + +// ---------------------------------------------------------------------------- + +void MBEntrySetup(void) + { + // for future expansion + } + +void MBExitCleanup(void) + { + // for future expansion + } + +// ---------------------------------------------------------------------------- + +int fiMBAlloc(MBHANDLE *pmbh, int iBytes) + { + // zero the entire memory block handle area, avoiding leaks + memset(pmbh, 0, sizeof(MBHANDLE)); + + pmbh->pcBase = (char *) malloc(iBytes); + if (pmbh->pcBase == NULL) + { + return FALSE; // indicates failure to allocate block + } + + pmbh->pcLimit = pmbh->pcBase + iBytes; + + return TRUE; // indicates success and handle set up + } + +int fiMBRealloc(MBHANDLE *pmbh, int iBytes) + { + char *pc; + + pc = (char *) realloc(pmbh->pcBase, iBytes); + if (pc == NULL) + { + return FALSE; // indicates failure to reallocate block + } + + pmbh->pcBase = pc; + pmbh->pcLimit = pmbh->pcBase + iBytes; + + return TRUE; // indicates success and handle updated + } + +int fiMBFree(MBHANDLE *pmbh) + { + if (pmbh->pcBase == NULL) + { + return FALSE; // indicates no such block allocated + } + + free(pmbh->pcBase); // this can't fail, apparently + + // zero the entire memory block handle area, avoiding leaks + memset(pmbh, 0, sizeof(MBHANDLE)); + + return TRUE; // indicates success, and handle zeroed + } + +// ---------------------------------------------------------------------------- + +#ifdef _INC_JLHANDLE +int hiMBNew(int iBytes) + { + int hi; + MBHANDLE *pmbh; + + // take a new handle, before bothering with memory + hi = hiJLHandleNew(patMBH); + pmbh = (MBHANDLE *) pcArrayElement(patMBH, 1, hi); + + // use inline wrapper to allocate the required bytes + MBAlloc(pmbh, iBytes); // this will bomb on failure + + return hi; // caller's reference is the opaque handle + } + +void MBResize(int hi, int iBytes) + { + MBHANDLE *pmbh; + + // find supplied handle, before bothering with memory + pmbh = (MBHANDLE *) pcArrayElement(patMBH, 1, hi); + + // use inline wrapper to reallocate the required bytes + MBRealloc(pmbh, iBytes); // this will bomb on failure + } + +void MBDelete(int hi) + { + // find supplied handle, before bothering with memory + pmbh = (MBHANDLE *) pcArrayElement(patMBH, 1, hi); + + // use inline wrapper to free up the allocated memory + MBFree(pmbh); // this will bomb on failure (null pcBase) + } + +int hiMBDelete(int hi) + { + MBDelete(hi); + return 0; // handy way for caller to zero out its copy of handle + } +#endif + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/hymb.h b/src/mkfont/hymb.h new file mode 100644 index 00000000..86e60e62 --- /dev/null +++ b/src/mkfont/hymb.h @@ -0,0 +1,95 @@ +// hymb.h + +#ifndef _INC_HYMB +#define _INC_HYMB + +// ---------------------------------------------------------------------------- + +typedef struct + { + char *pcBase; // also the 'handle' for malloc & free + char *pcLimit; // similar to Microsoft's _msize func. + } MBHANDLE; + +// ---------------------------------------------------------------------------- + +#ifdef _INC_JLHANDLE +// the optional registration of allocated memory blocks is based on a handle +// system identical to JLHANDLE.CPP, see comments for atJLHandle, patJLH etc + +extern ARRAYTAG atMBHandle; + +extern int hiMBHandleFree; // to head of most recently used free handles list +extern ARRAYTAG *patMBH; // patMBH is slightly more readable than &atMBHandle +#endif + +// ---------------------------------------------------------------------------- + +void MBEntrySetup(void); +void MBExitCleanup(void); + +int fiMBAlloc(MBHANDLE *pmbh, int iBytes); +int fiMBRealloc(MBHANDLE *pmbh, int iBytes); +int fiMBFree(MBHANDLE *pmbh); + +// ---------------------------------------------------------------------------- + +inline int iMBSize(MBHANDLE *pmbh) + { + return pmbh->pcLimit - pmbh->pcBase; + } + +// ---------------------------------------------------------------------------- +// handy functions for the client, not important to the interface: + +#ifdef _INC_STDIO +inline void MBAlloc(MBHANDLE *pmbh, int iBytes) + { + if (fiMBAlloc(pmbh, iBytes) == FALSE) + { + printf("MBAlloc: " + "Could not allocate %08x bytes, exiting\n", iBytes); + exit(1); + } + +#ifdef DEBUG + printf("MBAlloc: " + "Allocated memory block %08x size %08x\n", pmbh, iBytes); +#endif + } + +inline void MBRealloc(MBHANDLE *pmbh, int iBytes) + { + if (fiMBRealloc(pmbh, iBytes) == FALSE) + { + printf("MBRealloc: " + "Could not reallocate %08x bytes, exiting\n", iBytes); + exit(1); + } + +#ifdef DEBUG + printf("MBRealloc: " + "Reallocated memory block %08x size %08x\n", pmbh, iBytes); +#endif + } + +inline void MBFree(MBHANDLE *pmbh) + { + if (fiMBFree(pmbh) == FALSE) + { + printf("MBFree: " + "Could not free memory block %08x, exiting\n", pmbh); + exit(1); + } + +#ifdef DEBUG + printf("MBFree: " + "Freed memory block %08x\n", pmbh); +#endif + } +#endif + +// ---------------------------------------------------------------------------- + +#endif + diff --git a/src/mkfont/n.bat b/src/mkfont/n.bat new file mode 100644 index 00000000..c01cf7b4 --- /dev/null +++ b/src/mkfont/n.bat @@ -0,0 +1,18 @@ +cl -Zi -I. bmp2txt.cpp hyimage.cpp hyfile.cpp hyfs.cpp hymb.cpp +@if errorlevel 1 goto failure +copy bmp2txt.exe ..\bin + +cl -Zi -I. txt2chs.cpp hyfile.cpp hyfs.cpp hymb.cpp +@if errorlevel 1 goto failure +copy txt2chs.exe ..\bin + +cl -Zi -I. chs2cmd.cpp hyfile.cpp hyfs.cpp hymb.cpp +@if errorlevel 1 goto failure +copy chs2cmd.exe ..\bin + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/mkfont/txt2chs.cpp b/src/mkfont/txt2chs.cpp new file mode 100644 index 00000000..46f6c4ab --- /dev/null +++ b/src/mkfont/txt2chs.cpp @@ -0,0 +1,431 @@ +// txt2chs.cpp + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#pragma hdrstop +#include "hymb.h" +#include "hyfs.h" +#include "hyfile.h" + +int main(int argc, char **argv); +int fiProcess(FILETAG *ftOut, FILETAG *ftIn, int iICS, int iILS); +int iCompare(const void *pvLeft, const void *pvRight); +int iUpdateCRC(char *pcBase, int iCount, int iCRC); + +// ---------------------------------------------------------------------------- + +FILETAG ftIn; +char *pszInFileName; + +FILETAG ftOut; +char *pszOutFileName; +char szOutFileName[512]; + +// ---------------------------------------------------------------------------- + +int main(int argc, char **argv) + { + int i, iICS, iILS; + + if (argc > 1) + { + pszInFileName = argv[1]; + } + + iICS = 0; + iILS = 0; + if (argc > 2) + { + iICS = atoi(argv[2]); + if (iICS < 1 || iICS > 0xff) + { + pszOutFileName = argv[2]; + if (argc > 3) + { + iICS = atoi(argv[3]); + if (argc > 4) + { + iILS = atoi(argv[4]); + } + } + } + else + { + if (argc > 3) + { + iILS = atoi(argv[3]); + } + } + } + + if (pszInFileName == NULL) + { + printf("usage: txt2chs infile.txt [outfile.chs] [ICS] [ILS]\n"); + exit(1); + } + + if (pszOutFileName == NULL) + { + pszOutFileName = szOutFileName; + strcpy(pszOutFileName, pszInFileName); + + i = strlen(pszOutFileName); + while (i--) + { + if (pszOutFileName[i] == '\\') + { + break; /* no extension, so don't strip it */ + } + if (pszOutFileName[i] == '.') + { + pszOutFileName[i] = 0; /* strip dot and extension */ + break; /* ready to concatenate our extension */ + } + } + + strcat(pszOutFileName, ".chs"); + } + + if (!strcmp(pszInFileName, pszOutFileName)) + { + printf("Input and output filenames identical\n"); + exit(1); + } + + // read the input bmp file entirely to a malloc'd block + FileReadIn(&ftIn, pszInFileName); + + // prepare an output buffer for character set data + FileAllocate(&ftOut, 0x100000); // 64 kbytes + + // search for characters and write character set files + if (fiProcess(&ftOut, &ftIn, iICS, iILS) == FALSE) + { + exit(1); + } + + // ready to write the output we found + FileWriteOut(&ftOut, pszOutFileName); + + // all done my friend + FileFree(&ftIn); + FileFree(&ftOut); + + return 0; + } + +// ---------------------------------------------------------------------------- + +int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS) + { + char *pc; + char sz[0x203]; + int i, j, c, d; + int x, y, cx, cy; + int tx, ty, bx, fx; + int x0, x1, x2, y0, y1, y2; + int mx, my; + MBHANDLE mbh; + unsigned short *pus; + int iValue, iMask; + int iWidth[0x100], iHeight[0x100]; + int iCRC; + + pc = pftOut->pcBase; + + strcpy(pc, "XXXXYYMMDDHHMMSS"); + pc += 0x10; + pus = (unsigned short *)pc; + memset(pc, 0, 0x208); + pc += 0x208; + + // create the microspace characters + *pc++ = 1; // inter character space should be ignored here + pus[1] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = 2; // inter character space should be ignored here + pus[2] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = 3; // inter character space should be ignored here + pus[3] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = 4; // inter character space should be ignored here + pus[4] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = -4; // inter character space should be ignored here + pus[5] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = -3; // inter character space should be ignored here + pus[6] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = -2; // inter character space should be ignored here + pus[7] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = -1; // inter character space should be ignored here + pus[8] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = 12; // inter character space should be ignored here + pus[0x1c] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + *pc++ = -12; // inter character space should be ignored here + pus[0x1d] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + if (iICS < 1 || iICS > 0xff) + { + iICS = 1; + } + + if (iILS < 1 || iILS > 0xff) + { + iILS = 1; + } + + c = '!'; + d = 0; + while (fiFileGetLine(pftIn, sz, sizeof(sz) - 1, NULL)) + { + if (sscanf(sz, "at %d,%d size %d,%d", &x, &y, &cx, &cy) == 4) + { + /*printf("at %d,%d size %d,%d\n", x, y, cx, cy);*/ + + if (c >= 0x100 || d >= 0x100) + { + printf("Too many characters\n"); + break; /* exit(1); */ + } + + MBAlloc(&mbh, cx * cy); + i = 0; + + x0 = cx; + x1 = 0; + x2 = 0; + y0 = cy; + y1 = 0; + y2 = cy; + for (y = 0; y < cy; y++) + { + if (fiFileGetLine(pftIn, sz, sizeof(sz) - 1, + &j) == FALSE) + { + printf("Unexpected end of file\n"); + break; /* exit(1); */ + } + + if (j < (cx * 2)) + { + printf("Line too short in file\n"); + break; /* exit(1); */ + } + + for (x = 0; x < cx; x++) + { + if (sz[x * 2] == '#') + { + mbh.pcBase[i++] = 1; + x0 = min(x0, x); + x1 = max(x1, x + 1); + y0 = min(y0, y); + y1 = max(y1, y + 1); + } + else + { + mbh.pcBase[i++] = 0; + if (sz[x * 2] == '_') + { + y2 = y + 1; + } + } + } + } + + tx = max(0, x1 - x0); // trimmed width in pixels + ty = max(0, y1 - y0); // trimmed height in pixels + printf("at %d,%d trim %d,%d origin %d,%d\n", + x0, y0, tx, ty, x2, y2); + + iWidth[d] = tx; // save for median calculation + iHeight[d] = ty; // save for median calculation + + bx = (tx + 7) >> 3; // width in bytes + + if (x2) + { + *pc++ = x0 - x2; + *pc++ = y0 - y2; + *pc++ = tx + iICS; + pus[c] = pc - (char *)pus; + *pc++ = bx | 0xe0; + } + else if (y2) + { + *pc++ = y0 - y2; + *pc++ = tx + iICS; + pus[c] = pc - (char *)pus; + *pc++ = bx | 0x60; + } + else + { + *pc++ = tx + iICS; + pus[c] = pc - (char *)pus; + *pc++ = bx | 0x20; + } + + if (bx) + { + *pc++ = ty; + + i = y0 * cx; + for (y = y0; y < y1; y++) + { + j = i + x0; + i += cx; + + iValue = 0; + iMask = 0x80; + for (x = x0; x < x1; x++) + { + if (iMask == 0) + { + *pc++ = iValue; + + iValue = 0; + iMask = 0x80; + } + + if (mbh.pcBase[j++]) + { + iValue |= iMask; + } + + iMask >>= 1; + } + + *pc++ = iValue; + } + } + + MBFree(&mbh); + + c++; // character code for index updating + d++; // character code for median calculation + } + } + + printf("%d characters in range %d,%d inclusive\n", d, 0x21, c - 1); + + // post process widths/heights now we've had all characters + mx = 0; + my = 0; + if (d) + { + qsort(iWidth, d, sizeof(int), iCompare); + mx = iWidth[d / 2]; // find median width + + qsort(iHeight, d, sizeof(int), iCompare); + my = iHeight[d / 2]; // find median height + } + + printf("median %d,%d cell %d,%d space %d,%d\n", + mx, my, mx + iICS, my + iILS, iICS, iILS); + + // create the space character (now that we have width) + *pc++ = mx; // should be mx + iICS but we cheat a little + pus[' '] = pc - (char *)pus; + *pc++ = 0x60; // indicates we have width but nothing else + + // set file length, as all data has now been appended + pftOut->pcAppend = pc; + + // fill out the table with minus signs for undefined chars + for (c = 0; c < 0x100; c++) + { + if (pus[c] == 0) + { + pus[c] = pus['-']; + if (pus[c] == 0) + { + pus[c] = pus[' ']; // or space if no minus + } + } + } + + // fill in header fields that weren't known until now + pc = (char *)(pus + 0x100); + *pc++ = mx + iICS; + *pc++ = my + iILS; + *pc++ = iICS; + *pc++ = iILS; + *pc++ = 'O'; // character to use for uncrossed zero + *pc++ = 0; // spare + *(int *)pc = pftOut->pcAppend - pftOut->pcBase; + + // calculate and insert CRC using character set algorithm + pc = pftOut->pcBase + 4; + iCRC = iUpdateCRC(pc, pftOut->pcAppend - pc, 0xffff); + + pc = pftOut->pcBase; + for (i = 0; i < 4; i++) + { + *pc++ = "0123456789ABCDEF"[(iCRC >> 12) & 0xf]; + iCRC <<= 4; + } + + return TRUE; + } + +int iCompare(const void *pvLeft, const void *pvRight) + { + if (*(int *)pvLeft < *(int *)pvRight) + { + return -1; + } + + if (*(int *)pvLeft > *(int *)pvRight) + { + return 1; + } + + return 0; + } + +int iUpdateCRC(char *pcBase, int iCount, int iCRC) + { + int i, j; + + for (i = 0; i < iCount; i++) + { + iCRC ^= (pcBase[i] << 8); + for (j = 0; j < 8; j++) + { + if (iCRC & 0x8000) + { + iCRC = (iCRC << 1) ^ 0x1021; + } + else + { + iCRC <<= 1; + } + } + } + + return iCRC; + } + +// ---------------------------------------------------------------------------- + diff --git a/src/mkfont/txt2chs.exe b/src/mkfont/txt2chs.exe new file mode 100644 index 0000000000000000000000000000000000000000..e5eb754e6de2a2998defeb509c2ffaa14f3b75a1 GIT binary patch literal 86062 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

      EW)7 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 SiUA}Jl0#D~UmlVrN&jEP6kHep diff --git a/src/mkutil/as-z80/as-z80.exe b/src/mkutil/as-z80/as-z80.exe new file mode 100644 index 0000000000000000000000000000000000000000..912b5f73c0ced87ec20975ffd823cfe1e1182e42 GIT binary patch literal 122932 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 + 0003:00006020 _rel 0041b020 + 0003:00006040 _txt 0041b040 + 0003:00006050 _fflag 0041b050 + 0003:000064e0 _module 0041b4e0 + 0003:00006534 _tlevel 0041b534 + 0003:00006538 _symp 0041b538 + 0003:0000653c _inpfil 0041b53c + 0003:00006540 _afn 0041b540 + 0003:00006640 _afp 0041b640 + 0003:00006644 _lmode 0041b644 + 0003:00006660 _cbt 0041b660 + 0003:00006860 _symhash 0041b860 + 0003:00006960 _mnehash 0041b960 + 0003:00006a60 _srcfn 0041ba60 + 0003:00007060 _laddr 0041c060 + 0003:00007080 _srcfp 0041c080 + 0003:00007098 _cpt 0041c098 + 0003:0000709c _fuzz 0041c09c + 0003:000070a0 _erb 0041c0a0 + 0003:00007124 _incfil 0041c124 + 0003:00007140 _incfn 0041c140 + 0003:00007740 _incfp 0041c740 + 0003:00007760 _ifp 0041c760 + 0003:00007778 _cfile 0041c778 + 0003:0000777c _lfp 0041c77c + 0003:00007780 _gflag 0041c780 + 0003:00007784 _a_mask 0041c784 + 0003:00007788 _line 0041c788 + 0003:0000778c _lop 0041c78c + 0003:00007790 _ofp 0041c790 + 0003:00007794 _zflag 0041c794 + 0003:000077a0 _srcline 0041c7a0 + 0003:000077b8 _oflag 0041c7b8 + 0003:000077c0 _sfp 0041c7c0 + 0003:000077d8 _areap 0041c7d8 + 0003:000077dc _tfp 0041c7dc + 0003:000077e0 _page 0041c7e0 + 0003:00007800 _stb 0041c800 + 0003:00007850 _pass 0041c850 + 0003:00007854 _sflag 0041c854 + 0003:00007860 _cb 0041c860 + 0003:000078e0 _eb 0041c8e0 + 0003:000078e4 _cp 0041c8e4 + 0003:000078e8 _aserr 0041c8e8 + 0003:000078ec _ep 0041c8ec + 0003:00007900 _ib 0041c900 + 0003:00007980 _wflag 0041c980 + 0003:00007984 _ip 0041c984 + 0003:000079a0 _afntmp 0041c9a0 + 0003:00007aa0 _tb 0041caa0 + 0003:00007af0 _lflag 0041caf0 + 0003:00007af4 _a_bytes 0041caf4 + 0003:00007af8 _afptmp 0041caf8 + 0003:00007afc _pflag 0041cafc + 0003:00007b00 _incline 0041cb00 + 0003:00007b18 _aflag 0041cb18 + 0003:00007b20 _ifcnd 0041cb20 + 0003:00007b4c _s_mask 0041cb4c + 0003:00007b50 _xflag 0041cb50 + 0003:00007b54 _radix 0041cb54 + 0003:00007b58 _flevel 0041cb58 + 0003:00007b60 _jump_env 0041cb60 + 0003:00007ba0 _v_mask 0041cba0 + 0003:00007bc0 _iflvl 0041cbc0 + 0003:00007bec ___mbcodepage 0041cbec + 0003:00007c70 ___mbulinfo 0041cc70 + 0003:00007c7c ___ismbcodepage 0041cc7c + 0003:00007c80 __mbcasemap 0041cc80 + 0003:00007d80 __mbctype 0041cd80 + 0003:00007e84 ___mblcid 0041ce84 + 0003:00007e88 ___sbh_sizeHeaderList 0041ce88 + 0003:00007e9c ___sbh_indGroupDefer 0041ce9c + 0003:00007ea0 ___sbh_pHeaderScan 0041cea0 + 0003:00007ea4 ___sbh_initialized 0041cea4 + 0003:00007ea8 ___sbh_pHeaderDefer 0041cea8 + 0003:00007eac ___sbh_cntHeaderList 0041ceac + 0003:00007eb0 ___sbh_pHeaderList 0041ceb0 + 0003:00007eb4 ___sbh_threshold 0041ceb4 + 0003:00007eb8 __crtheap 0041ceb8 + 0003:00007ec8 ___active_heap 0041cec8 + 0003:00007ee0 ___pioinfo 0041cee0 + 0003:0000801c __nhandle 0041d01c + 0003:00008020 __acmdln 0041d020 + 0003:0000802c __setjmpexused 0041d02c + 0003:00008038 ___env_initialized 0041d038 + 0003:00008048 ___mbctype_initialized 0041d048 + 0003:0000804c ___onexitend 0041d04c + 0003:00008050 ___onexitbegin 0041d050 + 0003:00008054 __FPinit 0041d054 + 0003:00008058 ___piob 0041d058 + 0003:000083a0 __bufin 0041d3a0 + 0003:000093a0 __nstream 0041e3a0 + 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 0041f000 kernel32:KERNEL32.dll + 0004:00000014 __NULL_IMPORT_DESCRIPTOR 0041f014 kernel32:KERNEL32.dll + 0004:00000134 __imp__IsBadWritePtr@8 0041f134 kernel32:KERNEL32.dll + 0004:00000138 __imp__ExitProcess@4 0041f138 kernel32:KERNEL32.dll + 0004:0000013c __imp__TerminateProcess@8 0041f13c kernel32:KERNEL32.dll + 0004:00000140 __imp__GetCurrentProcess@0 0041f140 kernel32:KERNEL32.dll + 0004:00000144 __imp__GetCommandLineA@0 0041f144 kernel32:KERNEL32.dll + 0004:00000148 __imp__GetVersion@0 0041f148 kernel32:KERNEL32.dll + 0004:0000014c __imp__HeapFree@12 0041f14c kernel32:KERNEL32.dll + 0004:00000150 __imp__GetLastError@0 0041f150 kernel32:KERNEL32.dll + 0004:00000154 __imp__CloseHandle@4 0041f154 kernel32:KERNEL32.dll + 0004:00000158 __imp__SetFilePointer@16 0041f158 kernel32:KERNEL32.dll + 0004:0000015c __imp__SetHandleCount@4 0041f15c kernel32:KERNEL32.dll + 0004:00000160 __imp__GetStdHandle@4 0041f160 kernel32:KERNEL32.dll + 0004:00000164 __imp__GetFileType@4 0041f164 kernel32:KERNEL32.dll + 0004:00000168 __imp__GetStartupInfoA@4 0041f168 kernel32:KERNEL32.dll + 0004:0000016c __imp__WriteFile@20 0041f16c kernel32:KERNEL32.dll + 0004:00000170 __imp__GetModuleHandleA@4 0041f170 kernel32:KERNEL32.dll + 0004:00000174 __imp__GetModuleFileNameA@12 0041f174 kernel32:KERNEL32.dll + 0004:00000178 __imp__GetEnvironmentVariableA@12 0041f178 kernel32:KERNEL32.dll + 0004:0000017c __imp__GetVersionExA@4 0041f17c kernel32:KERNEL32.dll + 0004:00000180 __imp__HeapDestroy@4 0041f180 kernel32:KERNEL32.dll + 0004:00000184 __imp__HeapCreate@12 0041f184 kernel32:KERNEL32.dll + 0004:00000188 __imp__VirtualFree@12 0041f188 kernel32:KERNEL32.dll + 0004:0000018c __imp__VirtualAlloc@16 0041f18c kernel32:KERNEL32.dll + 0004:00000190 __imp__HeapReAlloc@16 0041f190 kernel32:KERNEL32.dll + 0004:00000194 __imp__HeapAlloc@12 0041f194 kernel32:KERNEL32.dll + 0004:00000198 __imp__RtlUnwind@16 0041f198 kernel32:KERNEL32.dll + 0004:0000019c __imp__UnhandledExceptionFilter@4 0041f19c kernel32:KERNEL32.dll + 0004:000001a0 __imp__FreeEnvironmentStringsA@4 0041f1a0 kernel32:KERNEL32.dll + 0004:000001a4 __imp__FreeEnvironmentStringsW@4 0041f1a4 kernel32:KERNEL32.dll + 0004:000001a8 __imp__WideCharToMultiByte@32 0041f1a8 kernel32:KERNEL32.dll + 0004:000001ac __imp__GetEnvironmentStrings@0 0041f1ac kernel32:KERNEL32.dll + 0004:000001b0 __imp__GetEnvironmentStringsW@0 0041f1b0 kernel32:KERNEL32.dll + 0004:000001b4 __imp__SetStdHandle@8 0041f1b4 kernel32:KERNEL32.dll + 0004:000001b8 __imp__FlushFileBuffers@4 0041f1b8 kernel32:KERNEL32.dll + 0004:000001bc __imp__ReadFile@20 0041f1bc kernel32:KERNEL32.dll + 0004:000001c0 __imp__CreateFileA@28 0041f1c0 kernel32:KERNEL32.dll + 0004:000001c4 __imp__GetCPInfo@8 0041f1c4 kernel32:KERNEL32.dll + 0004:000001c8 __imp__GetACP@0 0041f1c8 kernel32:KERNEL32.dll + 0004:000001cc __imp__GetOEMCP@0 0041f1cc kernel32:KERNEL32.dll + 0004:000001d0 __imp__GetProcAddress@8 0041f1d0 kernel32:KERNEL32.dll + 0004:000001d4 __imp__LoadLibraryA@4 0041f1d4 kernel32:KERNEL32.dll + 0004:000001d8 __imp__SetEndOfFile@4 0041f1d8 kernel32:KERNEL32.dll + 0004:000001dc __imp__MultiByteToWideChar@24 0041f1dc kernel32:KERNEL32.dll + 0004:000001e0 __imp__LCMapStringA@24 0041f1e0 kernel32:KERNEL32.dll + 0004:000001e4 __imp__LCMapStringW@24 0041f1e4 kernel32:KERNEL32.dll + 0004:000001e8 __imp__GetStringTypeA@20 0041f1e8 kernel32:KERNEL32.dll + 0004:000001ec __imp__GetStringTypeW@16 0041f1ec kernel32:KERNEL32.dll + 0004:000001f0 \177KERNEL32_NULL_THUNK_DATA 0041f1f0 kernel32:KERNEL32.dll + + entry point at 0001:0000acf3 + diff --git a/src/as-z80/asdata.c b/src/mkutil/as-z80/asdata.c similarity index 100% rename from src/as-z80/asdata.c rename to src/mkutil/as-z80/asdata.c diff --git a/src/as-z80/asexpr.c b/src/mkutil/as-z80/asexpr.c similarity index 100% rename from src/as-z80/asexpr.c rename to src/mkutil/as-z80/asexpr.c diff --git a/src/as-z80/aslex.c b/src/mkutil/as-z80/aslex.c similarity index 100% rename from src/as-z80/aslex.c rename to src/mkutil/as-z80/aslex.c diff --git a/src/as-z80/aslist.c b/src/mkutil/as-z80/aslist.c similarity index 100% rename from src/as-z80/aslist.c rename to src/mkutil/as-z80/aslist.c diff --git a/src/as-z80/asmain.c b/src/mkutil/as-z80/asmain.c similarity index 100% rename from src/as-z80/asmain.c rename to src/mkutil/as-z80/asmain.c diff --git a/src/as-z80/asout.c b/src/mkutil/as-z80/asout.c similarity index 100% rename from src/as-z80/asout.c rename to src/mkutil/as-z80/asout.c diff --git a/src/as-z80/assubr.c b/src/mkutil/as-z80/assubr.c similarity index 100% rename from src/as-z80/assubr.c rename to src/mkutil/as-z80/assubr.c diff --git a/src/as-z80/assym.c b/src/mkutil/as-z80/assym.c similarity index 100% rename from src/as-z80/assym.c rename to src/mkutil/as-z80/assym.c diff --git a/src/as-z80/asxxxx.h b/src/mkutil/as-z80/asxxxx.h similarity index 100% rename from src/as-z80/asxxxx.h rename to src/mkutil/as-z80/asxxxx.h diff --git a/src/as-z80/n.bat b/src/mkutil/as-z80/n.bat similarity index 93% rename from src/as-z80/n.bat rename to src/mkutil/as-z80/n.bat index b8d45f52..95e3d73c 100644 --- a/src/as-z80/n.bat +++ b/src/mkutil/as-z80/n.bat @@ -24,7 +24,7 @@ cl -Zi -I. -DWIN32 -c z80pst.c @if errorlevel 1 goto failure link @as-z80.lnk @if errorlevel 1 goto failure -copy as-z80.exe ..\bin +copy as-z80.exe ..\..\bin @echo SUCCESS @goto done diff --git a/src/as-z80/tz80.asm b/src/mkutil/as-z80/tz80.asm similarity index 100% rename from src/as-z80/tz80.asm rename to src/mkutil/as-z80/tz80.asm diff --git a/src/as-z80/tz80l.asm b/src/mkutil/as-z80/tz80l.asm similarity index 100% rename from src/as-z80/tz80l.asm rename to src/mkutil/as-z80/tz80l.asm diff --git a/src/as-z80/z80.h b/src/mkutil/as-z80/z80.h similarity index 100% rename from src/as-z80/z80.h rename to src/mkutil/as-z80/z80.h diff --git a/src/as-z80/z80adr.c b/src/mkutil/as-z80/z80adr.c similarity index 100% rename from src/as-z80/z80adr.c rename to src/mkutil/as-z80/z80adr.c diff --git a/src/as-z80/z80ext.c b/src/mkutil/as-z80/z80ext.c similarity index 100% rename from src/as-z80/z80ext.c rename to src/mkutil/as-z80/z80ext.c diff --git a/src/as-z80/z80mch.c b/src/mkutil/as-z80/z80mch.c similarity index 100% rename from src/as-z80/z80mch.c rename to src/mkutil/as-z80/z80mch.c diff --git a/src/as-z80/z80pst.c b/src/mkutil/as-z80/z80pst.c similarity index 100% rename from src/as-z80/z80pst.c rename to src/mkutil/as-z80/z80pst.c diff --git a/src/as-z80/z80pst.c$ b/src/mkutil/as-z80/z80pst.c$ similarity index 100% rename from src/as-z80/z80pst.c$ rename to src/mkutil/as-z80/z80pst.c$ diff --git a/src/mkutil/avra-0.8/COPYING b/src/mkutil/avra-0.8/COPYING new file mode 100644 index 00000000..1942c433 --- /dev/null +++ b/src/mkutil/avra-0.8/COPYING @@ -0,0 +1,341 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/mkutil/avra-0.8/ChangeLog b/src/mkutil/avra-0.8/ChangeLog new file mode 100644 index 00000000..f974ea4f --- /dev/null +++ b/src/mkutil/avra-0.8/ChangeLog @@ -0,0 +1,47 @@ +Release 0.8 released by Tobias Weber + (20030307) + - Added new macro assembler coding facilities + - Added error description for .include directives +Release 0.7 + (20000217) - Added supported() function to check in a .if if a instruction is + supported (From Lesha Bogdanow ). + - Added checking of which mnemonic that work on the different AVRs + (From Lesha Bogdanow ). + - Added constants __DEVICE__, __FLASH_SIZE__, __RAM_SIZE__ and + __EEPROM_SIZE__ (From Lesha Bogdanow ). + - Added tiny devices (From Lesha Bogdanow ). + (20000403) - Changed error on constant out of range into a warning. + (20010918) - Added support for instructions: (E)LPM Rd,Z(+), SPM, ESPM, BREAK, + MOVW, MULS, MULSU, FMUL, FMULS, FMULSU + - Added support for new devices: ATmega8, ATmega16, ATmega32, + ATmega128, ATmega162, ATmega163, ATmega323, AT94K + - Added --devices switch to list all supported devices. + (20010919) - Fixed bug in map file name when the name had more than one . (dot) + (20010920) - Added option --includedirs to add additional include dirs in + search path. + (20010925) - Added support for creation of intel hex 32 files to be able to + address memory above 64KB. Uses 02 records for addresses up to 1MB + and 04 record for addresses above 1MB. + +Release 0.6 + (20000124) - Added COFF support from Bob Harris + +Release 0.5 + (19990331) - Bugfix: a inline string copy did not terminate string. + (19990409) - Fixed bug causing --define symbol=value not to work. + (19990418) - Added output of memory usage. + (19990518) - Fixed bug when there was a { in a comment. + (19990715) - Fixed count for data segment. + (19990720) - Fix to make a forward referenced label in .db/.dw work. + (19990922) - Added ATmega161 and ATtiny15 in list. + - rjmp and rcall now wraps around with 4k word devices. + (19991220) - Fixed bug when branching backwards with BRBS or BRBC + +Release 0.4 + (19990202) - Added support for global keyword to use on labels in macros. + - Fixed get_next_token to handle commas inside ' ' + (19990204) - Fixed bug when searching for correct macro_call, so recursive + and nested macros will work. + - Now handles commas in strings. + - Added fix to handle semi colon in a string. + (19990205) - Improved mnemonic parsing for ld and st diff --git a/src/mkutil/avra-0.8/README b/src/mkutil/avra-0.8/README new file mode 100644 index 00000000..f520f32a --- /dev/null +++ b/src/mkutil/avra-0.8/README @@ -0,0 +1,274 @@ + + Avra - Assember for the Atmel AVR microcontroller series + Copyright (C) 1998-2003 Jon Anders Haugum, Tobias Weber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + + Authors of avra can be reached at: + email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + www: http://www.omegav.ntnu.no/~jonah/el/avra.html + + +---------------------------------------------------------------------- + +1. Introduction + +avra is an assembler for the Atmel AVR microcontrollers, and it is +almost compatible with Atmel's own assembler AVRASM32. The difference +is that avra supports some extra preprocessor directives, and the macro- +support is better. + +Since avra is written in ANSI C it should be possible to compile on +most systems. + +I would also like to thank the following people for giving +contributions and bug reports: + + Bernt Hembre + Nils Strøm + Roberto Biancardi + Qwerty Jones + Ben Hitchcock (Maker of the mac port) + Daniel Drotos + Laurence Boyd II + Varuzhan Danielyan + Laurence Turner + Eugene R. O'Bryan + Dmitry Dicky + Bob Harris (Maker of coff support) + Tobias Weber (enhanced macro support) + +---------------------------------------------------------------------- + +2. Installation + +To install avra you should copy the avra-executeable to a apropriate location. + +To compile you should rename the apropritate makefile, and do a make (use smake +for Amiga SAS/C, and nmake for Mickeysoft visual c++). + + +2.1 Linux + +First you should compile the source by typing make. + +avra should be copied to /usr/local/bin/ or other apropriate directory. + +Doing a 'make install' will do the same thing. + + +2.2 AmigaOS + +avra should be copied to c: or other apropriate directory. + +If you are using the source-distribution a 'make install' will do the same. + + +2.3 win32 (Windows 95 (++) and Windows NT) + +avra.exe should be copied to an apropriate location. A 'nmake install' will +copy it and avra.def to c:\bin\ + +2.4 Dev-C++ enviroment + +Dev-C++ is a GNU development enviroment available for the most common platforms. +A project file created with Dev-C++ 4.9.6.0 has added to the package. +Just open the project file and 'compile' with Ctrl-F9. This nice software +you can get at http://www.bloodshed.net/ + + +---------------------------------------------------------------------- + + +3. Compatibility + +This Version of AVRA should work as replacement of the build in assembler of +Atmel AVR Studio(c). Just replace the AVRASM32.EXE in your AVRStudio +directories. This Version has been tested with AVRStudio V4.06 and V3.55 +it worked 'almost' bugfree. + + +---------------------------------------------------------------------- + +4. Adding support for other systems + +avra is written mostly in ANSI-C, so it should be possible to port it +to other 32-bit systems. + + +---------------------------------------------------------------------- + +5. New Macro possibilities + +As a person who never liked reading through lots of manual pages, I keep it +short and start with some simple examples. Sometimes you work with 16 Bit +or greater variables stored in registers. The new macro support allows you to +write short and flexible macro code. The extended mode is active, as soon +as you use brackets like this [ ] to wrap macro parameters. + +5.1 Examples + +To simplify the parameters in the demonstration below, we need to redefine +some registers. + +.def a = r16 ;general purpose registers +.def b = r17 +.def c = r18 +.def d = r19 + +.def w = r20 ;working register + +If we substract 16 Bit values stored in a, higher byte and b, lower byte with +that in c:d, we usually have to use the following command sequence: + + sub b,d + sbc a,c + +Now we can do the following steps to simplify 16 or more Bit manipulations + +.macro subs +.message "no parameters" +.endm + +.macro subs_16_16 + sub @1,@3 + sbc @0,@2 +.endm + +.macro subs_16_8 + sub @1,@2 + sbci @0,0 +.endm + + ;hence, we can write a 16 Bit subraction as: + + subs [a:b,c:d] + + ;or for doing 16 minus 8 Bit + + subs [a:b,c] + + +5.2 more examples: + +.macro load +.message "no parameters" +.endm + +.macro load_16_i + ldi @0,high(@2) + ldi @1,low(@2) +.endm + +.macro load_32_i + ldi @0,BYTE4(@4) + ldi @1,BYTE3(@4) + ldi @2,high(@4) + ldi @3,low(@4) +.endm + + + load [a:b,15] ;uses macro load_16_i to load immediate + + load [a:b:c:d,15] ;uses macro load_32_i to load immediate + +5.3 Datatypes + +There are 3 Datatypes which can be used. They will be added as character +separated by one underline character. + + immediate values _i + registers _8,_16,_24,_32,_40,_48,_56,_64 + void parameter _v + + +5.4 even more expamples: + +.dseg +counter .byte 2 +.cseg + +.macro poke +.message "no parameters" +.endm + +.macro poke_i_16_i + ldi @1,high(@3) + sts @0+0,@1 + ldi @2,low(@3) + sts @0+1,@2 +.endm + +.macro poke_i_i + ldi w,@1 + sts @0+0,w +.endm + +.macro poke_i_v_i + ldi w,high(@3) + sts @0+0,w + ldi w,low(@3) + sts @0+1,w +.endm + +.macro poke_i_v_v_v_i + ldi w,high(@3) + sts @0+0,w + ldi w,low(@3) + sts @0+1,w + ldi w,BYTE3(@3) + sts @0+2,w + ldi w,BYTE4(@3) + sts @0+3,w +.endm + + + ;this writes '9999' into the memory at 'counter' + ;uses only the working register for transfering the values. + + poke [counter,w:w,9999] + + ;works same as above, but the transferred value '9999' is also + ;kept in the pair of register a:b + + poke [counter,a:b,9999] + + ;in my design 'w' is always working reg. which implies that + ;it cannot be used for normal variables. The following example uses poke_i_i + ;because the parameter contains two immediate values. + + poke [counter,9999] ;uses poke_i_i + + ;to be able to choose between a 8,16 or 32 Bit operation, you just + ;add a void parameter. + + poke [counter,,9999] ;uses poke_i_v_i + + ;and the same for 32 Bit pokes + + poke [counter,,,,9999] ;uses poke_i_v_v_v_i + +What I was trying to do with this new macro speech, was to create a platform +indipendent assembling language. Sometimes, but only sometimes, it would +be nice be able to port the code to Microchip PIC family more or less directly. + +---------------------------------------------------------------------- +6.0 Links + +http://www.avrfreaks.com/ + + diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.gcc b/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.gcc new file mode 100644 index 00000000..a8752cfc --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.gcc @@ -0,0 +1,80 @@ +#******************************************************************** +# Makefile for gcc (Geek Gadget) on Amiga +#******************************************************************** + +CC = gcc +LD = gcc +CFLAGS = -Wall -O3 +LDFLAGS = -s + +SOURCES = avra.c device.c parser.c expr.c mnemonic.c directiv.c macro.c file.c map.c coff.c + +OBJECTS = $(SOURCES:.c=.o) + +OBJ_ALL = $(OBJECTS) args.o stdextra.o + +DISTFILES = *.c *.h README ChangeLog Makefile.* COPYING avra.1 avra.txt strip-headers TODO + +ARCHFILES = $(DISTFILES) + +BINFILES = avra README ChangeLog COPYING avra.1 avra.txt + +VERSION = 0.7 + +#******************************************************************** + +all: avra + +install: avra + copy avra c: + +clean: + rm -f avra *.o *.p *~ + +avra: $(OBJ_ALL) + $(LD) -o avra $(OBJ_ALL) $(LDFLAGS) + +args.o: args.c misc.h args.h +avra.o: avra.c misc.h args.h avra.h device.h +device.o: device.c misc.h avra.h device.h +directiv.o: directiv.c misc.h args.h avra.h device.h +expr.o: expr.c misc.h avra.h +file.o: file.c misc.h avra.h +macro.o: macro.c misc.h args.h avra.h +mnemonic.o: mnemonic.c misc.h avra.h device.h +parser.o: parser.c misc.h avra.h +stdextra.o: stdextra.c misc.h +coff.o: coff.c coff.h + +avra.txt: avra.1 + groff -man -Tascii avra.1 | ./strip-headers | col -bx > avra.txt + +#******************************************************************** + +disk: archive + copy avra.tar.gz pc0:avra.tgz + +archive: avra.tar.gz + +avra.tar.gz: $(ARCHFILES) + tar cvf avra.tar $(ARCHFILES) + gzip -9 -f avra.tar + +dist: avra-$(VERSION).tar.gz + +avra-$(VERSION).tar.gz: $(DISTFILES) + mkdir avra-$(VERSION) + cp $(DISTFILES) avra-$(VERSION)/ + tar cvf avra-$(VERSION).tar avra-$(VERSION)/* + gzip -9 -f avra-$(VERSION).tar + rm -r avra-$(VERSION) + +bin: avra-$(VERSION)-Amiga-ixemul.lha + +avra-$(VERSION)-Amiga-ixemul.lha: $(BINFILES) + mkdir avra-$(VERSION) + cp $(BINFILES) avra-$(VERSION)/ + lha -xr u avra-$(VERSION)-Amiga-ixemul.lha avra-$(VERSION)/* + rm -r avra-$(VERSION) + +#******************************************************************** diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.sas b/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.sas new file mode 100644 index 00000000..1242ad3e --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.amiga.sas @@ -0,0 +1,75 @@ +#******************************************************************** +# Makefile for SAS/C on Amiga +#******************************************************************** + +CC = sc +LD = sc +CFLAGS = NOVERSION OPTIMIZE STRINGMERGE +LDFLAGS = NOVERSION + +SOURCES = avra.c device.c parser.c expr.c mnemonic.c directiv.c macro.c file.c map.c coff.c + +OBJECTS = avra.o device.o parser.o expr.o mnemonic.o directiv.o macro.o file.o map.o coff.o + +OBJ_ALL = $(OBJECTS) args.o stdextra.o + +DISTFILES = *.c *.h README ChangeLog Makefile.* COPYING avra.1 avra.txt strip-headers TODO + +ARCHFILES = $(DISTFILES) + +BINFILES = avra README ChangeLog COPYING avra.1 avra.txt + +VERSION = 0.7 + +#******************************************************************** + +all: avra + +install: avra + copy avra c: + +clean: + delete avra avra.info \#?.o \#?.lnk + +avra: $(OBJ_ALL) + $(LD) link $(OBJ_ALL) $(LDFLAGS) + +args.o: args.c misc.h args.h +avra.o: avra.c misc.h args.h avra.h device.h +device.o: device.c misc.h avra.h device.h +directiv.o: directiv.c misc.h args.h avra.h device.h +expr.o: expr.c misc.h avra.h +file.o: file.c misc.h avra.h +macro.o: macro.c misc.h args.h avra.h +mnemonic.o: mnemonic.c misc.h avra.h device.h +parser.o: parser.c misc.h avra.h +stdextra.o: stdextra.c misc.h +coff.o: coff.c coff.h + +#******************************************************************** + +disk: archive + copy avra.tar.gz pc0:avra.tgz + +archive: avra.lha + +avra.lha: $(ARCHFILES) + lha -xr u avra.lha $(ARCHFILES) + +dist: avra-$(VERSION).lha + +avra-$(VERSION).lha: $(DISTFILES) + makedir avra-$(VERSION) + copy $(DISTFILES) TO avra-$(VERSION)/ + lha -xr u avra-$(VERSION).lha avra-$(VERSION)/* + delete ALL avra-$(VERSION) + +bin: avra-$(VERSION)-Amiga.lha + +avra-$(VERSION)-Amiga.lha: $(BINFILES) + makedir avra-$(VERSION) + copy $(BINFILES) avra-$(VERSION)/ + lha -xr u avra-$(VERSION)-Amiga.lha avra-$(VERSION)/* + delete ALL avra-$(VERSION) + +#******************************************************************** diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.emx b/src/mkutil/avra-0.8/SOURCE/Makefile.emx new file mode 100644 index 00000000..fac7433d --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.emx @@ -0,0 +1,69 @@ +#******************************************************************** +# Makefile for gcc/emx +#******************************************************************** + +CC = gcc +LD = gcc +CFLAGS = -Wall -O3 +LDFLAGS = -s + +SOURCES = avra.c device.c parser.c expr.c mnemonic.c directiv.c macro.c file.c map.c coff.c + +OBJECTS = $(SOURCES:.c=.o) + +OBJ_ALL = $(OBJECTS) args.o stdextra.o + +DISTFILES = *.c *.h README ChangeLog Makefile.* COPYING avra.1 avra.txt strip-headers TODO + +ARCHFILES = $(DISTFILES) + +BINFILES = avra README ChangeLog COPYING avra.1 avra.txt + +VERSION = 0.7 + +#******************************************************************** + +all: avra.exe + +clean: + rm -f avra.exe *.o *.p *~ + +avra.exe: $(OBJ_ALL) + $(LD) -o avra.exe $(OBJ_ALL) $(LDFLAGS) + +args.o: args.c misc.h args.h +avra.o: avra.c misc.h args.h avra.h device.h +device.o: device.c misc.h avra.h device.h +directiv.o: directiv.c misc.h args.h avra.h device.h +expr.o: expr.c misc.h avra.h +file.o: file.c misc.h avra.h +macro.o: macro.c misc.h args.h avra.h +mnemonic.o: mnemonic.c misc.h avra.h device.h +parser.o: parser.c misc.h avra.h +stdextra.o: stdextra.c misc.h +coff.o: coff.c coff.h + +avra.txt: avra.1 + groff -man -Tascii avra.1 | ./strip-headers | col -bx > avra.txt + +#******************************************************************** + +disk: archive + mcopy -ovm avra.tar.gz a:avra.tgz + +archive: avra.tar.gz + +avra.tar.gz: $(ARCHFILES) + tar cvf avra.tar $(ARCHFILES) + gzip -9 -f avra.tar + +dist: avra-$(VERSION).tar.gz + +avra-$(VERSION).tar.gz: $(DISTFILES) + mkdir avra-$(VERSION) + cp $(DISTFILES) avra-$(VERSION)/ + tar cvf avra-$(VERSION).tar avra-$(VERSION)/* + gzip -9 -f avra-$(VERSION).tar + rm -r avra-$(VERSION) + +#******************************************************************** diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.linux b/src/mkutil/avra-0.8/SOURCE/Makefile.linux new file mode 100644 index 00000000..5a3e6176 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.linux @@ -0,0 +1,74 @@ +#******************************************************************** +# Makefile for gcc +#******************************************************************** + +CC = gcc +LD = gcc +CFLAGS = -Wall -O3 +LDFLAGS = -s + +SOURCES = avra.c device.c parser.c expr.c mnemonic.c directiv.c macro.c file.c map.c coff.c + +OBJECTS = $(SOURCES:.c=.o) + +OBJ_ALL = $(OBJECTS) args.o stdextra.o + +DISTFILES = *.c *.h README ChangeLog Makefile.* COPYING avra.1 avra.txt strip-headers TODO + +ARCHFILES = $(DISTFILES) + +BINFILES = avra README ChangeLog COPYING avra.1 avra.txt + +VERSION = 0.7 + +#******************************************************************** + +all: avra + +install: avra + cp avra /usr/local/bin + cp avra.1 /usr/local/man/man1 + chmod +r /usr/local/man/man1/avra.1 + +clean: + rm -f avra *.o *.p *~ + +avra: $(OBJ_ALL) + $(LD) -o avra $(OBJ_ALL) $(LDFLAGS) + +args.o: args.c misc.h args.h +avra.o: avra.c misc.h args.h avra.h device.h +device.o: device.c misc.h avra.h device.h +directiv.o: directiv.c misc.h args.h avra.h device.h +expr.o: expr.c misc.h avra.h +file.o: file.c misc.h avra.h +macro.o: macro.c misc.h args.h avra.h +mnemonic.o: mnemonic.c misc.h avra.h device.h +parser.o: parser.c misc.h avra.h +stdextra.o: stdextra.c misc.h +coff.o: coff.c coff.h + +avra.txt: avra.1 + groff -man -Tascii avra.1 | ./strip-headers | col -bx > avra.txt + +#******************************************************************** + +disk: archive + mcopy -ovm avra.tar.gz a:avra.tgz + +archive: avra.tar.gz + +avra.tar.gz: $(ARCHFILES) + tar cvf avra.tar $(ARCHFILES) + gzip -9 -f avra.tar + +dist: avra-$(VERSION).tar.gz + +avra-$(VERSION).tar.gz: $(DISTFILES) + mkdir avra-$(VERSION) + cp $(DISTFILES) avra-$(VERSION)/ + tar cvf avra-$(VERSION).tar avra-$(VERSION)/* + gzip -9 -f avra-$(VERSION).tar + rm -r avra-$(VERSION) + +#******************************************************************** diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.win b/src/mkutil/avra-0.8/SOURCE/Makefile.win new file mode 100644 index 00000000..e801c031 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.win @@ -0,0 +1,58 @@ +# Project: Console App +# Makefile created by Dev-C++ 4.9.6.0 + +CC = gcc.exe +WINDRES = windres.exe +RES = +OBJ = avra.o args.o stdextra.o device.o directiv.o expr.o file.o map.o mnemonic.o parser.o coff.o macro.o $(RES) +LIBS = -L"D:/system/Dev-Cpp/lib" +INCS = -I"D:/system/Dev-Cpp/include" +BIN = avra.exe +CFLAGS = $(INCS) -pg -g3 + +.PHONY: all all-before all-after clean clean-custom + +all: all-before avra.exe all-after + + +clean: clean-custom + rm -f $(OBJ) $(BIN) + +$(BIN): $(OBJ) + $(CC) $(OBJ) -o "avra.exe" $(LIBS) $(CFLAGS) + +avra.o: avra.c + $(CC) -c avra.c -o avra.o $(CFLAGS) + +args.o: args.c + $(CC) -c args.c -o args.o $(CFLAGS) + +stdextra.o: stdextra.c + $(CC) -c stdextra.c -o stdextra.o $(CFLAGS) + +device.o: device.c + $(CC) -c device.c -o device.o $(CFLAGS) + +directiv.o: directiv.c + $(CC) -c directiv.c -o directiv.o $(CFLAGS) + +expr.o: expr.c + $(CC) -c expr.c -o expr.o $(CFLAGS) + +file.o: file.c + $(CC) -c file.c -o file.o $(CFLAGS) + +map.o: map.c + $(CC) -c map.c -o map.o $(CFLAGS) + +mnemonic.o: mnemonic.c + $(CC) -c mnemonic.c -o mnemonic.o $(CFLAGS) + +parser.o: parser.c + $(CC) -c parser.c -o parser.o $(CFLAGS) + +coff.o: coff.c + $(CC) -c coff.c -o coff.o $(CFLAGS) + +macro.o: macro.c + $(CC) -c macro.c -o macro.o $(CFLAGS) diff --git a/src/mkutil/avra-0.8/SOURCE/Makefile.win32.mvc b/src/mkutil/avra-0.8/SOURCE/Makefile.win32.mvc new file mode 100644 index 00000000..1f1600fd --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/Makefile.win32.mvc @@ -0,0 +1,47 @@ +#******************************************************************** +# Makefile for Mickeysoft visual c++ +#******************************************************************** + +CC = cl -Zi +LD = link "/libpath:c:\Program Files\Microsoft Visual Studio\VC98\Lib" +CFLAGS = -nologo -Ox +LDFLAGS = -nologo + +SOURCES = avra.c device.c parser.c expr.c mnemonic.c directiv.c macro.c file.c map.c coff.c + +OBJECTS = $(SOURCES:.c=.obj) + +OBJ_ALL = $(OBJECTS) args.obj stdextra.obj + +#******************************************************************** + +all: avra.exe + +install: avra.exe + copy avra.exe ..\..\..\bin\ + +clean: + del *.obj + del avra.exe + +avra.exe: $(OBJ_ALL) + $(LD) $(OBJ_ALL) $(LDFLAGS) + +args.obj: args.c misc.h args.h +avra.obj: avra.c misc.h args.h avra.h device.h +device.obj: device.c misc.h avra.h device.h +directiv.obj: directiv.c misc.h args.h avra.h device.h +expr.obj: expr.c misc.h avra.h +file.obj: file.c misc.h avra.h +macro.obj: macro.c misc.h args.h avra.h +mnemonic.obj: mnemonic.c misc.h avra.h device.h +parser.obj: parser.c misc.h avra.h +stdextra.obj: stdextra.c misc.h +coff.obj: coff.c coff.h + +#******************************************************************** + + +#******************************************************************** + + diff --git a/src/mkutil/avra-0.8/SOURCE/args.c b/src/mkutil/avra-0.8/SOURCE/args.c new file mode 100644 index 00000000..e8004d2b --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/args.c @@ -0,0 +1,240 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include + +#include "misc.h" +#include "args.h" + + +struct args *alloc_args(int arg_count) + { + struct args *args; + + args = malloc(sizeof(struct args)); + if(args) + { + args->arg = malloc(sizeof(struct arg) * arg_count); + if(args->arg) + { + args->count = arg_count; + args->first_data = NULL; + return(args); + } + free(args); + } + printf("Error: Unable to allocate memory\n"); + return(NULL); + } + + + +int read_args(struct args *args, int argc, char *argv[]) + { + int i, j, k, ok = True, i_old; + struct data_list **last_data; + + args->first_data = NULL; + last_data = &args->first_data; + for(i = 1; (i < argc) && ok; i++) + { + + + if(argv[i][0] == '-') + { + last_data = &args->first_data; + if(argv[i][1] == '-') + { + j = 0; + while((args->arg[j].longarg ? strcmp(&argv[i][2], args->arg[j].longarg) : True) && (j != args->count)) + j++; + if(j == args->count) + { + printf("Error: Unknown option: %s\n", argv[i] ); + ok = False; + } + else + { + switch(args->arg[j].type) + { + case ARGTYPE_STRING: + case ARGTYPE_STRING_MULTISINGLE: + if((i + 1) == argc) + { + printf("Error: No argument supplied with option: %s\n", argv[i]); + ok = False; + } + else if(args->arg[j].type != ARGTYPE_STRING_MULTISINGLE) + args->arg[j].data = argv[++i]; + else + ok = add_arg((struct data_list **)&args->arg[j].data, argv[++i]); + break; + case ARGTYPE_BOOLEAN: + args->arg[j].data = (char *)True; + break; + case ARGTYPE_STRING_MULTI: + last_data = (struct data_list **)&args->arg[j].data; + break; + //added by TW + //case ARGTYPE_CHAR_ATTACHED: + // args->arg[j].data = argv[i]; + //break; + } + } + } + else + { + // ToDo: Sjekk for enkel - + for(k = 1, i_old = i; (argv[i][k] != '\0') && ok && (i == i_old); k++) + { + j = 0; + while((argv[i][k] != args->arg[j].letter) && (j != args->count)) + j++; + if(j == args->count) + { + printf("Error: Unknown option: -%c\n", argv[i][k]); + ok = False; + } + else + { + switch(args->arg[j].type) + { + case ARGTYPE_STRING: + case ARGTYPE_STRING_MULTISINGLE: + if(argv[i][k + 1] != '\0') + { + printf("Error: Option -%c must be followed by it's argument\n", argv[i][k]); + ok = False; + } + else + { + if((i + 1) == argc) + { + printf("Error: No argument supplied with option: -%c\n", argv[i][k]); + ok = False; + } + else if(args->arg[j].type != ARGTYPE_STRING_MULTISINGLE) + args->arg[j].data = argv[++i]; + else + ok = add_arg((struct data_list **)&args->arg[j].data, argv[++i]); + } + break; + case ARGTYPE_BOOLEAN: + args->arg[j].data = (char *)True; + break; + case ARGTYPE_STRING_MULTI: + last_data = (struct data_list **)&args->arg[j].data; + break; + //added by TW + case ARGTYPE_CHAR_ATTACHED: + if((i + 1) == argc) + { + printf("Error: missing arguments: asm file"); + ok = False; + } + else + { + switch(argv[i][++k]) + { + case 'O': args->arg[j].data = (char *)AVRSTUDIO; + break; + case 'G': args->arg[j].data = (char *)GENERIC; + break; + case 'I': args->arg[j].data = (char *)INTEL; + break; + case 'M': args->arg[j].data = (char *)MOTOROLA; + break; + default: printf("Error: wrong file type '%c'",argv[i][2]); + ok = False; + } + } + } + } + } + } + } + else + ok = add_arg(last_data, argv[i]); + } + return(ok); + } + + +int add_arg(struct data_list **last_data, char *argv) + { + struct data_list *data; + + while(*last_data) last_data = &((*last_data)->next); + data = malloc(sizeof(struct data_list)); + if(data) + { + data->next = NULL; + data->data = argv; + *last_data = data; + last_data = &data->next; + } + else + { + printf("Error: Unable to allocate memory\n"); + return(False); + } + return(True); + } + + +void free_args(struct args *args) + { + int i; + struct data_list *data, *temp; + + for(data = args->first_data; data;) + { + temp = data; + data = data->next; + free(temp); + } + for(i = 0; i != args->count; i++) + if((args->arg[i].type == ARGTYPE_STRING_MULTI) + || (args->arg[i].type == ARGTYPE_STRING_MULTISINGLE)) + for(data = args->arg[i].data; data;) + { + temp = data; + data = data->next; + free(temp); + } + free(args); + } + + +void define_arg(struct args *args, int index, int type, char letter, char *longarg, void *def_value) + { + args->arg[index].type = type; + args->arg[index].letter = letter; + args->arg[index].longarg = longarg; + args->arg[index].data = def_value; + } diff --git a/src/mkutil/avra-0.8/SOURCE/args.h b/src/mkutil/avra-0.8/SOURCE/args.h new file mode 100644 index 00000000..4bdc0c6d --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/args.h @@ -0,0 +1,65 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +enum + { + ARGTYPE_BOOLEAN = 0, /* boolean Value (0 = False) */ + ARGTYPE_STRING, /* Stringpointer in Data */ + ARGTYPE_STRING_MULTI, /* List of strings in Data */ + ARGTYPE_STRING_MULTISINGLE, /* List of strings in Data. requires an option for each elemtent */ + //added by TW + ARGTYPE_CHAR_ATTACHED + }; + +#define GET_ARG(args,argnum) (args->arg[argnum].data) +#define SET_ARG(args,argnum,value) (args->arg[argnum].data = (void *)value) + +struct args + { + struct arg *arg; + int count; + struct data_list *first_data; + }; + +struct arg + { + int type; + char letter; + char *longarg; + void *data; + }; + +struct data_list + { + struct data_list *next; + void *data; + }; + +struct args *alloc_args(int arg_count); +int read_args(struct args *args, int argc, char *argv[]); +int add_arg(struct data_list **last_data, char *argv); +void free_args(struct args *args); +void define_arg(struct args *args, int index, int type, char letter, char *longarg, void *def_value); diff --git a/src/mkutil/avra-0.8/SOURCE/avra.c b/src/mkutil/avra-0.8/SOURCE/avra.c new file mode 100644 index 00000000..408c4368 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/avra.c @@ -0,0 +1,333 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include + +#include "misc.h" +#include "args.h" +#include "avra.h" +#include "device.h" + +const char *title = "AVRA: advanced AVR macro assembler version %d.%d (%s)\n" + "Copyright (C) 2002-2003 Tobias Weber\n" + "Copyright (C) 1998-2001 Jon Anders Haugum\n" + "\n" + " AVRA is a replacement for the ATMEL AVR-Assembler 'AVRASM32.EXE'\n" + "\n" + " The words ATMEL and AVR are registered to Atmel Corp.\n" + " AVRA comes with NO WARRANTY, to the extent permitted by law.\n" + " You may redistribute copies of avra under the terms\n" + " of the GNU General Public License.\n" + " For more information about these matters, see the files named COPYING.\n" + "\n"; + +const char *usage = + "usage: AVRA [--define [=]] [--includedir ] [--listmac]\n" + " [--max_errors ] [--coff] [--devices] [--version]\n" + " [-h] [--help] general help\n" + " [-f][O|G|I|M] output file type\n" + " \n" + "\n" + " --define, -D : Define symbol.\n" + " --includedir, -I : Additional include dirs.\n" + " --listmac : List macro expansion in listfile.\n" + " --max_errors : Maximum number of errors before exit (default: 10)\n" + " --coff : Produce COFF output file for debugging with Atmel AVR Studio.\n" + " --devices : List out supported devices.\n" + " --version : Version information.\n" + " --help, -h : This help text.\n" + "\n" + "Don't bother about the command line options. Some may not work properly in V0.8\n" + "Just replace the AVRASM32.EXE in your AVRStudio directories. This Version has " + "been tested with AVRStudio V4.06 and it was 'almost' bugfree ;-)\n" + "\n" + "Report bugs to tobiw@suprafluid.com\n" + " or jonah@omegav.ntnu.no\n"; + + +int main(int argc, char *argv[]) + { + int show_usage = False; + struct prog_info *pi; + struct args *args; + + printf(title, VERSION, REVISION, DATESTRING); + + args = alloc_args(ARG_COUNT); + if(args) + { + define_arg(args, ARG_DEFINE, ARGTYPE_STRING_MULTISINGLE, 'D', "define", NULL); + define_arg(args, ARG_INCLUDEDIR, ARGTYPE_STRING_MULTISINGLE, 'I', "includedir", NULL); + define_arg(args, ARG_LISTMAC, ARGTYPE_BOOLEAN, 0, "listmac", "1"); + define_arg(args, ARG_MAX_ERRORS, ARGTYPE_STRING, 0, "max_errors", "10"); + define_arg(args, ARG_COFF, ARGTYPE_BOOLEAN, 0, "coff", "1"); + define_arg(args, ARG_DEVICES, ARGTYPE_BOOLEAN, 0, "devices", False); + define_arg(args, ARG_VER, ARGTYPE_BOOLEAN, 0, "version", False); + define_arg(args, ARG_HELP, ARGTYPE_BOOLEAN, 'h', "help", False); + //TW added + define_arg(args, ARG_WRAP, ARGTYPE_BOOLEAN, 'w', "wrap", False); + define_arg(args, ARG_FILEFORMAT, ARGTYPE_CHAR_ATTACHED, 'f', "filetype", "0"); + define_arg(args, ARG_LISTFILE, ARGTYPE_STRING, 'l', "listfile", False); + define_arg(args, ARG_OUTFILE, ARGTYPE_STRING, 'o', "outfile", False); + define_arg(args, ARG_MAPFILE, ARGTYPE_STRING, 'm', "mapfile", False); + define_arg(args, ARG_DEBUGFILE, ARGTYPE_STRING, 'd', "debugfile", False); + define_arg(args, ARG_EEPFILE, ARGTYPE_STRING, 'e', "eepfile", False); + + if(read_args(args, argc, argv)) + { + if(!GET_ARG(args, ARG_HELP) && (argc != 1)) + { + if(!GET_ARG(args, ARG_VER)) + { + if(!GET_ARG(args, ARG_DEVICES)) + { + pi = get_pi(args); + if(pi) + { + assemble(pi); + free_pi(pi); + } + } + else + list_devices(); + } + //else + } + else + show_usage = True; + } + free_args(args); + } + else + { + show_usage = True; + printf("\n"); + } + if(show_usage) + { +/* if(argc == 1) + { + printf(title, VERSION, REVISION, DATESTRING); + printf("\n"); + }*/ + printf("%s", usage); + } + exit(EXIT_SUCCESS); + } + + +void assemble(struct prog_info *pi) + { + if(pi->args->first_data) + { + printf("Pass 1... "); + if(!load_arg_defines(pi)) + return; + predef_dev(pi); + if(parse_file(pi, (char *)pi->args->first_data->data, PASS_1)) + { + if(pi->error_count == 0) + { + prepare_second_pass(pi); + if(!load_arg_defines(pi)) + return; + predef_dev(pi); + if(open_out_files(pi, pi->args->first_data->data)) + { + printf("done\nPass 2... "); + parse_file(pi, (char *)pi->args->first_data->data, PASS_2); + printf("done\n\n"); + + if(GET_ARG(pi->args, ARG_COFF) && (pi->error_count == 0)) + write_coff_file(pi); + write_map_file(pi); + close_out_files(pi); + if(pi->error_count) + printf("\nAssembly aborted with %d errors and %d warnings.\n", pi->error_count, pi->warning_count); + else if(pi->warning_count) + printf("\nAssembly complete with no errors (%d warnings).\n", pi->warning_count); + else + printf("\nAssembly complete with no errors.\n"); + } + } + } + } + else + printf("Error: You need to specify a file to assemble\n"); + } + + +int load_arg_defines(struct prog_info *pi) + { + int i; + char *expr, buff[256]; + struct data_list *define; + struct label *label; + + for(define = GET_ARG(pi->args, ARG_DEFINE); define; define = define->next) + { + strcpy(buff, define->data); + expr = get_next_token(buff, TERM_EQUAL); + if(expr) + { + if(!get_expr(pi, expr, &i)) + return(False); + } + else + i = 1; + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, buff)) + { + printf("Error: Can't define symbol %s twice\n", buff); + return(False); + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_constant) + pi->last_constant->next = label; + else + pi->first_constant = label; + pi->last_constant = label; + label->name = malloc(strlen(buff) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, buff); + label->value = i; + } + return(True); + } + + +struct prog_info *get_pi(struct args *args) + { + struct prog_info *pi; + + pi = (struct prog_info *)calloc(1, sizeof(struct prog_info)); + if(pi) + { + pi->args = args; + pi->device = get_device(pi,NULL); + pi->list_on = True; + pi->segment = SEGMENT_CODE; + pi->dseg_addr = DSEG_START; + pi->max_errors = atoi(GET_ARG(args, ARG_MAX_ERRORS)); + return(pi); + } + return(NULL); + } + + +void free_pi(struct prog_info *pi) + { + free(pi); + } + + +void prepare_second_pass(struct prog_info *pi) + { + struct def *def, *temp_def; + struct label *label, *temp_label; + + pi->segment = SEGMENT_CODE; + pi->cseg_addr = 0; + pi->dseg_addr = DSEG_START; + pi->eseg_addr = 0; + + for(def = pi->first_def; def;) + { + temp_def = def; + def = def->next; + free(temp_def->name); + free(temp_def); + } + pi->first_def = NULL; + pi->last_def = NULL; + + for(label = pi->first_constant; label;) + { + temp_label = label; + label = label->next; + free(temp_label->name); + free(temp_label); + } + pi->first_constant = NULL; + pi->last_constant = NULL; + + for(label = pi->first_variable; label;) + { + temp_label = label; + label = label->next; + free(temp_label->name); + free(temp_label); + } + pi->first_variable = NULL; + pi->last_variable = NULL; + } + + +void print_msg(struct prog_info *pi, int type, char *fmt, ... ) + { + va_list args; + + if(type == MSGTYPE_OUT_OF_MEM) + fprintf(stderr, "Error: Unable to allocate memory!\n"); + else + { + va_start(args, fmt); + fprintf(stderr, "%s(%d) : ", pi->fi->include_file->name, pi->fi->line_number); + + switch(type) + { + case MSGTYPE_ERROR: + pi->error_count++; + fprintf(stderr, "error : "); + break; + case MSGTYPE_WARNING: + pi->warning_count++; + fprintf(stderr, "warning : "); + break; + case MSGTYPE_MESSAGE: + break; + } + + if(pi->macro_call) + fprintf(stderr, "[Macro: %s: %d:] ", pi->macro_call->macro->include_file->name, pi->macro_call->line_index + pi->macro_call->macro->first_line_number); + + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + } + } diff --git a/src/mkutil/avra-0.8/SOURCE/avra.dev b/src/mkutil/avra-0.8/SOURCE/avra.dev new file mode 100644 index 00000000..60911d12 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/avra.dev @@ -0,0 +1,179 @@ +[Project] +FileName=avra.dev +Name=Console App +UnitCount=15 +Type=1 +Ver=1 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Resources= +Compiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=AVRASM32.exe +Folders= +CommandLine= +Focused=14 +Order=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 + +[Unit1] +FileName=avra.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Views] +ProjectView=1 + +[Unit2] +FileName=args.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit3] +FileName=stdextra.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit4] +FileName=device.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit5] +FileName=directiv.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit6] +FileName=expr.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit7] +FileName=file.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit9] +FileName=mnemonic.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit10] +FileName=parser.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit11] +FileName=coff.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit12] +FileName=macro.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit13] +FileName=misc.h +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit8] +FileName=map.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit14] +FileName=args.h +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit15] +FileName=avra.h +Open=1 +Folder= +Top=1 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + diff --git a/src/mkutil/avra-0.8/SOURCE/avra.exe b/src/mkutil/avra-0.8/SOURCE/avra.exe new file mode 100644 index 0000000000000000000000000000000000000000..5192df0ba8f74ef1199fbfca455289bf65745552 GIT binary patch literal 94208 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 P4!II`TImbByfeM+Y>REYn2 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 + +#define VERSION 0 +#define REVISION 8 +#define DATESTRING "31 January 2003" + +#define IS_HOR_SPACE(x) ((x == ' ') || (x == 9)) +#define IS_LABEL(x) (isalnum(x) || (x == '_')) +#define IS_END(x) ((x == ';') || (x == 10) || (x == 13)|| (x == '\0')) +#define IS_ENDLINE(x) ( (x == 10) || (x == 13)|| (x == '\0')) + +#define LINEBUFFER_LENGTH 256 + +//added by TW +#define MAX_MACRO_ARGS 10 + +#define DSEG_START 0x60 + +/* Option enumeration */ +enum + { + ARG_DEFINE = 0, /* --define, -D */ + ARG_INCLUDEDIR, /* --includedir, -I */ + ARG_LISTMAC, /* --listmac */ + ARG_MAX_ERRORS, /* --max_errors */ + ARG_COFF, /* --coff */ + ARG_DEVICES, /* --devices */ + ARG_VER, /* --version */ + ARG_HELP, /* --help, -h */ + //added by TW + ARG_WRAP, /* --wrap */ + ARG_FILEFORMAT, /* --filetype */ + ARG_LISTFILE, /* --listfile */ + ARG_OUTFILE, /* --outfile */ + ARG_MAPFILE, /* --mapfile */ + ARG_DEBUGFILE, /* --debugfile */ + ARG_EEPFILE, /* --eepfile */ + ARG_COUNT + }; + +enum + { + MSGTYPE_ERROR = 0, + MSGTYPE_WARNING, + MSGTYPE_MESSAGE, + MSGTYPE_OUT_OF_MEM + }; + +enum + { + PASS_1 = 0, + PASS_2 + }; + +enum + { + SEGMENT_CODE = 0, + SEGMENT_DATA, + SEGMENT_EEPROM + }; + +enum + { + TERM_END = 0, + TERM_SPACE, + TERM_COMMA, + TERM_EQUAL, + TERM_DASH, + TERM_DOUBLEQUOTE, + TERM_COLON + }; + +/* Structures */ + +struct prog_info + { + struct args *args; + struct device *device; + struct file_info *fi; + struct macro_call *macro_call; + struct macro_line *macro_line; + FILE *list_file; + int list_on; + char *list_line; + FILE *obj_file; + struct hex_file_info *hfi; + struct hex_file_info *eep_hfi; + int segment; + int cseg_addr; + int dseg_addr; + int eseg_addr; + int cseg_count; + int dseg_count; + int eseg_count; + int error_count; + int max_errors; + int warning_count; + struct include_file *last_include_file; + struct include_file *first_include_file; + struct def *first_def; + struct def *last_def; + struct label *first_label; + struct label *last_label; + struct label *first_constant; + struct label *last_constant; + struct label *first_variable; + struct label *last_variable; + struct macro *first_macro; + struct macro *last_macro; + struct macro_call *first_macro_call; + struct macro_call *last_macro_call; + int conditional_depth; + /* coff additions */ + FILE *coff_file; + }; + +struct file_info + { + FILE *fp; + struct include_file *include_file; + char buff[LINEBUFFER_LENGTH]; + char scratch[LINEBUFFER_LENGTH]; + int line_number; + int exit_file; + struct label *label; + }; + +struct hex_file_info + { + FILE *fp; + int count; + int linestart_addr; + int segment; + unsigned char hex_line[16]; + }; + +struct include_file + { + struct include_file *next; + char *name; + int num; + }; + +struct def + { + struct def *next; + char *name; + int reg; + }; + +struct label + { + struct label *next; + char *name; + int value; + }; + +struct macro + { + struct macro *next; + char *name; + struct include_file *include_file; + int first_line_number; + struct macro_line *first_macro_line; + }; + +struct macro_line + { + struct macro_line *next; + char *line; + }; + +struct macro_call + { + struct macro_call *next; + int line_number; + struct include_file *include_file; + struct macro_call *prev_on_stack; + struct macro *macro; + int line_index; + int prev_line_index; + int nest_level; + struct label *first_label; + struct label *last_label; + }; + +/* Prototypes */ +/* avra.c */ +void assemble(struct prog_info *pi); +int load_arg_defines(struct prog_info *pi); +struct prog_info *get_pi(struct args *args); +void free_pi(struct prog_info *pi); +void prepare_second_pass(struct prog_info *pi); +void print_msg(struct prog_info *pi, int type, char *fmt, ... ); + +/* parser.c */ +int parse_file(struct prog_info *pi, char *filename, int pass); +int parse_line(struct prog_info *pi, char *line, int pass); +char *get_next_token(char *scratch, int term); + +/* expr.c */ +int get_expr(struct prog_info *pi, char *data, int *value); +int get_operator(char *op); +int test_operator_at_precedence(int operator, int precedence); +int calc(struct prog_info *pi, int left, int operator, int right); +int get_function(char *function); +int do_function(int function, int value); +int log2(int value); +int get_symbol(struct prog_info *pi, char *label_name, int *data); +int par_length(char *data); + +/* mnemonic.c */ +int parse_mnemonic(struct prog_info *pi, int pass); +int get_mnemonic_type(char *mnemonic); +int get_register(struct prog_info *pi, char *data); +int get_bitnum(struct prog_info *pi, char *data, int *ret); +int get_indirect(struct prog_info *pi, char *operand); +int is_supported(struct prog_info *pi, char *name); +int count_supported_instructions(int flags); + +/* directiv.c */ +int parse_directive(struct prog_info *pi, int pass); +int get_directive_type(char *directive); +char *term_string(struct prog_info *pi, char *string); +int parse_db(struct prog_info *pi, char *next, int pass); +void write_db(struct prog_info *pi, char byte, char *prev, int count, int pass); +int spool_conditional(struct prog_info *pi, int only_endif); +int check_conditional(struct prog_info *pi, char *buff, int *current_depth, int *do_next, int only_endif); +int test_include(const char *filename); + +/* macro.c */ +int read_macro(struct prog_info *pi, char *name, int pass); +struct macro *get_macro(struct prog_info *pi, char *name); +int expand_macro(struct prog_info *pi, struct macro *macro, char *rest_line, int pass); + +/* file.c */ +int open_out_files(struct prog_info *pi, char *filename); +void close_out_files(struct prog_info *pi); +struct hex_file_info *open_hex_file(char *filename); +void close_hex_file(struct hex_file_info *hfi); +void write_ee_byte(struct prog_info *pi, int address, unsigned char data); +void write_prog_word(struct prog_info *pi, int address, int data); +void do_hex_line(struct hex_file_info *hfi); +FILE *open_obj_file(struct prog_info *pi, char *filename); +void close_obj_file(struct prog_info *pi, FILE *fp); +void write_obj_record(struct prog_info *pi, int address, int data); + +/* map.c */ +void write_map_file(struct prog_info *pi); +char *Space(char *n); + +/* stdextra.c */ +char *nocase_strcmp(char *s, char *t); +char *nocase_strncmp(char *s, char *t, int n); +char *nocase_strstr(char *s, char *t); +int atox(char *s); +int atoi_n(char *s, int n); +int atox_n(char *s, int n); +char *my_strlwr(char *in); +char *my_strupr(char *in); + +/* coff.c */ +FILE *open_coff_file(struct prog_info *pi, char *filename); +void write_coff_file(struct prog_info *pi); +void write_coff_eeprom( struct prog_info *pi, int address, unsigned char data); +void write_coff_program( struct prog_info *pi, int address, unsigned int data); +void close_coff_file(struct prog_info *pi, FILE *fp); +int parse_stabs( struct prog_info *pi, char *p, int pass ); +int parse_stabn( struct prog_info *pi, char *p, int pass ); diff --git a/src/mkutil/avra-0.8/SOURCE/coff.c b/src/mkutil/avra-0.8/SOURCE/coff.c new file mode 100644 index 00000000..b9332b8c --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/coff.c @@ -0,0 +1,2074 @@ +// +// coff.c - Common Object File Format (COFF) support +// +// This file was developed for the avra assembler in order to produce COFF output files +// for use with the Atmel AVR Studio. The Lean C Compiler (LCC) debugging stabs +// output was used as input to the assembler. The information used to develop this file +// was obtained from various sources on the Internet, most notably, the Free Software Foundation, +// The "stabs" debug format, ??? Chapter 7: Common Object File Format (COFF), +// +// This software has absolutely no warrantee! The money you paid for this will be +// promptly refunded if not fully satisfied. +// +// Beta release 1/20/2000 by Bob Harris +// +// This software has not been fully tested and probably has a few software deficiencies. +// Some software support may be possible by sending a problem description report to +// rth@mclean.sparta.com + +#include +#include +#include +#include +#include + +#include "misc.h" +#include "avra.h" +#include "args.h" + +#include "coff.h" +#include "device.h" /* device flash and eeprom size */ + + +struct FundamentalType { + + char *pString; + int Type; + int Size; +}; + +struct FundamentalType FundamentalTypes[] = { + "null", T_NULL, 0, + "void", T_VOID, 0, + "char", T_CHAR, 1, + "short", T_SHORT, 1, + "int", T_INT, 1, + "long", T_LONG, 2, + "float", T_FLOAT, 4, + "double", T_DOUBLE, 4, + "struct", T_STRUCT, 0, + "union", T_UNION, 0, + "enum", T_ENUM, 0, + "moe", T_MOE, 0, + "unsigned char", T_UCHAR, 1, + "unsigned short", T_USHORT, 1, + "unsigned int", T_UINT, 1, + "unsigned long", T_ULONG, 2, + "long double", T_LNGDBL, 2, + "long long int", T_LONG, 2, + "long int", T_LONG, 2, + "unsigned long long", T_ULONG, 2, + "signed char", T_CHAR, 1, + 0, 0 +}; + +struct coff_info *ci; + +/****************************************************************************************/ + +FILE *open_coff_file(struct prog_info *pi, char *filename){ + + int ok /*, i*/; + FILE *fp; + //unsigned long *pu4; + char*p; + + + ci = calloc( 1, sizeof(struct coff_info) ); + if ( !ci ) + return( 0 ); + + ok = True; + /* default values */ + ci->CurrentFileNumber = 0; + ci->pRomMemory = 0; + ci->pEEPRomMemory = 0; + ci->MaxRomAddress = 0; + ci->MaxEepromAddress = 0; + ci->NeedLineNumberFixup = 0; + ci->GlobalStartAddress = -1; + ci->GlobalEndAddress = 0; + + /* Linked lists start out at zero */ + InitializeList( &ci->ListOfSectionHeaders ); + InitializeList( &ci->ListOfRawData ); + InitializeList( &ci->ListOfRelocations ); + InitializeList( &ci->ListOfLineNumbers ); + InitializeList( &ci->ListOfSymbols ); + InitializeList( &ci->ListOfGlobals ); + InitializeList( &ci->ListOfSpecials ); + InitializeList( &ci->ListOfUndefined ); + InitializeList( &ci->ListOfStrings ); + InitializeList( &ci->ListOfTypes ); + InitializeList( &ci->ListOfSplitLines ); + + /* add two default sections to SectionHeaders */ + if ( !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) || + !AllocateListObject( &ci->ListOfSectionHeaders, sizeof(struct external_scnhdr) ) ) { + + fprintf(stderr, "\nOut of memory allocating section headers!"); + return( 0 ); + } + + /* add to string table */ + p = (char *)AllocateListObject( &ci->ListOfStrings, 4 ); + if ( !p ) { + fprintf(stderr, "\nOut of memory allocating string table space!"); + return( 0 ); + } + + /* Allocate space for binary output into ROM, and EEPROM memory buffers for COFF output */ + /* ASSUMES ci->device is accurate */ + if ( (ci->pRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->flash_size * 2 ) ) != 0) { + if ( (ci->pEEPRomMemory = AllocateListObject( &ci->ListOfRawData, pi->device->eeprom_size )) != 0) { + ok = True; /* only true if both buffers are properly allocated */ + /* now fill them with 0xff's to simulate flash erasure */ + memset( (void *)ci->pRomMemory, 0xff, pi->device->flash_size * 2 ); + memset( ( void *)ci->pEEPRomMemory, 0xff, pi->device->eeprom_size ); + } + } + if ( ok != True ) + return( 0 ); + + fp = fopen(filename,"wb"); + if ( fp == NULL ) { + fprintf(stderr,"Error: cannot write coff file\n"); + return( fp ); + } + /* simulate void type .stabs void:t15=r1;*/ + stab_add_local_type( "void", "15=r1;0;0;" ); + + return( fp ); +} + +/****************************************************************************************/ +void write_coff_file(struct prog_info *pi){ + + //FILE *fp; + //struct label *label; + char /* File[256],*/*p; + struct external_scnhdr *pSectionHdr; + struct syment *pEntry; + union auxent *pAux; + unsigned long *plong; + int NumberOfSymbols, SymbolIndex, LastFileIndex, LastFunctionIndex, LastFunctionAddress; + LISTNODE *pNode; + int LinesOffset, SymbolsOffset, StringsOffset, RawOffset; + struct lineno *pLine; + + /* add two special sections */ + /* one for .text */ + if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) { + fprintf(stderr, "\nOut of memory allocating special headers for .text!"); + return; + } + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".text" ); + pEntry->n_value = 0; + pEntry->n_scnum = 1; + pEntry->n_type = 0; + pEntry->n_sclass = C_STAT; + pEntry->n_numaux = 1; + pEntry++; + pAux = (union auxent *)pEntry; + pAux->x_scn.x_scnlen = ci->MaxRomAddress + 2; + pAux->x_scn.x_nreloc = 0; + pAux->x_scn.x_nlinno = ci->ListOfLineNumbers.TotalItems; + /* one for .bss */ + if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfSpecials, sizeof(struct syment) * 2 ) ) == 0 ) { + fprintf(stderr, "\nOut of memory allocating special header for .bss!"); + return; + } + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".bss" ); + if ( ci->GlobalStartAddress == -1 ) { + ci->GlobalEndAddress = ci->GlobalStartAddress = 0x60; + } + pEntry->n_value = ci->GlobalStartAddress; + pEntry->n_scnum = 2; + pEntry->n_type = 0; + pEntry->n_sclass = C_STAT; + pEntry->n_numaux = 1; + pEntry++; + pAux = (union auxent *)pEntry; + pAux->x_scn.x_scnlen = 0; /* we don't store any data here */ + pAux->x_scn.x_nreloc = 0; + pAux->x_scn.x_nlinno = 0; + + /* one more for .data - eeprom ??? */ + + /* Calculate common offsets into the file */ + RawOffset = sizeof(struct external_filehdr) + ci->ListOfSectionHeaders.TotalBytes; + LinesOffset = RawOffset + ci->MaxRomAddress + 2; /* ignore eeprom for now */ + SymbolsOffset = LinesOffset + ci->ListOfLineNumbers.TotalBytes; + StringsOffset = SymbolsOffset + ci->ListOfSymbols.TotalBytes + ci->ListOfSpecials.TotalBytes + ci->ListOfGlobals.TotalBytes; + + /* Clean up loose ends in string table */ + if ( !(plong = (unsigned long *)FindFirstListObject(&ci->ListOfStrings)) ) { + fprintf(stderr,"\nInternal error in string table!"); + return; + } + *plong = ci->ListOfStrings.TotalBytes; /* Size of string table */ + + /* Clean up loose ends in symbol table */ + + /* symbol table - Filename value - index to next .file or global symbol */ + /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */ + LastFunctionAddress = ci->MaxRomAddress; + NumberOfSymbols = ci->ListOfSymbols.TotalItems + ci->ListOfSpecials.TotalItems + ci->ListOfGlobals.TotalItems; + SymbolIndex = LastFileIndex = NumberOfSymbols; + LastFunctionIndex = 0; /* set to zero on last function */ + for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols); + pEntry != 0; + pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) { + + /* Search for .file entries designated by C_FILE */ + if ( pEntry->n_sclass == C_FILE ) { + pEntry->n_value = LastFileIndex; + LastFileIndex = SymbolIndex; /* save current index */ + } + /* Search for Function entries C_EXT */ + else if ( pEntry->n_sclass == C_EXT ) { + pEntry++; + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_fsize = LastFunctionAddress - pEntry->n_value; /* function updated size */ + pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr += LinesOffset; + LastFunctionAddress = pEntry->n_value; + pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex; /* point to next function index */ + pAux->x_sym.x_tvndx = 0; /* ??? */ + LastFunctionIndex = SymbolIndex; + } else if ( (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK) ) { + if ( pEntry->n_name[1] == 'b' ) { + /* .bf and .bb */ + pEntry++; + pAux = (union auxent *)pEntry; + pAux->x_sym.x_fcnary.x_fcn.x_endndx = LastFunctionIndex; + } + } + /* else do nothing */ + + /* update current symbol index */ + pNode = GetCurrentNode( &ci->ListOfSymbols ); + SymbolIndex -= ( pNode->Size / sizeof(struct syment) ); + } + + // File Header + ci->FileHeader.f_magic = MAGIC_NUMBER_AVR; + ci->FileHeader.f_nscns = 2; + ci->FileHeader.f_timdat = time( (time_t *)&ci->FileHeader.f_timdat); + ci->FileHeader.f_symptr = SymbolsOffset; + ci->FileHeader.f_nsyms = NumberOfSymbols; + ci->FileHeader.f_opthdr = 0; + ci->FileHeader.f_flags = 0xff; /*F_RELFLG;*/ /* No relocation information available */ + + /* write it out */ + if ( fwrite(&ci->FileHeader, 1, sizeof(struct external_filehdr), pi->coff_file ) != sizeof(struct external_filehdr) ) { + fprintf(stderr,"\nFile error writing header ...(disk full?)"); + return; + } + + // Optional Information + + // Section 1 Header + pSectionHdr = (struct external_scnhdr *)FindFirstListObject(&ci->ListOfSectionHeaders); + if ( !pSectionHdr ) { + fprintf(stderr, "\nInternal Coff error - cannot find section header .text!"); + return; + } + memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) ); + strcpy( &pSectionHdr->s_name[0], ".text"); + pSectionHdr->s_paddr = 0; + pSectionHdr->s_vaddr = 0; + pSectionHdr->s_size = ci->MaxRomAddress + 2; /* remember the last instruction */ + pSectionHdr->s_scnptr = RawOffset; + pSectionHdr->s_relptr = 0; + pSectionHdr->s_lnnoptr = LinesOffset; + pSectionHdr->s_nreloc = 0; + pSectionHdr->s_nlnno = ci->ListOfLineNumbers.TotalBytes/sizeof(struct lineno); + pSectionHdr->s_flags = STYP_TEXT; + + /* write it out */ + if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) != sizeof(struct external_scnhdr) ) { + fprintf(stderr,"\nFile error writing section header ...(disk full?)"); + return; + } + + // Section 2 Header + pSectionHdr = (struct external_scnhdr *)FindNextListObject(&ci->ListOfSectionHeaders); + if ( !pSectionHdr ) { + fprintf(stderr, "\nInternal Coff error - cannot find section header .bss!"); + return; + } + memset( &pSectionHdr->s_name[0], 0, sizeof(struct external_scnhdr) ); + strcpy( &pSectionHdr->s_name[0], ".bss"); + /* later expansion */ + pSectionHdr->s_paddr = ci->GlobalStartAddress; + pSectionHdr->s_vaddr = ci->GlobalStartAddress; + pSectionHdr->s_flags = STYP_DATA; /* seems it should be STYP_BSS */ + + /* write it out */ + if ( fwrite(&pSectionHdr->s_name[0], 1, sizeof(struct external_scnhdr), pi->coff_file ) != sizeof(struct external_scnhdr) ) { + fprintf(stderr,"\nFile error writing section header ...(disk full?)"); + return; + } + + /* Section N Header - .data or eeprom */ + + // Raw Data for Section 1 + if ( (p = (unsigned char *)FindFirstListObject(&ci->ListOfRawData) ) == 0 ) { + fprintf(stderr,"\nInternal error - unable to find binary data!"); + return; + } + + /* write it out */ + if ( fwrite( p, 1, ci->MaxRomAddress + 2, pi->coff_file ) != (size_t)(ci->MaxRomAddress + 2) ) { + fprintf(stderr,"\nFile error writing raw .text data ...(disk full?)"); + return; + } + // Raw data for section n + + // Relocation Info for section 1 + + // Relocation info for section n + + // Line numbers for section 1 + for ( pLine = (struct lineno *)FindFirstListObject( &ci->ListOfLineNumbers ); + pLine != 0; + pLine = (struct lineno *)FindNextListObject( &ci->ListOfLineNumbers ) ) { + + pNode = GetCurrentNode( &ci->ListOfLineNumbers ); + + /* write it out */ + if ( fwrite( pLine, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { + fprintf(stderr,"\nFile error writing line numbers ...(disk full?)"); + return; + } + } + + + // Line numbers for section n + + // Symbol table + for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSymbols ); + pEntry != 0; + pEntry = (struct syment *)FindNextListObject( &ci->ListOfSymbols ) ) { + + pNode = GetCurrentNode( &ci->ListOfSymbols ); + + /* write it out */ + if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { + fprintf(stderr,"\nFile error writing symbol table ...(disk full?)"); + return; + } + } + + // Symbol table of Globals + for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfGlobals ); + pEntry != 0; + pEntry = (struct syment *)FindNextListObject( &ci->ListOfGlobals ) ) { + + pNode = GetCurrentNode( &ci->ListOfGlobals ); + + /* write it out */ + if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { + fprintf(stderr,"\nFile error writing global symbols ...(disk full?)"); + return; + } + } + + /* Specials .text, .bss, .data */ + + for ( pEntry = (struct syment *)FindFirstListObject( &ci->ListOfSpecials ); + pEntry != 0; + pEntry = (struct syment *)FindNextListObject( &ci->ListOfSpecials ) ) { + + pNode = GetCurrentNode( &ci->ListOfSpecials ); + + /* write it out */ + if ( fwrite( pEntry, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { + fprintf(stderr,"\nFile error writing special symbols ...(disk full?)"); + return; + } + } + + // String Table + for ( p = (char *)FindFirstListObject( &ci->ListOfStrings ); + p != 0; + p = (char *)FindNextListObject( &ci->ListOfStrings ) ) { + + pNode = GetCurrentNode( &ci->ListOfStrings ); + + /* write it out */ + if ( fwrite( p, 1, pNode->Size, pi->coff_file ) != pNode->Size ) { + fprintf(stderr,"\nFile error writing strings data ...(disk full?)"); + return; + } + } + + return; +} + +/****************************************************************************************/ + +void write_coff_eeprom( struct prog_info *pi, int address, unsigned char data){ + + if ( !GET_ARG(pi->args, ARG_COFF) ) + return; + + /* Coff output keeps track of binary data in memory buffers */ + if ( ci->pEEPRomMemory ) { + if ( address <= pi->device->eeprom_size ) { + *(ci->pEEPRomMemory + address) = data; + if ( address >= ci->MaxEepromAddress ) + ci->MaxEepromAddress = address; /* keep high water mark */ + } else { + pi->error_count++; + fprintf(stderr, "Error: EEPROM address %d exceeds max range %d", address, pi->device->eeprom_size ); + } + } +} +/****************************************************************************************/ + +void write_coff_program( struct prog_info *pi, int address, unsigned int data){ + + unsigned char *pByte; + + if ( !GET_ARG(pi->args, ARG_COFF) ) + return; + + /* Coff output keeps track of binary data in memory buffers, address is in bytes not words */ + if ( ci->pRomMemory ) { + if ( address <= pi->device->flash_size ) { + pByte = (unsigned char *)(ci->pRomMemory + address); /* point to low byte in memory */ + *pByte++ = (data & 0xff); /* low byte */ + *pByte = ((data >> 8) & 0xff); /* high byte */ + + if ( address >= ci->MaxRomAddress ) + ci->MaxRomAddress = address; /* keep high water mark */ + } else { + pi->error_count++; + fprintf(stderr, "Error: FLASH address %d exceeds max range %d\n", address, pi->device->flash_size ); + /* Nick added \n above */ + } + } +} + +/****************************************************************************************/ + +void close_coff_file(struct prog_info *pi, FILE *fp){ + + /* close the output file */ + fclose( fp ); + pi->coff_file = 0; + + /* free all the internal memory buffers used by ci */ + + FreeList( &ci->ListOfSectionHeaders ); + FreeList( &ci->ListOfRawData ); + FreeList( &ci->ListOfRelocations ); + FreeList( &ci->ListOfLineNumbers ); + FreeList( &ci->ListOfSymbols ); + FreeList( &ci->ListOfGlobals ); + FreeList( &ci->ListOfUndefined ); + FreeList( &ci->ListOfStrings ); + FreeList( &ci->ListOfTypes ); + FreeList( &ci->ListOfSplitLines ); + + /* now free ci */ + free( ci ); + ci = 0; +} + +/****************************************************************************************/ + +int parse_stabs( struct prog_info *pi, char *p, int pass ){ + + int ok = True; + int TypeCode, n; + char *pString, *p2, *p3, *p4, *p5, *pType, *pEnd, *pp, *pJoined; + + + if ( !GET_ARG(pi->args, ARG_COFF) || ( pass == PASS_1 ) ) + return(True); + + /* stabs debugging information is in the form: + .stabs "symbolic info string", HexorDecimalTypecode, parm3, parm4, parm5 + parm1, parm2, parm3 depend on typecode + + N_LSYM 0x80 local sym: name,,0,type,offset + N_OPT 0x3c compiler options + N_SO 0x64 source file name: name,,0,0,address + N_SOL 0x84 #included file name: name,,0,0,address + N_FUN 0x24 procedure: name,,0,linenumber,address + N_GSYM 0x20 global symbol: name,,0,type,0 + N_LCSYM 0x28 .lcomm symbol: name,,0,type,address + N_STSYM 0x26 static symbol: name,,0,type,address + N_RSYM 0x40 register sym: name,,0,type,register + N_PSYM 0xa0 parameter: name,,0,type,offset + + */ + + /* Look for multiple commands per line */ + + /* .stabs "linktag:T19=s46next:20=*19,0,16;last:20,16,16;a:21=ar1;0;2;22=ar1;0;3;1,32,96;\\",128,0,0,0 */ + /* .stabs "b:23=ar1;0;4;24=ar1;0;5;2,128,240;;",128,0,0,0 */ + + + /* Look for continuation lines per line */ + + /* Get String information as a token */ + /* Parse the tokens in the stabn line buffer */ + pString = get_next_token(p, TERM_DOUBLEQUOTE ); /* zap first doublequote */ + p2 = get_next_token(pString, TERM_DOUBLEQUOTE ); /* zap last doublequote */ + p2 = get_next_token(p2, TERM_COMMA ); /* zap comma */ + p3 = get_next_token(p2, TERM_COMMA ); + p4 = get_next_token(p3, TERM_COMMA ); + p5 = get_next_token(p4, TERM_COMMA ); + pEnd = get_next_token(p5, TERM_END ); /* zap CR LF, make ASCIIZ */ + + if ( !pString || !p2 || !p3 || !p4 || !p5 ) + return( False ); + + /* Check for split lines */ + n = strlen( pString ); + if ( ( pString[n - 1] == '\\' ) && (pString[n - 2] == '\\') ) { + /* We have a continuation string here */ + pString[n - 2] = 0; + n -= 2; + if ( !(pp = (char *)AllocateListObject( &ci->ListOfSplitLines, n + 1 )) ) { + fprintf(stderr, "\nOut of memory allocating continuation line!"); + return( False ); + } + strcpy( pp, pString ); /* loose the continuation characters */ + return(True); + } + if ( ci->ListOfSplitLines.TotalItems > 0 ) { + /* Join lines together and process */ + if ( !(pJoined = calloc( 1, n + ci->ListOfSplitLines.TotalBytes ) ) ) { + fprintf(stderr, "\nOut of memory joining continuation lines!"); + return( False ); + } + for ( pp = (char *)FindFirstListObject( &ci->ListOfSplitLines ); + pp != 0; + pp = (char *)FindNextListObject( &ci->ListOfSplitLines ) ) { + + strcat( pJoined, pp ); /* connect the lines */ + } + strcat( pJoined, pString ); + FreeList( &ci->ListOfSplitLines ); + if ( !AddListObject( &ci->ListOfSplitLines, pJoined, n + ci->ListOfSplitLines.TotalBytes ) ) { + fprintf(stderr, "\nUnable to add joined continuation line"); + return( False ); + } + pString = pJoined; + } + + + if ( *p2 == '0' ) + TypeCode = atox(p2); /* presume to be hex 0x */ + else + TypeCode = atoi(p2); + + switch ( TypeCode ) { + + case N_OPT: /* compiler options */ + break; /* nothing used here */ + + case N_SO: /* source file name: name,,0,0,address */ + ok = stab_add_filename( pString, p5 ); + break; + + case N_GSYM: /* global symbol: name,,0,type,0 */ + pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ + ok = stab_add_global( pi, pString, pType ); + break; + + case N_FUN: /* procedure: name,,0,linenumber,address */ + ok = stab_add_function( pi, pString, p5 ); + break; + + case N_LSYM: /* local sym: name,,0,type,offset */ + /* pString, p2 = TypeCode, p3 = 0, p4 = 0, p5 = offset */ + pType = get_next_token(pString, TERM_COLON ); /* pType = symbol descriptor (character after the colon) */ + if ( *pType == 't') + ok = stab_add_local_type( pString, ++pType ); + else if (*pType == 'T') + ok = stab_add_tag_type( pString, ++pType ); + else + ok = stab_add_local( pi, pString, pType, p5 ); + break; + + case N_RSYM: /* Symbol:[P|r]type,0,size,register */ + pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ + ok = stab_add_local_register( pi, pString, pType, p5 ); + break; + + case N_LCSYM: /* .lcomm symbol: name,,0,type,address */ + ok = True; + break; /* ignore constants */ + + case N_STSYM: /* static symbol: name,,0,type,address */ + pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ + ok = stab_add_static_symbol( pi, pString, pType, p5 ); + break; + + case N_PSYM: /* parameter: name,,0,type,offset */ + pType = get_next_token(pString, TERM_COLON ); /* separate at colon */ + ok = stab_add_parameter_symbol( pi, pString, pType, p5 ); + break; + + case N_SOL: /* #included file name: name,,0,0,address */ + ok = True; + break; /* ignore include files */ + + default: + ok = False; + } + + if ( ci->ListOfSplitLines.TotalItems > 0 ) + FreeList( &ci->ListOfSplitLines ); + + return( ok ); +} +/****************************************************************************************/ + +int parse_stabn( struct prog_info *pi, char *p, int pass ){ + + int ok = True; + int TypeCode /* , LineNumber */, Level; + char *p1, *p2, *p3, *p4, *pLabel, *pFunction, *pEnd; + + /* stabn debugging information is in the form: + .stabn TypeCode, 0, parm1, parm2 + parm1 is level + parm2 is Label-Function + + compiler currently produces the following TypeCodes: + N_LBRAC 0xc0 left bracket: 0,,0,nesting level,address + N_RBRAC 0xe0 right bracket: 0,,0,nesting level,address + N_SLINE 0x44 src line: 0,,0,linenumber,address + */ + + if ( !GET_ARG(pi->args, ARG_COFF) || ( pass == PASS_1 ) ) + return(True); + + /* Parse the tokens in the stabn line buffer */ + p1 = get_next_token(p, TERM_SPACE ); + p2 = get_next_token(p1, TERM_COMMA ); + p3 = get_next_token(p2, TERM_COMMA ); + p4 = get_next_token(p3, TERM_COMMA ); + pEnd = get_next_token(p4, TERM_END ); /* zap CR LF, make ASCIIZ */ + + if ( !p1 || !p2 || !p3 || !p4 ) + return( False ); + + /* first convert TypeCode to binary */ + if ( *p1 == '0' ) + TypeCode = atox(p1); /* presume to be hex 0x */ + else + TypeCode = atoi(p1); + + Level = atoi(p3); /* line number or level */ + pLabel = p4; /* Assembly label */ + pFunction = get_next_token( pLabel, TERM_DASH ); /* Function */ + + switch ( TypeCode ) { + case N_SLINE: /* src line: 0,,0,linenumber,address */ + ok = stab_add_lineno( pi, Level, pLabel, pFunction ); + break; + + case N_LBRAC: /* left bracket: 0,,0,nesting level,address */ + ok = stab_add_lbracket( pi, Level, pLabel, pFunction ); + break; + + case N_RBRAC: /* right bracket: 0,,0,nesting level,address */ + ok = stab_add_rbracket( pi, Level, pLabel, pFunction ); + break; + + default: + fprintf(stderr, "\nUnknown .stabn TypeCode = 0x%x", TypeCode ); + ok = False; + } + return( ok ); +} + +/****************************************************************************************/ +int stab_add_lineno( struct prog_info *pi, int LineNumber, char *pLabel, char *pFunction ){ + + int Address; + struct lineno *pln; + struct syment *pEntry; + union auxent *pAux; + + /* Allocate LineNumber Table entry and fill it in */ + pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno) ); + if ( !pln ) { + fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pFunction ); + return( False ); + } + /* set value field to be address of label in bytes */ + if ( !get_symbol(pi, pLabel, &Address) ) { + fprintf(stderr, "\nUnable to locate label %s", pLabel ); + return( False ); + } + pln->l_addr.l_paddr = Address * 2; /* need byte quanities */ + + /* Line number is relative to beginning of function, starts at 1 */ + if ( ci->FunctionStartLine == 0 ) { + /* This line number is that same as the function start */ + ci->FunctionStartLine = LineNumber; + } + pln->l_lnno = LineNumber - ci->FunctionStartLine + 1; + ci->CurrentSourceLine = LineNumber; /* keep track of source line for .eb .ef arrays */ + if ( ci->NeedLineNumberFixup ) { + /* need to go into symbol table and fix last NeedLineNumberFixup entries */ + for ( pEntry = (struct syment *)FindLastListObject(&ci->ListOfSymbols); + (pEntry != 0) && ( ci->NeedLineNumberFixup != 0); + pEntry = (struct syment *)FindNextLastListObject(&ci->ListOfSymbols) ) { + + /* Fix up line number entries */ + if ( (pEntry->n_sclass == C_FCN ) || ( pEntry->n_sclass == C_BLOCK ) || ( pEntry->n_sclass == C_EXT) ) { + pEntry++; + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_lnsz.x_lnno = LineNumber; + ci->NeedLineNumberFixup--; + } + } + } + + return(True); +} +/****************************************************************************************/ + +int stab_add_lbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){ + + int Address; + struct syment *pEntry; + union auxent *pAux; + //char *p; + //struct lineno *pln; + + if ( !get_symbol(pi, pLabel, &Address) ) { + fprintf(stderr, "\nUnable to locate label %s", pLabel ); + return( False ); + } + + /* Now create a .bb symbol table entry and aux entry too */ + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry for .bb %s", pLabel ); + return( False ); + } + /* n_name */ + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".bb" ); + + pEntry->n_value = Address * 2; /* bytes not words */ + pEntry->n_scnum = 1; /* .text */ + pEntry->n_type = 0; + pEntry->n_sclass = C_BLOCK; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_lnsz.x_lnno = 0; /* UNKNOWN - post process */ + pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN - post process */ + ci->NeedLineNumberFixup++; /* once for .bb block */ + return(True); +} + +/****************************************************************************************/ +int stab_add_rbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ){ + + int Address; + struct syment *pEntry; + union auxent *pAux; + //char *p; + //struct lineno *pln; + + if ( !get_symbol(pi, pLabel, &Address) ) { + fprintf(stderr, "\nUnable to locate label %s", pLabel ); + return( False ); + } + + /* Now create a .eb symbol table entry */ + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry for .eb %s", pLabel ); + return( False ); + } + /* n_name */ + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".eb" ); + pEntry->n_sclass = C_BLOCK; + pEntry->n_value = Address * 2; /* bytes not words */ + pEntry->n_scnum = 1; /* .text */ + pEntry->n_type = 0; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine; + + /* create an .ef if at level 0 */ + if ( Level == 0 ) { + + /* Now create a .ef symbol table entry */ + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry for .ef %s", pLabel ); + return( False ); + } + /* n_name */ + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".ef" ); + pEntry->n_sclass = C_FCN; + pEntry->n_value = Address * 2; /* bytes not words */ + pEntry->n_scnum = 1; /* .text */ + pEntry->n_type = 0; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->CurrentSourceLine; + } + return(True); +} + +/****************************************************************************************/ +int stab_add_filename( char *pName, char *pLabel ){ + + int ok, n; + struct syment *pEntry; + union auxent *pAux; + char *p; + + /* if( pLabel == "Ltext0" ) then beginning of .text, pName = cwd, next pName = file */ + + /* if( pLabel == "Letext" ) then end of .text , pName == NULL */ + + /* we only need the one not ending in Slash */ + ok = True; + n = strlen(pName); + if ( n > 0 ) { + if ( ( pName[ n - 1] == '\\') || (pName[ n - 1] == '/') ) + return(True); /* ignore */ + } else + return(True); + + + /* allocate entry in symbol table list */ + pEntry = (struct syment *)AllocateTwoListObjects( + &ci->ListOfSymbols, sizeof(struct syment) * 2 ); /* aux entry too */ + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry for global %s", pName ); + return( False ); + } + /* n_name */ + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".file" ); + /* n_value is determined after processing done UNKNOWN - post process */ + /* The value of that symbol equals the symbol table entry index of the next .file symbol or .global */ + /* post process */ + pEntry->n_scnum = N_DEBUG; + pEntry->n_sclass = C_FILE; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + + /* Add Label name to symbol table */ + if ( n <= FILNMLEN ) { + /* inline filename */ + memset( pAux->x_file.x_fname, 0, FILNMLEN ); + strncpy( pAux->x_file.x_fname, pName, n ); /* might not be zero terminated */ + } else { + pAux->x_file.x_n.x_zeroes = 0; /* symbol name is in string table */ + pAux->x_file.x_n.x_offset = ci->ListOfStrings.TotalBytes; + + /* add to string table */ + p = (char *)AllocateListObject( &ci->ListOfStrings, n + 1 ); + if ( !p ) { + fprintf(stderr, "\nOut of memory allocating string table space!"); + return( False ); + } + strcpy( p, pName ); + } + return( ok ); +} + +/****************************************************************************************/ +int stab_add_function( struct prog_info *pi, char *pName, char *pLabel ){ + + int n, Address; + unsigned short CoffType, Type; + struct syment *pEntry; + char *pType; + struct lineno *pln; + union auxent *pAux; + int SymbolIndex; + + pType = get_next_token(pName, TERM_COLON ); /* pType = symbol descriptor (character after the colon) */ + Type = atoi(pType + 1); /* skip past F, predefined variable type */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized return type found for function %s = %d", pName, Type ); + return(False); + } + /* Get Current Symbol Index, Allocate Symbol Table entry and fill it in */ + SymbolIndex = ci->ListOfSymbols.TotalItems; + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry for function %s", pName ); + return( False ); + } + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + } + if ( !get_symbol(pi, pLabel, &Address) ) { + fprintf(stderr, "\nUnable to locate function %s", pName ); + return( False ); + } + pEntry->n_value = Address * 2; /* convert words to bytes */ + pEntry->n_scnum = 2; /* .bss */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for function %s = %d", pName, Type ); + return(False); + } + pEntry->n_type = (unsigned short)(CoffType | (DT_FCN << 4)); + pEntry->n_sclass = C_EXT; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_tagndx = SymbolIndex + 1; /* point to the .bf entry index */ + // wrong! + // pAux->x_sym.x_misc.x_lnsz.x_lnno = ci->ListOfLineNumbers.TotalBytes; /* Relative Fixup point to where line numbers start */ + // pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN till next function called */ + pAux->x_sym.x_misc.x_fsize = 0; /* unknown till end */ + pAux->x_sym.x_fcnary.x_fcn.x_lnnoptr = ci->ListOfLineNumbers.TotalBytes; /* relative offset to line number entry */ + pAux->x_sym.x_fcnary.x_fcn.x_endndx = 0; /* index to next entry */ + + /* Now add function entry into the line number table */ + /* Allocate Symbol Table entry and fill it in */ + pln = (struct lineno *)AllocateListObject(&ci->ListOfLineNumbers, sizeof(struct lineno) ); + if ( !pln ) { + fprintf(stderr, "\nOut of memory allocating lineno table for function %s", pName ); + return( False ); + } + pln->l_lnno = 0; + pln->l_addr.l_symndx = SymbolIndex; + + /* Initialize the FunctionStartLine from the beginning of the function */ + ci->FunctionStartLine = 0; + + /* Allocate Symbol Table entry and fill it in */ + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfSymbols, sizeof(struct syment) * 2 ); + if ( !pEntry ) { + fprintf(stderr, "\nOut of memory allocating symbol table entry .bf for function %s", pName ); + return( False ); + } + memset( pEntry->n_name, 0, 8 ); + strcpy( pEntry->n_name, ".bf" ); + pEntry->n_value = Address * 2; /* bytes not words */ + pEntry->n_scnum = 1; /* .text */ + pEntry->n_type = 0; + pEntry->n_sclass = C_FCN; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_misc.x_lnsz.x_lnno = 0; /* UNKNOWN - post process */ + pAux->x_sym.x_misc.x_lnsz.x_size = 0; /* UNKNOWN - post process */ + + ci->NeedLineNumberFixup++; /* once for function C_EXT symbol */ + ci->NeedLineNumberFixup++; /* once for .bf block */ + return( True ); +} +/****************************************************************************************/ + +int stab_add_global( struct prog_info *pi, char *pName, char *pType ){ + + int n, Address, IsArray, SymbolIndex; + unsigned short CoffType, Type; + struct syment *pEntry; + char *p; + STABCOFFMAP *pMap; + + + n = strlen( pName ); /* see if it's 8 bytes or less */ + Type = atoi(pType + 1); /* skip past G, predefined variable type */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for global %s = %d", pName, Type ); + return(False); + } + pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes ); + + SymbolIndex = ci->ListOfSymbols.TotalItems; + /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */ + if ( IsTypeArray( CoffType ) == True ) { + IsArray = True; + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ); + } else { + IsArray = False; + pEntry = (struct syment *)AllocateListObject( &ci->ListOfGlobals, sizeof(struct syment) ); + } + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + } + /* set value field to be address of label in bytes */ + /* add underscore to lookup label */ + if ( (p = calloc( 1, n + 2)) == 0 ) { + fprintf(stderr,"\nOut of memory adding global %s", pName ); + return(False); + } + *p = '_'; + strcpy( p + 1, pName ); + if ( !get_symbol(pi, p, &Address) ) { + fprintf(stderr, "\nUnable to locate global %s", p ); + free( p ); + return( False ); + } + free( p ); + pEntry->n_value = Address; /* already in bytes */ + if ( ci->GlobalStartAddress == -1 ) { + ci->GlobalStartAddress = Address; + } + if ( Address < ci->GlobalStartAddress ) + ci->GlobalStartAddress = Address; + if ( Address > ci->GlobalEndAddress ) + ci->GlobalEndAddress = Address; + + pEntry->n_scnum = 2; /* .bss */ + pEntry->n_type = CoffType; + pEntry->n_sclass = C_STAT; + if ( IsArray == False ) + pEntry->n_numaux = 0; + else { + pEntry->n_numaux = 1; + pEntry++; + AddArrayAuxInfo( (union auxent *)pEntry, (unsigned short)SymbolIndex, pMap ); + } + return( True ); +} + +/****************************************************************************************/ +int stab_add_local( struct prog_info *pi, char *pName, char *pType, char *pOffset ){ + + int n, Offset, IsArray; + unsigned short CoffType, Type, SymbolIndex; + struct syment *pEntry; + STABCOFFMAP *pMap; + + n = strlen( pName ); /* see if it's 8 bytes or less */ + Type = atoi(pType); /* predefined variable type */ + Offset = atoi(pOffset); /* offset in stack frame */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for local %s = %d", pName, Type ); + return(False); + } + pMap = (STABCOFFMAP *)GetCurrentListObject( &ci->ListOfTypes ); + SymbolIndex = ci->ListOfSymbols.TotalItems; + /* Allocate Symbol Table entry and fill it in, Auxiliary table if its an array */ + if ( IsTypeArray( CoffType ) == True ) { + IsArray = True; + pEntry = (struct syment *)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ); + } else { + IsArray = False; + pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); + } + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + } + pEntry->n_type = CoffType; + pEntry->n_sclass = C_AUTO; + pEntry->n_scnum = N_ABS; + pEntry->n_value = Offset + 1; /* Silly avr studio is set in its ways */ + if ( IsArray == False ) + pEntry->n_numaux = 0; + else { + pEntry->n_numaux = 1; + pEntry++; + AddArrayAuxInfo( (union auxent *)pEntry, SymbolIndex, pMap ); + } + return( True ); +} + +/****************************************************************************************/ +int stab_add_parameter_symbol( struct prog_info *pi, char *pName, char *pType, char *pOffset ){ + + int n, Offset; + unsigned short CoffType, Type; + struct syment *pEntry; + + n = strlen( pName ); /* see if it's 8 bytes or less */ + Type = atoi(pType); /* predefined variable type */ + Offset = atoi(pOffset); /* offset in stack frame */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); + return(False); + } + /* Allocate Symbol Table entry and fill it in */ + pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + } + pEntry->n_type = CoffType; + pEntry->n_sclass = C_ARG; + pEntry->n_scnum = N_ABS; + pEntry->n_value = Offset; + pEntry->n_numaux = 0; + return( True ); +} +/****************************************************************************************/ +int stab_add_static_symbol( struct prog_info *pi, char *pName, char *pType, char *pLabel ){ + + int n, Address; + unsigned short CoffType, Type; + struct syment *pEntry; + + n = strlen( pName ); /* see if it's 8 bytes or less */ + Type = atoi(pType + 1); /* skip past S, predefined variable type */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); + return(False); + } + /* Allocate Symbol Table entry and fill it in */ + pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + } + pEntry->n_type = CoffType; + pEntry->n_sclass = C_STAT; + pEntry->n_scnum = N_ABS; + if ( !get_symbol(pi, pLabel, &Address) ) { + fprintf(stderr, "\nUnable to locate label %s", pLabel ); + return( False ); + } + pEntry->n_value = Address * 2; /* find address of variable in bytes */ + pEntry->n_numaux = 0; + return( True ); +} +/****************************************************************************************/ + +int stab_add_local_register( struct prog_info *pi, char *pName, char *pType, char *pRegister ){ + + int n, Register, Size; + unsigned short CoffType, Type; + struct syment *pEntry; + + n = strlen( pName ); /* see if it's 8 bytes or less */ + Type = (unsigned short)atoi(pType + 1); /* skip past P, predefined variable type */ + Register = atoi(pRegister); /* offset in stack frame */ + if ( (CoffType = GetCoffType( Type )) == 0 ) { + fprintf(stderr, "\nUnrecognized type found for %s = %d", pName, Type ); + return(False); + } + Size = GetCoffTypeSize( Type ); /* Silly requirement for avr studio */ + /* Allocate Symbol Table entry and fill it in */ + pEntry = (struct syment *)AllocateListObject( &ci->ListOfSymbols, sizeof(struct syment) ); + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pName ); + return(False); + } + pEntry->n_type = CoffType; + // if( (*pType == 'r') || (*pType == 'R') ) + // pEntry->n_sclass = C_REG; + // else if( (*pType == 'p') || (*pType == 'P') ) + pEntry->n_sclass = C_REGPARM; /* Silly avr studio only accepts this for registers */ + // else{ + // fprintf(stderr,"\nUnknown register type -> %s", pType ); + // return(False); + // } + pEntry->n_scnum = N_ABS; + pEntry->n_numaux = 0; + if ( Size == 1 ) + pEntry->n_value = 0xffffff00 | Register; /* Silly requirement for avr studio */ + else if ( Size == 2 ) + pEntry->n_value = 0xffff0000 | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */ + else if ( Size == 4 ) + pEntry->n_value = ((Register + 3) << 24) | ((Register + 3) << 16) | ((Register + 1) << 8) | Register; /* Silly requirement for avr studio */ + else { + fprintf(stderr,"\nUnknown register size (%d) and coff type (%d)", Size, CoffType ); + return(False); + } + return( True ); +} + +/****************************************************************************************/ + +int stab_add_local_type( char *pName, char *pType ){ + + char *p; + unsigned short StabType; + + /* .stabs "int:t1=r1;-128;127;",128,0,0,0 */ + /* .stabs ":t20=ar1;0;1;21=ar1;0;1;2",128,0,0,0 */ + /* pType-----^ */ + /* Stab Type - convert to Coff type at end (after inline assignments */ + if ( GetStabType( pType, &StabType, &p ) != True ) { + fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p); + return(False); + } + + return(True); +} + +/****************************************************************************************/ + +int GetStructUnionTagItem( char *p, char **pEnd, char **pName, unsigned short *pType, unsigned short *pBitOffset, unsigned short *pBitSize) { + + unsigned short StabType; + /* Structure or Union Tag Item consists of -> name:type,bitoffset,bitsize; */ + + /* name */ + *pName = p; + while ( *p && (*p != ':') ) p++; // locate colon + if ( *p != ':' ) { + fprintf(stderr,"\nNo colon found in structure item ->", p); + return(False); + } + *p++ = 0; // Asciiz + /* Stab Type - convert to Coff type at end (after inline assignments */ + if ( GetStabType( p, &StabType, &p ) != True ) { + fprintf(stderr,"\nInvalid tag type found in structure item -> %s", p); + return(False); + } + + /* BitSize */ + if ( *p != ',' ) { + fprintf(stderr,"\nNo Bit size found in structure item -> %s", p ); + return(False); + } + *pBitOffset = (unsigned short)atoi( ++p ); + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + + /* BitOffset */ + if ( *p != ',' ) { + fprintf(stderr,"\nNo Bit offset found in structure item -> %s", p ); + return(False); + } + *pBitSize = (unsigned short)atoi( ++p ); + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + + /* Now convert stab type to COFF */ + if ( (*pType = GetCoffType( (unsigned short)StabType)) == 0 ) { + fprintf(stderr,"\nNo COFF type found for stab type %d", StabType ); + return( False); + } + if ( *++p == ';' ) /* Now eat last semicolon(s) */ + p++; + *pEnd = p; + + return( True ); +} +/****************************************************************************************/ + +int GetEnumTagItem( char *p, char **pEnd, char **pEnumName, int *pEnumValue ) { + + /* Enum Tag Item consists of -> member1:value,member2:value2,; */ + *pEnumName = p; + while ( *p && (*p != ':') ) p++; // locate colon + if ( *p != ':' ) { + fprintf(stderr,"\nNo colon found in enum item ->", p); + return(False); + } + *p++ = 0; // Asciiz + *pEnumValue = atoi(p); + + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + if ( *p != ',' ) { + fprintf(stderr,"\nNo comma found after enum value -> %s", p ); + return(False); + } + if ( *++p ==';' ) + p++; /* eat last semicolon */ + *pEnd = p; + return( True ); +} + +/****************************************************************************************/ +int GetArrayType( char *p, char **pEnd, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){ + + int MinIndex, MaxIndex, Result, Size, i; + char *pMinIndex, *pMaxIndex, *pType; + unsigned short Type; + + Result = True; + + pMinIndex = pMaxIndex = pType = 0; + while ( *p && (*p != ';') ) p++; /* find min index */ + pMinIndex = ++p; + while ( *p && (*p != ';') ) p++; /* find max index */ + pMaxIndex = ++p; + while ( *p && (*p != ';') ) p++; /* find type index */ + pType = ++p; + + /* bump the pointers to the digits */ + if ( !isdigit(*pMinIndex) ) + Result = False; + if ( !isdigit(*pMaxIndex) ) + Result = False; + if ( !isdigit(*pType) ) + Result = False; + /* Is syntax ok ? */ + if ( Result != True ) { + fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType ); + return(False); + } + MinIndex = atoi(pMinIndex); + MaxIndex = atoi(pMaxIndex); + + if ( GetStabType( p, &Type, &p ) != True ) + return(False); + + if ( !SetupDefinedType( Type, pMap, DerivedBits, ExtraLevels ) ) + return( False ); + + /* Now update the size based on the indicies */ + Size = (MaxIndex - MinIndex) + 1; + pMap->ByteSize *= Size; + pMap->Line = ci->CurrentSourceLine; + /* add the dimension information */ + for ( i = 5; i >= 0; i-- ) { + if ( pMap->Dimensions[i] != 0 ) { + i++; + pMap->Dimensions[i] = Size; + break; + } + } + + *pEnd = p; + return(True); +} + +/****************************************************************************************/ +int GetStabType( char *p, unsigned short *pType, char **pEnd ) { + + STABCOFFMAP *pMap; + int extra, ok; + unsigned short derivedbits[6]; + unsigned short LStabType, RStabType; + char *pHigh, *pLow; + + + LStabType = atoi( p ); + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + + *pType = LStabType; + + if ( GetCoffType( LStabType ) != 0 ) { + *pEnd = p; + return(True); + } + if ( *p != '=' ) { + fprintf(stderr, "\nSyntax error in type assignment -> %s", p ); + return(False); + } + p++; + + /* Allocate space for new internal type */ + if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) { + fprintf(stderr, "\nOut of memory allocating type info!"); + return(False); + } + pMap->StabType = LStabType; + + /* process items to right of equals */ + for ( extra = 0; extra < 6; extra++ ) { + + if ( isdigit( *p ) ) { + /* Finally found base type, try to terminate loop */ + GetStabType( p, &RStabType, &p ); + // RStabType = atoi( p ); + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + if ( SetupDefinedType( RStabType, pMap, &derivedbits[0], extra ) != True ) + return( False ); + break; + } else if ( *p == 'a' ) { + derivedbits[extra] = DT_ARY; + p++; + /* Calculate size */ + /* Since type assignment will be made we need to set extra bits here */ + extra++; + /* =ar1;MinIndex;MaxIndex;BaseType */ + if ( GetArrayType( p, &p, pMap, &derivedbits[0], extra ) != True ) + return(False); + break; + + } else if ( *p == 'f' ) { + derivedbits[extra] = DT_FCN; + p++; + } else if ( *p == '*' ) { + derivedbits[extra] = DT_PTR; + p++; + } else if ( *p == 'r' ) { + // if( LStabType < 15 ) + // ok = GetInternalType( pString, pMap ); /* internal types not yet installed */ + // else + while ( *p && (*p != ';' ) ) p++; + pLow = p++; + while ( *p && (*p != ';' ) ) p++; + pHigh = p++; + ok = GetSubRangeType( LStabType, pMap, pLow, pHigh ); + if ( ok != True ) + return(False); + while ( *p && (*p != ';' ) ) p++; /* find end of range */ + p++; + break; + } else { + fprintf(stderr, "\nUnrecognized Type modifier %c!", *p ); + return(False); + } + } + *pEnd = p; /* Update return pointer */ + + return(True); +} + + +/****************************************************************************************/ +int stab_add_tag_type( char *pName, char *pString ){ + + int SymbolIndex, StabType, TotalSize, n, EnumValue; + unsigned short TagType, ItemType, BitOffset, BitSize; + char *p; + struct syment* pEntry; + union auxent *pAux; + STABCOFFMAP *pMap; + + /* We arrived here due to :T defining either a structure, union or enumeration */ + /* store the basic type as for internals and emit coff structures for debugging */ + /* .stabs "stag:T17=s2i:1,0,8;c:2,8,8;;",128,0,0,0 */ + /* .stabs "2:T18=u2a:2,0,8;b:1,0,8;c:6,0,16;;",128,0,0,0 */ + /* .stabs "1:T19=eenum1:1,enum2:2,enum3:3,;",128,0,0,0 */ + /* we don't care about the name */ + + + /* check for bogus errors */ + if ( !pName || !pString ) { + fprintf(stderr,"\nInvalid .stabs type format - no information!"); + return(False); + } + + p = pString; + /* Stab Type - convert to Coff type at end (after inline assignments */ + if ( (StabType = (unsigned short)atoi(p)) == 0 ) { + fprintf(stderr,"\nInvalid .stabs type format - no information! - > %s", p ); + return(False); + } + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + if ( *p != '=' ) { + fprintf(stderr,"\nInvalid .stabs type format - no equals - > %s", p ); + return(False); + } + SymbolIndex = ci->ListOfSymbols.TotalItems; + if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { + fprintf(stderr, "\nOut of memory allocating symbol tag entries"); + return(False); + } + /* Prepare Tag Header */ + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pString ); + return(False); + } + if ( !(pMap = (STABCOFFMAP *)AllocateListObject(&ci->ListOfTypes, sizeof(STABCOFFMAP)) ) ) { + fprintf(stderr, "\nOut of memory allocating type info!"); + return(False); + } + pMap->StabType = StabType; + pEntry->n_value = 0; + pEntry->n_scnum = N_DEBUG; + pEntry->n_numaux = 1; + if ( *++p == 's' ) { + TagType = pEntry->n_type = pMap->CoffType = T_STRUCT; + pEntry->n_sclass = C_STRTAG; + TotalSize = (unsigned short)atoi(++p); + } else if ( *p == 'u' ) { + TagType = pEntry->n_type = pMap->CoffType = T_UNION; + pEntry->n_sclass = C_UNTAG; + TotalSize = (unsigned short)atoi(++p); + } else if ( *p == 'e' ) { + TagType = pEntry->n_type = pMap->CoffType = T_ENUM; + pEntry->n_sclass = C_ENTAG; + TotalSize = FundamentalTypes[T_INT].Size; /* use size of int for enums */ + } else { + fprintf(stderr,"\nUnknown tag type -> %s", p ); + return(False); + } + while ( *p && (*p >= '0') && (*p <= '9') ) p++; // locate end of digits + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_tagndx = SymbolIndex; + pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; + + /* update our local knowledge of tag type */ + pMap->CoffType = TagType; + pMap->ByteSize = TotalSize; + pMap->Line = ci->CurrentSourceLine; + + /* Process the items until the end of the line */ + while ( *pName ) { + + if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { + fprintf(stderr, "\nOut of memory allocating symbol tag member entries"); + return(False); + } + + if ( TagType == T_STRUCT ) { + if ( GetStructUnionTagItem( p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) { + return(False); + } + pEntry->n_value = BitOffset/8; + pEntry->n_type = ItemType; + pEntry->n_sclass = C_MOS; + } else if ( TagType == T_UNION ) { + if ( GetStructUnionTagItem( p, &p, &pName, &ItemType, &BitOffset, &BitSize) != True ) { + return(False); + } + pEntry->n_value = BitOffset/8; + pEntry->n_type = ItemType; + pEntry->n_sclass = C_MOU; + } else { /* T_ENUM */ + if ( GetEnumTagItem( p, &p, &pName, &EnumValue ) != True ) { + return(False); + } + pEntry->n_value = EnumValue; + pEntry->n_type = TotalSize; + pEntry->n_sclass = C_MOE; + } + + /* Prepare Common Tag Header items */ + if ( (n = AddNameToEntry( pName, pEntry )) == 0 ) { + fprintf(stderr,"\nOut of memory adding local %s to string table", pString ); + return(False); + } + pEntry->n_scnum = N_ABS; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_tagndx = SymbolIndex; + pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; + pName = p; + } + + /* End of Structures/Unions/Enumberations */ + if ( ( pEntry = (struct syment*)AllocateTwoListObjects( &ci->ListOfGlobals, sizeof(struct syment) * 2 ) ) == 0 ) { + fprintf(stderr, "\nOut of memory allocating special headers for structure!"); + return(False); + } + strcpy( pEntry->n_name, ".eos" ); + pEntry->n_value = TotalSize; + pEntry->n_scnum = N_ABS; + pEntry->n_type = 0; + pEntry->n_sclass = C_EOS; + pEntry->n_numaux = 1; + pEntry++; /* point to aux entry */ + pAux = (union auxent *)pEntry; + pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */ + pAux->x_sym.x_misc.x_lnsz.x_size = TotalSize; + + return(True); +} + +/****************************************************************************************/ +int SetupDefinedType( unsigned short Type, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ){ + + int i, Dlimit, Dstart; + unsigned short StabType; + + StabType = pMap->StabType; /* save the new type we found earlier */ + if ( CopyStabCoffMap( Type, pMap ) != True ) { + fprintf(stderr, "\nCould not find defined type %d", Type ); + return(False); + } + pMap->StabType = StabType; /* save the new type we found earlier */ + + /* Determine existing derived types for base class */ + for ( i = 0; i < 6; i++ ) { + if ( (pMap->CoffType & ( 3 << (4 + i + i))) == 0 ) + break; + } + Dstart = i; + Dlimit = i + ExtraLevels; + if ( (Dlimit) >= 6 ) { + fprintf(stderr, "\nStab Type %d has too many derived (%d) types!", pMap->StabType, Dlimit ); + return(False); + } + /* Add the new derived levels */ + for ( ; i < Dlimit; i++ ) { + pMap->CoffType |= ( ( DerivedBits[i - Dstart] & 3) << (4 + i + i) ); /* add in the derived bits */ + } + return(True); +} + +/****************************************************************************************/ +int GetArrayDefinitions( STABCOFFMAP *pMap , char *pMinIndex, char *pMaxIndex, char *pType, unsigned short *DerivedBits, int ExtraLevels ){ + + int MinIndex, MaxIndex, Result, Size, i; + unsigned short Type; + + Result = True; + if ( (*pMinIndex != ';') || (*pMaxIndex != ';') || (*pType != ';') ) + Result = False; + /* bump the pointers to the digits */ + pMinIndex++; + if ( !isdigit(*pMinIndex) ) + Result = False; + pMaxIndex++; + if ( !isdigit(*pMaxIndex) ) + Result = False; + pType++; + if ( !isdigit(*pType) ) + Result = False; + /* Is syntax ok ? */ + if ( Result != True ) { + fprintf(stderr,"\nSyntax error on array parameters %s%s%s", pMinIndex, pMaxIndex, pType ); + return(False); + } + MinIndex = atoi(pMinIndex); + MaxIndex = atoi(pMaxIndex); + Type = (unsigned short)atoi(pType); + if ( SetupDefinedType( Type, pMap, DerivedBits, ExtraLevels ) != True ) + return( False ); + /* Now update the size based on the indicies */ + Size = (MaxIndex - MinIndex) + 1; + pMap->ByteSize *= Size; + pMap->Line = ci->CurrentSourceLine; + /* add the dimension information */ + for ( i = 5; i >= 0; i-- ) { + if ( pMap->Dimensions[i] != 0 ) { + i++; + pMap->Dimensions[i] = Size; + break; + } + } + return(True); +} + +/****************************************************************************************/ + +int GetInternalType( char *pName, STABCOFFMAP *pMap ){ + + int n, found, i; + + if ( !pName ) { + return(False); + } + + found = False; + n = strlen(pName); + /* Find out if it is a local type */ + for (i = 0; FundamentalTypes[i].pString != 0; i++) { + if ( !strncmp(pName, FundamentalTypes[i].pString, n) ) { + /* found an internal type */ + pMap->CoffType = FundamentalTypes[i].Type; + pMap->ByteSize = FundamentalTypes[i].Size; + found = True; + } + } + return(found); +} + +/****************************************************************************************/ +int GetSubRangeType( unsigned short Type, STABCOFFMAP *pMap , char *pLow, char *pHigh ){ + + int Result, i; + long High, Low; + unsigned long Test; + + Result = True; + if ( (*pLow != ';') || (*pHigh != ';') || (Type <= 0) ) + Result = False; + + /* Is syntax ok ? */ + if ( Result != True ) { + fprintf(stderr,"\nSyntax error on sub range parameters!" ); + return(False); + } + Low = atol(++pLow); + High = atol(++pHigh); + + /* Special handling of type void */ + if ( (Low == 0) && (High == 0) ) { + /* Declare type void */ + pMap->ByteSize =0; + pMap->CoffType = T_VOID; + pMap->Line = ci->CurrentSourceLine; + return(True); + } + + if ( (pMap->CoffType = GetCoffType( Type )) != 0 ) { + pMap->ByteSize = GetCoffTypeSize( Type ); + } else { + /* Try to base everything off integer */ + pMap->ByteSize = FundamentalTypes[T_INT].Size; + } + + /* Now calculate the byte size */ + if ( High == 0 ) { + pMap->ByteSize = (unsigned short)Low; /* floating point */ + } else { + if ( Low == 0 ) { + /* Unsigned */ + Test = (unsigned long)High; + } else if ( Low < 0 ) { + /* signed */ + Test = (unsigned long)High << 1; + } else { + if ( Low <= High ) + Test = (unsigned long)High; + else + Test = (unsigned long)Low; + } + if ( pMap->ByteSize == 0 ) { + fprintf(stderr,"\nType Range Error 1, need previous type %d size!", pMap->CoffType ); + return(False); + } + for ( i = 0; i < sizeof(unsigned long); i++ ) { + if ( !(Test & (0xff << (i * 8))) ) + break; + } + pMap->ByteSize = i; + } + /* Now determine the best fit based on byte size, compare against IAR Compiler */ + if ( pMap->ByteSize == 1 ) { + if ( Low < 0 ) + pMap->CoffType = T_CHAR; + else + pMap->CoffType = T_UCHAR; + } else if ( pMap->ByteSize == 2 ) { + if ( Low < 0 ) + pMap->CoffType = T_INT; + else + pMap->CoffType = T_UINT; + } else if ( pMap->ByteSize == 4 ) { + if ( Low == 0 ) + pMap->CoffType = T_FLOAT; + if ( Low < 0 ) + pMap->CoffType = T_LONG; + else + pMap->CoffType = T_ULONG; + } else { + fprintf(stderr,"\nGetSubRangeType failure - byte size %d", pMap->ByteSize ); + return(False); + } + return(True); +} + +/****************************************************************************************/ +int CopyStabCoffMap( unsigned short StabType, STABCOFFMAP *pMap ){ + + STABCOFFMAP *p; + + for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { + if ( p->StabType == StabType ) { + memcpy( pMap, p, sizeof(STABCOFFMAP) ); + return(True); + } + } + return( False ); /* Nothing found */ +} + +/****************************************************************************************/ +unsigned short GetCoffType( unsigned short StabType ){ + + STABCOFFMAP *p; + + for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { + if ( p->StabType == StabType ) + return( p->CoffType ); + } + return( 0 ); /* Nothing found */ +} + +/****************************************************************************************/ +unsigned short GetCoffTypeSize( unsigned short StabType ){ + + STABCOFFMAP *p; + + for ( p = FindFirstListObject( &ci->ListOfTypes ); p != 0; p = FindNextListObject( &ci->ListOfTypes) ) { + if ( p->StabType == StabType ) + return( p->ByteSize ); + } + return( 0 ); /* Nothing found */ +} + + +/****************************************************************************************/ +int GetDigitLength( char *p ){ + + int i; + + if ( p == 0 ) + return(0); + + for ( i = 0; (*p != 0) && ( *p >= '0' ) && ( *p <= '9' ); i++ ); + + return( i ); + +} + +/****************************************************************************************/ +int GetStringDelimiters( char *pString, char **pTokens, int MaxTokens ){ + + int i; + char *p; + + p = pString; + + if ( !p ) + return( 0 ); + + for ( i = 0; i < MaxTokens; i++ ) { + while ( True ) { + if ( (*p == ':') || (*p == ';') || (*p == '=') || (*p == ',') || (*p == '"') || (*p == 0 ) ) { + *(pTokens + i) = p; /* Remember this location */ + p++; + if ( *p == 0 ) + return( i ); + break; + } + p++; + } + } + return( i ); +} + +/****************************************************************************************/ +int IsTypeArray( unsigned short CoffType ){ + + int Result; + + Result = False; + + if ( (CoffType & (DT_ARY << 4 )) == (DT_ARY << 4 ) ) + Result = True; + if ( (CoffType & (DT_ARY << 6 )) == (DT_ARY << 6 ) ) + Result = True; + if ( (CoffType & (DT_ARY << 8 )) == (DT_ARY << 8 ) ) + Result = True; + if ( (CoffType & (DT_ARY << 10 )) == (DT_ARY << 10 ) ) + Result = True; + if ( (CoffType & (DT_ARY << 12 )) == (DT_ARY << 12 ) ) + Result = True; + if ( (CoffType & (DT_ARY << 14 )) == (DT_ARY << 14 ) ) + Result = True; + + return(Result); +} + +/****************************************************************************************/ +void AddArrayAuxInfo( union auxent *pAux, unsigned short SymbolIndex, STABCOFFMAP *pMap ){ + + int i; + + pAux->x_sym.x_tagndx = SymbolIndex; /* point to the .bf entry index */ + pAux->x_sym.x_misc.x_lnsz.x_lnno = pMap->Line; + pAux->x_sym.x_misc.x_lnsz.x_size = pMap->ByteSize; + for ( i = 0; i < 4; i++ ) + pAux->x_sym.x_fcnary.x_ary.x_dimen[i] = pMap->Dimensions[i]; +} + +/****************************************************************************************/ +int AddNameToEntry( char *pName, struct syment *pEntry ) { + + int n; + char *p; + + n = strlen( pName ); /* see if it's 8 bytes or less */ + if ( n <= 8 ) { + strncpy( pEntry->n_name, pName, 8 ); + } else { + /* point to current offset in string table */ + pEntry->n_offset = ci->ListOfStrings.TotalBytes; + /* Allocate string table entry */ + if ( (p = (char *)AllocateListObject( &ci->ListOfStrings, n + 1 )) == 0 ) { + return(0); + } + strcpy( p, pName ); + } + return(n); /* return size of string */ +} + +/****************************************************************************************/ + +char *SkipPastDigits( char *p ){ + + if ( !p ) + return(p); + if ( *p == 0 ); + return(p); + for ( p--; (*p >= '0') && (*p <= '9') && (*p != 0); p-- ); + return(p); +} + +/****************************************************************************************/ + +/****************************************************************************************/ +/****************************************************************************************/ +/* List management routines */ +/****************************************************************************************/ +/****************************************************************************************/ + +/****************************************************************************************/ + +/****************************************************************************************/ +void InitializeList( LISTNODEHEAD *pHead ){ + + pHead->Node.Next = &pHead->Node; + pHead->Node.Last = &pHead->Node; + pHead->TotalBytes = 0; + pHead->TotalItems = 0; + pHead->current = &pHead->Node; + return; +} + +/****************************************************************************************/ + +void *AllocateTwoListObjects( LISTNODEHEAD *pHead, int size ){ + + void *p; + + if ( (p = AllocateListObject( pHead, size ) ) ) + pHead->TotalItems++; /* already incremented once in addtolist */ + return( p ); +} + +/****************************************************************************************/ +void *AllocateListObject( LISTNODEHEAD *pHead, int size ){ + + void *pObject; + + LISTNODE *pNode; + + if ( (pObject = calloc( 1, size )) != 0 ) { + if ( !(pNode = AddListObject( pHead, pObject, size )) ) { + free( pObject ); + pObject = 0; + } + } + return( pObject ); +} + +/****************************************************************************************/ +LISTNODE *AddListObject(LISTNODEHEAD *pHead, void *pObject, int size ){ + + LISTNODE *pNode; + + if ( (pNode = calloc( 1, sizeof(LISTNODE) )) != 0 ) { + pNode->pObject = pObject; + pNode->Size = size; + pNode->FileNumber = ci->CurrentFileNumber; + AddNodeToList( pHead, pNode ); + } + return( pNode ); +} + +/****************************************************************************************/ +LISTNODE *AllocateListNode( void *pObject, int size ){ + + LISTNODE *pNew; + + if ( (pNew = calloc( 1, sizeof( LISTNODE ) ) ) != 0 ) { + /* Then we initialize the node */ + pNew->pObject = pObject; + pNew->Size = size; + pNew->FileNumber = ci->CurrentFileNumber; + } + return(pNew); +} + +/****************************************************************************************/ +void AddNodeToList( LISTNODEHEAD *pHead, LISTNODE *pNode ){ + + LISTNODE *p; + + p = &pHead->Node; + + pNode->Next = p->Last->Next; + p->Last->Next = pNode; + pNode->Last = p->Last; + p->Last = pNode; + + /* and update current size of data contained in the list */ + pHead->TotalBytes += pNode->Size; + pHead->TotalItems++; +} + +/****************************************************************************************/ +void RemoveNodeFromList( LISTNODEHEAD *pHead, LISTNODE *pNode ){ + + pNode->Last->Next = pNode->Next; + pNode->Next->Last = pNode->Last; + + pHead->TotalBytes -= pNode->Size; + pHead->TotalItems--; +} + + +/****************************************************************************************/ +void *FindFirstListObject( LISTNODEHEAD *pHead ){ + + if ( pHead->Node.Next == &pHead->Node ) + return(0); /* Nothing in list */ + + pHead->current = pHead->Node.Next; + return( pHead->current->pObject ); +} +/****************************************************************************************/ +void *FindNextListObject( LISTNODEHEAD *pHead ){ + + if ( pHead->current->Next == &pHead->Node ) + return( 0 ); + + pHead->current = pHead->current->Next; + + return( pHead->current->pObject ); +} +/****************************************************************************************/ + +LISTNODE *GetCurrentNode( LISTNODEHEAD *pHead ){ + + return( pHead->current ); +} + +/****************************************************************************************/ +void *GetCurrentListObject( LISTNODEHEAD *pHead ){ + + return( pHead->current->pObject ); +} + + +/****************************************************************************************/ +void *FindLastListObject( LISTNODEHEAD *pHead ){ + + if ( pHead->Node.Last == &pHead->Node ) + return(0); /* Nothing in list */ + + pHead->current = pHead->Node.Last; + return( pHead->current->pObject ); +} +/****************************************************************************************/ +void *FindNextLastListObject( LISTNODEHEAD *pHead ){ + + if ( pHead->current->Last == &pHead->Node ) + return( 0 ); + + pHead->current = pHead->current->Last; + + return( pHead->current->pObject ); +} + +/****************************************************************************************/ + +void FreeList( LISTNODEHEAD *pHead ){ + + LISTNODE *pNode; + + for ( pNode = pHead->Node.Last; pNode->Next != &pHead->Node; pNode = pHead->Node.Last ) { + + RemoveNodeFromList( pHead, pNode ); + free( pNode->pObject ); + free( pNode ); + } + pHead->TotalBytes = 0; + pHead->TotalItems = 0; + pHead->current = &pHead->Node; +} +/****************************************************************************************/ + + diff --git a/src/mkutil/avra-0.8/SOURCE/coff.h b/src/mkutil/avra-0.8/SOURCE/coff.h new file mode 100644 index 00000000..a397be81 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/coff.h @@ -0,0 +1,403 @@ +// +// coff.h - Common Object File Format (COFF) support +// +// This file was developed for the avra assembler in order to produce COFF output files +// for use with the Atmel AVR Studio. The Lean C Compiler (LCC) debugging stabs +// output was used as input to the assembler. +// +// This software has absolutely no warrantee! The money you paid for this will be +// promptly refunded if not fully satisfied. +// +// Beta release 1/20/2000 by Bob Harris +// +// This software has not been fully tested and probably has a few software deficiencies. +// Some software support may be possible by sending a problem description report to +// rth@mclean.sparta.com + +#define MAGIC_NUMBER_AVR 0xa12 + +#define N_GSYM 0x20 /* global symbol: name,,0,type,0 */ +#define N_FNAME 0x22 /* procedure name (f77 kludge): name,,0 */ +#define N_FUN 0x24 /* procedure: name,,0,linenumber,address */ +#define N_STSYM 0x26 /* static symbol: name,,0,type,address */ +#define N_LCSYM 0x28 /* .lcomm symbol: name,,0,type,address */ +#define N_MAIN 0x2a /* name of main routine : name,,0,0,0 */ +#define N_ROSYM 0x2c /* ro_data objects */ +#define N_OBJ 0x38 /* object file path or name */ +#define N_OPT 0x3c /* compiler options */ +#define N_RSYM 0x40 /* register sym: name,,0,type,register */ +#define N_SLINE 0x44 /* src line: 0,,0,linenumber,address */ +#define N_FLINE 0x4c /* function start.end */ +#define N_SSYM 0x60 /* structure elt: name,,0,type,struct_offset */ +#define N_ENDM 0x62 /* last stab emitted for module */ +#define N_SO 0x64 /* source file name: name,,0,0,address */ +#define N_LSYM 0x80 /* local sym: name,,0,type,offset */ +#define N_BINCL 0x82 /* header file: name,,0,0,0 */ +#define N_SOL 0x84 /* #included file name: name,,0,0,address */ +#define N_PSYM 0xa0 /* parameter: name,,0,type,offset */ +#define N_EINCL 0xa2 /* end of include file */ +#define N_ENTRY 0xa4 /* alternate entry: name,linenumber,address */ +#define N_LBRAC 0xc0 /* left bracket: 0,,0,nesting level,address */ +#define N_EXCL 0xc2 /* excluded include file */ +#define N_RBRAC 0xe0 /* right bracket: 0,,0,nesting level,address */ +#define N_BCOMM 0xe2 /* begin common: name,, */ +#define N_ECOMM 0xe4 /* end common: name,, */ +#define N_ECOML 0xe8 /* end common (local name): ,,address */ +#define N_LENG 0xfe /* second stab entry with length information */ + + +/* + * Type of a symbol, in low N bits of the word + */ +#define T_NULL 0 +#define T_VOID 1 /* function argument (only used by compiler) */ +#define T_CHAR 2 /* character */ +#define T_SHORT 3 /* short integer */ +#define T_INT 4 /* integer */ +#define T_LONG 5 /* long integer */ +#define T_FLOAT 6 /* floating point */ +#define T_DOUBLE 7 /* double word */ +#define T_STRUCT 8 /* structure */ +#define T_UNION 9 /* union */ +#define T_ENUM 10 /* enumeration */ +#define T_MOE 11 /* member of enumeration*/ +#define T_UCHAR 12 /* unsigned character */ +#define T_USHORT 13 /* unsigned short */ +#define T_UINT 14 /* unsigned integer */ +#define T_ULONG 15 /* unsigned long */ +#define T_LNGDBL 16 /* long double */ + +/* + * derived types, in n_type +*/ +#define DT_NON (0) /* no derived type */ +#define DT_PTR (1) /* pointer */ +#define DT_FCN (2) /* function */ +#define DT_ARY (3) /* array */ + +struct external_filehdr { + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + unsigned long f_timdat; /* time & date stamp */ + unsigned long f_symptr; /* file pointer to symtab */ + unsigned long f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ +}; + +/* Bits for f_flags: + * F_RELFLG relocation info stripped from file + * F_EXEC file is executable (no unresolved external references) + * F_LNNO line numbers stripped from file + * F_LSYMS local symbols stripped from file + * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) + */ + +#define F_RELFLG (0x0001) +#define F_EXEC (0x0002) +#define F_LNNO (0x0004) +#define F_LSYMS (0x0008) + +/*********************************************************************/ +struct external_scnhdr { + char s_name[8]; /* section name */ + unsigned long s_paddr; /* physical address, aliased s_nlib */ + unsigned long s_vaddr; /* virtual address */ + unsigned long s_size; /* section size */ + unsigned long s_scnptr; /* file ptr to raw data for section */ + unsigned long s_relptr; /* file ptr to relocation */ + unsigned long s_lnnoptr; /* file ptr to line numbers */ + unsigned short s_nreloc; /* number of relocation entries */ + unsigned short s_nlnno; /* number of line number entries*/ + unsigned long s_flags; /* flags */ +}; + +#define SCNHDR struct external_scnhdr +#define SCNHSZ sizeof(SCNHDR) + +/* + * names of "special" sections + */ +#define _TEXT ".text" +#define _DATA ".data" +#define _BSS ".bss" +#define _COMMENT ".comment" +#define _LIB ".lib" + +/* + * s_flags "type" + */ +#define STYP_TEXT (0x0020) /* section contains text only */ +#define STYP_DATA (0x0040) /* section contains data only */ +#define STYP_BSS (0x0080) /* section contains bss only */ + + +/*********************************************************************/ + +struct lineno +{ + union + { + long l_symndx; /* symtbl index of func name */ + long l_paddr; /* paddr of line number */ + } l_addr; + unsigned short l_lnno; /* line number */ +}; + +#define LINENO struct lineno +#define LINESZ 6 + + + +#define N_UNDEF ((short)0) /* undefined symbol */ +#define N_ABS ((short)-1) /* value of symbol is absolute */ +#define N_DEBUG ((short)-2) /* debugging symbol -- value is meaningless */ + +/********************** STORAGE CLASSES **********************/ + +/* This used to be defined as -1, but now n_sclass is unsigned. */ +#define C_EFCN 0xff /* physical end of function */ +#define C_NULL 0 +#define C_AUTO 1 /* automatic variable */ +#define C_EXT 2 /* external symbol */ +#define C_STAT 3 /* static */ +#define C_REG 4 /* register variable */ +#define C_EXTDEF 5 /* external definition */ +#define C_LABEL 6 /* label */ +#define C_ULABEL 7 /* undefined label */ +#define C_MOS 8 /* member of structure */ +#define C_ARG 9 /* function argument */ +#define C_STRTAG 10 /* structure tag */ +#define C_MOU 11 /* member of union */ +#define C_UNTAG 12 /* union tag */ +#define C_TPDEF 13 /* type definition */ +#define C_USTATIC 14 /* undefined static */ +#define C_ENTAG 15 /* enumeration tag */ +#define C_MOE 16 /* member of enumeration */ +#define C_REGPARM 17 /* register parameter */ +#define C_FIELD 18 /* bit field */ +#define C_AUTOARG 19 /* auto argument */ +#define C_LASTENT 20 /* dummy entry (end of block) */ +#define C_BLOCK 100 /* ".bb" or ".eb" */ +#define C_FCN 101 /* ".bf" or ".ef" */ +#define C_EOS 102 /* end of structure */ +#define C_FILE 103 /* file name */ +#define C_LINE 104 /* line # reformatted as symbol table entry */ +#define C_ALIAS 105 /* duplicate tag */ +#define C_HIDDEN 106 /* ext symbol in dmert public lib */ + +#define E_SYMNMLEN 8 /* # characters in a symbol name */ +#define E_FILNMLEN 14 /* # characters in a file name */ +#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +struct syment +{ + union + { + char _n_name[E_SYMNMLEN]; /* symbol name*/ + struct + { + long _n_zeroes; /* symbol name */ + + long _n_offset; /* location in string table */ + } _n_n; + char *_n_nptr[2]; /* allows overlaying */ + } _n; + unsigned long n_value; /* value of symbol */ + + short n_scnum; /* section number */ + + unsigned short n_type; /* type and derived */ + + char n_sclass; /* storage class */ + + char n_numaux; /* number of aux entries */ +}; + +#define n_name _n._n_name +#define n_zeroes _n._n_n._n_zeroes +#define n_offset _n._n_n._n_offset +#define n_nptr _n._n_nptr[1] + +#define SYMNMLEN 8 +#define SYMESZ 18 /* size of a symbol table entry */ + +union auxent +{ + struct + { + long x_tagndx; + union + { + struct + { + unsigned short x_lnno; + unsigned short x_size; + } x_lnsz; + long x_fsize; + } x_misc; + union + { + struct + { + long x_lnnoptr; + long x_endndx; + } x_fcn; + struct + { + unsigned short x_dimen[E_DIMNUM]; + } x_ary; + } x_fcnary; + unsigned short x_tvndx; + } x_sym; + union + { + char x_fname[E_FILNMLEN]; + struct { + unsigned long x_zeroes; + unsigned long x_offset; + } x_n; + } x_file; + struct + { + long x_scnlen; + unsigned short x_nreloc; + unsigned short x_nlinno; + } x_scn; + struct + { + long x_tvfill; + unsigned short x_tvlen; + unsigned short x_tvran[2]; + } x_tv; +}; + +#define FILNMLEN 14 +#define DIMNUM 4 +#define AUXENT union auxent +#define AUXESZ 18 + + +/* Coff additions */ +typedef struct ListNodeTag{ + struct ListNodeTag *Next; /* Double Linked List */ + struct ListNodeTag *Last; /* Double Linked List */ + void *pObject; /* points to list object */ + unsigned long Size; + int FileNumber; /* corresponds to individual file(s) */ +} LISTNODE; + +//#define LISTNODE struct ListNodeTag; + +typedef struct ListNodeHeadTag { + LISTNODE Node; +// struct ListNodeTag *Next; /* Double Linked List */ +// struct ListNodeTag *Last; /* Double Linked List */ + int TotalBytes; /* size of allocated object(s) */ + int TotalItems; /* number of allocated objects */ + LISTNODE *current; /* pointer for FindFirst/FindNext */ +} LISTNODEHEAD ; + + +typedef struct { + unsigned short StabType; + unsigned short CoffType; + unsigned short ByteSize; + unsigned short Line; /* used by arrays */ + unsigned short Dimensions[6]; /* used by arrays */ +} STABCOFFMAP; + +struct coff_info { + + int CurrentFileNumber; + int FunctionStartLine; /* used in Line number table */ + int CurrentSourceLine; + + /* Internal */ + unsigned char *pRomMemory; /* 16 bit wide words/addresses */ + unsigned char *pEEPRomMemory; /* 8 bit wide words/addresses */ + int MaxRomAddress; + int MaxEepromAddress; + int NeedLineNumberFixup; + int GlobalStartAddress; + int GlobalEndAddress; + LISTNODEHEAD ListOfSplitLines; + + /* External */ + struct external_filehdr FileHeader; /* Only one of these per output file */ + LISTNODEHEAD ListOfSectionHeaders; /* .text, .bss */ + LISTNODEHEAD ListOfRawData; /* Program, EEPROM */ + LISTNODEHEAD ListOfRelocations; /* Not used now */ + LISTNODEHEAD ListOfLineNumbers; + LISTNODEHEAD ListOfSymbols; + LISTNODEHEAD ListOfGlobals; + LISTNODEHEAD ListOfSpecials; + LISTNODEHEAD ListOfUndefined; + LISTNODEHEAD ListOfStrings; + LISTNODEHEAD ListOfTypes; +}; + +#if 0 /* defined in avra.h */ + +FILE *open_coff_file(struct prog_info *pi, char *filename); +void write_coff_file(struct prog_info *pi); +void write_coff_eeprom( struct prog_info *pi, int address, unsigned char data); +void write_coff_program( struct prog_info *pi, int address, unsigned char data); +void close_coff_file(struct prog_info *pi, FILE *fp); +int parse_stabs( struct prog_info *pi, char *p, int pass ); +int parse_stabn( struct prog_info *pi, char *p, int pass ); + +#endif + +/**************************************************************/ +/*********** Internal Routines ********************************/ +/**************************************************************/ +int stab_add_lineno( struct prog_info *pi, int LineNumber, char *pLabel, char *pFunction ); +int stab_add_lbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ); +int stab_add_rbracket( struct prog_info *pi, int Level, char *pLabel, char *pFunction ); +int stab_add_filename( char *pName, char *pLabel ); +int stab_add_function( struct prog_info *pi, char *pName, char *pLabel ); +int stab_add_global( struct prog_info *pi, char *pName, char *pType ); +int stab_add_local( struct prog_info *pi, char *pName, char *pType, char *pOffset ); +int stab_add_parameter_symbol( struct prog_info *pi, char *pName, char *pType, char *pOffset ); +int stab_add_static_symbol( struct prog_info *pi, char *pName, char *pType, char *pLabel ); +int stab_add_local_register( struct prog_info *pi, char *pName, char *pType, char *pRegister ); +int stab_add_local_type( char *pString, char *pType ); +int stab_add_tag_type( char *pName, char *pDesciptor ); + +int GetStabType( char *p, unsigned short *pType, char **pEnd ); +int AddNameToEntry( char *pName, struct syment *pEntry ); +int GetArrayType( char *p, char **pEnd, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ); +int GetEnumTagItem( char *p, char **pEnd, char **pEnumName, int *pEnumValue ); +int GetStructUnionTagItem( char *p, char **pEnd, char **pName, unsigned short *pType, unsigned short *pBitOffset, unsigned short *pBitSize); +int GetStringDelimiters( char *pString, char **pTokens, int MaxTokens ); +int SetupDefinedType( unsigned short Type, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels ); +int GetArrayDefinitions( STABCOFFMAP *pMap , char *pMinIndex, char *pMaxIndex, char *pType, unsigned short *DerivedBits, int ExtraLevels ); +int GetInternalType( char *pName, STABCOFFMAP *pMap ); +unsigned short GetCoffType( unsigned short StabType ); +unsigned short GetCoffTypeSize( unsigned short StabType ); +int CopyStabCoffMap( unsigned short StabType, STABCOFFMAP *pMap ); +int IsTypeArray( unsigned short CoffType ); +void AddArrayAuxInfo( union auxent *pAux, unsigned short SymbolIndex, STABCOFFMAP *pMap ); +int GetSubRangeType( unsigned short Type, STABCOFFMAP *pMap , char *pLow, char *pHigh ); +char *SkipPastDigits( char *p ); +int GetDigitLength( char *p ); + +/****************************************************************************************/ +/* List management routines */ +/****************************************************************************************/ + +void InitializeList( LISTNODEHEAD *pNode ); +void *AllocateTwoListObjects( LISTNODEHEAD *pHead, int size ); +void *AllocateListObject( LISTNODEHEAD *pHead, int size ); +LISTNODE *AllocateListNode( void *pObject, int size ); +void AddNodeToList( LISTNODEHEAD *pHead, LISTNODE *pNode ); +void *FindFirstListObject( LISTNODEHEAD *pHead ); +void *FindNextListObject( LISTNODEHEAD *pHead ); +LISTNODE *GetCurrentNode( LISTNODEHEAD *pHead ); +void *GetCurrentListObject( LISTNODEHEAD *pHead ); +void *FindLastListObject( LISTNODEHEAD *pHead ); +void *FindNextLastListObject( LISTNODEHEAD *pHead ); +void FreeList( LISTNODEHEAD *pHead ); +LISTNODE *AddListObject(LISTNODEHEAD *pHead, void *pObject, int size ); + diff --git a/src/mkutil/avra-0.8/SOURCE/device.c b/src/mkutil/avra-0.8/SOURCE/device.c new file mode 100644 index 00000000..206e6b9a --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/device.c @@ -0,0 +1,206 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include + +#include "misc.h" +#include "avra.h" +#include "device.h" + +#define DEV_VAR "__DEVICE__" // Device var name +#define FLASH_VAR "__FLASH_SIZE__" // Flash size var name +#define EEPROM_VAR "__EEPROM_SIZE__" // EEPROM size var name +#define RAM_VAR "__RAM_SIZE__" // RAM size var name +#define DEV_PREFIX "__" // Device name prefix +#define DEV_SUFFIX "__" // Device name suffix +#define DEF_DEV_NAME "DEFAULT" // Default device name (without prefix/suffix) +#define MAX_DEV_NAME 32 // Max device name length + +// Name, Flash, RAM, EEPROM, flags +struct device device_list[] = +{ + { NULL, 4194304, 8388608, 65536, 0}, // Total instructions: 137 + {"AT90S1200", 512+32, 0, 64, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, // 137 - MUL(6) - JMP(2) - TINY(10) + {"ATtiny10", 1024+32, 0, 0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATtiny11", 1024+32, 0, 0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATtiny12", 1024+32, 0, 64, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATtiny15", 1024+32, 0, 64, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATtiny28", 2048+32, 0, 0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATtiny22", 2048+32, 128, 128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S2313", 1024+32, 128, 128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S2323", 1024+32, 128, 128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S2333", 1024+32, 128, 128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S2343", 1024+32, 128, 128, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S4414", 2048+32, 256, 256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S4433", 2048+32, 128, 256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S4434", 2048+32, 256, 256, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S8515", 4096+32, 512, 512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90C8534", 4096+32, 256, 512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"AT90S8535", 4096+4096+32, 512, 512, DF_NO_MUL|DF_NO_JMP|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP}, + {"ATmega8", 4096+32, 1024, 512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega161", 8192+32, 1024, 512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega162", 8192+32, 1024, 512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega163", 8192+32, 1024, 512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega16", 8192+32, 1024, 512, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega323", 16384+32, 2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, // 137 - EICALL - EIJMP - ELPM(3) - ESPM = 131 (Data sheet says 130 but it's wrong) + {"ATmega32", 16384+32, 2048, 1024, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_ESPM}, + {"ATmega603", 32768+32, 4096, 2048, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_MUL|DF_NO_MOVW|DF_NO_LPM_X|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK}, + {"ATmega103", 65536+32, 4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_MUL|DF_NO_MOVW|DF_NO_LPM_X|DF_NO_ELPM_X|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK}, // 137 - EICALL - EIJMP - MUL(6) - MOVW - LPM_X(2) - ELPM_X(2) - SPM - ESPM - BREAK = 121 + {"ATmega104", 65536+32, 4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM}, // Old name for mega128 + {"ATmega128", 65536+32, 4096, 4096, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ESPM}, // 137 - EICALL - EIJMP - ESPM = 134 (Data sheet says 133 but it's wrong) + {"AT94K", 8192+32, 16384, 0, DF_NO_EICALL|DF_NO_EIJMP|DF_NO_ELPM|DF_NO_SPM|DF_NO_ESPM|DF_NO_BREAK}, // 137 - EICALL - EIJMP - ELPM(3) - SPM - ESPM - BREAK = 129 + {NULL, 0, 0, 0, 0} +}; + +static int LastDevice=0; + +static int def_var(struct prog_info *pi, char *name, int value) + { + struct label *label; + + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, name)) + { + label->value = value; + return(True); + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_variable) + pi->last_variable->next = label; + else + pi->first_variable = label; + pi->last_variable = label; + label->name = malloc(strlen(name) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, name); + label->value = value; + return(True); + } + +// Define vars for device in LastDevice +static void def_dev(struct prog_info *pi) { + def_var(pi,DEV_VAR,LastDevice); + def_var(pi,FLASH_VAR,device_list[LastDevice].flash_size); + def_var(pi,EEPROM_VAR,device_list[LastDevice].eeprom_size); + def_var(pi,RAM_VAR,device_list[LastDevice].ram_size); + } +struct device *get_device(struct prog_info *pi, char *name) + { + int i = 1; + + LastDevice=0; + if(name == NULL) + { + def_dev(pi); + return(&device_list[0]); + } + while(device_list[i].name) + { + if(!nocase_strcmp(name, device_list[i].name)) + { + LastDevice=i; + def_dev(pi); + return(&device_list[i]); + } + i++; + } + def_dev(pi); + return(NULL); + } + +static int def_const(struct prog_info *pi, const char *name, int value) + { + struct label *label; + + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_constant) + pi->last_constant->next = label; + else + pi->first_constant = label; + pi->last_constant = label; + label->name = malloc(strlen(name) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, name); + label->value = value; + return(True); + } + +// Pre-define devices +void predef_dev(struct prog_info *pi) + { + int i; + char temp[MAX_DEV_NAME+1]; + + + def_dev(pi); + for (i=0;(!i)||(device_list[i].name);i++) + { + strncpy(temp,DEV_PREFIX,MAX_DEV_NAME); + if (!i) strncat(temp,DEF_DEV_NAME,MAX_DEV_NAME); + else strncat(temp,device_list[i].name,MAX_DEV_NAME); + strncat(temp,DEV_SUFFIX,MAX_DEV_NAME); + def_const(pi,temp,i); + } + } + +void list_devices() +{ + int i = 1; + printf("Device name | Flash size | RAM size | EEPROM size | Supported\n" + " | (words) | (bytes) | (bytes) | instructions\n" + "------------+------------+----------+-------------+--------------\n" + " (default) | %7d | %7d | %5d | %3d\n", + device_list[0].flash_size, device_list[0].ram_size, device_list[0].eeprom_size, + count_supported_instructions(device_list[0].flag)); + while(device_list[i].name) + { + printf(" %-10s | %7d | %7d | %5d | %3d\n", device_list[i].name, + device_list[i].flash_size, device_list[i].ram_size, + device_list[i].eeprom_size, count_supported_instructions(device_list[i].flag)); + i++; + } +} diff --git a/src/mkutil/avra-0.8/SOURCE/device.h b/src/mkutil/avra-0.8/SOURCE/device.h new file mode 100644 index 00000000..1d627bf5 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/device.h @@ -0,0 +1,32 @@ + +/* Device flags */ +#define DF_NO_MUL 0x00000001 +#define DF_NO_JMP 0x00000002 // No JMP, CALL +#define DF_NO_XREG 0x00000004 // No X register +#define DF_NO_YREG 0x00000008 // No Y register +#define DF_TINY1X 0x00000010 /* AT90S1200, ATtiny10-12 set: No ADIW, SBIW, + IJMP, ICALL, LDD, STD, LDS, STS, PUSH, POP */ +#define DF_NO_LPM 0x00000020 // No LPM instruction +#define DF_NO_LPM_X 0x00000040 // No LPM Rd,Z or LPM Rd,Z+ instruction +#define DF_NO_ELPM 0x00000080 // No ELPM instruction +#define DF_NO_ELPM_X 0x00000100 // No ELPM Rd,Z or LPM Rd,Z+ instruction +#define DF_NO_SPM 0x00000200 // No SPM instruction +#define DF_NO_ESPM 0x00000400 // No ESPM instruction +#define DF_NO_MOVW 0x00000800 // No MOVW instruction +#define DF_NO_BREAK 0x00001000 // No BREAK instruction +#define DF_NO_EICALL 0x00002000 // No EICALL instruction +#define DF_NO_EIJMP 0x00004000 // No EIJMP instruction + +struct device + { + char *name; + int flash_size; + int ram_size; + int eeprom_size; + int flag; + }; + +/* device.c */ +struct device *get_device(struct prog_info *pi,char *name); +void predef_dev(struct prog_info *pi); +void list_devices(); diff --git a/src/mkutil/avra-0.8/SOURCE/directiv.c b/src/mkutil/avra-0.8/SOURCE/directiv.c new file mode 100644 index 00000000..5f27dd4f --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/directiv.c @@ -0,0 +1,824 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "args.h" +#include "avra.h" +#include "device.h" + +enum + { + DIRECTIVE_BYTE = 0, + DIRECTIVE_CSEG, + DIRECTIVE_CSEGSIZE, + DIRECTIVE_DB, + DIRECTIVE_DEF, + DIRECTIVE_DEVICE, + DIRECTIVE_DSEG, + DIRECTIVE_DW, + DIRECTIVE_ENDM, + DIRECTIVE_ENDMACRO, + DIRECTIVE_EQU, + DIRECTIVE_ESEG, + DIRECTIVE_EXIT, + DIRECTIVE_INCLUDE, + DIRECTIVE_LIST, + DIRECTIVE_LISTMAC, + DIRECTIVE_MACRO, + DIRECTIVE_NOLIST, + DIRECTIVE_ORG, + DIRECTIVE_SET, + DIRECTIVE_DEFINE, + DIRECTIVE_UNDEF, + DIRECTIVE_IFDEF, + DIRECTIVE_IFNDEF, + DIRECTIVE_IF, + DIRECTIVE_ELSE, + DIRECTIVE_ELIF, + DIRECTIVE_ENDIF, + DIRECTIVE_MESSAGE, + DIRECTIVE_WARNING, + DIRECTIVE_ERROR, + DIRECTIVE_COUNT + }; + +char *directive_list[] = + { + "BYTE", + "CSEG", + "CSEGSIZE", + "DB", + "DEF", + "DEVICE", + "DSEG", + "DW", + "ENDM", + "ENDMACRO", + "EQU", + "ESEG", + "EXIT", + "INCLUDE", + "LIST", + "LISTMAC", + "MACRO", + "NOLIST", + "ORG", + "SET", + "DEFINE", + "UNDEF", + "IFDEF", + "IFNDEF", + "IF", + "ELSE", + "ELIF", + "ENDIF", + "MESSAGE", + "WARNING", + "ERROR" + }; + + +int parse_directive(struct prog_info *pi, int pass) + { + int directive, ok = True, i; + char *next, *data; + struct file_info *fi_bak; + struct label *label; + struct def *def; + struct data_list *includedir; + + next = get_next_token(pi->fi->scratch, TERM_SPACE); + for(i = 0; pi->fi->scratch[i] != '\0'; i++) + pi->fi->scratch[i] = toupper(pi->fi->scratch[i]); + directive = get_directive_type(pi->fi->scratch + 1); + if(directive == -1) + { + print_msg(pi, MSGTYPE_ERROR, "Unknown directive: %s", pi->fi->scratch); + return(True); + } + switch(directive) + { + case DIRECTIVE_BYTE: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".BYTE needs an operand"); + return(True); + } + if(pi->segment != SEGMENT_DATA) + print_msg(pi, MSGTYPE_ERROR, ".BYTE directive can only be used in data segment (.DSEG)"); + get_next_token(next, TERM_END); + if(!get_expr(pi, next, &i)) + return(False); + if((pass == PASS_2) && pi->list_line && pi->list_on) + { + fprintf(pi->list_file, "%06x %s", pi->dseg_addr, pi->list_line); + pi->list_line = NULL; + } + pi->dseg_addr += i; + if(pass == PASS_1) + pi->dseg_count += i; + break; + case DIRECTIVE_CSEG: + pi->segment = SEGMENT_CODE; + break; + case DIRECTIVE_CSEGSIZE: + break; + case DIRECTIVE_DB: + return(parse_db(pi, next, pass)); + break; + case DIRECTIVE_DEF: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".DEF needs an operand"); + return(True); + } + data = get_next_token(next, TERM_EQUAL); + if(!(data && (tolower(data[0]) == 'r') && isdigit(data[1]))) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs a register (e.g. .def BZZZT = r16)", next); + return(True); + } + i = atoi(&data[1]); + if(i > 31) + print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", i); + for(def = pi->first_def; def; def = def->next) + if(!nocase_strcmp(def->name, next)) + { + def->reg = i; + return(True); + } + def = malloc(sizeof(struct def)); + if(!def) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + def->next = NULL; + if(pi->last_def) + pi->last_def->next = def; + else + pi->first_def = def; + pi->last_def = def; + def->name = malloc(strlen(next) + 1); + if(!def->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(def->name, next); + def->reg = i; + break; + case DIRECTIVE_DEVICE: + if(pass == PASS_2) + return(True); + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".DEVICE needs an operand"); + return(True); + } + get_next_token(next, TERM_END); + pi->device = get_device(pi,next); + if(!pi->device) + print_msg(pi, MSGTYPE_ERROR, "Unknown device: %s", next); + break; + case DIRECTIVE_DSEG: + pi->segment = SEGMENT_DATA; + break; + case DIRECTIVE_DW: + if(pi->segment == SEGMENT_DATA) + { + print_msg(pi, MSGTYPE_ERROR, "Can't use .DW directive in data segment (.DSEG)"); + return(True); + } + while(next) + { + data = get_next_token(next, TERM_COMMA); + if(pass == PASS_2) + { + if(!get_expr(pi, next, &i)) + return(False); + if((i < -32768) || (i > 65535)) + print_msg(pi, MSGTYPE_WARNING, "Value %d is out of range (-32768 <= k <= 65535). Will be masked", i); + } + if(pi->segment == SEGMENT_EEPROM) + { + if(pass == PASS_2) + { + write_ee_byte(pi, pi->eseg_addr, (unsigned char)i); + write_ee_byte(pi, pi->eseg_addr + 1, (unsigned char)(i >> 8)); + } + pi->eseg_addr += 2; + if(pass == PASS_1) + pi->eseg_count += 2; + } + else + { + if((pass == PASS_2) && pi->hfi) + write_prog_word(pi, pi->cseg_addr, i); + pi->cseg_addr++; + if(pass == PASS_1) + pi->cseg_count++; + } + next = data; + } + break; + case DIRECTIVE_ENDM: + case DIRECTIVE_ENDMACRO: + print_msg(pi, MSGTYPE_ERROR, "No .MACRO found before .ENDMACRO"); + break; + case DIRECTIVE_EQU: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".EQU needs an operand"); + return(True); + } + data = get_next_token(next, TERM_EQUAL); + if(!data) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .EQU BZZZT = 0x2a)", next); + return(True); + } + get_next_token(data, TERM_END); + if(!get_expr(pi, data, &i)) + return(False); + for(label = pi->first_label; label; label = label->next) + { + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next); + return(True); + } + } + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .SET variable", next); + return(True); + } + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "Can't redefine constant %s, use .SET instead", next); + return(True); + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_constant) + pi->last_constant->next = label; + else + pi->first_constant = label; + pi->last_constant = label; + label->name = malloc(strlen(next) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, next); + label->value = i; + break; + case DIRECTIVE_ESEG: + pi->segment = SEGMENT_EEPROM; + break; + case DIRECTIVE_EXIT: + pi->fi->exit_file = True; + break; + case DIRECTIVE_INCLUDE: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, "Nothing to include"); + return(True); + } + next = term_string(pi, next); + if((pass == PASS_2) && pi->list_line && pi->list_on) + { + fprintf(pi->list_file, " %s", pi->list_line); + pi->list_line = NULL; + } + // Test if include is in local directory + ok = test_include(next); + data = NULL; + if(!ok) + for(includedir = GET_ARG(pi->args, ARG_INCLUDEDIR); includedir && !ok; includedir = includedir->next) + { + i = strlen(includedir->data); + if(data) + free(data); + data = malloc(i + strlen(next) + 2); + if(!data) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(data, includedir->data); + if((data[i - 1] != '\\') && (data[i - 1] != '/')) + data[i++] = '/'; + strcpy(&data[i], next); + ok = test_include(data); + } + if(ok) + { + fi_bak = pi->fi; + ok = parse_file(pi, data ? data : next, pass); + pi->fi = fi_bak; + } + else + print_msg(pi, MSGTYPE_ERROR, "cannot find include file"); + if(data) + free(data); + break; + case DIRECTIVE_LIST: + if(pass == PASS_2) + pi->list_on = True; + break; + case DIRECTIVE_LISTMAC: + if(pass == PASS_2) + SET_ARG(pi->args, ARG_LISTMAC, True); + break; + case DIRECTIVE_MACRO: + return(read_macro(pi, next, pass)); + break; + case DIRECTIVE_NOLIST: + if(pass == PASS_2) + pi->list_on = False; + break; + case DIRECTIVE_ORG: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".ORG needs an operand"); + return(True); + } + get_next_token(next, TERM_END); + if(!get_expr(pi, next, &i)) + return(False); + switch(pi->segment) + { + case SEGMENT_CODE: + pi->cseg_addr = i; + break; + case SEGMENT_DATA: + pi->dseg_addr = i; + break; + case SEGMENT_EEPROM: + pi->eseg_addr = i; + } + if(pi->fi->label) + pi->fi->label->value = i; + break; + case DIRECTIVE_SET: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".SET needs an operand"); + return(True); + } + data = get_next_token(next, TERM_EQUAL); + if(!data) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .SET BZZZT = 0x2a)", next); + return(True); + } + get_next_token(data, TERM_END); + if(!get_expr(pi, data, &i)) + return(False); + for(label = pi->first_label; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next); + return(True); + } + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .EQU constant", next); + return(True); + } + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + label->value = i; + return(True); + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_variable) + pi->last_variable->next = label; + else + pi->first_variable = label; + pi->last_variable = label; + label->name = malloc(strlen(next) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, next); + label->value = i; + break; + case DIRECTIVE_DEFINE: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".DEFINE needs an operand"); + return(True); + } + data = get_next_token(next, TERM_SPACE); + if(data) + { + get_next_token(data, TERM_END); + if(!get_expr(pi, data, &i)) + return(False); + } + else + i = 1; + for(label = pi->first_label; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next); + return(True); + } + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .SET variable", next); + return(True); + } + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, next)) + { + print_msg(pi, MSGTYPE_ERROR, "Can't redefine constant %s, use .SET instead", next); + return(True); + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + if(pi->last_constant) + pi->last_constant->next = label; + else + pi->first_constant = label; + pi->last_constant = label; + label->name = malloc(strlen(next) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, next); + label->value = i; + break; + case DIRECTIVE_UNDEF: // TODO + break; + case DIRECTIVE_IFDEF: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".IFDEF needs an operand"); + return(True); + } + get_next_token(next, TERM_END); + if(get_symbol(pi, next, NULL)) + pi->conditional_depth++; + else + { + if(!spool_conditional(pi, False)) + return(False); + } + break; + case DIRECTIVE_IFNDEF: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".IFNDEF needs an operand"); + return(True); + } + get_next_token(next, TERM_END); + if(get_symbol(pi, next, NULL)) + { + if(!spool_conditional(pi, False)) + return(False); + } + else + pi->conditional_depth++; + break; + case DIRECTIVE_IF: + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".IF needs an expression"); + return(True); + } + get_next_token(next, TERM_END); + if(!get_expr(pi, next, &i)) + return(False); + if(i) + pi->conditional_depth++; + else + { + if(!spool_conditional(pi, False)) + return(False); + } + break; + case DIRECTIVE_ELSE: + case DIRECTIVE_ELIF: + if(!spool_conditional(pi, True)) + return(False); + break; + case DIRECTIVE_ENDIF: + if(pi->conditional_depth == 0) + print_msg(pi, MSGTYPE_ERROR, "Too many .ENDIF"); + else + pi->conditional_depth--; + break; + case DIRECTIVE_MESSAGE: + if(pass == PASS_1) + return(True); + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, "No message string supplied"); + return(True); + } + next = term_string(pi, next); + print_msg(pi, MSGTYPE_MESSAGE, next); + break; + case DIRECTIVE_WARNING: + if(pass == PASS_1) + return(True); + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, "No warning string supplied"); + return(True); + } + next = term_string(pi, next); + print_msg(pi, MSGTYPE_WARNING, next); + break; + case DIRECTIVE_ERROR: + if(pass == PASS_1) + return(True); + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, "No error string supplied"); + return(True); + } + next = term_string(pi, next); + print_msg(pi, MSGTYPE_ERROR, next); + break; + } + return(ok); + } + + +int get_directive_type(char *directive) + { + int i; + + for(i = 0; i < DIRECTIVE_COUNT; i++) + if(!strcmp(directive, directive_list[i])) return(i); + return(-1); + } + + +char *term_string(struct prog_info *pi, char *string) + { + int i; + + if(string[0] != '\"') + print_msg(pi, MSGTYPE_ERROR, "String must be enclosed in \"-signs"); + else + string++; + for(i = 0; (string[i] != '\"') && !((string[i] == 10) || (string[i] == 13) || (string[i] == '\0')); i++); + if((string[i] == 10) || (string[i] == 13) || (string[i] == '\0')) + print_msg(pi, MSGTYPE_ERROR, "String is missing a closing \"-sign"); + string[i] = '\0'; + return(string); + } + + +int parse_db(struct prog_info *pi, char *next, int pass) + { + int i, count; + char *data, prev; + + if(pi->segment == SEGMENT_DATA) + { + print_msg(pi, MSGTYPE_ERROR, "Can't use .DB directive in data segment (.DSEG)"); + return(True); + } + count = 0; + while(next) + { + data = get_next_token(next, TERM_COMMA); + if(next[0] == '\"') + { + next = term_string(pi, next); + while(*next != '\0') + { + count++; + write_db(pi, *next, &prev, count, pass); + next++; + } + } + else + { + if(pass == PASS_2) + { + if(!get_expr(pi, next, &i)) + return(False); + if((i < -128) || (i > 255)) + print_msg(pi, MSGTYPE_WARNING, "Value %d is out of range (-128 <= k <= 255). Will be masked", i); + } + count++; + write_db(pi, (char)i, &prev, count, pass); + } + next = data; + } + if(pi->segment == SEGMENT_CODE) + { + if((count % 2) == 1) + { + if(pass == PASS_2) + { + write_prog_word(pi, pi->cseg_addr, prev & 0xff); + print_msg(pi, MSGTYPE_WARNING, "A .DB segment with an odd number of bytes is detected. A zero byte is added."); + } + pi->cseg_addr++; + if(pass == PASS_1) + pi->cseg_count++; + } + } + return(True); + } + + +void write_db(struct prog_info *pi, char byte, char *prev, int count, int pass) + { + if(pi->segment == SEGMENT_EEPROM) + { + if(pass == PASS_2) + write_ee_byte(pi, pi->eseg_addr, byte); + pi->eseg_addr++; + if(pass == PASS_1) + pi->eseg_count++; + } + else /* pi->segment == SEGMENT_CODE */ + { + if((count % 2) == 0) + { + if(pass == PASS_2) + write_prog_word(pi, pi->cseg_addr, (byte << 8) | (*prev & 0xff)); + pi->cseg_addr++; + if(pass == PASS_1) + pi->cseg_count++; + } + else + *prev = byte; + } + } + + +int spool_conditional(struct prog_info *pi, int only_endif) + { + int current_depth = 0, do_next; + + if(pi->macro_line) + { + while((pi->macro_line = pi->macro_line->next)) + { + pi->macro_call->line_index++; + if(check_conditional(pi, pi->macro_line->line, ¤t_depth, &do_next, only_endif)) + { + if(!do_next) + return(True); + } + else + return(False); + } + print_msg(pi, MSGTYPE_ERROR, "Found no closing .ENDIF in macro"); + } + else + { + while(fgets(pi->fi->buff, LINEBUFFER_LENGTH, pi->fi->fp)) + { + pi->fi->line_number++; + if(check_conditional(pi, pi->fi->buff, ¤t_depth, &do_next, only_endif)) + { + if(!do_next) + return(True); + } + else + return(False); + } + if(feof(pi->fi->fp)) + { + print_msg(pi, MSGTYPE_ERROR, "Found no closing .ENDIF"); + return(True); + } + else + { + perror(pi->fi->include_file->name); + return(False); + } + } + return(True); + } + + +int check_conditional(struct prog_info *pi, char *buff, int *current_depth, int *do_next, int only_endif) + { + int i = 0; + char *next; + + *do_next = False; + while(IS_HOR_SPACE(buff[i]) && !IS_END(buff[i])) i++; + if(buff[i] == '.') + { + i++; + if(!nocase_strncmp(&buff[i], "if", 2)) + (*current_depth)++; + else if(!nocase_strncmp(&buff[i], "endif", 5)) + { + if(*current_depth == 0) + return(True); + (*current_depth)--; + } + else if(!only_endif && (*current_depth == 0)) + { + if(!nocase_strncmp(&buff[i], "else", 4)) + { + pi->conditional_depth++; + return(True); + } + else if(!nocase_strncmp(&buff[i], "elif", 4)) + { + next = get_next_token(&buff[i], TERM_SPACE); + if(!next) + { + print_msg(pi, MSGTYPE_ERROR, ".ELIF needs an operand"); + return(True); + } + get_next_token(next, TERM_END); + if(!get_expr(pi, next, &i)) + return(False); + if(i) + pi->conditional_depth++; + else + { + if(!spool_conditional(pi, False)) + return(False); + } + return(True); + } + } + } + *do_next = True; + return(True); + } + +int test_include(const char *filename) +{ + FILE *fp; + fp = fopen(filename, "r"); + if(fp) + { + fclose(fp); + return(True); + } + else + return(False); +} diff --git a/src/mkutil/avra-0.8/SOURCE/expr.c b/src/mkutil/avra-0.8/SOURCE/expr.c new file mode 100644 index 00000000..67a75a32 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/expr.c @@ -0,0 +1,608 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "avra.h" +#include "device.h" + +#define IS_UNARY(x) ((x == '!') || (x == '-') || (x == '~')) +#define IS_OPERATOR(x) ((x == '+') || (x == '-') || (x == '*') || (x == '/') || (x == '%') || (x == '<') || (x == '>') || (x == '=') || (x == '!') || (x == '&') || (x == '^') || (x == '|')) +#define IS_2ND_OPERATOR(x) ((x == '<') || (x == '>') || (x == '=') || (x == '&') || (x == '|')) + +enum + { + OPERATOR_ERROR = 0, + OPERATOR_MUL, + OPERATOR_DIV, + OPERATOR_MOD, + OPERATOR_ADD, + OPERATOR_SUB, + OPERATOR_SHIFT_LEFT, + OPERATOR_SHIFT_RIGHT, + OPERATOR_LESS_THAN, + OPERATOR_LESS_OR_EQUAL, + OPERATOR_GREATER_THAN, + OPERATOR_GREATER_OR_EQUAL, + OPERATOR_EQUAL, + OPERATOR_NOT_EQUAL, + OPERATOR_BITWISE_AND, + OPERATOR_BITWISE_XOR, + OPERATOR_BITWISE_OR, + OPERATOR_LOGICAL_AND, + OPERATOR_LOGICAL_OR + }; + +enum + { + FUNCTION_LOW = 0, + FUNCTION_HIGH, + FUNCTION_BYTE2, + FUNCTION_BYTE3, + FUNCTION_BYTE4, + FUNCTION_LWRD, + FUNCTION_HWRD, + FUNCTION_PAGE, + FUNCTION_EXP2, + FUNCTION_LOG2, + FUNCTION_COUNT + }; + +struct element + { + struct element *next; + int data; + }; + +char *function_list[] = + { + "low(", + "high(", + "byte2(", + "byte3(", + "byte4(", + "lwrd(", + "hwrd(", + "page(", + "exp2(", + "log2(" + }; + +int get_expr(struct prog_info *pi, char *data, int *value) + { + int ok = True, end = False, i, count, first_flag, length, function; + char unary, *label; + struct element *element, *first_element = NULL, *temp_element; + struct element **last_element = &first_element; + + for(i = 0, count = 0, first_flag = True, unary = 0; ; i++) + { + if(IS_HOR_SPACE(data[i])); + else if(IS_END(data[i])) + { + if((count % 2) != 1) + print_msg(pi, MSGTYPE_ERROR, "Missing value in expression"); + else + end = True; + break; + } + else if(first_flag && IS_UNARY(data[i])) + { + unary = data[i]; + first_flag = False; + } + else if((count % 2) == 1) + { + if(!IS_OPERATOR(data[i])) + { + print_msg(pi, MSGTYPE_ERROR, "Illegal operator '%c'", data[i]); + break; + } + element = malloc(sizeof(struct element)); + if(!element) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + ok = False; + break; + } + element->next = NULL; + element->data = get_operator(&data[i]); + if(element->data == OPERATOR_ERROR) + { + if(IS_2ND_OPERATOR(data[i + 1])) + print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c%c", data[i], data[i + 1]); + else + print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c", data[i]); + break; + } + *last_element = element; + last_element = &element->next; + if(IS_2ND_OPERATOR(data[i + 1])) + i++; + count++; + first_flag = True; + unary = 0; + } + else + { + element = malloc(sizeof(struct element)); + if(!element) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + ok = False; + break; + } + element->next = NULL; + length = 0; + if(isdigit(data[i])) + { + if(tolower(data[i + 1]) == 'x') + { + i += 2; + while(isxdigit(data[i + length])) length++; // TODO: Sjekk overflow + element->data = atox_n(&data[i], length); + } + else if(tolower(data[i + 1]) == 'b') + { + i += 2; + element->data = 0; + while((data[i + length] == '1') || (data[i + length] == '0')) + { + element->data <<= 1; + element->data |= data[i + length++] - '0'; // TODO: Sjekk overflow + } + } + else + { + while(isdigit(data[i + length])) length++; + element->data = atoi_n(&data[i], length); // TODO: Sjekk overflow + } + } + else if(data[i] == '$') + { + i++; + while(isxdigit(data[i + length])) length++; + element->data = atox_n(&data[i], length); // TODO: Sjekk overflow + } + else if(data[i] == '\'') + { + i++; + element->data = data[i]; // TODO: Sjekk for siste ' + length = 2; + } + else if(data[i] == '(') + { + i++; + length = par_length(&data[i]); + if(length == -1) + { + print_msg(pi, MSGTYPE_ERROR, "Missing ')'"); + break; + } + data[i + length++] = '\0'; + ok = get_expr(pi, &data[i], &element->data); + if(!ok) + break; + } + else if(-1 != (function = get_function(&data[i]))) + { + while(data[i] != '(') i++; + i++; + length = par_length(&data[i]); + if(length == -1) + { + print_msg(pi, MSGTYPE_ERROR, "Missing ')'"); + break; + } + data[i + length++] = '\0'; + ok = get_expr(pi, &data[i], &element->data); + if(!ok) + break; + element->data = do_function(function, element->data); + } + else if(!nocase_strncmp(&data[i], "defined(", 8)) + { + i += 8; + length = par_length(&data[i]); + if(length == -1) + { + print_msg(pi, MSGTYPE_ERROR, "Missing ')'"); + break; + } + data[i + length++] = '\0'; + if(get_symbol(pi, &data[i], NULL)) + element->data = 1; + else + element->data = 0; + } + else if(!nocase_strncmp(&data[i], "supported(", 10)) + { + i += 10; + length = par_length(&data[i]); + if(length == -1) + { + print_msg(pi, MSGTYPE_ERROR, "Missing ')'"); + break; + } + data[i + length++] = '\0'; + element->data=is_supported(pi, &data[i]); + if (element->data<0) + { + if (toupper(data[i])=='X') + { + if (pi->device->flag&DF_NO_XREG) element->data = 0; + else element->data = 1; + } + else if (toupper(data[i])=='Y') + { + if (pi->device->flag&DF_NO_YREG) element->data = 0; + else element->data = 1; + } + else if (toupper(data[i])=='Z') + element->data = 1; + else + { + print_msg(pi, MSGTYPE_ERROR, "Unknown mnemonic: %s",&data[i]); + element->data = 0; + } + } + } + else + { + while(IS_LABEL(data[i + length])) length++; + if((length == 2) && !nocase_strncmp(&data[i], "PC", 2)) + element->data = pi->cseg_addr; + else + { + label = malloc(length + 1); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + ok = False; + break; + } + strncpy(label, &data[i], length); + label[length] = '\0'; + if(get_symbol(pi, label, &element->data)) + free(label); + else + { + print_msg(pi, MSGTYPE_ERROR, "Found no label/variable/constant named %s", label); + free(label); + break; + } + } + } + i += length - 1; + switch(unary) // TODO: Få den til å takle flere unary på rad. + { + case '-': + element->data = -element->data; + break; + case '!': + element->data = !element->data; + break; + case '~': + element->data = ~element->data; + } + *last_element = element; + last_element = &element->next; + count++; + first_flag = False; + } + } + if(end) + { + for(i = 13; (i >= 4) && (count != 1); i--) + { + for(element = first_element; element->next;) + { + if(test_operator_at_precedence(element->next->data, i)) // TODO: Vurder en hi_i for kjapphet + { + element->data = calc(pi, element->data, element->next->data, element->next->next->data); + temp_element = element->next->next->next; + free(element->next->next); + free(element->next); + count -= 2; + element->next = temp_element; + } + else + element = element->next->next; + } + } + *value = first_element->data; + } + for(element = first_element; element;) + { + temp_element = element; + element = element->next; + free(temp_element); + } + return(ok); + } + + +int get_operator(char *op) + { + switch(op[0]) + { + case '*': + return(OPERATOR_MUL); + case '/': + return(OPERATOR_DIV); + case '%': + return(OPERATOR_MOD); + case '+': + return(OPERATOR_ADD); + case '-': + return(OPERATOR_SUB); + case '<': + switch(op[1]) + { + case '<': + return(OPERATOR_SHIFT_LEFT); + case '=': + return(OPERATOR_LESS_OR_EQUAL); + default: + return(OPERATOR_LESS_THAN); + } + case '>': + switch(op[1]) + { + case '>': + return(OPERATOR_SHIFT_RIGHT); + case '=': + return(OPERATOR_GREATER_OR_EQUAL); + default: + return(OPERATOR_GREATER_THAN); + } + case '=': + if(op[1] == '=') + return(OPERATOR_EQUAL); + case '!': + if(op[1] == '=') + return(OPERATOR_NOT_EQUAL); + case '&': + if(op[1] == '&') + return(OPERATOR_LOGICAL_AND); + else + return(OPERATOR_BITWISE_AND); + case '^': + return(OPERATOR_BITWISE_XOR); + case '|': + if(op[1] == '|') + return(OPERATOR_LOGICAL_OR); + else + return(OPERATOR_BITWISE_OR); + } + return(OPERATOR_ERROR); + } + + +int test_operator_at_precedence(int operator, int precedence) + { + switch(precedence) + { + case 13: + return((operator == OPERATOR_MUL) || (operator == OPERATOR_DIV) + || (operator == OPERATOR_MOD)); + case 12: + return((operator == OPERATOR_ADD) || (operator == OPERATOR_SUB)); + case 11: + return((operator == OPERATOR_SHIFT_LEFT) || (operator == OPERATOR_SHIFT_RIGHT)); + case 10: + return((operator == OPERATOR_LESS_THAN) || (operator == OPERATOR_LESS_OR_EQUAL) + || (operator == OPERATOR_GREATER_THAN) || (operator == OPERATOR_GREATER_OR_EQUAL)); + case 9: + return((operator == OPERATOR_EQUAL) || (operator == OPERATOR_NOT_EQUAL)); + case 8: + return(operator == OPERATOR_BITWISE_AND); + case 7: + return(operator == OPERATOR_BITWISE_XOR); + case 6: + return(operator == OPERATOR_BITWISE_OR); + case 5: + return(operator == OPERATOR_LOGICAL_AND); + default: /* Makes the compiler shut up */ + case 4: + return(operator == OPERATOR_LOGICAL_OR); + } + } + + +int calc(struct prog_info *pi, int left, int operator, int right) // TODO: Sjekk litt resultater + { + switch(operator) + { + case OPERATOR_MUL: + return(left * right); + case OPERATOR_DIV: + if(right == 0) + { + print_msg(pi, MSGTYPE_ERROR, "Division by zero"); + return(0); + } + return(left / right); + case OPERATOR_MOD: + if(right == 0) + { + print_msg(pi, MSGTYPE_ERROR, "Division by zero (modulus operator)"); + return(0); + } + return(left % right); + case OPERATOR_ADD: + return(left + right); + case OPERATOR_SUB: + return(left - right); + case OPERATOR_SHIFT_LEFT: + return(left << right); + case OPERATOR_SHIFT_RIGHT: + return(left >> right); + case OPERATOR_LESS_THAN: + return(left < right); + case OPERATOR_LESS_OR_EQUAL: + return(left <= right); + case OPERATOR_GREATER_THAN: + return(left > right); + case OPERATOR_GREATER_OR_EQUAL: + return(left >= right); + case OPERATOR_EQUAL: + return(left == right); + case OPERATOR_NOT_EQUAL: + return(left != right); + case OPERATOR_BITWISE_AND: + return(left & right); + case OPERATOR_BITWISE_XOR: + return(left ^ right); + case OPERATOR_BITWISE_OR: + return(left | right); + case OPERATOR_LOGICAL_AND: + return(left && right); + default: /* Make the compiler shut up */ + case OPERATOR_LOGICAL_OR: + return(left || right); + } + } + + +int get_function(char *function) + { + int i; + + for(i = 0; i < FUNCTION_COUNT; i++) + if(!nocase_strncmp(function, function_list[i], strlen(function_list[i]))) return(i); + return(-1); + } + + +int do_function(int function, int value) + { + switch(function) + { + case FUNCTION_LOW: + return(value & 0xff); + case FUNCTION_HIGH: + case FUNCTION_BYTE2: + return((value >> 8) & 0xff); + case FUNCTION_BYTE3: + return((value >> 16) & 0xff); + case FUNCTION_BYTE4: + return((value >> 24) & 0xff); + case FUNCTION_LWRD: + return(value & 0xffff); + case FUNCTION_HWRD: + return((value >> 16) & 0xffff); + case FUNCTION_PAGE: + return((value >> 16) & 0xff); + case FUNCTION_EXP2: + return(1 << value); + case FUNCTION_LOG2: + return(log2(value)); + default: + return(0); + } + } + + +int log2(int value) + { + int i = 0; + + while(value >>= 1) i++; + return(i); + } + + +int get_symbol(struct prog_info *pi, char *label_name, int *data) + { + struct label *label; + struct macro_call *macro_call; + + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, label_name)) + { + if(data) + *data = label->value; + return(True); + } + + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, label_name)) + { + if(data) + *data = label->value; + return(True); + } + + for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) + { + for(label = pi->macro_call->first_label; label; label = label->next) + if(!nocase_strcmp(label->name, label_name)) + { + if(data) + *data = label->value; + return(True); + } + } + + for(label = pi->first_label; label; label = label->next) + if(!nocase_strcmp(label->name, label_name)) + { + if(data) + *data = label->value; + return(True); + } + + return(False); + } + + +int par_length(char *data) + { + int i = 0, b_count = 1; + + for(;;) + { + if(data[i] == ')') + { + b_count--; + if(!b_count) + return(i); + } + else if(data[i] == '(') + b_count++; + else if(data[i] == '\0') + return(-1); + i++; + } + } + + + diff --git a/src/mkutil/avra-0.8/SOURCE/file.c b/src/mkutil/avra-0.8/SOURCE/file.c new file mode 100644 index 00000000..a14654d2 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/file.c @@ -0,0 +1,272 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "avra.h" +#include "args.h" + + +int open_out_files(struct prog_info *pi, char *filename) + { + int length; + char *buff; + time_t tp; + int ok; /* flag for coff results */ + + length = strlen(filename); + buff = malloc(length + 9); + if(buff) + { + strcpy(buff, filename); + if(length >= 4) + if(!nocase_strcmp(&buff[length - 4], ".asm")) + { + length -= 4; + buff[length] = '\0'; + } + strcpy(&buff[length], ".list"); + pi->list_file = fopen(buff, "w"); + if(pi->cseg_count) + { + strcpy(&buff[length], ".hex"); + pi->hfi = open_hex_file(buff); + strcpy(&buff[length], ".obj"); + pi->obj_file = open_obj_file(pi, buff); + } + if(pi->eseg_count) + { + strcpy(&buff[length], ".eep.hex"); + pi->eep_hfi = open_hex_file(buff); + } + + if(GET_ARG(pi->args, ARG_COFF)){ + strcpy(&buff[length], ".cof"); + pi->coff_file = open_coff_file(pi, buff); + if( pi->coff_file ) + ok = True; + else + ok = False; + } + else{ + pi->coff_file = 0; + ok = True; + } + + free(buff); + + if(pi->list_file && pi->obj_file && (!pi->cseg_count || pi->hfi) && (!pi->eseg_count || pi->eep_hfi) && ok) + { + if(time(&tp) != -1) + fprintf(pi->list_file, "\navra ver. %d.%d %s %s\n\n", VERSION, REVISION, filename, ctime(&tp)); + return(True); + } + else + close_out_files(pi); + } + else + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + + +void close_out_files(struct prog_info *pi) + { + if(pi->error_count == 0) + { + printf("Segment usage:\n" + " Code : %7d words (%d bytes)\n" + " Data : %7d bytes\n" + " EEPROM : %7d bytes\n", + pi->cseg_count, pi->cseg_count * 2, pi->dseg_count, pi->eseg_count); + } + if(pi->hfi) close_hex_file(pi->hfi); + if(pi->eep_hfi) close_hex_file(pi->eep_hfi); + if(pi->list_file) + { + if(pi->error_count == 0) + fprintf(pi->list_file, "\nAssembly completed with no errors.\n"); + fclose(pi->list_file); + } + if(pi->obj_file) close_obj_file(pi, pi->obj_file); + if(pi->coff_file) close_coff_file(pi, pi->coff_file); + } + + +struct hex_file_info *open_hex_file(char *filename) + { + struct hex_file_info *hfi; + + hfi = calloc(1, sizeof(struct hex_file_info)); + if(hfi) + { + hfi->segment = -1; + hfi->fp = fopen(filename, "wb"); + if(!hfi->fp) + { + close_hex_file(hfi); + hfi = NULL; + } + } + return(hfi); + } + + +void close_hex_file(struct hex_file_info *hfi) + { + if(hfi->fp) + { + if(hfi->count != 0) + do_hex_line(hfi); + fprintf(hfi->fp, ":00000001FF\x0d\x0a"); + fclose(hfi->fp); + } + free(hfi); + } + + +void write_ee_byte(struct prog_info *pi, int address, unsigned char data) + { + if((pi->eep_hfi->count == 16) || ((address != (pi->eep_hfi->linestart_addr + pi->eep_hfi->count)) && (pi->eep_hfi->count != 0))) + do_hex_line(pi->eep_hfi); + if(pi->eep_hfi->count == 0) + pi->eep_hfi->linestart_addr = address; + pi->eep_hfi->hex_line[pi->eep_hfi->count++] = data; + + if(pi->coff_file) + write_coff_eeprom(pi, address, data); + } + + +void write_prog_word(struct prog_info *pi, int address, int data) + { + write_obj_record(pi, address, data); + address *= 2; + if(pi->hfi->segment != (address >> 16)) + { + if(pi->hfi->count != 0) + do_hex_line(pi->hfi); + pi->hfi->segment = address >> 16; + if(pi->hfi->segment >= 16) // Use 04 record for addresses above 1 meg since 02 can support max 1 meg + fprintf(pi->hfi->fp, ":02000004%04X%02X\x0d\x0a", pi->hfi->segment & 0xffff, + (0 - 2 - 4 - ((pi->hfi->segment >> 8) & 0xff) - (pi->hfi->segment & 0xff)) & 0xff); + else // Use 02 record for addresses below 1 meg since more programmers know about the 02 instead of the 04 + fprintf(pi->hfi->fp, ":02000002%04X%02X\x0d\x0a", (pi->hfi->segment << 12) & 0xffff, + (0 - 2 - 2 - ((pi->hfi->segment << 4) & 0xf0)) & 0xff); + } + if((pi->hfi->count == 16) || ((address != (pi->hfi->linestart_addr + pi->hfi->count)) && (pi->hfi->count != 0))) + do_hex_line(pi->hfi); + if(pi->hfi->count == 0) + pi->hfi->linestart_addr = address; + pi->hfi->hex_line[pi->hfi->count++] = data & 0xff; + pi->hfi->hex_line[pi->hfi->count++] = (data >> 8) & 0xff; + + if(pi->coff_file != 0) + write_coff_program(pi, address, data); + } + + +void do_hex_line(struct hex_file_info *hfi) + { + int i; + unsigned char checksum = 0; + + fprintf(hfi->fp, ":%02X%04X00", hfi->count, hfi->linestart_addr & 0xffff); + checksum -= hfi->count + ((hfi->linestart_addr >> 8) & 0xff) + (hfi->linestart_addr & 0xff); + for(i = 0; i < hfi->count; i++) + { + fprintf(hfi->fp, "%02X", hfi->hex_line[i]); + checksum -= hfi->hex_line[i]; + } + fprintf(hfi->fp, "%02X\x0d\x0a", checksum); + hfi->count = 0; + } + + +FILE *open_obj_file(struct prog_info *pi, char *filename) + { + int i; + FILE *fp; + struct include_file *include_file; + + fp = fopen(filename, "wb"); + if(fp) + { + i = pi->cseg_count * 9 + 26; + fputc((i >> 24) & 0xff, fp); + fputc((i >> 16) & 0xff, fp); + fputc((i >> 8) & 0xff, fp); + fputc(i & 0xff, fp); + i = 26; + fputc((i >> 24) & 0xff, fp); + fputc((i >> 16) & 0xff, fp); + fputc((i >> 8) & 0xff, fp); + fputc(i & 0xff, fp); + fputc(9, fp); + i = 0; + for(include_file = pi->first_include_file; include_file; include_file = include_file->next) + i++; + fputc(i, fp); + fprintf(fp, "AVR Object File"); + fputc('\0', fp); + } + return(fp); + } + + +void close_obj_file(struct prog_info *pi, FILE *fp) + { + struct include_file *include_file; + + for(include_file = pi->first_include_file; include_file; include_file = include_file->next) + { + fprintf(fp, "%s", include_file->name); + fputc('\0', fp); + } + fputc('\0', fp); + fclose(fp); + } + + +void write_obj_record(struct prog_info *pi, int address, int data) + { + fputc((address >> 16) & 0xff, pi->obj_file); + fputc((address >> 8) & 0xff, pi->obj_file); + fputc(address & 0xff, pi->obj_file); + fputc((data >> 8) & 0xff, pi->obj_file); + fputc(data & 0xff, pi->obj_file); + fputc(pi->fi->include_file->num & 0xff, pi->obj_file); + fputc((pi->fi->line_number >> 8) & 0xff, pi->obj_file); + fputc(pi->fi->line_number & 0xff, pi->obj_file); + if(pi->macro_call) + fputc(1, pi->obj_file); + else + fputc(0, pi->obj_file); + } diff --git a/src/mkutil/avra-0.8/SOURCE/macro.c b/src/mkutil/avra-0.8/SOURCE/macro.c new file mode 100644 index 00000000..14b38af7 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/macro.c @@ -0,0 +1,427 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "args.h" +#include "avra.h" +#include "device.h" + +int read_macro(struct prog_info *pi, char *name, int pass) + { + int loopok, i; + struct macro *macro; + struct macro_line *macro_line, **last_macro_line; + + if(pass == PASS_1) + { + if(!name) + { + print_msg(pi, MSGTYPE_ERROR, "Missing macro name"); + return(True); + } + get_next_token(name, TERM_END); + // TODO: Sjekk om navnet er gyldig. Bare isalnum() og '_' + macro = calloc(1, sizeof(struct macro)); + if(!macro) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + if(pi->last_macro) + pi->last_macro->next = macro; + else + pi->first_macro = macro; + pi->last_macro = macro; + macro->name = malloc(strlen(name) + 1); + if(!macro->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(macro->name, name); + macro->include_file = pi->fi->include_file; + macro->first_line_number = pi->fi->line_number; + last_macro_line = ¯o->first_macro_line; + } + else if(pi->list_line && pi->list_on) /* pass == PASS_2 */ + { + fprintf(pi->list_file, " %s", pi->list_line); + pi->list_line = NULL; + } + loopok = True; + while(loopok) + { + if(fgets(pi->fi->buff, LINEBUFFER_LENGTH, pi->fi->fp)) + { + pi->fi->line_number++; + i = 0; + while(IS_HOR_SPACE(pi->fi->buff[i]) && !IS_END(pi->fi->buff[i])) i++; + if(pi->fi->buff[i] == '.') + { + i++; + if(!nocase_strncmp(&pi->fi->buff[i], "endm", 4)) // TODO: Vurder å sjekke navnet bedre + loopok = False; + } + if(pass == PASS_1) + { + if(loopok) + { + macro_line = calloc(1, sizeof(struct macro_line)); + if(!macro_line) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + *last_macro_line = macro_line; + last_macro_line = ¯o_line->next; + macro_line->line = malloc(strlen(pi->fi->buff) + 1); + if(!macro_line->line) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(macro_line->line, pi->fi->buff); + } + } + else if(pi->fi->buff && pi->list_file) + { + if(pi->fi->buff[i] == ';') + fprintf(pi->list_file, " %s", pi->fi->buff); + else + fprintf(pi->list_file, " %s", pi->fi->buff); + } + } + else + { + if(feof(pi->fi->fp)) + { + print_msg(pi, MSGTYPE_ERROR, "Found no closing .ENDMACRO"); + return(True); + } + else + { + perror(pi->fi->include_file->name); + return(False); + } + } + } + return(True); + } + + +struct macro *get_macro(struct prog_info *pi, char *name) + { + struct macro *macro; + + for(macro = pi->first_macro; macro; macro = macro->next) + if(!nocase_strcmp(macro->name, name)) + return(macro); + return(NULL); + } +/* +append_arg(char * argfield, char * arg) +{ + argfield = arg; +} +*/ + +void append_type(struct prog_info *pi, char *name, int c, char *value) +{ + int p; + struct def *def; + + p = strlen(name); + name[p++] = '_'; + + if(c == 0) + { + name[p++] = 'v'; + name[p] = '\0'; + return; + } + + for(def = pi->first_def; def; def = def->next) + if(!nocase_strcmp(def->name, value)) + { + itoa((c*8),&name[p],10); + return; + } + + name[p++] = 'i'; + name[p] = '\0'; +} + +/* + * This routine replaces the macro call with mnemonics + */ + +int expand_macro(struct prog_info *pi, struct macro *macro, char *rest_line, int pass) +{ + int ok = True, macro_arg_count = 0, i, j; + char *line, *temp, *macro_args[MAX_MACRO_ARGS]; + char buff[LINEBUFFER_LENGTH]; + struct macro_line *old_macro_line; + struct macro_call *macro_call; + + // added by TW + int off,a,c ; + char arg,ec = False; // extended code switch + char macro_argtype[MAX_MACRO_ARGS][4]; // 3D array for argument types and name translation + char *nmn; //string buffer for new macro name + char buffer[LINEBUFFER_LENGTH]; + int p; + + if(rest_line) + { + line = malloc(strlen(rest_line) + 1); + if(!line) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(line, rest_line); + temp = line; + + /* here we split up the macro arguments into "macro_args" + * Extended macro code interpreter added by TW 2002 + */ + + if( temp[0] == '[' ) // there must be "[" "," "]", else it is garbage + { + if(!strchr(temp, ']')) + { + print_msg(pi, MSGTYPE_ERROR, "found no ']'"); + return(False); + } + temp = &temp[1]; // skip the first bracket + nmn = malloc(LINEBUFFER_LENGTH); + if(!nmn) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(nmn,macro->name); // create a new macro name buffer + c = 1; // byte counter + //ec = True; // switch to ext. code + arg = True; // loop flag + + while(arg) + { + while(IS_HOR_SPACE(temp[0])) //skip leading spaces + { temp = &temp[1]; } + + off = 0; // pointer offset + + do + { + switch(temp[off]) //test current character code + { + case ':': + temp[off] = '\0'; + if(off > 0) + { + c++; + macro_args[macro_arg_count++] = temp; + } + else + { + print_msg(pi, MSGTYPE_ERROR, "missig register before ':'",nmn); + return(False); + } + break; + + case ']': + arg = False; + case ',': + a = off; + do temp[a--] = '\0'; while( IS_HOR_SPACE(temp[a]) ); + if(off > 0) + { + macro_args[macro_arg_count++] = temp; + append_type(pi, nmn, c, temp); + c = 1; + } + else + { + append_type(pi, nmn, 0, temp); + c = 1; + } + break; + + default: + off++; + } + } + while(temp[off] != '\0'); + + if(arg) temp = &temp[off+1]; + else break; + } + + macro = get_macro(pi,nmn); + if(macro == NULL) + { + print_msg(pi, MSGTYPE_ERROR, "Macro %s not defined !",nmn); + return(False); + } + } + else + { + line = malloc(strlen(rest_line) + 1); + if(!line) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(line, rest_line); + temp = line; + while(temp) + { + macro_args[macro_arg_count++] = temp; + temp = get_next_token(temp, TERM_COMMA); + } + } + + + +/* + if(IS_END(temp[i])) + { + temp[i--] = '\0'; + while(IS_HOR_SPACE(temp[i])) temp[i--] = '\0'; + return(0); + } + + * former code from orginial + while(temp) // as long as there valid data in "temp" + { + macro_args[macro_arg_count++] = temp; + temp = get_next_token(temp, TERM_COMMA); + } + */ + } + + if(pass == PASS_1) + { + macro_call = calloc(1, sizeof(struct macro_call)); + if(!macro_call) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + if(pi->last_macro_call) + pi->last_macro_call->next = macro_call; + else + pi->first_macro_call = macro_call; + pi->last_macro_call = macro_call; + macro_call->line_number = pi->fi->line_number; + macro_call->include_file = pi->fi->include_file; + macro_call->macro = macro; + macro_call->prev_on_stack = pi->macro_call; + if(macro_call->prev_on_stack) + { + macro_call->nest_level = macro_call->prev_on_stack->nest_level + 1; + macro_call->prev_line_index = macro_call->prev_on_stack->line_index; + } + } + else + { + for(macro_call = pi->first_macro_call; macro_call; macro_call = macro_call->next) + { + if((macro_call->include_file->num == pi->fi->include_file->num) + && (macro_call->line_number == pi->fi->line_number)) + { + if(pi->macro_call) + { + /* Find correct macro_call when using recursion and nesting */ + if(macro_call->prev_on_stack == pi->macro_call) + if((macro_call->nest_level == (pi->macro_call->nest_level + 1)) + && (macro_call->prev_line_index == pi->macro_call->line_index)) + break; + } + else + break; + } + } + if(pi->list_line && pi->list_on) + { + fprintf(pi->list_file, "%06x + %s", pi->cseg_addr, pi->list_line); + pi->list_line = NULL; + } + } + macro_call->line_index = 0; + pi->macro_call = macro_call; + old_macro_line = pi->macro_line; + for(pi->macro_line = macro->first_macro_line; pi->macro_line && ok; pi->macro_line = pi->macro_line->next) + { + macro_call->line_index++; + if(GET_ARG(pi->args, ARG_LISTMAC)) + pi->list_line = buff; + else + pi->list_line = NULL; + for(i = 0, j = 0; pi->macro_line->line[i] != '\0'; i++) + { + if(pi->macro_line->line[i] == '@') + { + i++; + if(!isdigit(pi->macro_line->line[i])) + print_msg(pi, MSGTYPE_ERROR, "@ must be followed by a number"); + else if((pi->macro_line->line[i] - '0') >= macro_arg_count) + print_msg(pi, MSGTYPE_ERROR, "Missing macro argument (for @%c)", pi->macro_line->line[i]); + else + { + strcpy(&buff[j], macro_args[pi->macro_line->line[i] - '0']); + j += strlen(macro_args[pi->macro_line->line[i] - '0']); + } + } + else + buff[j++] = pi->macro_line->line[i]; + } + buff[j] = '\0'; + ok = parse_line(pi, buff, pass); + if(ok) + { + if((pass == PASS_2) && pi->list_line && pi->list_on) + fprintf(pi->list_file, " %s", pi->list_line); + if(pi->error_count >= pi->max_errors) + { + print_msg(pi, MSGTYPE_MESSAGE, "Maximum error count reached. Exiting..."); + break; + } + } + } + pi->macro_line = old_macro_line; + pi->macro_call = macro_call->prev_on_stack; + if(rest_line) + free(line); + return(ok); + } + diff --git a/src/mkutil/avra-0.8/SOURCE/map.c b/src/mkutil/avra-0.8/SOURCE/map.c new file mode 100644 index 00000000..04ce83c0 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/map.c @@ -0,0 +1,70 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include "avra.h" +#include +#include +#include "args.h" + +char *Space(char *n); + +void write_map_file(struct prog_info *pi) + { + FILE *fp; + struct label *label; + char File[200],*P; + + strcpy(File,(char *)pi->args->first_data->data); + P = strrchr(File,'.'); + if( P ) *P = 0; + strcat(File,".map"); + fp = fopen(File,"w"); + if( fp == NULL ) { + fprintf(stderr,"Error: cannot write map file\n"); + return; + } + for(label = pi->first_constant; label; label = label->next) + fprintf(fp,"%s%sC\t%04x\t%d\n",label->name,Space(label->name),label->value,label->value); + + for(label = pi->first_variable; label; label = label->next) + fprintf(fp,"%s%sV\t%04x\t%d\n",label->name,Space(label->name),label->value,label->value); + + for(label = pi->first_label; label; label = label->next) + fprintf(fp,"%s%sL\t%04x\t%d\n",label->name,Space(label->name),label->value,label->value); + + fprintf(fp,"\n"); + fclose(fp); + return; + } + +char *Space(char *n) { + int i; + + i = strlen(n); + if( i < 1) return "\t\t\t"; + if( i < 8 ) return "\t\t"; + return "\t"; +} diff --git a/src/mkutil/avra-0.8/SOURCE/misc.h b/src/mkutil/avra-0.8/SOURCE/misc.h new file mode 100644 index 00000000..b0a68bea --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/misc.h @@ -0,0 +1,14 @@ +/* + * Misc stuff + */ + +enum boolean {False = 0, True}; + +enum filetype + { + AVRSTUDIO = 0, + GENERIC, + INTEL, + MOTOROLA + }; + diff --git a/src/mkutil/avra-0.8/SOURCE/mnemonic.c b/src/mkutil/avra-0.8/SOURCE/mnemonic.c new file mode 100644 index 00000000..3b0f1f55 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/mnemonic.c @@ -0,0 +1,871 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "avra.h" +#include "device.h" + +#define MAX_MNEMONIC_LEN 8 // Maximum mnemonic length + +enum + { + MNEMONIC_NOP = 0, // 0000 0000 0000 0000 + MNEMONIC_SEC, // 1001 0100 0000 1000 + MNEMONIC_CLC, // 1001 0100 1000 1000 + MNEMONIC_SEN, // 1001 0100 0010 1000 + MNEMONIC_CLN, // 1001 0100 1010 1000 + MNEMONIC_SEZ, // 1001 0100 0001 1000 + MNEMONIC_CLZ, // 1001 0100 1001 1000 + MNEMONIC_SEI, // 1001 0100 0111 1000 + MNEMONIC_CLI, // 1001 0100 1111 1000 + MNEMONIC_SES, // 1001 0100 0100 1000 + MNEMONIC_CLS, // 1001 0100 1100 1000 + MNEMONIC_SEV, // 1001 0100 0011 1000 + MNEMONIC_CLV, // 1001 0100 1011 1000 + MNEMONIC_SET, // 1001 0100 0110 1000 + MNEMONIC_CLT, // 1001 0100 1110 1000 + MNEMONIC_SEH, // 1001 0100 0101 1000 + MNEMONIC_CLH, // 1001 0100 1101 1000 + MNEMONIC_SLEEP, // 1001 0101 1000 1000 + MNEMONIC_WDR, // 1001 0101 1010 1000 + MNEMONIC_IJMP, // 1001 0100 0000 1001 + MNEMONIC_EIJMP, // 1001 0100 0001 1001 + MNEMONIC_ICALL, // 1001 0101 0000 1001 + MNEMONIC_EICALL, // 1001 0101 0001 1001 + MNEMONIC_RET, // 1001 0101 0000 1000 + MNEMONIC_RETI, // 1001 0101 0001 1000 + MNEMONIC_SPM, // 1001 0101 1110 1000 + MNEMONIC_ESPM, // 1001 0101 1111 1000 + MNEMONIC_BREAK, // 1001 0101 1001 1000 + MNEMONIC_LPM, // 1001 0101 1100 1000 + MNEMONIC_ELPM, // 1001 0101 1101 1000 + MNEMONIC_BSET, // s 1001 0100 0sss 1000 + MNEMONIC_BCLR, // s 1001 0100 1sss 1000 + MNEMONIC_SER, // Rd 1110 1111 dddd 1111 + MNEMONIC_COM, // Rd 1001 010d dddd 0000 + MNEMONIC_NEG, // Rd 1001 010d dddd 0001 + MNEMONIC_INC, // Rd 1001 010d dddd 0011 + MNEMONIC_DEC, // Rd 1001 010d dddd 1010 + MNEMONIC_LSR, // Rd 1001 010d dddd 0110 + MNEMONIC_ROR, // Rd 1001 010d dddd 0111 + MNEMONIC_ASR, // Rd 1001 010d dddd 0101 + MNEMONIC_SWAP, // Rd 1001 010d dddd 0010 + MNEMONIC_PUSH, // Rr 1001 001r rrrr 1111 + MNEMONIC_POP, // Rd 1001 000d dddd 1111 + MNEMONIC_TST, // Rd 0010 00dd dddd dddd + MNEMONIC_CLR, // Rd 0010 01dd dddd dddd + MNEMONIC_LSL, // Rd 0000 11dd dddd dddd + MNEMONIC_ROL, // Rd 0001 11dd dddd dddd + MNEMONIC_BREQ, // k 1111 00kk kkkk k001 + MNEMONIC_BRNE, // k 1111 01kk kkkk k001 + MNEMONIC_BRCS, // k 1111 00kk kkkk k000 + MNEMONIC_BRCC, // k 1111 01kk kkkk k000 + MNEMONIC_BRSH, // k 1111 01kk kkkk k000 + MNEMONIC_BRLO, // k 1111 00kk kkkk k000 + MNEMONIC_BRMI, // k 1111 00kk kkkk k010 + MNEMONIC_BRPL, // k 1111 01kk kkkk k010 + MNEMONIC_BRGE, // k 1111 01kk kkkk k100 + MNEMONIC_BRLT, // k 1111 00kk kkkk k100 + MNEMONIC_BRHS, // k 1111 00kk kkkk k101 + MNEMONIC_BRHC, // k 1111 01kk kkkk k101 + MNEMONIC_BRTS, // k 1111 00kk kkkk k110 + MNEMONIC_BRTC, // k 1111 01kk kkkk k110 + MNEMONIC_BRVS, // k 1111 00kk kkkk k011 + MNEMONIC_BRVC, // k 1111 01kk kkkk k011 + MNEMONIC_BRIE, // k 1111 00kk kkkk k111 + MNEMONIC_BRID, // k 1111 01kk kkkk k111 + MNEMONIC_RJMP, // k 1100 kkkk kkkk kkkk + MNEMONIC_RCALL, // k 1101 kkkk kkkk kkkk + MNEMONIC_JMP, // k 1001 010k kkkk 110k + 16k + MNEMONIC_CALL, // k 1001 010k kkkk 111k + 16k + MNEMONIC_BRBS, // s, k 1111 00kk kkkk ksss + MNEMONIC_BRBC, // s, k 1111 01kk kkkk ksss + MNEMONIC_ADD, // Rd, Rr 0000 11rd dddd rrrr + MNEMONIC_ADC, // Rd, Rr 0001 11rd dddd rrrr + MNEMONIC_SUB, // Rd, Rr 0001 10rd dddd rrrr + MNEMONIC_SBC, // Rd, Rr 0000 10rd dddd rrrr + MNEMONIC_AND, // Rd, Rr 0010 00rd dddd rrrr + MNEMONIC_OR, // Rd, Rr 0010 10rd dddd rrrr + MNEMONIC_EOR, // Rd, Rr 0010 01rd dddd rrrr + MNEMONIC_CP, // Rd, Rr 0001 01rd dddd rrrr + MNEMONIC_CPC, // Rd, Rr 0000 01rd dddd rrrr + MNEMONIC_CPSE, // Rd, Rr 0001 00rd dddd rrrr + MNEMONIC_MOV, // Rd, Rr 0010 11rd dddd rrrr + MNEMONIC_MUL, // Rd, Rr 1001 11rd dddd rrrr + MNEMONIC_MOVW, // Rd, Rr 0000 0001 dddd rrrr + MNEMONIC_MULS, // Rd, Rr 0000 0010 dddd rrrr + MNEMONIC_MULSU, // Rd, Rr 0000 0011 0ddd 0rrr + MNEMONIC_FMUL, // Rd, Rr 0000 0011 0ddd 1rrr + MNEMONIC_FMULS, // Rd, Rr 0000 0011 1ddd 0rrr + MNEMONIC_FMULSU, // Rd, Rr 0000 0011 1ddd 1rrr + MNEMONIC_ADIW, // Rd, K 1001 0110 KKdd KKKK + MNEMONIC_SBIW, // Rd, K 1001 0111 KKdd KKKK + MNEMONIC_SUBI, // Rd, K 0101 KKKK dddd KKKK + MNEMONIC_SBCI, // Rd, K 0100 KKKK dddd KKKK + MNEMONIC_ANDI, // Rd, K 0111 KKKK dddd KKKK + MNEMONIC_ORI, // Rd, K 0110 KKKK dddd KKKK + MNEMONIC_SBR, // Rd, K 0110 KKKK dddd KKKK + MNEMONIC_CPI, // Rd, K 0011 KKKK dddd KKKK + MNEMONIC_LDI, // Rd, K 1110 KKKK dddd KKKK + MNEMONIC_CBR, // Rd, K 0111 KKKK dddd KKKK ~K + MNEMONIC_SBRC, // Rr, b 1111 110r rrrr 0bbb + MNEMONIC_SBRS, // Rr, b 1111 111r rrrr 0bbb + MNEMONIC_BST, // Rr, b 1111 101d dddd 0bbb + MNEMONIC_BLD, // Rd, b 1111 100d dddd 0bbb + MNEMONIC_IN, // Rd, P 1011 0PPd dddd PPPP + MNEMONIC_OUT, // P, Rr 1011 1PPr rrrr PPPP + MNEMONIC_SBIC, // P, b 1001 1001 PPPP Pbbb + MNEMONIC_SBIS, // P, b 1001 1011 PPPP Pbbb + MNEMONIC_SBI, // P, b 1001 1010 PPPP Pbbb + MNEMONIC_CBI, // P, b 1001 1000 PPPP Pbbb + MNEMONIC_LDS, // Rd, k 1001 000d dddd 0000 + 16k + MNEMONIC_STS, // k, Rr 1001 001d dddd 0000 + 16k + MNEMONIC_LD, // Rd, __ dummy + MNEMONIC_ST, // __, Rr dummy + MNEMONIC_LDD, // Rd, _+q dummy + MNEMONIC_STD, // _+q, Rr dummy + MNEMONIC_COUNT, + MNEMONIC_LPM_Z, // Rd, Z 1001 000d dddd 0100 + MNEMONIC_LPM_ZP, // Rd, Z+ 1001 000d dddd 0101 + MNEMONIC_ELPM_Z, // Rd, Z 1001 000d dddd 0110 + MNEMONIC_ELPM_ZP, // Rd, Z+ 1001 000d dddd 0111 + MNEMONIC_LD_X, // Rd, X 1001 000d dddd 1100 + MNEMONIC_LD_XP, // Rd, X+ 1001 000d dddd 1101 + MNEMONIC_LD_MX, // Rd, -X 1001 000d dddd 1110 + MNEMONIC_LD_Y, // Rd, Y 1000 000d dddd 1000 + MNEMONIC_LD_YP, // Rd, Y+ 1001 000d dddd 1001 + MNEMONIC_LD_MY, // Rd, -Y 1001 000d dddd 1010 + MNEMONIC_LD_Z, // Rd, Z 1000 000d dddd 0000 + MNEMONIC_LD_ZP, // Rd, Z+ 1001 000d dddd 0001 + MNEMONIC_LD_MZ, // Rd, -Z 1001 000d dddd 0010 + MNEMONIC_ST_X, // X, Rr 1001 001d dddd 1100 + MNEMONIC_ST_XP, // X+, Rr 1001 001d dddd 1101 + MNEMONIC_ST_MX, // -X, Rr 1001 001d dddd 1110 + MNEMONIC_ST_Y, // Y, Rr 1000 001d dddd 1000 + MNEMONIC_ST_YP, // Y+, Rr 1001 001d dddd 1001 + MNEMONIC_ST_MY, // -Y, Rr 1001 001d dddd 1010 + MNEMONIC_ST_Z, // Z, Rr 1000 001d dddd 0000 + MNEMONIC_ST_ZP, // Z+, Rr 1001 001d dddd 0001 + MNEMONIC_ST_MZ, // -Z, Rr 1001 001d dddd 0010 + MNEMONIC_LDD_Y, // Rd, Y+q 10q0 qq0d dddd 1qqq + MNEMONIC_LDD_Z, // Rd, Z+q 10q0 qq0d dddd 0qqq + MNEMONIC_STD_Y, // Y+q, Rr 10q0 qq1r rrrr 1qqq + MNEMONIC_STD_Z, // Z+q, Rr 10q0 qq1r rrrr 0qqq + MNEMONIC_END + }; + +struct instruction + { + char *mnemonic; + int opcode; + int flag; /* Device flags meaning the instruction is not + supported */ + }; + +struct instruction instruction_list[] = + { + {"nop", 0x0000, 0}, + {"sec", 0x9408, 0}, + {"clc", 0x9488, 0}, + {"sen", 0x9428, 0}, + {"cln", 0x94a8, 0}, + {"sez", 0x9418, 0}, + {"clz", 0x9498, 0}, + {"sei", 0x9478, 0}, + {"cli", 0x94f8, 0}, + {"ses", 0x9448, 0}, + {"cls", 0x94c8, 0}, + {"sev", 0x9438, 0}, + {"clv", 0x94b8, 0}, + {"set", 0x9468, 0}, + {"clt", 0x94e8, 0}, + {"seh", 0x9458, 0}, + {"clh", 0x94d8, 0}, + {"sleep", 0x9588, 0}, + {"wdr", 0x95a8, 0}, + {"ijmp", 0x9409, DF_TINY1X}, + {"eijmp", 0x9419, DF_NO_EIJMP}, + {"icall", 0x9509, DF_TINY1X}, + {"eicall",0x9519, DF_NO_EICALL}, + {"ret", 0x9508, 0}, + {"reti", 0x9518, 0}, + {"spm", 0x95e8, DF_NO_SPM}, + {"espm", 0x95f8, DF_NO_ESPM}, + {"break", 0x9598, DF_NO_BREAK}, + {"lpm", 0x95c8, DF_NO_LPM}, + {"elpm", 0x95d8, DF_NO_ELPM}, + {"bset", 0x9408, 0}, + {"bclr", 0x9488, 0}, + {"ser", 0xef0f, 0}, + {"com", 0x9400, 0}, + {"neg", 0x9401, 0}, + {"inc", 0x9403, 0}, + {"dec", 0x940a, 0}, + {"lsr", 0x9406, 0}, + {"ror", 0x9407, 0}, + {"asr", 0x9405, 0}, + {"swap", 0x9402, 0}, + {"push", 0x920f, DF_TINY1X}, + {"pop", 0x900f, DF_TINY1X}, + {"tst", 0x2000, 0}, + {"clr", 0x2400, 0}, + {"lsl", 0x0c00, 0}, + {"rol", 0x1c00, 0}, + {"breq", 0xf001, 0}, + {"brne", 0xf401, 0}, + {"brcs", 0xf000, 0}, + {"brcc", 0xf400, 0}, + {"brsh", 0xf400, 0}, + {"brlo", 0xf000, 0}, + {"brmi", 0xf002, 0}, + {"brpl", 0xf402, 0}, + {"brge", 0xf404, 0}, + {"brlt", 0xf004, 0}, + {"brhs", 0xf005, 0}, + {"brhc", 0xf405, 0}, + {"brts", 0xf006, 0}, + {"brtc", 0xf406, 0}, + {"brvs", 0xf003, 0}, + {"brvc", 0xf403, 0}, + {"brie", 0xf007, 0}, + {"brid", 0xf407, 0}, + {"rjmp", 0xc000, 0}, + {"rcall", 0xd000, 0}, + {"jmp", 0x940c, DF_NO_JMP}, + {"call", 0x940e, DF_NO_JMP}, + {"brbs", 0xf000, 0}, + {"brbc", 0xf400, 0}, + {"add", 0x0c00, 0}, + {"adc", 0x1c00, 0}, + {"sub", 0x1800, 0}, + {"sbc", 0x0800, 0}, + {"and", 0x2000, 0}, + {"or", 0x2800, 0}, + {"eor", 0x2400, 0}, + {"cp", 0x1400, 0}, + {"cpc", 0x0400, 0}, + {"cpse", 0x1000, 0}, + {"mov", 0x2c00, 0}, + {"mul", 0x9c00, DF_NO_MUL}, + {"movw", 0x0100, DF_NO_MOVW}, + {"muls", 0x0200, DF_NO_MUL}, + {"mulsu", 0x0300, DF_NO_MUL}, + {"fmul", 0x0308, DF_NO_MUL}, + {"fmuls", 0x0380, DF_NO_MUL}, + {"fmulsu",0x0388, DF_NO_MUL}, + {"adiw", 0x9600, DF_TINY1X}, + {"sbiw", 0x9700, DF_TINY1X}, + {"subi", 0x5000, 0}, + {"sbci", 0x4000, 0}, + {"andi", 0x7000, 0}, + {"ori", 0x6000, 0}, + {"sbr", 0x6000, 0}, + {"cpi", 0x3000, 0}, + {"ldi", 0xe000, 0}, + {"cbr", 0x7000, 0}, + {"sbrc", 0xfc00, 0}, + {"sbrs", 0xfe00, 0}, + {"bst", 0xfa00, 0}, + {"bld", 0xf800, 0}, + {"in", 0xb000, 0}, + {"out", 0xb800, 0}, + {"sbic", 0x9900, 0}, + {"sbis", 0x9b00, 0}, + {"sbi", 0x9a00, 0}, + {"cbi", 0x9800, 0}, + {"lds", 0x9000, DF_TINY1X}, + {"sts", 0x9200, DF_TINY1X}, + {"ld", 0, 0}, + {"st", 0, 0}, + {"ldd", 0, DF_TINY1X}, + {"std", 0, DF_TINY1X}, + {"count", 0, 0}, + {"lpm", 0x9004, DF_NO_LPM|DF_NO_LPM_X}, + {"lpm", 0x9005, DF_NO_LPM|DF_NO_LPM_X}, + {"elpm", 0x9006, DF_NO_ELPM|DF_NO_ELPM_X}, + {"elpm", 0x9007, DF_NO_ELPM|DF_NO_ELPM_X}, + {"ld", 0x900c, DF_NO_XREG}, + {"ld", 0x900d, DF_NO_XREG}, + {"ld", 0x900e, DF_NO_XREG}, + {"ld", 0x8008, DF_NO_YREG}, + {"ld", 0x9009, DF_NO_YREG}, + {"ld", 0x900a, DF_NO_YREG}, + {"ld", 0x8000, 0}, + {"ld", 0x9001, DF_TINY1X}, + {"ld", 0x9002, DF_TINY1X}, + {"st", 0x920c, DF_NO_XREG}, + {"st", 0x920d, DF_NO_XREG}, + {"st", 0x920e, DF_NO_XREG}, + {"st", 0x8208, DF_NO_YREG}, + {"st", 0x9209, DF_NO_YREG}, + {"st", 0x920a, DF_NO_YREG}, + {"st", 0x8200, 0}, + {"st", 0x9201, DF_TINY1X}, + {"st", 0x9202, DF_TINY1X}, + {"ldd", 0x8008, DF_TINY1X}, + {"ldd", 0x8000, DF_TINY1X}, + {"std", 0x8208, DF_TINY1X}, + {"std", 0x8200, DF_TINY1X}, + {"end", 0, 0} + }; + + +/* We try to parse the command name. Is it a assembler mnemonic or anything else ? + * If so, it may be a macro. + */ + +int parse_mnemonic(struct prog_info *pi, int pass) + { + int mnemonic, i, opcode, opcode2, instruction_long = False; + char *operand1, *operand2; + struct macro *macro; + char temp[MAX_MNEMONIC_LEN+1]; + + operand1 = get_next_token(pi->fi->scratch, TERM_SPACE); // we get the first word on line + mnemonic = get_mnemonic_type(my_strlwr(pi->fi->scratch)); + if(mnemonic == -1) // if -1 this must be a macro name + { + macro = get_macro(pi, pi->fi->scratch); // and so, we try to get the corresponding macro struct. + if(macro) + { + return(expand_macro(pi, macro, operand1, pass)); //we expand the macro + } + else // if we cant find a name, this is a unknown word. + { + print_msg(pi, MSGTYPE_ERROR, "Unknown mnemonic/macro: %s", pi->fi->scratch); + return(True); + } + } + if(pass == PASS_2) + { + if(mnemonic <= MNEMONIC_BREAK) + { + if(operand1) + print_msg(pi, MSGTYPE_WARNING, "Garbage after instruction %s: %s", instruction_list[mnemonic].mnemonic, operand1); + // No operand + opcode = 0; + } + else if(mnemonic <= MNEMONIC_ELPM) + { + if(operand1) + { + operand2 = get_next_token(operand1, TERM_COMMA); + if(!operand2) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs a second operand", instruction_list[mnemonic].mnemonic); + return(True); + } + get_next_token(operand2, TERM_END); + i = get_register(pi, operand1); + opcode = i << 4; + i = get_indirect(pi, operand2); + if(i == 6) // Means Z + { + if(mnemonic == MNEMONIC_LPM) + mnemonic = MNEMONIC_LPM_Z; + else if(mnemonic == MNEMONIC_ELPM) + mnemonic = MNEMONIC_ELPM_Z; + } + else if(i == 7) // Means Z+ + { + if(mnemonic == MNEMONIC_LPM) + mnemonic = MNEMONIC_LPM_ZP; + else if(mnemonic == MNEMONIC_ELPM) + mnemonic = MNEMONIC_ELPM_ZP; + } + else + { + print_msg(pi, MSGTYPE_ERROR, "Unsupported operand: %s", operand2); + return(True); + } + } + else + opcode = 0; + } + else + { + if(!operand1) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs an operand", instruction_list[mnemonic].mnemonic); + return(True); + } + operand2 = get_next_token(operand1, TERM_COMMA); + if(mnemonic >= MNEMONIC_BRBS) + { + if(!operand2) + { + print_msg(pi, MSGTYPE_ERROR, "%s needs a second operand", instruction_list[mnemonic].mnemonic); + return(True); + } + get_next_token(operand2, TERM_END); + } + if(mnemonic <= MNEMONIC_BCLR) + { + if(!get_bitnum(pi, operand1, &i)) + return(False); + opcode = i << 4; + } + else if(mnemonic <= MNEMONIC_ROL) + { + i = get_register(pi, operand1); + if((mnemonic == MNEMONIC_SER) && (i < 16)) + { + print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic); + i &= 0x0f; + } + opcode = i << 4; + if(mnemonic >= MNEMONIC_TST) + opcode |= ((i & 0x10) << 5) | (i & 0x0f); + } + else if(mnemonic <= MNEMONIC_RCALL) + { + if(!get_expr(pi, operand1, &i)) + return(False); + i -= pi->cseg_addr + 1; + if(mnemonic <= MNEMONIC_BRID) + { + if((i < -64) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "Branch out of range (-64 <= k <= 63)"); + opcode = (i & 0x7f) << 3; + } + else + { + if(((i < -2048) || (i > 2047)) && (pi->device->flash_size != 4096)) + print_msg(pi, MSGTYPE_ERROR, "Relative address out of range (-2048 <= k <= 2047)"); + opcode = i & 0x0fff; + } + } + else if(mnemonic <= MNEMONIC_CALL) + { + if(!get_expr(pi, operand1, &i)) + return(False); + if((i < 0) || (i > 4194303)) + print_msg(pi, MSGTYPE_ERROR, "Address out of range (0 <= k <= 4194303)"); + opcode = ((i & 0x3e0000) >> 13) | ((i & 0x01000) >> 16); + opcode2 = i & 0xffff; + instruction_long = True; + } + else if(mnemonic <= MNEMONIC_BRBC) + { + if(!get_bitnum(pi, operand1, &i)) + return(False); + opcode = i; + if(!get_expr(pi, operand2, &i)) + return(False); + i -= pi->cseg_addr + 1; + if((i < -64) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "Branch out of range (-64 <= k <= 63)"); + opcode |= (i & 0x7f) << 3; + } + else if(mnemonic <= MNEMONIC_MUL) + { + i = get_register(pi, operand1); + opcode = i << 4; + i = get_register(pi, operand2); + opcode |= ((i & 0x10) << 5) | (i & 0x0f); + } + else if(mnemonic <= MNEMONIC_MOVW) + { + i = get_register(pi, operand1); + if((i % 2) == 1) + print_msg(pi, MSGTYPE_ERROR, "%s must use a even numbered register for Rd", instruction_list[mnemonic].mnemonic); + opcode = (i / 2) << 4; + i = get_register(pi, operand2); + if((i % 2) == 1) + print_msg(pi, MSGTYPE_ERROR, "%s must use a even numbered register for Rr", instruction_list[mnemonic].mnemonic); + opcode |= i / 2; + } + else if(mnemonic <= MNEMONIC_MULS) + { + i = get_register(pi, operand1); + if(i < 16) + print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic); + opcode = (i & 0x0f) << 4; + i = get_register(pi, operand2); + if(i < 16) + print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic); + opcode |= (i & 0x0f); + } + else if(mnemonic <= MNEMONIC_FMULSU) + { + i = get_register(pi, operand1); + if((i < 16) || (i >= 24)) + print_msg(pi, MSGTYPE_ERROR, "%s can only use registers (r16 - r23)", instruction_list[mnemonic].mnemonic); + opcode = (i & 0x07) << 4; + i = get_register(pi, operand2); + if((i < 16) || (i >= 24)) + print_msg(pi, MSGTYPE_ERROR, "%s can only use registers (r16 - r23)", instruction_list[mnemonic].mnemonic); + opcode |= (i & 0x07); + } + else if(mnemonic <= MNEMONIC_SBIW) + { + i = get_register(pi, operand1); + if(!((i == 24) || (i == 26) || (i == 28) || (i == 30))) + print_msg(pi, MSGTYPE_ERROR, "%s can only use registers R24, R26, R28 or R30", instruction_list[mnemonic].mnemonic); + opcode = ((i - 24) / 2) << 4; + if(!get_expr(pi, operand2, &i)) + return(False); + if((i < 0) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "Constant out of range (0 <= k <= 63)"); + opcode |= ((i & 0x30) << 2) | (i & 0x0f); + } + else if(mnemonic <= MNEMONIC_CBR) + { + i = get_register(pi, operand1); + if(i < 16) + print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic); + opcode = (i & 0x0f) << 4; + if(!get_expr(pi, operand2, &i)) + return(False); + if((i < -128) || (i > 255)) + print_msg(pi, MSGTYPE_WARNING, "Constant out of range (-128 <= k <= 255). Will be masked"); + if(mnemonic == MNEMONIC_CBR) + i = ~i; + opcode |= ((i & 0xf0) << 4) | (i & 0x0f); + } + else if(mnemonic <= MNEMONIC_BLD) + { + i = get_register(pi, operand1); + opcode = i << 4; + if(!get_bitnum(pi, operand2, &i)) + return(False); + opcode |= i; + } + else if(mnemonic == MNEMONIC_IN) + { + i = get_register(pi, operand1); + opcode = i << 4; + if(!get_expr(pi, operand2, &i)) + return(False); + if((i < 0) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 63)"); + opcode |= ((i & 0x30) << 5) | (i & 0x0f); + } + else if(mnemonic == MNEMONIC_OUT) + { + if(!get_expr(pi, operand1, &i)) + return(False); + if((i < 0) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 63)"); + opcode = ((i & 0x30) << 5) | (i & 0x0f); + i = get_register(pi, operand2); + opcode |= i << 4; + } + else if(mnemonic <= MNEMONIC_CBI) + { + if(!get_expr(pi, operand1, &i)) + return(False); + if((i < 0) || (i > 31)) + print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 31)"); + opcode = i << 3; + if(!get_bitnum(pi, operand2, &i)) + return(False); + opcode |= i; + } + else if(mnemonic == MNEMONIC_LDS) + { + i = get_register(pi, operand1); + opcode = i << 4; + if(!get_expr(pi, operand2, &i)) + return(False); + if((i < 0) || (i > 65535)) + print_msg(pi, MSGTYPE_ERROR, "SRAM out of range (0 <= k <= 65535)"); + opcode2 = i; + instruction_long = True; + } + else if(mnemonic == MNEMONIC_STS) + { + if(!get_expr(pi, operand1, &i)) + return(False); + if((i < 0) || (i > 65535)) + print_msg(pi, MSGTYPE_ERROR, "SRAM out of range (0 <= k <= 65535)"); + opcode2 = i; + i = get_register(pi, operand2); + opcode = i << 4; + instruction_long = True; + } + else if(mnemonic == MNEMONIC_LD) + { + i = get_register(pi, operand1); + opcode = i << 4; + mnemonic = MNEMONIC_LD_X + get_indirect(pi, operand2); + } + else if(mnemonic == MNEMONIC_ST) + { + mnemonic = MNEMONIC_ST_X + get_indirect(pi, operand1); + i = get_register(pi, operand2); + opcode = i << 4; + } + else if(mnemonic == MNEMONIC_LDD) + { + i = get_register(pi, operand1); + opcode = i << 4; + if(tolower(operand2[0]) == 'z') + mnemonic = MNEMONIC_LDD_Z; + else if(tolower(operand2[0]) == 'y') + mnemonic = MNEMONIC_LDD_Y; + else + print_msg(pi, MSGTYPE_ERROR, "Garbage in second operand (%s)", operand2); + i = 1; + while((operand2[i] != '\0') && (operand2[i] != '+')) i++; + if(operand2[i] == '\0') + { + print_msg(pi, MSGTYPE_ERROR, "Garbage in second operand (%s)", operand2); + return(False); + } + if(!get_expr(pi, &operand2[i + 1], &i)) + return(False); + if((i < 0) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "Displacement out of range (0 <= q <= 63)"); + opcode |= ((i & 0x20) << 8) | ((i & 0x18) << 7) | (i & 0x07); + } + else if(mnemonic == MNEMONIC_STD) + { + if(tolower(operand1[0]) == 'z') + mnemonic = MNEMONIC_STD_Z; + else if(tolower(operand1[0]) == 'y') + mnemonic = MNEMONIC_STD_Y; + else + print_msg(pi, MSGTYPE_ERROR, "Garbage in first operand (%s)", operand1); + i = 1; + while((operand1[i] != '\0') && (operand1[i] != '+')) i++; + if(operand1[i] == '\0') + { + print_msg(pi, MSGTYPE_ERROR, "Garbage in first operand (%s)", operand1); + return(False); + } + if(!get_expr(pi, &operand1[i + 1], &i)) + return(False); + if((i < 0) || (i > 63)) + print_msg(pi, MSGTYPE_ERROR, "Displacement out of range (0 <= q <= 63)"); + opcode = ((i & 0x20) << 8) | ((i & 0x18) << 7) | (i & 0x07); + i = get_register(pi, operand2); + opcode |= i << 4; + } + else + print_msg(pi, MSGTYPE_ERROR, "Shit! Missing opcode check [%d]...", mnemonic); + } + if (pi->device->flag & instruction_list[mnemonic].flag) + { + strncpy(temp, instruction_list[mnemonic].mnemonic, MAX_MNEMONIC_LEN); + print_msg(pi, MSGTYPE_ERROR, "%s instruction is not supported on %s", + my_strupr(temp), pi->device->name); + } + opcode |= instruction_list[mnemonic].opcode; + if(pi->list_on && pi->list_line) + { + if(instruction_long) + fprintf(pi->list_file, "%06x %04x %04x %s", pi->cseg_addr, opcode, opcode2, pi->list_line); + else + fprintf(pi->list_file, "%06x %04x %s", pi->cseg_addr, opcode, pi->list_line); + pi->list_line = NULL; + } + if(pi->hfi) + { + write_prog_word(pi, pi->cseg_addr, opcode); + if(instruction_long) + write_prog_word(pi, pi->cseg_addr + 1, opcode2); + } + if(instruction_long) + pi->cseg_addr += 2; + else + pi->cseg_addr++; + } + else + { + if((mnemonic == MNEMONIC_JMP) || (mnemonic == MNEMONIC_CALL) || (mnemonic == MNEMONIC_LDS) || (mnemonic == MNEMONIC_STS)) + { + pi->cseg_addr += 2; + pi->cseg_count += 2; + } + else + { + pi->cseg_addr++; + pi->cseg_count++; + } + } + return(True); + } + + +int get_mnemonic_type(char *mnemonic) + { + int i; + + for(i = 0; i < MNEMONIC_COUNT; i++) + if(!strcmp(mnemonic, instruction_list[i].mnemonic)) + return(i); + return(-1); + } + + +int get_register(struct prog_info *pi, char *data) + { + char *second_reg; + int reg = 0; + struct def *def; + + // Check for any occurence of r1:r0 pairs, and if so skip to second register + second_reg = strchr(data, ':'); + if(second_reg != NULL) + data = second_reg + 1; + + for(def = pi->first_def; def; def = def->next) + if(!nocase_strcmp(def->name, data)) + { + reg = def->reg; + return(reg); + } + if((tolower(data[0]) == 'r') && isdigit(data[1])) + { + reg = atoi(&data[1]); + if(reg > 31) + print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", reg); + } + else + print_msg(pi, MSGTYPE_ERROR, "No register associated with %s", data); + return(reg); + } + + +int get_bitnum(struct prog_info *pi, char *data, int *ret) +{ + if(!get_expr(pi, data, ret)) + return(False); + if((*ret < 0) || (*ret > 7)) + { + print_msg(pi, MSGTYPE_ERROR, "Operand out of range (0 <= s <= 7)"); + return(False); + } + return(True); + } + + +int get_indirect(struct prog_info *pi, char *operand) + { + int i = 1; + + switch(tolower(operand[0])) + { + case '-': + while(IS_HOR_SPACE(operand[i])) i++; + if(operand[i + 1] != '\0') + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + switch(tolower(operand[i])) + { + case 'x': + if (pi->device->flag & DF_NO_XREG) + print_msg(pi, MSGTYPE_ERROR, "X register is not supported on %s", pi->device->name); + return(2); + case 'y': + if (pi->device->flag & DF_NO_YREG) + print_msg(pi, MSGTYPE_ERROR, "Y register is not supported on %s", pi->device->name); + return(5); + case 'z': + return(8); + default: + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + return(0); + } + case 'x': + if (pi->device->flag & DF_NO_XREG) + print_msg(pi, MSGTYPE_ERROR, "X register is not supported on %s", pi->device->name); + while(IS_HOR_SPACE(operand[i])) i++; + if(operand[i] == '+') + { + if(operand[i + 1] != '\0') + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + return(1); + } + else if(operand[i] == '\0') + return(0); + else + print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand); + return(0); + case 'y': + if (pi->device->flag & DF_NO_YREG) + print_msg(pi, MSGTYPE_ERROR, "Y register is not supported on %s", pi->device->name); + while(IS_HOR_SPACE(operand[i])) i++; + if(operand[i] == '+') + { + if(operand[i + 1] != '\0') + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + return(4); + } + else if(operand[i] == '\0') + return(3); + else + print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand); + return(0); + case 'z': + while(IS_HOR_SPACE(operand[i])) i++; + if(operand[i] == '+') + { + if(operand[i + 1] != '\0') + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + return(7); + } + else if(operand[i] == '\0') + return(6); + else + print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand); + return(0); + default: + print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand); + } + return(0); + } + +/* Return 1 if instruction name is supported by the current device, + 0 if unsupported, -1 if it is invalid */ +int is_supported(struct prog_info *pi, char *name) { + char temp[MAX_MNEMONIC_LEN+1]; + int mnemonic; + + strncpy(temp,name,MAX_MNEMONIC_LEN); + mnemonic = get_mnemonic_type(my_strlwr(temp)); + if (mnemonic == -1) return -1; + if (pi->device->flag & instruction_list[mnemonic].flag) return 0; + return 1; + } + +int count_supported_instructions(int flags) +{ + int i = 0, count = 0; + while(i < MNEMONIC_END) + { + if((i < MNEMONIC_LD) || (i > MNEMONIC_COUNT)) + if(!(flags & instruction_list[i].flag)) + count++; + i++; + } + return(count); +} diff --git a/src/mkutil/avra-0.8/SOURCE/n.bat b/src/mkutil/avra-0.8/SOURCE/n.bat new file mode 100644 index 00000000..38f21fef --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/n.bat @@ -0,0 +1,2 @@ +NMake /f Makefile.win32.mvc install +del *.obj diff --git a/src/mkutil/avra-0.8/SOURCE/parser.c b/src/mkutil/avra-0.8/SOURCE/parser.c new file mode 100644 index 00000000..fe1604d2 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/parser.c @@ -0,0 +1,397 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +#include +#include +#include +#include + +#include "misc.h" +#include "avra.h" +#include "args.h" + +/* + * Parses given assembler file + */ + +int parse_file(struct prog_info *pi, char *filename, int pass) + { + int ok = True, loopok; + struct file_info *fi; + struct include_file *include_file; + + fi = malloc(sizeof(struct file_info)); + if(fi) + { + pi->fi = fi; + if(pass == PASS_1) + { + include_file = malloc(sizeof(struct include_file)); + if(!include_file) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + free(fi); + return(False); + } + include_file->next = NULL; + if(pi->last_include_file) + { + pi->last_include_file->next = include_file; + include_file->num = pi->last_include_file->num + 1; + } + else + { + pi->first_include_file = include_file; + include_file->num = 0; + } + pi->last_include_file = include_file; + include_file->name = malloc(strlen(filename) + 1); + if(!include_file->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + free(fi); + return(False); + } + strcpy(include_file->name, filename); + } + else + { + for(include_file = pi->first_include_file; include_file; include_file = include_file->next) + if(!strcmp(include_file->name, filename)) + break; + } + if(!include_file) + { + print_msg(pi, MSGTYPE_ERROR, "Internal assembler error"); + free(fi); + return(False); + } + fi->include_file = include_file; + fi->line_number = 0; + fi->exit_file = False; + //printf("Opening %s\n",filename); + fi->fp = fopen(filename, "r"); + if(fi->fp != NULL) + { + + loopok = True; + while(loopok && !fi->exit_file) + { + if(fgets(fi->buff, LINEBUFFER_LENGTH, fi->fp)) + { + fi->line_number++; + pi->list_line = fi->buff; + ok = parse_line(pi, fi->buff, pass); + + if(ok) + { + if((pass == PASS_2) && pi->list_line && pi->list_on) + fprintf(pi->list_file, " %s", pi->list_line); + if(pi->error_count >= pi->max_errors) + { + print_msg(pi, MSGTYPE_MESSAGE, "Maximum error count reached. Exiting..."); + loopok = False; + } + } + else + { + loopok = False; + } + } + else + { + loopok = False; + if(!feof(fi->fp)) + { + ok = False; + perror(filename); + } + } + } + fclose(fi->fp); + } + else + { + ok = False; + perror(filename); + } + free(fi); + } + else + { + ok = False; + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + } + return(ok); + } + + +/* + * Parses one line + */ + +int parse_line(struct prog_info *pi, char *line, int pass) + { + int ok, i, j, k, global_label = False, textarea; + char temp[LINEBUFFER_LENGTH]; + struct label *label = NULL; + struct macro_call *macro_call; + + /* Find out if there is any relevant code on the line. If not? return */ + i = 0; + while(IS_HOR_SPACE(line[i]) && !IS_END(line[i])) i++; + if(IS_END(line[i])) + return(True); + + strcpy(temp, &line[i]); + + /* filter out .stab debugging information before it screws up the previous processing */ + /* .stabs sometimes contains colon : symbol - might be interpreted as label */ + if( *temp == '.' ){ /* minimal slowdown of existing code */ + /* compiler output is always lower case */ + if( strncmp( temp, ".stabs ", 7) == 0 ){ + ok = parse_stabs( pi, temp, pass ); + return( ok ); + } + + if( strncmp( temp, ".stabn ", 7) == 0 ){ + ok = parse_stabn( pi, temp, pass ); + return( ok ); + } + } + + /* Calculate any expression inside a pair of {} */ + for(i = 0, j = 0, textarea = False; temp[j] != '\0'; i++, j++) + { + if((temp[j] == '\'') || (temp[j] == '"')) + textarea = textarea ? False : True; + else if(!textarea && (temp[j] == ';')) + break; + if(temp[j] == '{') + { + k = ++j; + while((temp[j] != '\0') && (temp[j] != '}')) j++; + if(IS_END(temp[j])) + { + print_msg(pi, MSGTYPE_ERROR, "Found no matching }"); + break; + } + else + { + temp[j] = '\0'; + if(!get_expr(pi, &temp[k], &k)) + return(False); + sprintf(&pi->fi->scratch[i], "%d", k); + i = strlen(pi->fi->scratch) - 1; + } + } + else + pi->fi->scratch[i] = temp[j]; + } + pi->fi->scratch[i] = '\0'; + + /* Detect the global keyword for global labels */ + if(!nocase_strncmp(pi->fi->scratch, "global", 6) && IS_HOR_SPACE(pi->fi->scratch[6])) + { + global_label = True; + i = 7; + while(IS_HOR_SPACE(pi->fi->scratch[i]) && !IS_END(pi->fi->scratch[i])) i++; + if(IS_END(pi->fi->scratch[i])) + { + print_msg(pi, MSGTYPE_ERROR, "Found no label after global keyword"); + return(True); + } + strcpy(pi->fi->scratch, &pi->fi->scratch[i]); + } + + for(i = 0; IS_LABEL(pi->fi->scratch[i]) || (pi->fi->scratch[i] == ':'); i++) + if(pi->fi->scratch[i] == ':') + { + pi->fi->scratch[i] = '\0'; + if(pass == PASS_1) + { + for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) + { + for(label = pi->macro_call->first_label; label; label = label->next) + { + if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) + { + print_msg(pi, MSGTYPE_ERROR, "Can't redefine local label %s", &pi->fi->scratch[0]); + break; + } + } + } + for(label = pi->first_label; label; label = label->next) + { + if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) + { + print_msg(pi, MSGTYPE_ERROR, "Can't redefine label %s", &pi->fi->scratch[0]); + break; + } + } + for(label = pi->first_variable; label; label = label->next) + if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) + { + print_msg(pi, MSGTYPE_ERROR, "%s has already been defined as a .SET variable", &pi->fi->scratch[0]); + break; + } + for(label = pi->first_constant; label; label = label->next) + if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) + { + print_msg(pi, MSGTYPE_ERROR, "%s has already been defined as a .EQU constant", &pi->fi->scratch[0]); + break; + } + label = malloc(sizeof(struct label)); + if(!label) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + label->next = NULL; + label->name = malloc(strlen(&pi->fi->scratch[0]) + 1); + if(!label->name) + { + print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); + return(False); + } + strcpy(label->name, &pi->fi->scratch[0]); + switch(pi->segment) + { + case SEGMENT_CODE: + label->value = pi->cseg_addr; + break; + case SEGMENT_DATA: + label->value = pi->dseg_addr; + break; + case SEGMENT_EEPROM: + label->value = pi->eseg_addr; + break; + } + if(pi->macro_call && !global_label) + { + if(pi->macro_call->last_label) + pi->macro_call->last_label->next = label; + else + pi->macro_call->first_label = label; + pi->macro_call->last_label = label; + } + else + { + if(pi->last_label) + pi->last_label->next = label; + else + pi->first_label = label; + pi->last_label = label; + } + } + i++; + while(IS_HOR_SPACE(pi->fi->scratch[i]) && !IS_END(pi->fi->scratch[i])) i++; + if(IS_END(pi->fi->scratch[i])) + { + if((pass == PASS_2) && pi->list_on) // Diff tilpassing + { + fprintf(pi->list_file, " %s", pi->list_line); + pi->list_line = NULL; + } + return(True); + } + strcpy(pi->fi->scratch, &pi->fi->scratch[i]); + break; + } + + if(pi->fi->scratch[0] == '.') + { + pi->fi->label = label; + ok = parse_directive(pi, pass); + if((pass == PASS_2) && pi->list_on && pi->list_line) // Diff tilpassing + { + fprintf(pi->list_file, " %s", pi->list_line); + pi->list_line = NULL; + } + return(ok); + } + else + { + ok = parse_mnemonic(pi, pass); + return(ok); + } + } + + +/* + * Get the next token, and terminate the last one. + * Termination identifier is specified. + */ + +char *get_next_token(char *data, int term) + { + int i = 0, j, anti_comma = False; + + switch(term) + { + case TERM_END: + while(!IS_END(data[i])) i++; + break; + case TERM_SPACE: + while(!IS_HOR_SPACE(data[i]) && !IS_END(data[i])) i++; + break; + case TERM_DASH: + while((data[i] != '-') && !IS_END(data[i])) i++; + break; + case TERM_COLON: + while((data[i] != ':') && !IS_ENDLINE(data[i])) i++; + break; + case TERM_DOUBLEQUOTE: + while((data[i] != '"') && !IS_ENDLINE(data[i])) i++; + break; + case TERM_COMMA: + while(((data[i] != ',') || anti_comma) + && !(((data[i] == ';') && !anti_comma) || (data[i] == 10) || (data[i] == 13)|| (data[i] == '\0'))) + { + if((data[i] == '\'') || (data[i] == '"')) + anti_comma = anti_comma ? False : True; + i++; + } + break; + case TERM_EQUAL: + while((data[i] != '=') && !IS_END(data[i])) i++; + break; + } + if(IS_END(data[i])) + { + data[i--] = '\0'; + while(IS_HOR_SPACE(data[i])) data[i--] = '\0'; + return(0); + } + j = i - 1; + while(IS_HOR_SPACE(data[j])) data[j--] = '\0'; + data[i++] = '\0'; + while(IS_HOR_SPACE(data[i]) && !IS_END(data[i])) i++; + if(IS_END(data[i])) + return(0); + return(&data[i]); + } + diff --git a/src/mkutil/avra-0.8/SOURCE/stdextra.c b/src/mkutil/avra-0.8/SOURCE/stdextra.c new file mode 100644 index 00000000..45704953 --- /dev/null +++ b/src/mkutil/avra-0.8/SOURCE/stdextra.c @@ -0,0 +1,197 @@ +/*********************************************************************** + * avra - Assembler for the Atmel AVR microcontroller series + * Copyright (C) 1998-2001 Jon Anders Haugum + * Copyright (C) 2002-2003 Tobias Weber + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + * Authors of avra can be reached at: + * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com + * www: http://sourceforge.net/projects/avra + */ + +/******************************************************************** + * Extra standard functions + */ + +#include +#include + +#include "misc.h" + + +/******************************************************************** + * Case insensetive strcmp() + */ + +int nocase_strcmp(char *s, char *t) + { + int i; + + for(i = 0; tolower(s[i]) == tolower(t[i]); i++) + if(s[i] == '\0') + return(0); + return(tolower(s[i]) - tolower(t[i])); + } + + +/******************************************************************** + * Case insensetive strncmp() + */ + +int nocase_strncmp(char *s, char *t, int n) + { + int i; + + for(i = 0; (tolower(s[i]) == tolower(t[i])); i++, n--) + if((s[i] == '\0') || (n == 1)) + return(0); + return(tolower(s[i]) - tolower(t[i])); + } + + +/******************************************************************** + * Case insensetive strstr() + */ + +char *nocase_strstr(char *s, char *t) + { + int i = 0, j, found = False; + + while((s[i] != '\0') && !found) + { + j = 0; + while(tolower(t[j]) == tolower(s[i + j])) + { + j++; + if(t[j] == '\0') + { + found = True; + break; + } + else if(s[i + j] == '\0') + break; + } + i++; + } + i--; + if(found) + return(&s[i]); + return(NULL); + } + + +/******************************************************************** + * ascii to hex + * ignores "0x" + */ + +int atox(char *s) + { + int i = 0, ret = 0; + + while(s[i] != '\0') + { + ret <<= 4; + if((s[i] <= 'F') && (s[i] >= 'A')) + ret |= s[i] - 'A' + 10; + else if((s[i] <= 'f') && (s[i] >= 'a')) + ret |= s[i] - 'a' + 10; + else if((s[i] <= '9') && (s[i] >= '0')) + ret |= s[i] - '0'; + i++; + } + return(ret); + } + + +/******************************************************************** + * n ascii chars to int + */ + +int atoi_n(char *s, int n) + { + int i = 0, ret = 0; + + while((s[i] != '\0') && n) + { + ret = 10 * ret + (s[i] - '0'); + i++; + n--; + } + return(ret); + } + + +/******************************************************************** + * n ascii chars to hex + * 0 < n <= 8 + * ignores "0x" + */ + +int atox_n(char *s, int n) + { + int i = 0, ret = 0; + + while((s[i] != '\0') && n) + { + ret <<= 4; + if((s[i] <= 'F') && (s[i] >= 'A')) + ret |= s[i] - 'A' + 10; + else if((s[i] <= 'f') && (s[i] >= 'a')) + ret |= s[i] - 'a' + 10; + else if((s[i] <= '9') && (s[i] >= '0')) + ret |= s[i] - '0'; + i++; + n--; + } + return(ret); + } + + +/* + * My own strlwr function since this one only exists in win + */ + +char *my_strlwr(char *in) +{ + int i; + + for(i = 0; in[i] != '\0'; i++) + in[i] = tolower(in[i]); + + return(in); +} + + +/* + * My own strupr function since this one only exists in win + */ + +char *my_strupr(char *in) +{ + int i; + + for(i = 0; in[i] != '\0'; i++) + in[i] = toupper(in[i]); + + return(in); +} + + + + diff --git a/src/mkutil/avra-0.8/TODO b/src/mkutil/avra-0.8/TODO new file mode 100644 index 00000000..6be6fe18 --- /dev/null +++ b/src/mkutil/avra-0.8/TODO @@ -0,0 +1,10 @@ +- Hindre bruk av instrusjoner etter .dseg +- Støtt intel hex 32 istedet, da hex8m bare går opp til 64KB +- listfil generering +- Test instruksjoner i henhold til hvilken prosessor som er valgt. +- Støtt atmel generic +- Sjekk ut det med tom fil. +- Legg inn støtte for .def og macroer i get_symbol +- while +- AVRASM32 compatible parameter interpretation +- general bug fixing diff --git a/src/mkutil/avra-0.8/avra.dev b/src/mkutil/avra-0.8/avra.dev new file mode 100644 index 00000000..2643b7b9 --- /dev/null +++ b/src/mkutil/avra-0.8/avra.dev @@ -0,0 +1,179 @@ +[Project] +FileName=avra.dev +Name=Console App +UnitCount=15 +Type=1 +Ver=1 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Resources= +Compiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=AVRASM32.exe +Folders= +CommandLine= +Focused=0 +Order=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 + +[Unit1] +FileName=avra.c +Open=1 +Folder= +Top=1 +CursorCol=10 +CursorRow=82 +TopLine=43 +LeftChar=1 + +[Views] +ProjectView=1 + +[Unit2] +FileName=args.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit3] +FileName=stdextra.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit4] +FileName=device.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit5] +FileName=directiv.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit6] +FileName=expr.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit7] +FileName=file.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit9] +FileName=mnemonic.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit10] +FileName=parser.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit11] +FileName=coff.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit12] +FileName=macro.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit13] +FileName=misc.h +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit8] +FileName=map.c +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit14] +FileName=args.h +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + +[Unit15] +FileName=avra.h +Open=1 +Folder= +Top=0 +CursorCol=1 +CursorRow=1 +TopLine=1 +LeftChar=1 + diff --git a/src/mkutil/bin2avr.c b/src/mkutil/bin2avr.c new file mode 100644 index 00000000..ec646300 --- /dev/null +++ b/src/mkutil/bin2avr.c @@ -0,0 +1,162 @@ +/* bin2avr.c by Nick for UZI180 */ + +#include +#include +#include + +#define PATHLEN 512 + +void main(int argc, char **argv) + { + int i, count, fdin; + FILE *fileout; + char *infile = NULL; + char *outfile = NULL; + char line[PATHLEN]; + char name[PATHLEN]; + char buffer[16]; + + if (argc > 1) + { + infile = argv[1]; + } + + if (argc > 2) + { + outfile = argv[2]; + } + + if (infile == NULL) + { + printf("usage: bin2avr infile.bin [outfile.inc]\n"); + + fflush(stdout); + exit(1); + } + + if (outfile == NULL) + { + outfile = name; + strcpy(outfile, infile); + + i = strlen(outfile); + while (i--) + { + if (outfile[i] == '\\') + { + break; /* no extension, so don't strip it */ + } + if (outfile[i] == '.') + { + outfile[i] = 0; /* strip dot and extension */ + break; /* ready to concatenate our extension */ + } + } + + strcat(outfile, ".inc"); + } + + if (!strcmp(infile, outfile)) + { + fprintf(stderr, "input and output filenames identical\n"); + + fflush(stderr); + exit(1); + } + + fdin = open(infile, O_RDONLY | O_BINARY); + if (fdin < 0) + { + fprintf(stderr, "can't open: "); + perror(infile); + + fflush(stderr); + exit(1); + } + + fileout = fopen(outfile, "w"); + if (fileout == NULL) + { + fprintf(stderr, "can't create: "); + perror(outfile); + + fflush(stderr); + exit(1); + } + + strcpy(line, "; "); + strcat(line, outfile); + strcat(line, " generated from "); + strcat(line, infile); + strcat(line, ", do not edit!\n"); +#ifdef DEBUG + printf("%s", line); + fflush(stdout); +#endif + fputs(line, fileout); + + *line = 0; /* causes a blank line to be written after title */ + + count = read(fdin, buffer, 16); + while (count > 0) + { + if (*line) + { + line[strlen(line)-1] = 0; /* kill trailing comma */ + } + strcat(line, "\n"); +#ifdef DEBUG + printf("%s", line); + fflush(stdout); +#endif + fputs(line, fileout); + + strcpy(line, "\t.db\t"); + for (i = 0; i < count; i++) + { + sprintf(&line[5 + i*4], "$%02x,", buffer[i] & 0xff); + } + +#if 1 /* hack for AVR assembler bug */ + if (count < 16) + { + if (count & 1) + { + strcpy(&line[5 + i*4], "$00,"); + } + break; + } +#endif + + count = read(fdin, buffer, 16); + } + + if (*line) + { + line[strlen(line)-1] = 0; /* kill trailing comma */ + strcat(line, "\n"); +#ifdef DEBUG + printf("%s", line); + fflush(stdout); +#endif + fputs(line, fileout); + + *line = 0; /* causes a blank line to be written at end */ + } + + strcat(line, "\n"); +#ifdef DEBUG + printf("%s", line); + fflush(stdout); +#endif + fputs(line, fileout); + + fclose(fileout); + close(fdin); + + printf("converted %s to %s\n", infile, outfile); + + fflush(stdout); + exit(0); + } + diff --git a/src/mkutil/bin2avr.exe b/src/mkutil/bin2avr.exe new file mode 100644 index 0000000000000000000000000000000000000000..3ea5d5131218f0026f2f36d2168ae33fedca7fe7 GIT binary patch literal 73774 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 C?7l$& delta 11746 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 KYD|JG_5T1LK;c0E diff --git a/src/mkutil/crc.exe b/src/mkutil/crc.exe index ecd79d0c4f92bb82530f581fae061d0297341a42..e257bdf65dfdba0800ccd79aff2a1e30d4720198 100644 GIT binary patch delta 16347 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 delta 11517 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
      tIEC21PmvBHoCZZ_aS_b(2&WV{{Bd@^ zAdM5ky_sC|NScLF$2O76mUNHXUp6t5oN8X5hW!Q9mJvTjQy{sMQ+}uhYZDo& zbLU_iXq(6G9DE1()HLaqiDaMJii-~6AdmNWQt`3xinK`gAHx}bYMDhRJ+{0RoBujV zkiEhZ+z80C2u+@b+*D3feFBVAy{75p)3;>_%-=`M4`Vry2jGZ7DL1S3 z>Q?NBWw@kBmY!~3`Oju8B`$Z_ZBB6fc*##voWxl#3tCvK7&J=aZ+df<$HlX1 zz4)K5=(id5w(Mm~)*Yz}iI@(hEUN4XDmV&<`A;|eEj~kvH6A@<jKtkZT~)q_TLP<>e2`FCXK__%qcb4vb`bT6weooP233pS4*CrH5f;(&KBY$4$bkPpGdDsWiJP5h(O0%y*hyUQ#>Px*Z{E(+4-R?fQAn0FuF~ zYtdrCgMklXU|a<>wK{NCy6JZR8x6S3vDJbsVkQE=d*x6h`#>B2ZMlAtbj@?ezW#~t zyH}#7C6QG_9aofxqQ9%dFf|Oty&IghyHvL8Trf{_6mO;9GpDv8zZ%;8ELke5dRz)0 zT{T6w=Xm_e=V>D22qzK!(W6!1c%ud_FTLb%!mxi@HJ%~Es@zTy44bccg+0KejqDX8 zGGd95Y*MG&rOvOs@=7elmVM+HFRsdQ9)WmF@>WQDDuL87Q%cNhmS+CLoy5ZuaVVr| zBndKM=gTYZVTeg!h+*lHzD;B}Nec|NI=-`}C1480y( z#fP}m{x@a8@ileCcz0`e?@J(~)YUgY>sVI*oARJG-j+j}AUyVYO+&+RzIXMM3erWp zySt_%r>;)opTZ8T-8_yRcyimAkxtz;S94-Lqzi28W=?K?9e1HdVv`#eGTWymkon`+ z2LW?HB2f8*kcBb)rxJuV{*g7Vf($R#!Kvd4c!IsE+^lAM6pC(9SF2wJL+PUVXs!o7 zjL&*EijAbQjK8>Mx;(?nC#}^HG<$7E9uX8>L}`GAz;hkY3%CsU6!2HT>1BN7+J$M- zkRp++2RHy8FMo3F27j{;x`;Ra1LLhh71BmD8;ol(AHpg*qD=aGJpya8w;mio>;t^) z12vL54#)B08SX;uC&4j|gbG4J8KIDEa0Kv7)Ou`` zl>K#LKObnB6Hv%BS+B#Rc!e1L<2S9b76>c;Yrj&U!+HZi#IIEZYf(4=YgR~p6;?=o z1tNYWf?%)DfKCIt0BwLHfWv?Tfc+~Zze+=jL^8F~O{oDnDg{gJ*xl2uXX4E zjRDZ#UPVU`1e%I+Q>Q>4$y9TjlDrMd>;h}G&a{&+Q zkz#E6F+!Jv{=hfaaw|e%oT1bKQ#3QAtg zk+D{afeQ#;^3!bh&$AZ@h|lFmMAD^vUjm?>V;&GEiIQaNf#YQyz z`{VP&eeua4I2th&<=GIyj~^JkHv_p}XASt2oGzcPYK%p@52cj_?MLJ#mJsF!! zd><;dRT=nJdmAn>yR0a(l#3hL}za5Gn3qI)m$R_D3DqFxhs6ZbTbRB6GYqo~LbD zaYshTAKg5E;z)`W8xG2mFzMtUdAJ~aTFk40USeLpRL+u0y;Pc{lB8Q=oMoSR0dIo#k}p(hfXSMq;i*3)=A|asjQdE zeNy>?RPL9`2B|zCl?SEruv9inTY~C7}%+Et5`cm5+IKT0GZ! zp&mbi*7Lu6<4<8FVxL@jE<78*2pk4R=0ep0V`rkufm4BJ0gnY%0gnUzbg!Gr06qXb z5x5F?5^xc4Ca@Yf3-~gI+7A3z;9mfD0Y3?R1bB#|=1|S3kVLWp_}Bjb8oqCKQv@hJ zw_{w3y5qVmkvuwt zSpdgnYA*EvD&>FxU^8F`pdQcwXa<}Fd<3`x7`Tjo^m^d`N1a>T-`2@m60hGJ4PR6! z5jXpuOOWM;eWs^P4W>Vt+DxZRpO`M0zA+7$lFd`i2D7?ge8Gi+zZHC6ptOv&WLxqq z3oRuUpXE`@Cd)QUwWY=KzU6}DAC@uJN!C28$y#XD+NRjdwg>G~n7bXD9D5xH9ofz= zTvuIRxvshX;Tm-P;G%NyA99EQnZ8fouTL}F9X6~mtTk*k95DRJ@V?=)L1xT178oBk z{@nOW<38hC#=jXqH-2NBO5aVF&@1SN=*@IB{S>{2-b-Jm`{)~Vk}1WMW}0lWm|UhJ zlgG5o^r-0xlfyjU95Hv8Pnpk~zc!l+3JV@7*i>+=;4CI&urQd&5{ulbw(hou_gb5* zUt1Zw&;F?WU+qoyWG0=N&dg@qOes^rJi+W@o@Wj*CzvzL$IKVZAd}=sb4+sNIA%HK zIlPVs9nU*nc6{mRcTmnW=Tzrhr^#t|KIh!;yzIQYQ0>Zdt#GY#Rk`Y1FSyRTC_P18 z$Ly!;?fUKd{rV>Tk+A-_{vG{U{RMrGKFKi7kZs5_%r?-5g@%aXTZ7t|ZcL%G=sEOK zdM*7p{UjZwkI)q6XxHT51RjE ze%+j8(O4d_Y_ZI?(pH<*WnE$2WDQ$ut$VD`S;PCS2dsyzf3cphs+mbl4r6Cr%md6) zW&`s$vy<7!{GNFU^KXU)K4yBD7;}xe$;ce3jtP#H4w>`o!ofnBE6p{@rFU6ePS?Gz z64w&fa#z6hgo|_ScfIKPi;Hqo)M?Cmg8nGog~RL;eTDu9eUlz-8gI%En@py8riG>w zQ<-Uv=}A+KsUG3@Z>CmLyXiBN%lxqAHOqUJ&n;hBzPC`;OoZ7L>l9nQjkeuyTVvyF z&)HtI{lV5@J8ApC_J!@5t=~4xad$iM>{t=pK<=y`SZeKh3$o(74{b1DEy)D z9#_bPX?U=aA|LA4YvHUJ2B+a(gU9fcq2BPKq0{iT;Y-7HgJ@71)kdAsW^@_vH!d-* zGKP(u@i}9I@sRO|@wo8^V-l^VQ|a;a+%RpX5739`Zu&pyURq|FVw!ETo9;stZ!<+q z&zoK{y=pp&rKvLKn5UcPnoVY_*oV&@)~Bo&Y<;#HHqoZEtL$pK*}l>qvRBz_?7QrB_C5A``#$>% z_P^T&d#}CEe%-!;d621Le#Puz>Jd4AWFE-74H_(b37 zr13fS$ z95dA(XQrL$v{LMK?9>@L9edLt4&bHZrP{HrZ;P$%92?tGuc*}X{q_l1JD2aT@1HNv zv-WlEwfA0ot+m(Q`@ri#)$2j^7MnucYM<-cQ1r=*mbAZI{t@1|JQn%8j4xhh5YIKd zCC6pPJ(sP>zhijkau(t;mU!Ip4gtRArru#4n#!)fHzB#YlrOyvq0irH$tf|@RDRU~K(3W^?vdNfNAT9v7h zrX&TWQEW{bA2Z9l>LD+xdISW7^mgHE#l%bs9m~CtA~d`Gmy51vtz6+{H_^ck%6kW^ID8#q@a)C6fcGdkqzXx-oQGt=kcsfP<6UsHwPwJM%_ELG&V)5E= zisJUGo1J}}z3_;zR;O3IFKpG#R2&iZ>Lw%oxo)=Npb#_4gmB)dIlhCr6yG#(Q39@SGr-y9P7VA!LdMGbWPB9n7pH8Dlt8qYyK(T$sLR=ON*jF{z68 zgtucRDh>%B#Z1;EDDx=JPC|+u>p5{q7%_U13Rz+1=(GuhdEyf??=($8HsaiaV6b*i zG|C0<=&5NM%#^doBBZ>re4L#9T-)*aNWYv8MYocoj$U1xMiRP4FP==Y{-$2S*8mBb zXv4u=s!qfIisbxphJ!+OY=TY=v~?&vFBhsMVRh^>c~F0gO^qd$3^37dcq_@Yp_MxB zcbL%jIOoWhq6QZV(@`H5F2+q&mX`_>#w7XHN4n3d*6Bj(Xzv=TaVeAGm!UgYu|5kcBq4 zk1MvX1O;}KS9p5$&&P52u+`58K?sPLp6K*97L6pWJ#nm$>|>PSz1xmPJ}TT-5|ZG2MF zkzA_GEpCKe;rj#m$?+~A#k*x4ahLI@#6ID}@kzS(b1Cg#)p?=Ce2<$q+uj$3O~_U> z3Uek*QErihdnaT~1)WVJ+$Ev~e5j}h4R5ufO^dpGN*7c`&3A@Y@o{Lke?s=KEtris zLf0OV@F&I3X2ejGo9`Fj8AVajI-N)%2Dh7n8zZ8xWr9DZ=yr-q@bVJ zqI_8rc21n->q6V6UjjoC@CtS#-)=%QQIz+Wg%$go1J24d9bcI#bD5|(Fg6poKB(n=- zrMO%yQG$}4|#!ND3U1v=$xThf?9s?gRkIut~g*zv0j@*Ui(3A;hCQUFE zqAj%Jgg?#%M({mhf%Hckkn1=@s}B03(@0X(wM|D{Ly7xh1cN@-_l^-Pipxjyw*6Rl z@!<@LYV!a^oNS;dapi0TU-nB@Q+;Xfq8vKa0 zN5%ruw@6eBVnNKPPI+0#;+9*&Yq7rJ<`y(()y80GM8nNpBz;efqFjpDfG$^GEzoEb z>|)N=}RaLL>wzDO1e|294S1Pq*wF`!K9L@;4sJnO5?ViT2 zG-NyaVU~vZokz8g{}%EsB{xl*(QchQTY(*J&6KyW+f7M+NGY0x-zPtT%*+&Lw(BBR zgdO1a$2NRbk7;^ixs81kJ2KF;`v>T^6t@fr74CVurOE~w`^)b_q(xzvWQjmO`rCzbp7 z3myFt+*iIyyt=7Zok#KNKCWN#s-e&-E=uA$^m7`n^#XOniK@HR{B#&%$<)fahLg5iLLc$WBi2aWOD)#O{kmOvjc71 zQrr?qPm?d`Rr6h;L{jPYY$r7(Qk;ua1+|TT2dNrmc^e@@^gEe%CV*5#E3q;X8!N%= zu^Ne`v3R7-x#vjV{R(ZOqY0>q$@(% zWND`coU|+89B{csLp&Cd>=NElSRz_t2SjhUD5Sm3Os~Z7st$CPlwvE}kQ~d{6Cm$e z?iZL0-|geC%JMxakRXe9$5$#|btT`RR(RKxiA!NpA?+1j8z(8e5uBuC$J8jrd=%Fx zcu{1Ks9^q9;Y}zLXOlGK>wcLV>~Ja0gA^~q7=2SF{swlLS5?%nG^nYjZ@f{ZV$3Yy zhjekUez9DN9*c;zOpt`jvnDGK-xS8p&Qn$ygk`g{l@A+)r)K93C%U|;s1@2Od@*~j z3Rz)>!KutQ3Tq9qN=v%%3&TteQPF_yNGM|O%NK;bhPz^Sg0MfDgq^KJp)fN&-Y47R z8j70=GrkrhUEN?Qx{HnF3vEpYywR$TmcsGPBU^GOG#4nUh!XEki^0}1FO{MKO&;uP zC9ZBcCK@EgZIEZ}9nZb@5bBidDDJ)ck%*{;Us--m32_WGo%lwQJX>_oevi1z2gQtg zNN%NVJPI1dPXYmgVfj4?y`x(cwiO#_+ao@8n!Z_)XBo$S6DCnJ#^pH*10ZfN53WB; zhigLf15GR8pLx{i&jtJ71%1o!Nl_p`!rQ3+ge<9Zg=x6N7fnRkpt?CVX)f^;_FH5s zyoOx9#}e-yS#M=nb@RB8JfsUX!%JME2L=Fw2=VkLLVUgPFfHEEL`cP_K)HV7Kx73> zNl>-)K<SLs{W{_&j7A({2kwWEy2Qv=Ohun<)xt0xE69mtmtl{cy^|`WzZg6d+!_ zj)pM5+95xr9?jwWfYE~v5L%b9t4oZZSQGO>q?DgYbYN3%Yaw#Hy&0K+(3(EkC;Krc zxvto`jEuSA?~<9|-12cwRxS-qBfU=E+mC&LzseWrpl>5RR6SGxu0bE~L5zYp3cGXtMmn;hHl^VvA+~B>HZzf!|)>bS06z+HE&Q`I=`;_py1chKxY?z+Bi;yV~aJ%8|nP+*}_ zef5K+WxMlzH>23;7(&vxP*Pw)uZ(f4{+ZqT(E=Ee1fxRD7Y*>0nvjabB{aWOttz_Y zze~-RYA`AuiN&-Z<;Q+9fXaUE3ykYhc*{*?`}xZLjvMM4ho9BlQRQPkU8m$fRTcH~ z$3TR%WIja6hs?*`d&qsmgKFkMn$6{I=<5>p$m2is!M9gGO!Dr|zqwGQW~Y*&rH3X3 z?&y`P<;pk011I(J&>zImL5k+*tNn|@X*EBe_AjD+;5;T&Npl-7Q7p}TtZi&SFFe@2 z?3g;BIp(iI6WR|7i`0HlSfpka(d_aTa1cCgF4ErYXhym&rGBFpuHr2gV^~q+Zsh{` zyYr*sLo;L~-H(js^MO{OM#0-;ZXbLdXq1N@rQ@9g{z!kmVSsn`Nwl`UR@an3IX8qKWh~5o8wY)ZG8jv9eu~RRtJ+JDE@$sjaSp!GxjU&d2`PiSSo* zo(gIu+%UJ1xV<&=YlV-XvoVlJM&<`QY)}(X;->?1)H10sk!U?|-DO6J>0k|ke7_4L z#uzih~cZNa>lZtn^%thBO<54I+Fp8Z6->43UE+#oQ_)F7V+g;CbAGdIhP{RJBM zV(WCbXcAswvmeVXq9uQhf0J5@03(D_Yqbh3+W%^OMkP;!tZe74mGw}$6i$R%RiQ>U zy2XPgSDvQK=Kn{lypXf!`!F}frn&$3CH`+KJZqY~3x=0>ko{!!8qV8bxn%Ca*9Xsj z8;LplfSgNc zBXKCsAK6M0{sOh%OcFd2hQQ;bqrfkp0v&%rY@i_CzewZXr1KZh#&6#G9;L?P+z&eK z@Aoa3a%_Rquk#mT#cPLc({B4ISis`+bNBIBtjkEv%297)tB1gADOzZ3KtcDe42*XR>@@HPSB}^x{hm_ zKz>g=avJTMqZGROB&xweSkmpwRTJ4@$4U`o@|>N7IMdbW#2s)UD~RqD%N!=lQ^vb> z+;#An9DVssbl{iqdL+72yErkvqhHn0t5NM^uKAqiYzdBP z17giBdQ(BH!8sr=Q8&$O?5{l@rjp5+$+*37=jMXlemOH^l7AC@ZaNx6-*AH9`#B#j zG$T2mhJx$lVEVO<|G@l0B44c`g2Z3sJ5#T6-^O>`RCRo%QLWc;jD*9<#sS^N5m;`> z2$tUa9VS(y1`EQn<;KXRIN6MMX`6O~Agln}?-sY5#D!TYZiX~X$9dnOO@;vUw{)Ps z`4VuXfJ^On4ZKYj2Rb^cJ5OF8nLk_yEfo#0ANuWNPJzb>@0p%D4QG{btn8pe7nq(2 z!6_a7c^Yhi%>}f-nx3JWQJ@YijHCmslfkgKRD+Rw>E}#gw_Zp{s!e9aBlyMWtTwk0V6GBlA5-`_r3sSjA8# zv#)OS3@7QS*2G^7{Zad7P}LWDDUdKG+;ATn<_$F@Q)(U)D4_2rCjD|r=jbbTt*w{F@XZeLxjG3Ym1BH3ZN^|naL zd(A(WjP)L{e=hA;r544aBj*6t6E4)i(0cl~^LlR8S*j##fXe)(z1BD)UaU%Tp5+(l zxNA^%^4`F$5&@Se{-eMgXyy69qckyiV`XPI$~s4*Z6aDDIWL`imh@o^JVAt*`CiKr zKe65_X`6yb7!M>B^(PheB^3<>Oj;jfWFsYKKW>mA7HpIR57jx47g_)fVO(l$fSlyG zjX0&n@%xy01KQ0^C;)c1vmXbSu%RzjXy43Keb0Qjab&%1EXA(TzUduD&k3F95AvnG z4cEvxHVE*;8JaByG0J*lf&8yLlQ+1s~IJotR|s!#nL< zh@7T-q|nc5ZkC5qYJLb^s~HGguDKEVzUF%9o0@B(b2a^;FL~$L@V!?Q7rZ*e;IQ%B zPvx~&<(U-muOwphJ-Fd#4s9fN*5k3@S&Qr?8NG+%pJO z$K1@pjd20f{M2Is(_f~e2$wcomu3Nbm51lQ0|oY9;@y|LkCF@r0-?3`Ew>dlkfKWa z*4v7FjihXWUAV1`EKn%R9=NUOF;bLlf8w?xa&s0MWykUc+2P?XTTmp)BdMXK4=Vg} zvZ5+PbIWO}7$vZ3ZDf*UDWb>~VVv(NY~M>OJNYHaYCd{9#%+z$BXsX3p_j}Tvn6RR zsDUD>tvdE{Kr_E8pb3ytrh^oDVci2w*8OkMA{T&k1SHWELo5_m_w$CW>SMq|{2?@(2ueG#H+=ZsR zSmCU9*u9fW#TjUXJ0X9hjJ}$nmr0r8Zx12Cb*U>Hq5GwSdo;PJxi$VAjDOE=AbZr%cyi6{1*clcYmeW&L=s+cro{N)C!^-} z$1@i(1X|pGMCf%+jw0_o)m3d4Nf=R3pz2WN2}=s*$nnz!y$Q%uYHwuon1WnM(V{~f z(rVv4e&sQO_^WvtdGF$Fy9BpIFQY#kkUoJdW16fH9&jIX(F^e+7#I{4nl8od02bfR z+|V|DjS{&|pbKr2aI;Gt>n|zEEh%xiOG^Ct$tLL^yvT&S8KvTtgTg(9NmDm}OjxoE zJ`ezR{M!kw&QJ-t?pes(Ao2n7!mEW7E1ozwxIlO)x)K^uiYJuVi4^fh;JiLV+I5BP zcjZ#@5_LYGc>5kQN^wcJDIRI)nhD}oviyECxgo_xD|9ny{)BjvPYqW#YI*A_=-c({dPo&u*Ej8C1gsWiHVY&iF|68*=qDlt^#x$DqSVE-?-z z9(?{XSm4<#9pz)d2tBH4akLOrq~5^T=ZwwT$19*GD2X2i15TfZUBwPcgwt@ zWnRr0f9%Oz%? zCM#OeB(V!alZeufAAEj~8GL^K^y?u6hZ|eUZ7=TRFwXjtIs41t0Og(F7DFe(S~)Jn zL-5IAxTzz2819A|b-F|6v0Gnum({3@Qk7MH6Wx?gwqZPG?gIB_U&+;Q-e{NjbP&zR zbB|&kcQbawSQ$q$?Gg*{kS}K{xa3__0b`c;`wj2%=z!?ot)K9EvBgK;a(1u12!)}& zdML~s`>9JrVYq9fYZJL^$?N0ELgiA?P?AnwebNimHd4^paP3``)y6bjJBT=pMI*Hi z+blsCLs~%7xkHjsGG2L0whanQAuF(jSTMN330H*Gi<47ix+%ki13xw;hPS=50b}yH7Q^t!bg#pFfC_Gm)J~Mi=#@C=kABN@x%NH z24isPPhPEZDSTo?Hh1uYXn~uN4P#kdDc=DzL0*tSm%OkEYfHx9o&E6=eR-G~r!h$X z@&@)3YPU3`F5#!@L0!r3P%8rJ4zG%*I&XhMlS_!=61^A|pLyQdruPdGa~l$wYN+@8k$I8}eN zUJ^>m{un)o7k>T}MwUC2Q%4JTmS_L?!g<^3;sz!BwTFD}7CmnZe=N`R;joR{ks%O? zpGLl`fyv>{Yf89P{cuijGHaO>Sg-KoI}Lokh;3^Ve3{M~JOib^Np_WxmX9W1AEB^C zorh<9a4Di?VnOI={f(Ju#YS>PvC2?H{f$&M66Gl3op{^QZuV^kFUZFMjhviF);{qF z5;dr-V3X@_7`##4PTg>fDwNR@X?w^UZ7Y|Hh^B@n`HOVcA{{#xh-{2pueO!5bW4?@ zfOG;KF&@9l>h`KY)9<`AIC`9kH)-(6hWNl=uvcODBL=^nTFdp~TMI9(-E)XLX9#5s z&2|L*pt*m!4RtlIUOS~5s0*}vI$h$oqwsDCg*lhS6zS?RdA1+(r5W~8Z7fXo;2@ZT z>j)cg*n}b1slNB)S;pxbz%i~R{@hCJlYCJu?k(`LbESi3bxp^;kuc-9BO;3sD!S64 z-VG!ln}8Q7HitW-^hPz{jD{oQ`lzM@Y?{^Czi!$UXRIPDD3eixy{f2R3XKBg`ZLNa zA5A!L^&?e}zo;L?Bgoy7(uW30FU>pqubzTHBMw2l$<3b9ZyCJKs8I}w2Z_Zm@$yGR zBy5KRbEKu6fgQ={jS8$x#-)1;9$ZWKQyslDP8;;qedPTQZ^6UoSU&O|YdqjB4i~ZC zj5t-s`#L+m(78vP;)m~*ZrZQ zkVwJO4PSwBJ-ffEdMVk?=L}d*c{3Y>-tR1@z0(@cdjE+Jx=<8{qSGjfMA3=RudAxV zL!NUJ?K*vdIX{p%FlT^7WKQHR5MP$GjKT*Dy2j()H7yS+8n1Zo#Cz<*xQ>D)PWt%mDWse14s)^-nEnB>4y zsNRA&fyBE|b{asf5vnStDVx^_k5?p<=(URY6hbI4pYkEPAFvXz46p>S5RebBtr5Pi zD2$c6lnCYRfSrKg8lm8>l@3hLkek!ah^bn(}1&p^MFf$ z0e~9SWA76lTUr zv^a4;agjfyQG`8!X6J~o6Cm7Km2Mz=2f0%47KI%3t431+=V-X0CE}t>vXcd`eoXzw z(c{S{R(&O6-Ed)7Rig5hpm3zhrqbi9>5217UO%Y zj<3|O2A=J|B)nBUDXJIU(Obx|_DuCe-%d~gamv+3=!soO2Hrdml)c-Lf8m9SHjt-Y z2$kmL)jurZEK>-hhDZPUX3`y`0zV8|j&hUYNCFOca@&%uu0d#r-SEoFtip__Bq3HSWe&b>fR}VQM(&oQK5> z*Sc?2yCpMeBp!Nu5NF`uaXjQxvq8MJw}r&J$NC79bS>K=2+8IxK@1|4aAlv;s|)i_ zPpUvE^hN!4Qc30Js2$Dq zKeB%05V@ZEbNW#45HTjLt9B30Uaf=`X(2-h^v@5EIaSMRx=WgwO7t zpV?gZU+htB*dC!;wnrr1g|gECsxEAg>caM@E^Lp0LF^Ht`vEHf%K%FN3jz56TV2>5 zA<0WmA>0nw2?*AO?GgK1#(t+ffusAGV!9)JoFW%*RMa`BP1wct^I9QWQj#kP__Y z@k4;CFG3CXvF)#{rWL+#U%@)cj(SP>(CjX&tNYIfmn-?{aM;~0af%o|(~-;3A;&s& zC+R_UGZWy;i)1pVxEu0Enzy<0Q7*CnOY|7h^TWu8d%hn6_%IOHRJVVxce^($4~+}< zlI^mXvu}anq)OOCxJ-~@?dI2^^N?ii6EBj4s1IMZSJDkPD42td(}!F;O^vcdyzo4F z{?QFA=X#Y@Ftw!n`^ZQ15Sz}9ep>rx&z1ZIih6vPwrV)ljJKo8s2XJ`s(w`z)m%wF zz6%r$)F^N>q$5=r&$q z62r%YI1H5U=F4HB94?eYmmDsU zLvo2Dr7V-f<#M=E4v8pADfj#2XssN2~%-F(}>`Tq1 zx&T8plV|2qQvn3)L&P5gs;lQMymL<8!sdChFZx!(F4DlU zASME(K}^n+;-5hW@wNEQ2C)b6Xv8+ef6ArCBi?}+mv+?sh{>5h zAMrzoO^6>xoQ(Jp#IcA6C@PK8Awe7)3h~W#{~1U%e(jF-t(wu(2bYGFcv2J;{={)> zQk?J96a}?tvVyuBunzDTU>o3hz;3`nz-hn*fD*VdfQf)v02{ysSPiHLYymtA*a>(W za1fA-b|PXm9K?wL3%~`a0c=QC*r?4&{1&hiup6)+Z~`C#E&-Gn>qtO6AQ_MeC;*hF zDDbD6#sA+=K+x|Sh?%OGx5``e^OfxVs|r^%vn6DD-Bia!e-onzbgbbdKPt)r;3Ld4ONzJKOi z%}I7Fax8IBdWzbQwI6SoWUv_u3`-2vhI&`RQmYztaMlU zvh;h?*QM8|FV0wzu|DG^;|kM#=0BT1Fn?{X&YWgVwa&I0tyxya>afnWj>=BWwr0=E zUYxx;`~K`lvbpSS*{@~4n|&nvgfF`XuHF{!oJNuU{A_c@`$D0!dtdjp0+$|`J?3xOTXn= zE6@Czd6xMT^H(49K68Tkm^sUQ&3wmPW+H4OZPRU5o5Qx)_J)nh#oranvsqzy$gs)4 z8J;veWq8@pZupzwnBgt*Nbkz{EF;#KV9YemF)lW4HJ&kEGG>@oVJ?2tv!)}a4^1J{IP(;9 zzPZA@&is4xAIzuCpPT#4QJMP86`2P!&t`s;`6ZSi(n1D5&$8IE%Cgz=JInuCzPD(t z6Cjcct#@13Sl3${ty`^6TYWEC-?5&wUbkwpW3ne_-^=`*Ilz3tl-O3-Hrjq`+iu%w zJ8KKswDtu1bo+Yy2D{(>JNrxao%Rm<`}Q;T@j0d(TTX4xFLHhZQG6ewcrNFMoH$38 zV;*$sZbzNt7mk1<=r~AtKvBy9;DXAK0u8&HgGJcj(n6W(L-i%) zxPD`K&a%VuvSp{`q~(Ss&YED=Ta&HRt!Y++)nv6;AG0=FH(R$@w_&Og+4}5h*=gB^ zY*V(cIQvoP;v3n!p^w4r{n8OAdtZ_W(@H?J$>~QRI{ME6~an{l2 zxK22*mZA#5fe3@vFb=YCx6g3D;X%VXaABL_w}z;6E#x>Sy*Pb!dSm*N(A(G3k3yQi zO&>@fo)McdAtNp0p^PmVzsYzmV@Jlz89OshX57e#gS_aC$;Ro%G^4?2GFps}8Jmrp zja!V{jMt43;Mg=Mw83OD6`LM4y=HpDwA=KqDQMbn>M>OuhGvg9>&?mL>E<-^BWBL* zH~-4~TQK$y=63U2=Aij+<`2ym%pSm}LKEIK z1Pwig!v_4t@b!}u<{yQgptc{ArZUtSR3E$oO9(?MTS+Z#a|_Md$HsPPbrCl7`M&Qnn6^K@uh;kc-)CO0 zbAOzB?z#7zd+xdC-e(SUNDp*K8f~J!C+)N69{O&cW^nr*l{X=)@)YXNv4+YYkkgGh zLatcf;Gjl+ebnuu(V|fl zRR=^(6nQEQxf0OGP7tMuDAppHDea@EY_?gHqUZ+`&{K^RmBRjBoFh}8qp0C0GbXZq zB6(gQIMTOnBu94RmrhYDXRNKd*MBcXb<2PSi;;0Ai6`W1^r-Fzq>tptZv31S)iL9N zXxAz-dLMvHv4dhC5s#05F$QJKOu+S0ZO@7yh8 zZJ&F9tx=|ne#btkoGv=R9#&39`Mh$bXfK;E#(?zBF|&euofK0)e4Xc+g$gEd%OdWT zIKn|*-{GI++xai8O*dKtilefcb|)pmWFqr@yZ?o<`UWNV?D?101tYC79fXm;osCb> zF8~#{S}q9SJ4Gr>M=I1lR2Gg@45Z>5snn2)K3b_3ae2@W#P{vr$Nn-QM-*h=Oqe9v z$9|SDS-Am|rR^l80^@wA_OYYKrb$p`r;p8@NR-DtA?Qv~-w}{q{2AnmefVO*`8?cF|-~4b}G%y@p9@jnnLPQtK4V z)1($sY4);~#1v%}$kqdSNkCS$v-c-17bf*yVooAyw1N`-Zfho$7W9&;{u=`ARu$jA zI(B5CAdYlDds&qwmd{})CZz`VLztgQg;waqFA;RY#1R%b!aPE8K9p%YSwJd&>qV>~ zZ6_%C+A>B(bR-eR)pu;0C8Y;91PYlr0W0*@pV(F+qyOOv!9AduLm%PVG`Q*QWwl85)K4~+m)NZzIe2M)CI0VM< zezlxe<(_j=E?$+5jILEHC^xfQofxurfTSVy5FxZRXGghCX5!Q*oowNRBs;;Z`>w*L zei2+#p2r~5Fo@Ud%l$17*)IVxUO?1;zAT_5BZY)fc~$K>C)+e3BjbRRD)Vr5xDjSB zT%=BRfhgI-4FKUOW6p4`?57hll)rOQ@vln@Ba4_G4`a0bj*XdU5f!nsCQcFex3jA! z=4XM==FuKEXM!HQ-pFmuHuTvhT{5K`TSdxrMOHB?^gA-q64MW9xDVsoWGTNFO*=3K z12KbKA##4bl6xGE4BD>m*d(Km^N|E*P6`w`+Qm88zSIIyGMheWn^^t^yMNM*;DQ7S zTJ{FM(06os7zk%IUirO~dUUjhdl{=lno{Zq0+MP`1>GG_f79=&rg-C?!%m7T%6t|reIb}-&@@k43JBF=EPYk}C4cS!& zbZ?PjLAf<|P*h6~NH|p{MR8?nB$-1z-@FI7mY0yYc;ilFym1GidhD;l)I!Au5Cs;|w)#`3Qtq-aDJh)PTjZq29IJtg1dQ zq0C}Sb{iHXFiamw-11Ewr1U4!oBFB1?cw_NYuL9?J_x*ZKdcTUz+i5obKBTUnG;2& ztUPOp=s?@ONE1(Db@;#$<_z7X;R7AmJtcRrAKmetcqo%Sl>K1pswwculbw_Y@EgEq zfOCK(;D5^&P0bMR%wkth-5aE^)}HFb`i_b~OgkmU5jo1*y(xz2ZXqqzQWy7C78Ksn z3WFuKoKY?Hgp8z(``{-H^6ClPlLOdy`uE#wpmIh}7!SzCtsKw5hWJLE1I;vqZnK$Ks0 z@i+$VDrGKJ^S+m&rthSxnkoETRUsHFw#}tvx2G($ifiseAN}Xnu7D#9%fu%1`1YWW zhgTKBc_<$UXNBUg+H5q$Q6kp$jg1J07AaADLfEJ3A-R>wcQ=ESF%)}15PwsT_f#h6X zWkbhMai6uzUl}SN4%;Z^DBU4Z4|B62CPZMagaT*F+#c>E`({qAKn_|AoapjkXh9J6 zhnz__yg*uRYSjhIFEFR9tXj0pEy(*034c6gyvikr=9h<32~A{jS(!U3Hrf`9h&>s! zM`ffP_CT38C2l68VgB4Mw0OOt;>6|)?dA1eNrG#|557nva)DLrdWN8 z)ag;7nKPmC3)U~=x9&u@(5B(AbYfKSvuZYBx_LZN4BYNQOpy|p$v}}tD)K*2#uaC>{0!By88EnN z5yNqrD0r>!dHpG6+;~!kQ7jik2;9c2mY~FN@F3rnaa-U^8Hu;9N+YG}zw^hIa>K+w zMpSTEiF9Ti6c7E^wzH4SoGc#2v+T@5@!U-I)0q}=WhR@TDZGvBzs(DqvBTJM&1?y( zY>TEic?NvAHzH%^$U~#}^~wBtIq{2=v!2pUSCCB>wjGbi4%fZHnzc)V3SyXXB<*Ux znL^?5IBKMPFLt|M3b)yXgH7L2O___-avyP#@l72Ntx6EBg&bsl757`{3tKn-#>uu4 zt>{O(yY-)&Q+I-_l$lPHy}77)H)=6ZxZQ`I&%jK6rD*X zg|%yGnux+tSshY{hwja!C9J3;6J=Kz)xkujRKYBiyFE;ylKETC&lJqkVfx+Svd+K6 zGk;)yKK#J@Qf!sGh!JlW6=Cd9`IXSZenv5Npi>lDI2Z_a4oRyE=B)@VR9KI%mxMMc zm<3~{)&*nbfw{QP&_n6#QVwJ6x|4qmFAzzup3bOkExH~X$ib)?=3qokclM36gM5VK zQ0ozN0o5o%wGjcqSUFQWRvHqDQWWKq^1;wXIcCHB(8){hq4|RKlInsL%)(*%942-t zzJ51YCF=b-p}Mxots=l;+bL7RF!iY(RNk zX5FTE9Jp_hi89AeMxeIX@juqWMXg1#$&sl7kurQwpU^_6g7R3e6o?xuv{jgStcihM zi~B6=ZL=IC36*TQFRD%C?^7s68?0wUFb5R zo>-S$sE+h>D(O89M}lA#Wz0C0*XPcTQp{D>ZJZ6Q&?}|a1q{7G&Ii`GVfQr({SmNTgOu^KP<%l%-IIQg%VJ+KbTrb-qvjXRum+i z0tv7>tDvGl%*d_;CL|Bfk_xP%OybDK^pxp&YiB?cE(*CYYs8*p8f7<}LJdT-9`)Z# zM|ZKX)kk_0I^U5(>~uLKj&=yg7`6!EH#^2QZu%Obb7+nNhunJQk35OG;E~7Ccgy*Z zBeYq{%b*Ol)V4x`9&NANc1i>>$YOV4fuc($tZj6yePpdmcon?dNTZbD z+P*Ug*+iRX|NpJ>7ZczFZ!GbM`pN2TxnzR}6SRjQDrzMo`sP)B$bvIMPWSK^-xkM1 z>Qtg&J#V%X<*Y1Bk${8^7M7E|?aRVUv4k|l6y2o&?~)SuP-FU=&bECE3?lIh$QE5NAyNF^V8tRHMrg$?s^ zJ`NjRrGTQdD7srQKX8?y7-KCE_Fv*ji@f}h3JnI48hhg{s4WClZh!I?RB$W7&9}3+ z;OYq~-yXgN^%y~^?N8i-B2hVPdiEdL|#Zs%5;aq+PzL{RtEkaR?Mpi zE5Zb8?Ib8aE<4e)I~^XSf9Rd##s4Msj5g$g5+y-v|q4CoD{9esgIVckMK&IB#)Xf!#m3lv|HZ z)-G>olt8|YkeBg!+@C*1f$o-iCD%-8f%nUKVHR8`2XrWvunSFEQE^nJ#8gH37=9Ts zWEdNXJ${_O74v^55xVk8Vc;atS3^_H^!+mbz_eh-9gc2i2%~ryzE8-@Xl?B!xh&6yc zd(}P3d-ju&<-omoATqiXSH>|DDB=JR`PY$t-Q<3|qN02mxp-eHA|bJl%#v%4cEzPs zUOkc9g%yJxl6Vp(ik8i=SHrI?DEnH5{$=gELD$b zA`>5^dEP$`VxSBAa_Nk_2s2*Qh&Cb)eWa+%^A4FIGYSlG3wZb|JV0bo#G(d&3-j4Z&uWq#^CXXMz>bRC<}P`w;T86;o&hy^ z$iSt~ABO;V8f~vSfVB-|_=d5XTr!g86s&0Mk}1|5=x9~?N7EhhLOXd4sQuoF>U!MZ)HIJ~1-^!scSjG{S?CK?%L1L{yj1AW>$19-kB^GZm+~Ld06OBjd!Cw zE(x>21u3uk3a=t-2y5Actm6GHylP4HC)x#F$pu}_8qt-3dAGAqVr?Kzff%Na3{Ng6 zgePJ1&ql^w#r%91o6zTV4^FK_Dm7b~z-X{Np`b z|CiA%mKb>h0bv<8>LcNKjyZ~B6-tW?ddfW25D7FQRxqPJ+B{lL)h0M%sM~ZNW72r-E}Dg>_E9XQ`p$=MP^6eKDf~khBzI) z;B=_;u;OiE9|aZqJBaO+t;4%A(+|U;zex+*i0x41!XHoDw0s~>*o42TP|tn|*22Vu zQZ)LGWk0#CJ1KnTAjdFtK#bU96`Wexx>BYSyPUjsfiHPTcxpuwo&?9ONM90VMk_S@ zKVAKQ!t6);UYGJyEg&IIP$i!U)VO}0cr_K7^#TIR)lM0Hct zP+VO*`_+9f$BocMAAQ(el?CGahs^8@I)H)@H*zS;QP2Rk&5=y`xZzI8-JKW3_aGc!``We3&kytJ zr+b&N?&@qYvQ5>ROwtdWw<6mPXaej6>;dct90VL)#-6C2n;4x=9}pa15TIDj&Uo`WCu+|aXIkOg~!*o%k0XBGA6wMKHhD`xPe?|K2(UJo};07bkupUzkW!oAx1}I z?feTP1$C>&QsLsUIDOpQ?Sq0h#$ldRw`uGI@{HW?=6)Uf)WfOb;BhwXVVk7xEhk&? z@VMFS@SA3he=XgiffId|IMHx1ho@gvJEkN&HmhN|)lPkf_i#D_QF;?63K`Lzy1Z|1 zC{+y~*Z%O#$wG|kjQr&$;pKf{!y-I6cYY(?8{XA(kd1vLEw&ZI$s0-Bs(oZqP;n?4 zr@C4QKdu|1gkL)ZlEV~Qo`2rk0`}DNkMxx%fm7tGy4|Faauya^yVo9$%+q%WhZ;RtxOO}} zxb)G)Xb0uCp1RKTh6aIC8a;UL+OhQD&mX=02D_fRi|LWR8_cY^-D}@L#MMkxL7wNQ z$cP^B(T&`g@H$g{jZ4As-lH-g*qLkR<(aDfgFC8(#^8?7EVv_78&@LP4rr~6x}&P7 zJF1GhBTy1|ge(P+2v7i|fMN8x0=QHebw@xkJmKsDEC9>9LULBP>fQFnwQ!}lTO0D}O<{p^gu zf?zgm7T4!lzJ7$nys8H_O0IkU)r|27%DxLgm+_zCeVS1EUA|LMgs+3-ExADQpSEa_ zHIp)qx+K1rIaB|+|Mq5r1w!T~7(Cl2-vHcg2{#0LZ9@UMD0sac>nI%X?r5m&DO}h1oq`zP7!l?S{e$ow>XtAd*2T47#E6k} zCWd_G2wn^0vk7jdw|?HZ^%NvQLOXeV=N6%#n<fDV%bd zq_OdK^H0q~(0Blllfg%Fj%9QqN6yw(+fT32cX06Vp4@ zNxgrcv+eidIEg6GmeHLOBmbR~nggKNdp{c6w&bHR;sks;ZU9hS0P^c{w*BJxMzMHM z!cO|z3qb=mGr7jdk&|^i`;?Qq4S73qm_4-}`55HOktZNGAs>refjk-csVAM(c;x$$ zPeATRJ`uSMISFtRk#9gQMZOXF70l)5$S)utrYJSlhXOf`dy&7q`rks^BbT345RntI z`#?GJyX|XqKlfxtQn2wWikfkrqGka+fcpS`z+-?NfW3f2fD?f8fWHB*18zsZ6u>lq z2`~rX0aO9}fOOEjfV>0nN5J0ziVGAq2`~d-1KfRqnn^81;eNn+z&5}$fIWa#z?*<> zz!?As_{RnO7xM1^jdOn1DHaVs+b9wFpLIz@NupPtO_Peoy`CZ!eLWhhQz2DC!e?bl z(I>(09Lj>Ef-muOdLYqaaNk88u)Chbmbm-e{!GwnI;MQ!k}+N;_)U5ak9ZmLeF zGwTX!6%bFC^72 z)4rrTqC2CL>y`TT`p5K5`seh&)4!wtQ2&Mgd%e^!&M?hjH{5AhWVqkpH*7KdmmzHU zmEnM)%W%RVH6|L%jFrZRj9ZLP7DGi{>A*i=gUk* zrY6&irms!O=1FFoxy1aKIb_~tK4$*ZeATS5OtrWy6(8xC*8j0S zZQEme&34vy(RS4)wyW$m`(5_1z1e=){-OQP_F;R1W4z-IhrvSJm{!*>Am`g^!54|^{+!CC-h(8d(Sn!#$Yk5F|0E@ZP;%(Y&d23 zLRe6RG1GY3sLTtF&r|2wpn=-F$Me{{=knU~dh<@_Y4R=kcjlMmi%g?UAycF2H>PZ} z(|o7-9`j=J67zC%y?LMcJ?Nv?e9C;reAe7&zF_9eI*Z9-vp6k9mc5o&p_kJz>^_*b z$eLpCJDEY_^ltj1<- z((Kmk#dbZcd0%r}lYs4-q0PcRDALZ?zM(y={gd`DT9GbEXV3*_>F&|3(ADX->vlnz zZ^F1f)ScC3>z(>L_4nu(>zC-4L#6xl@9B@}d-bREXY^ukn=ejPa~-TAn`7oL8JTKW}l~ zvZB1oya)1X@&Zu*Z}Q&BKbil1zTBiTSxvJ{t4*6t3Fe9B1?H9JYV#xJ2AJRh^A$4% zSCVX*WKmnDSu~bBi|yH|NuqfVLnV!raMGzY*_!>DR?Q(zho(n!OhfI)>49biHcfh- z&F-|XEbtYqDX1yfP(ZcfL_yn5!I%!}4nYIQbf=($3%X0XE4pEwRIkt{>QnS;eYQSV huhARyCcRCMv;1J}GwC9EEQuM&xm@||m~_#k{{z6wz+nIY diff --git a/src/link-z80/aslink.h b/src/mkutil/link-z80/aslink.h similarity index 100% rename from src/link-z80/aslink.h rename to src/mkutil/link-z80/aslink.h diff --git a/src/mkutil/link-z80/link-z80.exe b/src/mkutil/link-z80/link-z80.exe new file mode 100644 index 0000000000000000000000000000000000000000..1462ae12c38edc6d3309792451e92e195b3cdba4 GIT binary patch literal 122936 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 Nsk?6`RF^E_{vW|xFaZDn literal 0 HcmV?d00001 diff --git a/src/link-z80/link-z80.lnk b/src/mkutil/link-z80/link-z80.lnk similarity index 100% rename from src/link-z80/link-z80.lnk rename to src/mkutil/link-z80/link-z80.lnk diff --git a/src/mkutil/link-z80/link-z80.map b/src/mkutil/link-z80/link-z80.map new file mode 100644 index 00000000..5d352670 --- /dev/null +++ b/src/mkutil/link-z80/link-z80.map @@ -0,0 +1,550 @@ + link-z80 + + Timestamp is 3ebb8be9 (Fri May 09 21:07:21 2003) + + Preferred load address is 00400000 + + Start Length Name Class + 0001:00000000 0001260dH .text CODE + 0002:00000000 00000606H .rdata DATA + 0002:00000606 00000000H .edata DATA + 0003:00000000 00000104H .CRT$XCA DATA + 0003:00000104 00000104H .CRT$XCZ DATA + 0003:00000208 00000104H .CRT$XIA DATA + 0003:0000030c 00000109H .CRT$XIC DATA + 0003:00000418 00000104H .CRT$XIZ DATA + 0003:0000051c 00000104H .CRT$XPA DATA + 0003:00000620 00000104H .CRT$XPX DATA + 0003:00000724 00000104H .CRT$XPZ DATA + 0003:00000828 00000104H .CRT$XTA DATA + 0003:0000092c 00000104H .CRT$XTZ DATA + 0003:00000a30 00004a7dH .data DATA + 0003:000054b0 00001f54H .bss DATA + 0004:00000000 00000014H .idata$2 DATA + 0004:00000014 00000014H .idata$3 DATA + 0004:00000028 0000010cH .idata$4 DATA + 0004:00000134 0000010cH .idata$5 DATA + 0004:00000240 00000488H .idata$6 DATA + + Address Publics by Value Rva+Base Lib:Object + + 0001:00000350 _newarea 00401350 f lkarea.obj + 0001:00000466 _lkparea 00401466 f lkarea.obj + 0001:00000593 _lnkarea 00401593 f lkarea.obj + 0001:000007b5 _lnksect 004017b5 f lkarea.obj + 0001:00000ce0 _eval 00401ce0 f lkeval.obj + 0001:00000d68 _expr 00401d68 f lkeval.obj + 0001:00000faa _term 00401faa f lkeval.obj + 0001:0000131a _digit 0040231a f lkeval.obj + 0001:000013cf _oprio 004023cf f lkeval.obj + 0001:00001620 _newhead 00402620 f lkhead.obj + 0001:00001720 _module 00402720 f lkhead.obj + 0001:000017d0 _getid 004027d0 f lklex.obj + 0001:0000183c _getfid 0040283c f lklex.obj + 0001:0000188f _getnb 0040288f f lklex.obj + 0001:000018b0 _skip 004028b0 f lklex.obj + 0001:000018ea _get 004028ea f lklex.obj + 0001:00001918 _unget 00402918 f lklex.obj + 0001:00001930 _getmap 00402930 f lklex.obj + 0001:00001a80 _getline 00402a80 f lklex.obj + 0001:00001cc0 _more 00402cc0 f lklex.obj + 0001:00001cfd _endline 00402cfd f lklex.obj + 0001:00001e90 _addpath 00402e90 f lklibr.obj + 0001:00001f21 _addlib 00402f21 f lklibr.obj + 0001:00001f83 _addfile 00402f83 f lklibr.obj + 0001:000021a7 _search 004031a7 f lklibr.obj + 0001:00002228 _fndsym 00403228 f lklibr.obj + 0001:000026df _library 004036df f lklibr.obj + 0001:0000271c _loadfile 0040371c f lklibr.obj + 0001:00002a20 _newpag 00403a20 f lklist.obj + 0001:00002a62 _dgt 00403a62 f lklist.obj + 0001:00002aaf _slew 00403aaf f lklist.obj + 0001:000030cb _lstarea 004040cb f lklist.obj + 0001:0000361a _lkulist 0040461a f lklist.obj + 0001:0000374f _lkalist 0040474f f lklist.obj + 0001:00003a53 _lkglist 00404a53 f lklist.obj + 0001:00004430 _main 00405430 f lkmain.obj + 0001:000047a1 _lkexit 004057a1 f lkmain.obj + 0001:00004831 _link 00405831 f lkmain.obj + 0001:00004aea _map 00405aea f lkmain.obj + 0001:00004df3 _parse 00405df3 f lkmain.obj + 0001:000053bc _doparse 004063bc f lkmain.obj + 0001:0000546b _bassav 0040646b f lkmain.obj + 0001:000054fd _setbas 004064fd f lkmain.obj + 0001:00005828 _gblsav 00406828 f lkmain.obj + 0001:000058ba _setgbl 004068ba f lkmain.obj + 0001:000059d8 _afile 004069d8 f lkmain.obj + 0001:00005bbc _fndidx 00406bbc f lkmain.obj + 0001:00005c32 _usage 00406c32 f lkmain.obj + 0001:000062b0 _lkout 004072b0 f lkout.obj + 0001:000062f2 _ixx 004072f2 f lkout.obj + 0001:000064a2 _iflush 004074a2 f lkout.obj + 0001:00006617 _sxx 00407617 f lkout.obj + 0001:000067e1 _sflush 004077e1 f lkout.obj + 0001:00006ac0 _reloc 00407ac0 f lkrloc.obj + 0001:00006b50 _relt 00407b50 f lkrloc.obj + 0001:00006ba3 _relr 00407ba3 f lkrloc.obj + 0001:000071d1 _relp 004081d1 f lkrloc.obj + 0001:000073d5 _rele 004083d5 f lkrloc.obj + 0001:00007400 _evword 00408400 f lkrloc.obj + 0001:00007446 _adb_1b 00408446 f lkrloc.obj + 0001:0000746c _adb_2b 0040846c f lkrloc.obj + 0001:00007522 _adb_3b 00408522 f lkrloc.obj + 0001:00007632 _adb_4b 00408632 f lkrloc.obj + 0001:0000779b _adb_xb 0040879b f lkrloc.obj + 0001:000078d2 _adb_lo 004088d2 f lkrloc.obj + 0001:0000794e _adb_hi 0040894e f lkrloc.obj + 0001:000079ca _adb_byte3 004089ca f lkrloc.obj + 0001:00007a46 _adb_byte4 00408a46 f lkrloc.obj + 0001:00007ac2 _adw_xb 00408ac2 f lkrloc.obj + 0001:00007b31 _relerr 00408b31 f lkrloc.obj + 0001:00007b63 _errdmp 00408b63 f lkrloc.obj + 0001:00007ce8 _prntval 00408ce8 f lkrloc.obj + 0001:00007da7 _relerp 00408da7 f lkrloc.obj + 0001:00007dd9 _erpdmp 00408dd9 f lkrloc.obj + 0001:00008360 _syminit 00409360 f lksym.obj + 0001:0000838c _newsym 0040938c f lksym.obj + 0001:0000855a _lkpsym 0040955a f lksym.obj + 0001:00008601 _symval 00409601 f lksym.obj + 0001:0000862d _symdef 0040962d f lksym.obj + 0001:000086a4 _symmod 004096a4 f lksym.obj + 0001:00008760 _symeq 00409760 f lksym.obj + 0001:00008805 _hash 00409805 f lksym.obj + 0001:00008866 _strsto 00409866 f lksym.obj + 0001:000088e5 _new 004098e5 f lksym.obj + 0001:00008ad1 _fprintf 00409ad1 f LIBC:fprintf.obj + 0001:00008b03 ___initstdio 00409b03 f LIBC:_file.obj + 0001:00008ba8 ___endstdio 00409ba8 f LIBC:_file.obj + 0001:00008bc0 _strcpy 00409bc0 f LIBC:strcat.obj + 0001:00008bd0 _strcat 00409bd0 f LIBC:strcat.obj + 0001:00008cb0 _strlen 00409cb0 f LIBC:strlen.obj + 0001:00008d2b _fclose 00409d2b f LIBC:fclose.obj + 0001:00008d81 _fgets 00409d81 f LIBC:fgets.obj + 0001:00008dd8 _free 00409dd8 f LIBC:free.obj + 0001:00008e41 __fsopen 00409e41 f LIBC:fopen.obj + 0001:00008e61 _fopen 00409e61 f LIBC:fopen.obj + 0001:00008e74 _sprintf 00409e74 f LIBC:sprintf.obj + 0001:00008ec6 _malloc 00409ec6 f LIBC:malloc.obj + 0001:00008ed8 __nh_malloc 00409ed8 f LIBC:malloc.obj + 0001:00008f04 __heap_alloc 00409f04 f LIBC:malloc.obj + 0001:00008f90 _strchr 00409f90 f LIBC:strchr.obj + 0001:00008f96 ___from_strstr_to_strchr 00409f96 f LIBC:strchr.obj + 0001:00009050 _strncmp 0040a050 f LIBC:strncmp.obj + 0001:00009088 _sscanf 0040a088 f LIBC:sscanf.obj + 0001:000090c0 _strcmp 0040a0c0 f LIBC:strcmp.obj + 0001:00009144 __flsbuf 0040a144 f LIBC:_flsbuf.obj + 0001:00009260 _strncpy 0040a260 f LIBC:strncpy.obj + 0001:0000935e __cinit 0040a35e f LIBC:crt0dat.obj + 0001:0000938b _exit 0040a38b f LIBC:crt0dat.obj + 0001:0000939c __exit 0040a39c f LIBC:crt0dat.obj + 0001:000093ad __cexit 0040a3ad f LIBC:crt0dat.obj + 0001:000093bc __c_exit 0040a3bc f LIBC:crt0dat.obj + 0001:00009480 _strrchr 0040a480 f LIBC:strrchr.obj + 0001:000094a7 _mainCRTStartup 0040a4a7 f LIBC:crt0.obj + 0001:00009586 __amsg_exit 0040a586 f LIBC:crt0.obj + 0001:000095cf __stbuf 0040a5cf f LIBC:_sftbuf.obj + 0001:0000965c __ftbuf 0040a65c f LIBC:_sftbuf.obj + 0001:00009699 __output 0040a699 f LIBC:output.obj + 0001:00009ea3 __ioinit 0040aea3 f LIBC:ioinit.obj + 0001:0000a04e __ioterm 0040b04e f LIBC:ioinit.obj + 0001:0000a071 _calloc 0040b071 f LIBC:calloc.obj + 0001:0000a122 __fcloseall 0040b122 f LIBC:closeall.obj + 0001:0000a17a _fflush 0040b17a f LIBC:fflush.obj + 0001:0000a1b5 __flush 0040b1b5 f LIBC:fflush.obj + 0001:0000a211 __flushall 0040b211 f LIBC:fflush.obj + 0001:0000a287 __close 0040b287 f LIBC:close.obj + 0001:0000a33a __freebuf 0040b33a f LIBC:_freebuf.obj + 0001:0000a365 __filbuf 0040b365 f LIBC:_filbuf.obj + 0001:0000a43e __GetLinkerVersion 0040b43e f LIBC:heapinit.obj + 0001:0000a46b ___heap_select 0040b46b f LIBC:heapinit.obj + 0001:0000a5b3 __heap_init 0040b5b3 f LIBC:heapinit.obj + 0001:0000a610 __heap_term 0040b610 f LIBC:heapinit.obj + 0001:0000a6b8 __get_sbh_threshold 0040b6b8 f LIBC:sbheap.obj + 0001:0000a6d7 __set_sbh_threshold 0040b6d7 f LIBC:sbheap.obj + 0001:0000a78a ___sbh_heap_init 0040b78a f LIBC:sbheap.obj + 0001:0000a7d2 ___sbh_find_block 0040b7d2 f LIBC:sbheap.obj + 0001:0000a7fd ___sbh_free_block 0040b7fd f LIBC:sbheap.obj + 0001:0000ab26 ___sbh_alloc_block 0040bb26 f LIBC:sbheap.obj + 0001:0000ae2f ___sbh_alloc_new_region 0040be2f f LIBC:sbheap.obj + 0001:0000aee0 ___sbh_alloc_new_group 0040bee0 f LIBC:sbheap.obj + 0001:0000afdb ___sbh_resize_block 0040bfdb f LIBC:sbheap.obj + 0001:0000b2d1 ___sbh_heapmin 0040c2d1 f LIBC:sbheap.obj + 0001:0000b3a2 ___sbh_heap_check 0040c3a2 f LIBC:sbheap.obj + 0001:0000b6d1 __get_old_sbh_threshold 0040c6d1 f LIBC:sbheap.obj + 0001:0000b6d7 __set_old_sbh_threshold 0040c6d7 f LIBC:sbheap.obj + 0001:0000b6f3 ___old_sbh_new_region 0040c6f3 f LIBC:sbheap.obj + 0001:0000b837 ___old_sbh_release_region 0040c837 f LIBC:sbheap.obj + 0001:0000b88d ___old_sbh_decommit_pages 0040c88d f LIBC:sbheap.obj + 0001:0000b94f ___old_sbh_find_block 0040c94f f LIBC:sbheap.obj + 0001:0000b9a6 ___old_sbh_free_block 0040c9a6 f LIBC:sbheap.obj + 0001:0000b9eb ___old_sbh_alloc_block 0040c9eb f LIBC:sbheap.obj + 0001:0000bbf3 ___old_sbh_alloc_block_from_page 0040cbf3 f LIBC:sbheap.obj + 0001:0000bd17 ___old_sbh_resize_block 0040cd17 f LIBC:sbheap.obj + 0001:0000bdc0 ___old_sbh_heap_check 0040cdc0 f LIBC:sbheap.obj + 0001:0000bf1e __openfile 0040cf1e f LIBC:_open.obj + 0001:0000c08e __getstream 0040d08e f LIBC:stream.obj + 0001:0000c106 ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z 0040d106 f LIBC:handler.obj + 0001:0000c116 ?_query_new_handler@@YAP6AHI@ZXZ 0040d116 f LIBC:handler.obj + 0001:0000c11c __callnewh 0040d11c f LIBC:handler.obj + 0001:0000c137 __input 0040d137 f LIBC:input.obj + 0001:0000cbe8 __lseek 0040dbe8 f LIBC:lseek.obj + 0001:0000cc82 __write 0040dc82 f LIBC:write.obj + 0001:0000ce2f __getbuf 0040de2f f LIBC:_getbuf.obj + 0001:0000ce73 __isatty 0040de73 f LIBC:isatty.obj + 0001:0000ce99 __XcptFilter 0040de99 f LIBC:winxfltr.obj + 0001:0000d01d __setenvp 0040e01d f LIBC:stdenvp.obj + 0001:0000d0d6 __setargv 0040e0d6 f LIBC:stdargv.obj + 0001:0000d323 ___crtGetEnvironmentStringsA 0040e323 f LIBC:a_env.obj + 0001:0000d458 __global_unwind2 0040e458 f LIBC:exsup.obj + 0001:0000d49a __local_unwind2 0040e49a f LIBC:exsup.obj + 0001:0000d4f2 __NLG_Return2 0040e4f2 f LIBC:exsup.obj + 0001:0000d502 __abnormal_termination 0040e502 f LIBC:exsup.obj + 0001:0000d525 __NLG_Notify1 0040e525 f LIBC:exsup.obj + 0001:0000d52e __NLG_Notify 0040e52e f LIBC:exsup.obj + 0001:0000d541 __NLG_Dispatch 0040e541 f LIBC:exsup.obj + 0001:0000d550 __except_handler3 0040e550 f LIBC:exsup3.obj + 0001:0000d60d __seh_longjmp_unwind@4 0040e60d f LIBC:exsup3.obj + 0001:0000d628 __FF_MSGBANNER 0040e628 f LIBC:crt0msg.obj + 0001:0000d661 __NMSG_WRITE 0040e661 f LIBC:crt0msg.obj + 0001:0000d7b4 __GET_RTERRMSG 0040e7b4 f LIBC:crt0msg.obj + 0001:0000d7e5 _wctomb 0040e7e5 f LIBC:wctomb.obj + 0001:0000d850 __aulldiv 0040e850 f LIBC:ulldiv.obj + 0001:0000d8c0 __aullrem 0040e8c0 f LIBC:ullrem.obj + 0001:0000d940 _memset 0040e940 f LIBC:memset.obj + 0001:0000d998 __commit 0040e998 f LIBC:commit.obj + 0001:0000d9ef __dosmaperr 0040e9ef f LIBC:dosmap.obj + 0001:0000da56 __alloc_osfhnd 0040ea56 f LIBC:osfinfo.obj + 0001:0000daeb __set_osfhnd 0040eaeb f LIBC:osfinfo.obj + 0001:0000db62 __free_osfhnd 0040eb62 f LIBC:osfinfo.obj + 0001:0000dbdc __get_osfhandle 0040ebdc f LIBC:osfinfo.obj + 0001:0000dc19 __open_osfhandle 0040ec19 f LIBC:osfinfo.obj + 0001:0000dcb6 __read 0040ecb6 f LIBC:read.obj + 0001:0000deac _strtol 0040eeac f LIBC:strtol.obj + 0001:0000e0cb _strtoul 0040f0cb f LIBC:strtol.obj + 0001:0000e0f0 _strstr 0040f0f0 f LIBC:strstr.obj + 0001:0000e170 __chkstk 0040f170 f LIBC:chkstk.obj + 0001:0000e170 __alloca_probe 0040f170 f LIBC:chkstk.obj + 0001:0000e1a0 _memmove 0040f1a0 f LIBC:memmove.obj + 0001:0000e4d5 __open 0040f4d5 f LIBC:open.obj + 0001:0000e4ec __sopen 0040f4ec f LIBC:open.obj + 0001:0000e7a5 _mbtowc 0040f7a5 f LIBC:mbtowc.obj + 0001:0000e86d _isalpha 0040f86d f LIBC:_ctype.obj + 0001:0000e89b _isupper 0040f89b f LIBC:_ctype.obj + 0001:0000e8c3 _islower 0040f8c3 f LIBC:_ctype.obj + 0001:0000e8eb _isdigit 0040f8eb f LIBC:_ctype.obj + 0001:0000e913 _isxdigit 0040f913 f LIBC:_ctype.obj + 0001:0000e940 _isspace 0040f940 f LIBC:_ctype.obj + 0001:0000e968 _ispunct 0040f968 f LIBC:_ctype.obj + 0001:0000e990 _isalnum 0040f990 f LIBC:_ctype.obj + 0001:0000e9be _isprint 0040f9be f LIBC:_ctype.obj + 0001:0000e9ec _isgraph 0040f9ec f LIBC:_ctype.obj + 0001:0000ea1a _iscntrl 0040fa1a f LIBC:_ctype.obj + 0001:0000ea42 ___isascii 0040fa42 f LIBC:_ctype.obj + 0001:0000ea4f ___toascii 0040fa4f f LIBC:_ctype.obj + 0001:0000ea57 ___iscsymf 0040fa57 f LIBC:_ctype.obj + 0001:0000ea94 ___iscsym 0040fa94 f LIBC:_ctype.obj + 0001:0000ead1 __isctype 0040fad1 f LIBC:isctype.obj + 0001:0000eb50 __allmul 0040fb50 f LIBC:llmul.obj + 0001:0000eb90 __allshl 0040fb90 f LIBC:llshl.obj + 0001:0000ebaf _ungetc 0040fbaf f LIBC:ungetc.obj + 0001:0000ec1d __setmbcp 0040fc1d f LIBC:mbctype.obj + 0001:0000efe1 __getmbcp 0040ffe1 f LIBC:mbctype.obj + 0001:0000eff1 ___initmbctable 0040fff1 f LIBC:mbctype.obj + 0001:0000f010 _memcpy 00410010 f LIBC:memcpy.obj + 0001:0000f345 ___crtMessageBoxA 00410345 f LIBC:crtmbox.obj + 0001:0000f3ce __fptrap 004103ce f LIBC:crt0fp.obj + 0001:0000f3d7 __toupper 004103d7 f LIBC:toupper.obj + 0001:0000f3df _toupper 004103df f LIBC:toupper.obj + 0001:0000f4ab __chsize 004104ab f LIBC:chsize.obj + 0001:0000f5f1 ___crtGetStringTypeA 004105f1 f LIBC:a_str.obj + 0001:0000f73a ___crtLCMapStringA 0041073a f LIBC:a_map.obj + 0001:0000f989 __setmode 00410989 f LIBC:setmode.obj + 0001:0000fa00 _HeapFree@12 00410a00 f kernel32:KERNEL32.dll + 0001:0000fa06 _HeapAlloc@12 00410a06 f kernel32:KERNEL32.dll + 0001:0000fa0c _ExitProcess@4 00410a0c f kernel32:KERNEL32.dll + 0001:0000fa12 _TerminateProcess@8 00410a12 f kernel32:KERNEL32.dll + 0001:0000fa18 _GetCurrentProcess@0 00410a18 f kernel32:KERNEL32.dll + 0001:0000fa1e _GetCommandLineA@0 00410a1e f kernel32:KERNEL32.dll + 0001:0000fa24 _GetVersion@0 00410a24 f kernel32:KERNEL32.dll + 0001:0000fa2a _SetHandleCount@4 00410a2a f kernel32:KERNEL32.dll + 0001:0000fa30 _GetStdHandle@4 00410a30 f kernel32:KERNEL32.dll + 0001:0000fa36 _GetFileType@4 00410a36 f kernel32:KERNEL32.dll + 0001:0000fa3c _GetStartupInfoA@4 00410a3c f kernel32:KERNEL32.dll + 0001:0000fa42 _GetLastError@0 00410a42 f kernel32:KERNEL32.dll + 0001:0000fa48 _CloseHandle@4 00410a48 f kernel32:KERNEL32.dll + 0001:0000fa4e _GetModuleHandleA@4 00410a4e f kernel32:KERNEL32.dll + 0001:0000fa54 _GetModuleFileNameA@12 00410a54 f kernel32:KERNEL32.dll + 0001:0000fa5a _GetEnvironmentVariableA@12 00410a5a f kernel32:KERNEL32.dll + 0001:0000fa60 _GetVersionExA@4 00410a60 f kernel32:KERNEL32.dll + 0001:0000fa66 _HeapDestroy@4 00410a66 f kernel32:KERNEL32.dll + 0001:0000fa6c _HeapCreate@12 00410a6c f kernel32:KERNEL32.dll + 0001:0000fa72 _VirtualFree@12 00410a72 f kernel32:KERNEL32.dll + 0001:0000fa78 _VirtualAlloc@16 00410a78 f kernel32:KERNEL32.dll + 0001:0000fa7e _HeapReAlloc@16 00410a7e f kernel32:KERNEL32.dll + 0001:0000fa84 _IsBadWritePtr@8 00410a84 f kernel32:KERNEL32.dll + 0001:0000fa8a _SetFilePointer@16 00410a8a f kernel32:KERNEL32.dll + 0001:0000fa90 _WriteFile@20 00410a90 f kernel32:KERNEL32.dll + 0001:0000fa96 _UnhandledExceptionFilter@4 00410a96 f kernel32:KERNEL32.dll + 0001:0000fa9c _FreeEnvironmentStringsA@4 00410a9c f kernel32:KERNEL32.dll + 0001:0000faa2 _FreeEnvironmentStringsW@4 00410aa2 f kernel32:KERNEL32.dll + 0001:0000faa8 _WideCharToMultiByte@32 00410aa8 f kernel32:KERNEL32.dll + 0001:0000faae _GetEnvironmentStrings@0 00410aae f kernel32:KERNEL32.dll + 0001:0000fab4 _GetEnvironmentStringsW@0 00410ab4 f kernel32:KERNEL32.dll + 0001:0000faba _RtlUnwind@16 00410aba f kernel32:KERNEL32.dll + 0001:0000fac0 _FlushFileBuffers@4 00410ac0 f kernel32:KERNEL32.dll + 0001:0000fac6 _SetStdHandle@8 00410ac6 f kernel32:KERNEL32.dll + 0001:0000facc _ReadFile@20 00410acc f kernel32:KERNEL32.dll + 0001:0000fad2 _CreateFileA@28 00410ad2 f kernel32:KERNEL32.dll + 0001:0000fad8 _MultiByteToWideChar@24 00410ad8 f kernel32:KERNEL32.dll + 0001:0000fade _GetCPInfo@8 00410ade f kernel32:KERNEL32.dll + 0001:0000fae4 _GetACP@0 00410ae4 f kernel32:KERNEL32.dll + 0001:0000faea _GetOEMCP@0 00410aea f kernel32:KERNEL32.dll + 0001:0000faf0 _GetProcAddress@8 00410af0 f kernel32:KERNEL32.dll + 0001:0000faf6 _LoadLibraryA@4 00410af6 f kernel32:KERNEL32.dll + 0001:0000fafc _SetEndOfFile@4 00410afc f kernel32:KERNEL32.dll + 0001:0000fb02 _GetStringTypeA@20 00410b02 f kernel32:KERNEL32.dll + 0001:0000fb08 _GetStringTypeW@16 00410b08 f kernel32:KERNEL32.dll + 0001:0000fb0e _LCMapStringA@24 00410b0e f kernel32:KERNEL32.dll + 0001:0000fb14 _LCMapStringW@24 00410b14 f kernel32:KERNEL32.dll + 0002:0000002c ___lookuptable 0041402c LIBC:output.obj + 0002:00000088 ??_C@_1O@POHA@?$AA?$CI?$AAn?$AAu?$AAl?$AAl?$AA?$CJ?$AA?$AA@ 00414088 LIBC:output.obj + 0002:00000098 ??_C@_06ONKE@?$CInull?$CJ?$AA@ 00414098 LIBC:output.obj + 0002:000000a0 ??_C@_0BH@PHHF@__GLOBAL_HEAP_SELECTED?$AA@ 004140a0 LIBC:heapinit.obj + 0002:000000b8 ??_C@_0BF@BBGL@__MSVCRT_HEAP_SELECT?$AA@ 004140b8 LIBC:heapinit.obj + 0002:000000d0 ??_C@_0P@GGKG@runtime?5error?5?$AA@ 004140d0 LIBC:crt0msg.obj + 0002:000000e0 ??_C@_02PIMC@?$AN?6?$AA@ 004140e0 LIBC:crt0msg.obj + 0002:000000e4 ??_C@_0O@DELO@TLOSS?5error?$AN?6?$AA@ 004140e4 LIBC:crt0msg.obj + 0002:000000f4 ??_C@_0N@OMLL@SING?5error?$AN?6?$AA@ 004140f4 LIBC:crt0msg.obj + 0002:00000104 ??_C@_0P@OJAK@DOMAIN?5error?$AN?6?$AA@ 00414104 LIBC:crt0msg.obj + 0002:00000114 ??_C@_0CF@EANP@R6028?$AN?6?9?5unable?5to?5initialize?5he@ 00414114 LIBC:crt0msg.obj + 0002:0000013c ??_C@_0DF@ECGN@R6027?$AN?6?9?5not?5enough?5space?5for?5lo@ 0041413c LIBC:crt0msg.obj + 0002:00000174 ??_C@_0DF@FKAC@R6026?$AN?6?9?5not?5enough?5space?5for?5st@ 00414174 LIBC:crt0msg.obj + 0002:000001ac ??_C@_0CG@DPMN@R6025?$AN?6?9?5pure?5virtual?5function?5c@ 004141ac LIBC:crt0msg.obj + 0002:000001d4 ??_C@_0DF@CKIP@R6024?$AN?6?9?5not?5enough?5space?5for?5_o@ 004141d4 LIBC:crt0msg.obj + 0002:0000020c ??_C@_0CJ@GGOE@R6019?$AN?6?9?5unable?5to?5open?5console?5@ 0041420c LIBC:crt0msg.obj + 0002:00000238 ??_C@_0CB@LBOB@R6018?$AN?6?9?5unexpected?5heap?5error?$AN?6@ 00414238 LIBC:crt0msg.obj + 0002:0000025c ??_C@_0CN@FPEG@R6017?$AN?6?9?5unexpected?5multithread?5@ 0041425c LIBC:crt0msg.obj + 0002:0000028c ??_C@_0CM@OBIC@R6016?$AN?6?9?5not?5enough?5space?5for?5th@ 0041428c LIBC:crt0msg.obj + 0002:000002b8 ??_C@_0CB@HPAL@?$AN?6abnormal?5program?5termination?$AN?6@ 004142b8 LIBC:crt0msg.obj + 0002:000002dc ??_C@_0CM@JOOB@R6009?$AN?6?9?5not?5enough?5space?5for?5en@ 004142dc LIBC:crt0msg.obj + 0002:00000308 ??_C@_0CK@OIBL@R6008?$AN?6?9?5not?5enough?5space?5for?5ar@ 00414308 LIBC:crt0msg.obj + 0002:00000334 ??_C@_0CF@LKPB@R6002?$AN?6?9?5floating?5point?5not?5load@ 00414334 LIBC:crt0msg.obj + 0002:0000035c ??_C@_0CF@JPDF@Microsoft?5Visual?5C?$CL?$CL?5Runtime?5Lib@ 0041435c LIBC:crt0msg.obj + 0002:00000384 ??_C@_02JJJH@?6?6?$AA@ 00414384 LIBC:crt0msg.obj + 0002:00000388 ??_C@_0BK@DEOK@Runtime?5Error?$CB?6?6Program?3?5?$AA@ 00414388 LIBC:crt0msg.obj + 0002:000003a4 ??_C@_03NAME@?4?4?4?$AA@ 004143a4 LIBC:crt0msg.obj + 0002:000003a8 ??_C@_0BH@NNCD@?$DMprogram?5name?5unknown?$DO?$AA@ 004143a8 LIBC:crt0msg.obj + 0002:000003c0 ??_C@_0BD@NJFP@GetLastActivePopup?$AA@ 004143c0 LIBC:crtmbox.obj + 0002:000003d4 ??_C@_0BA@GILI@GetActiveWindow?$AA@ 004143d4 LIBC:crtmbox.obj + 0002:000003e4 ??_C@_0M@PKCK@MessageBoxA?$AA@ 004143e4 LIBC:crtmbox.obj + 0002:000003f0 ??_C@_0L@HKL@user32?4dll?$AA@ 004143f0 LIBC:crtmbox.obj + 0002:000003fc ??_C@_01A@?$AA?$AA@ 004143fc LIBC:a_str.obj + 0002:00000400 ??_C@_13A@?$AA?$AA?$AA?$AA@ 00414400 LIBC:a_str.obj + 0003:00000000 ___xc_a 00415000 LIBC:crt0init.obj + 0003:00000104 ___xc_z 00415104 LIBC:crt0init.obj + 0003:00000208 ___xi_a 00415208 LIBC:crt0init.obj + 0003:00000418 ___xi_z 00415418 LIBC:crt0init.obj + 0003:0000051c ___xp_a 0041551c LIBC:crt0init.obj + 0003:00000724 ___xp_z 00415724 LIBC:crt0init.obj + 0003:00000828 ___xt_a 00415828 LIBC:crt0init.obj + 0003:0000092c ___xt_z 0041592c LIBC:crt0init.obj + 0003:00000b14 __abs_ 00415b14 lkdata.obj + 0003:00000b18 _rtaflg 00415b18 lkdata.obj + 0003:00000b1c _ctype 00415b1c lkdata.obj + 0003:00000b9c _ccase 00415b9c lkdata.obj + 0003:00001370 _usetxt 00416370 lkmain.obj + 0003:00001d7c _errmsg 00416d7c lkrloc.obj + 0003:000022d0 __iob 004172d0 LIBC:_file.obj + 0003:00002550 __aexit_rtn 00417550 LIBC:crt0.obj + 0003:00002554 ___app_type 00417554 LIBC:crt0.obj + 0003:00002558 ___nullstring 00417558 LIBC:output.obj + 0003:0000255c ___wnullstring 0041755c LIBC:output.obj + 0003:00002560 ___badioinfo 00417560 LIBC:ioinit.obj + 0003:00002568 __amblksiz 00417568 LIBC:heapinit.obj + 0003:00002570 ___old_small_block_heap 00417570 LIBC:sbheap.obj + 0003:00004594 ___old_sbh_threshold 00419594 LIBC:sbheap.obj + 0003:000045a8 __XcptActTab 004195a8 LIBC:winxfltr.obj + 0003:00004620 __First_FPE_Indx 00419620 LIBC:winxfltr.obj + 0003:00004624 __Num_FPE 00419624 LIBC:winxfltr.obj + 0003:00004628 __XcptActTabCount 00419628 LIBC:winxfltr.obj + 0003:0000462c __fpecode 0041962c LIBC:winxfltr.obj + 0003:00004630 __NLG_Destination 00419630 LIBC:exsup.obj + 0003:000046d0 __cfltcvt_tab 004196d0 LIBC:cmiscdat.obj + 0003:000046e8 __pctype 004196e8 LIBC:ctype.obj + 0003:000046ec __pwctype 004196ec LIBC:ctype.obj + 0003:000046f0 __ctype 004196f0 LIBC:ctype.obj + 0003:00004a70 ___mb_cur_max 00419a70 LIBC:nlsdata1.obj + 0003:00004a74 ___decimal_point 00419a74 LIBC:nlsdata1.obj + 0003:00004a78 ___decimal_point_length 00419a78 LIBC:nlsdata1.obj + 0003:000054b0 _rtadr0 0041a4b0 lkdata.obj + 0003:000054b4 _rtadr1 0041a4b4 lkdata.obj + 0003:000054b8 _rtadr2 0041a4b8 lkdata.obj + 0003:000054bc _obj_flag 0041a4bc lkdata.obj + 0003:000054e8 __cflush 0041a4e8 LIBC:_file.obj + 0003:000054ec _errno 0041a4ec LIBC:crt0dat.obj + 0003:000054f0 __doserrno 0041a4f0 LIBC:crt0dat.obj + 0003:000054f4 __umaskval 0041a4f4 LIBC:crt0dat.obj + 0003:000054f8 __osver 0041a4f8 LIBC:crt0dat.obj + 0003:000054fc __winver 0041a4fc LIBC:crt0dat.obj + 0003:00005500 __winmajor 0041a500 LIBC:crt0dat.obj + 0003:00005504 __winminor 0041a504 LIBC:crt0dat.obj + 0003:00005508 ___argc 0041a508 LIBC:crt0dat.obj + 0003:0000550c ___argv 0041a50c LIBC:crt0dat.obj + 0003:00005510 ___wargv 0041a510 LIBC:crt0dat.obj + 0003:00005514 __environ 0041a514 LIBC:crt0dat.obj + 0003:00005518 ___initenv 0041a518 LIBC:crt0dat.obj + 0003:0000551c __wenviron 0041a51c LIBC:crt0dat.obj + 0003:00005520 ___winitenv 0041a520 LIBC:crt0dat.obj + 0003:00005524 __pgmptr 0041a524 LIBC:crt0dat.obj + 0003:00005528 __wpgmptr 0041a528 LIBC:crt0dat.obj + 0003:0000552c __exitflag 0041a52c LIBC:crt0dat.obj + 0003:00005530 __C_Termination_Done 0041a530 LIBC:crt0dat.obj + 0003:00005534 __C_Exit_Done 0041a534 LIBC:crt0dat.obj + 0003:00005538 __aenvptr 0041a538 LIBC:crt0.obj + 0003:0000553c __wenvptr 0041a53c LIBC:crt0.obj + 0003:00005540 ___error_mode 0041a540 LIBC:crt0.obj + 0003:00005544 __stdbuf 0041a544 LIBC:_sftbuf.obj + 0003:00005550 __newmode 0041a550 LIBC:_newmode.obj + 0003:00005554 ?_pnhHeap@@3P6AHI@ZA 0041a554 LIBC:handler.obj + 0003:00005558 __pxcptinfoptrs 0041a558 LIBC:winxfltr.obj + 0003:00005664 __adbgmsg 0041a664 LIBC:crt0msg.obj + 0003:00005668 __commode 0041a668 LIBC:ncommode.obj + 0003:0000567c ___lc_handle 0041a67c LIBC:nlsdata2.obj + 0003:00005694 ___lc_codepage 0041a694 LIBC:nlsdata2.obj + 0003:00005698 ___lc_collate_cp 0041a698 LIBC:nlsdata2.obj + 0003:0000569c __fmode 0041a69c LIBC:txtmode.obj + 0003:000056a8 _uflag 0041a6a8 + 0003:0000578c _hilo 0041a78c + 0003:000057a0 _rtbuf 0041a7a0 + 0003:000057f0 _rtcnt 0041a7f0 + 0003:00005800 _rtflg 0041a800 + 0003:00005840 _lbfhead 0041a840 + 0003:00005860 _symhash 0041a860 + 0003:00005960 _cfp 0041a960 + 0003:00005964 _bsp 0041a964 + 0003:00005968 _axp 0041a968 + 0003:0000596c _lbnhead 0041a96c + 0003:00005970 _gcntr 0041a970 + 0003:00005974 _filep 0041a974 + 0003:00005978 _gsp 0041a978 + 0003:0000597c _globlp 0041a97c + 0003:00005980 _lfp 0041a980 + 0003:00005984 _mfp 0041a984 + 0003:00005988 _a_mask 0041a988 + 0003:0000598c _line 0041a98c + 0003:00005990 _lop 0041a990 + 0003:000059a0 _rtval 0041a9a0 + 0003:000059e0 _ofp 0041a9e0 + 0003:000059e4 _headp 0041a9e4 + 0003:000059e8 _zflag 0041a9e8 + 0003:000059ec _rfp 0041a9ec + 0003:000059f0 _oflag 0041a9f0 + 0003:00005a00 _sdp 0041aa00 + 0003:00005a0c _sfp 0041aa0c + 0003:00005a10 _areap 0041aa10 + 0003:00005a14 _tfp 0041aa14 + 0003:00005a18 _page 0041aa18 + 0003:00005a1c _pass 0041aa1c + 0003:00005a20 _ap 0041aa20 + 0003:00005a24 _outfp 0041aa24 + 0003:00005a40 _ib 0041aa40 + 0003:00005b08 _wflag 0041ab08 + 0003:00005b0c _hp 0041ab0c + 0003:00005b10 _ip 0041ab10 + 0003:00005b20 _rb 0041ab20 + 0003:00005be8 _rp 0041abe8 + 0003:00005bec _a_bytes 0041abec + 0003:00005bf0 _gline 0041abf0 + 0003:00005c00 _rerr 0041ac00 + 0003:00005c14 _pflag 0041ac14 + 0003:00005c18 _s_mask 0041ac18 + 0003:00005c1c _basep 0041ac1c + 0003:00005c20 _lbphead 0041ac20 + 0003:00005c24 _xflag 0041ac24 + 0003:00005c28 _startp 0041ac28 + 0003:00005c2c _radix 0041ac2c + 0003:00005c30 _mflag 0041ac30 + 0003:00005c34 _linkp 0041ac34 + 0003:00005c38 _objflg 0041ac38 + 0003:00005c3c _lkerr 0041ac3c + 0003:00005c40 _v_mask 0041ac40 + 0003:00005c44 ___mbcodepage 0041ac44 + 0003:00005cc0 ___mbulinfo 0041acc0 + 0003:00005ccc ___ismbcodepage 0041accc + 0003:00005ce0 __mbcasemap 0041ace0 + 0003:00005de0 __mbctype 0041ade0 + 0003:00005ee4 ___mblcid 0041aee4 + 0003:00005ee8 ___sbh_sizeHeaderList 0041aee8 + 0003:00005efc ___sbh_indGroupDefer 0041aefc + 0003:00005f00 ___sbh_pHeaderScan 0041af00 + 0003:00005f04 ___sbh_initialized 0041af04 + 0003:00005f08 ___sbh_pHeaderDefer 0041af08 + 0003:00005f0c ___sbh_cntHeaderList 0041af0c + 0003:00005f10 ___sbh_pHeaderList 0041af10 + 0003:00005f14 ___sbh_threshold 0041af14 + 0003:00005f18 __crtheap 0041af18 + 0003:00005f28 ___active_heap 0041af28 + 0003:00005f40 ___pioinfo 0041af40 + 0003:0000607c __nhandle 0041b07c + 0003:00006080 __acmdln 0041b080 + 0003:0000608c ___env_initialized 0041b08c + 0003:0000609c ___mbctype_initialized 0041b09c + 0003:000060a0 ___onexitend 0041b0a0 + 0003:000060a4 ___onexitbegin 0041b0a4 + 0003:000060a8 __FPinit 0041b0a8 + 0003:000060ac ___piob 0041b0ac + 0003:00006400 __bufin 0041b400 + 0003:00007400 __nstream 0041c400 + 0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 0041d000 kernel32:KERNEL32.dll + 0004:00000014 __NULL_IMPORT_DESCRIPTOR 0041d014 kernel32:KERNEL32.dll + 0004:00000134 __imp__WriteFile@20 0041d134 kernel32:KERNEL32.dll + 0004:00000138 __imp__HeapAlloc@12 0041d138 kernel32:KERNEL32.dll + 0004:0000013c __imp__ExitProcess@4 0041d13c kernel32:KERNEL32.dll + 0004:00000140 __imp__TerminateProcess@8 0041d140 kernel32:KERNEL32.dll + 0004:00000144 __imp__GetCurrentProcess@0 0041d144 kernel32:KERNEL32.dll + 0004:00000148 __imp__GetCommandLineA@0 0041d148 kernel32:KERNEL32.dll + 0004:0000014c __imp__GetVersion@0 0041d14c kernel32:KERNEL32.dll + 0004:00000150 __imp__SetHandleCount@4 0041d150 kernel32:KERNEL32.dll + 0004:00000154 __imp__GetStdHandle@4 0041d154 kernel32:KERNEL32.dll + 0004:00000158 __imp__GetFileType@4 0041d158 kernel32:KERNEL32.dll + 0004:0000015c __imp__GetStartupInfoA@4 0041d15c kernel32:KERNEL32.dll + 0004:00000160 __imp__GetLastError@0 0041d160 kernel32:KERNEL32.dll + 0004:00000164 __imp__CloseHandle@4 0041d164 kernel32:KERNEL32.dll + 0004:00000168 __imp__GetModuleHandleA@4 0041d168 kernel32:KERNEL32.dll + 0004:0000016c __imp__GetModuleFileNameA@12 0041d16c kernel32:KERNEL32.dll + 0004:00000170 __imp__GetEnvironmentVariableA@12 0041d170 kernel32:KERNEL32.dll + 0004:00000174 __imp__GetVersionExA@4 0041d174 kernel32:KERNEL32.dll + 0004:00000178 __imp__HeapDestroy@4 0041d178 kernel32:KERNEL32.dll + 0004:0000017c __imp__HeapCreate@12 0041d17c kernel32:KERNEL32.dll + 0004:00000180 __imp__VirtualFree@12 0041d180 kernel32:KERNEL32.dll + 0004:00000184 __imp__VirtualAlloc@16 0041d184 kernel32:KERNEL32.dll + 0004:00000188 __imp__HeapReAlloc@16 0041d188 kernel32:KERNEL32.dll + 0004:0000018c __imp__IsBadWritePtr@8 0041d18c kernel32:KERNEL32.dll + 0004:00000190 __imp__SetFilePointer@16 0041d190 kernel32:KERNEL32.dll + 0004:00000194 __imp__HeapFree@12 0041d194 kernel32:KERNEL32.dll + 0004:00000198 __imp__UnhandledExceptionFilter@4 0041d198 kernel32:KERNEL32.dll + 0004:0000019c __imp__FreeEnvironmentStringsA@4 0041d19c kernel32:KERNEL32.dll + 0004:000001a0 __imp__FreeEnvironmentStringsW@4 0041d1a0 kernel32:KERNEL32.dll + 0004:000001a4 __imp__WideCharToMultiByte@32 0041d1a4 kernel32:KERNEL32.dll + 0004:000001a8 __imp__GetEnvironmentStrings@0 0041d1a8 kernel32:KERNEL32.dll + 0004:000001ac __imp__GetEnvironmentStringsW@0 0041d1ac kernel32:KERNEL32.dll + 0004:000001b0 __imp__RtlUnwind@16 0041d1b0 kernel32:KERNEL32.dll + 0004:000001b4 __imp__FlushFileBuffers@4 0041d1b4 kernel32:KERNEL32.dll + 0004:000001b8 __imp__SetStdHandle@8 0041d1b8 kernel32:KERNEL32.dll + 0004:000001bc __imp__ReadFile@20 0041d1bc kernel32:KERNEL32.dll + 0004:000001c0 __imp__CreateFileA@28 0041d1c0 kernel32:KERNEL32.dll + 0004:000001c4 __imp__MultiByteToWideChar@24 0041d1c4 kernel32:KERNEL32.dll + 0004:000001c8 __imp__GetCPInfo@8 0041d1c8 kernel32:KERNEL32.dll + 0004:000001cc __imp__GetACP@0 0041d1cc kernel32:KERNEL32.dll + 0004:000001d0 __imp__GetOEMCP@0 0041d1d0 kernel32:KERNEL32.dll + 0004:000001d4 __imp__GetProcAddress@8 0041d1d4 kernel32:KERNEL32.dll + 0004:000001d8 __imp__LoadLibraryA@4 0041d1d8 kernel32:KERNEL32.dll + 0004:000001dc __imp__SetEndOfFile@4 0041d1dc kernel32:KERNEL32.dll + 0004:000001e0 __imp__GetStringTypeA@20 0041d1e0 kernel32:KERNEL32.dll + 0004:000001e4 __imp__GetStringTypeW@16 0041d1e4 kernel32:KERNEL32.dll + 0004:000001e8 __imp__LCMapStringA@24 0041d1e8 kernel32:KERNEL32.dll + 0004:000001ec __imp__LCMapStringW@24 0041d1ec kernel32:KERNEL32.dll + 0004:000001f0 \177KERNEL32_NULL_THUNK_DATA 0041d1f0 kernel32:KERNEL32.dll + + entry point at 0001:000094a7 + diff --git a/src/link-z80/lkarea.c b/src/mkutil/link-z80/lkarea.c similarity index 100% rename from src/link-z80/lkarea.c rename to src/mkutil/link-z80/lkarea.c diff --git a/src/link-z80/lkdata.c b/src/mkutil/link-z80/lkdata.c similarity index 100% rename from src/link-z80/lkdata.c rename to src/mkutil/link-z80/lkdata.c diff --git a/src/link-z80/lkeval.c b/src/mkutil/link-z80/lkeval.c similarity index 100% rename from src/link-z80/lkeval.c rename to src/mkutil/link-z80/lkeval.c diff --git a/src/link-z80/lkhead.c b/src/mkutil/link-z80/lkhead.c similarity index 100% rename from src/link-z80/lkhead.c rename to src/mkutil/link-z80/lkhead.c diff --git a/src/link-z80/lklex.c b/src/mkutil/link-z80/lklex.c similarity index 100% rename from src/link-z80/lklex.c rename to src/mkutil/link-z80/lklex.c diff --git a/src/link-z80/lklibr.c b/src/mkutil/link-z80/lklibr.c similarity index 100% rename from src/link-z80/lklibr.c rename to src/mkutil/link-z80/lklibr.c diff --git a/src/link-z80/lklist.c b/src/mkutil/link-z80/lklist.c similarity index 100% rename from src/link-z80/lklist.c rename to src/mkutil/link-z80/lklist.c diff --git a/src/link-z80/lkmain.c b/src/mkutil/link-z80/lkmain.c similarity index 100% rename from src/link-z80/lkmain.c rename to src/mkutil/link-z80/lkmain.c diff --git a/src/link-z80/lkout.c b/src/mkutil/link-z80/lkout.c similarity index 100% rename from src/link-z80/lkout.c rename to src/mkutil/link-z80/lkout.c diff --git a/src/link-z80/lkrloc.c b/src/mkutil/link-z80/lkrloc.c similarity index 100% rename from src/link-z80/lkrloc.c rename to src/mkutil/link-z80/lkrloc.c diff --git a/src/link-z80/lksym.c b/src/mkutil/link-z80/lksym.c similarity index 100% rename from src/link-z80/lksym.c rename to src/mkutil/link-z80/lksym.c diff --git a/src/link-z80/n.bat b/src/mkutil/link-z80/n.bat similarity index 93% rename from src/link-z80/n.bat rename to src/mkutil/link-z80/n.bat index 527a821c..58d1058b 100644 --- a/src/link-z80/n.bat +++ b/src/mkutil/link-z80/n.bat @@ -22,7 +22,7 @@ cl -Zi -I. -DWIN32 -DINDEXLIB -c lksym.c @if errorlevel 1 goto failure link @link-z80.lnk @if errorlevel 1 goto failure -copy link-z80.exe ..\bin +copy link-z80.exe ..\..\bin @echo SUCCESS @goto done diff --git a/src/link-z80/x.bat b/src/mkutil/link-z80/x.bat similarity index 100% rename from src/link-z80/x.bat rename to src/mkutil/link-z80/x.bat diff --git a/src/mkutil/n.bat b/src/mkutil/n.bat index 53a42a21..a3013c96 100644 --- a/src/mkutil/n.bat +++ b/src/mkutil/n.bat @@ -10,6 +10,10 @@ cl -Zi -I. bin2c.c @if errorlevel 1 goto failure copy bin2c.exe ..\bin +cl -Zi -I. bin2avr.c +@if errorlevel 1 goto failure +copy bin2avr.exe ..\bin + cl -Zi -I. -DVAX cr.c @if errorlevel 1 goto failure copy cr.exe ..\bin diff --git a/src/mkutil/tavrasm.118/README b/src/mkutil/tavrasm.118/README new file mode 100644 index 00000000..22b0b461 --- /dev/null +++ b/src/mkutil/tavrasm.118/README @@ -0,0 +1,320 @@ + + Toms AVR macro assembler - tavrasm 1.18 + ============================================================================= + + tavrasm - A GNU/Linux assembler for the Atmel AVR series of + micro-controllers. Copyright (C) 1999-2003 Tom Mortensen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + + Introduction + ============================================================================= + + tavrasm is an assembler for the Atmel AVR family of micro-controllers. + It uses a syntax similar to the one found in the Atmel AVR DOS assembler. + Some of the features includes: + + - Super-set of Atmel AVR assembler. + - Macros in macros. + - Save Intel HEX, Motorola S-record, Generic and binary output. + - More than 100 warning/error messages. + - Atmel object files compatible with Atmel's AVR Studio. + - C escape characters in char/string literals. + - Runs on (win)DOS, Linux, OS/2, Solaris, ... + - Free software released under GPL. + + Installation + ============================================================================= + + Copy the tavrasm executable (tavrasm.exe for OS/2 and DOS) to a + directory in your path. + + Running + ============================================================================= + + Just type 'tavrasm file.asm'. This will generate an Intel HEX output file + ('file.hex'). To get help, type 'tavrasm' with no arguments. + + Compiling + ============================================================================= + + tavrasm should compile on most systems that are supported by gcc. + I haven't check for endianes, so this might be a problem if + anybody wants to compile it on non-i386 systems (mail me, and I will + fix this). + + Check the makefile for additional information. + + Systems supported + ============================================================================= + + Linux/x86: I wrote parts of tavrasm on a Linux/x86. + + Linux/PPC: Andreas Bogk reports that he has successfully compiled + tavrasm on a LinuxPPC machine. + + Linux/Alpha: Now works (after a little bug fix). + + FreeBSD: Lots of people runs tavrasm on FreeBSD. + + Sparc: I have received reports from serveral people running + tavrasm on a Sparc station. + + OS/2: I wrote the initial version of tavrasm on OS/2 (using emx) + + Note: On non-x86 machines remove -m486 from the makefile :) + + Bugs/Suggestions/Patches + ============================================================================= + + Please send any bug-reports/suggestions/patches to me (tom@tavrasm.org). + + History + ============================================================================= + + 1.18 - Added support for specifying unsigned integer values [0; 2^32-1] + + Thanks to Richard Gerrits for pointing out the problem. + + Added support for specifying Z/Y/Z for adiw, sbiw and movw. + + Thanks to Richard Barrington for suggesting this. + + Added support for a bunch of Mega devices. + + Thanks to Andreas Schwarz for supplying a patch with these. + + Fixed problems compiling with GCC 3.2 + + Several people supplied patches, but I was just too busy + integrating them. + + Thanks to Patrick Dreker for supplying the final patch. + + 1.17 - Added support for the BYTE1 (same as LOW) function. + + Thanks to Timothy Lee for supplying this patch. + + Fixed path delimiter problem in include path. I used + DOS style '\' causing problems on *NIX. + + Thanks to Timothy Lee for reporting this. + + 1.16 - Fixed problem with long macro names. + + Thanks to Richard Gerrits for reporting this. + + Increased maximum identifier length to 64 (and no, this was + not the fix to the problem above :). + + Added support for using DOS (\13\10) files on *NIX systems. + + Change URL to www.tavrasm.org in help/README/... + + 1.15 - Added support for multiple include path. Use '-I' to specify + additional include paths. + + Thanks to Brian Rhodefer for adding this. + + Added option to omit address extension record in Intel HEX files. + Use '-h' to omit address extension record. + + Released November 2000 + + 1.14 - Added support for forward .org statements. Use '-f' to supress + warnings. + + Thanks to Brian Rhodefer for suggesting this. + + Not released + + 1.13 - Some overall clean up and german translations. + + Added support for local labels. Use _ as the first charcter of a + label to give it local scope between two non-local labels. + + Specify -x to enable local labels. + + Changed range checking code to allow negative numbers in some cases. + + Thanks to Kurt Stege for implementing local labels and cleaning up + the code. + + Not released + + 1.12 - Added the 'spm' instruction (forgot the first time around) + + Thanks to Jochen Pernsteiner for pointing this out. + + Released December 1999 + + 1.11 - Now the Alpha problem is fixed (I forgot to move fix from test to + release source). + + Fixed promlem with detecting supported instructions (Introduced in + 1.10) - Thanks to Mark V. Vaysman for reporting this. + + Removed carriage returns from source, so it will compile under + *NIX without problems. Thanks to Todd M. Squires for reporting this. + + Released December 1999 + + 1.10 - Added the new instructions: 'eijmp', 'eicall', 'espm', 'mulsu', + 'fmul', 'fmuls', 'fmulsu', 'muls', 'movw', 'elpm'. + + Changed behaviour of 'lpm' according to Atmel specs. + + Added spanish translation - Thanks to Lluis Ballester for supplying + the Spanish translation. + + Fixed .endm problem (it had to be lower case) - It was reported + on comp.arch.embedded by Ben Cantrick. + + Released December 1999 + + 1.09 - Fixed problem with BRBC/BRBS (they did not work). I used the status + bit number for both source and destination operand (word of advise - + don't use variable names like 'values' and 'valued' in the same + context :) + + Fixed problem when compiling on Alpha's + + Thanks to Todd M. Squires for reporting these (and supplying a patch + for the Alpha problem). + + Released December 1999 + + + 1.08 - Fixed problem with SBR (Set Bits in Register). This is the same + as ORI, but the SBR version had a bug (one of those that generates + faulty code), bit 0 was always set. + + Thanks to Dean Huxley for reporting this (and supplying a patch). + + Added support for AT90S4433 (similar to 4414/4434). + + Released July 1999 + + + 1.07 - Added support for using PC as program counter (i.e. rjmp PC+4), + EC as eeprom counter and DC as data counter. + + Thanks to Adam Dybkowski for suggesting this. + + Released May 1999 + + + 1.06 - Added support for wrapping branches and relative call/jumps + Use the '-a' switch to enable this feature. + + Thanks to Jochen Pernsteiner for suggesting this. + + Restored the generic hex format. The generic hex format + disappeared in version 1.03 (when the default file format was + changed to Intel Hex). Use the '-g' switch to generate + generic hex (files that looks like this: "000021:f7f0"). + + Released May 1999 + + + 1.05 - Fixed problem with detection of binary numbers like '0b010101'. + This was bug was introduced by the new hex detection feature in + V. 1.04 :( + + Thanks to Randy Ott for reporting this. + + Fixed problem with memset of context stack that caused the winDOS + version to crash on some systems (strange that Linux/NT did not + detect this obvious memory violation). + + Thanks to Steve Maddigan for reporting this, and to my friend + Henning for finding the bug. + + Released May 1999 + + + 1.04 - Fixed problem with tabs after include filename, thanks to + Andreas Bogk for reporting this. + + Added support for specifying hex values like 1AB without '$' or '0x' + thanks to Andreas Bogk for suggesting this. + + Changed distribution format, so source i now located in a + sub-directory. + + Released April 1999 + + + 1.03 - Modified to support Intel hex as the default. + + Now automatically determines the output file name. + + Exits with a count of the number of errors (for make). + + Thanks to Jim Dowling for supplying these patches. + + Released March 1999 + + + 1.02 - Added support for German - Thanks to Uwe Bonnes for supplying + the German translation. + + Released February 1999 + + + 1.01 - Fixed alignment problem with forward references to .db in CSEG + ,thanks to Rob Penny for reporting this. + + Added a -d option to list supported devices. + + Updated the device information. + + Released January 1999 + + + 1.00 - Initial release September 1998 + + + TODO - None of these are critical, but would be nice :-) + ============================================================================= + + - Write some documentation !!! + + - Change source to new {} style (they finally convinced me :-) + + - Change handling of code/ROM buffers. + + - Make more language versions (French/Italian) (find someone to help me) + + - 0m01010101 Set mask + + - .def PowerStatus = Autoreg high = reset, monitor + + - opcode aliases med SBCI / SUBI = 255-ADCI/ADBI + + - Sinw / Cosw / Sinb / Cosb + + - define macros + + ============================================================================= + + Copenhagen, March 2003 + Tom Mortensen + + E-mail : tom@tavrasm.org + WWW : http://www.tavrasm.org + + ============================================================================= diff --git a/src/mkutil/tavrasm.118/gpl.txt b/src/mkutil/tavrasm.118/gpl.txt new file mode 100644 index 00000000..3cd95613 --- /dev/null +++ b/src/mkutil/tavrasm.118/gpl.txt @@ -0,0 +1,285 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the +original, so that any problems introduced by others will not reflect +on the original authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at +all. + +The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether +that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a +fee. + +2. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, +provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that + in whole or in part contains or is derived from the Program or + any part thereof, to be licensed as a whole at no charge to all + third parties under the terms of this License. + + c) If the modified program normally reads commands + interactively when run, you must cause it, when started running + for such interactive use in the most ordinary way, to print or + display an announcement including an appropriate copyright + notice and a notice that there is no warranty (or else, saying + that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to + view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an + announcement, your work based on the Program is not required to + print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding + machine-readable source code, which must be distributed under + the terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the + offer to distribute corresponding source code. (This + alternative is allowed only for noncommercial distribution and + only if you received the program in object code or executable + form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and +will automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted +herein. You are not responsible for enforcing compliance by third +parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE +LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS +AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF +ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. diff --git a/src/mkutil/tavrasm.118/src/8535def.inc b/src/mkutil/tavrasm.118/src/8535def.inc new file mode 100644 index 00000000..56dbae59 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/8535def.inc @@ -0,0 +1,366 @@ +;*************************************************************************** +;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y +;* +;* Number :AVR000 +;* File Name :"8535def.inc" +;* Title :Register/Bit Definitions for the AT90S8535 +;* Date :98.05.22 +;* Version :1.22 +;* Support telephone :+47 72 88 43 88 (ATMEL Norway) +;* Support fax :+47 72 88 43 99 (ATMEL Norway) +;* Support E-mail :avr@atmel.com +;* Target MCU :AT90S8535 +;* +;* DESCRIPTION +;* When including this file in the assembly program file, all I/O register +;* names and I/O register bit names appearing in the data book can be used. +;* In addition, the six registers forming the three data pointers X, Y and +;* Z have been assigned names XL - ZH. Highest RAM address for Internal +;* SRAM is also defined +;* +;* The Register names are represented by their hexadecimal address. +;* +;* The Register Bit names are represented by their bit number (0-7). +;* +;* Please observe the difference in using the bit names with instructions +;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" +;* (skip if bit in register set/cleared). The following example illustrates +;* this: +;* +;* in r16,PORTB ;read PORTB latch +;* sbr r16,(1< +#include +#include +#include "avrasm.hh" +#include "symbol.hh" +#include "semantic.hh" +#include "utils.hh" +#include "devices.hh" + +/// Globals ////////////////////////////////////////////////////////////////// + +GLOBALS(;); + +/// Externals //////////////////////////////////////////////////////////////// + +extern int yyparse(void); +extern FILE *yyin; +extern char messages[MESSAGE_COUNT][MESSAGES_LEN]; + +/// Functions //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Main + // + +int main(int argc, char **args) +{ + int parseresult; + int c; + int unusedcode = 0; + int unusederom = 0; + + /// Process arguments ////////////////////////////////////////////////////// + + yyIncPathCount = 0; + + if(!getargs(argc, args)) + return 0; + + /// Print header /////////////////////////////////////////////////////////// + + if(yycfg -> info) + printf(INFOSTR); + + /// Open input file //////////////////////////////////////////////////////// + + if(! (yyin= fopen(yyfilename,"r")) ) + errorexit(X_UNABLE_TO_OPEN_FILE, yyfilename); + if(! (yyin2= fopen(yyfilename,"r")) ) + errorexit(X_UNABLE_TO_OPEN_FILE, yyfilename); + + if(yylogfilename[0]) + { + if(! (yylogfile = fopen(yylogfilename,"w")) ) + errorexit(X_UNABLE_TO_OPEN_LOGFILE, yylogfilename); + } + else + yylogfile = NULL; + + /// Setup global symbols /////////////////////////////////////////////////// + + INITEXTERN; + yyparseno = 0; + yyfilecount = 1; + + if( !(yyfilelist[0] = new char[MAX_FILENAME_LENGTH]) ) + errorexit(X_OUT_OF_MEMORY); + + strcpy(yyfilelist[0], yyfilename); + + /// Allocate buffers /////////////////////////////////////////////////////// + + if( !(symtab = new symbolTable) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yycodebuf = new unsigned char[MAX_CODE_SIZE]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yyerombuf = new unsigned char[MAX_EROM_SIZE]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yycodeusage = new unsigned char[MAX_CODE_SIZE]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yyeromusage = new unsigned char[MAX_EROM_SIZE]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yycodeline = new unsigned short[MAX_CODE_SIZE]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yylinetxt = new char[MAX_LINE_LENGTH+1]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yyinline = new char[MAX_LINE_LENGTH+1]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yyinlinenew = new char[MAX_LINE_LENGTH+1]) ) + errorexit(X_OUT_OF_MEMORY); + if( !(yyinlineold = new char[MAX_LINE_LENGTH+1]) ) + errorexit(X_OUT_OF_MEMORY); + + for(c=0; cfilename, yyfilename); + + /// Setup device info ////////////////////////////////////////////////////// + + for(c=0; c init(yycfg->casesensitive); + yysymbolstack[0] = symtab; + + /// Start assembler //////////////////////////////////////////////////////// + + if(yylogfile) + { + fputs(INFOSTR, yylogfile); + fputs("\n+------------------+--------------------", yylogfile); + fputs("---------------------------------------+\n", yylogfile); + fputs("| Value | Text ", yylogfile); + fputs(" |\n", yylogfile); + fputs("|------------------|--------------------", yylogfile); + fputs("---------------------------------------|\n", yylogfile); + } + + parseresult = yyparse(); + + yycodepos = (yycodepos>yycodeposhigh) ? yycodepos : yycodeposhigh; + yydatapos = (yydatapos>yydataposhigh) ? yydatapos : yydataposhigh; + yyerompos = (yyerompos>yyeromposhigh) ? yyerompos : yyeromposhigh; + + for(c=0;cinfo) + { + printf("\n"); + message(M_ERRORS , yyerrorcount); + message(M_WARNINGS , yywarningcount); + message(M_CODE , yycodepos/2); + message(M_ROM , yyerompos); + message(M_DATA , yydatapos-DEVINF.datastart); + message(M_UNUSED_CODE , unusedcode); + message(M_UNUSED_ROM , unusederom); + } + + /// Save results /////////////////////////////////////////////////////////// + + if(!yyerrorcount) + { + if(yycfg -> intel) + saveIHF(); + else if(yycfg -> motorola) + saveMotorola(); + else if(yycfg -> obj) + saveObj(); + else if(yycfg -> bin) + saveBin(); + else + saveGeneric(); + } + + exit(yyerrorcount); + +} + + //////////////////////////////////////////////////////////////////////////// + // + // Get commandline arguments. + // + //////////////////////////////////////////////////////////////////////////// + // + // -o = output file + // -r = rom file + // -e = list file + // -v = verbose + // -w = no warnings + // -c = case sensitive labels/defines + // -l = limit log width to 80 characters + // -x = allow local labels + // -a = do not align .db in CSEG + // -m = output Motorola S-record format + // -i = output Intel HEX format + // -j = output ATMEL .obj format + // -g = output ATMEL generic format + // + +int getargs(int argc, char **args) +{ + int c; + int ok = TRUE; + + if(argc==1) + { + printf(INFOSTR); + printf("\n"); + printf(HELPSTR); + return FALSE; + } + + // List devices //////////////////////////////////////////////////////////// + + else if( (argc==2) && !strcmp(args[1],"-d")) { + + int devno = 0; + printf("+---------------------------------------------------" + "-----------------+\n"); + message(M_DEVICE_HEADER); + printf("|------------------+-----------+------------+-------" + "---+-------------|\n"); + while(devices[devno].name[0]) { + printf("| %-16s | %8d | %10d | %8d | %11d |\n", devices[devno].name, + devices[devno].datastart, + devices[devno].flashsize, + devices[devno].ramsize, + devices[devno].eepromsize); + devno++; + } + printf("+---------------------------------------------------" + "-----------------+\n"); + return FALSE; /* Nick false; */ + } + + /// Allocate filename strings ////////////////////////////////////////////// + + if(!(yyfilename = new char[MAX_FILENAME_LENGTH+1])) + errorexit(X_OUT_OF_MEMORY); + if(!(yyromfilename = new char[MAX_FILENAME_LENGTH+1])) + errorexit(X_OUT_OF_MEMORY); + if(!(yylogfilename = new char[MAX_FILENAME_LENGTH+1])) + errorexit(X_OUT_OF_MEMORY); + if(!(yyoutfilename = new char[MAX_FILENAME_LENGTH+1])) + errorexit(X_OUT_OF_MEMORY); + + yyfilename[0]=yyromfilename[0]=yylogfilename[0]=yyoutfilename[0] = '\0'; + + /// Setup default configuration //////////////////////////////////////////// + + if( !(yycfg = new configuration) ) + errorexit(X_OUT_OF_MEMORY); + + memset(yycfg, 0, sizeof(configuration)); + + yycfg -> info = FALSE; // -v + yycfg -> warnings = TRUE; // -w + yycfg -> casesensitive = FALSE; // -c + yycfg -> cutlog = FALSE; // -l + yycfg -> aligndb = TRUE; // no command line option anymore + yycfg -> motorola = FALSE; // -m + yycfg -> intel = FALSE; // -i + yycfg -> hex = FALSE; // -g + yycfg -> obj = FALSE; // -j + yycfg -> bin = FALSE; // -b + yycfg -> wrap = FALSE; // -a + yycfg -> local_labels = FALSE; // -x + yycfg -> forwardorg = FALSE; // -f + yycfg -> addressext = TRUE; // -h + + /// Get command line options /////////////////////////////////////////////// + + for(c=1;cMAX_FILENAME_LENGTH) + message(M_INPUT_FILENAME_TOO_LONG); + else if(!checkfilename(args[c])) + message(M_ILLEGAL_INPUT_FILENAME); + else if(yyfilename[0]) + message(M_MULTIPLE_INPUT); + else + { + ok = TRUE; + strcpy(yyfilename, args[c]); + } + } + else + { + if(strlen(args[c])>2) + { + message(M_UNKNOWN_OPTION ,args[c]); + ok = FALSE; + } + else + { + switch(args[c][1]) + { + + /// Include path //////////////////////////////////////////////////// + // + case 'I' : + { + ok = FALSE; + if (c == argc-1) + message (M_NO_INCLUDEPATH); + + else if(strlen(args[c+1]) > MAX_INCPATH_LENGTH) + message(M_INCPATH_TOO_LONG); + + else if (MAX_INCPATH_QTY == yyIncPathCount) + message(M_TOO_MANY_INCPATHS); + + else + { + yyIncludePaths[yyIncPathCount++] = args[++c]; + ok = TRUE; + } + } break; + + + /// output file //////////////////////////////////////////////////// + + case 'o' : + { + ok = FALSE; + + if(c==argc-1) + message(M_NO_OUTPUT_FILENAME); + else if(strlen(args[c+1])>MAX_FILENAME_LENGTH) + message(M_OUTPUT_FILENAME_TOO_LONG); + else if(!checkfilename(args[c+1])) + message(M_ILLEGAL_OUTPUT_FILENAME); + else if(yyoutfilename[0]) + message(M_MULTIPLE_OUTPUT); + else + { + strcpy(yyoutfilename, args[c+1]); + c++; + ok = TRUE; + } + } break; + + /// rom file /////////////////////////////////////////////////////// + + case 'e' : + { + ok = FALSE; + + if(c==argc-1) + message(M_NO_LIST_FILENAME); + else if(strlen(args[c+1])>MAX_FILENAME_LENGTH) + message(M_LIST_FILENAME_TOO_LONG); + else if(!checkfilename(args[c+1])) + message(M_ILLEGAL_LIST_FILENAME); + else + { + strcpy(yylogfilename, args[c+1]); + c++; + ok = TRUE; + } + } break; + + /// list file ////////////////////////////////////////////////////// + + case 'r' : + { + ok = FALSE; + + if(c==argc-1) + message(M_NO_ROM_FILENAME); + else if(strlen(args[c+1])>MAX_FILENAME_LENGTH) + message(M_ROM_FILENAME_TOO_LONG); + else if(!checkfilename(args[c+1])) + message(M_ILLEGAL_ROM_FILENAME); + else + { + strcpy(yyromfilename, args[c+1]); + c++; + ok = TRUE; + } + } break; + + /// verbose //////////////////////////////////////////////////////// + + case 'v' : yycfg -> info = TRUE; break; + + /// no warnings //////////////////////////////////////////////////// + + case 'w' : yycfg -> warnings = FALSE; break; + + /// case sensitive labels/defines ////////////////////////////////// + + case 'c' : yycfg -> casesensitive = TRUE; break; + + /// limit log width to 80 characters /////////////////////////////// + + case 'l' : yycfg -> cutlog = TRUE; break; + + /// Wrap relative jumps/branches /////////////////////////////////// + + case 'a' : yycfg -> wrap = TRUE; break; + + /// allow local labels ///////////////////////////////////////////// + + case 'x' : yycfg -> local_labels = TRUE; break; + + /// do not align .db in CSEG /////////////////////////////////////// + + // case 'a' : yycfg -> aligndb = FALSE; break; + + /// output Motorola S-record format //////////////////////////////// + + case 'm' : + { + if(yycfg->intel || yycfg->obj || yycfg->bin || yycfg->hex ) + { + message(M_MORE_MIJBH); + ok = FALSE; + } + else + yycfg -> motorola = TRUE; + } + break; + + /// output Intel HEX format //////////////////////////////////////// + + case 'i' : + { + if(yycfg->motorola || yycfg->obj || yycfg->bin || yycfg->hex) + { + message(M_MORE_MIJBH); + ok = FALSE; + } + else + yycfg -> intel = TRUE; + + + } + break; + + /// output .obj format ///////////////////////////////////////////// + + case 'j' : + { + if(yycfg->motorola || yycfg->intel || yycfg->bin || yycfg->hex) + { + message(M_MORE_MIJBH); + ok = FALSE; + } + else + yycfg -> obj = TRUE; + } + break; + + /// output .bin format ///////////////////////////////////////////// + + case 'b' : + { + if(yycfg->motorola || yycfg->intel || yycfg->obj || yycfg->hex) + { + message(M_MORE_MIJBH); + ok = FALSE; + } + else + yycfg -> bin = TRUE; + } + break; + + /// Supress .org warnings ////////////////////////////////////////// + + case 'f' : + { + yycfg -> forwardorg = TRUE; + } + break; + + /// output .obj format ///////////////////////////////////////////// + + case 'g' : + { + if(yycfg->motorola || yycfg->intel || yycfg->obj || yycfg->bin) + { + message(M_MORE_MIJBH); + ok = FALSE; + } + else + yycfg -> hex = TRUE; + } + break; + + /// No address entension record in Intel HEX output //////////////// + + case 'h' : yycfg -> addressext = FALSE; break; + + /// ignore -d flag ///////////////////////////////////////////////// + + case 'd' : break; + + /// Unknown option ///////////////////////////////////////////////// + + default : message(M_UNKNOWN_OPTION , args[c]); ok=FALSE; + } + } + } + } + + if(!yyfilename[0]) + { + ok = FALSE; /* Nick false; */ + message(M_NO_INPUT_FILENAME); + } + + if(!yycfg->motorola&&!yycfg->hex&&!yycfg->intel&&!yycfg->bin&&!yycfg->obj) + yycfg->intel = TRUE; + + if(!yyoutfilename[0]) + { + char *type_start; + + strcpy(yyoutfilename, yyfilename); + type_start = strrchr(yyoutfilename, '.'); + if (type_start == NULL) + type_start = yyoutfilename + strlen(yyoutfilename); + + if (yycfg->intel) + strcpy(type_start, ".hex"); + else if (yycfg->motorola) + strcpy(type_start, ".s"); + else if (yycfg->bin) + strcpy(type_start, ".bin"); + else if (yycfg->obj) + strcpy(type_start, ".obj"); + else if (yycfg->hex) + strcpy(type_start, ".gen"); + else + strcpy(type_start,"."); + } + + return ok; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Save Intel Hex Format (IHF) + // + //////////////////////////////////////////////////////////////////////////// + // + // :LLAAAATTDD.......DDSS + // ^^ ^ ^ ^ ^ + // 12 4 8 10 end-2 (field positions) + // + // FIELD 1 (COLUMN 1) + // + // a : symbol, each record uses a colon as a start delimiter. + // + // FIELD 2 (COLUMN 2) + // + // length byte, a two digit ASCII hex representation of the number + // of data bytes to be transmitted in this record. + // + // FIELD 3 (COLUMN 4) + // + // address word, a four digit ASCII hex representation of the target + // load address of the first byte of the following packet. This field + // is always 4 digits long, hence addresses are limited to 16 bits. See + // note later for more information. + // + // FIELD 4 (COLUMN 8) + // + // record type, a two digit ASCII hex representation of an integer which + // in turn denotes the record type. + // There are three record types 0,1 and 2 + // + // Record Type 0 - Normal Data packet + // Record Type 1 - End of file record. The last record in the file has + // a type of 1. + // Record Type 2 - Address Extension Record. A special record type used + // to extend addresses beyond 16 bits. + // + // FIELD 5 (COLUMN 10) + // + // start of data bytes. Data bytes in two digit ASCII form. Variable + // length field, usually a small power of 2 e.g. 16. + // + // + // FIELD 6 (LAST 2 COLUMNS) + // + // checksum. A two digit ascii representation of a special checksum for + // the record. The checksum is the 2's complement of the true sum of all + // the bytes in the record, starting with the record length and ending + // with the last data byte. This allows limited error detection facilites + // for the data packet. + // + // Sample file : + // + // :020000020000FC + // :0600220018950895F89402 + // :1000440000000000000000000000000000000000AC + // :0E00540000000000000000000000000000F7A7 + // :00000001FF + // + +int saveIHF(void) +{ + int c, i; + FILE *out; + int count; + int line[16]; + int sum; + int last; + + /// Save code output file ////////////////////////////////////////////////// + + if(!yyoutfilename[0]) + return TRUE; + + if(! (out= fopen(yyoutfilename,"w")) ) + errorexit(X_UNABLE_TO_OPEN_OUTFILE, yyoutfilename); + + /// Address extension record, offset 0x0000 //////////////////////////////// + + if(yycfg -> addressext) + fprintf(out, ":020000020000FC\n"); + + /// Save data ////////////////////////////////////////////////////////////// + + if(!yycodepos) + message(M_EMPTY_CODE); + + c = 0; + + while(c>8); +#else + sum = count + (c&0x00FFL) + ((c&0xFF00L)>>8); +#endif + + fprintf(out, ":%02X%04X00",count,c); + + for(i=0;i addressext) + fprintf(out, ":020000020000FC\n"); + + /// Save data ////////////////////////////////////////////////////////////// + + c = 0; + + while(c>8); +#else + sum = count + (c&0x00FFL) + ((c&0xFF00L)>>8); +#endif + + fprintf(out, ":%02X%04X00",count,c); + + for(i=0;i>24, out); + fputc( (offset & 0x00FF0000)>>16, out); + fputc( (offset & 0x0000FF00)>> 8, out); + fputc( (offset & 0x000000FF)>> 0, out); + + fputc( ( 0x1A & 0xFF000000)>>24, out); + fputc( ( 0x1A & 0x00FF0000)>>16, out); + fputc( ( 0x1A & 0x0000FF00)>> 8, out); + fputc( ( 0x1A & 0x000000FF)>> 0, out); +#else + fputc( (offset & 0xFF000000L)>>24, out); + fputc( (offset & 0x00FF0000L)>>16, out); + fputc( (offset & 0x0000FF00L)>> 8, out); + fputc( (offset & 0x000000FFL)>> 0, out); + + fputc( ( 0x1A & 0xFF000000L)>>24, out); + fputc( ( 0x1A & 0x00FF0000L)>>16, out); + fputc( ( 0x1A & 0x0000FF00L)>> 8, out); + fputc( ( 0x1A & 0x000000FFL)>> 0, out); +#endif + + fputc( 0x09, out); + fputc( yyfilecount, out); + fputs( "AVR Object File", out); + fputc(0, out); + + for(c=0;c>16, out); + fputc( (c/2 & 0x0000FF00)>> 8, out); + fputc( (c/2 & 0x000000FF)>> 0, out); + fputc( (yycodebuf[c+1] & 0x00FF) >> 0, out); + fputc( (yycodebuf[c] & 0x00FF) >> 0, out); + fputc( (yycodeusage[c]-1 & 0x007F) >> 0, out); + fputc( (yycodeline[c] & 0xFF00) >> 8, out); + fputc( (yycodeline[c] & 0x00FF) >> 0, out); + fputc( (yycodeusage[c] & 0x0080) != 0, out); +#else + fputc( (c/2 & 0x00FF0000L)>>16, out); + fputc( (c/2 & 0x0000FF00L)>> 8, out); + fputc( (c/2 & 0x000000FFL)>> 0, out); + fputc( (yycodebuf[c+1] & 0x00FFL) >> 0, out); + fputc( (yycodebuf[c] & 0x00FFL) >> 0, out); + fputc( (yycodeusage[c]-1 & 0x007FL) >> 0, out); + fputc( (yycodeline[c] & 0xFF00L) >> 8, out); + fputc( (yycodeline[c] & 0x00FFL) >> 0, out); + fputc( (yycodeusage[c] & 0x0080L) != 0, out); +#endif + } + } + + for(c=0;c>8) + 3; +#else + sum = count + (c&0x00FFL) + ((c&0xFF00L)>>8) + 3; +#endif + + fprintf(out, "S1%02X%04X",count+3,c); + + for(i=0;i>8) + 3; +#else + sum = count + (c&0x00FFL) + ((c&0xFF00L)>>8) + 3; +#endif + + fprintf(out, "S1%02X%04X",count+3,c); + + for(i=0;i increased MAX_DEVICES from 13 to 23 +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _AVRASM_HH_ +#define _AVRASM_HH_ + +#ifndef _MSC_VER /* Nick */ +typedef int bool; +#endif + +/// Defines ////////////////////////////////////////////////////////////////// + +#define FALSE 0 // No +#define TRUE (!0) // Yes + +#ifdef _MSC_VER /* Nick original definition: */ +#define MAX_CODE_SIZE 0x100000 // Code size in bytes +#define MAX_EROM_SIZE 0x10000 // Erom size in bytes +#define MAX_LINE_LENGTH (255+3) // Maximum length of input lines +#define MAX_ID_LENGTH 64 // name defined as MAX_ID_LEN+1 +#define MAX_DEVICE_NAME_LENGTH 16 // Like "90S1200" +#define MAX_DEVICES 23 // Update with "devices.hh" +#define MAX_FILENAME_LENGTH 512 // Should be changed to platform +#else /* Nick reduced for 16-bit version: */ +#define MAX_CODE_SIZE 0x4000 // Code size in bytes +#define MAX_EROM_SIZE 0x400 // Erom size in bytes +#define MAX_LINE_LENGTH (255+3) // Maximum length of input lines +#define MAX_ID_LENGTH 32 // name defined as MAX_ID_LEN+1 +#define MAX_DEVICE_NAME_LENGTH 16 // Like "90S1200" +#define MAX_DEVICES 23 // Update with "devices.hh" +#define MAX_FILENAME_LENGTH 16 // Should be changed to platform +#endif +#define MAX_INCPATH_LENGTH 512 // Should be changed to platform +#define MAX_CONTEXT_DEPTH 32 // Depth of macros/include files +#define MAX_FILES 127 // Files/includes (don't change) +#define MAX_INCPATH_QTY 8 // Max number of include search dirs + +#define VERSIONSTR "1.18" // Version + +#define SEGMENT_CODE 1 // CSEG +#define SEGMENT_DATA 2 // DSEG +#define SEGMENT_EEPROM 3 // ESEG +#define SEGMENT_DEFINE_BYTE 1 // '.byte' in ESEG + +#define LIST_NO 1 // .nolist +#define LIST_NO_MACRO 2 // .nolistmac +#define LIST_YES_MACRO 3 // .listmac +#define LIST_YES 4 // .list + + /// Command line info ////////////////////////////////////////////////////// + +#define INFOSTR "Toms AVR macro assembler version "VERSIONSTR" ("__DATE__ \ + ")\nCopyright (C) 2000 - Tom Mortensen\n" \ + "E-mail: tom@tavrasm.org WWW: http://www.tavrasm.org\n" + +/// Supported instructions /////////////////////////////////////////////////// + +#define S_ADIW (1<< 0) +#define S_ICALL (1<< 1) +#define S_CALL (1<< 2) +#define S_IJMP (1<< 3) +#define S_JMP (1<< 4) +#define S_LD (1<< 5) +#define S_LDD (1<< 6) +#define S_LDS (1<< 7) +#define S_LPM (1<< 8) +#define S_MUL (1<< 9) +#define S_PUSH (1<<10) +#define S_POP (1<<11) +#define S_SBIW (1<<12) +#define S_ST (1<<13) +#define S_STD (1<<14) +#define S_STS (1<<15) +#define S_EIJMP (1<<16) +#define S_EICALL (1<<17) +#define S_ESPM (1<<18) +#define S_MULSU (1<<19) +#define S_FMUL (1<<20) +#define S_FMULS (1<<21) +#define S_FMULSU (1<<22) +#define S_MULS (1<<23) +#define S_MOVW (1<<24) +#define S_ELPM (1<<25) +#define S_SPM (1<<26) + +#define S_EXTENDED (0xFFFF0000) + +/// Macros /////////////////////////////////////////////////////////////////// + +#define STRIPNR(s) {char* pos;if((pos=strpbrk(s,"\r\n"))&&(*pos='\0'));} +#define STRIPWS(s) {char* pos;if((pos=strpbrk(s,"\v\t \r\n")))*pos='\0';} +#define DEVINF yydevices[yydeviceno] +#define ISUSED(s) (s->macro||s->isvar||s->valid||s->isdefine) +#define MSG(m) messages[MESSAGE_OFFSET_MESSAGES+m] +#define CONTEXT yycontextstack[yycontext] +#define ISMACRO (yycontextstack[yycontext]->ismacro) +#define CHECKREG(r,d) { if(r<0) r = d; else if(r>31) internalerror("REG"); } + +/// Globals ////////////////////////////////////////////////////////////////// + +#define GLOBALS(asextern) \ +asextern int yyline; \ +asextern int yyoffset; \ +asextern int yyeromoffset; \ +asextern int yydataoffset; \ +asextern int yycodepos; \ +asextern int yyerompos; \ +asextern int yydatapos; \ +asextern int yycodeposhigh; \ +asextern int yyeromposhigh; \ +asextern int yydataposhigh; \ +asextern int yyparseno; \ +asextern int yyerrorcount; \ +asextern int yyerrorline; \ +asextern int yywarningline; \ +asextern int yywarningcount; \ +asextern int yysegment; \ +asextern int yydefinestart; \ +asextern int yyinmacro; \ +asextern int yycontext; \ +asextern int yydeviceno; \ +asextern int yydefinetype; \ +asextern int yylist; \ +asextern int yylistmacro; \ +asextern int yyfirstmacroline; \ +asextern int yyinmacrodef; \ +asextern int yyfileno; \ +asextern int yyfilecount; \ +asextern int yyeol; \ +asextern int yyIncPathCount; \ +asextern char *yylinetxt; \ +asextern char *yyinline; \ +asextern char *yyinlinenew; \ +asextern char *yyinlineold; \ +asextern char *yyfilename; \ +asextern char *yyromfilename; \ +asextern char *yylogfilename; \ +asextern char *yyoutfilename; \ +asextern char *yyfilelist[MAX_FILES]; \ +asextern char *yyIncludePaths[MAX_INCPATH_QTY]; \ +asextern unsigned char *yycodebuf; \ +asextern unsigned char *yyerombuf; \ +asextern unsigned char *yycodeusage; \ +asextern unsigned char *yyeromusage; \ +asextern unsigned short *yycodeline; \ +asextern configuration *yycfg; \ +asextern symbolTable* symtab; \ +asextern context *yycontextstack[MAX_CONTEXT_DEPTH]; \ +asextern symbolTable *yysymbolstack[MAX_CONTEXT_DEPTH]; \ +asextern deviceinfo yydevices[MAX_DEVICES]; \ +asextern FILE* yyin2; \ +asextern FILE* yylogfile; \ +asextern char yylast_used_label[MAX_ID_LENGTH+1]; + +/// Init Globals ///////////////////////////////////////////////////////////// + +#define INITEXTERN \ +{ \ + yyline = 1; \ + yyoffset = 0; \ + yyeromoffset = 0; \ + yydataoffset = 0; \ + yycodepos = 0; \ + yyerompos = 0; \ + yydatapos = 96; \ + yycodeposhigh = 0; \ + yyeromposhigh = 0; \ + yydataposhigh = 0; \ + yyerrorcount = 0; \ + yywarningcount = 0; \ + yydefinestart = -1; \ + yysegment = SEGMENT_CODE; \ + yyinmacro = FALSE; \ + yycontext = 0; \ + yyerrorline =-1; \ + yywarningline = -1; \ + yydeviceno = 0; \ + yydefinetype = 0; \ + yylist = TRUE; \ + yylistmacro = FALSE; \ + yyfirstmacroline = FALSE; \ + yyinmacrodef = FALSE; \ + yyfileno = 1; \ + yyeol = FALSE; \ + yylast_used_label[0] = '\0'; \ +} + +/// Configuration //////////////////////////////////////////////////////////// + +struct configuration +{ + char aligndb; // Allow byte alignment + char casesensitive; // Case sensitive labels/vars + char cutlog; // Limit logfile width to 80 chars + char info; // Show info after compilation + char warnings; // Print warnings + char local_labels; // Allow local loabels + char motorola; // Output Motorola S-record format + char intel; // Output Intel HEX format + char obj; // Output ATMEL .obj format + bool hex; // Output generic hex + char bin; // Output binary format + bool wrap; // Wrap in relative jumps/branches + bool forwardorg; // Allow .org to jump around + bool addressext; // Include address extension record +}; + +/// Device info ////////////////////////////////////////////////////////////// + +struct deviceinfo { + char name[MAX_DEVICE_NAME_LENGTH+1]; // Device name + int datastart; // Registers + I/O ports + int ramsize; // Size of ram + int eepromsize; // Size of EEPROM + int flashsize; // Size of flash (in words) + int supported; // Unsupported instructions +}; + +/// Types //////////////////////////////////////////////////////////////////// + +struct context +{ + // Regular file + + char filename[MAX_FILENAME_LENGTH]; + int line; + FILE *file; + FILE *file2; + + // Macro + + int ismacro; + char *macstr; + int offset; + int eromoffset; + int dataoffset; + int stringpos; + + // Line buffers + + char yyinline[MAX_LINE_LENGTH+1]; + char yyinlinenew[MAX_LINE_LENGTH+1]; + char yyinlineold[MAX_LINE_LENGTH+1]; +}; + +/// Prototypes /////////////////////////////////////////////////////////////// + +void yyerror(char *s); +int getargs(int argc, char **args); +int saveIHF(void); +int saveGeneric(void); +int saveObj(void); +int saveMotorola(void); +int saveBin(void); + +#endif /* _AVRASM_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/avrlex.cc b/src/mkutil/tavrasm.118/src/avrlex.cc new file mode 100644 index 00000000..b4f3abc9 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrlex.cc @@ -0,0 +1,3202 @@ +/* #line 2 "avrlex.cc" */ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include +#ifdef _MSC_VER /* Nick */ +#include +/* #else */ +/* #include */ +#endif + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +/* Nick static */ void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +/* Nick static */ void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define yywrap() 1 +#define YY_SKIP_YYWRAP +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 198 +#define YY_END_OF_BUFFER 199 +static yyconst short /* Nick short int */ yy_accept[397] = + { 0, + 0, 0, 199, 197, 193, 192, 26, 197, 196, 197, + 3, 15, 197, 17, 18, 1, 22, 20, 23, 21, + 2, 180, 180, 19, 194, 8, 24, 9, 16, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 162, 163, + 164, 14, 25, 193, 197, 21, 193, 11, 0, 178, + 0, 196, 183, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 180, 184, 184, 0, 194, 4, 6, + 10, 7, 5, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 51, 168, 191, 169, + + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 155, 191, 158, 191, 191, 191, 191, 191, 191, 191, + 191, 59, 191, 191, 167, 191, 191, 179, 191, 191, + 191, 191, 191, 191, 191, 191, 159, 191, 191, 191, + 191, 12, 193, 0, 0, 0, 0, 0, 0, 0, + 178, 190, 0, 190, 0, 0, 0, 0, 30, 0, + 0, 31, 0, 29, 0, 0, 0, 195, 182, 181, + 55, 54, 191, 57, 99, 191, 152, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 153, 191, 191, 143, 154, 116, 121, 123, 118, + + 104, 120, 122, 119, 117, 106, 50, 70, 191, 101, + 191, 191, 191, 58, 191, 191, 191, 191, 191, 191, + 191, 98, 139, 160, 75, 76, 191, 39, 165, 151, + 100, 191, 60, 62, 96, 124, 73, 147, 191, 102, + 191, 191, 128, 191, 149, 107, 52, 144, 77, 108, + 113, 115, 110, 150, 112, 114, 111, 109, 191, 133, + 161, 148, 53, 191, 105, 130, 0, 0, 0, 0, + 0, 0, 189, 187, 0, 0, 0, 0, 27, 0, + 0, 0, 28, 0, 32, 34, 68, 74, 135, 141, + 142, 78, 79, 81, 86, 88, 89, 92, 93, 95, + + 87, 83, 80, 82, 94, 90, 91, 84, 85, 136, + 191, 140, 56, 191, 191, 166, 134, 48, 65, 40, + 46, 191, 126, 49, 45, 61, 63, 47, 103, 191, + 127, 138, 71, 145, 146, 69, 156, 157, 191, 72, + 97, 0, 0, 0, 0, 0, 187, 0, 185, 0, + 33, 36, 0, 37, 177, 38, 41, 42, 43, 44, + 191, 131, 66, 125, 64, 137, 129, 174, 0, 173, + 0, 0, 0, 0, 0, 132, 67, 0, 0, 176, + 0, 188, 0, 186, 0, 35, 0, 0, 171, 175, + 172, 0, 175, 0, 170, 0 + + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 1, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 27, 27, 28, 28, 29, 30, 31, + 32, 33, 1, 1, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 36, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 1, 34, 1, 35, 36, 1, 37, 38, 39, 40, + + 41, 42, 43, 44, 45, 46, 36, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 1, 62, 1, 63, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[64] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 4, 4, 4, 4, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 5, 4, 4, 4, 4, + 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 1, 1 + } ; + +static yyconst short /* Nick short int */ yy_base[412] = + { 0, + 0, 62, 536, 537, 65, 537, 503, 57, 0, 0, + 537, 522, 499, 537, 537, 537, 537, 537, 537, 34, + 511, 70, 31, 537, 0, 45, 499, 46, 537, 0, + 64, 67, 85, 42, 92, 482, 41, 94, 481, 94, + 69, 39, 47, 91, 131, 124, 474, 487, 0, 0, + 0, 464, 537, 181, 172, 164, 158, 537, 116, 537, + 159, 0, 0, 537, 512, 197, 464, 469, 187, 142, + 469, 480, 0, 67, 0, 79, 0, 0, 537, 537, + 537, 537, 537, 0, 150, 480, 466, 471, 477, 219, + 143, 461, 468, 116, 193, 466, 161, 0, 474, 0, + + 127, 461, 458, 459, 458, 452, 464, 453, 468, 456, + 464, 451, 186, 186, 453, 180, 447, 442, 451, 454, + 445, 450, 439, 450, 0, 441, 437, 236, 453, 434, + 440, 183, 216, 239, 446, 438, 195, 447, 447, 428, + 429, 537, 285, 293, 261, 262, 432, 435, 442, 428, + 200, 537, 464, 463, 302, 462, 419, 432, 537, 223, + 431, 537, 431, 414, 428, 425, 412, 0, 93, 0, + 0, 0, 408, 420, 0, 411, 0, 264, 265, 411, + 421, 268, 176, 262, 416, 419, 412, 414, 281, 284, + 402, 0, 415, 408, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, + 416, 404, 403, 0, 402, 425, 401, 403, 406, 398, + 393, 0, 0, 0, 0, 0, 419, 0, 0, 0, + 0, 402, 383, 383, 0, 0, 0, 0, 383, 0, + 375, 365, 362, 351, 0, 0, 352, 291, 292, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 348, 0, + 0, 0, 343, 336, 0, 0, 327, 340, 345, 329, + 343, 321, 537, 537, 328, 354, 324, 321, 537, 318, + 319, 313, 537, 305, 537, 537, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 333, 0, 0, 300, 293, 0, 0, 0, 289, 0, + 0, 295, 0, 0, 0, 0, 284, 0, 0, 292, + 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, + 0, 281, 287, 278, 279, 256, 537, 347, 537, 285, + 537, 537, 246, 537, 537, 537, 0, 0, 0, 0, + 234, 0, 223, 0, 0, 0, 0, 537, 216, 223, + 209, 199, 353, 239, 210, 0, 0, 203, 202, 537, + 152, 537, 368, 537, 186, 537, 156, 149, 120, 0, + 537, 112, 0, 99, 537, 537, 395, 400, 113, 405, + + 410, 412, 417, 422, 83, 81, 425, 427, 429, 431, + 435 + } ; + +static yyconst short /* Nick short int */ yy_def[412] = + { 0, + 396, 1, 396, 396, 396, 396, 396, 397, 398, 399, + 396, 396, 400, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 22, 396, 401, 396, 396, 396, 396, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 396, 396, 396, 396, 396, 396, 396, 397, 396, + 397, 398, 399, 396, 396, 403, 396, 396, 396, 396, + 396, 396, 404, 22, 405, 405, 406, 401, 396, 396, + 396, 396, 396, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 45, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 397, 396, 396, 396, 396, 407, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 404, 405, 406, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 408, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 396, 396, 396, 396, 396, 396, 396, 396, 409, + 396, 396, 396, 396, 396, 396, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 396, 396, 396, + 396, 396, 396, 410, 396, 402, 402, 396, 396, 396, + 396, 396, 396, 396, 410, 396, 396, 396, 396, 411, + 396, 396, 411, 396, 396, 0, 396, 396, 396, 396, + + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396 + } ; + +static yyconst short /* Nick short int */ yy_nxt[601] = + { 0, + 4, 5, 6, 4, 5, 5, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 23, 23, 23, 23, 23, 24, 25, + 26, 27, 28, 4, 29, 30, 31, 32, 33, 34, + 35, 36, 30, 37, 38, 39, 40, 41, 42, 43, + 44, 30, 45, 46, 47, 30, 30, 48, 49, 50, + 51, 52, 53, 54, 60, 55, 57, 54, 75, 57, + 57, 67, 68, 69, 70, 79, 80, 82, 83, 120, + 98, 56, 99, 71, 170, 107, 75, 72, 121, 396, + 61, 74, 74, 74, 74, 74, 74, 74, 108, 122, + + 169, 169, 123, 85, 75, 88, 75, 76, 75, 75, + 75, 75, 86, 89, 169, 169, 63, 87, 118, 90, + 91, 93, 94, 60, 119, 396, 92, 124, 77, 125, + 100, 95, 109, 113, 96, 97, 101, 395, 102, 110, + 126, 103, 111, 114, 115, 104, 127, 116, 394, 61, + 105, 117, 128, 128, 128, 128, 128, 128, 128, 57, + 195, 133, 57, 57, 134, 211, 151, 392, 196, 129, + 135, 130, 212, 144, 136, 144, 131, 144, 137, 138, + 132, 139, 143, 191, 144, 57, 143, 391, 171, 172, + 163, 145, 61, 164, 173, 165, 390, 192, 384, 207, + + 145, 67, 68, 69, 146, 208, 389, 60, 147, 154, + 148, 149, 150, 71, 209, 298, 299, 72, 155, 155, + 155, 155, 155, 155, 159, 224, 230, 160, 227, 245, + 225, 197, 231, 61, 261, 246, 198, 199, 388, 226, + 161, 200, 387, 228, 162, 201, 202, 203, 262, 204, + 386, 384, 381, 205, 247, 156, 178, 179, 380, 180, + 248, 181, 182, 183, 279, 184, 185, 186, 249, 187, + 379, 378, 188, 189, 84, 190, 84, 250, 377, 280, + 376, 84, 251, 252, 375, 84, 143, 253, 144, 57, + 143, 254, 255, 256, 144, 257, 144, 349, 144, 258, + + 372, 267, 290, 292, 145, 147, 296, 148, 149, 150, + 163, 300, 145, 164, 274, 165, 301, 291, 293, 306, + 268, 297, 308, 275, 275, 275, 275, 275, 275, 334, + 337, 371, 370, 369, 307, 368, 367, 309, 366, 365, + 347, 364, 363, 362, 335, 338, 361, 356, 336, 348, + 348, 348, 348, 348, 348, 357, 358, 359, 360, 347, + 355, 354, 353, 352, 351, 382, 349, 346, 373, 373, + 373, 373, 373, 373, 383, 383, 383, 383, 383, 383, + 382, 345, 344, 343, 342, 268, 341, 340, 339, 383, + 383, 383, 383, 383, 383, 59, 333, 59, 59, 59, + + 62, 332, 62, 62, 62, 65, 331, 65, 65, 65, + 78, 330, 78, 78, 78, 84, 84, 153, 329, 153, + 153, 153, 168, 328, 168, 168, 168, 276, 276, 350, + 350, 374, 374, 385, 385, 393, 327, 393, 393, 393, + 326, 325, 324, 323, 322, 321, 320, 319, 318, 317, + 316, 315, 314, 313, 312, 311, 310, 305, 304, 303, + 302, 295, 294, 289, 288, 287, 286, 285, 284, 283, + 282, 281, 278, 277, 273, 273, 273, 272, 271, 270, + 269, 266, 265, 264, 263, 260, 259, 244, 243, 242, + 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, + + 229, 223, 222, 221, 220, 219, 218, 217, 216, 215, + 214, 213, 210, 206, 194, 193, 177, 176, 175, 174, + 167, 166, 158, 157, 152, 142, 141, 140, 112, 106, + 81, 73, 66, 64, 58, 396, 3, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 + + } ; + +static yyconst short /* Nick short int */ yy_chk[601] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 8, 2, 5, 2, 23, 5, + 5, 20, 20, 20, 20, 26, 26, 28, 28, 42, + 34, 2, 34, 20, 406, 37, 405, 20, 42, 23, + 8, 22, 22, 22, 22, 22, 22, 22, 37, 43, + + 76, 76, 43, 31, 74, 32, 22, 22, 22, 22, + 22, 22, 31, 32, 169, 169, 399, 31, 41, 32, + 32, 33, 33, 59, 41, 74, 32, 44, 22, 44, + 35, 33, 38, 40, 33, 33, 35, 394, 35, 38, + 44, 35, 38, 40, 40, 35, 44, 40, 392, 59, + 35, 40, 45, 45, 45, 45, 45, 45, 45, 57, + 94, 46, 57, 57, 46, 101, 61, 389, 94, 45, + 46, 45, 101, 55, 46, 55, 45, 55, 46, 46, + 45, 46, 54, 91, 54, 54, 54, 388, 85, 85, + 70, 55, 61, 70, 85, 70, 387, 91, 385, 97, + + 54, 56, 56, 56, 56, 97, 381, 151, 56, 66, + 56, 56, 56, 56, 97, 183, 183, 56, 66, 66, + 66, 66, 66, 66, 69, 113, 116, 69, 114, 132, + 113, 95, 116, 151, 137, 132, 95, 95, 379, 113, + 69, 95, 378, 114, 69, 95, 95, 95, 137, 95, + 375, 374, 372, 95, 133, 66, 90, 90, 371, 90, + 133, 90, 90, 90, 160, 90, 90, 90, 133, 90, + 370, 369, 90, 90, 128, 90, 128, 134, 363, 160, + 361, 128, 134, 134, 353, 128, 143, 134, 143, 143, + 143, 134, 134, 134, 144, 134, 144, 350, 144, 134, + + 346, 145, 178, 179, 143, 145, 182, 145, 145, 145, + 146, 184, 144, 146, 155, 146, 184, 178, 179, 189, + 146, 182, 190, 155, 155, 155, 155, 155, 155, 248, + 249, 345, 344, 343, 189, 342, 339, 190, 330, 327, + 275, 322, 319, 315, 248, 249, 314, 284, 248, 275, + 275, 275, 275, 275, 275, 311, 311, 311, 311, 348, + 282, 281, 280, 278, 277, 373, 276, 272, 348, 348, + 348, 348, 348, 348, 373, 373, 373, 373, 373, 373, + 383, 271, 270, 269, 268, 267, 264, 263, 259, 383, + 383, 383, 383, 383, 383, 397, 247, 397, 397, 397, + + 398, 244, 398, 398, 398, 400, 243, 400, 400, 400, + 401, 242, 401, 401, 401, 402, 402, 403, 241, 403, + 403, 403, 404, 239, 404, 404, 404, 407, 407, 408, + 408, 409, 409, 410, 410, 411, 234, 411, 411, 411, + 233, 232, 227, 221, 220, 219, 218, 217, 216, 215, + 213, 212, 211, 209, 194, 193, 191, 188, 187, 186, + 185, 181, 180, 176, 174, 173, 167, 166, 165, 164, + 163, 161, 158, 157, 156, 154, 153, 150, 149, 148, + 147, 141, 140, 139, 138, 136, 135, 131, 130, 129, + 127, 126, 124, 123, 122, 121, 120, 119, 118, 117, + + 115, 112, 111, 110, 109, 108, 107, 106, 105, 104, + 103, 102, 99, 96, 93, 92, 89, 88, 87, 86, + 72, 71, 68, 67, 65, 52, 48, 47, 39, 36, + 27, 21, 13, 12, 7, 3, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396 + + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +/* #line 1 "avrlex.l" */ +#define INITIAL 0 +/* #line 2 "avrlex.l" */ +////////////////////////////////////////////////////////////////////////////// +// +// File : avrlex.l +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Scanner file for AVR assembler +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 990329 : Tom - Added support for hex values like 1AB without $ or 0x +// 990512 : Tom - Fixed detection on binary numbers. +// 990522 : Tom - Added support for PC/DC/EC. +// 991211 : Tom - Fixed .endm problem (it had to be lower case) +// 991217 : Kurt- Added # and support for local labels +// 001101 : Brian - Added support for multiple include search paths +// 010319 : Timothy Lee - Added byte1 function (sames as low()) +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include "symbol.hh" +#include "semantic.hh" +#include "avrparse.hh" +#include "avrasm.hh" +#include "utils.hh" + +/// Extern /////////////////////////////////////////////////////////////////// + +GLOBALS(extern); + +/// Global /////////////////////////////////////////////////////////////////// + +symbolTableEntry *sym; +YY_BUFFER_STATE statestack[MAX_CONTEXT_DEPTH]; +int restartcount = 0; +int ret; + +/// Defines ////////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER /* Nick */ +#define SKIPRESTART 0x02BABE // Any value that is not a token +#else +#define SKIPRESTART -2 // Any value that is not a token +#endif + +/// Prototypes for support function ////////////////////////////////////////// + +int restart(void); +int endofline(void); +int identifier(void); +int registers(void); +int integers(void); +int macrodef(void); +int includefile(void); +int string(void); +int character(void); +int doexit(void); +int macro(symbolSA symb); +void list(int listtype); +void illegal(void); + +/// Scanner definition /////////////////////////////////////////////////////// + +#define YY_NEVER_INTERACTIVE 1 +/* #line 730 "avrlex.cc" */ + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( /* 1 || */ yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ +/* buf[n] = 0; */ \ +/* printf("%s", buf); */ \ +/* fflush(stdout); */ \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + yy_current_buffer->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +#ifndef _MSC_VER /* Nick */ +#undef YY_BREAK +#define YY_BREAK return -1; + +int yy_function_nick_0(/*yy_state_type yy_current_state, + char *yy_cp, char *yy_bp,*/ int yy_act) + { + switch (yy_act) + { +#include "avrlex0.inc" + } + return -1; /* should never happen but keeps the compiler happy */ + } + +int yy_function_nick_1(/*yy_state_type yy_current_state, + char *yy_cp, char *yy_bp,*/ int yy_act) + { + switch (yy_act) + { +#include "avrlex1.inc" + } + return -1; /* should never happen but keeps the compiler happy */ + } + +#undef YY_BREAK +#define YY_BREAK break; +#endif + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; +#if 1 /* Nick */ + register int yy_return_code; + void *silly; +#endif + + silly = malloc(0x1000); + if (silly) + { + free(silly); + } + +#ifdef DEBUG /* Nick */ + printf("yylex() @ %08lx\n", silly); + fflush(stdout); +#endif + +/* #line 114 "avrlex.l" */ + + +/* #line 887 "avrlex.cc" */ + + if ( yy_init ) + { +#ifdef DEBUG /* Nick */ + printf("init\n"); + fflush(stdout); +#endif + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +#ifdef DEBUG /* Nick */ + printf("loop\n"); + fflush(stdout); +#endif + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 397 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 537 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + +#ifndef _MSC_VER /* Nick */ + if (yy_act >= 1 && yy_act <= 99) + { + yy_return_code = yy_function_nick_0(/*yy_current_state, + yy_cp, yy_bp,*/ + yy_act); + + if (yy_return_code == -1) + { +#ifdef DEBUG /* Nick */ + printf("break\n"); + fflush(stdout); +#endif + goto yy_return_break; + } + +#ifdef DEBUG /* Nick */ + printf("token %d\n", yy_return_code); + fflush(stdout); +#endif + return yy_return_code; + } + + if (yy_act >= 100 && yy_act <= 198) + { + yy_return_code = yy_function_nick_1(/*yy_current_state, + yy_cp, yy_bp,*/ + yy_act); + + if (yy_return_code == -1) + { +#ifdef DEBUG /* Nick */ + printf("break\n"); + fflush(stdout); +#endif + goto yy_return_break; + } + +#ifdef DEBUG /* Nick */ + printf("token %d\n", yy_return_code); + fflush(stdout); +#endif + return yy_return_code; + } + +/* #ifdef DEBUG */ /* Nick */ +/* printf("action %d\n", yy_act); */ +/* fflush(stdout); */ +/* #endif */ +#endif + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +#ifdef _MSC_VER /* Nick */ +#include "avrlex0.inc" +#include "avrlex1.inc" +#endif + +case YY_STATE_EOF(INITIAL): +/* #line 312 "avrlex.l" */ + yyeol=TRUE; + if ((ret=restart()) != SKIPRESTART) + { +#ifdef DEBUG /* Nick */ + printf("eof %d\n", ret); + fflush(stdout); +#endif + return ret; + } + YY_BREAK + +/* #line 1965 "avrlex.cc" */ + + case YY_END_OF_BUFFER: + { +#ifdef DEBUG /* Nick */ + printf("YY_END_OF_BUFFER\n"); + fflush(stdout); +#endif + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: +#ifdef DEBUG /* Nick */ + printf("yy_act = %d\n", yy_act); + fflush(stdout); +#endif + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ +#ifndef _MSC_VER /* Nick */ +yy_return_break: + ; +#endif + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer(void) /* Nick void */ + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 397 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 397 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 396); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + yy_current_buffer->yy_at_bol = (c == '\n'); + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +/* Nick static */ void *yy_flex_alloc( yy_size_t size ) +#else +/* Nick static */ void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { +#ifdef DEBUG /* Nick */ + printf("yy_flex_alloc(%d) starting\n", size); + fflush(stdout); +#endif + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +/* Nick static */ void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +/* Nick static */ void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ +#ifdef DEBUG /* Nick */ + printf("yy_flex_realloc(%08lx, %d) starting\n", ptr, size); + fflush(stdout); +#endif + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { +#ifdef DEBUG /* Nick */ + printf("yy_flex_free(%08lx) starting\n", ptr); + fflush(stdout); +#endif + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +/* #line 320 "avrlex.l" */ + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +/// /// +/// Scanner support functions /// +/// /// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Identifiers + // + +int character(void) +{ + yylval.val.value = 0; + yylval.val.valid = FALSE; + + if(yytext[1]=='\\') + { + switch (yytext[2]) + { + case 'n' : yylval.val.value = '\n' ; yylval.val.valid = TRUE; break; + case 't' : yylval.val.value = '\t' ; yylval.val.valid = TRUE; break; + case 'v' : yylval.val.value = '\v' ; yylval.val.valid = TRUE; break; + case 'b' : yylval.val.value = '\b' ; yylval.val.valid = TRUE; break; + case 'r' : yylval.val.value = '\r' ; yylval.val.valid = TRUE; break; + case 'f' : yylval.val.value = '\f' ; yylval.val.valid = TRUE; break; + case 'a' : yylval.val.value = '\a' ; yylval.val.valid = TRUE; break; + case '\\' : yylval.val.value = '\\' ; yylval.val.valid = TRUE; break; + case '\'' : yylval.val.value = '\'' ; yylval.val.valid = TRUE; break; + case '\"' : yylval.val.value = '\"' ; yylval.val.valid = TRUE; break; + case '\?' : yylval.val.value = '\?' ; yylval.val.valid = TRUE; break; + case 'x' : + case 'X' : + { + if(isdigit(yytext[3])) + yylval.val.value = yytext[3] - '0'; + else if(isxdigit(yytext[3])) + yylval.val.value = tolower(yytext[3]) - 'a' + 10; + + if(isxdigit(yytext[3]) && isxdigit(yytext[4])) + { + if(isdigit(yytext[4])) + yylval.val.value = 16*yylval.val.value + yytext[4] - '0'; + else + yylval.val.value = 16*yylval.val.value+tolower(yytext[4])-'a'+10; + } + yylval.val.valid = TRUE; + + } break; + + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + { + yylval.val.value = yytext[2] - '0'; + if(isdigit(yytext[3])) + { + yylval.val.value = 8*yylval.val.value + yytext[3] - '0'; + if(isdigit(yytext[4])) + yylval.val.value = 8*yylval.val.value + yytext[4] - '0'; + } + if(yylval.val.value > 0xFF) + { + yylval.val.value = 0; + warningin(W_OCT_OUT_OF_RANGE); + } + yylval.val.valid = TRUE; + + } break; + + default : errorin(E_UNDEF_ESCAPE,yytext); + } + } + else + { + yylval.val.value = yytext[1]; + yylval.val.valid = TRUE; + } + return INTEGER; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Identifiers + // + +int identifier(void) +{ + char name[MAX_ID_LENGTH+1]; + + if(yytext[0] == '_' && yycfg->local_labels) + { + if(strlen(yytext)+strlen(yylast_used_label)+2>MAX_ID_LENGTH) + { + size_t len; + + warningin(W_IDENTIFIER_TOO_LONG); + name[0]='@'; + memcpy(name+1, yylast_used_label, MAX_ID_LENGTH-1); + name[MAX_ID_LENGTH] = '\0'; + len = strlen(name); + if(len>MAX_ID_LENGTH-9) + len = MAX_ID_LENGTH-9; // truncate the last_used_label to leave at least 8 characters for the local label + name[len++] = '@'; + memcpy(name+len, yytext, MAX_ID_LENGTH-len); + name[MAX_ID_LENGTH] = '\0'; + } + else + { + sprintf(name, "@%s@%s", yylast_used_label, yytext); + } + } + else + { + if(strlen(yytext)>MAX_ID_LENGTH) + { + warningin(W_IDENTIFIER_TOO_LONG); + memcpy(name, yytext, MAX_ID_LENGTH); + name[MAX_ID_LENGTH] = '\0'; + } + else + strcpy(name, yytext); + } + + yylval.symb = getsym(name); + + if(yylval.symb -> macro) + return macro(yylval.symb); + + return SYMBOL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Registers : r0 - r31 + // + +int registers(void) +{ + int registerno; + + if(strlen(yytext)==2) + { + if(isdigit(yytext[1])) + registerno= yytext[1] - '0'; + else + return identifier(); + } + else if(strlen(yytext)==3) + { + if(isdigit(yytext[1]) && isdigit(yytext[2]) ) + registerno= 10 * (yytext[1] - '0') + yytext[2] - '0'; + else + return identifier(); + } + else + return identifier(); + + if(registerno <= 31) + { + yylval.regid = registerno; + return REGISTER; + } + return identifier(); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Strings + // + +int string(void) +{ + if( !(yylval.string = new char[strlen(yytext)+1]) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 2\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + strcpy(yylval.string, yytext); + + return STRING; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Integer constants : Decimal=10 Hex=0xA Hex=$A Octal=012 Binaray=0b1010 + // + +int integers(void) +{ +#ifdef _MSC_VER /* Nick */ + int val; +#else + long val; +#endif + int pos; + char temp[12]; + + bool foundhex = (strpbrk(yytext,"ABCDEFabcdef")!=NULL); + bool foundbin = !(strpbrk(yytext,"ACDEFacdef23456789")!=NULL); + + // Hex : $BABE + + if(yytext[0] == '$' ) + { + val = 0; + pos = 1; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + } + if(pos>9) + warningin(W_CONSTANT_TO_BIG); + } + + // Hex : 0xBABE or 0XBABE + + else if( (yytext[0] == '0' ) && (tolower(yytext[1]) == 'x' )) + { + val = 0; + pos = 2; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + + } + if(pos>10) + warningin(W_CONSTANT_TO_BIG); + } + + // Bin : 0b01010 or 0B01010 + + else if( (yytext[0] == '0' ) && (tolower(yytext[1]) == 'b' ) && foundbin) + { + val = 0; + pos = 2; + while( yytext[pos] ) + val = 2*val + yytext[pos++] - '0'; + if(pos>34) + warningin(W_CONSTANT_TO_BIG); + } + + // Hex : 1BABE (Hex that starts with a decimal) + + else if(isdigit(yytext[0]) && foundhex ) + { + val = 0; + pos = 0; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + } + if(pos>8) + warningin(W_CONSTANT_TO_BIG); + } + + + // Integer 47806 + + else + { +#ifdef _MSC_VER /* Nick */ + val = atoi(yytext); + sprintf(temp, "%i", val); +#else + val = atol(yytext); + sprintf(temp, "%ld", val); +#endif + if(strcmp(temp,yytext)) + warningin(W_CONSTANT_TO_BIG); + } + + yylval.val.value = val; + yylval.val.valid = TRUE; + return INTEGER; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Illegal character + // + +void illegal(void) +{ + if(isprint(yytext[0])) + warningin(W_INVALID_CHAR,yytext[0]); + else + warningin(W_INVALID_ASCII,(unsigned char)yytext[0]); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Include file + // + +int includefile(void) +{ + char name[MAX_LINE_LENGTH+2]; + char filename[MAX_FILENAME_LENGTH+1]; + int c; + FILE *f1,*f2; + + if(strlen(yytext)==strlen(".include")) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + /// Check filename //////////////////////////////////////////////////////// + + if(strlen(yytext) >= MAX_LINE_LENGTH) + errorexit(X_LINE_TOO_LONG, yyfilename); + + strcpy(name,yytext+8+strspn(yytext,"\t\v ") + +strspn(yytext+8+strspn(yytext,"\t\v "),"\t\v ")); + + if(!strlen(name)) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + striprem(name); + + if(!strlen(name)) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + /// Read NL (or EOF) ////////////////////////////////////////////////////// + + yyinput(); + endofline(); + + if( !getfilename(name, filename) ) + { + error(E_INVALID_FILENAME); + return EOL; + } + + /// Check context depth /////////////////////////////////////////////////// + + if( yycontext == (MAX_CONTEXT_DEPTH-1) ) + { + errorin(E_INCLUDE_DEPTH, name); + return EOL; + } + + if( !(f1 = fopenInIncpath(filename,"r")) ) + { + error(E_OPEN_FILE, filename); + return EOL; + } + else if( !(f2 = fopenInIncpath(filename,"r")) ) + { + fclose(f1); + error(E_OPEN_FILE, filename); + return EOL; + } + + /// Setup context stack /////////////////////////////////////////////////// + + CONTEXT->file = yyin; + CONTEXT->file2 = yyin2; + CONTEXT->line = yyline; + CONTEXT->offset = yyoffset; + CONTEXT->dataoffset = yydataoffset; + CONTEXT->eromoffset = yyeromoffset; + + strcpy(CONTEXT->yyinlineold, yyinlineold); + strcpy(CONTEXT->yyinline, yyinline); + strcpy(CONTEXT->yyinlinenew, yyinlinenew); + + statestack[yycontext++] = YY_CURRENT_BUFFER; + + /// Open input file /////////////////////////////////////////////////////// + + if(yyfilecount==MAX_FILES) + errorexit(X_TOO_MANY_FILES); + + yyfileno = -1; + + for(c=0;cfile = f1; + yyin2 = CONTEXT->file2 = f2; + + strcpy(CONTEXT->filename, filename); + strcpy(yyfilename, filename); + + /// Add .include line to log ////////////////////////////////////////////// + + tolog(); + + if(!yyinmacro) + yyline = 1; + else + yyline =0; + + yyline = 1; // XXX + + /// Read new lines into log buffers /////////////////////////////////////// + + if(!fgets(yyinline, MAX_LINE_LENGTH, yyin2)) + yyinline[0] = 0; + if(!fgets(yyinlinenew, MAX_LINE_LENGTH, yyin2)) + yyinlinenew[0] = 0; + + if(strlen(yyinline) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + if(strlen(yyinlinenew) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + + STRIPNR(yyinlinenew); + STRIPNR(yyinline); + + /// Setup scanner to read from new file /////////////////////////////////// + + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + + return TRUE; +} + + //////////////////////////////////////////////////////////////////////////// + // + // End of line + // + +int endofline(void) +{ + int pos; + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + + if(!ISMACRO) + { + if(!fgets(yyinlinenew,MAX_LINE_LENGTH,yyin2)) + yyinlinenew[0] = '\0'; + if(strlen(yyinlinenew)==MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + //if(yyinmacro) + yyline++; + } + else + { + if( (int)strlen(CONTEXT->macstr) > CONTEXT->stringpos) + { + pos = strcspn(CONTEXT->macstr+CONTEXT->stringpos,"\n"); + if(posmacstr+CONTEXT->stringpos, pos); + else + errorexit(X_MACRO_LINE_TOO_LONG, yyline, yyfilename); + + yyinlinenew[pos] = 0; + CONTEXT->stringpos += pos+1; + } + else + yyinlinenew[0] = 0; + } + + STRIPNR(yyinlinenew); + return EOL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Restart scanner after first parse, and handle macro/include context + // + +int restart(void) +{ + int c; + +#ifdef DEBUG /* Nick */ + printf("restart() starting\n"); + fflush(stdout); +#endif + + if(!restartcount++ && !ISMACRO) + { + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + strcpy(yyinlinenew, "This should never show up"); + yyline++; +#ifdef DEBUG /* Nick */ + printf("restart() returning EOL 0\n"); + fflush(stdout); +#endif + return EOL; + } + + restartcount = 0; + + if(yycontext) + { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(statestack[--yycontext]); + + if( yycontextstack[yycontext+1]->ismacro ) + { + yyinmacro--; + strcpy(yyinlineold, CONTEXT->yyinlineold); + strcpy(yyinline, CONTEXT->yyinline); + strcpy(yyinlinenew, CONTEXT->yyinlinenew); + delete yycontextstack[yycontext+1]->macstr; + + yysymbolstack[yycontext+1] = NULL; + yyoffset = CONTEXT->offset; + yydataoffset = CONTEXT->dataoffset; + yyeromoffset = CONTEXT->eromoffset; + yyline = CONTEXT->line + 1; + if(ISMACRO) + endofline(); + else + { + if(!fgets(yyinlinenew, MAX_LINE_LENGTH, yyin2)) + yyinlinenew[0] = 0; + } + + if(strlen(yyinlinenew) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + memset(yycontextstack[yycontext+1],0,sizeof(context)); +#ifdef DEBUG /* Nick */ + printf("restart() returning SKIPRESTART 0\n"); + fflush(stdout); +#endif + return SKIPRESTART; + } + else + { + if(ISMACRO) + { + for(c=yycontext;c>=0;c--) + { + if(!yycontextstack[c]->ismacro) + { + strcpy(yyfilename, yycontextstack[c]->filename); + c = -1; + } + } + } + else + strcpy(yyfilename, CONTEXT->filename); + + yyline = CONTEXT->line; + + fclose(yycontextstack[yycontext+1]->file); + fclose(yycontextstack[yycontext+1]->file2); + + yyin = CONTEXT->file; + yyin2 = CONTEXT->file2; + yyoffset = CONTEXT->offset; + yydataoffset = CONTEXT->dataoffset; + yyeromoffset = CONTEXT->eromoffset; + + strcpy(yyinline, CONTEXT->yyinline); + strcpy(yyinlinenew, CONTEXT->yyinlinenew); + memset(yycontextstack[yycontext+1],0,sizeof(context)); + + yyfileno = -1; + for(c=0;cismacro) + { + while( ((ch=yyinput())!='\r') && (ch!='\n') && (ch!=EOF) ); + errorin(E_MACRO_IN_MACRO); + endofline(); + return EOL; + } + + /// Allocate buffer /////////////////////////////////////////////////////// + + if( !(buf1 = new char[bufsize]) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 4\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + /// Get macro string from input /////////////////////////////////////////// + + while(!found) + { + ch = yyinput(); + + if(tolower(ch)==endmacro[founddot]) + founddot++; + else + founddot=0; + + if(founddot==4) + { + found = TRUE; + buf1[pos-3] = '\0'; + sprintf(yyinlinenew,".endm"); + } + else if(ch=='\n') + { + comment = FALSE; + temp[temppos] = 0; + temppos = 0; + if(temptime++) + { + STRIPNR(temp); + strcpy(yyinlinenew, temp); + endofline(); + tolog(); + } + } + else if(ch==EOF) + found = TRUE; + else if(ch==';') + comment = TRUE; + + buf1[pos++] = ch; + + if(ch!='\n') + temp[temppos++] = ch; + + if(pos==bufsize) + { + buf2 = new char[2*bufsize]; + memcpy(buf2, buf1, bufsize); + delete buf1; + buf1 = buf2; + bufsize *=2; + } + } + + /// Read until end of .endmacro line ////////////////////////////////////// + + while( ((ch=yyinput()) != EOF) && (ch!='\n') && (ch!='\r')) + yyinlinenew[temppos++] = ch; + + yyinlinenew[temppos] = 0; + + strcpy(temp, yyinlinenew); + + endofline(); + tolog(); + + if((ch==EOF)&&(founddot<4)) + { + delete buf1; + if(strlen(yyinlineold)) + yyinlineold[strlen(yyinlineold)-1] = '\0'; + STRIPWS(yyinlineold); + error(E_EOF_IN_MACRO); + return restart(); + } + + /// Process string //////////////////////////////////////////////////////// + + pos = strlen(buf1); + + if( pos && !(buf1[pos-1]=='\n') ) + strcat(buf1, "\n"); + + /// Get macro name //////////////////////////////////////////////////////// + + namestart = strspn(buf1,"\t\v "); + nameend = strcspn(buf1+namestart,"\t\v \r\n;")+namestart; + memcpy(name, buf1+namestart, nameend-namestart); + name[nameend-namestart] = '\0'; + + /// Setup macro /////////////////////////////////////////////////////////// + + for(i=yycontext; !yysymbolstack[i]; i--); + + if(!yyparseno) + { + if(strlen(name)>MAX_ID_LENGTH) { + warningin(W_MAC_IDENTIFIER_TOO_LONG); + name[MAX_ID_LENGTH] = '\0'; + } + + if( (symb=yysymbolstack[i]->get(name)) ) + { + error(E_MACRO_REDEF,name); + return EOL; + } + symb = yysymbolstack[i]->add(name); + } + else { + if(strlen(name)>MAX_ID_LENGTH) { + warningin(W_MAC_IDENTIFIER_TOO_LONG); + name[MAX_ID_LENGTH] = '\0'; + } + symb=yysymbolstack[i]->get(name); + } + + if(!symb) + internalerror("DM"); + + if( ISUSED(symb) && ((symb->macdefline != yyline) + ||(strcmp(symb->macfilename, yyfilename)) )) + { + strcpy(yyinlineold,".endmacro"); + error(E_MACRO_REDEF,name); + } + else + { + // If first parse - allocate space in symbol table for macro + + if(!yyparseno) + { + symb -> macro = TRUE; + symb -> macsize = strlen(buf1)-nameend; + symb -> macdefline = yyline; + + if( !(symb -> macstr = new char[symb->macsize+2])) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 5\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + strcpy(symb->macstr, buf1+nameend); + strcpy(symb->macfilename,yyfilename); + } + + // In second parse - check argument usage + + else if( yyline == symb->macdefline ) + { + l = symb->macsize; + symb -> macrodone = TRUE; + + while(l) + { + if( isdigit(symb->macstr[l]) && (symb->macstr[l-1] == '@' ) ) + symb->macparmlist[(symb->macstr[l]) -'0'] = 1; + l--; + } + lastparm = -1; + for(l=0;l<10;l++) + if(symb->macparmlist[l]) + lastparm = l; + + inmacro=yyinmacro; + yyinmacro=1; + + for(l=0;l<=lastparm;l++) + if(!symb->macparmlist[l]) + warningin(W_MACRO_UNUSES_PARM, l, name); + + yyinmacro=inmacro; + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + } + } + + strcpy(yyinline, temp); + endofline(); + delete buf1; + + if(!strlen(name)) + error(E_NO_MACRO_NAME); + + return MACRODEF; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert macro in input stream + // + +int macro(symbolSA symb) +{ + char **parmlist; + int c; + char line[MAX_LINE_LENGTH+2]; + int pos = 0; + int parm; + int inputparms = 0; + int parmpos; + int rem; + int next; + int l; + int len; + char *str; + int res; + int ch; + char orginline[MAX_LINE_LENGTH+2]; + + if( (!symb -> macrodone) && (yyparseno) ) + { + errorin(E_DEF_USE); + while(((ch=yyinput())!='\n') && (ch!=EOF) ); + endofline(); + + return EOL; + } + + strcpy(orginline, yyinline); + + /// Allocate space for parameters ///////////////////////////////////////// + + if( !(parmlist = new char*[10]) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 6\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + for(c=0;c<10;c++) + { + if(!(parmlist[c]= new char [MAX_LINE_LENGTH+1])) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 7\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + else + memset(parmlist[c], 0, MAX_LINE_LENGTH+1); + } + + /// Get parameters from input ///////////////////////////////////////////// + + while( ((line[pos]=yyinput())!='\n') && (line[pos++]!=EOF) ); + + if(pos && (line[pos-1]==EOF) ) + line[--pos] = 0; + + line[pos]=0; + line[pos+1]=0; + + /// Local strtok() that inserts parameters into parameter list //////////// + + if(pos) + { + pos = 0; + parm = 0; + rem = FALSE; + + striprem(line); + + while(line[pos] && (parm<10)) + { + next = FALSE; + parmpos = 0; + + while( (!next) && (line[pos]) ) + { + if( (line[pos]=='"') || (line[pos]=='\'') ) + rem ? rem = FALSE : rem = TRUE; + else if( line[pos]=='\\' ) + parmlist[parm][parmpos++] = line[pos++]; + else if ( (line[pos]==',') && !rem) + { + parmlist[parm][parmpos] = '\0'; + next = TRUE; + } + parmlist[parm][parmpos++] = line[pos++]; + } + parm++; + } + + inputparms = parm; + + /// Clean up parametes (remove leading/trailing whitespaces and ',' //////// + + for(c=0;c<10;c++) + { + pos = strlen(parmlist[c]); + if(pos) + pos--; + while( ((parmlist[c][pos]==',')||(isspace(parmlist[c][pos])))&&(pos>=0)) + parmlist[c][pos--] = '\0'; + + if(pos) + { + l = strspn(parmlist[c], "\t\v "); + len = strlen(parmlist[c])-l; + if(l) + memmove(parmlist[c], parmlist[c]+l,len); + parmlist[c][len] = '\0'; + } + } + } + + /// Check that number of parameters specified, equals the ones used //////// + + for(c=0;c<10;c++) + { + if( parmlist[c][0] && !symb->macparmlist[c]) + warningin(W_ARG_SPEC, c); + else if( !parmlist[c][0] && symb->macparmlist[c]) + warningin(W_ARG_USED, c); + } + + /// Insert parameters in macro string ////////////////////////////////////// + + if(! (str = new char[symb-> macsize + MAX_LINE_LENGTH +5] ) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 8\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + memset(str,0, symb-> macsize + MAX_LINE_LENGTH +5); + + pos = 0; + parm = 0; + res = 0; + + while( symb->macstr[pos] ) + { + if( (symb->macstr[pos]=='@') && (isdigit(symb->macstr[pos+1])) ) + { + parm = symb->macstr[pos+1] - '0'; + pos += 2; + parmpos = 0; + + while(parmlist[parm][parmpos]) + str[res++] = parmlist[parm][parmpos++]; + } + else + str[res++] = symb->macstr[pos++]; + } + + /// Setup new scanner context ////////////////////////////////////////////// + + if( yycontext == (MAX_CONTEXT_DEPTH-1) ) + { + errorexit(X_MACRO_DEPTH); + + for(c=0;c<10;c++) + delete parmlist[c]; + delete parmlist; + + return EOL; + } + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + + strcpy(CONTEXT->yyinlineold, yyinlineold); + strcpy(CONTEXT->yyinline, yyinline); + strcpy(CONTEXT->yyinlinenew, yyinlinenew); + + CONTEXT->line = yyline; + CONTEXT->offset = yyoffset; + CONTEXT->dataoffset = yydataoffset; + CONTEXT->eromoffset = yyeromoffset; + + statestack[yycontext++] = YY_CURRENT_BUFFER; + CONTEXT->ismacro = TRUE; + CONTEXT->macstr = str; + yyoffset = yycodepos/2; + yyeromoffset = yyerompos; + yydataoffset = yydatapos; + + memset(yyinlinenew, 0, MAX_LINE_LENGTH); + memset(yyinline, 0, MAX_LINE_LENGTH); + + pos = strcspn(str,"\n") + 1; + + strcpy(yyinline, symb->name); + + for(l=0;l= MAX_LINE_LENGTH-1 ) + errorexit(X_MACRO_LINE_TOO_LONG, yyline, yyfilename); + + memcpy(yyinline+strlen(yyinline), str ,pos); + + CONTEXT->stringpos = strcspn(str+pos,"\n") + 1; + + memcpy(yyinlinenew, str + pos, CONTEXT->stringpos); + + CONTEXT->stringpos += pos; + + strcpy(yyinline, orginline); + + yyinmacro++; + yyfirstmacroline = TRUE; + + yy_scan_string(str); + + /// Delete parameter list ////////////////////////////////////////////////// + + for(c=0;c<10;c++) + delete parmlist[c]; + delete parmlist; + + /// Allocate new symbol table ////////////////////////////////////////////// + + if(!yyparseno) + { + if(symb -> macsym) + yysymbolstack[yycontext] = symb -> macsym; + else + { + if( !(yysymbolstack[yycontext] = symb -> macsym = new symbolTable()) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 9\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + if( !symb -> macsym->init(yycfg->casesensitive, 16) ) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 10\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + } + } + else + yysymbolstack[yycontext] = symb -> macsym; + + if(!yysymbolstack[yycontext]) + internalerror("MA %i", yycontext); + +// yyline++; + + return SKIPRESTART; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Turn listing on/off + // + +void list(int listtype) +{ + switch(listtype) + { + case LIST_NO : yylist = FALSE; break; + case LIST_YES : yylist = TRUE ; break; + case LIST_NO_MACRO : yylistmacro = FALSE; break; + case LIST_YES_MACRO : yylistmacro = TRUE ; break; + default : internalerror("LU %04X",listtype); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Read to end of current context + // + +int doexit(void) +{ + while(yyinput()!=EOF); + yyeol=TRUE; + return restart(); +} + + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/avrlex.l b/src/mkutil/tavrasm.118/src/avrlex.l new file mode 100644 index 00000000..5750de24 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrlex.l @@ -0,0 +1,1428 @@ +%{ // -*- C -*- +////////////////////////////////////////////////////////////////////////////// +// +// File : avrlex.l +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Scanner file for AVR assembler +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 990329 : Tom - Added support for hex values like 1AB without $ or 0x +// 990512 : Tom - Fixed detection on binary numbers. +// 990522 : Tom - Added support for PC/DC/EC. +// 991211 : Tom - Fixed .endm problem (it had to be lower case) +// 991217 : Kurt- Added # and support for local labels +// 001101 : Brian - Added support for multiple include search paths +// 010319 : Timothy Lee - Added byte1 function (sames as low()) +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include "symbol.hh" +#include "semantic.hh" +#include "avrparse.hh" +#include "avrasm.hh" +#include "utils.hh" + +/// Extern /////////////////////////////////////////////////////////////////// + +GLOBALS(extern); + +/// Global /////////////////////////////////////////////////////////////////// + +symbolTableEntry *sym; +YY_BUFFER_STATE statestack[MAX_CONTEXT_DEPTH]; +int restartcount = 0; +int ret; + +/// Defines ////////////////////////////////////////////////////////////////// + +#define SKIPRESTART 0x02BABE // Any value that is not a token + +/// Prototypes for support function ////////////////////////////////////////// + +int restart(void); +int endofline(void); +int identifier(void); +int registers(void); +int integers(void); +int macrodef(void); +int includefile(void); +int string(void); +int character(void); +int doexit(void); +int macro(symbolSA symb); +void list(int listtype); +void illegal(void); + +/// Scanner definition /////////////////////////////////////////////////////// + +%} + +%option noyywrap +%option never-interactive +%option caseless + +DECDIGIT [0-9] +HEXDIGIT [0-9a-fA-F] +OCTDIGIT [0-7] +BINDIGIT [01] +LETTER [a-zA-Z_] +CHAR [a-zA-Z0-9_] +HTAB [\011] +NL [\012] +VTAB [\013] +FORMFEED [\014] +CR [\015] +SPACE [\040] +WHITE {HTAB}|{VTAB}|{SPACE} + +%% + +"*" return STAR; +"/" return DIV; +"%" return MOD; +"<<" return LS; +">>" return RS; +"<=" return LE; +">=" return GE; +"<" return LESS; +">" return GREAT; +"==" return EQ; +"!=" return NE; +"||" return OROR; +"&&" return ANDAND; +"|" return OR; +"&" return AND; +"^" return XOR; +"(" return LPAR; +")" return RPAR; +":" return COLON; +"," return COMMA; +"." return DOT; +"+" return PLUS; +"-" return MINUS; +"=" return EQUAL; +"~" return WAVE; +"!" return NOT; + +".def" return DEF; +".equ" return EQU; +".eq" return EQU; +".db" return DB; +".dw" return DW; +".org" return ORG; +".byte" return BYTE; +".set" return SET; +".device" return DEVICE; + +".cseg" { yysegment = SEGMENT_CODE; return CSEG; } +".dseg" { yysegment = SEGMENT_DATA; return ESEG; } +".eseg" { yysegment = SEGMENT_EEPROM; return DSEG; } + +"low" { yylval.func = OP_LOW; return FUNCTION;} +"high" { yylval.func = OP_HIGH; return FUNCTION;} +"byte1" { yylval.func = OP_LOW; return FUNCTION;} +"byte2" { yylval.func = OP_BYTE2; return FUNCTION;} +"byte3" { yylval.func = OP_BYTE3; return FUNCTION;} +"byte4" { yylval.func = OP_BYTE4; return FUNCTION;} +"lwrd" { yylval.func = OP_LWRD; return FUNCTION;} +"hwrd" { yylval.func = OP_HWRD; return FUNCTION;} +"page" { yylval.func = OP_PAGE; return FUNCTION;} +"exp2" { yylval.func = OP_EXP2; return FUNCTION;} +"log2" { yylval.func = OP_LOG2; return FUNCTION;} +"cpc" { yylval.opcode = O_CPC; return IREGREG; } /* Register */ +"cp" { yylval.opcode = O_CP; return IREGREG; } +"sbc" { yylval.opcode = O_SBC; return IREGREG; } +"sub" { yylval.opcode = O_SUB; return IREGREG; } +"add" { yylval.opcode = O_ADD; return IREGREG; } +"adc" { yylval.opcode = O_ADC; return IREGREG; } +"cpse" { yylval.opcode = O_CPSE; return IREGREG; } +"and" { yylval.opcode = O_AND; return IREGREG; } +"eor" { yylval.opcode = O_EOR; return IREGREG; } +"or" { yylval.opcode = O_OR; return IREGREG; } +"mov" { yylval.opcode = O_MOV; return IREGREG; } +"movw" { yylval.opcode = O_MOVW; return IREGREG; } +"mul" { yylval.opcode = O_MUL; return IREGREG; } +"muls" { yylval.opcode = O_MULS; return IREGREG; } +"mulsu" { yylval.opcode = O_MULSU; return IREGREG; } +"fmul" { yylval.opcode = O_FMUL; return IREGREG; } +"fmuls" { yylval.opcode = O_FMULS; return IREGREG; } +"fmulsu" { yylval.opcode = O_FMULSU; return IREGREG; } +"adiw" { yylval.opcode = O_ADIW; return IREGIMM; } /* Reg/Imm */ +"sbiw" { yylval.opcode = O_SBIW; return IREGIMM; } +"cpi" { yylval.opcode = O_CPI; return IREGIMM; } +"sbci" { yylval.opcode = O_SBCI; return IREGIMM; } +"subi" { yylval.opcode = O_SUBI; return IREGIMM; } +"ori" { yylval.opcode = O_ORI; return IREGIMM; } +"andi" { yylval.opcode = O_ANDI; return IREGIMM; } +"ldi" { yylval.opcode = O_LDI; return IREGIMM; } +"lds" { yylval.opcode = O_LDS; return IREGIMM; } +"sbr" { yylval.opcode = O_SBR; return IREGIMM; } +"brcc" { yylval.opcode = O_BRCC; return IIMM; } /* Immediate */ +"brcs" { yylval.opcode = O_BRCS; return IIMM; } +"brne" { yylval.opcode = O_BRNE; return IIMM; } +"breq" { yylval.opcode = O_BREQ; return IIMM; } +"brpl" { yylval.opcode = O_BRPL; return IIMM; } +"brmi" { yylval.opcode = O_BRMI; return IIMM; } +"brvc" { yylval.opcode = O_BRVC; return IIMM; } +"brvs" { yylval.opcode = O_BRVS; return IIMM; } +"brge" { yylval.opcode = O_BRGE; return IIMM; } +"brlt" { yylval.opcode = O_BRLT; return IIMM; } +"brhc" { yylval.opcode = O_BRHC; return IIMM; } +"brhs" { yylval.opcode = O_BRHS; return IIMM; } +"brtc" { yylval.opcode = O_BRTC; return IIMM; } +"brts" { yylval.opcode = O_BRTS; return IIMM; } +"brid" { yylval.opcode = O_BRID; return IIMM; } +"brie" { yylval.opcode = O_BRIE; return IIMM; } +"brsh" { yylval.opcode = O_BRSH; return IIMM; } +"brlo" { yylval.opcode = O_BRLO; return IIMM; } +"neg" { yylval.opcode = O_NEG; return IREG; } /* Register */ +"swap" { yylval.opcode = O_SWAP; return IREG; } +"inc" { yylval.opcode = O_INC; return IREG; } +"asr" { yylval.opcode = O_ASR; return IREG; } +"lsr" { yylval.opcode = O_LSR; return IREG; } +"dec" { yylval.opcode = O_DEC; return IREG; } +"pop" { yylval.opcode = O_POP; return IREG; } +"push" { yylval.opcode = O_PUSH; return IREG; } +"clr" { yylval.opcode = O_CLR; return IREG; } +"tst" { yylval.opcode = O_TST; return IREG; } +"com" { yylval.opcode = O_COM; return IREG; } +"ror" { yylval.opcode = O_ROR; return IREG; } +"sec" { yylval.opcode = O_SEC; return INOARGS; } /* No arguments */ +"sez" { yylval.opcode = O_SEZ; return INOARGS; } +"sen" { yylval.opcode = O_SEN; return INOARGS; } +"sev" { yylval.opcode = O_SEV; return INOARGS; } +"ses" { yylval.opcode = O_SES; return INOARGS; } +"seh" { yylval.opcode = O_SEH; return INOARGS; } +"set" { yylval.opcode = O_SET; return INOARGS; } +"sei" { yylval.opcode = O_SEI; return INOARGS; } +"clc" { yylval.opcode = O_CLC; return INOARGS; } +"clz" { yylval.opcode = O_CLZ; return INOARGS; } +"cln" { yylval.opcode = O_CLN; return INOARGS; } +"clv" { yylval.opcode = O_CLV; return INOARGS; } +"cls" { yylval.opcode = O_CLS; return INOARGS; } +"clh" { yylval.opcode = O_CLH; return INOARGS; } +"clt" { yylval.opcode = O_CLT; return INOARGS; } +"cli" { yylval.opcode = O_CLI; return INOARGS; } +"nop" { yylval.opcode = O_NOP; return INOARGS; } +"icall" { yylval.opcode = O_ICALL; return INOARGS; } /* Misc. */ +"ijmp" { yylval.opcode = O_IJMP; return INOARGS; } +"reti" { yylval.opcode = O_RETI; return INOARGS; } +"ret" { yylval.opcode = O_RET; return INOARGS; } +"sleep" { yylval.opcode = O_SLEEP; return INOARGS; } +"wdr" { yylval.opcode = O_WDR; return INOARGS; } +"eijmp" { yylval.opcode = O_EIJMP; return INOARGS; } +"eicall" { yylval.opcode = O_EICALL; return INOARGS; } +"spm" { yylval.opcode = O_SPM; return INOARGS; } +"espm" { yylval.opcode = O_ESPM; return INOARGS; } +"bclr" { yylval.opcode = O_BCLR; return IIMM; } +"bset" { yylval.opcode = O_BSET; return IIMM; } +"rcall" { yylval.opcode = O_RCALL; return IIMM; } +"rjmp" { yylval.opcode = O_RJMP; return IIMM; } +"jmp" { yylval.opcode = O_JMP; return IIMM; } +"call" { yylval.opcode = O_CALL; return IIMM; } +"brbc" { yylval.opcode = O_BRBC; return IIMMIMM; } +"brbs" { yylval.opcode = O_BRBS; return IIMMIMM; } +"cbi" { yylval.opcode = O_CBI; return IIMMIMM; } +"sbi" { yylval.opcode = O_SBI; return IIMMIMM; } +"sbic" { yylval.opcode = O_SBIC; return IIMMIMM; } +"sbis" { yylval.opcode = O_SBIS; return IIMMIMM; } +"out" { yylval.opcode = O_OUT; return IIMMREG; } +"sts" { yylval.opcode = O_STS; return IIMMREG; } +"rol" { yylval.opcode = O_ROL; return IREG; } +"ser" { yylval.opcode = O_SER; return IREG; } +"lsl" { yylval.opcode = O_LSL; return IREG; } +"bld" { yylval.opcode = O_BLD; return IREGIMM; } +"bst" { yylval.opcode = O_BST; return IREGIMM; } +"cbr" { yylval.opcode = O_CBR; return IREGIMM; } +"in" { yylval.opcode = O_IN; return IREGIMM; } +"sbrc" { yylval.opcode = O_SBRC; return IREGIMM; } +"sbrs" { yylval.opcode = O_SBRS; return IREGIMM; } +"ld" { yylval.opcode = O_LD; return IINDIRC; } +"st" { yylval.opcode = O_ST; return IINDIRC; } +"ldd" { yylval.opcode = O_LDD; return IINDIRC; } +"std" { yylval.opcode = O_STD; return IINDIRC; } +"X" { yylval.regid = 26; return REGXYZ; } +"Y" { yylval.regid = 28; return REGXYZ; } +"Z" { yylval.regid = 30; return REGXYZ; } +"lpm" { yylval.opcode = O_LPM; return ILPM; } +"elpm" { yylval.opcode = O_ELPM; return ILPM; } + +"PC" { yylval.val.value=yycodepos/2;yylval.val.valid=TRUE; return COUNTER;} +"DC" { yylval.val.value=yydatapos; yylval.val.valid=TRUE; return COUNTER;} +"EC" { yylval.val.value=yyerompos; yylval.val.valid=TRUE; return COUNTER;} + +^{WHITE}*".nolistmac" list(LIST_NO_MACRO); +^{WHITE}*".nolist" list(LIST_NO); +^{WHITE}*".listmac" list(LIST_YES_MACRO); +^{WHITE}*".list" list(LIST_YES); +^{WHITE}*".exit" yyeol=TRUE; if((ret=doexit() )!=SKIPRESTART) return ret; +^{WHITE}*".include"[^\n]* if(includefile()==EOL) return EOL; +^{WHITE}*".macro" return macrodef(); +".endm" errorin(E_ENDM); +"\""("\\\""|[^\n\"])*"\"" return string(); +[r]{DECDIGIT}+ return registers(); +{DECDIGIT}+ return integers(); +"0x"{HEXDIGIT}+ return integers(); +"0b"{BINDIGIT}+ return integers(); +"$"{HEXDIGIT}+ return integers(); +{DECDIGIT}{HEXDIGIT}* return integers(); +"'\\x"{HEXDIGIT}{1,2}"'" return character(); +"'\\x"{HEXDIGIT}{3,}"'" warningin(W_HEX_ESCAPE_INVALID);yylval.val.valid = TRUE;yylval.val.value = 0; return INTEGER; +"'\\"{OCTDIGIT}{1,3}"'" return character(); +"'\\"{OCTDIGIT}{4,}"'" warningin(W_OCT_ESCAPE_INVALID);yylval.val.valid = TRUE;yylval.val.value = 0; return INTEGER; +"'\\"."'" return character(); +"'"."'" return character(); +{LETTER}{CHAR}* if((ret=identifier())!=SKIPRESTART)return ret; +<> yyeol=TRUE; if((ret=restart() )!=SKIPRESTART)return ret; +[\n] yyeol=TRUE; return endofline(); +[ \t\r]+ ; +";".* ; +"//".* ; +"#".* ; +. illegal(); + +%% + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +/// /// +/// Scanner support functions /// +/// /// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Identifiers + // + +int character(void) +{ + yylval.val.value = 0; + yylval.val.valid = FALSE; + + if(yytext[1]=='\\') + { + switch (yytext[2]) + { + case 'n' : yylval.val.value = '\n' ; yylval.val.valid = TRUE; break; + case 't' : yylval.val.value = '\t' ; yylval.val.valid = TRUE; break; + case 'v' : yylval.val.value = '\v' ; yylval.val.valid = TRUE; break; + case 'b' : yylval.val.value = '\b' ; yylval.val.valid = TRUE; break; + case 'r' : yylval.val.value = '\r' ; yylval.val.valid = TRUE; break; + case 'f' : yylval.val.value = '\f' ; yylval.val.valid = TRUE; break; + case 'a' : yylval.val.value = '\a' ; yylval.val.valid = TRUE; break; + case '\\' : yylval.val.value = '\\' ; yylval.val.valid = TRUE; break; + case '\'' : yylval.val.value = '\'' ; yylval.val.valid = TRUE; break; + case '\"' : yylval.val.value = '\"' ; yylval.val.valid = TRUE; break; + case '\?' : yylval.val.value = '\?' ; yylval.val.valid = TRUE; break; + case 'x' : + case 'X' : + { + if(isdigit(yytext[3])) + yylval.val.value = yytext[3] - '0'; + else if(isxdigit(yytext[3])) + yylval.val.value = tolower(yytext[3]) - 'a' + 10; + + if(isxdigit(yytext[3]) && isxdigit(yytext[4])) + { + if(isdigit(yytext[4])) + yylval.val.value = 16*yylval.val.value + yytext[4] - '0'; + else + yylval.val.value = 16*yylval.val.value+tolower(yytext[4])-'a'+10; + } + yylval.val.valid = TRUE; + + } break; + + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + { + yylval.val.value = yytext[2] - '0'; + if(isdigit(yytext[3])) + { + yylval.val.value = 8*yylval.val.value + yytext[3] - '0'; + if(isdigit(yytext[4])) + yylval.val.value = 8*yylval.val.value + yytext[4] - '0'; + } + if(yylval.val.value > 0xFF) + { + yylval.val.value = 0; + warningin(W_OCT_OUT_OF_RANGE); + } + yylval.val.valid = TRUE; + + } break; + + default : errorin(E_UNDEF_ESCAPE,yytext); + } + } + else + { + yylval.val.value = yytext[1]; + yylval.val.valid = TRUE; + } + return INTEGER; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Identifiers + // + +int identifier(void) +{ + char name[MAX_ID_LENGTH+1]; + + if(yytext[0] == '_' && yycfg->local_labels) + { + if(strlen(yytext)+strlen(yylast_used_label)+2>MAX_ID_LENGTH) + { + size_t len; + + warningin(W_IDENTIFIER_TOO_LONG); + name[0]='@'; + memcpy(name+1, yylast_used_label, MAX_ID_LENGTH-1); + name[MAX_ID_LENGTH] = '\0'; + len = strlen(name); + if(len>MAX_ID_LENGTH-9) + len = MAX_ID_LENGTH-9; // truncate the last_used_label to leave at least 8 characters for the local label + name[len++] = '@'; + memcpy(name+len, yytext, MAX_ID_LENGTH-len); + name[MAX_ID_LENGTH] = '\0'; + } + else + { + sprintf(name, "@%s@%s", yylast_used_label, yytext); + } + } + else + { + if(strlen(yytext)>MAX_ID_LENGTH) + { + warningin(W_IDENTIFIER_TOO_LONG); + memcpy(name, yytext, MAX_ID_LENGTH); + name[MAX_ID_LENGTH] = '\0'; + } + else + strcpy(name, yytext); + } + + yylval.symb = getsym(name); + + if(yylval.symb -> macro) + return macro(yylval.symb); + + return SYMBOL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Registers : r0 - r31 + // + +int registers(void) +{ + int registerno; + + if(strlen(yytext)==2) + { + if(isdigit(yytext[1])) + registerno= yytext[1] - '0'; + else + return identifier(); + } + else if(strlen(yytext)==3) + { + if(isdigit(yytext[1]) && isdigit(yytext[2]) ) + registerno= 10 * (yytext[1] - '0') + yytext[2] - '0'; + else + return identifier(); + } + else + return identifier(); + + if(registerno <= 31) + { + yylval.regid = registerno; + return REGISTER; + } + return identifier(); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Strings + // + +int string(void) +{ + if( !(yylval.string = new char[strlen(yytext)+1]) ) + errorexit(X_OUT_OF_MEMORY); + + strcpy(yylval.string, yytext); + + return STRING; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Integer constants : Decimal=10 Hex=0xA Hex=$A Octal=012 Binaray=0b1010 + // + +int integers(void) +{ + int val; + int pos; + char temp[12]; + + bool foundhex = (strpbrk(yytext,"ABCDEFabcdef")!=NULL); + bool foundbin = !(strpbrk(yytext,"ACDEFacdef23456789")!=NULL); + + // Hex : $BABE + + if(yytext[0] == '$' ) + { + val = 0; + pos = 1; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + } + if(pos>9) + warningin(W_CONSTANT_TO_BIG); + } + + // Hex : 0xBABE or 0XBABE + + else if( (yytext[0] == '0' ) && (tolower(yytext[1]) == 'x' )) + { + val = 0; + pos = 2; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + + } + if(pos>10) + warningin(W_CONSTANT_TO_BIG); + } + + // Bin : 0b01010 or 0B01010 + + else if( (yytext[0] == '0' ) && (tolower(yytext[1]) == 'b' ) && foundbin) + { + val = 0; + pos = 2; + while( yytext[pos] ) + val = 2*val + yytext[pos++] - '0'; + if(pos>34) + warningin(W_CONSTANT_TO_BIG); + } + + // Hex : 1BABE (Hex that starts with a decimal) + + else if(isdigit(yytext[0]) && foundhex ) + { + val = 0; + pos = 0; + while( yytext[pos] ) + { + if(isdigit(yytext[pos])) + val = 16*val + yytext[pos] - '0'; + else + val = 16*val + tolower(yytext[pos]) - 'a' + 10; + pos++; + } + if(pos>8) + warningin(W_CONSTANT_TO_BIG); + } + + + // Integer 47806 + + else + { + val = atoi(yytext); + sprintf(temp, "%i", val); + if(strcmp(temp,yytext)) + warningin(W_CONSTANT_TO_BIG); + } + + yylval.val.value = val; + yylval.val.valid = TRUE; + return INTEGER; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Illegal character + // + +void illegal(void) +{ + if(isprint(yytext[0])) + warningin(W_INVALID_CHAR,yytext[0]); + else + warningin(W_INVALID_ASCII,(unsigned char)yytext[0]); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Include file + // + +int includefile(void) +{ + char name[MAX_LINE_LENGTH+2]; + char filename[MAX_FILENAME_LENGTH+1]; + int c; + FILE *f1,*f2; + + if(strlen(yytext)==strlen(".include")) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + /// Check filename //////////////////////////////////////////////////////// + + if(strlen(yytext) >= MAX_LINE_LENGTH) + errorexit(X_LINE_TOO_LONG, yyfilename); + + strcpy(name,yytext+8+strspn(yytext,"\t\v ") + +strspn(yytext+8+strspn(yytext,"\t\v "),"\t\v ")); + + if(!strlen(name)) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + striprem(name); + + if(!strlen(name)) + { + yyinput(); + endofline(); + error(E_NO_FILENAME); + return EOL; + } + + /// Read NL (or EOF) ////////////////////////////////////////////////////// + + yyinput(); + endofline(); + + if( !getfilename(name, filename) ) + { + error(E_INVALID_FILENAME); + return EOL; + } + + /// Check context depth /////////////////////////////////////////////////// + + if( yycontext == (MAX_CONTEXT_DEPTH-1) ) + { + errorin(E_INCLUDE_DEPTH, name); + return EOL; + } + + if( !(f1 = fopenInIncpath(filename,"r")) ) + { + error(E_OPEN_FILE, filename); + return EOL; + } + else if( !(f2 = fopenInIncpath(filename,"r")) ) + { + fclose(f1); + error(E_OPEN_FILE, filename); + return EOL; + } + + /// Setup context stack /////////////////////////////////////////////////// + + CONTEXT->file = yyin; + CONTEXT->file2 = yyin2; + CONTEXT->line = yyline; + CONTEXT->offset = yyoffset; + CONTEXT->dataoffset = yydataoffset; + CONTEXT->eromoffset = yyeromoffset; + + strcpy(CONTEXT->yyinlineold, yyinlineold); + strcpy(CONTEXT->yyinline, yyinline); + strcpy(CONTEXT->yyinlinenew, yyinlinenew); + + statestack[yycontext++] = YY_CURRENT_BUFFER; + + /// Open input file /////////////////////////////////////////////////////// + + if(yyfilecount==MAX_FILES) + errorexit(X_TOO_MANY_FILES); + + yyfileno = -1; + + for(c=0;cfile = f1; + yyin2 = CONTEXT->file2 = f2; + + strcpy(CONTEXT->filename, filename); + strcpy(yyfilename, filename); + + /// Add .include line to log ////////////////////////////////////////////// + + tolog(); + + if(!yyinmacro) + yyline = 1; + else + yyline =0; + + yyline = 1; // XXX + + /// Read new lines into log buffers /////////////////////////////////////// + + if(!fgets(yyinline, MAX_LINE_LENGTH, yyin2)) + yyinline[0] = 0; + if(!fgets(yyinlinenew, MAX_LINE_LENGTH, yyin2)) + yyinlinenew[0] = 0; + + if(strlen(yyinline) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + if(strlen(yyinlinenew) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + + STRIPNR(yyinlinenew); + STRIPNR(yyinline); + + /// Setup scanner to read from new file /////////////////////////////////// + + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + + return TRUE; +} + + //////////////////////////////////////////////////////////////////////////// + // + // End of line + // + +int endofline(void) +{ + int pos; + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + + if(!ISMACRO) + { + if(!fgets(yyinlinenew,MAX_LINE_LENGTH,yyin2)) + yyinlinenew[0] = '\0'; + if(strlen(yyinlinenew)==MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + //if(yyinmacro) + yyline++; + } + else + { + if( (int)strlen(CONTEXT->macstr) > CONTEXT->stringpos) + { + pos = strcspn(CONTEXT->macstr+CONTEXT->stringpos,"\n"); + if(posmacstr+CONTEXT->stringpos, pos); + else + errorexit(X_MACRO_LINE_TOO_LONG, yyline, yyfilename); + + yyinlinenew[pos] = 0; + CONTEXT->stringpos += pos+1; + } + else + yyinlinenew[0] = 0; + } + + STRIPNR(yyinlinenew); + return EOL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Restart scanner after first parse, and handle macro/include context + // + +int restart(void) +{ + int c; + + if(!restartcount++ && !ISMACRO) + { + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + strcpy(yyinlinenew, "This should never show up"); + yyline++; + return EOL; + } + + restartcount = 0; + + if(yycontext) + { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(statestack[--yycontext]); + + if( yycontextstack[yycontext+1]->ismacro ) + { + yyinmacro--; + strcpy(yyinlineold, CONTEXT->yyinlineold); + strcpy(yyinline, CONTEXT->yyinline); + strcpy(yyinlinenew, CONTEXT->yyinlinenew); + delete yycontextstack[yycontext+1]->macstr; + + yysymbolstack[yycontext+1] = NULL; + yyoffset = CONTEXT->offset; + yydataoffset = CONTEXT->dataoffset; + yyeromoffset = CONTEXT->eromoffset; + yyline = CONTEXT->line + 1; + if(ISMACRO) + endofline(); + else + { + if(!fgets(yyinlinenew, MAX_LINE_LENGTH, yyin2)) + yyinlinenew[0] = 0; + } + + if(strlen(yyinlinenew) == MAX_LINE_LENGTH-1) + errorexit(X_LINE_TOO_LONG, yyfilename); + memset(yycontextstack[yycontext+1],0,sizeof(context)); + return SKIPRESTART; + } + else + { + if(ISMACRO) + { + for(c=yycontext;c>=0;c--) + { + if(!yycontextstack[c]->ismacro) + { + strcpy(yyfilename, yycontextstack[c]->filename); + c = -1; + } + } + } + else + strcpy(yyfilename, CONTEXT->filename); + + yyline = CONTEXT->line; + + fclose(yycontextstack[yycontext+1]->file); + fclose(yycontextstack[yycontext+1]->file2); + + yyin = CONTEXT->file; + yyin2 = CONTEXT->file2; + yyoffset = CONTEXT->offset; + yydataoffset = CONTEXT->dataoffset; + yyeromoffset = CONTEXT->eromoffset; + + strcpy(yyinline, CONTEXT->yyinline); + strcpy(yyinlinenew, CONTEXT->yyinlinenew); + memset(yycontextstack[yycontext+1],0,sizeof(context)); + + yyfileno = -1; + for(c=0;cismacro) + { + while( ((ch=yyinput())!='\r') && (ch!='\n') && (ch!=EOF) ); + errorin(E_MACRO_IN_MACRO); + endofline(); + return EOL; + } + + /// Allocate buffer /////////////////////////////////////////////////////// + + if( !(buf1 = new char[bufsize]) ) + errorexit(X_OUT_OF_MEMORY); + + /// Get macro string from input /////////////////////////////////////////// + + while(!found) + { + ch = yyinput(); + + if(tolower(ch)==endmacro[founddot]) + founddot++; + else + founddot=0; + + if(founddot==4) + { + found = TRUE; + buf1[pos-3] = '\0'; + sprintf(yyinlinenew,".endm"); + } + else if(ch=='\n') + { + comment = FALSE; + temp[temppos] = 0; + temppos = 0; + if(temptime++) + { + STRIPNR(temp); + strcpy(yyinlinenew, temp); + endofline(); + tolog(); + } + } + else if(ch==EOF) + found = TRUE; + else if(ch==';') + comment = TRUE; + + buf1[pos++] = ch; + + if(ch!='\n') + temp[temppos++] = ch; + + if(pos==bufsize) + { + buf2 = new char[2*bufsize]; + memcpy(buf2, buf1, bufsize); + delete buf1; + buf1 = buf2; + bufsize *=2; + } + } + + /// Read until end of .endmacro line ////////////////////////////////////// + + while( ((ch=yyinput()) != EOF) && (ch!='\n') && (ch!='\r')) + yyinlinenew[temppos++] = ch; + + yyinlinenew[temppos] = 0; + + strcpy(temp, yyinlinenew); + + endofline(); + tolog(); + + if((ch==EOF)&&(founddot<4)) + { + delete buf1; + if(strlen(yyinlineold)) + yyinlineold[strlen(yyinlineold)-1] = '\0'; + STRIPWS(yyinlineold); + error(E_EOF_IN_MACRO); + return restart(); + } + + /// Process string //////////////////////////////////////////////////////// + + pos = strlen(buf1); + + if( pos && !(buf1[pos-1]=='\n') ) + strcat(buf1, "\n"); + + /// Get macro name //////////////////////////////////////////////////////// + + namestart = strspn(buf1,"\t\v "); + nameend = strcspn(buf1+namestart,"\t\v \r\n;")+namestart; + memcpy(name, buf1+namestart, nameend-namestart); + name[nameend-namestart] = '\0'; + + /// Setup macro /////////////////////////////////////////////////////////// + + for(i=yycontext; !yysymbolstack[i]; i--); + + if(!yyparseno) + { + if(strlen(name)>MAX_ID_LENGTH) { + warningin(W_MAC_IDENTIFIER_TOO_LONG); + name[MAX_ID_LENGTH] = '\0'; + } + + if( (symb=yysymbolstack[i]->get(name)) ) + { + error(E_MACRO_REDEF,name); + return EOL; + } + symb = yysymbolstack[i]->add(name); + } + else { + if(strlen(name)>MAX_ID_LENGTH) { + warningin(W_MAC_IDENTIFIER_TOO_LONG); + name[MAX_ID_LENGTH] = '\0'; + } + symb=yysymbolstack[i]->get(name); + } + + if(!symb) + internalerror("DM"); + + if( ISUSED(symb) && ((symb->macdefline != yyline) + ||(strcmp(symb->macfilename, yyfilename)) )) + { + strcpy(yyinlineold,".endmacro"); + error(E_MACRO_REDEF,name); + } + else + { + // If first parse - allocate space in symbol table for macro + + if(!yyparseno) + { + symb -> macro = TRUE; + symb -> macsize = strlen(buf1)-nameend; + symb -> macdefline = yyline; + + if( !(symb -> macstr = new char[symb->macsize+2])) + errorexit(X_OUT_OF_MEMORY); + + strcpy(symb->macstr, buf1+nameend); + strcpy(symb->macfilename,yyfilename); + } + + // In second parse - check argument usage + + else if( yyline == symb->macdefline ) + { + l = symb->macsize; + symb -> macrodone = TRUE; + + while(l) + { + if( isdigit(symb->macstr[l]) && (symb->macstr[l-1] == '@' ) ) + symb->macparmlist[(symb->macstr[l]) -'0'] = 1; + l--; + } + lastparm = -1; + for(l=0;l<10;l++) + if(symb->macparmlist[l]) + lastparm = l; + + inmacro=yyinmacro; + yyinmacro=1; + + for(l=0;l<=lastparm;l++) + if(!symb->macparmlist[l]) + warningin(W_MACRO_UNUSES_PARM, l, name); + + yyinmacro=inmacro; + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + } + } + + strcpy(yyinline, temp); + endofline(); + delete buf1; + + if(!strlen(name)) + error(E_NO_MACRO_NAME); + + return MACRODEF; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert macro in input stream + // + +int macro(symbolSA symb) +{ + char **parmlist; + int c; + char line[MAX_LINE_LENGTH+2]; + int pos = 0; + int parm; + int inputparms = 0; + int parmpos; + int rem; + int next; + int l; + int len; + char *str; + int res; + int ch; + char orginline[MAX_LINE_LENGTH+2]; + + if( (!symb -> macrodone) && (yyparseno) ) + { + errorin(E_DEF_USE); + while(((ch=yyinput())!='\n') && (ch!=EOF) ); + endofline(); + + return EOL; + } + + strcpy(orginline, yyinline); + + /// Allocate space for parameters ///////////////////////////////////////// + + if( !(parmlist = new char*[10]) ) + errorexit(X_OUT_OF_MEMORY); + + for(c=0;c<10;c++) + { + if(!(parmlist[c]= new char [MAX_LINE_LENGTH+1])) + errorexit(X_OUT_OF_MEMORY); + else + memset(parmlist[c], 0, MAX_LINE_LENGTH+1); + } + + /// Get parameters from input ///////////////////////////////////////////// + + while( ((line[pos]=yyinput())!='\n') && (line[pos++]!=EOF) ); + + if(pos && (line[pos-1]==EOF) ) + line[--pos] = 0; + + line[pos]=0; + line[pos+1]=0; + + /// Local strtok() that inserts parameters into parameter list //////////// + + if(pos) + { + pos = 0; + parm = 0; + rem = FALSE; + + striprem(line); + + while(line[pos] && (parm<10)) + { + next = FALSE; + parmpos = 0; + + while( (!next) && (line[pos]) ) + { + if( (line[pos]=='"') || (line[pos]=='\'') ) + rem ? rem = FALSE : rem = TRUE; + else if( line[pos]=='\\' ) + parmlist[parm][parmpos++] = line[pos++]; + else if ( (line[pos]==',') && !rem) + { + parmlist[parm][parmpos] = '\0'; + next = TRUE; + } + parmlist[parm][parmpos++] = line[pos++]; + } + parm++; + } + + inputparms = parm; + + /// Clean up parametes (remove leading/trailing whitespaces and ',' //////// + + for(c=0;c<10;c++) + { + pos = strlen(parmlist[c]); + if(pos) + pos--; + while( ((parmlist[c][pos]==',')||(isspace(parmlist[c][pos])))&&(pos>=0)) + parmlist[c][pos--] = '\0'; + + if(pos) + { + l = strspn(parmlist[c], "\t\v "); + len = strlen(parmlist[c])-l; + if(l) + memmove(parmlist[c], parmlist[c]+l,len); + parmlist[c][len] = '\0'; + } + } + } + + /// Check that number of parameters specified, equals the ones used //////// + + for(c=0;c<10;c++) + { + if( parmlist[c][0] && !symb->macparmlist[c]) + warningin(W_ARG_SPEC, c); + else if( !parmlist[c][0] && symb->macparmlist[c]) + warningin(W_ARG_USED, c); + } + + /// Insert parameters in macro string ////////////////////////////////////// + + if(! (str = new char[symb-> macsize + MAX_LINE_LENGTH +5] ) ) + errorexit(X_OUT_OF_MEMORY); + + memset(str,0, symb-> macsize + MAX_LINE_LENGTH +5); + + pos = 0; + parm = 0; + res = 0; + + while( symb->macstr[pos] ) + { + if( (symb->macstr[pos]=='@') && (isdigit(symb->macstr[pos+1])) ) + { + parm = symb->macstr[pos+1] - '0'; + pos += 2; + parmpos = 0; + + while(parmlist[parm][parmpos]) + str[res++] = parmlist[parm][parmpos++]; + } + else + str[res++] = symb->macstr[pos++]; + } + + /// Setup new scanner context ////////////////////////////////////////////// + + if( yycontext == (MAX_CONTEXT_DEPTH-1) ) + { + errorexit(X_MACRO_DEPTH); + + for(c=0;c<10;c++) + delete parmlist[c]; + delete parmlist; + + return EOL; + } + + strcpy(yyinlineold, yyinline); + strcpy(yyinline, yyinlinenew); + + strcpy(CONTEXT->yyinlineold, yyinlineold); + strcpy(CONTEXT->yyinline, yyinline); + strcpy(CONTEXT->yyinlinenew, yyinlinenew); + + CONTEXT->line = yyline; + CONTEXT->offset = yyoffset; + CONTEXT->dataoffset = yydataoffset; + CONTEXT->eromoffset = yyeromoffset; + + statestack[yycontext++] = YY_CURRENT_BUFFER; + CONTEXT->ismacro = TRUE; + CONTEXT->macstr = str; + yyoffset = yycodepos/2; + yyeromoffset = yyerompos; + yydataoffset = yydatapos; + + memset(yyinlinenew, 0, MAX_LINE_LENGTH); + memset(yyinline, 0, MAX_LINE_LENGTH); + + pos = strcspn(str,"\n") + 1; + + strcpy(yyinline, symb->name); + + for(l=0;l= MAX_LINE_LENGTH-1 ) + errorexit(X_MACRO_LINE_TOO_LONG, yyline, yyfilename); + + memcpy(yyinline+strlen(yyinline), str ,pos); + + CONTEXT->stringpos = strcspn(str+pos,"\n") + 1; + + memcpy(yyinlinenew, str + pos, CONTEXT->stringpos); + + CONTEXT->stringpos += pos; + + strcpy(yyinline, orginline); + + yyinmacro++; + yyfirstmacroline = TRUE; + + yy_scan_string(str); + + /// Delete parameter list ////////////////////////////////////////////////// + + for(c=0;c<10;c++) + delete parmlist[c]; + delete parmlist; + + /// Allocate new symbol table ////////////////////////////////////////////// + + if(!yyparseno) + { + if(symb -> macsym) + yysymbolstack[yycontext] = symb -> macsym; + else + { + if( !(yysymbolstack[yycontext] = symb -> macsym = new symbolTable()) ) + errorexit(X_OUT_OF_MEMORY); + + if( !symb -> macsym->init(yycfg->casesensitive, 16) ) + errorexit(X_OUT_OF_MEMORY); + } + } + else + yysymbolstack[yycontext] = symb -> macsym; + + if(!yysymbolstack[yycontext]) + internalerror("MA %i", yycontext); + +// yyline++; + + return SKIPRESTART; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Turn listing on/off + // + +void list(int listtype) +{ + switch(listtype) + { + case LIST_NO : yylist = FALSE; break; + case LIST_YES : yylist = TRUE ; break; + case LIST_NO_MACRO : yylistmacro = FALSE; break; + case LIST_YES_MACRO : yylistmacro = TRUE ; break; + default : internalerror("LU %04X",listtype); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Read to end of current context + // + +int doexit(void) +{ + while(yyinput()!=EOF); + yyeol=TRUE; + return restart(); +} + + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/avrlex0.inc b/src/mkutil/tavrasm.118/src/avrlex0.inc new file mode 100644 index 00000000..cea70320 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrlex0.inc @@ -0,0 +1,495 @@ +case 1: +YY_RULE_SETUP +/* #line 116 "avrlex.l" */ +return STAR; + YY_BREAK +case 2: +YY_RULE_SETUP +/* #line 117 "avrlex.l" */ +return DIV; + YY_BREAK +case 3: +YY_RULE_SETUP +/* #line 118 "avrlex.l" */ +return MOD; + YY_BREAK +case 4: +YY_RULE_SETUP +/* #line 119 "avrlex.l" */ +return LS; + YY_BREAK +case 5: +YY_RULE_SETUP +/* #line 120 "avrlex.l" */ +return RS; + YY_BREAK +case 6: +YY_RULE_SETUP +/* #line 121 "avrlex.l" */ +return LE; + YY_BREAK +case 7: +YY_RULE_SETUP +/* #line 122 "avrlex.l" */ +return GE; + YY_BREAK +case 8: +YY_RULE_SETUP +/* #line 123 "avrlex.l" */ +return LESS; + YY_BREAK +case 9: +YY_RULE_SETUP +/* #line 124 "avrlex.l" */ +return GREAT; + YY_BREAK +case 10: +YY_RULE_SETUP +/* #line 125 "avrlex.l" */ +return EQ; + YY_BREAK +case 11: +YY_RULE_SETUP +/* #line 126 "avrlex.l" */ +return NE; + YY_BREAK +case 12: +YY_RULE_SETUP +/* #line 127 "avrlex.l" */ +return OROR; + YY_BREAK +case 13: +YY_RULE_SETUP +/* #line 128 "avrlex.l" */ +return ANDAND; + YY_BREAK +case 14: +YY_RULE_SETUP +/* #line 129 "avrlex.l" */ +return OR; + YY_BREAK +case 15: +YY_RULE_SETUP +/* #line 130 "avrlex.l" */ +return AND; + YY_BREAK +case 16: +YY_RULE_SETUP +/* #line 131 "avrlex.l" */ +return XOR; + YY_BREAK +case 17: +YY_RULE_SETUP +/* #line 132 "avrlex.l" */ +return LPAR; + YY_BREAK +case 18: +YY_RULE_SETUP +/* #line 133 "avrlex.l" */ +return RPAR; + YY_BREAK +case 19: +YY_RULE_SETUP +/* #line 134 "avrlex.l" */ +return COLON; + YY_BREAK +case 20: +YY_RULE_SETUP +/* #line 135 "avrlex.l" */ +return COMMA; + YY_BREAK +case 21: +YY_RULE_SETUP +/* #line 136 "avrlex.l" */ +return DOT; + YY_BREAK +case 22: +YY_RULE_SETUP +/* #line 137 "avrlex.l" */ +return PLUS; + YY_BREAK +case 23: +YY_RULE_SETUP +/* #line 138 "avrlex.l" */ +return MINUS; + YY_BREAK +case 24: +YY_RULE_SETUP +/* #line 139 "avrlex.l" */ +return EQUAL; + YY_BREAK +case 25: +YY_RULE_SETUP +/* #line 140 "avrlex.l" */ +return WAVE; + YY_BREAK +case 26: +YY_RULE_SETUP +/* #line 141 "avrlex.l" */ +return NOT; + YY_BREAK +case 27: +YY_RULE_SETUP +/* #line 143 "avrlex.l" */ +return DEF; + YY_BREAK +case 28: +YY_RULE_SETUP +/* #line 144 "avrlex.l" */ +return EQU; + YY_BREAK +case 29: +YY_RULE_SETUP +/* #line 145 "avrlex.l" */ +return EQU; + YY_BREAK +case 30: +YY_RULE_SETUP +/* #line 146 "avrlex.l" */ +return DB; + YY_BREAK +case 31: +YY_RULE_SETUP +/* #line 147 "avrlex.l" */ +return DW; + YY_BREAK +case 32: +YY_RULE_SETUP +/* #line 148 "avrlex.l" */ +return ORG; + YY_BREAK +case 33: +YY_RULE_SETUP +/* #line 149 "avrlex.l" */ +return BYTE; + YY_BREAK +case 34: +YY_RULE_SETUP +/* #line 150 "avrlex.l" */ +return SET; + YY_BREAK +case 35: +YY_RULE_SETUP +/* #line 151 "avrlex.l" */ +return DEVICE; + YY_BREAK +case 36: +YY_RULE_SETUP +/* #line 153 "avrlex.l" */ +{ yysegment = SEGMENT_CODE; return CSEG; } + YY_BREAK +case 37: +YY_RULE_SETUP +/* #line 154 "avrlex.l" */ +{ yysegment = SEGMENT_DATA; return ESEG; } + YY_BREAK +case 38: +YY_RULE_SETUP +/* #line 155 "avrlex.l" */ +{ yysegment = SEGMENT_EEPROM; return DSEG; } + YY_BREAK +case 39: +YY_RULE_SETUP +/* #line 157 "avrlex.l" */ +{ yylval.func = OP_LOW; return FUNCTION;} + YY_BREAK +case 40: +YY_RULE_SETUP +/* #line 158 "avrlex.l" */ +{ yylval.func = OP_HIGH; return FUNCTION;} + YY_BREAK +case 41: +YY_RULE_SETUP +/* #line 159 "avrlex.l" */ +{ yylval.func = OP_LOW; return FUNCTION;} + YY_BREAK +case 42: +YY_RULE_SETUP +/* #line 160 "avrlex.l" */ +{ yylval.func = OP_BYTE2; return FUNCTION;} + YY_BREAK +case 43: +YY_RULE_SETUP +/* #line 161 "avrlex.l" */ +{ yylval.func = OP_BYTE3; return FUNCTION;} + YY_BREAK +case 44: +YY_RULE_SETUP +/* #line 162 "avrlex.l" */ +{ yylval.func = OP_BYTE4; return FUNCTION;} + YY_BREAK +case 45: +YY_RULE_SETUP +/* #line 163 "avrlex.l" */ +{ yylval.func = OP_LWRD; return FUNCTION;} + YY_BREAK +case 46: +YY_RULE_SETUP +/* #line 164 "avrlex.l" */ +{ yylval.func = OP_HWRD; return FUNCTION;} + YY_BREAK +case 47: +YY_RULE_SETUP +/* #line 165 "avrlex.l" */ +{ yylval.func = OP_PAGE; return FUNCTION;} + YY_BREAK +case 48: +YY_RULE_SETUP +/* #line 166 "avrlex.l" */ +{ yylval.func = OP_EXP2; return FUNCTION;} + YY_BREAK +case 49: +YY_RULE_SETUP +/* #line 167 "avrlex.l" */ +{ yylval.func = OP_LOG2; return FUNCTION;} + YY_BREAK +case 50: +YY_RULE_SETUP +/* #line 168 "avrlex.l" */ +{ yylval.opcode = O_CPC; return IREGREG; } /* Register */ + YY_BREAK +case 51: +YY_RULE_SETUP +/* #line 169 "avrlex.l" */ +{ yylval.opcode = O_CP; return IREGREG; } + YY_BREAK +case 52: +YY_RULE_SETUP +/* #line 170 "avrlex.l" */ +{ yylval.opcode = O_SBC; return IREGREG; } + YY_BREAK +case 53: +YY_RULE_SETUP +/* #line 171 "avrlex.l" */ +{ yylval.opcode = O_SUB; return IREGREG; } + YY_BREAK +case 54: +YY_RULE_SETUP +/* #line 172 "avrlex.l" */ +{ yylval.opcode = O_ADD; return IREGREG; } + YY_BREAK +case 55: +YY_RULE_SETUP +/* #line 173 "avrlex.l" */ +{ yylval.opcode = O_ADC; return IREGREG; } + YY_BREAK +case 56: +YY_RULE_SETUP +/* #line 174 "avrlex.l" */ +{ yylval.opcode = O_CPSE; return IREGREG; } + YY_BREAK +case 57: +YY_RULE_SETUP +/* #line 175 "avrlex.l" */ +{ yylval.opcode = O_AND; return IREGREG; } + YY_BREAK +case 58: +YY_RULE_SETUP +/* #line 176 "avrlex.l" */ +{ yylval.opcode = O_EOR; return IREGREG; } + YY_BREAK +case 59: +YY_RULE_SETUP +/* #line 177 "avrlex.l" */ +{ yylval.opcode = O_OR; return IREGREG; } + YY_BREAK +case 60: +YY_RULE_SETUP +/* #line 178 "avrlex.l" */ +{ yylval.opcode = O_MOV; return IREGREG; } + YY_BREAK +case 61: +YY_RULE_SETUP +/* #line 179 "avrlex.l" */ +{ yylval.opcode = O_MOVW; return IREGREG; } + YY_BREAK +case 62: +YY_RULE_SETUP +/* #line 180 "avrlex.l" */ +{ yylval.opcode = O_MUL; return IREGREG; } + YY_BREAK +case 63: +YY_RULE_SETUP +/* #line 181 "avrlex.l" */ +{ yylval.opcode = O_MULS; return IREGREG; } + YY_BREAK +case 64: +YY_RULE_SETUP +/* #line 182 "avrlex.l" */ +{ yylval.opcode = O_MULSU; return IREGREG; } + YY_BREAK +case 65: +YY_RULE_SETUP +/* #line 183 "avrlex.l" */ +{ yylval.opcode = O_FMUL; return IREGREG; } + YY_BREAK +case 66: +YY_RULE_SETUP +/* #line 184 "avrlex.l" */ +{ yylval.opcode = O_FMULS; return IREGREG; } + YY_BREAK +case 67: +YY_RULE_SETUP +/* #line 185 "avrlex.l" */ +{ yylval.opcode = O_FMULSU; return IREGREG; } + YY_BREAK +case 68: +YY_RULE_SETUP +/* #line 186 "avrlex.l" */ +{ yylval.opcode = O_ADIW; return IREGIMM; } /* Reg/Imm */ + YY_BREAK +case 69: +YY_RULE_SETUP +/* #line 187 "avrlex.l" */ +{ yylval.opcode = O_SBIW; return IREGIMM; } + YY_BREAK +case 70: +YY_RULE_SETUP +/* #line 188 "avrlex.l" */ +{ yylval.opcode = O_CPI; return IREGIMM; } + YY_BREAK +case 71: +YY_RULE_SETUP +/* #line 189 "avrlex.l" */ +{ yylval.opcode = O_SBCI; return IREGIMM; } + YY_BREAK +case 72: +YY_RULE_SETUP +/* #line 190 "avrlex.l" */ +{ yylval.opcode = O_SUBI; return IREGIMM; } + YY_BREAK +case 73: +YY_RULE_SETUP +/* #line 191 "avrlex.l" */ +{ yylval.opcode = O_ORI; return IREGIMM; } + YY_BREAK +case 74: +YY_RULE_SETUP +/* #line 192 "avrlex.l" */ +{ yylval.opcode = O_ANDI; return IREGIMM; } + YY_BREAK +case 75: +YY_RULE_SETUP +/* #line 193 "avrlex.l" */ +{ yylval.opcode = O_LDI; return IREGIMM; } + YY_BREAK +case 76: +YY_RULE_SETUP +/* #line 194 "avrlex.l" */ +{ yylval.opcode = O_LDS; return IREGIMM; } + YY_BREAK +case 77: +YY_RULE_SETUP +/* #line 195 "avrlex.l" */ +{ yylval.opcode = O_SBR; return IREGIMM; } + YY_BREAK +case 78: +YY_RULE_SETUP +/* #line 196 "avrlex.l" */ +{ yylval.opcode = O_BRCC; return IIMM; } /* Immediate */ + YY_BREAK +case 79: +YY_RULE_SETUP +/* #line 197 "avrlex.l" */ +{ yylval.opcode = O_BRCS; return IIMM; } + YY_BREAK +case 80: +YY_RULE_SETUP +/* #line 198 "avrlex.l" */ +{ yylval.opcode = O_BRNE; return IIMM; } + YY_BREAK +case 81: +YY_RULE_SETUP +/* #line 199 "avrlex.l" */ +{ yylval.opcode = O_BREQ; return IIMM; } + YY_BREAK +case 82: +YY_RULE_SETUP +/* #line 200 "avrlex.l" */ +{ yylval.opcode = O_BRPL; return IIMM; } + YY_BREAK +case 83: +YY_RULE_SETUP +/* #line 201 "avrlex.l" */ +{ yylval.opcode = O_BRMI; return IIMM; } + YY_BREAK +case 84: +YY_RULE_SETUP +/* #line 202 "avrlex.l" */ +{ yylval.opcode = O_BRVC; return IIMM; } + YY_BREAK +case 85: +YY_RULE_SETUP +/* #line 203 "avrlex.l" */ +{ yylval.opcode = O_BRVS; return IIMM; } + YY_BREAK +case 86: +YY_RULE_SETUP +/* #line 204 "avrlex.l" */ +{ yylval.opcode = O_BRGE; return IIMM; } + YY_BREAK +case 87: +YY_RULE_SETUP +/* #line 205 "avrlex.l" */ +{ yylval.opcode = O_BRLT; return IIMM; } + YY_BREAK +case 88: +YY_RULE_SETUP +/* #line 206 "avrlex.l" */ +{ yylval.opcode = O_BRHC; return IIMM; } + YY_BREAK +case 89: +YY_RULE_SETUP +/* #line 207 "avrlex.l" */ +{ yylval.opcode = O_BRHS; return IIMM; } + YY_BREAK +case 90: +YY_RULE_SETUP +/* #line 208 "avrlex.l" */ +{ yylval.opcode = O_BRTC; return IIMM; } + YY_BREAK +case 91: +YY_RULE_SETUP +/* #line 209 "avrlex.l" */ +{ yylval.opcode = O_BRTS; return IIMM; } + YY_BREAK +case 92: +YY_RULE_SETUP +/* #line 210 "avrlex.l" */ +{ yylval.opcode = O_BRID; return IIMM; } + YY_BREAK +case 93: +YY_RULE_SETUP +/* #line 211 "avrlex.l" */ +{ yylval.opcode = O_BRIE; return IIMM; } + YY_BREAK +case 94: +YY_RULE_SETUP +/* #line 212 "avrlex.l" */ +{ yylval.opcode = O_BRSH; return IIMM; } + YY_BREAK +case 95: +YY_RULE_SETUP +/* #line 213 "avrlex.l" */ +{ yylval.opcode = O_BRLO; return IIMM; } + YY_BREAK +case 96: +YY_RULE_SETUP +/* #line 214 "avrlex.l" */ +{ yylval.opcode = O_NEG; return IREG; } /* Register */ + YY_BREAK +case 97: +YY_RULE_SETUP +/* #line 215 "avrlex.l" */ +{ yylval.opcode = O_SWAP; return IREG; } + YY_BREAK +case 98: +YY_RULE_SETUP +/* #line 216 "avrlex.l" */ +{ yylval.opcode = O_INC; return IREG; } + YY_BREAK +case 99: +YY_RULE_SETUP +/* #line 217 "avrlex.l" */ +{ yylval.opcode = O_ASR; return IREG; } + YY_BREAK diff --git a/src/mkutil/tavrasm.118/src/avrlex1.inc b/src/mkutil/tavrasm.118/src/avrlex1.inc new file mode 100644 index 00000000..665f2cb0 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrlex1.inc @@ -0,0 +1,495 @@ +case 100: +YY_RULE_SETUP +/* #line 218 "avrlex.l" */ +{ yylval.opcode = O_LSR; return IREG; } + YY_BREAK +case 101: +YY_RULE_SETUP +/* #line 219 "avrlex.l" */ +{ yylval.opcode = O_DEC; return IREG; } + YY_BREAK +case 102: +YY_RULE_SETUP +/* #line 220 "avrlex.l" */ +{ yylval.opcode = O_POP; return IREG; } + YY_BREAK +case 103: +YY_RULE_SETUP +/* #line 221 "avrlex.l" */ +{ yylval.opcode = O_PUSH; return IREG; } + YY_BREAK +case 104: +YY_RULE_SETUP +/* #line 222 "avrlex.l" */ +{ yylval.opcode = O_CLR; return IREG; } + YY_BREAK +case 105: +YY_RULE_SETUP +/* #line 223 "avrlex.l" */ +{ yylval.opcode = O_TST; return IREG; } + YY_BREAK +case 106: +YY_RULE_SETUP +/* #line 224 "avrlex.l" */ +{ yylval.opcode = O_COM; return IREG; } + YY_BREAK +case 107: +YY_RULE_SETUP +/* #line 225 "avrlex.l" */ +{ yylval.opcode = O_ROR; return IREG; } + YY_BREAK +case 108: +YY_RULE_SETUP +/* #line 226 "avrlex.l" */ +{ yylval.opcode = O_SEC; return INOARGS; } /* No arguments */ + YY_BREAK +case 109: +YY_RULE_SETUP +/* #line 227 "avrlex.l" */ +{ yylval.opcode = O_SEZ; return INOARGS; } + YY_BREAK +case 110: +YY_RULE_SETUP +/* #line 228 "avrlex.l" */ +{ yylval.opcode = O_SEN; return INOARGS; } + YY_BREAK +case 111: +YY_RULE_SETUP +/* #line 229 "avrlex.l" */ +{ yylval.opcode = O_SEV; return INOARGS; } + YY_BREAK +case 112: +YY_RULE_SETUP +/* #line 230 "avrlex.l" */ +{ yylval.opcode = O_SES; return INOARGS; } + YY_BREAK +case 113: +YY_RULE_SETUP +/* #line 231 "avrlex.l" */ +{ yylval.opcode = O_SEH; return INOARGS; } + YY_BREAK +case 114: +YY_RULE_SETUP +/* #line 232 "avrlex.l" */ +{ yylval.opcode = O_SET; return INOARGS; } + YY_BREAK +case 115: +YY_RULE_SETUP +/* #line 233 "avrlex.l" */ +{ yylval.opcode = O_SEI; return INOARGS; } + YY_BREAK +case 116: +YY_RULE_SETUP +/* #line 234 "avrlex.l" */ +{ yylval.opcode = O_CLC; return INOARGS; } + YY_BREAK +case 117: +YY_RULE_SETUP +/* #line 235 "avrlex.l" */ +{ yylval.opcode = O_CLZ; return INOARGS; } + YY_BREAK +case 118: +YY_RULE_SETUP +/* #line 236 "avrlex.l" */ +{ yylval.opcode = O_CLN; return INOARGS; } + YY_BREAK +case 119: +YY_RULE_SETUP +/* #line 237 "avrlex.l" */ +{ yylval.opcode = O_CLV; return INOARGS; } + YY_BREAK +case 120: +YY_RULE_SETUP +/* #line 238 "avrlex.l" */ +{ yylval.opcode = O_CLS; return INOARGS; } + YY_BREAK +case 121: +YY_RULE_SETUP +/* #line 239 "avrlex.l" */ +{ yylval.opcode = O_CLH; return INOARGS; } + YY_BREAK +case 122: +YY_RULE_SETUP +/* #line 240 "avrlex.l" */ +{ yylval.opcode = O_CLT; return INOARGS; } + YY_BREAK +case 123: +YY_RULE_SETUP +/* #line 241 "avrlex.l" */ +{ yylval.opcode = O_CLI; return INOARGS; } + YY_BREAK +case 124: +YY_RULE_SETUP +/* #line 242 "avrlex.l" */ +{ yylval.opcode = O_NOP; return INOARGS; } + YY_BREAK +case 125: +YY_RULE_SETUP +/* #line 243 "avrlex.l" */ +{ yylval.opcode = O_ICALL; return INOARGS; } /* Misc. */ + YY_BREAK +case 126: +YY_RULE_SETUP +/* #line 244 "avrlex.l" */ +{ yylval.opcode = O_IJMP; return INOARGS; } + YY_BREAK +case 127: +YY_RULE_SETUP +/* #line 245 "avrlex.l" */ +{ yylval.opcode = O_RETI; return INOARGS; } + YY_BREAK +case 128: +YY_RULE_SETUP +/* #line 246 "avrlex.l" */ +{ yylval.opcode = O_RET; return INOARGS; } + YY_BREAK +case 129: +YY_RULE_SETUP +/* #line 247 "avrlex.l" */ +{ yylval.opcode = O_SLEEP; return INOARGS; } + YY_BREAK +case 130: +YY_RULE_SETUP +/* #line 248 "avrlex.l" */ +{ yylval.opcode = O_WDR; return INOARGS; } + YY_BREAK +case 131: +YY_RULE_SETUP +/* #line 249 "avrlex.l" */ +{ yylval.opcode = O_EIJMP; return INOARGS; } + YY_BREAK +case 132: +YY_RULE_SETUP +/* #line 250 "avrlex.l" */ +{ yylval.opcode = O_EICALL; return INOARGS; } + YY_BREAK +case 133: +YY_RULE_SETUP +/* #line 251 "avrlex.l" */ +{ yylval.opcode = O_SPM; return INOARGS; } + YY_BREAK +case 134: +YY_RULE_SETUP +/* #line 252 "avrlex.l" */ +{ yylval.opcode = O_ESPM; return INOARGS; } + YY_BREAK +case 135: +YY_RULE_SETUP +/* #line 253 "avrlex.l" */ +{ yylval.opcode = O_BCLR; return IIMM; } + YY_BREAK +case 136: +YY_RULE_SETUP +/* #line 254 "avrlex.l" */ +{ yylval.opcode = O_BSET; return IIMM; } + YY_BREAK +case 137: +YY_RULE_SETUP +/* #line 255 "avrlex.l" */ +{ yylval.opcode = O_RCALL; return IIMM; } + YY_BREAK +case 138: +YY_RULE_SETUP +/* #line 256 "avrlex.l" */ +{ yylval.opcode = O_RJMP; return IIMM; } + YY_BREAK +case 139: +YY_RULE_SETUP +/* #line 257 "avrlex.l" */ +{ yylval.opcode = O_JMP; return IIMM; } + YY_BREAK +case 140: +YY_RULE_SETUP +/* #line 258 "avrlex.l" */ +{ yylval.opcode = O_CALL; return IIMM; } + YY_BREAK +case 141: +YY_RULE_SETUP +/* #line 259 "avrlex.l" */ +{ yylval.opcode = O_BRBC; return IIMMIMM; } + YY_BREAK +case 142: +YY_RULE_SETUP +/* #line 260 "avrlex.l" */ +{ yylval.opcode = O_BRBS; return IIMMIMM; } + YY_BREAK +case 143: +YY_RULE_SETUP +/* #line 261 "avrlex.l" */ +{ yylval.opcode = O_CBI; return IIMMIMM; } + YY_BREAK +case 144: +YY_RULE_SETUP +/* #line 262 "avrlex.l" */ +{ yylval.opcode = O_SBI; return IIMMIMM; } + YY_BREAK +case 145: +YY_RULE_SETUP +/* #line 263 "avrlex.l" */ +{ yylval.opcode = O_SBIC; return IIMMIMM; } + YY_BREAK +case 146: +YY_RULE_SETUP +/* #line 264 "avrlex.l" */ +{ yylval.opcode = O_SBIS; return IIMMIMM; } + YY_BREAK +case 147: +YY_RULE_SETUP +/* #line 265 "avrlex.l" */ +{ yylval.opcode = O_OUT; return IIMMREG; } + YY_BREAK +case 148: +YY_RULE_SETUP +/* #line 266 "avrlex.l" */ +{ yylval.opcode = O_STS; return IIMMREG; } + YY_BREAK +case 149: +YY_RULE_SETUP +/* #line 267 "avrlex.l" */ +{ yylval.opcode = O_ROL; return IREG; } + YY_BREAK +case 150: +YY_RULE_SETUP +/* #line 268 "avrlex.l" */ +{ yylval.opcode = O_SER; return IREG; } + YY_BREAK +case 151: +YY_RULE_SETUP +/* #line 269 "avrlex.l" */ +{ yylval.opcode = O_LSL; return IREG; } + YY_BREAK +case 152: +YY_RULE_SETUP +/* #line 270 "avrlex.l" */ +{ yylval.opcode = O_BLD; return IREGIMM; } + YY_BREAK +case 153: +YY_RULE_SETUP +/* #line 271 "avrlex.l" */ +{ yylval.opcode = O_BST; return IREGIMM; } + YY_BREAK +case 154: +YY_RULE_SETUP +/* #line 272 "avrlex.l" */ +{ yylval.opcode = O_CBR; return IREGIMM; } + YY_BREAK +case 155: +YY_RULE_SETUP +/* #line 273 "avrlex.l" */ +{ yylval.opcode = O_IN; return IREGIMM; } + YY_BREAK +case 156: +YY_RULE_SETUP +/* #line 274 "avrlex.l" */ +{ yylval.opcode = O_SBRC; return IREGIMM; } + YY_BREAK +case 157: +YY_RULE_SETUP +/* #line 275 "avrlex.l" */ +{ yylval.opcode = O_SBRS; return IREGIMM; } + YY_BREAK +case 158: +YY_RULE_SETUP +/* #line 276 "avrlex.l" */ +{ yylval.opcode = O_LD; return IINDIRC; } + YY_BREAK +case 159: +YY_RULE_SETUP +/* #line 277 "avrlex.l" */ +{ yylval.opcode = O_ST; return IINDIRC; } + YY_BREAK +case 160: +YY_RULE_SETUP +/* #line 278 "avrlex.l" */ +{ yylval.opcode = O_LDD; return IINDIRC; } + YY_BREAK +case 161: +YY_RULE_SETUP +/* #line 279 "avrlex.l" */ +{ yylval.opcode = O_STD; return IINDIRC; } + YY_BREAK +case 162: +YY_RULE_SETUP +/* #line 280 "avrlex.l" */ +{ yylval.regid = 26; return REGXYZ; } + YY_BREAK +case 163: +YY_RULE_SETUP +/* #line 281 "avrlex.l" */ +{ yylval.regid = 28; return REGXYZ; } + YY_BREAK +case 164: +YY_RULE_SETUP +/* #line 282 "avrlex.l" */ +{ yylval.regid = 30; return REGXYZ; } + YY_BREAK +case 165: +YY_RULE_SETUP +/* #line 283 "avrlex.l" */ +{ yylval.opcode = O_LPM; return ILPM; } + YY_BREAK +case 166: +YY_RULE_SETUP +/* #line 284 "avrlex.l" */ +{ yylval.opcode = O_ELPM; return ILPM; } + YY_BREAK +case 167: +YY_RULE_SETUP +/* #line 286 "avrlex.l" */ +{ yylval.val.value=yycodepos/2;yylval.val.valid=TRUE; return COUNTER;} + YY_BREAK +case 168: +YY_RULE_SETUP +/* #line 287 "avrlex.l" */ +{ yylval.val.value=yydatapos; yylval.val.valid=TRUE; return COUNTER;} + YY_BREAK +case 169: +YY_RULE_SETUP +/* #line 288 "avrlex.l" */ +{ yylval.val.value=yyerompos; yylval.val.valid=TRUE; return COUNTER;} + YY_BREAK +case 170: +YY_RULE_SETUP +/* #line 290 "avrlex.l" */ +list(LIST_NO_MACRO); + YY_BREAK +case 171: +YY_RULE_SETUP +/* #line 291 "avrlex.l" */ +list(LIST_NO); + YY_BREAK +case 172: +YY_RULE_SETUP +/* #line 292 "avrlex.l" */ +list(LIST_YES_MACRO); + YY_BREAK +case 173: +YY_RULE_SETUP +/* #line 293 "avrlex.l" */ +list(LIST_YES); + YY_BREAK +case 174: +YY_RULE_SETUP +/* #line 294 "avrlex.l" */ +yyeol=TRUE; if((ret=doexit() )!=SKIPRESTART) return ret; + YY_BREAK +case 175: +YY_RULE_SETUP +/* #line 295 "avrlex.l" */ +if(includefile()==EOL) return EOL; + YY_BREAK +case 176: +YY_RULE_SETUP +/* #line 296 "avrlex.l" */ +return macrodef(); + YY_BREAK +case 177: +YY_RULE_SETUP +/* #line 297 "avrlex.l" */ +errorin(E_ENDM); + YY_BREAK +case 178: +YY_RULE_SETUP +/* #line 298 "avrlex.l" */ +return string(); + YY_BREAK +case 179: +YY_RULE_SETUP +/* #line 299 "avrlex.l" */ +return registers(); + YY_BREAK +case 180: +YY_RULE_SETUP +/* #line 300 "avrlex.l" */ +return integers(); + YY_BREAK +case 181: +YY_RULE_SETUP +/* #line 301 "avrlex.l" */ +return integers(); + YY_BREAK +case 182: +YY_RULE_SETUP +/* #line 302 "avrlex.l" */ +return integers(); + YY_BREAK +case 183: +YY_RULE_SETUP +/* #line 303 "avrlex.l" */ +return integers(); + YY_BREAK +case 184: +YY_RULE_SETUP +/* #line 304 "avrlex.l" */ +return integers(); + YY_BREAK +case 185: +YY_RULE_SETUP +/* #line 305 "avrlex.l" */ +return character(); + YY_BREAK +case 186: +YY_RULE_SETUP +/* #line 306 "avrlex.l" */ +warningin(W_HEX_ESCAPE_INVALID);yylval.val.valid = TRUE;yylval.val.value = 0; return INTEGER; + YY_BREAK +case 187: +YY_RULE_SETUP +/* #line 307 "avrlex.l" */ +return character(); + YY_BREAK +case 188: +YY_RULE_SETUP +/* #line 308 "avrlex.l" */ +warningin(W_OCT_ESCAPE_INVALID);yylval.val.valid = TRUE;yylval.val.value = 0; return INTEGER; + YY_BREAK +case 189: +YY_RULE_SETUP +/* #line 309 "avrlex.l" */ +return character(); + YY_BREAK +case 190: +YY_RULE_SETUP +/* #line 310 "avrlex.l" */ +return character(); + YY_BREAK +case 191: +YY_RULE_SETUP +/* #line 311 "avrlex.l" */ +if((ret=identifier())!=SKIPRESTART)return ret; + YY_BREAK +case 192: +YY_RULE_SETUP +/* #line 313 "avrlex.l" */ +yyeol=TRUE; return endofline(); + YY_BREAK +case 193: +YY_RULE_SETUP +/* #line 314 "avrlex.l" */ +; + YY_BREAK +case 194: +YY_RULE_SETUP +/* #line 315 "avrlex.l" */ +; + YY_BREAK +case 195: +YY_RULE_SETUP +/* #line 316 "avrlex.l" */ +; + YY_BREAK +case 196: +YY_RULE_SETUP +/* #line 317 "avrlex.l" */ +; + YY_BREAK +case 197: +YY_RULE_SETUP +/* #line 318 "avrlex.l" */ +illegal(); + YY_BREAK +case 198: +YY_RULE_SETUP +/* #line 320 "avrlex.l" */ +ECHO; + YY_BREAK diff --git a/src/mkutil/tavrasm.118/src/avrparse.cc b/src/mkutil/tavrasm.118/src/avrparse.cc new file mode 100644 index 00000000..4328041a --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrparse.cc @@ -0,0 +1,1753 @@ +/* A Bison parser, made from avrparse.y + by GNU bison 1.35. */ + +#define YYBISON 1 /* Identify Bison output. */ + +# define STAR 257 +# define DIV 258 +# define MOD 259 +# define LS 260 +# define RS 261 +# define LE 262 +# define GE 263 +# define LESS 264 +# define GREAT 265 +# define EQ 266 +# define NE 267 +# define OR 268 +# define XOR 269 +# define AND 270 +# define OROR 271 +# define ANDAND 272 +# define LPAR 273 +# define RPAR 274 +# define COLON 275 +# define COMMA 276 +# define DOT 277 +# define EQUAL 278 +# define PLUS 279 +# define MINUS 280 +# define WAVE 281 +# define NOT 282 +# define EOL 283 +# define RESTART 284 +# define ENDOFFILE 285 +# define DEF 286 +# define EQU 287 +# define DB 288 +# define DW 289 +# define ORG 290 +# define CSEG 291 +# define DSEG 292 +# define ESEG 293 +# define BYTE 294 +# define SET 295 +# define DEVICE 296 +# define STRING 297 +# define MACRODEF 298 +# define REGISTER 299 +# define REGXYZ 300 +# define SYMBOL 301 +# define INTEGER 302 +# define COUNTER 303 +# define FUNCTION 304 +# define IREGREG 305 +# define IIMMIMM 306 +# define IREGIMM 307 +# define IIMMREG 308 +# define IREG 309 +# define IIMM 310 +# define INOARGS 311 +# define IINDIRC 312 +# define ILPM 313 + +/* #line 43 "avrparse.y" */ + + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#ifdef _MSC_VER /* Nick */ +#include +#else +#include +#endif +#include "avrasm.hh" +#include "symbol.hh" +#include "semantic.hh" +#include "utils.hh" + +/// Extern /////////////////////////////////////////////////////////////////// + +GLOBALS(extern); +extern char *yytext; + +/// Prototypes /////////////////////////////////////////////////////////////// + +int yylex(); + +/// yyerror ////////////////////////////////////////////////////////////////// + +void yyerror(char *s) +{ + s = s; // Used for debugging purposes +} + +/// Start of grammar ///////////////////////////////////////////////////////// + + +/* #line 77 "avrparse.y" */ +#ifndef YYSTYPE +typedef union +{ + regSA regid; + instSA inst; + opcodeSA opcode; + valueSA val; + nameSA name; + symbolSA symb; + indirectSA indi; + functionSA func; + stringSA string; +} yystype; +# define YYSTYPE yystype +# define YYSTYPE_IS_TRIVIAL 1 +#endif +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + + + +#define YYFINAL 223 +#define YYFLAG -32768 +#define YYNTBASE 60 + +/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ +#define YYTRANSLATE(x) ((unsigned)(x) <= 313 ? yytranslate[x] : 89) + +/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ +static const char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59 +}; + +#if YYDEBUG +static const short yyprhs[] = +{ + 0, 0, 4, 5, 8, 10, 13, 16, 19, 21, + 24, 30, 36, 42, 48, 52, 56, 59, 65, 71, + 73, 77, 81, 85, 89, 93, 97, 101, 105, 108, + 114, 118, 120, 122, 125, 127, 133, 139, 145, 146, + 151, 152, 157, 161, 164, 167, 170, 174, 180, 182, + 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, + 226, 230, 233, 235, 238, 242, 246, 248, 250, 252, + 256, 258, 260, 262, 264, 266, 270, 275, 278, 281, + 284, 286, 288, 292, 296, 300, 302, 306, 310, 312, + 316, 320, 322, 326, 330, 334, 338, 340, 344, 348, + 350, 354, 356, 360, 362, 366, 368, 372, 374, 378 +}; +static const short yyrhs[] = +{ + 62, 30, 62, 0, 0, 62, 63, 0, 63, 0, + 67, 64, 0, 67, 29, 0, 67, 68, 0, 29, + 0, 1, 29, 0, 51, 66, 22, 66, 29, 0, + 53, 66, 22, 75, 29, 0, 54, 75, 22, 66, + 29, 0, 52, 75, 22, 75, 29, 0, 56, 75, + 29, 0, 55, 66, 29, 0, 57, 29, 0, 58, + 66, 22, 71, 29, 0, 58, 71, 22, 66, 29, + 0, 65, 0, 51, 1, 29, 0, 53, 1, 29, + 0, 54, 1, 29, 0, 52, 1, 29, 0, 56, + 1, 29, 0, 55, 1, 29, 0, 57, 1, 29, + 0, 58, 1, 29, 0, 59, 29, 0, 59, 66, + 22, 71, 29, 0, 59, 1, 29, 0, 45, 0, + 47, 0, 47, 21, 0, 61, 0, 32, 47, 24, + 45, 29, 0, 32, 47, 24, 47, 29, 0, 33, + 47, 24, 75, 29, 0, 0, 34, 69, 72, 29, + 0, 0, 35, 70, 74, 29, 0, 36, 75, 29, + 0, 37, 29, 0, 38, 29, 0, 39, 29, 0, + 40, 75, 29, 0, 41, 47, 24, 75, 29, 0, + 44, 0, 42, 47, 29, 0, 32, 1, 29, 0, + 33, 1, 29, 0, 34, 1, 29, 0, 35, 1, + 29, 0, 36, 1, 29, 0, 37, 1, 29, 0, + 38, 1, 29, 0, 39, 1, 29, 0, 40, 1, + 29, 0, 41, 1, 29, 0, 42, 1, 29, 0, + 26, 46, 0, 46, 0, 46, 25, 0, 46, 25, + 75, 0, 72, 22, 73, 0, 73, 0, 43, 0, + 75, 0, 74, 22, 75, 0, 75, 0, 88, 0, + 48, 0, 49, 0, 47, 0, 19, 75, 20, 0, + 50, 19, 75, 20, 0, 26, 77, 0, 27, 77, + 0, 28, 77, 0, 76, 0, 77, 0, 78, 3, + 77, 0, 78, 4, 77, 0, 78, 5, 77, 0, + 78, 0, 79, 25, 78, 0, 79, 26, 78, 0, + 79, 0, 80, 6, 79, 0, 80, 7, 79, 0, + 80, 0, 81, 10, 80, 0, 81, 11, 80, 0, + 81, 8, 80, 0, 81, 9, 80, 0, 81, 0, + 82, 12, 81, 0, 82, 13, 81, 0, 82, 0, + 83, 16, 82, 0, 83, 0, 84, 15, 83, 0, + 84, 0, 85, 14, 84, 0, 85, 0, 86, 18, + 85, 0, 86, 0, 87, 17, 86, 0, 87, 0 +}; + +#endif + +#if YYDEBUG +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const short yyrline[] = +{ + 0, 173, 176, 190, 191, 204, 205, 206, 207, 211, + 245, 247, 249, 251, 253, 255, 257, 259, 261, 264, + 268, 269, 270, 271, 272, 273, 274, 275, 288, 290, + 295, 308, 309, 331, 332, 357, 358, 359, 360, 360, + 361, 361, 362, 363, 364, 365, 366, 367, 368, 369, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 401, 403, 405, 407, 426, 427, 430, 431, 434, + 435, 448, 451, 452, 453, 462, 464, 468, 469, 470, + 471, 474, 475, 477, 479, 483, 484, 486, 490, 491, + 493, 497, 498, 500, 502, 504, 508, 509, 511, 515, + 516, 520, 521, 525, 526, 530, 531, 535, 536, 540 +}; +#endif + + +#if (YYDEBUG) || defined YYERROR_VERBOSE + +/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ +static const char *const yytname[] = +{ + "$", "error", "$undefined.", "STAR", "DIV", "MOD", "LS", "RS", "LE", "GE", + "LESS", "GREAT", "EQ", "NE", "OR", "XOR", "AND", "OROR", "ANDAND", + "LPAR", "RPAR", "COLON", "COMMA", "DOT", "EQUAL", "PLUS", "MINUS", + "WAVE", "NOT", "EOL", "RESTART", "ENDOFFILE", "DEF", "EQU", "DB", "DW", + "ORG", "CSEG", "DSEG", "ESEG", "BYTE", "SET", "DEVICE", "STRING", + "MACRODEF", "REGISTER", "REGXYZ", "SYMBOL", "INTEGER", "COUNTER", + "FUNCTION", "IREGREG", "IIMMIMM", "IREGIMM", "IIMMREG", "IREG", "IIMM", + "INOARGS", "IINDIRC", "ILPM", "program", "e", "programlist", + "programelement", "instruction", "lpminst", "registername", "label", + "directive", "@1", "@2", "indirectaddr", "byteexprlist", "byteelement", + "wordexprlist", "expr", "primary_expr", "unary_expr", "mult_expr", + "additive_expr", "shift_expr", "relational_expr", "equality_expr", + "AND_expression", "exclusive_OR", "inclusive_OR", "logical_AND", + "logical_OR", "composite_expr", 0 +}; +#endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const short yyr1[] = +{ + 0, 60, 61, 62, 62, 63, 63, 63, 63, 63, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, + 65, 66, 66, 67, 67, 68, 68, 68, 69, 68, + 70, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 71, 71, 71, 71, 72, 72, 73, 73, 74, + 74, 75, 76, 76, 76, 76, 76, 77, 77, 77, + 77, 78, 78, 78, 78, 79, 79, 79, 80, 80, + 80, 81, 81, 81, 81, 81, 82, 82, 82, 83, + 83, 84, 84, 85, 85, 86, 86, 87, 87, 88 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const short yyr2[] = +{ + 0, 3, 0, 2, 1, 2, 2, 2, 1, 2, + 5, 5, 5, 5, 3, 3, 2, 5, 5, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, + 3, 1, 1, 2, 1, 5, 5, 5, 0, 4, + 0, 4, 3, 2, 2, 2, 3, 5, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 1, 2, 3, 3, 1, 1, 1, 3, + 1, 1, 1, 1, 1, 3, 4, 2, 2, 2, + 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1 +}; + +/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ +static const short yydefact[] = +{ + 0, 0, 8, 0, 34, 0, 4, 0, 9, 33, + 0, 3, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 19, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 74, 72, 73, 0, 0, 80, 81, 85, 88, + 91, 96, 99, 101, 103, 105, 107, 109, 71, 0, + 43, 0, 44, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 0, 62, + 0, 0, 0, 28, 0, 50, 0, 51, 0, 52, + 67, 0, 66, 68, 53, 0, 70, 54, 0, 77, + 78, 79, 0, 42, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 56, 57, 58, 46, 59, 0, 60, + 49, 20, 0, 23, 0, 21, 0, 22, 0, 25, + 15, 24, 14, 26, 27, 61, 63, 0, 0, 30, + 0, 0, 0, 0, 0, 39, 0, 41, 75, 0, + 82, 83, 84, 86, 87, 89, 90, 94, 95, 92, + 93, 97, 98, 100, 102, 104, 106, 108, 0, 0, + 0, 0, 0, 64, 0, 0, 0, 35, 36, 37, + 65, 69, 76, 47, 10, 13, 11, 12, 17, 18, + 29, 0, 0, 0 +}; + +static const short yydefgoto[] = +{ + 221, 4, 5, 6, 34, 35, 84, 7, 36, 43, + 45, 101, 111, 112, 115, 113, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68 +}; + +static const short yypact[] = +{ + 170, -19,-32768, -16,-32768, 128,-32768, 289,-32768,-32768, + 170,-32768,-32768, 32, 33, 59, 96, 212, 34, 75, + 88, 217, 37, 63,-32768, 43, 229, 56, 262, 73, + 267, 98, 36, 30,-32768,-32768,-32768, 14, -8, 12, + 13, 21, 66, 256, 71, 223, 87, 223, 223, 223, + 223,-32768,-32768,-32768, 100, 92,-32768,-32768, 130, 115, + 141, 15, 138, 109, 113, 116, 118, 121,-32768, 125, + -32768, 147,-32768, 148,-32768, 149, 159, 160, 166, 162, + 163, 164,-32768,-32768, 172, 167, 173, 168, 176, 171, + 179, 186, 187, 190, 191, 203,-32768, 204, 188, 210, + 215, 219, 218,-32768, 224,-32768, -6,-32768, 223,-32768, + -32768, -10,-32768,-32768,-32768, -2,-32768,-32768, 232,-32768, + -32768,-32768, 223,-32768, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223,-32768,-32768,-32768,-32768,-32768,-32768, 223,-32768, + -32768,-32768, 51,-32768, 223,-32768, 223,-32768, 51,-32768, + -32768,-32768,-32768,-32768,-32768,-32768, 223, -24, 51,-32768, + -24, 225, 240, 245, 256,-32768, 223,-32768,-32768, 233, + -32768,-32768,-32768, 130, 130, 115, 115, 141, 141, 141, + 141, 15, 15, 138, 109, 113, 116, 118, 251, 258, + 263, 268, 269,-32768, 271, 272, 273,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768, 285, 291,-32768 +}; + +static const short yypgoto[] = +{ + -32768,-32768, 248, 3,-32768,-32768, -26,-32768,-32768,-32768, + -32768, -138,-32768, 122,-32768, -17,-32768, -32, 25, 26, + -20, 38, 182, 169, 174, 180, 193,-32768,-32768 +}; + + +#define YYLAST 348 + + +static const short yytable[] = +{ + 55, 88, 98, 92, 76, 9, 100, 104, 11, 86, + 8, 90, 174, 94, -1, 1, 119, 120, 121, 175, + 176, 105, 99, 131, 132, 133, 134, 177, 116, 204, + 118, 102, 206, 38, 40, 69, 106, 97, 77, 171, + 11, 172, 107, 2, 81, 108, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, 87, -2, 103, + 42, 3, 98, 70, 79, -2, -2, -2, -2, -2, + -2, -2, -2, -2, 91, 82, 71, 83, -38, 39, + 41, 82, 99, 83, 78, -38, -38, -38, 82, 73, + 83, 173, 180, 181, 182, 109, 82, 44, 83, 95, + 114, 82, -38, 83, 72, 179, -38, -38, -38, -38, + 80, 187, 188, 189, 190, -40, 117, 74, 82, 122, + 83, 123, -40, -40, -40, 137, 199, 96, 138, 1, + 139, 198, 202, 124, 125, 126, 140, 200, 141, 201, + 127, 128, 205, -40, -40, -40, -40, 129, 130, 203, + 135, 136, 183, 184, 142, 185, 186, 2, 10, 211, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, 1, -2, 191, 192, 3, 143, 144, 145, -2, + -2, -2, -2, -2, -2, -2, -2, -2, 146, 147, + 148, 149, 150, 151, 152, 154, 153, 155, 156, 2, + 157, 158, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, 46, -2, 159, 160, 3, 75, 161, + 162, -2, -2, -2, -2, -2, -2, -2, -2, -2, + 85, 47, 163, 164, 165, 166, 47, 167, 48, 49, + 50, 168, 47, 48, 49, 50, 170, 169, 47, 48, + 49, 50, 178, 212, 207, 48, 49, 50, 37, 51, + 52, 53, 54, 89, 51, 52, 53, 54, 93, 208, + 51, 52, 53, 54, 209, 47, 51, 52, 53, 54, + 213, 47, 48, 49, 50, 222, 47, 214, 48, 49, + 50, 223, 215, 48, 49, 50, 210, 216, 217, 110, + 218, 219, 220, 51, 52, 53, 54, 194, 0, 51, + 52, 53, 54, 195, 51, 52, 53, 54, 12, 193, + 196, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 0, 24, 197, 0, 0, 0, 0, 0, + 25, 26, 27, 28, 29, 30, 31, 32, 33 +}; + +static const short yycheck[] = +{ + 17, 27, 26, 29, 21, 21, 32, 33, 5, 26, + 29, 28, 22, 30, 0, 1, 48, 49, 50, 29, + 22, 29, 46, 8, 9, 10, 11, 29, 45, 167, + 47, 1, 170, 1, 1, 1, 24, 1, 1, 45, + 37, 47, 29, 29, 1, 24, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 1, 44, 29, + 1, 47, 26, 29, 1, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 1, 45, 1, 47, 19, 47, + 47, 45, 46, 47, 47, 26, 27, 28, 45, 1, + 47, 108, 124, 125, 126, 29, 45, 1, 47, 1, + 29, 45, 43, 47, 29, 122, 47, 48, 49, 50, + 47, 131, 132, 133, 134, 19, 29, 29, 45, 19, + 47, 29, 26, 27, 28, 16, 152, 29, 15, 1, + 14, 148, 158, 3, 4, 5, 18, 154, 17, 156, + 25, 26, 168, 47, 48, 49, 50, 6, 7, 166, + 12, 13, 127, 128, 29, 129, 130, 29, 30, 176, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 1, 44, 135, 136, 47, 29, 29, 29, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 29, 29, + 24, 29, 29, 29, 22, 22, 29, 29, 22, 29, + 29, 22, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 1, 44, 29, 29, 47, 1, 29, + 29, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 1, 19, 29, 29, 46, 25, 19, 22, 26, 27, + 28, 22, 19, 26, 27, 28, 22, 29, 19, 26, + 27, 28, 20, 20, 29, 26, 27, 28, 10, 47, + 48, 49, 50, 1, 47, 48, 49, 50, 1, 29, + 47, 48, 49, 50, 29, 19, 47, 48, 49, 50, + 29, 19, 26, 27, 28, 0, 19, 29, 26, 27, + 28, 0, 29, 26, 27, 28, 174, 29, 29, 43, + 29, 29, 29, 47, 48, 49, 50, 138, -1, 47, + 48, 49, 50, 139, 47, 48, 49, 50, 29, 137, + 140, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, -1, 44, 141, -1, -1, -1, -1, -1, + 51, 52, 53, 54, 55, 56, 57, 58, 59 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +/* #line 3 "/usr/share/bison/bison.simple" */ + +/* Skeleton output parser for bison, + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* This is the parser code that is written into each bison parser when + the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#if 1 /* Nick */ +void *yy_flex_alloc( unsigned long size ); +void yy_flex_free( void *ptr ); +#define YYSTACK_ALLOC yy_flex_alloc +#define YYSTACK_FREE yy_flex_free +#else +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +#endif +# endif +#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; +# if YYLSP_NEEDED + YYLTYPE yyls; +# endif +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# if YYLSP_NEEDED +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAX) +# else +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAX) +# endif + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up"); \ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). + + When YYLLOC_DEFAULT is run, CURRENT is set the location of the + first token. By default, to implement support for ranges, extend + its range to the last symbol. */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#if YYPURE +# if YYLSP_NEEDED +# ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +# else +# define YYLEX yylex (&yylval, &yylloc) +# endif +# else /* !YYLSP_NEEDED */ +# ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +# else +# define YYLEX yylex (&yylval) +# endif +# endif /* !YYLSP_NEEDED */ +#else /* !YYPURE */ +# define YYLEX yylex () +#endif /* !YYPURE */ + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +#endif /* !YYDEBUG */ + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + +#ifdef YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif +#endif + +/* #line 315 "/usr/share/bison/bison.simple" */ + + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +# define YYPARSE_PARAM_DECL +# else +# define YYPARSE_PARAM_ARG YYPARSE_PARAM +# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +# endif +#else /* !YYPARSE_PARAM */ +# define YYPARSE_PARAM_ARG +# define YYPARSE_PARAM_DECL +#endif /* !YYPARSE_PARAM */ + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +# ifdef YYPARSE_PARAM +int yyparse (void *); +# else +int yyparse (void); +# endif +#endif + +/* YY_DECL_VARIABLES -- depending whether we use a pure parser, + variables are global, or local to YYPARSE. */ + +#define YY_DECL_NON_LSP_VARIABLES \ +/* The lookahead symbol. */ \ +int yychar; \ + \ +/* The semantic value of the lookahead symbol. */ \ +YYSTYPE yylval; \ + \ +/* Number of parse errors so far. */ \ +int yynerrs; + +#if YYLSP_NEEDED +# define YY_DECL_VARIABLES \ +YY_DECL_NON_LSP_VARIABLES \ + \ +/* Location data for the lookahead symbol. */ \ +YYLTYPE yylloc; +#else +# define YY_DECL_VARIABLES \ +YY_DECL_NON_LSP_VARIABLES +#endif + + +/* If nonreentrant, generate the variables here. */ + +#if !YYPURE +YY_DECL_VARIABLES +#endif /* !YYPURE */ + +int +yyparse (YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + /* If reentrant, generate the variables here. */ +#if YYPURE + YY_DECL_VARIABLES +#endif /* !YYPURE */ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yychar1 = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + +#if YYLSP_NEEDED + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; +#endif + +#if YYLSP_NEEDED +# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +# define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + YYSIZE_T yystacksize = YYINITDEPTH; + + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; +#if YYLSP_NEEDED + YYLTYPE yyloc; +#endif + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; +#if YYLSP_NEEDED + yylsp = yyls; +#endif + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. */ +# if YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + yyls = yyls1; +# else + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); +# endif + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + goto yyoverflowlab; + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); +# if YYLSP_NEEDED + YYSTACK_RELOCATE (yyls); +# endif +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; +#if YYLSP_NEEDED + yylsp = yyls + yysize - 1; +#endif + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yychar1 = YYTRANSLATE (yychar); + +#if YYDEBUG + /* We have to keep this `#if YYDEBUG', since we use variables + which are defined only if `YYDEBUG' is set. */ + if (yydebug) + { + YYFPRINTF (stderr, "Next token is %d (%s", + yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise + meaning of a token, for further debugging info. */ +# ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +# endif + YYFPRINTF (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %d (%s), ", + yychar, yytname[yychar1])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#if YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to the semantic value of + the lookahead token. This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + +#if YYLSP_NEEDED + /* Similarly for the default location. Let the user run additional + commands if for instance locations are ranges. */ + yyloc = yylsp[1-yylen]; + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); +#endif + +#if YYDEBUG + /* We have to keep this `#if YYDEBUG', since we use variables which + are defined only if `YYDEBUG' is set. */ + if (yydebug) + { + int yyi; + + YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) + YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); + YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + switch (yyn) { + +case 5: +/* #line 204 "avrparse.y" */ +{ tolog(); ; + break;} +case 6: +/* #line 205 "avrparse.y" */ +{ tolog(); ; + break;} +case 7: +/* #line 206 "avrparse.y" */ +{ tolog(); ; + break;} +case 8: +/* #line 207 "avrparse.y" */ +{ tolog(); ; + break;} +case 9: +/* #line 211 "avrparse.y" */ +{ error(E_UNKNOWN_OPCODE); tolog(); ; + break;} +case 10: +/* #line 246 "avrparse.y" */ +{genRegReg(yyvsp[-4].opcode, yyvsp[-3].regid, yyvsp[-1].regid);; + break;} +case 11: +/* #line 248 "avrparse.y" */ +{genRegImm(yyvsp[-4].opcode, yyvsp[-3].regid, &yyvsp[-1].val);; + break;} +case 12: +/* #line 250 "avrparse.y" */ +{genImmReg(yyvsp[-4].opcode, &yyvsp[-3].val, yyvsp[-1].regid);; + break;} +case 13: +/* #line 252 "avrparse.y" */ +{genImmImm(yyvsp[-4].opcode, &yyvsp[-3].val, &yyvsp[-1].val);; + break;} +case 14: +/* #line 254 "avrparse.y" */ +{genImmedi(yyvsp[-2].opcode, &yyvsp[-1].val);; + break;} +case 15: +/* #line 256 "avrparse.y" */ +{genRegist(yyvsp[-2].opcode, yyvsp[-1].regid);; + break;} +case 16: +/* #line 258 "avrparse.y" */ +{genNoargs(yyvsp[-1].opcode);; + break;} +case 17: +/* #line 260 "avrparse.y" */ +{genIndirc(yyvsp[-4].opcode, &yyvsp[-1].indi, yyvsp[-3].regid,TRUE);; + break;} +case 18: +/* #line 262 "avrparse.y" */ +{genIndirc(yyvsp[-4].opcode, &yyvsp[-3].indi, yyvsp[-1].regid);; + break;} +case 20: +/* #line 268 "avrparse.y" */ +{ error(E_REGISTER_EXPECTED); ; + break;} +case 21: +/* #line 269 "avrparse.y" */ +{ error(E_INVALID_REGIMM_SPEC); ; + break;} +case 22: +/* #line 270 "avrparse.y" */ +{ error(E_INVALID_REGIMM_SPEC); ; + break;} +case 23: +/* #line 271 "avrparse.y" */ +{ error(E_INVALID_IMMEDIATE_SPEC); ; + break;} +case 24: +/* #line 272 "avrparse.y" */ +{ error(E_INVALID_IMMEDIATE_SPEC); ; + break;} +case 25: +/* #line 273 "avrparse.y" */ +{ error(E_INVALID_REGISTER_SPEC); ; + break;} +case 26: +/* #line 274 "avrparse.y" */ +{ error(E_NOARGS_EXPECTED_SPEC); ; + break;} +case 27: +/* #line 275 "avrparse.y" */ +{ error(E_INVALID_REGISTER_SPEC); ; + break;} +case 28: +/* #line 289 "avrparse.y" */ +{ genLpm(yyvsp[-1].opcode, 0, NULL, FALSE); ; + break;} +case 29: +/* #line 291 "avrparse.y" */ +{ genLpm(yyvsp[-4].opcode, yyvsp[-3].regid, &yyvsp[-1].indi, TRUE); ; + break;} +case 30: +/* #line 295 "avrparse.y" */ +{ error(E_INVALID_REGISTER_SPEC); ; + break;} +case 32: +/* #line 310 "avrparse.y" */ +{ if(yyvsp[0].symb->isdefine) + yyval.regid=yyvsp[0].symb->reg; + else + { + yyval.regid=-1; + errorin(E_INVALID_REGISTER_SPEC); + } + ; + break;} +case 33: +/* #line 331 "avrparse.y" */ +{ doLab(yyvsp[-1].symb); ; + break;} +case 35: +/* #line 357 "avrparse.y" */ +{doDef(yyvsp[-3].symb,yyvsp[-1].regid);; + break;} +case 36: +/* #line 358 "avrparse.y" */ +{doDef(yyvsp[-3].symb,yyvsp[-1].symb); ; + break;} +case 37: +/* #line 359 "avrparse.y" */ +{doEqu(yyvsp[-3].symb,&yyvsp[-1].val); ; + break;} +case 38: +/* #line 360 "avrparse.y" */ +{doAdb();; + break;} +case 39: +/* #line 360 "avrparse.y" */ +{/*XXX*/ ; + break;} +case 40: +/* #line 361 "avrparse.y" */ +{doAdw();; + break;} +case 41: +/* #line 361 "avrparse.y" */ +{ ; + break;} +case 42: +/* #line 362 "avrparse.y" */ +{doOrg(&yyvsp[-1].val); ; + break;} +case 43: +/* #line 363 "avrparse.y" */ +{ ; + break;} +case 44: +/* #line 364 "avrparse.y" */ +{ ; + break;} +case 45: +/* #line 365 "avrparse.y" */ +{ ; + break;} +case 46: +/* #line 366 "avrparse.y" */ +{doByt(&yyvsp[-1].val); ; + break;} +case 47: +/* #line 367 "avrparse.y" */ +{doSet(yyvsp[-3].symb,&yyvsp[-1].val); ; + break;} +case 48: +/* #line 368 "avrparse.y" */ +{ ; + break;} +case 49: +/* #line 369 "avrparse.y" */ +{doDev(yyvsp[-1].symb); ; + break;} +case 50: +/* #line 373 "avrparse.y" */ +{ error(E_EXPECTED_ID_REG); ; + break;} +case 51: +/* #line 374 "avrparse.y" */ +{ error(E_EXPECTED_ID_EXPR); ; + break;} +case 52: +/* #line 375 "avrparse.y" */ +{ error(E_EXPECTED_VALLIST); ; + break;} +case 53: +/* #line 376 "avrparse.y" */ +{ error(E_EXPECTED_VALLIST); ; + break;} +case 54: +/* #line 377 "avrparse.y" */ +{ error(E_EXPECTED_VAL_LABEL); ; + break;} +case 55: +/* #line 378 "avrparse.y" */ +{ error(E_EXPECTED_NOARGS); ; + break;} +case 56: +/* #line 379 "avrparse.y" */ +{ error(E_EXPECTED_NOARGS); ; + break;} +case 57: +/* #line 380 "avrparse.y" */ +{ error(E_EXPECTED_NOARGS); ; + break;} +case 58: +/* #line 381 "avrparse.y" */ +{ error(E_EXPECTED_VAL_LABEL); ; + break;} +case 59: +/* #line 382 "avrparse.y" */ +{ error(E_EXPECTED_ID_EXPR); ; + break;} +case 60: +/* #line 383 "avrparse.y" */ +{ error(E_EXPECTED_DEVICE); ; + break;} +case 61: +/* #line 402 "avrparse.y" */ +{yyval.indi.regno=yyvsp[0].regid;yyval.indi.plus=2;yyval.indi.disp=0;; + break;} +case 62: +/* #line 404 "avrparse.y" */ +{yyval.indi.regno=yyvsp[0].regid;yyval.indi.plus=0;yyval.indi.disp=0;; + break;} +case 63: +/* #line 406 "avrparse.y" */ +{yyval.indi.regno=yyvsp[-1].regid;yyval.indi.plus=1;yyval.indi.disp=0;; + break;} +case 64: +/* #line 408 "avrparse.y" */ +{ yyval.indi.regno = yyvsp[-2].regid; + yyval.indi.plus=1;yyval.indi.disp=1;yyval.indi.offset=yyvsp[0].val;; + break;} +case 67: +/* #line 430 "avrparse.y" */ +{doAdb(yyvsp[0].string); ; + break;} +case 68: +/* #line 431 "avrparse.y" */ +{doAdb(&yyvsp[0].val);; + break;} +case 69: +/* #line 434 "avrparse.y" */ +{doAdw(&yyvsp[0].val);; + break;} +case 70: +/* #line 435 "avrparse.y" */ +{doAdw(&yyvsp[0].val);; + break;} +case 74: +/* #line 454 "avrparse.y" */ +{yyval.val.valid=yyvsp[0].symb->valid; + yyval.val.value=yyvsp[0].symb->value + +yyvsp[0].symb->islabel*yyvsp[0].symb->macrolabel* + (yyoffset *(yyvsp[0].symb->segment==SEGMENT_CODE)) + +yyvsp[0].symb->islabel*yyvsp[0].symb->macrolabel* + (yydataoffset*(yyvsp[0].symb->segment==SEGMENT_DATA)) + +yyvsp[0].symb->islabel*yyvsp[0].symb->macrolabel* + (yyeromoffset*(yyvsp[0].symb->segment==SEGMENT_EEPROM));; + break;} +case 75: +/* #line 463 "avrparse.y" */ +{ yyval.val=yyvsp[-1].val; ; + break;} +case 76: +/* #line 465 "avrparse.y" */ +{ genFun(yyvsp[-3].func, &yyvsp[-1].val, &yyval.val); ; + break;} +case 77: +/* #line 468 "avrparse.y" */ +{ oprUna(OP_MINUS, &yyvsp[0].val, &yyval.val); ; + break;} +case 78: +/* #line 469 "avrparse.y" */ +{ oprUna(OP_WAVE , &yyvsp[0].val, &yyval.val); ; + break;} +case 79: +/* #line 470 "avrparse.y" */ +{ oprUna(OP_NOT , &yyvsp[0].val, &yyval.val); ; + break;} +case 82: +/* #line 476 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_STAR , &yyvsp[0].val, &yyval.val); ; + break;} +case 83: +/* #line 478 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_DIV , &yyvsp[0].val, &yyval.val); ; + break;} +case 84: +/* #line 480 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_MOD , &yyvsp[0].val, &yyval.val); ; + break;} +case 86: +/* #line 485 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_PLUS , &yyvsp[0].val, &yyval.val); ; + break;} +case 87: +/* #line 487 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_MINUS , &yyvsp[0].val, &yyval.val); ; + break;} +case 89: +/* #line 492 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_LS , &yyvsp[0].val, &yyval.val); ; + break;} +case 90: +/* #line 494 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_RS , &yyvsp[0].val, &yyval.val); ; + break;} +case 92: +/* #line 499 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_LESS , &yyvsp[0].val, &yyval.val); ; + break;} +case 93: +/* #line 501 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_GREAT , &yyvsp[0].val, &yyval.val); ; + break;} +case 94: +/* #line 503 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_LE , &yyvsp[0].val, &yyval.val); ; + break;} +case 95: +/* #line 505 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_GE , &yyvsp[0].val, &yyval.val); ; + break;} +case 97: +/* #line 510 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_EQ , &yyvsp[0].val, &yyval.val); ; + break;} +case 98: +/* #line 512 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_NE , &yyvsp[0].val, &yyval.val); ; + break;} +case 100: +/* #line 517 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_AND , &yyvsp[0].val, &yyval.val); ; + break;} +case 102: +/* #line 522 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_XOR , &yyvsp[0].val, &yyval.val); ; + break;} +case 104: +/* #line 527 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_OR , &yyvsp[0].val, &yyval.val); ; + break;} +case 106: +/* #line 532 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_ANDAND, &yyvsp[0].val, &yyval.val); ; + break;} +case 108: +/* #line 537 "avrparse.y" */ +{ oprBin(&yyvsp[-2].val,OP_OROR , &yyvsp[0].val, &yyval.val); ; + break;} +} + +/* #line 705 "/usr/share/bison/bison.simple" */ + + + yyvsp -= yylen; + yyssp -= yylen; +#if YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG + if (yydebug) + { + short *yyssp1 = yyss - 1; + YYFPRINTF (stderr, "state stack now"); + while (yyssp1 != yyssp) + YYFPRINTF (stderr, " %d", *++yyssp1); + YYFPRINTF (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; +#if YYLSP_NEEDED + *++yylsp = yyloc; +#endif + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("parse error, unexpected ") + 1; + yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "parse error, unexpected "); + yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("parse error; also virtual memory exhausted"); + } + else +#endif /* defined (YYERROR_VERBOSE) */ + yyerror ("parse error"); + } + goto yyerrlab1; + + +/*--------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action | +`--------------------------------------------------*/ +yyerrlab1: + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + YYDPRINTF ((stderr, "Discarding token %d (%s).\n", + yychar, yytname[yychar1])); + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + + +/*-------------------------------------------------------------------. +| yyerrdefault -- current state does not do anything special for the | +| error token. | +`-------------------------------------------------------------------*/ +yyerrdefault: +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + + /* If its default is to accept any token, ok. Otherwise pop it. */ + yyn = yydefact[yystate]; + if (yyn) + goto yydefault; +#endif + + +/*---------------------------------------------------------------. +| yyerrpop -- pop the current state because it cannot handle the | +| error token | +`---------------------------------------------------------------*/ +yyerrpop: + if (yyssp == yyss) + YYABORT; + yyvsp--; + yystate = *--yyssp; +#if YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG + if (yydebug) + { + short *yyssp1 = yyss - 1; + YYFPRINTF (stderr, "Error: state stack now"); + while (yyssp1 != yyssp) + YYFPRINTF (stderr, " %d", *++yyssp1); + YYFPRINTF (stderr, "\n"); + } +#endif + +/*--------------. +| yyerrhandle. | +`--------------*/ +yyerrhandle: + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; +#if YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +/*---------------------------------------------. +| yyoverflowab -- parser overflow comes here. | +`---------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} +/* #line 544 "avrparse.y" */ diff --git a/src/mkutil/tavrasm.118/src/avrparse.hh b/src/mkutil/tavrasm.118/src/avrparse.hh new file mode 100644 index 00000000..16e371e8 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrparse.hh @@ -0,0 +1,81 @@ +#ifndef BISON_AVRPARSE_H +# define BISON_AVRPARSE_H + +#ifndef YYSTYPE +typedef union +{ + regSA regid; + instSA inst; + opcodeSA opcode; + valueSA val; + nameSA name; + symbolSA symb; + indirectSA indi; + functionSA func; + stringSA string; +} yystype; +# define YYSTYPE yystype +# define YYSTYPE_IS_TRIVIAL 1 +#endif +# define STAR 257 +# define DIV 258 +# define MOD 259 +# define LS 260 +# define RS 261 +# define LE 262 +# define GE 263 +# define LESS 264 +# define GREAT 265 +# define EQ 266 +# define NE 267 +# define OR 268 +# define XOR 269 +# define AND 270 +# define OROR 271 +# define ANDAND 272 +# define LPAR 273 +# define RPAR 274 +# define COLON 275 +# define COMMA 276 +# define DOT 277 +# define EQUAL 278 +# define PLUS 279 +# define MINUS 280 +# define WAVE 281 +# define NOT 282 +# define EOL 283 +# define RESTART 284 +# define ENDOFFILE 285 +# define DEF 286 +# define EQU 287 +# define DB 288 +# define DW 289 +# define ORG 290 +# define CSEG 291 +# define DSEG 292 +# define ESEG 293 +# define BYTE 294 +# define SET 295 +# define DEVICE 296 +# define STRING 297 +# define MACRODEF 298 +# define REGISTER 299 +# define REGXYZ 300 +# define SYMBOL 301 +# define INTEGER 302 +# define COUNTER 303 +# define FUNCTION 304 +# define IREGREG 305 +# define IIMMIMM 306 +# define IREGIMM 307 +# define IIMMREG 308 +# define IREG 309 +# define IIMM 310 +# define INOARGS 311 +# define IINDIRC 312 +# define ILPM 313 + + +extern YYSTYPE yylval; + +#endif /* not BISON_AVRPARSE_H */ diff --git a/src/mkutil/tavrasm.118/src/avrparse.y b/src/mkutil/tavrasm.118/src/avrparse.y new file mode 100644 index 00000000..613377e9 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/avrparse.y @@ -0,0 +1,543 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : avrparse.y +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : This module implements the grammar file for AVRASM +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +%{ + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "avrasm.hh" +#include "symbol.hh" +#include "semantic.hh" +#include "utils.hh" + +/// Extern /////////////////////////////////////////////////////////////////// + +GLOBALS(extern); +extern char *yytext; + +/// Prototypes /////////////////////////////////////////////////////////////// + +int yylex(); + +/// yyerror ////////////////////////////////////////////////////////////////// + +void yyerror(char *s) +{ + s = s; // Used for debugging purposes +} + +/// Start of grammar ///////////////////////////////////////////////////////// + +%} + +/// Attribute union ////////////////////////////////////////////////////////// + +%union +{ + regSA regid; + instSA inst; + opcodeSA opcode; + valueSA val; + nameSA name; + symbolSA symb; + indirectSA indi; + functionSA func; + stringSA string; +} + +/// Terminal symbols that synthesizes default value ////////////////////////// + +%token STAR DIV MOD +%token LS RS +%token LE GE LESS GREAT EQ NE +%token OR XOR AND +%token OROR ANDAND +%token LPAR RPAR +%token COLON COMMA DOT EQUAL PLUS MINUS WAVE NOT +%token EOL RESTART ENDOFFILE +%token DEF EQU DB DW ORG CSEG DSEG ESEG +%token BYTE SET DEVICE STRING MACRODEF + +/// Attributes for terminal symbols ////////////////////////////////////////// + +%token REGISTER +%token REGXYZ +%token SYMBOL +%token INTEGER +%token COUNTER +%token FUNCTION +%token IREGREG +%token IIMMIMM +%token IREGIMM +%token IIMMREG +%token IREG +%token IIMM +%token INOARGS +%token IINDIRC +%token ILPM +%token STRING + +/// Attributes for non-terminal symbols ////////////////////////////////////// + +%type instruction +%type lpminst +%type expr +%type indirectaddr +%type registername +%type unary_expr +%type primary_expr +%type mult_expr +%type additive_expr +%type shift_expr +%type relational_expr +%type equality_expr +%type AND_expression +%type exclusive_OR +%type inclusive_OR +%type logical_AND +%type logical_OR +%type composite_expr + +/// Expect 4 shift/reduce conflicts ////////////////////////////////////////// + +%expect 4 + +/// The goal symbol ////////////////////////////////////////////////////////// + +%start program + +%% // Start of grammar /////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // program : programlist RESTART programlist + // + // e : + // + //////////////////////////////////////////////////////////////////////////// + // + // We start by defining the goal symbol 'program'. There is only one + // production that can reduce the input to 'program': + // + // - 'programlist' RESTART 'programlist' + // + // with one 'programlist' for each pass. + // + // The symbol 'e' (or epsilon) is also defined. It should be considered + // a terminal symbol, and is only used to increase readability. + // + //////////////////////////////////////////////////////////////////////////// + +program : programlist RESTART programlist + ; + +e : + ; + + //////////////////////////////////////////////////////////////////////////// + // + // programlist := programlist programelement | programelement + // + //////////////////////////////////////////////////////////////////////////// + // + // 'programlist' is a left recursive list production, that parses one or + // more 'programelement's. + // + //////////////////////////////////////////////////////////////////////////// + +programlist : programlist programelement + | programelement + ; + + //////////////////////////////////////////////////////////////////////////// + // + // programelement := label instruction | label EOL | label directive | EOL + // + //////////////////////////////////////////////////////////////////////////// + // + // All instructions / defines are limited to a single line + // + //////////////////////////////////////////////////////////////////////////// + +programelement : label instruction { tolog(); } + | label EOL { tolog(); } + | label directive { tolog(); } + | EOL { tolog(); } + + /// Error recovery ////////////////////////////////////////// + + | error EOL { error(E_UNKNOWN_OPCODE); tolog(); } + ; + + //////////////////////////////////////////////////////////////////////////// + // + // instruction := IREGREG registername COMMA registername EOL + // | IREGIMM registername COMMA expr EOL + // | IIMMREG expr COMMA registername EOL + // | IIMMIMM expr COMMA expr EOL + // | IIMM expr EOL + // | IREG registername EOL + // | INOARGS EOL + // | IINDIRC registername COMMA indirectaddr EOL + // | IINDIRC indirectaddr COMMA registername EOL + // + //////////////////////////////////////////////////////////////////////////// + // + // There are nine different forms of 'instruction' : + // + // MOV r1, r1 ; Register / Register + // MOV r1, 0x10 ; Register / expr + // OUT 0x10, r1 ; expr / Register + // BRBS 6, bitfound ; expr / expr + // JMP 0x1000 ; expr + // CLR r29 ; Register + // CLI ; Noargs + // LD r2, -Y ; Indirect + // ST Y+, r2 ; Indirect + // + // Notice: LPM/ELPM are special, since they can be specified with or + // without arguments (arrgh). + // + //////////////////////////////////////////////////////////////////////////// + +instruction : IREGREG registername COMMA registername EOL + {genRegReg($1, $2, $4);} + | IREGIMM registername COMMA expr EOL + {genRegImm($1, $2, &$4);} + | IIMMREG expr COMMA registername EOL + {genImmReg($1, &$2, $4);} + | IIMMIMM expr COMMA expr EOL + {genImmImm($1, &$2, &$4);} + | IIMM expr EOL + {genImmedi($1, &$2);} + | IREG registername EOL + {genRegist($1, $2);} + | INOARGS EOL + {genNoargs($1);} + | IINDIRC registername COMMA indirectaddr EOL + {genIndirc($1, &$4, $2,TRUE);} + | IINDIRC indirectaddr COMMA registername EOL + {genIndirc($1, &$2, $4);} + + | lpminst + + /// Error recovery ////////////////////////////////////////// + + | IREGREG error EOL { error(E_REGISTER_EXPECTED); } + | IREGIMM error EOL { error(E_INVALID_REGIMM_SPEC); } + | IIMMREG error EOL { error(E_INVALID_REGIMM_SPEC); } + | IIMMIMM error EOL { error(E_INVALID_IMMEDIATE_SPEC); } + | IIMM error EOL { error(E_INVALID_IMMEDIATE_SPEC); } + | IREG error EOL { error(E_INVALID_REGISTER_SPEC); } + | INOARGS error EOL { error(E_NOARGS_EXPECTED_SPEC); } + | IINDIRC error EOL { error(E_INVALID_REGISTER_SPEC); } + ; + + //////////////////////////////////////////////////////////////////////////// + // + // lpminst := ILPM EOL | ILPM registername COMMA indirectaddr + // + //////////////////////////////////////////////////////////////////////////// + // + // Handles LPM and ELPM instructions + // + //////////////////////////////////////////////////////////////////////////// + +lpminst : ILPM EOL + { genLpm($1, 0, NULL, FALSE); } + | ILPM registername COMMA indirectaddr EOL + { genLpm($1, $2, &$4, TRUE); } + + /// Error recovery ////////////////////////////////////////// + + | ILPM error EOL { error(E_INVALID_REGISTER_SPEC); } + ; + + //////////////////////////////////////////////////////////////////////////// + // + // registername := REGISTER | SYMBOL + // + //////////////////////////////////////////////////////////////////////////// + // + // Handle registers: r0 - r31 + // + //////////////////////////////////////////////////////////////////////////// + +registername : REGISTER + | SYMBOL + { if($1->isdefine) + $$=$1->reg; + else + { + $$=-1; + errorin(E_INVALID_REGISTER_SPEC); + } + } + ; + + //////////////////////////////////////////////////////////////////////////// + // + // lable := SYMBOL COLON + // | e + // + //////////////////////////////////////////////////////////////////////////// + // + // SYMBOL COLON = Create new label + // + //////////////////////////////////////////////////////////////////////////// + +label : SYMBOL COLON { doLab($1); } + | e + ; + + //////////////////////////////////////////////////////////////////////////// + // + // directive := DEF SYMBOL EQUAL REGISTER EOL + // | DEF SYMBOL EQUAL SYMBOL EOL + // | EQU SYMBOL EQUAL expr EOL + // | DB {doAdb();} byteexprlist EOL + // | DW {doAdw();} wordexprlist EOL + // | ORG expr EOL + // | CSEG EOL + // | DSEG EOL + // | ESEG EOL + // | BYTE expr EOL + // | SET SYMBOL EQUAL expr EOL + // | MACRODEF + // | DEVICE SYMBOL EOL + // + //////////////////////////////////////////////////////////////////////////// + // + // 'directive' insert assembler directives + // + //////////////////////////////////////////////////////////////////////////// + +directive : DEF SYMBOL EQUAL REGISTER EOL {doDef($2,$4);} + | DEF SYMBOL EQUAL SYMBOL EOL {doDef($2,$4); } + | EQU SYMBOL EQUAL expr EOL {doEqu($2,&$4); } + | DB {doAdb();} byteexprlist EOL {/*XXX*/ } + | DW {doAdw();} wordexprlist EOL { } + | ORG expr EOL {doOrg(&$2); } + | CSEG EOL { } + | DSEG EOL { } + | ESEG EOL { } + | BYTE expr EOL {doByt(&$2); } + | SET SYMBOL EQUAL expr EOL {doSet($2,&$4); } + | MACRODEF { } + | DEVICE SYMBOL EOL {doDev($2); } + + /// Error recovery ////////////////////////////////////////// + + | DEF error EOL { error(E_EXPECTED_ID_REG); } + | EQU error EOL { error(E_EXPECTED_ID_EXPR); } + | DB error EOL { error(E_EXPECTED_VALLIST); } + | DW error EOL { error(E_EXPECTED_VALLIST); } + | ORG error EOL { error(E_EXPECTED_VAL_LABEL); } + | CSEG error EOL { error(E_EXPECTED_NOARGS); } + | DSEG error EOL { error(E_EXPECTED_NOARGS); } + | ESEG error EOL { error(E_EXPECTED_NOARGS); } + | BYTE error EOL { error(E_EXPECTED_VAL_LABEL); } + | SET error EOL { error(E_EXPECTED_ID_EXPR); } + | DEVICE error EOL { error(E_EXPECTED_DEVICE); } + ; + + //////////////////////////////////////////////////////////////////////////// + // + // indirectaddr := MINUS REGXYZ + // | REGXYZ + // | REGXYZ PLUS + // | REGXYZ PLUS expr + // + //////////////////////////////////////////////////////////////////////////// + // + // There are 4 different forms of indirect addressing: + // + // "-Z", "Z", "Z+" and "Z+offset" + // + //////////////////////////////////////////////////////////////////////////// + +indirectaddr : MINUS REGXYZ + {$$.regno=$2;$$.plus=2;$$.disp=0;} + | REGXYZ + {$$.regno=$1;$$.plus=0;$$.disp=0;} + | REGXYZ PLUS + {$$.regno=$1;$$.plus=1;$$.disp=0;} + | REGXYZ PLUS expr + { $$.regno = $1; + $$.plus=1;$$.disp=1;$$.offset=$3;} + ; + + //////////////////////////////////////////////////////////////////////////// + // + // byteexprlist := byteexprlist COMMA expr + // | expr + // + // wordexprlist := wordexprlist COMMA expr + // | expr + // + //////////////////////////////////////////////////////////////////////////// + // + // List of bytes and words for .db and .dw respectively + // + //////////////////////////////////////////////////////////////////////////// + +byteexprlist : byteexprlist COMMA byteelement + | byteelement + ; + +byteelement : STRING {doAdb($1); } + | expr {doAdb(&$1);} + ; + +wordexprlist : wordexprlist COMMA expr {doAdw(&$3);} + | expr {doAdw(&$1);} + ; + + //////////////////////////////////////////////////////////////////////////// + // + // expr := ... + // + //////////////////////////////////////////////////////////////////////////// + // + // Constant expressions with 'C' precedence + // + //////////////////////////////////////////////////////////////////////////// + +expr : composite_expr + ; + +primary_expr : INTEGER + | COUNTER + | SYMBOL + {$$.valid=$1->valid; + $$.value=$1->value + +$1->islabel*$1->macrolabel* + (yyoffset *($1->segment==SEGMENT_CODE)) + +$1->islabel*$1->macrolabel* + (yydataoffset*($1->segment==SEGMENT_DATA)) + +$1->islabel*$1->macrolabel* + (yyeromoffset*($1->segment==SEGMENT_EEPROM));} + | LPAR expr RPAR + { $$=$2; } + | FUNCTION LPAR expr RPAR + { genFun($1, &$3, &$$); } + ; + +unary_expr : MINUS unary_expr { oprUna(OP_MINUS, &$2, &$$); } + | WAVE unary_expr { oprUna(OP_WAVE , &$2, &$$); } + | NOT unary_expr { oprUna(OP_NOT , &$2, &$$); } + | primary_expr + ; + +mult_expr : unary_expr + | mult_expr STAR unary_expr + { oprBin(&$1,OP_STAR , &$3, &$$); } + | mult_expr DIV unary_expr + { oprBin(&$1,OP_DIV , &$3, &$$); } + | mult_expr MOD unary_expr + { oprBin(&$1,OP_MOD , &$3, &$$); } + ; + +additive_expr : mult_expr + | additive_expr PLUS mult_expr + { oprBin(&$1,OP_PLUS , &$3, &$$); } + | additive_expr MINUS mult_expr + { oprBin(&$1,OP_MINUS , &$3, &$$); } + ; + +shift_expr : additive_expr + | shift_expr LS additive_expr + { oprBin(&$1,OP_LS , &$3, &$$); } + | shift_expr RS additive_expr + { oprBin(&$1,OP_RS , &$3, &$$); } + ; + +relational_expr : shift_expr + | relational_expr LESS shift_expr + { oprBin(&$1,OP_LESS , &$3, &$$); } + | relational_expr GREAT shift_expr + { oprBin(&$1,OP_GREAT , &$3, &$$); } + | relational_expr LE shift_expr + { oprBin(&$1,OP_LE , &$3, &$$); } + | relational_expr GE shift_expr + { oprBin(&$1,OP_GE , &$3, &$$); } + ; + +equality_expr : relational_expr + | equality_expr EQ relational_expr + { oprBin(&$1,OP_EQ , &$3, &$$); } + | equality_expr NE relational_expr + { oprBin(&$1,OP_NE , &$3, &$$); } + ; + +AND_expression : equality_expr + | AND_expression AND equality_expr + { oprBin(&$1,OP_AND , &$3, &$$); } + ; + +exclusive_OR : AND_expression + | exclusive_OR XOR AND_expression + { oprBin(&$1,OP_XOR , &$3, &$$); } + ; + +inclusive_OR : exclusive_OR + | inclusive_OR OR exclusive_OR + { oprBin(&$1,OP_OR , &$3, &$$); } + ; + +logical_AND : inclusive_OR + | logical_AND ANDAND inclusive_OR + { oprBin(&$1,OP_ANDAND, &$3, &$$); } + ; + +logical_OR : logical_AND + | logical_OR OROR logical_AND + { oprBin(&$1,OP_OROR , &$3, &$$); } + ; + +composite_expr : logical_OR + ; + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/devices.hh b/src/mkutil/tavrasm.118/src/devices.hh new file mode 100644 index 00000000..1a9694dd --- /dev/null +++ b/src/mkutil/tavrasm.118/src/devices.hh @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : devices.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : AVR Controller descriptions +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 990721 : Tom - Added AT90S4433 +// 021218 : Andreas Schwarz added AT90S2333, ATmegaXX +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _DEVICES_HH_ +#define _DEVICES_HH_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include "avrasm.hh" + +/// Device descriptions ////////////////////////////////////////////////////// +// +// struct deviceinfo { +// char name[MAX_DEVICE_NAME_LENGTH+1]; // Device name +// int datastart; // Registers + I/O ports +// int ramsize; // Size of ram +// int eepromsize; // Size of EEPROM +// int flashsize; // Size of flash (in words) +// int supported; // Unsupported instructions +// }; +// + +deviceinfo devices[MAX_DEVICES] = { + + // ----------------------------------------------------------------------- + // Name |Reg| Ram | EEPROM |Flash Size | Unsupported instuctions | + // ----------------------------------------------------------------------- + // | | | | | | + { "GENERIC" , 96, 65536, 0x10000, 0x1000000 , 0 }, + { "AT90S1200" , 96, 0, 64, 512 , S_JMP |S_CALL |S_MUL | + S_ADIW |S_CALL |S_ICALL| + S_IJMP |S_LD |S_ST | + S_LDS |S_LPM |S_PUSH | + S_POP |S_SBIW |S_LDD | + S_STD |S_STS |S_EXTENDED }, + { "AT90S2313" , 96, 128, 128, 1024 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S2323" , 96, 128, 128, 1024 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S2343" , 96, 128, 128, 1024 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S4414" , 96, 256, 256, 2048 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S4433" , 96, 256, 256, 2048 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S4434" , 96, 256, 256, 2048 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S8515" , 96, 512, 512, 4096 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "AT90S8535" , 96, 512, 512, 4096 , S_JMP |S_CALL |S_MUL| S_EXTENDED }, + { "ATMega103" , 96, 4096, 4096, 65536 , S_MUL | S_EXTENDED }, + { "ATMega8" , 96, 1024, 512, 4096 , 0 }, + { "ATMega161" , 96, 1024, 512, 8192 , 0 }, + { "ATMega162" , 96, 1024, 512, 8192 , 0 }, + { "ATMega163" , 96, 1024, 512, 8192 , 0 }, + { "ATMega16" , 96, 1024, 512, 8192 , 0 }, + { "ATMega323" , 96, 2048, 1024, 16384 , 0 }, + { "ATMega32" , 96, 2048, 1024, 16384 , 0 }, + { "ATmega8515", 96, 512, 512, 4096 , 0 }, + { "ATmega8535", 96, 512, 512, 4096 , 0 }, + // | | | | | | + // ----------------------------------------------------------------------- + + // Test device + + { "" , 96, 2 , 5 , 10 , 0 }, + + // NULL - terminating device. + + { "" , 0 , 0, 0x000, 0x1000000 , 0 } + +}; + +#endif /* _DEVICES_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/mac.inc b/src/mkutil/tavrasm.118/src/mac.inc new file mode 100644 index 00000000..f2f9930a --- /dev/null +++ b/src/mkutil/tavrasm.118/src/mac.inc @@ -0,0 +1,195 @@ +; MAC.INC +; MACROS FOR THE AVR PROCESSOR + +.MACRO RJEQ + BRNE LOCAL + RJMP @0 +LOCAL: +.ENDMACRO + +.MACRO RJNE + BREQ LOCAL + RJMP @0 +LOCAL: +.ENDMACRO + +.MACRO OUTI @0,@1 + LDI A,@1 ; OUT IMMEDIATE TO PORT + OUT @0,A +.ENDMACRO + +.MACRO ADDI @0,@1 + SUBI @0,-@1 ; ADD IMMEDIATE +.ENDMACRO + +.MACRO EORI @0,@1 + LDI A,@1 ; EOR IMMEDIATE + EOR @0,A +.ENDMACRO + +.MACRO STI @0,@1 + LDI A,@1 ; STORE IMMEDIATE + ST @0,A +.ENDMACRO + +.MACRO ADDIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + ADD @0,A +.ENDMACRO + +.MACRO SUBIL @0,@1 + LDI A,@1 ; ADD IMMEDIATE LOWER REGISTER SET + SUB @0,A +.ENDMACRO + +.MACRO ANDIL @0,@1 + LDI A,@1 ; AND IMMEDIATE LOWER REGISTER SET + AND @0,A +.ENDMACRO + +.MACRO LDIL @0,@1 + LDI A,@1 ; LOAD IMMEDIATE LOWER REGISTER SET + MOV @0,A +.ENDMACRO + +.MACRO LDIX @0 ; LOAD IMMEDIATE XL, XH WITH FLASH ADDRESS + LDI XL,LOW((@0)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((@0)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION +.ENDMACRO + +.MACRO LDIZ @0 ; LOAD IMMEDIATE ZL, ZH WITH FLASH ADDRESS + LDI ZL,LOW((@0)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((@0)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION +.ENDMACRO + +.MACRO LDE @0,@1 ; LOAD REGISTER FROM EEPROM + RCALL LDE1 + LDI @0,LOW(@1*2) ; POINT TO EEPROM CONSTANT + OUT EEAR,@0 ; SET UP ADDRESS + SBI EECR,EERE ; ASSERT READ STROBE + IN @0,EEDR +.ENDMACRO + +.MACRO LDFL @0,@1 ; LOAD REGISTER FROM FLASH LOW BYTE + LDI ZL,LOW(@1*2) + LDI ZH,HIGH(@1*2) + LPM + MOV @0,R0 +.ENDMACRO + +.MACRO LDFH @0,@1 ; LOAD REGISTER FROM FLASH HIGH BYTE + LDI ZL,LOW(@1*2+1) + LDI ZH,HIGH(@1*2+1) + LPM + MOV @0,R0 +.ENDMACRO + +;.MACRO LDF @0,@1 ; LOAD REGISTER FROM FLASH +; LDI ZL,@1 ; POINT TO FLASH CONSTANT +; LPM +; MOV @0,R0 +;.ENDMACRO + +;------------------------------------------------------------------------------ + +.MACRO FLD @0 ; LOAD FA REGISTER FROM SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL LDS_FA +.ENDMACRO + +.MACRO FLDF @0 ; LOAD FA REGISTER FROM FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL LDF_FA +.ENDMACRO + +.MACRO FLDE @0 ; LOAD FA REGISTER FROM EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL LDE_FA +.ENDMACRO + +.MACRO FLD3 @0 ; LOAD FA REGISTER WITH 3 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS3_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FLD2 @0 ; LOAD FA REGISTER WITH 2 BYTE SRAM INTEGER + LDI YL,LOW(@0) ; POINT TO SOURCE + RCALL LDS2_FA ; CONVERT TO INTERNAL FP FORMAT +.ENDMACRO + +.MACRO FST @0 ; STORE FP REGISTER TO FP ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL STS_FA +.ENDMACRO + +.MACRO FCHS @0 ; CHANGE SIGN OF SRAM ARGUMENT + LDI YL,LOW(@0) + RCALL CHSS +.ENDMACRO + +.MACRO FAD @0 ; ADD SRAM ARGUMENT TO FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL ADD_FA +.ENDMACRO + +.MACRO FADF @0 ; ADD FLASH CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL ADDF_FA +.ENDMACRO + +.MACRO FADE @0 ; ADD EEPROM CONSTANT TO FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO EEPROM CONSTANT + RCALL ADDE_FA +.ENDMACRO + +.MACRO FSB @0 ; SUBTRACT SRAM ARGUMENT FROM FA REGISTER + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL SUB_FA +.ENDMACRO + +.MACRO FSBF @0 ; SUBTRACT FLASH CONSTANT FROM FA REGISTER + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL SUBF_FA +.ENDMACRO + +.MACRO FML @0 ; MULTIPLY FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL MUL_FA +.ENDMACRO + +.MACRO FMLF @0 ; MULTIPLY FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL MULF_FA +.ENDMACRO + +.MACRO FDV @0 ; DIVIDE FA REGISTER BY SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL DIV_FA +.ENDMACRO + +.MACRO FDVF @0 ; DIVIDE FA REGISTER BY FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL DIVF_FA +.ENDMACRO + +.MACRO FCP @0 ; COMPARE FA REGISTER WITH SRAM ARGUMENT + LDI YL,LOW(@0) ; POINT TO SRAM ARGUMENT + RCALL CP_FA +.ENDMACRO + +.MACRO FCPF @0 ; COMPARE FA REGISTER WITH FLASH CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + LDI ZH,HIGH(@0*2) + RCALL CPF_FA +.ENDMACRO + +.MACRO FCPE @0 ; COMPARE FA REGISTER WITH EEPROM CONSTANT + LDI ZL,LOW(@0*2) ; POINT TO FLASH CONSTANT + RCALL CPE_FA +.ENDMACRO + diff --git a/src/mkutil/tavrasm.118/src/makefile b/src/mkutil/tavrasm.118/src/makefile new file mode 100644 index 00000000..c61830cd --- /dev/null +++ b/src/mkutil/tavrasm.118/src/makefile @@ -0,0 +1,117 @@ +############################################################################# +# +# Title : TAVRASM Makefile +# +# Author : Tom Mortensen - (C) 1998 +# +# Create : 980902 +# +# Notice : Select compiler as appropriate (egcs or gcc) +# +# rm/mv : Versions of rm (remove/delete) and mv (move) that supports +# "Unix" style parameters must be available. +# +############################################################################# + +### Program name ############################################################ + +EXENAME = tavrasm + +### Language : US, DE ####################################################### + +LANGUAGE = US +VERSION = 117 + +### Compiler options ######################################################### + +CC = gcc +CFLAGS = -O2 -Wall -DAVRLANG=LANGUAGE_$(LANGUAGE) +CPPFLAGS = +CCFLAGS = $(CFLAGS) $(CPPFLAGS) +LINK = -lm -lstdc++ +OBJS = avrparse.o avrlex.o avrasm.o symbol.o semantic.o utils.o + +### Defaul CC files ######################################################### + +.cc.o: + $(CC) -c $(CCFLAGS) $< + +### Executable ############################################################## + +$(EXENAME): $(OBJS) + $(CC) $(CCFLAGS) $(OBJS) $(LINK) -o $@ + +### Parser file ############################################################# + +avrparse.cc: avrparse.y avrasm.hh symbol.hh semantic.hh opcodes.hh + bison -d -o avrparse avrparse.y + mv avrparse avrparse.cc + mv avrparse.h avrparse.hh + +### Scanner file ############################################################ + +avrlex.cc: avrparse.cc avrlex.l symbol.hh semantic.hh avrparse.hh \ + opcodes.hh avrasm.hh messages.hh + flex -o$@ avrlex.l + +### Dependencies ############################################################ + +avrlex.o: avrlex.l +avrparse.o: avrparse.y +avrasm.o: avrasm.cc avrasm.hh symbol.hh devices.hh messages.hh +symbol.o: symbol.cc symbol.hh avrasm.hh +utils.o: utils.cc utils.hh avrasm.hh messages.hh msg_us.hh msg_de.hh msg_sp.hh +semantic.o: semantic.cc semantic.hh symbol.hh opcodes.hh avrasm.hh \ + messages.hh + +### Clean ################################################################### + +clean: + rm -rf *.o + rm -rf *.O + rm -rf avrparse.cc + rm -rf avrparse.hh + rm -rf avrlex.cc + rm -rf core *~ + rm -rf *.output + rm -rf $(EXENAME) + rm -rf $(EXENAME).EXE + rm -rf *.obj + rm -rf *.out + +### Distribution ############################################################ + +dist: + rm -rf tavrasm$(VERSION) + mkdir tavrasm$(VERSION) + mkdir tavrasm$(VERSION)/src + cp *.cc tavrasm$(VERSION)/src/. + cp *.hh tavrasm$(VERSION)/src/. + cp *.l tavrasm$(VERSION)/src/. + cp *.y tavrasm$(VERSION)/src/. + cp makefile tavrasm$(VERSION)/src/. + cp gpl.txt tavrasm$(VERSION)/. + cp README tavrasm$(VERSION)/. + +dist2: clean dist $(EXENAME) + cp $(EXENAME) tavrasm$(VERSION)/. + tar cvfz tavrasm.tar.gz tavrasm$(VERSION) + +distribution: dist2 + rm -rf *.o + rm -rf avrparse.cc + rm -rf avrparse.hh + rm -rf avrlex.cc + rm -rf core *~ + rm -rf *.output + rm -rf $(EXENAME) + rm -rf $(EXENAME).EXE + rm -rf *.obj + rm -rf *.out + rm -rf tavrasm$(VERSION) + +### END OF FILE ############################################################# + + + + diff --git a/src/mkutil/tavrasm.118/src/messages.hh b/src/mkutil/tavrasm.118/src/messages.hh new file mode 100644 index 00000000..4d6f194f --- /dev/null +++ b/src/mkutil/tavrasm.118/src/messages.hh @@ -0,0 +1,258 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : messages.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : AVR Macro assembler messages +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 990127 : Tom - Messages moved to 'msg_us.hh', multi language added +// 000111 : Brian Rhodefer - added message for too many include paths +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _MESSAGES_HH_ +#define _MESSAGES_HH_ + +/// Defines ////////////////////////////////////////////////////////////////// + +#define MESSAGES_LEN 77 + +/// Warnings ///////////////////////////////////////////////////////////////// + +#define W_INVALID_CHAR 1 +#define W_INVALID_ASCII 2 +#define W_ARG_SPEC 3 +#define W_ARG_USED 4 +#define W_REGLABEL 5 +#define W_REGREDEF 6 +#define W_INTEGERRESULT_EXP2_IS_ZERO 7 +#define W_INTEGERRESULT_LOG2_IS_ZERO 8 +#define W_BIT_OUT_OF_RANGE 9 +#define W_PORT_OUT_OF_RANGE_1F 10 +#define W_PORT_OUT_OF_RANGE_3F 11 +#define W_BITMASK_OUT_OF_RANGE 12 +#define W_CONST_OUT_OF_RANGE_3F 13 +#define W_CONST_OUT_OF_RANGE_FF 14 +#define W_CONST_OUT_OF_RANGE_FFFF 15 +#define W_ADDR_OUT_OF_RANGE_FFFF 16 +#define W_DISPLACEMENT_OUT_OF_RANGE 17 +#define W_ILLEGAL_DEST_ADDR 18 +#define W_DB_OUT_OF_RANGE 19 +#define W_DW_OUT_OF_RANGE 20 +#define W_ORG_OUT_OF_RANGE 21 +#define W_ORG_OUT_OF_RANGE_ESEG 22 +#define W_ORG_OUT_OF_RANGE_DSEG 23 +#define W_ORG_OVER_REG 24 +#define W_SRAM_EXCEED 25 +#define W_MACRO_UNUSES_PARM 26 +#define W_LISTMACRO_NOT_SUP 27 +#define W_LIST_NOT_SUP 28 +#define W_NOLIST_NOT_SUP 29 +#define W_UNSUP 30 +#define W_UNKNOWN_DEV 31 +#define W_CONSTANT_TO_BIG 32 +#define W_IDENTIFIER_TOO_LONG 33 +#define W_EROM_EXCEED 34 +#define W_OCT_ESCAPE_INVALID 35 +#define W_HEX_ESCAPE_INVALID 36 +#define W_OCT_OUT_OF_RANGE 37 +#define W_CHAR_INVALID 38 +#define W_FLASH_EXCEEDED 39 +#define W_MAC_IDENTIFIER_TOO_LONG 40 +#define MESSAGE_WARNING_LAST 40 + +/// Errors /////////////////////////////////////////////////////////////////// + +#define E_UNKNOWN 1 +#define E_UNKNOWN_BIT 2 +#define E_UNKNOWN_PORT 3 +#define E_UNKNOWN_BRANCH 4 +#define E_UNKNOWN_BITMASK 5 +#define E_UNKNOWN_CONSTANT 6 +#define E_UNKNOWN_ADDRESS 7 +#define E_UNKNOWN_DISP 8 +#define E_UNKNOWN_RCALL_DEST 9 +#define E_UNKNOWN_RJUMP_DEST 10 +#define E_UNKNOWN_JUMP_CALL_DEST 11 +#define E_UNKNOWN_DB 12 +#define E_UNKNOWN_DW 13 +#define E_UNKNOWN_ORG 14 +#define E_UNKNOWN_BYTE 15 +#define E_DIVISION_BY_ZERO 16 +#define E_INVALID_REGISTER_R16_R31 17 +#define E_INVALID_REGISTER 18 +#define E_BRANCH_OUT_OF_RANGE_B 19 +#define E_BRANCH_OUT_OF_RANGE_F 20 +#define E_INVALID_REG_R24_R30 21 +#define E_INVALID_SOURCE_REG_XYZ 22 +#define E_INVALID_DEST_REG_XYZ 23 +#define E_RCALL_OUT_OF_RANGE_B 24 +#define E_RCALL_OUT_OF_RANGE_F 25 +#define E_RJUMP_OUT_OF_RANGE_B 26 +#define E_RJUMP_OUT_OF_RANGE_F 27 +#define E_EQU_REDEF 28 +#define E_LABEL_REDEF 29 +#define E_LABEL_VAR 30 +#define E_DW_IN_DSEG 31 +#define E_DB_IN_DSEG 32 +#define E_MACRO_REDEF 33 +#define E_PROGRAM_IN_DSEG 34 +#define E_PROGRAM_IN_ESEG 35 +#define E_INCLUDE_DEPTH 36 +#define E_INVALID_INCLUDE_NAME 37 +#define E_OPEN_FILE 38 +#define E_MACRO_DEPTH 39 +#define E_EOF_IN_MACRO 40 +#define E_FILENAME_TOO_LONG 41 +#define E_INVALID_FILENAME 42 +#define E_REGISTER_EXPECTED 43 +#define E_INVALID_REGISTER_SPEC 44 +#define E_INVALID_REGIMM_SPEC 45 +#define E_INVALID_IMMEDIATE_SPEC 46 +#define E_NOARGS_EXPECTED_SPEC 47 +#define E_UNKNOWN_OPCODE 48 +#define E_EXPECTED_ID_REG 49 +#define E_EXPECTED_VALLIST 50 +#define E_EXPECTED_NOARGS 51 +#define E_EXPECTED_VAL_LABEL 52 +#define E_EXPECTED_ID_EXPR 53 +#define E_EXPECTED_DEVICE 54 +#define E_VAR_IN_CSEG 55 +#define E_NO_MACRO_NAME 56 +#define E_UNDEF_ESCAPE 57 +#define E_NO_FILENAME 58 +#define E_DEF_USE 59 +#define E_UNDEF_ESCAPE_C 60 +#define E_ENDM 61 +#define E_MACRO_IN_MACRO 62 +#define E_REG_DISP 63 +#define E_DISP_REG 64 + +#define E_NO_DISP 65 +#define E_INVALID_REGISTER_R23_R31 66 +#define E_DISP_ILLEGAL 67 +#define E_INVALID_REG_Z_EXPECTED 68 +#define E_INVALID_PREINCREMENT 69 +#define E_INVALID_REG_EXPECTED 70 +#define E_INVALID_REG_EXPECTED_0_2_4 71 +#define MESSAGE_ERROR_LAST 71 + +#define X_OUT_OF_MEMORY 1 +#define X_LINE_TOO_LONG 2 +#define X_MACRO_LINE_TOO_LONG 3 +#define X_UNABLE_TO_OPEN_FILE 4 +#define X_UNABLE_TO_OPEN_LOGFILE 5 +#define X_UNABLE_TO_OPEN_OUTFILE 6 +#define X_UNABLE_TO_OPEN_ROMFILE 7 +#define X_TOO_MANY_FILES 8 +#define X_TOO_MUCH_CODE 9 +#define X_TOO_MUCH_DATA 10 +#define X_MACRO_DEPTH 11 +#define MESSAGE_FATAL_LAST 11 + +#define M_EMPTY_ROM_FILE 1 +#define M_NOT_SAVE_EROM_OBJ 2 +#define M_NO_INPUT_FILENAME 3 +#define M_UNKNOWN_OPTION 4 +#define M_MORE_MIJBH 5 +#define M_NO_ROM_FILENAME 6 +#define M_ROM_FILENAME_TOO_LONG 7 +#define M_ILLEGAL_ROM_FILENAME 8 +#define M_NO_LIST_FILENAME 9 +#define M_LIST_FILENAME_TOO_LONG 10 +#define M_ILLEGAL_LIST_FILENAME 11 +#define M_NO_OUTPUT_FILENAME 12 +#define M_OUTPUT_FILENAME_TOO_LONG 13 +#define M_ILLEGAL_OUTPUT_FILENAME 14 +#define M_MULTIPLE_OUTPUT 15 +#define M_INPUT_FILENAME_TOO_LONG 16 +#define M_ILLEGAL_INPUT_FILENAME 17 +#define M_MULTIPLE_INPUT 18 +#define M_ERRORS 19 +#define M_WARNINGS 20 +#define M_CODE 21 +#define M_ROM 22 +#define M_DATA 23 +#define M_UNUSED_CODE 24 +#define M_UNUSED_ROM 25 +#define M_EMPTY_CODE 26 +#define M_DEVICE_HEADER 27 +#define M_NO_INCLUDEPATH 28 +#define M_TOO_MANY_INCPATHS 29 +#define M_INCPATH_TOO_LONG 30 +#define MESSAGE_MESSAGES_LAST 30 + +/// Message count //////////////////////////////////////////////////////////// + +#define MESSAGES_WARNING MESSAGE_WARNING_LAST +#define MESSAGES_ERROR MESSAGE_ERROR_LAST +#define MESSAGES_FATAL MESSAGE_FATAL_LAST +#define MESSAGES_MESSAGES MESSAGE_MESSAGES_LAST + +#define MESSAGE_OFFSET_WARNING 0 +#define MESSAGE_OFFSET_ERROR MESSAGES_WARNING +#define MESSAGE_OFFSET_FATAL (MESSAGES_WARNING + MESSAGES_ERROR + 1) +#define MESSAGE_OFFSET_MESSAGES (MESSAGE_OFFSET_FATAL+MESSAGES_FATAL+1) + + +#define MESSAGE_COUNT (4+MESSAGES_WARNING+MESSAGES_ERROR+\ + MESSAGES_FATAL+MESSAGES_MESSAGES) + +/// Languages //////////////////////////////////////////////////////////////// + +#define LANGUAGE_US 1 // US English +#define LANGUAGE_DE 2 // German +#define LANGUAGE_SP 3 // Spanish + +/// Message strings ////////////////////////////////////////////////////////// + +#ifdef AVRLANG +#if AVRLANG == LANGUAGE_DE +#include "msg_de.hh" +#elif AVRLANG == LANGUAGE_US +#include "msg_us.hh" +#elif AVRLANG == LANGUAGE_SP +#include "msg_sp.hh" +#else +#error "Invalid language selected" +#endif /* AVRLANG */ +#else +#error "No language selected" +#endif + +#endif /* _MESSAGES_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/tavrasm.118/src/msg_de.hh b/src/mkutil/tavrasm.118/src/msg_de.hh new file mode 100644 index 00000000..658431d9 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/msg_de.hh @@ -0,0 +1,243 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : msg_de.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : German assembler messages +// +// History +// ======================================================================== +// +// 980127 : Tom - File created - Messages received from Uwe Bonnes. +// 991222 : Kurt- New command line option -x +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSG_DE_HH_ +#define _MSG_DE_HH_ + +// Command line info ///////////////////////////////////////////////////////// + +#define HELPSTR \ +"usage: tavrasm [-vwclxmihjgbafd] " \ +" [-I ]... [-o ] [-r ] [-e ]\n" \ +" -v verbose\n" \ +" -w no warnings\n" \ +" -c case sensitive labels/defines\n" \ +" -l limit log width to 80 characters\n" \ +" -x allow local labels\n" \ +" -m output Motorola S-record format\n" \ +" -i output Intel HEX format (default)\n" \ +" -h omit address extension record from Intel HEX files\n" \ +" -j output .obj format\n" \ +" -g output generic hex\n" \ +" -b output binary format\n" \ +" -a wrap relative jumps\n" \ +" -f allow forward org's\n" \ +" -d list supported devices\n" + +/// Message strings ////////////////////////////////////////////////////////// + +#ifdef _UTILS_CC_ + +char messages[MESSAGE_COUNT][MESSAGES_LEN]= +{ + "Keine Warnung", + "Ungültiger Character \'%c\' im Quelltext", + "Ungültiger Character 0x%02X im Quelltext", + "Argument @%i angegeben, aber nicht im Makro benutzt", + "Argument @%i nicht angegeben, aber im Makro benutzt", + "\'%s\' wurde schon in Zeile %i in Routine \'%s als Label definiert\'", + "\'%s\' wurde schon in Zeile %i in Routine \'%s definiert\'", + "Ganzzahlergebnis von EXP2(%i) wurde Null gesetzt", + "Ganzzahlergebnis von LOG2(%i) wurde Null gesetzt", + "Bit Nummer '\%i\' ist außerhalb des Bereichs (0-7)", + "I/O Port 0x%X ist außerhalb des Bereichs (0x00-0x1F)", + "I/O Port 0x%X ist außerhalb des Bereichs (0x00-0x3F)", + "Bit mask 0x%X ist außerhalb des Bereichs (0x00-0xFF)", + "Konstante 0x%X ist außerhalb des Bereichs (0x00-0x3F)", + "Konstante 0x%X ist außerhalb des Bereichs (0x00-0xFF)", + "Konstante 0x%X ist außerhalb des Bereichs (0x00-0xFFFF)", + "Adresse 0x%X ist außerhalb des Bereichs (0x0-0xFFFF)", + "Versatz \'%X\' ist außerhalb des Bereichs (0x00 - 0x3F)", + "ZielAdresse \'0x%X\' ist außerhalb des Bereichs (0x0-0x3FFFFF)", + "Wert %i ist außerhalb des Bereichs .db (-128 to 255)", + "Wert %i ist außerhalb des Bereichs .dw (-32768 to 65535)", + "Wert %i setzt PC (um %i Worte) im Kode zurück", + "Wert %i überschreibt EEPROM Daten (um %i Byte(s))", + "Wert %i überschreibt Daten (um %i Byte(s))", + "Wert %i überschreibt Register oder I/O Bereich (um %i Byte(s))", + "SRAM Größe um %i byte(s) überschritten", + "Unbenutzter Parameter @%i in Makro Definition", + "Directive '.listmac' nicht unterstützt (ignoriert)", + "Directive '.list' nicht unterstützt (ignoriert)", + "Directive '.nolist' nicht unterstützt (ignoriert)", + "\'%s\' für diesen Baustein nicht unterstützt", + "Unbekannter Baustein \'%s\'", + "Konstante zu groß", + "Bezeichner zu lang", + "EEPROM Größe um %i byte(s) überschritten", + "Illegaler oktaler Escapewert", + "Illegaler hex Escapewert", + "Oktaler Escapewert außerhalb des Bereichs", + "Illegale Character Konstante", + "Flash Speichergröße um %i word(s) überschritten", + "Macro name too long", + + /// Error messages ///////////////////////////////////////////////////////// + + "Kein Fehler" + "Undefinierte Variable referenziert", + "Undefinierte Variable referenziert in Bit Nummer", + "Undefinierte Variable referenziert in I/O Port Adresse", + "Undefinierte Variable referenziert in Sprung", + "Undefinierte Variable referenziert in Bitmaske", + "Undefinierte Variable referenziert in Konstante", + "Undefinierte Variable referenziert in Adresse", + "Undefinierte Variable referenziert in Versatz", + "Undefinierte Variable referenziert in relativen Aufruf", + "Undefinierte Variable referenziert in relativen Sprung", + "Undefinierte Variable referenziert in Sprung/Aufruf", + "Undefinierte Variable referenziert in Konstante in .db", + "Undefinierte Variable referenziert in Konstante in .dw", + "Undefinierte Variable referenziert in Offset", + "Undefinierte Variable referenziert in Konstante in .byte", + "Division durch Null", + "Ungültiges register (r16-r31)", + "Ungültiges register %s", + "Verzweigung (rückwärts) überschreitet Bereich um %i Worte", + "Verzweigung (vorwärts) überschreitet Bereich um %i Worte", + "Ungültiges Register (r24/r26/r28/r30)", + "Ungültiges Quellregister r%i (X/Y/Z)", + "Ungültiges Zielregister r%i (X/Y/Z)", + "Aufruf (rückwärts) überschreitet Bereich um %i Worte", + "Aufruf (vorwärts) überschreitet Bereich um %i Worte", + "Sprung (rückwärts) überschreitet Bereich um %i Worte", + "Sprung (vorwärts) überschreitet Bereich um %i Worte", + "Label \'%s\' bereits in Zeile %i in \'%s\' definiert", + "Label \'%s\' bereits in Zeile %i in \'%s\' definiert", + "Variable \'%s\' bereits in Zeile %i in \'%s\' als Label definiert", + ".dw in DSEG (nur in CSEG and ESEG zulässig)", + ".db in DSEG (nur in CSEG and ESEG zulässig)", + "Makro \'%s\' bereits definiert (oder Label doppelt verwendet)", + "Programkode in DSEG (nur in CSEG erlaubt)", + "Programkode in ESEG (nur in CSEG erlaubt)", + "Include \'%s\' kann nicht verarbeitet werden - zu viele Includedateien", /*FIXME*/ + "Ungültiger Name für Includedatei", + "Datei \'%s\' kann nicht geöffnet werden", + "Makro kann nicht aufgelöst werden - zu viele Makroebenen",/*FIXME*/ + "Dateiende in Makrodefinition erreicht", + "Dateiname zu lang in Zeile %i in \'%s\'", + "Ungültiger Dateiname", + "Register erwartet", + "Ungültiges Register verwendet", + "Ungültiges Register oder immediate",/*FIXME*/ + "Ungültige immediate Konstante",/*FIXME*/ + "Unerwartetes Argument", + "Unbekannter Opcode", + "ID = register erwartet", + "Wert (,Wert ,...) erwartet", + "Argumente dürfen nicht angegeben werden", + "Wert/Label erwartet", + "ID = Ausdruck erwartet", + "Bausteinname erwartet", + "Variablen Deklaration in CSEG", + "Macro ohne Name", + "Undefinierte Escapesequence %s", + "Kein Dateiname angegeben", + "Macro vor Definition benutzt", + "Undefinierte Escapesequence \'\\%c\'", + ".endmacro Directive nicht erwartet", + "Macro Definition innerhalb Makro nicht erlaubt", + "Register, Versatz erwartet", + "Versatz, Register erwartet", + "Für X kann kein Versatz angegeben werden ( nur für Y/Z)", + "Invalid register r%d (expected r23-r31)", + "Displacement can not be specified here", + "Invalid register specified, expected 'Z'", + "Pre-increment is invalid here (use 'Z' or 'Z+')", + "Invalid register r%d (expected r%d-r%d)", + "Invalid register r%d (expected r0, r2, ...)", + + /// Fatal errors /////////////////////////////////////////////////////////// + + "Kein fataler Fehler", + "Speicherbedarf zu groß", + "Zeile zu kang in \'%s\'", + "Makro mit zu langer Zeile in %i in \'%s\'", + "Eingabedatei kann nicht geöffnet werden \'%s\'", + "Listdatei kann nicht geöffnet werden \'%s\'", + "Ausgabedatei kann nicht geöffnet werden\'%s\'", + "ROM Datei kann nicht geöffnet werden \'%s\'", + "Zu viele Includedateinen", + "Kodegröße überschritten", + "EEPROM Größe überschritten", + "Makroschachtelung zu tief", + + /// Messages /////////////////////////////////////////////////////////////// + + "Keine Mitteilung", + "Leere ROM Datei", + "ROM Datei kann nicht im .obj Formay gespeichert werden", + "Keine Eingabedatei angegeben", + "Unbekannte Option '%s'", + "Mehr Optionen als m/i/j/b/h angegeben", + "Keine ROM Datei angegeben", + "Rom Dateiname zu lang", + "Ungültiger Name für ROM Datei", + "Keine Listdatei angegeben", + "Name für Listdatei zu lang", + "Ungültiger Name für Listdatei", + "Name für Ausgabedatei fehlt", + "Name für Ausgabedatei zu lang", + "Ungültiger Name für Ausgabedatei", + "Mehrere Namen für Ausgabedatei angegeben", + "Name für Eingabedatei zu lang", + "Ungültiger Name für Eingabedatei", + "Mehrere Namen für Eingabedatei angegeben", + "Fehler : %i", + "Warnungen : %i", + "Kode : %i", + "Rom : %i", + "Data : %i", + "Freier Kode : %i", + "Freies Rom : %i", + "Kein Kode erzeugt", + "| Bausteintype | Ram Start |Flash Größe |Ram Größe |EEPROM Größe |", + "No include path found after '-I' flag", + "Too many include paths specified", + "Include pathname too long" +}; + +#endif /* _UTILS_CC_ */ + +#endif /* _MSG_DE_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/msg_sp.hh b/src/mkutil/tavrasm.118/src/msg_sp.hh new file mode 100644 index 00000000..848df9a8 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/msg_sp.hh @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Archivo : msg_sp.hh +// +// Autor : Lluis Ballester - Copyright (C) 1999 +// +// Descripcion : Spanish assembler messages +// +// Historia +// ======================================================================== +// +// 980127 : Tom - Archivo creado - Mensajes trasladados desde 'message.hh'. +// 991222 : Kurt- New command line option -x +// +//////////////////////////////////////////////////////// Tom hizo esto /////// +// +// Nota Copyright : +// +// tavrasm - Un ensamblador GNU/Linux para las series Atmel AVR +// de microcontroladoras. Copyright (C) 1999 Tom Mortensen +// +// Este programa es software gratuito; puedes redistribuirlo y/o modificarlo +// bajo los terminos de la licencia publica general GNU +// como fue publicado por la Free Software Foindation (findacion de Software gratuito); desde la +// version 2 de la Licencia, o (a tu eleccion) cualquier version posterior. +// +// Este programa es distribuido con la esperanza de que sea totalmente funcional, +// pero SIN NINGuN TIPO DE GARANTiA; sin igualmente la garantia incluida de +// MERCHANTABILITY(mercantibilidad) o FITNESS (propiedad) PARA PROPOSITO +// PERSONAL.Ver la GNU General Public License( Licencia Publica General ) para mas detalles. +// +// Deberias haber recibido una copia de la GNU ( Licencia Publica General ) +// con este programa ; si no lo has recibido, escribe a la: Free Software +// Fundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + + +#ifndef _MSG_US_HH_ +#define _MSG_US_HH_ + +// info linea comandos /////////////////////////////////////////////////////// + +#define HELPSTR \ +"uso: tavrasm [-vwclxmihjgbafd] \n" \ +" [-I ]... [-o ] [-r ] [-e ]\n" \ +" -v verbose\n" \ +" -w no advertencias\n" \ +" -c etiquetas case sensitive /defenes\n" \ +" -l limite ancho log a 80 caracters\n" \ +" -x allow local labels\n" \ +" -m Formato de salida Motorola S-record \n" \ +" -i Formato de salida Intel HEX (default)\n" \ +" -h omit address extension record from Intel HEX files\n" \ +" -j Formato de salida .obj \n" \ +" -g Salida generica hex\n" \ +" -b Formato de salida binaria\n" \ +" -a wrap relativa jumps\n" \ +" -f allow forward org's\n" \ +" -d Lista de los dispositivos soportados\n" + +// Cadenas de mensajes ////////////////////////////////////////////////////// + +#ifdef _UTILS_CC_ + +char messages[MESSAGE_COUNT][MESSAGES_LEN]= +{ + "No advertencias", + "Caracter invalido \'%c\' en codigo", + "Caracter invalido 0x%02X en codigo", + "Argumento @%i especificados, pero no usado en macro", + "Argumento @%i no especificado, pero usado en macro", + "\'%s\' ya definida como etiqueta en linea %i en \'%s\'", + "\'%s\' ya definida en linea %i en \'%s\'", + "Resultado Integer de EXP2(%i) esta fijado a cero", + "Resultado Integer de LOG2(%i) esta fijado a cero", + "Numero bit '\%i\' fuera de rango (0-7)", + "I/O Pot 0x%X fuera de rango (0x00-0x1F)", + "I/O Pot 0x%X fuera de rango (0x00-0x3F)", + "Bit mask 0x%X fuera de rango (0x00-0xFF)", + "Constante 0x%X fuera de rango (0x00-0x3F)", + "Constante 0x%X fuera de rango (0x00-0xFF)", + "Constante 0x%X fuera de rango (0x00-0xFFFF)", + "Direccion 0x%X fuera de rango (0x0-0xFFFF)", + "Desplazamiento \'%X\' esta fuera de rango (0x00 - 0x3F)", + "Direccion de destino \'0x%X\' fuera de rango (0x0-0x3FFFFF)", + "Valor %i fuera de rango en .db (-128 to 255)", + "Valor %i fuera de rango en .dw (-32768 to 65535)", + "Valor %i mueve PC atras sobre codigo (by %i wods)", + "Valor %i sobreescribe informacion EEPROM (by %i byte(s))", + "Valor %i sobreescribe informacion (by %i byte(s))", + "Valor %i sobreescribe Registro o I/O area (by %i byte(s))", + "SRAM tamanyo excedido por %i byte(s)", + " Parametro no usado @%i en definicion de macro", + "La directiva '.listmac' no es soportada (ignorada)", + "La directiva '.list' no es soportada (ignorada)", + "La directiva '.nolist' is nosuppoted (ignorada)", + "\'%s\' no soportado por este dispositivo", + "Dispositivo desconocido \'%s\'", + "Constante demasiada grande", + "Identificador demasiado largo", + "Tamanyo EEPROM excedido por %i byte(s)", + "Valor de escape octal ilegal" + "Valor de escape hexadecimal ilegal", + "Valor Octal de escape fuera de rango", + " Caracter de constante ilegal", + "Tamanyo flash excedido por %i word(s)", + "Macro name too long", + + /// Mensajes de error ////////////////////////////////////////////////////// + + "No error" + "Variable referenciada indefinida " + "Variable referenciada indefinida en numero bit ", + "Variable referenciada indefinida en I/O puerto direccion", + "Variable referenciada indefinida en rama", + "Variable referenciada indefinida en bit mask", + "Variable referenciada indefinida en constante", + "Variable referenciada indefinida en direccion", + "Variable referenciada indefinida en desplazamiento", + "Variable referenciada indefinida en relative call", + "Variable referenciada indefinida en relative jump", + "Variable referenciada indefinida en jump/call", + "Variable referenciada indefinida en constante en .db", + "Variable referenciada indefinida en constante en .dw", + "Variable referenciada indefinida en offset", + "Variable referenciada indefinida en constante en .byte", + "Division por cero", + "Registro invalido (r16-r31)", + "Registro invalido %s", + "Rama fuera de rango por %i words (por detras)", + "Rama fuera de rango por %i words (por delante)", + "Registro invalido (r24/r26/r28/r30)", + "Registro de codigo invalido r%i (X/Y/Z)", + "Registro de destino invalido r%i (X/Y/Z)", + "Llamada(call) fuera de rango por %i words (por detras)", + "Llamada(call) fuera de rango por%i words (por delante)", + "Jump fuera de rango por %i words (por detras)", + "Jump fuera de rango por %i words (por delante)", + "Etiqueta \'%s\' ya definida en linea %i en \'%s\'", + "Etiqueta \'%s\' ya definida en linea %i en \'%s\'", + "Variable \'%s\' ya definida como etiqueta en linea %i en \'%s\'", + ".dw en DSEG (solo permitido en CSEG y ESEG)", + ".db en DSEG (solo permitido en CSEG y ESEG)", + "Macro \'%s\' ya definida (o etiqueta duplicada)", + "Codigo de programa en DSEG (solo permitido en CSEG)", + "Codigo de programa en ESEG (solo permitido en CSEG)", + "Imposible incluir archivo \'%s\' - incluir profundidad(depth) excedida", + "Nombre de archivo incluido invalido especificado", + "Imposible abrir archivo \'%s\'", + "Imposible expandir macro - profundidad contextual (context depth) excedida", + "Final de archivo alcanzado en definicion de macro", + "Nombre de archivo demasiado largo en linea %i en \'%s\'", + "Invalido nombre de archivo", + "Registro esperado", + "Registro invalido especificado", + "Registro invalido o inmediato", + "Constante inmediata invalida", + "No argumento esperado", + "Desconocido opcodigo", + "Esperado ID = registro", + "Esperado valor (,valor ,...) ", + "No argumentos deben ser especificados", + "Esperado valor/etiqueta", + "Esperado ID = expresion", + "Esperado nombre de dispositivo", + "Declaracion de variable en CSEG", + "Macro sin nombre", + "Secuencia de escape indefinida %s", + "No nombre de archivo especificado", + "Macro usada antes definida", + "Secuencia de escape indefinida \'\\%c\'", + "Inesperada directiva .finalmacro ", + "Definicion de macro dentro de macro no permitida", + "Registro esperado, desplazamiento", + "Desplazamiento esperado, registro", + "No desplazamiento pueden ser especificados para X (usar Y/Z)", + "Invalid register r%d (expected r23-r31)", + "Displacement can not be specified here", + "Invalid register specified, expected 'Z'", + "Pre-increment is invalid here (use 'Z' or 'Z+')", + "Invalid register r%d (expected r%d-r%d)", + "Invalid register r%d (expected r0, r2, ...)", + + /// Errores fatales //////////////////////////////////////////////////////// + + "No error fatal", + "Fuera de memoria", + "Linea demasiada larga en \'%s\'", + "Linea de macro demasiado larga en linea %i en \'%s\'", + "Imposible abrir archivo de entrada \'%s\'", + "Imposible abrir archivo list\'%s\'", + "Imposible abrir archivo de salida \'%s\'", + "Imposible abrir archivo rom\'%s\'", + "Demasiados archivos incluidos", + "Tamanyo de codigo excedido", + "Tamanyo EEPROM excedido", + "Profundidad maxima de macro excedida", + + /// Mensajes /////////////////////////////////////////////////////////////// + + "No mensaje", + "Archivo rom vacio", + "No se puede salvar archivo rom con formato .obj", + "No nombre de archivo de entrada especificado", + "Opcion desconocida '%s'", + "Mas de uno de m/i/j/b/h especificados", + "No nombre de archivo rom especificados", + "Nombre de archivo rom demasiado largo", + "Nombre de Archivo rom ilegal", + "No nombre de archivo rom especificado", + "Lista de nombre de archivos demasiada larga", + "Lista de nombres de archivos ilegal", + "No nombre de archivo de salida especificado", + "Nombre de archivo de salida demasiado largo", + "Nombre de archivo de salida ilegal", + "Multiples archivos de salida especificados", + "Nombre de entrada demasiado largo ", + "Nombre de entrada ilegal", + "Multitud de archivos de entrada especificados", + "Errores : %i", + "Advertencias : %i", + "Codigo : %i", + "Rom : %i", + "Informacion(data) : %i", + "Codigo sin usar : %i", + "Rom sin usar : %i", + "No codigo generado", + "| Dispositivo | Ram start | Flash | Ram | EEPROM |", + "No include path found after '-I' flag", + "Too many include paths specified", + "Include pathname too long" + +}; + +#endif /* _UTILS_CC_ */ + +#endif /* _MESSAGES_HH_ */ + +/// FINAL DE ARCHIVO ///////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/msg_us.hh b/src/mkutil/tavrasm.118/src/msg_us.hh new file mode 100644 index 00000000..3678da2b --- /dev/null +++ b/src/mkutil/tavrasm.118/src/msg_us.hh @@ -0,0 +1,243 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : msg_us.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : US assembler messages +// +// History +// ======================================================================== +// +// 980127 : Tom - File created - Messages moved from 'message.hh'. +// 991222 : Kurt- New command line option -x +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSG_US_HH_ +#define _MSG_US_HH_ + +// Command line info ///////////////////////////////////////////////////////// + +#define HELPSTR \ +"usage: tavrasm [-vwclxmihjgbafd] \n" \ +" [-I ]... [-o ] [-r ] [-e ]\n" \ +" -v verbose\n" \ +" -w no warnings\n" \ +" -c case sensitive labels/defines\n" \ +" -l limit log width to 80 characters\n" \ +" -x allow local labels\n" \ +" -m output Motorola S-record format\n" \ +" -i output Intel HEX format (default)\n" \ +" -h omit address extension record from Intel HEX files\n"\ +" -j output .obj format\n" \ +" -g output generic hex\n" \ +" -b output binary format\n" \ +" -a wrap relative jumps\n" \ +" -f allow forward org's\n" \ +" -d list supported devices\n" + +// Message strings /////////////////////////////////////////////////////////// + +#ifdef _UTILS_CC_ + +char messages[MESSAGE_COUNT][MESSAGES_LEN]= +{ + "No warning", + "Invalid character \'%c\' in source", + "Invalid character 0x%02X in source", + "Argument @%i specified, but not used in macro", + "Argument @%i not specified, but used in macro", + "\'%s\' already defined as label at line %i in \'%s\'", + "\'%s\' already defined at line %i in \'%s\'", + "Integer result of EXP2(%i) is set to zero", + "Integer result of LOG2(%i) is set to zero", + "Bit number '%i' out of range (0-7)", /* Nick */ + "I/O Port 0x%X out of range (0x00-0x1F)", + "I/O Port 0x%X out of range (0x00-0x3F)", + "Bit mask 0x%X out of range (0x00-0xFF)", + "Constant 0x%X out of range (0x00-0x3F)", + "Constant 0x%X out of range (0x00-0xFF)", + "Constant 0x%X out of range (0x00-0xFFFF)", + "Address 0x%X out of range (0x0-0xFFFF)", + "Displacement \'%X\' is out of range (0x00 - 0x3F)", + "Destination address \'0x%X\' out of range (0x0-0x3FFFFF)", + "Value %i out of range in .db (-128 to 255)", + "Value %i out of range in .dw (-32768 to 65535)", + "Value %i moves PC back over code (by %i words)", + "Value %i overwrites EEPROM data (by %i byte(s))", + "Value %i overwrites data (by %i byte(s))", + "Value %i overwrites Register or I/O area (by %i byte(s))", + "SRAM size exceeded by %i byte(s)", + "Unused parameter @%i in macro definition", + "The directive '.listmac' is not supported (ignored)", + "The directive '.list' is not supported (ignored)", + "The directive '.nolist' is not supported (ignored)", + "\'%s\' not supported on this device", + "Unknown device \'%s\'", + "Constant too big", + "Identifier too long", + "EEPROM size exceeded by %i byte(s)", + "Illegal octal escape value", + "Illegal hex escape value", + "Octal escape value out of range", + "Illegal character constant", + "Flash size exceeded by %i word(s)", + "Macro name too long", + + /// Error messages ///////////////////////////////////////////////////////// + + "No error" + "Undefined variable referenced", + "Undefined variable referenced in bit number", + "Undefined variable referenced in I/O port address", + "Undefined variable referenced in branch", + "Undefined variable referenced in bit mask", + "Undefined variable referenced in constant", + "Undefined variable referenced in address", + "Undefined variable referenced in displacement", + "Undefined variable referenced in relative call", + "Undefined variable referenced in relative jump", + "Undefined variable referenced in jump/call", + "Undefined variable referenced in constant in .db", + "Undefined variable referenced in constant in .dw", + "Undefined variable referenced in offset", + "Undefined variable referenced in constant in .byte", + "Division by zero", + "Invalid register (r16-r31)", + "Invalid register %s", + "Branch out of range by %i words (backwards)", + "Branch out of range by %i words (forward)", + "Invalid register (r24/r26/r28/r30)", + "Invalid source register r%i (X/Y/Z)", + "Invalid destination register r%i (X/Y/Z)", + "Call out of range by %i words (backwards)", + "Call out of range by %i words (forward)", + "Jump out of range by %i words (backwards)", + "Jump out of range by %i words (forward)", + "Label \'%s\' already defined at line %i in \'%s\'", + "Label \'%s\' already defined at line %i in \'%s\'", + "Variable \'%s\' already defined as label at line %i in \'%s\'", + ".dw in DSEG (only allowed in CSEG and ESEG)", + ".db in DSEG (only allowed in CSEG and ESEG)", + "Macro \'%s\' already defined (or duplicates label)", + "Program code in DSEG (only allowed in CSEG)", + "Program code in ESEG (only allowed in CSEG)", + "Unable to include file \'%s\' - include depth exceeded", + "Invalid include filename specified", + "Unable to open file \'%s\'", + "Unable to expand macro - context depth exceeded", + "End of file reached in macro definition", + "Filename too long at line %i in \'%s\'", + "Invalid filename", + "Register expected", + "Invalid register specified", + "Invalid register or immediate", + "Invalid immediate constant", + "No argument expected", + "Unknown opcode", + "Expected ID = register", + "Expected value (,value ,...) ", + "No arguments should be specified", + "Expected value/label", + "Expected ID = expression", + "Expected device name", + "Variable declaration in CSEG", + "Macro with no name", + "Undefined escape sequence %s", + "No filename specified", + "Macro used before it is defined", + "Undefined escape sequence \'\\%c\'", + "Unexpected .endmacro directive", + "Macro definition within macro not allowed", + "Expected register, displacement", + "Expected displacement, register", + "No displacement can be specified for X (use Y/Z)", + "Invalid register r%d (expected r23-r31)", + "Displacement can not be specified here", + "Invalid register specified, expected 'Z'", + "Pre-increment is invalid here (use 'Z' or 'Z+')", + "Invalid register r%d (expected r%d-r%d)", + "Invalid register r%d (expected r0, r2, ...)", + + /// Fatal errors /////////////////////////////////////////////////////////// + + "No fatal error", + "Out of memory", + "Line too long in \'%s\'", + "Macro line too long at line %i in \'%s\'", + "Unable to open input file \'%s\'", + "Unable to open list file \'%s\'", + "Unable to open output file \'%s\'", + "Unable to open rom file \'%s\'", + "Too many files included", + "Code size exceeded", + "EEPROM size exceeded", + "Max macro depth exceeded", + + /// Messages /////////////////////////////////////////////////////////////// + + "No message", + "Empty rom file", + "Can not save rom file with .obj format", + "No input filename specified", + "Unknown option '%s'", + "More than one of m/i/j/b/h specified", + "No rom filename specified", + "Rom filename too long", + "Illegal rom filename", + "No list filename specified", + "List filename too long", + "Illegal list filename", + "No output filename specified", + "Output filename too long", + "Illegal output filename", + "Multiple output files specified", + "Input filename too long", + "Illegal input filename", + "Multiple input files specified", + "Errors : %i", + "Warnings : %i", + "Code : %i", + "Rom : %i", + "Data : %i", + "Unused Code : %i", + "Unused Rom : %i", + "No code generated", + "| Device name | Ram start | Flash Size | Ram size | EEPROM Size |", + "No include path found after '-I' flag", + "Too many include paths specified", + "Include pathname too long" +}; + +#endif /* _UTILS_CC_ */ + +#endif /* _MESSAGES_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/n.bat b/src/mkutil/tavrasm.118/src/n.bat new file mode 100644 index 00000000..14eb1182 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/n.bat @@ -0,0 +1,6 @@ +del tavrasm.exe +cl -Zi -I. -DAVRLANG=LANGUAGE_US -otavrasm.exe -Tpavrasm.cc -Tpsemantic.cc -Tpsymbol.cc -Tputils.cc -Tpavrparse.cc -Tpavrlex.cc +del *.obj +del *.pdb +del *.ilk +copy tavrasm.exe ..\..\..\bin diff --git a/src/mkutil/tavrasm.118/src/opcodes.hh b/src/mkutil/tavrasm.118/src/opcodes.hh new file mode 100644 index 00000000..35235b04 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/opcodes.hh @@ -0,0 +1,227 @@ +///////////////////////////////////////////////////////////////////////////// +// +// File : opcodes.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : ATMEL AVR opcodes +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _OPCODES_HH_ +#define _OPCODES_HH_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include "avrasm.hh" + +////////////////////////////////////////////////////////////////////////////// +// +// Branch instructions - [1111 0#-- ---- -###] +// + +#define O_BRCC 0xF400 // i Branch if Carry Cleared +#define O_BRCS 0xF000 // i Branch if Carry Set +#define O_BRNE 0xF401 // i Branch if Not Equal +#define O_BREQ 0xF001 // i Branch if Equal +#define O_BRPL 0xF402 // i Branch if Plus +#define O_BRMI 0xF002 // i Branch if Minus +#define O_BRVC 0xF403 // i Branch if Overflow Cleared +#define O_BRVS 0xF003 // i Branch if Overflow Set +#define O_BRGE 0xF404 // i Branch if Greater or Equal (Signed) +#define O_BRLT 0xF004 // i Branch if Less Than (Signed) +#define O_BRHC 0xF405 // i Branch if Half Carry Flag is Cleared +#define O_BRHS 0xF005 // i Branch if Half Carry Flag is Set +#define O_BRTC 0xF406 // i Branch if the T Flag is Cleared +#define O_BRTS 0xF006 // i Branch if the T Flag is Set +#define O_BRID 0xF407 // i Branch if Global Interrupt is Disabled +#define O_BRIE 0xF007 // i Branch if Global Interrupt is Enabled +#define O_BRSH (8+0xF400) // i Branch if Same or Higher (Unsigned)(BRCC) +#define O_BRLO (8+0xF000) // i Branch if Lower (BRCS) + +////////////////////////////////////////////////////////////////////////////// +// +// Noarg instructions - [1001 0100 #### 0100] +// + +#define O_SEC 0x9408 // Set Carry Flag +#define O_SEZ 0x9418 // Set Zero Flag +#define O_SEN 0x9428 // Set Negative Flag +#define O_SEV 0x9438 // Set Overflow Flag +#define O_SES 0x9448 // Set Signed Flag +#define O_SEH 0x9458 // Set Half Carry Flag +#define O_SET 0x9468 // Set T Flag +#define O_SEI 0x9478 // Set Global Interrupt Flag + +#define O_CLC 0x9488 // Clear Carry Flag +#define O_CLZ 0x9498 // Clear Zero Flag +#define O_CLN 0x94A8 // Clear Negative Flag +#define O_CLV 0x94B8 // Clear Overflow Flag +#define O_CLS 0x94C8 // Clear Signed Flag +#define O_CLH 0x94D8 // Clear Half Carry Flag +#define O_CLT 0x94E8 // Clear T Flag +#define O_CLI 0x94F8 // Clear Global Interrupt Flag + +#define O_NOP 0x0000 // No Operation +#define O_ICALL 0x9509 // Indirect Call to Subroutine +#define O_IJMP 0x9409 // Indirect Jump + +#define O_RETI 0x9518 // Return from Interrupt +#define O_RET 0x9508 // Return from Subroutine +#define O_SLEEP 0x9588 // Sleep +#define O_WDR 0x95A8 // Wathcdog Reset + +#define O_EIJMP 0x9419 // Extended indirect jump (1) +#define O_EICALL 0x9519 // Extended indirect call to subroutine (1) +#define O_ESPM 0x95F8 // Extended store program memory (1) +#define O_SPM 0x95E8 // Store program memory (1) + +////////////////////////////////////////////////////////////////////////////// +// +// Reg/Reg instructions - [#-## ##-- ---- ----] +// + +#define O_CPC 0x0400 // rr Compare with Carry +#define O_CP 0x1400 // rr Compare +#define O_SBC 0x0800 // rr Subtract with Carry +#define O_SUB 0x1800 // rr Subtract without Carry +#define O_ADD 0x0C00 // rr Add without Carry +#define O_ADC 0x1C00 // rr Add with Carry +#define O_CPSE 0x1000 // rr Compares Skip if Equal +#define O_AND 0x2000 // rr Logical AND +#define O_EOR 0x2400 // rr Exclusive OR +#define O_OR 0x2800 // rr Logical OR +#define O_MOV 0x2C00 // rr Copy Register +#define O_MUL 0x9C00 // rr Multiply +#define O_MOVW 0x0100 // rr Copy register word (1) +#define O_MULS 0x0200 // rr Multiply Signed (1) +#define O_MULSU 0x0300 // rr Multiply Signed with Unsiged (1) +#define O_FMUL 0x0308 // rr Fractional Multiply (1) +#define O_FMULS 0x0380 // rr Fractional Multiply Signed (1) +#define O_FMULSU 0x0388 // rr Fractional Multiply Signed with Unsiged (1) + +////////////////////////////////////////////////////////////////////////////// +// +// Reg/Imm instructions - [#-## ##-- ---- ----] +// + + // Reg/Imm word + +#define O_ADIW 0x9600 // rw Add Immediate to Word +#define O_SBIW 0x9700 // rw Subtract Immediate to Word + + // Reg/imm - [#### ---- ---- ----] + +#define O_CPI 0x3000 // ri Compare with Immediate +#define O_SBCI 0x4000 // ri Subtract Immediate with Carry +#define O_SUBI 0x5000 // ri Subtract Immediate +#define O_ORI 0x6000 // ri Logical OR with Immediate +#define O_ANDI 0x7000 // ri Logical AND with Immediate +#define O_LDI 0xE000 // ri Load Immediate +#define O_SBR (1+0x6000) // ri Set Bits in register (Same as ORI) + +////////////////////////////////////////////////////////////////////////////// +// +// Register instructions - [---- ---- ---- ----] +// + +#define O_COM 0x9400 // r One's Complement +#define O_NEG 0x9401 // r Two's Complement +#define O_SWAP 0x9402 // r Swap Nibbles +#define O_INC 0x9403 // r Increment +#define O_ASR 0x9405 // r Arithmetic Shift Right +#define O_LSR 0x9406 // r Logical Shift Right +#define O_ROR 0x9407 // r Rotate Right Trough Carry +#define O_DEC 0x940A // r Decrement +#define O_POP 0x900F // r Pop Register from Stack +#define O_PUSH 0x920F // r Push Register on Stack +#define O_CLR (1+0x2400) // r Clear Regiser (Same as EOR Rd, Rd) +#define O_TST 0x2000 // r Test for Zero or Minus + +////////////////////////////////////////////////////////////////////////////// +// +// immediate instructions - [---- ---- ---- ----] +// + +#define O_BCLR 0x9488 // i Bit Clear in SREG +#define O_BSET 0x9408 // i Bit Set in SREG +#define O_RCALL 0xD000 // i Relative Call To Subroutine +#define O_RJMP 0xC000 // i Relative Jump +#define O_BRBC 0xF400 // ii Branch if Bit in SREG is Cleared +#define O_BRBS 0xF000 // ii Branch if Bit in SREG is Set +#define O_CBI 0x9800 // ii Clear Bit in I/O Register +#define O_SBI 0x9A00 // ii Set Bit in I/O Register +#define O_SBIC 0x9900 // ii Skip if Bit in I/O Register is Cleared +#define O_SBIS 0x9B00 // ii Skip if Bit in I/O Register is Set +#define O_OUT 0xB800 // ir Store Register to I/O Port +#define O_BLD 0xF800 // ri Bit Load from T in Sreg to bit in Register +#define O_BST 0xFA00 // ri Bit store from Bit in Register to T in SREG +#define O_CBR (1+0x7000) // ri Clear Bits in Register (Same as ANDI) +#define O_IN 0xB000 // ri Load an I/O Port to register +#define O_SBRC 0xFC00 // ri Skip if Bit in Register is Cleared +#define O_SBRS 0xFE00 // ri Skip if Bit in Register is Set +#define O_ROL (1+0x1C00) // r Rotate Left trough Carry (Same as ADC Rd,Rd) +#define O_SER 0xEF0F // r Set all bits in Register +#define O_LSL (1+0x0C00) // r Logical Shift Left (Same as ADD Rd,Rd) +#define O_JMP 0x940C // i Jump +#define O_CALL 0x940E // i Long Call to a Subroutine +#define O_LDS 0x9000 // rl Load direct from SRAM +#define O_STS 0x9200 // lr Store direct to SRAM + +#define O_LD 0x8000 // rX Load indirect from SRAM using index X/Y/Z +#define O_ST 0x8200 // Xr Store Indirect to SRAM using index X/Y/Z +#define O_LDD (8+0x8000) // rD Load indirect from SRAM using displacement +#define O_STD (8+0x8200) // Dr Store Indirect to SRAM using displacement + +#define O_STD (8+0x8200) // Dr Store Indirect to SRAM using displacement + +////////////////////////////////////////////////////////////////////////////// +// +// (E)LPM instructions - [---- ---- ---- ----] +// + +#define O_LPM 0x95C8 // Load Program Memory +#define O_ELPM 0x95D8 // __ Extended load program memory (1) + + + + + + + +#endif /* _OPCODES_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/tavrasm.118/src/semantic.cc b/src/mkutil/tavrasm.118/src/semantic.cc new file mode 100644 index 00000000..9e8dc3fe --- /dev/null +++ b/src/mkutil/tavrasm.118/src/semantic.cc @@ -0,0 +1,1659 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : semantic.cc +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Implements code generation functions +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 990516 : Tom - Added support for wrapping in branch/rcall/rjmp +// 990721 : Tom - Fixed SBR (bit 0 was always set) +// 991209 : Tom - Fixed problem with BRBC/BRBS (they did not work :( +// 991211 : Tom - Added the new instructions: 'eijmp', 'eicall', 'espm', +// 'mulsu', 'fmul', 'fmuls', 'fmulsu', 'muls', 'movw', +// 'elpm'. And changed behaviour of 'lpm' according to +// Atmel specs. +// 991217 : Kurt- Valid range for W_CONST_OUT_OF_RANGE_FF expanded to +// -255...255. TODO: Change the error messages. +// 991217 : Kurt- Support of local labels. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "avrasm.hh" +#include "semantic.hh" +#include "symbol.hh" +#include "utils.hh" + +/// Externals //////////////////////////////////////////////////////////////// + +GLOBALS(extern); + +/// Functions //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Handle '.device' directive + // + +void doDev(symbolSA devicename) +{ + int devfound = -1; + + for(int devno=0; (devfound==-1) && yydevices[devno].name[0]; devno++) + { + // this is just a stricmp/strcasecmp + + int c; + + for(c=0; devicename->name[c] && + (tolower(yydevices[devno].name[c]) == + tolower(devicename->name[c])); c++); + + if(!yydevices[devno].name[c] && !devicename->name[c]) + devfound = devno; + } + + if(devfound == -1) + warning(W_UNKNOWN_DEV, devicename -> name); + else + yydeviceno = devfound; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle directive '.byte' + // + +void doByt(valueSA *value) +{ + if(! (value->valid)) + error(E_UNKNOWN_BYTE); + else if(yysegment == SEGMENT_CODE) + error(E_VAR_IN_CSEG); + else if(yysegment == SEGMENT_DATA) + { + yydefinestart = yydatapos; + yydatapos+=value->value; + } + else if(yysegment == SEGMENT_EEPROM) + { + yydefinestart = yyerompos; + yydefinetype = SEGMENT_DEFINE_BYTE; + + for(int c=0;cvalue;c++) + insertdata(0); + + if(yyerompos > DEVINF.eepromsize) + warning(W_EROM_EXCEED,yyerompos-DEVINF.eepromsize); + } + else + internalerror("BY %04X", yysegment); + +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle directive '.org' + // + +void doOrg(valueSA *value) +{ + if( !value->valid ) + { + error(E_UNKNOWN_ORG); + return; + } + + if(yysegment == SEGMENT_CODE) + { + if(!yycfg->forwardorg && (value->value < (yycodepos+1)/2)) + warning(W_ORG_OUT_OF_RANGE,value->value,(yycodepos+1)/2-value->value); + if(yycodeposhigh < yycodepos) + yycodeposhigh = yycodepos; + yycodepos = 2*value->value; + } + else if(yysegment == SEGMENT_EEPROM) + { + if(!yycfg->forwardorg && (value->value < yyerompos)) + warning(W_ORG_OUT_OF_RANGE_ESEG,value->value, yyerompos - value->value); + if(yyeromposhighvalue; + } + else if(yysegment == SEGMENT_DATA) + { + if(value->value < DEVINF.datastart) + warning(W_ORG_OVER_REG,value->value,DEVINF.datastart-value->value); + else if(!yycfg->forwardorg && (value->value < yydatapos)) + warning(W_ORG_OUT_OF_RANGE_DSEG,value->value, yydatapos - value->value); + if(yydataposhigh < yydatapos) + yydataposhigh = yydatapos; + yydatapos = value->value; + } + else + internalerror("US %08X", yysegment); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Initialize '.db' directive + // + +void doAdb(void) +{ + if(yysegment == SEGMENT_CODE) + yydefinestart = yycodepos; + else if(yysegment == SEGMENT_EEPROM) + yydefinestart = yyerompos; + else + errorin(E_DB_IN_DSEG); + + yyeol = FALSE; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add '.db' arguments + // + +void doAdb(valueSA *value) +{ + if( value->valid) + { + if( yyeol && ((value->value < -128) || (value->value > 255)) ) + warning(W_DB_OUT_OF_RANGE, value->value); + else if( (value->value < -128) || (value->value > 255) ) + warningin(W_DB_OUT_OF_RANGE, value->value); + if(yysegment == SEGMENT_CODE) + insertdbdw(value->value & 0xFF); + else if(yysegment == SEGMENT_EEPROM) + insertdata(value->value & 0xFF); + } + else if(yyparseno && !(value->valid) ) + error(E_UNKNOWN_DB); + else + { + if(yysegment == SEGMENT_CODE) + insertdbdw(0); + else if(yysegment == SEGMENT_EEPROM) + insertdata(value->value); + } +} + +void doAdb(stringSA str) +{ + int c; + int val; + + str++; + + for(c=0;c<(int)strlen(str)-1; c++) + { + if(str[c]=='\\') + { + switch (str[c+1]) + { + case 'n' : val = '\n'; break; + case 't' : val = '\t'; break; + case 'v' : val = '\v'; break; + case 'b' : val = '\b'; break; + case 'r' : val = '\r'; break; + case 'f' : val = '\f'; break; + case 'a' : val = '\a'; break; + case '\\' : val = '\\'; break; + case '\'' : val = '\''; break; + case '\"' : val = '\"'; break; + case '\?' : val = '\?'; break; + case 'X' : + case 'x' : + { + val = 0; + + if( isxdigit(str[c+2] ) ) + { + if(isdigit(str[c+2])) + val = str[c+2] - '0'; + else + val = tolower(str[c+2]) - 'a' + 10; + c++; + + if( isxdigit(str[c+2] ) ) + { + if(isdigit(str[c+2])) + val = val*16 + str[c+2] - '0'; + else + val = val*16 + tolower(str[c+2]) - 'a' + 10; + c++; + } + } + } break; + + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + { + val = str[c+1] - '0'; + if( (str[c+2]>='0') && (str[c+2]<='7')) + { + val = val * 8 + str[++c+1] - '0'; + if( (str[c+2]>='0') && (str[c+2]<='7')) + val = val * 8 + str[++c+1] - '0'; + } + + if(val > 0xFF) + { + val = 0; + warningin(W_OCT_OUT_OF_RANGE); + } + } break; + + default : val = 0 ; errorin(E_UNDEF_ESCAPE_C,str[c+1]); + } + c++; + } + else + val = str[c]; + + if(yysegment == SEGMENT_CODE) + insertdbdw(val); + else if(yysegment == SEGMENT_EEPROM) + insertdata(val); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Initialize '.dw' directive + // + +void doAdw(void) +{ + if(yysegment == SEGMENT_CODE) + yydefinestart = yycodepos; + else if(yysegment == SEGMENT_EEPROM) + yydefinestart = yyerompos; + else + errorin(E_DW_IN_DSEG); + + yyeol = FALSE; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add '.dw' arguments + // + +void doAdw(valueSA *value) +{ + if( value-> valid ) + { + if(yyeol && ((value->value < -32768) || (value->value > 65535) ) ) + warning(W_DW_OUT_OF_RANGE, value->value); + else if( (value->value < -32768) || (value->value > 65535) ) + warningin(W_DW_OUT_OF_RANGE, value->value); + + if(yysegment == SEGMENT_CODE) + { +#ifdef _MSC_VER /* Nick */ + insertdbdw( (value->value & 0x000000FF) >> 0); + insertdbdw( (value->value & 0x0000FF00) >> 8); +#else + insertdbdw( (value->value & 0x000000FFL) >> 0); + insertdbdw( (value->value & 0x0000FF00L) >> 8); +#endif + } + else if(yysegment == SEGMENT_EEPROM) + { +#ifdef _MSC_VER /* Nick */ + insertdata( (value->value & 0x000000FF) >> 0); + insertdata( (value->value & 0x0000FF00) >> 8); +#else + insertdata( (value->value & 0x000000FFL) >> 0); + insertdata( (value->value & 0x0000FF00L) >> 8); +#endif + } + } + else if(yyparseno) + error(E_UNKNOWN_DW); + else + { + if(yysegment == SEGMENT_CODE) + { + insertdbdw(0); + insertdbdw(0); + } + else if(yysegment == SEGMENT_EEPROM) + { + insertdata(0); + insertdata(0); + } + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle directive '.equ' + // + +void doEqu(symbolSA symb, valueSA *value) +{ + if( symb->valid && (symb->valdefline != yyline-1) ) + error(E_EQU_REDEF, symb->name, symb->valdefline,symb->valfilename); + else + { + symb -> valid = value -> valid; + symb -> value = value -> value; + symb -> valdefline = yyline - 1; + symb -> segment = yysegment; + strcpy(symb->valfilename, yyfilename); + if( !value -> valid ) + error(E_UNKNOWN); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle directive '.set' + // + +void doSet(symbolSA symb, valueSA *value) +{ + if( (symb->valid) && (!symb->isvar)) + error(E_LABEL_VAR, symb->name, symb->valdefline, symb->valfilename); + else + { + symb -> isvar = TRUE; + symb -> valid = value -> valid; + symb -> value = value -> value; + symb -> valdefline = yyline; + symb -> segment = yysegment; + strcpy(symb->valfilename, yyfilename); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Defines like ".def REG0 = r0" + // + +void doDef(symbolSA symb, regSA reg) +{ + if( symb->isdefine ) + { + if( (symb->reg != reg) && yyparseno ) + { + warning(W_REGREDEF ,symb->name,symb->regdefline,symb->regfilename); + symb -> regdefline = yyline - 1; + symb -> reg = reg; + strcpy(symb->regfilename, yyfilename); + } + if(symb->valid) + warning(W_REGLABEL ,symb->name,symb->valdefline,symb->valfilename); + } + else + { + symb -> isdefine = TRUE; + symb -> regdefline = yyline - 1; + symb -> reg = reg; + strcpy(symb->regfilename, yyfilename); + if(symb->valid) + warning(W_REGLABEL ,symb->name,symb->valdefline,symb->valfilename); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Defines like ".def REG0 = IR0" - Notice: Not supported by ATMEL Assembler + // + +void doDef(symbolSA symbl, symbolSA symbr) +{ + if(!yyparseno) + return; + + if( symbr->isdefine ) + { + if( symbl->isdefine && (symbl->reg != symbr->reg) ) + warning(W_REGREDEF,symbl->name,symbl->regdefline,symbl->regfilename); + symbl -> isdefine = TRUE; + symbl -> regdefline = yyline - 1; + symbl -> reg = symbr -> reg; + strcpy(symbl->regfilename, yyfilename); + } + else + error(E_INVALID_REGISTER, symbr->name); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add label + // + +void doLab(symbolSA symb) +{ + if(yyinmacro) + { + // Check if it is a redef + + if(symb->valid && ( + ((yyoffset ==symb->offset)&&(symb->segment==SEGMENT_CODE )) || + ((yyeromoffset==symb->offset)&&(symb->segment==SEGMENT_EEPROM)) || + ((yydataoffset==symb->offset)&&(symb->segment==SEGMENT_DATA )) ) ) + { + if( (yysegment == SEGMENT_CODE) + && (symb -> value != yycodepos/2 - yyoffset) ) + errorin(E_LABEL_REDEF,symb->name,symb->valdefline,symb->valfilename); + else if( (yysegment == SEGMENT_EEPROM) + && (symb -> value != yyerompos - yyeromoffset) ) + errorin(E_LABEL_REDEF,symb->name,symb->valdefline,symb->valfilename); + else if( (yysegment == SEGMENT_DATA) + && (symb -> value != yydatapos - yydataoffset) ) + errorin(E_LABEL_REDEF,symb->name,symb->valdefline,symb->valfilename); + } + + // No it is not, so we set value if this is first occurence of macro + + else if( !symb->valid ) + { + symb -> valid = TRUE; + symb -> valdefline = yyline; + symb -> segment = yysegment; + symb -> islabel = 1; + symb -> macrolabel = 1; + + strcpy(symb->valfilename, yyfilename); + + if(yysegment == SEGMENT_CODE) + { + symb -> value = yycodepos/2 - yyoffset; + symb -> offset = yyoffset; + } + else if(yysegment == SEGMENT_EEPROM) + { + symb -> value = yyerompos - yyeromoffset; + symb -> offset = yyeromoffset; + } + else + { + symb -> value = yydatapos - yydataoffset; + symb -> offset = yydataoffset; + } + } + } + else + { + if(symb->valid && ((symb->valdefline !=yyline) + || strcmp(symb->valfilename, yyfilename))) + errorin(E_LABEL_REDEF,symb->name,symb->valdefline,symb->valfilename); + else + { + symb -> valid = TRUE; + symb -> valdefline = yyline; + symb -> segment = yysegment; + symb -> islabel = 1; + + strcpy(symb->valfilename, yyfilename); + + if(yysegment == SEGMENT_CODE) + { + symb -> value = yycodepos/2 - yyoffset; + symb -> offset = yyoffset; + } + else if(yysegment == SEGMENT_EEPROM) + { + symb -> value = yyerompos - yyeromoffset; + symb -> offset = yyeromoffset; + } + else + { + symb -> value = yydatapos - yydataoffset; + symb -> offset = yydataoffset; + } + + if (symb->name[0] != '@') + { + strcpy(yylast_used_label, symb->name); + } + } + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Register / Register opcodes + // + +void genRegReg(int opcode, regSA dest, regSA src) +{ +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + + checkSupported(opcode); + + CHECKREG(src ,0); + CHECKREG(dest ,0); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_MULSU : // Multiply Signed with Unsiged + case O_FMUL : // Fractional Multiply + case O_FMULS : // Fractional Multiply Signed + case O_FMULSU : // Fractional Multiply Signed with Unsiged + { + CHECKREG(src, 16); + CHECKREG(dest, 16); + + if( (src<16) || (src>23) ) + error(E_INVALID_REG_EXPECTED, src, 16,23); + if( (dest<16) || (dest>23) ) + error(E_INVALID_REG_EXPECTED, dest, 16,23); + + inst |= (((src-16) & 0x0007) << 0) | (((dest-16) & 0x0007) << 4); + + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_MOVW : // Copy register word + { + CHECKREG(src, 0); + CHECKREG(dest, 0); + + if( src & 1 ) + error(E_INVALID_REG_EXPECTED_0_2_4, src); + if( dest & 1 ) + error(E_INVALID_REG_EXPECTED_0_2_4, dest); + + inst |= (((src>>1) & 0x000F) << 0) | (((dest>>1) & 0x000F) << 4); + + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_MULS : // Multiply Signed + { + CHECKREG(src, 16); + CHECKREG(dest, 16); + + if( (src<16) || (src>31) ) + error(E_INVALID_REG_EXPECTED, dest, 16,31); + if( (dest<16) || (dest>31) ) + error(E_INVALID_REG_EXPECTED, dest, 16,31); + + inst |= (((src-16) & 0x000F) << 0) | (((dest-16) & 0x000F) << 4); + + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_CPC : // Compare with Carry + case O_CP : // Compare + case O_SBC : // Subtract with Carry + case O_SUB : // Subtract without Carry + case O_ADD : // without Carry + case O_ADC : // with Carry + case O_CPSE : // Compares Skip if Equal + case O_AND : // Logical AND + case O_EOR : // Exclusive OR + case O_OR : // Logical OR + case O_MOV : // Copy Register + case O_MUL : // Multiply + { + inst |= (src & 0x0010) << 5; + inst |= (src & 0x000F) << 0; + inst |= (dest & 0x0010) << 4; + inst |= (dest & 0x000F) << 4; + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("RR %04X",opcode); + } + insertInst(inst, 2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Immediate opcodes + // + +void genImmedi(int opcode, valueSA *value) +{ + int size = 2; +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + int tmp; + + checkSupported(opcode); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_BRCC : // Branch if Carry Cleared + case O_BRCS : // Branch if Carry Set + case O_BRNE : // Branch if Not Equal + case O_BREQ : // Branch if Equal + case O_BRPL : // Branch if Plus + case O_BRMI : // Branch if Minus + case O_BRVC : // Branch if Overflow Cleared + case O_BRVS : // Branch if Overflow Set + case O_BRGE : // Branch if Greater or Equal (Signed) + case O_BRLT : // Branch if Less Than (Signed) + case O_BRHC : // Branch if Half C Flag is Cleared + case O_BRHS : // Branch if Half C Flag is Set + case O_BRTC : // Branch if the T Flag is Cleared + case O_BRTS : // Branch if the T Flag is Set + case O_BRID : // Branch if Global Int is Disabled + case O_BRIE : // Branch if Global Int is Enabled + case O_BRSH : // Branch if Same or Higher (BRCC) + case O_BRLO : // Branch if Lower (BRCS) + { + inst = opcode & 0xFC07; + if(value->valid) + { + tmp = value -> value - yycodepos/2 - 1; + + if(tmp < -64 ) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + // We might reach it by jumping forward + + int dist = DEVINF.flashsize - ( yycodepos/2 + 1) + value->value; + + if( (dist>63) || (dist<0) ) + error(E_BRANCH_OUT_OF_RANGE_B,-1*(tmp+64)); + else + inst |= ((dist & 0x7F ) << 3); + } + + // No wrapping + + else + error(E_BRANCH_OUT_OF_RANGE_B,-1*(tmp+64)); + } + else if(tmp > 63) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + int dist = -1*(DEVINF.flashsize - value->value + yycodepos/2 + 1); + + if( (dist < -64) || (dist >= 0) ) + error(E_BRANCH_OUT_OF_RANGE_F,tmp-63); + else + inst |= ((dist & 0x7F ) << 3); + } + + // No wrapping + + else + error(E_BRANCH_OUT_OF_RANGE_F,tmp-63); + } + else + inst |= ( tmp & 0x7F ) << 3; + } + else + error(E_UNKNOWN_BRANCH); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_BCLR : // Bit Clear in SREG + case O_BSET : // Bit Set in SREG + { + if( value->valid ) + { + if( (value->value < 0) || (value->value > 7) ) + warning(W_BIT_OUT_OF_RANGE, value->value); + inst |= (value->value & 7) << 4; + } + else + error(E_UNKNOWN_BIT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_RCALL: // Relative Call To Subroutine + { + if(value->valid) + { + tmp = value -> value - yycodepos/2 -1; + if(tmp < -2048 ) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + // We might reach it by jumping forward + + int dist = DEVINF.flashsize - ( yycodepos/2 + 1) + value->value; + + if( (dist>2047) || (dist<0) ) + error(E_RCALL_OUT_OF_RANGE_B, -1*(tmp+2048)); + else + inst |= (dist & 0xFFF); + } + + // No wrapping + + else + error(E_RCALL_OUT_OF_RANGE_B, -1*(tmp+2048)); + } + else if(tmp > 2047) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + int dist = -1*(DEVINF.flashsize - value->value + yycodepos/2 + 1); + + if( (dist < -2048) || (dist >= 0) ) + error(E_RCALL_OUT_OF_RANGE_F, tmp-2047); + else + inst |= (dist & 0xFFF); + } + + // No wrapping + + else + error(E_RCALL_OUT_OF_RANGE_F, tmp-2047); + } + + else + inst |= tmp & 0xFFF ; + } + else + error(E_UNKNOWN_RCALL_DEST); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_RJMP : // Relative Jump + { + if(value->valid) + { + tmp = value -> value - yycodepos/2 -1; + if(tmp < -2048 ) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + // We might reach it by jumping forward + + int dist = DEVINF.flashsize - ( yycodepos/2 + 1) + value->value; + + if( (dist>2047) || (dist<0) ) + error(E_RJUMP_OUT_OF_RANGE_B, -1*(tmp+2048)); + else + inst |= (dist & 0xFFF); + } + + // No wrapping + + else + error(E_RJUMP_OUT_OF_RANGE_B, -1*(tmp+2048)); + } + else if(tmp > 2047) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + int dist = -1*(DEVINF.flashsize - value->value + yycodepos/2 + 1); + + if( (dist < -2048) || (dist >= 0) ) + error(E_RJUMP_OUT_OF_RANGE_F, tmp-2047); + else + inst |= (dist & 0xFFF); + } + + // No wrapping + + else + error(E_RJUMP_OUT_OF_RANGE_F, tmp-2047); + } + else + inst |= tmp & 0xFFF ; + + } + else + error(E_UNKNOWN_RJUMP_DEST); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_JMP : // Jump + case O_CALL : // Long Call to a Subroutine + { + size = 4; + if(value->valid) + { + if( (value -> value <0) || (value -> value > 0x3FFFFF) ) + warning(W_ILLEGAL_DEST_ADDR, value->value); + + inst |= ( (value -> value & 0x3FFFFF) >> 16) & 0x0001; + inst |= (( (value -> value & 0x3F0000) >> 16) & 0x003E) << 3; + inst |= ( (value -> value & 0x00FFFF) << 16); + } + else + error(E_UNKNOWN_JUMP_CALL_DEST); + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("IM %04X",opcode); + } + insertInst(inst, size); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Load / Store opcods - Notice : 'ld' = 'ldd' and 'ld' = 'ldd' + // + +void genIndirc(int opcode, indirectSA *indi, regSA reg, int right) +{ +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + int store = 0x0000; + + checkSupported(opcode); + + CHECKREG(reg, 0); + CHECKREG(indi->regno, 28); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_ST : // Store Indirect SRAM index X/Y/Z + case O_STD : // Store Indirect SRAM displacement + { + store = 0x0200; + } + case O_LD : // Load indirect SRAM index X/Y/Z + case O_LDD : // Load indirect SRAM displacement + { + if( ((opcode==O_LD) || (opcode==O_LDD)) && !right ) + error(E_REG_DISP); + if( indi->disp && (indi->regno==26) ) + error(E_NO_DISP); + else if( ((opcode==O_ST) || (opcode==O_STD)) && right ) + error(E_DISP_REG); + else + { + if( indi -> regno == 26 ) + inst = 0x900C | (reg << 4) | indi->plus; + else if( (indi -> regno == 28) || (indi -> regno == 30 ) ) + { + if(indi -> disp) + { + inst = 0x8000 | (reg<<4) | (8*(indi -> regno == 28)); + if(indi->offset.valid) + { + if( (indi->offset.value<0) || (indi->offset.value>63) ) + warning(W_DISPLACEMENT_OUT_OF_RANGE, indi->offset.value); + inst |= (indi->offset.value & 0x20) << 8; + inst |= (indi->offset.value & 0x18) << 7; + inst |= (indi->offset.value & 0x07) << 0; + } + else + error(E_UNKNOWN_DISP); + } + else + { + inst = 0x8000|(reg<<4)|indi->plus|(0x1000*(indi->plus!=0)); + inst |= 8*(indi -> regno == 28) ; + } + } + else + { + if(store) + error(E_INVALID_SOURCE_REG_XYZ, indi->regno); + else + error(E_INVALID_DEST_REG_XYZ, indi->regno); + } + inst |= store; + } + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("LS %04X", opcode); + + } + insertInst(inst, 2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Immediate / Register opcodes + // + +void genImmReg(int opcode, valueSA *value, regSA reg) +{ + int size = 2; +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + + checkSupported(opcode); + + CHECKREG(reg, 0); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_OUT : // Store Register to I/O Port + { + inst |= reg << 4; + + if(value->valid) + { + if( (value->value<0) || (value->value>63) ) + warning(W_PORT_OUT_OF_RANGE_3F, value->value); + inst |= (value->value & 0x30) << 5; + inst |= value->value & 0x0F; + } + else + error(E_UNKNOWN_PORT); + + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_STS : // Store direct to SRAM + { + size = 4; + inst |= reg << 4; + + if(value->valid) + { + if( (value->value<0) || (value->value>0xFFFF) ) + warning(W_ADDR_OUT_OF_RANGE_FFFF, value->value); + inst |= (value -> value & 0xFFFF) << 16; + } + else + error(E_UNKNOWN_ADDRESS); + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("IR %04X",opcode); + } + insertInst(inst, size); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Register / Immediate opcodes + // + +void genRegImm(int opcode, regSA reg, valueSA *value) +{ + int size = 2; +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + + checkSupported(opcode); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_SBRC : // Skip if Bit in Register is Cleared + case O_SBRS : // Skip if Bit in Register is Set + { + CHECKREG(reg, 0); + + inst |= reg << 4; + + if(value->valid) + { + if( (value->value < 0) || (value->value > 7) ) + warning(W_BIT_OUT_OF_RANGE, value->value); + inst |= value->value & 7; + } + else + error(E_UNKNOWN_BIT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_IN : // Load an I/O Port to register + { + CHECKREG(reg, 0); + + inst |= reg << 4; + + if(value->valid) + { + if( (value->value < 0) || (value->value > 0x3F) ) + warning(W_PORT_OUT_OF_RANGE_3F, value->value); + inst |= (value->value & 0x30) << 5; + inst |= (value->value & 0x0F); + } + else + error(E_UNKNOWN_PORT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_CBR : // Clear Bits in Reg. (Same as 'andi') + { + CHECKREG(reg, 16); + + inst = 0x7000; + + if( (reg<16) || (reg>31) ) + error(E_INVALID_REGISTER_R16_R31); + else + { + inst |= (reg-16) << 4; + + if(value->valid) + { + if( (value->value < 0) || (value->value > 0xFF) ) + warning(W_BITMASK_OUT_OF_RANGE, value->value); + inst |= ((0xFF - (value->value & 0xFF)) & 0xF0) << 4; + inst |= ((0xFF - (value->value & 0xFF)) & 0x0F); + } + else + error(E_UNKNOWN_BITMASK); + } + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_BLD : // Bit Load from T to Register bit + case O_BST : // Bit store from Register to T + { + CHECKREG(reg, 0); + + inst |= reg << 4; + + if(value->valid) + { + if( (value->value < 0) || (value->value > 7) ) + warning(W_BIT_OUT_OF_RANGE, value->value); + inst |= value->value & 7; + } + else + error(E_UNKNOWN_BIT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_ADIW : // Add Immediate to Word + case O_SBIW : // Subtract Immediate from Word + { + CHECKREG(reg, 24); + + if( (reg!=24) && (reg!=26) && (reg!=28) && (reg!=30) ) + error(E_INVALID_REG_R24_R30); + else + { + inst |= (reg-24) << 3; + + if(value->valid) + { + if( (value->value < 0) || (value->value >= 0x40) ) + warning(W_CONST_OUT_OF_RANGE_3F, value->value); + inst |= (value->value & 0x30) << 2; + inst |= (value->value & 0x0F); + } + else + error(E_UNKNOWN_CONSTANT); + } + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_SBR : // Set Bits in register (Same as ORI) + { inst = O_ORI; } + case O_CPI : // Compare with Immediate + case O_SBCI : // Subtract Immediate with Carry + case O_SUBI : // Subtract Immediate + case O_ORI : // Logical OR with Immediate + case O_ANDI : // Logical AND with Immediate + case O_LDI : // Load Immediate + { + CHECKREG(reg, 16); + + if( (reg<16) || (reg>31) ) + error(E_INVALID_REGISTER_R16_R31); + else + { + inst |= (reg-16) << 4; + + if(value->valid) + { + if( (value->value < -0xFF) || (value->value > 0xFF) ) + warning(W_CONST_OUT_OF_RANGE_FF, value->value); + inst |= (value->value & 0xF0) << 4; + inst |= (value->value & 0x0F); + } + else + error(E_UNKNOWN_CONSTANT); + } + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_LDS : // Load direct from SRAM + { + CHECKREG(reg, 0); + + size = 4; + inst |= reg << 4; + if(value->valid) + { + if( (value->value < 0) || (value->value > 0xFFFF) ) + warning(W_CONST_OUT_OF_RANGE_FFFF, value->value); + inst |= ((value -> value)&0xFFFF) << 16; + } + else + error(E_UNKNOWN_CONSTANT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("RI %04X",opcode); + } + insertInst(inst, size); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Immediate / Immediate opcodes + // + +void genImmImm(int opcode, valueSA *valued, valueSA *values) +{ +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + int tmp; + + checkSupported(opcode); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_BRBC : // Branch if Bit in SREG is Cleared + case O_BRBS : // Branch if Bit in SREG is Set + { + + if( valued->valid ) + { + if( (valued->value < 0) || (valued->value > 7) ) + warning(W_BIT_OUT_OF_RANGE ,valued->value); + inst |= valued->value & 7; + } + else + error(E_UNKNOWN_BIT); + + if(values->valid) + { + + tmp = values -> value - yycodepos/2 - 1; + + if(tmp < -64 ) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + // We might reach it by jumping forward + + int dist = DEVINF.flashsize - ( yycodepos/2 + 1) + values->value; + + if( (dist>63) || (dist<0) ) + error(E_BRANCH_OUT_OF_RANGE_B,-1*(tmp+64)); + else + inst |= ((dist & 0x7F ) << 3); + } + + // No wrapping + + else + error(E_BRANCH_OUT_OF_RANGE_B,-1*(tmp+64)); + } + else if(tmp > 63) { + + // Maybe we can do a wrap + + if(yycfg->wrap) { + + int dist = -1*(DEVINF.flashsize - values->value + yycodepos/2 + 1); + + if( (dist < -64) || (dist >= 0) ) + error(E_BRANCH_OUT_OF_RANGE_F,tmp-63); + else + inst |= ((dist & 0x7F ) << 3); + } + + // No wrapping + + else + error(E_BRANCH_OUT_OF_RANGE_F,tmp-63); + } + else + inst |= ( tmp & 0x7F ) << 3; + + } + else + error(E_UNKNOWN_BRANCH); + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_CBI : // Clear Bit in I/O Register + case O_SBI : // Set Bit in I/O Register + case O_SBIC : // Skip if Bit in I/O is Cleared + case O_SBIS : // Skip if Bit in I/O is Set + { + if( valued->valid ) + { + if( (valued->value < 0) || (valued->value > 31) ) + warning(W_PORT_OUT_OF_RANGE_1F, valued->value); + inst |= ((valued->value)&0x1F) << 3; + } + else + error(E_UNKNOWN_PORT); + + if( values->valid ) + { + if( (values->value < 0) || (values->value > 7) ) + warning(W_BIT_OUT_OF_RANGE,values->value); + inst |= values->value & 7; + } + else + error(E_UNKNOWN_BIT); + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("II %04X",opcode); + } + insertInst(inst, 2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate no argument opcodes + // + +void genNoargs(int opcode) +{ +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + + checkSupported(opcode); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_SEC : // Set Carry Flag + case O_SEZ : // Set Zero Flag + case O_SEN : // Set Negative Flag + case O_SEV : // Set Overflow Flag + case O_SES : // Set Signed Flag + case O_SEH : // Set Half Carry Flag + case O_SET : // Set T Flag + case O_SEI : // Set Global Interrupt Flag + case O_CLC : // Clear Carry Flag + case O_CLZ : // Clear Zero Flag + case O_CLN : // Clear Negative Flag + case O_CLV : // Clear Overflow Flag + case O_CLS : // Clear Signed Flag + case O_CLH : // Clear Half Carry Flag + case O_CLT : // Clear T Flag + case O_CLI : // Clear Global Interrupt Flag + case O_NOP : // No Operation + case O_ICALL : // Indirect Call to Subroutine + case O_IJMP : // Indirect Jump + case O_RETI : // Return from Interrupt + case O_RET : // Return from Subroutine + case O_SLEEP : // Sleep + case O_WDR : // Wathcdog Reset + case O_EIJMP : // Extended indirect jump + case O_EICALL : // Extended indirect call to subroutine + case O_ESPM : // Extended store program memory + case O_SPM : // Store program memory + { + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("NA %04X",opcode); + } + insertInst(inst, 2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Generate Register only opcodes + // + +void genRegist(int opcode, regSA reg) +{ +#ifdef _MSC_VER /* Nick */ + int inst = opcode; +#else + long inst = (unsigned)opcode; +#endif + + checkSupported(opcode); + + switch ((unsigned int)opcode) /* Nick cast */ + { + ////////////////////////////////////////////////////////////////////////// + + case O_ROR : // Rotate Right Trough Carry + case O_COM : // One's Complement + case O_NEG : // Two's Complement + case O_SWAP : // Swap Nibbles + case O_INC : // Increment + case O_ASR : // Arithmetic Shift Right + case O_LSR : // Logical Shift Right + case O_DEC : // Decrement + case O_POP : // Pop Register from Stack + case O_PUSH : // Push Register on Stack + { + CHECKREG(reg, 0); + inst |= reg << 4; + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_TST : // Test for Zero or Minus + case O_CLR : // Logical Shift Left (ADD Rd,Rd) + { + CHECKREG(reg, 0); + inst = opcode & 0x2400; + inst |= (reg & 0x10) << 5; + inst |= (reg & 0x0F) << 0; + inst |= (reg & 0x10) << 4; + inst |= (reg & 0x0F) << 4; + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_ROL : // Rotate Left trough C (ADC Rd,Rd) + case O_LSL : // Logical Shift Left (ADD Rd,Rd) + { + CHECKREG(reg, 0); + inst = opcode & 0x1C00; + inst |= (reg & 0x10) << 5; + inst |= (reg & 0x0F) << 0; + inst |= (reg & 0x10) << 4; + inst |= (reg & 0x0F) << 4; + } break; + + ////////////////////////////////////////////////////////////////////////// + + case O_SER : // Set all bits in Register + { + CHECKREG(reg, 16); + if( (reg<16) || (reg>31) ) + error(E_INVALID_REGISTER_R16_R31); + else + inst |= reg << 4; + + } break; + + ////////////////////////////////////////////////////////////////////////// + + default : internalerror("RO %04X",opcode); + } + insertInst(inst, 2); +} + + + //////////////////////////////////////////////////////////////////////////// + // + // Generate 'Load Program Memory' instructions + // + +void genLpm(int opcode, regSA reg, indirectSA *indi, int useregs) +{ + int inst = opcode; + + // Generate: (E)LPM rX, Z(+) + + if(useregs) { + + // Check that no displacement is specified + + if(indi->disp) + error(E_DISP_ILLEGAL); + + // Check that Z is specified + + CHECKREG(indi->regno, 30); + + if(indi->regno != 30) + error(E_INVALID_REG_Z_EXPECTED); + + // Check that pre-increment is not used + + if( indi->plus == 2) + error(E_INVALID_PREINCREMENT); + + if(opcode==O_LPM) + inst = 0x9004 + (indi->plus==1 ? 1 : 0) + ((reg&0x1f)<<4); + else + inst = 0x9006 + (indi->plus==1 ? 1 : 0) + ((reg&0x1f)<<4); + } + + insertInst(inst, 2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle functions + // + +void genFun(functionSA func, valueSA *value, valueSA *res) +{ + if( !value->valid ) + { + res -> valid = FALSE; + res -> value = 0; + } + else + { + res -> valid = TRUE; + res -> value = 0; + switch(func) + { +#ifdef _MSC_VER /* Nick */ + case OP_LOW : res->value = (value->value & 0x000000FF)>> 0; break; + case OP_HIGH : res->value = (value->value & 0x0000FF00)>> 8; break; + case OP_BYTE2 : res->value = (value->value & 0x0000FF00)>> 8; break; + case OP_BYTE3 : res->value = (value->value & 0x00FF0000)>>16; break; + case OP_BYTE4 : res->value = (value->value & 0xFF000000)>>24; break; + case OP_LWRD : res->value = (value->value & 0x0000FFFF)>> 0; break; + case OP_HWRD : res->value = (value->value & 0xFFFF0000)>>16; break; + case OP_PAGE : res->value = (value->value & 0x003F0000)>>16; break; +#else + case OP_LOW : res->value = (value->value & 0x000000FFL)>> 0; break; + case OP_HIGH : res->value = (value->value & 0x0000FF00L)>> 8; break; + case OP_BYTE2 : res->value = (value->value & 0x0000FF00L)>> 8; break; + case OP_BYTE3 : res->value = (value->value & 0x00FF0000L)>>16; break; + case OP_BYTE4 : res->value = (value->value & 0xFF000000L)>>24; break; + case OP_LWRD : res->value = (value->value & 0x0000FFFFL)>> 0; break; + case OP_HWRD : res->value = (value->value & 0xFFFF0000L)>>16; break; + case OP_PAGE : res->value = (value->value & 0x003F0000L)>>16; break; +#endif + case OP_LOG2 : + { + if( value->value < 0 ) + warningin(W_INTEGERRESULT_LOG2_IS_ZERO, value->value); + else + res->value = (int) (0.5+log10(value->value)/log10(2)); + } break; + case OP_EXP2 : + { + if( (value->value > 31) || (value->value < 0) ) + warningin(W_INTEGERRESULT_EXP2_IS_ZERO, value->value); + else + res->value = 1<< value->value; + } break; + default : internalerror("FU %08X",func); + } + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle unary operators + // + +void oprUna(int opr, valueSA *value, valueSA *res) +{ + if( !value->valid ) + { + res -> valid = FALSE; + res -> value = 0; + } + else + { + res -> valid = TRUE; + res -> value = 0; + switch(opr) + { + case OP_MINUS : ; res->value = -1*value->value; break; + case OP_WAVE : ; res->value = ~value->value; break; + case OP_NOT : ; res->value = !value->value; break; + default : internalerror("UO %08X", opr); + } + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Handle binary operators + // + +void oprBin(valueSA *vl, int opr, valueSA *vr, valueSA *res) +{ + if( !vl->valid || !vr->valid ) + { + res -> valid = FALSE; + res -> value = 0; + } + else + { + res -> valid = TRUE; + res -> value = 0; + + switch(opr) + { + case OP_STAR : res->value = ( vl->value * vr->value ); break; + case OP_MOD : res->value = ( vl->value % vr->value ); break; + case OP_PLUS : res->value = ( vl->value + vr->value ); break; + case OP_MINUS : res->value = ( vl->value - vr->value ); break; + case OP_LS : res->value = ( vl->value << vr->value ); break; + case OP_RS : res->value = ( vl->value >> vr->value ); break; + case OP_LESS : res->value = ( vl->value < vr->value ); break; + case OP_GREAT : res->value = ( vl->value > vr->value ); break; + case OP_LE : res->value = ( vl->value <= vr->value ); break; + case OP_GE : res->value = ( vl->value >= vr->value ); break; + case OP_EQ : res->value = ( vl->value == vr->value ); break; + case OP_NE : res->value = ( vl->value != vr->value ); break; + case OP_AND : res->value = ( vl->value & vr->value ); break; + case OP_XOR : res->value = ( vl->value ^ vr->value ); break; + case OP_OR : res->value = ( vl->value | vr->value ); break; + case OP_ANDAND : res->value = ( vl->value && vr->value ); break; + case OP_OROR : res->value = ( vl->value || vr->value ); break; + case OP_DIV : + { + if(vr->value) + res->value = ( vl->value / vr->value ); + else + { + errorin(E_DIVISION_BY_ZERO); + res->valid = FALSE; + } + } break; + default : internalerror("BO %08X",opr); + } + } +} + +/// END OF FILE ////////////////////////////////////////////////////////////// diff --git a/src/mkutil/tavrasm.118/src/semantic.hh b/src/mkutil/tavrasm.118/src/semantic.hh new file mode 100644 index 00000000..57f7d1d0 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/semantic.hh @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : semantic.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Code generation header +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _SEMANTIC_HH_ +#define _SEMANTIC_HH_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include "opcodes.hh" +#include "avrasm.hh" +#include "symbol.hh" +#include "messages.hh" + +/// Defines ////////////////////////////////////////////////////////////////// + +#define OP_AND 1 +#define OP_STAR 2 +#define OP_PLUS 3 +#define OP_MINUS 4 +#define OP_WAVE 5 +#define OP_NOT 6 + +#define OP_DIV 7 +#define OP_MOD 8 +#define OP_LS 9 +#define OP_RS 10 +#define OP_LESS 11 +#define OP_GREAT 12 +#define OP_LE 13 +#define OP_GE 14 +#define OP_EQ 15 +#define OP_NE 16 +#define OP_XOR 17 +#define OP_OR 18 +#define OP_ANDAND 19 +#define OP_OROR 20 + +#define OP_LOW 21 +#define OP_HIGH 22 +#define OP_BYTE2 23 +#define OP_BYTE3 24 +#define OP_BYTE4 25 +#define OP_LWRD 26 +#define OP_HWRD 27 +#define OP_PAGE 28 +#define OP_EXP2 29 +#define OP_LOG2 30 + +/// Types //////////////////////////////////////////////////////////////////// + + /// Attribute structs (also typedef'ed below) //////////////////////////// + +struct instructionstruct + { +#ifdef _MSC_VER /* Nick */ + int value; +#else + long value; +#endif + int size; + int opcode; + }; + +struct valuestruct + { +#ifdef _MSC_VER /* Nick */ + int value; +#else + long value; +#endif + int valid; + }; + +struct indirectstruct + { + int regno; + int plus; + int disp; + valuestruct offset; + }; + + /// Synthesized attributes /////////////////////////////////////////////// + +typedef int regSA; +typedef instructionstruct instSA; +typedef int opcodeSA; +typedef valuestruct valueSA; +typedef char nameSA[MAX_ID_LENGTH+1]; +typedef symbolTableEntry* symbolSA; +typedef indirectstruct indirectSA; +typedef int functionSA; +typedef char* stringSA; + +/// Prototypes /////////////////////////////////////////////////////////////// + + /// Generate functions /////////////////////////////////////////////////// + +void genRegReg(int opcode, regSA dest, regSA src); +void genRegImm(int opcode, regSA reg, valueSA *value); +void genImmReg(int opcode, valueSA *value, regSA reg); +void genImmImm(int opcode, valueSA *valued, valueSA *values); +void genImmedi(int opcode, valueSA *value); +void genNoargs(int opcode); +void genRegist(int opcode, regSA reg); +void genIndirc(int opcode, indirectSA *indi, regSA reg, int right = FALSE); +void genLpm(int opcode, regSA reg, indirectSA *indi, int useregs); + + /// Handle directives //////////////////////////////////////////////////// + +void doDef(symbolSA symb, regSA reg); // Handle '.def' +void doDef(symbolSA symbl, symbolSA symbr); // Handle '.def' +void doEqu(symbolSA symb, valueSA *value); // Handle '.eq' +void doAdb(void); // Init '.db' +void doAdb(valueSA *value); // Handle '.db' +void doAdb(stringSA str); // Handle '.db' +void doAdw(void); // Init '.dw' +void doAdw(valueSA *value); // Handle '.dw' +void doOrg(valueSA *value); // Handle '.org' +void doByt(valueSA *value); // Handle '.byte' +void doSet(symbolSA symb, valueSA *value); // Handle '.set' +void doDev(symbolSA devicename); // Handle '.device' + + /// Add label //////////////////////////////////////////////////////////// + +void doLab(symbolSA symb); // Add a label + + /// Operators //////////////////////////////////////////////////////////// + +void oprUna(int opr, valueSA *value, valueSA *res); +void oprBin(valueSA *vl, int opr, valueSA *vr, valueSA *res); +void genFun(functionSA func, valueSA *value, valueSA *res); + +#endif /* _SEMANTIC_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/tavrasm.118/src/symbol.cc b/src/mkutil/tavrasm.118/src/symbol.cc new file mode 100644 index 00000000..212279c6 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/symbol.cc @@ -0,0 +1,474 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : symbol.cc +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Symbol table (see additional info below). +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// +// +// Description : +// +// This module implements the symbol-table, and the functions needed to +// manipulate it. The symbol-table supports scopes, scope import/export +// and arbitrary types. +// +// The size of the hash vector is set using 'init', and can't be changed +// after initialization. The default size of the hash-table is 1024. +// The size must be 2^N, N=1, 2, ... +// +// To get a case in-sensitive symbol table, initialize with : init(TRUE); +// +// 'symbol.hh' defines the class interface and the structure of a +// symbol-table entry. +// +// Functions : +// +// init - Initialize symbol-table +// add - Add symbol to symbol-table, no check is made to see +// if symbol already exist. +// get - Return pointer to symbol. +// scopeDown - Add new scope +// scopeUp - Delete scope +// printTable - Print symbol table. +// +////////////////////////////////////////////////////////////////////////////// + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "symbol.hh" +#include "utils.hh" + +/// Macros /////////////////////////////////////////////////////////////////// + +#define LOWERCOMP(c1, c2) (tolower(c1)==tolower(c2)) + +/// Functions //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Constructor + // + +symbolTable::symbolTable(void) +{ + + hashSize = 0; + symtab = NULL; + scope = 0; + scopeTop = NULL; + currentScope = NULL; + currentSymbol = NULL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Destructor + // + +symbolTable::~symbolTable(void) +{ + if(symtab) + delete symtab; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Allocate and initialize a new symbol table. + // + +int symbolTable::init(int cs, unsigned int hashsize) +{ + unsigned int size = 1; + symbolScopeStack *newscope; + + // Return if already initialized + + if(symtab) + return 0;; + + // Align hashsize to 2^N + + while(hashsize>>=1) + size<<=1; + + if(size>HASH_MAX_SIZE) + size = HASH_MAX_SIZE; + + // Check case sensitive + + if(cs) + casesensitive = TRUE; + else + casesensitive = FALSE; + + // Allocate mew symbol-table + + if(size && (symtab = new symbolTableEntry*[size])) /* Nick removed paren */ + { + // Clear hash-table + + memset(symtab,0,size*sizeof(symbolTableEntry*)); + hashSize = size - 1; + + // Allocate first element on scope stack + + if(! (newscope = new symbolScopeStack)) + { + delete symtab; + symtab = NULL; + return 0; + } + + currentScope = newscope; + scopeTop = newscope; + + currentScope -> down = NULL; + currentScope -> up = NULL; + currentScope -> last = NULL; + currentScope -> first = NULL; + + // scope is set to 1 + + currentScope -> level = ++scope; + + return size; + } + + return 0; +} + + //////////////////////////////////////////////////////////////////////////// + // + // The hash function does three things to create the hash value : + // + // 1 : Adding the ASCII value of all characters + // + // This works fine for small hash tables, but hash values tends to pile + // up in large tables, since ASCII values for alpha numeric characters + // are "small", ie. adding 1 to 8 values in the interval 48 to 123 + // result in a hash value between 48 and 984, so there would be no point + // in using a hash table larger than 1024 (since we assume that the + // table is 2^N, where N = 1, 2, ... + // + // 2 : Shifting value right + // + // To improve the hash functions we shift the previous hash value right + // 4 times, this creates much larger values, thus solving the 'add' + // problem. + // + // 3 : XOR'ing value + // + // The solution to the 'add' problem creates another problem when using + // small hash tables, since the shifting has the effect that the hash + // value tends to forget the previous character values, because they are + // shifted to the right, and the eventually lost when the hash value + // is AND'ed with the size of the hash table. This problem is fixed + // by XOR'ing the previous value with the shifted value. + // + // An alternate solution that does not change the name pointer : + // + // for(h=i=0; name[i]; h^= ( h << 4 ) + name[i++]); + // h&=hashsize; + // + +inline int symbolTable::hash(char *name) +{ + int h = 0; + + if(!casesensitive) + while(*name) + h^= ( h << 4 ) + tolower(*name++); + else + while(*name) + h^= ( h << 4 ) + *name++; + + return h &= hashSize; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Get a pointer to a symbol. + // + +symbolTableEntry* symbolTable::get(char *name, int inscope) +{ + int notfound; + int p; + + // Get a pointer to the first element in the hash chain + + symbolTableEntry *next = symtab[hash(name)]; + + // If 'next' == NULL then the symbol is not in the table and we return. + + if(!next) + return NULL; + + // Set scope + + if(inscope<0) + inscope = scope; + + notfound = TRUE; /* Nick true; */ + + // If 'next' != NULL the chain is not empty, and we have have to + // scan all symbols at the current scope level. Since new symbols are + // added at the front of the chain, we can end the scan, when the first + // identifier with a higher scope level (lower 'scope') is found. + + if(casesensitive) + { + while(next && (inscope<=next->scope)&&(notfound=strcmp(name, next->name))) + next = next -> next; + } + else + { + while(next && (inscope<=next->scope) && notfound) + { + p = 0; + while( name[p] && next->name[p] && LOWERCOMP(name[p],next->name[p]) ) + p++; + if( name[p] || next->name[p] ) + next = next -> next; + else + notfound = FALSE; + } + } + + if(!notfound) + return next; + + return NULL; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add a symbol to symbol-table. + // + +symbolTableEntry* symbolTable::add(char *name) +{ + int h; + + // Get a pointer to the first element in the hash chain + + symbolTableEntry *next = symtab[h=hash(name)]; + + // Allocate new symbol + + symtab[h] = new symbolTableEntry; + + if(!(symtab[h])) + return NULL; + + // Clear symbol + + memset(symtab[h], 0, sizeof(symbolTableEntry)); + + // Link with next symbol in chain. + + symtab[h] -> next = next; + + if(next) + next -> prev = symtab[h]; + + // Add to scope chain + + if(currentSymbol) + { + currentSymbol -> down = symtab[h]; + symtab[h] -> up = currentSymbol; + } + else + currentScope -> first = symtab[h]; + + currentSymbol = symtab[h]; + + currentScope -> last = symtab[h]; + + // Setup new symbol + + if(strlen(name) > MAX_ID_LENGTH) + internalerror("ID TOO LONG"); + + strcpy(symtab[h]->name, name); + + symtab[h] -> scope = scope; + + next = symtab[h]; + + // return pointer to new symbol + + return symtab[h]; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add new scope + // + +int symbolTable::scopeDown(void) +{ + symbolScopeStack *newscope; + + // Allocate new element on top of the scope stack. + + if(! (newscope = new symbolScopeStack)) + return -1; + + // Setup new element + + currentScope -> down = newscope; + newscope -> up = currentScope; + currentScope = newscope; + currentScope -> down = NULL; + currentScope -> first = NULL; + currentScope -> last = NULL; + currentScope -> level = ++scope; + currentSymbol = NULL; + + return scope; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Delete scope + // + +int symbolTable::scopeUp(void) +{ + symbolTableEntry *next, *current; + int h; + + current = currentScope -> first; + + // Kill current scope + + while(current) + { + if(current->prev) + current -> prev -> next = current -> next; + else + symtab[h=hash(current -> name)]= current -> next; + + if(current->next) + current -> next -> prev = current -> prev; + + next = current -> down; + delete current; + current = next; + } + + // Decrement scope + + if(currentScope -> up) + { + currentScope = currentScope -> up; + delete currentScope -> down; + currentScope -> down = NULL; + currentSymbol = currentScope -> last; + } + else + { + currentScope -> up = NULL; + currentScope -> down = NULL; + currentScope -> first = NULL; + currentScope -> last = NULL; + } + + return --scope; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Print symbol-table to stdout. + // + +int symbolTable::printTable(int fromscope, int toscope, int format) +{ + symbolScopeStack *thescope = scopeTop; + symbolTableEntry *next; + int count =0; + + if(toscope == -1) + toscope = scope; + if(fromscope == -1) + fromscope = scope; + + if(!thescope) + printf("Symbol table is empty\n"); + else + { + while(thescope) + { + if( (thescope -> level >= fromscope ) && (thescope -> level <= toscope ) ) + { + printf("\n+---------------------------------------------------+\n"); + printf("| S:%5i I V S M |\n",thescope -> level); + printf("|---------------------------------------------------|\n"); + next = thescope -> first; + while(next) + { + // Print detailed information + + if(format) + { + } + + // Print just the symbol names + else + printf("| %08X %i %i %X %i %-32s |\n",next->value,next->isvar,next->valid,next->segment,next->macro,next->name); + + next = next -> down; + count++; + } + printf("+---------------------------------------------------+\n"); + + } + thescope = thescope -> down; + } + } + + return count; + +} + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/tavrasm.118/src/symbol.hh b/src/mkutil/tavrasm.118/src/symbol.hh new file mode 100644 index 00000000..e11f9c96 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/symbol.hh @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : symbol.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Symbol table header +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _SYMBOL_HH_ +#define _SYMBOL_HH_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include "avrasm.hh" + +/// Defines ////////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER /* Nick original definition: */ +#define HASH_DEFAULT_SIZE 1024 // Could be any 2^N +#define HASH_MAX_SIZE 0x10000 // Could be any 2^N +#else /* Nick reduced for 16-bit version: */ +#define HASH_DEFAULT_SIZE 0x100 // Could be any 2^N +#define HASH_MAX_SIZE 0x1000 // Could be any 2^N +#endif + +/// Type/Class definitions /////////////////////////////////////////////////// + +class symbolTable; + + //////////////////////////////////////////////////////////////////////////// + // + // Symbol-table entry + // + +struct symbolTableEntry +{ + // Identifier + + char name[MAX_ID_LENGTH+1]; + + // House keeping + + int scope; + symbolTableEntry *prev; + symbolTableEntry *next; + symbolTableEntry *up; + symbolTableEntry *down; + + // Symbol defines a macro + + int macro; + char macfilename[MAX_FILENAME_LENGTH+1]; + int macdefline; + int macsize; + char *macstr; + int macparms; + char macparmlist[10]; + symbolTable *macsym; + int macrodone; + + // Symbol defines a variable + + int isvar; + + // Symbol defines a label + + int islabel; + int offset; + int macrolabel; + + // Symbol defines a value + + int valid; + int valdefline; +#ifdef _MSC_VER /* Nick */ + int value; +#else + long value; +#endif + char valfilename[MAX_FILENAME_LENGTH+1]; + int segment; + int mask; + + // Symbol defines a register + + int isdefine; + int regdefline; + int reg; + char regfilename[MAX_FILENAME_LENGTH+1]; +}; + + //////////////////////////////////////////////////////////////////////////// + // + // Symbol-table class + // + +class symbolTable +{ + +public: + + // Constructor/destructor + + symbolTable(); + ~symbolTable(); + + // Public member functions + + int init(int cs=0, unsigned int hashsize=HASH_DEFAULT_SIZE); + symbolTableEntry* add(char *name); + symbolTableEntry* get(char *name, int inscope = -1); + int scopeDown(void); + int scopeUp(void); + int printTable(int fromscope=-1,int toscope=-1,int format=0); + +private: + + // Private member functions + + inline int hash(char *name); + + // Private data members + + // Scope stack entry + + struct symbolScopeStack + { + symbolScopeStack *up; + symbolScopeStack *down; + symbolTableEntry *first; + symbolTableEntry *last; + int level; + }; + + int hashSize; + int scope; + symbolTableEntry **symtab; + symbolScopeStack *scopeTop; + symbolScopeStack *currentScope; + symbolTableEntry *currentSymbol; + int casesensitive; + +}; + +#endif /* _SYMBOL_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// + + diff --git a/src/mkutil/tavrasm.118/src/t.bat b/src/mkutil/tavrasm.118/src/t.bat new file mode 100644 index 00000000..5c03e466 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/t.bat @@ -0,0 +1,11 @@ +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c avrasm.cc +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c semantic.cc +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c symbol.cc +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c utils.cc +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c avrparse.cc +c:\tc\bin\tcc -ml -P -I. -DAVRLANG=LANGUAGE_US -c avrlex.cc +del tavrasm.exe +c:\tc\bin\tlink @t.lnk +del *.obj +del *.map +copy tavrasm.exe \hytech\src\avr diff --git a/src/mkutil/tavrasm.118/src/t.lnk b/src/mkutil/tavrasm.118/src/t.lnk new file mode 100644 index 00000000..14f2be57 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/t.lnk @@ -0,0 +1,4 @@ +/m c:\tc\lib\c0l avrasm semantic symbol utils avrparse avrlex +tavrasm +tavrasm +c:\tc\lib\cl c:\tc\lib\oldstrml c:\tc\lib\mathl c:\tc\lib\emu diff --git a/src/mkutil/tavrasm.118/src/tavrasm.exe b/src/mkutil/tavrasm.118/src/tavrasm.exe new file mode 100644 index 0000000000000000000000000000000000000000..fa3f52cd6f39e37ed0248d9d3fbb4f74e971102a GIT binary patch literal 225342 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 literal 0 HcmV?d00001 diff --git a/src/mkutil/tavrasm.118/src/tsv4.asm b/src/mkutil/tavrasm.118/src/tsv4.asm new file mode 100644 index 00000000..c27643ed --- /dev/null +++ b/src/mkutil/tavrasm.118/src/tsv4.asm @@ -0,0 +1,3616 @@ +; TSV4.ASM + +; 19FEB02 REVISE FOR GREATER CONTRAST VOLTAGE FOR ALBERT'S 2ND BATCH -15V +; 01FEB02 REVISE FOR 7.3728MHz XTAL (SEE !!!) + +; 22JUN01 REVISE -VE VOLTAGE GENERATION +; TO WORK WITH REV E PARTS +; ;!! INDICATES CHANGES + +;** INDICATES CHANGES FOR LOW VCC AVR MOD + +.INCLUDE "8535DEF.INC" +.INCLUDE "MAC.INC" +.INCLUDE "APITS.INC" ; NOT API.INC BECAUSE APITS.INC ALSO HAS TURNON COMMAND +;.INCLUDE "TERTS.INC" ; NOT TER.INC BECAUSE FLAGS IN LOWER HALF OF REGISTER SET + +.LISTMAC +.MACRO LDIYADR ; POINT Y TO DSPRAM ADDR + LDI YH,HIGH(@0>>6) + STS XPAGE,YH + RCALL ADRYP ; AND SET XPAGE + LDI YH,HIGH(@0<<2) + LDI YL,(LOW(@0) & $3F) | (HIGH(@0) & $C0) +.ENDMACRO + +.MACRO ADRL + OUT PORTC,@0 ; SET L ADDRESS FOR DSPRAM +.ENDMACRO + +.MACRO ADRH + OUT PORTA,@0 ; SET H ADDRESS FOR DSPRAM + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@0 ; IS THIS NEEDED? +.ENDMACRO + +;.MACRO ADRINC +; INC @0 ; INC LOW ORDER DSPRAM ADDRESS +; SBRC @0,6 ; ROLLS OVER IF BIT 6 SET +;; RCALL INCADRY ; INC HIGH ORDER DSPRAM ADDRESS +;.ENDMACRO ; (RCALL IS IN MAINLINE CODE) + +.MACRO A0_A13 + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + CLI + SBI PORTB,3 + CBI PORTB,3 + SEI + STS LATCH11_SAV,R19 +.ENDMACRO + +.MACRO A14_A18 + CLI + LDS R19,LATCH10_SAV ; AND THIS + EOR R19,@0 + ANDI R19,$E0 + EOR R19,@0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + SEI + STS LATCH10_SAV,R19 ; MUST BE ATOMIC DUE TO TOGGLING M +.ENDMACRO + +.MACRO A0_A15 + PUSH R19 + + MOV R19,@0 + ANDI R19,$3F + OUT PORTC,R19 + + MOV R19,@1 + LSL R19 + LSL R19 + BST @0,7 ; A7 + BLD R19,1 + BST @0,6 ; A6 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,@1 + + LDS R19,LATCH10_SAV ; AND THIS + BST @1,7 ; A15 + BLD R19,1 + BST @1,6 ; A14 + BLD R19,0 + OUT PORTA,R19 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,R19 + + POP R19 +.ENDMACRO + +.MACRO RAMWR + OUT PORTA,@0 + CLI + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMWRX + OUT PORTA,@0 + CBI PORTB,1 + CBI PORTB,0 + NOP + SBI PORTB,0 + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRXW + CLR @1 + OUT DDRA,@1 + CLI + CBI PORTB,0 + NOP + CBI PORTB,1 + IN @1,PINA + EOR @0,@1 + SBRC FLAGS,0 + OR @0,@1 + LDI @1,$FF + OUT DDRA,@1 + OUT PORTA,@0 + NOP + SBI PORTB,0 + SEI + SBI PORTB,1 +.ENDMACRO + +.MACRO RAMRD + CLR F + OUT DDRA,F ; PORTA INPUT + CLI + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + SEI + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO RAMRDX + CLR F + OUT DDRA,F ; PORTA INPUT + CBI PORTB,0 ; CS_ON + NOP + SBI PORTB,0 ; CS_OFF + IN @0,PINA ; READ DATA + LDI F,$FF + OUT DDRA,F ; PORTA OUTPUT +.ENDMACRO + +.MACRO PHOTO + OUT PORTA,@0 ; SELECT PHOTODIODE CHANNEL + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,0 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LED + OUT PORTA,@0 ; MAIN LED DRIVE PORT + LDS @0,LATCH12_SAV + OUT PORTC,@0 + SBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 + CBI PORTC,1 + SBI PORTB,2 ; THIS WILL PROVIDE LE=1 + CBI PORTB,2 ; THIS WILL PROVIDE G=0 +.ENDMACRO + +.MACRO LEDLO + LDS D,LATCH12_SAV ; DRIVE LED COMMON LO + CBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO LEDHI + LDS D,LATCH12_SAV ; DRIVE LED COMMON HI + SBR D,1<<4 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKHI + LDS D,LATCH12_SAV ; DRIVE SPEAKER HI + SBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKLO + LDS D,LATCH12_SAV ; DRIVE SPEAKER LO + CBR D,1<<3 + SBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.MACRO SPKOFF + LDS D,LATCH12_SAV ; DRIVE SPEAKER OFF + CBR D,1<<3 + CBR D,1<<2 + OUT PORTC,D + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,D +.ENDMACRO + +.EQU T1_INIT =-818 ;$FB35 +.EQU T1_FULL_SCALE =-716 ;50.0HZ ; SETS LCD FRAME RATE TEMPORARY TO STOP FLIKER +;.EQU T1_FULL_SCALE =-651 ;53.5HZ ; SETS LCD FRAME RATE +;.EQU T1_FULL_SCALE =-600 ;54.8HZ ; SETS LCD FRAME RATE + +.EQU CONTRAST_LONG =-340 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +;.EQU CONTRAST_LONG =-250 ; ALL LONG PULSES IS FULLY DARK (DON'T SATURATE) +.EQU CONTRAST_MID =-200 +.EQU CONTRAST_SHORT = -43 ; ALL SHORT PULSES IS FULLY LIGHT + +.EQU VCC_NOMINAL =-552 ;$FCC4 + +.EQU VEE_MIN =-710 ; MIN IS FULLY DARK +.EQU VEE_INIT =-340 +.EQU VEE_MAX = -43 ; MAX IS FULLY LIGHT + +; WHEN VCC = $FCC4 FOR 6.0V: +.EQU CONTRAST_MIN =-710 ; MIN IS FULLY DARK +.EQU CONTRAST_INIT =-640 +.EQU CONTRAST_MAX =-580 ; MAX IS FULLY LIGHT + +; GENEROUS LIMITS FOR EXPERIMENTATION: +;.EQU CONTRAST_MIN =$FC80 ; MIN IS FULLY DARK +;.EQU CONTRAST_MAX =$FF80 ; MAX IS FULLY LIGHT +;.EQU CONTRAST_INIT =$FE10 + +.EQU CONTRAST_STEP =4 + +.EQU DISP_DSPRAM =$60000 ; DISPLAY BUFFER +.EQU DRAW_DSPRAM =$62000 ; DRAWING BUFFER +.EQU CHSET_DSPRAM =$64000 ; START OF CHARACTER SETS +.EQU RTN_DSPRAM =$6E000 ; KEYBOARD RETURN CODE TABLE +.EQU DISPLAY_LINES =$80 +.EQU CHARACTER_SETS =10 +.EQU RAM =$60 ; START OF SRAM +.EQU TX_SIZE =$20 +.EQU RX_SIZE =$80 + +.EQU TK_LED_PULSE =14 ; 18US ?? CLOCKS OF /8 +.EQU TK_DELAY_0 =19 ; ??US DELAY TILL START OF LED PULSE (/8) +;.EQU TK_DELAY_0 =$20 ;$38 ; ??US DELAY TILL START OF LED PULSE +;.EQU TK_DELAY_0 =$25 ;$38 ; 54US ?? CLOCKS OF /8 +.EQU TK_DELAY_1 =$10 ;$28 ; CLOCKS OF /64, CHANNEL SELECT DELAY +.EQU TK_DELAY_2 =$00 ; CLOCKS OF /1024, VDD POWER ON DELAY + ; $D0 IS TOO SHORT, $E0 SEEMS TO WORK + +.EQU API_ADDRESS =$02 ; TOUCHSCREEN ADDRESS +.EQU API_TIMEOUT =33 ;50 ; 50 * 100 uSEC = APPROX 5mSEC +.EQU API_RATE_SLOW =$17 ;$5F ; DIVISOR FOR 19200 BPS +.EQU API_RATE_FAST =$00 ;$03 ; DIVISOR FOR 460800 BPS +.EQU EEWR_ENABLE =5 ; SET BY FG WHILE OK TO WRITE EEPROM +.EQU APISIZE =6 ; SET IF EXPECTING API DATA SIZE CMD +.EQU APIDATA =7 ; SET IF TRANSFERRING API DATA TX/RX + +.DEF PATTERN =R0 ; FOR HALFTONE_RECT ROUTINE +.DEF SR =R1 +.DEF RX_PTR =R2 +.DEF RX_COUNT =R3 +.DEF TX_PTR =R4 +.DEF TX_COUNT =R5 +.DEF API_REMAIN =R6 +.DEF API_WATCHDOG =R12 + +.DEF Y_SIZE =R7 +.DEF X_SIZE =R8 +.DEF LINE_CNT =R9 +.DEF XBYTE =R10 +.DEF FLAGS =R11 +; FLAGS BIT 0 0=XOR MODE 1=OR MODE +; BIT 1 0=FILL RECT 1=CLEAR RECT +; BIT 2 0=OPEN ZEROS 1=CROSSED ZEROS +; BIT 3 0=TEXT MODE 1=GRAPHICS MODE +; BIT 4 0=FIXED 1=PROPORTIONAL +; BIT 5 0=DISPLAY DISABLED 1=DISPLAY ENABLED +; BIT 6 0=TURNED OFF VIA TRANSIT SW 1=TURNED OFF VIA COMMAND +; BIT 7 USED TO CONTROL LED PULSING FOR TOUCHSCREEN EVERY 2ND CYCLE +.DEF SCAN =R13 +.DEF API_STATE =R14 + +.DEF W =R15 +.DEF F =R16 ; FG +.DEF A =R17 ; FG +.DEF B =R18 ; FG +.DEF C =R20 ; INT +.DEF D =R21 ; INT +.DEF E =R25 ; INT +;.DEF ? =R19 ; INT + +.DEF XPIXEL =R22 +.DEF CURSORX =R23 +.DEF CURSORY =R24 + +; for AVRA / TAVRASM: +;.def XL =R26 +;.def XH =R27 +;.def YL =R28 +;.def YH =R29 +;.def ZL =R30 +;.def ZH =R31 + +.DSEG +.ORG RAM + +TX_BUF: .BYTE TX_SIZE +RX_BUF: .BYTE RX_SIZE + +XBYTE_SAV: .BYTE 1 ; 063 +X_SIZE_SAV: .BYTE 1 ; 066 +XPIXEL_SAV: .BYTE 1 ; 067 +PTR: .BYTE 3 ; 068 +PORT_STATE: .BYTE 1 ; 0FA +ACTIVE_ZONE: .BYTE 1 ; 0FB + +TMPL: .BYTE 1 ; 0FE +TMPH: .BYTE 1 ; 0FF +VCCL: .BYTE 1 ; 100 +VCCH: .BYTE 1 ; 101 +VEEL: .BYTE 1 ; 102 +VEEH: .BYTE 1 ; 103 +CONTRASTL: .BYTE 1 ; 104 +CONTRASTH: .BYTE 1 ; 105 + +BUZZ_TIME: .BYTE 1 ; 10B +BUZZ_PERIOD: .BYTE 1 +TEMP: .BYTE 1 ; 10C + +DEBOUNCE: .BYTE 1 +ROW_INDEX: .BYTE 1 +ROW_BITMAP: .BYTE 2 +LATCH10_SAV: .BYTE 1 +LATCH11_SAV: .BYTE 1 +LATCH12_SAV: .BYTE 1 +XPAGE: .BYTE 1 +ROWBUF: .BYTE 32 ; BUFFER FOR DSPRAM BLOCK READ/WRITE + +LINE_COUNT: .BYTE 1 ; CURRENT POSITION TO TEST LINE_FLAGS +LINE_FLAGS: .BYTE 16 ; BUFFER 1 BIT PER LINE FOR COPY REQUIRED + +CLOCKING_PTR: .BYTE 2 + +CHAR_X: .BYTE 1 +CHAR_Y: .BYTE 1 +CHAR_PTR: .BYTE 2 + +RECT_X: .BYTE 1 +RECT_Y: .BYTE 1 +RECT_XX: .BYTE 1 +RECT_YY: .BYTE 1 + +RECTNC_X: .BYTE 1 +RECTNC_Y: .BYTE 1 +RECTNC_XX: .BYTE 1 +RECTNC_YY: .BYTE 1 + +TOUCH_KEY: .BYTE 1 +TOUCH_X: .BYTE 1 +TOUCH_Y: .BYTE 1 +TOUCH_XX: .BYTE 1 +TOUCH_YY: .BYTE 1 + +TIME_HSEC_64K: .BYTE 1 +TIME_HSEC_256: .BYTE 1 +TIME_HSEC: .BYTE 1 +TIME_SECOND: .BYTE 1 +TIME_MINUTE: .BYTE 1 +TIME_HOUR: .BYTE 1 +DATE_DAY: .BYTE 1 +DATE_MONTH: .BYTE 1 +DATE_YEAR: .BYTE 1 + +SCAN_STATE: .BYTE 1 +LATCH5_SAV: .BYTE 1 +TURNON_COUNT: .BYTE 1 +BREAK_COUNT: .BYTE 1 + +CURSORX_SAVE: .BYTE 1 +CURSORY_SAVE: .BYTE 1 +FLAGS_SAVE: .BYTE 1 +PTR_SAVE: .BYTE 3 + +SCROLL_COUNT: .BYTE 1 +SCROLL_X: .BYTE 1 +SCROLL_Y: .BYTE 1 +SCROLL_XX: .BYTE 1 +SCROLL_YY: .BYTE 1 + +.ESEG +.ORG $000 + + .DB $00,$00 ; DON'T USE ADDR $000 +EE_CONTRAST: .DB $00,$00 ; RELY ON CONTRAST_INIT TO INITIALISE + +.CSEG +.ORG $0000 + + RJMP RESET_ENTRY + RJMP GO_EXT_INT0 + RJMP GO_EXT_INT1 + RETI ; TIM2_CMP + RJMP GO_TIM2_OVF ; TIM2_OVF + RETI ; TIM1_CAPT + RETI ; TIM1_COMPA + RETI ; TIM1_COMPB + RJMP GO_T1_OVERFLOW + RJMP GO_T0_OVERFLOW + RETI ; SPI_STC + INT_HANDLERS ; API BUS + +RESET_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + LDI A,$80 + OUT ACSR,A ; POWER DOWN ANALOG COMPARATOR + + WDR ; RESET WATCHDOG + LDI A,$0F ; ENABLE WATCHDOG WITH 3 SEC TIMEOUT + OUT WDTCR,A + + LDI F,0 + STS TIME_HSEC_64K,F + STS TIME_HSEC_256,F + STS TIME_HSEC,F + STS TIME_SECOND,F + STS TIME_MINUTE,F + STS TIME_HOUR,F + LDI F,1 + STS DATE_DAY,F + STS DATE_MONTH,F + LDI F,20 + STS DATE_YEAR,F + +RESTART_ENTRY: +;**: + LDI F,8 ; TIMER 2 CLOCKED BY 32 KHZ +;** LDI F,0 ; TIMER 2 CLOCKED BY 11 MHZ + OUT ASSR,F +;**: + ; MUST MATCH SET_TIME ROUTINE % + LDI F,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;!! LDI F,$11 ; DIVIDE BY 2, TOGGLE OC2 (PIN 21) + ; (RTC DIAGNOSTIC) +;** LDI F,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,F + ; % + LDI F,$40 + OUT TIMSK,F ; TIMER 2 OVERFLOW INTERRUPTS ENABLED + LDI F,$00 + OUT GIMSK,F + + LDI F,$B8 ; INIT_PORTS + OUT DDRD,F + OUT PORTD,F ; D2 = TRI-STATE, VSWT ON + LDI F,$1F + OUT DDRB,F + LDI F,$FF + OUT DDRA,F + OUT DDRC,F + + CLR F + OUT PORTA,F + + LDI F,$03 ; CS, WE HI, LEs ALL LO + OUT PORTB,F + + LDI F,$10 ; LED COMMON OFF, SPEAKER OFF + OUT PORTC,F + SBI PORTB,2 + CBI PORTB,2 + STS LATCH12_SAV,F + + LDI F,$20 + MOV FLAGS,F ; START WITH DISPLAY ENABLED + + INIT_API_BUS + + LDI D,$18 ; A18|A17|A16|A15|A14=11000 + OUT PORTA,D ; CL1=M=FLM=0 + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + CLR D + STS LATCH11_SAV,D + STS LINE_COUNT,D ; START UPDATE AT TOP OF SCREEN + STS TURNON_COUNT,D ; REDUNDANTLY REQUEST TURNON + STS BREAK_COUNT,D ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BUZZ_TIME,D ; NOT BUZZING (SHORT BEEP COMES LATER) + + CLR SCAN + STS ROW_INDEX,SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + + LDI D,$F4 ; BIT 6 = 1 VDD ON, BIT 7 = 1 LCD ON + STS LATCH5_SAV,D + PHOTO D + + ; NEED THIS FOR RTC + SEI ; ALLOW TIMER 2 INTERRUPTS ONLY + + ; INITIALISE ACTIVE KEYS +RTNCDE: ;LDIZ RTN_CODE ; POINT Z TO FLASH + LDI ZL,LOW((RTN_CODE)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX RTN_CODE_END-RTN_CODE ; BYTE COUNTER + LDI XL,LOW((RTN_CODE_END-RTN_CODE)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((RTN_CODE_END-RTN_CODE)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR RTN_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CDE0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CDE1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + CLR R0 ; TEMPORARY CLEAR KB + RAMWRX R0 ; WRITE DATA TO DSPRAM + DEC XL + BREQ RTNCDE_END ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CDE1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CDE0 +RTNCDE_END: + + ; INITIALISE DEFAULT CHARACTER SET + LDI A,'0' + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + PUSH YL + PUSH YH + RCALL CHARACTER_SET_CRC ; Y = CALCULATED CRC WORD + POP XH + POP XL + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YH + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + SWAP A + RCALL HEX_NIBBLE + CP A,B + BRNE CHARACTER_SET_INIT + ADIW XL,1 + + RCALL GO_READ_BYTE + MOV B,A + MOV A,YL + RCALL HEX_NIBBLE + CP A,B + BREQ CHARACTER_SET_INIT_DONE + +CHARACTER_SET_INIT: + ;LDIZ CHSET00 ; POINT Z TO FLASH + LDI ZL,LOW((CHSET00)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ;LDIX CHSET00_END-CHSET00 ; BYTE COUNTER + LDI XL,LOW((CHSET00_END-CHSET00)*2) ; USE AS BYTE COUNTER + LDI XH,HIGH((CHSET00_END-CHSET00)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + LDIYADR CHSET_DSPRAM ; POINT Y TO DSPRAM & SET XPAGE +CHST0: ADRH YH ; SET ADDRESS H FOR DSPRAM +CHST1: ADRL YL ; SET ADDRESS L FOR DSPRAM + LPM ; GET DATA FROM FLASH + RAMWRX R0 ; WRITE DATA TO DSPRAM + SBIW XL,1 + BREQ CHARACTER_SET_INIT_DONE ; CHECK IF ALL DONE + ADIW ZL,$01 ; INC FLASH ADDRESS + INC YL ; INC ADDRESS L FOR DSPRAM + MOV A,YL ; + ANDI A,$3F ;YL,$3F + BRNE CHST1 + SUBI YL,$40 ; + INC YH ; INC ADDRESS H (ON L ROLLOVER) + RJMP CHST0 + +CHARACTER_SET_INIT_DONE: + LDI B,LOW(CHSET_DSPRAM+$10) ; SET POINTER TO HEADER + STS PTR,B + LDI B,HIGH(CHSET_DSPRAM+$10) ;<<2 + STS PTR+1,B + LDI B,HIGH((CHSET_DSPRAM+$10)>>6) + STS PTR+2,B + + ; CLEAR REFRESH BUFFER TO AVOID A BRIEF FLICKER + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL GO_SELECT_XPAGE + + LDI B,DISPLAY_LINES ; B = LINES TO CLEAR + +CLEAR_REFRESH: + PUSH B + PUSH YL + PUSH YH + + LDI B,32 + RCALL GO_CLEAR_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + ADIW YL,6 + LDI B,2 + RCALL GO_CLEAR_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP YH + POP YL + POP B + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE CLEAR_REFRESH + + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + + LDI A,0 + STS BUZZ_PERIOD,A ; HIGHEST FREQUENCY + LDI A,54 ;$40 + STS BUZZ_TIME,A ; SHORT BEEP ON STARTUP + + LDI A,0 + STS SCAN_STATE,A ; START ON FIRST LED / PHOTODIODE PAIR + + LDI A,0 + STS CLOCKING_PTR,A + STS CLOCKING_PTR+1,A ; INITIALISE CURRENT LINE FOR CLOCKING + + LDI A,HIGH(VEE_INIT) + STS VEEH,A + LDI A,LOW(VEE_INIT) + STS VEEL,A ; INIT MEASURED VEE + + LDI B,EE_CONTRAST*2 + RCALL EE_READ + ANDI A,~(CONTRAST_STEP-1) + STS CONTRASTL,A + LDI B,EE_CONTRAST*2+1 + RCALL EE_READ + STS CONTRASTH,A + + LDS A,CONTRASTL + LDS B,CONTRASTH + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_RESET + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRLO CONTRAST_PRESERVE + +CONTRAST_RESET: + LDI A,HIGH(CONTRAST_INIT) + STS CONTRASTH,A + LDI A,LOW(CONTRAST_INIT) + STS CONTRASTL,A ; INIT REQUESTED CONTRAST + +CONTRAST_PRESERVE: + LDI A,HIGH(CONTRAST_MID) + OUT OCR1BH,A + LDI A,LOW(CONTRAST_MID) + OUT OCR1BL,A ; INIT GENERATOR PULSE WIDTH + + LDI A,HIGH(T1_INIT) + OUT TCNT1H,A + LDI A,LOW(T1_INIT) + OUT TCNT1L,A + + LDI A,$50 + OUT TCCR1A,A ; TIMER 1 TOGGLE ON COMPARE MATCH + LDI A,$01 + OUT TCCR1B,A ; TIMER 1 RUNNING + + LDI F,$00 + OUT TCCR0,F ; TIMER 0 NOT RUNNING YET + + LDI F,$05 + OUT TIFR,F ; RESET TIMER 0, 1 INTERRUPT FLAGS + LDI F,$45 + OUT TIMSK,F ; TURN ON TIMER 0, 1, 2 INTERRUPTS + + LDI F,$0A + OUT MCUCR,F ; SET EXTERNAL INTERRUPT 0, 1 SENSE + LDI F,$C0 + OUT GIFR,F ; RESET EXTERNAL INTERRUPT 0, 1 FLAGS + OUT GIMSK,F ; TURN ON EXTERNAL INTERRUPT 0, 1 + + ;RCALL HELLO_DISPLAY ; SHOW EXAMPLE DISPLAY + + ;RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP SAVE_ENTRY ; IN CASE STATE INADVERTENTLY RESTORED + +; ----------------------------------------------------------------------------- + +SLEEP_ENTRY: + LDI F,HIGH(RAMEND) ; INIT STACK POINTER + OUT SPH,F + LDI F,LOW(RAMEND) + OUT SPL,F + + LDI D,$00 + OUT TCCR1A,D ; DISCONNECT PWM FROM OC1A, OC1B + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + OUT TCCR1B,D ; STOP TIMER 1 ALTOGETHER + + SBI PORTD,4 ; TURN TRANSISTOR OFF + CBI PORTD,5 ; DROP CL2 + + LDS D,LATCH10_SAV + ANDI D,$BF ; DROP M + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + + LDI D,$74 ; BIT 6 = 1 VDD ON, BIT 7 = 0 LCD OFF + SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + LDI D,$34 ; BIT 6 = 0 VDD OFF, BIT 7 = 0 LCD OFF + STS LATCH5_SAV,D + PHOTO D + + LDI D,$41 + OUT TIMSK,D ; DISABLE TIMER 1 INTERRUPTS + + LDI D,0 + OUT TCCR0,D ; DISABLE TIMER 0 TEMPORARILY ONLY + OUT GIMSK,D ; DISABLE THERMISTOR INTERRUPTS + + LDI F,4 + STS TURNON_COUNT,F ; .25 SEC TO BREAK, .75 SEC TO MAKE + + INIT_API_BUS ; RESET UART TO RECEIVE TURNON COMMAND + +SLEEP_LOOP: + CLI + IN F,TCCR0 + TST F + LDI F,$4A ; SE=1 SM1:SM0=00 FOR IDLE MODE + BRNE SLEEP_SETUP ; TIMER 0 RUNNING, STAY IN IDLE MODE + SBIS PIND,0 ; BREAK OFF, UART ACTIVE, STAY IN IDLE + LDI F,$7A ; SE=1 SM1:SM0=11 FOR POWER SAVE MODE +SLEEP_SETUP: + OUT MCUCR,F + SEI + SLEEP + + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDS F,TURNON_COUNT + TST F ; HAD TOUCHSCREEN ACTIVITY FOR TIMEOUT? + ;SBRS FLAGS,6 ; IF WE TURNED OFF VIA BREAK DETECT, + ;SBIS PIND,0 ; AND BREAK HAS DISAPPEARED, WAKE UP + BRNE SLEEP_LOOP ; NO, GO BACK TO SLEEP + + CLI + RJMP RESTART_ENTRY ; GO AND CLEAR DISPLAY ETC + +; ----------------------------------------------------------------------------- + +ADRYP: LDS YH,XPAGE ; SET XPAGE ADDRESS FOR DSPRAM + LDS YL,LATCH10_SAV + ANDI YL,$E0 + OR YH,YL + OUT PORTA,YH + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,YH + RET + +;INCADRY: +; CLR YL +; INC YH +; BRNE INCRET +; LDS YH,XPAGE +; INC YH +; ANDI YH,$1F +; STS XPAGE,YH +; CLR YH +;INCRET: RET + +; ----------------------------------------------------------------------------- + +;HELLO_DISPLAY: +; LDI A,0 +; STS RECTNC_X,A +; STS RECTNC_Y,A +; STS RECTNC_XX,A +; LDI A,$80 +; STS RECTNC_YY,A +; RCALL DRAW_RECTNC +; +; LDI A,16 +; STS CHAR_X,A +; STS CHAR_Y,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; RCALL STRING_DRAW +; +; LDI A,240 +; STS CHAR_X,A +; LDI B,5 +; LDI ZL,LOW(HELLO_MESSAGE*2) +; LDI ZH,HIGH(HELLO_MESSAGE*2) +; +;STRING_RIGHT_JUST: +; PUSH B +; PUSH ZL +; PUSH ZH +; RCALL STRING_WIDTH +; POP ZH +; POP ZL +; POP B +; LDS A,CHAR_X +; SUB A,R0 +; STS CHAR_X,A +; +;STRING_DRAW: +; PUSH B +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; PUSH R0 +; RCALL DRAW_CHAR +; POP R0 +; POP ZH +; POP ZL +; LDS A,CHAR_X +; ADD A,R0 +; STS CHAR_X,A +; POP B +; DEC B +; BRNE STRING_DRAW +; RET +; +;STRING_WIDTH: +; CLR R0 +;STRING_WIDTH_LOOP: +; PUSH B +; PUSH R0 +; LPM +; MOV A,R0 +; ADIW ZL,1 +; PUSH ZL +; PUSH ZH +; RCALL FIND_CHAR +; RCALL CHAR_WIDTH +; POP ZH +; POP ZL +; POP A +; ADD R0,A +; POP B +; DEC B +; BRNE STRING_WIDTH_LOOP +; RET +; +;HELLO_MESSAGE: .DB 'H','E','L','L','O',0 + +; ----------------------------------------------------------------------------- + +MAIN_LOOP: + SEI ; SHOULD BE BEFORE MAIN_LOOP + + LDI A,~(1< CHARACTER SET + LDI YL,$10 + STS PTR,YL + STS PTR+1,YH + STS PTR+2,B + RJMP MAIN_LOOP + +SET_TIME: + LDI A,0 + OUT TCCR2,A ; STOP COUNTING WHILE SETTING CLOCK + STS TIME_HSEC_64K,A + STS TIME_HSEC_256,A + STS TIME_HSEC,A + RCALL RX_WAIT + STS TIME_HOUR,A + RCALL RX_WAIT + STS TIME_MINUTE,A + RCALL RX_WAIT + STS TIME_SECOND,A + RCALL RX_WAIT + STS DATE_MONTH,A + RCALL RX_WAIT + STS DATE_DAY,A + RCALL RX_WAIT + STS DATE_YEAR,A + LDI A,3 ; TIMER 2 DIVIDE BY 32 (4 HZ) +;** LDI A,6 ; TIMER 2 DIVIDE BY 256 + OUT TCCR2,A + RJMP MAIN_LOOP + +LF: RCALL LINE_FEED + RJMP MAIN_LOOP + +LINE_FEED: + PUSH R0 + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + INC YL + A14_A18 B + RCALL LPMS + MOV A,CURSORY + ADD A,R0 + ADD A,R0 + DEC A + CPI A,DISPLAY_LINES + BRLO INC_CURSORY + RCALL GO_SCROLL + POP R0 + RET + +INC_CURSORY: + ADD CURSORY,R0 + POP R0 + RET + +CLR_DISP: + RCALL CLEAR_DISPLAY ; CLEARS DISPLAY AND HOMES CURSOR + RJMP MAIN_LOOP + +INTERPRET_MODE: + RCALL RX_WAIT + CPI A,$30 + BRNE TEXT_MODE + RJMP L01A4 +TEXT_MODE: + CPI A,$31 + RJEQ GRAPHICS_MODE +;L01A3: + RJMP MAIN_LOOP + +L01A4: LDI F,$F7 + AND FLAGS,F + RJMP MAIN_LOOP + +GRAPHICS_MODE: + LDI F,$08 + OR FLAGS,F + RJMP MAIN_LOOP + +PROP_FIXED_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ FIXED +;L01AE: + CPI A,$31 + RJEQ PROPORTIONAL +L01B1: +; RJMP MAIN_LOOP + +FIXED: LDI F,$EF + AND FLAGS,F + RJMP MAIN_LOOP + +PROPORTIONAL: + LDI F,$10 + OR FLAGS,F + RJMP MAIN_LOOP + +BACK_SPACE: + LDS YL,PTR + LDS YH,PTR+1 + LDS B,PTR+2 + SUBI YH,$FE + A14_A18 B + RCALL LPMS + SUB CURSORX,R0 + IN A,SREG + SBRS A,2 + RJMP MAIN_LOOP + +CR: CLR CURSORX + RJMP MAIN_LOOP + +ENABLE_CNTRL: + RCALL RX_WAIT + SBRC A,1 + RJMP ENABLE_UPDATE + SBRC A,0 + RJMP ENABLE_ON +;ENABLE_OFF: + LDI F,$DF + AND FLAGS,F + RJMP MAIN_LOOP +ENABLE_ON: + LDI F,$20 + OR FLAGS,F +ENABLE_UPDATE: + CLR F + STS LINE_COUNT,F ; START UPDATE AT TOP OF SCREEN +ENABLE_LOOP: + RCALL NICK_SUB2 ; IMMEDIATE UPDATE OF ENTIRE SCREEN + BRNE ENABLE_LOOP + RJMP MAIN_LOOP + +DRAW_MODE: + RCALL RX_WAIT + CPI A,$30 + RJEQ XOR_MODE +;L01D3: + CPI A,$31 + RJEQ OR_MODE +;L01D6: + RJMP MAIN_LOOP + +XOR_MODE: + LDI F,$FE + AND FLAGS,F + RJMP MAIN_LOOP + +OR_MODE: + LDI F,$01 + OR FLAGS,F + RJMP MAIN_LOOP + +SET_CURSOR: + RCALL RX_WAIT + MOV CURSORX,A +GET_Y: RCALL RX_WAIT + MOV CURSORY,A + RJMP MAIN_LOOP + +CLEAR_RECTANGLE: + LDI F,$02 + OR FLAGS,F + +GET_RECT_SIZE: + STS RECT_X,CURSORX + STS RECT_Y,CURSORY + RCALL RX_WAIT + STS RECT_XX,A + RCALL RX_WAIT + STS RECT_YY,A + RCALL DRAW_RECT + LDI F,$FD + AND FLAGS,F + RJMP MAIN_LOOP + +GET_FILLED_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL FILLED_RECTNC + RJMP MAIN_LOOP + +GET_RECTNC_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL RX_WAIT + STS RECTNC_XX,A + RCALL RX_WAIT + STS RECTNC_YY,A + RCALL DRAW_RECTNC + RJMP MAIN_LOOP + +CONTRAST_CONTROL: + RCALL RX_WAIT + + SBRS A,0 + RJMP CONTRAST_DARKER + +;CONTRAST_LIGHTER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(-CONTRAST_STEP) + SBCI B,HIGH(-CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MAX) + LDI F,HIGH(CONTRAST_MAX) + CPC B,F + BRSH CONTRAST_DONE + RJMP CONTRAST_WRITE + +CONTRAST_DARKER: + LDS A,CONTRASTL + LDS B,CONTRASTH + SUBI A,LOW(CONTRAST_STEP) + SBCI B,HIGH(CONTRAST_STEP) + + CPI A,LOW(CONTRAST_MIN) + LDI F,HIGH(CONTRAST_MIN) + CPC B,F + BRLO CONTRAST_DONE + +CONTRAST_WRITE: + STS CONTRASTL,A + STS CONTRASTH,B + + LDI B,EE_CONTRAST*2 + RCALL EE_WRITE + LDS A,CONTRASTH + LDI B,EE_CONTRAST*2+1 + RCALL EE_WRITE + +CONTRAST_DONE: + RJMP MAIN_LOOP + +EE_READ: + SBIC EECR,EEWE + RJMP EE_READ ; WAIT UNTIL EEPROM BECOMES READY + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + SBI EECR,EERE ; READ DATA BYTE + IN A,EEDR ; GET LATCHED DATA BYTE + RET + +EE_WRITE: + SBIC EECR,EEWE + RJMP EE_WRITE ; WAIT FOR EEPROM TO BECOME READY + + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT0: + RJMP EE_WRITE_HALT0 ; HALT PROCESSOR IF EE WRITING DISABLED + + OUT EEARL,B + CLR B + OUT EEARH,B ; ASSUME EEPROM ADDRESSES < $100 + OUT EEDR,A ; LATCH NEW VALUE + + CLI + SBRS API_STATE,EEWR_ENABLE +EE_WRITE_HALT1: + RJMP EE_WRITE_HALT1 ; HALT PROCESSOR IF EE WRITING DISABLED + + SBI EECR,EEMWE ; MASTER WRITE ENABLE + SBI EECR,EEWE ; START WRITING NEW VALUE + RETI + +GO_SCROLL: + RJMP SCROLL + +CHARACTER_SET_DOWNLOAD: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + RCALL RX_WAIT + MOV XL,A + RCALL RX_WAIT + MOV XH,A + +CHARACTER_SET_DOWNLOAD_LOOP: + RCALL RX_WAIT + + A14_A18 B + RCALL GO_WRITE_BYTE + + ADIW YL,1 + SBIW XL,1 + MOV A,XL + OR A,XH + RJNE CHARACTER_SET_DOWNLOAD_LOOP ; BRNE ?? + RJMP MAIN_LOOP + +CHARACTER_SET_QUERY: + RCALL RX_WAIT + RCALL CHARACTER_SET_FIND ; B:Y -> CHARACTER SET + + PUSH A + RCALL CHARACTER_SET_CRC + + LDI A,$1B + RCALL TX_WAIT + LDI A,'?' + RCALL TX_WAIT + POP A + SUBI A,-'0' + RCALL TX_WAIT + + MOV A,YH + RCALL TX_HEX_BYTE + MOV A,YL + RCALL TX_HEX_BYTE + RJMP MAIN_LOOP + +CHARACTER_SET_FIND: + LDI YL,LOW(CHSET_DSPRAM) + LDI YH,HIGH(CHSET_DSPRAM)<<4 + LDI B,HIGH(CHSET_DSPRAM>>4) + + ANDI A,$0F + CPI A,CHARACTER_SETS + BRSH CHARACTER_SET_FIND_DONE ; DEFAULT TO SET 0 + + ADD B,A + +CHARACTER_SET_FIND_DONE: + LSR B + ROR YH + LSR B + ROR YH + LSR YH + LSR YH + RET + +CHARACTER_SET_CRC: + LDI XL,LOW($216) + LDI XH,HIGH($216) ; PAST CRC, INDEX, CELL SIZES + ADD XL,YL + ADC XH,YH ; B:X -> LENGTH WORD IN CHARACTER SET + A14_A18 B + RCALL GO_READ_BYTE + MOV ZL,A + ADIW XL,1 + RCALL GO_READ_BYTE + MOV ZH,A ; Z = LENGTH OF DATA INCLUDING CRC + + MOV XL,YL + MOV XH,YH + ADIW XL,4 ; B:X -> DATA BLOCK EXCLUDING CRC + + LDI YL,$FF + LDI YH,$FF ; Y = SEED FOR CRC CALCULATION + + SBIW ZL,1 + ANDI ZH,$0F + SBIW ZL,4 ; Z = LENGTH OF DATA-1 EXCLUDING CRC + BRLO CHARACTER_SET_CRC_DONE + ADIW ZL,1 + +CHARACTER_SET_CRC_BYTE: + RCALL GO_READ_BYTE + ADIW XL,1 + + LDI F,$21 + LDI B,$10 ; B:F = CRC POLYNOMIAL + EOR YH,A ; Y = CRC REGISTER WITH NEW DATA BYTE + + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT0 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT0: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT1 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT1: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT2 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT2: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT3 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT3: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT4 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT4: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT5 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT5: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT6 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT6: + LSL YL + ROL YH + BRCC CHARACTER_SET_CRC_BIT7 + EOR YL,F + EOR YH,B +CHARACTER_SET_CRC_BIT7: + + SBIW ZL,1 + BRNE CHARACTER_SET_CRC_BYTE + +CHARACTER_SET_CRC_DONE: + RET + +TX_HEX_BYTE: + PUSH A + SWAP A + RCALL HEX_NIBBLE + RCALL TX_WAIT + POP A + RCALL HEX_NIBBLE + RJMP TX_WAIT + +HEX_NIBBLE: + ANDI A,$0F + ORI A,$30 + CPI A,$3A + BRLO HEX_NIBBLE_DONE + SUBI A,-7 +HEX_NIBBLE_DONE: + RET + +SAVE_STATE: + RCALL RX_WAIT + SBRC A,0 + RJMP RESTORE_STATE + +SAVE_ENTRY: + STS CURSORX_SAVE,CURSORX + STS CURSORY_SAVE,CURSORY + STS FLAGS_SAVE,FLAGS + LDS A,PTR + STS PTR_SAVE,A + LDS A,PTR+1 + STS PTR_SAVE+1,A + LDS A,PTR+2 + STS PTR_SAVE+2,A + RJMP MAIN_LOOP + +RESTORE_STATE: + LDS CURSORX,CURSORX_SAVE + LDS CURSORY,CURSORY_SAVE + LDI A,$C0 + AND FLAGS,A + LDS A,FLAGS_SAVE + ANDI A,$3F + OR FLAGS,A + LDS A,PTR_SAVE + STS PTR,A + LDS A,PTR_SAVE+1 + STS PTR+1,A + LDS A,PTR_SAVE+2 + STS PTR+2,A + RJMP MAIN_LOOP + +TOUCH_ZONE: + RCALL RX_WAIT + STS TOUCH_KEY,A + + RCALL RX_WAIT + MOV YL,A + SUBI A,-9 + RCALL DIVIDE_10 + STS TOUCH_X,B + + RCALL RX_WAIT + MOV YH,A + SUBI A,-4 + RCALL DIVIDE_13 + STS TOUCH_Y,B + + RCALL RX_WAIT + ADD A,YL + SUBI A,15 + RCALL DIVIDE_10 + STS TOUCH_XX,B + + RCALL RX_WAIT + ADD A,YH + SUBI A,17 + RCALL DIVIDE_13 + STS TOUCH_YY,B + + LDS YH,TOUCH_Y +TOUCH_ZONE_Y: + LDS A,TOUCH_YY + SUB A,YH + BRSH TOUCH_ZONE_Y_CONT + RJMP TOUCH_ZONE_Y_END +TOUCH_ZONE_Y_CONT: + + LDS YL,TOUCH_X + MOV A,YL + ADD A,YH + MOV B,YH + LSL B + LSL B + LSL B + ADD A,B + LSL B + ADD A,B + + LDI XL,LOW(RTN_DSPRAM) + LDI XH,HIGH(RTN_DSPRAM) ;<<2 + LDI B,0 + ADD XL,A + ADC XH,B + + LDI B,HIGH(RTN_DSPRAM>>6) ; B:X -> RETURN CODE TABLE + A14_A18 B + +TOUCH_ZONE_X: + LDS A,TOUCH_XX + SUB A,YL + BRLO TOUCH_ZONE_X_END + + A0_A13 XL,XH + LDS A,TOUCH_KEY + RAMWR A ; WRITE DATA TO DSPRAM + + ADIW XL,1 + INC YL + RJMP TOUCH_ZONE_X + +TOUCH_ZONE_X_END: + INC YH + RJMP TOUCH_ZONE_Y + +TOUCH_ZONE_Y_END: + RJMP MAIN_LOOP + +DIVIDE_10: + LDI B,-1 +DIVIDE_10_LOOP: + INC B + SUBI A,10 + BRCC DIVIDE_10_LOOP + RET + +DIVIDE_13: + LDI B,-1 +DIVIDE_13_LOOP: + INC B + SUBI A,13 + BRCC DIVIDE_13_LOOP + RET + +NULLSUB2: + RCALL RX_WAIT + +NULLSUB: + RCALL RX_WAIT + RJMP MAIN_LOOP + +RX_WAIT: + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +RX_WAIT_LOOP: + ; FORMERLY DONE IN TIMER 2 OVERFLOW INTERRUPT + WDR + + LDI A,0 + OUT EEARL,A ; RESET EEPROM ADDRESS REG WHILE IDLE + OUT EEARH,A + + LDI A,-$40 + SBIC PIND,0 ; RXD HIGH? + STS BREAK_COUNT,A ; YES, TOP UP VERY SHORT BREAK TIMEOUT + + SBRC FLAGS,5 ; DISPLAY ENABLED? + RCALL NICK_SUB2 ; IF SO, COPY 1 LINE ACCORDING TO FLAGS + + TST RX_COUNT + BREQ RX_WAIT_LOOP + + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE PROCESSING CHARACTER + +RX_CHAR: + MRX_CHAR +TX_WAIT: + MTX_WAIT +TX_CHAR: + MTX_CHAR + +DRAW_CHAR_TTY: + RCALL FIND_CHAR ; SET UP CHAR_PTR FROM A = CHAR + RCALL CHAR_WIDTH ; SET UP R0 = PROP WIDTH FROM CHAR PTR + + CLR F + STS TEMP,F ; NUDGE FOR FIXED SPACING MODE + + SBRC FLAGS,4 + RJMP PROP_MODE ; FORCED TO FIXED SPACING MODE? + + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + MOV W,R0 + RCALL LPMS ; GET R0 = CELL WIDTH FOR CHARACTER SET + PUSH R0 + SUB R0,W + BRCC NUDGE_OK + CLR R0 ; NO NEGATIVE CENTRING +NUDGE_OK: + LSR R0 + STS TEMP,R0 + POP R0 ; RESTORE R0 = FIXED CELL WIDTH + +PROP_MODE: + SBRC FLAGS,3 + RJMP OK_LINE ; FORCED TO GRAPHICS MODE? + + MOV F,CURSORX + ADD F,R0 ; CHECK IF CHAR WILL FIT ON THIS LINE + BRCC OK_LINE + + CLR CURSORX + RCALL LINE_FEED ; NO, WRAP CURSOR PRIOR TO DRAWING CHAR + + LDS A,PTR+2 + RCALL SELECT_XPAGE ; IN CASE WE SCROLLED THE DISPLAY + +OK_LINE: + LDS F,TEMP + ADD F,CURSORX + STS CHAR_X,F + STS CHAR_Y,CURSORY ; SET UP TOP LEFT COORDINATES + + ADD CURSORX,R0 ; ADVANCE CURSOR + +DRAW_CHAR: + LDS XPIXEL,CHAR_X + LDS LINE_CNT,CHAR_Y + + SBRS X_SIZE,6 + RJMP Y_OFFSET_DONE ; Y OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$02 + RCALL LPMS + ADD LINE_CNT,R0 + +Y_OFFSET_DONE: + SBRS X_SIZE,7 + RJMP X_OFFSET_DONE ; X OFFSET FOUND? + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + SBIW YL,$03 + RCALL LPMS + ADD XPIXEL,R0 + +X_OFFSET_DONE: + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + ADIW YL,$01 + RCALL LPMS ; GET R0 = Y LINES FOR CHARACTER + MOV Y_SIZE,R0 + + LDI F,$FF + OUT DDRA,F + SBI PORTB,0 ; REMOVE_CS + LDI F,$1F + AND X_SIZE,F + STS X_SIZE_SAV,X_SIZE + CLR F + CPSE X_SIZE,F + RJMP DRAW_IT + RJMP DONE + +DRAW_IT: + CLR XL + MOV XH,LINE_CNT + LSR XH + ROR XL + LSR XH + ROR XL + SUBI XH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + RJMP FIRSTT + +MORE_Y: INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + + LDS X_SIZE,X_SIZE_SAV + LDS XBYTE,XBYTE_SAV + +FIRSTT: OR XBYTE,XL + CLR B ; RESIDUAL + +MORE_X: ADIW YL,$01 + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + + CLR A + LDS XPIXEL,XPIXEL_SAV + TST XPIXEL + BREQ OUT_DATA + + CLC +SHIFT_AGAIN: + ROR R0 + ROR A + DEC XPIXEL + BRNE SHIFT_AGAIN + + OR R0,B + MOV B,A + +OUT_DATA: + LDI F,HIGH(DRAW_DSPRAM>>6) + A14_A18 F + A0_A13 XBYTE,XH + RAMRXW R0,F + + INC XBYTE + DEC X_SIZE + RJNE MORE_X + + TST B + BREQ SKIP_FINAL + A0_A13 XBYTE,XH + RAMRXW B,F + +SKIP_FINAL: + RCALL NICK_SUB1 + DEC Y_SIZE + RJNE MORE_Y + +DONE: RET + +FIND_CHAR: + MOV YL,A + CLR YH + LSL YL + ROL YH + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + LDS A,PTR+2 + RCALL SELECT_XPAGE + RCALL LPMS + ADIW YL,$01 + MOV W,R0 + RCALL LPMS + MOV YL,W + MOV YH,R0 + LDS A,PTR + ADD YL,A + LDS A,PTR+1 + ADC YH,A + STS CHAR_PTR,YL + STS CHAR_PTR+1,YH + RET + +CHAR_WIDTH: + LDS YL,CHAR_PTR + LDS YH,CHAR_PTR+1 + RCALL LPMS + MOV X_SIZE,R0 + SBIW YL,$01 + SBRC X_SIZE,5 + RJMP LPMS ; PROPORTIONAL WIDTH IS PRESENT + LDS YL,PTR + LDS YH,PTR+1 + SUBI YH,$FE + RJMP LPMS ; NO PROPORTIONAL WIDTH, USE CELL WIDTH + +NICK_SUB1: ; SET FLAG FOR COPY, LINE_CNT + PUSH YL + PUSH YH + + MOV A,LINE_CNT + RCALL FIND_BIT + LD A,Y + OR A,B + ST Y,A + + POP YH + POP YL + RET + +NICK_SUB2: ; TEST FLAG AND COPY, LINE_COUNT + PUSH B + PUSH YL + PUSH YH + + LDS A,LINE_COUNT + RCALL FIND_BIT + LD A,Y + AND A,B + RJEQ NICK_SUB2_DONE + + LD B,Y + EOR B,A + ST Y,B + + ; LET'S BE SAFE + LDI A,0 ; SET LONGEST POSSIBLE BREAK TIMEOUT + STS BREAK_COUNT,A ; WHILE COPYING TO DISPLAY BUFFER + + PUSH XL + PUSH XH + + CLR YL + LDS YH,LINE_COUNT + LSR YH + ROR YL + LSR YH + ROR YL ; Y -> DISPLAY BUFFER + + MOV XL,YL + MOV XH,YH + SUBI XH,HIGH(-DRAW_DSPRAM) ; X -> DRAWING BUFFER + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + LDI B,32 + RCALL COPY_BYTES ; 240 PIXELS, PLUS 16 FOR SAMSUNG + + SBIW XL,2 + ADIW YL,6 + LDI B,2 + RCALL COPY_BYTES ; REPEAT FINAL 16 PIXELS FOR HYUNDAI + + POP XH + POP XL + + LDI A,-$40 + STS BREAK_COUNT,A ; SET VERY SHORT BREAK TIMEOUT + +NICK_SUB2_DONE: + LDS A,LINE_COUNT + INC A + ANDI A,DISPLAY_LINES-1 + STS LINE_COUNT,A + + POP YH + POP YL + POP B + RET + +; NEW CODE: (NOT WORKING YET) +; WE HAVE JUST DRAWN INTO THE DRAWING BUFFER AT $62000, +; AND NOW WANT TO COPY THE DOT ROW CONCERNED +; TO THE THE DISPLAY BUFFER AT $60000 +; CLI +; +; PUSH YL +; PUSH XL +; PUSH XH +; +; A0_A13 YL,YH +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; CLR A +; OUT DDRA,A ; PORTA INPUT +; CBI PORTB,0 ; CS ON +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +;NSUB0: OUT PORTC,YL ; SET ADDRESS +; INC YL ; NEED SOME DELAY HERE +; DEC B +; IN A,PINA ; READ DATA +; ST X+,A ; SAVE IN ROW BUFFER +; BRNE NSUB0 +; SBI PORTB,0 ; CS OFF +; SER A +; OUT DDRA,A ; PORTA OUTPUT +; +; LDI XL,LOW(ROWBUF) ; SRAM BUFFER FOR BLOCK READ +; LDI XH,HIGH(ROWBUF) +; +; LDI A,LATCH11_SAV +; ANDI A,$7F ; POINT TO $2000 LOWER +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; IN YL,PORTC +; ANDI YL,$C0 ; POINT TO START OF ROW +; LDI B,$20 ; COPYING 32 BYTES +; CBI PORTB,1 ; WE ON +;NSUB1: OUT PORTC,YL ; SET ADDRESS +; LD A,X+ ; GET DATA FROM ROW BUFFER +; OUT PORTA,A +; INC YL ; MAY AS WELL DELAY HERE +; DEC B +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; BRNE NSUB1 +; +; ADDI YL,7 ; SHIFT LAST 2 BYTES FOR HYUNDAI +; OUT PORTC,YL ; SET ADDRESS +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; DEC YL +; OUT PORTC,YL ; SET ADDRESS +; SBIW XL,2 +; LD A,X +; OUT PORTA,A +; CBI PORTB,0 ; CS ON +; SBI PORTB,0 ; CS OFF +; +; SBI PORTB,1 ; WE OFF +; LDI A,LATCH11_SAV ; RESTORE H ADDRESS +; OUT PORTA,A +; SBI PORTB,3 +; CBI PORTB,3 +; +; POP XH +; POP XL +; POP YL +; SEI +; RET + +FIND_BIT: + LDI YL,LOW(LINE_FLAGS) + LDI YH,HIGH(LINE_FLAGS) + ; LET'S BE SAFE + ANDI A,$7F + MOV B,A + LSR B + LSR B + LSR B + ADD YL,B + LDI B,0 + ADC YH,B + LDI B,1 + ANDI A,7 + BREQ FIND_BIT_RET +FIND_BIT_LOOP: + LSL B + DEC A + BRNE FIND_BIT_LOOP +FIND_BIT_RET: + RET + +GO_READ_BYTE: + RJMP READ_BYTE + +GO_WRITE_BYTE: + RJMP WRITE_BYTE + +GO_CLEAR_BYTES: + RJMP CLEAR_BYTES + +GO_SELECT_XPAGE: + RJMP SELECT_XPAGE + +GO_SCROLL_REGION: + RJMP SCROLL_REGION + +;GO_MAIN_LOOP: +; RJMP MAIN_LOOP + +GO_EXT_INT0: + RJMP EXT_INT0 + +GO_EXT_INT1: + RJMP EXT_INT1 + +GO_TIM2_OVF: + RJMP TIM2_OVF + +GO_T1_OVERFLOW: + RJMP T1_OVERFLOW + +GO_T0_OVERFLOW: + RJMP T0_OVERFLOW + +DRAW_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP L03A3 +L039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +L03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ L03B0 + LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + TST XPIXEL + BREQ L03B0 +L03AD: LSR A + DEC XPIXEL + BRNE L03AD +L03B0: RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +L03B8: LDI F,$08 + CP X_SIZE,F + BRLO L03C2 + BREQ L03D2 + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP L03B8 +L03C2: TST X_SIZE + BREQ L03D3 +L03C4: LSR A + DEC X_SIZE + BRNE L03C4 + COM A + TST XPIXEL + BREQ L03D2 + CLR B +L03CB: LSR A + ROR B + DEC XPIXEL + BRNE L03CB + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +L03D2: RCALL WR_DISP_MEM +L03D3: RCALL NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP L039A +NO_GO: RET + +FILLED_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + STS RECT_XX,X_SIZE + RJMP FILLED_RECTNC_ENTRY + +DRAW_RECTNC: + LDS F,RECTNC_XX + DEC F + CPI F,2 + BRLO NO_GO + LDS F,RECTNC_YY + CPI F,3 + BRLO NO_GO + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS F,RECTNC_Y + STS RECT_Y,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDI F,$01 + STS RECT_YY,F + RCALL DRAW_RECT + + LDS F,RECTNC_X + STS RECT_X,F + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + LDI F,$01 + STS RECT_XX,F + RCALL DRAW_RECT + + LDS X_SIZE,RECTNC_XX + LDS F,RECTNC_X + ADD F,X_SIZE + DEC F + STS RECT_X,F + LDI F,$01 + STS RECT_XX,F +FILLED_RECTNC_ENTRY: + LDS F,RECTNC_Y + INC F + STS RECT_Y,F + LDS Y_SIZE,RECTNC_YY + DEC Y_SIZE + DEC Y_SIZE + STS RECT_YY,Y_SIZE + RCALL DRAW_RECT + + LDS F,RECTNC_X + INC F + STS RECT_X,F + LDS X_SIZE,RECTNC_XX + DEC X_SIZE + DEC X_SIZE + STS RECT_XX,X_SIZE + LDS Y_SIZE,RECTNC_YY + LDS F,RECTNC_Y + ADD F,Y_SIZE + DEC F + STS RECT_Y,F + LDI F,$01 + STS RECT_YY,F + RJMP DRAW_RECT + +; ----------------------------------------------------------------------------- + +TX_EMPTY: + MTX_EMPTY +RX_COMPLETE: + MRX_COMPLETE +;FEED_WDOG: +; MFEED_WDOG +TX_COMPLETE: + MTX_COMPLETE +API_TIMEOUT_ERROR: + MAPI_TIMEOUT_ERROR +API_FRAMING_ERROR: +API_RESET_ERROR: + MAPI_FRAMING_ERROR +API_REINIT: + MAPI_REINIT +API_REVERT: + MAPI_REVERT +API_DONE: + MAPI_DONE + +; ----------------------------------------------------------------------------- + +CALCULATE_XBYTE: + CLR XBYTE + LDI F,$F0 + SUB XBYTE,F + SBRS XPIXEL,7 + CLR XBYTE + ANDI XPIXEL,$7F +L0415: SUBI XPIXEL,$08 + BRLT L0419 + INC XBYTE + RJMP L0415 +L0419: SUBI XPIXEL,$F8 + RET + +LPMS: A0_A13 YL,YH + RAMRD R0 + RET ;RETI + +WR_DISP_MEM: + A0_A13 XBYTE,YH + RAMRD W + SBRS FLAGS,1 + RJMP L043E + COM A + AND W,A + RJMP L0441 +L043E: EOR W,A + SBRC FLAGS,0 + OR W,A +L0441: A0_A13 XBYTE,YH + RAMWR W + RET ;RETI + +CLEAR_DISPLAY: + CLR CURSORX ; HOME CURSOR + CLR CURSORY + CLR LINE_CNT + LDI YL,LOW(DRAW_DSPRAM) + LDI YH,HIGH(DRAW_DSPRAM) + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE +CLEAR_DISPLAY_LOOP: + CLR XBYTE + STS XBYTE_SAV,XBYTE +L065C: LDS A,XBYTE_SAV + OR A,YL + A0_A13 A,YH + LDI F,$00 + RAMWR F + INC XBYTE + LDI F,$20 + CP XBYTE,F + BREQ L0674 + STS XBYTE_SAV,XBYTE + RJMP L065C +L0674: RCALL NICK_SUB1 + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + CPI YH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE CLEAR_DISPLAY_LOOP + RET + +; ----------------------------------------------------------------------------- + +EXT_INT0: +;**: +RETI +;** IN SR,SREG ; MEASURE VCC +;** SBI DDRD,2 +;** IN C,TCNT1L +;** IN D,TCNT1H +;** STS VCCH,D +;** STS VCCL,C +;** RJMP EXT_INT_RET + +EXT_INT1: + IN SR,SREG ; MEASURE TEMPERATURE + SBI DDRD,3 + IN C,TCNT1L + IN D,TCNT1H + STS TMPH,D + STS TMPL,C + RJMP EXT_INT_RET + +T1_OVERFLOW: + IN SR,SREG + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDI D,$70 ; FORCE DUMMY COMPARE MATCH + OUT TCCR1A,D ; TO SET OC1B, TOGGLE OC1A + IN C,TCNT1L ; (FOR REV E PARTS) + IN D,TCNT1H ; READ CURRENT COUNT + SUBI C,LOW(-8) ; ADD JUST ENOUGH TIME + SBCI D,HIGH(-8) ; FOR THESE INSTRUCTIONS + OUT OCR1AH,D ; AND WRITE TO COMPARE REGISTERS + OUT OCR1AL,C + OUT OCR1BH,D + OUT OCR1BL,C + + LDS C,CLOCKING_PTR + TST C ; START OF 4 LINE BLOCK? (1 BASED) + BRNE BREAK0 ; NO, BREAK COUNTER IS OK FOR NOW + + LDS D,BREAK_COUNT + INC D ; HAD BREAK SOLIDLY FOR TIMEOUT? + STS BREAK_COUNT,D + BRNE BREAK1 ; NO, CLOCK OUT TO DISPLAY AS NORMAL + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION +GO_SLEEP_ENTRY: + RJMP SLEEP_ENTRY + +BREAK0: NOP + NOP + NOP + NOP + NOP + NOP + NOP +BREAK1: SBI DDRD,3 ; PRECHARGE TEMPERATURE MEASUREMENT + SBI PORTD,3 + + CLR D + OUT TCCR1B,D ; STOP TIMER1 + OUT TCNT1H,D ; AND CLEAR COUNT + OUT TCNT1L,D + + LDS D,CLOCKING_PTR+1 + OR D,C ; START OF FRAME? (REALLY LINE 1) + BREQ L04E6 ; YES, GO AND TOGGLE M ETC + + LDS D,LATCH10_SAV + OUT PORTA,D + SBI PORTB,4 + SBI PORTA,5 ; PULSE CL1 + CBI PORTA,5 + CBI PORTB,4 + NOP ; EQUALIZE DELAY + NOP + NOP + NOP + NOP + NOP + RJMP L04F9 + +GO_NICK_SUB1: + RJMP NICK_SUB1 + +GO_RX_WAIT: + RJMP RX_WAIT + +GO_MAIN_LOOP: + RJMP MAIN_LOOP + +GO_GET_HALFTONE_RECT_SIZE: + RJMP GET_HALFTONE_RECT_SIZE + +L04E6: LDS D,LATCH10_SAV + ORI D,$80 ; RAISE FLM + ORI D,$20 ; RAISE CL1 + OUT PORTA,D + + SBI PORTB,4 + LDI C,$60 ; TOGGLE M AND CL1 + EOR D,C + OUT PORTA,D + ANDI D,$7F ; DROP FLM + OUT PORTA,D + CBI PORTB,4 + STS LATCH10_SAV,D + +L04F9: LDS D,LATCH10_SAV ; SAVE STATE + PUSH D + + PUSH ZL + PUSH ZH + LDS ZL,CLOCKING_PTR + LDS ZH,CLOCKING_PTR+1 + + SUBI ZL,LOW(-$40) + SBCI ZH,HIGH(-$40) + ANDI ZH,HIGH(DISPLAY_LINES*$40-1) + + A0_A15 ZL,ZH + + CBI PORTB,1 ; CLR HC590 + SBI PORTB,1 + CBI PORTD,7 ; DROP OE FOR HC590 + CLR C + OUT DDRA,C ; PORTA HI Z + LDI C,$C0 + OUT DDRC,C ; PORTC HI Z + CBI PORTB,0 ; DROP CS FOR DSPRAM + + CLR D + OUT OCR1AH,D + +; LDI D,1 ; TO CLOCK AT 5.5/2 MHZ + OUT OCR1AL,D ; TO CLOCK AT 7.3/2 MHZ + LDI D,$09 + OUT TCCR1B,D ; START CL2 CLOCKING WITH CLR ON MATCH + + STS CLOCKING_PTR,ZL + STS CLOCKING_PTR+1,ZH + POP ZH + POP ZL + +;!!! LDI D,$7A ; WAIT FOR 32uSEC +; LDI D,58 ;$7A ; WAIT FOR 32uSEC GOOD + LDI D,60 ; WAIT FOR 32uSEC +; LDI D,61 ;$7A ; WAIT FOR 32uSEC +; LDI D,62 ;$7A ; WAIT FOR 32uSEC GOOD + +L050E: DEC D + BRNE L050E + + SBI PORTB,0 ; RAISE CS FOR DSPRAM + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + SBI PORTD,7 ; RAISE OE FOR HC590 + OUT DDRC,D ; PORTC OUTPUT + + CBI DDRD,5 ; CL2 INPUT TO MEASURE VEE + CBI PORTD,5 ; REMOVE PULL UP + + LDI D,$01 ; KILL CLR ON COMPARE MATCH + NOP ; !WITH OC1A LEFT IN LOW STATE + OUT TCCR1B,D + + LDI D,$0B ; WAIT FOR 3uSEC +SETTLE_CL2: + DEC D + BRNE SETTLE_CL2 + + LDS D,VEEH + LDS C,VEEL + SBI DDRD,5 ; CL2 LOW OUTPUT + SBIC PIND,5 ; SAMPLE CL2 JUST BEFORE CHANGE + RJMP L052F + + CPI C,LOW(VEE_MIN) + LDI E,HIGH(VEE_MIN) + CPC D,E + BRMI L0535 + + SUBI C,$01 + SBCI D,$00 + RJMP L0536 + +L052F: CPI C,LOW(VEE_MAX) + LDI E,HIGH(VEE_MAX) + CPC D,E + BRPL L0535 + + SUBI C,$FF + SBCI D,$FF + RJMP L0536 + +L0535: NOP ; EQUALIZE DELAYS + NOP + NOP + NOP +L0536: STS VEEH,D + STS VEEL,C + OUT OCR1AH,D ; SET SWITCHING TIME FOR VEE MEASURE + OUT OCR1AL,C + + LDS C,VEEL + LDS D,VEEH + LDS E,CONTRASTL + SUB C,E + LDS E,CONTRASTH + SBC D,E + BRPL L0545 + + LDI C,LOW(CONTRAST_SHORT) + LDI D,HIGH(CONTRAST_SHORT) + RJMP L0547 + +L0545: LDI C,LOW(CONTRAST_LONG) + LDI D,HIGH(CONTRAST_LONG) + NOP + NOP + +L0547: OUT OCR1BH,D ; SET SWITCHING TIME FOR VEE GENERATOR + OUT OCR1BL,C + + LDI D,2 ; SET TIME FOR START OF LED PULSE + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_DELAY_0 ; 54uSEC + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI D,HIGH(T1_FULL_SCALE) + OUT TCNT1H,D + LDI D,LOW(T1_FULL_SCALE) + OUT TCNT1L,D + + CBI DDRD,3 ; START TEMPERATURE MEASUREMENT + CBI PORTD,3 + + LDI D,$E0 ; NEXT COMPARE MATCH MUST SET OC1A + OUT TCCR1A,D ; AND CLR OC1B (FOR REV E PARTS) + + RJMP T1_OVERFLOW_RET + +T0_OVERFLOW: + IN SR,SREG ; LED/PHOTODIODE SCANNING + IN D,DDRA ; SAVE STATE OF THE WORLD + PUSH D + IN D,PORTA + PUSH D + IN D,PORTC + PUSH D + LDS D,LATCH11_SAV + PUSH D + LDS D,LATCH10_SAV + PUSH D + + PUSH ZH + PUSH ZL + PUSH R0 + + LDI D,$FF + OUT DDRA,D ; PORTA OUTPUT + + LDS D,SCAN_STATE + INC D + STS SCAN_STATE,D + DEC D + BREQ SCAN_START ; IF SCAN_STATE WAS = 0 + DEC D + BREQ SCAN_BEEPER ; IF SCAN_STATE WAS = 1 + ; IMPLEMENT ENTRY POINT FOR SCAN_PULSE_LED HERE + DEC D + RJEQ SCAN_PHOTO ; IF SCAN_STATE WAS = 2 + +T0_OVERFLOW_RET: + POP R0 + POP ZL + POP ZH + +T1_OVERFLOW_RET: + POP D ; RESTORE STATE OF THE WORLD + OUT PORTA,D + SBI PORTB,4 + CBI PORTB,4 + STS LATCH10_SAV,D + POP D + OUT PORTA,D + SBI PORTB,3 + CBI PORTB,3 + STS LATCH11_SAV,D + POP D + OUT PORTC,D + POP D + OUT PORTA,D + POP D + OUT DDRA,D + ;MFEED_WDOG +EXT_INT_RET: + OUT SREG,SR + RETI + +SCAN_START: + LDI D,3 ;5 + OUT TCCR0,D ; PRESCALE=CK/1024 + LDI D,-TK_DELAY_1 ;TK_DELAY_2 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + RJMP L0617_RESET + +SCAN_BEEPER: + LDS D,BUZZ_TIME + TST D + BREQ SCAN_PULSE_LED + LDS D,BUZZ_PERIOD + SUBI D,$10 + BRLO BUZZ_TOGGLE + STS BUZZ_PERIOD,D + RJMP SCAN_PULSE_LED +BUZZ_TOGGLE: ; ASSUME D = $F0 + PERIOD-1 + MOV C,D ; EG. C = $F3 FOR PERIOD = 4 + SWAP C ; EG. C = $3F FOR PERIOD = 4 + AND D,C ; EG. D = $33 FOR PERIOD = 4 + STS BUZZ_PERIOD,D + LDS C,LATCH12_SAV + SBRS C,3 ; TEST PREVIOUS SPEAKER STATE + RJMP BEEPER_SPKHI + LDS D,BUZZ_TIME + DEC D + STS BUZZ_TIME,D + BREQ BEEPER_SPKOFF +;BEEPER_SPKLO: + SPKLO + RJMP SCAN_PULSE_LED +BEEPER_SPKHI: + SPKHI + RJMP SCAN_PULSE_LED +BEEPER_SPKOFF: + SPKOFF + +SCAN_PULSE_LED: + LDS D,LATCH5_SAV +;**: + SBRS D,7 ; ARE WE INSIDE SLEEP_LOOP? +;** SBRC D,7 + RJMP SCAN_PULSE_LED_OK ; YES, KEEP TIMER 0 TO RETAIN CONTROL + + LDI D,1<<7 + EOR FLAGS,D + BRPL SCAN_PULSE_LED_OK ; PULSE LED EVERY 2ND CYCLE + + CLR D + OUT TCCR0,D ; STOP TIMER + RJMP T0_OVERFLOW_RET ; AND WASTE EVERY REMAINING CYCLE + +SCAN_PULSE_LED_OK: + LDI D,2 + OUT TCCR0,D ; PRESCALE=CK/8 + LDI D,-TK_LED_PULSE ; 22uSEC + OUT TCNT0,D + + ;LDIZ SCAN_TBL ; POINT TO FIRST LED CHANNEL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM ; R0 = LED DRIVE VALUE + LDI D,13*4 + CP SCAN,D + BRSH L0570 + LEDLO ; ENABLE HORIZ LED DRIVE + RJMP L0574 +L0570: LEDHI ; DISABLE HORIZ LED DRIVE +L0574: LED R0 + RJMP T0_OVERFLOW_RET + +SCAN_PHOTO: + IN D,PIND ; PHOTODIODE STATUS IN BIT 6,D + LDI C,$E0 + LED C ; TURN OFF LED ?? + + CLC + SBRC D,6 + RJMP L0593 ; ROW/COLUMN IS INACTIVE + + ; ROW/COLUMN IS ACTIVE + LDS D,DEBOUNCE + TST D + BREQ L0591 + LDI D,$04 + STS DEBOUNCE,D +L0591: SEC + +L0593: ; WE HAVE A ROW/COLUMN STATUS IN CF + IN C,SREG + + LDI D,13*4 + CP SCAN,D + BRSH L05A8 + + ; WE HAVE A ROW STATUS + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + LDS ZL,ROW_BITMAP + LDS ZH,ROW_BITMAP+1 + ROL ZL + ROL ZH + STS ROW_BITMAP,ZL + STS ROW_BITMAP+1,ZH + RJMP L05F9 + +L05A8: ; WE HAVE A COLUMN STATUS +; LDS D,LATCH5_SAV +;;**: +; SBRS D,7 ; TURNED OFF? +;;** SBRC D,7 +; RJMP L05F9 ; YES, NO FURTHER PROCESSING + OUT SREG,C ; CF = 0 INACTIVE, CF = 1 ACTIVE + BRCS L05AB + RJMP L05F9 + +L05AB: ; WE HAVE AN ACTIVE COLUMN + LDS D,DEBOUNCE + TST D + BREQ L05B3 + LDI D,$04 + STS DEBOUNCE,D + RJMP L05F9 + +L05B3: ; LOOK FOR ANY ACTIVE ROW + LDS ZH,ROW_BITMAP+1 + LDS ZL,ROW_BITMAP + + LDS D,ROW_INDEX + TST D + BREQ ROW_BITMAP_LOOP + + MOV C,D +ROW_BITMAP_SKIP: + ROR ZH + ROR ZL + SUBI C,4 + BRNE ROW_BITMAP_SKIP + +ROW_BITMAP_LOOP: + SUBI D,-4 + ROR ZH + ROR ZL + BRCS FOUND_INTERSECTION +ROW_BITMAP_LOOPE: + CPI D,13*4 + BRLO ROW_BITMAP_LOOP + + ; NO FURTHER INTERSECTING ROWS FOUND + RJMP L05F9 + +FOUND_INTERSECTION: + ; FOUND AN INTERSECTING ROW FOR COLUMN + STS ROW_INDEX,D + + LDI C,$34 ; BECAUSE ROW_BITMAP IS BEING TESTED + SUB C,D ; IN THE REVERSE ORDER TO ITS CREATION + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,C + ADC ZH,D + LPM + MOV C,R0 + LSL R0 + LSL R0 + LSL R0 + ADD C,R0 + LSL R0 + ADD C,R0 + + ;LDIZ SCAN_TBL+1 ; POINT TO FIRST TOUCH CHANNEL + LDI ZL,LOW((SCAN_TBL+1)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL+1)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + ADD C,R0 + LDI ZL,LOW(RTN_DSPRAM) ; RETURN CODE TABLE + LDI ZH,HIGH(RTN_DSPRAM) + CLR D + ADD ZL,C + ADC ZH,D + + A0_A15 ZL,ZH + + PUSH F + RAMRDX R0 + POP F + + TST R0 + BRNE VALID_INTERSECTION + + ; INTERSECTION IS NULL, GO ON TO NEXT + LDS D,ROW_INDEX + CPI D,13*4 + BRSH L05F9 ; DONE LAST ROW, GO ON TO NEXT COLUMN +GO_L0617: + RJMP L0617 ; GO ON TO NEXT ROW, SAME COLUMN + +VALID_INTERSECTION: + ; INTERSECTION IS VALID, WE HAVE KEY MAKE + LDI D,$04 + STS DEBOUNCE,D + STS ACTIVE_ZONE,R0 + LDI D,54 ;43 + STS BUZZ_TIME,D ; SHORT BEEP ON MAKE + + MOV D,TX_COUNT + CPI D,TX_SIZE-1 + BRSH L05F9 + + PUSH A + MOV A,R0 + RCALL TX_CHAR + CPI A,$1B + BRNE TX_CONT + RCALL TX_CHAR +TX_CONT: + POP A + +L05F9: + LDI D,4 ; SCAN TO NEXT LED / PHOTODIODE PAIR + ADD SCAN,D + + LDS D,LATCH5_SAV + SBRC D,7 + RJMP TURNED_ON + + LDI D,3 + OUT TCCR0,D ; PRESCALE=CK/64 + LDI D,-TK_DELAY_1 + OUT TCNT0,D + LDI D,1 + STS SCAN_STATE,D + + LDI C,13*4 + CP SCAN,C + BRLO GO_L0617 + + ; KEEP VDD ON, TO AVOID THE LONG TK_DELAY_2 + ;LDS D,LATCH5_SAV + ;ANDI D,$BF ; BIT 6 = 0 VDD OFF + ;STS LATCH5_SAV,D + ;PHOTO D ; READY TO SLEEP FOR ANOTHER 0.25 SEC + + LDI D,0 + OUT TCCR0,D ; STOP TIMER SINCE COMPLETE SCAN DONE + ;RJMP T0_OVERFLOW_RET + + ;LDI D,$05 + ;OUT UBRR,D + ;LDI D,$18 + ;OUT UCR,D + LDS D,ROW_BITMAP+1 + LDS C,ROW_BITMAP + ;OUT UDR,C + ;OUT UDR,D + OR C,D ; HAVE WE SOME ACTIVITY? + + LDS D,TURNON_COUNT + CPI D,4 + BRSH TURNON_BREAK ; WAITING FOR BREAK + CPI D,1 + BRSH TURNON_MAKE ; WAITING FOR MAKE +GO_T0_OVERFLOW_RET: + RJMP T0_OVERFLOW_RET ; ALREADY HAD MAKE, NOT TURNED ON YET + +TURNON_BREAK: + TST C ; HAD SOME ACTIVITY? + BREQ TURNON_SAVE ; NO, COUNT DOWN TO BREAK + LDI D,4+1 ; YES, RESTART COUNTDOWN TO BREAK + RJMP TURNON_SAVE +TURNON_MAKE: + TST C ; HAD SOME ACTIVITY? + BRNE TURNON_SAVE ; YES, COUNT DOWN TO MAKE + LDI D,3+1 ; NO, RESTART COUNTDOWN TO MAKE +TURNON_SAVE: + DEC D ; COUNT DOWN TO MAKE OR BREAK + STS TURNON_COUNT,D + BRNE GO_T0_OVERFLOW_RET ; NOT READY TO TRY TURNON YET + + LDI D,~(1<<6) + AND FLAGS,D ; SAY WE TURNED OFF VIA BREAK DETECTION + CBI DDRD,2 ; D2 = TRI-STATE, VSWT ON + RJMP GO_SLEEP_ENTRY ; WE WILL NOW WAIT FOR TURNON COMMAND + +TURNED_ON: + LDI D,0 ; STOP TIMER, WE WILL REGAIN + OUT TCCR0,D ; CONTROL VIA NEXT CLOCKING INTERRUPT + STS ROW_INDEX,D + + LDI C,50*4 + CP SCAN,C + BRLO L0617 + + LDS D,DEBOUNCE ; COMPLETED ENTIRE SCAN, START NEW SCAN + TST D + BREQ L0617_RESET + DEC D + STS DEBOUNCE,D + BRNE L0617_RESET + + LDS D,ACTIVE_ZONE + TST D + BREQ L0617_RESET + + MOV D,TX_COUNT + CPI D,TX_SIZE + BRSH L0617_RESET + + PUSH A + LDI A,0 + RCALL TX_CHAR + POP A + +L0617_RESET: + CLR SCAN + STS ROW_BITMAP,SCAN + STS ROW_BITMAP+1,SCAN + +L0617: ; SELECT PHOTODIODE AND ALLOW TO SETTLE + ;LDIZ SCAN_TBL + LDI ZL,LOW((SCAN_TBL)*2) ; USE PRIOR TO LPM INSTRUCTION + LDI ZH,HIGH((SCAN_TBL)*2) ; EXTRA BRACKETS NEEDED IF @0=EXPRESSION + + ADIW ZL,1 ; POINT TO FIRST PHOTO CHANNEL + CLR D + ADD ZL,SCAN + ADC ZH,D + LPM + LDS D,LATCH5_SAV + ANDI D,$80 ; BIT 7 = PRESERVED, LCD ON/OFF STATUS + ORI D,$40 ; BIT 6 = 1 VDD ON + OR D,R0 + STS LATCH5_SAV,D + PHOTO D + RJMP T0_OVERFLOW_RET + +SCROLL: CLR LINE_CNT + + LDI YL,LOW(DRAW_DSPRAM) ; SCROLL UP + LDI YH,HIGH(DRAW_DSPRAM) + LDI XL,LOW(DRAW_DSPRAM) + LDI XH,HIGH(DRAW_DSPRAM) + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + +L0628: SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + DEC R0 + BRNE L0628 + +L062C: LDI B,$20 ; COPYING 32 BYTES +L062D: PUSH B + RCALL READ_BYTE + RCALL WRITE_BYTE + INC XL + INC YL + POP B + DEC B + RJNE L062D ;BRNE L062D + + RCALL NICK_SUB1 + INC LINE_CNT + ADIW YL,$20 + ADIW XL,$20 + CPI XH,HIGH(DRAW_DSPRAM+DISPLAY_LINES*$40) + RJNE L062C ;BRNE L062C + RJMP CLEAR_DISPLAY_LOOP + +SCROLL_REGION: + RCALL RX_WAIT + PUSH A ; DIRECTION TO SCROLL + + RCALL RX_WAIT + STS SCROLL_COUNT,A ; AMOUNT TO SCROLL IN PIXEL LINES + + RCALL RX_WAIT + LSR A + LSR A + LSR A + BRNE SCROLL_WIDTH_OK + LDI A,32 ; ENTRY WIDTH OF 0 = FULL +SCROLL_WIDTH_OK: + STS SCROLL_XX,A ; X SIZE OF REGION IN BYTES + + RCALL RX_WAIT + STS SCROLL_YY,A ; Y SIZE OF REGION IN PIXEL LINES + + MOV A,CURSORX + LSR A + LSR A + LSR A + STS SCROLL_X,A + STS SCROLL_Y,CURSORY + + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + + POP A ; DIRECTION TO SCROLL + SBRC A,0 + RJMP SCROLL_DOWN + +;SCROLL_UP: + CLR YL + LDS YH,SCROLL_Y + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_UP_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_UP_LOOP: + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + INC LINE_CNT + SUBI XL,LOW(-$40) + SBCI XH,HIGH(-$40) + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_UP_CLEAR: + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + INC LINE_CNT + SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + + DEC B + BRNE SCROLL_UP_CLEAR + + RJMP GO_MAIN_LOOP + +SCROLL_DOWN: + CLR YL + LDS YH,SCROLL_Y + LDS F,SCROLL_YY + ADD YH,F + MOV LINE_CNT,YH ; FOR NICK_SUB1 + LSR YH + ROR YL + LSR YH + ROR YL + LDS A,SCROLL_X + ADD YL,A + SUBI YH,HIGH(-DRAW_DSPRAM) ; Y = DESTINATION WITHIN DRAWING BUFFER + + MOV B,F ;LDS B,SCROLL_YY + LDS A,SCROLL_COUNT + CP A,B + BRSH SCROLL_DOWN_CLEAR ; WITH B = LINES TO CLEAR + SUB B,A ; CALCULATE B = LINES TO COPY INTACT + + CLR XL + LDS XH,SCROLL_Y + ADD XH,F + SUB XH,A ; SCROLL_COUNT + LSR XH + ROR XL + LSR XH + ROR XL + LDS A,SCROLL_X + ADD XL,A + SUBI XH,HIGH(-DRAW_DSPRAM) ; X = SOURCE WITHIN DRAWING BUFFER + +SCROLL_DOWN_LOOP: + DEC LINE_CNT + SUBI XL,LOW($40) + SBCI XH,HIGH($40) + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH XL + PUSH XH + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL COPY_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP XH + POP XL + POP B + + DEC B + BRNE SCROLL_DOWN_LOOP + + LDS B,SCROLL_COUNT ; B = LINES TO CLEAR + +SCROLL_DOWN_CLEAR: + DEC LINE_CNT + SUBI YL,LOW($40) + SBCI YH,HIGH($40) + + PUSH B + PUSH YL + PUSH YH + + LDS B,SCROLL_XX + RCALL CLEAR_BYTES + RCALL NICK_SUB1 + + POP YH + POP YL + POP B + + DEC B + BRNE SCROLL_DOWN_CLEAR + + RJMP GO_MAIN_LOOP + +COPY_BYTES: + RCALL READ_BYTE + ADIW XL,1 + + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE COPY_BYTES + + RET + +CLEAR_BYTES: + LDI A,0 + +FILL_BYTES: + RCALL WRITE_BYTE + ADIW YL,1 + + DEC B + BRNE FILL_BYTES + + RET + +READ_BYTE: + A0_A13 XL,XH + RAMRD A + RET + +WRITE_BYTE: + A0_A13 YL,YH + RAMWR A + RET + +SELECT_XPAGE: + A14_A18 A + RET + +; HOW MANY SECS/6553600 PER 4HZ INTERRUPT ? +; EACH TIME THROUGH ADD 1638400 SECS/6553600 = 1/4 SEC +; OSCILLATOR IS SLOW SO WE WILL ADD 1 PART IN 10000 +; HENCE EACH TIME THROUGH ADD 1638400+164 = 1638564 UNITS TO COUNT + +TIM2_OVF: + IN SR,SREG + + ; REMOVED BECAUSE DON'T WANT TO HAVE IN AN INTERRUPT + ;WDR + +;!! LDI A,$10 ; DIAGNOSTIC +;!! STS BUZZ_TIME,A ; SHORT BEEP + + LDS D,TIME_HSEC_64K + SUBI D,LOW(-1638564) + STS TIME_HSEC_64K,D + + LDS D,TIME_HSEC_256 + SBCI D,HIGH(-1638564) + STS TIME_HSEC_256,D + + LDS D,TIME_HSEC + SBCI D,HIGH(-1638564>>8) + CPI D,100 + BRSH TIM2_CARRY + STS TIME_HSEC,D + +TIM2_END: + OUT SREG,SR + SBRS FLAGS,6 ; IF WE TURNED OFF VIA COMMAND, + RETI ; START A NEW SCAN, OTHERWISE DONE + + LDI D,0 + STS SCAN_STATE,D ; WE WILL EXECUTE SCAN_START ROUTINE + RJMP T0_OVERFLOW ; GO AND TURN VDD ON + +GO_TX_CHAR: + RJMP TX_CHAR + +TIM2_CARRY: + LDI D,0 + STS TIME_HSEC,D + + LDS D,TIME_SECOND + INC D + CPI D,60 + BRLO TIM2_SECOND + + LDS D,TIME_MINUTE + INC D + CPI D,60 + BRLO TIM2_MINUTE + + LDS D,TIME_HOUR + INC D + CPI D,24 + BRLO TIM2_HOUR + + PUSH ZL + PUSH ZH + PUSH R0 + LDI ZL,LOW(MONTH_TABLE*2-1) + LDI ZH,HIGH(MONTH_TABLE*2-1) + LDS E,DATE_MONTH + ADD ZL,E + LDI E,0 + ADC ZH,E + LPM + MOV E,R0 + CPI E,28 + BRNE FEBRUARY_OK + LDS E,DATE_YEAR + ANDI E,3 + LDI E,28 + BRNE FEBRUARY_OK + LDI E,29 +FEBRUARY_OK: + POP R0 + POP ZH + POP ZL + + LDS D,DATE_DAY + CP D,E + BRLO TIM2_DAY + + LDS D,DATE_MONTH + CPI D,12 + BRLO TIM2_MONTH + + LDS D,DATE_YEAR + INC D + STS DATE_YEAR,D + CLR D +TIM2_MONTH: + INC D + STS DATE_MONTH,D + CLR D +TIM2_DAY: + INC D + STS DATE_DAY,D + CLR D +TIM2_HOUR: + STS TIME_HOUR,D + CLR D +TIM2_MINUTE: + STS TIME_MINUTE,D + CLR D +TIM2_SECOND: + STS TIME_SECOND,D + +TIM2_SEND: + MOV D,TX_COUNT + CPI D,TX_SIZE-7 + BRSH TIM2_SEND_SKIP + + PUSH A + LDI A,$1B + RCALL TX_CHAR + LDI A,'T' + RCALL TX_CHAR +; LDS A,VCCL +; RCALL TX_CHAR +; LDS A,VCCH +; RCALL TX_CHAR +; LDS A,VEEL +; RCALL TX_CHAR +; LDS A,VEEH +; RCALL TX_CHAR +; LDI A,$0D +; RCALL TX_CHAR + LDS A,TIME_HOUR + RCALL GO_TX_CHAR + LDS A,TIME_MINUTE + RCALL GO_TX_CHAR + LDS A,TIME_SECOND + RCALL GO_TX_CHAR + LDS A,DATE_MONTH + RCALL GO_TX_CHAR + LDS A,DATE_DAY + RCALL GO_TX_CHAR + LDS A,DATE_YEAR + RCALL GO_TX_CHAR + POP A + +TIM2_SEND_SKIP: + RJMP TIM2_END + +; ----------------------------------------------------------------------------- + +MONTH_TABLE: + .DB 31,28,31,30,31,30,31,31,30,31,30,31 + +; 1ST BYTE = LED +; 2ND BYTE = PHOTO +; 3RD BYTE = TOUCH CHANNEL + +SCAN_TBL: + .DB $F0,$34,$00,$00,$E8,$34,$01,$00,$F0,$33,$01,$00,$E8,$33,$02,$00 + .DB $E4,$33,$03,$00,$E8,$32,$03,$00,$E4,$32,$04,$00,$E2,$32,$05,$00 + .DB $E4,$31,$05,$00,$E2,$31,$06,$00,$E1,$31,$07,$00,$E2,$30,$07,$00 + .DB $E1,$30,$08,$00,$C1,$2A,$00,$00,$C2,$2A,$01,$00,$C1,$2B,$01,$00 + .DB $C2,$2B,$02,$00,$C4,$2B,$03,$00,$C2,$2C,$03,$00,$C4,$2C,$04,$00 + .DB $C8,$2C,$05,$00,$C4,$18,$05,$00,$C8,$18,$06,$00,$D0,$18,$07,$00 + .DB $C8,$19,$07,$00,$D0,$19,$08,$00,$A1,$19,$09,$00,$D0,$1A,$09,$00 + .DB $A1,$1A,$0A,$00,$A2,$1A,$0B,$00,$A1,$1B,$0B,$00,$A2,$1B,$0C,$00 + .DB $A4,$1B,$0D,$00,$A2,$1C,$0D,$00,$A4,$1C,$0E,$00,$A8,$1C,$0F,$00 + .DB $A4,$1D,$0F,$00,$A8,$1D,$10,$00,$B0,$1D,$11,$00,$A8,$1E,$11,$00 + .DB $B0,$1E,$12,$00,$61,$1E,$13,$00,$B0,$1F,$13,$00,$61,$1F,$14,$00 + .DB $62,$1F,$15,$00,$61,$28,$15,$00,$62,$28,$16,$00,$64,$28,$17,$00 + .DB $62,$29,$17,$00,$64,$29,$18,$00 + +RTN_CODE: + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$7E,$00,$31,$00,$32,$00,$33,$00,$34,$00,$35,$00,$36,$00 + .DB $37,$00,$38,$00,$39,$00,$30,$00,$2D,$00,$3D,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$51,$00,$57,$00,$45,$00,$52,$00,$54,$00,$59,$00 + .DB $55,$00,$49,$00,$4F,$00,$50,$00,$5B,$00,$5D,$00,$5C,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$41,$00,$53,$00,$44,$00,$46,$00,$47,$00 + .DB $48,$00,$4A,$00,$4B,$00,$4C,$00,$3B,$00,$27,$00,$0D,$0D,$0D,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$5A,$00,$58,$00,$43,$00 + .DB $56,$00,$42,$00,$4E,$00,$4D,$00,$2C,$00,$2E,$00,$2F,$00,$00,$00 + .DB $00,$00 +RTN_CODE_END: + +; ----------------------------------------------------------------------------- + +CHSET00: + .DB $32,$38,$32,$34,$30,$33,$31,$37,$30,$33,$31,$36,$32,$36,$31,$35 + .DB $11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $C0,$00,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $C1,$00,$CA,$00,$D3,$00,$DC,$00,$E5,$00,$EE,$00,$F7,$00,$00,$01 + .DB $09,$01,$12,$01,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $11,$02,$1B,$01,$24,$01,$2D,$01,$36,$01,$3F,$01,$48,$01,$51,$01 + .DB $5A,$01,$64,$01,$6D,$01,$76,$01,$7F,$01,$88,$01,$91,$01,$9A,$01 + .DB $A3,$01,$AC,$01,$B5,$01,$BE,$01,$C7,$01,$D0,$01,$D9,$01,$E2,$01 + .DB $EB,$01,$F4,$01,$08,$02,$11,$02,$11,$02,$11,$02,$11,$02,$11,$02 + .DB $00,$01,$07,$70,$88,$98,$A8,$C8,$88,$70,$01,$07,$20,$60,$20,$20 + .DB $20,$20,$70,$01,$07,$70,$88,$08,$10,$20,$40,$F8,$01,$07,$F8,$10 + .DB $20,$10,$08,$88,$70,$01,$07,$10,$30,$50,$90,$F8,$10,$10,$01,$07 + .DB $F8,$80,$F0,$08,$08,$88,$70,$01,$07,$30,$40,$80,$F0,$88,$88,$70 + .DB $01,$07,$F8,$08,$10,$20,$40,$40,$40,$01,$07,$70,$88,$88,$70,$88 + .DB $88,$70,$01,$07,$70,$88,$88,$78,$08,$10,$60,$01,$07,$70,$88,$88 + .DB $88,$F8,$88,$88,$01,$07,$F0,$88,$88,$F0,$88,$88,$F0,$01,$07,$70 + .DB $88,$80,$80,$80,$88,$70,$01,$07,$E0,$90,$88,$88,$88,$90,$E0,$01 + .DB $07,$F8,$80,$80,$F0,$80,$80,$F8,$01,$07,$F8,$80,$80,$F0,$80,$80 + .DB $80,$01,$07,$70,$88,$80,$B8,$88,$88,$78,$01,$07,$88,$88,$88,$F8 + .DB $88,$88,$88,$02,$21,$07,$80,$80,$80,$80,$80,$80,$80,$01,$07,$08 + .DB $08,$08,$08,$08,$88,$70,$01,$07,$88,$90,$A0,$C0,$A0,$90,$88,$01 + .DB $07,$80,$80,$80,$80,$80,$80,$F8,$01,$07,$88,$D8,$A8,$A8,$88,$88 + .DB $88,$01,$07,$88,$88,$C8,$A8,$98,$88,$88,$01,$07,$70,$88,$88,$88 + .DB $88,$88,$70,$01,$07,$F0,$88,$88,$F0,$80,$80,$80,$01,$07,$70,$88 + .DB $88,$88,$A8,$90,$68,$01,$07,$F0,$88,$88,$F0,$A0,$90,$88,$01,$07 + .DB $70,$88,$80,$70,$08,$88,$70,$01,$07,$F8,$20,$20,$20,$20,$20,$20 + .DB $01,$07,$88,$88,$88,$88,$88,$88,$70,$01,$07,$88,$88,$88,$88,$88 + .DB $50,$20,$01,$07,$88,$88,$88,$A8,$A8,$A8,$50,$01,$07,$88,$88,$50 + .DB $20,$50,$88,$88,$01,$07,$88,$88,$88,$50,$20,$20,$20,$02,$11,$02 + .DB $06,$08,$01,$01,$4F,$00,$2A,$02,$01,$07,$F8,$08,$10,$20,$40,$80 + .DB $F8,$01,$07,$F8,$F8,$F8,$F8,$F8,$F8,$F8 +CHSET00_END: + +; ----------------------------------------------------------------------------- + +GET_HALFTONE_RECT_SIZE: + STS RECTNC_X,CURSORX + STS RECTNC_Y,CURSORY + RCALL GO_RX_WAIT + STS RECTNC_XX,A + RCALL GO_RX_WAIT + STS RECTNC_YY,A + RCALL HALFTONE_RECT + RJMP GO_MAIN_LOOP + +HALFTONE_RECT: + SEI + LDS LINE_CNT,RECT_Y + LDS XPIXEL,RECT_X + RCALL CALCULATE_XBYTE + STS XPIXEL_SAV,XPIXEL + STS XBYTE_SAV,XBYTE + LDS Y_SIZE,RECT_YY + CLR YL + MOV YH,LINE_CNT + LDI A,$55 + SBRS YH,0 + LDI A,$AA + MOV PATTERN,A + LSR YH + ROR YL + LSR YH + ROR YL + SUBI YH,HIGH(-DRAW_DSPRAM) ; DRAW INTO DRAWING BUFFER + LDI A,HIGH(DRAW_DSPRAM>>6) + RCALL SELECT_XPAGE + RJMP X03A3 +X039A: SUBI YL,LOW(-$40) + SBCI YH,HIGH(-$40) + INC LINE_CNT + LDS XPIXEL,XPIXEL_SAV + LDS XBYTE,XBYTE_SAV +X03A3: OR XBYTE,YL + LDI A,$FF + LDS X_SIZE,RECT_XX + LDI F,$00 + CP X_SIZE,F + BREQ X03B0 + LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + TST XPIXEL + BREQ X03B0 +X03AD: LSR A + DEC XPIXEL + BRNE X03AD +X03B0: AND A,PATTERN + RCALL WR_DISP_MEM + LDI F,$08 + LDS A,XPIXEL_SAV + SUB F,A + SUB X_SIZE,F + INC XBYTE + LDI A,$FF +X03B8: LDI F,$08 + CP X_SIZE,F + BRLO X03C2 + BREQ X03D2 + AND A,PATTERN + RCALL WR_DISP_MEM + LDI A,$FF + LDI F,$08 + SUB X_SIZE,F + INC XBYTE + RJMP X03B8 +X03C2: TST X_SIZE + BREQ X03D3 +X03C4: LSR A + DEC X_SIZE + BRNE X03C4 + COM A + TST XPIXEL + BREQ X03D2 + CLR B +X03CB: LSR A + ROR B + DEC XPIXEL + BRNE X03CB + AND A,PATTERN + RCALL WR_DISP_MEM + INC XBYTE + MOV A,B +X03D2: AND A,PATTERN + RCALL WR_DISP_MEM +X03D3: COM PATTERN + RCALL GO_NICK_SUB1 + DEC Y_SIZE + CLR F + CPSE Y_SIZE,F + RJMP X039A + +; ----------------------------------------------------------------------------- + + .ORG $1000 + + .DW $4102 ; SELECT ADDRESS COMMAND + +; ----------------------------------------------------------------------------- + diff --git a/src/mkutil/tavrasm.118/src/utils.cc b/src/mkutil/tavrasm.118/src/utils.cc new file mode 100644 index 00000000..84058350 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/utils.cc @@ -0,0 +1,983 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : utils.cc +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Implements functions for logging, error reporting etc. +// +// History +// ======================================================================= +// +// 980902 : Tom - File created. +// 990117 : Tom - Fixed alignment of .db in CSEG with forward refs. +// 990124 : Tom - Added GPL notice. +// 990329 : Tom - Fixed problem with tabs after include filename +// 991212 : Tom - Fixed promlem with detecting supported instructions +// (Introduced in 1.10) +// 001101 : Brian Rhodefer - Added "fopenInIncpath()" +// 010403 : Tom - Fixed path delimiter problem in include path +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#define _UTILS_CC_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "messages.hh" +#include "avrasm.hh" +#include "utils.hh" +#include "symbol.hh" +#include "semantic.hh" + +/// Externals //////////////////////////////////////////////////////////////// + +GLOBALS(extern); + +/// Defines ////////////////////////////////////////////////////////////////// + +#define SEP yyinmacro?'>':'|' +#define CUT if( yycfg -> cutlog ) \ + { \ + strcat(yyinlineold, sp ); \ + yyinlineold[58] = '|'; \ + yyinlineold[59] = '\0'; \ + } + +/// Functions //////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // + // Get symbol + // + +symbolTableEntry* getsym(char *name) +{ + int c; + symbolTableEntry *symb = NULL; +#ifdef DEBUG /* Nick */ + void *silly; + + silly = malloc(0x1000); + if (silly) + { + free(silly); + } + + printf("getsym() @ %08lx\n", silly); + fflush(stdout); +#endif + + // Is it a macro def + + for(c=yycontext; c>=0 ; c--) + if( yysymbolstack[c] && (symb=yysymbolstack[c]->get(name)) && symb->macro) + return symb; + + // No it was not + + c = yycontext; + symb = NULL; + + if(!yyparseno) + { + while(!yysymbolstack[c]) + c--; + + symb = yysymbolstack[c]->get(name); + if(!symb) + { + symb = yysymbolstack[c]->add(name); + if (!symb) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 0\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); /* Nick */ + } +#ifdef DEBUG /* Nick */ + silly = malloc(0x1000); + if (silly) + { + free(silly); + } + printf("add() @ %08lx\n", silly); + fflush(stdout); +#endif + } + + } + else + { + while( (c>=0) && !symb ) + { + if( yysymbolstack[c--] ) + { + symb = yysymbolstack[c+1]->get(name); + if(! (symb && ISUSED(symb)) ) + symb = NULL; + } + } + if(!symb) + { + c = yycontext; + while( (c>=0) && !symb ) + { + if( yysymbolstack[c--] ) + symb = yysymbolstack[c+1]->get(name); + } + } + } + + if(!symb) + internalerror("GS %s",name); + + return symb; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert code i CSEG + // + +void insertcode(int val) +{ + if(yycodepos>=MAX_CODE_SIZE) + errorexit(X_TOO_MUCH_CODE); + + yycodebuf[yycodepos] = val; + yycodeusage[yycodepos] = yyfileno|0x80*(ISMACRO!=FALSE); /* Nick false); */ + yycodeline[yycodepos++] = yyline-1+(ISMACRO!=0); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert .db or .dw in CSEG + // + +void insertdbdw(int val) +{ + if(yycodepos>=MAX_CODE_SIZE) + errorexit(X_TOO_MUCH_CODE); + + yycodebuf[yycodepos] = val; + yycodeusage[yycodepos] = yyfileno|0x80*(ISMACRO!=FALSE); /* Nick false); */ + yycodeline[yycodepos++] = yyline; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert data in ESEG + // + +void insertdata(int val) +{ + if(yycodepos>=MAX_EROM_SIZE) + errorexit(X_TOO_MUCH_DATA); + + yyerombuf[yyerompos] = val; + yyeromusage[yyerompos++] = yyfileno; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Check if instruction is supported with the current device + // + +#define NOSUP(_inst_) (DEVINF.supported & (_inst_)) + +void checkSupported(int opcode) +{ + switch((unsigned int)opcode) /* Nick cast */ + { + case O_ADIW : if(NOSUP(S_ADIW )) warning(W_UNSUP,"adiw"); break; + case O_ICALL : if(NOSUP(S_ICALL )) warning(W_UNSUP,"icall"); break; + case O_CALL : if(NOSUP(S_CALL )) warning(W_UNSUP,"call"); break; + case O_IJMP : if(NOSUP(S_IJMP )) warning(W_UNSUP,"ijmp"); break; + case O_JMP : if(NOSUP(S_JMP )) warning(W_UNSUP,"jmp"); break; + case O_LD : if(NOSUP(S_LD )) warning(W_UNSUP,"ld"); break; + case O_LDD : if(NOSUP(S_LDD )) warning(W_UNSUP,"ldd"); break; + case O_LDS : if(NOSUP(S_LDS )) warning(W_UNSUP,"lds"); break; + case O_LPM : if(NOSUP(S_LPM )) warning(W_UNSUP,"lpm"); break; + case O_MUL : if(NOSUP(S_MUL )) warning(W_UNSUP,"mul"); break; + case O_PUSH : if(NOSUP(S_PUSH )) warning(W_UNSUP,"push"); break; + case O_POP : if(NOSUP(S_POP )) warning(W_UNSUP,"pop"); break; + case O_SBIW : if(NOSUP(S_SBIW )) warning(W_UNSUP,"sbiw"); break; + case O_ST : if(NOSUP(S_ST )) warning(W_UNSUP,"st"); break; + case O_STD : if(NOSUP(S_STD )) warning(W_UNSUP,"std"); break; + case O_STS : if(NOSUP(S_STS )) warning(W_UNSUP,"sts"); break; + case O_EIJMP : if(NOSUP(S_EIJMP )) warning(W_UNSUP,"eijmp"); break; + case O_EICALL : if(NOSUP(S_EICALL)) warning(W_UNSUP,"eicall"); break; + case O_ESPM : if(NOSUP(S_ESPM )) warning(W_UNSUP,"espm"); break; + case O_MULSU : if(NOSUP(S_MULSU )) warning(W_UNSUP,"mulsu"); break; + case O_FMUL : if(NOSUP(S_FMUL )) warning(W_UNSUP,"fmul"); break; + case O_FMULS : if(NOSUP(S_FMULS )) warning(W_UNSUP,"fmuls"); break; + case O_FMULSU : if(NOSUP(S_FMULSU)) warning(W_UNSUP,"fmulsu"); break; + case O_MULS : if(NOSUP(S_MULS )) warning(W_UNSUP,"muls"); break; + case O_MOVW : if(NOSUP(S_MOVW )) warning(W_UNSUP,"movw"); break; + case O_ELPM : if(NOSUP(S_ELPM )) warning(W_UNSUP,"elpm"); break; + case O_SPM : if(NOSUP(S_SPM )) warning(W_UNSUP,"spm"); break; + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Insert instruction into code segment + // + +#ifdef _MSC_VER /* Nick */ +void insertInst(int v, int s) +#else +void insertInst(long v, int s) +#endif +{ + if(yysegment==SEGMENT_DATA) + error(E_PROGRAM_IN_DSEG); + else if(yysegment==SEGMENT_EEPROM) + error(E_PROGRAM_IN_DSEG); + else + { + if(s==1) + { + insertcode( (v & 0x000000FF) >> 0); + } + else if(s==2) + { +#ifdef _MSC_VER /* Nick */ + insertcode( (v & 0x000000FF) >> 0); + insertcode( (v & 0x0000FF00) >> 8); +#else + insertcode( (v & 0x000000FFL) >> 0); + insertcode( (v & 0x0000FF00L) >> 8); +#endif + } + else if(s==4) + { +#ifdef _MSC_VER /* Nick */ + insertcode( (v & 0x000000FF) >> 0); + insertcode( (v & 0x0000FF00) >> 8); + insertcode( (v & 0x00FF0000) >> 16); + insertcode( (v & 0xFF000000) >> 24); +#else + insertcode( (v & 0x000000FFL) >> 0); + insertcode( (v & 0x0000FF00L) >> 8); + insertcode( (v & 0x00FF0000L) >> 16); + insertcode( (v & 0xFF000000L) >> 24); +#endif + } + else + internalerror("GG %08X %08X",v,s); + + if(s==1) + sprintf(yylinetxt,"?????? %02X%02X ", + yycodebuf[yycodepos-1], yycodebuf[yycodepos-2]); + else if(s==2) + sprintf(yylinetxt,"%06X %02X%02X ", (yycodepos-2)/2, + yycodebuf[yycodepos-1], yycodebuf[yycodepos-2]); + else if(s==4) + sprintf(yylinetxt,"%06X %02X%02X %02X%02X", (yycodepos-4)/2, + yycodebuf[yycodepos-3], yycodebuf[yycodepos-4], + yycodebuf[yycodepos-1], yycodebuf[yycodepos-2]); + else + internalerror("PH %08X %08X",v,s); + } +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report warning at end of line + // + +int warning(int warnno, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + if(!yyparseno || !warnno) + return FALSE; /* Nick false; */ + + yywarningcount++; + + if(!yycfg -> warnings) + return FALSE; /* Nick false; */ + + if( (yywarningline==yyline-!ISMACRO) && !ISMACRO ) + return FALSE; /* Nick false; */ + + yywarningline = yyline-!ISMACRO; + + if( (warnno<1) || (warnno>MESSAGES_WARNING) ) + internalerror("WW %04X", warnno); + + va_start(args, warnno); + vsprintf(errtext, messages[warnno], args); + va_end(args); + + if(yyinmacro) + printf("%s:%i: Warning in macro : %s\n",yyfilename, + yyline-!ISMACRO,errtext); + else + printf("%s:%i: Warning : %s\n",yyfilename,yyline-!ISMACRO,errtext); + + if(yylogfile) + { + if(yyinmacro) + fprintf(yylogfile, "%s:%i: Warning in macro : %s\n",yyfilename, + yyline-!ISMACRO,errtext); + else + fprintf(yylogfile, "%s:%i: Warning : %s\n",yyfilename, + yyline-!ISMACRO,errtext); + } + + STRIPNR(yyinlineold); + + printf("%s:%i: \'%s\'\n",yyfilename,yyline-!ISMACRO,yyinlineold); + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report warning inline + // + +int warningin(int warnno, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + if(!yyparseno || !warnno) + return FALSE; /* Nick false; */ + + yywarningcount++; + + if(!yycfg -> warnings) + return FALSE; /* Nick false; */ + + if( (yywarningline==yyline) && !ISMACRO ) + return FALSE; /* Nick false; */ + + yywarningline = yyline; + + if( (warnno<1) || (warnno>MESSAGES_WARNING) ) + internalerror("WI %04X", warnno); + + va_start(args, warnno); + vsprintf(errtext, messages[warnno], args); + va_end(args); + + if(yyinmacro) + printf("%s:%i: Warning in macro : %s\n",yyfilename,yyline,errtext); + else + printf("%s:%i: Warning : %s\n",yyfilename,yyline,errtext); + + if(yylogfile) + { + if(yyinmacro) + fprintf(yylogfile, "%s:%i: Warning in macro : %s\n",yyfilename, + yyline,errtext); + else + fprintf(yylogfile, "%s:%i: Warning : %s\n",yyfilename,yyline,errtext); + } + + STRIPNR(yyinline); + + printf("%s:%i: \'%s\'\n",yyfilename,yyline,yyinline); + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report error at end of line + // + +int error(int errorno, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + if(!yyparseno) + return FALSE; /* Nick false; */ + + if( (yyerrorline == yyline- !ISMACRO) && !ISMACRO ) + return FALSE; /* Nick false; */ + + yyerrorline = yyline - !ISMACRO; + + yyerrorcount++; + + if( (errorno<1) || (errorno>MESSAGES_ERROR) ) + internalerror("EE %04X", errorno); + + errorno += MESSAGES_WARNING; + + va_start(args, errorno); + vsprintf(errtext, messages[errorno], args); + va_end(args); + + if(yyinmacro) + printf("%s:%i: Error in macro : %s\n",yyfilename,yyline-!ISMACRO,errtext); + else + printf("%s:%i: Error : %s\n",yyfilename,yyline-!ISMACRO,errtext); + + if(yylogfile) + { + if(yyinmacro) + fprintf(yylogfile, "%s:%i: Error in macro : %s\n",yyfilename, + yyline-!ISMACRO,errtext); + else + fprintf(yylogfile, "%s:%i: Error : %s\n",yyfilename, + yyline-!ISMACRO,errtext); + } + + STRIPNR(yyinlineold); + + printf("%s:%i: \'%s\'\n",yyfilename,yyline-!ISMACRO,yyinlineold); + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report error inline + // + +int errorin(int errorno, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + if(!yyparseno) + return FALSE; /* Nick false; */ + + if( (yyerrorline == yyline) && !ISMACRO ) + return FALSE; /* Nick false; */ + + yyerrorline = yyline; + + yyerrorcount++; + + if( (errorno<1) || (errorno>MESSAGES_ERROR) ) + internalerror("EI %04X", errorno); + + errorno += MESSAGES_WARNING; + + va_start(args, errorno); + vsprintf(errtext, messages[errorno], args); + va_end(args); + + if(yyinmacro) + printf("%s:%i: Error in macro : %s\n",yyfilename,yyline,errtext); + else + printf("%s:%i: Error : %s\n",yyfilename,yyline,errtext); + + STRIPNR(yyinline); + + printf("%s:%i: \'%s\'\n",yyfilename,yyline,yyinline); + + if(yylogfile) + { + if(yyinmacro) + fprintf(yylogfile, "%s:%i: Error in macro : %s\n",yyfilename,yyline,errtext); + else + fprintf(yylogfile, "%s:%i: Error : %s\n",yyfilename,yyline,errtext); + } + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Print a message + // + +int message(int msgno, ...) +{ + va_list args; + char msgtext[MAX_LINE_LENGTH+1]; + + msgno += MESSAGES_WARNING + MESSAGES_ERROR + MESSAGES_FATAL + 2; + + va_start(args, msgno); + vsprintf(msgtext, messages[msgno], args); + va_end(args); + + printf("%s\n",msgtext); + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report fatal error and exit(1) + // + +void errorexit(int errorno, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + if( (errorno<1) || (errorno>MESSAGES_FATAL) ) + internalerror("EX %04X", errorno); + + errorno += MESSAGES_WARNING + MESSAGES_ERROR + 1; + + va_start(args, errorno); + vsprintf(errtext, messages[errorno], args); + va_end(args); + + printf("Program terminated - %s\n",errtext); + exit(1); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Report internal error and exit(2) + // + +void internalerror(char const *fmt, ...) +{ + va_list args; + char errtext[MAX_LINE_LENGTH+1]; + + va_start(args, fmt); + vsprintf(errtext, fmt, args); + va_end(args); + + sprintf(errtext+strlen(errtext)," %s",VERSIONSTR); + + while(strlen(errtext)<57) + strcat(errtext," "); + + printf("\n"); + printf(" ************************************************************\n"); + printf(" * *\n"); + printf(" * Internal compiler error !!! *\n"); + printf(" * *\n"); + printf(" * Please note the error text and report to Tom : *\n"); + printf(" * *\n"); + printf(" * %s*\n",errtext); + printf(" * *\n"); + printf(" ************************************************************\n"); + exit(2); +} + + //////////////////////////////////////////////////////////////////////////// + // + // Add line to log file + // + +void tolog(void) +{ + int c; + char temp[MAX_LINE_LENGTH+100]; + char sp[]=" |\n"; + static int rompos = 0; + static int codepos = 0; + static int rampos = 0; + + // Check alignment ///////////////////////////////////////////////////////// + + if( (yysegment==SEGMENT_CODE) && (yycodepos&1) && (yycfg->aligndb) ) { + yyline-=(ISMACRO==0); + insertdbdw(0); + yyline+=(ISMACRO==0); + } + + // Return if first parse /////////////////////////////////////////////////// + + if(!yyparseno) + return; + + // Check if eeprom/flash size has been exceeded //////////////////////////// + + if( (yycodepos > DEVINF.flashsize*2) && (yycodepos != codepos) ) { + warning(W_FLASH_EXCEEDED,(yycodepos-DEVINF.flashsize*2)/2); + codepos = yycodepos; + } + + if( (yyerompos > DEVINF.eepromsize) && (yyerompos!=rompos) ) { + warning(W_EROM_EXCEED,yyerompos-DEVINF.eepromsize); + rompos = yyerompos; + } + + if( (yydatapos > DEVINF.datastart+DEVINF.ramsize) && (yydatapos!=rampos)) { + warning(W_SRAM_EXCEED,yydatapos-(DEVINF.datastart+DEVINF.ramsize)); + rampos = yydatapos; + } + + // Clean-up log line /////////////////////////////////////////////////////// + + STRIPNR(yyinlineold); + exptabs(yyinlineold); + + CUT; + + /// Check if this line was a '.db' or '.dw' //////////////////////////////// + + if(yydefinestart!=-1) + { + if(yysegment == SEGMENT_CODE) + { + if( (yycodepos & 1) && ( yycfg -> aligndb ) ) + { + yyline-=(ISMACRO==0); + insertdbdw(0); + yyline+=(ISMACRO==0); + } + + if(!ISMACRO && (yycodeline[yycodepos-2]==yyline) ) + yycodeline[yycodepos-2]--; + + if(yylist && yylogfile && !(yyinmacro && !yylistmacro)) + { + sprintf(temp,"%06X ", yydefinestart/2); + + for(c=0;c<((yycodepos-yydefinestart)&3);c++) /* Nick added paren */ + { + sprintf(temp+strlen(temp),"%02X",yycodebuf[yydefinestart+c]); + if(c&1) + strcat(temp," "); + } + + strcat(temp," "); + temp[16] = '\0'; + + CUT; + + fprintf(yylogfile,"| %s %c %s\n",temp,SEP,yyinlineold); + + if(yycodepos-yydefinestart>3) + { + for(c=0;c< (yycodepos-yydefinestart)-4;c++) + { + if(c%4 == 0) + sprintf(temp,"%06X ",(c+4+yydefinestart)/2); + + sprintf(temp+strlen(temp),"%02X",yycodebuf[yydefinestart+c+4]); + if(c&1) + strcat(temp," "); + if( (c%4 == 3) && c) + { + strcat(temp," "); + temp[16] = '\0'; + + fprintf(yylogfile,"| %s %c",temp,SEP); + if( yycfg -> cutlog) + fprintf(yylogfile, sp); + else + fprintf(yylogfile,"\n"); + } + } + } + if( (yycodepos-yydefinestart>4) && (c%4 != 0) ) + { + strcat(temp," "); + temp[16] = '\0'; + fprintf(yylogfile,"| %s %c",temp,SEP); + if( yycfg -> cutlog) + fprintf(yylogfile, sp); + else + fprintf(yylogfile,"\n"); + } + } + } + else if(yysegment == SEGMENT_EEPROM) + { + if(yylist && yylogfile && !(yyinmacro && !yylistmacro)) + { + if(yydefinetype!=SEGMENT_DEFINE_BYTE) + { + c = yydefinestart; + CUT; + fprintf(yylogfile,"| %06X %02X EEPROM %c %s\n", c, + yyerombuf[c],SEP,yyinlineold); + for(c++;c cutlog) + fprintf(yylogfile, sp); + else + fprintf(yylogfile,"\n"); + } + } + else + { + CUT; + fprintf(yylogfile, "| %06X EEPROM %c %s\n",yydefinestart, + SEP,yyinlineold); + yydefinetype = 0; + } + } + } + else if(yysegment == SEGMENT_DATA) + { + if(yylist && yylogfile && !(yyinmacro && !yylistmacro)) + { + c = yydefinestart; + CUT; + fprintf(yylogfile, "| %06X -DATA- %c %s\n", c, SEP,yyinlineold); + } + } + else + internalerror("LI %04X",yysegment); + } + + /// No it is a regular instruction ///////////////////////////////////////// + + else + { + if(yyinmacro) + { + if((yylistmacro||yyfirstmacroline) && yylist && yylogfile) + { + if( strlen(yylinetxt) ) + { + CUT; + fprintf(yylogfile,"| %s > %s\n",yylinetxt,yyinlineold); + } + else if(yyfirstmacroline) + { + CUT; + fprintf(yylogfile,"| %06X > %s\n",yycodepos/2,yyinlineold); + } + else + { + CUT; + fprintf(yylogfile,"| > %s\n",yyinlineold); + } + } + } + else + { + if(yylist && yylogfile) + { + if( strlen(yylinetxt) ) + { + CUT; + fprintf(yylogfile, "| %s | %s\n",yylinetxt,yyinlineold); + } + else if(!(yyinmacrodef && !yylistmacro)) + { + CUT; + fprintf(yylogfile, "| | %s\n",yyinlineold); + } + } + } + } + + yylinetxt[0] = 0; + yydefinestart = -1; + yyfirstmacroline = FALSE; /* Nick false; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Strip comment from line + // + +int striprem(char *str) +{ + int l = 0; + int rem = FALSE; /* Nick false; */ + char *pos; + + if( (pos=strpbrk(str,"\r\n")) ) + *pos = '\0'; + + while(str[l]) + { + if( (str[l]=='"') || (str[l]=='\'') ) + rem ? rem = FALSE /* Nick false */ : rem = TRUE; /* Nick true; */ + else if( str[l]=='\\' ) + { + if(str[l+1]) + l++; + } + else if ( (str[l]==';') && !rem) + str[l--] = '\0'; + l++; + } + + l = strlen(str); + + if(l) + while(--l, ((str[l]==' ')||(str[l]=='\t'))) + str[l] = '\0'; + + return l; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Expand tabs in string + // + +int exptabs(char *str) +{ + int l = strlen(str); + int c = 0; + char *temp; + + /// Expand tabs /////////////////////////////////////////////////////////// + + if(l) + { + if(!(temp = new char[strlen(str)+1])) + { +#ifdef DEBUG /* Nick */ + printf("Nick error 1\n"); + fflush(stdout); +#endif + errorexit(X_OUT_OF_MEMORY); + } + + strcpy(temp, str); + c = l = 0; + while(temp[l] && (c<(MAX_LINE_LENGTH-10))) + { + if(temp[l]=='\t') + { + if(temp[l]=='\t') + str[c++]=' '; + while((c%8)!=0) + str[c++]=' '; + l++; + if(temp[l]=='\t') + str[c++]=' '; + } + else + str[c++]=temp[l++]; + } + str[c] = '\0'; + delete temp; + } + return c; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Get file.name from "file.name" or + // + +int getfilename(char *name, char *newname) +{ + + if( (name[0]!='"') || (name[strlen(name)-1]!='"') ) + { + if( (name[0]!='<') || (name[strlen(name)-1]!='>') ) + return FALSE; /* Nick false; */ + else + { + memmove(name,name+1,strlen(name)-1); + name[strlen(name)-2] = 0; + + // Search include tree here - XXX + + strcpy(newname, name); + } + + if(!strlen(newname)) + return FALSE; /* Nick false; */ + } + else + { + memcpy(newname,name+1,strlen(name)-1); + newname[strlen(name)-2] = 0; + } + + if(strlen(newname)>MAX_FILENAME_LENGTH) + { + errorin(E_FILENAME_TOO_LONG); + return FALSE; /* Nick false; */ + } + + return TRUE; /* Nick true; */ +} + + //////////////////////////////////////////////////////////////////////////// + // + // Check that filename is valid + // + +int checkfilename(char *name) +{ + return 1; + + int c = strlen(name); + int valid = TRUE; /* Nick true; */ + + while(name[c]) + if( ! isalnum(name[c++]) ) + valid = FALSE; /* Nick false; */ + + return valid; +} + + //////////////////////////////////////////////////////////////////////////// + // + // Open a file somewhere in the "include path". Try in the current dir first. + // + +FILE * fopenInIncpath(const char *name, const char *mode) +{ + FILE *fp = fopen(name, mode); + + if(fp) + return fp; + + if (MAX_FILENAME_LENGTH <= strlen(name)) + errorin(E_FILENAME_TOO_LONG); + else + { + int c; + + for(c=0; !fp && (cMAX_FILENAME_LENGTH) + continue; + char *slash = strrchr(path, '/'); + char file[2 * MAX_FILENAME_LENGTH + 3]; + sprintf(file, "%s%s%s", path, (slash && !slash[1]) ? "" : "/", name); + fp = fopen(file, mode); + } + } + + return fp; +} + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/tavrasm.118/src/utils.hh b/src/mkutil/tavrasm.118/src/utils.hh new file mode 100644 index 00000000..90d568b2 --- /dev/null +++ b/src/mkutil/tavrasm.118/src/utils.hh @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////// +// +// File : utils.hh +// +// Author : Tom Mortensen - Copyright (C) 1999 +// +// Description : Utility header +// +// History +// ======================================================================== +// +// 980902 : Tom - File created. +// 990124 : Tom - Added GPL notice. +// 001101 : Brian Rhodefer - Added "fopenInIncpath()" +// +//////////////////////////////////////////////////////// Tom did this //////// +// +// Copyright notice: +// +// tavrasm - A GNU/Linux assembler for the Atmel AVR series +// of microcontrollers. Copyright (C) 1999 Tom Mortensen +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Tom Mortensen +// +// E-mail : tom@tavrasm.org +// WWW : http://www.tavrasm.org +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef _UTILS_HH_ +#define _UTILS_HH_ + +/// Include ////////////////////////////////////////////////////////////////// + +#include "symbol.hh" +#include + +/// Prototypes /////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER /* Nick */ +void insertInst(int v, int s); +#else +void insertInst(long v, int s); +#endif +void checkSupported(int opcode); +symbolTableEntry* getsym(char *name); +void insertcode(int val); +void insertdbdw(int val); +void insertdata(int val); +FILE * fopenInIncpath(const char *name, const char *mode); + + /// Error handling /////////////////////////////////////////////////////// + +int error(int errorno, ...); +int errorin(int errorno, ...); +int warning(int warnno, ...); +int warningin(int warnno, ...); +void errorexit(int errorno, ...); +void internalerror(char const *fmt, ...); +int message(int msgno, ...); + + /// Strip comments /////////////////////////////////////////////////////// + +void tolog(void); +int getfilename(char *name, char *newname); +int striprem(char *str); +int exptabs(char *str); +int checkfilename(char *name); + +#endif /* _UTILS_HH_ */ + +/// END OF FILE ////////////////////////////////////////////////////////////// + diff --git a/src/mkutil/touch.exe b/src/mkutil/touch.exe index a607f979711785e655f70c3e785a92e775023bb1..84db3811603fd4ae226377008bc68c8b7cf9aa8c 100644 GIT binary patch delta 18750 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 SdUYenONGKQ3&gnIN&g%AAv~V| delta 14221 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 diff --git a/src/sh/msh/closedir.c b/src/sh/msh/closedir.c new file mode 100644 index 00000000..fe241251 --- /dev/null +++ b/src/sh/msh/closedir.c @@ -0,0 +1,31 @@ +/* closedir.c closedir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +/* don't bother freeing anything, since msh doesn't like sharing its heap */ + +int nick_closedir(DIR *dir) +{ + if (dir == NULL || dir->dd_buf == NULL || dir->dd_fd == 0) { + errno = EFAULT; + return -1; + } + close(dir->dd_fd); +#if 0 + free(dir->dd_buf); +#endif + dir->dd_fd = 0; + dir->dd_buf = NULL; +#if 0 + free(dir); +#endif + return 0; +} + diff --git a/src/sh/msh/closedir.rel b/src/sh/msh/closedir.rel new file mode 100644 index 00000000..f70b0d85 --- /dev/null +++ b/src/sh/msh/closedir.rel @@ -0,0 +1,49 @@ +XL4 +H 2 areas 8 global symbols +M closedir +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S close Ref00000000 +S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S errno Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 5B flags 0 +S nick_closedir Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 7B B2 28 1A 21 +R 00 00 01 00 02 05 02 00 +T 08 00 00 00 06 00 DD 4E 02 DD 46 03 09 7E 23 +R 00 00 01 00 +T 13 00 00 00 B6 28 0B DD 6E 02 DD 66 03 7E 23 +R 00 00 01 00 +T 1E 00 00 00 B6 20 0B +R 00 00 01 00 +T 21 00 00 00 +R 00 00 01 00 +T 21 00 00 00 +R 00 00 01 00 +T 21 00 00 00 +R 00 00 01 00 +T 21 00 00 00 21 0E 00 22 00 00 00 00 21 FF FF +R 00 00 01 00 02 08 04 00 +T 2A 00 00 00 18 2C +R 00 00 01 00 +T 2C 00 00 00 +R 00 00 01 00 +T 2C 00 00 00 DD 6E 02 DD 66 03 5E 23 56 3E +R 00 00 01 00 +T 36 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 01 00 02 09 01 00 +T 3B 00 00 00 00 00 00 00 DD 6E 02 DD 66 03 AF +R 00 00 01 00 02 04 03 00 +T 44 00 00 00 77 23 77 21 06 00 DD 4E 02 DD 46 +R 00 00 01 00 +T 4F 00 00 00 03 09 AF 77 23 77 21 00 00 +R 00 00 01 00 +T 58 00 00 00 +R 00 00 01 00 +T 58 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 00 00 diff --git a/src/sh/msh/msh.lnk b/src/sh/msh/msh.lnk index 6d248765..155534e3 100644 --- a/src/sh/msh/msh.lnk +++ b/src/sh/msh/msh.lnk @@ -16,3 +16,6 @@ sh3 sh4 sh5 sh6 +opendir +closedir +readdir diff --git a/src/sh/msh/msh.map b/src/sh/msh/msh.map index 0f32f356..9a7e2fec 100644 --- a/src/sh/msh/msh.map +++ b/src/sh/msh/msh.map @@ -10,14 +10,14 @@ Area Addr Size Decimal Bytes (Attributes) 00000000 l_CONST | 00000000 .__.ABS. | 00000000 ?CL64180L 00000000 ?CL64180B | 00000014 e__DEFAUL | 00000014 l__DEFAUL 00000185 l_RCODE | 00000520 l_CDATA0 | 00000520 l_IDATA0 - 00000530 l_CSTR | 000009C5 l_UDATA0 | 00001000 l_CSTACK + 000005E7 l_CSTR | 000009EB l_UDATA0 | 00001000 l_CSTACK 00004000 s_CODE | 00008100 s_RCODE | 00008285 s_CSTR 00008285 e_RCODE | 00008285 e_CONST | 00008285 s_CONST - 000087B5 e_CSTR | 000087B5 s_IDATA0 | 000087B5 s_CDATA0 - 00008CD5 s_UDATA0 | 00008CD5 e_CCSTR | 00008CD5 e_ECSTR - 00008CD5 s_CCSTR | 00008CD5 e_CDATA0 | 00008CD5 s_ECSTR - 00008CD5 e_IDATA0 | 0000969A e_UDATA0 | 0000969A s_CSTACK - 0000A69A e_CSTACK | 00018909 l_CODE | 0001C909 e_CODE + 0000886C e_CSTR | 0000886C s_IDATA0 | 0000886C s_CDATA0 + 00008D8C s_UDATA0 | 00008D8C e_CCSTR | 00008D8C e_ECSTR + 00008D8C s_CCSTR | 00008D8C e_CDATA0 | 00008D8C s_ECSTR + 00008D8C e_IDATA0 | 00009777 e_UDATA0 | 00009777 s_CSTACK + 0000A777 e_CSTACK | 000187BA l_CODE | 0001C7BA e_CODE Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) @@ -55,7 +55,7 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTR 00008285 00000530 = 1328. bytes (REL,CON) +CSTR 00008285 000005E7 = 1511. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -63,19 +63,19 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -IDATA0 000087B5 00000520 = 1312. bytes (NUL,CON) +IDATA0 0000886C 00000520 = 1312. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 000087B5 flag | 000087B7 elinep | 000087B9 null - 000087BB heedint | 000087BD env | 000087C9 shellname - 000087D1 search | 000087E0 qflag | 000087E5 restab - 00008CC7 temparg + 0000886C flag | 0000886E elinep | 00008870 null + 00008872 heedint | 00008874 env | 00008880 shellname + 00008888 search | 00008897 qflag | 0000889C restab + 00008D7E temparg Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CDATA0 000087B5 00000520 = 1312. bytes (REL,CON) +CDATA0 0000886C 00000520 = 1312. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -83,7 +83,7 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -ECSTR 00008CD5 00000000 = 0. bytes (NUL,CON) +ECSTR 00008D8C 00000000 = 0. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -91,7 +91,7 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CCSTR 00008CD5 00000000 = 0. bytes (REL,CON) +CCSTR 00008D8C 00000000 = 0. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -99,26 +99,26 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CODE 00004000 00018909 = 100617. bytes (NUL,CON) +CODE 00004000 000187BA = 100282. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00004BE9 main | 00005266 setdash | 000052C9 newfile - 00005346 onecomman | 000054A6 fail | 000054BC leave - 000054FA warn | 00005539 err | 0000558B newenv - 000055F6 quitenv | 00005656 anys | 00005693 any - 000056C9 putn | 000056DA sh_itoa | 00005785 next - 000057A3 onintr | 000057FD letter | 0000584E digit - 00005876 letnum | 000058A2 space | 000058D3 strsave - 0000594C xfree | 0000595A sig | 0000597D runtrap - 000059D4 lookup | 00005BE8 setval | 00005BFB nameval - 00005DCC export | 00005DDA ronly | 00005E04 isassign - 00005E5B assign | 00005F24 checkname | 00005F78 putvlist - 0000606D eqname | 000060F9 gmatch | 0000632D initarea - 0000637D getcell | 00006571 freecell | 000065BE freearea - 0000661F setarea | 0000664C getarea | 0000665C garbage - 000066E9 yyparse | 0000700D rlookup | 00007250 yyerror - 00007616 collect | 000076D0 dual | 0000782A printf + 00004CA0 main | 0000531D setdash | 00005380 newfile + 000053FD onecomman | 0000555D fail | 00005573 leave + 000055B1 warn | 000055F0 err | 00005642 newenv + 000056AD quitenv | 0000570D anys | 0000574A any + 00005780 putn | 00005791 sh_itoa | 0000583C next + 0000585A onintr | 000058B4 letter | 00005905 digit + 0000592D letnum | 00005959 space | 0000598A strsave + 00005A03 xfree | 00005A11 sig | 00005A34 runtrap + 00005A8B lookup | 00005C9F setval | 00005CB2 nameval + 00005E83 export | 00005E91 ronly | 00005EBB isassign + 00005F12 assign | 00005FDB checkname | 0000602F putvlist + 00006124 eqname | 000061B0 gmatch | 000063E4 initarea + 00006434 getcell | 000066B4 freecell | 00006701 freearea + 00006762 setarea | 0000678F getarea | 0000679F garbage + 0000682C yyparse | 00007150 rlookup | 00007393 yyerror + 00007759 collect | 00007813 dual | 0000796D printf 00014000 execute | 00014C48 iosetup | 00015097 waitfor 00015277 setstatus | 000152AB rexecve | 00015493 run 000155A1 dolabel | 000155A7 dochdir | 00015633 doshift @@ -131,68 +131,71 @@ CODE 00004000 00018909 = 100617. bytes (NUL,CON) 0001640C dotimes | 00016412 inbuilt | 0001646C eval 00016612 makenv | 00016696 evalstr | 00016B22 subgetc 0001715C unquote | 00017198 glob | 0001747D globname - 000178F9 newword | 00017936 addword | 00017A05 getwords - 00017A92 glob0 | 00017ACD glob1 | 00017D8F glob2 - 00017DF2 glob3 | 00017E7C memcopy | 00024000 getc + 00017905 newword | 00017942 addword | 00017A11 getwords + 00017A9E glob0 | 00017AD9 glob1 | 00017D9B glob2 + 00017DFE glob3 | 00017E88 memcopy | 00024000 getc 000240B8 unget | 000240DA eofc | 0002410A readc 00024259 ioecho | 00024281 pushio | 00024460 setbase 0002447B nlchar | 000244C4 wdchar | 00024535 dolchar 000245E5 strchar | 0002461F qstrchar | 0002465F filechar 00024828 herechar | 00024874 gravechar | 000248AC qgravecha - 0002498D linechar | 000249DA prs | 00024A07 putc - 00024A23 prn | 00024A3D closef | 00024A5B closeall - 00024A94 remap | 00024B7A openpipe | 00024BAB closepipe - 00024BE1 markhere | 00024D28 gethere | 00024FB9 herein - 00025104 scraphere | 0002517C freehere | 00025246 tempname - 000252D2 execve | 000252F1 unix | 0002530B dup - 00025320 chdir | 00025335 _write | 00025354 creat - 0002536B unlink | 00025380 strncpy | 000253FF setjmp - 00025429 lseek | 00025456 closedir | 000254CC close - 000254E1 abort | 0002554F strlen | 00025586 _exit - 0002559B strcmp | 000255F2 readdir | 000256D5 pause - 000256E5 isatty | 00025720 umask | 0002573A fstat - 00025751 free | 00025831 geteuid | 00025846 kill - 0002585D pipe | 00025872 opendir | 00025953 fork + 0002498D linechar | 000249DA prs | 00024A07 prs_expan + 00024B86 putc | 00024BA2 prn | 00024BBC closef + 00024BDA closeall | 00024C13 remap | 00024CF9 openpipe + 00024D2A closepipe | 00024D60 markhere | 00024EA7 gethere + 00025138 herein | 00025283 scraphere | 000252FB freehere + 000253C5 tempname | 00025451 nick_open | 000254E6 nick_clos + 00025541 nick_read | 00025624 execve | 00025643 unix + 0002565D dup | 00025672 getenv | 00025723 chdir + 00025738 _write | 00025757 creat | 0002576E unlink + 00025783 strncpy | 00025802 setjmp | 0002582C lseek + 00025859 uname | 00025917 close | 0002592C strlen + 00025963 strcmp | 000259BA isatty | 000259F5 umask + 00025A0F fstat | 00025A26 free | 00025B06 strcpy + 00025B2D geteuid | 00025B42 pipe | 00025B57 fork Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CODE 00004000 00018909 = 100617. bytes (NUL,CON) +CODE 00004000 000187BA = 100282. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00025963 waitpid | 00025982 open | 000259AD sbrk - 000259C2 longjmp | 000259ED exit | 00025A1D _read - 00025A3C dup2 | 00025A53 stat | 00025A6A getpid - 00025A7F signal | 00025AA4 malloc | 00025CD0 unix_long - 00025CEA calloc | 00025D32 memset + 00025B67 waitpid | 00025B86 open | 00025BB1 sbrk + 00025BC6 longjmp | 00025BF1 exit | 00025C21 _read + 00025C40 dup2 | 00025C57 stat | 00025C6E getpid + 00025EC8 getcwd | 00025F25 signal | 00025F4A memcmp + 00025FB7 getfsys | 00025FCE malloc | 000261FA memcpy + 0002624C strcat | 0002626C unix_long | 00026286 closedir + 000262FC _exit | 00026311 readdir | 000263F4 opendir + 000264D5 calloc | 0002651D memset Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -UDATA0 00008CD5 000009C5 = 2501. bytes (REL,CON) +UDATA0 00008D8C 000009EB = 2539. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00008CD5 _argc | 00008CD7 _argv | 00008CD9 environ - 00008CDB errno | 00008CDD __cleanup | 00008CE0 intr - 00008CE2 inparse | 00008CE4 flags | 00008D2B func - 00008D2E globv | 00008D36 dolv | 00008D38 dolc - 00008D3A exstat | 00008D3C gflg | 00008D3D talking - 00008D3F execflg | 00008D41 multiline | 00008D43 outtree - 00008D45 failpt | 00008D47 errpt | 00008D49 brklist - 00008D4B isbreak | 00008D4D wdlist | 00008D4F iolist - 00008D51 trap | 00008D73 ourtrap | 00008D84 trapset - 00008D86 yynerrs | 00008D88 line | 000095BC vlist - 000095BE homedir | 000095C0 prompt | 000095C2 cprompt - 000095C4 path | 000095C6 shell | 000095C8 ifs - 000095CA ioargstac | 0000963A iostack | 00009692 areanum - 00009694 __malloc_ | 00009698 __malloc_ + 00008D8C _argc | 00008D8E _argv | 00008D90 environ + 00008D92 errno | 00008D94 __cleanup | 00008D97 intr + 00008D99 inparse | 00008D9B flags | 00008DE2 func + 00008DE5 globv | 00008DED dolv | 00008DEF dolc + 00008DF1 exstat | 00008DF3 gflg | 00008DF4 talking + 00008DF6 execflg | 00008DF8 multiline | 00008DFA outtree + 00008DFC failpt | 00008DFE errpt | 00008E00 brklist + 00008E02 isbreak | 00008E04 wdlist | 00008E06 iolist + 00008E08 trap | 00008E2A ourtrap | 00008E3B trapset + 00008E3D yynerrs | 00008E3F line | 00009673 vlist + 00009675 homedir | 00009677 prompt | 00009679 cprompt + 0000967B path | 0000967D shell | 0000967F ifs + 00009681 ioargstac | 000096F1 iostack | 00009749 areanum + 00009771 __malloc_ | 00009775 __malloc_ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTACK 0000969A 00001000 = 4096. bytes (REL,CON) +CSTACK 00009777 00001000 = 4096. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -206,6 +209,9 @@ sh3 [ sh3 ] sh4 [ sh4 ] sh5 [ sh5 ] sh6 [ sh6 ] +opendir [ opendir ] +closedir [ closedir ] +readdir [ readdir ] Libraries Linked [ object file ] @@ -214,6 +220,7 @@ Libraries Linked [ object file ] ..\..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] ..\..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] ..\..\..\lib\libsysb.lib [ relsysb\dup.rel ] +..\..\..\lib\libcb.lib [ relcb\getenv.rel ] ..\..\..\lib\libsysb.lib [ relsysb\chdir.rel ] ..\..\..\lib\libsysb.lib [ relsysb\write.rel ] ..\..\..\lib\libiar.lib [ reliar\SMUL.rel ] @@ -222,32 +229,27 @@ Libraries Linked [ object file ] ..\..\..\lib\libcb.lib [ relcb\strncpy.rel ] ..\..\..\lib\libcb.lib [ relcb\setjmpb.rel ] ..\..\..\lib\libsysb.lib [ relsysb\lseek.rel ] -..\..\..\lib\libcb.lib [ relcb\closedir.rel ] +..\..\..\lib\libcb.lib [ relcb\utsname.rel ] ..\..\..\lib\libsysb.lib [ relsysb\close.rel ] -..\..\..\lib\libcb.lib [ relcb\abort.rel ] ..\..\..\lib\libcb.lib [ relcb\strlen.rel ] -..\..\..\lib\libsysb.lib [ relsysb\_exit.rel ] ..\..\..\lib\libcb.lib [ relcb\strcmp.rel ] ..\..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] ..\..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] -..\..\..\lib\libcb.lib [ relcb\readdir.rel ] -..\..\..\lib\libsysb.lib [ relsysb\pause.rel ] ..\..\..\lib\libcb.lib [ relcb\isatty.rel ] ..\..\..\lib\libsysb.lib [ relsysb\umask.rel ] ..\..\..\lib\libsysb.lib [ relsysb\fstat.rel ] ..\..\..\lib\libcb.lib [ relcb\free.rel ] ..\..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] ..\..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\..\lib\libcb.lib [ relcb\strcpy.rel ] ..\..\..\lib\libiar.lib [ reliar\SSSWITCH.rel ] ..\..\..\lib\libsysb.lib [ relsysb\geteuid.rel ] ..\..\..\lib\libiar.lib [ reliar\SVSWITCH.rel ] ..\..\..\lib\libiar.lib [ reliar\SSWITCHEND.rel ] -..\..\..\lib\libsysb.lib [ relsysb\kill.rel ] ..\..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] ..\..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] ..\..\..\lib\libiar.lib [ reliar\LINCASG.rel ] ..\..\..\lib\libsysb.lib [ relsysb\pipe.rel ] -..\..\..\lib\libcb.lib [ relcb\opendir.rel ] ..\..\..\lib\libiar.lib [ reliar\SSCMP.rel ] ..\..\..\lib\libiar.lib [ reliar\USDIVASG.rel ] ..\..\..\lib\libiar.lib [ reliar\LINC.rel ] @@ -265,15 +267,24 @@ Libraries Linked [ object file ] ..\..\..\lib\libsysb.lib [ relsysb\dup2.rel ] ..\..\..\lib\libsysb.lib [ relsysb\stat.rel ] ..\..\..\lib\libsysb.lib [ relsysb\getpid.rel ] +..\..\..\lib\libcb.lib [ relcb\getcwd.rel ] ..\..\..\lib\libiar.lib [ reliar\SSRSH.rel ] ..\..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] ..\..\..\lib\libsysb.lib [ relsysb\signal.rel ] +..\..\..\lib\libcb.lib [ relcb\memcmp.rel ] ..\..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] +..\..\..\lib\libsysb.lib [ relsysb\getfsys.rel ] ..\..\..\lib\libiar.lib [ reliar\LENDASG.rel ] ..\..\..\lib\libcb.lib [ relcb\malloc.rel ] +..\..\..\lib\libcb.lib [ relcb\memcpy.rel ] +..\..\..\lib\libcb.lib [ relcb\strcat.rel ] ..\..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] -..\..\..\lib\libcb.lib [ relcb\calloc.rel ] +..\..\..\lib\libcb.lib [ relcb\closedir.rel ] +..\..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\..\lib\libcb.lib [ relcb\readdir.rel ] ..\..\..\lib\libiar.lib [ reliar\SFINDSIGN.rel ] +..\..\..\lib\libcb.lib [ relcb\opendir.rel ] +..\..\..\lib\libcb.lib [ relcb\calloc.rel ] ..\..\..\lib\libcb.lib [ relcb\memset.rel ] diff --git a/src/sh/msh/n.bat b/src/sh/msh/n.bat index 917f65fb..f2bbbdc6 100644 --- a/src/sh/msh/n.bat +++ b/src/sh/msh/n.bat @@ -34,6 +34,24 @@ del sh6.r01 as-z80 -l -o sh6.s01 @if errorlevel 1 goto failure +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ opendir +@if errorlevel 1 goto failure +del opendir.r01 +as-z80 -l -o opendir.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ closedir +@if errorlevel 1 goto failure +del closedir.r01 +as-z80 -l -o closedir.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ readdir +@if errorlevel 1 goto failure +del readdir.r01 +as-z80 -l -o readdir.s01 +@if errorlevel 1 goto failure + link-z80 -f msh @if errorlevel 1 goto failure ihex2bin -l msh.i86 ..\..\..\bin\banked\msh diff --git a/src/sh/msh/opendir.c b/src/sh/msh/opendir.c new file mode 100644 index 00000000..4ee4de44 --- /dev/null +++ b/src/sh/msh/opendir.c @@ -0,0 +1,44 @@ +/* opendir.c opendir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +/* take some extra arguments, since msh doesn't like sharing its heap */ + +DIR *nick_opendir(char *path, DIR *dir, struct dirent *dd_buf) +{ + struct stat statbuf; + + if (stat(path, &statbuf) != 0) + goto Err; + if ((statbuf.st_mode & S_IFDIR) == 0) { + errno = ENOTDIR; + goto Err; + } +#if 1 + dir->dd_buf = dd_buf; +#else + if ((dir = (DIR *)calloc(1,sizeof(DIR))) == NULL) { + errno = ENOMEM; + goto Err; + } + if ((dir->dd_buf = calloc(1,sizeof(struct dirent))) == NULL) { + free(dir); + errno = ENOMEM; + goto Err; + } +#endif + if ((dir->dd_fd = open(path, O_BINARY)) < 0) { + free(dir->dd_buf); + free(dir); +Err: return NULL; + } + return dir; +} + diff --git a/src/sh/msh/opendir.rel b/src/sh/msh/opendir.rel new file mode 100644 index 00000000..4e22ad9e --- /dev/null +++ b/src/sh/msh/opendir.rel @@ -0,0 +1,77 @@ +XL4 +H 2 areas A global symbols +M opendir +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S free Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S errno Ref00000000 +S ?ENT_AUTO_DIRECT_L09 Ref00000000 +S open Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S stat Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size 95 flags 0 +S nick_opendir Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 E2 FF 21 00 00 39 +R 00 00 01 00 02 05 04 00 +T 09 00 00 00 4D 44 DD 5E 02 DD 56 03 3E +R 00 00 01 00 +T 12 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 17 00 00 00 00 00 00 00 7D B4 28 02 +R 00 00 01 00 02 04 02 00 +T 1D 00 00 00 +R 00 00 01 00 +T 1D 00 00 00 18 68 +R 00 00 01 00 +T 1F 00 00 00 +R 00 00 01 00 +T 1F 00 00 00 DD 7E E6 E6 00 47 DD 7E E7 E6 40 +R 00 00 01 00 +T 2A 00 00 00 B0 20 08 +R 00 00 01 00 +T 2D 00 00 00 +R 00 00 01 00 +T 2D 00 00 00 21 14 00 22 00 00 00 00 18 52 +R 00 00 01 00 02 08 03 00 +T 35 00 00 00 +R 00 00 01 00 +T 35 00 00 00 21 06 00 DD 4E 04 DD 46 05 09 DD +R 00 00 01 00 +T 40 00 00 00 5E 0A DD 56 0B 73 23 72 21 00 80 +R 00 00 01 00 +T 4B 00 00 00 E5 DD 6E 02 DD 66 03 E5 3E +R 00 00 01 00 +T 54 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 05 00 02 09 05 00 +T 59 00 00 00 00 00 00 00 F1 F1 E5 69 60 C1 71 +R 00 00 01 00 02 04 02 00 +T 62 00 00 00 23 70 CB 78 28 24 +R 00 00 01 00 +T 68 00 00 00 +R 00 00 01 00 +T 68 00 00 00 21 06 00 DD 4E 04 DD 46 05 09 5E +R 00 00 01 00 +T 73 00 00 00 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 01 00 +T 78 00 00 00 00 00 00 00 CD 00 00 00 00 59 50 +R 00 00 01 00 02 04 01 00 02 09 02 00 +T 7F 00 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 01 00 02 0A 01 00 +T 85 00 00 00 00 00 00 00 +R 00 00 01 00 02 04 02 00 +T 87 00 00 00 +R 00 00 01 00 +T 87 00 00 00 21 00 00 18 06 +R 00 00 01 00 +T 8C 00 00 00 +R 00 00 01 00 +T 8C 00 00 00 DD 6E 04 DD 66 05 +R 00 00 01 00 +T 92 00 00 00 +R 00 00 01 00 +T 92 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 00 00 diff --git a/src/sh/msh/readdir.c b/src/sh/msh/readdir.c new file mode 100644 index 00000000..e2ff879f --- /dev/null +++ b/src/sh/msh/readdir.c @@ -0,0 +1,33 @@ +/* readdir.c readdir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +struct dirent *nick_readdir(DIR *dir) +{ + direct_t direntry; + register struct dirent *buf; + + if (dir == NULL || dir->dd_buf == NULL || dir->dd_fd == 0) { + errno = EFAULT; +Err: return NULL; + } + direntry.d_name[0] = 0; + while (direntry.d_name[0] == 0) + if (read(dir->dd_fd, &direntry, sizeof(direntry)) != sizeof(direntry)) + goto Err; + buf = dir->dd_buf; + buf->d_ino = direntry.d_ino; + buf->d_off = dir->dd_loc++; + strncpy(buf->d_name, (char *)direntry.d_name, DIRNAMELEN); + buf->d_name[DIRNAMELEN] = 0; + buf->d_reclen = strlen(buf->d_name); + return buf; +} + diff --git a/src/sh/msh/readdir.rel b/src/sh/msh/readdir.rel new file mode 100644 index 00000000..c7715320 --- /dev/null +++ b/src/sh/msh/readdir.rel @@ -0,0 +1,95 @@ +XL4 +H 2 areas A global symbols +M readdir +S strncpy Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 +S strlen Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 +S errno Ref00000000 +S ?ENT_AUTO_DIRECT_L09 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 +S _read Ref00000000 +S .__.ABS. Def00000000 +A _DEFAULT size 0 flags 0 +A CODE size E3 flags 0 +S nick_readdir Def00000000 +T 00 00 00 00 +R 00 00 01 00 +T 00 00 00 00 CD 00 00 00 00 EE FF DD 7E 02 DD +R 00 00 01 00 02 05 05 00 +T 09 00 00 00 B6 03 28 1A 21 06 00 DD 4E 02 DD +R 00 00 01 00 +T 14 00 00 00 46 03 09 7E 23 B6 28 0B DD 6E 02 +R 00 00 01 00 +T 1F 00 00 00 DD 66 03 7E 23 B6 20 0C +R 00 00 01 00 +T 27 00 00 00 +R 00 00 01 00 +T 27 00 00 00 +R 00 00 01 00 +T 27 00 00 00 +R 00 00 01 00 +T 27 00 00 00 21 0E 00 22 00 00 00 00 +R 00 00 01 00 02 08 04 00 +T 2D 00 00 00 +R 00 00 01 00 +T 2D 00 00 00 21 00 00 C3 E0 00 00 00 +R 00 00 01 00 00 08 01 00 +T 33 00 00 00 +R 00 00 01 00 +T 33 00 00 00 DD 36 F0 00 +R 00 00 01 00 +T 37 00 00 00 +R 00 00 01 00 +T 37 00 00 00 DD 7E F0 B7 20 26 +R 00 00 01 00 +T 3D 00 00 00 +R 00 00 01 00 +T 3D 00 00 00 21 10 00 E5 21 02 00 39 4D 44 DD +R 00 00 01 00 +T 48 00 00 00 6E 02 DD 66 03 5E 23 56 3E +R 00 00 01 00 +T 51 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 56 00 00 00 00 00 00 00 F1 3E 10 AD B4 28 02 +R 00 00 01 00 02 04 03 00 +T 5F 00 00 00 +R 00 00 01 00 +T 5F 00 00 00 18 CC +R 00 00 01 00 +T 61 00 00 00 +R 00 00 01 00 +T 61 00 00 00 18 D4 +R 00 00 01 00 +T 63 00 00 00 +R 00 00 01 00 +T 63 00 00 00 21 06 00 DD 4E 02 DD 46 03 09 56 +R 00 00 01 00 +T 6E 00 00 00 23 66 6A DD 75 FE DD 74 FF DD 5E +R 00 00 01 00 +T 79 00 00 00 EE DD 56 EF 73 23 72 DD 6E FE DD +R 00 00 01 00 +T 84 00 00 00 66 FF 23 23 E5 69 60 23 23 4E 23 +R 00 00 01 00 +T 8F 00 00 00 46 03 70 2B 71 0B E1 71 23 70 21 +R 00 00 01 00 +T 9A 00 00 00 0E 00 E5 21 02 00 39 01 02 00 09 +R 00 00 01 00 +T A5 00 00 00 4D 44 21 06 00 DD 5E FE DD 56 FF +R 00 00 01 00 +T B0 00 00 00 19 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 00 00 +T B5 00 00 00 00 00 00 00 CD 00 00 00 00 F1 21 +R 00 00 01 00 02 04 00 00 02 09 03 00 +T BC 00 00 00 14 00 DD 4E FE DD 46 FF 09 36 00 +R 00 00 01 00 +T C7 00 00 00 21 04 00 09 E5 21 06 00 09 EB 3E +R 00 00 01 00 +T D2 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 02 00 02 09 02 00 +T D7 00 00 00 00 00 00 00 EB E1 73 23 72 69 60 +R 00 00 01 00 02 04 03 00 +T E0 00 00 00 +R 00 00 01 00 +T E0 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 01 00 diff --git a/src/sh/msh/sh.h b/src/sh/msh/sh.h index c4cf37ec..3d51275f 100644 --- a/src/sh/msh/sh.h +++ b/src/sh/msh/sh.h @@ -2,6 +2,7 @@ #include #include #include +#include /* Nick, for nick_opendir() prototype definition */ /* Need a way to have void used for ANSI, nothing for K&R. */ #ifndef _ANSI @@ -349,6 +350,9 @@ _PROTOTYPE(int readc , (void)); _PROTOTYPE(void unget , (int c )); _PROTOTYPE(void ioecho , (char c )); /* Nick, formerly int c */ _PROTOTYPE(void prs , (char *s )); +#if 1 /* Nick */ +_PROTOTYPE(void prs_expand , (char *p )); +#endif _PROTOTYPE(void sh_putc , (char c )); /* Nick, formerly int c */ _PROTOTYPE(void prn , (unsigned u )); _PROTOTYPE(void closef , (int i )); @@ -398,3 +402,12 @@ Extern int areanum; /* current allocation area */ #define NEW(type) (type *)getcell(sizeof(type)) #define DELETE(obj) freecell((char *)obj) + +/* modifications by Nick for compatibility with uzi libc library */ + +DIR *nick_opendir(char *path, DIR *dir, struct dirent *dd_buf); +int nick_closedir(DIR *dir); +struct dirent *nick_readdir(DIR *dir); + +/* end of modifications by Nick */ + diff --git a/src/sh/msh/sh1.c b/src/sh/msh/sh1.c index 51299f8a..6f920120 100644 --- a/src/sh/msh/sh1.c +++ b/src/sh/msh/sh1.c @@ -181,7 +181,11 @@ register char **argv; for (;;) { if (talking && env.iop <= iostack) +#if 1 /* Nick */ + prs_expand(prompt->value); +#else prs(prompt->value); +#endif onecommand(); } } @@ -848,7 +852,14 @@ unsigned nbytes; register i; if (nbytes == 0) + { +#if 1 /* Nick */ + prs("fatal: getcell() nbytes == 0\n"); + exit(1); +#else abort(); /* silly and defeats the algorithm */ +#endif + } /* * round upwards and add administration area */ @@ -876,7 +887,18 @@ unsigned nbytes; return((char *)NULL); p--; if (p != areatop) + { +#if 1 /* Nick */ + prs("fatal: getcell() p != areatop ("); + prn((int)p); + prs(", "); + prn((int)areatop); + prs(")\n"); + exit(1); +#else abort(); /* allocated areas are contiguous */ +#endif + } q = p + i; p->next = q; p->area = FREE; @@ -893,7 +915,18 @@ found: * split into requested area and rest */ if (areanxt+1 > q) + { +#if 1 /* Nick */ + prs("fatal: getcell() areanxt+1 > q ("); + prn((int)areanxt+1); + prs(", "); + prn((int)q); + prs(")\n"); + exit(1); +#else abort(); /* insufficient space left for admin */ +#endif + } areanxt->next = q; areanxt->area = FREE; p->next = areanxt; diff --git a/src/sh/msh/sh1.rel b/src/sh/msh/sh1.rel index 27e197ae..e9a03bca 100644 --- a/src/sh/msh/sh1.rel +++ b/src/sh/msh/sh1.rel @@ -1,5 +1,5 @@ XL4 -H 6 areas 78 global symbols +H 6 areas 79 global symbols M sh1 S failpt Ref00000000 S environ Ref00000000 @@ -14,6 +14,7 @@ S _write Ref00000000 S ?S_MUL_L02 Ref00000000 S yyparse Ref00000000 S closeall Ref00000000 +S prn Ref00000000 S setjmp Ref00000000 S multiline Ref00000000 S ?BANK_LEAVE_DIRECT_L08 Ref00000000 @@ -26,7 +27,6 @@ S wdlist Ref00000000 S strlen Ref00000000 S shell Ref00000000 S pushio Ref00000000 -S abort Ref00000000 S ?C_V_SWITCH_L06 Ref00000000 S strcmp Ref00000000 S exstat Ref00000000 @@ -55,6 +55,7 @@ S sbrk Ref00000000 S open Ref00000000 S ?US_MOD_L02 Ref00000000 S execute Ref00000000 +S prs_expand Ref00000000 S dolv Ref00000000 S ?CL64180B_4_06_L00 Ref00000000 S trap Ref00000000 @@ -69,14 +70,14 @@ S signal Ref00000000 S filechar Ref00000000 S .__.ABS. Def00000000 A _DEFAULT size 0 flags 0 -A CODE size 1B00 flags 0 -S freecell Def00001988 +A CODE size 1B8C flags 0 +S freecell Def00001A14 S sig Def00000D71 S assign Def00001272 S putn Def00000AE0 S strsave Def00000CEA S any Def00000AAA -S garbage Def00001A73 +S garbage Def00001AFF S err Def00000950 S putvlist Def0000138F S space Def00000CB9 @@ -89,7 +90,7 @@ S letter Def00000C14 S digit Def00000C65 S newenv Def000009A2 S letnum Def00000C8D -S getarea Def00001A63 +S getarea Def00001AEF S xfree Def00000D63 S onintr Def00000BBA S lookup Def00000DEB @@ -100,7 +101,7 @@ S onecommand Def0000075D S isassign Def0000121B S export Def000011E3 S nameval Def00001012 -S setarea Def00001A36 +S setarea Def00001AC2 S main Def00000000 S sh_itoa Def00000AF1 S newfile Def000006E0 @@ -109,10 +110,10 @@ S ronly Def000011F1 S gmatch Def00001510 S eqname Def00001484 S warn Def00000911 -S freearea Def000019D5 +S freearea Def00001A61 S anys Def00000A6D S next Def00000B9C -A CSTR size 8C flags 0 +A CSTR size F1 flags 0 A UDATA0 size 3F flags 0 S flags Def00000004 S inparse Def00000002 @@ -186,7 +187,7 @@ R 00 00 01 00 02 04 28 00 00 09 02 00 T 91 00 00 00 EB 0D 00 00 21 EB 0D 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 96 00 00 00 00 00 00 00 22 00 00 00 00 46 23 -R 00 00 01 00 02 04 24 00 02 09 17 00 +R 00 00 01 00 02 04 24 00 02 09 18 00 T 9D 00 00 00 66 68 ED 4B 04 00 00 00 A7 ED 42 R 00 00 01 00 00 08 04 00 T A6 00 00 00 20 0F @@ -194,7 +195,7 @@ R 00 00 01 00 T A8 00 00 00 R 00 00 01 00 T A8 00 00 00 01 14 00 00 00 ED 5B 00 00 00 00 -R 00 00 01 00 00 05 04 00 02 0B 17 00 +R 00 00 01 00 00 05 04 00 02 0B 18 00 T AF 00 00 00 3E FF 0F 00 00 21 FF 0F 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T B5 00 00 00 00 00 00 00 @@ -202,7 +203,7 @@ R 00 00 01 00 02 04 24 00 T B7 00 00 00 R 00 00 01 00 T B7 00 00 00 ED 5B 00 00 00 00 3E E3 11 00 00 -R 00 00 01 00 02 06 17 00 29 0B 01 00 +R 00 00 01 00 02 06 18 00 29 0B 01 00 T BD 00 00 00 21 E3 11 00 00 CD 00 00 00 00 11 R 00 00 01 00 00 05 01 00 02 0A 24 00 T C4 00 00 00 07 00 00 00 3E EB 0D 00 00 21 @@ -228,9 +229,9 @@ R 00 00 01 00 02 06 27 00 29 0B 01 00 T F3 00 00 00 21 E3 11 00 00 CD 00 00 00 00 01 R 00 00 01 00 00 05 01 00 02 0A 24 00 T FA 00 00 00 05 00 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 3F 00 +R 00 00 01 00 2B 07 40 00 T FF 00 00 00 00 00 00 00 CD 00 00 00 00 EB 3E -R 00 00 01 00 02 04 3F 00 02 09 24 00 +R 00 00 01 00 02 04 40 00 02 09 24 00 T 06 01 00 00 F1 0A 00 00 21 F1 0A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 0B 01 00 00 00 00 00 00 4D 44 11 0E 00 00 00 @@ -334,9 +335,9 @@ R 00 00 01 00 02 04 24 00 T FE 01 00 00 R 00 00 01 00 T FE 01 00 00 DD 36 FC 00 00 00 00 DD 36 FD -R 00 00 01 00 0B 07 41 00 +R 00 00 01 00 0B 07 42 00 T 05 02 00 00 00 00 00 00 DD 36 FE 00 00 00 00 -R 00 00 01 00 8B 04 41 00 2B 0B 41 00 +R 00 00 01 00 8B 04 42 00 2B 0B 42 00 T 0A 02 00 00 AF DD 77 F6 DD 77 F7 DD 6E 04 DD R 00 00 01 00 T 15 02 00 00 66 05 4D 44 03 03 DD 71 04 DD 70 @@ -418,15 +419,15 @@ R 00 00 01 00 T FB 02 00 00 DD 74 05 46 23 66 68 22 R 00 00 01 00 T 03 03 00 00 00 00 00 00 DD 36 FC 00 00 00 00 -R 00 00 01 00 02 04 2E 00 0B 0B 3A 00 +R 00 00 01 00 02 04 2E 00 0B 0B 3B 00 T 09 03 00 00 DD 36 FD 00 00 00 00 DD 36 FE -R 00 00 01 00 8B 07 3A 00 +R 00 00 01 00 8B 07 3B 00 T 10 03 00 00 00 00 00 00 0E 00 00 00 00 C5 21 -R 00 00 01 00 2B 04 3A 00 2B 09 3A 00 +R 00 00 01 00 2B 04 3B 00 2B 09 3B 00 T 15 03 00 00 00 00 00 00 E5 11 00 00 00 00 3E -R 00 00 01 00 02 04 3A 00 02 0A 2E 00 +R 00 00 01 00 02 04 3B 00 02 0A 2E 00 T 1C 03 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 18 00 02 09 18 00 +R 00 00 01 00 2B 04 19 00 02 09 19 00 T 21 03 00 00 00 00 00 00 E1 E1 R 00 00 01 00 02 04 24 00 T 25 03 00 00 @@ -506,7 +507,7 @@ R 00 00 01 00 T AF 03 00 00 R 00 00 01 00 T AF 03 00 00 0E 00 00 00 00 11 00 00 00 00 DD -R 00 00 01 00 2B 05 41 00 02 0A 41 00 +R 00 00 01 00 2B 05 42 00 02 0A 42 00 T B5 03 00 00 7E FE DD 6E FC DD 66 FD B9 20 7F R 00 00 01 00 T C0 03 00 00 ED 52 20 7B DD 4E 02 DD 46 03 0B @@ -548,9 +549,9 @@ R 00 00 01 00 02 04 24 00 T 34 04 00 00 R 00 00 01 00 T 34 04 00 00 11 01 00 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 3B 00 +R 00 00 01 00 2B 08 3C 00 T 3A 04 00 00 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 04 3B 00 02 09 24 00 +R 00 00 01 00 02 04 3C 00 02 09 24 00 T 3F 04 00 00 R 00 00 01 00 T 3F 04 00 00 @@ -570,9 +571,9 @@ R 00 00 01 00 02 08 2E 00 T 5B 04 00 00 E5 DD 6E FC DD 66 FD E5 11 R 00 00 01 00 T 64 04 00 00 00 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 02 04 2E 00 2B 09 18 00 +R 00 00 01 00 02 04 2E 00 2B 09 19 00 T 69 04 00 00 00 00 00 00 CD 00 00 00 00 E1 E1 -R 00 00 01 00 02 04 18 00 02 09 24 00 +R 00 00 01 00 02 04 19 00 02 09 24 00 T 70 04 00 00 11 00 00 3E 00 00 00 00 21 R 00 00 01 00 2B 08 1F 00 T 76 04 00 00 00 00 00 00 CD 00 00 00 00 7D B4 @@ -600,7 +601,7 @@ R 00 00 01 00 00 05 04 00 00 0B 04 00 T A4 04 00 00 06 00 C5 E5 11 03 00 3E R 00 00 01 00 T AC 04 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 40 00 02 09 40 00 +R 00 00 01 00 2B 04 41 00 02 09 41 00 T B1 04 00 00 00 00 00 00 F1 F1 DD 7E F8 DD B6 R 00 00 01 00 02 04 24 00 T BA 04 00 00 F9 28 78 DD 6E F8 DD 66 F9 7E FE @@ -626,9 +627,9 @@ R 00 00 01 00 T EB 04 00 00 R 00 00 01 00 T EB 04 00 00 DD 5E F2 DD 56 F3 3E 00 00 00 00 -R 00 00 01 00 2B 0B 12 00 +R 00 00 01 00 2B 0B 13 00 T F3 04 00 00 21 00 00 00 00 CD 00 00 00 00 EB -R 00 00 01 00 02 05 12 00 02 0A 24 00 +R 00 00 01 00 02 05 13 00 02 0A 24 00 T FA 04 00 00 3E 9C 0B 00 00 21 9C 0B 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 00 05 00 00 00 00 00 00 @@ -646,9 +647,9 @@ R 00 00 01 00 T 1E 05 00 00 R 00 00 01 00 T 1E 05 00 00 DD 5E F2 DD 56 F3 3E 00 00 00 00 -R 00 00 01 00 2B 0B 12 00 +R 00 00 01 00 2B 0B 13 00 T 26 05 00 00 21 00 00 00 00 CD 00 00 00 00 EB -R 00 00 01 00 02 05 12 00 02 0A 24 00 +R 00 00 01 00 02 05 13 00 02 0A 24 00 T 2D 05 00 00 3E 9C 0B 00 00 21 9C 0B 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 33 05 00 00 00 00 00 00 @@ -666,7 +667,7 @@ R 00 00 01 00 00 07 01 00 T 42 05 00 00 71 0D 00 00 C5 E5 11 0C 00 3E R 00 00 01 00 29 04 01 00 T 49 05 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 40 00 02 09 40 00 +R 00 00 01 00 2B 04 41 00 02 09 41 00 T 4E 05 00 00 00 00 00 00 F1 F1 R 00 00 01 00 02 04 24 00 T 52 05 00 00 @@ -674,7 +675,7 @@ R 00 00 01 00 T 52 05 00 00 21 00 00 E5 21 01 00 E5 11 02 00 R 00 00 01 00 T 5D 05 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 40 00 02 0A 40 00 +R 00 00 01 00 2B 05 41 00 02 0A 41 00 T 63 05 00 00 00 00 00 00 F1 F1 3E 01 AD B4 B1 R 00 00 01 00 02 04 24 00 T 6C 05 00 00 B0 28 16 @@ -686,13 +687,13 @@ R 00 00 01 00 00 07 01 00 T 75 05 00 00 BA 0B 00 00 C5 E5 11 02 00 3E R 00 00 01 00 29 04 01 00 T 7C 05 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 40 00 02 09 40 00 +R 00 00 01 00 2B 04 41 00 02 09 41 00 T 81 05 00 00 00 00 00 00 F1 F1 R 00 00 01 00 02 04 24 00 T 85 05 00 00 R 00 00 01 00 T 85 05 00 00 DD 6E 04 DD 66 05 22 00 00 00 00 -R 00 00 01 00 02 0B 36 00 +R 00 00 01 00 02 0B 37 00 T 8E 05 00 00 DD 4E 02 DD 46 03 ED 43 R 00 00 01 00 T 96 05 00 00 00 00 00 00 DD 5E F8 DD 56 F9 73 @@ -788,7 +789,7 @@ R 00 00 01 00 T 65 06 00 00 2A 00 00 00 00 5E 23 56 3E R 00 00 01 00 02 05 21 00 T 6C 06 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 13 00 02 09 13 00 +R 00 00 01 00 2B 04 36 00 02 09 36 00 T 71 06 00 00 00 00 00 00 R 00 00 01 00 02 04 24 00 T 73 06 00 00 @@ -836,7 +837,7 @@ R 00 00 01 00 02 04 24 00 29 0A 01 00 T D8 06 00 00 FF 0F 00 00 CD 00 00 00 00 C3 R 00 00 01 00 00 04 01 00 02 09 24 00 T DE 06 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 +R 00 00 01 00 02 04 10 00 T E0 06 00 00 R 00 00 01 00 T E0 06 00 00 CD 00 00 00 00 FE FF 01 @@ -860,9 +861,9 @@ R 00 00 01 00 T 19 07 00 00 R 00 00 01 00 T 19 07 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 -R 00 00 01 00 2B 0B 13 00 +R 00 00 01 00 2B 0B 14 00 T 21 07 00 00 21 00 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 02 05 13 00 02 0A 24 00 +R 00 00 01 00 02 05 14 00 02 0A 24 00 T 28 07 00 00 48 00 00 00 3E 50 09 00 00 21 R 00 00 01 00 00 04 02 00 29 09 01 00 T 2D 07 00 00 50 09 00 00 CD 00 00 00 00 21 @@ -880,9 +881,9 @@ R 00 00 01 00 T 40 07 00 00 R 00 00 01 00 T 40 07 00 00 DD 5E FE DD 56 FF 3E 00 00 00 00 -R 00 00 01 00 2B 0B 12 00 +R 00 00 01 00 2B 0B 13 00 T 48 07 00 00 21 00 00 00 00 CD 00 00 00 00 EB -R 00 00 01 00 02 05 12 00 02 0A 24 00 +R 00 00 01 00 02 05 13 00 02 0A 24 00 T 4F 07 00 00 3E 9C 0B 00 00 21 9C 0B 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 55 07 00 00 00 00 00 00 21 00 00 @@ -890,7 +891,7 @@ R 00 00 01 00 02 04 24 00 T 5A 07 00 00 R 00 00 01 00 T 5A 07 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 5D 07 00 00 R 00 00 01 00 T 5D 07 00 00 CD 00 00 00 00 F2 FF @@ -915,16 +916,16 @@ T 7B 07 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 06 00 02 09 06 00 T 80 07 00 00 00 00 00 00 ED 5B 00 00 00 00 3E R 00 00 01 00 02 04 24 00 02 0A 28 00 -T 87 07 00 00 D5 19 00 00 21 D5 19 00 00 CD +T 87 07 00 00 61 1A 00 00 21 61 1A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T 8C 07 00 00 00 00 00 00 3E 73 1A 00 00 21 +T 8C 07 00 00 00 00 00 00 3E FF 1A 00 00 21 R 00 00 01 00 02 04 24 00 29 09 01 00 -T 91 07 00 00 73 1A 00 00 CD 00 00 00 00 21 +T 91 07 00 00 FF 1A 00 00 CD 00 00 00 00 21 R 00 00 01 00 00 04 01 00 02 09 24 00 T 97 07 00 00 00 00 22 00 00 00 00 21 00 00 22 -R 00 00 01 00 02 07 15 00 +R 00 00 01 00 02 07 16 00 T A0 07 00 00 00 00 00 00 21 00 00 22 -R 00 00 01 00 02 04 10 00 +R 00 00 01 00 02 04 11 00 T A6 07 00 00 0E 00 00 00 21 00 00 00 00 22 R 00 00 01 00 00 04 04 00 02 09 26 00 T AC 07 00 00 08 00 00 00 21 00 00 22 @@ -932,7 +933,7 @@ R 00 00 01 00 00 04 04 00 T B2 07 00 00 00 00 00 00 21 00 00 22 R 00 00 01 00 02 04 1E 00 T B8 07 00 00 00 00 00 00 21 01 00 22 -R 00 00 01 00 02 04 0E 00 +R 00 00 01 00 02 04 0F 00 T BE 07 00 00 02 00 00 00 21 00 00 22 R 00 00 01 00 00 04 03 00 T C4 07 00 00 00 00 00 00 21 00 00 22 @@ -940,13 +941,13 @@ R 00 00 01 00 00 04 03 00 T CA 07 00 00 00 00 00 00 21 02 00 39 22 R 00 00 01 00 02 04 20 00 T D1 07 00 00 00 00 00 00 EB 3E 00 00 00 00 21 -R 00 00 01 00 02 04 00 00 2B 0A 0D 00 +R 00 00 01 00 02 04 00 00 2B 0A 0E 00 T D7 07 00 00 00 00 00 00 CD 00 00 00 00 21 -R 00 00 01 00 02 04 0D 00 02 09 24 00 +R 00 00 01 00 02 04 0E 00 02 09 24 00 T DD 07 00 00 02 00 39 22 00 00 00 00 EB 3E R 00 00 01 00 02 08 00 00 T E5 07 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0D 00 02 09 0D 00 +R 00 00 01 00 2B 04 0E 00 02 09 0E 00 T EA 07 00 00 00 00 00 00 7D B4 20 13 3E R 00 00 01 00 02 04 24 00 T F1 07 00 00 00 00 00 00 21 00 00 00 00 CD @@ -974,7 +975,7 @@ R 00 00 01 00 02 04 24 00 T 14 08 00 00 R 00 00 01 00 T 14 08 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 3E 00 02 0A 3E 00 +R 00 00 01 00 2B 05 3F 00 02 0A 3F 00 T 1A 08 00 00 00 00 00 00 2A 00 00 00 00 7D B4 R 00 00 01 00 02 04 24 00 02 09 29 00 T 21 08 00 00 20 0F 2A 00 00 00 00 7D B4 28 08 @@ -1000,7 +1001,7 @@ R 00 00 01 00 T 40 08 00 00 21 00 00 22 02 00 00 00 21 00 00 R 00 00 01 00 00 08 03 00 T 49 08 00 00 22 00 00 00 00 21 00 00 22 -R 00 00 01 00 02 05 3C 00 +R 00 00 01 00 02 05 3D 00 T 50 08 00 00 00 00 00 00 21 00 00 22 R 00 00 01 00 00 04 03 00 T 56 08 00 00 00 00 00 00 21 6E 00 ED 4B @@ -1054,13 +1055,13 @@ R 00 00 01 00 T BA 08 00 00 R 00 00 01 00 T BA 08 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T BD 08 00 00 R 00 00 01 00 T BD 08 00 00 C5 D5 01 01 00 ED 5B 00 00 00 00 R 00 00 01 00 02 0B 00 00 T C6 08 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 39 00 02 0A 39 00 +R 00 00 01 00 2B 05 3A 00 02 0A 3A 00 T CC 08 00 00 00 00 00 00 D1 C1 C3 00 00 00 00 R 00 00 01 00 02 04 24 00 02 0B 07 00 T D3 08 00 00 @@ -1076,7 +1077,7 @@ R 00 00 01 00 02 04 24 00 T E3 08 00 00 R 00 00 01 00 T E3 08 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 3E 00 02 0A 3E 00 +R 00 00 01 00 2B 05 3F 00 02 0A 3F 00 T E9 08 00 00 00 00 00 00 11 01 00 3E R 00 00 01 00 02 04 24 00 T EF 08 00 00 00 00 00 00 21 00 00 00 00 CD @@ -1088,7 +1089,7 @@ R 00 00 01 00 29 04 01 00 00 09 01 00 T FF 08 00 00 00 00 00 00 ED 5B 00 00 00 00 3E R 00 00 01 00 02 04 24 00 02 0A 1C 00 T 06 09 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 3B 00 02 09 3B 00 +R 00 00 01 00 2B 04 3C 00 02 09 3C 00 T 0B 09 00 00 00 00 00 00 D1 C3 00 00 00 00 R 00 00 01 00 02 04 24 00 02 0A 07 00 T 11 09 00 00 @@ -1098,17 +1099,17 @@ R 00 00 01 00 02 05 23 00 T 1A 09 00 00 R 00 00 01 00 T 1A 09 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 -R 00 00 01 00 2B 0B 13 00 +R 00 00 01 00 2B 0B 14 00 T 22 09 00 00 21 00 00 00 00 CD 00 00 00 00 21 -R 00 00 01 00 02 05 13 00 02 0A 24 00 +R 00 00 01 00 02 05 14 00 02 0A 24 00 T 29 09 00 00 FF FF 22 00 00 00 00 R 00 00 01 00 02 07 1C 00 T 2E 09 00 00 R 00 00 01 00 T 2E 09 00 00 11 56 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 05 02 00 2B 0A 13 00 +R 00 00 01 00 00 05 02 00 2B 0A 14 00 T 34 09 00 00 00 00 00 00 CD 00 00 00 00 21 -R 00 00 01 00 02 04 13 00 02 09 24 00 +R 00 00 01 00 02 04 14 00 02 09 24 00 T 3A 09 00 00 65 00 ED 4B 00 00 00 00 09 7E B7 R 00 00 01 00 00 08 04 00 T 43 09 00 00 28 08 @@ -1122,7 +1123,7 @@ R 00 00 01 00 02 04 24 00 T 4D 09 00 00 R 00 00 01 00 T 4D 09 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 50 09 00 00 R 00 00 01 00 T 50 09 00 00 CD 00 00 00 00 3E 11 09 00 00 21 @@ -1156,7 +1157,7 @@ R 00 00 01 00 T 7F 09 00 00 01 01 00 ED 5B 0E 00 00 00 3E R 00 00 01 00 00 09 04 00 T 87 09 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 39 00 02 09 39 00 +R 00 00 01 00 2B 04 3A 00 02 09 3A 00 T 8C 09 00 00 00 00 00 00 R 00 00 01 00 02 04 24 00 T 8E 09 00 00 @@ -1170,7 +1171,7 @@ R 00 00 01 00 00 04 04 00 00 09 04 00 T 9F 09 00 00 R 00 00 01 00 T 9F 09 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T A2 09 00 00 R 00 00 01 00 T A2 09 00 00 CD 00 00 00 00 FE FF DD 7E 02 DD @@ -1222,7 +1223,7 @@ R 00 00 01 00 00 04 04 00 T 0A 0A 00 00 R 00 00 01 00 T 0A 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 0D 0A 00 00 R 00 00 01 00 T 0D 0A 00 00 CD 00 00 00 00 FC FF 2A @@ -1239,7 +1240,7 @@ T 28 0A 00 00 11 08 00 00 00 DD 6E FC DD 66 FD R 00 00 01 00 00 05 04 00 T 31 0A 00 00 01 0C 00 ED B0 DD 5E FC DD 56 FD R 00 00 01 00 -T 3C 0A 00 00 3E 88 19 00 00 21 88 19 00 00 CD +T 3C 0A 00 00 3E 14 1A 00 00 21 14 1A 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 42 0A 00 00 00 00 00 00 R 00 00 01 00 02 04 24 00 @@ -1254,9 +1255,9 @@ R 00 00 01 00 02 04 30 00 T 5A 0A 00 00 R 00 00 01 00 T 5A 0A 00 00 DD 5E FE DD 56 FF 3E 00 00 00 00 -R 00 00 01 00 2B 0B 14 00 +R 00 00 01 00 2B 0B 15 00 T 62 0A 00 00 21 00 00 00 00 CD 00 00 00 00 18 -R 00 00 01 00 02 05 14 00 02 0A 24 00 +R 00 00 01 00 02 05 15 00 02 0A 24 00 T 69 0A 00 00 DA R 00 00 01 00 T 6A 0A 00 00 @@ -1264,7 +1265,7 @@ R 00 00 01 00 T 6A 0A 00 00 R 00 00 01 00 T 6A 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 6D 0A 00 00 R 00 00 01 00 T 6D 0A 00 00 CD 00 00 00 00 @@ -1300,7 +1301,7 @@ R 00 00 01 00 T A7 0A 00 00 R 00 00 01 00 T A7 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T AA 0A 00 00 R 00 00 01 00 T AA 0A 00 00 CD 00 00 00 00 @@ -1334,7 +1335,7 @@ R 00 00 01 00 T DD 0A 00 00 R 00 00 01 00 T DD 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T E0 0A 00 00 R 00 00 01 00 T E0 0A 00 00 CD 00 00 00 00 01 FF FF 3E @@ -1342,7 +1343,7 @@ R 00 00 01 00 02 05 23 00 T E7 0A 00 00 F1 0A 00 00 21 F1 0A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T EC 0A 00 00 00 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 04 24 00 02 09 0F 00 +R 00 00 01 00 02 04 24 00 02 09 10 00 T F1 0A 00 00 R 00 00 01 00 T F1 0A 00 00 CD 00 00 00 00 FC FF AF DD 77 FE @@ -1402,19 +1403,19 @@ R 00 00 01 00 T 93 0B 00 00 R 00 00 01 00 T 93 0B 00 00 DD 6E FC DD 66 FD C3 00 00 00 00 -R 00 00 01 00 02 0B 0F 00 +R 00 00 01 00 02 0B 10 00 T 9C 0B 00 00 R 00 00 01 00 T 9C 0B 00 00 CD 00 00 00 00 ED 53 04 00 00 00 R 00 00 01 00 02 05 23 00 02 0B 2E 00 T A3 0B 00 00 0E 00 00 00 00 C5 21 00 00 00 00 -R 00 00 01 00 2B 05 41 00 02 0B 41 00 +R 00 00 01 00 2B 05 42 00 02 0B 42 00 T A9 0B 00 00 E5 11 00 00 00 00 3E 00 00 00 00 -R 00 00 01 00 02 06 2E 00 2B 0B 18 00 +R 00 00 01 00 02 06 2E 00 2B 0B 19 00 T AF 0B 00 00 21 00 00 00 00 CD 00 00 00 00 E1 -R 00 00 01 00 02 05 18 00 02 0A 24 00 +R 00 00 01 00 02 05 19 00 02 0A 24 00 T B6 0B 00 00 E1 C3 00 00 00 00 -R 00 00 01 00 02 06 0F 00 +R 00 00 01 00 02 06 10 00 T BA 0B 00 00 R 00 00 01 00 T BA 0B 00 00 CD 00 00 00 00 06 00 21 @@ -1422,9 +1423,9 @@ R 00 00 01 00 02 05 23 00 T C0 0B 00 00 BA 0B 00 00 0E BA 0B 00 00 C5 E5 R 00 00 01 00 00 04 01 00 29 09 01 00 T C6 0B 00 00 11 02 00 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 40 00 +R 00 00 01 00 2B 08 41 00 T CC 0B 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 -R 00 00 01 00 02 04 40 00 02 09 24 00 +R 00 00 01 00 02 04 41 00 02 09 24 00 T D3 0B 00 00 21 01 00 22 00 00 00 00 2A R 00 00 01 00 00 08 03 00 T DA 0B 00 00 00 00 00 00 7D B4 28 1C @@ -1436,9 +1437,9 @@ R 00 00 01 00 00 05 03 00 T E7 0B 00 00 R 00 00 01 00 T E7 0B 00 00 11 56 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 05 02 00 2B 0A 13 00 +R 00 00 01 00 00 05 02 00 2B 0A 14 00 T ED 0B 00 00 00 00 00 00 CD 00 00 00 00 3E -R 00 00 01 00 02 04 13 00 02 09 24 00 +R 00 00 01 00 02 04 14 00 02 09 24 00 T F3 0B 00 00 BD 08 00 00 21 BD 08 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T F8 0B 00 00 00 00 00 00 @@ -1464,7 +1465,7 @@ R 00 00 01 00 T 11 0C 00 00 R 00 00 01 00 T 11 0C 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 14 0C 00 00 R 00 00 01 00 T 14 0C 00 00 CD 00 00 00 00 01 61 80 EB 3E 80 @@ -1494,7 +1495,7 @@ R 00 00 01 00 T 62 0C 00 00 R 00 00 01 00 T 62 0C 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 65 0C 00 00 R 00 00 01 00 T 65 0C 00 00 CD 00 00 00 00 01 30 80 EB 3E 80 @@ -1512,7 +1513,7 @@ R 00 00 01 00 T 8A 0C 00 00 R 00 00 01 00 T 8A 0C 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 8D 0C 00 00 R 00 00 01 00 T 8D 0C 00 00 CD 00 00 00 00 3E 14 0C 00 00 21 @@ -1534,7 +1535,7 @@ R 00 00 01 00 T B6 0C 00 00 R 00 00 01 00 T B6 0C 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T B9 0C 00 00 R 00 00 01 00 T B9 0C 00 00 CD 00 00 00 00 FE FF DD 5E 02 DD @@ -1554,15 +1555,15 @@ R 00 00 01 00 00 04 01 00 02 09 24 00 T E1 0C 00 00 R 00 00 01 00 T E1 0C 00 00 DD 6E FE DD 66 FF C3 00 00 00 00 -R 00 00 01 00 02 0B 0F 00 +R 00 00 01 00 02 0B 10 00 T EA 0C 00 00 R 00 00 01 00 T EA 0C 00 00 CD 00 00 00 00 FC FF DD 5E 02 DD R 00 00 01 00 02 05 2A 00 T F3 0C 00 00 56 03 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 16 00 +R 00 00 01 00 2B 07 17 00 T F8 0C 00 00 00 00 00 00 CD 00 00 00 00 EB 13 -R 00 00 01 00 02 04 16 00 02 09 24 00 +R 00 00 01 00 02 04 17 00 02 09 24 00 T FF 0C 00 00 3E B9 0C 00 00 21 B9 0C 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 05 0D 00 00 00 00 00 00 DD 75 FC DD 74 FD 7D @@ -1573,7 +1574,7 @@ T 11 0D 00 00 R 00 00 01 00 T 11 0D 00 00 DD 4E 04 DD 46 05 DD 5E FC DD 56 R 00 00 01 00 -T 1C 0D 00 00 FD 3E 36 1A 00 00 21 36 1A 00 00 +T 1C 0D 00 00 FD 3E C2 1A 00 00 21 C2 1A 00 00 R 00 00 01 00 29 06 01 00 00 0B 01 00 T 22 0D 00 00 CD 00 00 00 00 DD 6E FC DD 66 FD R 00 00 01 00 02 05 24 00 @@ -1604,15 +1605,15 @@ R 00 00 01 00 00 05 02 00 T 60 0D 00 00 R 00 00 01 00 T 60 0D 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 63 0D 00 00 R 00 00 01 00 -T 63 0D 00 00 CD 00 00 00 00 3E 88 19 00 00 21 +T 63 0D 00 00 CD 00 00 00 00 3E 14 1A 00 00 21 R 00 00 01 00 02 05 23 00 29 0A 01 00 -T 69 0D 00 00 88 19 00 00 CD 00 00 00 00 C3 +T 69 0D 00 00 14 1A 00 00 CD 00 00 00 00 C3 R 00 00 01 00 00 04 01 00 02 09 24 00 T 6F 0D 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 +R 00 00 01 00 02 04 10 00 T 71 0D 00 00 R 00 00 01 00 T 71 0D 00 00 CD 00 00 00 00 ED 53 00 00 00 00 @@ -1622,17 +1623,17 @@ R 00 00 01 00 00 07 01 00 T 7E 0D 00 00 71 0D 00 00 C5 E5 DD 5E 02 DD 56 R 00 00 01 00 29 04 01 00 T 86 0D 00 00 03 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 40 00 02 0B 40 00 +R 00 00 01 00 2B 06 41 00 02 0B 41 00 T 8C 0D 00 00 CD 00 00 00 00 F1 F1 C3 R 00 00 01 00 02 05 24 00 T 92 0D 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 +R 00 00 01 00 02 04 10 00 T 94 0D 00 00 R 00 00 01 00 T 94 0D 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD R 00 00 01 00 02 05 2A 00 T 9D 0D 00 00 66 03 29 01 00 00 00 00 09 46 23 -R 00 00 01 00 02 08 38 00 +R 00 00 01 00 02 08 39 00 T A6 0D 00 00 66 68 DD 75 FE DD 74 FF 7D B4 20 R 00 00 01 00 T B1 0D 00 00 02 @@ -1650,23 +1651,23 @@ R 00 00 01 00 T BC 0D 00 00 DD 6E 02 DD 66 03 29 01 R 00 00 01 00 T C4 0D 00 00 00 00 00 00 09 AF 77 23 77 -R 00 00 01 00 02 04 38 00 +R 00 00 01 00 02 04 39 00 T CB 0D 00 00 R 00 00 01 00 T CB 0D 00 00 DD 6E FE DD 66 FF 22 00 00 00 00 R 00 00 01 00 02 0B 2E 00 T D4 0D 00 00 0E 00 00 00 00 C5 21 00 00 00 00 -R 00 00 01 00 2B 05 3A 00 02 0B 3A 00 +R 00 00 01 00 2B 05 3B 00 02 0B 3B 00 T DA 0D 00 00 E5 11 00 00 00 00 3E 00 00 00 00 -R 00 00 01 00 02 06 2E 00 2B 0B 11 00 +R 00 00 01 00 02 06 2E 00 2B 0B 12 00 T E0 0D 00 00 21 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 02 05 11 00 02 0A 24 00 +R 00 00 01 00 02 05 12 00 02 0A 24 00 T E7 0D 00 00 F1 R 00 00 01 00 T E8 0D 00 00 R 00 00 01 00 T E8 0D 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T EB 0D 00 00 R 00 00 01 00 T EB 0D 00 00 CD 00 00 00 00 FA FF DD 6E 02 DD @@ -1724,7 +1725,7 @@ R 00 00 01 00 02 07 22 00 T 79 0E 00 00 00 00 00 00 38 0E 69 60 29 ED 4B R 00 00 01 00 02 04 30 00 T 82 0E 00 00 00 00 00 00 09 46 23 66 68 18 03 -R 00 00 01 00 02 04 36 00 +R 00 00 01 00 02 04 37 00 T 8B 0E 00 00 R 00 00 01 00 T 8B 0E 00 00 2A 04 00 00 00 @@ -1839,15 +1840,15 @@ T 97 0F 00 00 DD 6E FC DD 66 FD 23 DD 75 FC DD R 00 00 01 00 T A2 0F 00 00 74 FD 36 00 01 00 00 DD 5E FA DD R 00 00 01 00 -T AD 0F 00 00 56 FB 3E 36 1A 00 00 21 +T AD 0F 00 00 56 FB 3E C2 1A 00 00 21 R 00 00 01 00 29 07 01 00 -T B2 0F 00 00 36 1A 00 00 CD 00 00 00 00 01 +T B2 0F 00 00 C2 1A 00 00 CD 00 00 00 00 01 R 00 00 01 00 00 04 01 00 02 09 24 00 T B8 0F 00 00 00 00 DD 6E FA DD 66 FB 23 23 5E R 00 00 01 00 -T C3 0F 00 00 23 56 3E 36 1A 00 00 21 +T C3 0F 00 00 23 56 3E C2 1A 00 00 21 R 00 00 01 00 29 07 01 00 -T C8 0F 00 00 36 1A 00 00 CD 00 00 00 00 2A +T C8 0F 00 00 C2 1A 00 00 CD 00 00 00 00 2A R 00 00 01 00 00 04 01 00 02 09 24 00 T CE 0F 00 00 04 00 00 00 E5 DD 6E FA DD 66 FB R 00 00 01 00 00 04 04 00 @@ -1862,7 +1863,7 @@ R 00 00 01 00 02 04 31 00 T FC 0F 00 00 R 00 00 01 00 T FC 0F 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T FF 0F 00 00 R 00 00 01 00 T FF 0F 00 00 CD 00 00 00 00 21 00 00 E5 3E @@ -1870,7 +1871,7 @@ R 00 00 01 00 02 05 23 00 T 07 10 00 00 12 10 00 00 21 12 10 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 0C 10 00 00 00 00 00 00 E1 C3 00 00 00 00 -R 00 00 01 00 02 04 24 00 02 0A 0F 00 +R 00 00 01 00 02 04 24 00 02 0A 10 00 T 12 10 00 00 R 00 00 01 00 T 12 10 00 00 CD 00 00 00 00 F8 FF 21 06 00 DD @@ -1898,9 +1899,9 @@ R 00 00 01 00 T 4D 10 00 00 DD 6E FA DD 66 FB 23 DD 75 FA DD R 00 00 01 00 T 58 10 00 00 74 FB 2B 5E 16 00 3E 00 00 00 00 -R 00 00 01 00 2B 0B 3D 00 +R 00 00 01 00 2B 0B 3E 00 T 60 10 00 00 21 00 00 00 00 CD 00 00 00 00 18 -R 00 00 01 00 02 05 3D 00 02 0A 24 00 +R 00 00 01 00 02 05 3E 00 02 0A 24 00 T 67 10 00 00 D0 R 00 00 01 00 T 68 10 00 00 @@ -1922,11 +1923,11 @@ R 00 00 01 00 T 86 10 00 00 DD 6E 02 DD 66 03 23 23 5E 23 56 R 00 00 01 00 T 91 10 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 16 00 02 0A 16 00 +R 00 00 01 00 2B 05 17 00 02 0A 17 00 T 97 10 00 00 00 00 00 00 E5 DD 5E 04 DD 56 05 R 00 00 01 00 02 04 24 00 T A0 10 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 16 00 02 0A 16 00 +R 00 00 01 00 2B 05 17 00 02 0A 17 00 T A6 10 00 00 00 00 00 00 4D 44 E1 09 EB 13 13 R 00 00 01 00 02 04 24 00 T AF 10 00 00 3E B9 0C 00 00 21 B9 0C 00 00 CD @@ -1943,7 +1944,7 @@ T C4 10 00 00 R 00 00 01 00 T C4 10 00 00 01 00 00 DD 5E FA DD 56 FB 3E R 00 00 01 00 -T CE 10 00 00 36 1A 00 00 21 36 1A 00 00 CD +T CE 10 00 00 C2 1A 00 00 21 C2 1A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T D3 10 00 00 00 00 00 00 DD 6E FA DD 66 FB DD R 00 00 01 00 02 04 24 00 @@ -2042,13 +2043,13 @@ R 00 00 01 00 T E0 11 00 00 R 00 00 01 00 T E0 11 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T E3 11 00 00 R 00 00 01 00 T E3 11 00 00 CD 00 00 00 00 21 06 00 19 7E F6 R 00 00 01 00 02 05 23 00 T EC 11 00 00 02 77 C3 00 00 00 00 -R 00 00 01 00 02 07 0F 00 +R 00 00 01 00 02 07 10 00 T F1 11 00 00 R 00 00 01 00 T F1 11 00 00 CD 00 00 00 00 13 13 EB 7E 23 66 @@ -2068,7 +2069,7 @@ R 00 00 01 00 T 18 12 00 00 R 00 00 01 00 T 18 12 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 1B 12 00 00 R 00 00 01 00 T 1B 12 00 00 CD 00 00 00 00 1A 5F 16 00 3E @@ -2120,7 +2121,7 @@ R 00 00 01 00 T 6F 12 00 00 R 00 00 01 00 T 6F 12 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 72 12 00 00 R 00 00 01 00 T 72 12 00 00 CD 00 00 00 00 FC FF DD 6E 02 DD @@ -2210,7 +2211,7 @@ R 00 00 01 00 T 38 13 00 00 R 00 00 01 00 T 38 13 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 3B 13 00 00 R 00 00 01 00 T 3B 13 00 00 CD 00 00 00 00 13 DD 73 02 DD 72 @@ -2256,7 +2257,7 @@ R 00 00 01 00 T 8C 13 00 00 R 00 00 01 00 T 8C 13 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 8F 13 00 00 R 00 00 01 00 T 8F 13 00 00 CD 00 00 00 00 FE FF 2A @@ -2344,7 +2345,7 @@ R 00 00 01 00 00 04 01 00 T 81 14 00 00 R 00 00 01 00 T 81 14 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 84 14 00 00 R 00 00 01 00 T 84 14 00 00 CD 00 00 00 00 @@ -2398,7 +2399,7 @@ R 00 00 01 00 T E2 14 00 00 R 00 00 01 00 T E2 14 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T E5 14 00 00 R 00 00 01 00 T E5 14 00 00 CD 00 00 00 00 @@ -2562,7 +2563,7 @@ R 00 00 01 00 T 2A 16 00 00 R 00 00 01 00 T 2A 16 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +R 00 00 01 00 02 05 10 00 T 2D 16 00 00 R 00 00 01 00 T 2D 16 00 00 CD 00 00 00 00 F8 FF DD 6E 02 DD @@ -2731,338 +2732,384 @@ T 94 17 00 00 R 00 00 01 00 T 94 17 00 00 CD 00 00 00 00 F8 FF DD 7E 02 DD R 00 00 01 00 02 05 2A 00 -T 9D 17 00 00 B6 03 20 08 +T 9D 17 00 00 B6 03 20 16 R 00 00 01 00 T A1 17 00 00 R 00 00 01 00 -T A1 17 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 19 00 02 0A 19 00 -T A7 17 00 00 00 00 00 00 -R 00 00 01 00 02 04 24 00 -T A9 17 00 00 +T A1 17 00 00 11 8C 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 02 00 2B 0A 14 00 +T A7 17 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 14 00 02 09 24 00 +T AD 17 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 3C 00 +T B2 17 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 3C 00 02 09 24 00 +T B7 17 00 00 R 00 00 01 00 -T A9 17 00 00 DD 6E 02 DD 66 03 23 23 23 CB 3C +T B7 17 00 00 DD 6E 02 DD 66 03 23 23 23 CB 3C R 00 00 01 00 -T B4 17 00 00 CB 1D CB 3C CB 1D 23 DD 75 F8 DD +T C2 17 00 00 CB 1D CB 3C CB 1D 23 DD 75 F8 DD R 00 00 01 00 -T BF 17 00 00 74 F9 2A 3D 00 00 00 DD 75 FA DD +T CD 17 00 00 74 F9 2A 3D 00 00 00 DD 75 FA DD R 00 00 01 00 00 07 03 00 -T C8 17 00 00 74 FB +T D6 17 00 00 74 FB R 00 00 01 00 -T CA 17 00 00 +T D8 17 00 00 R 00 00 01 00 -T CA 17 00 00 DD 6E FA DD 66 FB 23 23 4E 23 46 +T D8 17 00 00 DD 6E FA DD 66 FB 23 23 4E 23 46 R 00 00 01 00 -T D5 17 00 00 2A 00 00 00 00 CD 00 00 00 00 30 +T E3 17 00 00 2A 00 00 00 00 CD 00 00 00 00 30 R 00 00 01 00 02 05 28 00 02 0A 30 00 -T DC 17 00 00 61 +T EA 17 00 00 61 R 00 00 01 00 -T DD 17 00 00 +T EB 17 00 00 R 00 00 01 00 -T DD 17 00 00 +T EB 17 00 00 R 00 00 01 00 -T DD 17 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD +T EB 17 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD R 00 00 01 00 -T E8 17 00 00 75 FC DD 74 FD 23 23 4E 23 46 2A +T F6 17 00 00 75 FC DD 74 FD 23 23 4E 23 46 2A R 00 00 01 00 -T F3 17 00 00 00 00 00 00 CD 00 00 00 00 30 25 +T 01 18 00 00 00 00 00 00 CD 00 00 00 00 30 25 R 00 00 01 00 02 04 28 00 02 09 30 00 -T FA 17 00 00 2A 3D 00 00 00 DD 4E FC DD 46 FD +T 08 18 00 00 2A 3D 00 00 00 DD 4E FC DD 46 FD R 00 00 01 00 00 05 03 00 -T 03 18 00 00 A7 ED 42 28 17 +T 11 18 00 00 A7 ED 42 28 17 R 00 00 01 00 -T 08 18 00 00 +T 16 18 00 00 R 00 00 01 00 -T 08 18 00 00 +T 16 18 00 00 R 00 00 01 00 -T 08 18 00 00 +T 16 18 00 00 R 00 00 01 00 -T 08 18 00 00 DD 6E FC DD 66 FD 46 23 66 68 E5 +T 16 18 00 00 DD 6E FC DD 66 FD 46 23 66 68 E5 R 00 00 01 00 -T 13 18 00 00 DD 6E FA DD 66 FB C1 71 23 70 18 +T 21 18 00 00 DD 6E FA DD 66 FB C1 71 23 70 18 R 00 00 01 00 -T 1E 18 00 00 BE +T 2C 18 00 00 BE R 00 00 01 00 -T 1F 18 00 00 +T 2D 18 00 00 R 00 00 01 00 -T 1F 18 00 00 DD 6E F8 DD 66 F9 29 29 DD 4E FA +T 2D 18 00 00 DD 6E F8 DD 66 F9 29 29 DD 4E FA R 00 00 01 00 -T 2A 18 00 00 DD 46 FB 09 4D 44 DD 6E FC DD 66 +T 38 18 00 00 DD 46 FB 09 4D 44 DD 6E FC DD 66 R 00 00 01 00 -T 35 18 00 00 FD A7 ED 42 38 03 +T 43 18 00 00 FD A7 ED 42 38 03 R 00 00 01 00 -T 3B 18 00 00 +T 49 18 00 00 R 00 00 01 00 -T 3B 18 00 00 C3 0C 19 00 00 +T 49 18 00 00 C3 58 19 00 00 R 00 00 01 00 00 05 01 00 -T 3E 18 00 00 +T 4C 18 00 00 R 00 00 01 00 -T 3E 18 00 00 +T 4C 18 00 00 R 00 00 01 00 -T 3E 18 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD +T 4C 18 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD R 00 00 01 00 -T 49 18 00 00 75 FA DD 74 FB ED 4B 3D 00 00 00 +T 57 18 00 00 75 FA DD 74 FB ED 4B 3D 00 00 00 R 00 00 01 00 00 0B 03 00 -T 52 18 00 00 A7 ED 42 20 02 +T 60 18 00 00 A7 ED 42 20 02 R 00 00 01 00 -T 57 18 00 00 +T 65 18 00 00 R 00 00 01 00 -T 57 18 00 00 18 03 +T 65 18 00 00 18 03 R 00 00 01 00 -T 59 18 00 00 +T 67 18 00 00 R 00 00 01 00 -T 59 18 00 00 C3 CA 17 00 00 +T 67 18 00 00 C3 D8 17 00 00 R 00 00 01 00 00 05 01 00 -T 5C 18 00 00 +T 6A 18 00 00 R 00 00 01 00 -T 5C 18 00 00 01 00 81 DD 6E F8 DD 66 F9 3E 80 +T 6A 18 00 00 01 00 81 DD 6E F8 DD 66 F9 3E 80 R 00 00 01 00 -T 67 18 00 00 AC 67 ED 42 38 08 DD 6E F8 DD 66 +T 75 18 00 00 AC 67 ED 42 38 08 DD 6E F8 DD 66 R 00 00 01 00 -T 72 18 00 00 F9 18 03 +T 80 18 00 00 F9 18 03 R 00 00 01 00 -T 75 18 00 00 +T 83 18 00 00 R 00 00 01 00 -T 75 18 00 00 21 00 01 +T 83 18 00 00 21 00 01 R 00 00 01 00 -T 78 18 00 00 +T 86 18 00 00 R 00 00 01 00 -T 78 18 00 00 DD 75 FE DD 74 FF 29 29 EB 3E +T 86 18 00 00 DD 75 FE DD 74 FF 29 29 EB 3E R 00 00 01 00 -T 82 18 00 00 00 00 00 00 21 00 00 00 00 CD +T 90 18 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 32 00 02 09 32 00 -T 87 18 00 00 00 00 00 00 DD 75 FA DD 74 FB 7D +T 95 18 00 00 00 00 00 00 DD 75 FA DD 74 FB 7D R 00 00 01 00 02 04 24 00 -T 90 18 00 00 A4 3C 20 06 +T 9E 18 00 00 A4 3C 20 06 R 00 00 01 00 -T 94 18 00 00 +T A2 18 00 00 R 00 00 01 00 -T 94 18 00 00 21 00 00 C3 85 19 00 00 +T A2 18 00 00 21 00 00 C3 11 1A 00 00 R 00 00 01 00 00 08 01 00 -T 9A 18 00 00 +T A8 18 00 00 R 00 00 01 00 -T 9A 18 00 00 DD 7E FA D6 04 DD 77 FA DD 7E FB +T A8 18 00 00 DD 7E FA D6 04 DD 77 FA DD 7E FB R 00 00 01 00 -T A5 18 00 00 DE 00 DD 77 FB 2A 3B 00 00 00 DD +T B3 18 00 00 DE 00 DD 77 FB 2A 3B 00 00 00 DD R 00 00 01 00 00 0A 03 00 -T AE 18 00 00 4E FA DD 46 FB A7 ED 42 28 08 +T BC 18 00 00 4E FA DD 46 FB A7 ED 42 28 46 R 00 00 01 00 -T B8 18 00 00 +T C6 18 00 00 R 00 00 01 00 -T B8 18 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 19 00 02 0A 19 00 -T BE 18 00 00 00 00 00 00 -R 00 00 01 00 02 04 24 00 -T C0 18 00 00 +T C6 18 00 00 11 AA 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 02 00 2B 0A 14 00 +T CC 18 00 00 00 00 00 00 CD 00 00 00 00 DD 5E +R 00 00 01 00 02 04 14 00 02 09 24 00 +T D3 18 00 00 FA DD 56 FB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 0D 00 +T DA 18 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0D 00 02 09 24 00 +T E0 18 00 00 CA 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 14 00 +T E5 18 00 00 00 00 00 00 CD 00 00 00 00 ED 5B +R 00 00 01 00 02 04 14 00 02 09 24 00 +T EC 18 00 00 3B 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0D 00 +T F1 18 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0D 00 02 09 24 00 +T F7 18 00 00 CD 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 14 00 +T FC 18 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 14 00 02 09 24 00 +T 02 19 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 3C 00 +T 07 19 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 3C 00 02 09 24 00 +T 0C 19 00 00 R 00 00 01 00 -T C0 18 00 00 DD 6E FE DD 66 FF 29 29 DD 4E FA +T 0C 19 00 00 DD 6E FE DD 66 FF 29 29 DD 4E FA R 00 00 01 00 -T CB 18 00 00 DD 46 FB 09 DD 75 FC DD 74 FD E5 +T 17 19 00 00 DD 46 FB 09 DD 75 FC DD 74 FD E5 R 00 00 01 00 -T D6 18 00 00 69 60 C1 71 23 70 DD 6E FA DD 66 +T 22 19 00 00 69 60 C1 71 23 70 DD 6E FA DD 66 R 00 00 01 00 -T E1 18 00 00 FB 23 23 36 FF 23 36 7F 2A +T 2D 19 00 00 FB 23 23 36 FF 23 36 7F 2A R 00 00 01 00 -T EA 18 00 00 39 00 00 00 E5 DD 6E FC DD 66 FD +T 36 19 00 00 39 00 00 00 E5 DD 6E FC DD 66 FD R 00 00 01 00 00 04 03 00 -T F3 18 00 00 C1 71 23 70 DD 6E FC DD 66 FD 23 +T 3F 19 00 00 C1 71 23 70 DD 6E FC DD 66 FD 23 R 00 00 01 00 -T FE 18 00 00 23 AF 77 23 77 DD 6E FC DD 66 FD +T 4A 19 00 00 23 AF 77 23 77 DD 6E FC DD 66 FD R 00 00 01 00 -T 09 19 00 00 22 3B 00 00 00 +T 55 19 00 00 22 3B 00 00 00 R 00 00 01 00 00 05 03 00 -T 0C 19 00 00 +T 58 19 00 00 R 00 00 01 00 -T 0C 19 00 00 DD 6E F8 DD 66 F9 29 29 DD 4E FA +T 58 19 00 00 DD 6E F8 DD 66 F9 29 29 DD 4E FA R 00 00 01 00 -T 17 19 00 00 DD 46 FB 09 22 3D 00 00 00 DD 4E +T 63 19 00 00 DD 46 FB 09 22 3D 00 00 00 DD 4E R 00 00 01 00 00 09 03 00 -T 20 19 00 00 FC DD 46 FD A7 ED 42 30 43 +T 6C 19 00 00 FC DD 46 FD A7 ED 42 D2 R 00 00 01 00 -T 29 19 00 00 +T 74 19 00 00 F8 19 00 00 +R 00 00 01 00 00 04 01 00 +T 76 19 00 00 R 00 00 01 00 -T 29 19 00 00 21 04 00 ED 4B 3D 00 00 00 09 4D +T 76 19 00 00 21 04 00 ED 4B 3D 00 00 00 09 4D R 00 00 01 00 00 09 03 00 -T 32 19 00 00 44 DD 6E FC DD 66 FD A7 ED 42 30 +T 7F 19 00 00 44 DD 6E FC DD 66 FD A7 ED 42 30 R 00 00 01 00 -T 3D 19 00 00 08 +T 8A 19 00 00 47 R 00 00 01 00 -T 3E 19 00 00 +T 8B 19 00 00 R 00 00 01 00 -T 3E 19 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 19 00 02 0A 19 00 -T 44 19 00 00 00 00 00 00 -R 00 00 01 00 02 04 24 00 -T 46 19 00 00 +T 8B 19 00 00 11 D0 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 02 00 2B 0A 14 00 +T 91 19 00 00 00 00 00 00 CD 00 00 00 00 ED 5B +R 00 00 01 00 02 04 14 00 02 09 24 00 +T 98 19 00 00 3D 00 00 00 13 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 0A 0D 00 +T 9E 19 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0D 00 02 09 24 00 +T A4 19 00 00 CA 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 14 00 +T A9 19 00 00 00 00 00 00 CD 00 00 00 00 DD 5E +R 00 00 01 00 02 04 14 00 02 09 24 00 +T B0 19 00 00 FC DD 56 FD 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 0D 00 +T B7 19 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0D 00 02 09 24 00 +T BD 19 00 00 CD 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 14 00 +T C2 19 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 14 00 02 09 24 00 +T C8 19 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 3C 00 +T CD 19 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 3C 00 02 09 24 00 +T D2 19 00 00 R 00 00 01 00 -T 46 19 00 00 DD 6E FC DD 66 FD E5 2A +T D2 19 00 00 DD 6E FC DD 66 FD E5 2A R 00 00 01 00 -T 4E 19 00 00 3D 00 00 00 C1 71 23 70 2A +T DA 19 00 00 3D 00 00 00 C1 71 23 70 2A R 00 00 01 00 00 04 03 00 -T 55 19 00 00 3D 00 00 00 23 23 36 FF 23 36 7F +T E1 19 00 00 3D 00 00 00 23 23 36 FF 23 36 7F R 00 00 01 00 00 04 03 00 -T 5E 19 00 00 2A 3D 00 00 00 E5 DD 6E FA DD 66 +T EA 19 00 00 2A 3D 00 00 00 E5 DD 6E FA DD 66 R 00 00 01 00 00 05 03 00 -T 67 19 00 00 FB C1 71 23 70 +T F3 19 00 00 FB C1 71 23 70 R 00 00 01 00 -T 6C 19 00 00 +T F8 19 00 00 R 00 00 01 00 -T 6C 19 00 00 DD 6E FA DD 66 FB 23 23 ED 4B +T F8 19 00 00 DD 6E FA DD 66 FB 23 23 ED 4B R 00 00 01 00 -T 76 19 00 00 00 00 00 00 71 23 70 21 04 00 DD +T 02 1A 00 00 00 00 00 00 71 23 70 21 04 00 DD R 00 00 01 00 02 04 28 00 -T 7F 19 00 00 4E FA DD 46 FB 09 +T 0B 1A 00 00 4E FA DD 46 FB 09 R 00 00 01 00 -T 85 19 00 00 +T 11 1A 00 00 R 00 00 01 00 -T 85 19 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 88 19 00 00 +T 11 1A 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 10 00 +T 14 1A 00 00 R 00 00 01 00 -T 88 19 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD +T 14 1A 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD R 00 00 01 00 02 05 2A 00 -T 91 19 00 00 66 03 DD 75 FE DD 74 FF 7D B4 28 +T 1D 1A 00 00 66 03 DD 75 FE DD 74 FF 7D B4 28 R 00 00 01 00 -T 9C 19 00 00 35 +T 28 1A 00 00 35 R 00 00 01 00 -T 9D 19 00 00 +T 29 1A 00 00 R 00 00 01 00 -T 9D 19 00 00 DD 7E FE D6 04 DD 77 FE DD 7E FF +T 29 1A 00 00 DD 7E FE D6 04 DD 77 FE DD 7E FF R 00 00 01 00 -T A8 19 00 00 DE 00 DD 77 FF ED 4B 3D 00 00 00 +T 34 1A 00 00 DE 00 DD 77 FF ED 4B 3D 00 00 00 R 00 00 01 00 00 0B 03 00 -T B1 19 00 00 DD 6E FE DD 66 FF A7 ED 42 30 09 +T 3D 1A 00 00 DD 6E FE DD 66 FF A7 ED 42 30 09 R 00 00 01 00 -T BC 19 00 00 +T 48 1A 00 00 R 00 00 01 00 -T BC 19 00 00 DD 6E FE DD 66 FF 22 3D 00 00 00 +T 48 1A 00 00 DD 6E FE DD 66 FF 22 3D 00 00 00 R 00 00 01 00 00 0B 03 00 -T C5 19 00 00 +T 51 1A 00 00 R 00 00 01 00 -T C5 19 00 00 DD 6E FE DD 66 FF 23 23 36 FF 23 +T 51 1A 00 00 DD 6E FE DD 66 FF 23 23 36 FF 23 R 00 00 01 00 -T D0 19 00 00 36 7F +T 5C 1A 00 00 36 7F R 00 00 01 00 -T D2 19 00 00 +T 5E 1A 00 00 R 00 00 01 00 -T D2 19 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T D5 19 00 00 +T 5E 1A 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 10 00 +T 61 1A 00 00 R 00 00 01 00 -T D5 19 00 00 CD 00 00 00 00 FC FF 2A +T 61 1A 00 00 CD 00 00 00 00 FC FF 2A R 00 00 01 00 02 05 2A 00 -T DB 19 00 00 3B 00 00 00 DD 75 FE DD 74 FF 2A +T 67 1A 00 00 3B 00 00 00 DD 75 FE DD 74 FF 2A R 00 00 01 00 00 04 03 00 -T E4 19 00 00 39 00 00 00 DD 75 FC DD 74 FD +T 70 1A 00 00 39 00 00 00 DD 75 FC DD 74 FD R 00 00 01 00 00 04 03 00 -T EC 19 00 00 +T 78 1A 00 00 R 00 00 01 00 -T EC 19 00 00 DD 6E FE DD 66 FF DD 4E FC DD 46 +T 78 1A 00 00 DD 6E FE DD 66 FF DD 4E FC DD 46 R 00 00 01 00 -T F7 19 00 00 FD A7 ED 42 28 36 +T 83 1A 00 00 FD A7 ED 42 28 36 R 00 00 01 00 -T FD 19 00 00 +T 89 1A 00 00 R 00 00 01 00 -T FD 19 00 00 DD 6E FC DD 66 FD 23 23 46 23 66 +T 89 1A 00 00 DD 6E FC DD 66 FD 23 23 46 23 66 R 00 00 01 00 -T 08 1A 00 00 68 DD 4E 02 DD 46 03 CD +T 94 1A 00 00 68 DD 4E 02 DD 46 03 CD R 00 00 01 00 -T 10 1A 00 00 00 00 00 00 38 0D +T 9C 1A 00 00 00 00 00 00 38 0D R 00 00 01 00 02 04 30 00 -T 14 1A 00 00 +T A0 1A 00 00 R 00 00 01 00 -T 14 1A 00 00 DD 6E FC DD 66 FD 23 23 36 FF 23 +T A0 1A 00 00 DD 6E FC DD 66 FD 23 23 36 FF 23 R 00 00 01 00 -T 1F 1A 00 00 36 7F +T AB 1A 00 00 36 7F R 00 00 01 00 -T 21 1A 00 00 +T AD 1A 00 00 R 00 00 01 00 -T 21 1A 00 00 DD 6E FC DD 66 FD 46 23 66 68 DD +T AD 1A 00 00 DD 6E FC DD 66 FD 46 23 66 68 DD R 00 00 01 00 -T 2C 1A 00 00 75 FC DD 74 FD 18 B9 +T B8 1A 00 00 75 FC DD 74 FD 18 B9 R 00 00 01 00 -T 33 1A 00 00 +T BF 1A 00 00 R 00 00 01 00 -T 33 1A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 36 1A 00 00 +T BF 1A 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 10 00 +T C2 1A 00 00 R 00 00 01 00 -T 36 1A 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD +T C2 1A 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD R 00 00 01 00 02 05 2A 00 -T 3F 1A 00 00 66 03 DD 75 FE DD 74 FF 7D B4 28 +T CB 1A 00 00 66 03 DD 75 FE DD 74 FF 7D B4 28 R 00 00 01 00 -T 4A 1A 00 00 15 +T D6 1A 00 00 15 R 00 00 01 00 -T 4B 1A 00 00 +T D7 1A 00 00 R 00 00 01 00 -T 4B 1A 00 00 21 FC FF DD 4E FE DD 46 FF 09 23 +T D7 1A 00 00 21 FC FF DD 4E FE DD 46 FF 09 23 R 00 00 01 00 -T 56 1A 00 00 23 DD 4E 04 DD 46 05 71 23 70 +T E2 1A 00 00 23 DD 4E 04 DD 46 05 71 23 70 R 00 00 01 00 -T 60 1A 00 00 +T EC 1A 00 00 R 00 00 01 00 -T 60 1A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 63 1A 00 00 +T EC 1A 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 10 00 +T EF 1A 00 00 R 00 00 01 00 -T 63 1A 00 00 CD 00 00 00 00 21 FC FF 19 23 23 +T EF 1A 00 00 CD 00 00 00 00 21 FC FF 19 23 23 R 00 00 01 00 02 05 23 00 -T 6C 1A 00 00 46 23 66 68 C3 00 00 00 00 -R 00 00 01 00 02 09 0F 00 -T 73 1A 00 00 +T F8 1A 00 00 46 23 66 68 C3 00 00 00 00 +R 00 00 01 00 02 09 10 00 +T FF 1A 00 00 R 00 00 01 00 -T 73 1A 00 00 CD 00 00 00 00 FA FF 2A +T FF 1A 00 00 CD 00 00 00 00 FA FF 2A R 00 00 01 00 02 05 2A 00 -T 79 1A 00 00 3B 00 00 00 DD 75 FE DD 74 FF 2A +T 05 1B 00 00 3B 00 00 00 DD 75 FE DD 74 FF 2A R 00 00 01 00 00 04 03 00 -T 82 1A 00 00 39 00 00 00 DD 75 FA DD 74 FB +T 0E 1B 00 00 39 00 00 00 DD 75 FA DD 74 FB R 00 00 01 00 00 04 03 00 -T 8A 1A 00 00 +T 16 1B 00 00 R 00 00 01 00 -T 8A 1A 00 00 DD 6E FE DD 66 FF DD 4E FA DD 46 +T 16 1B 00 00 DD 6E FE DD 66 FF DD 4E FA DD 46 R 00 00 01 00 -T 95 1A 00 00 FB A7 ED 42 28 62 +T 21 1B 00 00 FB A7 ED 42 28 62 R 00 00 01 00 -T 9B 1A 00 00 +T 27 1B 00 00 R 00 00 01 00 -T 9B 1A 00 00 DD 6E FA DD 66 FB 23 23 4E 23 46 +T 27 1B 00 00 DD 6E FA DD 66 FB 23 23 4E 23 46 R 00 00 01 00 -T A6 1A 00 00 2A 00 00 00 00 CD 00 00 00 00 30 +T 32 1B 00 00 2A 00 00 00 00 CD 00 00 00 00 30 R 00 00 01 00 02 05 28 00 02 0A 30 00 -T AD 1A 00 00 3D +T 39 1B 00 00 3D R 00 00 01 00 -T AE 1A 00 00 +T 3A 1B 00 00 R 00 00 01 00 -T AE 1A 00 00 +T 3A 1B 00 00 R 00 00 01 00 -T AE 1A 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD +T 3A 1B 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD R 00 00 01 00 -T B9 1A 00 00 75 FC DD 74 FD 23 23 4E 23 46 2A +T 45 1B 00 00 75 FC DD 74 FD 23 23 4E 23 46 2A R 00 00 01 00 -T C4 1A 00 00 00 00 00 00 CD 00 00 00 00 30 17 +T 50 1B 00 00 00 00 00 00 CD 00 00 00 00 30 17 R 00 00 01 00 02 04 28 00 02 09 30 00 -T CB 1A 00 00 +T 57 1B 00 00 R 00 00 01 00 -T CB 1A 00 00 DD 6E FC DD 66 FD 46 23 66 68 E5 +T 57 1B 00 00 DD 6E FC DD 66 FD 46 23 66 68 E5 R 00 00 01 00 -T D6 1A 00 00 DD 6E FA DD 66 FB C1 71 23 70 18 +T 62 1B 00 00 DD 6E FA DD 66 FB C1 71 23 70 18 R 00 00 01 00 -T E1 1A 00 00 CC +T 6D 1B 00 00 CC R 00 00 01 00 -T E2 1A 00 00 +T 6E 1B 00 00 R 00 00 01 00 -T E2 1A 00 00 DD 6E FA DD 66 FB 22 3D 00 00 00 +T 6E 1B 00 00 DD 6E FA DD 66 FB 22 3D 00 00 00 R 00 00 01 00 00 0B 03 00 -T EB 1A 00 00 +T 77 1B 00 00 R 00 00 01 00 -T EB 1A 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD +T 77 1B 00 00 DD 6E FA DD 66 FB 46 23 66 68 DD R 00 00 01 00 -T F6 1A 00 00 75 FA DD 74 FB 18 8D +T 82 1B 00 00 75 FA DD 74 FB 18 8D R 00 00 01 00 -T FD 1A 00 00 +T 89 1B 00 00 R 00 00 01 00 -T FD 1A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 +T 89 1B 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 10 00 T 00 00 00 00 R 00 00 02 00 T 00 00 00 00 00 @@ -3163,6 +3210,38 @@ T 82 00 00 00 R 00 00 02 00 T 82 00 00 00 72 65 61 64 6F 6E 6C 79 20 00 R 00 00 02 00 +T 8C 00 00 00 +R 00 00 02 00 +T 8C 00 00 00 66 61 74 61 6C 3A 20 67 65 74 63 +R 00 00 02 00 +T 97 00 00 00 65 6C 6C 28 29 20 6E 62 79 74 65 +R 00 00 02 00 +T A2 00 00 00 73 20 3D 3D 20 30 0A 00 +R 00 00 02 00 +T AA 00 00 00 +R 00 00 02 00 +T AA 00 00 00 66 61 74 61 6C 3A 20 67 65 74 63 +R 00 00 02 00 +T B5 00 00 00 65 6C 6C 28 29 20 70 20 21 3D 20 +R 00 00 02 00 +T C0 00 00 00 61 72 65 61 74 6F 70 20 28 00 +R 00 00 02 00 +T CA 00 00 00 +R 00 00 02 00 +T CA 00 00 00 2C 20 00 +R 00 00 02 00 +T CD 00 00 00 +R 00 00 02 00 +T CD 00 00 00 29 0A 00 +R 00 00 02 00 +T D0 00 00 00 +R 00 00 02 00 +T D0 00 00 00 66 61 74 61 6C 3A 20 67 65 74 63 +R 00 00 02 00 +T DB 00 00 00 65 6C 6C 28 29 20 61 72 65 61 6E +R 00 00 02 00 +T E6 00 00 00 78 74 2B 31 20 3E 20 71 20 28 00 +R 00 00 02 00 T 00 00 00 00 R 00 00 03 00 T 00 00 00 00 diff --git a/src/sh/msh/sh2.c b/src/sh/msh/sh2.c index f0f83133..c23057cb 100644 --- a/src/sh/msh/sh2.c +++ b/src/sh/msh/sh2.c @@ -687,7 +687,11 @@ loop: startl = 1; if (multiline || cf & CONTIN) { if (talking && env.iop <= iostack) +#if 1 /* Nick */ + prs_expand(cprompt->value); +#else prs(cprompt->value); +#endif if (cf & CONTIN) goto loop; } @@ -735,7 +739,11 @@ register c, c1; return(YYERRCODE); } if (talking && c == '\n' && env.iop <= iostack) +#if 1 /* Nick */ + prs_expand(cprompt->value); +#else prs(cprompt->value); +#endif *env.linep++ = c; } *env.linep++ = c; diff --git a/src/sh/msh/sh2.rel b/src/sh/msh/sh2.rel index 7c37267d..dcf87894 100644 --- a/src/sh/msh/sh2.rel +++ b/src/sh/msh/sh2.rel @@ -1,5 +1,5 @@ XL4 -H 6 areas 2B global symbols +H 6 areas 2C global symbols M sh2 S cprompt Ref00000000 S ?BANK_FAST_LEAVE_L08 Ref00000000 @@ -34,6 +34,7 @@ S ?ENT_AUTO_DIRECT_L09 Ref00000000 S iostack Ref00000000 S getwords Ref00000000 S ?SS_CMP_L02 Ref00000000 +S prs_expand Ref00000000 S ?CL64180B_4_06_L00 Ref00000000 S elinep Ref00000000 S .__.ABS. Def00000000 @@ -1477,7 +1478,7 @@ R 00 00 01 00 T 2B 0E 00 00 2A 00 00 00 00 5E 23 56 3E R 00 00 01 00 02 05 00 00 T 32 0E 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +R 00 00 01 00 2B 04 21 00 02 09 21 00 T 37 0E 00 00 00 00 00 00 R 00 00 01 00 02 04 14 00 T 39 0E 00 00 @@ -1529,7 +1530,7 @@ R 00 00 01 00 T 93 0E 00 00 R 00 00 01 00 T 93 0E 00 00 2A 00 00 00 00 ED 4B 00 00 00 00 -R 00 00 01 00 02 05 06 00 02 0B 22 00 +R 00 00 01 00 02 05 06 00 02 0B 23 00 T 9A 0E 00 00 A7 ED 42 38 0D R 00 00 01 00 T 9F 0E 00 00 @@ -1659,7 +1660,7 @@ R 00 00 01 00 T B8 0F 00 00 2A 00 00 00 00 5E 23 56 3E R 00 00 01 00 02 05 00 00 T BF 0F 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +R 00 00 01 00 2B 04 21 00 02 09 21 00 T C4 0F 00 00 00 00 00 00 R 00 00 01 00 02 04 14 00 T C6 0F 00 00 diff --git a/src/sh/msh/sh3.c b/src/sh/msh/sh3.c index f25fabcb..b7a4509f 100644 --- a/src/sh/msh/sh3.c +++ b/src/sh/msh/sh3.c @@ -356,7 +356,11 @@ parent() i = fork(); if (i != 0) { if (i == -1) +#if 1 /* Nick */ + warn("can't fork - try again"); +#else warn("try again"); +#endif } return(i); } diff --git a/src/sh/msh/sh3.rel b/src/sh/msh/sh3.rel index 80a4e0e8..eea5f9d1 100644 --- a/src/sh/msh/sh3.rel +++ b/src/sh/msh/sh3.rel @@ -134,7 +134,7 @@ S doexec Def00001867 S docontinue Def00001FCD S doeval Def00001C1A S waitfor Def00001097 -A CSTR size 2D4 flags 0 +A CSTR size 2E1 flags 0 A IDATA0 size 84 flags 0 A CDATA0 size 84 flags 0 T 00 00 00 00 @@ -1419,11 +1419,11 @@ T AD 0C 00 00 R 00 00 01 00 T AD 0C 00 00 DD 6E 02 DD 66 03 23 23 7E E6 03 R 00 00 01 00 -T B8 0C 00 00 28 05 21 DB 00 00 00 18 03 +T B8 0C 00 00 28 05 21 E8 00 00 00 18 03 R 00 00 01 00 00 07 02 00 T BF 0C 00 00 R 00 00 01 00 -T BF 0C 00 00 21 E0 00 00 00 +T BF 0C 00 00 21 ED 00 00 00 R 00 00 01 00 00 05 02 00 T C2 0C 00 00 R 00 00 01 00 @@ -1483,7 +1483,7 @@ T 43 0D 00 00 DD 5E FC DD 56 FD 3E 00 00 00 00 R 00 00 01 00 2B 0B 25 00 T 4B 0D 00 00 21 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 05 25 00 02 0A 3D 00 -T 52 0D 00 00 E7 00 00 00 3E 00 00 00 00 21 +T 52 0D 00 00 F4 00 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 0F 00 T 57 0D 00 00 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -1543,9 +1543,9 @@ T F6 0D 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 59 00 02 09 59 00 T FB 0D 00 00 00 00 00 00 DD 75 FA DD 74 FB DD R 00 00 01 00 02 04 3D 00 -T 04 0E 00 00 36 FC FD 00 00 00 DD 36 FD +T 04 0E 00 00 36 FC 0A 01 00 00 DD 36 FD R 00 00 01 00 09 06 02 00 -T 0A 0E 00 00 FD 00 00 00 C3 A2 0E 00 00 +T 0A 0E 00 00 0A 01 00 00 C3 A2 0E 00 00 R 00 00 01 00 89 04 02 00 00 09 01 00 T 0E 0E 00 00 R 00 00 01 00 @@ -1609,7 +1609,7 @@ T A8 0E 00 00 DD 5E FC DD 56 FD 3E 00 00 00 00 R 00 00 01 00 2B 0B 25 00 T B0 0E 00 00 21 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 05 25 00 02 0A 3D 00 -T B7 0E 00 00 07 01 00 00 3E 00 00 00 00 21 +T B7 0E 00 00 14 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 25 00 T BC 0E 00 00 00 00 00 00 CD 00 00 00 00 DD 5E R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -1649,7 +1649,7 @@ T 14 0F 00 00 R 00 00 01 00 T 14 0F 00 00 CD 00 00 00 00 FE FF 11 R 00 00 01 00 02 05 46 00 -T 1A 0F 00 00 11 01 00 00 3E 00 00 00 00 21 +T 1A 0F 00 00 1E 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 25 00 T 1F 0F 00 00 00 00 00 00 CD 00 00 00 00 AF DD R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -1667,7 +1667,7 @@ T 3E 0F 00 00 DD 7E FE DD B6 FF 28 0B R 00 00 01 00 T 46 0F 00 00 R 00 00 01 00 -T 46 0F 00 00 11 13 01 00 00 3E 00 00 00 00 21 +T 46 0F 00 00 11 20 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 25 00 T 4C 0F 00 00 00 00 00 00 CD 00 00 00 00 R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -1917,7 +1917,7 @@ T 89 11 00 00 00 00 00 00 CD 00 00 00 00 R 00 00 01 00 02 04 25 00 02 09 3D 00 T 8E 11 00 00 R 00 00 01 00 -T 8E 11 00 00 11 15 01 00 00 3E 00 00 00 00 21 +T 8E 11 00 00 11 22 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 25 00 T 94 11 00 00 00 00 00 00 CD 00 00 00 00 DD 5E R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -1925,7 +1925,7 @@ T 9B 11 00 00 FA DD 56 FB 3E 00 00 00 00 21 R 00 00 01 00 2B 09 1D 00 T A2 11 00 00 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 04 1D 00 02 09 3D 00 -T A8 11 00 00 13 01 00 00 3E 00 00 00 00 21 +T A8 11 00 00 20 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 25 00 T AD 11 00 00 00 00 00 00 CD 00 00 00 00 R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -1937,7 +1937,7 @@ T BD 11 00 00 B0 28 0B R 00 00 01 00 T C0 11 00 00 R 00 00 01 00 -T C0 11 00 00 11 1D 01 00 00 3E 00 00 00 00 21 +T C0 11 00 00 11 2A 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 25 00 T C6 11 00 00 00 00 00 00 CD 00 00 00 00 R 00 00 01 00 02 04 25 00 02 09 3D 00 @@ -2031,7 +2031,7 @@ T 7E 12 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 R 00 00 01 00 2B 0B 0B 00 T 86 12 00 00 21 00 00 00 00 CD 00 00 00 00 4D R 00 00 01 00 02 05 0B 00 02 0A 3D 00 -T 8D 12 00 00 44 11 2C 01 00 00 3E 00 00 00 00 +T 8D 12 00 00 44 11 39 01 00 00 3E 00 00 00 00 R 00 00 01 00 00 06 02 00 2B 0B 30 00 T 93 12 00 00 21 00 00 00 00 CD 00 00 00 00 EB R 00 00 01 00 02 05 30 00 02 0A 3D 00 @@ -2177,15 +2177,15 @@ T F0 13 00 00 F4 13 00 00 6D 14 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 T F4 13 00 00 R 00 00 01 00 -T F4 13 00 00 21 2E 01 00 00 C3 90 14 00 00 +T F4 13 00 00 21 3B 01 00 00 C3 90 14 00 00 R 00 00 01 00 00 05 02 00 00 0A 01 00 T FA 13 00 00 R 00 00 01 00 -T FA 13 00 00 21 46 01 00 00 C3 90 14 00 00 +T FA 13 00 00 21 53 01 00 00 C3 90 14 00 00 R 00 00 01 00 00 05 02 00 00 0A 01 00 T 00 14 00 00 R 00 00 01 00 -T 00 14 00 00 21 5A 01 00 00 C3 90 14 00 00 +T 00 14 00 00 21 67 01 00 00 C3 90 14 00 00 R 00 00 01 00 00 05 02 00 00 0A 01 00 T 06 14 00 00 R 00 00 01 00 @@ -2201,7 +2201,7 @@ T 2E 14 00 00 00 00 00 00 DD 6E 04 DD 66 05 71 R 00 00 01 00 02 04 10 00 T 37 14 00 00 23 70 DD 6E 0A DD 66 0B E5 DD 4E R 00 00 01 00 -T 42 14 00 00 04 DD 46 05 11 75 01 00 00 3E +T 42 14 00 00 04 DD 46 05 11 82 01 00 00 3E R 00 00 01 00 00 09 02 00 T 4A 14 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 01 00 02 09 01 00 @@ -2209,15 +2209,15 @@ T 4F 14 00 00 00 00 00 00 F1 DD 6E FA DD 66 FB R 00 00 01 00 02 04 3D 00 T 58 14 00 00 E5 DD 6E 04 DD 66 05 C1 71 23 70 R 00 00 01 00 -T 63 14 00 00 21 7D 01 00 00 18 28 +T 63 14 00 00 21 8A 01 00 00 18 28 R 00 00 01 00 00 05 02 00 T 68 14 00 00 R 00 00 01 00 -T 68 14 00 00 21 86 01 00 00 18 23 +T 68 14 00 00 21 93 01 00 00 18 23 R 00 00 01 00 00 05 02 00 T 6D 14 00 00 R 00 00 01 00 -T 6D 14 00 00 21 96 01 00 00 18 1E +T 6D 14 00 00 21 A3 01 00 00 18 1E R 00 00 01 00 00 05 02 00 T 72 14 00 00 R 00 00 01 00 @@ -2235,11 +2235,11 @@ T 7F 14 00 00 R 00 00 01 00 T 7F 14 00 00 2A 00 00 00 00 3E 02 AD B4 20 05 R 00 00 01 00 02 05 40 00 -T 88 14 00 00 21 AD 01 00 00 18 03 +T 88 14 00 00 21 BA 01 00 00 18 03 R 00 00 01 00 00 05 02 00 T 8D 14 00 00 R 00 00 01 00 -T 8D 14 00 00 21 B7 01 00 00 +T 8D 14 00 00 21 C4 01 00 00 R 00 00 01 00 00 05 02 00 T 90 14 00 00 R 00 00 01 00 @@ -2357,9 +2357,9 @@ T D9 15 00 00 R 00 00 01 00 T D9 15 00 00 R 00 00 01 00 -T D9 15 00 00 DD 36 FE C6 01 00 00 DD 36 FF +T D9 15 00 00 DD 36 FE D3 01 00 00 DD 36 FF R 00 00 01 00 09 07 02 00 -T E0 15 00 00 C6 01 00 00 18 21 +T E0 15 00 00 D3 01 00 00 18 21 R 00 00 01 00 89 04 02 00 T E3 15 00 00 R 00 00 01 00 @@ -2371,9 +2371,9 @@ T F2 15 00 00 7C 28 0A R 00 00 01 00 T F5 15 00 00 R 00 00 01 00 -T F5 15 00 00 DD 36 FE DA 01 00 00 DD 36 FF +T F5 15 00 00 DD 36 FE E7 01 00 00 DD 36 FF R 00 00 01 00 09 07 02 00 -T FC 15 00 00 DA 01 00 00 18 05 +T FC 15 00 00 E7 01 00 00 18 05 R 00 00 01 00 89 04 02 00 T FF 15 00 00 R 00 00 01 00 @@ -2389,7 +2389,7 @@ T 0F 16 00 00 DD 56 FD 18 03 R 00 00 01 00 T 14 16 00 00 R 00 00 01 00 -T 14 16 00 00 11 EA 01 00 00 +T 14 16 00 00 11 F7 01 00 00 R 00 00 01 00 00 05 02 00 T 17 16 00 00 R 00 00 01 00 @@ -2431,7 +2431,7 @@ T 72 16 00 00 00 00 00 00 CD 00 00 00 00 30 10 R 00 00 01 00 02 04 3B 00 02 09 4B 00 T 79 16 00 00 R 00 00 01 00 -T 79 16 00 00 11 ED 01 00 00 3E 00 00 00 00 21 +T 79 16 00 00 11 FA 01 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 0F 00 T 7F 16 00 00 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -2455,7 +2455,7 @@ T BE 16 00 00 00 00 00 00 3E 00 00 00 00 21 R 00 00 01 00 02 04 3B 00 2B 09 0B 00 T C3 16 00 00 00 00 00 00 CD 00 00 00 00 4D 44 R 00 00 01 00 02 04 0B 00 02 09 3D 00 -T CA 16 00 00 11 FE 01 00 00 3E 00 00 00 00 21 +T CA 16 00 00 11 0B 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 30 00 T D0 16 00 00 00 00 00 00 CD 00 00 00 00 EB 3E R 00 00 01 00 02 04 30 00 02 09 3D 00 @@ -2693,7 +2693,7 @@ T 5A 19 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 0E 00 02 09 0E 00 T 5F 19 00 00 00 00 00 00 7D B4 28 05 21 R 00 00 01 00 02 04 3D 00 -T 66 19 00 00 00 02 00 00 18 07 +T 66 19 00 00 0D 02 00 00 18 07 R 00 00 01 00 00 04 02 00 T 6A 19 00 00 R 00 00 01 00 @@ -2797,7 +2797,7 @@ T 4E 1A 00 00 DD 5E FE DD 56 FF 3E 00 00 00 00 R 00 00 01 00 2B 0B 25 00 T 56 1A 00 00 21 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 05 25 00 02 0A 3D 00 -T 5D 1A 00 00 02 02 00 00 3E 00 00 00 00 21 +T 5D 1A 00 00 0F 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 0F 00 T 62 1A 00 00 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -2863,7 +2863,7 @@ T E9 1A 00 00 46 23 66 68 23 23 7E 23 B6 20 11 R 00 00 01 00 T F4 1A 00 00 R 00 00 01 00 -T F4 1A 00 00 11 0E 02 00 00 3E 00 00 00 00 21 +T F4 1A 00 00 11 1B 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 0F 00 T FA 1A 00 00 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -3243,7 +3243,7 @@ T 90 1E 00 00 R 00 00 01 00 T 90 1E 00 00 R 00 00 01 00 -T 90 1E 00 00 11 23 02 00 00 3E 00 00 00 00 21 +T 90 1E 00 00 11 30 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 0F 00 T 96 1E 00 00 00 00 00 00 CD 00 00 00 00 AF DD R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -3349,7 +3349,7 @@ T 89 1F 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 R 00 00 01 00 2B 0B 25 00 T 91 1F 00 00 21 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 05 25 00 02 0A 3D 00 -T 98 1F 00 00 3B 02 00 00 3E 00 00 00 00 21 +T 98 1F 00 00 48 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 0F 00 T 9D 1F 00 00 00 00 00 00 CD 00 00 00 00 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -3427,7 +3427,7 @@ T 4E 20 00 00 DD 7E FE DD B6 FF 28 10 R 00 00 01 00 T 56 20 00 00 R 00 00 01 00 -T 56 20 00 00 11 48 02 00 00 3E 00 00 00 00 21 +T 56 20 00 00 11 55 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 05 02 00 2B 0A 0F 00 T 5C 20 00 00 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -3565,7 +3565,7 @@ T 8B 21 00 00 CD 00 00 00 00 3E 00 00 00 00 21 R 00 00 01 00 02 05 3C 00 2B 0A 25 00 T 91 21 00 00 00 00 00 00 CD 00 00 00 00 11 R 00 00 01 00 02 04 25 00 02 09 3D 00 -T 97 21 00 00 61 02 00 00 3E 00 00 00 00 21 +T 97 21 00 00 6E 02 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 02 00 2B 09 0F 00 T 9C 21 00 00 00 00 00 00 CD 00 00 00 00 C3 R 00 00 01 00 02 04 0F 00 02 09 3D 00 @@ -3761,7 +3761,7 @@ T 81 23 00 00 00 00 00 00 ED 5B 00 00 00 00 3E R 00 00 01 00 02 04 52 00 02 0A 3B 00 T 88 23 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 0B 00 02 09 0B 00 -T 8D 23 00 00 00 00 00 00 4D 44 11 FE 01 00 00 +T 8D 23 00 00 00 00 00 00 4D 44 11 0B 02 00 00 R 00 00 01 00 02 04 3D 00 00 0B 02 00 T 94 23 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 30 00 02 0A 30 00 @@ -3959,243 +3959,247 @@ T CE 00 00 00 3A 20 00 R 00 00 02 00 T D1 00 00 00 R 00 00 02 00 -T D1 00 00 00 74 72 79 20 61 67 61 69 6E 00 +T D1 00 00 00 63 61 6E 27 74 20 66 6F 72 6B 20 R 00 00 02 00 -T DB 00 00 00 +T DC 00 00 00 2D 20 74 72 79 20 61 67 61 69 6E R 00 00 02 00 -T DB 00 00 00 6F 70 65 6E 00 +T E7 00 00 00 00 R 00 00 02 00 -T E0 00 00 00 +T E8 00 00 00 R 00 00 02 00 -T E0 00 00 00 63 72 65 61 74 65 00 +T E8 00 00 00 6F 70 65 6E 00 R 00 00 02 00 -T E7 00 00 00 +T ED 00 00 00 R 00 00 02 00 -T E7 00 00 00 3A 20 69 6C 6C 65 67 61 6C 20 3E +T ED 00 00 00 63 72 65 61 74 65 00 R 00 00 02 00 -T F2 00 00 00 26 20 61 72 67 75 6D 65 6E 74 00 +T F4 00 00 00 R 00 00 02 00 -T FD 00 00 00 +T F4 00 00 00 3A 20 69 6C 6C 65 67 61 6C 20 3E R 00 00 02 00 -T FD 00 00 00 68 65 72 65 20 66 69 6C 65 00 +T FF 00 00 00 26 20 61 72 67 75 6D 65 6E 74 00 R 00 00 02 00 -T 07 01 00 00 +T 0A 01 00 00 R 00 00 02 00 -T 07 01 00 00 3A 20 63 61 6E 6E 6F 74 20 00 +T 0A 01 00 00 68 65 72 65 20 66 69 6C 65 00 R 00 00 02 00 -T 11 01 00 00 +T 14 01 00 00 R 00 00 02 00 -T 11 01 00 00 2B 00 +T 14 01 00 00 3A 20 63 61 6E 6E 6F 74 20 00 R 00 00 02 00 -T 13 01 00 00 +T 1E 01 00 00 R 00 00 02 00 -T 13 01 00 00 20 00 +T 1E 01 00 00 2B 00 R 00 00 02 00 -T 15 01 00 00 +T 20 01 00 00 R 00 00 02 00 -T 15 01 00 00 53 69 67 6E 61 6C 20 00 +T 20 01 00 00 20 00 R 00 00 02 00 -T 1D 01 00 00 +T 22 01 00 00 R 00 00 02 00 -T 1D 01 00 00 20 2D 20 63 6F 72 65 20 64 75 6D +T 22 01 00 00 53 69 67 6E 61 6C 20 00 R 00 00 02 00 -T 28 01 00 00 70 65 64 00 +T 2A 01 00 00 R 00 00 02 00 -T 2C 01 00 00 +T 2A 01 00 00 20 2D 20 63 6F 72 65 20 64 75 6D R 00 00 02 00 -T 2C 01 00 00 3F 00 +T 35 01 00 00 70 65 64 00 R 00 00 02 00 -T 2E 01 00 00 +T 39 01 00 00 R 00 00 02 00 -T 2E 01 00 00 65 78 65 63 75 74 61 62 6C 65 20 +T 39 01 00 00 3F 00 R 00 00 02 00 -T 39 01 00 00 66 6F 72 6D 61 74 20 65 72 72 6F +T 3B 01 00 00 R 00 00 02 00 -T 44 01 00 00 72 00 +T 3B 01 00 00 65 78 65 63 75 74 61 62 6C 65 20 R 00 00 02 00 -T 46 01 00 00 +T 46 01 00 00 66 6F 72 6D 61 74 20 65 72 72 6F R 00 00 02 00 -T 46 01 00 00 66 69 6C 65 20 69 73 20 6E 6F 74 +T 51 01 00 00 72 00 R 00 00 02 00 -T 51 01 00 00 20 61 6C 69 67 6E 65 64 00 +T 53 01 00 00 R 00 00 02 00 -T 5A 01 00 00 +T 53 01 00 00 66 69 6C 65 20 69 73 20 6E 6F 74 R 00 00 02 00 -T 5A 01 00 00 66 69 6C 65 20 69 73 20 74 6F 6F +T 5E 01 00 00 20 61 6C 69 67 6E 65 64 00 R 00 00 02 00 -T 65 01 00 00 20 73 68 6F 72 74 2C 20 6F 72 20 +T 67 01 00 00 R 00 00 02 00 -T 70 01 00 00 68 6F 6C 65 00 +T 67 01 00 00 66 69 6C 65 20 69 73 20 74 6F 6F R 00 00 02 00 -T 75 01 00 00 +T 72 01 00 00 20 73 68 6F 72 74 2C 20 6F 72 20 R 00 00 02 00 -T 75 01 00 00 2F 62 69 6E 2F 73 68 00 +T 7D 01 00 00 68 6F 6C 65 00 R 00 00 02 00 -T 7D 01 00 00 +T 82 01 00 00 R 00 00 02 00 -T 7D 01 00 00 6E 6F 20 53 68 65 6C 6C 00 +T 82 01 00 00 2F 62 69 6E 2F 73 68 00 R 00 00 02 00 -T 86 01 00 00 +T 8A 01 00 00 R 00 00 02 00 -T 86 01 00 00 70 72 6F 67 72 61 6D 20 74 6F 6F +T 8A 01 00 00 6E 6F 20 53 68 65 6C 6C 00 R 00 00 02 00 -T 91 01 00 00 20 62 69 67 00 +T 93 01 00 00 R 00 00 02 00 -T 96 01 00 00 +T 93 01 00 00 70 72 6F 67 72 61 6D 20 74 6F 6F R 00 00 02 00 -T 96 01 00 00 61 72 67 75 6D 65 6E 74 20 6C 69 +T 9E 01 00 00 20 62 69 67 00 R 00 00 02 00 -T A1 01 00 00 73 74 20 74 6F 6F 20 6C 6F 6E 67 +T A3 01 00 00 R 00 00 02 00 -T AC 01 00 00 00 +T A3 01 00 00 61 72 67 75 6D 65 6E 74 20 6C 69 R 00 00 02 00 -T AD 01 00 00 +T AE 01 00 00 73 74 20 74 6F 6F 20 6C 6F 6E 67 R 00 00 02 00 -T AD 01 00 00 6E 6F 74 20 66 6F 75 6E 64 00 +T B9 01 00 00 00 R 00 00 02 00 -T B7 01 00 00 +T BA 01 00 00 R 00 00 02 00 -T B7 01 00 00 63 61 6E 6E 6F 74 20 65 78 65 63 +T BA 01 00 00 6E 6F 74 20 66 6F 75 6E 64 00 R 00 00 02 00 -T C2 01 00 00 75 74 65 00 +T C4 01 00 00 R 00 00 02 00 -T C6 01 00 00 +T C4 01 00 00 63 61 6E 6E 6F 74 20 65 78 65 63 R 00 00 02 00 -T C6 01 00 00 3A 20 6E 6F 20 68 6F 6D 65 20 64 +T CF 01 00 00 75 74 65 00 R 00 00 02 00 -T D1 01 00 00 69 72 65 63 74 6F 72 79 00 +T D3 01 00 00 R 00 00 02 00 -T DA 01 00 00 +T D3 01 00 00 3A 20 6E 6F 20 68 6F 6D 65 20 64 R 00 00 02 00 -T DA 01 00 00 3A 20 62 61 64 20 64 69 72 65 63 +T DE 01 00 00 69 72 65 63 74 6F 72 79 00 R 00 00 02 00 -T E5 01 00 00 74 6F 72 79 00 +T E7 01 00 00 R 00 00 02 00 -T EA 01 00 00 +T E7 01 00 00 3A 20 62 61 64 20 64 69 72 65 63 R 00 00 02 00 -T EA 01 00 00 63 64 00 +T F2 01 00 00 74 6F 72 79 00 R 00 00 02 00 -T ED 01 00 00 +T F7 01 00 00 R 00 00 02 00 -T ED 01 00 00 6E 6F 74 68 69 6E 67 20 74 6F 20 +T F7 01 00 00 63 64 00 R 00 00 02 00 -T F8 01 00 00 73 68 69 66 74 00 +T FA 01 00 00 R 00 00 02 00 -T FE 01 00 00 +T FA 01 00 00 6E 6F 74 68 69 6E 67 20 74 6F 20 R 00 00 02 00 -T FE 01 00 00 23 00 +T 05 02 00 00 73 68 69 66 74 00 R 00 00 02 00 -T 00 02 00 00 +T 0B 02 00 00 R 00 00 02 00 -T 00 02 00 00 3A 00 +T 0B 02 00 00 23 00 R 00 00 02 00 -T 02 02 00 00 +T 0D 02 00 00 R 00 00 02 00 -T 02 02 00 00 3A 20 6E 6F 74 20 66 6F 75 6E 64 +T 0D 02 00 00 3A 00 R 00 00 02 00 -T 0D 02 00 00 00 +T 0F 02 00 00 R 00 00 02 00 -T 0E 02 00 00 +T 0F 02 00 00 3A 20 6E 6F 74 20 66 6F 75 6E 64 R 00 00 02 00 -T 0E 02 00 00 55 73 61 67 65 3A 20 72 65 61 64 +T 1A 02 00 00 00 R 00 00 02 00 -T 19 02 00 00 20 6E 61 6D 65 20 2E 2E 2E 00 +T 1B 02 00 00 R 00 00 02 00 -T 23 02 00 00 +T 1B 02 00 00 55 73 61 67 65 3A 20 72 65 61 64 R 00 00 02 00 -T 23 02 00 00 74 72 61 70 3A 20 62 61 64 20 73 +T 26 02 00 00 20 6E 61 6D 65 20 2E 2E 2E 00 R 00 00 02 00 -T 2E 02 00 00 69 67 6E 61 6C 20 6E 75 6D 62 65 +T 30 02 00 00 R 00 00 02 00 -T 39 02 00 00 72 00 +T 30 02 00 00 74 72 61 70 3A 20 62 61 64 20 73 R 00 00 02 00 -T 3B 02 00 00 -R 00 00 02 00 -T 3B 02 00 00 3A 20 62 61 64 20 6E 75 6D 62 65 +T 3B 02 00 00 69 67 6E 61 6C 20 6E 75 6D 62 65 R 00 00 02 00 T 46 02 00 00 72 00 R 00 00 02 00 T 48 02 00 00 R 00 00 02 00 -T 48 02 00 00 62 61 64 20 62 72 65 61 6B 2F 63 -R 00 00 02 00 -T 53 02 00 00 6F 6E 74 69 6E 75 65 20 6C 65 76 +T 48 02 00 00 3A 20 62 61 64 20 6E 75 6D 62 65 R 00 00 02 00 -T 5E 02 00 00 65 6C 00 +T 53 02 00 00 72 00 R 00 00 02 00 -T 61 02 00 00 +T 55 02 00 00 R 00 00 02 00 -T 61 02 00 00 3A 20 62 61 64 20 69 64 65 6E 74 +T 55 02 00 00 62 61 64 20 62 72 65 61 6B 2F 63 R 00 00 02 00 -T 6C 02 00 00 69 66 69 65 72 00 +T 60 02 00 00 6F 6E 74 69 6E 75 65 20 6C 65 76 R 00 00 02 00 -T 72 02 00 00 +T 6B 02 00 00 65 6C 00 R 00 00 02 00 -T 72 02 00 00 73 68 69 66 74 00 +T 6E 02 00 00 R 00 00 02 00 -T 78 02 00 00 +T 6E 02 00 00 3A 20 62 61 64 20 69 64 65 6E 74 R 00 00 02 00 -T 78 02 00 00 65 78 65 63 00 +T 79 02 00 00 69 66 69 65 72 00 R 00 00 02 00 -T 7D 02 00 00 +T 7F 02 00 00 R 00 00 02 00 -T 7D 02 00 00 77 61 69 74 00 +T 7F 02 00 00 73 68 69 66 74 00 R 00 00 02 00 -T 82 02 00 00 +T 85 02 00 00 R 00 00 02 00 -T 82 02 00 00 72 65 61 64 00 +T 85 02 00 00 65 78 65 63 00 R 00 00 02 00 -T 87 02 00 00 +T 8A 02 00 00 R 00 00 02 00 -T 87 02 00 00 65 76 61 6C 00 +T 8A 02 00 00 77 61 69 74 00 R 00 00 02 00 -T 8C 02 00 00 +T 8F 02 00 00 R 00 00 02 00 -T 8C 02 00 00 74 72 61 70 00 +T 8F 02 00 00 72 65 61 64 00 R 00 00 02 00 -T 91 02 00 00 +T 94 02 00 00 R 00 00 02 00 -T 91 02 00 00 62 72 65 61 6B 00 +T 94 02 00 00 65 76 61 6C 00 R 00 00 02 00 -T 97 02 00 00 +T 99 02 00 00 R 00 00 02 00 -T 97 02 00 00 63 6F 6E 74 69 6E 75 65 00 +T 99 02 00 00 74 72 61 70 00 R 00 00 02 00 -T A0 02 00 00 +T 9E 02 00 00 R 00 00 02 00 -T A0 02 00 00 65 78 69 74 00 +T 9E 02 00 00 62 72 65 61 6B 00 R 00 00 02 00 -T A5 02 00 00 +T A4 02 00 00 R 00 00 02 00 -T A5 02 00 00 65 78 70 6F 72 74 00 +T A4 02 00 00 63 6F 6E 74 69 6E 75 65 00 R 00 00 02 00 -T AC 02 00 00 +T AD 02 00 00 R 00 00 02 00 -T AC 02 00 00 72 65 61 64 6F 6E 6C 79 00 +T AD 02 00 00 65 78 69 74 00 R 00 00 02 00 -T B5 02 00 00 +T B2 02 00 00 R 00 00 02 00 -T B5 02 00 00 73 65 74 00 +T B2 02 00 00 65 78 70 6F 72 74 00 R 00 00 02 00 T B9 02 00 00 R 00 00 02 00 -T B9 02 00 00 2E 00 +T B9 02 00 00 72 65 61 64 6F 6E 6C 79 00 R 00 00 02 00 -T BB 02 00 00 +T C2 02 00 00 R 00 00 02 00 -T BB 02 00 00 75 6D 61 73 6B 00 +T C2 02 00 00 73 65 74 00 R 00 00 02 00 -T C1 02 00 00 +T C6 02 00 00 R 00 00 02 00 -T C1 02 00 00 6C 6F 67 69 6E 00 +T C6 02 00 00 2E 00 R 00 00 02 00 -T C7 02 00 00 +T C8 02 00 00 R 00 00 02 00 -T C7 02 00 00 6E 65 77 67 72 70 00 +T C8 02 00 00 75 6D 61 73 6B 00 R 00 00 02 00 T CE 02 00 00 R 00 00 02 00 -T CE 02 00 00 74 69 6D 65 73 00 +T CE 02 00 00 6C 6F 67 69 6E 00 +R 00 00 02 00 +T D4 02 00 00 +R 00 00 02 00 +T D4 02 00 00 6E 65 77 67 72 70 00 +R 00 00 02 00 +T DB 02 00 00 +R 00 00 02 00 +T DB 02 00 00 74 69 6D 65 73 00 R 00 00 02 00 T 00 00 00 00 R 00 00 03 00 @@ -4219,43 +4223,43 @@ T 16 00 00 00 6B 00 00 00 78 00 00 00 00 00 R 00 00 04 00 00 04 02 00 00 08 02 00 T 1C 00 00 00 88 00 00 00 94 00 00 00 R 00 00 04 00 00 04 02 00 00 08 02 00 -T 20 00 00 00 00 02 00 00 A1 15 00 00 +T 20 00 00 00 0D 02 00 00 A1 15 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 25 00 00 00 EA 01 00 00 A7 15 00 00 +T 25 00 00 00 F7 01 00 00 A7 15 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 2A 00 00 00 72 02 00 00 33 16 00 00 +T 2A 00 00 00 7F 02 00 00 33 16 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 2F 00 00 00 78 02 00 00 67 18 00 00 +T 2F 00 00 00 85 02 00 00 67 18 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 34 00 00 00 7D 02 00 00 6D 1A 00 00 +T 34 00 00 00 8A 02 00 00 6D 1A 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 39 00 00 00 82 02 00 00 D5 1A 00 00 +T 39 00 00 00 8F 02 00 00 D5 1A 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 3E 00 00 00 87 02 00 00 1A 1C 00 00 +T 3E 00 00 00 94 02 00 00 1A 1C 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 43 00 00 00 8C 02 00 00 40 1C 00 00 +T 43 00 00 00 99 02 00 00 40 1C 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 48 00 00 00 91 02 00 00 B5 1F 00 00 +T 48 00 00 00 9E 02 00 00 B5 1F 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 4D 00 00 00 97 02 00 00 CD 1F 00 00 +T 4D 00 00 00 A4 02 00 00 CD 1F 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 52 00 00 00 A0 02 00 00 83 20 00 00 +T 52 00 00 00 AD 02 00 00 83 20 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 57 00 00 00 A5 02 00 00 CC 20 00 00 +T 57 00 00 00 B2 02 00 00 CC 20 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 5C 00 00 00 AC 02 00 00 EE 20 00 00 +T 5C 00 00 00 B9 02 00 00 EE 20 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 61 00 00 00 B5 02 00 00 A4 21 00 00 +T 61 00 00 00 C2 02 00 00 A4 21 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 66 00 00 00 B9 02 00 00 29 19 00 00 +T 66 00 00 00 C6 02 00 00 29 19 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 6B 00 00 00 BB 02 00 00 84 17 00 00 +T 6B 00 00 00 C8 02 00 00 84 17 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 70 00 00 00 C1 02 00 00 E4 16 00 00 +T 70 00 00 00 CE 02 00 00 E4 16 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 75 00 00 00 C7 02 00 00 E4 16 00 00 +T 75 00 00 00 D4 02 00 00 E4 16 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 -T 7A 00 00 00 CE 02 00 00 0C 24 00 00 00 00 00 +T 7A 00 00 00 DB 02 00 00 0C 24 00 00 00 00 00 R 00 00 04 00 00 04 02 00 48 08 01 00 T 82 00 00 00 00 00 R 00 00 04 00 diff --git a/src/sh/msh/sh4.c b/src/sh/msh/sh4.c index 006650cc..619ac5ac 100644 --- a/src/sh/msh/sh4.c +++ b/src/sh/msh/sh4.c @@ -365,7 +365,11 @@ int quoted; return(0); if ((i = fork()) == -1) { closepipe(pf); +#if 1 /* Nick */ + err("can't fork - try again"); +#else err("try again"); +#endif return(0); } if (i != 0) { @@ -481,6 +485,10 @@ register char *pp; struct dirent *de; char dname[NAME_MAX+1]; struct stat dbuf; +#if 1 /* Nick, preallocate buffers, as msh doesn't like sharing its heap */ + DIR dir; + struct dirent dd; +#endif for (np = we; np != pp; pp--) if (pp[-1] == '/') @@ -492,14 +500,22 @@ register char *pp; for (gp = cp = space(strlen(pp)+1); *np && *np != '/';) *cp++ = *np++; *cp = '\0'; +#if 1 /* Nick, preallocate buffers, as msh doesn't like sharing its heap */ + dirp = nick_opendir(dp, &dir, &dd); +#else dirp = opendir(dp); +#endif if (dirp == 0) { DELETE(dp); DELETE(gp); return; } dname[NAME_MAX] = '\0'; +#if 1 /* Nick, preallocate buffers, as msh doesn't like sharing its heap */ + while ((de=nick_readdir(dirp))!=NULL) { +#else while ((de=readdir(dirp))!=NULL) { +#endif /* XXX Hmmm... What this could be? (abial) */ /* if (ent[j].d_ino == 0) @@ -523,7 +539,11 @@ register char *pp; nl = addword(name, nl); } } +#if 1 /* Nick, preallocate buffers, as msh doesn't like sharing its heap */ + nick_closedir(dirp); +#else closedir(dirp); +#endif DELETE(dp); DELETE(gp); } diff --git a/src/sh/msh/sh4.rel b/src/sh/msh/sh4.rel index 3c570d27..7f418374 100644 --- a/src/sh/msh/sh4.rel +++ b/src/sh/msh/sh4.rel @@ -23,16 +23,16 @@ S ?BANK_LEAVE_DIRECT_L08 Ref00000000 S remap Ref00000000 S prs Ref00000000 S letnum Ref00000000 -S closedir Ref00000000 S close Ref00000000 S strlen Ref00000000 S pushio Ref00000000 S strcmp Ref00000000 +S nick_closedir Ref00000000 S ?LEAVE_DIRECT_L09 Ref00000000 S lookup Ref00000000 S flag Ref00000000 -S readdir Ref00000000 S dolchar Ref00000000 +S nick_readdir Ref00000000 S openpipe Ref00000000 S gflg Ref00000000 S onecommand Ref00000000 @@ -51,11 +51,11 @@ S errpt Ref00000000 S iostack Ref00000000 S temparg Ref00000000 S ?SS_CMP_L02 Ref00000000 -S opendir Ref00000000 S vlist Ref00000000 S fork Ref00000000 S gravechar Ref00000000 S gmatch Ref00000000 +S nick_opendir Ref00000000 S dolv Ref00000000 S ?US_DIV_L02 Ref00000000 S ?CL64180B_4_06_L00 Ref00000000 @@ -72,23 +72,23 @@ S signal Ref00000000 S .__.ABS. Def00000000 S readc Ref00000000 A _DEFAULT size 0 flags 0 -A CODE size 1A5B flags 0 +A CODE size 1A67 flags 0 S evalstr Def0000022A S makenv Def000001A6 S globname Def00001011 -S newword Def0000148D +S newword Def00001499 S unquote Def00000CF0 -S glob0 Def00001626 -S glob1 Def00001661 -S glob2 Def00001923 -S glob3 Def00001986 +S glob0 Def00001632 +S glob1 Def0000166D +S glob2 Def0000192F +S glob3 Def00001992 S glob Def00000D2C -S addword Def000014CA +S addword Def000014D6 S eval Def00000000 S subgetc Def000006B6 -S getwords Def00001599 -S memcopy Def00001A10 -A CSTR size 92 flags 0 +S getwords Def000015A5 +S memcopy Def00001A1C +A CSTR size 9F flags 0 A UDATA0 size 9 flags 0 S globv Def00000007 S func Def00000004 @@ -188,7 +188,7 @@ T EB 00 00 00 R 00 00 01 00 T EB 00 00 00 DD 4E EE DD 46 EF 11 00 00 3E R 00 00 01 00 -T F5 00 00 00 CA 14 00 00 21 CA 14 00 00 CD +T F5 00 00 00 D6 14 00 00 21 D6 14 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T FA 00 00 00 00 00 00 00 DD 75 EE DD 74 EF R 00 00 01 00 02 04 26 00 @@ -234,11 +234,11 @@ T 5D 01 00 00 R 00 00 01 00 T 5D 01 00 00 DD 4E EE DD 46 EF 11 00 00 3E R 00 00 01 00 -T 67 01 00 00 CA 14 00 00 21 CA 14 00 00 CD +T 67 01 00 00 D6 14 00 00 21 D6 14 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 6C 01 00 00 00 00 00 00 DD 75 EE DD 74 EF EB R 00 00 01 00 02 04 26 00 -T 75 01 00 00 3E 99 15 00 00 21 99 15 00 00 CD +T 75 01 00 00 3E A5 15 00 00 21 A5 15 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 7B 01 00 00 00 00 00 00 DD 75 F0 DD 74 F1 3E R 00 00 01 00 02 04 26 00 @@ -269,7 +269,7 @@ R 00 00 01 00 T A6 01 00 00 CD 00 00 00 00 FC FF AF DD 77 FC R 00 00 01 00 02 05 2D 00 T AF 01 00 00 DD 77 FD 2A 00 00 00 00 DD 75 FE -R 00 00 01 00 02 08 33 00 +R 00 00 01 00 02 08 32 00 T B8 01 00 00 DD 74 FF R 00 00 01 00 T BB 01 00 00 @@ -286,9 +286,9 @@ T D2 01 00 00 R 00 00 01 00 T D2 01 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 R 00 00 01 00 -T DD 01 00 00 FF 23 23 5E 23 56 3E CA 14 00 00 +T DD 01 00 00 FF 23 23 5E 23 56 3E D6 14 00 00 R 00 00 01 00 29 0B 01 00 -T E5 01 00 00 21 CA 14 00 00 CD 00 00 00 00 DD +T E5 01 00 00 21 D6 14 00 00 CD 00 00 00 00 DD R 00 00 01 00 00 05 01 00 02 0A 26 00 T EC 01 00 00 75 FC DD 74 FD R 00 00 01 00 @@ -302,11 +302,11 @@ T 07 02 00 00 R 00 00 01 00 T 07 02 00 00 DD 4E FC DD 46 FD 11 00 00 3E R 00 00 01 00 -T 11 02 00 00 CA 14 00 00 21 CA 14 00 00 CD +T 11 02 00 00 D6 14 00 00 21 D6 14 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 16 02 00 00 00 00 00 00 DD 75 FC DD 74 FD EB R 00 00 01 00 02 04 26 00 -T 1F 02 00 00 3E 99 15 00 00 21 99 15 00 00 CD +T 1F 02 00 00 3E A5 15 00 00 21 A5 15 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 25 02 00 00 00 00 00 00 C3 00 00 00 00 R 00 00 01 00 02 04 26 00 02 09 12 00 @@ -422,9 +422,9 @@ T 35 03 00 00 R 00 00 01 00 T 35 03 00 00 DD 6E 04 DD 66 05 4E 23 46 DD 5E R 00 00 01 00 -T 40 03 00 00 02 DD 56 03 3E CA 14 00 00 21 +T 40 03 00 00 02 DD 56 03 3E D6 14 00 00 21 R 00 00 01 00 29 09 01 00 -T 47 03 00 00 CA 14 00 00 CD 00 00 00 00 E5 DD +T 47 03 00 00 D6 14 00 00 CD 00 00 00 00 E5 DD R 00 00 01 00 00 04 01 00 02 09 26 00 T 4E 03 00 00 6E 04 DD 66 05 C1 71 23 70 21 R 00 00 01 00 @@ -449,9 +449,9 @@ R 00 00 01 00 02 0B 30 00 T 84 03 00 00 0E 00 00 00 00 C5 21 00 00 00 00 R 00 00 01 00 2B 05 3A 00 02 0B 3A 00 T 8A 03 00 00 E5 11 00 00 00 00 3E 00 00 00 00 -R 00 00 01 00 02 06 30 00 2B 0B 19 00 +R 00 00 01 00 02 06 30 00 2B 0B 18 00 T 90 03 00 00 21 00 00 00 00 CD 00 00 00 00 E1 -R 00 00 01 00 02 05 19 00 02 0A 26 00 +R 00 00 01 00 02 05 18 00 02 0A 26 00 T 97 03 00 00 E1 2A 04 00 00 00 22 02 00 00 00 R 00 00 01 00 02 06 07 00 02 0B 07 00 T 9E 03 00 00 @@ -496,9 +496,9 @@ T FD 03 00 00 R 00 00 01 00 T FD 03 00 00 DD 6E 04 DD 66 05 4E 23 46 DD 5E R 00 00 01 00 -T 08 04 00 00 02 DD 56 03 3E CA 14 00 00 21 +T 08 04 00 00 02 DD 56 03 3E D6 14 00 00 21 R 00 00 01 00 29 09 01 00 -T 0F 04 00 00 CA 14 00 00 CD 00 00 00 00 E5 DD +T 0F 04 00 00 D6 14 00 00 CD 00 00 00 00 E5 DD R 00 00 01 00 00 04 01 00 02 09 26 00 T 16 04 00 00 6E 04 DD 66 05 C1 71 23 70 18 22 R 00 00 01 00 @@ -1117,11 +1117,11 @@ R 00 00 01 00 02 0B 07 00 T 17 09 00 00 2A 00 00 00 00 23 23 22 R 00 00 01 00 02 05 37 00 T 1D 09 00 00 02 00 00 00 0E 00 00 00 00 C5 21 -R 00 00 01 00 02 04 30 00 2B 09 1F 00 +R 00 00 01 00 02 04 30 00 2B 09 1E 00 T 23 09 00 00 00 00 00 00 E5 11 00 00 00 00 3E -R 00 00 01 00 02 04 1F 00 02 0A 30 00 +R 00 00 01 00 02 04 1E 00 02 0A 30 00 T 2A 09 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 19 00 02 09 19 00 +R 00 00 01 00 2B 04 18 00 02 09 18 00 T 2F 09 00 00 00 00 00 00 E1 E1 21 00 00 C3 R 00 00 01 00 02 04 26 00 T 37 09 00 00 B2 0A 00 00 @@ -1273,7 +1273,7 @@ R 00 00 01 00 T 9F 0A 00 00 4F C5 E5 11 00 00 00 00 3E R 00 00 01 00 02 08 30 00 T A6 0A 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 19 00 02 09 19 00 +R 00 00 01 00 2B 04 18 00 02 09 18 00 T AB 0A 00 00 00 00 00 00 E1 E1 21 00 00 R 00 00 01 00 02 04 26 00 T B2 0A 00 00 @@ -1327,7 +1327,7 @@ R 00 00 01 00 00 08 01 00 T 16 0B 00 00 R 00 00 01 00 T 16 0B 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 34 00 02 0A 34 00 +R 00 00 01 00 2B 05 33 00 02 0A 33 00 T 1C 0B 00 00 00 00 00 00 DD 75 FA DD 74 FB 7D R 00 00 01 00 02 04 26 00 T 25 0B 00 00 A4 3C 20 1F @@ -1357,7 +1357,7 @@ R 00 00 01 00 T 64 0B 00 00 DD 70 F9 71 23 70 DD 5E FE DD 56 R 00 00 01 00 T 6F 0B 00 00 FF 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 17 00 02 0B 17 00 +R 00 00 01 00 2B 06 16 00 02 0B 16 00 T 75 0B 00 00 CD 00 00 00 00 DD 5E FC DD 56 FD R 00 00 01 00 02 05 26 00 T 7E 0B 00 00 3E 00 00 00 00 21 00 00 00 00 CD @@ -1371,13 +1371,13 @@ R 00 00 01 00 02 05 29 00 T 98 0B 00 00 R 00 00 01 00 T 98 0B 00 00 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 05 35 00 02 0A 35 00 +R 00 00 01 00 2B 05 34 00 02 0A 34 00 T 9D 0B 00 00 R 00 00 01 00 T 9D 0B 00 00 4F C5 E5 11 00 00 00 00 3E R 00 00 01 00 02 08 30 00 T A4 0B 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 19 00 02 09 19 00 +R 00 00 01 00 2B 04 18 00 02 09 18 00 T A9 0B 00 00 00 00 00 00 E1 E1 21 01 00 C3 R 00 00 01 00 02 04 26 00 T B1 0B 00 00 ED 0C 00 00 @@ -1479,9 +1479,9 @@ R 00 00 01 00 02 07 30 00 T C7 0C 00 00 00 00 00 00 C5 21 00 00 00 00 E5 R 00 00 01 00 2B 04 3B 00 02 0A 3B 00 T CD 0C 00 00 11 00 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 02 05 30 00 2B 0A 19 00 +R 00 00 01 00 02 05 30 00 2B 0A 18 00 T D3 0C 00 00 00 00 00 00 CD 00 00 00 00 E1 E1 -R 00 00 01 00 02 04 19 00 02 09 26 00 +R 00 00 01 00 02 04 18 00 02 09 26 00 T DA 0C 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 22 00 02 0A 22 00 T E0 0C 00 00 00 00 00 00 11 01 00 3E @@ -1594,13 +1594,13 @@ T C2 0D 00 00 5E 02 DD 56 03 3E 00 00 00 00 21 R 00 00 01 00 2B 0A 04 00 T CA 0D 00 00 00 00 00 00 CD 00 00 00 00 EB 3E R 00 00 01 00 02 04 04 00 02 09 26 00 -T D1 0D 00 00 CA 14 00 00 21 CA 14 00 00 C1 CD +T D1 0D 00 00 D6 14 00 00 21 D6 14 00 00 C1 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T D7 0D 00 00 00 00 00 00 22 00 00 00 00 R 00 00 01 00 02 04 26 00 00 09 03 00 T DC 0D 00 00 R 00 00 01 00 -T DC 0D 00 00 ED 5B 00 00 00 00 CD 0D 14 00 00 +T DC 0D 00 00 ED 5B 00 00 00 00 CD 19 14 00 00 R 00 00 01 00 00 06 03 00 00 0B 01 00 T E3 0D 00 00 7D B4 CA 1C 0F 00 00 R 00 00 01 00 00 07 01 00 @@ -1608,9 +1608,9 @@ T E8 0D 00 00 R 00 00 01 00 T E8 0D 00 00 2A 00 00 00 00 23 23 46 23 66 68 R 00 00 01 00 00 05 03 00 -T F1 0D 00 00 29 EB 3E 8D 14 00 00 21 +T F1 0D 00 00 29 EB 3E 99 14 00 00 21 R 00 00 01 00 29 07 01 00 -T F6 0D 00 00 8D 14 00 00 CD 00 00 00 00 22 +T F6 0D 00 00 99 14 00 00 CD 00 00 00 00 22 R 00 00 01 00 00 04 01 00 02 09 26 00 T FC 0D 00 00 02 00 00 00 AF DD 77 FC DD 77 FD R 00 00 01 00 00 04 03 00 @@ -1680,7 +1680,7 @@ T A5 0E 00 00 5E 23 56 3E 00 00 00 00 21 R 00 00 01 00 2B 08 04 00 T AB 0E 00 00 00 00 00 00 CD 00 00 00 00 EB 3E R 00 00 01 00 02 04 04 00 02 09 26 00 -T B2 0E 00 00 CA 14 00 00 21 CA 14 00 00 C1 CD +T B2 0E 00 00 D6 14 00 00 21 D6 14 00 00 C1 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T B8 0E 00 00 00 00 00 00 22 02 00 00 00 R 00 00 01 00 02 04 26 00 00 09 03 00 @@ -1760,15 +1760,15 @@ T 59 0F 00 00 18 C8 R 00 00 01 00 T 5B 0F 00 00 R 00 00 01 00 -T 5B 0F 00 00 0E 76 14 00 00 C5 21 76 14 00 00 +T 5B 0F 00 00 0E 82 14 00 00 C5 21 82 14 00 00 R 00 00 01 00 29 05 01 00 00 0B 01 00 T 61 0F 00 00 E5 21 02 00 E5 2A 00 00 00 00 23 R 00 00 01 00 00 0A 03 00 T 6A 0F 00 00 23 4E 23 46 21 04 00 ED 5B R 00 00 01 00 -T 73 0F 00 00 00 00 00 00 19 EB 3E 26 16 00 00 +T 73 0F 00 00 00 00 00 00 19 EB 3E 32 16 00 00 R 00 00 01 00 00 04 03 00 29 0B 01 00 -T 79 0F 00 00 21 26 16 00 00 CD 00 00 00 00 E1 +T 79 0F 00 00 21 32 16 00 00 CD 00 00 00 00 E1 R 00 00 01 00 00 05 01 00 02 0A 26 00 T 80 0F 00 00 E1 E1 2A 00 00 00 00 23 23 7E 23 R 00 00 01 00 00 07 03 00 @@ -1792,9 +1792,9 @@ T A6 0F 00 00 DD 4E 04 DD 46 05 DD 6E FC DD 66 R 00 00 01 00 T B1 0F 00 00 FD 29 ED 5B 00 00 00 00 19 11 R 00 00 01 00 00 08 03 00 -T B9 0F 00 00 04 00 19 5E 23 56 3E CA 14 00 00 +T B9 0F 00 00 04 00 19 5E 23 56 3E D6 14 00 00 R 00 00 01 00 29 0B 01 00 -T C1 0F 00 00 21 CA 14 00 00 CD 00 00 00 00 DD +T C1 0F 00 00 21 D6 14 00 00 CD 00 00 00 00 DD R 00 00 01 00 00 05 01 00 02 0A 26 00 T C8 0F 00 00 75 04 DD 74 05 DD 34 FC 20 03 DD R 00 00 01 00 @@ -1820,9 +1820,9 @@ T EB 0F 00 00 DD 4E 04 DD 46 05 DD 5E 02 DD 56 R 00 00 01 00 T F6 0F 00 00 03 3E F0 0C 00 00 21 F0 0C 00 00 R 00 00 01 00 29 06 01 00 00 0B 01 00 -T FC 0F 00 00 CD 00 00 00 00 EB 3E CA 14 00 00 +T FC 0F 00 00 CD 00 00 00 00 EB 3E D6 14 00 00 R 00 00 01 00 02 05 26 00 29 0B 01 00 -T 02 10 00 00 21 CA 14 00 00 CD 00 00 00 00 DD +T 02 10 00 00 21 D6 14 00 00 CD 00 00 00 00 DD R 00 00 01 00 00 05 01 00 02 0A 26 00 T 09 10 00 00 75 04 DD 74 05 R 00 00 01 00 @@ -1832,7 +1832,7 @@ T 0E 10 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 T 11 10 00 00 R 00 00 01 00 -T 11 10 00 00 CD 00 00 00 00 CC FE 21 00 00 39 +T 11 10 00 00 CD 00 00 00 00 AE FE 21 00 00 39 R 00 00 01 00 02 05 2D 00 T 1A 10 00 00 DD 5E 02 DD 56 03 73 23 72 R 00 00 01 00 @@ -1897,7 +1897,7 @@ R 00 00 01 00 T D5 10 00 00 04 00 39 E5 DD 5E 04 DD 56 05 3E R 00 00 01 00 T E0 10 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 18 00 02 09 18 00 +R 00 00 01 00 2B 04 17 00 02 09 17 00 T E5 10 00 00 00 00 00 00 EB 13 3E 00 00 00 00 R 00 00 01 00 02 04 26 00 2B 0B 09 00 T EB 10 00 00 21 00 00 00 00 CD 00 00 00 00 4D @@ -1928,779 +1928,781 @@ T 32 11 00 00 R 00 00 01 00 T 32 11 00 00 21 02 00 39 7E 23 66 6F 36 00 21 R 00 00 01 00 -T 3D 11 00 00 12 00 39 E5 21 0A 00 39 5E 23 56 +T 3D 11 00 00 12 00 39 E5 21 3E 01 39 E5 21 R 00 00 01 00 -T 48 11 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 32 00 02 0A 32 00 -T 4E 11 00 00 00 00 00 00 4D 44 E1 71 23 70 21 -R 00 00 01 00 02 04 26 00 -T 57 11 00 00 12 00 39 7E 23 B6 20 21 +T 47 11 00 00 38 01 39 4D 44 21 0C 00 39 5E 23 +R 00 00 01 00 +T 52 11 00 00 56 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 36 00 02 0B 36 00 +T 58 11 00 00 CD 00 00 00 00 F1 4D 44 E1 71 23 +R 00 00 01 00 02 05 26 00 +T 61 11 00 00 70 21 12 00 39 7E 23 B6 20 21 R 00 00 01 00 -T 5F 11 00 00 +T 6B 11 00 00 R 00 00 01 00 -T 5F 11 00 00 21 08 00 39 5E 23 56 3E +T 6B 11 00 00 21 08 00 39 5E 23 56 3E R 00 00 01 00 -T 67 11 00 00 00 00 00 00 21 00 00 00 00 CD +T 73 11 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 01 00 02 09 01 00 -T 6C 11 00 00 00 00 00 00 21 06 00 39 5E 23 56 +T 78 11 00 00 00 00 00 00 21 06 00 39 5E 23 56 R 00 00 01 00 02 04 26 00 -T 75 11 00 00 3E 00 00 00 00 21 00 00 00 00 CD +T 81 11 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 01 00 02 0A 01 00 -T 7B 11 00 00 00 00 00 00 C3 0B 13 00 00 +T 87 11 00 00 00 00 00 00 C3 17 13 00 00 R 00 00 01 00 02 04 26 00 00 09 01 00 -T 80 11 00 00 +T 8C 11 00 00 R 00 00 01 00 -T 80 11 00 00 DD 36 E1 00 +T 8C 11 00 00 DD 36 C3 00 R 00 00 01 00 -T 84 11 00 00 +T 90 11 00 00 R 00 00 01 00 -T 84 11 00 00 21 14 00 39 E5 21 14 00 39 5E 23 +T 90 11 00 00 21 14 00 39 E5 21 14 00 39 5E 23 R 00 00 01 00 -T 8F 11 00 00 56 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 1E 00 02 0B 1E 00 -T 95 11 00 00 CD 00 00 00 00 4D 44 E1 71 23 70 +T 9B 11 00 00 56 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 1F 00 02 0B 1F 00 +T A1 11 00 00 CD 00 00 00 00 4D 44 E1 71 23 70 R 00 00 01 00 02 05 26 00 -T 9E 11 00 00 79 B0 CA DE 12 00 00 +T AA 11 00 00 79 B0 CA EA 12 00 00 R 00 00 01 00 00 07 01 00 -T A3 11 00 00 +T AF 11 00 00 R 00 00 01 00 -T A3 11 00 00 21 FF 00 E5 21 06 00 E5 21 18 00 +T AF 11 00 00 21 FF 00 E5 21 06 00 E5 21 18 00 R 00 00 01 00 -T AE 11 00 00 39 4E 23 46 E1 09 4D 44 21 18 00 +T BA 11 00 00 39 4E 23 46 E1 09 4D 44 21 18 00 R 00 00 01 00 -T B9 11 00 00 39 5D 54 3E 00 00 00 00 21 +T C5 11 00 00 39 5D 54 3E 00 00 00 00 21 R 00 00 01 00 2B 08 0F 00 -T BF 11 00 00 00 00 00 00 CD 00 00 00 00 F1 21 +T CB 11 00 00 00 00 00 00 CD 00 00 00 00 F1 21 R 00 00 01 00 02 04 0F 00 02 09 26 00 -T C6 11 00 00 16 00 39 7E FE 2E 20 0F +T D2 11 00 00 16 00 39 7E FE 2E 20 0F R 00 00 01 00 -T CE 11 00 00 +T DA 11 00 00 R 00 00 01 00 -T CE 11 00 00 21 06 00 39 7E 23 66 6F 7E FE 2E +T DA 11 00 00 21 06 00 39 7E 23 66 6F 7E FE 2E R 00 00 01 00 -T D9 11 00 00 28 02 +T E5 11 00 00 28 02 R 00 00 01 00 -T DB 11 00 00 +T E7 11 00 00 R 00 00 01 00 -T DB 11 00 00 18 A7 +T E7 11 00 00 18 A7 R 00 00 01 00 -T DD 11 00 00 +T E9 11 00 00 R 00 00 01 00 -T DD 11 00 00 +T E9 11 00 00 R 00 00 01 00 -T DD 11 00 00 21 10 00 39 AF 77 23 77 +T E9 11 00 00 21 10 00 39 AF 77 23 77 R 00 00 01 00 -T E5 11 00 00 +T F1 11 00 00 R 00 00 01 00 -T E5 11 00 00 01 FF 80 21 10 00 39 56 23 66 6A +T F1 11 00 00 01 FF 80 21 10 00 39 56 23 66 6A R 00 00 01 00 -T F0 11 00 00 3E 80 AC 67 ED 42 30 3D +T FC 11 00 00 3E 80 AC 67 ED 42 30 3D R 00 00 01 00 -T F8 11 00 00 +T 04 12 00 00 R 00 00 01 00 -T F8 11 00 00 01 00 00 00 00 21 16 00 39 E5 21 +T 04 12 00 00 01 00 00 00 00 21 16 00 39 E5 21 R 00 00 01 00 00 05 04 00 -T 01 12 00 00 12 00 39 5E 23 56 E1 19 5E 16 00 +T 0D 12 00 00 12 00 39 5E 23 56 E1 19 5E 16 00 R 00 00 01 00 -T 0C 12 00 00 3E 00 00 00 00 21 00 00 00 00 CD +T 18 12 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 05 00 02 0A 05 00 -T 12 12 00 00 00 00 00 00 7D B4 28 12 +T 1E 12 00 00 00 00 00 00 7D B4 28 12 R 00 00 01 00 02 04 26 00 -T 18 12 00 00 +T 24 12 00 00 R 00 00 01 00 -T 18 12 00 00 21 16 00 39 E5 21 12 00 39 4E 23 +T 24 12 00 00 21 16 00 39 E5 21 12 00 39 4E 23 R 00 00 01 00 -T 23 12 00 00 46 E1 09 7E F6 80 77 +T 2F 12 00 00 46 E1 09 7E F6 80 77 R 00 00 01 00 -T 2A 12 00 00 +T 36 12 00 00 R 00 00 01 00 -T 2A 12 00 00 21 10 00 39 34 23 20 01 34 +T 36 12 00 00 21 10 00 39 34 23 20 01 34 R 00 00 01 00 -T 33 12 00 00 +T 3F 12 00 00 R 00 00 01 00 -T 33 12 00 00 18 B0 +T 3F 12 00 00 18 B0 R 00 00 01 00 -T 35 12 00 00 +T 41 12 00 00 R 00 00 01 00 -T 35 12 00 00 21 06 00 39 4E 23 46 21 16 00 39 +T 41 12 00 00 21 06 00 39 4E 23 46 21 16 00 39 R 00 00 01 00 -T 40 12 00 00 5D 54 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 36 00 -T 45 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 -R 00 00 01 00 02 04 36 00 02 09 26 00 -T 4C 12 00 00 CA DB 12 00 00 +T 4C 12 00 00 5D 54 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 35 00 +T 51 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 02 04 35 00 02 09 26 00 +T 58 12 00 00 CA E7 12 00 00 R 00 00 01 00 00 05 01 00 -T 4F 12 00 00 +T 5B 12 00 00 R 00 00 01 00 -T 4F 12 00 00 21 04 00 39 E5 21 02 00 39 4E 23 +T 5B 12 00 00 21 04 00 39 E5 21 02 00 39 4E 23 R 00 00 01 00 -T 5A 12 00 00 46 C5 21 1A 00 39 E5 DD 4E 04 DD +T 66 12 00 00 46 C5 21 1A 00 39 E5 DD 4E 04 DD R 00 00 01 00 -T 65 12 00 00 46 05 DD 5E 02 DD 56 03 CD +T 71 12 00 00 46 05 DD 5E 02 DD 56 03 CD R 00 00 01 00 -T 6E 12 00 00 0E 13 00 00 F1 F1 4D 44 E1 71 23 +T 7A 12 00 00 1A 13 00 00 F1 F1 4D 44 E1 71 23 R 00 00 01 00 00 04 01 00 -T 77 12 00 00 70 21 00 00 39 7E 23 66 6F AF B6 +T 83 12 00 00 70 21 00 00 39 7E 23 66 6F AF B6 R 00 00 01 00 -T 82 12 00 00 28 41 01 00 00 00 00 21 00 00 39 +T 8E 12 00 00 28 41 01 00 00 00 00 21 00 00 39 R 00 00 01 00 00 07 04 00 -T 8B 12 00 00 5E 23 56 3E 00 00 00 00 21 +T 97 12 00 00 5E 23 56 3E 00 00 00 00 21 R 00 00 01 00 2B 08 40 00 -T 91 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +T 9D 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 R 00 00 01 00 02 04 40 00 02 09 26 00 -T 98 12 00 00 20 2B +T A4 12 00 00 20 2B R 00 00 01 00 -T 9A 12 00 00 +T A6 12 00 00 R 00 00 01 00 -T 9A 12 00 00 +T A6 12 00 00 R 00 00 01 00 -T 9A 12 00 00 +T A6 12 00 00 R 00 00 01 00 -T 9A 12 00 00 21 16 01 39 4D 44 21 04 00 39 5E +T A6 12 00 00 21 16 01 39 4D 44 21 04 00 39 5E R 00 00 01 00 -T A5 12 00 00 23 56 3E 00 00 00 00 21 +T B1 12 00 00 23 56 3E 00 00 00 00 21 R 00 00 01 00 2B 07 41 00 -T AA 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +T B6 12 00 00 00 00 00 00 CD 00 00 00 00 7D B4 R 00 00 01 00 02 04 41 00 02 09 26 00 -T B1 12 00 00 28 12 +T BD 12 00 00 28 12 R 00 00 01 00 -T B3 12 00 00 +T BF 12 00 00 R 00 00 01 00 -T B3 12 00 00 21 04 00 39 5E 23 56 3E +T BF 12 00 00 21 04 00 39 5E 23 56 3E R 00 00 01 00 -T BB 12 00 00 00 00 00 00 21 00 00 00 00 CD +T C7 12 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 01 00 02 09 01 00 -T C0 12 00 00 00 00 00 00 C3 84 11 00 00 +T CC 12 00 00 00 00 00 00 C3 90 11 00 00 R 00 00 01 00 02 04 26 00 00 09 01 00 -T C5 12 00 00 +T D1 12 00 00 R 00 00 01 00 -T C5 12 00 00 +T D1 12 00 00 R 00 00 01 00 -T C5 12 00 00 ED 4B 02 00 00 00 21 04 00 39 5E +T D1 12 00 00 ED 4B 02 00 00 00 21 04 00 39 5E R 00 00 01 00 00 06 03 00 -T CE 12 00 00 23 56 3E CA 14 00 00 21 +T DA 12 00 00 23 56 3E D6 14 00 00 21 R 00 00 01 00 29 07 01 00 -T D3 12 00 00 CA 14 00 00 CD 00 00 00 00 22 +T DF 12 00 00 D6 14 00 00 CD 00 00 00 00 22 R 00 00 01 00 00 04 01 00 02 09 26 00 -T D9 12 00 00 02 00 00 00 +T E5 12 00 00 02 00 00 00 R 00 00 01 00 00 04 03 00 -T DB 12 00 00 +T E7 12 00 00 R 00 00 01 00 -T DB 12 00 00 C3 84 11 00 00 +T E7 12 00 00 C3 90 11 00 00 R 00 00 01 00 00 05 01 00 -T DE 12 00 00 +T EA 12 00 00 R 00 00 01 00 -T DE 12 00 00 21 12 00 39 5E 23 56 3E +T EA 12 00 00 21 12 00 39 5E 23 56 3E R 00 00 01 00 -T E6 12 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 16 00 02 09 16 00 -T EB 12 00 00 00 00 00 00 21 08 00 39 5E 23 56 +T F2 12 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 1A 00 02 09 1A 00 +T F7 12 00 00 00 00 00 00 21 08 00 39 5E 23 56 R 00 00 01 00 02 04 26 00 -T F4 12 00 00 3E 00 00 00 00 21 00 00 00 00 CD +T 00 13 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 01 00 02 0A 01 00 -T FA 12 00 00 00 00 00 00 21 06 00 39 5E 23 56 +T 06 13 00 00 00 00 00 00 21 06 00 39 5E 23 56 R 00 00 01 00 02 04 26 00 -T 03 13 00 00 3E 00 00 00 00 21 00 00 00 00 CD +T 0F 13 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 05 01 00 02 0A 01 00 -T 09 13 00 00 00 00 00 00 +T 15 13 00 00 00 00 00 00 R 00 00 01 00 02 04 26 00 -T 0B 13 00 00 +T 17 13 00 00 R 00 00 01 00 -T 0B 13 00 00 C3 00 00 00 00 +T 17 13 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 -T 0E 13 00 00 +T 1A 13 00 00 R 00 00 01 00 -T 0E 13 00 00 CD 00 00 00 00 FA FF DD 5E 0A DD +T 1A 13 00 00 CD 00 00 00 00 FA FF DD 5E 0A DD R 00 00 01 00 02 05 2D 00 -T 17 13 00 00 56 0B 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 18 00 -T 1C 13 00 00 00 00 00 00 CD 00 00 00 00 E5 DD -R 00 00 01 00 02 04 18 00 02 09 26 00 -T 23 13 00 00 5E 08 DD 56 09 3E 00 00 00 00 21 -R 00 00 01 00 2B 0A 18 00 -T 2B 13 00 00 00 00 00 00 CD 00 00 00 00 EB E1 -R 00 00 01 00 02 04 18 00 02 09 26 00 -T 32 13 00 00 19 E5 DD 5E 02 DD 56 03 69 60 A7 -R 00 00 01 00 -T 3D 13 00 00 ED 52 4D 44 E1 09 EB 13 13 3E -R 00 00 01 00 -T 47 13 00 00 00 00 00 00 21 00 00 00 00 CD +T 23 13 00 00 56 0B 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 17 00 +T 28 13 00 00 00 00 00 00 CD 00 00 00 00 E5 DD +R 00 00 01 00 02 04 17 00 02 09 26 00 +T 2F 13 00 00 5E 08 DD 56 09 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 17 00 +T 37 13 00 00 00 00 00 00 CD 00 00 00 00 EB E1 +R 00 00 01 00 02 04 17 00 02 09 26 00 +T 3E 13 00 00 19 E5 DD 5E 02 DD 56 03 69 60 A7 +R 00 00 01 00 +T 49 13 00 00 ED 52 4D 44 E1 09 EB 13 13 3E +R 00 00 01 00 +T 53 13 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 09 00 02 09 09 00 -T 4C 13 00 00 00 00 00 00 DD 75 FC DD 74 FD DD +T 58 13 00 00 00 00 00 00 DD 75 FC DD 74 FD DD R 00 00 01 00 02 04 26 00 -T 55 13 00 00 75 FA DD 74 FB DD 6E 02 DD 66 03 +T 61 13 00 00 75 FA DD 74 FB DD 6E 02 DD 66 03 R 00 00 01 00 -T 60 13 00 00 DD 75 FE DD 74 FF +T 6C 13 00 00 DD 75 FE DD 74 FF R 00 00 01 00 -T 66 13 00 00 +T 72 13 00 00 R 00 00 01 00 -T 66 13 00 00 DD 6E 04 DD 66 05 DD 4E FE DD 46 +T 72 13 00 00 DD 6E 04 DD 66 05 DD 4E FE DD 46 R 00 00 01 00 -T 71 13 00 00 FF A7 ED 42 28 20 +T 7D 13 00 00 FF A7 ED 42 28 20 R 00 00 01 00 -T 77 13 00 00 +T 83 13 00 00 R 00 00 01 00 -T 77 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T 83 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T 82 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 +T 8E 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 R 00 00 01 00 -T 8D 13 00 00 DD 75 FC DD 74 FD 2B 70 18 CF +T 99 13 00 00 DD 75 FC DD 74 FD 2B 70 18 CF R 00 00 01 00 -T 97 13 00 00 +T A3 13 00 00 R 00 00 01 00 -T 97 13 00 00 DD 6E 08 DD 66 09 DD 75 FE DD 74 +T A3 13 00 00 DD 6E 08 DD 66 09 DD 75 FE DD 74 R 00 00 01 00 -T A2 13 00 00 FF +T AE 13 00 00 FF R 00 00 01 00 -T A3 13 00 00 +T AF 13 00 00 R 00 00 01 00 -T A3 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T AF 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T AE 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 +T BA 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 R 00 00 01 00 -T B9 13 00 00 DD 75 FC DD 74 FD 2B 70 04 05 28 +T C5 13 00 00 DD 75 FC DD 74 FD 2B 70 04 05 28 R 00 00 01 00 -T C4 13 00 00 02 +T D0 13 00 00 02 R 00 00 01 00 -T C5 13 00 00 +T D1 13 00 00 R 00 00 01 00 -T C5 13 00 00 18 DC +T D1 13 00 00 18 DC R 00 00 01 00 -T C7 13 00 00 +T D3 13 00 00 R 00 00 01 00 -T C7 13 00 00 DD 6E FC DD 66 FD 2B DD 75 FC DD +T D3 13 00 00 DD 6E FC DD 66 FD 2B DD 75 FC DD R 00 00 01 00 -T D2 13 00 00 74 FD DD 6E 0A DD 66 0B DD 75 FE +T DE 13 00 00 74 FD DD 6E 0A DD 66 0B DD 75 FE R 00 00 01 00 -T DD 13 00 00 DD 74 FF +T E9 13 00 00 DD 74 FF R 00 00 01 00 -T E0 13 00 00 +T EC 13 00 00 R 00 00 01 00 -T E0 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T EC 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T EB 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 +T F7 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 23 R 00 00 01 00 -T F6 13 00 00 DD 75 FC DD 74 FD 2B 70 04 05 28 +T 02 14 00 00 DD 75 FC DD 74 FD 2B 70 04 05 28 R 00 00 01 00 -T 01 14 00 00 02 +T 0D 14 00 00 02 R 00 00 01 00 -T 02 14 00 00 +T 0E 14 00 00 R 00 00 01 00 -T 02 14 00 00 18 DC +T 0E 14 00 00 18 DC R 00 00 01 00 -T 04 14 00 00 +T 10 14 00 00 R 00 00 01 00 -T 04 14 00 00 DD 6E FA DD 66 FB C3 00 00 00 00 +T 10 14 00 00 DD 6E FA DD 66 FB C3 00 00 00 00 R 00 00 01 00 02 0B 1B 00 -T 0D 14 00 00 +T 19 14 00 00 R 00 00 01 00 -T 0D 14 00 00 CD 00 00 00 00 FC FF 21 04 00 DD +T 19 14 00 00 CD 00 00 00 00 FC FF 21 04 00 DD R 00 00 01 00 02 05 2D 00 -T 16 14 00 00 4E 02 DD 46 03 09 DD 75 FE DD 74 +T 22 14 00 00 4E 02 DD 46 03 09 DD 75 FE DD 74 R 00 00 01 00 -T 21 14 00 00 FF AF DD 77 FC DD 77 FD +T 2D 14 00 00 FF AF DD 77 FC DD 77 FD R 00 00 01 00 -T 29 14 00 00 +T 35 14 00 00 R 00 00 01 00 -T 29 14 00 00 DD 6E 02 DD 66 03 23 23 4E 23 46 +T 35 14 00 00 DD 6E 02 DD 66 03 23 23 4E 23 46 R 00 00 01 00 -T 34 14 00 00 DD 6E FC DD 66 FD CD 00 00 00 00 +T 40 14 00 00 DD 6E FC DD 66 FD CD 00 00 00 00 R 00 00 01 00 02 0B 31 00 -T 3D 14 00 00 30 31 +T 49 14 00 00 30 31 R 00 00 01 00 -T 3F 14 00 00 +T 4B 14 00 00 R 00 00 01 00 -T 3F 14 00 00 DD 6E FE DD 66 FF 4D 44 03 03 DD +T 4B 14 00 00 DD 6E FE DD 66 FF 4D 44 03 03 DD R 00 00 01 00 -T 4A 14 00 00 71 FE DD 70 FF 4E 23 46 11 +T 56 14 00 00 71 FE DD 70 FF 4E 23 46 11 R 00 00 01 00 -T 53 14 00 00 00 00 00 00 3E 00 00 00 00 21 +T 5F 14 00 00 00 00 00 00 3E 00 00 00 00 21 R 00 00 01 00 00 04 04 00 2B 09 40 00 -T 58 14 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +T 64 14 00 00 00 00 00 00 CD 00 00 00 00 7D B4 R 00 00 01 00 02 04 40 00 02 09 26 00 -T 5F 14 00 00 28 05 +T 6B 14 00 00 28 05 R 00 00 01 00 -T 61 14 00 00 +T 6D 14 00 00 R 00 00 01 00 -T 61 14 00 00 21 01 00 18 0D +T 6D 14 00 00 21 01 00 18 0D R 00 00 01 00 -T 66 14 00 00 +T 72 14 00 00 R 00 00 01 00 -T 66 14 00 00 DD 34 FC 20 03 DD 34 FD +T 72 14 00 00 DD 34 FC 20 03 DD 34 FD R 00 00 01 00 -T 6E 14 00 00 +T 7A 14 00 00 R 00 00 01 00 -T 6E 14 00 00 18 B9 +T 7A 14 00 00 18 B9 R 00 00 01 00 -T 70 14 00 00 +T 7C 14 00 00 R 00 00 01 00 -T 70 14 00 00 21 00 00 +T 7C 14 00 00 21 00 00 R 00 00 01 00 -T 73 14 00 00 +T 7F 14 00 00 R 00 00 01 00 -T 73 14 00 00 C3 00 00 00 00 +T 7F 14 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 1B 00 -T 76 14 00 00 +T 82 14 00 00 R 00 00 01 00 -T 76 14 00 00 CD 00 00 00 00 69 60 4E 23 46 EB +T 82 14 00 00 CD 00 00 00 00 69 60 4E 23 46 EB R 00 00 01 00 02 05 25 00 -T 7F 14 00 00 5E 23 56 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 1A 00 -T 85 14 00 00 00 00 00 00 CD 00 00 00 00 C3 -R 00 00 01 00 02 04 1A 00 02 09 26 00 -T 8B 14 00 00 00 00 00 00 +T 8B 14 00 00 5E 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 19 00 +T 91 14 00 00 00 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 02 04 19 00 02 09 26 00 +T 97 14 00 00 00 00 00 00 R 00 00 01 00 02 04 12 00 -T 8D 14 00 00 +T 99 14 00 00 R 00 00 01 00 -T 8D 14 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD +T 99 14 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD R 00 00 01 00 02 05 2D 00 -T 96 14 00 00 66 03 29 01 06 00 09 EB 3E +T A2 14 00 00 66 03 29 01 06 00 09 EB 3E R 00 00 01 00 -T 9F 14 00 00 00 00 00 00 21 00 00 00 00 CD +T AB 14 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 09 00 02 09 09 00 -T A4 14 00 00 00 00 00 00 DD 75 FE DD 74 FF DD +T B0 14 00 00 00 00 00 00 DD 75 FE DD 74 FF DD R 00 00 01 00 02 04 26 00 -T AD 14 00 00 4E 02 DD 46 03 71 23 70 DD 6E FE +T B9 14 00 00 4E 02 DD 46 03 71 23 70 DD 6E FE R 00 00 01 00 -T B8 14 00 00 DD 66 FF 23 23 AF 77 23 77 DD 6E +T C4 14 00 00 DD 66 FF 23 23 AF 77 23 77 DD 6E R 00 00 01 00 -T C3 14 00 00 FE DD 66 FF C3 00 00 00 00 +T CF 14 00 00 FE DD 66 FF C3 00 00 00 00 R 00 00 01 00 02 09 12 00 -T CA 14 00 00 +T D6 14 00 00 R 00 00 01 00 -T CA 14 00 00 CD 00 00 00 00 FC FF 79 B0 20 11 +T D6 14 00 00 CD 00 00 00 00 FC FF 79 B0 20 11 R 00 00 01 00 02 05 2D 00 -T D3 14 00 00 +T DF 14 00 00 R 00 00 01 00 -T D3 14 00 00 11 10 00 3E 8D 14 00 00 21 +T DF 14 00 00 11 10 00 3E 99 14 00 00 21 R 00 00 01 00 29 08 01 00 -T D9 14 00 00 8D 14 00 00 CD 00 00 00 00 DD 75 +T E5 14 00 00 99 14 00 00 CD 00 00 00 00 DD 75 R 00 00 01 00 00 04 01 00 02 09 26 00 -T E0 14 00 00 04 DD 74 05 +T EC 14 00 00 04 DD 74 05 R 00 00 01 00 -T E4 14 00 00 +T F0 14 00 00 R 00 00 01 00 -T E4 14 00 00 DD 6E 04 DD 66 05 4E 23 46 DD 6E +T F0 14 00 00 DD 6E 04 DD 66 05 4E 23 46 DD 6E R 00 00 01 00 -T EF 14 00 00 04 DD 66 05 23 23 56 23 66 6A DD +T FB 14 00 00 04 DD 66 05 23 23 56 23 66 6A DD R 00 00 01 00 -T FA 14 00 00 75 FE DD 74 FF CD 00 00 00 00 38 +T 06 15 00 00 75 FE DD 74 FF CD 00 00 00 00 38 R 00 00 01 00 02 0A 31 00 -T 03 15 00 00 69 +T 0F 15 00 00 69 R 00 00 01 00 -T 04 15 00 00 +T 10 15 00 00 R 00 00 01 00 -T 04 15 00 00 DD 6E FE DD 66 FF 29 EB 3E +T 10 15 00 00 DD 6E FE DD 66 FF 29 EB 3E R 00 00 01 00 -T 0D 15 00 00 8D 14 00 00 21 8D 14 00 00 CD +T 19 15 00 00 99 14 00 00 21 99 14 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T 12 15 00 00 00 00 00 00 DD 75 FC DD 74 FD DD +T 1E 15 00 00 00 00 00 00 DD 75 FC DD 74 FD DD R 00 00 01 00 02 04 26 00 -T 1B 15 00 00 6E FE DD 66 FF 29 E5 21 04 00 DD +T 27 15 00 00 6E FE DD 66 FF 29 E5 21 04 00 DD R 00 00 01 00 -T 26 15 00 00 4E 04 DD 46 05 09 4D 44 21 04 00 +T 32 15 00 00 4E 04 DD 46 05 09 4D 44 21 04 00 R 00 00 01 00 -T 31 15 00 00 DD 5E FC DD 56 FD 19 EB 3E +T 3D 15 00 00 DD 5E FC DD 56 FD 19 EB 3E R 00 00 01 00 -T 3A 15 00 00 10 1A 00 00 21 10 1A 00 00 CD +T 46 15 00 00 1C 1A 00 00 21 1C 1A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T 3F 15 00 00 00 00 00 00 F1 DD 6E FC DD 66 FD +T 4B 15 00 00 00 00 00 00 F1 DD 6E FC DD 66 FD R 00 00 01 00 02 04 26 00 -T 48 15 00 00 23 23 DD 4E FE DD 46 FF 71 23 70 +T 54 15 00 00 23 23 DD 4E FE DD 46 FF 71 23 70 R 00 00 01 00 -T 53 15 00 00 DD 5E 04 DD 56 05 3E 00 00 00 00 +T 5F 15 00 00 DD 5E 04 DD 56 05 3E 00 00 00 00 R 00 00 01 00 2B 0B 01 00 -T 5B 15 00 00 21 00 00 00 00 CD 00 00 00 00 DD +T 67 15 00 00 21 00 00 00 00 CD 00 00 00 00 DD R 00 00 01 00 02 05 01 00 02 0A 26 00 -T 62 15 00 00 6E FC DD 66 FD DD 75 04 DD 74 05 +T 6E 15 00 00 6E FC DD 66 FD DD 75 04 DD 74 05 R 00 00 01 00 -T 6D 15 00 00 +T 79 15 00 00 R 00 00 01 00 -T 6D 15 00 00 DD 6E 04 DD 66 05 23 23 4E 23 46 +T 79 15 00 00 DD 6E 04 DD 66 05 23 23 4E 23 46 R 00 00 01 00 -T 78 15 00 00 03 70 2B 71 0B 69 60 29 DD 4E 04 +T 84 15 00 00 03 70 2B 71 0B 69 60 29 DD 4E 04 R 00 00 01 00 -T 83 15 00 00 DD 46 05 09 11 04 00 19 DD 5E 02 +T 8F 15 00 00 DD 46 05 09 11 04 00 19 DD 5E 02 R 00 00 01 00 -T 8E 15 00 00 DD 56 03 73 23 72 69 60 C3 +T 9A 15 00 00 DD 56 03 73 23 72 69 60 C3 R 00 00 01 00 -T 97 15 00 00 00 00 00 00 +T A3 15 00 00 00 00 00 00 R 00 00 01 00 02 04 12 00 -T 99 15 00 00 +T A5 15 00 00 R 00 00 01 00 -T 99 15 00 00 CD 00 00 00 00 FC FF DD 7E 02 DD +T A5 15 00 00 CD 00 00 00 00 FC FF DD 7E 02 DD R 00 00 01 00 02 05 2D 00 -T A2 15 00 00 B6 03 20 05 +T AE 15 00 00 B6 03 20 05 R 00 00 01 00 -T A6 15 00 00 +T B2 15 00 00 R 00 00 01 00 -T A6 15 00 00 21 00 00 18 78 +T B2 15 00 00 21 00 00 18 78 R 00 00 01 00 -T AB 15 00 00 +T B7 15 00 00 R 00 00 01 00 -T AB 15 00 00 DD 6E 02 DD 66 03 23 23 7E 23 B6 +T B7 15 00 00 DD 6E 02 DD 66 03 23 23 7E 23 B6 R 00 00 01 00 -T B6 15 00 00 20 13 +T C2 15 00 00 20 13 R 00 00 01 00 -T B8 15 00 00 +T C4 15 00 00 R 00 00 01 00 -T B8 15 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 +T C4 15 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 R 00 00 01 00 2B 0B 01 00 -T C0 15 00 00 21 00 00 00 00 CD 00 00 00 00 21 +T CC 15 00 00 21 00 00 00 00 CD 00 00 00 00 21 R 00 00 01 00 02 05 01 00 02 0A 26 00 -T C7 15 00 00 00 00 18 58 +T D3 15 00 00 00 00 18 58 R 00 00 01 00 -T CB 15 00 00 +T D7 15 00 00 R 00 00 01 00 -T CB 15 00 00 DD 6E 02 DD 66 03 23 23 46 23 66 +T D7 15 00 00 DD 6E 02 DD 66 03 23 23 46 23 66 R 00 00 01 00 -T D6 15 00 00 68 29 DD 75 FE DD 74 FF EB 3E +T E2 15 00 00 68 29 DD 75 FE DD 74 FF EB 3E R 00 00 01 00 -T E0 15 00 00 00 00 00 00 21 00 00 00 00 CD +T EC 15 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 09 00 02 09 09 00 -T E5 15 00 00 00 00 00 00 DD 75 FC DD 74 FD DD +T F1 15 00 00 00 00 00 00 DD 75 FC DD 74 FD DD R 00 00 01 00 02 04 26 00 -T EE 15 00 00 4E FE DD 46 FF C5 21 04 00 DD 4E +T FA 15 00 00 4E FE DD 46 FF C5 21 04 00 DD 4E R 00 00 01 00 -T F9 15 00 00 02 DD 46 03 09 4D 44 DD 5E FC DD +T 05 16 00 00 02 DD 46 03 09 4D 44 DD 5E FC DD R 00 00 01 00 -T 04 16 00 00 56 FD 3E 10 1A 00 00 21 +T 10 16 00 00 56 FD 3E 1C 1A 00 00 21 R 00 00 01 00 29 07 01 00 -T 09 16 00 00 10 1A 00 00 CD 00 00 00 00 F1 DD +T 15 16 00 00 1C 1A 00 00 CD 00 00 00 00 F1 DD R 00 00 01 00 00 04 01 00 02 09 26 00 -T 10 16 00 00 5E 02 DD 56 03 3E 00 00 00 00 21 +T 1C 16 00 00 5E 02 DD 56 03 3E 00 00 00 00 21 R 00 00 01 00 2B 0A 01 00 -T 18 16 00 00 00 00 00 00 CD 00 00 00 00 DD 6E +T 24 16 00 00 00 00 00 00 CD 00 00 00 00 DD 6E R 00 00 01 00 02 04 01 00 02 09 26 00 -T 1F 16 00 00 FC DD 66 FD +T 2B 16 00 00 FC DD 66 FD R 00 00 01 00 -T 23 16 00 00 +T 2F 16 00 00 R 00 00 01 00 -T 23 16 00 00 C3 00 00 00 00 +T 2F 16 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 -T 26 16 00 00 +T 32 16 00 00 R 00 00 01 00 -T 26 16 00 00 CD 00 00 00 00 DD 7E 0E DD 6E 0C +T 32 16 00 00 CD 00 00 00 00 DD 7E 0E DD 6E 0C R 00 00 01 00 02 05 25 00 -T 2F 16 00 00 DD 66 0D 32 06 00 00 00 22 +T 3B 16 00 00 DD 66 0D 32 06 00 00 00 22 R 00 00 01 00 00 08 03 00 -T 36 16 00 00 04 00 00 00 DD 6E 0A DD 66 0B 22 +T 42 16 00 00 04 00 00 00 DD 6E 0A DD 66 0B 22 R 00 00 01 00 00 04 03 00 -T 3F 16 00 00 07 00 00 00 D5 DD 5E 0A DD 56 0B +T 4B 16 00 00 07 00 00 00 D5 DD 5E 0A DD 56 0B R 00 00 01 00 00 04 03 00 -T 48 16 00 00 CD 00 00 00 00 EB D1 19 4D 44 DD +T 54 16 00 00 CD 00 00 00 00 EB D1 19 4D 44 DD R 00 00 01 00 02 05 08 00 -T 51 16 00 00 5E 02 DD 56 03 3E 61 16 00 00 21 +T 5D 16 00 00 5E 02 DD 56 03 3E 6D 16 00 00 21 R 00 00 01 00 29 0A 01 00 -T 59 16 00 00 61 16 00 00 CD 00 00 00 00 C3 +T 65 16 00 00 6D 16 00 00 CD 00 00 00 00 C3 R 00 00 01 00 00 04 01 00 02 09 26 00 -T 5F 16 00 00 00 00 00 00 +T 6B 16 00 00 00 00 00 00 R 00 00 01 00 02 04 12 00 -T 61 16 00 00 +T 6D 16 00 00 R 00 00 01 00 -T 61 16 00 00 CD 00 00 00 00 F2 FF 2A +T 6D 16 00 00 CD 00 00 00 00 F2 FF 2A R 00 00 01 00 02 05 2D 00 -T 67 16 00 00 07 00 00 00 DD 75 F6 DD 74 F7 +T 73 16 00 00 07 00 00 00 DD 75 F6 DD 74 F7 R 00 00 01 00 00 04 03 00 -T 6F 16 00 00 +T 7B 16 00 00 R 00 00 01 00 -T 6F 16 00 00 DD 4E 02 DD 46 03 DD 6E 04 DD 66 +T 7B 16 00 00 DD 4E 02 DD 46 03 DD 6E 04 DD 66 R 00 00 01 00 -T 7A 16 00 00 05 A7 ED 42 DD 75 FE DD 74 FF 4D +T 86 16 00 00 05 A7 ED 42 DD 75 FE DD 74 FF 4D R 00 00 01 00 -T 85 16 00 00 44 DD 6E F6 DD 66 F7 A7 ED 42 38 +T 91 16 00 00 44 DD 6E F6 DD 66 F7 A7 ED 42 38 R 00 00 01 00 -T 90 16 00 00 03 +T 9C 16 00 00 03 R 00 00 01 00 -T 91 16 00 00 +T 9D 16 00 00 R 00 00 01 00 -T 91 16 00 00 C3 00 00 00 00 +T 9D 16 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 -T 94 16 00 00 +T A0 16 00 00 R 00 00 01 00 -T 94 16 00 00 DD 6E F6 DD 66 F7 29 4D 44 DD 5E +T A0 16 00 00 DD 6E F6 DD 66 F7 29 4D 44 DD 5E R 00 00 01 00 -T 9F 16 00 00 FE DD 56 FF CD 00 00 00 00 DD 4E +T AB 16 00 00 FE DD 56 FF CD 00 00 00 00 DD 4E R 00 00 01 00 02 09 38 00 -T A8 16 00 00 F6 DD 46 F7 CD 00 00 00 00 DD 73 +T B4 16 00 00 F6 DD 46 F7 CD 00 00 00 00 DD 73 R 00 00 01 00 02 09 08 00 -T B1 16 00 00 FE DD 72 FF DD 6E 02 DD 66 03 19 +T BD 16 00 00 FE DD 72 FF DD 6E 02 DD 66 03 19 R 00 00 01 00 -T BC 16 00 00 DD 75 F8 DD 74 F9 DD 75 FA DD 74 +T C8 16 00 00 DD 75 F8 DD 74 F9 DD 75 FA DD 74 R 00 00 01 00 -T C7 16 00 00 FB DD 6E 02 DD 66 03 DD 75 F2 DD +T D3 16 00 00 FB DD 6E 02 DD 66 03 DD 75 F2 DD R 00 00 01 00 -T D2 16 00 00 74 F3 DD 4E F6 DD 46 F7 DD 6E 04 +T DE 16 00 00 74 F3 DD 4E F6 DD 46 F7 DD 6E 04 R 00 00 01 00 -T DD 16 00 00 DD 66 05 A7 ED 42 DD 75 F4 DD 74 +T E9 16 00 00 DD 66 05 A7 ED 42 DD 75 F4 DD 74 R 00 00 01 00 -T E8 16 00 00 F5 +T F4 16 00 00 F5 R 00 00 01 00 -T E9 16 00 00 +T F5 16 00 00 R 00 00 01 00 -T E9 16 00 00 DD 4E F8 DD 46 F9 DD 6E F2 DD 66 +T F5 16 00 00 DD 4E F8 DD 46 F9 DD 6E F2 DD 66 R 00 00 01 00 -T F4 16 00 00 F3 A7 ED 42 30 5A +T 00 17 00 00 F3 A7 ED 42 30 5A R 00 00 01 00 -T FA 16 00 00 +T 06 17 00 00 R 00 00 01 00 -T FA 16 00 00 DD 4E F8 DD 46 F9 DD 5E F2 DD 56 +T 06 17 00 00 DD 4E F8 DD 46 F9 DD 5E F2 DD 56 R 00 00 01 00 -T 05 17 00 00 F3 3A 06 00 00 00 2A 04 00 00 00 +T 11 17 00 00 F3 3A 06 00 00 00 2A 04 00 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 0C 17 00 00 CD 00 00 00 00 DD 75 FC DD 74 FD +T 18 17 00 00 CD 00 00 00 00 DD 75 FC DD 74 FD R 00 00 01 00 02 05 26 00 -T 15 17 00 00 7D B4 20 24 +T 21 17 00 00 7D B4 20 24 R 00 00 01 00 -T 19 17 00 00 +T 25 17 00 00 R 00 00 01 00 -T 19 17 00 00 21 06 00 39 7E DD 96 F6 77 23 7E +T 25 17 00 00 21 06 00 39 7E DD 96 F6 77 23 7E R 00 00 01 00 -T 24 17 00 00 DD 9E F7 77 2B 6E 67 4D 44 DD 5E +T 30 17 00 00 DD 9E F7 77 2B 6E 67 4D 44 DD 5E R 00 00 01 00 -T 2F 17 00 00 F2 DD 56 F3 3E 23 19 00 00 21 +T 3B 17 00 00 F2 DD 56 F3 3E 2F 19 00 00 21 R 00 00 01 00 29 09 01 00 -T 36 17 00 00 23 19 00 00 CD 00 00 00 00 18 AC +T 42 17 00 00 2F 19 00 00 CD 00 00 00 00 18 AC R 00 00 01 00 00 04 01 00 02 09 26 00 -T 3D 17 00 00 +T 49 17 00 00 R 00 00 01 00 -T 3D 17 00 00 DD CB FD 7E 28 11 +T 49 17 00 00 DD CB FD 7E 28 11 R 00 00 01 00 -T 43 17 00 00 +T 4F 17 00 00 R 00 00 01 00 -T 43 17 00 00 21 00 00 39 7E DD 86 F6 77 23 7E +T 4F 17 00 00 21 00 00 39 7E DD 86 F6 77 23 7E R 00 00 01 00 -T 4E 17 00 00 DD 8E F7 77 18 95 +T 5A 17 00 00 DD 8E F7 77 18 95 R 00 00 01 00 -T 54 17 00 00 +T 60 17 00 00 R 00 00 01 00 -T 54 17 00 00 +T 60 17 00 00 R 00 00 01 00 -T 54 17 00 00 +T 60 17 00 00 R 00 00 01 00 -T 54 17 00 00 DD 4E F4 DD 46 F5 DD 6E FA DD 66 +T 60 17 00 00 DD 4E F4 DD 46 F5 DD 6E FA DD 66 R 00 00 01 00 -T 5F 17 00 00 FB A7 ED 42 D2 54 18 00 00 +T 6B 17 00 00 FB A7 ED 42 D2 60 18 00 00 R 00 00 01 00 00 09 01 00 -T 66 17 00 00 +T 72 17 00 00 R 00 00 01 00 -T 66 17 00 00 DD 4E F4 DD 46 F5 DD 5E FA DD 56 +T 72 17 00 00 DD 4E F4 DD 46 F5 DD 5E FA DD 56 R 00 00 01 00 -T 71 17 00 00 FB 3A 06 00 00 00 2A 04 00 00 00 +T 7D 17 00 00 FB 3A 06 00 00 00 2A 04 00 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 78 17 00 00 CD 00 00 00 00 DD 75 FC DD 74 FD +T 84 17 00 00 CD 00 00 00 00 DD 75 FC DD 74 FD R 00 00 01 00 02 05 26 00 -T 81 17 00 00 7D B4 20 23 +T 8D 17 00 00 7D B4 20 23 R 00 00 01 00 -T 85 17 00 00 +T 91 17 00 00 R 00 00 01 00 -T 85 17 00 00 DD 4E F4 DD 46 F5 21 08 00 39 7E +T 91 17 00 00 DD 4E F4 DD 46 F5 21 08 00 39 7E R 00 00 01 00 -T 90 17 00 00 DD 86 F6 77 23 7E DD 8E F7 77 2B +T 9C 17 00 00 DD 86 F6 77 23 7E DD 8E F7 77 2B R 00 00 01 00 -T 9B 17 00 00 6E 67 EB 3E 23 19 00 00 21 +T A7 17 00 00 6E 67 EB 3E 2F 19 00 00 21 R 00 00 01 00 29 08 01 00 -T A1 17 00 00 23 19 00 00 CD 00 00 00 00 18 AC +T AD 17 00 00 2F 19 00 00 CD 00 00 00 00 18 AC R 00 00 01 00 00 04 01 00 02 09 26 00 -T A8 17 00 00 +T B4 17 00 00 R 00 00 01 00 -T A8 17 00 00 DD 4E FC DD 46 FD 21 00 00 CD +T B4 17 00 00 DD 4E FC DD 46 FD 21 00 00 CD R 00 00 01 00 -T B2 17 00 00 00 00 00 00 D2 42 18 00 00 +T BE 17 00 00 00 00 00 00 D2 4E 18 00 00 R 00 00 01 00 02 04 31 00 00 09 01 00 -T B7 17 00 00 +T C3 17 00 00 R 00 00 01 00 -T B7 17 00 00 DD 6E F8 DD 66 F9 DD 4E F2 DD 46 +T C3 17 00 00 DD 6E F8 DD 66 F9 DD 4E F2 DD 46 R 00 00 01 00 -T C2 17 00 00 F3 A7 ED 42 20 45 +T CE 17 00 00 F3 A7 ED 42 20 45 R 00 00 01 00 -T C8 17 00 00 +T D4 17 00 00 R 00 00 01 00 -T C8 17 00 00 DD 6E F4 DD 66 F5 E5 21 0A 00 39 +T D4 17 00 00 DD 6E F4 DD 66 F5 E5 21 0A 00 39 R 00 00 01 00 -T D3 17 00 00 7E DD 86 F6 77 23 7E DD 8E F7 77 +T DF 17 00 00 7E DD 86 F6 77 23 7E DD 8E F7 77 R 00 00 01 00 -T DE 17 00 00 2B 6E 67 4D 44 DD 5E F2 DD 56 F3 +T EA 17 00 00 2B 6E 67 4D 44 DD 5E F2 DD 56 F3 R 00 00 01 00 -T E9 17 00 00 3E 86 19 00 00 21 86 19 00 00 CD +T F5 17 00 00 3E 92 19 00 00 21 92 19 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 -T EF 17 00 00 00 00 00 00 E1 21 06 00 39 7E DD +T FB 17 00 00 00 00 00 00 E1 21 06 00 39 7E DD R 00 00 01 00 02 04 26 00 -T F8 17 00 00 86 F6 77 23 7E DD 8E F7 77 2B 6E +T 04 18 00 00 86 F6 77 23 7E DD 8E F7 77 2B 6E R 00 00 01 00 -T 03 18 00 00 67 DD 75 F2 DD 74 F3 C3 +T 0F 18 00 00 67 DD 75 F2 DD 74 F3 C3 R 00 00 01 00 -T 0B 18 00 00 54 17 00 00 +T 17 18 00 00 60 17 00 00 R 00 00 01 00 00 04 01 00 -T 0D 18 00 00 +T 19 18 00 00 R 00 00 01 00 -T 0D 18 00 00 DD 4E F4 DD 46 F5 DD 5E F2 DD 56 +T 19 18 00 00 DD 4E F4 DD 46 F5 DD 5E F2 DD 56 R 00 00 01 00 -T 18 18 00 00 F3 3E 23 19 00 00 21 23 19 00 00 +T 24 18 00 00 F3 3E 2F 19 00 00 21 2F 19 00 00 R 00 00 01 00 29 06 01 00 00 0B 01 00 -T 1E 18 00 00 CD 00 00 00 00 21 02 00 39 7E DD +T 2A 18 00 00 CD 00 00 00 00 21 02 00 39 7E DD R 00 00 01 00 02 05 26 00 -T 27 18 00 00 96 F6 77 23 7E DD 9E F7 77 21 +T 33 18 00 00 96 F6 77 23 7E DD 9E F7 77 21 R 00 00 01 00 -T 31 18 00 00 00 00 39 7E DD 86 F6 77 23 7E DD +T 3D 18 00 00 00 00 39 7E DD 86 F6 77 23 7E DD R 00 00 01 00 -T 3C 18 00 00 8E F7 77 C3 E9 16 00 00 +T 48 18 00 00 8E F7 77 C3 F5 16 00 00 R 00 00 01 00 00 08 01 00 -T 42 18 00 00 +T 4E 18 00 00 R 00 00 01 00 -T 42 18 00 00 21 02 00 39 7E DD 96 F6 77 23 7E +T 4E 18 00 00 21 02 00 39 7E DD 96 F6 77 23 7E R 00 00 01 00 -T 4D 18 00 00 DD 9E F7 77 C3 54 17 00 00 +T 59 18 00 00 DD 9E F7 77 C3 60 17 00 00 R 00 00 01 00 00 09 01 00 -T 54 18 00 00 +T 60 18 00 00 R 00 00 01 00 -T 54 18 00 00 DD 6E F8 DD 66 F9 DD 4E F2 DD 46 +T 60 18 00 00 DD 6E F8 DD 66 F9 DD 4E F2 DD 46 R 00 00 01 00 -T 5F 18 00 00 F3 A7 ED 42 20 79 +T 6B 18 00 00 F3 A7 ED 42 20 79 R 00 00 01 00 -T 65 18 00 00 +T 71 18 00 00 R 00 00 01 00 -T 65 18 00 00 DD 4E FA DD 46 FB DD 6E 04 DD 66 +T 71 18 00 00 DD 4E FA DD 46 FB DD 6E 04 DD 66 R 00 00 01 00 -T 70 18 00 00 05 A7 ED 42 4D 44 DD 5E 02 DD 56 +T 7C 18 00 00 05 A7 ED 42 4D 44 DD 5E 02 DD 56 R 00 00 01 00 -T 7B 18 00 00 03 DD 6E F8 DD 66 F9 A7 ED 52 CD +T 87 18 00 00 03 DD 6E F8 DD 66 F9 A7 ED 52 CD R 00 00 01 00 -T 86 18 00 00 00 00 00 00 38 2A +T 92 18 00 00 00 00 00 00 38 2A R 00 00 01 00 02 04 31 00 -T 8A 18 00 00 +T 96 18 00 00 R 00 00 01 00 -T 8A 18 00 00 DD 4E 04 DD 46 05 DD 6E F6 DD 66 +T 96 18 00 00 DD 4E 04 DD 46 05 DD 6E F6 DD 66 R 00 00 01 00 -T 95 18 00 00 F7 DD 5E FA DD 56 FB 19 EB 3E +T A1 18 00 00 F7 DD 5E FA DD 56 FB 19 EB 3E R 00 00 01 00 -T 9F 18 00 00 61 16 00 00 21 61 16 00 00 CD +T AB 18 00 00 6D 16 00 00 21 6D 16 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T A4 18 00 00 00 00 00 00 DD 6E F8 DD 66 F9 DD +T B0 18 00 00 00 00 00 00 DD 6E F8 DD 66 F9 DD R 00 00 01 00 02 04 26 00 -T AD 18 00 00 75 04 DD 74 05 18 27 +T B9 18 00 00 75 04 DD 74 05 18 27 R 00 00 01 00 -T B4 18 00 00 +T C0 18 00 00 R 00 00 01 00 -T B4 18 00 00 DD 4E F8 DD 46 F9 DD 5E 02 DD 56 +T C0 18 00 00 DD 4E F8 DD 46 F9 DD 5E 02 DD 56 R 00 00 01 00 -T BF 18 00 00 03 3E 61 16 00 00 21 61 16 00 00 +T CB 18 00 00 03 3E 6D 16 00 00 21 6D 16 00 00 R 00 00 01 00 29 06 01 00 00 0B 01 00 -T C5 18 00 00 CD 00 00 00 00 DD 6E F6 DD 66 F7 +T D1 18 00 00 CD 00 00 00 00 DD 6E F6 DD 66 F7 R 00 00 01 00 02 05 26 00 -T CE 18 00 00 DD 4E FA DD 46 FB 09 DD 75 02 DD +T DA 18 00 00 DD 4E FA DD 46 FB 09 DD 75 02 DD R 00 00 01 00 -T D9 18 00 00 74 03 +T E5 18 00 00 74 03 R 00 00 01 00 -T DB 18 00 00 +T E7 18 00 00 R 00 00 01 00 -T DB 18 00 00 C3 6F 16 00 00 +T E7 18 00 00 C3 7B 16 00 00 R 00 00 01 00 00 05 01 00 -T DE 18 00 00 +T EA 18 00 00 R 00 00 01 00 -T DE 18 00 00 DD 6E F2 DD 66 F3 E5 21 08 00 39 +T EA 18 00 00 DD 6E F2 DD 66 F3 E5 21 08 00 39 R 00 00 01 00 -T E9 18 00 00 7E DD 96 F6 77 23 7E DD 9E F7 77 +T F5 18 00 00 7E DD 96 F6 77 23 7E DD 9E F7 77 R 00 00 01 00 -T F4 18 00 00 2B 6E 67 4D 44 DD 5E F4 DD 56 F5 +T 00 19 00 00 2B 6E 67 4D 44 DD 5E F4 DD 56 F5 R 00 00 01 00 -T FF 18 00 00 3E 86 19 00 00 21 86 19 00 00 CD +T 0B 19 00 00 3E 92 19 00 00 21 92 19 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 -T 05 19 00 00 00 00 00 00 E1 21 08 00 39 7E DD +T 11 19 00 00 00 00 00 00 E1 21 08 00 39 7E DD R 00 00 01 00 02 04 26 00 -T 0E 19 00 00 96 F6 77 23 7E DD 9E F7 77 2B 6E +T 1A 19 00 00 96 F6 77 23 7E DD 9E F7 77 2B 6E R 00 00 01 00 -T 19 19 00 00 67 DD 75 F4 DD 74 F5 C3 +T 25 19 00 00 67 DD 75 F4 DD 74 F5 C3 R 00 00 01 00 -T 21 19 00 00 E9 16 00 00 +T 2D 19 00 00 F5 16 00 00 R 00 00 01 00 00 04 01 00 -T 23 19 00 00 +T 2F 19 00 00 R 00 00 01 00 -T 23 19 00 00 CD 00 00 00 00 F8 FF 2A +T 2F 19 00 00 CD 00 00 00 00 F8 FF 2A R 00 00 01 00 02 05 2D 00 -T 29 19 00 00 07 00 00 00 DD 75 FD DD 74 FE DD +T 35 19 00 00 07 00 00 00 DD 75 FD DD 74 FE DD R 00 00 01 00 00 04 03 00 -T 32 19 00 00 6E 02 DD 66 03 DD 75 F8 DD 74 F9 +T 3E 19 00 00 6E 02 DD 66 03 DD 75 F8 DD 74 F9 R 00 00 01 00 -T 3D 19 00 00 DD 71 FA DD 70 FB +T 49 19 00 00 DD 71 FA DD 70 FB R 00 00 01 00 -T 43 19 00 00 +T 4F 19 00 00 R 00 00 01 00 -T 43 19 00 00 DD 6E F8 DD 66 F9 46 DD 70 FC DD +T 4F 19 00 00 DD 6E F8 DD 66 F9 46 DD 70 FC DD R 00 00 01 00 -T 4E 19 00 00 6E FA DD 66 FB 4E DD 6E F8 DD 66 +T 5A 19 00 00 6E FA DD 66 FB 4E DD 6E F8 DD 66 R 00 00 01 00 -T 59 19 00 00 F9 23 DD 75 F8 DD 74 F9 2B 71 DD +T 65 19 00 00 F9 23 DD 75 F8 DD 74 F9 2B 71 DD R 00 00 01 00 -T 64 19 00 00 6E FA DD 66 FB 23 DD 75 FA DD 74 +T 70 19 00 00 6E FA DD 66 FB 23 DD 75 FA DD 74 R 00 00 01 00 -T 6F 19 00 00 FB 2B 70 DD 6E FD DD 66 FE 2B DD +T 7B 19 00 00 FB 2B 70 DD 6E FD DD 66 FE 2B DD R 00 00 01 00 -T 7A 19 00 00 75 FD DD 74 FE 7D B4 20 C0 +T 86 19 00 00 75 FD DD 74 FE 7D B4 20 C0 R 00 00 01 00 -T 83 19 00 00 +T 8F 19 00 00 R 00 00 01 00 -T 83 19 00 00 C3 00 00 00 00 +T 8F 19 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 -T 86 19 00 00 +T 92 19 00 00 R 00 00 01 00 -T 86 19 00 00 CD 00 00 00 00 F6 FF 2A +T 92 19 00 00 CD 00 00 00 00 F6 FF 2A R 00 00 01 00 02 05 2D 00 -T 8C 19 00 00 07 00 00 00 DD 75 FE DD 74 FF DD +T 98 19 00 00 07 00 00 00 DD 75 FE DD 74 FF DD R 00 00 01 00 00 04 03 00 -T 95 19 00 00 6E 02 DD 66 03 DD 75 F6 DD 74 F7 +T A1 19 00 00 6E 02 DD 66 03 DD 75 F6 DD 74 F7 R 00 00 01 00 -T A0 19 00 00 DD 71 F8 DD 70 F9 DD 6E 0A DD 66 +T AC 19 00 00 DD 71 F8 DD 70 F9 DD 6E 0A DD 66 R 00 00 01 00 -T AB 19 00 00 0B DD 75 FA DD 74 FB +T B7 19 00 00 0B DD 75 FA DD 74 FB R 00 00 01 00 -T B2 19 00 00 +T BE 19 00 00 R 00 00 01 00 -T B2 19 00 00 DD 6E F6 DD 66 F7 4E 06 00 DD 71 +T BE 19 00 00 DD 6E F6 DD 66 F7 4E 06 00 DD 71 R 00 00 01 00 -T BD 19 00 00 FC DD 70 FD DD 6E FA DD 66 FB 56 +T C9 19 00 00 FC DD 70 FD DD 6E FA DD 66 FB 56 R 00 00 01 00 -T C8 19 00 00 DD 6E F6 DD 66 F7 23 DD 75 F6 DD +T D4 19 00 00 DD 6E F6 DD 66 F7 23 DD 75 F6 DD R 00 00 01 00 -T D3 19 00 00 74 F7 2B 72 DD 6E F8 DD 66 F9 56 +T DF 19 00 00 74 F7 2B 72 DD 6E F8 DD 66 F9 56 R 00 00 01 00 -T DE 19 00 00 DD 6E FA DD 66 FB 23 DD 75 FA DD +T EA 19 00 00 DD 6E FA DD 66 FB 23 DD 75 FA DD R 00 00 01 00 -T E9 19 00 00 74 FB 2B 72 DD 6E F8 DD 66 F9 23 +T F5 19 00 00 74 FB 2B 72 DD 6E F8 DD 66 F9 23 R 00 00 01 00 -T F4 19 00 00 DD 75 F8 DD 74 F9 2B 71 DD 6E FE +T 00 1A 00 00 DD 75 F8 DD 74 F9 2B 71 DD 6E FE R 00 00 01 00 -T FF 19 00 00 DD 66 FF 2B DD 75 FE DD 74 FF 7D +T 0B 1A 00 00 DD 66 FF 2B DD 75 FE DD 74 FF 7D R 00 00 01 00 -T 0A 1A 00 00 B4 20 A5 +T 16 1A 00 00 B4 20 A5 R 00 00 01 00 -T 0D 1A 00 00 +T 19 1A 00 00 R 00 00 01 00 -T 0D 1A 00 00 C3 00 00 00 00 +T 19 1A 00 00 C3 00 00 00 00 R 00 00 01 00 02 05 12 00 -T 10 1A 00 00 +T 1C 1A 00 00 R 00 00 01 00 -T 10 1A 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD +T 1C 1A 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD R 00 00 01 00 02 05 2D 00 -T 19 1A 00 00 66 03 DD 75 FE DD 74 FF +T 25 1A 00 00 66 03 DD 75 FE DD 74 FF R 00 00 01 00 -T 21 1A 00 00 +T 2D 1A 00 00 R 00 00 01 00 -T 21 1A 00 00 DD 6E 0A DD 66 0B 2B DD 75 0A DD +T 2D 1A 00 00 DD 6E 0A DD 66 0B 2B DD 75 0A DD R 00 00 01 00 -T 2C 1A 00 00 74 0B CB 7C 20 20 +T 38 1A 00 00 74 0B CB 7C 20 20 R 00 00 01 00 -T 32 1A 00 00 +T 3E 1A 00 00 R 00 00 01 00 -T 32 1A 00 00 DD 6E 04 DD 66 05 23 DD 75 04 DD +T 3E 1A 00 00 DD 6E 04 DD 66 05 23 DD 75 04 DD R 00 00 01 00 -T 3D 1A 00 00 74 05 2B 46 DD 6E FE DD 66 FF 23 +T 49 1A 00 00 74 05 2B 46 DD 6E FE DD 66 FF 23 R 00 00 01 00 -T 48 1A 00 00 DD 75 FE DD 74 FF 2B 70 18 CF +T 54 1A 00 00 DD 75 FE DD 74 FF 2B 70 18 CF R 00 00 01 00 -T 52 1A 00 00 +T 5E 1A 00 00 R 00 00 01 00 -T 52 1A 00 00 DD 6E 02 DD 66 03 C3 00 00 00 00 +T 5E 1A 00 00 DD 6E 02 DD 66 03 C3 00 00 00 00 R 00 00 01 00 02 0B 12 00 T 00 00 00 00 R 00 00 02 00 @@ -2768,7 +2770,11 @@ T 86 00 00 00 60 00 R 00 00 02 00 T 88 00 00 00 R 00 00 02 00 -T 88 00 00 00 74 72 79 20 61 67 61 69 6E 00 +T 88 00 00 00 63 61 6E 27 74 20 66 6F 72 6B 20 +R 00 00 02 00 +T 93 00 00 00 2D 20 74 72 79 20 61 67 61 69 6E +R 00 00 02 00 +T 9E 00 00 00 00 R 00 00 02 00 T 00 00 00 00 R 00 00 03 00 diff --git a/src/sh/msh/sh5.c b/src/sh/msh/sh5.c index b41a79f5..a4e79ad1 100644 --- a/src/sh/msh/sh5.c +++ b/src/sh/msh/sh5.c @@ -4,6 +4,7 @@ #define _NSIG NSIGS /* Nick NSIG */ #include #include +#include /* Nick see prs_expand() routine */ #include "sh.h" /* -------- io.c -------- */ @@ -96,7 +97,11 @@ readc() if (multiline) return env.iop->prev = 0; if (talking && env.iop == iostack+1) +#if 1 /* Nick */ + prs_expand(prompt->value); +#else prs(prompt->value); +#endif } } if (env.iop >= iostack) @@ -391,6 +396,72 @@ register char *s; write(2, s, strlen(s)); } +#if 1 /* Nick */ +void prs_expand(char *p) + { + char *q, *r; + struct utsname name; + char buf[PATHLEN]; + + for (q = p; *q; q++) + { + if (*q == '\\') + { + write(2, p, q-p); + p = ++q; + switch (*q) + { + case '#': + p++; + if (geteuid() == 0) + { + prs("#"); + } + else + { + prs("$"); + } + break; + case 'u': + p++; + if ((r = getenv("USER")) == NULL) + { + prs("someone"); + } + else + { + prs(r); + } + break; + case 'h': + p++; + if (uname(&name) == -1) + { + prs("somehost"); + } + else + { + prs(name.nodename); + } + break; + case 'w': + p++; + if (getcwd(buf, PATHLEN) == NULL) + { + prs("somewhere"); + } + else + { + prs(buf); + } + break; + } + } + } + prs(p); + } +#endif + void putc(c) char c; @@ -561,7 +632,11 @@ int ec; env.iobase = env.iop; for (;;) { if (talking && env.iop <= iostack) +#if 1 /* Nick */ + prs_expand(cprompt->value); +#else prs(cprompt->value); +#endif next = line; while ((c = getc(ec)) != '\n' && c) { if (ec == '\'') diff --git a/src/sh/msh/sh5.rel b/src/sh/msh/sh5.rel index 66a32818..656b786f 100644 --- a/src/sh/msh/sh5.rel +++ b/src/sh/msh/sh5.rel @@ -1,11 +1,12 @@ XL4 -H 6 areas 52 global symbols +H 6 areas 58 global symbols M sh5 S evalstr Ref00000000 S cprompt Ref00000000 S ?BANK_FAST_LEAVE_L08 Ref00000000 S putn Ref00000000 S strsave Ref00000000 +S getenv Ref00000000 S err Ref00000000 S env Ref00000000 S dup Ref00000000 @@ -21,8 +22,10 @@ S newenv Ref00000000 S multiline Ref00000000 S ?BANK_LEAVE_DIRECT_L08 Ref00000000 S lseek Ref00000000 +S uname Ref00000000 S close Ref00000000 S strlen Ref00000000 +S ?C_V_SWITCH_L06 Ref00000000 S strcmp Ref00000000 S getarea Ref00000000 S ?LEAVE_DIRECT_L09 Ref00000000 @@ -34,6 +37,7 @@ S ?ENT_PARM_DIRECT_L09 Ref00000000 S ?BANK_CALL_DIRECT_L08 Ref00000000 S errno Ref00000000 S sh_itoa Ref00000000 +S geteuid Ref00000000 S ioargstack Ref00000000 S areanum Ref00000000 S talking Ref00000000 @@ -50,41 +54,43 @@ S ?CL64180B_4_06_L00 Ref00000000 S _read Ref00000000 S getpid Ref00000000 S elinep Ref00000000 +S getcwd Ref00000000 S .__.ABS. Def00000000 A _DEFAULT size 0 flags 0 -A CODE size 12D2 flags 0 +A CODE size 1451 flags 0 S herechar Def00000828 -S closepipe Def00000BAB +S closepipe Def00000D2A S linechar Def0000098D -S freehere Def0000117C -S markhere Def00000BE1 -S closeall Def00000A5B -S prn Def00000A23 -S remap Def00000A94 +S freehere Def000012FB +S markhere Def00000D60 +S closeall Def00000BDA +S prn Def00000BA2 +S remap Def00000C13 S prs Def000009DA -S tempname Def00001246 +S tempname Def000013C5 S pushio Def00000281 S eofc Def000000DA S dolchar Def00000535 -S openpipe Def00000B7A +S openpipe Def00000CF9 S unget Def000000B8 S getc Def00000000 S qgravechar Def000008AC -S gethere Def00000D28 +S gethere Def00000EA7 S setbase Def00000460 S qstrchar Def0000061F S gravechar Def00000874 +S prs_expand Def00000A07 S strchar Def000005E5 S ioecho Def00000259 S nlchar Def0000047B S wdchar Def000004C4 -S herein Def00000FB9 -S putc Def00000A07 -S closef Def00000A3D -S scraphere Def00001104 +S herein Def00001138 +S putc Def00000B86 +S closef Def00000BBC +S scraphere Def00001283 S filechar Def0000065F S readc Def0000010A -A CSTR size 92 flags 0 +A CSTR size B6 flags 0 A UDATA0 size 6 flags 0 A IDATA0 size 41C flags 0 S temparg Def0000040E @@ -92,9 +98,9 @@ A CDATA0 size 41C flags 0 T 00 00 00 00 R 00 00 01 00 T 00 00 00 00 CD 00 00 00 00 FE FF ED 4B -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 07 00 00 00 00 00 00 00 2A 00 00 00 00 A7 ED -R 00 00 01 00 02 04 06 00 02 09 30 00 +R 00 00 01 00 02 04 07 00 02 09 34 00 T 0E 00 00 00 42 30 35 R 00 00 01 00 T 11 00 00 00 @@ -104,7 +110,7 @@ R 00 00 01 00 T 11 00 00 00 3E 0A 01 00 00 21 0A 01 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 17 00 00 00 00 00 00 00 DD 75 FE DD 74 FF 3E -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 20 00 00 00 0A AD B4 28 0A DD 7E FE DD B6 FF R 00 00 01 00 T 2B 00 00 00 28 02 @@ -120,11 +126,11 @@ R 00 00 01 00 T 2F 00 00 00 R 00 00 01 00 T 2F 00 00 00 11 00 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 05 02 00 2B 0A 05 00 +R 00 00 01 00 00 05 02 00 2B 0A 06 00 T 35 00 00 00 00 00 00 00 CD 00 00 00 00 21 -R 00 00 01 00 02 04 05 00 02 09 1E 00 +R 00 00 01 00 02 04 06 00 02 09 21 00 T 3B 00 00 00 00 00 00 00 34 DD 6E FE DD 66 FF -R 00 00 01 00 02 04 1B 00 +R 00 00 01 00 02 04 1E 00 T 44 00 00 00 18 6F R 00 00 01 00 T 46 00 00 00 @@ -132,11 +138,11 @@ R 00 00 01 00 T 46 00 00 00 3E 0A 01 00 00 21 0A 01 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 4C 00 00 00 00 00 00 00 DD 75 FE DD 74 FF 3E -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 55 00 00 00 27 DD AE 02 DD B6 03 28 51 2A R 00 00 01 00 T 5F 00 00 00 04 00 00 00 01 0A 00 09 46 05 05 -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 68 00 00 00 28 45 R 00 00 01 00 T 6A 00 00 00 @@ -152,7 +158,7 @@ R 00 00 01 00 T 74 00 00 00 3E 0A 01 00 00 21 0A 01 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 T 7A 00 00 00 00 00 00 00 DD 75 FE DD 74 FF 3E -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 83 00 00 00 0A AD B4 20 1A 3E 22 DD AE 02 DD R 00 00 01 00 T 8E 00 00 00 B6 03 28 10 @@ -166,7 +172,7 @@ R 00 00 01 00 T 92 00 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 R 00 00 01 00 29 0B 01 00 T 9A 00 00 00 21 00 00 00 00 CD 00 00 00 00 18 -R 00 00 01 00 00 05 01 00 02 0A 1E 00 +R 00 00 01 00 00 05 01 00 02 0A 21 00 T A1 00 00 00 13 R 00 00 01 00 T A2 00 00 00 @@ -184,33 +190,33 @@ R 00 00 01 00 T B5 00 00 00 R 00 00 01 00 T B5 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T B8 00 00 00 R 00 00 01 00 T B8 00 00 00 CD 00 00 00 00 ED 4B 02 00 00 00 -R 00 00 01 00 02 05 1D 00 02 0B 06 00 +R 00 00 01 00 02 05 20 00 02 0B 07 00 T BF 00 00 00 2A 04 00 00 00 A7 ED 42 38 10 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T C7 00 00 00 R 00 00 01 00 T C7 00 00 00 2A 04 00 00 00 01 05 00 09 DD 4E -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T D0 00 00 00 02 DD 46 03 71 23 70 R 00 00 01 00 T D7 00 00 00 R 00 00 01 00 T D7 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T DA 00 00 00 R 00 00 01 00 T DA 00 00 00 C5 ED 4B 02 00 00 00 2A -R 00 00 01 00 02 07 06 00 +R 00 00 01 00 02 07 07 00 T E0 00 00 00 04 00 00 00 A7 ED 42 38 1C 2A -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T E8 00 00 00 04 00 00 00 01 05 00 09 7E 23 B6 -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T F1 00 00 00 20 0B 2A 04 00 00 00 01 07 00 09 -R 00 00 01 00 02 07 06 00 +R 00 00 01 00 02 07 07 00 T FA 00 00 00 7E B7 28 05 R 00 00 01 00 T FE 00 00 00 @@ -228,19 +234,19 @@ R 00 00 01 00 02 06 02 00 T 0A 01 00 00 R 00 00 01 00 T 0A 01 00 00 CD 00 00 00 00 FE FF -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 0F 01 00 00 R 00 00 01 00 T 0F 01 00 00 R 00 00 01 00 T 0F 01 00 00 ED 4B 02 00 00 00 2A 04 00 00 00 -R 00 00 01 00 02 06 06 00 02 0B 06 00 +R 00 00 01 00 02 06 07 00 02 0B 07 00 T 16 01 00 00 A7 ED 42 DA 3E 02 00 00 R 00 00 01 00 00 08 01 00 T 1C 01 00 00 R 00 00 01 00 T 1C 01 00 00 2A 04 00 00 00 01 05 00 09 46 23 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 25 01 00 00 66 68 DD 75 FE DD 74 FF 7D B4 28 R 00 00 01 00 T 30 01 00 00 14 @@ -248,7 +254,7 @@ R 00 00 01 00 T 31 01 00 00 R 00 00 01 00 T 31 01 00 00 2A 04 00 00 00 01 05 00 09 AF 77 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 3A 01 00 00 23 77 DD 6E FE DD 66 FF C3 R 00 00 01 00 T 43 01 00 00 56 02 00 00 @@ -256,19 +262,19 @@ R 00 00 01 00 00 04 01 00 T 45 01 00 00 R 00 00 01 00 T 45 01 00 00 2A 04 00 00 00 01 07 00 09 7E B7 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 4E 01 00 00 CA EF 01 00 00 R 00 00 01 00 00 05 01 00 T 51 01 00 00 R 00 00 01 00 T 51 01 00 00 ED 4B 04 00 00 00 C5 2A -R 00 00 01 00 02 06 06 00 +R 00 00 01 00 02 06 07 00 T 57 01 00 00 04 00 00 00 23 23 23 5E 23 56 2A -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 60 01 00 00 04 00 00 00 4E 23 46 23 7E 69 60 -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 69 01 00 00 C1 CD 00 00 00 00 DD 75 FE DD 74 -R 00 00 01 00 02 06 1E 00 +R 00 00 01 00 02 06 21 00 T 72 01 00 00 FF 7D B4 28 3D R 00 00 01 00 T 77 01 00 00 @@ -278,13 +284,13 @@ R 00 00 01 00 T 80 01 00 00 R 00 00 01 00 T 80 01 00 00 2A 04 00 00 00 01 0B 00 09 22 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 88 01 00 00 04 00 00 00 C3 31 02 00 00 -R 00 00 01 00 02 04 06 00 00 09 01 00 +R 00 00 01 00 02 04 07 00 00 09 01 00 T 8D 01 00 00 R 00 00 01 00 T 8D 01 00 00 2A 04 00 00 00 01 00 00 00 00 A7 -R 00 00 01 00 02 05 06 00 02 0A 29 00 +R 00 00 01 00 02 05 07 00 02 0A 2D 00 T 94 01 00 00 ED 42 20 0B R 00 00 01 00 T 98 01 00 00 @@ -292,19 +298,19 @@ R 00 00 01 00 T 98 01 00 00 DD 5E FE 3E 59 02 00 00 21 R 00 00 01 00 29 08 01 00 T 9E 01 00 00 59 02 00 00 CD 00 00 00 00 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +R 00 00 01 00 00 04 01 00 02 09 21 00 T A3 01 00 00 R 00 00 01 00 T A3 01 00 00 2A 04 00 00 00 01 07 00 09 DD 46 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T AC 01 00 00 FE 70 68 26 00 C3 56 02 00 00 R 00 00 01 00 00 0A 01 00 T B4 01 00 00 R 00 00 01 00 T B4 01 00 00 2A 04 00 00 00 01 0A 00 09 7E FE -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T BD 01 00 00 03 20 2F 2A 04 00 00 00 01 07 00 -R 00 00 01 00 02 08 06 00 +R 00 00 01 00 02 08 07 00 T C6 01 00 00 09 7E FE 0A 28 23 R 00 00 01 00 T CC 01 00 00 @@ -314,9 +320,9 @@ R 00 00 01 00 T CC 01 00 00 R 00 00 01 00 T CC 01 00 00 2A 04 00 00 00 01 07 00 09 36 00 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T D5 01 00 00 2A 04 00 00 00 01 00 00 00 00 A7 -R 00 00 01 00 02 05 06 00 02 0A 29 00 +R 00 00 01 00 02 05 07 00 02 0A 2D 00 T DC 01 00 00 ED 42 20 0A R 00 00 01 00 T E0 01 00 00 @@ -324,7 +330,7 @@ R 00 00 01 00 T E0 01 00 00 1E 0A 3E 59 02 00 00 21 R 00 00 01 00 29 07 01 00 T E5 01 00 00 59 02 00 00 CD 00 00 00 00 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +R 00 00 01 00 00 04 01 00 02 09 21 00 T EA 01 00 00 R 00 00 01 00 T EA 01 00 00 21 0A 00 18 67 @@ -334,25 +340,25 @@ R 00 00 01 00 T EF 01 00 00 R 00 00 01 00 T EF 01 00 00 2A 04 00 00 00 01 0A 00 09 7E FE -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T F8 01 00 00 03 20 36 R 00 00 01 00 T FB 01 00 00 R 00 00 01 00 T FB 01 00 00 2A 00 00 00 00 7D B4 28 0F -R 00 00 01 00 02 05 11 00 +R 00 00 01 00 02 05 12 00 T 02 02 00 00 R 00 00 01 00 T 02 02 00 00 2A 04 00 00 00 01 07 00 09 36 00 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 0B 02 00 00 2E 00 26 00 18 45 R 00 00 01 00 T 11 02 00 00 R 00 00 01 00 T 11 02 00 00 2A 00 00 00 00 7D B4 28 19 2A -R 00 00 01 00 02 05 23 00 +R 00 00 01 00 02 05 27 00 T 19 02 00 00 04 00 00 00 01 0B 00 00 00 A7 ED -R 00 00 01 00 02 04 06 00 02 09 29 00 +R 00 00 01 00 02 04 07 00 02 09 2D 00 T 20 02 00 00 42 20 0E R 00 00 01 00 T 23 02 00 00 @@ -362,11 +368,11 @@ R 00 00 01 00 T 23 02 00 00 R 00 00 01 00 T 23 02 00 00 2A 00 00 00 00 5E 23 56 3E -R 00 00 01 00 02 05 1C 00 -T 2A 02 00 00 DA 09 00 00 21 DA 09 00 00 CD +R 00 00 01 00 02 05 1F 00 +T 2A 02 00 00 07 0A 00 00 21 07 0A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 2F 02 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 31 02 00 00 R 00 00 01 00 T 31 02 00 00 @@ -374,13 +380,13 @@ R 00 00 01 00 T 31 02 00 00 R 00 00 01 00 T 31 02 00 00 2A 04 00 00 00 01 F5 FF 09 22 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 39 02 00 00 04 00 00 00 C3 0F 01 00 00 -R 00 00 01 00 02 04 06 00 00 09 01 00 +R 00 00 01 00 02 04 07 00 00 09 01 00 T 3E 02 00 00 R 00 00 01 00 T 3E 02 00 00 01 00 00 00 00 2A 04 00 00 00 A7 -R 00 00 01 00 02 05 29 00 02 0A 06 00 +R 00 00 01 00 02 05 2D 00 02 0A 07 00 T 45 02 00 00 ED 42 38 05 R 00 00 01 00 T 49 02 00 00 @@ -390,55 +396,55 @@ R 00 00 01 00 T 4E 02 00 00 R 00 00 01 00 T 4E 02 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 0C 00 02 0A 0C 00 +R 00 00 01 00 2B 05 0D 00 02 0A 0D 00 T 54 02 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 56 02 00 00 R 00 00 01 00 T 56 02 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 59 02 00 00 R 00 00 01 00 T 59 02 00 00 CD 00 00 00 00 21 76 00 ED 4B -R 00 00 01 00 02 05 1D 00 +R 00 00 01 00 02 05 20 00 T 61 02 00 00 00 00 00 00 09 7E B7 28 16 -R 00 00 01 00 02 04 19 00 +R 00 00 01 00 02 04 1C 00 T 68 02 00 00 R 00 00 01 00 T 68 02 00 00 21 01 00 E5 21 04 00 39 4D 44 11 R 00 00 01 00 T 73 02 00 00 02 00 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 08 00 +R 00 00 01 00 2B 07 09 00 T 78 02 00 00 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 02 04 08 00 02 09 1E 00 +R 00 00 01 00 02 04 09 00 02 09 21 00 T 7E 02 00 00 R 00 00 01 00 T 7E 02 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 81 02 00 00 R 00 00 01 00 T 81 02 00 00 CD 00 00 00 00 01 58 00 00 00 2A -R 00 00 01 00 02 05 1D 00 02 0A 29 00 +R 00 00 01 00 02 05 20 00 02 0A 2D 00 T 88 02 00 00 04 00 00 00 11 0B 00 19 22 -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 8F 02 00 00 04 00 00 00 A7 ED 42 38 1C -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 96 02 00 00 R 00 00 01 00 T 96 02 00 00 2A 04 00 00 00 01 F5 FF 09 22 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 9E 02 00 00 04 00 00 00 11 14 00 00 00 3E -R 00 00 01 00 02 04 06 00 00 09 02 00 +R 00 00 01 00 02 04 07 00 00 09 02 00 T A4 02 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 05 00 02 09 05 00 +R 00 00 01 00 2B 04 06 00 02 09 06 00 T A9 02 00 00 00 00 00 00 21 00 00 00 00 34 C3 -R 00 00 01 00 02 04 1E 00 02 09 1B 00 +R 00 00 01 00 02 04 21 00 02 09 1E 00 T B0 02 00 00 5D 04 00 00 R 00 00 01 00 00 04 01 00 T B2 02 00 00 R 00 00 01 00 T B2 02 00 00 2A 04 00 00 00 DD 56 0C DD 4E 0A -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T BB 02 00 00 DD 46 0B 71 23 70 23 72 21 06 00 R 00 00 01 00 T C6 02 00 00 DD 4E 02 DD 46 03 09 7E 23 A6 3C @@ -448,31 +454,31 @@ R 00 00 01 00 T D3 02 00 00 R 00 00 01 00 T D3 02 00 00 2A 04 00 00 00 23 23 23 DD 4E 02 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T DC 02 00 00 DD 46 03 71 23 70 C3 C4 03 00 00 R 00 00 01 00 00 0B 01 00 T E5 02 00 00 R 00 00 01 00 T E5 02 00 00 2A 04 00 00 00 23 23 23 E5 01 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T ED 02 00 00 00 00 00 00 2A 04 00 00 00 A7 ED -R 00 00 01 00 02 04 29 00 02 09 06 00 +R 00 00 01 00 02 04 2D 00 02 09 07 00 T F4 02 00 00 42 EB 01 0B 00 CD 00 00 00 00 01 -R 00 00 01 00 02 0A 2C 00 +R 00 00 01 00 02 0A 30 00 T FD 02 00 00 0E 00 CD 00 00 00 00 21 -R 00 00 01 00 02 07 09 00 +R 00 00 01 00 02 07 0A 00 T 03 03 00 00 00 00 00 00 19 4D 44 E1 71 23 70 -R 00 00 01 00 02 04 21 00 +R 00 00 01 00 02 04 25 00 T 0C 03 00 00 2A 04 00 00 00 23 23 23 5E 23 56 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 15 03 00 00 DD 6E 02 DD 66 03 01 0E 00 ED B0 R 00 00 01 00 T 20 03 00 00 2A 04 00 00 00 23 23 23 46 23 66 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 29 03 00 00 68 01 0C 00 09 E5 2A 04 00 00 00 -R 00 00 01 00 02 0B 06 00 +R 00 00 01 00 02 0B 07 00 T 32 03 00 00 01 00 00 00 00 A7 ED 42 20 05 11 -R 00 00 01 00 02 05 29 00 +R 00 00 01 00 02 05 2D 00 T 3B 03 00 00 06 02 00 00 18 03 R 00 00 01 00 00 04 04 00 T 3F 03 00 00 @@ -482,25 +488,25 @@ R 00 00 01 00 00 05 04 00 T 42 03 00 00 R 00 00 01 00 T 42 03 00 00 E1 73 23 72 2A 04 00 00 00 23 23 -R 00 00 01 00 02 09 06 00 +R 00 00 01 00 02 09 07 00 T 4B 03 00 00 23 46 23 66 68 01 04 00 09 5E 23 R 00 00 01 00 T 56 03 00 00 56 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 1A 00 02 0B 1A 00 +R 00 00 01 00 2B 06 1D 00 02 0B 1D 00 T 5C 03 00 00 CD 00 00 00 00 7D B4 20 61 2A -R 00 00 01 00 02 05 1E 00 +R 00 00 01 00 02 05 21 00 T 64 03 00 00 04 00 00 00 01 00 00 00 00 A7 ED -R 00 00 01 00 02 04 06 00 02 09 29 00 +R 00 00 01 00 02 04 07 00 02 09 2D 00 T 6B 03 00 00 42 28 2F 21 01 00 E5 21 00 00 E5 R 00 00 01 00 T 76 03 00 00 21 00 00 E5 2A 04 00 00 00 23 23 -R 00 00 01 00 02 09 06 00 +R 00 00 01 00 02 09 07 00 T 7F 03 00 00 23 46 23 66 68 01 04 00 09 5E 23 R 00 00 01 00 T 8A 03 00 00 56 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 13 00 02 0B 13 00 +R 00 00 01 00 2B 06 14 00 02 0B 14 00 T 90 03 00 00 CD 00 00 00 00 F1 F1 F1 7D A4 A1 -R 00 00 01 00 02 05 1E 00 +R 00 00 01 00 02 05 21 00 T 99 03 00 00 A0 3C 28 27 R 00 00 01 00 T 9D 03 00 00 @@ -524,7 +530,7 @@ R 00 00 01 00 00 08 04 00 T AF 03 00 00 R 00 00 01 00 T AF 03 00 00 2A 04 00 00 00 23 23 23 46 23 66 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T B8 03 00 00 68 01 06 00 09 ED 4B 0C 04 00 00 R 00 00 01 00 00 0B 04 00 T C1 03 00 00 71 23 70 @@ -534,13 +540,13 @@ R 00 00 01 00 T C4 03 00 00 R 00 00 01 00 T C4 03 00 00 2A 04 00 00 00 01 07 00 09 36 F5 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T CD 03 00 00 2A 04 00 00 00 01 05 00 09 AF 77 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T D6 03 00 00 23 77 2A 04 00 00 00 01 09 00 09 -R 00 00 01 00 02 07 06 00 +R 00 00 01 00 02 07 07 00 T DF 03 00 00 36 00 2A 04 00 00 00 01 08 00 09 -R 00 00 01 00 02 07 06 00 +R 00 00 01 00 02 07 07 00 T E8 03 00 00 36 00 0E 5F 06 00 00 11 R 00 00 01 00 29 07 01 00 T ED 03 00 00 5F 06 00 00 DD 7E 0C DD 6E 0A DD @@ -562,7 +568,7 @@ R 00 00 01 00 T 14 04 00 00 R 00 00 01 00 T 14 04 00 00 2A 04 00 00 00 01 0A 00 09 36 03 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 1D 04 00 00 18 3E R 00 00 01 00 T 1F 04 00 00 @@ -588,13 +594,13 @@ R 00 00 01 00 T 49 04 00 00 R 00 00 01 00 T 49 04 00 00 2A 04 00 00 00 01 0A 00 09 36 02 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 52 04 00 00 18 09 R 00 00 01 00 T 54 04 00 00 R 00 00 01 00 T 54 04 00 00 2A 04 00 00 00 01 0A 00 09 36 00 -R 00 00 01 00 02 05 06 00 +R 00 00 01 00 02 05 07 00 T 5D 04 00 00 R 00 00 01 00 T 5D 04 00 00 @@ -602,21 +608,21 @@ R 00 00 01 00 T 5D 04 00 00 R 00 00 01 00 T 5D 04 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 60 04 00 00 R 00 00 01 00 T 60 04 00 00 CD 00 00 00 00 FE FF 2A -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 66 04 00 00 02 00 00 00 DD 75 FE DD 74 FF DD -R 00 00 01 00 02 04 06 00 +R 00 00 01 00 02 04 07 00 T 6F 04 00 00 4E 02 DD 46 03 ED 43 02 00 00 00 -R 00 00 01 00 02 0B 06 00 +R 00 00 01 00 02 0B 07 00 T 78 04 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 7B 04 00 00 R 00 00 01 00 T 7B 04 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 84 04 00 00 66 03 7E 23 B6 20 05 R 00 00 01 00 T 8B 04 00 00 @@ -644,11 +650,11 @@ R 00 00 01 00 T C1 04 00 00 R 00 00 01 00 T C1 04 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T C4 04 00 00 R 00 00 01 00 T C4 04 00 00 CD 00 00 00 00 FC FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T CD 04 00 00 66 03 23 23 46 23 66 68 DD 75 FD R 00 00 01 00 T D8 04 00 00 DD 74 FE 7D B4 20 05 @@ -690,11 +696,11 @@ R 00 00 01 00 T 32 05 00 00 R 00 00 01 00 T 32 05 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 35 05 00 00 R 00 00 01 00 T 35 05 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 3E 05 00 00 66 03 23 23 4E 23 46 59 50 13 13 R 00 00 01 00 T 49 05 00 00 72 2B 73 0A 6F 03 0A 67 DD 75 FE @@ -722,7 +728,7 @@ R 00 00 01 00 00 08 04 00 T 88 05 00 00 81 02 00 00 21 81 02 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 T 8D 05 00 00 00 00 00 00 E1 E1 21 FF FF 18 03 -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 96 05 00 00 R 00 00 01 00 T 96 05 00 00 21 00 00 @@ -730,11 +736,11 @@ R 00 00 01 00 T 99 05 00 00 R 00 00 01 00 T 99 05 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 9C 05 00 00 R 00 00 01 00 T 9C 05 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T A5 05 00 00 66 03 7E 23 B6 20 05 R 00 00 01 00 T AC 05 00 00 @@ -762,11 +768,11 @@ R 00 00 01 00 T E2 05 00 00 R 00 00 01 00 T E2 05 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T E5 05 00 00 R 00 00 01 00 T E5 05 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T EE 05 00 00 66 03 7E 23 B6 28 1C DD 6E 02 DD R 00 00 01 00 T F9 05 00 00 66 03 4E 23 46 03 70 2B 71 0B 0A @@ -790,11 +796,11 @@ R 00 00 01 00 T 1C 06 00 00 R 00 00 01 00 T 1C 06 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 1F 06 00 00 R 00 00 01 00 T 1F 06 00 00 CD 00 00 00 00 FE FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 28 06 00 00 66 03 7E 23 B6 28 1C DD 6E 02 DD R 00 00 01 00 T 33 06 00 00 66 03 4E 23 46 03 70 2B 71 0B 0A @@ -820,11 +826,11 @@ R 00 00 01 00 T 5C 06 00 00 R 00 00 01 00 T 5C 06 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 5F 06 00 00 R 00 00 01 00 T 5F 06 00 00 CD 00 00 00 00 FA FF 21 0C 00 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 68 06 00 00 4E 02 DD 46 03 09 56 23 66 6A DD R 00 00 01 00 T 73 06 00 00 75 FD DD 74 FE 21 06 00 09 7E 23 @@ -872,9 +878,9 @@ R 00 00 01 00 T EE 06 00 00 D5 21 04 00 DD 4E 02 DD 46 03 09 R 00 00 01 00 T F9 06 00 00 5E 23 56 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 13 00 +R 00 00 01 00 2B 08 14 00 T FF 06 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 -R 00 00 01 00 02 04 13 00 02 09 1E 00 +R 00 00 01 00 02 04 14 00 02 09 21 00 T 06 07 00 00 F1 R 00 00 01 00 T 07 07 00 00 @@ -886,27 +892,27 @@ R 00 00 01 00 T 12 07 00 00 03 21 04 00 DD 5E 02 DD 56 03 19 R 00 00 01 00 T 1D 07 00 00 5E 23 56 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 2E 00 +R 00 00 01 00 2B 08 32 00 T 23 07 00 00 00 00 00 00 CD 00 00 00 00 F1 DD -R 00 00 01 00 02 04 2E 00 02 09 1E 00 +R 00 00 01 00 02 04 32 00 02 09 21 00 T 2A 07 00 00 75 FA DD 74 FB CB 7C 28 09 2A R 00 00 01 00 T 34 07 00 00 00 00 00 00 3E 04 AD B4 28 CB -R 00 00 01 00 02 04 1F 00 +R 00 00 01 00 02 04 22 00 T 3C 07 00 00 R 00 00 01 00 T 3C 07 00 00 DD 4E FA DD 46 FB 21 00 00 CD R 00 00 01 00 T 46 07 00 00 00 00 00 00 38 1B -R 00 00 01 00 02 04 2A 00 +R 00 00 01 00 02 04 2E 00 T 4A 07 00 00 R 00 00 01 00 T 4A 07 00 00 21 04 00 DD 4E 02 DD 46 03 09 5E R 00 00 01 00 -T 55 07 00 00 23 56 3E 3D 0A 00 00 21 +T 55 07 00 00 23 56 3E BC 0B 00 00 21 R 00 00 01 00 29 07 01 00 -T 5A 07 00 00 3D 0A 00 00 CD 00 00 00 00 21 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +T 5A 07 00 00 BC 0B 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 21 00 T 60 07 00 00 00 00 C3 25 08 00 00 R 00 00 01 00 00 07 01 00 T 65 07 00 00 @@ -928,7 +934,7 @@ R 00 00 01 00 T 9F 07 00 00 21 08 00 DD 4E 02 DD 46 03 09 CD R 00 00 01 00 T AA 07 00 00 00 00 00 00 21 02 02 DD 4E FD DD -R 00 00 01 00 02 04 25 00 +R 00 00 01 00 02 04 29 00 T B3 07 00 00 46 FE 09 4E 23 46 03 70 2B 71 0B R 00 00 01 00 T BE 07 00 00 0A E6 7F 6F 26 00 18 5F @@ -942,11 +948,11 @@ R 00 00 01 00 T D1 07 00 00 04 00 DD 5E 02 DD 56 03 19 5E 23 R 00 00 01 00 T DC 07 00 00 56 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 2E 00 02 0B 2E 00 +R 00 00 01 00 2B 06 32 00 02 0B 32 00 T E2 07 00 00 CD 00 00 00 00 F1 DD 75 FA DD 74 -R 00 00 01 00 02 05 1E 00 +R 00 00 01 00 02 05 21 00 T EB 07 00 00 FB CB 7C 28 09 2A 00 00 00 00 3E -R 00 00 01 00 02 0A 1F 00 +R 00 00 01 00 02 0A 22 00 T F4 07 00 00 04 AD B4 28 CD R 00 00 01 00 T F9 07 00 00 @@ -959,10 +965,10 @@ T 0D 08 00 00 R 00 00 01 00 T 0D 08 00 00 21 04 00 DD 4E 02 DD 46 03 09 5E R 00 00 01 00 -T 18 08 00 00 23 56 3E 3D 0A 00 00 21 +T 18 08 00 00 23 56 3E BC 0B 00 00 21 R 00 00 01 00 29 07 01 00 -T 1D 08 00 00 3D 0A 00 00 CD 00 00 00 00 21 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +T 1D 08 00 00 BC 0B 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 21 00 T 23 08 00 00 00 00 R 00 00 01 00 T 25 08 00 00 @@ -970,41 +976,41 @@ R 00 00 01 00 T 25 08 00 00 R 00 00 01 00 T 25 08 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 28 08 00 00 R 00 00 01 00 T 28 08 00 00 CD 00 00 00 00 FE FF 21 01 00 E5 -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 31 08 00 00 21 02 00 39 4D 44 21 04 00 DD 5E R 00 00 01 00 T 3C 08 00 00 02 DD 56 03 19 5E 23 56 3E R 00 00 01 00 T 45 08 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 2E 00 02 09 2E 00 +R 00 00 01 00 2B 04 32 00 02 09 32 00 T 4A 08 00 00 00 00 00 00 F1 3E 01 AD B4 28 19 -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 53 08 00 00 R 00 00 01 00 T 53 08 00 00 21 04 00 DD 4E 02 DD 46 03 09 5E R 00 00 01 00 T 5E 08 00 00 23 56 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 14 00 +R 00 00 01 00 2B 07 16 00 T 63 08 00 00 00 00 00 00 CD 00 00 00 00 DD 36 -R 00 00 01 00 02 04 14 00 02 09 1E 00 +R 00 00 01 00 02 04 16 00 02 09 21 00 T 6A 08 00 00 FE 00 R 00 00 01 00 T 6C 08 00 00 R 00 00 01 00 T 6C 08 00 00 DD 6E FE 26 00 C3 00 00 00 00 -R 00 00 01 00 02 0A 12 00 +R 00 00 01 00 02 0A 13 00 T 74 08 00 00 R 00 00 01 00 T 74 08 00 00 CD 00 00 00 00 FE FF DD 5E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 7D 08 00 00 56 03 3E AC 08 00 00 21 R 00 00 01 00 29 07 01 00 T 82 08 00 00 AC 08 00 00 CD 00 00 00 00 7D E6 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +R 00 00 01 00 00 04 01 00 02 09 21 00 T 89 08 00 00 7F 4F 7C E6 FF 47 DD 71 FE DD 70 R 00 00 01 00 T 94 08 00 00 FF 3E 0A A9 B0 20 08 @@ -1016,11 +1022,11 @@ R 00 00 01 00 T A3 08 00 00 R 00 00 01 00 T A3 08 00 00 DD 6E FE DD 66 FF C3 00 00 00 00 -R 00 00 01 00 02 0B 12 00 +R 00 00 01 00 02 0B 13 00 T AC 08 00 00 R 00 00 01 00 T AC 08 00 00 CD 00 00 00 00 FE FF 21 09 00 09 -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T B5 08 00 00 7E B7 28 3A R 00 00 01 00 T B9 08 00 00 @@ -1048,7 +1054,7 @@ R 00 00 01 00 T F3 08 00 00 DD 5E 02 DD 56 03 3E 5F 06 00 00 R 00 00 01 00 29 0B 01 00 T FB 08 00 00 21 5F 06 00 00 CD 00 00 00 00 DD -R 00 00 01 00 00 05 01 00 02 0A 1E 00 +R 00 00 01 00 00 05 01 00 02 0A 21 00 T 02 09 00 00 75 FE DD 74 FF 3E 0A AD B4 20 64 R 00 00 01 00 T 0D 09 00 00 @@ -1062,7 +1068,7 @@ R 00 00 01 00 T 19 09 00 00 DD 5E 02 DD 56 03 3E 5F 06 00 00 R 00 00 01 00 29 0B 01 00 T 21 09 00 00 21 5F 06 00 00 CD 00 00 00 00 DD -R 00 00 01 00 00 05 01 00 02 0A 1E 00 +R 00 00 01 00 00 05 01 00 02 0A 21 00 T 28 09 00 00 75 FE DD 74 FF 3E 0A AD B4 20 0D R 00 00 01 00 T 33 09 00 00 @@ -1104,29 +1110,29 @@ R 00 00 01 00 T 8A 09 00 00 R 00 00 01 00 T 8A 09 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 8D 09 00 00 R 00 00 01 00 T 8D 09 00 00 CD 00 00 00 00 FE FF DD 5E 02 DD -R 00 00 01 00 02 05 24 00 +R 00 00 01 00 02 05 28 00 T 96 09 00 00 56 03 3E 5F 06 00 00 21 R 00 00 01 00 29 07 01 00 T 9B 09 00 00 5F 06 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +R 00 00 01 00 00 04 01 00 02 09 21 00 T A2 09 00 00 FE DD 74 FF 3E 0A AD B4 20 25 R 00 00 01 00 T AC 09 00 00 R 00 00 01 00 T AC 09 00 00 2A 00 00 00 00 7D B4 20 1E -R 00 00 01 00 02 05 11 00 +R 00 00 01 00 02 05 12 00 T B3 09 00 00 R 00 00 01 00 T B3 09 00 00 21 04 00 DD 4E 02 DD 46 03 09 5E R 00 00 01 00 -T BE 09 00 00 23 56 3E 3D 0A 00 00 21 +T BE 09 00 00 23 56 3E BC 0B 00 00 21 R 00 00 01 00 29 07 01 00 -T C3 09 00 00 3D 0A 00 00 CD 00 00 00 00 21 -R 00 00 01 00 00 04 01 00 02 09 1E 00 +T C3 09 00 00 BC 0B 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 21 00 T C9 09 00 00 04 00 09 36 FF 23 36 FF R 00 00 01 00 T D1 09 00 00 @@ -1134,915 +1140,1089 @@ R 00 00 01 00 T D1 09 00 00 R 00 00 01 00 T D1 09 00 00 DD 6E FE DD 66 FF C3 00 00 00 00 -R 00 00 01 00 02 0B 12 00 +R 00 00 01 00 02 0B 13 00 T DA 09 00 00 R 00 00 01 00 T DA 09 00 00 CD 00 00 00 00 6B 62 AF B6 28 21 -R 00 00 01 00 02 05 1D 00 +R 00 00 01 00 02 05 20 00 T E3 09 00 00 R 00 00 01 00 T E3 09 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 -R 00 00 01 00 2B 0B 15 00 +R 00 00 01 00 2B 0B 17 00 T EB 09 00 00 21 00 00 00 00 CD 00 00 00 00 E5 -R 00 00 01 00 02 05 15 00 02 0A 1E 00 +R 00 00 01 00 02 05 17 00 02 0A 21 00 T F2 09 00 00 DD 4E 02 DD 46 03 11 02 00 3E R 00 00 01 00 T FC 09 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 08 00 02 09 08 00 +R 00 00 01 00 2B 04 09 00 02 09 09 00 T 01 0A 00 00 00 00 00 00 F1 -R 00 00 01 00 02 04 1E 00 +R 00 00 01 00 02 04 21 00 T 04 0A 00 00 R 00 00 01 00 T 04 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +R 00 00 01 00 02 05 13 00 T 07 0A 00 00 R 00 00 01 00 -T 07 0A 00 00 CD 00 00 00 00 21 01 00 E5 21 -R 00 00 01 00 02 05 1D 00 -T 0F 0A 00 00 04 00 39 4D 44 11 02 00 3E -R 00 00 01 00 -T 18 0A 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 08 00 02 09 08 00 -T 1D 0A 00 00 00 00 00 00 F1 C3 00 00 00 00 -R 00 00 01 00 02 04 1E 00 02 0A 12 00 -T 23 0A 00 00 -R 00 00 01 00 -T 23 0A 00 00 CD 00 00 00 00 01 00 00 3E -R 00 00 01 00 02 05 1D 00 -T 2A 0A 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 20 00 02 09 20 00 -T 2F 0A 00 00 00 00 00 00 EB 3E DA 09 00 00 21 -R 00 00 01 00 02 04 1E 00 29 0A 01 00 -T 35 0A 00 00 DA 09 00 00 CD 00 00 00 00 C3 -R 00 00 01 00 00 04 01 00 02 09 1E 00 -T 3B 0A 00 00 00 00 00 00 -R 00 00 01 00 02 04 12 00 -T 3D 0A 00 00 -R 00 00 01 00 -T 3D 0A 00 00 CD 00 00 00 00 4B 42 21 02 00 CD -R 00 00 01 00 02 05 1D 00 -T 46 0A 00 00 00 00 00 00 30 0E -R 00 00 01 00 02 04 2A 00 -T 4A 0A 00 00 -R 00 00 01 00 -T 4A 0A 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 -R 00 00 01 00 2B 0B 14 00 -T 52 0A 00 00 21 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 14 00 02 0A 1E 00 -T 58 0A 00 00 -R 00 00 01 00 -T 58 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T 5B 0A 00 00 +T 07 0A 00 00 CD 00 00 00 00 BA FE 21 00 00 39 +R 00 00 01 00 02 05 28 00 +T 10 0A 00 00 DD 4E 02 DD 46 03 71 23 70 R 00 00 01 00 -T 5B 0A 00 00 CD 00 00 00 00 FE FF DD 36 FE 0A -R 00 00 01 00 02 05 24 00 -T 64 0A 00 00 DD 36 FF 00 +T 19 0A 00 00 R 00 00 01 00 -T 68 0A 00 00 +T 19 0A 00 00 21 00 00 39 7E 23 66 6F AF B6 CA R 00 00 01 00 -T 68 0A 00 00 01 14 80 DD 6E FE DD 66 FF 3E 80 +T 24 0A 00 00 75 0B 00 00 +R 00 00 01 00 00 04 01 00 +T 26 0A 00 00 R 00 00 01 00 -T 73 0A 00 00 AC 67 ED 42 30 18 +T 26 0A 00 00 21 00 00 39 7E 23 66 6F 7E FE 5C R 00 00 01 00 -T 79 0A 00 00 +T 31 0A 00 00 C2 69 0B 00 00 +R 00 00 01 00 00 05 01 00 +T 34 0A 00 00 R 00 00 01 00 -T 79 0A 00 00 DD 5E FE DD 56 FF 13 DD 73 FE DD +T 34 0A 00 00 DD 4E 02 DD 46 03 21 00 00 39 56 R 00 00 01 00 -T 84 0A 00 00 72 FF 1B 3E 00 00 00 00 21 -R 00 00 01 00 2B 08 14 00 -T 8A 0A 00 00 00 00 00 00 CD 00 00 00 00 18 D7 -R 00 00 01 00 02 04 14 00 02 09 1E 00 -T 91 0A 00 00 +T 3F 0A 00 00 23 66 6A A7 ED 42 E5 DD 4E 02 DD R 00 00 01 00 -T 91 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T 94 0A 00 00 +T 4A 0A 00 00 46 03 11 02 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 09 00 +T 52 0A 00 00 00 00 00 00 CD 00 00 00 00 F1 21 +R 00 00 01 00 02 04 09 00 02 09 21 00 +T 59 0A 00 00 00 00 39 4E 23 46 03 70 2B 71 DD R 00 00 01 00 -T 94 0A 00 00 CD 00 00 00 00 D6 FF ED 4B -R 00 00 01 00 02 05 24 00 -T 9B 0A 00 00 08 00 00 00 DD 6E 02 DD 66 03 CD -R 00 00 01 00 02 04 06 00 -T A4 0A 00 00 00 00 00 00 D2 71 0B 00 00 -R 00 00 01 00 02 04 2A 00 00 09 01 00 -T A9 0A 00 00 +T 64 0A 00 00 71 02 DD 70 03 21 00 00 39 7E 23 R 00 00 01 00 -T A9 0A 00 00 AF DD 77 D6 DD 77 D7 +T 6F 0A 00 00 66 6F 5E CD 00 00 00 00 04 00 23 +R 00 00 01 00 02 08 18 00 +T 78 0A 00 00 68 75 77 69 0B 00 00 2F 0B 00 00 +R 00 00 01 00 00 07 01 00 00 0B 01 00 +T 7F 0A 00 00 B4 0A 00 00 F4 0A 00 00 +R 00 00 01 00 00 04 01 00 00 08 01 00 +T 83 0A 00 00 85 0A 00 00 +R 00 00 01 00 00 04 01 00 +T 85 0A 00 00 R 00 00 01 00 -T B0 0A 00 00 +T 85 0A 00 00 DD 34 02 20 03 DD 34 03 R 00 00 01 00 -T B0 0A 00 00 01 14 80 DD 6E D6 DD 66 D7 3E 80 +T 8D 0A 00 00 R 00 00 01 00 -T BB 0A 00 00 AC 67 ED 42 30 1E +T 8D 0A 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 24 00 02 0A 24 00 +T 93 0A 00 00 00 00 00 00 7D B4 20 0D +R 00 00 01 00 02 04 21 00 +T 99 0A 00 00 R 00 00 01 00 -T C1 0A 00 00 +T 99 0A 00 00 11 32 00 00 00 3E DA 09 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 9F 0A 00 00 DA 09 00 00 CD 00 00 00 00 18 0B +R 00 00 01 00 00 04 01 00 02 09 21 00 +T A6 0A 00 00 R 00 00 01 00 -T C1 0A 00 00 DD 6E D6 DD 66 D7 29 E5 21 04 00 +T A6 0A 00 00 11 34 00 00 00 3E DA 09 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T AC 0A 00 00 DA 09 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 21 00 +T B1 0A 00 00 R 00 00 01 00 -T CC 0A 00 00 39 4D 44 E1 09 AF 77 23 77 DD 34 +T B1 0A 00 00 C3 69 0B 00 00 +R 00 00 01 00 00 05 01 00 +T B4 0A 00 00 R 00 00 01 00 -T D7 0A 00 00 D6 20 03 DD 34 D7 +T B4 0A 00 00 DD 34 02 20 03 DD 34 03 R 00 00 01 00 -T DD 0A 00 00 +T BC 0A 00 00 R 00 00 01 00 -T DD 0A 00 00 18 D1 +T BC 0A 00 00 21 02 00 39 E5 11 36 00 00 00 3E +R 00 00 01 00 00 0A 02 00 +T C5 0A 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 05 00 02 09 05 00 +T CA 0A 00 00 00 00 00 00 4D 44 E1 71 23 70 79 +R 00 00 01 00 02 04 21 00 +T D3 0A 00 00 B0 20 0D R 00 00 01 00 -T DF 0A 00 00 +T D6 0A 00 00 R 00 00 01 00 -T DF 0A 00 00 +T D6 0A 00 00 11 3B 00 00 00 3E DA 09 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T DC 0A 00 00 DA 09 00 00 CD 00 00 00 00 18 0F +R 00 00 01 00 00 04 01 00 02 09 21 00 +T E3 0A 00 00 R 00 00 01 00 -T DF 0A 00 00 DD 6E 02 DD 66 03 29 E5 21 04 00 +T E3 0A 00 00 21 02 00 39 5E 23 56 3E R 00 00 01 00 -T EA 0A 00 00 39 4D 44 E1 09 36 01 23 36 00 DD +T EB 0A 00 00 DA 09 00 00 21 DA 09 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T F0 0A 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T F2 0A 00 00 R 00 00 01 00 -T F5 0A 00 00 5E 02 DD 56 03 3E 00 00 00 00 21 -R 00 00 01 00 2B 0A 07 00 -T FD 0A 00 00 00 00 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 02 04 07 00 02 09 1E 00 -T 04 0B 00 00 02 DD 74 03 CB 7C 20 0F ED 4B +T F2 0A 00 00 18 75 R 00 00 01 00 -T 0E 0B 00 00 08 00 00 00 DD 6E 02 DD 66 03 CD -R 00 00 01 00 02 04 06 00 -T 17 0B 00 00 00 00 00 00 38 C4 -R 00 00 01 00 02 04 2A 00 -T 1B 0B 00 00 +T F4 0A 00 00 R 00 00 01 00 -T 1B 0B 00 00 AF DD 77 D6 DD 77 D7 +T F4 0A 00 00 DD 34 02 20 03 DD 34 03 R 00 00 01 00 -T 22 0B 00 00 +T FC 0A 00 00 R 00 00 01 00 -T 22 0B 00 00 01 14 80 DD 6E D6 DD 66 D7 3E 80 +T FC 0A 00 00 21 04 00 39 5D 54 3E 00 00 00 00 +R 00 00 01 00 2B 0B 15 00 +T 04 0B 00 00 21 00 00 00 00 CD 00 00 00 00 7D +R 00 00 01 00 02 05 15 00 02 0A 21 00 +T 0B 0B 00 00 A4 3C 20 0D R 00 00 01 00 -T 2D 0B 00 00 AC 67 ED 42 30 2D +T 0F 0B 00 00 R 00 00 01 00 -T 33 0B 00 00 +T 0F 0B 00 00 11 43 00 00 00 3E DA 09 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 15 0B 00 00 DA 09 00 00 CD 00 00 00 00 18 11 +R 00 00 01 00 00 04 01 00 02 09 21 00 +T 1C 0B 00 00 R 00 00 01 00 -T 33 0B 00 00 DD 6E D6 DD 66 D7 29 E5 21 04 00 +T 1C 0B 00 00 21 04 00 39 01 0E 00 09 EB 3E R 00 00 01 00 -T 3E 0B 00 00 39 4D 44 E1 09 7E 23 B6 28 0E +T 26 0B 00 00 DA 09 00 00 21 DA 09 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 2B 0B 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T 2D 0B 00 00 R 00 00 01 00 -T 48 0B 00 00 +T 2D 0B 00 00 18 3A R 00 00 01 00 -T 48 0B 00 00 DD 5E D6 DD 56 D7 3E 00 00 00 00 -R 00 00 01 00 2B 0B 14 00 -T 50 0B 00 00 21 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 14 00 02 0A 1E 00 -T 56 0B 00 00 +T 2F 0B 00 00 R 00 00 01 00 -T 56 0B 00 00 DD 34 D6 20 03 DD 34 D7 +T 2F 0B 00 00 DD 34 02 20 03 DD 34 03 R 00 00 01 00 -T 5E 0B 00 00 +T 37 0B 00 00 R 00 00 01 00 -T 5E 0B 00 00 18 C2 +T 37 0B 00 00 01 00 01 21 46 00 39 5D 54 3E R 00 00 01 00 -T 60 0B 00 00 +T 41 0B 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 35 00 02 09 35 00 +T 46 0B 00 00 00 00 00 00 7D B4 20 0D +R 00 00 01 00 02 04 21 00 +T 4C 0B 00 00 R 00 00 01 00 -T 60 0B 00 00 DD CB 03 7E 28 0B +T 4C 0B 00 00 11 4C 00 00 00 3E DA 09 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 52 0B 00 00 DA 09 00 00 CD 00 00 00 00 18 0E +R 00 00 01 00 00 04 01 00 02 09 21 00 +T 59 0B 00 00 +R 00 00 01 00 +T 59 0B 00 00 21 46 00 39 5D 54 3E DA 09 00 00 +R 00 00 01 00 29 0B 01 00 +T 61 0B 00 00 21 DA 09 00 00 CD 00 00 00 00 +R 00 00 01 00 00 05 01 00 02 0A 21 00 +T 67 0B 00 00 R 00 00 01 00 -T 66 0B 00 00 +T 67 0B 00 00 18 00 R 00 00 01 00 -T 66 0B 00 00 11 32 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 05 02 00 2B 0A 05 00 -T 6C 0B 00 00 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 04 05 00 02 09 1E 00 -T 71 0B 00 00 +T 69 0B 00 00 R 00 00 01 00 -T 71 0B 00 00 +T 69 0B 00 00 R 00 00 01 00 -T 71 0B 00 00 DD 6E 02 DD 66 03 C3 00 00 00 00 -R 00 00 01 00 02 0B 12 00 -T 7A 0B 00 00 +T 69 0B 00 00 21 00 00 39 34 23 20 01 34 R 00 00 01 00 -T 7A 0B 00 00 CD 00 00 00 00 FE FF DD 5E 02 DD -R 00 00 01 00 02 05 24 00 -T 83 0B 00 00 56 03 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 28 00 -T 88 0B 00 00 00 00 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 02 04 28 00 02 09 1E 00 -T 8F 0B 00 00 FE DD 74 FF CB 7C 28 0B +T 72 0B 00 00 R 00 00 01 00 -T 97 0B 00 00 +T 72 0B 00 00 C3 19 0A 00 00 +R 00 00 01 00 00 05 01 00 +T 75 0B 00 00 R 00 00 01 00 -T 97 0B 00 00 11 4F 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 05 02 00 2B 0A 05 00 -T 9D 0B 00 00 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 04 05 00 02 09 1E 00 +T 75 0B 00 00 DD 5E 02 DD 56 03 3E DA 09 00 00 +R 00 00 01 00 29 0B 01 00 +T 7D 0B 00 00 21 DA 09 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 05 01 00 02 0A 21 00 +T 84 0B 00 00 00 00 00 00 +R 00 00 01 00 02 04 13 00 +T 86 0B 00 00 +R 00 00 01 00 +T 86 0B 00 00 CD 00 00 00 00 21 01 00 E5 21 +R 00 00 01 00 02 05 20 00 +T 8E 0B 00 00 04 00 39 4D 44 11 02 00 3E +R 00 00 01 00 +T 97 0B 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 09 00 02 09 09 00 +T 9C 0B 00 00 00 00 00 00 F1 C3 00 00 00 00 +R 00 00 01 00 02 04 21 00 02 0A 13 00 T A2 0B 00 00 R 00 00 01 00 -T A2 0B 00 00 DD 6E FE DD 66 FF C3 00 00 00 00 -R 00 00 01 00 02 0B 12 00 -T AB 0B 00 00 +T A2 0B 00 00 CD 00 00 00 00 01 00 00 3E +R 00 00 01 00 02 05 20 00 +T A9 0B 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T AE 0B 00 00 00 00 00 00 EB 3E DA 09 00 00 21 +R 00 00 01 00 02 04 21 00 29 0A 01 00 +T B4 0B 00 00 DA 09 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 02 09 21 00 +T BA 0B 00 00 00 00 00 00 +R 00 00 01 00 02 04 13 00 +T BC 0B 00 00 +R 00 00 01 00 +T BC 0B 00 00 CD 00 00 00 00 4B 42 21 02 00 CD +R 00 00 01 00 02 05 20 00 +T C5 0B 00 00 00 00 00 00 30 0E +R 00 00 01 00 02 04 2E 00 +T C9 0B 00 00 +R 00 00 01 00 +T C9 0B 00 00 DD 5E 02 DD 56 03 3E 00 00 00 00 +R 00 00 01 00 2B 0B 16 00 +T D1 0B 00 00 21 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 16 00 02 0A 21 00 +T D7 0B 00 00 +R 00 00 01 00 +T D7 0B 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T DA 0B 00 00 +R 00 00 01 00 +T DA 0B 00 00 CD 00 00 00 00 FE FF DD 36 FE 0A +R 00 00 01 00 02 05 28 00 +T E3 0B 00 00 DD 36 FF 00 +R 00 00 01 00 +T E7 0B 00 00 +R 00 00 01 00 +T E7 0B 00 00 01 14 80 DD 6E FE DD 66 FF 3E 80 +R 00 00 01 00 +T F2 0B 00 00 AC 67 ED 42 30 18 +R 00 00 01 00 +T F8 0B 00 00 +R 00 00 01 00 +T F8 0B 00 00 DD 5E FE DD 56 FF 13 DD 73 FE DD +R 00 00 01 00 +T 03 0C 00 00 72 FF 1B 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 16 00 +T 09 0C 00 00 00 00 00 00 CD 00 00 00 00 18 D7 +R 00 00 01 00 02 04 16 00 02 09 21 00 +T 10 0C 00 00 +R 00 00 01 00 +T 10 0C 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T 13 0C 00 00 +R 00 00 01 00 +T 13 0C 00 00 CD 00 00 00 00 D6 FF ED 4B +R 00 00 01 00 02 05 28 00 +T 1A 0C 00 00 08 00 00 00 DD 6E 02 DD 66 03 CD +R 00 00 01 00 02 04 07 00 +T 23 0C 00 00 00 00 00 00 D2 F0 0C 00 00 +R 00 00 01 00 02 04 2E 00 00 09 01 00 +T 28 0C 00 00 +R 00 00 01 00 +T 28 0C 00 00 AF DD 77 D6 DD 77 D7 R 00 00 01 00 -T AB 0B 00 00 CD 00 00 00 00 7B B2 28 2C -R 00 00 01 00 02 05 1D 00 -T B2 0B 00 00 +T 2F 0C 00 00 R 00 00 01 00 -T B2 0B 00 00 DD 6E 02 DD 66 03 4D 44 03 03 DD +T 2F 0C 00 00 01 14 80 DD 6E D6 DD 66 D7 3E 80 R 00 00 01 00 -T BD 0B 00 00 71 02 DD 70 03 5E 23 56 3E +T 3A 0C 00 00 AC 67 ED 42 30 1E R 00 00 01 00 -T C6 0B 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 14 00 02 09 14 00 -T CB 0B 00 00 00 00 00 00 DD 6E 02 DD 66 03 5E -R 00 00 01 00 02 04 1E 00 -T D4 0B 00 00 23 56 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 14 00 -T D9 0B 00 00 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 04 14 00 02 09 1E 00 -T DE 0B 00 00 +T 40 0C 00 00 R 00 00 01 00 -T DE 0B 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T E1 0B 00 00 +T 40 0C 00 00 DD 6E D6 DD 66 D7 29 E5 21 04 00 R 00 00 01 00 -T E1 0B 00 00 CD 00 00 00 00 FC FF 11 08 00 3E -R 00 00 01 00 02 05 24 00 -T EA 0B 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0A 00 02 09 0A 00 -T EF 0B 00 00 00 00 00 00 DD 75 FC DD 74 FD 7D -R 00 00 01 00 02 04 1E 00 -T F8 0B 00 00 B4 20 03 +T 4B 0C 00 00 39 4D 44 E1 09 AF 77 23 77 DD 34 +R 00 00 01 00 +T 56 0C 00 00 D6 20 03 DD 34 D7 +R 00 00 01 00 +T 5C 0C 00 00 R 00 00 01 00 -T FB 0B 00 00 +T 5C 0C 00 00 18 D1 R 00 00 01 00 -T FB 0B 00 00 C3 25 0D 00 00 +T 5E 0C 00 00 +R 00 00 01 00 +T 5E 0C 00 00 +R 00 00 01 00 +T 5E 0C 00 00 DD 6E 02 DD 66 03 29 E5 21 04 00 +R 00 00 01 00 +T 69 0C 00 00 39 4D 44 E1 09 36 01 23 36 00 DD +R 00 00 01 00 +T 74 0C 00 00 5E 02 DD 56 03 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 08 00 +T 7C 0C 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 08 00 02 09 21 00 +T 83 0C 00 00 02 DD 74 03 CB 7C 20 0F ED 4B +R 00 00 01 00 +T 8D 0C 00 00 08 00 00 00 DD 6E 02 DD 66 03 CD +R 00 00 01 00 02 04 07 00 +T 96 0C 00 00 00 00 00 00 38 C4 +R 00 00 01 00 02 04 2E 00 +T 9A 0C 00 00 +R 00 00 01 00 +T 9A 0C 00 00 AF DD 77 D6 DD 77 D7 +R 00 00 01 00 +T A1 0C 00 00 +R 00 00 01 00 +T A1 0C 00 00 01 14 80 DD 6E D6 DD 66 D7 3E 80 +R 00 00 01 00 +T AC 0C 00 00 AC 67 ED 42 30 2D +R 00 00 01 00 +T B2 0C 00 00 +R 00 00 01 00 +T B2 0C 00 00 DD 6E D6 DD 66 D7 29 E5 21 04 00 +R 00 00 01 00 +T BD 0C 00 00 39 4D 44 E1 09 7E 23 B6 28 0E +R 00 00 01 00 +T C7 0C 00 00 +R 00 00 01 00 +T C7 0C 00 00 DD 5E D6 DD 56 D7 3E 00 00 00 00 +R 00 00 01 00 2B 0B 16 00 +T CF 0C 00 00 21 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 16 00 02 0A 21 00 +T D5 0C 00 00 +R 00 00 01 00 +T D5 0C 00 00 DD 34 D6 20 03 DD 34 D7 +R 00 00 01 00 +T DD 0C 00 00 +R 00 00 01 00 +T DD 0C 00 00 18 C2 +R 00 00 01 00 +T DF 0C 00 00 +R 00 00 01 00 +T DF 0C 00 00 DD CB 03 7E 28 0B +R 00 00 01 00 +T E5 0C 00 00 +R 00 00 01 00 +T E5 0C 00 00 11 56 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 02 00 2B 0A 06 00 +T EB 0C 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 06 00 02 09 21 00 +T F0 0C 00 00 +R 00 00 01 00 +T F0 0C 00 00 +R 00 00 01 00 +T F0 0C 00 00 DD 6E 02 DD 66 03 C3 00 00 00 00 +R 00 00 01 00 02 0B 13 00 +T F9 0C 00 00 +R 00 00 01 00 +T F9 0C 00 00 CD 00 00 00 00 FE FF DD 5E 02 DD +R 00 00 01 00 02 05 28 00 +T 02 0D 00 00 56 03 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 2C 00 +T 07 0D 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 2C 00 02 09 21 00 +T 0E 0D 00 00 FE DD 74 FF CB 7C 28 0B +R 00 00 01 00 +T 16 0D 00 00 +R 00 00 01 00 +T 16 0D 00 00 11 73 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 02 00 2B 0A 06 00 +T 1C 0D 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 06 00 02 09 21 00 +T 21 0D 00 00 +R 00 00 01 00 +T 21 0D 00 00 DD 6E FE DD 66 FF C3 00 00 00 00 +R 00 00 01 00 02 0B 13 00 +T 2A 0D 00 00 +R 00 00 01 00 +T 2A 0D 00 00 CD 00 00 00 00 7B B2 28 2C +R 00 00 01 00 02 05 20 00 +T 31 0D 00 00 +R 00 00 01 00 +T 31 0D 00 00 DD 6E 02 DD 66 03 4D 44 03 03 DD +R 00 00 01 00 +T 3C 0D 00 00 71 02 DD 70 03 5E 23 56 3E +R 00 00 01 00 +T 45 0D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 16 00 02 09 16 00 +T 4A 0D 00 00 00 00 00 00 DD 6E 02 DD 66 03 5E +R 00 00 01 00 02 04 21 00 +T 53 0D 00 00 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 16 00 +T 58 0D 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 16 00 02 09 21 00 +T 5D 0D 00 00 +R 00 00 01 00 +T 5D 0D 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T 60 0D 00 00 +R 00 00 01 00 +T 60 0D 00 00 CD 00 00 00 00 FC FF 11 08 00 3E +R 00 00 01 00 02 05 28 00 +T 69 0D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +T 6E 0D 00 00 00 00 00 00 DD 75 FC DD 74 FD 7D +R 00 00 01 00 02 04 21 00 +T 77 0D 00 00 B4 20 03 +R 00 00 01 00 +T 7A 0D 00 00 +R 00 00 01 00 +T 7A 0D 00 00 C3 A4 0E 00 00 R 00 00 01 00 00 05 01 00 -T FE 0B 00 00 +T 7D 0D 00 00 R 00 00 01 00 -T FE 0B 00 00 01 01 00 DD 5E 02 DD 56 03 3E +T 7D 0D 00 00 01 01 00 DD 5E 02 DD 56 03 3E R 00 00 01 00 -T 08 0C 00 00 00 00 00 00 21 00 00 00 00 CD +T 87 0D 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 00 00 02 09 00 00 -T 0D 0C 00 00 00 00 00 00 E5 DD 6E FC DD 66 FD -R 00 00 01 00 02 04 1E 00 -T 16 0C 00 00 C1 71 23 70 DD 6E FC DD 66 FD 7E +T 8C 0D 00 00 00 00 00 00 E5 DD 6E FC DD 66 FD +R 00 00 01 00 02 04 21 00 +T 95 0D 00 00 C1 71 23 70 DD 6E FC DD 66 FD 7E R 00 00 01 00 -T 21 0C 00 00 23 B6 20 03 +T A0 0D 00 00 23 B6 20 03 R 00 00 01 00 -T 25 0C 00 00 +T A4 0D 00 00 R 00 00 01 00 -T 25 0C 00 00 C3 25 0D 00 00 +T A4 0D 00 00 C3 A4 0E 00 00 R 00 00 01 00 00 05 01 00 -T 28 0C 00 00 +T A7 0D 00 00 R 00 00 01 00 -T 28 0C 00 00 21 04 00 DD 4E FC DD 46 FD 09 DD +T A7 0D 00 00 21 04 00 DD 4E FC DD 46 FD 09 DD R 00 00 01 00 -T 33 0C 00 00 5E 04 DD 56 05 73 23 72 21 04 00 +T B2 0D 00 00 5E 04 DD 56 05 73 23 72 21 04 00 R 00 00 01 00 -T 3E 0C 00 00 19 AF 77 23 77 21 06 00 09 AF 77 +T BD 0D 00 00 19 AF 77 23 77 21 06 00 09 AF 77 R 00 00 01 00 -T 49 0C 00 00 23 77 2A 00 00 00 00 7D B4 20 0B +T C8 0D 00 00 23 77 2A 00 00 00 00 7D B4 20 0B R 00 00 01 00 00 07 03 00 -T 52 0C 00 00 +T D1 0D 00 00 R 00 00 01 00 -T 52 0C 00 00 DD 6E FC DD 66 FD 22 00 00 00 00 +T D1 0D 00 00 DD 6E FC DD 66 FD 22 00 00 00 00 R 00 00 01 00 00 0B 03 00 -T 5B 0C 00 00 18 4B +T DA 0D 00 00 18 4B R 00 00 01 00 -T 5D 0C 00 00 +T DC 0D 00 00 R 00 00 01 00 -T 5D 0C 00 00 2A 00 00 00 00 DD 75 FE DD 74 FF +T DC 0D 00 00 2A 00 00 00 00 DD 75 FE DD 74 FF R 00 00 01 00 00 05 03 00 -T 66 0C 00 00 +T E5 0D 00 00 R 00 00 01 00 -T 66 0C 00 00 DD 7E FE DD B6 FF 28 3A +T E5 0D 00 00 DD 7E FE DD B6 FF 28 3A R 00 00 01 00 -T 6E 0C 00 00 +T ED 0D 00 00 R 00 00 01 00 -T 6E 0C 00 00 21 06 00 DD 4E FE DD 46 FF 09 7E +T ED 0D 00 00 21 06 00 DD 4E FE DD 46 FF 09 7E R 00 00 01 00 -T 79 0C 00 00 23 B6 20 15 +T F8 0D 00 00 23 B6 20 15 R 00 00 01 00 -T 7D 0C 00 00 +T FC 0D 00 00 R 00 00 01 00 -T 7D 0C 00 00 21 06 00 DD 4E FE DD 46 FF 09 DD +T FC 0D 00 00 21 06 00 DD 4E FE DD 46 FF 09 DD R 00 00 01 00 -T 88 0C 00 00 4E FC DD 46 FD 71 23 70 18 16 +T 07 0E 00 00 4E FC DD 46 FD 71 23 70 18 16 R 00 00 01 00 -T 92 0C 00 00 +T 11 0E 00 00 R 00 00 01 00 -T 92 0C 00 00 21 06 00 DD 4E FE DD 46 FF 09 56 +T 11 0E 00 00 21 06 00 DD 4E FE DD 46 FF 09 56 R 00 00 01 00 -T 9D 0C 00 00 23 66 6A DD 75 FE DD 74 FF 18 BE +T 1C 0E 00 00 23 66 6A DD 75 FE DD 74 FF 18 BE R 00 00 01 00 -T A8 0C 00 00 +T 27 0E 00 00 R 00 00 01 00 -T A8 0C 00 00 +T 27 0E 00 00 R 00 00 01 00 -T A8 0C 00 00 DD 6E 04 DD 66 05 23 23 7E F6 12 +T 27 0E 00 00 DD 6E 04 DD 66 05 23 23 7E F6 12 R 00 00 01 00 -T B3 0C 00 00 77 23 7E F6 00 77 DD 6E FC DD 66 +T 32 0E 00 00 77 23 7E F6 00 77 DD 6E FC DD 66 R 00 00 01 00 -T BE 0C 00 00 FD 46 23 66 68 DD 75 02 DD 74 03 +T 3D 0E 00 00 FD 46 23 66 68 DD 75 02 DD 74 03 R 00 00 01 00 -T C9 0C 00 00 +T 48 0E 00 00 R 00 00 01 00 -T C9 0C 00 00 DD 6E 02 DD 66 03 AF B6 28 30 +T 48 0E 00 00 DD 6E 02 DD 66 03 AF B6 28 30 R 00 00 01 00 -T D3 0C 00 00 +T 52 0E 00 00 R 00 00 01 00 -T D3 0C 00 00 DD 6E 02 DD 66 03 7E E6 80 28 1B +T 52 0E 00 00 DD 6E 02 DD 66 03 7E E6 80 28 1B R 00 00 01 00 -T DE 0C 00 00 +T 5D 0E 00 00 R 00 00 01 00 -T DE 0C 00 00 DD 6E 04 DD 66 05 23 23 7E E6 EF +T 5D 0E 00 00 DD 6E 04 DD 66 05 23 23 7E E6 EF R 00 00 01 00 -T E9 0C 00 00 77 23 7E E6 FF 77 DD 6E 02 DD 66 +T 68 0E 00 00 77 23 7E E6 FF 77 DD 6E 02 DD 66 R 00 00 01 00 -T F4 0C 00 00 03 7E E6 7F 77 +T 73 0E 00 00 03 7E E6 7F 77 R 00 00 01 00 -T F9 0C 00 00 +T 78 0E 00 00 R 00 00 01 00 -T F9 0C 00 00 DD 34 02 20 03 DD 34 03 +T 78 0E 00 00 DD 34 02 20 03 DD 34 03 R 00 00 01 00 -T 01 0D 00 00 +T 80 0E 00 00 R 00 00 01 00 -T 01 0D 00 00 18 C6 +T 80 0E 00 00 18 C6 R 00 00 01 00 -T 03 0D 00 00 +T 82 0E 00 00 R 00 00 01 00 -T 03 0D 00 00 DD 6E FC DD 66 FD 23 23 E5 DD 4E +T 82 0E 00 00 DD 6E FC DD 66 FD 23 23 E5 DD 4E R 00 00 01 00 -T 0E 0D 00 00 04 DD 46 05 03 03 69 60 4E 23 46 +T 8D 0E 00 00 04 DD 46 05 03 03 69 60 4E 23 46 R 00 00 01 00 -T 19 0D 00 00 79 E6 10 5F 78 E6 00 57 E1 73 23 +T 98 0E 00 00 79 E6 10 5F 78 E6 00 57 E1 73 23 R 00 00 01 00 -T 24 0D 00 00 72 +T A3 0E 00 00 72 R 00 00 01 00 -T 25 0D 00 00 +T A4 0E 00 00 R 00 00 01 00 -T 25 0D 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T 28 0D 00 00 +T A4 0E 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T A7 0E 00 00 R 00 00 01 00 -T 28 0D 00 00 CD 00 00 00 00 FC FF 2A -R 00 00 01 00 02 05 24 00 -T 2E 0D 00 00 00 00 00 00 DD 75 FC DD 74 FD DD +T A7 0E 00 00 CD 00 00 00 00 FC FF 2A +R 00 00 01 00 02 05 28 00 +T AD 0E 00 00 00 00 00 00 DD 75 FC DD 74 FD DD R 00 00 01 00 00 04 03 00 -T 37 0D 00 00 75 FE DD 74 FF +T B6 0E 00 00 75 FE DD 74 FF R 00 00 01 00 -T 3C 0D 00 00 +T BB 0E 00 00 R 00 00 01 00 -T 3C 0D 00 00 DD 7E FC DD B6 FD 28 58 +T BB 0E 00 00 DD 7E FC DD B6 FD 28 58 R 00 00 01 00 -T 44 0D 00 00 +T C3 0E 00 00 R 00 00 01 00 -T 44 0D 00 00 DD 6E FC DD 66 FD 23 23 7E 23 B6 +T C3 0E 00 00 DD 6E FC DD 66 FD 23 23 7E 23 B6 R 00 00 01 00 -T 4F 0D 00 00 28 05 21 00 00 18 03 +T CE 0E 00 00 28 05 21 00 00 18 03 R 00 00 01 00 -T 56 0D 00 00 +T D5 0E 00 00 R 00 00 01 00 -T 56 0D 00 00 21 27 00 +T D5 0E 00 00 21 27 00 R 00 00 01 00 -T 59 0D 00 00 +T D8 0E 00 00 R 00 00 01 00 -T 59 0D 00 00 E5 DD 6E FC DD 66 FD 4E 23 46 21 +T D8 0E 00 00 E5 DD 6E FC DD 66 FD 4E 23 46 21 R 00 00 01 00 -T 64 0D 00 00 04 00 DD 5E FC DD 56 FD 19 7E 23 +T E3 0E 00 00 04 00 DD 5E FC DD 56 FD 19 7E 23 R 00 00 01 00 -T 6F 0D 00 00 66 6F 11 04 00 19 EB CD +T EE 0E 00 00 66 6F 11 04 00 19 EB CD R 00 00 01 00 -T 77 0D 00 00 C4 0D 00 00 E1 DD 6E FC DD 66 FD +T F6 0E 00 00 43 0F 00 00 E1 DD 6E FC DD 66 FD R 00 00 01 00 00 04 01 00 -T 80 0D 00 00 DD 75 FE DD 74 FF 21 06 00 DD 4E +T FF 0E 00 00 DD 75 FE DD 74 FF 21 06 00 DD 4E R 00 00 01 00 -T 8B 0D 00 00 FC DD 46 FD 09 56 23 66 6A DD 75 +T 0A 0F 00 00 FC DD 46 FD 09 56 23 66 6A DD 75 R 00 00 01 00 -T 96 0D 00 00 FC DD 74 FD 18 A0 +T 15 0F 00 00 FC DD 74 FD 18 A0 R 00 00 01 00 -T 9C 0D 00 00 +T 1B 0F 00 00 R 00 00 01 00 -T 9C 0D 00 00 DD 7E FE DD B6 FF 28 1D +T 1B 0F 00 00 DD 7E FE DD B6 FF 28 1D R 00 00 01 00 -T A4 0D 00 00 +T 23 0F 00 00 R 00 00 01 00 -T A4 0D 00 00 21 06 00 DD 4E FE DD 46 FF 09 ED +T 23 0F 00 00 21 06 00 DD 4E FE DD 46 FF 09 ED R 00 00 01 00 -T AF 0D 00 00 4B 02 00 00 00 71 23 70 2A +T 2E 0F 00 00 4B 02 00 00 00 71 23 70 2A R 00 00 01 00 00 05 03 00 -T B6 0D 00 00 00 00 00 00 22 02 00 00 00 21 +T 35 0F 00 00 00 00 00 00 22 02 00 00 00 21 R 00 00 01 00 00 04 03 00 00 09 03 00 -T BC 0D 00 00 00 00 22 00 00 00 00 +T 3B 0F 00 00 00 00 22 00 00 00 00 R 00 00 01 00 00 07 03 00 -T C1 0D 00 00 +T 40 0F 00 00 R 00 00 01 00 -T C1 0D 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T C4 0D 00 00 +T 40 0F 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T 43 0F 00 00 R 00 00 01 00 -T C4 0D 00 00 CD 00 00 00 00 9C F7 21 02 00 39 -R 00 00 01 00 02 05 24 00 -T CD 0D 00 00 5D 54 3E 46 12 00 00 21 +T 43 0F 00 00 CD 00 00 00 00 9C F7 21 02 00 39 +R 00 00 01 00 02 05 28 00 +T 4C 0F 00 00 5D 54 3E C5 13 00 00 21 R 00 00 01 00 29 07 01 00 -T D2 0D 00 00 46 12 00 00 CD 00 00 00 00 ED 4B -R 00 00 01 00 00 04 01 00 02 09 1E 00 -T D9 0D 00 00 00 00 00 00 21 02 00 39 5D 54 3E -R 00 00 01 00 02 04 22 00 -T E2 0D 00 00 00 00 00 00 21 00 00 00 00 CD +T 51 0F 00 00 C5 13 00 00 CD 00 00 00 00 ED 4B +R 00 00 01 00 00 04 01 00 02 09 21 00 +T 58 0F 00 00 00 00 00 00 21 02 00 39 5D 54 3E +R 00 00 01 00 02 04 26 00 +T 61 0F 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 04 00 02 09 04 00 -T E7 0D 00 00 00 00 00 00 E5 DD 6E 02 DD 66 03 -R 00 00 01 00 02 04 1E 00 -T F0 0D 00 00 C1 71 23 70 21 00 00 39 E5 01 +T 66 0F 00 00 00 00 00 00 E5 DD 6E 02 DD 66 03 +R 00 00 01 00 02 04 21 00 +T 6F 0F 00 00 C1 71 23 70 21 00 00 39 E5 01 R 00 00 01 00 -T FA 0D 00 00 80 01 21 04 00 39 5D 54 3E +T 79 0F 00 00 80 01 21 04 00 39 5D 54 3E R 00 00 01 00 -T 03 0E 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0D 00 02 09 0D 00 -T 08 0E 00 00 00 00 00 00 4D 44 E1 71 23 70 21 -R 00 00 01 00 02 04 1E 00 -T 11 0E 00 00 00 00 39 23 CB 7E 28 03 +T 82 0F 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0E 00 02 09 0E 00 +T 87 0F 00 00 00 00 00 00 4D 44 E1 71 23 70 21 +R 00 00 01 00 02 04 21 00 +T 90 0F 00 00 00 00 39 23 CB 7E 28 03 R 00 00 01 00 -T 19 0E 00 00 +T 98 0F 00 00 R 00 00 01 00 -T 19 0E 00 00 C3 B6 0F 00 00 +T 98 0F 00 00 C3 35 11 00 00 R 00 00 01 00 00 05 01 00 -T 1C 0E 00 00 -R 00 00 01 00 -T 1C 0E 00 00 21 22 00 39 22 00 00 00 00 EB 3E -R 00 00 01 00 02 09 27 00 -T 25 0E 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0F 00 02 09 0F 00 -T 2A 0E 00 00 00 00 00 00 EB 3E 00 00 00 00 21 -R 00 00 01 00 02 04 1E 00 2B 0A 10 00 -T 30 0E 00 00 00 00 00 00 CD 00 00 00 00 7D B4 -R 00 00 01 00 02 04 10 00 02 09 1E 00 -T 37 0E 00 00 28 11 -R 00 00 01 00 -T 39 0E 00 00 -R 00 00 01 00 -T 39 0E 00 00 21 02 00 39 5D 54 3E 00 00 00 00 -R 00 00 01 00 2B 0B 0E 00 -T 41 0E 00 00 21 00 00 00 00 CD 00 00 00 00 C3 -R 00 00 01 00 02 05 0E 00 02 0A 1E 00 -T 48 0E 00 00 A7 0F 00 00 +T 9B 0F 00 00 +R 00 00 01 00 +T 9B 0F 00 00 21 22 00 39 22 00 00 00 00 EB 3E +R 00 00 01 00 02 09 2B 00 +T A4 0F 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 10 00 02 09 10 00 +T A9 0F 00 00 00 00 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 02 04 21 00 2B 0A 11 00 +T AF 0F 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 02 04 11 00 02 09 21 00 +T B6 0F 00 00 28 11 +R 00 00 01 00 +T B8 0F 00 00 +R 00 00 01 00 +T B8 0F 00 00 21 02 00 39 5D 54 3E 00 00 00 00 +R 00 00 01 00 2B 0B 0F 00 +T C0 0F 00 00 21 00 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 02 05 0F 00 02 0A 21 00 +T C7 0F 00 00 26 11 00 00 R 00 00 01 00 00 04 01 00 -T 4A 0E 00 00 +T C9 0F 00 00 R 00 00 01 00 -T 4A 0E 00 00 2A 04 00 00 00 23 23 4E C5 2B 46 -R 00 00 01 00 02 05 06 00 -T 53 0E 00 00 2B 4E C5 2A 04 00 00 00 23 23 23 -R 00 00 01 00 02 08 06 00 -T 5C 0E 00 00 5E 23 56 3E 81 02 00 00 21 +T C9 0F 00 00 2A 04 00 00 00 23 23 4E C5 2B 46 +R 00 00 01 00 02 05 07 00 +T D2 0F 00 00 2B 4E C5 2A 04 00 00 00 23 23 23 +R 00 00 01 00 02 08 07 00 +T DB 0F 00 00 5E 23 56 3E 81 02 00 00 21 R 00 00 01 00 29 08 01 00 -T 62 0E 00 00 81 02 00 00 CD 00 00 00 00 E1 E1 -R 00 00 01 00 00 04 01 00 02 09 1E 00 -T 69 0E 00 00 2A 04 00 00 00 22 02 00 00 00 -R 00 00 01 00 02 05 06 00 02 0A 06 00 -T 6F 0E 00 00 -R 00 00 01 00 -T 6F 0E 00 00 2A 00 00 00 00 7D B4 28 1A ED 4B -R 00 00 01 00 02 05 23 00 -T 78 0E 00 00 04 00 00 00 21 00 00 00 00 A7 ED -R 00 00 01 00 02 04 06 00 02 09 29 00 -T 7F 0E 00 00 42 38 0E +T E1 0F 00 00 81 02 00 00 CD 00 00 00 00 E1 E1 +R 00 00 01 00 00 04 01 00 02 09 21 00 +T E8 0F 00 00 2A 04 00 00 00 22 02 00 00 00 +R 00 00 01 00 02 05 07 00 02 0A 07 00 +T EE 0F 00 00 R 00 00 01 00 -T 82 0E 00 00 +T EE 0F 00 00 2A 00 00 00 00 7D B4 28 1A ED 4B +R 00 00 01 00 02 05 27 00 +T F7 0F 00 00 04 00 00 00 21 00 00 00 00 A7 ED +R 00 00 01 00 02 04 07 00 02 09 2D 00 +T FE 0F 00 00 42 38 0E R 00 00 01 00 -T 82 0E 00 00 +T 01 10 00 00 R 00 00 01 00 -T 82 0E 00 00 +T 01 10 00 00 +R 00 00 01 00 +T 01 10 00 00 R 00 00 01 00 -T 82 0E 00 00 2A 00 00 00 00 5E 23 56 3E +T 01 10 00 00 2A 00 00 00 00 5E 23 56 3E R 00 00 01 00 02 05 01 00 -T 89 0E 00 00 DA 09 00 00 21 DA 09 00 00 CD +T 08 10 00 00 07 0A 00 00 21 07 0A 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T 8E 0E 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T 90 0E 00 00 +T 0D 10 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T 0F 10 00 00 R 00 00 01 00 -T 90 0E 00 00 21 2D 00 39 DD 75 FE DD 74 FF +T 0F 10 00 00 21 2D 00 39 DD 75 FE DD 74 FF R 00 00 01 00 -T 9A 0E 00 00 +T 19 10 00 00 R 00 00 01 00 -T 9A 0E 00 00 21 20 00 39 E5 DD 5E 08 DD 56 09 +T 19 10 00 00 21 20 00 39 E5 DD 5E 08 DD 56 09 R 00 00 01 00 -T A5 0E 00 00 3E 00 00 00 00 21 00 00 00 00 CD +T 24 10 00 00 3E 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 29 05 01 00 00 0A 01 00 -T AB 0E 00 00 00 00 00 00 4D 44 E1 71 23 70 3E -R 00 00 01 00 02 04 1E 00 -T B4 0E 00 00 0A A9 B0 28 55 21 20 00 39 7E 23 +T 2A 10 00 00 00 00 00 00 4D 44 E1 71 23 70 3E +R 00 00 01 00 02 04 21 00 +T 33 10 00 00 0A A9 B0 28 55 21 20 00 39 7E 23 R 00 00 01 00 -T BF 0E 00 00 B6 28 4C +T 3E 10 00 00 B6 28 4C R 00 00 01 00 -T C2 0E 00 00 +T 41 10 00 00 R 00 00 01 00 -T C2 0E 00 00 +T 41 10 00 00 R 00 00 01 00 -T C2 0E 00 00 +T 41 10 00 00 R 00 00 01 00 -T C2 0E 00 00 3E 27 DD AE 08 DD B6 09 20 0D +T 41 10 00 00 3E 27 DD AE 08 DD B6 09 20 0D R 00 00 01 00 -T CC 0E 00 00 +T 4B 10 00 00 R 00 00 01 00 -T CC 0E 00 00 21 20 00 39 7E E6 7F 77 23 7E E6 +T 4B 10 00 00 21 20 00 39 7E E6 7F 77 23 7E E6 R 00 00 01 00 -T D7 0E 00 00 FF 77 +T 56 10 00 00 FF 77 R 00 00 01 00 -T D9 0E 00 00 +T 58 10 00 00 R 00 00 01 00 -T D9 0E 00 00 21 2D 00 39 01 34 08 09 4D 44 DD +T 58 10 00 00 21 2D 00 39 01 34 08 09 4D 44 DD R 00 00 01 00 -T E4 0E 00 00 6E FE DD 66 FF A7 ED 42 38 0A +T 63 10 00 00 6E FE DD 66 FF A7 ED 42 38 0A R 00 00 01 00 -T EE 0E 00 00 +T 6D 10 00 00 R 00 00 01 00 -T EE 0E 00 00 21 20 00 39 AF 77 23 77 18 16 +T 6D 10 00 00 21 20 00 39 AF 77 23 77 18 16 R 00 00 01 00 -T F8 0E 00 00 +T 77 10 00 00 R 00 00 01 00 -T F8 0E 00 00 21 20 00 39 46 DD 6E FE DD 66 FF +T 77 10 00 00 21 20 00 39 46 DD 6E FE DD 66 FF R 00 00 01 00 -T 03 0F 00 00 23 DD 75 FE DD 74 FF 2B 70 18 8C +T 82 10 00 00 23 DD 75 FE DD 74 FF 2B 70 18 8C R 00 00 01 00 -T 0E 0F 00 00 +T 8D 10 00 00 R 00 00 01 00 -T 0E 0F 00 00 DD 6E FE DD 66 FF 36 00 21 2D 00 +T 8D 10 00 00 DD 6E FE DD 66 FF 36 00 21 2D 00 R 00 00 01 00 -T 19 0F 00 00 39 4D 44 DD 5E 04 DD 56 05 3E +T 98 10 00 00 39 4D 44 DD 5E 04 DD 56 05 3E R 00 00 01 00 -T 23 0F 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 16 00 02 09 16 00 -T 28 0F 00 00 00 00 00 00 7D B4 28 09 21 20 00 -R 00 00 01 00 02 04 1E 00 -T 31 0F 00 00 39 7E 23 B6 20 02 +T A2 10 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 19 00 02 09 19 00 +T A7 10 00 00 00 00 00 00 7D B4 28 09 21 20 00 +R 00 00 01 00 02 04 21 00 +T B0 10 00 00 39 7E 23 B6 20 02 R 00 00 01 00 -T 37 0F 00 00 +T B6 10 00 00 R 00 00 01 00 -T 37 0F 00 00 +T B6 10 00 00 R 00 00 01 00 -T 37 0F 00 00 +T B6 10 00 00 R 00 00 01 00 -T 37 0F 00 00 18 39 +T B6 10 00 00 18 39 R 00 00 01 00 -T 39 0F 00 00 +T B8 10 00 00 R 00 00 01 00 -T 39 0F 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T B8 10 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T 44 0F 00 00 74 FF 2B 36 0A 21 2D 00 39 4D 44 +T C3 10 00 00 74 FF 2B 36 0A 21 2D 00 39 4D 44 R 00 00 01 00 -T 4F 0F 00 00 DD 6E FE DD 66 FF A7 ED 42 E5 21 +T CE 10 00 00 DD 6E FE DD 66 FF A7 ED 42 E5 21 R 00 00 01 00 -T 5A 0F 00 00 2F 00 39 4D 44 21 02 00 39 5E 23 +T D9 10 00 00 2F 00 39 4D 44 21 02 00 39 5E 23 R 00 00 01 00 -T 65 0F 00 00 56 3E 00 00 00 00 21 00 00 00 00 -R 00 00 01 00 2B 06 08 00 02 0B 08 00 -T 6B 0F 00 00 CD 00 00 00 00 F1 C3 6F 0E 00 00 -R 00 00 01 00 02 05 1E 00 00 0B 01 00 -T 72 0F 00 00 +T E4 10 00 00 56 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 09 00 02 0B 09 00 +T EA 10 00 00 CD 00 00 00 00 F1 C3 EE 0F 00 00 +R 00 00 01 00 02 05 21 00 00 0B 01 00 +T F1 10 00 00 R 00 00 01 00 -T 72 0F 00 00 21 20 00 39 7E 23 B6 20 24 +T F1 10 00 00 21 20 00 39 7E 23 B6 20 24 R 00 00 01 00 -T 7B 0F 00 00 +T FA 10 00 00 R 00 00 01 00 -T 7B 0F 00 00 11 6D 00 00 00 3E DA 09 00 00 21 +T FA 10 00 00 11 91 00 00 00 3E DA 09 00 00 21 R 00 00 01 00 00 05 02 00 29 0A 01 00 -T 81 0F 00 00 DA 09 00 00 CD 00 00 00 00 DD 5E -R 00 00 01 00 00 04 01 00 02 09 1E 00 -T 88 0F 00 00 04 DD 56 05 3E DA 09 00 00 21 +T 00 11 00 00 DA 09 00 00 CD 00 00 00 00 DD 5E +R 00 00 01 00 00 04 01 00 02 09 21 00 +T 07 11 00 00 04 DD 56 05 3E DA 09 00 00 21 R 00 00 01 00 29 09 01 00 -T 8F 0F 00 00 DA 09 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 04 01 00 02 09 1E 00 -T 95 0F 00 00 7D 00 00 00 3E 00 00 00 00 21 -R 00 00 01 00 00 04 02 00 2B 09 05 00 -T 9A 0F 00 00 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 04 05 00 02 09 1E 00 -T 9F 0F 00 00 -R 00 00 01 00 -T 9F 0F 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 0B 00 02 0A 0B 00 -T A5 0F 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T A7 0F 00 00 +T 0E 11 00 00 DA 09 00 00 CD 00 00 00 00 11 +R 00 00 01 00 00 04 01 00 02 09 21 00 +T 14 11 00 00 A1 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 09 06 00 +T 19 11 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 06 00 02 09 21 00 +T 1E 11 00 00 +R 00 00 01 00 +T 1E 11 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 0C 00 02 0A 0C 00 +T 24 11 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T 26 11 00 00 R 00 00 01 00 -T A7 0F 00 00 21 00 00 39 5E 23 56 3E +T 26 11 00 00 21 00 00 39 5E 23 56 3E R 00 00 01 00 -T AF 0F 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 14 00 02 09 14 00 -T B4 0F 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T B6 0F 00 00 +T 2E 11 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 16 00 02 09 16 00 +T 33 11 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T 35 11 00 00 R 00 00 01 00 -T B6 0F 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 18 00 -T B9 0F 00 00 +T 35 11 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 1B 00 +T 38 11 00 00 R 00 00 01 00 -T B9 0F 00 00 CD 00 00 00 00 D2 FF DD 7E 02 DD -R 00 00 01 00 02 05 24 00 -T C2 0F 00 00 B6 03 20 06 +T 38 11 00 00 CD 00 00 00 00 D2 FF DD 7E 02 DD +R 00 00 01 00 02 05 28 00 +T 41 11 00 00 B6 03 20 06 R 00 00 01 00 -T C6 0F 00 00 +T 45 11 00 00 R 00 00 01 00 -T C6 0F 00 00 21 FF FF C3 01 11 00 00 +T 45 11 00 00 21 FF FF C3 80 12 00 00 R 00 00 01 00 00 08 01 00 -T CC 0F 00 00 +T 4B 11 00 00 R 00 00 01 00 -T CC 0F 00 00 21 00 00 E5 DD 6E 02 DD 66 03 E5 +T 4B 11 00 00 21 00 00 E5 DD 6E 02 DD 66 03 E5 R 00 00 01 00 -T D7 0F 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 2B 00 02 0A 2B 00 -T DD 0F 00 00 00 00 00 00 F1 F1 DD 75 D2 DD 74 -R 00 00 01 00 02 04 1E 00 -T E6 0F 00 00 D3 CB 7C 28 06 +T 56 11 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 2F 00 02 0A 2F 00 +T 5C 11 00 00 00 00 00 00 F1 F1 DD 75 D2 DD 74 +R 00 00 01 00 02 04 21 00 +T 65 11 00 00 D3 CB 7C 28 06 R 00 00 01 00 -T EB 0F 00 00 +T 6A 11 00 00 R 00 00 01 00 -T EB 0F 00 00 21 FF FF C3 01 11 00 00 +T 6A 11 00 00 21 FF FF C3 80 12 00 00 R 00 00 01 00 00 08 01 00 -T F1 0F 00 00 +T 70 11 00 00 R 00 00 01 00 -T F1 0F 00 00 DD 7E 04 DD B6 05 CA FB 10 00 00 +T 70 11 00 00 DD 7E 04 DD B6 05 CA 7A 12 00 00 R 00 00 01 00 00 0B 01 00 -T FA 0F 00 00 +T 79 11 00 00 R 00 00 01 00 -T FA 0F 00 00 21 05 00 39 5D 54 3E 46 12 00 00 +T 79 11 00 00 21 05 00 39 5D 54 3E C5 13 00 00 R 00 00 01 00 29 0B 01 00 -T 02 10 00 00 21 46 12 00 00 CD 00 00 00 00 01 -R 00 00 01 00 00 05 01 00 02 0A 1E 00 -T 09 10 00 00 80 01 21 05 00 39 5D 54 3E +T 81 11 00 00 21 C5 13 00 00 CD 00 00 00 00 01 +R 00 00 01 00 00 05 01 00 02 0A 21 00 +T 88 11 00 00 80 01 21 05 00 39 5D 54 3E R 00 00 01 00 -T 12 10 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0D 00 02 09 0D 00 -T 17 10 00 00 00 00 00 00 DD 75 D4 DD 74 D5 CB -R 00 00 01 00 02 04 1E 00 -T 20 10 00 00 7C 28 06 +T 91 11 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0E 00 02 09 0E 00 +T 96 11 00 00 00 00 00 00 DD 75 D4 DD 74 D5 CB +R 00 00 01 00 02 04 21 00 +T 9F 11 00 00 7C 28 06 R 00 00 01 00 -T 23 10 00 00 +T A2 11 00 00 R 00 00 01 00 -T 23 10 00 00 21 FF FF C3 01 11 00 00 +T A2 11 00 00 21 FF FF C3 80 12 00 00 R 00 00 01 00 00 08 01 00 -T 29 10 00 00 +T A8 11 00 00 R 00 00 01 00 -T 29 10 00 00 21 23 00 39 22 00 00 00 00 EB 3E -R 00 00 01 00 02 09 27 00 -T 32 10 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0F 00 02 09 0F 00 -T 37 10 00 00 00 00 00 00 EB 3E 00 00 00 00 21 -R 00 00 01 00 02 04 1E 00 2B 0A 10 00 -T 3D 10 00 00 00 00 00 00 CD 00 00 00 00 7D B4 -R 00 00 01 00 02 04 10 00 02 09 1E 00 -T 44 10 00 00 20 6A +T A8 11 00 00 21 23 00 39 22 00 00 00 00 EB 3E +R 00 00 01 00 02 09 2B 00 +T B1 11 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 10 00 02 09 10 00 +T B6 11 00 00 00 00 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 02 04 21 00 2B 0A 11 00 +T BC 11 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 02 04 11 00 02 09 21 00 +T C3 11 00 00 20 6A R 00 00 01 00 -T 46 10 00 00 +T C5 11 00 00 R 00 00 01 00 -T 46 10 00 00 DD 6E D2 DD 66 D3 22 12 04 00 00 +T C5 11 00 00 DD 6E D2 DD 66 D3 22 12 04 00 00 R 00 00 01 00 00 0B 04 00 -T 4F 10 00 00 0E 28 08 00 00 C5 21 28 08 00 00 +T CE 11 00 00 0E 28 08 00 00 C5 21 28 08 00 00 R 00 00 01 00 29 05 01 00 00 0B 01 00 -T 55 10 00 00 E5 11 0E 04 00 00 3E 81 02 00 00 +T D4 11 00 00 E5 11 0E 04 00 00 3E 81 02 00 00 R 00 00 01 00 00 06 04 00 29 0B 01 00 -T 5B 10 00 00 21 81 02 00 00 CD 00 00 00 00 E1 -R 00 00 01 00 00 05 01 00 02 0A 1E 00 -T 62 10 00 00 E1 ED 5B 04 00 00 00 3E -R 00 00 01 00 02 07 06 00 -T 68 10 00 00 60 04 00 00 21 60 04 00 00 CD +T DA 11 00 00 21 81 02 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 21 00 +T E1 11 00 00 E1 ED 5B 04 00 00 00 3E +R 00 00 01 00 02 07 07 00 +T E7 11 00 00 60 04 00 00 21 60 04 00 00 CD R 00 00 01 00 29 04 01 00 00 09 01 00 -T 6D 10 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T 6F 10 00 00 +T EC 11 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T EE 11 00 00 R 00 00 01 00 -T 6F 10 00 00 01 00 00 1E 00 3E 00 00 00 00 21 -R 00 00 01 00 2B 0A 26 00 -T 77 10 00 00 00 00 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 02 04 26 00 02 09 1E 00 -T 7E 10 00 00 D6 2C 2D 28 23 +T EE 11 00 00 01 00 00 1E 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 2A 00 +T F6 11 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 2A 00 02 09 21 00 +T FD 11 00 00 D6 2C 2D 28 23 R 00 00 01 00 -T 83 10 00 00 +T 02 12 00 00 R 00 00 01 00 -T 83 10 00 00 DD 7E D6 E6 7F DD 77 D6 21 01 00 +T 02 12 00 00 DD 7E D6 E6 7F DD 77 D6 21 01 00 R 00 00 01 00 -T 8E 10 00 00 E5 21 06 00 39 4D 44 DD 5E D4 DD +T 0D 12 00 00 E5 21 06 00 39 4D 44 DD 5E D4 DD R 00 00 01 00 -T 99 10 00 00 56 D5 3E 00 00 00 00 21 -R 00 00 01 00 2B 07 08 00 -T 9E 10 00 00 00 00 00 00 CD 00 00 00 00 F1 18 -R 00 00 01 00 02 04 08 00 02 09 1E 00 -T A5 10 00 00 C9 +T 18 12 00 00 56 D5 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 09 00 +T 1D 12 00 00 00 00 00 00 CD 00 00 00 00 F1 18 +R 00 00 01 00 02 04 09 00 02 09 21 00 +T 24 12 00 00 C9 R 00 00 01 00 -T A6 10 00 00 +T 25 12 00 00 R 00 00 01 00 -T A6 10 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 0B 00 02 0A 0B 00 -T AC 10 00 00 00 00 00 00 18 0E -R 00 00 01 00 02 04 1E 00 -T B0 10 00 00 -R 00 00 01 00 -T B0 10 00 00 21 05 00 39 5D 54 3E 00 00 00 00 -R 00 00 01 00 2B 0B 0E 00 -T B8 10 00 00 21 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 0E 00 02 0A 1E 00 -T BE 10 00 00 -R 00 00 01 00 -T BE 10 00 00 DD 5E D4 DD 56 D5 3E 00 00 00 00 -R 00 00 01 00 2B 0B 14 00 -T C6 10 00 00 21 00 00 00 00 CD 00 00 00 00 21 -R 00 00 01 00 02 05 14 00 02 0A 1E 00 -T CD 10 00 00 00 00 E5 21 07 00 39 E5 3E -R 00 00 01 00 -T D6 10 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 2B 00 02 09 2B 00 -T DB 10 00 00 00 00 00 00 F1 F1 DD 75 D4 DD 74 -R 00 00 01 00 02 04 1E 00 -T E4 10 00 00 D5 21 05 00 39 5D 54 3E +T 25 12 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 0C 00 02 0A 0C 00 +T 2B 12 00 00 00 00 00 00 18 0E +R 00 00 01 00 02 04 21 00 +T 2F 12 00 00 +R 00 00 01 00 +T 2F 12 00 00 21 05 00 39 5D 54 3E 00 00 00 00 +R 00 00 01 00 2B 0B 0F 00 +T 37 12 00 00 21 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 0F 00 02 0A 21 00 +T 3D 12 00 00 +R 00 00 01 00 +T 3D 12 00 00 DD 5E D4 DD 56 D5 3E 00 00 00 00 +R 00 00 01 00 2B 0B 16 00 +T 45 12 00 00 21 00 00 00 00 CD 00 00 00 00 21 +R 00 00 01 00 02 05 16 00 02 0A 21 00 +T 4C 12 00 00 00 00 E5 21 07 00 39 E5 3E +R 00 00 01 00 +T 55 12 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 2F 00 02 09 2F 00 +T 5A 12 00 00 00 00 00 00 F1 F1 DD 75 D4 DD 74 +R 00 00 01 00 02 04 21 00 +T 63 12 00 00 D5 21 05 00 39 5D 54 3E R 00 00 01 00 -T EC 10 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0E 00 02 09 0E 00 -T F1 10 00 00 00 00 00 00 DD 6E D4 DD 66 D5 18 -R 00 00 01 00 02 04 1E 00 -T FA 10 00 00 06 +T 6B 12 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0F 00 02 09 0F 00 +T 70 12 00 00 00 00 00 00 DD 6E D4 DD 66 D5 18 +R 00 00 01 00 02 04 21 00 +T 79 12 00 00 06 R 00 00 01 00 -T FB 10 00 00 +T 7A 12 00 00 R 00 00 01 00 -T FB 10 00 00 DD 6E D2 DD 66 D3 +T 7A 12 00 00 DD 6E D2 DD 66 D3 R 00 00 01 00 -T 01 11 00 00 +T 80 12 00 00 R 00 00 01 00 -T 01 11 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T 04 11 00 00 +T 80 12 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T 83 12 00 00 R 00 00 01 00 -T 04 11 00 00 CD 00 00 00 00 FE FF 2A -R 00 00 01 00 02 05 24 00 -T 0A 11 00 00 00 00 00 00 DD 75 FE DD 74 FF +T 83 12 00 00 CD 00 00 00 00 FE FF 2A +R 00 00 01 00 02 05 28 00 +T 89 12 00 00 00 00 00 00 DD 75 FE DD 74 FF R 00 00 01 00 00 04 03 00 -T 12 11 00 00 +T 91 12 00 00 R 00 00 01 00 -T 12 11 00 00 DD 7E FE DD B6 FF 28 59 +T 91 12 00 00 DD 7E FE DD B6 FF 28 59 R 00 00 01 00 -T 1A 11 00 00 +T 99 12 00 00 R 00 00 01 00 -T 1A 11 00 00 21 04 00 DD 4E FE DD 46 FF 09 7E +T 99 12 00 00 21 04 00 DD 4E FE DD 46 FF 09 7E R 00 00 01 00 -T 25 11 00 00 23 B6 28 34 21 04 00 DD 4E FE DD +T A4 12 00 00 23 B6 28 34 21 04 00 DD 4E FE DD R 00 00 01 00 -T 30 11 00 00 46 FF 09 46 23 66 68 01 04 00 09 +T AF 12 00 00 46 FF 09 46 23 66 68 01 04 00 09 R 00 00 01 00 -T 3B 11 00 00 7E 23 B6 28 1D +T BA 12 00 00 7E 23 B6 28 1D R 00 00 01 00 -T 40 11 00 00 +T BF 12 00 00 R 00 00 01 00 -T 40 11 00 00 +T BF 12 00 00 R 00 00 01 00 -T 40 11 00 00 +T BF 12 00 00 R 00 00 01 00 -T 40 11 00 00 21 04 00 DD 4E FE DD 46 FF 09 46 +T BF 12 00 00 21 04 00 DD 4E FE DD 46 FF 09 46 R 00 00 01 00 -T 4B 11 00 00 23 66 68 01 04 00 09 5E 23 56 3E +T CA 12 00 00 23 66 68 01 04 00 09 5E 23 56 3E R 00 00 01 00 -T 56 11 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0E 00 02 09 0E 00 -T 5B 11 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T 5D 11 00 00 +T D5 12 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0F 00 02 09 0F 00 +T DA 12 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T DC 12 00 00 R 00 00 01 00 -T 5D 11 00 00 21 06 00 DD 4E FE DD 46 FF 09 56 +T DC 12 00 00 21 06 00 DD 4E FE DD 46 FF 09 56 R 00 00 01 00 -T 68 11 00 00 23 66 6A DD 75 FE DD 74 FF 18 9F +T E7 12 00 00 23 66 6A DD 75 FE DD 74 FF 18 9F R 00 00 01 00 -T 73 11 00 00 +T F2 12 00 00 R 00 00 01 00 -T 73 11 00 00 21 00 00 22 00 00 00 00 C3 +T F2 12 00 00 21 00 00 22 00 00 00 00 C3 R 00 00 01 00 00 08 03 00 -T 7A 11 00 00 00 00 00 00 -R 00 00 01 00 02 04 12 00 -T 7C 11 00 00 +T F9 12 00 00 00 00 00 00 +R 00 00 01 00 02 04 13 00 +T FB 12 00 00 R 00 00 01 00 -T 7C 11 00 00 CD 00 00 00 00 FC FF AF DD 77 FE -R 00 00 01 00 02 05 24 00 -T 85 11 00 00 DD 77 FF 2A 02 00 00 00 DD 75 FC +T FB 12 00 00 CD 00 00 00 00 FC FF AF DD 77 FE +R 00 00 01 00 02 05 28 00 +T 04 13 00 00 DD 77 FF 2A 02 00 00 00 DD 75 FC R 00 00 01 00 00 08 03 00 -T 8E 11 00 00 DD 74 FD +T 0D 13 00 00 DD 74 FD R 00 00 01 00 -T 91 11 00 00 +T 10 13 00 00 R 00 00 01 00 -T 91 11 00 00 DD 7E FC DD B6 FD CA 43 12 00 00 +T 10 13 00 00 DD 7E FC DD B6 FD CA C2 13 00 00 R 00 00 01 00 00 0B 01 00 -T 9A 11 00 00 +T 19 13 00 00 R 00 00 01 00 -T 9A 11 00 00 DD 5E FC DD 56 FD 3E 00 00 00 00 -R 00 00 01 00 2B 0B 17 00 -T A2 11 00 00 21 00 00 00 00 CD 00 00 00 00 DD -R 00 00 01 00 02 05 17 00 02 0A 1E 00 -T A9 11 00 00 4E 02 DD 46 03 CD 00 00 00 00 38 -R 00 00 01 00 02 0A 2A 00 -T B2 11 00 00 6D +T 19 13 00 00 DD 5E FC DD 56 FD 3E 00 00 00 00 +R 00 00 01 00 2B 0B 1A 00 +T 21 13 00 00 21 00 00 00 00 CD 00 00 00 00 DD +R 00 00 01 00 02 05 1A 00 02 0A 21 00 +T 28 13 00 00 4E 02 DD 46 03 CD 00 00 00 00 38 +R 00 00 01 00 02 0A 2E 00 +T 31 13 00 00 6D R 00 00 01 00 -T B3 11 00 00 +T 32 13 00 00 R 00 00 01 00 -T B3 11 00 00 21 04 00 DD 4E FC DD 46 FD 09 46 +T 32 13 00 00 21 04 00 DD 4E FC DD 46 FD 09 46 R 00 00 01 00 -T BE 11 00 00 23 66 68 01 04 00 09 7E 23 B6 28 +T 3D 13 00 00 23 66 68 01 04 00 09 7E 23 B6 28 R 00 00 01 00 -T C9 11 00 00 1D +T 48 13 00 00 1D R 00 00 01 00 -T CA 11 00 00 +T 49 13 00 00 R 00 00 01 00 -T CA 11 00 00 21 04 00 DD 4E FC DD 46 FD 09 46 +T 49 13 00 00 21 04 00 DD 4E FC DD 46 FD 09 46 R 00 00 01 00 -T D5 11 00 00 23 66 68 01 04 00 09 5E 23 56 3E +T 54 13 00 00 23 66 68 01 04 00 09 5E 23 56 3E R 00 00 01 00 -T E0 11 00 00 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 04 0E 00 02 09 0E 00 -T E5 11 00 00 00 00 00 00 -R 00 00 01 00 02 04 1E 00 -T E7 11 00 00 +T 5F 13 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0F 00 02 09 0F 00 +T 64 13 00 00 00 00 00 00 +R 00 00 01 00 02 04 21 00 +T 66 13 00 00 R 00 00 01 00 -T E7 11 00 00 DD 7E FE DD B6 FF 20 13 +T 66 13 00 00 DD 7E FE DD B6 FF 20 13 R 00 00 01 00 -T EF 11 00 00 +T 6E 13 00 00 R 00 00 01 00 -T EF 11 00 00 21 06 00 DD 4E FC DD 46 FD 09 46 +T 6E 13 00 00 21 06 00 DD 4E FC DD 46 FD 09 46 R 00 00 01 00 -T FA 11 00 00 23 66 68 22 02 00 00 00 18 1C +T 79 13 00 00 23 66 68 22 02 00 00 00 18 1C R 00 00 01 00 00 08 03 00 -T 02 12 00 00 +T 81 13 00 00 R 00 00 01 00 -T 02 12 00 00 21 06 00 DD 4E FE DD 46 FF 09 E5 +T 81 13 00 00 21 06 00 DD 4E FE DD 46 FF 09 E5 R 00 00 01 00 -T 0D 12 00 00 21 06 00 DD 4E FC DD 46 FD 09 4E +T 8C 13 00 00 21 06 00 DD 4E FC DD 46 FD 09 4E R 00 00 01 00 -T 18 12 00 00 23 46 E1 71 23 70 +T 97 13 00 00 23 46 E1 71 23 70 R 00 00 01 00 -T 1E 12 00 00 +T 9D 13 00 00 R 00 00 01 00 -T 1E 12 00 00 18 0C +T 9D 13 00 00 18 0C R 00 00 01 00 -T 20 12 00 00 +T 9F 13 00 00 R 00 00 01 00 -T 20 12 00 00 DD 6E FC DD 66 FD DD 75 FE DD 74 +T 9F 13 00 00 DD 6E FC DD 66 FD DD 75 FE DD 74 R 00 00 01 00 -T 2B 12 00 00 FF +T AA 13 00 00 FF R 00 00 01 00 -T 2C 12 00 00 +T AB 13 00 00 R 00 00 01 00 -T 2C 12 00 00 21 06 00 DD 4E FC DD 46 FD 09 56 +T AB 13 00 00 21 06 00 DD 4E FC DD 46 FD 09 56 R 00 00 01 00 -T 37 12 00 00 23 66 6A DD 75 FC DD 74 FD C3 +T B6 13 00 00 23 66 6A DD 75 FC DD 74 FD C3 R 00 00 01 00 -T 41 12 00 00 91 11 00 00 +T C0 13 00 00 10 13 00 00 R 00 00 01 00 00 04 01 00 -T 43 12 00 00 +T C2 13 00 00 R 00 00 01 00 -T 43 12 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 -T 46 12 00 00 +T C2 13 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 +T C5 13 00 00 R 00 00 01 00 -T 46 12 00 00 CD 00 00 00 00 FC FF DD 6E 02 DD -R 00 00 01 00 02 05 24 00 -T 4F 12 00 00 66 03 DD 75 FC DD 74 FD DD 36 FE +T C5 13 00 00 CD 00 00 00 00 FC FF DD 6E 02 DD +R 00 00 01 00 02 05 28 00 +T CE 13 00 00 66 03 DD 75 FC DD 74 FD DD 36 FE R 00 00 01 00 -T 5A 12 00 00 88 00 00 00 DD 36 FF 88 00 00 00 +T D9 13 00 00 AC 00 00 00 DD 36 FF AC 00 00 00 R 00 00 01 00 09 04 02 00 89 0B 02 00 -T 5F 12 00 00 +T DE 13 00 00 R 00 00 01 00 -T 5F 12 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T DE 13 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T 6A 12 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 70 +T E9 13 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 70 R 00 00 01 00 -T 75 12 00 00 04 05 28 0A +T F4 13 00 00 04 05 28 0A R 00 00 01 00 -T 79 12 00 00 +T F8 13 00 00 R 00 00 01 00 -T 79 12 00 00 DD 34 FC 20 03 DD 34 FD +T F8 13 00 00 DD 34 FC 20 03 DD 34 FD R 00 00 01 00 -T 81 12 00 00 +T 00 14 00 00 R 00 00 01 00 -T 81 12 00 00 18 DC +T 00 14 00 00 18 DC R 00 00 01 00 -T 83 12 00 00 +T 02 14 00 00 R 00 00 01 00 -T 83 12 00 00 3E 00 00 00 00 21 00 00 00 00 CD -R 00 00 01 00 2B 05 2F 00 02 0A 2F 00 -T 89 12 00 00 00 00 00 00 4D 44 11 E8 03 CD -R 00 00 01 00 02 04 1E 00 -T 91 12 00 00 00 00 00 00 2A 04 00 00 00 23 22 -R 00 00 01 00 02 04 09 00 00 09 03 00 -T 98 12 00 00 04 00 00 00 2B 19 EB 3E +T 02 14 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 33 00 02 0A 33 00 +T 08 14 00 00 00 00 00 00 4D 44 11 E8 03 CD +R 00 00 01 00 02 04 21 00 +T 10 14 00 00 00 00 00 00 2A 04 00 00 00 23 22 +R 00 00 01 00 02 04 0A 00 00 09 03 00 +T 17 14 00 00 04 00 00 00 2B 19 EB 3E R 00 00 01 00 00 04 03 00 -T 9E 12 00 00 00 00 00 00 21 00 00 00 00 CD +T 1D 14 00 00 00 00 00 00 21 00 00 00 00 CD R 00 00 01 00 2B 04 03 00 02 09 03 00 -T A3 12 00 00 00 00 00 00 DD 75 FE DD 74 FF -R 00 00 01 00 02 04 1E 00 -T AB 12 00 00 +T 22 14 00 00 00 00 00 00 DD 75 FE DD 74 FF +R 00 00 01 00 02 04 21 00 +T 2A 14 00 00 R 00 00 01 00 -T AB 12 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T 2A 14 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T B6 12 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 70 +T 35 14 00 00 74 FF 2B 46 DD 6E FC DD 66 FD 70 R 00 00 01 00 -T C1 12 00 00 04 05 28 0A +T 40 14 00 00 04 05 28 0A R 00 00 01 00 -T C5 12 00 00 +T 44 14 00 00 R 00 00 01 00 -T C5 12 00 00 DD 34 FC 20 03 DD 34 FD +T 44 14 00 00 DD 34 FC 20 03 DD 34 FD R 00 00 01 00 -T CD 12 00 00 +T 4C 14 00 00 R 00 00 01 00 -T CD 12 00 00 18 DC +T 4C 14 00 00 18 DC R 00 00 01 00 -T CF 12 00 00 +T 4E 14 00 00 R 00 00 01 00 -T CF 12 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 12 00 +T 4E 14 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 13 00 T 00 00 00 00 R 00 00 02 00 T 00 00 00 00 69 6E 70 75 74 20 6C 69 6E 65 20 @@ -2059,33 +2239,57 @@ T 2A 00 00 00 20 64 65 65 70 6C 79 00 R 00 00 02 00 T 32 00 00 00 R 00 00 02 00 -T 32 00 00 00 74 6F 6F 20 6D 61 6E 79 20 66 69 +T 32 00 00 00 23 00 +R 00 00 02 00 +T 34 00 00 00 +R 00 00 02 00 +T 34 00 00 00 24 00 +R 00 00 02 00 +T 36 00 00 00 +R 00 00 02 00 +T 36 00 00 00 55 53 45 52 00 +R 00 00 02 00 +T 3B 00 00 00 +R 00 00 02 00 +T 3B 00 00 00 73 6F 6D 65 6F 6E 65 00 +R 00 00 02 00 +T 43 00 00 00 +R 00 00 02 00 +T 43 00 00 00 73 6F 6D 65 68 6F 73 74 00 +R 00 00 02 00 +T 4C 00 00 00 +R 00 00 02 00 +T 4C 00 00 00 73 6F 6D 65 77 68 65 72 65 00 +R 00 00 02 00 +T 56 00 00 00 +R 00 00 02 00 +T 56 00 00 00 74 6F 6F 20 6D 61 6E 79 20 66 69 R 00 00 02 00 -T 3D 00 00 00 6C 65 73 20 6F 70 65 6E 20 69 6E +T 61 00 00 00 6C 65 73 20 6F 70 65 6E 20 69 6E R 00 00 02 00 -T 48 00 00 00 20 73 68 65 6C 6C 00 +T 6C 00 00 00 20 73 68 65 6C 6C 00 R 00 00 02 00 -T 4F 00 00 00 +T 73 00 00 00 R 00 00 02 00 -T 4F 00 00 00 63 61 6E 27 74 20 63 72 65 61 74 +T 73 00 00 00 63 61 6E 27 74 20 63 72 65 61 74 R 00 00 02 00 -T 5A 00 00 00 65 20 70 69 70 65 20 2D 20 74 72 +T 7E 00 00 00 65 20 70 69 70 65 20 2D 20 74 72 R 00 00 02 00 -T 65 00 00 00 79 20 61 67 61 69 6E 00 +T 89 00 00 00 79 20 61 67 61 69 6E 00 R 00 00 02 00 -T 6D 00 00 00 +T 91 00 00 00 R 00 00 02 00 -T 6D 00 00 00 68 65 72 65 20 64 6F 63 75 6D 65 +T 91 00 00 00 68 65 72 65 20 64 6F 63 75 6D 65 R 00 00 02 00 -T 78 00 00 00 6E 74 20 60 00 +T 9C 00 00 00 6E 74 20 60 00 R 00 00 02 00 -T 7D 00 00 00 +T A1 00 00 00 R 00 00 02 00 -T 7D 00 00 00 27 20 75 6E 63 6C 6F 73 65 64 00 +T A1 00 00 00 27 20 75 6E 63 6C 6F 73 65 64 00 R 00 00 02 00 -T 88 00 00 00 +T AC 00 00 00 R 00 00 02 00 -T 88 00 00 00 2F 74 6D 70 2F 73 68 74 6D 00 +T AC 00 00 00 2F 74 6D 70 2F 73 68 74 6D 00 R 00 00 02 00 T 00 00 00 00 R 00 00 03 00 diff --git a/src/simple/align.c b/src/simple/align.c index 6ce97c17..ae3a45d4 100644 --- a/src/simple/align.c +++ b/src/simple/align.c @@ -14,6 +14,10 @@ #include #include +#ifndef DEBUG +#define DEBUG 0 +#endif + #if 0 void wr(char *s) { write(STDERR_FILENO, s, strlen(s)); @@ -107,7 +111,13 @@ int main(argc, argv) } else { +#if DEBUG > 0 + sysdebug(DEBUG); +#endif er = falign(fd, XIP_ALIGN); +#if DEBUG > 0 + sysdebug(0); +#endif close(fd); } if (er) diff --git a/src/simple/build-b.ban b/src/simple/build-b.ban index 9675ef8a..d7e66f02 100644 --- a/src/simple/build-b.ban +++ b/src/simple/build-b.ban @@ -1,4 +1,4 @@ -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\adduser +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\adduser @if errorlevel 1 goto failure del adduser.r01 as-z80 -l -o adduser.s01 @@ -9,7 +9,7 @@ link-z80 -f adduser ihex2bin -l adduser.i86 ..\..\..\bin\banked\adduser @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\align +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\align @if errorlevel 1 goto failure del align.r01 as-z80 -l -o align.s01 @@ -20,7 +20,7 @@ link-z80 -f align ihex2bin -l align.i86 ..\..\..\bin\banked\align @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\banner +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\banner @if errorlevel 1 goto failure del banner.r01 as-z80 -l -o banner.s01 @@ -31,7 +31,7 @@ link-z80 -f banner ihex2bin -l banner.i86 ..\..\..\bin\banked\banner @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\basename +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\basename @if errorlevel 1 goto failure del basename.r01 as-z80 -l -o basename.s01 @@ -43,7 +43,7 @@ ihex2bin -l basename.i86 ..\..\..\bin\banked\basename @if errorlevel 1 goto failure rem bogomips doesn't work under tc because too much use of z80 inline assembler -rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\bogomips +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\bogomips rem @if errorlevel 1 goto failure rem del bogomips.r01 rem as-z80 -l -o bogomips.s01 @@ -54,7 +54,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l bogomips.i86 ..\..\..\bin\banked\bogomips rem @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cal +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cal @if errorlevel 1 goto failure del cal.r01 as-z80 -l -o cal.s01 @@ -65,7 +65,7 @@ link-z80 -f cal ihex2bin -l cal.i86 ..\..\..\bin\banked\cal @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cat +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cat @if errorlevel 1 goto failure del cat.r01 as-z80 -l -o cat.s01 @@ -76,7 +76,7 @@ link-z80 -f cat ihex2bin -l cat.i86 ..\..\..\bin\banked\cat @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cdiff +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cdiff @if errorlevel 1 goto failure del cdiff.r01 as-z80 -l -o cdiff.s01 @@ -87,7 +87,7 @@ link-z80 -f cdiff ihex2bin -l cdiff.i86 ..\..\..\bin\banked\cdiff @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cgrep +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cgrep @if errorlevel 1 goto failure del cgrep.r01 as-z80 -l -o cgrep.s01 @@ -98,7 +98,7 @@ link-z80 -f cgrep ihex2bin -l cgrep.i86 ..\..\..\bin\banked\cgrep @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chgrp +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chgrp @if errorlevel 1 goto failure del chgrp.r01 as-z80 -l -o chgrp.s01 @@ -109,7 +109,7 @@ link-z80 -f chgrp ihex2bin -l chgrp.i86 ..\..\..\bin\banked\chgrp @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chmod +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chmod @if errorlevel 1 goto failure del chmod.r01 as-z80 -l -o chmod.s01 @@ -120,7 +120,7 @@ link-z80 -f chmod ihex2bin -l chmod.i86 ..\..\..\bin\banked\chmod @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chown +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chown @if errorlevel 1 goto failure del chown.r01 as-z80 -l -o chown.s01 @@ -131,7 +131,7 @@ link-z80 -f chown ihex2bin -l chown.i86 ..\..\..\bin\banked\chown @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cksum +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cksum @if errorlevel 1 goto failure del cksum.r01 as-z80 -l -o cksum.s01 @@ -142,7 +142,7 @@ link-z80 -f cksum ihex2bin -l cksum.i86 ..\..\..\bin\banked\cksum @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cmp +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cmp @if errorlevel 1 goto failure del cmp.r01 as-z80 -l -o cmp.s01 @@ -153,7 +153,7 @@ link-z80 -f cmp ihex2bin -l cmp.i86 ..\..\..\bin\banked\cmp @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cp +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 -DNDEBUG ..\cp @if errorlevel 1 goto failure del cp.r01 as-z80 -l -o cp.s01 @@ -164,7 +164,7 @@ link-z80 -f cp ihex2bin -l cp.i86 ..\..\..\bin\banked\cp @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cr +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cr @if errorlevel 1 goto failure del cr.r01 as-z80 -l -o cr.s01 @@ -175,7 +175,7 @@ link-z80 -f cr ihex2bin -l cr.i86 ..\..\..\bin\banked\cr @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\crc +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\crc @if errorlevel 1 goto failure del crc.r01 as-z80 -l -o crc.s01 @@ -186,7 +186,7 @@ link-z80 -f crc ihex2bin -l crc.i86 ..\..\..\bin\banked\crc @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cron +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cron @if errorlevel 1 goto failure del cron.r01 as-z80 -l -o cron.s01 @@ -197,7 +197,7 @@ link-z80 -f cron ihex2bin -l cron.i86 ..\..\..\bin\banked\cron @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\date +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\date @if errorlevel 1 goto failure del date.r01 as-z80 -l -o date.s01 @@ -208,7 +208,7 @@ link-z80 -f date ihex2bin -l date.i86 ..\..\..\bin\banked\date @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dd +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dd @if errorlevel 1 goto failure del dd.r01 as-z80 -l -o dd.s01 @@ -219,7 +219,7 @@ link-z80 -f dd ihex2bin -l dd.i86 ..\..\..\bin\banked\dd @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\df +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\df @if errorlevel 1 goto failure del df.r01 as-z80 -l -o df.s01 @@ -230,7 +230,7 @@ link-z80 -f df ihex2bin -l df.i86 ..\..\..\bin\banked\df @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dhry +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dhry @if errorlevel 1 goto failure del dhry.r01 as-z80 -l -o dhry.s01 @@ -241,7 +241,7 @@ link-z80 -f dhry ihex2bin -l dhry.i86 ..\..\..\bin\banked\dhry @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diff +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\diff @if errorlevel 1 goto failure del diff.r01 as-z80 -l -o diff.s01 @@ -252,7 +252,7 @@ link-z80 -f diff ihex2bin -l diff.i86 ..\..\..\bin\banked\diff @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dirname +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dirname @if errorlevel 1 goto failure del dirname.r01 as-z80 -l -o dirname.s01 @@ -263,7 +263,7 @@ link-z80 -f dirname ihex2bin -l dirname.i86 ..\..\..\bin\banked\dirname @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diskusag +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\diskusag @if errorlevel 1 goto failure del diskusag.r01 as-z80 -l -o diskusag.s01 @@ -275,7 +275,7 @@ ihex2bin -l diskusag.i86 ..\..\..\bin\banked\diskusag @if errorlevel 1 goto failure rem dosread is not necessary for the hytech system (no floppy drive) -rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dosread +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 -DNDEBUG ..\dosread rem @if errorlevel 1 goto failure rem del dosread.r01 rem as-z80 -l -o dosread.s01 @@ -286,7 +286,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l dosread.i86 ..\..\..\bin\banked\dosread rem @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dtree +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dtree @if errorlevel 1 goto failure del dtree.r01 as-z80 -l -o dtree.s01 @@ -297,7 +297,7 @@ link-z80 -f dtree ihex2bin -l dtree.i86 ..\..\..\bin\banked\dtree @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\du +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\du @if errorlevel 1 goto failure del du.r01 as-z80 -l -o du.s01 @@ -308,7 +308,7 @@ link-z80 -f du ihex2bin -l du.i86 ..\..\..\bin\banked\du @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\echo +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\echo @if errorlevel 1 goto failure del echo.r01 as-z80 -l -o echo.s01 @@ -319,7 +319,7 @@ link-z80 -f echo ihex2bin -l echo.i86 ..\..\..\bin\banked\echo @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ed +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ed @if errorlevel 1 goto failure del ed.r01 as-z80 -l -o ed.s01 @@ -330,7 +330,7 @@ link-z80 -f ed ihex2bin -l ed.i86 ..\..\..\bin\banked\ed @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\expr +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\expr @if errorlevel 1 goto failure del expr.r01 as-z80 -l -o expr.s01 @@ -341,7 +341,7 @@ link-z80 -f expr ihex2bin -l expr.i86 ..\..\..\bin\banked\expr @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\false +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\false @if errorlevel 1 goto failure del false.r01 as-z80 -l -o false.s01 @@ -352,7 +352,7 @@ link-z80 -f false ihex2bin -l false.i86 ..\..\..\bin\banked\false @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fgrep +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fgrep @if errorlevel 1 goto failure del fgrep.r01 as-z80 -l -o fgrep.s01 @@ -363,7 +363,7 @@ link-z80 -f fgrep ihex2bin -l fgrep.i86 ..\..\..\bin\banked\fgrep @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\file +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\file @if errorlevel 1 goto failure del file.r01 as-z80 -l -o file.s01 @@ -374,7 +374,7 @@ link-z80 -f file ihex2bin -l file.i86 ..\..\..\bin\banked\file @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\find +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\find @if errorlevel 1 goto failure del find.r01 as-z80 -l -o find.s01 @@ -385,7 +385,7 @@ link-z80 -f find ihex2bin -l find.i86 ..\..\..\bin\banked\find @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fld +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fld @if errorlevel 1 goto failure del fld.r01 as-z80 -l -o fld.s01 @@ -396,7 +396,7 @@ link-z80 -f fld ihex2bin -l fld.i86 ..\..\..\bin\banked\fld @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fortune +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fortune @if errorlevel 1 goto failure del fortune.r01 as-z80 -l -o fortune.s01 @@ -407,7 +407,7 @@ link-z80 -f fortune ihex2bin -l fortune.i86 ..\..\..\bin\banked\fortune @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\grep +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\grep @if errorlevel 1 goto failure del grep.r01 as-z80 -l -o grep.s01 @@ -418,7 +418,7 @@ link-z80 -f grep ihex2bin -l grep.i86 ..\..\..\bin\banked\grep @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\gres +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\gres @if errorlevel 1 goto failure del gres.r01 as-z80 -l -o gres.s01 @@ -429,7 +429,7 @@ link-z80 -f gres ihex2bin -l gres.i86 ..\..\..\bin\banked\gres @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\head +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\head @if errorlevel 1 goto failure del head.r01 as-z80 -l -o head.s01 @@ -440,7 +440,7 @@ link-z80 -f head ihex2bin -l head.i86 ..\..\..\bin\banked\head @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\id +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\id @if errorlevel 1 goto failure del id.r01 as-z80 -l -o id.s01 @@ -451,7 +451,7 @@ link-z80 -f id ihex2bin -l id.i86 ..\..\..\bin\banked\id @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\inodes +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\inodes @if errorlevel 1 goto failure del inodes.r01 as-z80 -l -o inodes.s01 @@ -462,7 +462,7 @@ link-z80 -f inodes ihex2bin -l inodes.i86 ..\..\..\bin\banked\inodes @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\kill +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\kill @if errorlevel 1 goto failure del kill.r01 as-z80 -l -o kill.s01 @@ -473,7 +473,7 @@ link-z80 -f kill ihex2bin -l kill.i86 ..\..\..\bin\banked\kill @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpd +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\lpd @if errorlevel 1 goto failure del lpd.r01 as-z80 -l -o lpd.s01 @@ -484,7 +484,7 @@ link-z80 -f lpd ihex2bin -l lpd.i86 ..\..\..\bin\banked\lpd @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpr +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\lpr @if errorlevel 1 goto failure del lpr.r01 as-z80 -l -o lpr.s01 @@ -495,7 +495,7 @@ link-z80 -f lpr ihex2bin -l lpr.i86 ..\..\..\bin\banked\lpr @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ls +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ls @if errorlevel 1 goto failure del ls.r01 as-z80 -l -o ls.s01 @@ -506,7 +506,7 @@ link-z80 -f ls ihex2bin -l ls.i86 ..\..\..\bin\banked\ls @if errorlevel 1 goto failure -rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\man +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\man rem @if errorlevel 1 goto failure rem del man.r01 rem as-z80 -l -o man.s01 @@ -517,7 +517,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l man.i86 ..\..\..\bin\banked\man rem @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mkdir +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mkdir @if errorlevel 1 goto failure del mkdir.r01 as-z80 -l -o mkdir.s01 @@ -528,7 +528,7 @@ link-z80 -f mkdir ihex2bin -l mkdir.i86 ..\..\..\bin\banked\mkdir @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mknod +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mknod @if errorlevel 1 goto failure del mknod.r01 as-z80 -l -o mknod.s01 @@ -539,7 +539,7 @@ link-z80 -f mknod ihex2bin -l mknod.i86 ..\..\..\bin\banked\mknod @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\more +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\more @if errorlevel 1 goto failure del more.r01 as-z80 -l -o more.s01 @@ -550,7 +550,7 @@ link-z80 -f more ihex2bin -l more.i86 ..\..\..\bin\banked\more @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mount +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mount @if errorlevel 1 goto failure del mount.r01 as-z80 -l -o mount.s01 @@ -561,7 +561,7 @@ link-z80 -f mount ihex2bin -l mount.i86 ..\..\..\bin\banked\mount @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncheck +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ncheck @if errorlevel 1 goto failure del ncheck.r01 as-z80 -l -o ncheck.s01 @@ -572,7 +572,7 @@ link-z80 -f ncheck ihex2bin -l ncheck.i86 ..\..\..\bin\banked\ncheck @if errorlevel 1 goto failure -rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncr +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ncr rem @if errorlevel 1 goto failure rem del ncr.r01 rem as-z80 -l -o ncr.s01 @@ -583,7 +583,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l ncr.i86 ..\..\..\bin\banked\ncr rem @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\od +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\od @if errorlevel 1 goto failure del od.r01 as-z80 -l -o od.s01 @@ -594,7 +594,7 @@ link-z80 -f od ihex2bin -l od.i86 ..\..\..\bin\banked\od @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\passwd +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\passwd @if errorlevel 1 goto failure del passwd.r01 as-z80 -l -o passwd.s01 @@ -605,7 +605,7 @@ link-z80 -f passwd ihex2bin -l passwd.i86 ..\..\..\bin\banked\passwd @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pathchk +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pathchk @if errorlevel 1 goto failure del pathchk.r01 as-z80 -l -o pathchk.s01 @@ -616,7 +616,7 @@ link-z80 -f pathchk ihex2bin -l pathchk.i86 ..\..\..\bin\banked\pathchk @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pr +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pr @if errorlevel 1 goto failure del pr.r01 as-z80 -l -o pr.s01 @@ -627,7 +627,7 @@ link-z80 -f pr ihex2bin -l pr.i86 ..\..\..\bin\banked\pr @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\printenv +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\printenv @if errorlevel 1 goto failure del printenv.r01 as-z80 -l -o printenv.s01 @@ -638,7 +638,7 @@ link-z80 -f printenv ihex2bin -l printenv.i86 ..\..\..\bin\banked\printenv @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ps +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ps @if errorlevel 1 goto failure del ps.r01 as-z80 -l -o ps.s01 @@ -649,7 +649,7 @@ link-z80 -f ps ihex2bin -l ps.i86 ..\..\..\bin\banked\ps @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pwd +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pwd @if errorlevel 1 goto failure del pwd.r01 as-z80 -l -o pwd.s01 @@ -660,7 +660,7 @@ link-z80 -f pwd ihex2bin -l pwd.i86 ..\..\..\bin\banked\pwd @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\readall +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\readall @if errorlevel 1 goto failure del readall.r01 as-z80 -l -o readall.s01 @@ -671,7 +671,7 @@ link-z80 -f readall ihex2bin -l readall.i86 ..\..\..\bin\banked\readall @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\reboot +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\reboot @if errorlevel 1 goto failure del reboot.r01 as-z80 -l -o reboot.s01 @@ -682,7 +682,7 @@ link-z80 -f reboot ihex2bin -l reboot.i86 ..\..\..\bin\banked\reboot @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\renice +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\renice @if errorlevel 1 goto failure del renice.r01 as-z80 -l -o renice.s01 @@ -693,7 +693,7 @@ link-z80 -f renice ihex2bin -l renice.i86 ..\..\..\bin\banked\renice @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rm +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\rm @if errorlevel 1 goto failure del rm.r01 as-z80 -l -o rm.s01 @@ -704,7 +704,7 @@ link-z80 -f rm ihex2bin -l rm.i86 ..\..\..\bin\banked\rm @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rmdir +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\rmdir @if errorlevel 1 goto failure del rmdir.r01 as-z80 -l -o rmdir.s01 @@ -715,7 +715,7 @@ link-z80 -f rmdir ihex2bin -l rmdir.i86 ..\..\..\bin\banked\rmdir @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\roff +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\roff @if errorlevel 1 goto failure del roff.r01 as-z80 -l -o roff.s01 @@ -726,7 +726,7 @@ link-z80 -f roff ihex2bin -l roff.i86 ..\..\..\bin\banked\roff @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\setclock +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\setclock @if errorlevel 1 goto failure del setclock.r01 as-z80 -l -o setclock.s01 @@ -737,7 +737,7 @@ link-z80 -f setclock ihex2bin -l setclock.i86 ..\..\..\bin\banked\setclock @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sort +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sort @if errorlevel 1 goto failure del sort.r01 as-z80 -l -o sort.s01 @@ -748,7 +748,7 @@ link-z80 -f sort ihex2bin -l sort.i86 ..\..\..\bin\banked\sort @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\split +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\split @if errorlevel 1 goto failure del split.r01 as-z80 -l -o split.s01 @@ -759,7 +759,7 @@ link-z80 -f split ihex2bin -l split.i86 ..\..\..\bin\banked\split @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\su +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\su @if errorlevel 1 goto failure del su.r01 as-z80 -l -o su.s01 @@ -770,7 +770,7 @@ link-z80 -f su ihex2bin -l su.i86 ..\..\..\bin\banked\su @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sum +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sum @if errorlevel 1 goto failure del sum.r01 as-z80 -l -o sum.s01 @@ -781,7 +781,7 @@ link-z80 -f sum ihex2bin -l sum.i86 ..\..\..\bin\banked\sum @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sync +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sync @if errorlevel 1 goto failure del sync.r01 as-z80 -l -o sync.s01 @@ -792,7 +792,7 @@ link-z80 -f sync ihex2bin -l sync.i86 ..\..\..\bin\banked\sync @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tail +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tail @if errorlevel 1 goto failure del tail.r01 as-z80 -l -o tail.s01 @@ -803,7 +803,7 @@ link-z80 -f tail ihex2bin -l tail.i86 ..\..\..\bin\banked\tail @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tar +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tar @if errorlevel 1 goto failure del tar.r01 as-z80 -l -o tar.s01 @@ -814,7 +814,7 @@ link-z80 -f tar ihex2bin -l tar.i86 ..\..\..\bin\banked\tar @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tee +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tee @if errorlevel 1 goto failure del tee.r01 as-z80 -l -o tee.s01 @@ -825,7 +825,7 @@ link-z80 -f tee ihex2bin -l tee.i86 ..\..\..\bin\banked\tee @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ter +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ter @if errorlevel 1 goto failure del ter.r01 as-z80 -l -o ter.s01 @@ -836,7 +836,7 @@ link-z80 -f ter ihex2bin -l ter.i86 ..\..\..\bin\banked\ter @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\termcap +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\termcap @if errorlevel 1 goto failure del termcap.r01 as-z80 -l -o termcap.s01 @@ -847,7 +847,7 @@ link-z80 -f termcap ihex2bin -l termcap.i86 ..\..\..\bin\banked\termcap @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\test +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\test @if errorlevel 1 goto failure del test.r01 as-z80 -l -o test.s01 @@ -858,7 +858,7 @@ link-z80 -f test ihex2bin -l test.i86 ..\..\..\bin\banked\test @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tget +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tget @if errorlevel 1 goto failure del tget.r01 as-z80 -l -o tget.s01 @@ -869,7 +869,7 @@ link-z80 -f tget ihex2bin -l tget.i86 ..\..\..\bin\banked\tget @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\time +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\time @if errorlevel 1 goto failure del time.r01 as-z80 -l -o time.s01 @@ -880,7 +880,7 @@ link-z80 -f time ihex2bin -l time.i86 ..\..\..\bin\banked\time @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\top +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\top @if errorlevel 1 goto failure del top.r01 as-z80 -l -o top.s01 @@ -891,7 +891,7 @@ link-z80 -f top ihex2bin -l top.i86 ..\..\..\bin\banked\top @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\touch +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\touch @if errorlevel 1 goto failure del touch.r01 as-z80 -l -o touch.s01 @@ -902,7 +902,7 @@ link-z80 -f touch ihex2bin -l touch.i86 ..\..\..\bin\banked\touch @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tr +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tr @if errorlevel 1 goto failure del tr.r01 as-z80 -l -o tr.s01 @@ -913,7 +913,7 @@ link-z80 -f tr ihex2bin -l tr.i86 ..\..\..\bin\banked\tr @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\true +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\true @if errorlevel 1 goto failure del true.r01 as-z80 -l -o true.s01 @@ -924,7 +924,7 @@ link-z80 -f true ihex2bin -l true.i86 ..\..\..\bin\banked\true @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ualign +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ualign @if errorlevel 1 goto failure del ualign.r01 as-z80 -l -o ualign.s01 @@ -935,7 +935,7 @@ link-z80 -f ualign ihex2bin -l ualign.i86 ..\..\..\bin\banked\ualign @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\umount +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\umount @if errorlevel 1 goto failure del umount.r01 as-z80 -l -o umount.s01 @@ -946,7 +946,7 @@ link-z80 -f umount ihex2bin -l umount.i86 ..\..\..\bin\banked\umount @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uname +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uname @if errorlevel 1 goto failure del uname.r01 as-z80 -l -o uname.s01 @@ -957,7 +957,7 @@ link-z80 -f uname ihex2bin -l uname.i86 ..\..\..\bin\banked\uname @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uniq +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uniq @if errorlevel 1 goto failure del uniq.r01 as-z80 -l -o uniq.s01 @@ -968,7 +968,7 @@ link-z80 -f uniq ihex2bin -l uniq.i86 ..\..\..\bin\banked\uniq @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uudecode +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uudecode @if errorlevel 1 goto failure del uudecode.r01 as-z80 -l -o uudecode.s01 @@ -979,7 +979,7 @@ link-z80 -f uudecode ihex2bin -l uudecode.i86 ..\..\..\bin\banked\uudecode @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uuencode +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uuencode @if errorlevel 1 goto failure del uuencode.r01 as-z80 -l -o uuencode.s01 @@ -990,7 +990,7 @@ link-z80 -f uuencode ihex2bin -l uuencode.i86 ..\..\..\bin\banked\uuencode @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\wc +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\wc @if errorlevel 1 goto failure del wc.r01 as-z80 -l -o wc.s01 @@ -1001,7 +1001,7 @@ link-z80 -f wc ihex2bin -l wc.i86 ..\..\..\bin\banked\wc @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\which +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\which @if errorlevel 1 goto failure del which.r01 as-z80 -l -o which.s01 @@ -1012,7 +1012,7 @@ link-z80 -f which ihex2bin -l which.i86 ..\..\..\bin\banked\which @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\whoami +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\whoami @if errorlevel 1 goto failure del whoami.r01 as-z80 -l -o whoami.s01 @@ -1023,7 +1023,7 @@ link-z80 -f whoami ihex2bin -l whoami.i86 ..\..\..\bin\banked\whoami @if errorlevel 1 goto failure -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\yes +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\yes @if errorlevel 1 goto failure del yes.r01 as-z80 -l -o yes.s01 diff --git a/src/simple/build-l.ban b/src/simple/build-l.ban index 2eef51d1..a1f3e4c4 100644 --- a/src/simple/build-l.ban +++ b/src/simple/build-l.ban @@ -1,4 +1,4 @@ -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\adduser +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\adduser @if errorlevel 1 goto failure del adduser.r01 as-z80 -l -o adduser.s01 @@ -9,7 +9,7 @@ link-z80 -f adduser ihex2bin -l adduser.i86 ..\..\..\bin\large\adduser @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\align +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\align @if errorlevel 1 goto failure del align.r01 as-z80 -l -o align.s01 @@ -20,7 +20,7 @@ link-z80 -f align ihex2bin -l align.i86 ..\..\..\bin\large\align @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\banner +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\banner @if errorlevel 1 goto failure del banner.r01 as-z80 -l -o banner.s01 @@ -31,7 +31,7 @@ link-z80 -f banner ihex2bin -l banner.i86 ..\..\..\bin\large\banner @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\basename +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\basename @if errorlevel 1 goto failure del basename.r01 as-z80 -l -o basename.s01 @@ -43,7 +43,7 @@ ihex2bin -l basename.i86 ..\..\..\bin\large\basename @if errorlevel 1 goto failure rem bogomips doesn't work under tc because too much use of z80 inline assembler -rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\bogomips +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\bogomips rem @if errorlevel 1 goto failure rem del bogomips.r01 rem as-z80 -l -o bogomips.s01 @@ -54,7 +54,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l bogomips.i86 ..\..\..\bin\large\bogomips rem @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cal +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cal @if errorlevel 1 goto failure del cal.r01 as-z80 -l -o cal.s01 @@ -65,7 +65,7 @@ link-z80 -f cal ihex2bin -l cal.i86 ..\..\..\bin\large\cal @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cat +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cat @if errorlevel 1 goto failure del cat.r01 as-z80 -l -o cat.s01 @@ -76,7 +76,7 @@ link-z80 -f cat ihex2bin -l cat.i86 ..\..\..\bin\large\cat @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cdiff +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cdiff @if errorlevel 1 goto failure del cdiff.r01 as-z80 -l -o cdiff.s01 @@ -87,7 +87,7 @@ link-z80 -f cdiff ihex2bin -l cdiff.i86 ..\..\..\bin\large\cdiff @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cgrep +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cgrep @if errorlevel 1 goto failure del cgrep.r01 as-z80 -l -o cgrep.s01 @@ -98,7 +98,7 @@ link-z80 -f cgrep ihex2bin -l cgrep.i86 ..\..\..\bin\large\cgrep @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chgrp +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chgrp @if errorlevel 1 goto failure del chgrp.r01 as-z80 -l -o chgrp.s01 @@ -109,7 +109,7 @@ link-z80 -f chgrp ihex2bin -l chgrp.i86 ..\..\..\bin\large\chgrp @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chmod +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chmod @if errorlevel 1 goto failure del chmod.r01 as-z80 -l -o chmod.s01 @@ -120,7 +120,7 @@ link-z80 -f chmod ihex2bin -l chmod.i86 ..\..\..\bin\large\chmod @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chown +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\chown @if errorlevel 1 goto failure del chown.r01 as-z80 -l -o chown.s01 @@ -131,7 +131,7 @@ link-z80 -f chown ihex2bin -l chown.i86 ..\..\..\bin\large\chown @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cksum +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cksum @if errorlevel 1 goto failure del cksum.r01 as-z80 -l -o cksum.s01 @@ -142,7 +142,7 @@ link-z80 -f cksum ihex2bin -l cksum.i86 ..\..\..\bin\large\cksum @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cmp +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cmp @if errorlevel 1 goto failure del cmp.r01 as-z80 -l -o cmp.s01 @@ -153,7 +153,7 @@ link-z80 -f cmp ihex2bin -l cmp.i86 ..\..\..\bin\large\cmp @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cp +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 -DNDEBUG ..\cp @if errorlevel 1 goto failure del cp.r01 as-z80 -l -o cp.s01 @@ -164,7 +164,7 @@ link-z80 -f cp ihex2bin -l cp.i86 ..\..\..\bin\large\cp @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cr +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cr @if errorlevel 1 goto failure del cr.r01 as-z80 -l -o cr.s01 @@ -175,7 +175,7 @@ link-z80 -f cr ihex2bin -l cr.i86 ..\..\..\bin\large\cr @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\crc +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\crc @if errorlevel 1 goto failure del crc.r01 as-z80 -l -o crc.s01 @@ -186,7 +186,7 @@ link-z80 -f crc ihex2bin -l crc.i86 ..\..\..\bin\large\crc @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cron +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\cron @if errorlevel 1 goto failure del cron.r01 as-z80 -l -o cron.s01 @@ -197,7 +197,7 @@ link-z80 -f cron ihex2bin -l cron.i86 ..\..\..\bin\large\cron @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\date +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\date @if errorlevel 1 goto failure del date.r01 as-z80 -l -o date.s01 @@ -208,7 +208,7 @@ link-z80 -f date ihex2bin -l date.i86 ..\..\..\bin\large\date @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dd +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dd @if errorlevel 1 goto failure del dd.r01 as-z80 -l -o dd.s01 @@ -219,7 +219,7 @@ link-z80 -f dd ihex2bin -l dd.i86 ..\..\..\bin\large\dd @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\df +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\df @if errorlevel 1 goto failure del df.r01 as-z80 -l -o df.s01 @@ -230,7 +230,7 @@ link-z80 -f df ihex2bin -l df.i86 ..\..\..\bin\large\df @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dhry +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dhry @if errorlevel 1 goto failure del dhry.r01 as-z80 -l -o dhry.s01 @@ -241,7 +241,7 @@ link-z80 -f dhry ihex2bin -l dhry.i86 ..\..\..\bin\large\dhry @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diff +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\diff @if errorlevel 1 goto failure del diff.r01 as-z80 -l -o diff.s01 @@ -252,7 +252,7 @@ link-z80 -f diff ihex2bin -l diff.i86 ..\..\..\bin\large\diff @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dirname +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dirname @if errorlevel 1 goto failure del dirname.r01 as-z80 -l -o dirname.s01 @@ -263,7 +263,7 @@ link-z80 -f dirname ihex2bin -l dirname.i86 ..\..\..\bin\large\dirname @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diskusag +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\diskusag @if errorlevel 1 goto failure del diskusag.r01 as-z80 -l -o diskusag.s01 @@ -275,7 +275,7 @@ ihex2bin -l diskusag.i86 ..\..\..\bin\large\diskusag @if errorlevel 1 goto failure rem dosread is not necessary for the hytech system (no floppy drive) -rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dosread +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 -DNDEBUG ..\dosread rem @if errorlevel 1 goto failure rem del dosread.r01 rem as-z80 -l -o dosread.s01 @@ -286,7 +286,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l dosread.i86 ..\..\..\bin\large\dosread rem @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dtree +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\dtree @if errorlevel 1 goto failure del dtree.r01 as-z80 -l -o dtree.s01 @@ -297,7 +297,7 @@ link-z80 -f dtree ihex2bin -l dtree.i86 ..\..\..\bin\large\dtree @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\du +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\du @if errorlevel 1 goto failure del du.r01 as-z80 -l -o du.s01 @@ -308,7 +308,7 @@ link-z80 -f du ihex2bin -l du.i86 ..\..\..\bin\large\du @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\echo +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\echo @if errorlevel 1 goto failure del echo.r01 as-z80 -l -o echo.s01 @@ -319,7 +319,7 @@ link-z80 -f echo ihex2bin -l echo.i86 ..\..\..\bin\large\echo @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ed +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ed @if errorlevel 1 goto failure del ed.r01 as-z80 -l -o ed.s01 @@ -330,7 +330,7 @@ link-z80 -f ed ihex2bin -l ed.i86 ..\..\..\bin\large\ed @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\expr +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\expr @if errorlevel 1 goto failure del expr.r01 as-z80 -l -o expr.s01 @@ -341,7 +341,7 @@ link-z80 -f expr ihex2bin -l expr.i86 ..\..\..\bin\large\expr @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\false +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\false @if errorlevel 1 goto failure del false.r01 as-z80 -l -o false.s01 @@ -352,7 +352,7 @@ link-z80 -f false ihex2bin -l false.i86 ..\..\..\bin\large\false @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fgrep +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fgrep @if errorlevel 1 goto failure del fgrep.r01 as-z80 -l -o fgrep.s01 @@ -363,7 +363,7 @@ link-z80 -f fgrep ihex2bin -l fgrep.i86 ..\..\..\bin\large\fgrep @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\file +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\file @if errorlevel 1 goto failure del file.r01 as-z80 -l -o file.s01 @@ -374,7 +374,7 @@ link-z80 -f file ihex2bin -l file.i86 ..\..\..\bin\large\file @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\find +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\find @if errorlevel 1 goto failure del find.r01 as-z80 -l -o find.s01 @@ -385,7 +385,7 @@ link-z80 -f find ihex2bin -l find.i86 ..\..\..\bin\large\find @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fld +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fld @if errorlevel 1 goto failure del fld.r01 as-z80 -l -o fld.s01 @@ -396,7 +396,7 @@ link-z80 -f fld ihex2bin -l fld.i86 ..\..\..\bin\large\fld @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fortune +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\fortune @if errorlevel 1 goto failure del fortune.r01 as-z80 -l -o fortune.s01 @@ -407,7 +407,7 @@ link-z80 -f fortune ihex2bin -l fortune.i86 ..\..\..\bin\large\fortune @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\grep +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\grep @if errorlevel 1 goto failure del grep.r01 as-z80 -l -o grep.s01 @@ -418,7 +418,7 @@ link-z80 -f grep ihex2bin -l grep.i86 ..\..\..\bin\large\grep @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\gres +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\gres @if errorlevel 1 goto failure del gres.r01 as-z80 -l -o gres.s01 @@ -429,7 +429,7 @@ link-z80 -f gres ihex2bin -l gres.i86 ..\..\..\bin\large\gres @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\head +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\head @if errorlevel 1 goto failure del head.r01 as-z80 -l -o head.s01 @@ -440,7 +440,7 @@ link-z80 -f head ihex2bin -l head.i86 ..\..\..\bin\large\head @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\id +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\id @if errorlevel 1 goto failure del id.r01 as-z80 -l -o id.s01 @@ -451,7 +451,7 @@ link-z80 -f id ihex2bin -l id.i86 ..\..\..\bin\large\id @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\inodes +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\inodes @if errorlevel 1 goto failure del inodes.r01 as-z80 -l -o inodes.s01 @@ -462,7 +462,7 @@ link-z80 -f inodes ihex2bin -l inodes.i86 ..\..\..\bin\large\inodes @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\kill +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\kill @if errorlevel 1 goto failure del kill.r01 as-z80 -l -o kill.s01 @@ -473,7 +473,7 @@ link-z80 -f kill ihex2bin -l kill.i86 ..\..\..\bin\large\kill @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpd +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\lpd @if errorlevel 1 goto failure del lpd.r01 as-z80 -l -o lpd.s01 @@ -484,7 +484,7 @@ link-z80 -f lpd ihex2bin -l lpd.i86 ..\..\..\bin\large\lpd @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpr +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\lpr @if errorlevel 1 goto failure del lpr.r01 as-z80 -l -o lpr.s01 @@ -495,7 +495,7 @@ link-z80 -f lpr ihex2bin -l lpr.i86 ..\..\..\bin\large\lpr @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ls +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ls @if errorlevel 1 goto failure del ls.r01 as-z80 -l -o ls.s01 @@ -506,7 +506,7 @@ link-z80 -f ls ihex2bin -l ls.i86 ..\..\..\bin\large\ls @if errorlevel 1 goto failure -rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\man +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\man rem @if errorlevel 1 goto failure rem del man.r01 rem as-z80 -l -o man.s01 @@ -517,7 +517,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l man.i86 ..\..\..\bin\large\man rem @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mkdir +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mkdir @if errorlevel 1 goto failure del mkdir.r01 as-z80 -l -o mkdir.s01 @@ -528,7 +528,7 @@ link-z80 -f mkdir ihex2bin -l mkdir.i86 ..\..\..\bin\large\mkdir @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mknod +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mknod @if errorlevel 1 goto failure del mknod.r01 as-z80 -l -o mknod.s01 @@ -539,7 +539,7 @@ link-z80 -f mknod ihex2bin -l mknod.i86 ..\..\..\bin\large\mknod @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\more +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\more @if errorlevel 1 goto failure del more.r01 as-z80 -l -o more.s01 @@ -550,7 +550,7 @@ link-z80 -f more ihex2bin -l more.i86 ..\..\..\bin\large\more @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mount +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\mount @if errorlevel 1 goto failure del mount.r01 as-z80 -l -o mount.s01 @@ -561,7 +561,7 @@ link-z80 -f mount ihex2bin -l mount.i86 ..\..\..\bin\large\mount @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncheck +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ncheck @if errorlevel 1 goto failure del ncheck.r01 as-z80 -l -o ncheck.s01 @@ -572,7 +572,7 @@ link-z80 -f ncheck ihex2bin -l ncheck.i86 ..\..\..\bin\large\ncheck @if errorlevel 1 goto failure -rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncr +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ncr rem @if errorlevel 1 goto failure rem del ncr.r01 rem as-z80 -l -o ncr.s01 @@ -583,7 +583,7 @@ rem @if errorlevel 1 goto failure rem ihex2bin -l ncr.i86 ..\..\..\bin\large\ncr rem @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\od +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\od @if errorlevel 1 goto failure del od.r01 as-z80 -l -o od.s01 @@ -594,7 +594,7 @@ link-z80 -f od ihex2bin -l od.i86 ..\..\..\bin\large\od @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\passwd +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\passwd @if errorlevel 1 goto failure del passwd.r01 as-z80 -l -o passwd.s01 @@ -605,7 +605,7 @@ link-z80 -f passwd ihex2bin -l passwd.i86 ..\..\..\bin\large\passwd @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pathchk +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pathchk @if errorlevel 1 goto failure del pathchk.r01 as-z80 -l -o pathchk.s01 @@ -616,7 +616,7 @@ link-z80 -f pathchk ihex2bin -l pathchk.i86 ..\..\..\bin\large\pathchk @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pr +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pr @if errorlevel 1 goto failure del pr.r01 as-z80 -l -o pr.s01 @@ -627,7 +627,7 @@ link-z80 -f pr ihex2bin -l pr.i86 ..\..\..\bin\large\pr @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\printenv +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\printenv @if errorlevel 1 goto failure del printenv.r01 as-z80 -l -o printenv.s01 @@ -638,7 +638,7 @@ link-z80 -f printenv ihex2bin -l printenv.i86 ..\..\..\bin\large\printenv @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ps +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ps @if errorlevel 1 goto failure del ps.r01 as-z80 -l -o ps.s01 @@ -649,7 +649,7 @@ link-z80 -f ps ihex2bin -l ps.i86 ..\..\..\bin\large\ps @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pwd +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\pwd @if errorlevel 1 goto failure del pwd.r01 as-z80 -l -o pwd.s01 @@ -660,7 +660,7 @@ link-z80 -f pwd ihex2bin -l pwd.i86 ..\..\..\bin\large\pwd @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\readall +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\readall @if errorlevel 1 goto failure del readall.r01 as-z80 -l -o readall.s01 @@ -671,7 +671,7 @@ link-z80 -f readall ihex2bin -l readall.i86 ..\..\..\bin\large\readall @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\reboot +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\reboot @if errorlevel 1 goto failure del reboot.r01 as-z80 -l -o reboot.s01 @@ -682,7 +682,7 @@ link-z80 -f reboot ihex2bin -l reboot.i86 ..\..\..\bin\large\reboot @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\renice +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\renice @if errorlevel 1 goto failure del renice.r01 as-z80 -l -o renice.s01 @@ -693,7 +693,7 @@ link-z80 -f renice ihex2bin -l renice.i86 ..\..\..\bin\large\renice @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rm +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\rm @if errorlevel 1 goto failure del rm.r01 as-z80 -l -o rm.s01 @@ -704,7 +704,7 @@ link-z80 -f rm ihex2bin -l rm.i86 ..\..\..\bin\large\rm @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rmdir +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\rmdir @if errorlevel 1 goto failure del rmdir.r01 as-z80 -l -o rmdir.s01 @@ -715,7 +715,7 @@ link-z80 -f rmdir ihex2bin -l rmdir.i86 ..\..\..\bin\large\rmdir @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\roff +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\roff @if errorlevel 1 goto failure del roff.r01 as-z80 -l -o roff.s01 @@ -726,7 +726,7 @@ link-z80 -f roff ihex2bin -l roff.i86 ..\..\..\bin\large\roff @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\setclock +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\setclock @if errorlevel 1 goto failure del setclock.r01 as-z80 -l -o setclock.s01 @@ -737,7 +737,7 @@ link-z80 -f setclock ihex2bin -l setclock.i86 ..\..\..\bin\large\setclock @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sort +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sort @if errorlevel 1 goto failure del sort.r01 as-z80 -l -o sort.s01 @@ -748,7 +748,7 @@ link-z80 -f sort ihex2bin -l sort.i86 ..\..\..\bin\large\sort @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\split +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\split @if errorlevel 1 goto failure del split.r01 as-z80 -l -o split.s01 @@ -759,7 +759,7 @@ link-z80 -f split ihex2bin -l split.i86 ..\..\..\bin\large\split @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\su +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\su @if errorlevel 1 goto failure del su.r01 as-z80 -l -o su.s01 @@ -770,7 +770,7 @@ link-z80 -f su ihex2bin -l su.i86 ..\..\..\bin\large\su @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sum +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sum @if errorlevel 1 goto failure del sum.r01 as-z80 -l -o sum.s01 @@ -781,7 +781,7 @@ link-z80 -f sum ihex2bin -l sum.i86 ..\..\..\bin\large\sum @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sync +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\sync @if errorlevel 1 goto failure del sync.r01 as-z80 -l -o sync.s01 @@ -792,7 +792,7 @@ link-z80 -f sync ihex2bin -l sync.i86 ..\..\..\bin\large\sync @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tail +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tail @if errorlevel 1 goto failure del tail.r01 as-z80 -l -o tail.s01 @@ -803,7 +803,7 @@ link-z80 -f tail ihex2bin -l tail.i86 ..\..\..\bin\large\tail @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tar +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tar @if errorlevel 1 goto failure del tar.r01 as-z80 -l -o tar.s01 @@ -814,7 +814,7 @@ link-z80 -f tar ihex2bin -l tar.i86 ..\..\..\bin\large\tar @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tee +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tee @if errorlevel 1 goto failure del tee.r01 as-z80 -l -o tee.s01 @@ -825,7 +825,7 @@ link-z80 -f tee ihex2bin -l tee.i86 ..\..\..\bin\large\tee @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ter +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ter @if errorlevel 1 goto failure del ter.r01 as-z80 -l -o ter.s01 @@ -836,7 +836,7 @@ link-z80 -f ter ihex2bin -l ter.i86 ..\..\..\bin\large\ter @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\termcap +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\termcap @if errorlevel 1 goto failure del termcap.r01 as-z80 -l -o termcap.s01 @@ -847,7 +847,7 @@ link-z80 -f termcap ihex2bin -l termcap.i86 ..\..\..\bin\large\termcap @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\test +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\test @if errorlevel 1 goto failure del test.r01 as-z80 -l -o test.s01 @@ -858,7 +858,7 @@ link-z80 -f test ihex2bin -l test.i86 ..\..\..\bin\large\test @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tget +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tget @if errorlevel 1 goto failure del tget.r01 as-z80 -l -o tget.s01 @@ -869,7 +869,7 @@ link-z80 -f tget ihex2bin -l tget.i86 ..\..\..\bin\large\tget @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\time +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\time @if errorlevel 1 goto failure del time.r01 as-z80 -l -o time.s01 @@ -880,7 +880,7 @@ link-z80 -f time ihex2bin -l time.i86 ..\..\..\bin\large\time @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\top +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\top @if errorlevel 1 goto failure del top.r01 as-z80 -l -o top.s01 @@ -891,7 +891,7 @@ link-z80 -f top ihex2bin -l top.i86 ..\..\..\bin\large\top @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\touch +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\touch @if errorlevel 1 goto failure del touch.r01 as-z80 -l -o touch.s01 @@ -902,7 +902,7 @@ link-z80 -f touch ihex2bin -l touch.i86 ..\..\..\bin\large\touch @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tr +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\tr @if errorlevel 1 goto failure del tr.r01 as-z80 -l -o tr.s01 @@ -913,7 +913,7 @@ link-z80 -f tr ihex2bin -l tr.i86 ..\..\..\bin\large\tr @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\true +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\true @if errorlevel 1 goto failure del true.r01 as-z80 -l -o true.s01 @@ -924,7 +924,7 @@ link-z80 -f true ihex2bin -l true.i86 ..\..\..\bin\large\true @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ualign +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\ualign @if errorlevel 1 goto failure del ualign.r01 as-z80 -l -o ualign.s01 @@ -935,7 +935,7 @@ link-z80 -f ualign ihex2bin -l ualign.i86 ..\..\..\bin\large\ualign @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\umount +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\umount @if errorlevel 1 goto failure del umount.r01 as-z80 -l -o umount.s01 @@ -946,7 +946,7 @@ link-z80 -f umount ihex2bin -l umount.i86 ..\..\..\bin\large\umount @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uname +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uname @if errorlevel 1 goto failure del uname.r01 as-z80 -l -o uname.s01 @@ -957,7 +957,7 @@ link-z80 -f uname ihex2bin -l uname.i86 ..\..\..\bin\large\uname @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uniq +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uniq @if errorlevel 1 goto failure del uniq.r01 as-z80 -l -o uniq.s01 @@ -968,7 +968,7 @@ link-z80 -f uniq ihex2bin -l uniq.i86 ..\..\..\bin\large\uniq @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uudecode +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uudecode @if errorlevel 1 goto failure del uudecode.r01 as-z80 -l -o uudecode.s01 @@ -979,7 +979,7 @@ link-z80 -f uudecode ihex2bin -l uudecode.i86 ..\..\..\bin\large\uudecode @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uuencode +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\uuencode @if errorlevel 1 goto failure del uuencode.r01 as-z80 -l -o uuencode.s01 @@ -990,7 +990,7 @@ link-z80 -f uuencode ihex2bin -l uuencode.i86 ..\..\..\bin\large\uuencode @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\wc +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\wc @if errorlevel 1 goto failure del wc.r01 as-z80 -l -o wc.s01 @@ -1001,7 +1001,7 @@ link-z80 -f wc ihex2bin -l wc.i86 ..\..\..\bin\large\wc @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\which +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\which @if errorlevel 1 goto failure del which.r01 as-z80 -l -o which.s01 @@ -1012,7 +1012,7 @@ link-z80 -f which ihex2bin -l which.i86 ..\..\..\bin\large\which @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\whoami +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\whoami @if errorlevel 1 goto failure del whoami.r01 as-z80 -l -o whoami.s01 @@ -1023,7 +1023,7 @@ link-z80 -f whoami ihex2bin -l whoami.i86 ..\..\..\bin\large\whoami @if errorlevel 1 goto failure -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\yes +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\yes @if errorlevel 1 goto failure del yes.r01 as-z80 -l -o yes.s01 diff --git a/src/simple/cat.c b/src/simple/cat.c index 2cf3b0d7..415b79a8 100644 --- a/src/simple/cat.c +++ b/src/simple/cat.c @@ -21,7 +21,7 @@ int main(argc, argv) if (argc < 2) { if (isatty(STDIN_FILENO)) { - write(STDERR_FILENO, "usage: cat filename ...\n", 20); + write(STDERR_FILENO, "usage: cat filename ...\n", 24); return 0; } else { argc++; diff --git a/src/simple/dosread.c b/src/simple/dosread.c index a89a630b..c701df81 100644 --- a/src/simple/dosread.c +++ b/src/simple/dosread.c @@ -13,12 +13,16 @@ * a: Set ASCII bit. */ -#ifdef MSX_UZIX_TARGET +/* Nick #ifdef MSX_UZIX_TARGET */ /* no assertions for MSX UZIX - let's save memory! */ -#define NDEBUG -#undef CACHE_ROOT -#endif +/* Nick #define NDEBUG 1 */ +/* Nick #undef CACHE_ROOT */ +/* Nick #endif */ +#ifndef DEBUG /* Nick */ +#define DEBUG 0 +#define NDEBUG 1 +#endif #include #include #include diff --git a/src/simple/ls.c b/src/simple/ls.c index e5837e79..0acc9c26 100644 --- a/src/simple/ls.c +++ b/src/simple/ls.c @@ -106,11 +106,12 @@ char *inofield(ino_t ino, int inoflag) void dols(int d, char *path, int wide, char *year, int inoflag) { - int i, fd; + int i, j, fd; direct_t buf; char dname[512]; struct stat statbuf; + j = 0; /* current column */ while (read(d, (char *) &buf, sizeof(direct_t)) == sizeof(direct_t)) { if (buf.d_name[0] == '\0') @@ -189,13 +190,34 @@ void dols(int d, char *path, int wide, char *year, int inoflag) else i--; if (wide >= 2) { - if (i < 16) putchar('\t'); - if (i < 8) putchar('\t'); + if (j >= 4) + { + j = 0; + putchar('\n'); + } + else + { + j++; + if (i < 16) + { + putchar('\t'); + } + if (i < 8) + { + putchar('\t'); + } + } } } - if (wide < 2) putchar('\n'); + if (wide < 2) + { + putchar('\n'); + } + } + if (j) + { + putchar('\n'); } - if (wide >= 2) putchar('\n'); #if 1 /* Nick */ fflush(stdout); #endif diff --git a/src/simple/m.bat b/src/simple/m.bat index de973440..854fb259 100644 --- a/src/simple/m.bat +++ b/src/simple/m.bat @@ -2,7 +2,7 @@ cd build-l @if .%1==. goto failure call mklink-l %1 ..\ -iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\%1 +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\%1 @if errorlevel 1 goto failure del %1.r01 as-z80 -l -o %1.s01 @@ -16,7 +16,7 @@ ihex2bin -l %1.i86 ..\..\..\bin\large\%1 cd ..\build-b call mklink-b %1 ..\ -iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\%1 +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DDEBUG=0 ..\%1 @if errorlevel 1 goto failure del %1.r01 as-z80 -l -o %1.s01 diff --git a/src/simple/mkdir.c b/src/simple/mkdir.c index 98388422..6d79d05e 100644 --- a/src/simple/mkdir.c +++ b/src/simple/mkdir.c @@ -40,7 +40,11 @@ int main (argc,argv) char *p; int i, n, parent = 0, er = 0; +#if 1 /* Nick */ + newmode = 0777 & ~umask(0); +#else newmode = 0666 & ~umask(0); +#endif argc--; argv++; diff --git a/src/simple/setclock.c b/src/simple/setclock.c index cc639d06..1f2b4748 100644 --- a/src/simple/setclock.c +++ b/src/simple/setclock.c @@ -80,7 +80,7 @@ int main(argc, argv) } argv++; if (!conv_time(*argv, *(argv + 1), &tt)) { - wr("Bad date/time format\n"); + wr("Bad time/date format\n"); return 1; } #ifdef __TURBOC__ diff --git a/src/troff/nroff.exe b/src/troff/nroff.exe index 60199e7624f65ea3fa82bb219ff1fdf87178fd3d..250afd09743ddf0679e7fd194696eb64d54c07a4 100644 GIT binary patch delta 46157 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 Pf@u9u=5O2ZBkunIYDK(6 delta 15598 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 diff --git a/src/fsutil/fsck.lnk b/src/fsutil/fsck.lnk index aeeac6d4..6415e4ee 100644 --- a/src/fsutil/fsck.lnk +++ b/src/fsutil/fsck.lnk @@ -1,12 +1,14 @@ -k ..\..\lib --l libcl.lib --l libsysl.lib +-l libcb.lib +-l libsysb.lib -l libiar.lib -m -u -i -o fsck -bl RCODE=0x8100 -..\..\lib\c0l.rel +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\lib\c0b.rel fsck -utils +utils diff --git a/src/fsutil/fsck.map b/src/fsutil/fsck.map index 8e4abd56..851ad610 100644 --- a/src/fsutil/fsck.map +++ b/src/fsutil/fsck.map @@ -9,15 +9,15 @@ Area Addr Size Decimal Bytes (Attributes) 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR 00000000 l_CONST | 00000000 .__.ABS. | 00000000 ?CL64180L 00000000 ?CL64180B | 00000014 e__DEFAUL | 00000014 l__DEFAUL - 0000016C l_CDATA0 | 0000016C l_IDATA0 | 00000352 l_RCODE - 000007A9 l_CSTR | 000008C2 l_UDATA0 | 00001000 l_CSTACK - 000038A8 l_CODE | 00008100 s_RCODE | 00008452 e_RCODE - 00008452 s_CODE | 0000BCFA s_CSTR | 0000BCFA e_CODE - 0000BCFA e_CONST | 0000BCFA s_CONST | 0000C4A3 e_CSTR - 0000C4A3 s_IDATA0 | 0000C4A3 s_CDATA0 | 0000C60F s_UDATA0 - 0000C60F e_CCSTR | 0000C60F e_ECSTR | 0000C60F s_CCSTR - 0000C60F e_CDATA0 | 0000C60F s_ECSTR | 0000C60F e_IDATA0 - 0000CED1 e_UDATA0 | 0000CED1 s_CSTACK | 0000DED1 e_CSTACK + 0000016C l_CDATA0 | 0000016C l_IDATA0 | 00000377 l_RCODE + 000007A9 l_CSTR | 000008CD l_UDATA0 | 00001000 l_CSTACK + 00004000 s_CODE | 00008100 s_RCODE | 00008477 s_CSTR + 00008477 e_RCODE | 00008477 e_CONST | 00008477 s_CONST + 00008C20 e_CSTR | 00008C20 s_IDATA0 | 00008C20 s_CDATA0 + 00008D8C s_UDATA0 | 00008D8C e_CCSTR | 00008D8C e_ECSTR + 00008D8C s_CCSTR | 00008D8C e_CDATA0 | 00008D8C s_ECSTR + 00008D8C e_IDATA0 | 00009659 e_UDATA0 | 00009659 s_CSTACK + 0000A659 e_CSTACK | 0000C015 l_CODE | 00010015 e_CODE Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) @@ -30,61 +30,35 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -RCODE 00008100 00000352 = 850. bytes (REL,CON) +RCODE 00008100 00000377 = 887. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00008100 __init | 00008115 ?US_RSH_L | 0000811F ?S_LSH_L0 - 00008128 ?LEAVE_DI | 0000812F ?ENT_PARM | 0000813B ?L_ANDASG - 00008154 ?SL_CMP_L | 00008185 ?ENT_AUTO | 00008199 ?SL_DIV_L - 000081C9 ?SS_CMP_L | 000081DB ?L_INC_L0 | 000081E3 ?US_MOD_L - 000081EC ?C_LSH_L0 | 000081F3 ?US_DIV_L | 00008201 ?SL_RSH_L - 0000820F ?L_DIVMOD | 00008267 ?L_LSH_L0 | 0000827F ?S_DIVMOD - 00008295 ?LEAVE_32 | 0000829D ?S_MULASG | 000082A7 ?L_NOT_L0 - 000082B6 ?S_MUL_L0 | 000082CC ?C_V_SWIT | 000082DE ?CALL_IND - 000082DF ?L_FIND_S | 00008323 ?UL_DIVAS | 00008333 ?V_SWITCH - 0000833D ?UL_MOD_L | 00008362 ?UL_DIV_L | 0000838A ?L_NEG_L0 - 0000839C ?L_END_MU | 000083A5 ?L_MULASG | 000083B5 ?L_MUL_L0 - 00008439 ?L_ADDASG + 00008100 __init | 0000811F ?US_RSH_L | 00008129 ?S_LSH_L0 + 00008132 ?BANK_LEA | 00008138 ?BANK_FAS | 0000813D ?ENT_PARM + 00008149 ?BANK_CAL | 00008156 ?L_ANDASG | 0000816F ?SL_CMP_L + 000081A0 ?ENT_AUTO | 000081B4 ?SL_DIV_L | 000081E4 ?SS_CMP_L + 000081F6 ?L_INC_L0 | 000081FE ?US_MOD_L | 00008207 ?C_LSH_L0 + 0000820E ?US_DIV_L | 0000821C ?SL_RSH_L | 0000822A ?L_DIVMOD + 00008282 ?BANK_LEA | 0000828E ?L_LSH_L0 | 000082A6 ?S_DIVMOD + 000082BC ?S_MULASG | 000082C6 ?L_NOT_L0 | 000082D5 ?S_MUL_L0 + 000082EB ?C_V_SWIT | 000082FD ?LEAVE_DI | 00008304 ?L_FIND_S + 00008348 ?UL_DIVAS | 00008358 ?V_SWITCH | 00008362 ?UL_MOD_L + 00008387 ?UL_DIV_L | 000083AF ?L_NEG_L0 | 000083C1 ?L_END_MU + 000083CA ?L_MULASG | 000083DA ?L_MUL_L0 | 0000845E ?L_ADDASG Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CODE 00008452 000038A8 = 14504. bytes (REL,CON) +CONST 00008477 00000000 = 0. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00008452 da_read | 000084C5 da_write | 00008538 pass1 - 000089A8 pass2 | 00008C22 pass3 | 00008EF0 ckdir - 000092FF pass4 | 0000932B mkentry | 000093EE pass5 - 000095DA getblkno | 000096C7 setblkno | 000097F5 _blk_allo - 000098AD daread | 000098DD dwrite | 00009907 iread - 0000994B iwrite | 000099A9 dirread | 00009A09 dirwrite - 00009A7A yes | 00009AC4 main | 00009D79 bitmap_du - 00009E5B bitmap_fi | 00009F9E mypanic | 00009FBA bzero - 00009FE4 bfill | 0000A010 bcopy | 0000A048 int_min - 0000A069 int_max | 0000A07F sprintf | 0000A0BE fflush - 0000A2B3 _write | 0000A2CD strcat | 0000A2E3 printf - 0000A30D lseek | 0000A335 __stdio_c | 0000A38C __stdio_i - 0000A3BA close | 0000A3CA strlen | 0000A401 abort - 0000A445 _exit | 0000A455 fgets | 0000A4F5 strcmp - 0000A591 perror | 0000A5C9 pause | 0000A5D2 isatty - 0000A608 fstat | 0000A61A strcpy | 0000A637 kill - 0000A7BA vfprintf | 0000ACED ltoa | 0000AD4B __longtoa - 0000AEDF itoa | 0000AF43 open | 0000AF69 malloc - 0000B18B fprintf | 0000B1B8 exit | 0000B1DD _read - 0000B1F7 getpid | 0000B205 signal | 0000B225 strerror - 0000B3B4 unix | 0000B3CC fgetc | 0000B4D2 memcpy - 0000B58B on_exit | 0000B5ED atexit | 0000B5F9 unix_long - 0000B611 strchr | 0000B64C free | 0000B72C fputc - 0000B82A ultoa | 0000B87A atoi | 0000B88B sbrk - 0000B89B fread | 0000BA30 strtol | 0000BB59 strtoul - 0000BCB0 toupper | 0000BCD5 tolower Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CONST 0000BCFA 00000000 = 0. bytes (REL,CON) +CSTR 00008477 000007A9 = 1961. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -92,26 +66,26 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTR 0000BCFA 000007A9 = 1961. bytes (REL,CON) +IDATA0 00008C20 0000016C = 364. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ + 00008C20 _yes | 00008C3A __IO_list | 00008C3C stdin + 00008C54 stdout | 00008C6C stderr | 00008C86 __sys_err + 00008C88 __sys_ner | 00008C8A __on_exit | 00008C8C __ctype Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -IDATA0 0000C4A3 0000016C = 364. bytes (NUL,CON) +CDATA0 00008C20 0000016C = 364. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 0000C4A3 _yes | 0000C4BD __IO_list | 0000C4BF stdin - 0000C4D7 stdout | 0000C4EF stderr | 0000C509 __sys_err - 0000C50B __sys_ner | 0000C50D __on_exit | 0000C50F __ctype Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CDATA0 0000C4A3 0000016C = 364. bytes (REL,CON) +ECSTR 00008D8C 00000000 = 0. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -119,7 +93,7 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -ECSTR 0000C60F 00000000 = 0. bytes (NUL,CON) +CCSTR 00008D8C 00000000 = 0. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -127,120 +101,147 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CCSTR 0000C60F 00000000 = 0. bytes (REL,CON) +CODE 00004000 0000C015 = 49173. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ + 00004CA0 da_read | 00004D45 da_write | 00004DEA pass1 + 000052C9 pass2 | 00005570 pass3 | 0000589D ckdir + 00005D38 pass4 | 00005D70 mkentry | 00005E52 pass5 + 0000608F getblkno | 0000618B setblkno | 000062E1 _blk_allo + 000063B3 daread | 000063F2 dwrite | 0000642B iread + 00006479 iwrite | 000064E6 dirread | 0000655A dirwrite + 000065E4 yes | 0000663D main | 000069D9 bitmap_du + 00006ACF bitmap_fi | 00006C21 mypanic | 00006C4C bzero + 00006C76 bfill | 00006CA2 bcopy | 00006CDA int_min + 00006CFB int_max | 00006D11 sprintf | 00006D55 fflush + 00006F68 _write | 00006F87 strcat | 00006FA7 printf + 00006FD6 lseek | 00007003 __stdio_c | 0000706E __stdio_i + 000070AC close | 000070C1 strlen | 000070F8 abort + 00007166 _exit | 0000717B fgets | 00007220 strcmp + 000072C1 perror | 000072FE pause | 0000730E isatty + 00007349 fstat | 00007360 strcpy | 00007387 kill + 0000751E vfprintf | 00007A79 ltoa | 00007ADC __longtoa + 00007C70 itoa | 00007CD9 open | 00007D04 malloc + 00007F30 fprintf | 00007F62 exit | 00007F92 _read + 00007FB1 getpid | 00007FC6 signal | 00014000 strerror + 000141BD unix | 000141D7 fgetc | 000142E7 memcpy + 000143B5 on_exit | 0001442E atexit | 00014441 unix_long + 0001445B strchr | 00014496 free | 00014576 fputc + 00014688 ultoa | 000146DD atoi | 000146F3 sbrk + 00014708 fread | 000148B6 strtol | 000149E4 strtoul + 00014B3B toupper | 00014B60 tolower Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -UDATA0 0000C60F 000008C2 = 2242. bytes (REL,CON) +UDATA0 00008D8C 000008CD = 2253. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 0000C60F _argc | 0000C611 _argv | 0000C613 environ - 0000C615 errno | 0000C617 __cleanup | 0000C619 device_ha - 0000C61B device_na | 0000C81B zeroed | 0000CA1B depth - 0000CA1D dev | 0000CA1F filsys | 0000CA3D ninodes - 0000CA3F finode | 0000CA41 bitmap_in | 0000CA45 bitmap_bl - 0000CA49 bitmap_im | 0000CA4D inode_bit | 0000CA4F block_bit - 0000CA51 link_coun | 0000CE53 __malloc_ | 0000CE57 __malloc_ - 0000CEA9 __on_exit + 00008D8C _argc | 00008D8E _argv | 00008D90 environ + 00008D92 errno | 00008D94 __cleanup | 00008D97 device_ha + 00008D99 device_na | 00008F99 zeroed | 00009199 depth + 0000919B dev | 0000919D filsys | 000091BB ninodes + 000091BD finode | 000091BF bitmap_in | 000091C3 bitmap_bl + 000091C7 bitmap_im | 000091CB inode_bit | 000091CD block_bit + 000091CF link_coun | 000095D1 __malloc_ | 000095D5 __malloc_ + 00009627 __on_exit Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTACK 0000CED1 00001000 = 4096. bytes (REL,CON) +CSTACK 00009659 00001000 = 4096. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ Files Linked [ module(s) ] -..\..\lib\c0l.rel [ _c0l ] +..\..\lib\c0b.rel [ _c0b ] fsck [ fsck ] utils [ utils ] Libraries Linked [ object file ] -..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] ..\..\lib\libiar.lib [ reliar\USRSH.rel ] ..\..\lib\libiar.lib [ reliar\SLSH.rel ] -..\..\lib\libcl.lib [ relcl\sprintf.rel ] -..\..\lib\libcl.lib [ relcl\fflush.rel ] -..\..\lib\libsysl.lib [ relsysl\write.rel ] -..\..\lib\libcl.lib [ relcl\strcat.rel ] -..\..\lib\libcl.lib [ relcl\printf.rel ] -..\..\lib\libsysl.lib [ relsysl\lseek.rel ] -..\..\lib\libcl.lib [ relcl\stdio0.rel ] -..\..\lib\libsysl.lib [ relsysl\close.rel ] -..\..\lib\libcl.lib [ relcl\strlen.rel ] -..\..\lib\libcl.lib [ relcl\abort.rel ] -..\..\lib\libsysl.lib [ relsysl\_exit.rel ] -..\..\lib\libcl.lib [ relcl\fgets.rel ] -..\..\lib\libcl.lib [ relcl\strcmp.rel ] -..\..\lib\libcl.lib [ relcl\perror.rel ] -..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] -..\..\lib\libsysl.lib [ relsysl\pause.rel ] -..\..\lib\libcl.lib [ relcl\isatty.rel ] -..\..\lib\libsysl.lib [ relsysl\fstat.rel ] +..\..\lib\libcb.lib [ relcb\sprintf.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libcb.lib [ relcb\printf.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libcb.lib [ relcb\abort.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libcb.lib [ relcb\fgets.rel ] +..\..\lib\libcb.lib [ relcb\strcmp.rel ] +..\..\lib\libcb.lib [ relcb\perror.rel ] +..\..\lib\libsysb.lib [ relsysb\pause.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] ..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] -..\..\lib\libcl.lib [ relcl\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] ..\..\lib\libiar.lib [ reliar\LANDASG.rel ] ..\..\lib\libiar.lib [ reliar\SLCMP.rel ] -..\..\lib\libsysl.lib [ relsysl\kill.rel ] +..\..\lib\libsysb.lib [ relsysb\kill.rel ] ..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] ..\..\lib\libiar.lib [ reliar\SLDIV.rel ] -..\..\lib\libcl.lib [ relcl\vfprintf.rel ] -..\..\lib\libcl.lib [ relcl\ltoa.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] ..\..\lib\libiar.lib [ reliar\SSCMP.rel ] -..\..\lib\libcl.lib [ relcl\itoa.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] ..\..\lib\libiar.lib [ reliar\LINC.rel ] -..\..\lib\libsysl.lib [ relsysl\open.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] ..\..\lib\libiar.lib [ reliar\USMOD.rel ] ..\..\lib\libiar.lib [ reliar\CLSH.rel ] ..\..\lib\libiar.lib [ reliar\USDIV.rel ] -..\..\lib\libcl.lib [ relcl\malloc.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] ..\..\lib\libiar.lib [ reliar\SLRSH.rel ] -..\..\lib\libcl.lib [ relcl\fprintf.rel ] -..\..\lib\libcl.lib [ relcl\exit.rel ] +..\..\lib\libcb.lib [ relcb\fprintf.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] ..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] -..\..\lib\libsysl.lib [ relsysl\read.rel ] -..\..\lib\libsysl.lib [ relsysl\getpid.rel ] -..\..\lib\libsysl.lib [ relsysl\signal.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libsysb.lib [ relsysb\getpid.rel ] +..\..\lib\libsysb.lib [ relsysb\signal.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] ..\..\lib\libiar.lib [ reliar\LLSH.rel ] ..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] -..\..\lib\libcl.lib [ relcl\error.rel ] -..\..\lib\libiar.lib [ reliar\LEAVE32.rel ] -..\..\lib\libsysl.lib [ relsysl\sys0l.rel ] +..\..\lib\libcb.lib [ relcb\error.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] ..\..\lib\libiar.lib [ reliar\SMULASG.rel ] ..\..\lib\libiar.lib [ reliar\LNOT.rel ] -..\..\lib\libcl.lib [ relcl\fgetc.rel ] -..\..\lib\libcl.lib [ relcl\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\fgetc.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] ..\..\lib\libiar.lib [ reliar\SMUL.rel ] -..\..\lib\libcl.lib [ relcl\atexit.rel ] -..\..\lib\libsysl.lib [ relsysl\sys1l.rel ] -..\..\lib\libcl.lib [ relcl\strchr.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libcb.lib [ relcb\strchr.rel ] ..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] -..\..\lib\libcl.lib [ relcl\free.rel ] -..\..\lib\libcl.lib [ relcl\fputc.rel ] -..\..\lib\libcl.lib [ relcl\ultoa.rel ] -..\..\lib\libiar.lib [ reliar\CALLIND.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] ..\..\lib\libiar.lib [ reliar\LFINDSIGN.rel ] ..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] ..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] -..\..\lib\libcl.lib [ relcl\atoi.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] ..\..\lib\libiar.lib [ reliar\ULMOD.rel ] ..\..\lib\libiar.lib [ reliar\ULDIV.rel ] -..\..\lib\libsysl.lib [ relsysl\sbrk.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] ..\..\lib\libiar.lib [ reliar\LNEG.rel ] -..\..\lib\libcl.lib [ relcl\fread.rel ] +..\..\lib\libcb.lib [ relcb\fread.rel ] ..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] -..\..\lib\libcl.lib [ relcl\strtol.rel ] -..\..\lib\libcl.lib [ relcl\strtoul.rel ] -..\..\lib\libcl.lib [ relcl\ctype.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] ..\..\lib\libiar.lib [ reliar\LMULASG.rel ] ..\..\lib\libiar.lib [ reliar\LMUL.rel ] ..\..\lib\libiar.lib [ reliar\LADDASG.rel ] @@ -249,3 +250,5 @@ Libraries Linked [ object file ] User Base Address Definitions l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/fsutil/fsck.rel b/src/fsutil/fsck.rel index 5f9624b5..d2974fdf 100644 --- a/src/fsutil/fsck.rel +++ b/src/fsutil/fsck.rel @@ -1,26 +1,27 @@ XL4 -H 6 areas 4B global symbols +H 6 areas 4D global symbols M fsck S ?US_RSH_L02 Ref00000000 -S ?CL64180L_4_06_L00 Ref00000000 S ?S_LSH_L02 Ref00000000 S sprintf Ref00000000 +S ?BANK_FAST_LEAVE_L08 Ref00000000 S fflush Ref00000000 S bfill Ref00000000 S _write Ref00000000 S strcat Ref00000000 S printf Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 S stderr Ref00000000 S lseek Ref00000000 S close Ref00000000 S abort Ref00000000 S strcmp Ref00000000 S fgets Ref00000000 -S ?LEAVE_DIRECT_L09 Ref00000000 S perror Ref00000000 S bcopy Ref00000000 S stdin Ref00000000 S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 S stdout Ref00000000 S strcpy Ref00000000 S ?L_ANDASG_L03 Ref00000000 @@ -31,6 +32,7 @@ S int_min Ref00000000 S ?SS_CMP_L02 Ref00000000 S open Ref00000000 S ?C_LSH_L01 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 S ?SL_RSH_L03 Ref00000000 S malloc Ref00000000 S fprintf Ref00000000 @@ -39,30 +41,30 @@ S _read Ref00000000 S .__.ABS. Def00000000 S ?L_LSH_L03 Ref00000000 A _DEFAULT size 0 flags 0 -A CODE size 1B68 flags 0 +A CODE size 1FAC flags 0 S da_read Def00000000 -S _blk_alloc Def000013A3 -S iread Def000014B5 -S mkentry Def00000ED9 -S ckdir Def00000A9E -S dwrite Def0000148B -S da_write Def00000073 -S yes Def00001628 -S bitmap_dump Def00001927 -S iwrite Def000014F9 -S getblkno Def00001188 -S dirread Def00001557 -S daread Def0000145B -S setblkno Def00001275 -S main Def00001672 -S pass1 Def000000E6 -S pass2 Def00000556 -S pass3 Def000007D0 -S dirwrite Def000015B7 -S pass4 Def00000EAD -S pass5 Def00000F9C -S mypanic Def00001B4C -S bitmap_find Def00001A09 +S _blk_alloc Def00001641 +S iread Def0000178B +S mkentry Def000010D0 +S ckdir Def00000BFD +S dwrite Def00001752 +S da_write Def000000A5 +S yes Def00001944 +S bitmap_dump Def00001D39 +S iwrite Def000017D9 +S getblkno Def000013EF +S dirread Def00001846 +S daread Def00001713 +S setblkno Def000014EB +S main Def0000199D +S pass1 Def0000014A +S pass2 Def00000629 +S pass3 Def000008D0 +S dirwrite Def000018BA +S pass4 Def00001098 +S pass5 Def000011B2 +S mypanic Def00001F81 +S bitmap_find Def00001E2F A CSTR size 771 flags 0 A UDATA0 size 63A flags 0 S bitmap_immov Def00000430 @@ -87,2519 +89,2941 @@ R 00 00 01 00 T 00 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 R 00 00 01 00 02 05 13 00 T 09 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 -R 00 00 01 00 02 0A 24 00 -T 12 00 00 00 E5 ED 5B 00 00 00 00 CD +R 00 00 01 00 02 0A 26 00 +T 12 00 00 00 E5 ED 5B 00 00 00 00 3E R 00 00 01 00 00 07 03 00 -T 18 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 1A -R 00 00 01 00 02 04 0A 00 -T 21 00 00 00 -R 00 00 01 00 -T 21 00 00 00 21 00 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 28 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 2F 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 10 00 -T 36 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 21 00 -T 3B 00 00 00 -R 00 00 01 00 -T 3B 00 00 00 21 00 02 E5 DD 4E 08 DD 46 09 ED -R 00 00 01 00 -T 46 00 00 00 5B 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 00 05 03 00 02 0A 22 00 -T 4D 00 00 00 3E 02 AC B5 28 1A -R 00 00 01 00 -T 53 00 00 00 -R 00 00 01 00 -T 53 00 00 00 21 0D 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 5A 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 61 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 10 00 -T 68 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 21 00 -T 6D 00 00 00 -R 00 00 01 00 -T 6D 00 00 00 21 00 02 C3 00 00 00 00 -R 00 00 01 00 02 08 0F 00 -T 73 00 00 00 -R 00 00 01 00 -T 73 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 +T 18 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +T 1D 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 2E +R 00 00 01 00 02 04 14 00 +T 26 00 00 00 +R 00 00 01 00 +T 26 00 00 00 21 00 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 2C 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 33 00 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T 39 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 3F 00 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 10 00 +T 44 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 10 00 02 09 14 00 +T 4A 00 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T 4F 00 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T 54 00 00 00 +R 00 00 01 00 +T 54 00 00 00 21 00 02 E5 DD 4E 0A DD 46 0B ED +R 00 00 01 00 +T 5F 00 00 00 5B 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 03 00 2B 0A 24 00 +T 65 00 00 00 00 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 02 04 24 00 02 09 14 00 +T 6C 00 00 00 02 AC B5 28 2E +R 00 00 01 00 +T 71 00 00 00 +R 00 00 01 00 +T 71 00 00 00 21 0D 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 77 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 7E 00 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T 84 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 8A 00 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 10 00 +T 8F 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 10 00 02 09 14 00 +T 95 00 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T 9A 00 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T 9F 00 00 00 +R 00 00 01 00 +T 9F 00 00 00 21 00 02 C3 00 00 00 00 +R 00 00 01 00 02 08 09 00 +T A5 00 00 00 +R 00 00 01 00 +T A5 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 R 00 00 01 00 02 05 13 00 -T 7C 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 -R 00 00 01 00 02 0A 24 00 -T 85 00 00 00 E5 ED 5B 00 00 00 00 CD +T AE 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 +R 00 00 01 00 02 0A 26 00 +T B7 00 00 00 E5 ED 5B 00 00 00 00 3E R 00 00 01 00 00 07 03 00 -T 8B 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 1A -R 00 00 01 00 02 04 0A 00 -T 94 00 00 00 -R 00 00 01 00 -T 94 00 00 00 21 00 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 9B 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T A2 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 10 00 -T A9 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 21 00 -T AE 00 00 00 -R 00 00 01 00 -T AE 00 00 00 21 00 02 E5 DD 4E 08 DD 46 09 ED -R 00 00 01 00 -T B9 00 00 00 5B 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 00 05 03 00 02 0A 06 00 -T C0 00 00 00 3E 02 AC B5 28 1A -R 00 00 01 00 -T C6 00 00 00 -R 00 00 01 00 -T C6 00 00 00 21 1A 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T CD 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T D4 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 10 00 -T DB 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 21 00 -T E0 00 00 00 -R 00 00 01 00 -T E0 00 00 00 21 00 02 C3 00 00 00 00 -R 00 00 01 00 02 08 0F 00 -T E6 00 00 00 -R 00 00 01 00 -T E6 00 00 00 CD 00 00 00 00 B2 FF AF DD 77 B6 -R 00 00 01 00 02 05 18 00 -T EF 00 00 00 DD 77 B7 DD 36 B2 01 DD 36 B3 00 -R 00 00 01 00 -T FA 00 00 00 -R 00 00 01 00 -T FA 00 00 00 ED 4B 24 04 00 00 DD 6E B2 DD 66 +T BD 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0B 00 02 09 0B 00 +T C2 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 2E +R 00 00 01 00 02 04 14 00 +T CB 00 00 00 +R 00 00 01 00 +T CB 00 00 00 21 00 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T D1 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T D8 00 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T DE 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T E4 00 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 10 00 +T E9 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 10 00 02 09 14 00 +T EF 00 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T F4 00 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T F9 00 00 00 +R 00 00 01 00 +T F9 00 00 00 21 00 02 E5 DD 4E 0A DD 46 0B ED +R 00 00 01 00 +T 04 01 00 00 5B 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 03 00 2B 0A 06 00 +T 0A 01 00 00 00 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 02 04 06 00 02 09 14 00 +T 11 01 00 00 02 AC B5 28 2E +R 00 00 01 00 +T 16 01 00 00 +R 00 00 01 00 +T 16 01 00 00 21 1A 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 1C 01 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 23 01 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T 29 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 2F 01 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 10 00 +T 34 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 10 00 02 09 14 00 +T 3A 01 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T 3F 01 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T 44 01 00 00 +R 00 00 01 00 +T 44 01 00 00 21 00 02 C3 00 00 00 00 +R 00 00 01 00 02 08 09 00 +T 4A 01 00 00 +R 00 00 01 00 +T 4A 01 00 00 CD 00 00 00 00 B2 FF AF DD 77 B6 +R 00 00 01 00 02 05 19 00 +T 53 01 00 00 DD 77 B7 DD 36 B2 01 DD 36 B3 00 +R 00 00 01 00 +T 5E 01 00 00 +R 00 00 01 00 +T 5E 01 00 00 ED 4B 24 04 00 00 DD 6E B2 DD 66 R 00 00 01 00 00 06 03 00 -T 03 01 00 00 B3 A7 ED 42 D2 03 05 00 00 +T 67 01 00 00 B3 A7 ED 42 D2 C7 05 00 00 R 00 00 01 00 00 09 01 00 -T 0A 01 00 00 +T 6E 01 00 00 R 00 00 01 00 -T 0A 01 00 00 21 0E 00 39 4D 44 DD 5E B2 DD 56 +T 6E 01 00 00 21 0E 00 39 4D 44 DD 5E B2 DD 56 R 00 00 01 00 -T 15 01 00 00 B3 CD B5 14 00 00 DD 6E B2 DD 66 -R 00 00 01 00 00 06 01 00 -T 1E 01 00 00 B3 ED 4B 38 04 00 00 09 36 FF DD -R 00 00 01 00 00 07 03 00 -T 27 01 00 00 6E C0 DD 66 C1 7D B4 20 03 +T 79 01 00 00 B3 3E 8B 17 00 00 21 8B 17 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 7F 01 00 00 CD 00 00 00 00 DD 6E B2 DD 66 B3 +R 00 00 01 00 02 05 14 00 +T 88 01 00 00 ED 4B 38 04 00 00 09 36 FF DD 6E +R 00 00 01 00 00 06 03 00 +T 91 01 00 00 C0 DD 66 C1 7D B4 20 03 R 00 00 01 00 -T 30 01 00 00 +T 99 01 00 00 R 00 00 01 00 -T 30 01 00 00 C3 F8 04 00 00 +T 99 01 00 00 C3 BC 05 00 00 R 00 00 01 00 00 05 01 00 -T 33 01 00 00 -R 00 00 01 00 -T 33 01 00 00 DD 7E C0 E6 00 6F DD 7E C1 E6 F0 +T 9C 01 00 00 R 00 00 01 00 -T 3E 01 00 00 67 DD 75 B4 DD 74 B5 3E A0 AC B5 +T 9C 01 00 00 DD 7E C0 E6 00 6F DD 7E C1 E6 F0 R 00 00 01 00 -T 49 01 00 00 28 71 3E 80 DD AE B5 DD B6 B4 28 +T A7 01 00 00 67 DD 75 B4 DD 74 B5 3E A0 AC B5 R 00 00 01 00 -T 54 01 00 00 67 3E 40 DD AE B5 DD B6 B4 28 5D +T B2 01 00 00 CA 35 02 00 00 3E 80 DD AE B5 DD +R 00 00 01 00 00 05 01 00 +T BB 01 00 00 B6 B4 28 76 3E 40 DD AE B5 DD B6 R 00 00 01 00 -T 5F 01 00 00 3E 90 DD AE B5 DD B6 B4 28 53 3E +T C6 01 00 00 B4 28 6C 3E 90 DD AE B5 DD B6 B4 R 00 00 01 00 -T 6A 01 00 00 60 DD AE B5 DD B6 B4 28 49 3E 20 +T D1 01 00 00 28 62 3E 60 DD AE B5 DD B6 B4 28 R 00 00 01 00 -T 75 01 00 00 DD AE B5 DD B6 B4 28 3F +T DC 01 00 00 58 3E 20 DD AE B5 DD B6 B4 28 4E R 00 00 01 00 -T 7D 01 00 00 +T E7 01 00 00 R 00 00 01 00 -T 7D 01 00 00 +T E7 01 00 00 R 00 00 01 00 -T 7D 01 00 00 +T E7 01 00 00 R 00 00 01 00 -T 7D 01 00 00 DD 6E C0 DD 66 C1 E5 DD 6E B2 DD +T E7 01 00 00 DD 6E C0 DD 66 C1 E5 DD 6E B2 DD R 00 00 01 00 -T 88 01 00 00 66 B3 E5 21 28 00 00 00 E5 CD +T F2 01 00 00 66 B3 E5 21 28 00 00 00 E5 3E R 00 00 01 00 00 08 02 00 -T 90 01 00 00 00 00 00 00 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T 96 01 00 00 28 16 00 00 7D B4 28 20 +T FA 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T FF 01 00 00 00 00 00 00 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 05 02 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 0A 02 00 00 00 00 00 00 7D B4 28 25 +R 00 00 01 00 02 04 14 00 +T 10 02 00 00 +R 00 00 01 00 +T 10 02 00 00 AF DD 77 C0 DD 77 C1 AF DD 77 C2 +R 00 00 01 00 +T 1B 02 00 00 DD 77 C3 21 0E 00 39 4D 44 DD 5E +R 00 00 01 00 +T 26 02 00 00 B2 DD 56 B3 3E D9 17 00 00 21 +R 00 00 01 00 29 09 01 00 +T 2D 02 00 00 D9 17 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 33 02 00 00 BC 05 00 00 R 00 00 01 00 00 04 01 00 -T 9C 01 00 00 +T 35 02 00 00 R 00 00 01 00 -T 9C 01 00 00 AF DD 77 C0 DD 77 C1 AF DD 77 C2 +T 35 02 00 00 R 00 00 01 00 -T A7 01 00 00 DD 77 C3 21 0E 00 39 4D 44 DD 5E +T 35 02 00 00 DD 6E B2 DD 66 B3 ED 4B R 00 00 01 00 -T B2 01 00 00 B2 DD 56 B3 CD F9 14 00 00 C3 -R 00 00 01 00 00 09 01 00 -T BA 01 00 00 F8 04 00 00 -R 00 00 01 00 00 04 01 00 -T BC 01 00 00 -R 00 00 01 00 -T BC 01 00 00 -R 00 00 01 00 -T BC 01 00 00 DD 6E B2 DD 66 B3 ED 4B -R 00 00 01 00 -T C4 01 00 00 38 04 00 00 09 36 00 DD 34 B6 20 +T 3D 02 00 00 38 04 00 00 09 36 00 DD 34 B6 20 R 00 00 01 00 00 04 03 00 -T CD 01 00 00 03 DD 34 B7 +T 46 02 00 00 03 DD 34 B7 R 00 00 01 00 -T D1 01 00 00 +T 4A 02 00 00 R 00 00 01 00 -T D1 01 00 00 3E A0 DD AE B5 DD B6 B4 28 1F 3E +T 4A 02 00 00 3E A0 DD AE B5 DD B6 B4 28 1F 3E R 00 00 01 00 -T DC 01 00 00 80 DD AE B5 DD B6 B4 28 15 3E 40 +T 55 02 00 00 80 DD AE B5 DD B6 B4 28 15 3E 40 R 00 00 01 00 -T E7 01 00 00 DD AE B5 DD B6 B4 28 0B 3E 90 DD +T 60 02 00 00 DD AE B5 DD B6 B4 28 0B 3E 90 DD R 00 00 01 00 -T F2 01 00 00 AE B5 DD B6 B4 C2 F8 04 00 00 +T 6B 02 00 00 AE B5 DD B6 B4 C2 BC 05 00 00 R 00 00 01 00 00 0A 01 00 -T FA 01 00 00 +T 73 02 00 00 R 00 00 01 00 -T FA 01 00 00 +T 73 02 00 00 R 00 00 01 00 -T FA 01 00 00 +T 73 02 00 00 R 00 00 01 00 -T FA 01 00 00 DD 36 B8 12 DD 36 B9 00 +T 73 02 00 00 DD 36 B8 12 DD 36 B9 00 R 00 00 01 00 -T 02 02 00 00 +T 7B 02 00 00 R 00 00 01 00 -T 02 02 00 00 DD 4E B8 DD 46 B9 21 13 00 A7 ED +T 7B 02 00 00 DD 4E B8 DD 46 B9 21 13 00 A7 ED R 00 00 01 00 -T 0D 02 00 00 42 DA 3D 03 00 00 +T 86 02 00 00 42 DA D4 03 00 00 R 00 00 01 00 00 06 01 00 -T 11 02 00 00 +T 8A 02 00 00 R 00 00 01 00 -T 11 02 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 +T 8A 02 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 R 00 00 01 00 -T 1C 02 00 00 39 01 18 00 09 4D 44 E1 09 46 23 +T 95 02 00 00 39 01 18 00 09 4D 44 E1 09 46 23 R 00 00 01 00 -T 27 02 00 00 66 68 DD 75 BC DD 74 BD 7D B4 28 +T A0 02 00 00 66 68 DD 75 BC DD 74 BD 7D B4 28 R 00 00 01 00 -T 32 02 00 00 6C ED 4B 26 04 00 00 DD 6E BC DD +T AB 02 00 00 7B ED 4B 26 04 00 00 DD 6E BC DD R 00 00 01 00 00 07 03 00 -T 3B 02 00 00 66 BD A7 ED 42 38 0F ED 4B +T B4 02 00 00 66 BD A7 ED 42 38 0F ED 4B R 00 00 01 00 -T 44 02 00 00 0C 04 00 00 DD 6E BC DD 66 BD A7 +T BD 02 00 00 0C 04 00 00 DD 6E BC DD 66 BD A7 R 00 00 01 00 00 04 03 00 -T 4D 02 00 00 ED 42 38 4E +T C6 02 00 00 ED 42 38 5D R 00 00 01 00 -T 51 02 00 00 +T CA 02 00 00 R 00 00 01 00 -T 51 02 00 00 +T CA 02 00 00 R 00 00 01 00 -T 51 02 00 00 +T CA 02 00 00 R 00 00 01 00 -T 51 02 00 00 +T CA 02 00 00 R 00 00 01 00 -T 51 02 00 00 +T CA 02 00 00 R 00 00 01 00 -T 51 02 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD +T CA 02 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD R 00 00 01 00 -T 5C 02 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 +T D5 02 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 R 00 00 01 00 -T 67 02 00 00 5D 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 6E 02 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T 77 02 00 00 27 +T E0 02 00 00 5D 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T E6 02 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T ED 02 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T F2 02 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T F9 02 00 00 28 2C R 00 00 01 00 -T 78 02 00 00 +T FB 02 00 00 R 00 00 01 00 -T 78 02 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 +T FB 02 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 R 00 00 01 00 -T 83 02 00 00 39 01 18 00 09 4D 44 E1 09 AF 77 +T 06 03 00 00 39 01 18 00 09 4D 44 E1 09 AF 77 R 00 00 01 00 -T 8E 02 00 00 23 77 21 0E 00 39 4D 44 DD 5E B2 +T 11 03 00 00 23 77 21 0E 00 39 4D 44 DD 5E B2 R 00 00 01 00 -T 99 02 00 00 DD 56 B3 CD F9 14 00 00 -R 00 00 01 00 00 08 01 00 -T 9F 02 00 00 +T 1C 03 00 00 DD 56 B3 3E D9 17 00 00 21 +R 00 00 01 00 29 08 01 00 +T 22 03 00 00 D9 17 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 27 03 00 00 R 00 00 01 00 -T 9F 02 00 00 +T 27 03 00 00 R 00 00 01 00 -T 9F 02 00 00 DD 7E BC DD B6 BD 28 67 21 16 00 +T 27 03 00 00 DD 7E BC DD B6 BD 28 76 21 16 00 R 00 00 01 00 -T AA 02 00 00 39 5E 23 56 23 4E 23 46 EB 3E 09 +T 32 03 00 00 39 5E 23 56 23 4E 23 46 EB 3E 09 R 00 00 01 00 -T B5 02 00 00 CD 00 00 00 00 01 12 00 A7 ED 42 -R 00 00 01 00 02 05 1E 00 -T BE 02 00 00 30 4E +T 3D 03 00 00 CD 00 00 00 00 01 12 00 A7 ED 42 +R 00 00 01 00 02 05 20 00 +T 46 03 00 00 30 5D R 00 00 01 00 -T C0 02 00 00 +T 48 03 00 00 R 00 00 01 00 -T C0 02 00 00 +T 48 03 00 00 R 00 00 01 00 -T C0 02 00 00 +T 48 03 00 00 R 00 00 01 00 -T C0 02 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD +T 48 03 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD R 00 00 01 00 -T CB 02 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 +T 53 03 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 R 00 00 01 00 -T D6 02 00 00 A7 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T DD 02 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T E6 02 00 00 27 +T 5E 03 00 00 A7 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 64 03 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 6B 03 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 70 03 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 77 03 00 00 28 2C R 00 00 01 00 -T E7 02 00 00 +T 79 03 00 00 R 00 00 01 00 -T E7 02 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 +T 79 03 00 00 DD 6E B8 DD 66 B9 29 E5 21 10 00 R 00 00 01 00 -T F2 02 00 00 39 01 18 00 09 4D 44 E1 09 AF 77 +T 84 03 00 00 39 01 18 00 09 4D 44 E1 09 AF 77 R 00 00 01 00 -T FD 02 00 00 23 77 21 0E 00 39 4D 44 DD 5E B2 +T 8F 03 00 00 23 77 21 0E 00 39 4D 44 DD 5E B2 R 00 00 01 00 -T 08 03 00 00 DD 56 B3 CD F9 14 00 00 -R 00 00 01 00 00 08 01 00 -T 0E 03 00 00 +T 9A 03 00 00 DD 56 B3 3E D9 17 00 00 21 +R 00 00 01 00 29 08 01 00 +T A0 03 00 00 D9 17 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T A5 03 00 00 R 00 00 01 00 -T 0E 03 00 00 +T A5 03 00 00 R 00 00 01 00 -T 0E 03 00 00 DD 7E BC DD B6 BD 28 1C +T A5 03 00 00 DD 7E BC DD B6 BD 28 1C R 00 00 01 00 -T 16 03 00 00 +T AD 03 00 00 R 00 00 01 00 -T 16 03 00 00 06 03 DD 5E BC DD 56 BD CD +T AD 03 00 00 06 03 DD 5E BC DD 56 BD CD R 00 00 01 00 -T 1F 03 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T B6 03 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 26 03 00 00 7E BC E6 07 47 3E 01 CD +T BD 03 00 00 7E BC E6 07 47 3E 01 CD R 00 00 01 00 -T 2E 03 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T 32 03 00 00 +T C5 03 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T C9 03 00 00 R 00 00 01 00 -T 32 03 00 00 DD 34 B8 20 03 DD 34 B9 +T C9 03 00 00 DD 34 B8 20 03 DD 34 B9 R 00 00 01 00 -T 3A 03 00 00 +T D1 03 00 00 R 00 00 01 00 -T 3A 03 00 00 C3 02 02 00 00 +T D1 03 00 00 C3 7B 02 00 00 R 00 00 01 00 00 05 01 00 -T 3D 03 00 00 +T D4 03 00 00 R 00 00 01 00 -T 3D 03 00 00 DD 6E FE DD 66 FF 7D B4 CA +T D4 03 00 00 DD 6E FE DD 66 FF 7D B4 CA R 00 00 01 00 -T 46 03 00 00 18 04 00 00 +T DD 03 00 00 C3 04 00 00 R 00 00 01 00 00 04 01 00 -T 48 03 00 00 +T DF 03 00 00 R 00 00 01 00 -T 48 03 00 00 DD 5E FE DD 56 FF CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 51 03 00 00 DD 75 BE DD 74 BF AF DD 77 B8 DD +T DF 03 00 00 DD 5E FE DD 56 FF 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T E7 03 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T EE 03 00 00 75 BE DD 74 BF AF DD 77 B8 DD 77 R 00 00 01 00 -T 5C 03 00 00 77 B9 +T F9 03 00 00 B9 R 00 00 01 00 -T 5E 03 00 00 +T FA 03 00 00 R 00 00 01 00 -T 5E 03 00 00 01 00 01 DD 6E B8 DD 66 B9 A7 ED +T FA 03 00 00 01 00 01 DD 6E B8 DD 66 B9 A7 ED R 00 00 01 00 -T 69 03 00 00 42 D2 18 04 00 00 +T 05 04 00 00 42 D2 C3 04 00 00 R 00 00 01 00 00 06 01 00 -T 6D 03 00 00 +T 09 04 00 00 R 00 00 01 00 -T 6D 03 00 00 DD 6E B2 DD 66 B3 29 DD 4E BE DD +T 09 04 00 00 DD 6E B2 DD 66 B3 29 DD 4E BE DD R 00 00 01 00 -T 78 03 00 00 46 BF 09 46 23 66 68 DD 75 BC DD +T 14 04 00 00 46 BF 09 46 23 66 68 DD 75 BC DD R 00 00 01 00 -T 83 03 00 00 74 BD 7D B4 28 60 ED 4B +T 1F 04 00 00 74 BD 7D B4 28 6F ED 4B R 00 00 01 00 -T 8B 03 00 00 26 04 00 00 DD 6E BC DD 66 BD A7 +T 27 04 00 00 26 04 00 00 DD 6E BC DD 66 BD A7 R 00 00 01 00 00 04 03 00 -T 94 03 00 00 ED 42 38 0F ED 4B 0C 04 00 00 DD +T 30 04 00 00 ED 42 38 0F ED 4B 0C 04 00 00 DD R 00 00 01 00 00 0A 03 00 -T 9D 03 00 00 6E BC DD 66 BD A7 ED 42 38 42 +T 39 04 00 00 6E BC DD 66 BD A7 ED 42 38 51 R 00 00 01 00 -T A7 03 00 00 +T 43 04 00 00 R 00 00 01 00 -T A7 03 00 00 +T 43 04 00 00 R 00 00 01 00 -T A7 03 00 00 +T 43 04 00 00 R 00 00 01 00 -T A7 03 00 00 +T 43 04 00 00 R 00 00 01 00 -T A7 03 00 00 +T 43 04 00 00 R 00 00 01 00 -T A7 03 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD +T 43 04 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD R 00 00 01 00 -T B2 03 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 +T 4E 04 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 R 00 00 01 00 -T BD 03 00 00 F5 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T C4 03 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T CD 03 00 00 1B +T 59 04 00 00 F5 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 5F 04 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 66 04 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 6B 04 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 72 04 00 00 28 20 R 00 00 01 00 -T CE 03 00 00 +T 74 04 00 00 R 00 00 01 00 -T CE 03 00 00 DD 6E B8 DD 66 B9 29 DD 4E BE DD +T 74 04 00 00 DD 6E B8 DD 66 B9 29 DD 4E BE DD R 00 00 01 00 -T D9 03 00 00 46 BF 09 AF 77 23 77 DD 5E B8 DD +T 7F 04 00 00 46 BF 09 AF 77 23 77 DD 5E B8 DD R 00 00 01 00 -T E4 03 00 00 56 B9 CD 8B 14 00 00 -R 00 00 01 00 00 07 01 00 -T E9 03 00 00 +T 8A 04 00 00 56 B9 3E 52 17 00 00 21 +R 00 00 01 00 29 07 01 00 +T 8F 04 00 00 52 17 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 94 04 00 00 R 00 00 01 00 -T E9 03 00 00 +T 94 04 00 00 R 00 00 01 00 -T E9 03 00 00 DD 7E BC DD B6 BD 28 1C +T 94 04 00 00 DD 7E BC DD B6 BD 28 1C R 00 00 01 00 -T F1 03 00 00 +T 9C 04 00 00 R 00 00 01 00 -T F1 03 00 00 06 03 DD 5E BC DD 56 BD CD +T 9C 04 00 00 06 03 DD 5E BC DD 56 BD CD R 00 00 01 00 -T FA 03 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T A5 04 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 01 04 00 00 7E BC E6 07 47 3E 01 CD +T AC 04 00 00 7E BC E6 07 47 3E 01 CD R 00 00 01 00 -T 09 04 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T 0D 04 00 00 +T B4 04 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T B8 04 00 00 R 00 00 01 00 -T 0D 04 00 00 DD 34 B8 20 03 DD 34 B9 +T B8 04 00 00 DD 34 B8 20 03 DD 34 B9 R 00 00 01 00 -T 15 04 00 00 +T C0 04 00 00 R 00 00 01 00 -T 15 04 00 00 C3 5E 03 00 00 +T C0 04 00 00 C3 FA 03 00 00 R 00 00 01 00 00 05 01 00 -T 18 04 00 00 +T C3 04 00 00 R 00 00 01 00 -T 18 04 00 00 +T C3 04 00 00 R 00 00 01 00 -T 18 04 00 00 AF DD 77 B8 DD 77 B9 21 16 00 39 +T C3 04 00 00 AF DD 77 B8 DD 77 B9 21 16 00 39 R 00 00 01 00 -T 23 04 00 00 5E 23 56 23 4E 23 46 EB 3E 09 CD +T CE 04 00 00 5E 23 56 23 4E 23 46 EB 3E 09 CD R 00 00 01 00 -T 2E 04 00 00 00 00 00 00 DD 75 BA DD 74 BB -R 00 00 01 00 02 04 1E 00 -T 36 04 00 00 +T D9 04 00 00 00 00 00 00 DD 75 BA DD 74 BB +R 00 00 01 00 02 04 20 00 +T E1 04 00 00 R 00 00 01 00 -T 36 04 00 00 DD 4E B8 DD 46 B9 DD 6E BA DD 66 +T E1 04 00 00 DD 4E B8 DD 46 B9 DD 6E BA DD 66 R 00 00 01 00 -T 41 04 00 00 BB A7 ED 42 DA F8 04 00 00 +T EC 04 00 00 BB A7 ED 42 DA BC 05 00 00 R 00 00 01 00 00 09 01 00 -T 48 04 00 00 +T F3 04 00 00 R 00 00 01 00 -T 48 04 00 00 DD 4E B8 DD 46 B9 21 0E 00 39 5D +T F3 04 00 00 DD 4E B8 DD 46 B9 21 0E 00 39 5D R 00 00 01 00 -T 53 04 00 00 54 CD 88 11 00 00 DD 75 BC DD 74 -R 00 00 01 00 00 06 01 00 -T 5C 04 00 00 BD 7D B4 28 68 ED 4B 26 04 00 00 -R 00 00 01 00 00 0B 03 00 -T 65 04 00 00 DD 6E BC DD 66 BD A7 ED 42 38 0F +T FE 04 00 00 54 3E EF 13 00 00 21 EF 13 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 04 05 00 00 CD 00 00 00 00 DD 75 BC DD 74 BD +R 00 00 01 00 02 05 14 00 +T 0D 05 00 00 7D B4 28 7C ED 4B 26 04 00 00 DD +R 00 00 01 00 00 0A 03 00 +T 16 05 00 00 6E BC DD 66 BD A7 ED 42 38 0F ED R 00 00 01 00 -T 70 04 00 00 ED 4B 0C 04 00 00 DD 6E BC DD 66 -R 00 00 01 00 00 06 03 00 -T 79 04 00 00 BD A7 ED 42 38 4A +T 21 05 00 00 4B 0C 04 00 00 DD 6E BC DD 66 BD +R 00 00 01 00 00 05 03 00 +T 2A 05 00 00 A7 ED 42 38 5E R 00 00 01 00 -T 7F 04 00 00 +T 2F 05 00 00 R 00 00 01 00 -T 7F 04 00 00 +T 2F 05 00 00 R 00 00 01 00 -T 7F 04 00 00 +T 2F 05 00 00 R 00 00 01 00 -T 7F 04 00 00 +T 2F 05 00 00 R 00 00 01 00 -T 7F 04 00 00 +T 2F 05 00 00 R 00 00 01 00 -T 7F 04 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD +T 2F 05 00 00 DD 6E BC DD 66 BD E5 DD 6E B8 DD R 00 00 01 00 -T 8A 04 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 +T 3A 05 00 00 66 B9 E5 DD 6E B2 DD 66 B3 E5 21 R 00 00 01 00 -T 95 04 00 00 3F 01 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 9C 04 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T A5 04 00 00 23 +T 45 05 00 00 3F 01 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 4B 05 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 52 05 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 57 05 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 5E 05 00 00 28 2D R 00 00 01 00 -T A6 04 00 00 +T 60 05 00 00 R 00 00 01 00 -T A6 04 00 00 21 00 00 E5 DD 4E B8 DD 46 B9 21 +T 60 05 00 00 21 00 00 E5 DD 4E B8 DD 46 B9 21 R 00 00 01 00 -T B1 04 00 00 10 00 39 5D 54 CD 75 12 00 00 E1 -R 00 00 01 00 00 0A 01 00 -T BA 04 00 00 21 0E 00 39 4D 44 DD 5E B2 DD 56 +T 6B 05 00 00 10 00 39 5D 54 3E EB 14 00 00 21 +R 00 00 01 00 29 0A 01 00 +T 73 05 00 00 EB 14 00 00 CD 00 00 00 00 E1 21 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 7A 05 00 00 0E 00 39 4D 44 DD 5E B2 DD 56 B3 R 00 00 01 00 -T C5 04 00 00 B3 CD F9 14 00 00 -R 00 00 01 00 00 06 01 00 -T C9 04 00 00 +T 85 05 00 00 3E D9 17 00 00 21 D9 17 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 8B 05 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 8D 05 00 00 R 00 00 01 00 -T C9 04 00 00 +T 8D 05 00 00 R 00 00 01 00 -T C9 04 00 00 DD 7E BC DD B6 BD 28 1C +T 8D 05 00 00 DD 7E BC DD B6 BD 28 1C R 00 00 01 00 -T D1 04 00 00 +T 95 05 00 00 R 00 00 01 00 -T D1 04 00 00 06 03 DD 5E BC DD 56 BD CD +T 95 05 00 00 06 03 DD 5E BC DD 56 BD CD R 00 00 01 00 -T DA 04 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 9E 05 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T E1 04 00 00 7E BC E6 07 47 3E 01 CD +T A5 05 00 00 7E BC E6 07 47 3E 01 CD R 00 00 01 00 -T E9 04 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T ED 04 00 00 +T AD 05 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T B1 05 00 00 R 00 00 01 00 -T ED 04 00 00 DD 34 B8 20 03 DD 34 B9 +T B1 05 00 00 DD 34 B8 20 03 DD 34 B9 R 00 00 01 00 -T F5 04 00 00 +T B9 05 00 00 R 00 00 01 00 -T F5 04 00 00 C3 36 04 00 00 +T B9 05 00 00 C3 E1 04 00 00 R 00 00 01 00 00 05 01 00 -T F8 04 00 00 +T BC 05 00 00 R 00 00 01 00 -T F8 04 00 00 +T BC 05 00 00 R 00 00 01 00 -T F8 04 00 00 +T BC 05 00 00 R 00 00 01 00 -T F8 04 00 00 DD 34 B2 20 03 DD 34 B3 +T BC 05 00 00 DD 34 B2 20 03 DD 34 B3 R 00 00 01 00 -T 00 05 00 00 +T C4 05 00 00 R 00 00 01 00 -T 00 05 00 00 C3 FA 00 00 00 +T C4 05 00 00 C3 5E 01 00 00 R 00 00 01 00 00 05 01 00 -T 03 05 00 00 +T C7 05 00 00 R 00 00 01 00 -T 03 05 00 00 DD 4E B6 DD 46 B7 2A 24 04 00 00 +T C7 05 00 00 DD 4E B6 DD 46 B7 2A 24 04 00 00 R 00 00 01 00 00 0B 03 00 -T 0C 05 00 00 A7 ED 42 01 FF FF 09 DD 75 B8 DD +T D0 05 00 00 A7 ED 42 01 FF FF 09 DD 75 B8 DD R 00 00 01 00 -T 17 05 00 00 74 B9 ED 4B 10 04 00 00 A7 ED 42 +T DB 05 00 00 74 B9 ED 4B 10 04 00 00 A7 ED 42 R 00 00 01 00 00 08 03 00 -T 20 05 00 00 28 31 +T E4 05 00 00 28 40 R 00 00 01 00 -T 22 05 00 00 +T E6 05 00 00 R 00 00 01 00 -T 22 05 00 00 DD 6E B8 DD 66 B9 E5 21 +T E6 05 00 00 DD 6E B8 DD 66 B9 E5 21 R 00 00 01 00 -T 2A 05 00 00 10 04 00 00 4E 23 46 C5 21 +T EE 05 00 00 10 04 00 00 4E 23 46 C5 21 R 00 00 01 00 00 04 03 00 -T 31 05 00 00 79 01 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 38 05 00 00 F1 F1 CD 28 16 00 00 7D B4 28 12 -R 00 00 01 00 00 07 01 00 -T 41 05 00 00 -R 00 00 01 00 -T 41 05 00 00 DD 6E B8 DD 66 B9 22 10 04 00 00 +T F5 05 00 00 79 01 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T FB 05 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 02 06 00 00 F1 3E 44 19 00 00 21 44 19 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 08 06 00 00 CD 00 00 00 00 7D B4 28 17 +R 00 00 01 00 02 05 14 00 +T 0F 06 00 00 +R 00 00 01 00 +T 0F 06 00 00 DD 6E B8 DD 66 B9 22 10 04 00 00 R 00 00 01 00 00 0B 03 00 -T 4A 05 00 00 01 06 04 00 00 11 01 00 CD +T 18 06 00 00 01 06 04 00 00 11 01 00 3E R 00 00 01 00 00 05 03 00 -T 51 05 00 00 8B 14 00 00 -R 00 00 01 00 00 04 01 00 -T 53 05 00 00 +T 1F 06 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 24 06 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 26 06 00 00 R 00 00 01 00 -T 53 05 00 00 +T 26 06 00 00 R 00 00 01 00 -T 53 05 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 56 05 00 00 +T 26 06 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 29 06 00 00 R 00 00 01 00 -T 56 05 00 00 CD 00 00 00 00 F0 FF 2A -R 00 00 01 00 02 05 18 00 -T 5C 05 00 00 0E 04 00 00 DD 75 F6 DD 74 F7 2A +T 29 06 00 00 CD 00 00 00 00 F0 FF 2A +R 00 00 01 00 02 05 19 00 +T 2F 06 00 00 0E 04 00 00 DD 75 F6 DD 74 F7 2A R 00 00 01 00 00 04 03 00 -T 65 05 00 00 10 04 00 00 DD 75 F8 DD 74 F9 21 +T 38 06 00 00 10 04 00 00 DD 75 F8 DD 74 F9 21 R 00 00 01 00 00 04 03 00 -T 6E 05 00 00 B3 01 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 75 05 00 00 CD 28 16 00 00 7D B4 20 03 -R 00 00 01 00 00 05 01 00 -T 7C 05 00 00 -R 00 00 01 00 -T 7C 05 00 00 C3 CD 07 00 00 +T 41 06 00 00 B3 01 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 47 06 00 00 00 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 4E 06 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 53 06 00 00 00 00 00 00 7D B4 20 03 +R 00 00 01 00 02 04 14 00 +T 59 06 00 00 +R 00 00 01 00 +T 59 06 00 00 C3 CD 08 00 00 R 00 00 01 00 00 05 01 00 -T 7F 05 00 00 +T 5C 06 00 00 R 00 00 01 00 -T 7F 05 00 00 2A 16 04 00 00 DD 75 FA DD 74 FB +T 5C 06 00 00 2A 16 04 00 00 DD 75 FA DD 74 FB R 00 00 01 00 00 05 03 00 -T 88 05 00 00 2A 18 04 00 00 DD 75 FC DD 74 FD +T 65 06 00 00 2A 18 04 00 00 DD 75 FC DD 74 FD R 00 00 01 00 00 05 03 00 -T 91 05 00 00 2A 1A 04 00 00 DD 75 FE DD 74 FF +T 6E 06 00 00 2A 1A 04 00 00 DD 75 FE DD 74 FF R 00 00 01 00 00 05 03 00 -T 9A 05 00 00 AF DD 77 F2 DD 77 F3 +T 77 06 00 00 AF DD 77 F2 DD 77 F3 R 00 00 01 00 -T A1 05 00 00 +T 7E 06 00 00 R 00 00 01 00 -T A1 05 00 00 2A 0A 04 00 00 ED 4B 26 04 00 00 +T 7E 06 00 00 2A 0A 04 00 00 ED 4B 26 04 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T A8 05 00 00 09 4D 44 DD 6E F2 DD 66 F3 A7 ED +T 85 06 00 00 09 4D 44 DD 6E F2 DD 66 F3 A7 ED R 00 00 01 00 -T B3 05 00 00 42 30 26 +T 90 06 00 00 42 30 26 R 00 00 01 00 -T B6 05 00 00 +T 93 06 00 00 R 00 00 01 00 -T B6 05 00 00 06 03 DD 5E F2 DD 56 F3 CD +T 93 06 00 00 06 03 DD 5E F2 DD 56 F3 CD R 00 00 01 00 -T BF 05 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 9C 06 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T C6 05 00 00 7E F2 E6 07 47 3E 01 CD +T A3 06 00 00 7E F2 E6 07 47 3E 01 CD R 00 00 01 00 -T CE 05 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 -R 00 00 01 00 02 04 1D 00 -T D7 05 00 00 DD 34 F3 +T AB 06 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 +R 00 00 01 00 02 04 1E 00 +T B4 06 00 00 DD 34 F3 R 00 00 01 00 -T DA 05 00 00 +T B7 06 00 00 R 00 00 01 00 -T DA 05 00 00 18 C5 +T B7 06 00 00 18 C5 R 00 00 01 00 -T DC 05 00 00 +T B9 06 00 00 R 00 00 01 00 -T DC 05 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 +T B9 06 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 R 00 00 01 00 -T E7 05 00 00 FF A7 ED 42 29 29 29 DD 75 F4 DD +T C4 06 00 00 FF A7 ED 42 29 29 29 DD 75 F4 DD R 00 00 01 00 -T F2 05 00 00 74 F5 2A 0C 04 00 00 DD 75 F2 DD +T CF 06 00 00 74 F5 2A 0C 04 00 00 DD 75 F2 DD R 00 00 01 00 00 07 03 00 -T FB 05 00 00 74 F3 +T D8 06 00 00 74 F3 R 00 00 01 00 -T FD 05 00 00 +T DA 06 00 00 R 00 00 01 00 -T FD 05 00 00 DD 6E F4 DD 66 F5 DD 4E F2 DD 46 +T DA 06 00 00 DD 6E F4 DD 66 F5 DD 4E F2 DD 46 R 00 00 01 00 -T 08 06 00 00 F3 A7 ED 42 28 26 +T E5 06 00 00 F3 A7 ED 42 28 26 R 00 00 01 00 -T 0E 06 00 00 +T EB 06 00 00 R 00 00 01 00 -T 0E 06 00 00 06 03 DD 5E F2 DD 56 F3 CD +T EB 06 00 00 06 03 DD 5E F2 DD 56 F3 CD R 00 00 01 00 -T 17 06 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T F4 06 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 1E 06 00 00 7E F2 E6 07 47 3E 01 CD +T FB 06 00 00 7E F2 E6 07 47 3E 01 CD R 00 00 01 00 -T 26 06 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 -R 00 00 01 00 02 04 1D 00 -T 2F 06 00 00 DD 34 F3 +T 03 07 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 +R 00 00 01 00 02 04 1E 00 +T 0C 07 00 00 DD 34 F3 R 00 00 01 00 -T 32 06 00 00 +T 0F 07 00 00 R 00 00 01 00 -T 32 06 00 00 18 C9 +T 0F 07 00 00 18 C9 R 00 00 01 00 -T 34 06 00 00 +T 11 07 00 00 R 00 00 01 00 -T 34 06 00 00 21 00 00 22 0E 04 00 00 2A +T 11 07 00 00 21 00 00 22 0E 04 00 00 2A R 00 00 01 00 00 08 03 00 -T 3B 06 00 00 0A 04 00 00 ED 4B 26 04 00 00 09 +T 18 07 00 00 0A 04 00 00 ED 4B 26 04 00 00 09 R 00 00 01 00 00 04 03 00 00 0A 03 00 -T 42 06 00 00 DD 75 F2 DD 74 F3 +T 1F 07 00 00 DD 75 F2 DD 74 F3 R 00 00 01 00 -T 48 06 00 00 +T 25 07 00 00 R 00 00 01 00 -T 48 06 00 00 ED 4B 0C 04 00 00 DD 6E F2 DD 66 +T 25 07 00 00 ED 4B 0C 04 00 00 DD 6E F2 DD 66 R 00 00 01 00 00 06 03 00 -T 51 06 00 00 F3 A7 ED 42 30 2E +T 2E 07 00 00 F3 A7 ED 42 30 2E R 00 00 01 00 -T 57 06 00 00 +T 34 07 00 00 R 00 00 01 00 -T 57 06 00 00 06 03 DD 5E F2 DD 56 F3 CD +T 34 07 00 00 06 03 DD 5E F2 DD 56 F3 CD R 00 00 01 00 -T 60 06 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 3D 07 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 67 06 00 00 7E F2 E6 07 47 3E 01 CD +T 44 07 00 00 7E F2 E6 07 47 3E 01 CD R 00 00 01 00 -T 6F 06 00 00 00 00 00 00 A6 20 07 -R 00 00 01 00 02 04 1D 00 -T 74 06 00 00 +T 4C 07 00 00 00 00 00 00 A6 20 07 +R 00 00 01 00 02 04 1E 00 +T 51 07 00 00 R 00 00 01 00 -T 74 06 00 00 2A 0E 04 00 00 23 22 0E 04 00 00 +T 51 07 00 00 2A 0E 04 00 00 23 22 0E 04 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T 7B 06 00 00 +T 58 07 00 00 R 00 00 01 00 -T 7B 06 00 00 DD 34 F2 20 03 DD 34 F3 +T 58 07 00 00 DD 34 F2 20 03 DD 34 F3 R 00 00 01 00 -T 83 06 00 00 +T 60 07 00 00 R 00 00 01 00 -T 83 06 00 00 18 C3 +T 60 07 00 00 18 C3 R 00 00 01 00 -T 85 06 00 00 +T 62 07 00 00 R 00 00 01 00 -T 85 06 00 00 DD 6E FE DD 66 FF 01 00 00 C5 E5 +T 62 07 00 00 DD 6E FE DD 66 FF 01 00 00 C5 E5 R 00 00 01 00 -T 90 06 00 00 DD 6E FC DD 66 FD 01 00 00 C5 E5 +T 6D 07 00 00 DD 6E FC DD 66 FD 01 00 00 C5 E5 R 00 00 01 00 -T 9B 06 00 00 ED 5B 36 04 00 00 CD 27 19 00 00 -R 00 00 01 00 00 06 03 00 00 0B 01 00 -T A2 06 00 00 E1 E1 E1 E1 2A 34 04 00 00 7E F6 -R 00 00 01 00 00 09 03 00 -T AB 06 00 00 01 77 2A 34 04 00 00 7E F6 02 77 -R 00 00 01 00 00 07 03 00 -T B4 06 00 00 DD 36 F2 02 DD 36 F3 00 +T 78 07 00 00 ED 5B 36 04 00 00 3E 39 1D 00 00 +R 00 00 01 00 00 06 03 00 29 0B 01 00 +T 7E 07 00 00 21 39 1D 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 85 07 00 00 E1 E1 E1 2A 34 04 00 00 7E F6 01 +R 00 00 01 00 00 08 03 00 +T 8E 07 00 00 77 2A 34 04 00 00 7E F6 02 77 DD +R 00 00 01 00 00 06 03 00 +T 97 07 00 00 36 F2 02 DD 36 F3 00 R 00 00 01 00 -T BC 06 00 00 +T 9E 07 00 00 R 00 00 01 00 -T BC 06 00 00 ED 4B 24 04 00 00 DD 6E F2 DD 66 +T 9E 07 00 00 ED 4B 24 04 00 00 DD 6E F2 DD 66 R 00 00 01 00 00 06 03 00 -T C5 06 00 00 F3 A7 ED 42 30 35 +T A7 07 00 00 F3 A7 ED 42 30 35 R 00 00 01 00 -T CB 06 00 00 +T AD 07 00 00 R 00 00 01 00 -T CB 06 00 00 DD 6E F2 DD 66 F3 ED 4B +T AD 07 00 00 DD 6E F2 DD 66 F3 ED 4B R 00 00 01 00 -T D3 06 00 00 38 04 00 00 09 46 04 28 1C +T B5 07 00 00 38 04 00 00 09 46 04 28 1C R 00 00 01 00 00 04 03 00 -T DA 06 00 00 +T BC 07 00 00 R 00 00 01 00 -T DA 06 00 00 06 03 DD 5E F2 DD 56 F3 CD +T BC 07 00 00 06 03 DD 5E F2 DD 56 F3 CD R 00 00 01 00 -T E3 06 00 00 00 00 00 00 2A 34 04 00 00 19 DD +T C5 07 00 00 00 00 00 00 2A 34 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T EA 06 00 00 7E F2 E6 07 47 3E 01 CD +T CC 07 00 00 7E F2 E6 07 47 3E 01 CD R 00 00 01 00 -T F2 06 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T F6 06 00 00 +T D4 07 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T D8 07 00 00 R 00 00 01 00 -T F6 06 00 00 DD 34 F2 20 03 DD 34 F3 +T D8 07 00 00 DD 34 F2 20 03 DD 34 F3 R 00 00 01 00 -T FE 06 00 00 +T E0 07 00 00 R 00 00 01 00 -T FE 06 00 00 18 BC +T E0 07 00 00 18 BC R 00 00 01 00 -T 00 07 00 00 +T E2 07 00 00 R 00 00 01 00 -T 00 07 00 00 DD 4E FA DD 46 FB DD 6E FC DD 66 +T E2 07 00 00 DD 4E FA DD 46 FB DD 6E FC DD 66 R 00 00 01 00 -T 0B 07 00 00 FD A7 ED 42 29 29 29 DD 75 F4 DD +T ED 07 00 00 FD A7 ED 42 29 29 29 DD 75 F4 DD R 00 00 01 00 -T 16 07 00 00 74 F5 2A 0A 04 00 00 29 29 29 DD +T F8 07 00 00 74 F5 2A 0A 04 00 00 29 29 29 DD R 00 00 01 00 00 07 03 00 -T 1F 07 00 00 75 F2 DD 74 F3 +T 01 08 00 00 75 F2 DD 74 F3 R 00 00 01 00 -T 24 07 00 00 +T 06 08 00 00 R 00 00 01 00 -T 24 07 00 00 DD 6E F4 DD 66 F5 DD 4E F2 DD 46 +T 06 08 00 00 DD 6E F4 DD 66 F5 DD 4E F2 DD 46 R 00 00 01 00 -T 2F 07 00 00 F3 A7 ED 42 28 26 +T 11 08 00 00 F3 A7 ED 42 28 26 R 00 00 01 00 -T 35 07 00 00 +T 17 08 00 00 R 00 00 01 00 -T 35 07 00 00 06 03 DD 5E F2 DD 56 F3 CD +T 17 08 00 00 06 03 DD 5E F2 DD 56 F3 CD R 00 00 01 00 -T 3E 07 00 00 00 00 00 00 2A 34 04 00 00 19 DD +T 20 08 00 00 00 00 00 00 2A 34 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 45 07 00 00 7E F2 E6 07 47 3E 01 CD +T 27 08 00 00 7E F2 E6 07 47 3E 01 CD R 00 00 01 00 -T 4D 07 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 -R 00 00 01 00 02 04 1D 00 -T 56 07 00 00 DD 34 F3 +T 2F 08 00 00 00 00 00 00 B6 77 DD 34 F2 20 03 +R 00 00 01 00 02 04 1E 00 +T 38 08 00 00 DD 34 F3 R 00 00 01 00 -T 59 07 00 00 +T 3B 08 00 00 R 00 00 01 00 -T 59 07 00 00 18 C9 +T 3B 08 00 00 18 C9 R 00 00 01 00 -T 5B 07 00 00 +T 3D 08 00 00 R 00 00 01 00 -T 5B 07 00 00 DD 6E FC DD 66 FD 01 00 00 C5 E5 +T 3D 08 00 00 DD 6E FC DD 66 FD 01 00 00 C5 E5 R 00 00 01 00 -T 66 07 00 00 DD 6E FA DD 66 FB 01 00 00 C5 E5 +T 48 08 00 00 DD 6E FA DD 66 FB 01 00 00 C5 E5 R 00 00 01 00 -T 71 07 00 00 ED 5B 34 04 00 00 CD 27 19 00 00 -R 00 00 01 00 00 06 03 00 00 0B 01 00 -T 78 07 00 00 E1 E1 E1 E1 11 04 00 CD +T 53 08 00 00 ED 5B 34 04 00 00 3E 39 1D 00 00 +R 00 00 01 00 00 06 03 00 29 0B 01 00 +T 59 08 00 00 21 39 1D 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 60 08 00 00 E1 E1 E1 11 04 00 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 68 08 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 6F 08 00 00 75 F0 DD 74 F1 01 1E 00 C5 4D 44 R 00 00 01 00 -T 80 07 00 00 5B 14 00 00 DD 75 F0 DD 74 F1 01 -R 00 00 01 00 00 04 01 00 -T 89 07 00 00 1E 00 C5 4D 44 11 06 04 00 00 CD -R 00 00 01 00 00 0A 03 00 -T 92 07 00 00 00 00 00 00 E1 DD 4E F0 DD 46 F1 -R 00 00 01 00 02 04 11 00 -T 9B 07 00 00 11 04 00 CD 8B 14 00 00 2A -R 00 00 01 00 00 08 01 00 -T A2 07 00 00 0E 04 00 00 DD 4E F6 DD 46 F7 A7 -R 00 00 01 00 00 04 03 00 -T AB 07 00 00 ED 42 28 1E +T 7A 08 00 00 11 06 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 03 00 2B 0A 11 00 +T 80 08 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T 87 08 00 00 4E F0 DD 46 F1 11 04 00 3E R 00 00 01 00 -T AF 07 00 00 +T 90 08 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 95 08 00 00 00 00 00 00 2A 0E 04 00 00 DD 4E +R 00 00 01 00 02 04 14 00 00 09 03 00 +T 9C 08 00 00 F6 DD 46 F7 A7 ED 42 28 28 R 00 00 01 00 -T AF 07 00 00 DD 6E F6 DD 66 F7 E5 21 +T A5 08 00 00 R 00 00 01 00 -T B7 07 00 00 0E 04 00 00 4E 23 46 C5 21 +T A5 08 00 00 DD 6E F6 DD 66 F7 E5 21 +R 00 00 01 00 +T AD 08 00 00 0E 04 00 00 4E 23 46 C5 21 R 00 00 01 00 00 04 03 00 -T BE 07 00 00 D2 01 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T C5 07 00 00 F1 F1 11 00 00 00 00 CD -R 00 00 01 00 02 07 14 00 -T CB 07 00 00 00 00 00 00 -R 00 00 01 00 02 04 04 00 -T CD 07 00 00 -R 00 00 01 00 -T CD 07 00 00 -R 00 00 01 00 -T CD 07 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T D0 07 00 00 -R 00 00 01 00 -T D0 07 00 00 CD 00 00 00 00 B4 FF 2A -R 00 00 01 00 02 05 18 00 -T D6 07 00 00 26 04 00 00 DD 75 F8 DD 74 F9 +T B4 08 00 00 D2 01 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T BA 08 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T C1 08 00 00 F1 11 00 00 00 00 3E 00 00 00 00 +R 00 00 01 00 02 06 15 00 2B 0B 04 00 +T C7 08 00 00 21 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 04 00 02 0A 14 00 +T CD 08 00 00 +R 00 00 01 00 +T CD 08 00 00 +R 00 00 01 00 +T CD 08 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T D0 08 00 00 +R 00 00 01 00 +T D0 08 00 00 CD 00 00 00 00 B4 FF 2A +R 00 00 01 00 02 05 19 00 +T D6 08 00 00 26 04 00 00 DD 75 F8 DD 74 F9 R 00 00 01 00 00 04 03 00 -T DE 07 00 00 +T DE 08 00 00 R 00 00 01 00 -T DE 07 00 00 ED 4B 0C 04 00 00 DD 6E F8 DD 66 +T DE 08 00 00 ED 4B 0C 04 00 00 DD 6E F8 DD 66 R 00 00 01 00 00 06 03 00 -T E7 07 00 00 F9 A7 ED 42 30 27 +T E7 08 00 00 F9 A7 ED 42 30 27 R 00 00 01 00 -T ED 07 00 00 +T ED 08 00 00 R 00 00 01 00 -T ED 07 00 00 06 03 DD 5E F8 DD 56 F9 CD +T ED 08 00 00 06 03 DD 5E F8 DD 56 F9 CD R 00 00 01 00 -T F6 07 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T F6 08 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T FD 07 00 00 7E F8 E6 07 47 3E 01 CD +T FD 08 00 00 7E F8 E6 07 47 3E 01 CD R 00 00 01 00 -T 05 08 00 00 00 00 00 00 2F A6 77 DD 34 F8 20 -R 00 00 01 00 02 04 1D 00 -T 0E 08 00 00 03 DD 34 F9 +T 05 09 00 00 00 00 00 00 2F A6 77 DD 34 F8 20 +R 00 00 01 00 02 04 1E 00 +T 0E 09 00 00 03 DD 34 F9 R 00 00 01 00 -T 12 08 00 00 +T 12 09 00 00 R 00 00 01 00 -T 12 08 00 00 18 CA +T 12 09 00 00 18 CA R 00 00 01 00 -T 14 08 00 00 +T 14 09 00 00 R 00 00 01 00 -T 14 08 00 00 DD 36 B4 01 DD 36 B5 00 +T 14 09 00 00 DD 36 B4 01 DD 36 B5 00 R 00 00 01 00 -T 1C 08 00 00 +T 1C 09 00 00 R 00 00 01 00 -T 1C 08 00 00 ED 4B 24 04 00 00 DD 6E B4 DD 66 +T 1C 09 00 00 ED 4B 24 04 00 00 DD 6E B4 DD 66 R 00 00 01 00 00 06 03 00 -T 25 08 00 00 B5 A7 ED 42 D2 9B 0A 00 00 +T 25 09 00 00 B5 A7 ED 42 D2 FA 0B 00 00 R 00 00 01 00 00 09 01 00 -T 2C 08 00 00 +T 2C 09 00 00 R 00 00 01 00 -T 2C 08 00 00 21 04 00 39 4D 44 DD 5E B4 DD 56 +T 2C 09 00 00 21 04 00 39 4D 44 DD 5E B4 DD 56 R 00 00 01 00 -T 37 08 00 00 B5 CD B5 14 00 00 DD 7E B8 E6 00 -R 00 00 01 00 00 06 01 00 -T 40 08 00 00 6F DD 7E B9 E6 F0 67 DD 75 B6 DD +T 37 09 00 00 B5 3E 8B 17 00 00 21 8B 17 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 3D 09 00 00 CD 00 00 00 00 DD 7E B8 E6 00 6F +R 00 00 01 00 02 05 14 00 +T 46 09 00 00 DD 7E B9 E6 F0 67 DD 75 B6 DD 74 R 00 00 01 00 -T 4B 08 00 00 74 B7 3E A0 AC B5 28 21 3E 80 DD +T 51 09 00 00 B7 3E A0 AC B5 28 21 3E 80 DD AE R 00 00 01 00 -T 56 08 00 00 AE B7 DD B6 B6 28 17 3E 40 DD AE +T 5C 09 00 00 B7 DD B6 B6 28 17 3E 40 DD AE B7 R 00 00 01 00 -T 61 08 00 00 B7 DD B6 B6 28 0D 3E 90 DD AE B7 +T 67 09 00 00 DD B6 B6 28 0D 3E 90 DD AE B7 DD R 00 00 01 00 -T 6C 08 00 00 DD B6 B6 28 03 +T 72 09 00 00 B6 B6 28 03 R 00 00 01 00 -T 71 08 00 00 +T 76 09 00 00 R 00 00 01 00 -T 71 08 00 00 +T 76 09 00 00 R 00 00 01 00 -T 71 08 00 00 +T 76 09 00 00 R 00 00 01 00 -T 71 08 00 00 C3 90 0A 00 00 +T 76 09 00 00 C3 EF 0B 00 00 R 00 00 01 00 00 05 01 00 -T 74 08 00 00 +T 79 09 00 00 R 00 00 01 00 -T 74 08 00 00 DD 36 F8 12 DD 36 F9 00 +T 79 09 00 00 DD 36 F8 12 DD 36 F9 00 R 00 00 01 00 -T 7C 08 00 00 +T 81 09 00 00 R 00 00 01 00 -T 7C 08 00 00 DD 4E F8 DD 46 F9 21 13 00 A7 ED +T 81 09 00 00 DD 4E F8 DD 46 F9 21 13 00 A7 ED R 00 00 01 00 -T 87 08 00 00 42 DA 7C 09 00 00 +T 8C 09 00 00 42 DA A9 0A 00 00 R 00 00 01 00 00 06 01 00 -T 8B 08 00 00 +T 90 09 00 00 R 00 00 01 00 -T 8B 08 00 00 DD 6E F8 DD 66 F9 29 E5 21 06 00 +T 90 09 00 00 DD 6E F8 DD 66 F9 29 E5 21 06 00 R 00 00 01 00 -T 96 08 00 00 39 01 18 00 09 4D 44 E1 09 46 23 +T 9B 09 00 00 39 01 18 00 09 4D 44 E1 09 46 23 R 00 00 01 00 -T A1 08 00 00 66 68 DD 75 FC DD 74 FD 7D B4 CA +T A6 09 00 00 66 68 DD 75 FC DD 74 FD 7D B4 CA R 00 00 01 00 -T AC 08 00 00 71 09 00 00 +T B1 09 00 00 9E 0A 00 00 R 00 00 01 00 00 04 01 00 -T AE 08 00 00 +T B3 09 00 00 R 00 00 01 00 -T AE 08 00 00 06 03 DD 5E FC DD 56 FD CD +T B3 09 00 00 06 03 DD 5E FC DD 56 FD CD R 00 00 01 00 -T B7 08 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T BC 09 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T BE 08 00 00 7E FC E6 07 47 3E 01 CD +T C3 09 00 00 7E FC E6 07 47 3E 01 CD R 00 00 01 00 -T C6 08 00 00 00 00 00 00 A6 CA 55 09 00 00 -R 00 00 01 00 02 04 1D 00 00 0A 01 00 -T CC 08 00 00 +T CB 09 00 00 00 00 00 00 A6 CA 82 0A 00 00 +R 00 00 01 00 02 04 1E 00 00 0A 01 00 +T D1 09 00 00 R 00 00 01 00 -T CC 08 00 00 DD 6E FC DD 66 FD E5 DD 6E B4 DD +T D1 09 00 00 DD 6E FC DD 66 FD E5 DD 6E B4 DD R 00 00 01 00 -T D7 08 00 00 66 B5 E5 DD 6E F8 DD 66 F9 E5 21 +T DC 09 00 00 66 B5 E5 DD 6E F8 DD 66 F9 E5 21 R 00 00 01 00 -T E2 08 00 00 14 02 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T E9 08 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T F2 08 00 00 60 +T E7 09 00 00 14 02 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T ED 09 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T F4 09 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T F9 09 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 00 0A 00 00 28 7E R 00 00 01 00 -T F3 08 00 00 +T 02 0A 00 00 R 00 00 01 00 -T F3 08 00 00 11 06 04 00 00 CD A3 13 00 00 DD -R 00 00 01 00 00 05 03 00 00 0A 01 00 -T FA 08 00 00 75 FE DD 74 FF 7D B4 20 10 +T 02 0A 00 00 11 06 04 00 00 3E 41 16 00 00 21 +R 00 00 01 00 00 05 03 00 29 0A 01 00 +T 08 0A 00 00 41 16 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 0F 0A 00 00 FE DD 74 FF 7D B4 20 1A R 00 00 01 00 -T 03 09 00 00 +T 17 0A 00 00 R 00 00 01 00 -T 03 09 00 00 21 55 02 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 0A 09 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 11 09 00 00 18 40 +T 17 0A 00 00 21 55 02 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 1D 0A 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 24 0A 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T 2A 0A 00 00 00 00 00 00 CD 00 00 00 00 18 4F +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 31 0A 00 00 R 00 00 01 00 -T 13 09 00 00 +T 31 0A 00 00 DD 5E FC DD 56 FD 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 39 0A 00 00 21 13 17 00 00 CD 00 00 00 00 4D +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 40 0A 00 00 44 DD 5E FE DD 56 FF 3E R 00 00 01 00 -T 13 09 00 00 DD 5E FC DD 56 FD CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 1C 09 00 00 4D 44 DD 5E FE DD 56 FF CD +T 48 0A 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 4D 0A 00 00 00 00 00 00 DD 6E F8 DD 66 F9 29 +R 00 00 01 00 02 04 14 00 +T 56 0A 00 00 E5 21 06 00 39 01 18 00 09 4D 44 R 00 00 01 00 -T 25 09 00 00 8B 14 00 00 DD 6E F8 DD 66 F9 29 -R 00 00 01 00 00 04 01 00 -T 2E 09 00 00 E5 21 06 00 39 01 18 00 09 4D 44 +T 61 0A 00 00 E1 09 DD 4E FE DD 46 FF 71 23 70 R 00 00 01 00 -T 39 09 00 00 E1 09 DD 4E FE DD 46 FF 71 23 70 +T 6C 0A 00 00 21 04 00 39 4D 44 DD 5E B4 DD 56 R 00 00 01 00 -T 44 09 00 00 21 04 00 39 4D 44 DD 5E B4 DD 56 +T 77 0A 00 00 B5 3E D9 17 00 00 21 D9 17 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T 7D 0A 00 00 CD 00 00 00 00 +R 00 00 01 00 02 05 14 00 +T 80 0A 00 00 R 00 00 01 00 -T 4F 09 00 00 B5 CD F9 14 00 00 -R 00 00 01 00 00 06 01 00 -T 53 09 00 00 -R 00 00 01 00 -T 53 09 00 00 +T 80 0A 00 00 R 00 00 01 00 -T 53 09 00 00 18 1C +T 80 0A 00 00 18 1C R 00 00 01 00 -T 55 09 00 00 +T 82 0A 00 00 R 00 00 01 00 -T 55 09 00 00 06 03 DD 5E FC DD 56 FD CD +T 82 0A 00 00 06 03 DD 5E FC DD 56 FD CD R 00 00 01 00 -T 5E 09 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 8B 0A 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 65 09 00 00 7E FC E6 07 47 3E 01 CD +T 92 0A 00 00 7E FC E6 07 47 3E 01 CD R 00 00 01 00 -T 6D 09 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T 71 09 00 00 +T 9A 0A 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T 9E 0A 00 00 R 00 00 01 00 -T 71 09 00 00 +T 9E 0A 00 00 R 00 00 01 00 -T 71 09 00 00 DD 34 F8 20 03 DD 34 F9 +T 9E 0A 00 00 DD 34 F8 20 03 DD 34 F9 R 00 00 01 00 -T 79 09 00 00 +T A6 0A 00 00 R 00 00 01 00 -T 79 09 00 00 C3 7C 08 00 00 +T A6 0A 00 00 C3 81 09 00 00 R 00 00 01 00 00 05 01 00 -T 7C 09 00 00 +T A9 0A 00 00 R 00 00 01 00 -T 7C 09 00 00 AF DD 77 F8 DD 77 F9 21 0C 00 39 +T A9 0A 00 00 AF DD 77 F8 DD 77 F9 21 0C 00 39 R 00 00 01 00 -T 87 09 00 00 5E 23 56 23 4E 23 46 EB 3E 09 CD +T B4 0A 00 00 5E 23 56 23 4E 23 46 EB 3E 09 CD R 00 00 01 00 -T 92 09 00 00 00 00 00 00 DD 75 FA DD 74 FB -R 00 00 01 00 02 04 1E 00 -T 9A 09 00 00 +T BF 0A 00 00 00 00 00 00 DD 75 FA DD 74 FB +R 00 00 01 00 02 04 20 00 +T C7 0A 00 00 R 00 00 01 00 -T 9A 09 00 00 DD 4E F8 DD 46 F9 DD 6E FA DD 66 +T C7 0A 00 00 DD 4E F8 DD 46 F9 DD 6E FA DD 66 R 00 00 01 00 -T A5 09 00 00 FB A7 ED 42 DA 90 0A 00 00 +T D2 0A 00 00 FB A7 ED 42 DA EF 0B 00 00 R 00 00 01 00 00 09 01 00 -T AC 09 00 00 +T D9 0A 00 00 R 00 00 01 00 -T AC 09 00 00 DD 4E F8 DD 46 F9 21 04 00 39 5D +T D9 0A 00 00 DD 4E F8 DD 46 F9 21 04 00 39 5D R 00 00 01 00 -T B7 09 00 00 54 CD 88 11 00 00 DD 75 FC DD 74 -R 00 00 01 00 00 06 01 00 -T C0 09 00 00 FD 7D B4 20 03 +T E4 0A 00 00 54 3E EF 13 00 00 21 EF 13 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T EA 0A 00 00 CD 00 00 00 00 DD 75 FC DD 74 FD +R 00 00 01 00 02 05 14 00 +T F3 0A 00 00 7D B4 20 03 R 00 00 01 00 -T C5 09 00 00 +T F7 0A 00 00 R 00 00 01 00 -T C5 09 00 00 C3 85 0A 00 00 +T F7 0A 00 00 C3 E4 0B 00 00 R 00 00 01 00 00 05 01 00 -T C8 09 00 00 +T FA 0A 00 00 R 00 00 01 00 -T C8 09 00 00 06 03 DD 5E FC DD 56 FD CD +T FA 0A 00 00 06 03 DD 5E FC DD 56 FD CD R 00 00 01 00 -T D1 09 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 03 0B 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T D8 09 00 00 7E FC E6 07 47 3E 01 CD -R 00 00 01 00 -T E0 09 00 00 00 00 00 00 A6 CA 69 0A 00 00 -R 00 00 01 00 02 04 1D 00 00 0A 01 00 -T E6 09 00 00 -R 00 00 01 00 -T E6 09 00 00 DD 6E FC DD 66 FD E5 DD 6E B4 DD -R 00 00 01 00 -T F1 09 00 00 66 B5 E5 DD 6E F8 DD 66 F9 E5 21 -R 00 00 01 00 -T FC 09 00 00 74 02 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 03 0A 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T 0C 0A 00 00 5A -R 00 00 01 00 -T 0D 0A 00 00 -R 00 00 01 00 -T 0D 0A 00 00 11 06 04 00 00 CD A3 13 00 00 DD -R 00 00 01 00 00 05 03 00 00 0A 01 00 -T 14 0A 00 00 75 FE DD 74 FF 7D B4 20 10 -R 00 00 01 00 -T 1D 0A 00 00 -R 00 00 01 00 -T 1D 0A 00 00 21 55 02 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 24 0A 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 2B 0A 00 00 18 3A -R 00 00 01 00 -T 2D 0A 00 00 -R 00 00 01 00 -T 2D 0A 00 00 DD 5E FC DD 56 FD CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 36 0A 00 00 4D 44 DD 5E FE DD 56 FF CD -R 00 00 01 00 -T 3F 0A 00 00 8B 14 00 00 DD 6E FE DD 66 FF E5 -R 00 00 01 00 00 04 01 00 -T 48 0A 00 00 DD 4E F8 DD 46 F9 21 06 00 39 5D -R 00 00 01 00 -T 53 0A 00 00 54 CD 75 12 00 00 E1 21 04 00 39 -R 00 00 01 00 00 06 01 00 -T 5C 0A 00 00 4D 44 DD 5E B4 DD 56 B5 CD -R 00 00 01 00 -T 65 0A 00 00 F9 14 00 00 -R 00 00 01 00 00 04 01 00 -T 67 0A 00 00 -R 00 00 01 00 -T 67 0A 00 00 -R 00 00 01 00 -T 67 0A 00 00 18 1C -R 00 00 01 00 -T 69 0A 00 00 -R 00 00 01 00 -T 69 0A 00 00 06 03 DD 5E FC DD 56 FD CD -R 00 00 01 00 -T 72 0A 00 00 00 00 00 00 2A 36 04 00 00 19 DD +T 0A 0B 00 00 7E FC E6 07 47 3E 01 CD +R 00 00 01 00 +T 12 0B 00 00 00 00 00 00 A6 CA C8 0B 00 00 +R 00 00 01 00 02 04 1E 00 00 0A 01 00 +T 18 0B 00 00 +R 00 00 01 00 +T 18 0B 00 00 DD 6E FC DD 66 FD E5 DD 6E B4 DD +R 00 00 01 00 +T 23 0B 00 00 66 B5 E5 DD 6E F8 DD 66 F9 E5 21 +R 00 00 01 00 +T 2E 0B 00 00 74 02 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 34 0B 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 3B 0B 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 40 0B 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 47 0B 00 00 28 7D +R 00 00 01 00 +T 49 0B 00 00 +R 00 00 01 00 +T 49 0B 00 00 11 06 04 00 00 3E 41 16 00 00 21 +R 00 00 01 00 00 05 03 00 29 0A 01 00 +T 4F 0B 00 00 41 16 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 56 0B 00 00 FE DD 74 FF 7D B4 20 1A +R 00 00 01 00 +T 5E 0B 00 00 +R 00 00 01 00 +T 5E 0B 00 00 21 55 02 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 64 0B 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 6B 0B 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T 71 0B 00 00 00 00 00 00 CD 00 00 00 00 18 4E +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 78 0B 00 00 +R 00 00 01 00 +T 78 0B 00 00 DD 5E FC DD 56 FD 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 80 0B 00 00 21 13 17 00 00 CD 00 00 00 00 4D +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 87 0B 00 00 44 DD 5E FE DD 56 FF 3E +R 00 00 01 00 +T 8F 0B 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 94 0B 00 00 00 00 00 00 DD 6E FE DD 66 FF E5 +R 00 00 01 00 02 04 14 00 +T 9D 0B 00 00 DD 4E F8 DD 46 F9 21 06 00 39 5D +R 00 00 01 00 +T A8 0B 00 00 54 3E EB 14 00 00 21 EB 14 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T AE 0B 00 00 CD 00 00 00 00 E1 21 04 00 39 4D +R 00 00 01 00 02 05 14 00 +T B7 0B 00 00 44 DD 5E B4 DD 56 B5 3E +R 00 00 01 00 +T BF 0B 00 00 D9 17 00 00 21 D9 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T C4 0B 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T C6 0B 00 00 +R 00 00 01 00 +T C6 0B 00 00 +R 00 00 01 00 +T C6 0B 00 00 18 1C +R 00 00 01 00 +T C8 0B 00 00 +R 00 00 01 00 +T C8 0B 00 00 06 03 DD 5E FC DD 56 FD CD +R 00 00 01 00 +T D1 0B 00 00 00 00 00 00 2A 36 04 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 79 0A 00 00 7E FC E6 07 47 3E 01 CD +T D8 0B 00 00 7E FC E6 07 47 3E 01 CD R 00 00 01 00 -T 81 0A 00 00 00 00 00 00 B6 77 -R 00 00 01 00 02 04 1D 00 -T 85 0A 00 00 +T E0 0B 00 00 00 00 00 00 B6 77 +R 00 00 01 00 02 04 1E 00 +T E4 0B 00 00 R 00 00 01 00 -T 85 0A 00 00 +T E4 0B 00 00 R 00 00 01 00 -T 85 0A 00 00 DD 34 F8 20 03 DD 34 F9 +T E4 0B 00 00 DD 34 F8 20 03 DD 34 F9 R 00 00 01 00 -T 8D 0A 00 00 +T EC 0B 00 00 R 00 00 01 00 -T 8D 0A 00 00 C3 9A 09 00 00 +T EC 0B 00 00 C3 C7 0A 00 00 R 00 00 01 00 00 05 01 00 -T 90 0A 00 00 +T EF 0B 00 00 R 00 00 01 00 -T 90 0A 00 00 +T EF 0B 00 00 R 00 00 01 00 -T 90 0A 00 00 DD 34 B4 20 03 DD 34 B5 +T EF 0B 00 00 DD 34 B4 20 03 DD 34 B5 R 00 00 01 00 -T 98 0A 00 00 +T F7 0B 00 00 R 00 00 01 00 -T 98 0A 00 00 C3 1C 08 00 00 +T F7 0B 00 00 C3 1C 09 00 00 R 00 00 01 00 00 05 01 00 -T 9B 0A 00 00 +T FA 0B 00 00 R 00 00 01 00 -T 9B 0A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 9E 0A 00 00 +T FA 0B 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T FD 0B 00 00 R 00 00 01 00 -T 9E 0A 00 00 CD 00 00 00 00 14 FF 21 00 00 39 -R 00 00 01 00 02 05 18 00 -T A7 0A 00 00 4D 44 DD 5E 02 DD 56 03 CD +T FD 0B 00 00 CD 00 00 00 00 14 FF 21 00 00 39 +R 00 00 01 00 02 05 19 00 +T 06 0C 00 00 4D 44 DD 5E 02 DD 56 03 3E R 00 00 01 00 -T B0 0A 00 00 B5 14 00 00 21 00 00 39 7E E6 00 -R 00 00 01 00 00 04 01 00 -T B9 0A 00 00 4F 23 7E E6 F0 47 3E 40 A8 B1 28 +T 0F 0C 00 00 8B 17 00 00 21 8B 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 14 0C 00 00 00 00 00 00 21 00 00 39 7E E6 00 +R 00 00 01 00 02 04 14 00 +T 1D 0C 00 00 4F 23 7E E6 F0 47 3E 40 A8 B1 28 R 00 00 01 00 -T C4 0A 00 00 03 +T 28 0C 00 00 03 R 00 00 01 00 -T C5 0A 00 00 +T 29 0C 00 00 R 00 00 01 00 -T C5 0A 00 00 C3 AA 0E 00 00 +T 29 0C 00 00 C3 95 10 00 00 R 00 00 01 00 00 05 01 00 -T C8 0A 00 00 +T 2C 0C 00 00 R 00 00 01 00 -T C8 0A 00 00 2A 02 04 00 00 23 22 02 04 00 00 +T 2C 0C 00 00 2A 02 04 00 00 23 22 02 04 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T CF 0A 00 00 21 52 00 39 E5 21 0A 00 39 5E 23 +T 33 0C 00 00 21 52 00 39 E5 21 0A 00 39 5E 23 R 00 00 01 00 -T DA 0A 00 00 56 23 4E 23 46 EB 7D E6 0F 4F 7C +T 3E 0C 00 00 56 23 4E 23 46 EB 7D E6 0F 4F 7C R 00 00 01 00 -T E5 0A 00 00 E6 00 47 E1 71 23 70 21 52 00 39 +T 49 0C 00 00 E6 00 47 E1 71 23 70 21 52 00 39 R 00 00 01 00 -T F0 0A 00 00 7E 23 B6 28 3C +T 54 0C 00 00 7E 23 B6 28 4B R 00 00 01 00 -T F5 0A 00 00 +T 59 0C 00 00 R 00 00 01 00 -T F5 0A 00 00 21 52 00 39 4E 23 46 C5 DD 6E 02 +T 59 0C 00 00 21 52 00 39 4E 23 46 C5 DD 6E 02 R 00 00 01 00 -T 00 0B 00 00 DD 66 03 E5 21 AC 02 00 00 E5 CD +T 64 0C 00 00 DD 66 03 E5 21 AC 02 00 00 E5 3E R 00 00 01 00 00 09 02 00 -T 09 0B 00 00 00 00 00 00 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T 0F 0B 00 00 28 16 00 00 7D B4 28 1C -R 00 00 01 00 00 04 01 00 -T 15 0B 00 00 +T 6D 0C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 72 0C 00 00 00 00 00 00 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 78 0C 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 7D 0C 00 00 00 00 00 00 7D B4 28 21 +R 00 00 01 00 02 04 14 00 +T 83 0C 00 00 R 00 00 01 00 -T 15 0B 00 00 21 08 00 39 01 00 00 11 F0 FF CD +T 83 0C 00 00 21 08 00 39 01 00 00 11 F0 FF CD R 00 00 01 00 -T 20 0B 00 00 00 00 00 00 21 00 00 39 4D 44 DD -R 00 00 01 00 02 04 16 00 -T 29 0B 00 00 5E 02 DD 56 03 CD F9 14 00 00 -R 00 00 01 00 00 0A 01 00 -T 31 0B 00 00 +T 8E 0C 00 00 00 00 00 00 21 00 00 39 4D 44 DD +R 00 00 01 00 02 04 17 00 +T 97 0C 00 00 5E 02 DD 56 03 3E D9 17 00 00 21 +R 00 00 01 00 29 0A 01 00 +T 9F 0C 00 00 D9 17 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T A4 0C 00 00 R 00 00 01 00 -T 31 0B 00 00 +T A4 0C 00 00 R 00 00 01 00 -T 31 0B 00 00 21 54 00 39 E5 01 00 00 C5 01 +T A4 0C 00 00 21 54 00 39 E5 01 00 00 C5 01 R 00 00 01 00 -T 3B 0B 00 00 10 00 C5 21 0E 00 39 5E 23 56 23 +T AE 0C 00 00 10 00 C5 21 0E 00 39 5E 23 56 23 R 00 00 01 00 -T 46 0B 00 00 4E 23 46 EB CD 00 00 00 00 EB E1 -R 00 00 01 00 02 09 19 00 -T 4F 0B 00 00 73 23 72 21 50 00 39 AF 77 23 77 +T B9 0C 00 00 4E 23 46 EB CD 00 00 00 00 EB E1 +R 00 00 01 00 02 09 1A 00 +T C2 0C 00 00 73 23 72 21 50 00 39 AF 77 23 77 R 00 00 01 00 -T 5A 0B 00 00 +T CD 0C 00 00 R 00 00 01 00 -T 5A 0B 00 00 21 54 00 39 4E 23 46 21 50 00 39 +T CD 0C 00 00 21 54 00 39 4E 23 46 21 50 00 39 R 00 00 01 00 -T 65 0B 00 00 56 23 66 6A A7 ED 42 D2 +T D8 0C 00 00 56 23 66 6A A7 ED 42 D2 R 00 00 01 00 -T 6D 0B 00 00 A3 0E 00 00 +T E0 0C 00 00 8E 10 00 00 R 00 00 01 00 00 04 01 00 -T 6F 0B 00 00 +T E2 0C 00 00 R 00 00 01 00 -T 6F 0B 00 00 21 40 00 39 E5 21 52 00 39 4E 23 +T E2 0C 00 00 21 40 00 39 E5 21 52 00 39 4E 23 R 00 00 01 00 -T 7A 0B 00 00 46 21 02 00 39 5D 54 CD +T ED 0C 00 00 46 21 02 00 39 5D 54 3E R 00 00 01 00 -T 82 0B 00 00 57 15 00 00 E1 21 40 00 39 46 23 -R 00 00 01 00 00 04 01 00 -T 8B 0B 00 00 66 68 7D B4 20 03 +T F5 0C 00 00 46 18 00 00 21 46 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T FA 0C 00 00 00 00 00 00 E1 21 40 00 39 46 23 +R 00 00 01 00 02 04 14 00 +T 03 0D 00 00 66 68 7D B4 20 03 R 00 00 01 00 -T 91 0B 00 00 +T 09 0D 00 00 R 00 00 01 00 -T 91 0B 00 00 C3 97 0E 00 00 +T 09 0D 00 00 C3 82 10 00 00 R 00 00 01 00 00 05 01 00 -T 94 0B 00 00 +T 0C 0D 00 00 R 00 00 01 00 -T 94 0B 00 00 21 40 00 39 46 23 66 68 01 01 00 +T 0C 0D 00 00 21 40 00 39 46 23 66 68 01 01 00 R 00 00 01 00 -T 9F 0B 00 00 A7 ED 42 38 15 2A 0A 04 00 00 29 +T 17 0D 00 00 A7 ED 42 38 15 2A 0A 04 00 00 29 R 00 00 01 00 00 0A 03 00 -T A8 0B 00 00 29 29 4D 44 21 40 00 39 56 23 66 +T 20 0D 00 00 29 29 4D 44 21 40 00 39 56 23 66 R 00 00 01 00 -T B3 0B 00 00 6A A7 ED 42 38 51 +T 2B 0D 00 00 6A A7 ED 42 38 60 R 00 00 01 00 -T B9 0B 00 00 +T 31 0D 00 00 R 00 00 01 00 -T B9 0B 00 00 +T 31 0D 00 00 R 00 00 01 00 -T B9 0B 00 00 +T 31 0D 00 00 R 00 00 01 00 -T B9 0B 00 00 21 40 00 39 4E 23 46 C5 21 42 00 +T 31 0D 00 00 21 40 00 39 4E 23 46 C5 21 42 00 R 00 00 01 00 -T C4 0B 00 00 39 01 02 00 09 E5 DD 6E 08 DD 66 +T 3C 0D 00 00 39 01 02 00 09 E5 DD 6E 0A DD 66 R 00 00 01 00 -T CF 0B 00 00 09 E5 21 E5 02 00 00 E5 CD +T 47 0D 00 00 0B E5 21 E5 02 00 00 E5 3E R 00 00 01 00 00 07 02 00 -T D6 0B 00 00 00 00 00 00 F1 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T DD 0B 00 00 28 16 00 00 7D B4 28 27 -R 00 00 01 00 00 04 01 00 -T E3 0B 00 00 +T 4E 0D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 53 0D 00 00 00 00 00 00 F1 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 5A 0D 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 5F 0D 00 00 00 00 00 00 7D B4 28 2C +R 00 00 01 00 02 04 14 00 +T 65 0D 00 00 R 00 00 01 00 -T E3 0B 00 00 21 40 00 39 AF 77 23 77 21 42 00 +T 65 0D 00 00 21 40 00 39 AF 77 23 77 21 42 00 R 00 00 01 00 -T EE 0B 00 00 39 36 00 21 40 00 39 E5 21 52 00 +T 70 0D 00 00 39 36 00 21 40 00 39 E5 21 52 00 R 00 00 01 00 -T F9 0B 00 00 39 4E 23 46 21 02 00 39 5D 54 CD +T 7B 0D 00 00 39 4E 23 46 21 02 00 39 5D 54 3E R 00 00 01 00 -T 04 0C 00 00 B7 15 00 00 E1 C3 97 0E 00 00 -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 0A 0C 00 00 +T 86 0D 00 00 BA 18 00 00 21 BA 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 8B 0D 00 00 00 00 00 00 E1 C3 82 10 00 00 +R 00 00 01 00 02 04 14 00 00 0A 01 00 +T 91 0D 00 00 R 00 00 01 00 -T 0A 0C 00 00 +T 91 0D 00 00 R 00 00 01 00 -T 0A 0C 00 00 21 40 00 39 46 23 66 68 7D B4 28 +T 91 0D 00 00 21 40 00 39 46 23 66 68 7D B4 28 R 00 00 01 00 -T 15 0C 00 00 62 21 40 00 39 46 23 66 68 ED 4B +T 9C 0D 00 00 71 21 40 00 39 46 23 66 68 ED 4B R 00 00 01 00 -T 20 0C 00 00 38 04 00 00 09 46 04 20 51 +T A7 0D 00 00 38 04 00 00 09 46 04 20 60 R 00 00 01 00 00 04 03 00 -T 27 0C 00 00 +T AE 0D 00 00 R 00 00 01 00 -T 27 0C 00 00 +T AE 0D 00 00 R 00 00 01 00 -T 27 0C 00 00 +T AE 0D 00 00 R 00 00 01 00 -T 27 0C 00 00 21 40 00 39 4E 23 46 C5 21 42 00 +T AE 0D 00 00 21 40 00 39 4E 23 46 C5 21 42 00 R 00 00 01 00 -T 32 0C 00 00 39 01 02 00 09 E5 DD 6E 08 DD 66 +T B9 0D 00 00 39 01 02 00 09 E5 DD 6E 0A DD 66 R 00 00 01 00 -T 3D 0C 00 00 09 E5 21 20 03 00 00 E5 CD +T C4 0D 00 00 0B E5 21 20 03 00 00 E5 3E R 00 00 01 00 00 07 02 00 -T 44 0C 00 00 00 00 00 00 F1 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T 4B 0C 00 00 28 16 00 00 7D B4 28 27 -R 00 00 01 00 00 04 01 00 -T 51 0C 00 00 +T CB 0D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T D0 0D 00 00 00 00 00 00 F1 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T D7 0D 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T DC 0D 00 00 00 00 00 00 7D B4 28 2C +R 00 00 01 00 02 04 14 00 +T E2 0D 00 00 R 00 00 01 00 -T 51 0C 00 00 21 40 00 39 AF 77 23 77 21 42 00 +T E2 0D 00 00 21 40 00 39 AF 77 23 77 21 42 00 R 00 00 01 00 -T 5C 0C 00 00 39 36 00 21 40 00 39 E5 21 52 00 +T ED 0D 00 00 39 36 00 21 40 00 39 E5 21 52 00 R 00 00 01 00 -T 67 0C 00 00 39 4E 23 46 21 02 00 39 5D 54 CD +T F8 0D 00 00 39 4E 23 46 21 02 00 39 5D 54 3E R 00 00 01 00 -T 72 0C 00 00 B7 15 00 00 E1 C3 97 0E 00 00 -R 00 00 01 00 00 04 01 00 00 0A 01 00 -T 78 0C 00 00 +T 03 0E 00 00 BA 18 00 00 21 BA 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 08 0E 00 00 00 00 00 00 E1 C3 82 10 00 00 +R 00 00 01 00 02 04 14 00 00 0A 01 00 +T 0E 0E 00 00 R 00 00 01 00 -T 78 0C 00 00 +T 0E 0E 00 00 R 00 00 01 00 -T 78 0C 00 00 21 40 00 39 46 23 66 68 ED 4B +T 0E 0E 00 00 21 40 00 39 46 23 66 68 ED 4B R 00 00 01 00 -T 82 0C 00 00 38 04 00 00 09 46 34 04 04 20 1C +T 18 0E 00 00 38 04 00 00 09 46 34 04 04 20 26 R 00 00 01 00 00 04 03 00 -T 8B 0C 00 00 +T 21 0E 00 00 R 00 00 01 00 -T 8B 0C 00 00 21 40 00 39 4E 23 46 C5 21 +T 21 0E 00 00 21 40 00 39 4E 23 46 C5 21 R 00 00 01 00 -T 94 0C 00 00 5A 03 00 00 E5 21 00 00 00 00 E5 -R 00 00 01 00 00 04 02 00 02 0A 09 00 -T 9B 0C 00 00 CD 00 00 00 00 F1 F1 F1 11 01 00 -R 00 00 01 00 02 05 20 00 -T A4 0C 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 21 00 -T A7 0C 00 00 +T 2A 0E 00 00 5A 03 00 00 E5 21 00 00 00 00 E5 +R 00 00 01 00 00 04 02 00 02 0A 0A 00 +T 31 0E 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 22 00 02 0A 22 00 +T 37 0E 00 00 00 00 00 00 F1 F1 F1 11 01 00 3E +R 00 00 01 00 02 04 14 00 +T 40 0E 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T 45 0E 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 47 0E 00 00 R 00 00 01 00 -T A7 0C 00 00 21 52 00 39 AF 77 23 77 +T 47 0E 00 00 21 52 00 39 AF 77 23 77 R 00 00 01 00 -T AF 0C 00 00 +T 4F 0E 00 00 R 00 00 01 00 -T AF 0C 00 00 01 0E 00 21 52 00 39 56 23 66 6A +T 4F 0E 00 00 01 0E 00 21 52 00 39 56 23 66 6A R 00 00 01 00 -T BA 0C 00 00 A7 ED 42 D2 44 0D 00 00 21 40 00 +T 5A 0E 00 00 A7 ED 42 D2 F3 0E 00 00 21 40 00 R 00 00 01 00 00 08 01 00 -T C3 0C 00 00 39 01 02 00 09 E5 21 54 00 39 4E +T 63 0E 00 00 39 01 02 00 09 E5 21 54 00 39 4E R 00 00 01 00 -T CE 0C 00 00 23 46 E1 09 7E B7 28 6E +T 6E 0E 00 00 23 46 E1 09 7E B7 28 7D R 00 00 01 00 -T D6 0C 00 00 +T 76 0E 00 00 R 00 00 01 00 -T D6 0C 00 00 +T 76 0E 00 00 R 00 00 01 00 -T D6 0C 00 00 +T 76 0E 00 00 R 00 00 01 00 -T D6 0C 00 00 21 40 00 39 01 02 00 09 E5 21 +T 76 0E 00 00 21 40 00 39 01 02 00 09 E5 21 R 00 00 01 00 -T E0 0C 00 00 54 00 39 4E 23 46 E1 09 7E FE 2F +T 80 0E 00 00 54 00 39 4E 23 46 E1 09 7E FE 2F R 00 00 01 00 -T EB 0C 00 00 20 4B +T 8B 0E 00 00 20 5A R 00 00 01 00 -T ED 0C 00 00 +T 8D 0E 00 00 R 00 00 01 00 -T ED 0C 00 00 21 40 00 39 01 02 00 09 E5 DD 6E +T 8D 0E 00 00 21 40 00 39 01 02 00 09 E5 DD 6E R 00 00 01 00 -T F8 0C 00 00 08 DD 66 09 E5 21 9D 03 00 00 E5 +T 98 0E 00 00 0A DD 66 0B E5 21 9D 03 00 00 E5 R 00 00 01 00 00 0A 02 00 -T 01 0D 00 00 CD 00 00 00 00 F1 F1 F1 CD -R 00 00 01 00 02 05 08 00 -T 08 0D 00 00 28 16 00 00 7D B4 28 2A -R 00 00 01 00 00 04 01 00 -T 0E 0D 00 00 +T A1 0E 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 08 00 02 0A 08 00 +T A7 0E 00 00 00 00 00 00 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T AD 0E 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T B2 0E 00 00 00 00 00 00 7D B4 28 2F +R 00 00 01 00 02 04 14 00 +T B8 0E 00 00 R 00 00 01 00 -T 0E 0D 00 00 21 40 00 39 01 02 00 09 E5 21 +T B8 0E 00 00 21 40 00 39 01 02 00 09 E5 21 R 00 00 01 00 -T 18 0D 00 00 54 00 39 4E 23 46 E1 09 36 7E 21 +T C2 0E 00 00 54 00 39 4E 23 46 E1 09 36 7E 21 R 00 00 01 00 -T 23 0D 00 00 40 00 39 E5 21 52 00 39 4E 23 46 +T CD 0E 00 00 40 00 39 E5 21 52 00 39 4E 23 46 R 00 00 01 00 -T 2E 0D 00 00 21 02 00 39 5D 54 CD B7 15 00 00 -R 00 00 01 00 00 0B 01 00 -T 37 0D 00 00 E1 +T D8 0E 00 00 21 02 00 39 5D 54 3E BA 18 00 00 +R 00 00 01 00 29 0B 01 00 +T E0 0E 00 00 21 BA 18 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T E7 0E 00 00 R 00 00 01 00 -T 38 0D 00 00 +T E7 0E 00 00 R 00 00 01 00 -T 38 0D 00 00 +T E7 0E 00 00 21 52 00 39 34 23 20 01 34 R 00 00 01 00 -T 38 0D 00 00 21 52 00 39 34 23 20 01 34 +T F0 0E 00 00 R 00 00 01 00 -T 41 0D 00 00 -R 00 00 01 00 -T 41 0D 00 00 C3 AF 0C 00 00 +T F0 0E 00 00 C3 4F 0E 00 00 R 00 00 01 00 00 05 01 00 -T 44 0D 00 00 +T F3 0E 00 00 R 00 00 01 00 -T 44 0D 00 00 01 CD 03 00 00 21 40 00 39 11 +T F3 0E 00 00 01 CD 03 00 00 21 40 00 39 11 R 00 00 01 00 00 05 02 00 -T 4C 0D 00 00 02 00 19 EB CD 00 00 00 00 7D B4 -R 00 00 01 00 02 09 0D 00 -T 55 0D 00 00 20 5C 21 40 00 39 46 23 66 68 DD +T FB 0E 00 00 02 00 19 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 0E 00 +T 02 0F 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 02 04 0E 00 02 09 14 00 +T 09 0F 00 00 20 6B 21 40 00 39 46 23 66 68 DD R 00 00 01 00 -T 60 0D 00 00 4E 02 DD 46 03 A7 ED 42 28 49 +T 14 0F 00 00 4E 02 DD 46 03 A7 ED 42 28 58 R 00 00 01 00 -T 6A 0D 00 00 +T 1E 0F 00 00 R 00 00 01 00 -T 6A 0D 00 00 +T 1E 0F 00 00 R 00 00 01 00 -T 6A 0D 00 00 +T 1E 0F 00 00 R 00 00 01 00 -T 6A 0D 00 00 21 40 00 39 01 02 00 09 E5 21 +T 1E 0F 00 00 21 40 00 39 01 02 00 09 E5 21 R 00 00 01 00 -T 74 0D 00 00 0E 00 E5 DD 6E 08 DD 66 09 E5 21 +T 28 0F 00 00 0E 00 E5 DD 6E 0A DD 66 0B E5 21 R 00 00 01 00 -T 7F 0D 00 00 CF 03 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 86 0D 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T 8F 0D 00 00 23 +T 33 0F 00 00 CF 03 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 39 0F 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 40 0F 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 45 0F 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 4C 0F 00 00 28 28 R 00 00 01 00 -T 90 0D 00 00 +T 4E 0F 00 00 R 00 00 01 00 -T 90 0D 00 00 21 40 00 39 DD 4E 02 DD 46 03 71 +T 4E 0F 00 00 21 40 00 39 DD 4E 02 DD 46 03 71 R 00 00 01 00 -T 9B 0D 00 00 23 70 21 40 00 39 E5 21 52 00 39 +T 59 0F 00 00 23 70 21 40 00 39 E5 21 52 00 39 R 00 00 01 00 -T A6 0D 00 00 4E 23 46 21 02 00 39 5D 54 CD +T 64 0F 00 00 4E 23 46 21 02 00 39 5D 54 3E R 00 00 01 00 -T B0 0D 00 00 B7 15 00 00 E1 -R 00 00 01 00 00 04 01 00 -T B3 0D 00 00 +T 6E 0F 00 00 BA 18 00 00 21 BA 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 73 0F 00 00 00 00 00 00 E1 +R 00 00 01 00 02 04 14 00 +T 76 0F 00 00 R 00 00 01 00 -T B3 0D 00 00 +T 76 0F 00 00 R 00 00 01 00 -T B3 0D 00 00 01 FF 03 00 00 21 40 00 39 11 +T 76 0F 00 00 01 FF 03 00 00 21 40 00 39 11 R 00 00 01 00 00 05 02 00 -T BB 0D 00 00 02 00 19 EB CD 00 00 00 00 7D B4 -R 00 00 01 00 02 09 0D 00 -T C4 0D 00 00 20 5C 21 40 00 39 46 23 66 68 DD +T 7E 0F 00 00 02 00 19 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 0E 00 +T 85 0F 00 00 00 00 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 02 04 0E 00 02 09 14 00 +T 8C 0F 00 00 20 6B 21 40 00 39 46 23 66 68 DD R 00 00 01 00 -T CF 0D 00 00 4E 04 DD 46 05 A7 ED 42 28 49 +T 97 0F 00 00 4E 04 DD 46 05 A7 ED 42 28 58 R 00 00 01 00 -T D9 0D 00 00 +T A1 0F 00 00 R 00 00 01 00 -T D9 0D 00 00 +T A1 0F 00 00 R 00 00 01 00 -T D9 0D 00 00 +T A1 0F 00 00 R 00 00 01 00 -T D9 0D 00 00 21 40 00 39 01 02 00 09 E5 21 +T A1 0F 00 00 21 40 00 39 01 02 00 09 E5 21 R 00 00 01 00 -T E3 0D 00 00 0E 00 E5 DD 6E 08 DD 66 09 E5 21 +T AB 0F 00 00 0E 00 E5 DD 6E 0A DD 66 0B E5 21 R 00 00 01 00 -T EE 0D 00 00 02 04 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T F5 0D 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T FE 0D 00 00 23 +T B6 0F 00 00 02 04 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T BC 0F 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T C3 0F 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T C8 0F 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T CF 0F 00 00 28 28 R 00 00 01 00 -T FF 0D 00 00 +T D1 0F 00 00 R 00 00 01 00 -T FF 0D 00 00 21 40 00 39 DD 4E 04 DD 46 05 71 +T D1 0F 00 00 21 40 00 39 DD 4E 04 DD 46 05 71 R 00 00 01 00 -T 0A 0E 00 00 23 70 21 40 00 39 E5 21 52 00 39 +T DC 0F 00 00 23 70 21 40 00 39 E5 21 52 00 39 R 00 00 01 00 -T 15 0E 00 00 4E 23 46 21 02 00 39 5D 54 CD +T E7 0F 00 00 4E 23 46 21 02 00 39 5D 54 3E R 00 00 01 00 -T 1F 0E 00 00 B7 15 00 00 E1 -R 00 00 01 00 00 04 01 00 -T 22 0E 00 00 +T F1 0F 00 00 BA 18 00 00 21 BA 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T F6 0F 00 00 00 00 00 00 E1 +R 00 00 01 00 02 04 14 00 +T F9 0F 00 00 R 00 00 01 00 -T 22 0E 00 00 +T F9 0F 00 00 R 00 00 01 00 -T 22 0E 00 00 21 40 00 39 46 23 66 68 DD 4E 04 +T F9 0F 00 00 21 40 00 39 46 23 66 68 DD 4E 04 R 00 00 01 00 -T 2D 0E 00 00 DD 46 05 A7 ED 42 28 62 21 40 00 +T 04 10 00 00 DD 46 05 A7 ED 42 28 76 21 40 00 R 00 00 01 00 -T 38 0E 00 00 39 46 23 66 68 DD 4E 02 DD 46 03 +T 0F 10 00 00 39 46 23 66 68 DD 4E 02 DD 46 03 R 00 00 01 00 -T 43 0E 00 00 A7 ED 42 28 4F 01 21 00 2A +T 1A 10 00 00 A7 ED 42 28 63 01 21 00 2A R 00 00 01 00 -T 4C 0E 00 00 02 04 00 00 A7 ED 42 30 44 +T 23 10 00 00 02 04 00 00 A7 ED 42 30 58 R 00 00 01 00 00 04 03 00 -T 53 0E 00 00 -R 00 00 01 00 -T 53 0E 00 00 +T 2A 10 00 00 R 00 00 01 00 -T 53 0E 00 00 +T 2A 10 00 00 R 00 00 01 00 -T 53 0E 00 00 DD 4E 08 DD 46 09 21 56 00 39 5D +T 2A 10 00 00 R 00 00 01 00 -T 5E 0E 00 00 54 CD 00 00 00 00 21 40 00 39 01 -R 00 00 01 00 02 06 15 00 -T 67 0E 00 00 02 00 09 4D 44 21 56 00 39 5D 54 +T 2A 10 00 00 DD 4E 0A DD 46 0B 21 56 00 39 5D R 00 00 01 00 -T 72 0E 00 00 CD 00 00 00 00 01 33 04 00 00 21 -R 00 00 01 00 02 05 07 00 00 0A 02 00 -T 79 0E 00 00 56 00 39 5D 54 CD 00 00 00 00 21 -R 00 00 01 00 02 0A 07 00 -T 82 0E 00 00 56 00 39 E5 DD 4E 02 DD 46 03 21 +T 35 10 00 00 54 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 16 00 02 0B 16 00 +T 3B 10 00 00 CD 00 00 00 00 21 40 00 39 01 +R 00 00 01 00 02 05 14 00 +T 43 10 00 00 02 00 09 4D 44 21 56 00 39 5D 54 R 00 00 01 00 -T 8D 0E 00 00 42 00 39 5E 23 56 CD 9E 0A 00 00 -R 00 00 01 00 00 0B 01 00 -T 96 0E 00 00 E1 +T 4E 10 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 07 00 02 0A 07 00 +T 54 10 00 00 00 00 00 00 01 33 04 00 00 21 +R 00 00 01 00 02 04 14 00 00 09 02 00 +T 5A 10 00 00 56 00 39 5D 54 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 07 00 +T 62 10 00 00 00 00 00 00 CD 00 00 00 00 21 +R 00 00 01 00 02 04 07 00 02 09 14 00 +T 68 10 00 00 56 00 39 E5 DD 4E 02 DD 46 03 21 R 00 00 01 00 -T 97 0E 00 00 +T 73 10 00 00 42 00 39 5E 23 56 3E FD 0B 00 00 +R 00 00 01 00 29 0B 01 00 +T 7B 10 00 00 21 FD 0B 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 82 10 00 00 R 00 00 01 00 -T 97 0E 00 00 +T 82 10 00 00 R 00 00 01 00 -T 97 0E 00 00 21 50 00 39 34 23 20 01 34 +T 82 10 00 00 21 50 00 39 34 23 20 01 34 R 00 00 01 00 -T A0 0E 00 00 +T 8B 10 00 00 R 00 00 01 00 -T A0 0E 00 00 C3 5A 0B 00 00 +T 8B 10 00 00 C3 CD 0C 00 00 R 00 00 01 00 00 05 01 00 -T A3 0E 00 00 +T 8E 10 00 00 R 00 00 01 00 -T A3 0E 00 00 2A 02 04 00 00 2B 22 02 04 00 00 +T 8E 10 00 00 2A 02 04 00 00 2B 22 02 04 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T AA 0E 00 00 +T 95 10 00 00 R 00 00 01 00 -T AA 0E 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T AD 0E 00 00 +T 95 10 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 98 10 00 00 R 00 00 01 00 -T AD 0E 00 00 C5 D5 21 00 00 22 02 04 00 00 2A +T 98 10 00 00 C5 D5 21 00 00 22 02 04 00 00 2A R 00 00 01 00 00 0A 03 00 -T B6 0E 00 00 38 04 00 00 23 36 01 21 +T A1 10 00 00 38 04 00 00 23 36 01 21 R 00 00 01 00 00 04 03 00 -T BC 0E 00 00 33 04 00 00 E5 01 01 00 11 01 00 +T A7 10 00 00 33 04 00 00 E5 01 01 00 11 01 00 R 00 00 01 00 00 04 02 00 -T C5 0E 00 00 CD 9E 0A 00 00 E1 2A 02 04 00 00 -R 00 00 01 00 00 05 01 00 00 0B 03 00 -T CC 0E 00 00 7D B4 28 06 +T B0 10 00 00 3E FD 0B 00 00 21 FD 0B 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T B6 10 00 00 00 00 00 00 E1 2A 02 04 00 00 7D +R 00 00 01 00 02 04 14 00 00 0A 03 00 +T BD 10 00 00 B4 28 0B R 00 00 01 00 -T D0 0E 00 00 +T C0 10 00 00 R 00 00 01 00 -T D0 0E 00 00 11 35 04 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T D6 0E 00 00 +T C0 10 00 00 11 35 04 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T C6 10 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T CB 10 00 00 R 00 00 01 00 -T D6 0E 00 00 D1 C1 C9 +T CB 10 00 00 D1 C1 C3 00 00 00 00 +R 00 00 01 00 02 07 03 00 +T D0 10 00 00 R 00 00 01 00 -T D9 0E 00 00 +T D0 10 00 00 CD 00 00 00 00 AC FF 21 00 00 39 +R 00 00 01 00 02 05 19 00 +T D9 10 00 00 4D 44 11 01 00 3E 8B 17 00 00 21 +R 00 00 01 00 29 0A 01 00 +T E1 10 00 00 8B 17 00 00 CD 00 00 00 00 AF DD +R 00 00 01 00 00 04 01 00 02 09 14 00 +T E8 10 00 00 77 FC DD 77 FD 21 00 00 E5 21 R 00 00 01 00 -T D9 0E 00 00 CD 00 00 00 00 AC FF 21 00 00 39 -R 00 00 01 00 02 05 18 00 -T E2 0E 00 00 4D 44 11 01 00 CD B5 14 00 00 AF -R 00 00 01 00 00 0A 01 00 -T EB 0E 00 00 DD 77 FC DD 77 FD 21 00 00 E5 21 -R 00 00 01 00 -T F6 0E 00 00 10 00 E5 21 0C 00 39 5E 23 56 23 +T F2 10 00 00 10 00 E5 21 0C 00 39 5E 23 56 23 R 00 00 01 00 -T 01 0F 00 00 4E 23 46 EB CD 00 00 00 00 DD 75 -R 00 00 01 00 02 09 19 00 -T 0A 0F 00 00 FE DD 74 FF +T FD 10 00 00 4E 23 46 EB CD 00 00 00 00 DD 75 +R 00 00 01 00 02 09 1A 00 +T 06 11 00 00 FE DD 74 FF R 00 00 01 00 -T 0E 0F 00 00 +T 0A 11 00 00 R 00 00 01 00 -T 0E 0F 00 00 DD 4E FE DD 46 FF DD 6E FC DD 66 +T 0A 11 00 00 DD 4E FE DD 46 FF DD 6E FC DD 66 R 00 00 01 00 -T 19 0F 00 00 FD A7 ED 42 30 6C +T 15 11 00 00 FD A7 ED 42 30 7C R 00 00 01 00 -T 1F 0F 00 00 +T 1B 11 00 00 R 00 00 01 00 -T 1F 0F 00 00 21 40 00 39 E5 DD 4E FC DD 46 FD +T 1B 11 00 00 21 40 00 39 E5 DD 4E FC DD 46 FD R 00 00 01 00 -T 2A 0F 00 00 21 02 00 39 5D 54 CD 57 15 00 00 -R 00 00 01 00 00 0B 01 00 -T 33 0F 00 00 E1 DD 6E EC DD 66 ED 7D B4 20 43 +T 26 11 00 00 21 02 00 39 5D 54 3E 46 18 00 00 +R 00 00 01 00 29 0B 01 00 +T 2E 11 00 00 21 46 18 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 35 11 00 00 DD 6E EC DD 66 ED 7D B4 20 4D DD R 00 00 01 00 -T 3E 0F 00 00 DD 7E EE B7 20 3D +T 40 11 00 00 7E EE B7 20 47 R 00 00 01 00 -T 44 0F 00 00 +T 45 11 00 00 R 00 00 01 00 -T 44 0F 00 00 +T 45 11 00 00 R 00 00 01 00 -T 44 0F 00 00 +T 45 11 00 00 R 00 00 01 00 -T 44 0F 00 00 DD 6E 02 DD 66 03 DD 75 EC DD 74 +T 45 11 00 00 DD 6E 02 DD 66 03 DD 75 EC DD 74 R 00 00 01 00 -T 4F 0F 00 00 ED DD 6E 02 DD 66 03 E5 21 +T 50 11 00 00 ED DD 6E 02 DD 66 03 E5 21 R 00 00 01 00 -T 58 0F 00 00 48 04 00 00 E5 21 44 00 39 01 +T 59 11 00 00 48 04 00 00 E5 21 44 00 39 01 R 00 00 01 00 00 04 02 00 -T 60 0F 00 00 02 00 09 E5 CD 00 00 00 00 F1 F1 -R 00 00 01 00 02 09 03 00 -T 69 0F 00 00 F1 21 40 00 39 E5 DD 4E FC DD 46 +T 61 11 00 00 02 00 09 E5 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 02 00 +T 68 11 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 02 00 02 09 14 00 +T 6F 11 00 00 F1 21 40 00 39 E5 DD 4E FC DD 46 R 00 00 01 00 -T 74 0F 00 00 FD 21 02 00 39 5D 54 CD +T 7A 11 00 00 FD 21 02 00 39 5D 54 3E R 00 00 01 00 -T 7C 0F 00 00 B7 15 00 00 E1 18 18 -R 00 00 01 00 00 04 01 00 -T 81 0F 00 00 +T 82 11 00 00 BA 18 00 00 21 BA 18 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 87 11 00 00 00 00 00 00 E1 18 23 +R 00 00 01 00 02 04 14 00 +T 8C 11 00 00 R 00 00 01 00 -T 81 0F 00 00 DD 34 FC 20 03 DD 34 FD +T 8C 11 00 00 DD 34 FC 20 03 DD 34 FD R 00 00 01 00 -T 89 0F 00 00 +T 94 11 00 00 R 00 00 01 00 -T 89 0F 00 00 18 83 -R 00 00 01 00 -T 8B 0F 00 00 +T 94 11 00 00 C3 0A 11 00 00 +R 00 00 01 00 00 05 01 00 +T 97 11 00 00 R 00 00 01 00 -T 8B 0F 00 00 21 4E 04 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 92 0F 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 99 0F 00 00 +T 97 11 00 00 21 4E 04 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 9D 11 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T A4 11 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T AA 11 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T AF 11 00 00 R 00 00 01 00 -T 99 0F 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 9C 0F 00 00 +T AF 11 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T B2 11 00 00 R 00 00 01 00 -T 9C 0F 00 00 CD 00 00 00 00 BC FF DD 36 BE 01 -R 00 00 01 00 02 05 18 00 -T A5 0F 00 00 DD 36 BF 00 +T B2 11 00 00 CD 00 00 00 00 BC FF DD 36 BE 01 +R 00 00 01 00 02 05 19 00 +T BB 11 00 00 DD 36 BF 00 R 00 00 01 00 -T A9 0F 00 00 +T BF 11 00 00 R 00 00 01 00 -T A9 0F 00 00 ED 4B 24 04 00 00 DD 6E BE DD 66 +T BF 11 00 00 ED 4B 24 04 00 00 DD 6E BE DD 66 R 00 00 01 00 00 06 03 00 -T B2 0F 00 00 BF A7 ED 42 D2 85 11 00 00 +T C8 11 00 00 BF A7 ED 42 D2 EC 13 00 00 R 00 00 01 00 00 09 01 00 -T B9 0F 00 00 +T CF 11 00 00 R 00 00 01 00 -T B9 0F 00 00 21 04 00 39 4D 44 DD 5E BE DD 56 +T CF 11 00 00 21 04 00 39 4D 44 DD 5E BE DD 56 R 00 00 01 00 -T C4 0F 00 00 BF CD B5 14 00 00 DD 6E C0 DD 66 -R 00 00 01 00 00 06 01 00 -T CD 0F 00 00 C1 7D B4 20 18 +T DA 11 00 00 BF 3E 8B 17 00 00 21 8B 17 00 00 +R 00 00 01 00 29 06 01 00 00 0B 01 00 +T E0 11 00 00 CD 00 00 00 00 DD 6E C0 DD 66 C1 +R 00 00 01 00 02 05 14 00 +T E9 11 00 00 7D B4 20 1D R 00 00 01 00 -T D2 0F 00 00 +T ED 11 00 00 R 00 00 01 00 -T D2 0F 00 00 DD 6E BE DD 66 BF ED 4B +T ED 11 00 00 DD 6E BE DD 66 BF ED 4B R 00 00 01 00 -T DA 0F 00 00 38 04 00 00 09 46 04 28 06 +T F5 11 00 00 38 04 00 00 09 46 04 28 0B R 00 00 01 00 00 04 03 00 -T E1 0F 00 00 +T FC 11 00 00 R 00 00 01 00 -T E1 0F 00 00 11 7A 04 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T E7 0F 00 00 +T FC 11 00 00 11 7A 04 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 02 12 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 07 12 00 00 R 00 00 01 00 -T E7 0F 00 00 C3 7A 11 00 00 +T 07 12 00 00 C3 E1 13 00 00 R 00 00 01 00 00 05 01 00 -T EA 0F 00 00 +T 0A 12 00 00 R 00 00 01 00 -T EA 0F 00 00 DD 6E BE DD 66 BF ED 4B +T 0A 12 00 00 DD 6E BE DD 66 BF ED 4B R 00 00 01 00 -T F2 0F 00 00 38 04 00 00 09 46 04 20 10 DD 6E +T 12 12 00 00 38 04 00 00 09 46 04 20 15 DD 6E R 00 00 01 00 00 04 03 00 -T FB 0F 00 00 C0 DD 66 C1 7D B4 28 06 +T 1B 12 00 00 C0 DD 66 C1 7D B4 28 0B R 00 00 01 00 -T 03 10 00 00 +T 23 12 00 00 R 00 00 01 00 -T 03 10 00 00 +T 23 12 00 00 R 00 00 01 00 -T 03 10 00 00 +T 23 12 00 00 R 00 00 01 00 -T 03 10 00 00 11 7A 04 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T 09 10 00 00 +T 23 12 00 00 11 7A 04 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 29 12 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 2E 12 00 00 R 00 00 01 00 -T 09 10 00 00 DD 6E BE DD 66 BF ED 4B +T 2E 12 00 00 DD 6E BE DD 66 BF ED 4B R 00 00 01 00 -T 11 10 00 00 38 04 00 00 09 46 04 28 6B DD 6E +T 36 12 00 00 38 04 00 00 09 46 04 28 7A DD 6E R 00 00 01 00 00 04 03 00 -T 1A 10 00 00 BE DD 66 BF ED 4B 38 04 00 00 09 +T 3F 12 00 00 BE DD 66 BF ED 4B 38 04 00 00 09 R 00 00 01 00 00 0A 03 00 -T 23 10 00 00 4E 06 00 DD 6E C2 DD 66 C3 A7 ED +T 48 12 00 00 4E 06 00 DD 6E C2 DD 66 C3 A7 ED R 00 00 01 00 -T 2E 10 00 00 42 28 52 +T 53 12 00 00 42 28 61 R 00 00 01 00 -T 31 10 00 00 +T 56 12 00 00 R 00 00 01 00 -T 31 10 00 00 +T 56 12 00 00 R 00 00 01 00 -T 31 10 00 00 +T 56 12 00 00 R 00 00 01 00 -T 31 10 00 00 DD 6E BE DD 66 BF ED 4B +T 56 12 00 00 DD 6E BE DD 66 BF ED 4B R 00 00 01 00 -T 39 10 00 00 38 04 00 00 09 4E 06 00 C5 DD 6E +T 5E 12 00 00 38 04 00 00 09 4E 06 00 C5 DD 6E R 00 00 01 00 00 04 03 00 -T 42 10 00 00 C2 DD 66 C3 E5 DD 6E BE DD 66 BF +T 67 12 00 00 C2 DD 66 C3 E5 DD 6E BE DD 66 BF R 00 00 01 00 -T 4D 10 00 00 E5 21 92 04 00 00 E5 CD +T 72 12 00 00 E5 21 92 04 00 00 E5 3E R 00 00 01 00 00 06 02 00 -T 53 10 00 00 00 00 00 00 F1 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T 5A 10 00 00 28 16 00 00 7D B4 28 23 -R 00 00 01 00 00 04 01 00 -T 60 10 00 00 -R 00 00 01 00 -T 60 10 00 00 DD 6E BE DD 66 BF ED 4B -R 00 00 01 00 -T 68 10 00 00 38 04 00 00 09 4E 06 00 DD 71 C2 +T 78 12 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 7D 12 00 00 00 00 00 00 F1 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 84 12 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 89 12 00 00 00 00 00 00 7D B4 28 28 +R 00 00 01 00 02 04 14 00 +T 8F 12 00 00 +R 00 00 01 00 +T 8F 12 00 00 DD 6E BE DD 66 BF ED 4B +R 00 00 01 00 +T 97 12 00 00 38 04 00 00 09 4E 06 00 DD 71 C2 R 00 00 01 00 00 04 03 00 -T 71 10 00 00 DD 70 C3 21 04 00 39 4D 44 DD 5E +T A0 12 00 00 DD 70 C3 21 04 00 39 4D 44 DD 5E R 00 00 01 00 -T 7C 10 00 00 BE DD 56 BF CD F9 14 00 00 -R 00 00 01 00 00 09 01 00 -T 83 10 00 00 +T AB 12 00 00 BE DD 56 BF 3E D9 17 00 00 21 +R 00 00 01 00 29 09 01 00 +T B2 12 00 00 D9 17 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T B7 12 00 00 R 00 00 01 00 -T 83 10 00 00 +T B7 12 00 00 R 00 00 01 00 -T 83 10 00 00 DD 6E BE DD 66 BF ED 4B +T B7 12 00 00 DD 6E BE DD 66 BF ED 4B R 00 00 01 00 -T 8B 10 00 00 38 04 00 00 09 7E B7 C2 +T BF 12 00 00 38 04 00 00 09 7E B7 C2 R 00 00 01 00 00 04 03 00 -T 91 10 00 00 7A 11 00 00 +T C5 12 00 00 E1 13 00 00 R 00 00 01 00 00 04 01 00 -T 93 10 00 00 +T C7 12 00 00 R 00 00 01 00 -T 93 10 00 00 DD 7E C0 E6 00 6F DD 7E C1 E6 F0 +T C7 12 00 00 DD 7E C0 E6 00 6F DD 7E C1 E6 F0 R 00 00 01 00 -T 9E 10 00 00 67 3E 60 AC B5 28 24 DD 7E C0 E6 +T D2 12 00 00 67 3E 60 AC B5 28 25 DD 7E C0 E6 R 00 00 01 00 -T A9 10 00 00 00 6F DD 7E C1 E6 F0 67 3E 20 AC +T DD 12 00 00 00 6F DD 7E C1 E6 F0 67 3E 20 AC R 00 00 01 00 -T B4 10 00 00 B5 28 12 21 0C 00 39 5E 23 56 23 +T E8 12 00 00 B5 28 13 21 0C 00 39 5E 23 56 23 R 00 00 01 00 -T BF 10 00 00 4E 23 46 EB 7D B4 B1 B0 20 72 +T F3 12 00 00 4E 23 46 EB 7D B4 B1 B0 C2 R 00 00 01 00 -T C9 10 00 00 +T FC 12 00 00 8E 13 00 00 +R 00 00 01 00 00 04 01 00 +T FE 12 00 00 R 00 00 01 00 -T C9 10 00 00 +T FE 12 00 00 R 00 00 01 00 -T C9 10 00 00 +T FE 12 00 00 R 00 00 01 00 -T C9 10 00 00 DD 6E C2 DD 66 C3 E5 DD 6E C0 DD +T FE 12 00 00 DD 6E C2 DD 66 C3 E5 DD 6E C0 DD R 00 00 01 00 -T D4 10 00 00 66 C1 E5 DD 6E BE DD 66 BF E5 21 +T 09 13 00 00 66 C1 E5 DD 6E BE DD 66 BF E5 21 R 00 00 01 00 -T DF 10 00 00 C1 04 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T E6 10 00 00 F1 F1 F1 CD 28 16 00 00 7D B4 28 -R 00 00 01 00 00 08 01 00 -T EF 10 00 00 49 +T 14 13 00 00 C1 04 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 1A 13 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 21 13 00 00 F1 F1 3E 44 19 00 00 21 +R 00 00 01 00 29 07 01 00 +T 26 13 00 00 44 19 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 2D 13 00 00 28 5D R 00 00 01 00 -T F0 10 00 00 +T 2F 13 00 00 R 00 00 01 00 -T F0 10 00 00 AF DD 77 C2 DD 77 C3 AF DD 77 C0 +T 2F 13 00 00 AF DD 77 C2 DD 77 C3 AF DD 77 C0 R 00 00 01 00 -T FB 10 00 00 DD 77 C1 21 04 00 39 4D 44 DD 5E +T 3A 13 00 00 DD 77 C1 21 04 00 39 4D 44 DD 5E R 00 00 01 00 -T 06 11 00 00 BE DD 56 BF CD F9 14 00 00 2A -R 00 00 01 00 00 09 01 00 -T 0E 11 00 00 10 04 00 00 23 22 10 04 00 00 11 +T 45 13 00 00 BE DD 56 BF 3E D9 17 00 00 21 +R 00 00 01 00 29 09 01 00 +T 4C 13 00 00 D9 17 00 00 CD 00 00 00 00 2A +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 52 13 00 00 10 04 00 00 23 22 10 04 00 00 11 R 00 00 01 00 00 04 03 00 00 0A 03 00 -T 15 11 00 00 04 00 CD 5B 14 00 00 DD 75 BC DD -R 00 00 01 00 00 07 01 00 -T 1E 11 00 00 74 BD 01 1E 00 C5 4D 44 11 +T 59 13 00 00 04 00 3E 13 17 00 00 21 +R 00 00 01 00 29 07 01 00 +T 5E 13 00 00 13 17 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 65 13 00 00 BC DD 74 BD 01 1E 00 C5 4D 44 11 R 00 00 01 00 -T 27 11 00 00 06 04 00 00 CD 00 00 00 00 E1 DD -R 00 00 01 00 00 04 03 00 02 09 11 00 -T 2E 11 00 00 4E BC DD 46 BD 11 04 00 CD +T 70 13 00 00 06 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 11 00 +T 75 13 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T 7C 13 00 00 4E BC DD 46 BD 11 04 00 3E R 00 00 01 00 -T 37 11 00 00 8B 14 00 00 -R 00 00 01 00 00 04 01 00 -T 39 11 00 00 +T 85 13 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 8A 13 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 8C 13 00 00 R 00 00 01 00 -T 39 11 00 00 18 3F +T 8C 13 00 00 18 53 R 00 00 01 00 -T 3B 11 00 00 +T 8E 13 00 00 R 00 00 01 00 -T 3B 11 00 00 DD 6E C2 DD 66 C3 E5 DD 6E BE DD +T 8E 13 00 00 DD 6E C2 DD 66 C3 E5 DD 6E BE DD R 00 00 01 00 -T 46 11 00 00 66 BF E5 21 0D 05 00 00 E5 CD +T 99 13 00 00 66 BF E5 21 0D 05 00 00 E5 3E R 00 00 01 00 00 08 02 00 -T 4E 11 00 00 00 00 00 00 F1 F1 F1 CD -R 00 00 01 00 02 04 08 00 -T 54 11 00 00 28 16 00 00 7D B4 28 20 -R 00 00 01 00 00 04 01 00 -T 5A 11 00 00 +T A1 13 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T A6 13 00 00 00 00 00 00 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T AC 13 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T B1 13 00 00 00 00 00 00 7D B4 28 2A +R 00 00 01 00 02 04 14 00 +T B7 13 00 00 R 00 00 01 00 -T 5A 11 00 00 DD 36 C2 01 DD 36 C3 00 21 04 00 +T B7 13 00 00 DD 36 C2 01 DD 36 C3 00 21 04 00 R 00 00 01 00 -T 65 11 00 00 39 4D 44 DD 5E BE DD 56 BF CD +T C2 13 00 00 39 4D 44 DD 5E BE DD 56 BF 3E R 00 00 01 00 -T 6F 11 00 00 F9 14 00 00 DD 5E BE DD 56 BF CD -R 00 00 01 00 00 04 01 00 -T 78 11 00 00 D9 0E 00 00 -R 00 00 01 00 00 04 01 00 -T 7A 11 00 00 +T CC 13 00 00 D9 17 00 00 21 D9 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T D1 13 00 00 00 00 00 00 DD 5E BE DD 56 BF 3E +R 00 00 01 00 02 04 14 00 +T DA 13 00 00 D0 10 00 00 21 D0 10 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T DF 13 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T E1 13 00 00 R 00 00 01 00 -T 7A 11 00 00 +T E1 13 00 00 R 00 00 01 00 -T 7A 11 00 00 +T E1 13 00 00 R 00 00 01 00 -T 7A 11 00 00 +T E1 13 00 00 R 00 00 01 00 -T 7A 11 00 00 DD 34 BE 20 03 DD 34 BF +T E1 13 00 00 DD 34 BE 20 03 DD 34 BF R 00 00 01 00 -T 82 11 00 00 +T E9 13 00 00 R 00 00 01 00 -T 82 11 00 00 C3 A9 0F 00 00 +T E9 13 00 00 C3 BF 11 00 00 R 00 00 01 00 00 05 01 00 -T 85 11 00 00 +T EC 13 00 00 R 00 00 01 00 -T 85 11 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 88 11 00 00 +T EC 13 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T EF 13 00 00 R 00 00 01 00 -T 88 11 00 00 CD 00 00 00 00 FA FF 11 12 00 69 -R 00 00 01 00 02 05 18 00 -T 91 11 00 00 60 A7 ED 52 30 19 +T EF 13 00 00 CD 00 00 00 00 FA FF 11 12 00 69 +R 00 00 01 00 02 05 19 00 +T F8 13 00 00 60 A7 ED 52 30 19 R 00 00 01 00 -T 97 11 00 00 +T FE 13 00 00 R 00 00 01 00 -T 97 11 00 00 DD 6E 04 DD 66 05 29 DD 4E 02 DD +T FE 13 00 00 DD 6E 04 DD 66 05 29 DD 4E 02 DD R 00 00 01 00 -T A2 11 00 00 46 03 09 01 18 00 09 46 23 66 68 +T 09 14 00 00 46 03 09 01 18 00 09 46 23 66 68 R 00 00 01 00 -T AD 11 00 00 C3 72 12 00 00 +T 14 14 00 00 C3 E8 14 00 00 R 00 00 01 00 00 05 01 00 -T B0 11 00 00 +T 17 14 00 00 R 00 00 01 00 -T B0 11 00 00 01 12 01 DD 6E 04 DD 66 05 A7 ED +T 17 14 00 00 01 12 01 DD 6E 04 DD 66 05 A7 ED R 00 00 01 00 -T BB 11 00 00 42 30 43 +T 22 14 00 00 42 30 48 R 00 00 01 00 -T BE 11 00 00 +T 25 14 00 00 R 00 00 01 00 -T BE 11 00 00 21 3C 00 DD 4E 02 DD 46 03 09 46 +T 25 14 00 00 21 3C 00 DD 4E 02 DD 46 03 09 46 R 00 00 01 00 -T C9 11 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 +T 30 14 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 R 00 00 01 00 -T D4 11 00 00 20 06 +T 3B 14 00 00 20 06 R 00 00 01 00 -T D6 11 00 00 +T 3D 14 00 00 R 00 00 01 00 -T D6 11 00 00 21 00 00 C3 72 12 00 00 +T 3D 14 00 00 21 00 00 C3 E8 14 00 00 R 00 00 01 00 00 08 01 00 -T DC 11 00 00 +T 43 14 00 00 R 00 00 01 00 -T DC 11 00 00 DD 5E FA DD 56 FB CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T E5 11 00 00 DD 75 FE DD 74 FF E5 DD 6E 04 DD +T 43 14 00 00 DD 5E FA DD 56 FB 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 4B 14 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 52 14 00 00 75 FE DD 74 FF E5 DD 6E 04 DD 66 R 00 00 01 00 -T F0 11 00 00 66 05 29 4D 44 E1 09 01 DC FF 09 +T 5D 14 00 00 05 29 4D 44 E1 09 01 DC FF 09 46 R 00 00 01 00 -T FB 11 00 00 46 23 66 68 18 71 +T 68 14 00 00 23 66 68 18 7B R 00 00 01 00 -T 01 12 00 00 +T 6D 14 00 00 R 00 00 01 00 -T 01 12 00 00 21 3E 00 DD 4E 02 DD 46 03 09 46 +T 6D 14 00 00 21 3E 00 DD 4E 02 DD 46 03 09 46 R 00 00 01 00 -T 0C 12 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 +T 78 14 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 R 00 00 01 00 -T 17 12 00 00 20 05 +T 83 14 00 00 20 05 R 00 00 01 00 -T 19 12 00 00 +T 85 14 00 00 R 00 00 01 00 -T 19 12 00 00 21 00 00 18 54 +T 85 14 00 00 21 00 00 18 5E R 00 00 01 00 -T 1E 12 00 00 +T 8A 14 00 00 R 00 00 01 00 -T 1E 12 00 00 DD 5E FA DD 56 FB CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 27 12 00 00 DD 75 FE DD 74 FF 21 E0 00 DD 4E +T 8A 14 00 00 DD 5E FA DD 56 FB 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 92 14 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 99 14 00 00 75 FE DD 74 FF 21 E0 00 DD 4E 04 R 00 00 01 00 -T 32 12 00 00 04 DD 46 05 09 DD 75 FA DD 74 FB +T A4 14 00 00 DD 46 05 09 DD 75 FA DD 74 FB 6C R 00 00 01 00 -T 3D 12 00 00 6C 26 00 29 DD 4E FE DD 46 FF 09 +T AF 14 00 00 26 00 29 DD 4E FE DD 46 FF 09 56 R 00 00 01 00 -T 48 12 00 00 56 23 66 6A DD 75 FC DD 74 FD EB +T BA 14 00 00 23 66 6A DD 75 FC DD 74 FD EB 3E R 00 00 01 00 -T 53 12 00 00 CD 5B 14 00 00 DD 75 FE DD 74 FF -R 00 00 01 00 00 05 01 00 -T 5C 12 00 00 E5 DD 7E FA E6 FF 6F DD 7E FB E6 +T C5 14 00 00 13 17 00 00 21 13 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T CA 14 00 00 00 00 00 00 DD 75 FE DD 74 FF E5 +R 00 00 01 00 02 04 14 00 +T D3 14 00 00 DD 7E FA E6 FF 6F DD 7E FB E6 00 R 00 00 01 00 -T 67 12 00 00 00 67 29 4D 44 E1 09 46 23 66 68 +T DE 14 00 00 67 29 4D 44 E1 09 46 23 66 68 R 00 00 01 00 -T 72 12 00 00 +T E8 14 00 00 R 00 00 01 00 -T 72 12 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 75 12 00 00 +T E8 14 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T EB 14 00 00 R 00 00 01 00 -T 75 12 00 00 CD 00 00 00 00 FA FF 11 12 00 69 -R 00 00 01 00 02 05 18 00 -T 7E 12 00 00 60 A7 ED 52 30 1E +T EB 14 00 00 CD 00 00 00 00 FA FF 11 12 00 69 +R 00 00 01 00 02 05 19 00 +T F4 14 00 00 60 A7 ED 52 30 1E R 00 00 01 00 -T 84 12 00 00 +T FA 14 00 00 R 00 00 01 00 -T 84 12 00 00 DD 6E 04 DD 66 05 29 DD 4E 02 DD +T FA 14 00 00 DD 6E 04 DD 66 05 29 DD 4E 02 DD R 00 00 01 00 -T 8F 12 00 00 46 03 09 01 18 00 09 DD 4E 08 DD +T 05 15 00 00 46 03 09 01 18 00 09 DD 4E 0A DD R 00 00 01 00 -T 9A 12 00 00 46 09 71 23 70 C3 A0 13 00 00 +T 10 15 00 00 46 0B 71 23 70 C3 3E 16 00 00 R 00 00 01 00 00 0A 01 00 -T A2 12 00 00 +T 18 15 00 00 R 00 00 01 00 -T A2 12 00 00 01 12 01 DD 6E 04 DD 66 05 A7 ED +T 18 15 00 00 01 12 01 DD 6E 04 DD 66 05 A7 ED R 00 00 01 00 -T AD 12 00 00 42 30 58 +T 23 15 00 00 42 30 67 R 00 00 01 00 -T B0 12 00 00 +T 26 15 00 00 R 00 00 01 00 -T B0 12 00 00 21 3C 00 DD 4E 02 DD 46 03 09 46 +T 26 15 00 00 21 3C 00 DD 4E 02 DD 46 03 09 46 R 00 00 01 00 -T BB 12 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 +T 31 15 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 R 00 00 01 00 -T C6 12 00 00 20 06 +T 3C 15 00 00 20 0B R 00 00 01 00 -T C8 12 00 00 +T 3E 15 00 00 R 00 00 01 00 -T C8 12 00 00 11 43 05 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T CE 12 00 00 +T 3E 15 00 00 11 43 05 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 44 15 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 49 15 00 00 R 00 00 01 00 -T CE 12 00 00 DD 5E FA DD 56 FB CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T D7 12 00 00 DD 75 FE DD 74 FF E5 DD 6E 04 DD +T 49 15 00 00 DD 5E FA DD 56 FB 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 51 15 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 58 15 00 00 75 FE DD 74 FF E5 DD 6E 04 DD 66 R 00 00 01 00 -T E2 12 00 00 66 05 29 4D 44 E1 09 01 DC FF 09 +T 63 15 00 00 05 29 4D 44 E1 09 01 DC FF 09 DD R 00 00 01 00 -T ED 12 00 00 DD 4E 08 DD 46 09 71 23 70 DD 4E +T 6E 15 00 00 4E 0A DD 46 0B 71 23 70 DD 4E FE R 00 00 01 00 -T F8 12 00 00 FE DD 46 FF DD 5E FA DD 56 FB CD +T 79 15 00 00 DD 46 FF DD 5E FA DD 56 FB 3E R 00 00 01 00 -T 03 13 00 00 8B 14 00 00 C3 A0 13 00 00 -R 00 00 01 00 00 04 01 00 00 09 01 00 -T 08 13 00 00 +T 83 15 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 88 15 00 00 00 00 00 00 C3 3E 16 00 00 +R 00 00 01 00 02 04 14 00 00 09 01 00 +T 8D 15 00 00 R 00 00 01 00 -T 08 13 00 00 21 3E 00 DD 4E 02 DD 46 03 09 46 +T 8D 15 00 00 21 3E 00 DD 4E 02 DD 46 03 09 46 R 00 00 01 00 -T 13 13 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 +T 98 15 00 00 23 66 68 DD 75 FA DD 74 FB 7D B4 R 00 00 01 00 -T 1E 13 00 00 20 06 +T A3 15 00 00 20 0B R 00 00 01 00 -T 20 13 00 00 +T A5 15 00 00 R 00 00 01 00 -T 20 13 00 00 11 43 05 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T 26 13 00 00 +T A5 15 00 00 11 43 05 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T AB 15 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T B0 15 00 00 R 00 00 01 00 -T 26 13 00 00 DD 5E FA DD 56 FB CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 2F 13 00 00 DD 75 FE DD 74 FF 21 0A 00 39 7E +T B0 15 00 00 DD 5E FA DD 56 FB 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T B8 15 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T BF 15 00 00 75 FE DD 74 FF 21 0A 00 39 7E D6 R 00 00 01 00 -T 3A 13 00 00 D6 12 77 23 7E DE 01 77 DD 6E 04 +T CA 15 00 00 12 77 23 7E DE 01 77 DD 6E 04 DD R 00 00 01 00 -T 45 13 00 00 DD 66 05 6C 26 00 29 DD 4E FE DD +T D5 15 00 00 66 05 6C 26 00 29 DD 4E FE DD 46 R 00 00 01 00 -T 50 13 00 00 46 FF 09 46 23 66 68 DD 75 FC DD +T E0 15 00 00 FF 09 46 23 66 68 DD 75 FC DD 74 R 00 00 01 00 -T 5B 13 00 00 74 FD 7D B4 20 06 +T EB 15 00 00 FD 7D B4 20 0B R 00 00 01 00 -T 61 13 00 00 +T F0 15 00 00 R 00 00 01 00 -T 61 13 00 00 11 43 05 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T 67 13 00 00 +T F0 15 00 00 11 43 05 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T F6 15 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T FB 15 00 00 R 00 00 01 00 -T 67 13 00 00 DD 5E FC DD 56 FD CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 70 13 00 00 DD 75 FE DD 74 FF E5 DD 7E 04 E6 +T FB 15 00 00 DD 5E FC DD 56 FD 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 03 16 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 0A 16 00 00 75 FE DD 74 FF E5 DD 7E 04 E6 FF R 00 00 01 00 -T 7B 13 00 00 FF 6F DD 7E 05 E6 00 67 29 4D 44 +T 15 16 00 00 6F DD 7E 05 E6 00 67 29 4D 44 E1 R 00 00 01 00 -T 86 13 00 00 E1 09 DD 4E 04 DD 46 05 71 23 70 +T 20 16 00 00 09 DD 4E 04 DD 46 05 71 23 70 DD R 00 00 01 00 -T 91 13 00 00 DD 4E FE DD 46 FF DD 5E FA DD 56 +T 2B 16 00 00 4E FE DD 46 FF DD 5E FA DD 56 FB R 00 00 01 00 -T 9C 13 00 00 FB CD 8B 14 00 00 -R 00 00 01 00 00 06 01 00 -T A0 13 00 00 -R 00 00 01 00 -T A0 13 00 00 +T 36 16 00 00 3E 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 3C 16 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 3E 16 00 00 R 00 00 01 00 -T A0 13 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T A3 13 00 00 +T 3E 16 00 00 R 00 00 01 00 -T A3 13 00 00 CD 00 00 00 00 F6 FF 21 12 00 DD -R 00 00 01 00 02 05 18 00 -T AC 13 00 00 4E 02 DD 46 03 09 56 23 66 6A DD +T 3E 16 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 41 16 00 00 R 00 00 01 00 -T B7 13 00 00 75 FC DD 74 FD 21 14 00 09 46 23 +T 41 16 00 00 CD 00 00 00 00 F6 FF 21 12 00 DD +R 00 00 01 00 02 05 19 00 +T 4A 16 00 00 4E 02 DD 46 03 09 56 23 66 6A DD R 00 00 01 00 -T C2 13 00 00 66 68 DD 75 FE DD 74 FF 4D 44 DD +T 55 16 00 00 75 FC DD 74 FD 21 14 00 09 46 23 R 00 00 01 00 -T CD 13 00 00 5E FC DD 56 FD CD 09 1A 00 00 DD -R 00 00 01 00 00 0A 01 00 -T D6 13 00 00 75 FA DD 74 FB 7D A4 3C 20 05 +T 60 16 00 00 66 68 DD 75 FE DD 74 FF 4D 44 DD R 00 00 01 00 -T E0 13 00 00 +T 6B 16 00 00 5E FC DD 56 FD 3E 2F 1E 00 00 21 +R 00 00 01 00 29 0A 01 00 +T 73 16 00 00 2F 1E 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 7A 16 00 00 FA DD 74 FB 7D A4 3C 20 06 R 00 00 01 00 -T E0 13 00 00 21 00 00 18 73 +T 83 16 00 00 R 00 00 01 00 -T E5 13 00 00 +T 83 16 00 00 21 00 00 C3 10 17 00 00 +R 00 00 01 00 00 08 01 00 +T 89 16 00 00 R 00 00 01 00 -T E5 13 00 00 21 08 00 DD 4E 02 DD 46 03 09 4E +T 89 16 00 00 21 08 00 DD 4E 02 DD 46 03 09 4E R 00 00 01 00 -T F0 13 00 00 23 46 0B 70 2B 71 ED 4B +T 94 16 00 00 23 46 0B 70 2B 71 ED 4B R 00 00 01 00 -T F8 13 00 00 26 04 00 00 DD 6E FA DD 66 FB A7 +T 9C 16 00 00 26 04 00 00 DD 6E FA DD 66 FB A7 R 00 00 01 00 00 04 03 00 -T 01 14 00 00 ED 42 38 18 21 06 00 DD 4E 02 DD +T A5 16 00 00 ED 42 38 18 21 06 00 DD 4E 02 DD R 00 00 01 00 -T 0C 14 00 00 46 03 09 4E 23 46 DD 6E FA DD 66 +T B0 16 00 00 46 03 09 4E 23 46 DD 6E FA DD 66 R 00 00 01 00 -T 17 14 00 00 FB A7 ED 42 38 0D +T BB 16 00 00 FB A7 ED 42 38 12 R 00 00 01 00 -T 1D 14 00 00 +T C1 16 00 00 R 00 00 01 00 -T 1D 14 00 00 +T C1 16 00 00 R 00 00 01 00 -T 1D 14 00 00 +T C1 16 00 00 R 00 00 01 00 -T 1D 14 00 00 21 5A 05 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 24 14 00 00 F1 21 00 00 18 2E +T C1 16 00 00 21 5A 05 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T C7 16 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T CE 16 00 00 21 00 00 18 3D R 00 00 01 00 -T 2A 14 00 00 +T D3 16 00 00 R 00 00 01 00 -T 2A 14 00 00 11 04 00 CD 5B 14 00 00 DD 75 F8 -R 00 00 01 00 00 08 01 00 -T 33 14 00 00 DD 74 F9 01 02 00 C5 4D 44 21 +T D3 16 00 00 11 04 00 3E 13 17 00 00 21 +R 00 00 01 00 29 08 01 00 +T D9 16 00 00 13 17 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T E0 16 00 00 F8 DD 74 F9 01 02 00 C5 4D 44 21 R 00 00 01 00 -T 3D 14 00 00 0E 00 39 5D 54 CD 00 00 00 00 E1 -R 00 00 01 00 02 0A 11 00 -T 46 14 00 00 DD 4E F8 DD 46 F9 11 04 00 CD +T EB 16 00 00 0E 00 39 5D 54 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 11 00 +T F3 16 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T FA 16 00 00 4E F8 DD 46 F9 11 04 00 3E R 00 00 01 00 -T 50 14 00 00 8B 14 00 00 DD 6E FA DD 66 FB -R 00 00 01 00 00 04 01 00 -T 58 14 00 00 +T 03 17 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 08 17 00 00 00 00 00 00 DD 6E FA DD 66 FB +R 00 00 01 00 02 04 14 00 +T 10 17 00 00 R 00 00 01 00 -T 58 14 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 5B 14 00 00 +T 10 17 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 13 17 00 00 R 00 00 01 00 -T 5B 14 00 00 CD 00 00 00 00 21 3A 04 00 00 E5 +T 13 17 00 00 CD 00 00 00 00 21 3A 04 00 00 E5 R 00 00 01 00 02 05 13 00 00 0A 03 00 -T 62 14 00 00 4B 42 ED 5B 04 04 00 00 CD +T 1A 17 00 00 4B 42 ED 5B 04 04 00 00 3E R 00 00 01 00 00 08 03 00 -T 69 14 00 00 00 00 00 00 F1 3E 02 AC B5 28 13 -R 00 00 01 00 00 04 01 00 -T 72 14 00 00 -R 00 00 01 00 -T 72 14 00 00 DD 6E 02 DD 66 03 E5 21 -R 00 00 01 00 -T 7A 14 00 00 86 05 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 81 14 00 00 F1 CD 00 00 00 00 -R 00 00 01 00 02 06 0C 00 -T 85 14 00 00 -R 00 00 01 00 -T 85 14 00 00 21 3A 04 00 00 C3 00 00 00 00 -R 00 00 01 00 00 05 03 00 02 0A 0F 00 -T 8B 14 00 00 -R 00 00 01 00 -T 8B 14 00 00 CD 00 00 00 00 C5 4B 42 ED 5B +T 21 17 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 26 17 00 00 00 00 00 00 F1 3E 02 AC B5 28 1D +R 00 00 01 00 02 04 14 00 +T 2F 17 00 00 +R 00 00 01 00 +T 2F 17 00 00 DD 6E 02 DD 66 03 E5 21 +R 00 00 01 00 +T 37 17 00 00 86 05 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 3D 17 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 44 17 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 0D 00 02 0A 0D 00 +T 4A 17 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 4C 17 00 00 +R 00 00 01 00 +T 4C 17 00 00 21 3A 04 00 00 C3 00 00 00 00 +R 00 00 01 00 00 05 03 00 02 0A 09 00 +T 52 17 00 00 +R 00 00 01 00 +T 52 17 00 00 CD 00 00 00 00 C5 4B 42 ED 5B R 00 00 01 00 02 05 13 00 -T 93 14 00 00 04 04 00 00 CD 73 00 00 00 F1 3E -R 00 00 01 00 00 04 03 00 00 09 01 00 -T 9A 14 00 00 02 AC B5 28 13 -R 00 00 01 00 -T 9F 14 00 00 -R 00 00 01 00 -T 9F 14 00 00 DD 6E 02 DD 66 03 E5 21 -R 00 00 01 00 -T A7 14 00 00 A0 05 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T AE 14 00 00 F1 CD 00 00 00 00 -R 00 00 01 00 02 06 0C 00 -T B2 14 00 00 -R 00 00 01 00 -T B2 14 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T B5 14 00 00 -R 00 00 01 00 -T B5 14 00 00 CD 00 00 00 00 FE FF 06 03 DD 5E -R 00 00 01 00 02 05 18 00 -T BE 14 00 00 02 DD 56 03 CD 00 00 00 00 2A -R 00 00 01 00 02 09 00 00 -T C6 14 00 00 26 04 00 00 19 EB CD 5B 14 00 00 -R 00 00 01 00 00 04 03 00 00 0B 01 00 -T CD 14 00 00 DD 75 FE DD 74 FF 01 40 00 C5 DD -R 00 00 01 00 -T D8 14 00 00 4E 04 DD 46 05 C5 DD 7E 02 E6 07 -R 00 00 01 00 -T E3 14 00 00 5F DD 7E 03 E6 00 57 06 06 CD -R 00 00 01 00 -T ED 14 00 00 00 00 00 00 19 EB C1 CD -R 00 00 01 00 02 04 02 00 -T F3 14 00 00 00 00 00 00 E1 C3 00 00 00 00 -R 00 00 01 00 02 04 11 00 02 0A 0F 00 -T F9 14 00 00 -R 00 00 01 00 -T F9 14 00 00 CD 00 00 00 00 FE FF 06 03 DD 5E -R 00 00 01 00 02 05 18 00 -T 02 15 00 00 02 DD 56 03 CD 00 00 00 00 2A +T 5A 17 00 00 04 04 00 00 3E A5 00 00 00 21 +R 00 00 01 00 00 04 03 00 29 09 01 00 +T 5F 17 00 00 A5 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 66 17 00 00 02 AC B5 28 1D +R 00 00 01 00 +T 6B 17 00 00 +R 00 00 01 00 +T 6B 17 00 00 DD 6E 02 DD 66 03 E5 21 +R 00 00 01 00 +T 73 17 00 00 A0 05 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 79 17 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 80 17 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 0D 00 02 0A 0D 00 +T 86 17 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 88 17 00 00 +R 00 00 01 00 +T 88 17 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 8B 17 00 00 +R 00 00 01 00 +T 8B 17 00 00 CD 00 00 00 00 FE FF 06 03 DD 5E +R 00 00 01 00 02 05 19 00 +T 94 17 00 00 02 DD 56 03 CD 00 00 00 00 2A R 00 00 01 00 02 09 00 00 -T 0A 15 00 00 26 04 00 00 19 EB CD 5B 14 00 00 -R 00 00 01 00 00 04 03 00 00 0B 01 00 -T 11 15 00 00 DD 75 FE DD 74 FF 01 40 00 C5 DD -R 00 00 01 00 -T 1C 15 00 00 7E 02 E6 07 5F DD 7E 03 E6 00 57 -R 00 00 01 00 -T 27 15 00 00 06 06 CD 00 00 00 00 19 4D 44 DD -R 00 00 01 00 02 07 02 00 -T 30 15 00 00 5E 04 DD 56 05 CD 00 00 00 00 E1 -R 00 00 01 00 02 0A 11 00 -T 39 15 00 00 DD 4E FE DD 46 FF C5 06 03 DD 5E -R 00 00 01 00 -T 44 15 00 00 02 DD 56 03 CD 00 00 00 00 2A +T 9C 17 00 00 26 04 00 00 19 EB 3E 13 17 00 00 +R 00 00 01 00 00 04 03 00 29 0B 01 00 +T A2 17 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T A9 17 00 00 75 FE DD 74 FF 01 40 00 C5 DD 4E +R 00 00 01 00 +T B4 17 00 00 04 DD 46 05 C5 DD 7E 02 E6 07 5F +R 00 00 01 00 +T BF 17 00 00 DD 7E 03 E6 00 57 06 06 CD +R 00 00 01 00 +T C8 17 00 00 00 00 00 00 19 EB 3E 00 00 00 00 +R 00 00 01 00 02 04 01 00 2B 0B 11 00 +T CE 17 00 00 21 00 00 00 00 C1 CD 00 00 00 00 +R 00 00 01 00 02 05 11 00 02 0B 14 00 +T D5 17 00 00 E1 C3 00 00 00 00 +R 00 00 01 00 02 06 09 00 +T D9 17 00 00 +R 00 00 01 00 +T D9 17 00 00 CD 00 00 00 00 FE FF 06 03 DD 5E +R 00 00 01 00 02 05 19 00 +T E2 17 00 00 02 DD 56 03 CD 00 00 00 00 2A R 00 00 01 00 02 09 00 00 -T 4C 15 00 00 26 04 00 00 19 EB C1 CD -R 00 00 01 00 00 04 03 00 -T 52 15 00 00 8B 14 00 00 C3 00 00 00 00 -R 00 00 01 00 00 04 01 00 02 09 0F 00 -T 57 15 00 00 -R 00 00 01 00 -T 57 15 00 00 CD 00 00 00 00 FC FF 06 05 DD 5E -R 00 00 01 00 02 05 18 00 -T 60 15 00 00 04 DD 56 05 CD 00 00 00 00 4B 42 +T EA 17 00 00 26 04 00 00 19 EB 3E 13 17 00 00 +R 00 00 01 00 00 04 03 00 29 0B 01 00 +T F0 17 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T F7 17 00 00 75 FE DD 74 FF 01 40 00 C5 DD 7E +R 00 00 01 00 +T 02 18 00 00 02 E6 07 5F DD 7E 03 E6 00 57 06 +R 00 00 01 00 +T 0D 18 00 00 06 CD 00 00 00 00 19 4D 44 DD 5E +R 00 00 01 00 02 06 01 00 +T 16 18 00 00 04 DD 56 05 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 11 00 +T 1D 18 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T 24 18 00 00 4E FE DD 46 FF C5 06 03 DD 5E 02 +R 00 00 01 00 +T 2F 18 00 00 DD 56 03 CD 00 00 00 00 2A +R 00 00 01 00 02 08 00 00 +T 36 18 00 00 26 04 00 00 19 EB 3E 52 17 00 00 +R 00 00 01 00 00 04 03 00 29 0B 01 00 +T 3C 18 00 00 21 52 17 00 00 C1 CD 00 00 00 00 +R 00 00 01 00 00 05 01 00 02 0B 14 00 +T 43 18 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 46 18 00 00 +R 00 00 01 00 +T 46 18 00 00 CD 00 00 00 00 FC FF 06 05 DD 5E +R 00 00 01 00 02 05 19 00 +T 4F 18 00 00 04 DD 56 05 CD 00 00 00 00 4B 42 R 00 00 01 00 02 09 00 00 -T 69 15 00 00 DD 5E 02 DD 56 03 CD 88 11 00 00 -R 00 00 01 00 00 0B 01 00 -T 72 15 00 00 DD 75 FE DD 74 FF 7D B4 20 06 -R 00 00 01 00 -T 7C 15 00 00 -R 00 00 01 00 -T 7C 15 00 00 11 BB 05 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T 82 15 00 00 -R 00 00 01 00 -T 82 15 00 00 DD 5E FE DD 56 FF CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T 8B 15 00 00 DD 75 FC DD 74 FD 01 10 00 C5 DD -R 00 00 01 00 -T 96 15 00 00 4E 08 DD 46 09 E5 DD 7E 04 E6 1F -R 00 00 01 00 -T A1 15 00 00 6F DD 7E 05 E6 00 67 29 29 29 29 -R 00 00 01 00 -T AC 15 00 00 EB E1 19 EB CD 00 00 00 00 E1 C3 -R 00 00 01 00 02 09 11 00 -T B5 15 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 -T B7 15 00 00 -R 00 00 01 00 -T B7 15 00 00 CD 00 00 00 00 FC FF 06 05 DD 5E -R 00 00 01 00 02 05 18 00 -T C0 15 00 00 04 DD 56 05 CD 00 00 00 00 4B 42 +T 58 18 00 00 DD 5E 02 DD 56 03 3E EF 13 00 00 +R 00 00 01 00 29 0B 01 00 +T 60 18 00 00 21 EF 13 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 67 18 00 00 75 FE DD 74 FF 7D B4 20 0B +R 00 00 01 00 +T 70 18 00 00 +R 00 00 01 00 +T 70 18 00 00 11 BB 05 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T 76 18 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T 7B 18 00 00 +R 00 00 01 00 +T 7B 18 00 00 DD 5E FE DD 56 FF 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T 83 18 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 8A 18 00 00 75 FC DD 74 FD 01 10 00 C5 DD 4E +R 00 00 01 00 +T 95 18 00 00 0A DD 46 0B E5 DD 7E 04 E6 1F 6F +R 00 00 01 00 +T A0 18 00 00 DD 7E 05 E6 00 67 29 29 29 29 EB +R 00 00 01 00 +T AB 18 00 00 E1 19 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 11 00 +T B1 18 00 00 00 00 00 00 CD 00 00 00 00 E1 C3 +R 00 00 01 00 02 04 11 00 02 09 14 00 +T B8 18 00 00 00 00 00 00 +R 00 00 01 00 02 04 09 00 +T BA 18 00 00 +R 00 00 01 00 +T BA 18 00 00 CD 00 00 00 00 FC FF 06 05 DD 5E +R 00 00 01 00 02 05 19 00 +T C3 18 00 00 04 DD 56 05 CD 00 00 00 00 4B 42 R 00 00 01 00 02 09 00 00 -T C9 15 00 00 DD 5E 02 DD 56 03 CD 88 11 00 00 -R 00 00 01 00 00 0B 01 00 -T D2 15 00 00 DD 75 FE DD 74 FF 7D B4 20 06 -R 00 00 01 00 -T DC 15 00 00 -R 00 00 01 00 -T DC 15 00 00 11 BB 05 00 00 CD 4C 1B 00 00 -R 00 00 01 00 00 05 02 00 00 0A 01 00 -T E2 15 00 00 -R 00 00 01 00 -T E2 15 00 00 DD 5E FE DD 56 FF CD 5B 14 00 00 -R 00 00 01 00 00 0B 01 00 -T EB 15 00 00 DD 75 FC DD 74 FD 01 10 00 C5 E5 -R 00 00 01 00 -T F6 15 00 00 DD 7E 04 E6 1F 6F DD 7E 05 E6 00 -R 00 00 01 00 -T 01 16 00 00 67 29 29 29 29 4D 44 E1 09 4D 44 -R 00 00 01 00 -T 0C 16 00 00 DD 5E 08 DD 56 09 CD 00 00 00 00 -R 00 00 01 00 02 0B 11 00 -T 15 16 00 00 E1 DD 4E FC DD 46 FD DD 5E FE DD -R 00 00 01 00 -T 20 16 00 00 56 FF CD 8B 14 00 00 C3 -R 00 00 01 00 00 07 01 00 -T 26 16 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 -T 28 16 00 00 -R 00 00 01 00 -T 28 16 00 00 CD 00 00 00 00 EC FF 11 -R 00 00 01 00 02 05 18 00 -T 2E 16 00 00 00 00 00 00 CD 00 00 00 00 2A -R 00 00 01 00 02 04 14 00 02 09 04 00 -T 34 16 00 00 00 00 00 00 7D B4 28 0A +T CC 18 00 00 DD 5E 02 DD 56 03 3E EF 13 00 00 +R 00 00 01 00 29 0B 01 00 +T D4 18 00 00 21 EF 13 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T DB 18 00 00 75 FE DD 74 FF 7D B4 20 0B +R 00 00 01 00 +T E4 18 00 00 +R 00 00 01 00 +T E4 18 00 00 11 BB 05 00 00 3E 81 1F 00 00 21 +R 00 00 01 00 00 05 02 00 29 0A 01 00 +T EA 18 00 00 81 1F 00 00 CD 00 00 00 00 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T EF 18 00 00 +R 00 00 01 00 +T EF 18 00 00 DD 5E FE DD 56 FF 3E 13 17 00 00 +R 00 00 01 00 29 0B 01 00 +T F7 18 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T FE 18 00 00 75 FC DD 74 FD 01 10 00 C5 E5 DD +R 00 00 01 00 +T 09 19 00 00 7E 04 E6 1F 6F DD 7E 05 E6 00 67 +R 00 00 01 00 +T 14 19 00 00 29 29 29 29 4D 44 E1 09 4D 44 DD +R 00 00 01 00 +T 1F 19 00 00 5E 0A DD 56 0B 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 11 00 +T 27 19 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T 2E 19 00 00 4E FC DD 46 FD DD 5E FE DD 56 FF +R 00 00 01 00 +T 39 19 00 00 3E 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 3F 19 00 00 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 04 14 00 02 09 09 00 +T 44 19 00 00 +R 00 00 01 00 +T 44 19 00 00 CD 00 00 00 00 EC FF 11 +R 00 00 01 00 02 05 19 00 +T 4A 19 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 15 00 2B 09 04 00 +T 4F 19 00 00 00 00 00 00 CD 00 00 00 00 2A +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 55 19 00 00 00 00 00 00 7D B4 28 0F R 00 00 01 00 00 04 04 00 -T 3A 16 00 00 +T 5B 19 00 00 R 00 00 01 00 -T 3A 16 00 00 21 D6 05 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 41 16 00 00 F1 18 28 +T 5B 19 00 00 21 D6 05 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 61 19 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T 68 19 00 00 18 2D R 00 00 01 00 -T 44 16 00 00 +T 6A 19 00 00 R 00 00 01 00 -T 44 16 00 00 21 00 00 00 00 E5 01 14 00 21 +T 6A 19 00 00 21 00 00 00 00 E5 01 14 00 21 R 00 00 01 00 02 05 12 00 -T 4C 16 00 00 02 00 39 5D 54 CD 00 00 00 00 F1 -R 00 00 01 00 02 0A 0E 00 -T 55 16 00 00 7D B4 28 0E DD 7E EC FE 79 28 0C +T 72 19 00 00 02 00 39 5D 54 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 0F 00 +T 7A 19 00 00 00 00 00 00 CD 00 00 00 00 F1 7D +R 00 00 01 00 02 04 0F 00 02 09 14 00 +T 81 19 00 00 B4 28 0E DD 7E EC FE 79 28 0C DD R 00 00 01 00 -T 60 16 00 00 DD 7E EC FE 59 28 05 +T 8C 19 00 00 7E EC FE 59 28 05 R 00 00 01 00 -T 67 16 00 00 +T 92 19 00 00 R 00 00 01 00 -T 67 16 00 00 +T 92 19 00 00 R 00 00 01 00 -T 67 16 00 00 +T 92 19 00 00 R 00 00 01 00 -T 67 16 00 00 +T 92 19 00 00 R 00 00 01 00 -T 67 16 00 00 +T 92 19 00 00 R 00 00 01 00 -T 67 16 00 00 21 00 00 18 03 +T 92 19 00 00 21 00 00 18 03 R 00 00 01 00 -T 6C 16 00 00 +T 97 19 00 00 R 00 00 01 00 -T 6C 16 00 00 +T 97 19 00 00 R 00 00 01 00 -T 6C 16 00 00 21 01 00 +T 97 19 00 00 21 01 00 R 00 00 01 00 -T 6F 16 00 00 +T 9A 19 00 00 R 00 00 01 00 -T 6F 16 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 72 16 00 00 +T 9A 19 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 9D 19 00 00 R 00 00 01 00 -T 72 16 00 00 CD 00 00 00 00 F8 FF DD 36 FC 01 -R 00 00 01 00 02 05 18 00 -T 7B 16 00 00 DD 36 FD 00 DD 6E 02 DD 66 03 DD +T 9D 19 00 00 CD 00 00 00 00 F8 FF DD 36 FC 01 +R 00 00 01 00 02 05 19 00 +T A6 19 00 00 DD 36 FD 00 DD 6E 02 DD 66 03 DD R 00 00 01 00 -T 86 16 00 00 75 FE DD 74 FF 2B DD 75 FE DD 74 +T B1 19 00 00 75 FE DD 74 FF 2B DD 75 FE DD 74 R 00 00 01 00 -T 91 16 00 00 FF 4D 44 21 00 00 CD 00 00 00 00 -R 00 00 01 00 02 0B 1B 00 -T 9A 16 00 00 30 6C DD 6E FC DD 66 FD 29 DD 4E +T BC 19 00 00 FF 4D 44 21 00 00 CD 00 00 00 00 +R 00 00 01 00 02 0B 1C 00 +T C5 19 00 00 30 76 DD 6E FC DD 66 FD 29 DD 4E R 00 00 01 00 -T A5 16 00 00 04 DD 46 05 09 46 23 66 68 DD 75 +T D0 19 00 00 04 DD 46 05 09 46 23 66 68 DD 75 R 00 00 01 00 -T B0 16 00 00 FA DD 74 FB 7E FE 2D 20 4F +T DB 19 00 00 FA DD 74 FB 7E FE 2D 20 59 R 00 00 01 00 -T B9 16 00 00 +T E4 19 00 00 R 00 00 01 00 -T B9 16 00 00 +T E4 19 00 00 R 00 00 01 00 -T B9 16 00 00 +T E4 19 00 00 R 00 00 01 00 -T B9 16 00 00 DD 6E FA DD 66 FB 23 7E FE 79 28 +T E4 19 00 00 DD 6E FA DD 66 FB 23 7E FE 79 28 R 00 00 01 00 -T C4 16 00 00 27 DD 6E FA DD 66 FB 23 7E FE 59 +T EF 19 00 00 31 DD 6E FA DD 66 FB 23 7E FE 59 R 00 00 01 00 -T CF 16 00 00 28 1B +T FA 19 00 00 28 25 R 00 00 01 00 -T D1 16 00 00 +T FC 19 00 00 R 00 00 01 00 -T D1 16 00 00 +T FC 19 00 00 R 00 00 01 00 -T D1 16 00 00 +T FC 19 00 00 R 00 00 01 00 -T D1 16 00 00 DD 6E FA DD 66 FB E5 21 +T FC 19 00 00 DD 6E FA DD 66 FB E5 21 R 00 00 01 00 -T D9 16 00 00 D9 05 00 00 E5 21 00 00 00 00 E5 -R 00 00 01 00 00 04 02 00 02 0A 09 00 -T E0 16 00 00 CD 00 00 00 00 F1 F1 F1 11 01 00 -R 00 00 01 00 02 05 20 00 -T E9 16 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 21 00 -T EC 16 00 00 +T 04 1A 00 00 D9 05 00 00 E5 21 00 00 00 00 E5 +R 00 00 01 00 00 04 02 00 02 0A 0A 00 +T 0B 1A 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 22 00 02 0A 22 00 +T 11 1A 00 00 00 00 00 00 F1 F1 F1 11 01 00 3E +R 00 00 01 00 02 04 14 00 +T 1A 1A 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T 1F 1A 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 21 1A 00 00 R 00 00 01 00 -T EC 16 00 00 2A 00 00 00 00 23 22 00 00 00 00 +T 21 1A 00 00 2A 00 00 00 00 23 22 00 00 00 00 R 00 00 01 00 00 05 04 00 00 0B 04 00 -T F3 16 00 00 DD 34 FC 20 03 DD 34 FD +T 28 1A 00 00 DD 34 FC 20 03 DD 34 FD R 00 00 01 00 -T FB 16 00 00 +T 30 1A 00 00 R 00 00 01 00 -T FB 16 00 00 DD 6E FE DD 66 FF 2B DD 75 FE DD +T 30 1A 00 00 DD 6E FE DD 66 FF 2B DD 75 FE DD R 00 00 01 00 -T 06 17 00 00 74 FF +T 3B 1A 00 00 74 FF R 00 00 01 00 -T 08 17 00 00 +T 3D 1A 00 00 R 00 00 01 00 -T 08 17 00 00 3E 01 DD AE FE DD B6 FF 28 13 +T 3D 1A 00 00 3E 01 DD AE FE DD B6 FF 28 1D R 00 00 01 00 -T 12 17 00 00 +T 47 1A 00 00 R 00 00 01 00 -T 12 17 00 00 21 EC 05 00 00 E5 21 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 09 00 -T 19 17 00 00 E5 CD 00 00 00 00 F1 F1 11 01 00 -R 00 00 01 00 02 06 20 00 -T 22 17 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 21 00 -T 25 17 00 00 +T 47 1A 00 00 21 EC 05 00 00 E5 21 00 00 00 00 +R 00 00 01 00 00 05 02 00 02 0B 0A 00 +T 4E 1A 00 00 E5 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 22 00 02 0B 22 00 +T 54 1A 00 00 CD 00 00 00 00 F1 F1 11 01 00 3E +R 00 00 01 00 02 05 14 00 +T 5D 1A 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T 62 1A 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 64 1A 00 00 R 00 00 01 00 -T 25 17 00 00 DD 6E FC DD 66 FD 29 DD 4E 04 DD +T 64 1A 00 00 DD 6E FC DD 66 FD 29 DD 4E 04 DD R 00 00 01 00 -T 30 17 00 00 46 05 09 4E 23 46 11 02 00 00 00 +T 6F 1A 00 00 46 05 09 4E 23 46 11 02 00 00 00 R 00 00 01 00 00 0B 03 00 -T 39 17 00 00 CD 00 00 00 00 21 02 80 E5 21 -R 00 00 01 00 02 05 15 00 -T 41 17 00 00 02 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 03 00 02 0A 1C 00 -T 48 17 00 00 F1 22 00 00 00 00 CB 7C 28 1A -R 00 00 01 00 00 06 03 00 -T 50 17 00 00 -R 00 00 01 00 -T 50 17 00 00 21 05 06 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 08 00 -T 57 17 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 14 00 02 0B 04 00 -T 5E 17 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 10 00 -T 65 17 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 21 00 -T 6A 17 00 00 -R 00 00 01 00 -T 6A 17 00 00 11 04 00 CD 5B 14 00 00 DD 75 F8 -R 00 00 01 00 00 08 01 00 -T 73 17 00 00 DD 74 F9 01 1E 00 C5 01 -R 00 00 01 00 -T 7B 17 00 00 06 04 00 00 EB CD 00 00 00 00 E1 -R 00 00 01 00 00 04 03 00 02 0A 11 00 -T 82 17 00 00 2A 06 04 00 00 01 C6 31 A7 ED 42 +T 78 1A 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 16 00 02 0A 16 00 +T 7E 1A 00 00 00 00 00 00 21 02 80 E5 21 +R 00 00 01 00 02 04 14 00 +T 85 1A 00 00 02 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 0A 1D 00 +T 8B 1A 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 1D 00 02 09 14 00 +T 92 1A 00 00 22 00 00 00 00 CB 7C 28 2E R 00 00 01 00 00 05 03 00 -T 8B 17 00 00 28 45 +T 99 1A 00 00 +R 00 00 01 00 +T 99 1A 00 00 21 05 06 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 08 00 +T 9F 1A 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 08 00 02 0A 14 00 +T A6 1A 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 15 00 2B 0A 04 00 +T AC 1A 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T B2 1A 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 10 00 +T B7 1A 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 10 00 02 09 14 00 +T BD 1A 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T C2 1A 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T C7 1A 00 00 +R 00 00 01 00 +T C7 1A 00 00 11 04 00 3E 13 17 00 00 21 +R 00 00 01 00 29 08 01 00 +T CD 1A 00 00 13 17 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T D4 1A 00 00 F8 DD 74 F9 01 1E 00 C5 01 +R 00 00 01 00 +T DD 1A 00 00 06 04 00 00 EB 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 0A 11 00 +T E3 1A 00 00 00 00 00 00 CD 00 00 00 00 E1 2A +R 00 00 01 00 02 04 11 00 02 09 14 00 +T EA 1A 00 00 06 04 00 00 01 C6 31 A7 ED 42 28 +R 00 00 01 00 00 04 03 00 +T F3 1A 00 00 5E R 00 00 01 00 -T 8D 17 00 00 +T F4 1A 00 00 R 00 00 01 00 -T 8D 17 00 00 21 06 04 00 00 4E 23 46 C5 2A +T F4 1A 00 00 21 06 04 00 00 4E 23 46 C5 2A R 00 00 01 00 00 05 03 00 -T 95 17 00 00 04 04 00 00 E5 21 12 06 00 00 E5 +T FC 1A 00 00 04 04 00 00 E5 21 12 06 00 00 E5 R 00 00 01 00 00 04 03 00 00 0A 02 00 -T 9C 17 00 00 CD 00 00 00 00 F1 F1 F1 CD -R 00 00 01 00 02 05 08 00 -T A3 17 00 00 28 16 00 00 7D B4 20 06 -R 00 00 01 00 00 04 01 00 -T A9 17 00 00 -R 00 00 01 00 -T A9 17 00 00 11 01 00 CD 00 00 00 00 -R 00 00 01 00 02 08 21 00 -T AF 17 00 00 -R 00 00 01 00 -T AF 17 00 00 21 C6 31 22 06 04 00 00 21 1E 00 +T 03 1B 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 08 00 02 0A 08 00 +T 09 1B 00 00 00 00 00 00 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 0F 1B 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 14 1B 00 00 00 00 00 00 7D B4 20 0B +R 00 00 01 00 02 04 14 00 +T 1A 1B 00 00 +R 00 00 01 00 +T 1A 1B 00 00 11 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 23 00 +T 20 1B 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T 25 1B 00 00 +R 00 00 01 00 +T 25 1B 00 00 21 C6 31 22 06 04 00 00 21 1E 00 R 00 00 01 00 00 08 03 00 -T B8 17 00 00 E5 DD 4E F8 DD 46 F9 11 +T 2E 1B 00 00 E5 DD 4E F8 DD 46 F9 11 R 00 00 01 00 -T C0 17 00 00 06 04 00 00 CD 00 00 00 00 E1 DD -R 00 00 01 00 00 04 03 00 02 09 11 00 -T C7 17 00 00 4E F8 DD 46 F9 11 04 00 CD +T 36 1B 00 00 06 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 11 00 +T 3B 1B 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 11 00 02 09 14 00 +T 42 1B 00 00 4E F8 DD 46 F9 11 04 00 3E R 00 00 01 00 -T D0 17 00 00 8B 14 00 00 -R 00 00 01 00 00 04 01 00 -T D2 17 00 00 +T 4B 1B 00 00 52 17 00 00 21 52 17 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 50 1B 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 52 1B 00 00 R 00 00 01 00 -T D2 17 00 00 2A 08 04 00 00 01 FB FF 09 E5 21 +T 52 1B 00 00 2A 08 04 00 00 01 FB FF 09 E5 21 R 00 00 01 00 00 05 03 00 -T DB 17 00 00 0A 04 00 00 4E 23 46 C5 21 +T 5B 1B 00 00 0A 04 00 00 4E 23 46 C5 21 R 00 00 01 00 00 04 03 00 -T E2 17 00 00 0C 04 00 00 4E 23 46 C5 21 +T 62 1B 00 00 0C 04 00 00 4E 23 46 C5 21 R 00 00 01 00 00 04 03 00 -T E9 17 00 00 02 00 00 00 E5 21 3F 06 00 00 E5 +T 69 1B 00 00 02 00 00 00 E5 21 3F 06 00 00 E5 R 00 00 01 00 00 04 03 00 00 0A 02 00 -T F0 17 00 00 CD 00 00 00 00 F1 F1 F1 F1 F1 CD -R 00 00 01 00 02 05 08 00 -T F9 17 00 00 28 16 00 00 7D B4 20 06 -R 00 00 01 00 00 04 01 00 -T FF 17 00 00 -R 00 00 01 00 -T FF 17 00 00 11 01 00 CD 00 00 00 00 -R 00 00 01 00 02 08 21 00 -T 05 18 00 00 -R 00 00 01 00 -T 05 18 00 00 ED 4B 16 04 00 00 2A 18 04 00 00 +T 70 1B 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 08 00 02 0A 08 00 +T 76 1B 00 00 00 00 00 00 F1 F1 F1 F1 F1 3E +R 00 00 01 00 02 04 14 00 +T 7E 1B 00 00 44 19 00 00 21 44 19 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 83 1B 00 00 00 00 00 00 7D B4 20 0B +R 00 00 01 00 02 04 14 00 +T 89 1B 00 00 +R 00 00 01 00 +T 89 1B 00 00 11 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 23 00 +T 8F 1B 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T 94 1B 00 00 +R 00 00 01 00 +T 94 1B 00 00 ED 4B 16 04 00 00 2A 18 04 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 0C 18 00 00 A7 ED 42 EB CD 00 00 00 00 22 -R 00 00 01 00 02 09 1F 00 -T 14 18 00 00 34 04 00 00 7D B4 20 0A +T 9B 1B 00 00 A7 ED 42 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 21 00 +T A2 1B 00 00 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 04 21 00 02 09 14 00 +T A8 1B 00 00 34 04 00 00 7D B4 20 0B R 00 00 01 00 00 04 03 00 -T 1A 18 00 00 +T AE 1B 00 00 R 00 00 01 00 -T 1A 18 00 00 DD 36 FA 79 06 00 00 DD 36 FB +T AE 1B 00 00 DD 36 FA 79 06 00 00 DD 36 FB R 00 00 01 00 09 07 02 00 -T 21 18 00 00 79 06 00 00 18 6D -R 00 00 01 00 89 04 02 00 -T 24 18 00 00 +T B5 1B 00 00 79 06 00 00 C3 3A 1C 00 00 +R 00 00 01 00 89 04 02 00 00 09 01 00 +T B9 1B 00 00 R 00 00 01 00 -T 24 18 00 00 ED 4B 16 04 00 00 2A 18 04 00 00 +T B9 1B 00 00 ED 4B 16 04 00 00 2A 18 04 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 2B 18 00 00 A7 ED 42 E5 0E 00 ED 5B +T C0 1B 00 00 A7 ED 42 E5 0E 00 ED 5B R 00 00 01 00 -T 33 18 00 00 34 04 00 00 CD 00 00 00 00 E1 ED -R 00 00 01 00 00 04 03 00 02 09 05 00 -T 3A 18 00 00 4B 18 04 00 00 2A 1A 04 00 00 A7 +T C8 1B 00 00 34 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 05 00 +T CD 1B 00 00 00 00 00 00 CD 00 00 00 00 E1 ED +R 00 00 01 00 02 04 05 00 02 09 14 00 +T D4 1B 00 00 4B 18 04 00 00 2A 1A 04 00 00 A7 R 00 00 01 00 00 05 03 00 00 0A 03 00 -T 41 18 00 00 ED 42 EB CD 00 00 00 00 22 -R 00 00 01 00 02 08 1F 00 -T 48 18 00 00 36 04 00 00 7D B4 20 0A +T DB 1B 00 00 ED 42 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 21 00 +T E1 1B 00 00 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 04 21 00 02 09 14 00 +T E7 1B 00 00 36 04 00 00 7D B4 20 0A R 00 00 01 00 00 04 03 00 -T 4E 18 00 00 +T ED 1B 00 00 R 00 00 01 00 -T 4E 18 00 00 DD 36 FA 86 06 00 00 DD 36 FB +T ED 1B 00 00 DD 36 FA 86 06 00 00 DD 36 FB R 00 00 01 00 09 07 02 00 -T 55 18 00 00 86 06 00 00 18 39 +T F4 1B 00 00 86 06 00 00 18 43 R 00 00 01 00 89 04 02 00 -T 58 18 00 00 +T F7 1B 00 00 R 00 00 01 00 -T 58 18 00 00 ED 4B 18 04 00 00 2A 1A 04 00 00 +T F7 1B 00 00 ED 4B 18 04 00 00 2A 1A 04 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 5F 18 00 00 A7 ED 42 E5 0E 00 ED 5B +T FE 1B 00 00 A7 ED 42 E5 0E 00 ED 5B R 00 00 01 00 -T 67 18 00 00 36 04 00 00 CD 00 00 00 00 E1 2A -R 00 00 01 00 00 04 03 00 02 09 05 00 -T 6E 18 00 00 0A 04 00 00 29 29 29 22 +T 06 1C 00 00 36 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 05 00 +T 0B 1C 00 00 00 00 00 00 CD 00 00 00 00 E1 2A +R 00 00 01 00 02 04 05 00 02 09 14 00 +T 12 1C 00 00 0A 04 00 00 29 29 29 22 R 00 00 01 00 00 04 03 00 -T 74 18 00 00 24 04 00 00 ED 4B 08 04 00 00 ED +T 18 1C 00 00 24 04 00 00 ED 4B 08 04 00 00 ED R 00 00 01 00 00 04 03 00 00 0A 03 00 -T 7B 18 00 00 43 26 04 00 00 EB CD 00 00 00 00 -R 00 00 01 00 00 05 03 00 02 0B 1F 00 -T 82 18 00 00 22 38 04 00 00 7D B4 20 23 -R 00 00 01 00 00 05 03 00 -T 89 18 00 00 +T 1F 1C 00 00 43 26 04 00 00 EB 3E 00 00 00 00 +R 00 00 01 00 00 05 03 00 2B 0B 21 00 +T 25 1C 00 00 21 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 05 21 00 02 0A 14 00 +T 2C 1C 00 00 38 04 00 00 7D B4 20 2D +R 00 00 01 00 00 04 03 00 +T 32 1C 00 00 R 00 00 01 00 -T 89 18 00 00 DD 36 FA 93 06 00 00 DD 36 FB +T 32 1C 00 00 DD 36 FA 93 06 00 00 DD 36 FB R 00 00 01 00 09 07 02 00 -T 90 18 00 00 93 06 00 00 +T 39 1C 00 00 93 06 00 00 R 00 00 01 00 89 04 02 00 -T 91 18 00 00 -R 00 00 01 00 -T 91 18 00 00 DD 6E FA DD 66 FB E5 21 -R 00 00 01 00 -T 99 18 00 00 9F 06 00 00 E5 21 00 00 00 00 E5 -R 00 00 01 00 00 04 02 00 02 0A 09 00 -T A0 18 00 00 CD 00 00 00 00 F1 F1 F1 11 01 00 -R 00 00 01 00 02 05 20 00 -T A9 18 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 21 00 -T AC 18 00 00 -R 00 00 01 00 -T AC 18 00 00 2A 24 04 00 00 E5 0E 00 ED 5B +T 3A 1C 00 00 +R 00 00 01 00 +T 3A 1C 00 00 DD 6E FA DD 66 FB E5 21 +R 00 00 01 00 +T 42 1C 00 00 9F 06 00 00 E5 21 00 00 00 00 E5 +R 00 00 01 00 00 04 02 00 02 0A 0A 00 +T 49 1C 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 22 00 02 0A 22 00 +T 4F 1C 00 00 00 00 00 00 F1 F1 F1 11 01 00 3E +R 00 00 01 00 02 04 14 00 +T 58 1C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T 5D 1C 00 00 00 00 00 00 +R 00 00 01 00 02 04 14 00 +T 5F 1C 00 00 +R 00 00 01 00 +T 5F 1C 00 00 2A 24 04 00 00 E5 0E 00 ED 5B R 00 00 01 00 00 05 03 00 -T B4 18 00 00 38 04 00 00 CD 00 00 00 00 E1 21 -R 00 00 01 00 00 04 03 00 02 09 05 00 -T BB 18 00 00 BA 06 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T C2 18 00 00 11 00 00 00 00 CD 00 00 00 00 CD -R 00 00 01 00 02 05 14 00 02 0A 04 00 -T C9 18 00 00 E6 00 00 00 21 D5 06 00 00 E5 CD -R 00 00 01 00 00 04 01 00 00 09 02 00 -T D0 18 00 00 00 00 00 00 F1 11 00 00 00 00 CD -R 00 00 01 00 02 04 08 00 02 0A 14 00 -T D7 18 00 00 00 00 00 00 CD 56 05 00 00 21 -R 00 00 01 00 02 04 04 00 00 09 01 00 -T DD 18 00 00 F7 06 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T E4 18 00 00 11 00 00 00 00 CD 00 00 00 00 CD -R 00 00 01 00 02 05 14 00 02 0A 04 00 -T EB 18 00 00 D0 07 00 00 21 1B 07 00 00 E5 CD -R 00 00 01 00 00 04 01 00 00 09 02 00 -T F2 18 00 00 00 00 00 00 F1 11 00 00 00 00 CD -R 00 00 01 00 02 04 08 00 02 0A 14 00 -T F9 18 00 00 00 00 00 00 CD AD 0E 00 00 21 -R 00 00 01 00 02 04 04 00 00 09 01 00 -T FF 18 00 00 40 07 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 08 00 -T 06 19 00 00 11 00 00 00 00 CD 00 00 00 00 CD -R 00 00 01 00 02 05 14 00 02 0A 04 00 -T 0D 19 00 00 9C 0F 00 00 ED 5B 00 00 00 00 CD -R 00 00 01 00 00 04 01 00 00 0A 03 00 -T 14 19 00 00 00 00 00 00 21 5F 07 00 00 E5 CD -R 00 00 01 00 02 04 0B 00 00 09 02 00 -T 1B 19 00 00 00 00 00 00 F1 11 00 00 CD -R 00 00 01 00 02 04 08 00 -T 22 19 00 00 00 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 04 21 00 02 09 0F 00 -T 27 19 00 00 -R 00 00 01 00 -T 27 19 00 00 CD 00 00 00 00 FA FF DD 6E 08 DD -R 00 00 01 00 02 05 18 00 -T 30 19 00 00 66 09 DD 75 FC DD 74 FD -R 00 00 01 00 -T 38 19 00 00 -R 00 00 01 00 -T 38 19 00 00 DD 6E 0E DD 66 0F E5 DD 6E 0C DD -R 00 00 01 00 -T 43 19 00 00 66 0D E5 DD 6E FC DD 66 FD 01 -R 00 00 01 00 -T 4D 19 00 00 00 00 CD 00 00 00 00 D2 -R 00 00 01 00 02 07 17 00 -T 53 19 00 00 06 1A 00 00 +T 67 1C 00 00 38 04 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 05 00 +T 6C 1C 00 00 00 00 00 00 CD 00 00 00 00 E1 21 +R 00 00 01 00 02 04 05 00 02 09 14 00 +T 73 1C 00 00 BA 06 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T 79 1C 00 00 00 00 00 00 CD 00 00 00 00 F1 11 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 80 1C 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 15 00 2B 09 04 00 +T 85 1C 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 8B 1C 00 00 4A 01 00 00 21 4A 01 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 90 1C 00 00 00 00 00 00 21 D5 06 00 00 E5 3E +R 00 00 01 00 02 04 14 00 00 09 02 00 +T 97 1C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 9C 1C 00 00 00 00 00 00 F1 11 00 00 00 00 3E +R 00 00 01 00 02 04 14 00 02 0A 15 00 +T A3 1C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 04 00 02 09 04 00 +T A8 1C 00 00 00 00 00 00 3E 29 06 00 00 21 +R 00 00 01 00 02 04 14 00 29 09 01 00 +T AD 1C 00 00 29 06 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T B3 1C 00 00 F7 06 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T B9 1C 00 00 00 00 00 00 CD 00 00 00 00 F1 11 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T C0 1C 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 15 00 2B 09 04 00 +T C5 1C 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 04 00 02 09 14 00 +T CB 1C 00 00 D0 08 00 00 21 D0 08 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T D0 1C 00 00 00 00 00 00 21 1B 07 00 00 E5 3E +R 00 00 01 00 02 04 14 00 00 09 02 00 +T D7 1C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T DC 1C 00 00 00 00 00 00 F1 11 00 00 00 00 3E +R 00 00 01 00 02 04 14 00 02 0A 15 00 +T E3 1C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 04 00 02 09 04 00 +T E8 1C 00 00 00 00 00 00 3E 98 10 00 00 21 +R 00 00 01 00 02 04 14 00 29 09 01 00 +T ED 1C 00 00 98 10 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T F3 1C 00 00 40 07 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 08 00 +T F9 1C 00 00 00 00 00 00 CD 00 00 00 00 F1 11 +R 00 00 01 00 02 04 08 00 02 09 14 00 +T 00 1D 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 15 00 2B 09 04 00 +T 05 1D 00 00 00 00 00 00 CD 00 00 00 00 3E +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 0B 1D 00 00 B2 11 00 00 21 B2 11 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 10 1D 00 00 00 00 00 00 ED 5B 00 00 00 00 3E +R 00 00 01 00 02 04 14 00 00 0A 03 00 +T 17 1D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0C 00 02 09 0C 00 +T 1C 1D 00 00 00 00 00 00 21 5F 07 00 00 E5 3E +R 00 00 01 00 02 04 14 00 00 09 02 00 +T 23 1D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 08 00 02 09 08 00 +T 28 1D 00 00 00 00 00 00 F1 11 00 00 3E +R 00 00 01 00 02 04 14 00 +T 2F 1D 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 23 00 02 09 23 00 +T 34 1D 00 00 00 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 04 14 00 02 09 09 00 +T 39 1D 00 00 +R 00 00 01 00 +T 39 1D 00 00 CD 00 00 00 00 FA FF DD 6E 0A DD +R 00 00 01 00 02 05 19 00 +T 42 1D 00 00 66 0B DD 75 FC DD 74 FD +R 00 00 01 00 +T 4A 1D 00 00 +R 00 00 01 00 +T 4A 1D 00 00 DD 6E 10 DD 66 11 E5 DD 6E 0E DD +R 00 00 01 00 +T 55 1D 00 00 66 0F E5 DD 6E FC DD 66 FD 01 +R 00 00 01 00 +T 5F 1D 00 00 00 00 CD 00 00 00 00 D2 +R 00 00 01 00 02 07 18 00 +T 65 1D 00 00 2C 1E 00 00 R 00 00 01 00 00 04 01 00 -T 55 19 00 00 +T 67 1D 00 00 R 00 00 01 00 -T 55 19 00 00 DD 4E 0C DD 46 0D DD 6E FC DD 66 +T 67 1D 00 00 DD 4E 0E DD 46 0F DD 6E FC DD 66 R 00 00 01 00 -T 60 19 00 00 FD 3E 02 84 67 7D E6 00 5F 7C E6 +T 72 1D 00 00 FD 3E 02 84 67 7D E6 00 5F 7C E6 R 00 00 01 00 -T 6B 19 00 00 FE 57 CD 00 00 00 00 DD 75 FE DD -R 00 00 01 00 02 07 1A 00 -T 74 19 00 00 74 FF DD 4E FC DD 46 FD A7 ED 42 +T 7D 1D 00 00 FE 57 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 1B 00 +T 82 1D 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 1B 00 02 09 14 00 +T 89 1D 00 00 FE DD 74 FF DD 4E FC DD 46 FD A7 R 00 00 01 00 -T 7F 19 00 00 01 00 02 A7 ED 42 30 16 +T 94 1D 00 00 ED 42 01 00 02 A7 ED 42 30 1B R 00 00 01 00 -T 87 19 00 00 +T 9E 1D 00 00 R 00 00 01 00 -T 87 19 00 00 06 09 DD 5E FC DD 56 FD CD +T 9E 1D 00 00 06 09 DD 5E FC DD 56 FD CD R 00 00 01 00 -T 90 19 00 00 00 00 00 00 CD 5B 14 00 00 DD 75 -R 00 00 01 00 02 04 00 00 00 09 01 00 -T 97 19 00 00 FA DD 74 FB 18 08 +T A7 1D 00 00 00 00 00 00 3E 13 17 00 00 21 +R 00 00 01 00 02 04 00 00 29 09 01 00 +T AC 1D 00 00 13 17 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 14 00 +T B3 1D 00 00 FA DD 74 FB 18 08 R 00 00 01 00 -T 9D 19 00 00 +T B9 1D 00 00 R 00 00 01 00 -T 9D 19 00 00 DD 36 FA 02 02 00 00 DD 36 FB +T B9 1D 00 00 DD 36 FA 02 02 00 00 DD 36 FB R 00 00 01 00 09 07 03 00 -T A4 19 00 00 02 02 00 00 +T C0 1D 00 00 02 02 00 00 R 00 00 01 00 89 04 03 00 -T A5 19 00 00 +T C1 1D 00 00 R 00 00 01 00 -T A5 19 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 +T C1 1D 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 R 00 00 01 00 -T B0 19 00 00 FF A7 ED 42 E5 79 E6 FF 6F 78 E6 +T CC 1D 00 00 FF A7 ED 42 E5 79 E6 FF 6F 78 E6 R 00 00 01 00 -T BB 19 00 00 01 67 DD 5E FA DD 56 FB 19 4D 44 +T D7 1D 00 00 01 67 DD 5E FA DD 56 FB 19 4D 44 R 00 00 01 00 -T C6 19 00 00 DD 5E 08 DD 56 09 DD 6E FC DD 66 +T E2 1D 00 00 DD 5E 0A DD 56 0B DD 6E FC DD 66 R 00 00 01 00 -T D1 19 00 00 FD A7 ED 52 DD 5E 02 DD 56 03 19 +T ED 1D 00 00 FD A7 ED 52 DD 5E 02 DD 56 03 19 R 00 00 01 00 -T DC 19 00 00 EB CD 00 00 00 00 E1 DD 4E FA DD -R 00 00 01 00 02 06 11 00 -T E5 19 00 00 46 FB C5 06 09 DD 5E FC DD 56 FD +T F8 1D 00 00 EB 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 11 00 02 0B 11 00 +T FE 1D 00 00 CD 00 00 00 00 E1 DD 4E FA DD 46 +R 00 00 01 00 02 05 14 00 +T 07 1E 00 00 FB C5 06 09 DD 5E FC DD 56 FD CD R 00 00 01 00 -T F0 19 00 00 CD 00 00 00 00 C1 CD 8B 14 00 00 -R 00 00 01 00 02 05 00 00 00 0B 01 00 -T F7 19 00 00 DD 6E FE DD 66 FF DD 75 FC DD 74 +T 12 1E 00 00 00 00 00 00 3E 52 17 00 00 21 +R 00 00 01 00 02 04 00 00 29 09 01 00 +T 17 1E 00 00 52 17 00 00 C1 CD 00 00 00 00 DD +R 00 00 01 00 00 04 01 00 02 0A 14 00 +T 1E 1E 00 00 6E FE DD 66 FF DD 75 FC DD 74 FD R 00 00 01 00 -T 02 1A 00 00 FD C3 38 19 00 00 -R 00 00 01 00 00 06 01 00 -T 06 1A 00 00 +T 29 1E 00 00 C3 4A 1D 00 00 +R 00 00 01 00 00 05 01 00 +T 2C 1E 00 00 R 00 00 01 00 -T 06 1A 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 09 1A 00 00 +T 2C 1E 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 2F 1E 00 00 R 00 00 01 00 -T 09 1A 00 00 CD 00 00 00 00 F4 FF DD 6E 02 DD -R 00 00 01 00 02 05 18 00 -T 12 1A 00 00 66 03 DD 75 FA DD 74 FB +T 2F 1E 00 00 CD 00 00 00 00 F4 FF DD 6E 02 DD +R 00 00 01 00 02 05 19 00 +T 38 1E 00 00 66 03 DD 75 FA DD 74 FB R 00 00 01 00 -T 1A 1A 00 00 +T 40 1E 00 00 R 00 00 01 00 -T 1A 1A 00 00 DD 4E 04 DD 46 05 DD 6E FA DD 66 +T 40 1E 00 00 DD 4E 04 DD 46 05 DD 6E FA DD 66 R 00 00 01 00 -T 25 1A 00 00 FB A7 ED 42 D2 46 1B 00 00 +T 4B 1E 00 00 FB A7 ED 42 D2 7B 1F 00 00 R 00 00 01 00 00 09 01 00 -T 2C 1A 00 00 +T 52 1E 00 00 R 00 00 01 00 -T 2C 1A 00 00 DD 4E 04 DD 46 05 DD 6E FA DD 66 +T 52 1E 00 00 DD 4E 04 DD 46 05 DD 6E FA DD 66 R 00 00 01 00 -T 37 1A 00 00 FB 3E 02 84 67 7D E6 00 5F 7C E6 +T 5D 1E 00 00 FB 3E 02 84 67 7D E6 00 5F 7C E6 R 00 00 01 00 -T 42 1A 00 00 FE 57 CD 00 00 00 00 DD 75 FC DD -R 00 00 01 00 02 07 1A 00 -T 4B 1A 00 00 74 FD 06 09 DD 5E FA DD 56 FB CD +T 68 1E 00 00 FE 57 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 1B 00 +T 6D 1E 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 1B 00 02 09 14 00 +T 74 1E 00 00 FC DD 74 FD 06 09 DD 5E FA DD 56 R 00 00 01 00 -T 56 1A 00 00 00 00 00 00 CD 5B 14 00 00 DD 75 -R 00 00 01 00 02 04 00 00 00 09 01 00 -T 5D 1A 00 00 F4 DD 74 F5 DD 7E FA E6 FF 4F DD +T 7F 1E 00 00 FB CD 00 00 00 00 3E 13 17 00 00 +R 00 00 01 00 02 06 00 00 29 0B 01 00 +T 85 1E 00 00 21 13 17 00 00 CD 00 00 00 00 DD +R 00 00 01 00 00 05 01 00 02 0A 14 00 +T 8C 1E 00 00 75 F4 DD 74 F5 DD 7E FA E6 FF 4F R 00 00 01 00 -T 68 1A 00 00 7E FB E6 01 47 09 DD 75 F6 DD 74 +T 97 1E 00 00 DD 7E FB E6 01 47 09 DD 75 F6 DD R 00 00 01 00 -T 73 1A 00 00 F7 DD 6E FA DD 66 FB DD 75 F8 DD +T A2 1E 00 00 74 F7 DD 6E FA DD 66 FB DD 75 F8 R 00 00 01 00 -T 7E 1A 00 00 74 F9 +T AD 1E 00 00 DD 74 F9 R 00 00 01 00 -T 80 1A 00 00 +T B0 1E 00 00 R 00 00 01 00 -T 80 1A 00 00 DD 4E FC DD 46 FD DD 6E F8 DD 66 +T B0 1E 00 00 DD 4E FC DD 46 FD DD 6E F8 DD 66 R 00 00 01 00 -T 8B 1A 00 00 F9 A7 ED 42 D2 37 1B 00 00 +T BB 1E 00 00 F9 A7 ED 42 D2 6C 1F 00 00 R 00 00 01 00 00 09 01 00 -T 92 1A 00 00 +T C2 1E 00 00 R 00 00 01 00 -T 92 1A 00 00 DD 6E F6 DD 66 F7 46 04 CA +T C2 1E 00 00 DD 6E F6 DD 66 F7 46 04 CA R 00 00 01 00 -T 9B 1A 00 00 24 1B 00 00 +T CB 1E 00 00 59 1F 00 00 R 00 00 01 00 00 04 01 00 -T 9D 1A 00 00 +T CD 1E 00 00 R 00 00 01 00 -T 9D 1A 00 00 DD 4E 02 DD 46 03 DD 6E F8 DD 66 +T CD 1E 00 00 DD 4E 02 DD 46 03 DD 6E F8 DD 66 R 00 00 01 00 -T A8 1A 00 00 F9 A7 ED 42 29 29 29 DD 75 FE DD +T D8 1E 00 00 F9 A7 ED 42 29 29 29 DD 75 FE DD R 00 00 01 00 -T B3 1A 00 00 74 FF AF DD 77 F8 DD 77 F9 +T E3 1E 00 00 74 FF AF DD 77 F8 DD 77 F9 R 00 00 01 00 -T BC 1A 00 00 +T EC 1E 00 00 R 00 00 01 00 -T BC 1A 00 00 01 07 00 DD 6E F8 DD 66 F9 A7 ED +T EC 1E 00 00 01 07 00 DD 6E F8 DD 66 F9 A7 ED R 00 00 01 00 -T C7 1A 00 00 42 30 1D +T F7 1E 00 00 42 30 1D R 00 00 01 00 -T CA 1A 00 00 +T FA 1E 00 00 R 00 00 01 00 -T CA 1A 00 00 DD 6E F6 DD 66 F7 DD 46 F8 3E 01 +T FA 1E 00 00 DD 6E F6 DD 66 F7 DD 46 F8 3E 01 R 00 00 01 00 -T D5 1A 00 00 CD 00 00 00 00 A6 20 02 -R 00 00 01 00 02 05 1D 00 -T DB 1A 00 00 +T 05 1F 00 00 CD 00 00 00 00 A6 20 02 +R 00 00 01 00 02 05 1E 00 +T 0B 1F 00 00 R 00 00 01 00 -T DB 1A 00 00 18 0A +T 0B 1F 00 00 18 0A R 00 00 01 00 -T DD 1A 00 00 +T 0D 1F 00 00 R 00 00 01 00 -T DD 1A 00 00 DD 34 F8 20 03 DD 34 F9 +T 0D 1F 00 00 DD 34 F8 20 03 DD 34 F9 R 00 00 01 00 -T E5 1A 00 00 +T 15 1F 00 00 R 00 00 01 00 -T E5 1A 00 00 18 D5 +T 15 1F 00 00 18 D5 R 00 00 01 00 -T E7 1A 00 00 +T 17 1F 00 00 R 00 00 01 00 -T E7 1A 00 00 21 0A 00 39 7E DD 86 F8 77 23 7E +T 17 1F 00 00 21 0A 00 39 7E DD 86 F8 77 23 7E R 00 00 01 00 -T F2 1A 00 00 DD 8E F9 77 DD 6E F6 DD 66 F7 DD +T 22 1F 00 00 DD 8E F9 77 DD 6E F6 DD 66 F7 DD R 00 00 01 00 -T FD 1A 00 00 46 F8 3E 01 CD 00 00 00 00 B6 77 -R 00 00 01 00 02 09 1D 00 -T 06 1B 00 00 DD 4E F4 DD 46 F5 C5 06 09 DD 5E +T 2D 1F 00 00 46 F8 3E 01 CD 00 00 00 00 B6 77 +R 00 00 01 00 02 09 1E 00 +T 36 1F 00 00 DD 4E F4 DD 46 F5 C5 06 09 DD 5E R 00 00 01 00 -T 11 1B 00 00 FA DD 56 FB CD 00 00 00 00 C1 CD +T 41 1F 00 00 FA DD 56 FB CD 00 00 00 00 3E R 00 00 01 00 02 09 00 00 -T 1A 1B 00 00 8B 14 00 00 DD 6E FE DD 66 FF 18 -R 00 00 01 00 00 04 01 00 -T 23 1B 00 00 25 +T 49 1F 00 00 52 17 00 00 21 52 17 00 00 C1 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 4F 1F 00 00 00 00 00 00 DD 6E FE DD 66 FF 18 +R 00 00 01 00 02 04 14 00 +T 58 1F 00 00 25 R 00 00 01 00 -T 24 1B 00 00 +T 59 1F 00 00 R 00 00 01 00 -T 24 1B 00 00 DD 34 F6 20 03 DD 34 F7 +T 59 1F 00 00 DD 34 F6 20 03 DD 34 F7 R 00 00 01 00 -T 2C 1B 00 00 +T 61 1F 00 00 R 00 00 01 00 -T 2C 1B 00 00 DD 34 F8 20 03 DD 34 F9 +T 61 1F 00 00 DD 34 F8 20 03 DD 34 F9 R 00 00 01 00 -T 34 1B 00 00 +T 69 1F 00 00 R 00 00 01 00 -T 34 1B 00 00 C3 80 1A 00 00 +T 69 1F 00 00 C3 B0 1E 00 00 R 00 00 01 00 00 05 01 00 -T 37 1B 00 00 +T 6C 1F 00 00 R 00 00 01 00 -T 37 1B 00 00 DD 6E FC DD 66 FD DD 75 FA DD 74 +T 6C 1F 00 00 DD 6E FC DD 66 FD DD 75 FA DD 74 R 00 00 01 00 -T 42 1B 00 00 FB C3 1A 1A 00 00 +T 77 1F 00 00 FB C3 40 1E 00 00 R 00 00 01 00 00 06 01 00 -T 46 1B 00 00 +T 7B 1F 00 00 R 00 00 01 00 -T 46 1B 00 00 21 FF FF +T 7B 1F 00 00 21 FF FF R 00 00 01 00 -T 49 1B 00 00 +T 7E 1F 00 00 R 00 00 01 00 -T 49 1B 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0F 00 -T 4C 1B 00 00 +T 7E 1F 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 09 00 +T 81 1F 00 00 R 00 00 01 00 -T 4C 1B 00 00 CD 00 00 00 00 D5 21 67 07 00 00 +T 81 1F 00 00 CD 00 00 00 00 D5 21 67 07 00 00 R 00 00 01 00 02 05 13 00 00 0B 02 00 -T 53 1B 00 00 E5 CD 00 00 00 00 F1 F1 11 -R 00 00 01 00 02 06 08 00 -T 5A 1B 00 00 00 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 02 04 14 00 02 09 04 00 -T 60 1B 00 00 01 00 CD 00 00 00 00 C3 -R 00 00 01 00 02 07 21 00 -T 66 1B 00 00 00 00 00 00 -R 00 00 01 00 02 04 0F 00 +T 88 1F 00 00 E5 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 08 00 02 0B 08 00 +T 8E 1F 00 00 CD 00 00 00 00 F1 F1 11 +R 00 00 01 00 02 05 14 00 +T 94 1F 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 15 00 2B 09 04 00 +T 99 1F 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 04 00 02 09 14 00 +T 9F 1F 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 23 00 +T A4 1F 00 00 00 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 02 04 23 00 02 09 14 00 +T AA 1F 00 00 00 00 00 00 +R 00 00 01 00 02 04 09 00 T 00 00 00 00 R 00 00 02 00 T 00 00 00 00 63 61 6E 27 74 20 73 65 65 6B 3A diff --git a/src/fsutil/m.bat b/src/fsutil/m.bat deleted file mode 100644 index e476e5ba..00000000 --- a/src/fsutil/m.bat +++ /dev/null @@ -1,13 +0,0 @@ -cl -Zi -I. -I..\kernel -DVAX -DUTIL -DDEBUG=1 -c utils.c -@if errorlevel 1 goto failure -cl -Zi -I. -I..\kernel -DVAX -DUTIL -DNATIVE -DDEBUG=1 -c mkfs.c -@if errorlevel 1 goto failure -link @mkfs.lnk -@if errorlevel 1 goto failure - -@echo SUCCESS -@goto done -:failure -@echo FAILURE -:done - diff --git a/src/fsutil/mkfs.c b/src/fsutil/mkfs.c index 9c0b56bc..22073d50 100644 --- a/src/fsutil/mkfs.c +++ b/src/fsutil/mkfs.c @@ -197,10 +197,17 @@ int da_read(dev, blk, addr) if (read(device_handle, addr, BUFSIZE) != BUFSIZE) { + if (errno == 0) + { + bfill(addr, 0xaa, BUFSIZE); /* for creation of unpadded initrd images */ + } + else + { printf("can't read: "); fflush(stdout); perror(device_name); exit(1); + } } #else bufptr buf = bread(dev, blk, 0); diff --git a/src/fsutil/mkfs.exe b/src/fsutil/mkfs.exe index 601230695b1347fb222da583a9548dba437598dd..34770ddee32f087ce9653091649453f19e6f7459 100644 GIT binary patch delta 19803 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 WOMKon>ozQTaP6uM(@IzTj`?3pGES=i diff --git a/src/fsutil/mkfs.lnk b/src/fsutil/mkfs.lnk index a7a9d4cb..e48eab74 100644 --- a/src/fsutil/mkfs.lnk +++ b/src/fsutil/mkfs.lnk @@ -1,12 +1,14 @@ -k ..\..\lib --l libcl.lib --l libsysl.lib +-l libcb.lib +-l libsysb.lib -l libiar.lib -m -u -i -o mkfs -bl RCODE=0x8100 -..\..\lib\c0l.rel +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\lib\c0b.rel mkfs -utils +utils diff --git a/src/fsutil/mkfs.map b/src/fsutil/mkfs.map index 0ce2377c..6b653807 100644 --- a/src/fsutil/mkfs.map +++ b/src/fsutil/mkfs.map @@ -6,18 +6,18 @@ Area Addr Size Decimal Bytes (Attributes) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00000000 s__DEFAUL | 00000000 l_CCSTR | 00000000 l_ECSTR - 00000000 l_CONST | 00000000 .__.ABS. | 00000000 ?CL64180L - 00000000 ?CL64180B | 00000014 e__DEFAUL | 00000014 l__DEFAUL - 00000232 l_CSTR | 000002D2 l_RCODE | 00000AA2 l_UDATA0 - 00000AD7 l_CDATA0 | 00000AD7 l_IDATA0 | 00001000 l_CSTACK - 00002955 l_CODE | 00008100 s_RCODE | 000083D2 e_RCODE - 000083D2 s_CODE | 0000AD27 s_CSTR | 0000AD27 e_CODE - 0000AD27 e_CONST | 0000AD27 s_CONST | 0000AF59 e_CSTR - 0000AF59 s_IDATA0 | 0000AF59 s_CDATA0 | 0000BA30 s_UDATA0 - 0000BA30 e_CCSTR | 0000BA30 e_ECSTR | 0000BA30 s_CCSTR - 0000BA30 e_CDATA0 | 0000BA30 s_ECSTR | 0000BA30 e_IDATA0 - 0000C4D2 e_UDATA0 | 0000C4D2 s_CSTACK | 0000D4D2 e_CSTACK + 00000000 s__DEFAUL | 00000000 l_CODE | 00000000 l_CCSTR + 00000000 l_ECSTR | 00000000 l_CONST | 00000000 .__.ABS. + 00000000 ?CL64180L | 00000000 ?CL64180B | 00000014 e__DEFAUL + 00000014 l__DEFAUL | 00000232 l_CSTR | 000002F7 l_RCODE + 00000AAD l_UDATA0 | 00000AD7 l_CDATA0 | 00000AD7 l_IDATA0 + 00001000 l_CSTACK | 00004000 e_CODE | 00004000 s_CODE + 00008100 s_RCODE | 000083F7 s_CSTR | 000083F7 e_RCODE + 000083F7 e_CONST | 000083F7 s_CONST | 00008629 e_CSTR + 00008629 s_IDATA0 | 00008629 s_CDATA0 | 00009100 s_UDATA0 + 00009100 e_CCSTR | 00009100 e_ECSTR | 00009100 s_CCSTR + 00009100 e_CDATA0 | 00009100 s_ECSTR | 00009100 e_IDATA0 + 00009BAD e_UDATA0 | 00009BAD s_CSTACK | 0000ABAD e_CSTACK Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) @@ -30,54 +30,34 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -RCODE 00008100 000002D2 = 722. bytes (REL,CON) +RCODE 00008100 000002F7 = 759. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 00008100 __init | 00008115 ?US_RSH_L | 0000811F ?C_V_SWIT - 00008131 ?LEAVE_DI | 00008138 ?ENT_PARM | 00008144 ?L_AND_L0 - 00008162 ?SL_CMP_L | 00008193 ?ENT_AUTO | 000081A7 ?V_SWITCH - 000081B1 ?SS_CMP_L | 000081C3 ?US_MOD_L | 000081CC ?C_LSH_L0 - 000081D3 ?US_DIV_L | 000081E1 ?SL_RSH_L | 000081EF ?L_LSH_L0 - 00008207 ?S_DIVMOD | 0000821D ?LEAVE_32 | 00008225 ?S_MULASG - 0000822F ?S_MUL_L0 | 00008245 ?CALL_IND | 00008246 ?UL_DIVAS - 00008256 ?UL_MOD_L | 0000827B ?UL_DIV_L | 000082A3 ?L_NEG_L0 - 000082B5 ?L_DIVMOD | 0000830D ?L_NOT_L0 | 0000831C ?L_END_MU - 00008325 ?L_MULASG | 00008335 ?L_MUL_L0 | 000083B9 ?L_ADDASG + 00008100 __init | 0000811F ?US_RSH_L | 00008129 ?BANK_LEA + 0000812F ?BANK_FAS | 00008134 ?C_V_SWIT | 00008146 ?ENT_PARM + 00008152 ?BANK_CAL | 0000815F ?L_AND_L0 | 0000817D ?SL_CMP_L + 000081AE ?ENT_AUTO | 000081C2 ?V_SWITCH | 000081CC ?SS_CMP_L + 000081DE ?US_MOD_L | 000081E7 ?C_LSH_L0 | 000081EE ?US_DIV_L + 000081FC ?SL_RSH_L | 0000820A ?BANK_LEA | 00008216 ?L_LSH_L0 + 0000822E ?S_DIVMOD | 00008244 ?S_MULASG | 0000824E ?S_MUL_L0 + 00008264 ?LEAVE_DI | 0000826B ?UL_DIVAS | 0000827B ?UL_MOD_L + 000082A0 ?UL_DIV_L | 000082C8 ?L_NEG_L0 | 000082DA ?L_DIVMOD + 00008332 ?L_NOT_L0 | 00008341 ?L_END_MU | 0000834A ?L_MULASG + 0000835A ?L_MUL_L0 | 000083DE ?L_ADDASG Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CODE 000083D2 00002955 = 10581. bytes (REL,CON) +CONST 000083F7 00000000 = 0. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 000083D2 daread | 00008402 dwrite | 0000842C da_read - 0000849F da_write | 00008512 yes | 00008568 mkfs - 00008A11 doformatt | 00008A73 main | 00008F42 bitmap_du - 00009024 bzero | 0000904E bfill | 0000907A bcopy - 000090B2 int_min | 000090D3 int_max | 000090E9 fflush - 000092DE _write | 000092F8 printf | 00009322 lseek - 0000934A __stdio_c | 000093A1 __stdio_i | 000093CF close - 000093DF abort | 00009423 _exit | 00009433 fgets - 00009518 perror | 00009550 pause | 00009559 isatty - 0000958F fstat | 000095A1 strcpy | 000095BE kill - 000095D0 atoi | 00009752 vfprintf | 00009C85 ltoa - 00009CE3 __longtoa | 00009E77 itoa | 00009EDB fputs - 00009F34 open | 00009F5A malloc | 0000A17C fprintf - 0000A1A9 exit | 0000A1CE _read | 0000A1E8 getpid - 0000A1F6 signal | 0000A216 strerror | 0000A3A5 unix - 0000A3BD fgetc | 0000A4C3 memcpy | 0000A57C on_exit - 0000A5DE atexit | 0000A5EA strcat | 0000A600 unix_long - 0000A618 strchr | 0000A653 strlen | 0000A68A free - 0000A76A fputc | 0000A868 ultoa | 0000A8B8 strtol - 0000A95B sbrk | 0000A96B fread | 0000AB86 strtoul - 0000ACDD toupper | 0000AD02 tolower Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CONST 0000AD27 00000000 = 0. bytes (REL,CON) +CSTR 000083F7 00000232 = 562. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -85,28 +65,28 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTR 0000AD27 00000232 = 562. bytes (REL,CON) +IDATA0 00008629 00000AD7 = 2775. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ + 00008629 bootblock | 00008DA9 dirbuf | 00008FA9 _fmt + 00008FAA _yes | 00008FAB _quick | 00008FAC _verb + 00008FAD _immov | 00008FAE __IO_list | 00008FB0 stdin + 00008FC8 stdout | 00008FE0 stderr | 00008FFA __sys_err + 00008FFC __sys_ner | 00008FFE __on_exit | 00009000 __ctype Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -IDATA0 0000AF59 00000AD7 = 2775. bytes (NUL,CON) +CDATA0 00008629 00000AD7 = 2775. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 0000AF59 bootblock | 0000B6D9 dirbuf | 0000B8D9 _fmt - 0000B8DA _yes | 0000B8DB _quick | 0000B8DC _verb - 0000B8DD _immov | 0000B8DE __IO_list | 0000B8E0 stdin - 0000B8F8 stdout | 0000B910 stderr | 0000B92A __sys_err - 0000B92C __sys_ner | 0000B92E __on_exit | 0000B930 __ctype Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CDATA0 0000AF59 00000AD7 = 2775. bytes (REL,CON) +ECSTR 00009100 00000000 = 0. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -114,7 +94,7 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -ECSTR 0000BA30 00000000 = 0. bytes (NUL,CON) +CCSTR 00009100 00000000 = 0. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ @@ -122,114 +102,136 @@ Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CCSTR 0000BA30 00000000 = 0. bytes (REL,CON) +CODE 00004000 00000000 = 0. bytes (NUL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ + 00005014 daread | 00005053 dwrite | 0000508C da_read + 0000514F da_write | 000051F4 yes | 0000525E mkfs + 00005785 doformatt | 000057FB main | 00005D71 bitmap_du + 00005E67 bzero | 00005E91 bfill | 00005EBD bcopy + 00005EF5 int_min | 00005F16 int_max | 00005F2C fflush + 0000613F _write | 0000615E printf | 0000618D lseek + 000061BA __stdio_c | 00006225 __stdio_i | 00006263 close + 00006278 abort | 000062E6 _exit | 000062FB fgets + 000063EA perror | 00006427 pause | 00006437 isatty + 00006472 fstat | 00006489 strcpy | 000064B0 kill + 000064C7 atoi | 0000665D vfprintf | 00006BB8 ltoa + 00006C1B __longtoa | 00006DAF itoa | 00006E18 fputs + 00006E76 open | 00006EA1 malloc | 000070CD fprintf + 000070FF exit | 0000712F _read | 0000714E getpid + 00007163 signal | 00007188 strerror | 00007345 unix + 0000735F fgetc | 0000746F memcpy | 0000753D on_exit + 000075B6 atexit | 000075C9 strcat | 000075E9 unix_long + 00007603 strchr | 0000763E strlen | 00007675 free + 00007755 fputc | 00007867 ultoa | 000078BC strtol + 00007964 sbrk | 00007979 fread | 00007BAD strtoul + 00007D04 toupper | 00007D29 tolower Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -UDATA0 0000BA30 00000AA2 = 2722. bytes (REL,CON) +UDATA0 00009100 00000AAD = 2733. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ - 0000BA30 _argc | 0000BA32 _argv | 0000BA34 environ - 0000BA36 errno | 0000BA38 __cleanup | 0000BA3A device_ha - 0000BA3C device_na | 0000BC3C zeroed | 0000BE3C dev - 0000BE3E inode | 0000C03E bitmap_in | 0000C042 bitmap_bl - 0000C046 bitmap_im | 0000C04A bitmap_fi | 0000C04E inode_bit - 0000C050 block_bit | 0000C052 immov_bit | 0000C454 __malloc_ - 0000C458 __malloc_ | 0000C4AA __on_exit + 00009100 _argc | 00009102 _argv | 00009104 environ + 00009106 errno | 00009108 __cleanup | 0000910B device_ha + 0000910D device_na | 0000930D zeroed | 0000950D dev + 0000950F inode | 0000970F bitmap_in | 00009713 bitmap_bl + 00009717 bitmap_im | 0000971B bitmap_fi | 0000971F inode_bit + 00009721 block_bit | 00009723 immov_bit | 00009B25 __malloc_ + 00009B29 __malloc_ | 00009B7B __on_exit Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------- ---- ---- ------- ----- ------------ -CSTACK 0000C4D2 00001000 = 4096. bytes (REL,CON) +CSTACK 00009BAD 00001000 = 4096. bytes (REL,CON) Value Global Value Global Value Global ----- ------ ----- ------ ----- ------ Files Linked [ module(s) ] -..\..\lib\c0l.rel [ _c0l ] +..\..\lib\c0b.rel [ _c0b ] mkfs [ mkfs ] utils [ utils ] Libraries Linked [ object file ] -..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] ..\..\lib\libiar.lib [ reliar\USRSH.rel ] -..\..\lib\libcl.lib [ relcl\fflush.rel ] -..\..\lib\libsysl.lib [ relsysl\write.rel ] -..\..\lib\libcl.lib [ relcl\printf.rel ] -..\..\lib\libsysl.lib [ relsysl\lseek.rel ] -..\..\lib\libcl.lib [ relcl\stdio0.rel ] -..\..\lib\libsysl.lib [ relsysl\close.rel ] -..\..\lib\libcl.lib [ relcl\abort.rel ] -..\..\lib\libsysl.lib [ relsysl\_exit.rel ] -..\..\lib\libcl.lib [ relcl\fgets.rel ] +..\..\lib\libcb.lib [ relcb\fflush.rel ] +..\..\lib\libsysb.lib [ relsysb\write.rel ] +..\..\lib\libcb.lib [ relcb\printf.rel ] +..\..\lib\libsysb.lib [ relsysb\lseek.rel ] +..\..\lib\libcb.lib [ relcb\stdio0.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVEDIRECT.rel ] +..\..\lib\libsysb.lib [ relsysb\close.rel ] +..\..\lib\libcb.lib [ relcb\abort.rel ] +..\..\lib\libsysb.lib [ relsysb\_exit.rel ] +..\..\lib\libcb.lib [ relcb\fgets.rel ] ..\..\lib\libiar.lib [ reliar\CVSWITCH.rel ] -..\..\lib\libcl.lib [ relcl\perror.rel ] -..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] -..\..\lib\libsysl.lib [ relsysl\pause.rel ] -..\..\lib\libcl.lib [ relcl\isatty.rel ] -..\..\lib\libsysl.lib [ relsysl\fstat.rel ] +..\..\lib\libcb.lib [ relcb\perror.rel ] +..\..\lib\libsysb.lib [ relsysb\pause.rel ] +..\..\lib\libcb.lib [ relcb\isatty.rel ] +..\..\lib\libsysb.lib [ relsysb\fstat.rel ] ..\..\lib\libiar.lib [ reliar\ENTPARMDIRECT.rel ] -..\..\lib\libcl.lib [ relcl\strcpy.rel ] +..\..\lib\libiar.lib [ reliar\BANKCALLDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\strcpy.rel ] ..\..\lib\libiar.lib [ reliar\LAND.rel ] ..\..\lib\libiar.lib [ reliar\SLCMP.rel ] -..\..\lib\libsysl.lib [ relsysl\kill.rel ] +..\..\lib\libsysb.lib [ relsysb\kill.rel ] ..\..\lib\libiar.lib [ reliar\ENTAUTODIRECT.rel ] ..\..\lib\libiar.lib [ reliar\VSWITCHEND.rel ] -..\..\lib\libcl.lib [ relcl\atoi.rel ] -..\..\lib\libcl.lib [ relcl\vfprintf.rel ] -..\..\lib\libcl.lib [ relcl\ltoa.rel ] +..\..\lib\libcb.lib [ relcb\atoi.rel ] +..\..\lib\libcb.lib [ relcb\vfprintf.rel ] +..\..\lib\libcb.lib [ relcb\ltoa.rel ] ..\..\lib\libiar.lib [ reliar\SSCMP.rel ] -..\..\lib\libcl.lib [ relcl\itoa.rel ] -..\..\lib\libcl.lib [ relcl\fputs.rel ] -..\..\lib\libsysl.lib [ relsysl\open.rel ] +..\..\lib\libcb.lib [ relcb\itoa.rel ] +..\..\lib\libcb.lib [ relcb\fputs.rel ] +..\..\lib\libsysb.lib [ relsysb\open.rel ] ..\..\lib\libiar.lib [ reliar\USMOD.rel ] ..\..\lib\libiar.lib [ reliar\CLSH.rel ] +..\..\lib\libiar.lib [ reliar\LIBVERSION.rel ] ..\..\lib\libiar.lib [ reliar\USDIV.rel ] -..\..\lib\libcl.lib [ relcl\malloc.rel ] +..\..\lib\libcb.lib [ relcb\malloc.rel ] ..\..\lib\libiar.lib [ reliar\SLRSH.rel ] -..\..\lib\libcl.lib [ relcl\fprintf.rel ] -..\..\lib\libcl.lib [ relcl\exit.rel ] -..\..\lib\libsysl.lib [ relsysl\read.rel ] -..\..\lib\libsysl.lib [ relsysl\getpid.rel ] -..\..\lib\libsysl.lib [ relsysl\signal.rel ] +..\..\lib\libcb.lib [ relcb\fprintf.rel ] +..\..\lib\libcb.lib [ relcb\exit.rel ] +..\..\lib\libsysb.lib [ relsysb\read.rel ] +..\..\lib\libsysb.lib [ relsysb\getpid.rel ] +..\..\lib\libsysb.lib [ relsysb\signal.rel ] +..\..\lib\libiar.lib [ reliar\BANKLEAVE32.rel ] ..\..\lib\libiar.lib [ reliar\LLSH.rel ] ..\..\lib\libiar.lib [ reliar\SDIVMOD.rel ] -..\..\lib\libcl.lib [ relcl\error.rel ] -..\..\lib\libiar.lib [ reliar\LEAVE32.rel ] -..\..\lib\libsysl.lib [ relsysl\sys0l.rel ] +..\..\lib\libcb.lib [ relcb\error.rel ] +..\..\lib\libsysb.lib [ relsysb\sys0b.rel ] ..\..\lib\libiar.lib [ reliar\SMULASG.rel ] -..\..\lib\libcl.lib [ relcl\fgetc.rel ] -..\..\lib\libcl.lib [ relcl\memcpy.rel ] +..\..\lib\libcb.lib [ relcb\fgetc.rel ] +..\..\lib\libcb.lib [ relcb\memcpy.rel ] ..\..\lib\libiar.lib [ reliar\SMUL.rel ] -..\..\lib\libcl.lib [ relcl\atexit.rel ] -..\..\lib\libcl.lib [ relcl\strcat.rel ] -..\..\lib\libsysl.lib [ relsysl\sys1l.rel ] -..\..\lib\libcl.lib [ relcl\strchr.rel ] -..\..\lib\libcl.lib [ relcl\strlen.rel ] -..\..\lib\libcl.lib [ relcl\free.rel ] -..\..\lib\libcl.lib [ relcl\fputc.rel ] -..\..\lib\libcl.lib [ relcl\ultoa.rel ] -..\..\lib\libcl.lib [ relcl\strtol.rel ] -..\..\lib\libiar.lib [ reliar\CALLIND.rel ] +..\..\lib\libcb.lib [ relcb\atexit.rel ] +..\..\lib\libcb.lib [ relcb\strcat.rel ] +..\..\lib\libsysb.lib [ relsysb\sys1b.rel ] +..\..\lib\libcb.lib [ relcb\strchr.rel ] +..\..\lib\libcb.lib [ relcb\strlen.rel ] +..\..\lib\libiar.lib [ reliar\LEAVEDIRECT.rel ] +..\..\lib\libcb.lib [ relcb\free.rel ] +..\..\lib\libcb.lib [ relcb\fputc.rel ] +..\..\lib\libcb.lib [ relcb\ultoa.rel ] +..\..\lib\libcb.lib [ relcb\strtol.rel ] ..\..\lib\libiar.lib [ reliar\ULDIVASG.rel ] ..\..\lib\libiar.lib [ reliar\ULMOD.rel ] ..\..\lib\libiar.lib [ reliar\ULDIV.rel ] -..\..\lib\libsysl.lib [ relsysl\sbrk.rel ] +..\..\lib\libsysb.lib [ relsysb\sbrk.rel ] ..\..\lib\libiar.lib [ reliar\LNEG.rel ] ..\..\lib\libiar.lib [ reliar\LDIVMOD.rel ] -..\..\lib\libcl.lib [ relcl\fread.rel ] +..\..\lib\libcb.lib [ relcb\fread.rel ] ..\..\lib\libiar.lib [ reliar\LNOT.rel ] ..\..\lib\libiar.lib [ reliar\LENDMULDIVASG.rel ] -..\..\lib\libcl.lib [ relcl\strtoul.rel ] -..\..\lib\libcl.lib [ relcl\ctype.rel ] +..\..\lib\libcb.lib [ relcb\strtoul.rel ] +..\..\lib\libcb.lib [ relcb\ctype.rel ] ..\..\lib\libiar.lib [ reliar\LMULASG.rel ] ..\..\lib\libiar.lib [ reliar\LMUL.rel ] ..\..\lib\libiar.lib [ reliar\LADDASG.rel ] @@ -238,3 +240,5 @@ Libraries Linked [ object file ] User Base Address Definitions l RCODE=0x8100 +l CODE=0x4000,0x10000 +c CODE=0x4000 diff --git a/src/fsutil/mkfs.rel b/src/fsutil/mkfs.rel index a997a24a..e12e8062 100644 --- a/src/fsutil/mkfs.rel +++ b/src/fsutil/mkfs.rel @@ -1,26 +1,27 @@ XL4 -H 6 areas 42 global symbols +H 6 areas 44 global symbols M mkfs S ?US_RSH_L02 Ref00000000 -S ?CL64180L_4_06_L00 Ref00000000 S fflush Ref00000000 S bfill Ref00000000 S _write Ref00000000 S printf Ref00000000 +S ?BANK_LEAVE_DIRECT_L08 Ref00000000 S stderr Ref00000000 S lseek Ref00000000 S close Ref00000000 S abort Ref00000000 S ?C_V_SWITCH_L06 Ref00000000 S fgets Ref00000000 -S ?LEAVE_DIRECT_L09 Ref00000000 S perror Ref00000000 S bcopy Ref00000000 S stdin Ref00000000 S bzero Ref00000000 S ?ENT_PARM_DIRECT_L09 Ref00000000 +S ?BANK_CALL_DIRECT_L08 Ref00000000 S stdout Ref00000000 S strcpy Ref00000000 +S errno Ref00000000 S ?SL_CMP_L03 Ref00000000 S ?L_AND_L03 Ref00000000 S ?ENT_AUTO_DIRECT_L09 Ref00000000 @@ -32,6 +33,7 @@ S fputs Ref00000000 S ?US_MOD_L02 Ref00000000 S ?C_LSH_L01 Ref00000000 S ?US_DIV_L02 Ref00000000 +S ?CL64180B_4_06_L00 Ref00000000 S ?SL_RSH_L03 Ref00000000 S malloc Ref00000000 S fprintf Ref00000000 @@ -40,16 +42,16 @@ S _read Ref00000000 S .__.ABS. Def00000000 S ?L_LSH_L03 Ref00000000 A _DEFAULT size 0 flags 0 -A CODE size C52 flags 0 -S da_read Def0000005A -S doformatting Def0000063F -S dwrite Def00000030 -S da_write Def000000CD -S yes Def00000140 -S bitmap_dump Def00000B70 +A CODE size E53 flags 0 +S da_read Def00000078 +S doformatting Def00000771 +S dwrite Def0000003F +S da_write Def0000013B +S yes Def000001E0 +S bitmap_dump Def00000D5D S daread Def00000000 -S main Def000006A1 -S mkfs Def00000196 +S main Def000007E7 +S mkfs Def0000024A A CSTR size 1FA flags 0 A UDATA0 size 81A flags 0 S immov_bitmap Def00000618 @@ -76,1101 +78,1307 @@ A CDATA0 size 985 flags 0 T 00 00 00 00 R 00 00 01 00 T 00 00 00 00 CD 00 00 00 00 21 1A 06 00 00 E5 -R 00 00 01 00 02 05 11 00 00 0A 03 00 -T 07 00 00 00 4B 42 ED 5B 02 04 00 00 CD +R 00 00 01 00 02 05 10 00 00 0A 03 00 +T 07 00 00 00 4B 42 ED 5B 02 04 00 00 3E R 00 00 01 00 00 08 03 00 -T 0E 00 00 00 5A 00 00 00 F1 3E 02 AC B5 28 13 -R 00 00 01 00 00 04 01 00 -T 17 00 00 00 -R 00 00 01 00 -T 17 00 00 00 DD 6E 02 DD 66 03 E5 21 -R 00 00 01 00 -T 1F 00 00 00 00 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 05 00 -T 26 00 00 00 F1 CD 00 00 00 00 -R 00 00 01 00 02 06 09 00 -T 2A 00 00 00 -R 00 00 01 00 -T 2A 00 00 00 21 1A 06 00 00 C3 00 00 00 00 -R 00 00 01 00 00 05 03 00 02 0A 0C 00 -T 30 00 00 00 -R 00 00 01 00 -T 30 00 00 00 CD 00 00 00 00 C5 4B 42 ED 5B -R 00 00 01 00 02 05 11 00 -T 38 00 00 00 02 04 00 00 CD CD 00 00 00 F1 3E -R 00 00 01 00 00 04 03 00 00 09 01 00 -T 3F 00 00 00 02 AC B5 28 13 -R 00 00 01 00 -T 44 00 00 00 -R 00 00 01 00 -T 44 00 00 00 DD 6E 02 DD 66 03 E5 21 -R 00 00 01 00 -T 4C 00 00 00 1A 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 05 00 -T 53 00 00 00 F1 CD 00 00 00 00 -R 00 00 01 00 02 06 09 00 -T 57 00 00 00 -R 00 00 01 00 -T 57 00 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0C 00 -T 5A 00 00 00 +T 0E 00 00 00 78 00 00 00 21 78 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 13 00 00 00 00 00 00 00 F1 3E 02 AC B5 28 1D +R 00 00 01 00 02 04 11 00 +T 1C 00 00 00 +R 00 00 01 00 +T 1C 00 00 00 DD 6E 02 DD 66 03 E5 21 +R 00 00 01 00 +T 24 00 00 00 00 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 04 00 +T 2A 00 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 04 00 02 09 11 00 +T 31 00 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 09 00 02 0A 09 00 +T 37 00 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T 39 00 00 00 +R 00 00 01 00 +T 39 00 00 00 21 1A 06 00 00 C3 00 00 00 00 +R 00 00 01 00 00 05 03 00 02 0A 05 00 +T 3F 00 00 00 +R 00 00 01 00 +T 3F 00 00 00 CD 00 00 00 00 C5 4B 42 ED 5B +R 00 00 01 00 02 05 10 00 +T 47 00 00 00 02 04 00 00 3E 3B 01 00 00 21 +R 00 00 01 00 00 04 03 00 29 09 01 00 +T 4C 00 00 00 3B 01 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 00 04 01 00 02 09 11 00 +T 53 00 00 00 02 AC B5 28 1D +R 00 00 01 00 +T 58 00 00 00 +R 00 00 01 00 +T 58 00 00 00 DD 6E 02 DD 66 03 E5 21 +R 00 00 01 00 +T 60 00 00 00 1A 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 04 00 +T 66 00 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 04 00 02 09 11 00 +T 6D 00 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 09 00 02 0A 09 00 +T 73 00 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T 75 00 00 00 +R 00 00 01 00 +T 75 00 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 05 00 +T 78 00 00 00 R 00 00 01 00 -T 5A 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 -R 00 00 01 00 02 05 11 00 -T 63 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 -R 00 00 01 00 02 0A 25 00 -T 6C 00 00 00 E5 ED 5B 00 00 00 00 CD +T 78 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 +R 00 00 01 00 02 05 10 00 +T 81 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 +R 00 00 01 00 02 0A 27 00 +T 8A 00 00 00 E5 ED 5B 00 00 00 00 3E R 00 00 01 00 00 07 03 00 -T 72 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 1A -R 00 00 01 00 02 04 07 00 -T 7B 00 00 00 -R 00 00 01 00 -T 7B 00 00 00 21 35 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 82 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T 89 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 0D 00 -T 90 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 22 00 -T 95 00 00 00 -R 00 00 01 00 -T 95 00 00 00 21 00 02 E5 DD 4E 08 DD 46 09 ED -R 00 00 01 00 -T A0 00 00 00 5B 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 00 05 03 00 02 0A 23 00 -T A7 00 00 00 3E 02 AC B5 28 1A -R 00 00 01 00 -T AD 00 00 00 -R 00 00 01 00 -T AD 00 00 00 21 42 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T B4 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T BB 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 0D 00 -T C2 00 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 22 00 -T C7 00 00 00 -R 00 00 01 00 -T C7 00 00 00 21 00 02 C3 00 00 00 00 -R 00 00 01 00 02 08 0C 00 -T CD 00 00 00 -R 00 00 01 00 -T CD 00 00 00 CD 00 00 00 00 21 00 00 E5 69 60 +T 90 00 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 95 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 2E +R 00 00 01 00 02 04 11 00 +T 9E 00 00 00 +R 00 00 01 00 +T 9E 00 00 00 21 35 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T A4 00 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T AB 00 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T B1 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T B7 00 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0C 00 +T BC 00 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0C 00 02 09 11 00 +T C2 00 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 24 00 +T C7 00 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T CC 00 00 00 +R 00 00 01 00 +T CC 00 00 00 21 00 02 E5 DD 4E 0A DD 46 0B ED +R 00 00 01 00 +T D7 00 00 00 5B 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 03 00 2B 0A 25 00 +T DD 00 00 00 00 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 02 04 25 00 02 09 11 00 +T E4 00 00 00 02 AC B5 28 4C +R 00 00 01 00 +T E9 00 00 00 +R 00 00 01 00 +T E9 00 00 00 2A 00 00 00 00 7D B4 20 17 +R 00 00 01 00 02 05 14 00 +T F0 00 00 00 +R 00 00 01 00 +T F0 00 00 00 21 00 02 E5 0E AA DD 5E 0A DD 56 +R 00 00 01 00 +T FB 00 00 00 0B 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 02 00 02 0B 02 00 +T 01 01 00 00 CD 00 00 00 00 E1 18 2E R 00 00 01 00 02 05 11 00 -T D6 00 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 -R 00 00 01 00 02 0A 25 00 -T DF 00 00 00 E5 ED 5B 00 00 00 00 CD +T 07 01 00 00 +R 00 00 01 00 +T 07 01 00 00 21 42 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 0D 01 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 14 01 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 1A 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 20 01 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0C 00 +T 25 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0C 00 02 09 11 00 +T 2B 01 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 24 00 +T 30 01 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T 35 01 00 00 +R 00 00 01 00 +T 35 01 00 00 +R 00 00 01 00 +T 35 01 00 00 21 00 02 C3 00 00 00 00 +R 00 00 01 00 02 08 05 00 +T 3B 01 00 00 +R 00 00 01 00 +T 3B 01 00 00 CD 00 00 00 00 21 00 00 E5 69 60 +R 00 00 01 00 02 05 10 00 +T 44 01 00 00 01 00 00 3E 09 CD 00 00 00 00 C5 +R 00 00 01 00 02 0A 27 00 +T 4D 01 00 00 E5 ED 5B 00 00 00 00 3E R 00 00 01 00 00 07 03 00 -T E5 00 00 00 00 00 00 00 F1 F1 F1 CB 78 28 1A -R 00 00 01 00 02 04 07 00 -T EE 00 00 00 -R 00 00 01 00 -T EE 00 00 00 21 35 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T F5 00 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T FC 00 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 0D 00 -T 03 01 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 22 00 -T 08 01 00 00 -R 00 00 01 00 -T 08 01 00 00 21 00 02 E5 DD 4E 08 DD 46 09 ED -R 00 00 01 00 -T 13 01 00 00 5B 00 00 00 00 CD 00 00 00 00 F1 -R 00 00 01 00 00 05 03 00 02 0A 04 00 -T 1A 01 00 00 3E 02 AC B5 28 1A -R 00 00 01 00 -T 20 01 00 00 -R 00 00 01 00 -T 20 01 00 00 21 4F 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 27 01 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T 2E 01 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 0D 00 -T 35 01 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 22 00 -T 3A 01 00 00 -R 00 00 01 00 -T 3A 01 00 00 21 00 02 C3 00 00 00 00 -R 00 00 01 00 02 08 0C 00 -T 40 01 00 00 -R 00 00 01 00 -T 40 01 00 00 CD 00 00 00 00 EC FF 01 -R 00 00 01 00 02 05 16 00 -T 46 01 00 00 00 00 00 00 DD 5E 02 DD 56 03 CD +T 53 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 07 00 02 09 07 00 +T 58 01 00 00 00 00 00 00 F1 F1 F1 CB 78 28 2E +R 00 00 01 00 02 04 11 00 +T 61 01 00 00 +R 00 00 01 00 +T 61 01 00 00 21 35 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 67 01 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 6E 01 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 74 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 7A 01 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0C 00 +T 7F 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0C 00 02 09 11 00 +T 85 01 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 24 00 +T 8A 01 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T 8F 01 00 00 +R 00 00 01 00 +T 8F 01 00 00 21 00 02 E5 DD 4E 0A DD 46 0B ED +R 00 00 01 00 +T 9A 01 00 00 5B 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 05 03 00 2B 0A 03 00 +T A0 01 00 00 00 00 00 00 CD 00 00 00 00 F1 3E +R 00 00 01 00 02 04 03 00 02 09 11 00 +T A7 01 00 00 02 AC B5 28 2E +R 00 00 01 00 +T AC 01 00 00 +R 00 00 01 00 +T AC 01 00 00 21 4F 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T B2 01 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T B9 01 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T BF 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T C5 01 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0C 00 +T CA 01 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0C 00 02 09 11 00 +T D0 01 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 24 00 +T D5 01 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T DA 01 00 00 +R 00 00 01 00 +T DA 01 00 00 21 00 02 C3 00 00 00 00 +R 00 00 01 00 02 08 05 00 +T E0 01 00 00 +R 00 00 01 00 +T E0 01 00 00 CD 00 00 00 00 EC FF 01 +R 00 00 01 00 02 05 17 00 +T E6 01 00 00 00 00 00 00 DD 5E 02 DD 56 03 3E R 00 00 01 00 02 04 12 00 -T 4F 01 00 00 00 00 00 00 11 00 00 00 00 CD -R 00 00 01 00 02 04 1B 00 02 09 12 00 -T 55 01 00 00 00 00 00 00 3A 81 09 00 00 B7 28 -R 00 00 01 00 02 04 02 00 00 09 04 00 -T 5C 01 00 00 0B -R 00 00 01 00 -T 5D 01 00 00 -R 00 00 01 00 -T 5D 01 00 00 01 00 00 00 00 11 5D 00 00 00 CD +T EF 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 1C 00 02 09 1C 00 +T F4 01 00 00 00 00 00 00 11 00 00 00 00 3E +R 00 00 01 00 02 04 11 00 02 09 12 00 +T FA 01 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 01 00 02 09 01 00 +T FF 01 00 00 00 00 00 00 3A 81 09 00 00 B7 28 +R 00 00 01 00 02 04 11 00 00 09 04 00 +T 06 02 00 00 10 +R 00 00 01 00 +T 07 02 00 00 +R 00 00 01 00 +T 07 02 00 00 01 00 00 00 00 11 5D 00 00 00 3E R 00 00 01 00 02 05 12 00 00 0A 02 00 -T 64 01 00 00 00 00 00 00 18 28 -R 00 00 01 00 02 04 1B 00 -T 68 01 00 00 +T 0E 02 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 1C 00 02 09 1C 00 +T 13 02 00 00 00 00 00 00 18 2D +R 00 00 01 00 02 04 11 00 +T 17 02 00 00 R 00 00 01 00 -T 68 01 00 00 21 00 00 00 00 E5 01 14 00 21 -R 00 00 01 00 02 05 0F 00 -T 70 01 00 00 02 00 39 5D 54 CD 00 00 00 00 F1 -R 00 00 01 00 02 0A 0B 00 -T 79 01 00 00 7D B4 28 0E DD 7E EC FE 79 28 0C +T 17 02 00 00 21 00 00 00 00 E5 01 14 00 21 +R 00 00 01 00 02 05 0E 00 +T 1F 02 00 00 02 00 39 5D 54 3E 00 00 00 00 21 +R 00 00 01 00 2B 0A 0B 00 +T 27 02 00 00 00 00 00 00 CD 00 00 00 00 F1 7D +R 00 00 01 00 02 04 0B 00 02 09 11 00 +T 2E 02 00 00 B4 28 0E DD 7E EC FE 79 28 0C DD R 00 00 01 00 -T 84 01 00 00 DD 7E EC FE 59 28 05 +T 39 02 00 00 7E EC FE 59 28 05 R 00 00 01 00 -T 8B 01 00 00 +T 3F 02 00 00 R 00 00 01 00 -T 8B 01 00 00 +T 3F 02 00 00 R 00 00 01 00 -T 8B 01 00 00 +T 3F 02 00 00 R 00 00 01 00 -T 8B 01 00 00 +T 3F 02 00 00 R 00 00 01 00 -T 8B 01 00 00 +T 3F 02 00 00 R 00 00 01 00 -T 8B 01 00 00 21 00 00 18 03 +T 3F 02 00 00 21 00 00 18 03 R 00 00 01 00 -T 90 01 00 00 +T 44 02 00 00 R 00 00 01 00 -T 90 01 00 00 +T 44 02 00 00 R 00 00 01 00 -T 90 01 00 00 21 01 00 +T 44 02 00 00 21 01 00 R 00 00 01 00 -T 93 01 00 00 +T 47 02 00 00 R 00 00 01 00 -T 93 01 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0C 00 -T 96 01 00 00 +T 47 02 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 05 00 +T 4A 02 00 00 R 00 00 01 00 -T 96 01 00 00 CD 00 00 00 00 DC FF 3A -R 00 00 01 00 02 05 16 00 -T 9C 01 00 00 83 09 00 00 B7 28 0E +T 4A 02 00 00 CD 00 00 00 00 DC FF 3A +R 00 00 01 00 02 05 17 00 +T 50 02 00 00 83 09 00 00 B7 28 18 R 00 00 01 00 00 04 04 00 -T A1 01 00 00 -R 00 00 01 00 -T A1 01 00 00 21 60 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T A8 01 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T AF 01 00 00 +T 55 02 00 00 R 00 00 01 00 -T AF 01 00 00 AF DD 77 DC DD 77 DD +T 55 02 00 00 21 60 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 5B 02 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 62 02 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 68 02 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 6D 02 00 00 R 00 00 01 00 -T B6 01 00 00 +T 6D 02 00 00 AF DD 77 DC DD 77 DD R 00 00 01 00 -T B6 01 00 00 01 80 07 DD 6E DC DD 66 DD A7 ED +T 74 02 00 00 R 00 00 01 00 -T C1 01 00 00 42 30 7C +T 74 02 00 00 01 80 07 DD 6E DC DD 66 DD A7 ED R 00 00 01 00 -T C4 01 00 00 +T 7F 02 00 00 42 D2 13 03 00 00 +R 00 00 01 00 00 06 01 00 +T 83 02 00 00 R 00 00 01 00 -T C4 01 00 00 01 00 02 DD 5E DC DD 56 DD 21 +T 83 02 00 00 01 00 02 DD 5E DC DD 56 DD 21 R 00 00 01 00 -T CE 01 00 00 80 07 A7 ED 52 EB CD 00 00 00 00 -R 00 00 01 00 02 0B 18 00 -T D7 01 00 00 DD 75 DE DD 74 DF 01 00 02 A7 ED +T 8D 02 00 00 80 07 A7 ED 52 EB 3E 00 00 00 00 +R 00 00 01 00 2B 0B 19 00 +T 95 02 00 00 21 00 00 00 00 CD 00 00 00 00 DD +R 00 00 01 00 02 05 19 00 02 0A 11 00 +T 9C 02 00 00 75 DE DD 74 DF 01 00 02 A7 ED 42 R 00 00 01 00 -T E2 01 00 00 42 30 16 +T A7 02 00 00 30 1B R 00 00 01 00 -T E5 01 00 00 +T A9 02 00 00 R 00 00 01 00 -T E5 01 00 00 06 09 DD 5E DC DD 56 DD CD +T A9 02 00 00 06 09 DD 5E DC DD 56 DD CD R 00 00 01 00 -T EE 01 00 00 00 00 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 02 04 00 00 00 09 01 00 -T F5 01 00 00 FE DD 74 FF 18 08 +T B2 02 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 00 00 29 09 01 00 +T B7 02 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T BE 02 00 00 FE DD 74 FF 18 08 R 00 00 01 00 -T FB 01 00 00 +T C4 02 00 00 R 00 00 01 00 -T FB 01 00 00 DD 36 FE 02 02 00 00 DD 36 FF +T C4 02 00 00 DD 36 FE 02 02 00 00 DD 36 FF R 00 00 01 00 09 07 03 00 -T 02 02 00 00 02 02 00 00 +T CB 02 00 00 02 02 00 00 R 00 00 01 00 89 04 03 00 -T 03 02 00 00 +T CC 02 00 00 R 00 00 01 00 -T 03 02 00 00 DD 6E DE DD 66 DF E5 DD 4E FE DD +T CC 02 00 00 DD 6E DE DD 66 DF E5 DD 4E FE DD R 00 00 01 00 -T 0E 02 00 00 46 FF 21 00 00 00 00 DD 5E DC DD +T D7 02 00 00 46 FF 21 00 00 00 00 DD 5E DC DD R 00 00 01 00 00 07 04 00 -T 17 02 00 00 56 DD 19 EB CD 00 00 00 00 E1 DD -R 00 00 01 00 02 09 0E 00 -T 20 02 00 00 4E FE DD 46 FF C5 06 09 DD 5E DC +T E0 02 00 00 56 DD 19 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 0D 00 +T E7 02 00 00 00 00 00 00 CD 00 00 00 00 E1 DD +R 00 00 01 00 02 04 0D 00 02 09 11 00 +T EE 02 00 00 4E FE DD 46 FF C5 06 09 DD 5E DC R 00 00 01 00 -T 2B 02 00 00 DD 56 DD CD 00 00 00 00 C1 CD +T F9 02 00 00 DD 56 DD CD 00 00 00 00 3E R 00 00 01 00 02 08 00 00 -T 33 02 00 00 30 00 00 00 3E 02 DD 86 DD DD 77 -R 00 00 01 00 00 04 01 00 -T 3C 02 00 00 DD C3 B6 01 00 00 +T 00 03 00 00 3F 00 00 00 21 3F 00 00 00 C1 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 06 03 00 00 00 00 00 00 3E 02 DD 86 DD DD 77 +R 00 00 01 00 02 04 11 00 +T 0F 03 00 00 DD C3 74 02 00 00 R 00 00 01 00 00 06 01 00 -T 40 02 00 00 +T 13 03 00 00 R 00 00 01 00 -T 40 02 00 00 01 00 02 11 02 02 00 00 CD +T 13 03 00 00 01 00 02 11 02 02 00 00 3E R 00 00 01 00 00 08 03 00 -T 47 02 00 00 00 00 00 00 3A 83 09 00 00 B7 28 -R 00 00 01 00 02 04 10 00 00 09 04 00 -T 4E 02 00 00 0E -R 00 00 01 00 -T 4F 02 00 00 -R 00 00 01 00 -T 4F 02 00 00 21 78 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 56 02 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T 5D 02 00 00 -R 00 00 01 00 -T 5D 02 00 00 3A 82 09 00 00 B7 28 19 +T 1A 03 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0F 00 02 09 0F 00 +T 1F 03 00 00 00 00 00 00 3A 83 09 00 00 B7 28 +R 00 00 01 00 02 04 11 00 00 09 04 00 +T 26 03 00 00 18 +R 00 00 01 00 +T 27 03 00 00 +R 00 00 01 00 +T 27 03 00 00 21 78 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 2D 03 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 34 03 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 3A 03 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 3F 03 00 00 +R 00 00 01 00 +T 3F 03 00 00 3A 82 09 00 00 B7 28 19 R 00 00 01 00 00 05 04 00 -T 63 02 00 00 +T 45 03 00 00 R 00 00 01 00 -T 63 02 00 00 DD 6E 04 DD 66 05 DD 4E 08 DD 46 +T 45 03 00 00 DD 6E 04 DD 66 05 DD 4E 0A DD 46 R 00 00 01 00 -T 6E 02 00 00 09 09 01 05 00 09 DD 75 DE DD 74 +T 50 03 00 00 0B 09 01 05 00 09 DD 75 DE DD 74 R 00 00 01 00 -T 79 02 00 00 DF 18 0C +T 5B 03 00 00 DF 18 0C R 00 00 01 00 -T 7C 02 00 00 +T 5E 03 00 00 R 00 00 01 00 -T 7C 02 00 00 DD 6E 02 DD 66 03 DD 75 DE DD 74 +T 5E 03 00 00 DD 6E 02 DD 66 03 DD 75 DE DD 74 R 00 00 01 00 -T 87 02 00 00 DF +T 69 03 00 00 DF R 00 00 01 00 -T 88 02 00 00 +T 6A 03 00 00 R 00 00 01 00 -T 88 02 00 00 21 05 00 DD 4E 08 DD 46 09 09 DD +T 6A 03 00 00 21 05 00 DD 4E 0A DD 46 0B 09 DD R 00 00 01 00 -T 93 02 00 00 75 DC DD 74 DD +T 75 03 00 00 75 DC DD 74 DD R 00 00 01 00 -T 98 02 00 00 +T 7A 03 00 00 R 00 00 01 00 -T 98 02 00 00 DD 4E DE DD 46 DF DD 6E DC DD 66 +T 7A 03 00 00 DD 4E DE DD 46 DF DD 6E DC DD 66 R 00 00 01 00 -T A3 02 00 00 DD A7 ED 42 30 42 +T 85 03 00 00 DD A7 ED 42 30 51 R 00 00 01 00 -T A9 02 00 00 +T 8B 03 00 00 R 00 00 01 00 -T A9 02 00 00 3A 83 09 00 00 B7 28 26 01 09 00 +T 8B 03 00 00 3A 83 09 00 00 B7 28 30 01 09 00 R 00 00 01 00 00 05 04 00 -T B2 02 00 00 DD 5E DC DD 56 DD CD 00 00 00 00 -R 00 00 01 00 02 0B 1C 00 -T BB 02 00 00 7B B2 20 16 +T 94 03 00 00 DD 5E DC DD 56 DD CD 00 00 00 00 +R 00 00 01 00 02 0B 1D 00 +T 9D 03 00 00 7B B2 20 20 R 00 00 01 00 -T BF 02 00 00 +T A1 03 00 00 R 00 00 01 00 -T BF 02 00 00 +T A1 03 00 00 R 00 00 01 00 -T BF 02 00 00 +T A1 03 00 00 R 00 00 01 00 -T BF 02 00 00 DD 6E DC DD 66 DD E5 21 +T A1 03 00 00 DD 6E DC DD 66 DD E5 21 R 00 00 01 00 -T C7 02 00 00 9C 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 02 00 02 0A 05 00 -T CE 02 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T D5 02 00 00 +T A9 03 00 00 9C 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 02 00 2B 0A 04 00 +T AF 03 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 04 00 02 09 11 00 +T B6 03 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T BC 03 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T C1 03 00 00 R 00 00 01 00 -T D5 02 00 00 01 02 02 00 00 DD 5E DC DD 56 DD +T C1 03 00 00 01 02 02 00 00 DD 5E DC DD 56 DD R 00 00 01 00 00 05 03 00 -T DE 02 00 00 13 DD 73 DC DD 72 DD 1B CD +T CA 03 00 00 13 DD 73 DC DD 72 DD 1B 3E R 00 00 01 00 -T E7 02 00 00 30 00 00 00 18 AD -R 00 00 01 00 00 04 01 00 -T EB 02 00 00 +T D3 03 00 00 3F 00 00 00 21 3F 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T D8 03 00 00 00 00 00 00 18 9E +R 00 00 01 00 02 04 11 00 +T DC 03 00 00 R 00 00 01 00 -T EB 02 00 00 3A 83 09 00 00 B7 28 1D +T DC 03 00 00 3A 83 09 00 00 B7 28 27 R 00 00 01 00 00 05 04 00 -T F1 02 00 00 +T E2 03 00 00 R 00 00 01 00 -T F1 02 00 00 DD 6E DC DD 66 DD 2B DD 75 DC DD +T E2 03 00 00 DD 6E DC DD 66 DD 2B DD 75 DC DD R 00 00 01 00 -T FC 02 00 00 74 DD E5 21 A5 00 00 00 E5 CD +T ED 03 00 00 74 DD E5 21 A5 00 00 00 E5 3E R 00 00 01 00 00 08 02 00 -T 04 03 00 00 00 00 00 00 F1 F1 11 00 00 00 00 -R 00 00 01 00 02 04 05 00 02 0B 12 00 -T 0B 03 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 02 00 -T 0E 03 00 00 -R 00 00 01 00 -T 0E 03 00 00 3A 83 09 00 00 B7 28 0E +T F5 03 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 04 00 02 09 04 00 +T FA 03 00 00 00 00 00 00 F1 F1 11 00 00 00 00 +R 00 00 01 00 02 04 11 00 02 0B 12 00 +T 01 04 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 01 00 02 0A 01 00 +T 07 04 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T 09 04 00 00 +R 00 00 01 00 +T 09 04 00 00 3A 83 09 00 00 B7 28 18 R 00 00 01 00 00 05 04 00 -T 14 03 00 00 +T 0F 04 00 00 R 00 00 01 00 -T 14 03 00 00 21 AE 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 1B 03 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T 22 03 00 00 +T 0F 04 00 00 21 AE 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 15 04 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 1C 04 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 22 04 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 27 04 00 00 R 00 00 01 00 -T 22 03 00 00 01 1E 00 21 04 00 39 5D 54 CD +T 27 04 00 00 01 1E 00 21 04 00 39 5D 54 3E R 00 00 01 00 -T 2C 03 00 00 00 00 00 00 DD 36 E0 C6 DD 36 E1 -R 00 00 01 00 02 04 10 00 -T 35 03 00 00 31 21 05 00 DD 4E 08 DD 46 09 09 +T 31 04 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 0F 00 02 09 0F 00 +T 36 04 00 00 00 00 00 00 DD 36 E0 C6 DD 36 E1 +R 00 00 01 00 02 04 11 00 +T 3F 04 00 00 31 21 05 00 DD 4E 0A DD 46 0B 09 R 00 00 01 00 -T 40 03 00 00 DD 75 E2 DD 74 E3 DD 6E 04 DD 66 +T 4A 04 00 00 DD 75 E2 DD 74 E3 DD 6E 04 DD 66 R 00 00 01 00 -T 4B 03 00 00 05 DD 75 E4 DD 74 E5 DD 6E 02 DD +T 55 04 00 00 05 DD 75 E4 DD 74 E5 DD 6E 02 DD R 00 00 01 00 -T 56 03 00 00 66 03 DD 75 E6 DD 74 E7 DD 6E 04 +T 60 04 00 00 66 03 DD 75 E6 DD 74 E7 DD 6E 04 R 00 00 01 00 -T 61 03 00 00 DD 66 05 29 29 29 11 FE FF 19 DD +T 6B 04 00 00 DD 66 05 29 29 29 11 FE FF 19 DD R 00 00 01 00 -T 6C 03 00 00 75 EA DD 74 EB DD 6E 04 DD 66 05 +T 76 04 00 00 75 EA DD 74 EB DD 6E 04 DD 66 05 R 00 00 01 00 -T 77 03 00 00 09 01 06 00 09 4D 44 DD 6E 02 DD +T 81 04 00 00 09 01 06 00 09 4D 44 DD 6E 02 DD R 00 00 01 00 -T 82 03 00 00 66 03 A7 ED 42 DD 75 E8 DD 74 E9 +T 8C 04 00 00 66 03 A7 ED 42 DD 75 E8 DD 74 E9 R 00 00 01 00 -T 8D 03 00 00 2A 04 06 00 00 DD 75 F0 DD 74 F1 +T 97 04 00 00 2A 04 06 00 00 DD 75 F0 DD 74 F1 R 00 00 01 00 00 05 03 00 -T 96 03 00 00 2A 08 06 00 00 DD 75 F2 DD 74 F3 +T A0 04 00 00 2A 08 06 00 00 DD 75 F2 DD 74 F3 R 00 00 01 00 00 05 03 00 -T 9F 03 00 00 2A 0C 06 00 00 DD 75 F4 DD 74 F5 +T A9 04 00 00 2A 0C 06 00 00 DD 75 F4 DD 74 F5 R 00 00 01 00 00 05 03 00 -T A8 03 00 00 2A 10 06 00 00 DD 75 F6 DD 74 F7 +T B2 04 00 00 2A 10 06 00 00 DD 75 F6 DD 74 F7 R 00 00 01 00 00 05 03 00 -T B1 03 00 00 AF DD 77 DC DD 77 DD +T BB 04 00 00 AF DD 77 DC DD 77 DD R 00 00 01 00 -T B8 03 00 00 +T C2 04 00 00 R 00 00 01 00 -T B8 03 00 00 DD 6E 04 DD 66 05 DD 4E 08 DD 46 +T C2 04 00 00 DD 6E 04 DD 66 05 DD 4E 0A DD 46 R 00 00 01 00 -T C3 03 00 00 09 09 01 06 00 09 4D 44 DD 6E DC +T CD 04 00 00 0B 09 01 06 00 09 4D 44 DD 6E DC R 00 00 01 00 -T CE 03 00 00 DD 66 DD A7 ED 42 30 26 +T D8 04 00 00 DD 66 DD A7 ED 42 30 26 R 00 00 01 00 -T D6 03 00 00 +T E0 04 00 00 R 00 00 01 00 -T D6 03 00 00 06 03 DD 5E DC DD 56 DD CD +T E0 04 00 00 06 03 DD 5E DC DD 56 DD CD R 00 00 01 00 -T DF 03 00 00 00 00 00 00 2A 16 06 00 00 19 DD +T E9 04 00 00 00 00 00 00 2A 16 06 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T E6 03 00 00 7E DC E6 07 47 3E 01 CD +T F0 04 00 00 7E DC E6 07 47 3E 01 CD R 00 00 01 00 -T EE 03 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 -R 00 00 01 00 02 04 1D 00 -T F7 03 00 00 DD 34 DD +T F8 04 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 +R 00 00 01 00 02 04 1E 00 +T 01 05 00 00 DD 34 DD R 00 00 01 00 -T FA 03 00 00 +T 04 05 00 00 R 00 00 01 00 -T FA 03 00 00 18 BC +T 04 05 00 00 18 BC R 00 00 01 00 -T FC 03 00 00 +T 06 05 00 00 R 00 00 01 00 -T FC 03 00 00 ED 4B 08 06 00 00 2A 0C 06 00 00 +T 06 05 00 00 ED 4B 08 06 00 00 2A 0C 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 03 04 00 00 A7 ED 42 29 29 29 DD 75 DE DD 74 +T 0D 05 00 00 A7 ED 42 29 29 29 DD 75 DE DD 74 R 00 00 01 00 -T 0E 04 00 00 DF DD 6E 02 DD 66 03 DD 75 DC DD +T 18 05 00 00 DF DD 6E 02 DD 66 03 DD 75 DC DD R 00 00 01 00 -T 19 04 00 00 74 DD +T 23 05 00 00 74 DD R 00 00 01 00 -T 1B 04 00 00 +T 25 05 00 00 R 00 00 01 00 -T 1B 04 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 +T 25 05 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 R 00 00 01 00 -T 26 04 00 00 DD A7 ED 42 28 26 +T 30 05 00 00 DD A7 ED 42 28 26 R 00 00 01 00 -T 2C 04 00 00 +T 36 05 00 00 R 00 00 01 00 -T 2C 04 00 00 06 03 DD 5E DC DD 56 DD CD +T 36 05 00 00 06 03 DD 5E DC DD 56 DD CD R 00 00 01 00 -T 35 04 00 00 00 00 00 00 2A 16 06 00 00 19 DD +T 3F 05 00 00 00 00 00 00 2A 16 06 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T 3C 04 00 00 7E DC E6 07 47 3E 01 CD +T 46 05 00 00 7E DC E6 07 47 3E 01 CD R 00 00 01 00 -T 44 04 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 -R 00 00 01 00 02 04 1D 00 -T 4D 04 00 00 DD 34 DD +T 4E 05 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 +R 00 00 01 00 02 04 1E 00 +T 57 05 00 00 DD 34 DD R 00 00 01 00 -T 50 04 00 00 +T 5A 05 00 00 R 00 00 01 00 -T 50 04 00 00 18 C9 +T 5A 05 00 00 18 C9 R 00 00 01 00 -T 52 04 00 00 +T 5C 05 00 00 R 00 00 01 00 -T 52 04 00 00 2A 0E 06 00 00 E5 2A 0C 06 00 00 +T 5C 05 00 00 2A 0E 06 00 00 E5 2A 0C 06 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T 59 04 00 00 E5 2A 0A 06 00 00 E5 2A +T 63 05 00 00 E5 2A 0A 06 00 00 E5 2A R 00 00 01 00 00 06 03 00 -T 5F 04 00 00 08 06 00 00 E5 ED 5B 16 06 00 00 +T 69 05 00 00 08 06 00 00 E5 ED 5B 16 06 00 00 R 00 00 01 00 00 04 03 00 00 0B 03 00 -T 66 04 00 00 CD 70 0B 00 00 E1 E1 E1 E1 3A -R 00 00 01 00 00 05 01 00 -T 6E 04 00 00 84 09 00 00 B7 CA 30 05 00 00 +T 70 05 00 00 3E 5D 0D 00 00 21 5D 0D 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 76 05 00 00 00 00 00 00 E1 E1 E1 E1 3A +R 00 00 01 00 02 04 11 00 +T 7D 05 00 00 84 09 00 00 B7 CA 44 06 00 00 R 00 00 01 00 00 04 04 00 00 0A 01 00 -T 74 04 00 00 +T 83 05 00 00 R 00 00 01 00 -T 74 04 00 00 AF DD 77 DC DD 77 DD +T 83 05 00 00 AF DD 77 DC DD 77 DD R 00 00 01 00 -T 7B 04 00 00 +T 8A 05 00 00 R 00 00 01 00 -T 7B 04 00 00 DD 6E 04 DD 66 05 DD 4E 08 DD 46 +T 8A 05 00 00 DD 6E 04 DD 66 05 DD 4E 0A DD 46 R 00 00 01 00 -T 86 04 00 00 09 09 01 06 00 09 4D 44 DD 6E DC +T 95 05 00 00 0B 09 01 06 00 09 4D 44 DD 6E DC R 00 00 01 00 -T 91 04 00 00 DD 66 DD A7 ED 42 30 26 +T A0 05 00 00 DD 66 DD A7 ED 42 30 26 R 00 00 01 00 -T 99 04 00 00 +T A8 05 00 00 R 00 00 01 00 -T 99 04 00 00 06 03 DD 5E DC DD 56 DD CD +T A8 05 00 00 06 03 DD 5E DC DD 56 DD CD R 00 00 01 00 -T A2 04 00 00 00 00 00 00 2A 18 06 00 00 19 DD +T B1 05 00 00 00 00 00 00 2A 18 06 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T A9 04 00 00 7E DC E6 07 47 3E 01 CD +T B8 05 00 00 7E DC E6 07 47 3E 01 CD R 00 00 01 00 -T B1 04 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 -R 00 00 01 00 02 04 1D 00 -T BA 04 00 00 DD 34 DD +T C0 05 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 +R 00 00 01 00 02 04 1E 00 +T C9 05 00 00 DD 34 DD R 00 00 01 00 -T BD 04 00 00 +T CC 05 00 00 R 00 00 01 00 -T BD 04 00 00 18 BC +T CC 05 00 00 18 BC R 00 00 01 00 -T BF 04 00 00 +T CE 05 00 00 R 00 00 01 00 -T BF 04 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 +T CE 05 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T C6 04 00 00 A7 ED 42 29 29 29 DD 75 DE DD 74 +T D5 05 00 00 A7 ED 42 29 29 29 DD 75 DE DD 74 R 00 00 01 00 -T D1 04 00 00 DF DD 6E 02 DD 66 03 DD 75 DC DD +T E0 05 00 00 DF DD 6E 02 DD 66 03 DD 75 DC DD R 00 00 01 00 -T DC 04 00 00 74 DD +T EB 05 00 00 74 DD R 00 00 01 00 -T DE 04 00 00 +T ED 05 00 00 R 00 00 01 00 -T DE 04 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 +T ED 05 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 R 00 00 01 00 -T E9 04 00 00 DD A7 ED 42 28 26 +T F8 05 00 00 DD A7 ED 42 28 26 R 00 00 01 00 -T EF 04 00 00 +T FE 05 00 00 R 00 00 01 00 -T EF 04 00 00 06 03 DD 5E DC DD 56 DD CD +T FE 05 00 00 06 03 DD 5E DC DD 56 DD CD R 00 00 01 00 -T F8 04 00 00 00 00 00 00 2A 18 06 00 00 19 DD +T 07 06 00 00 00 00 00 00 2A 18 06 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T FF 04 00 00 7E DC E6 07 47 3E 01 CD +T 0E 06 00 00 7E DC E6 07 47 3E 01 CD R 00 00 01 00 -T 07 05 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 -R 00 00 01 00 02 04 1D 00 -T 10 05 00 00 DD 34 DD +T 16 06 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 +R 00 00 01 00 02 04 1E 00 +T 1F 06 00 00 DD 34 DD R 00 00 01 00 -T 13 05 00 00 +T 22 06 00 00 R 00 00 01 00 -T 13 05 00 00 18 C9 +T 22 06 00 00 18 C9 R 00 00 01 00 -T 15 05 00 00 +T 24 06 00 00 R 00 00 01 00 -T 15 05 00 00 2A 12 06 00 00 E5 2A 10 06 00 00 +T 24 06 00 00 2A 12 06 00 00 E5 2A 10 06 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T 1C 05 00 00 E5 2A 0E 06 00 00 E5 2A +T 2B 06 00 00 E5 2A 0E 06 00 00 E5 2A R 00 00 01 00 00 06 03 00 -T 22 05 00 00 0C 06 00 00 E5 ED 5B 18 06 00 00 +T 31 06 00 00 0C 06 00 00 E5 ED 5B 18 06 00 00 R 00 00 01 00 00 04 03 00 00 0B 03 00 -T 29 05 00 00 CD 70 0B 00 00 E1 E1 E1 E1 -R 00 00 01 00 00 05 01 00 -T 30 05 00 00 +T 38 06 00 00 3E 5D 0D 00 00 21 5D 0D 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 3E 06 00 00 00 00 00 00 E1 E1 E1 E1 +R 00 00 01 00 02 04 11 00 +T 44 06 00 00 R 00 00 01 00 -T 30 05 00 00 21 ED 41 22 44 04 00 00 21 03 00 +T 44 06 00 00 21 ED 41 22 44 04 00 00 21 03 00 R 00 00 01 00 00 08 03 00 -T 39 05 00 00 22 46 04 00 00 01 00 00 21 20 00 +T 4D 06 00 00 22 46 04 00 00 01 00 00 21 20 00 R 00 00 01 00 00 05 03 00 -T 42 05 00 00 22 4C 04 00 00 ED 43 4E 04 00 00 +T 56 06 00 00 22 4C 04 00 00 ED 43 4E 04 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T 49 05 00 00 DD 6E 04 DD 66 05 DD 4E 08 DD 46 +T 5D 06 00 00 DD 6E 04 DD 66 05 DD 4E 0A DD 46 R 00 00 01 00 -T 54 05 00 00 09 09 01 05 00 09 22 5C 04 00 00 +T 68 06 00 00 0B 09 01 05 00 09 22 5C 04 00 00 R 00 00 01 00 00 0B 03 00 -T 5D 05 00 00 21 01 00 22 06 04 00 00 21 FF FF +T 71 06 00 00 21 01 00 22 06 04 00 00 21 FF FF R 00 00 01 00 00 08 03 00 -T 66 05 00 00 22 04 04 00 00 2A 14 06 00 00 7E +T 7A 06 00 00 22 04 04 00 00 2A 14 06 00 00 7E R 00 00 01 00 00 05 03 00 00 0A 03 00 -T 6D 05 00 00 F6 01 77 2A 14 06 00 00 7E F6 02 +T 81 06 00 00 F6 01 77 2A 14 06 00 00 7E F6 02 R 00 00 01 00 00 08 03 00 -T 76 05 00 00 77 ED 4B 04 06 00 00 2A +T 8A 06 00 00 77 ED 4B 04 06 00 00 2A R 00 00 01 00 00 07 03 00 -T 7C 05 00 00 08 06 00 00 A7 ED 42 29 29 29 DD +T 90 06 00 00 08 06 00 00 A7 ED 42 29 29 29 DD R 00 00 01 00 00 04 03 00 -T 85 05 00 00 75 DE DD 74 DF DD 6E 04 DD 66 05 +T 99 06 00 00 75 DE DD 74 DF DD 6E 04 DD 66 05 R 00 00 01 00 -T 90 05 00 00 29 29 29 DD 75 DC DD 74 DD +T A4 06 00 00 29 29 29 DD 75 DC DD 74 DD R 00 00 01 00 -T 99 05 00 00 +T AD 06 00 00 R 00 00 01 00 -T 99 05 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 +T AD 06 00 00 DD 6E DE DD 66 DF DD 4E DC DD 46 R 00 00 01 00 -T A4 05 00 00 DD A7 ED 42 28 26 +T B8 06 00 00 DD A7 ED 42 28 26 R 00 00 01 00 -T AA 05 00 00 +T BE 06 00 00 R 00 00 01 00 -T AA 05 00 00 06 03 DD 5E DC DD 56 DD CD +T BE 06 00 00 06 03 DD 5E DC DD 56 DD CD R 00 00 01 00 -T B3 05 00 00 00 00 00 00 2A 14 06 00 00 19 DD +T C7 06 00 00 00 00 00 00 2A 14 06 00 00 19 DD R 00 00 01 00 02 04 00 00 00 09 03 00 -T BA 05 00 00 7E DC E6 07 47 3E 01 CD +T CE 06 00 00 7E DC E6 07 47 3E 01 CD R 00 00 01 00 -T C2 05 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 -R 00 00 01 00 02 04 1D 00 -T CB 05 00 00 DD 34 DD +T D6 06 00 00 00 00 00 00 B6 77 DD 34 DC 20 03 +R 00 00 01 00 02 04 1E 00 +T DF 06 00 00 DD 34 DD R 00 00 01 00 -T CE 05 00 00 +T E2 06 00 00 R 00 00 01 00 -T CE 05 00 00 18 C9 +T E2 06 00 00 18 C9 R 00 00 01 00 -T D0 05 00 00 +T E4 06 00 00 R 00 00 01 00 -T D0 05 00 00 2A 0A 06 00 00 E5 2A 08 06 00 00 +T E4 06 00 00 2A 0A 06 00 00 E5 2A 08 06 00 00 R 00 00 01 00 00 05 03 00 00 0B 03 00 -T D7 05 00 00 E5 2A 06 06 00 00 E5 2A +T EB 06 00 00 E5 2A 06 06 00 00 E5 2A R 00 00 01 00 00 06 03 00 -T DD 05 00 00 04 06 00 00 E5 ED 5B 14 06 00 00 +T F1 06 00 00 04 06 00 00 E5 ED 5B 14 06 00 00 R 00 00 01 00 00 04 03 00 00 0B 03 00 -T E4 05 00 00 CD 70 0B 00 00 E1 E1 E1 E1 01 -R 00 00 01 00 00 05 01 00 -T EC 05 00 00 04 04 00 00 21 05 00 DD 5E 08 DD +T F8 06 00 00 3E 5D 0D 00 00 21 5D 0D 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T FE 06 00 00 00 00 00 00 E1 E1 E1 E1 01 +R 00 00 01 00 02 04 11 00 +T 05 07 00 00 04 04 00 00 21 05 00 DD 5E 0A DD R 00 00 01 00 00 04 03 00 -T F5 05 00 00 56 09 19 EB CD 30 00 00 00 01 -R 00 00 01 00 00 09 01 00 -T FD 05 00 00 80 07 00 00 DD 6E 04 DD 66 05 DD +T 0E 07 00 00 56 0B 19 EB 3E 3F 00 00 00 21 +R 00 00 01 00 29 09 01 00 +T 15 07 00 00 3F 00 00 00 CD 00 00 00 00 01 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T 1B 07 00 00 80 07 00 00 DD 6E 04 DD 66 05 DD R 00 00 01 00 00 04 04 00 -T 06 06 00 00 5E 08 DD 56 09 19 11 05 00 19 EB -R 00 00 01 00 -T 11 06 00 00 CD 30 00 00 00 11 04 00 CD -R 00 00 01 00 00 05 01 00 -T 18 06 00 00 00 00 00 00 DD 75 FE DD 74 FF 01 -R 00 00 01 00 00 04 01 00 -T 21 06 00 00 1E 00 C5 4D 44 21 06 00 39 5D 54 -R 00 00 01 00 -T 2C 06 00 00 CD 00 00 00 00 E1 DD 4E FE DD 46 -R 00 00 01 00 02 05 0E 00 -T 35 06 00 00 FF 11 04 00 CD 30 00 00 00 C3 -R 00 00 01 00 00 09 01 00 -T 3D 06 00 00 00 00 00 00 -R 00 00 01 00 02 04 0C 00 -T 3F 06 00 00 -R 00 00 01 00 -T 3F 06 00 00 CD 00 00 00 00 FE FD 3A -R 00 00 01 00 02 05 16 00 -T 45 06 00 00 83 09 00 00 B7 28 0E +T 24 07 00 00 5E 0A DD 56 0B 19 11 05 00 19 EB +R 00 00 01 00 +T 2F 07 00 00 3E 3F 00 00 00 21 3F 00 00 00 CD +R 00 00 01 00 29 05 01 00 00 0A 01 00 +T 35 07 00 00 00 00 00 00 11 04 00 3E +R 00 00 01 00 02 04 11 00 +T 3B 07 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 40 07 00 00 00 00 00 00 DD 75 FE DD 74 FF 01 +R 00 00 01 00 02 04 11 00 +T 49 07 00 00 1E 00 C5 4D 44 21 06 00 39 5D 54 +R 00 00 01 00 +T 54 07 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 0D 00 02 0A 0D 00 +T 5A 07 00 00 00 00 00 00 E1 DD 4E FE DD 46 FF +R 00 00 01 00 02 04 11 00 +T 63 07 00 00 11 04 00 3E 3F 00 00 00 21 +R 00 00 01 00 29 08 01 00 +T 69 07 00 00 3F 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T 6F 07 00 00 00 00 00 00 +R 00 00 01 00 02 04 05 00 +T 71 07 00 00 +R 00 00 01 00 +T 71 07 00 00 CD 00 00 00 00 FE FD 3A +R 00 00 01 00 02 05 17 00 +T 77 07 00 00 83 09 00 00 B7 28 18 R 00 00 01 00 00 04 04 00 -T 4A 06 00 00 -R 00 00 01 00 -T 4A 06 00 00 21 C7 00 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 51 06 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T 58 06 00 00 -R 00 00 01 00 -T 58 06 00 00 21 00 02 E5 0E AA 21 04 00 39 5D -R 00 00 01 00 -T 63 06 00 00 54 CD 00 00 00 00 E1 21 00 00 39 -R 00 00 01 00 02 06 03 00 -T 6C 06 00 00 AF 77 23 77 +T 7C 07 00 00 +R 00 00 01 00 +T 7C 07 00 00 21 C7 00 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 82 07 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 89 07 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 8F 07 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 94 07 00 00 +R 00 00 01 00 +T 94 07 00 00 21 00 02 E5 0E AA 21 04 00 39 5D +R 00 00 01 00 +T 9F 07 00 00 54 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 02 00 02 0B 02 00 +T A5 07 00 00 CD 00 00 00 00 E1 21 00 00 39 AF +R 00 00 01 00 02 05 11 00 +T AE 07 00 00 77 23 77 R 00 00 01 00 -T 70 06 00 00 +T B1 07 00 00 R 00 00 01 00 -T 70 06 00 00 DD 4E 02 DD 46 03 21 00 00 39 56 +T B1 07 00 00 DD 4E 02 DD 46 03 21 00 00 39 56 R 00 00 01 00 -T 7B 06 00 00 23 66 6A A7 ED 42 30 1B +T BC 07 00 00 23 66 6A A7 ED 42 30 20 R 00 00 01 00 -T 83 06 00 00 +T C4 07 00 00 R 00 00 01 00 -T 83 06 00 00 21 02 00 39 4D 44 21 00 00 39 5E +T C4 07 00 00 21 02 00 39 4D 44 21 00 00 39 5E R 00 00 01 00 -T 8E 06 00 00 23 56 CD 30 00 00 00 21 00 00 39 -R 00 00 01 00 00 07 01 00 -T 97 06 00 00 34 23 20 01 34 +T CF 07 00 00 23 56 3E 3F 00 00 00 21 +R 00 00 01 00 29 07 01 00 +T D4 07 00 00 3F 00 00 00 CD 00 00 00 00 21 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T DA 07 00 00 00 00 39 34 23 20 01 34 R 00 00 01 00 -T 9C 06 00 00 +T E2 07 00 00 R 00 00 01 00 -T 9C 06 00 00 18 D2 +T E2 07 00 00 18 CD R 00 00 01 00 -T 9E 06 00 00 +T E4 07 00 00 R 00 00 01 00 -T 9E 06 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0C 00 -T A1 06 00 00 +T E4 07 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 05 00 +T E7 07 00 00 R 00 00 01 00 -T A1 06 00 00 CD 00 00 00 00 F4 FF AF DD 77 F8 -R 00 00 01 00 02 05 16 00 -T AA 06 00 00 DD 77 F9 DD 36 FA 01 DD 36 FB 00 +T E7 07 00 00 CD 00 00 00 00 F4 FF AF DD 77 F8 +R 00 00 01 00 02 05 17 00 +T F0 07 00 00 DD 77 F9 DD 36 FA 01 DD 36 FB 00 R 00 00 01 00 -T B5 06 00 00 DD 6E 02 DD 66 03 DD 75 FC DD 74 +T FB 07 00 00 DD 6E 02 DD 66 03 DD 75 FC DD 74 R 00 00 01 00 -T C0 06 00 00 FD +T 06 08 00 00 FD R 00 00 01 00 -T C1 06 00 00 +T 07 08 00 00 R 00 00 01 00 -T C1 06 00 00 DD 4E 02 DD 46 03 DD 6E FA DD 66 +T 07 08 00 00 DD 4E 02 DD 46 03 DD 6E FA DD 66 R 00 00 01 00 -T CC 06 00 00 FB CD 00 00 00 00 D2 8F 07 00 00 -R 00 00 01 00 02 06 19 00 00 0B 01 00 -T D3 06 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD +T 12 08 00 00 FB CD 00 00 00 00 D2 E0 08 00 00 +R 00 00 01 00 02 06 1A 00 00 0B 01 00 +T 19 08 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD R 00 00 01 00 -T DE 06 00 00 46 05 09 46 23 66 68 DD 75 FE DD +T 24 08 00 00 46 05 09 46 23 66 68 DD 75 FE DD R 00 00 01 00 -T E9 06 00 00 74 FF 7E FE 2D C2 8F 07 00 00 +T 2F 08 00 00 74 FF 7E FE 2D C2 E0 08 00 00 R 00 00 01 00 00 0A 01 00 -T F1 06 00 00 +T 37 08 00 00 R 00 00 01 00 -T F1 06 00 00 +T 37 08 00 00 R 00 00 01 00 -T F1 06 00 00 +T 37 08 00 00 R 00 00 01 00 -T F1 06 00 00 DD 34 FE 20 03 DD 34 FF +T 37 08 00 00 DD 34 FE 20 03 DD 34 FF R 00 00 01 00 -T F9 06 00 00 +T 3F 08 00 00 R 00 00 01 00 -T F9 06 00 00 DD 34 FA 20 03 DD 34 FB +T 3F 08 00 00 DD 34 FA 20 03 DD 34 FB R 00 00 01 00 -T 01 07 00 00 +T 47 08 00 00 R 00 00 01 00 -T 01 07 00 00 DD 6E FC DD 66 FD 2B DD 75 FC DD +T 47 08 00 00 DD 6E FC DD 66 FD 2B DD 75 FC DD R 00 00 01 00 -T 0C 07 00 00 74 FD +T 52 08 00 00 74 FD R 00 00 01 00 -T 0E 07 00 00 +T 54 08 00 00 R 00 00 01 00 -T 0E 07 00 00 DD 6E FE DD 66 FF AF B6 28 74 +T 54 08 00 00 DD 6E FE DD 66 FF AF B6 28 7F R 00 00 01 00 -T 18 07 00 00 +T 5E 08 00 00 R 00 00 01 00 -T 18 07 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD +T 5E 08 00 00 DD 6E FE DD 66 FF 23 DD 75 FE DD R 00 00 01 00 -T 23 07 00 00 74 FF 2B 5E CD 00 00 00 00 0A 00 +T 69 08 00 00 74 FF 2B 5E CD 00 00 00 00 0A 00 R 00 00 01 00 02 09 0A 00 -T 2C 07 00 00 46 4C 51 56 59 66 6C 71 76 79 +T 72 08 00 00 46 4C 51 56 59 66 6C 71 76 79 R 00 00 01 00 -T 36 07 00 00 6F 07 00 00 4C 07 00 00 +T 7C 08 00 00 B5 08 00 00 92 08 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 -T 3A 07 00 00 61 07 00 00 5A 07 00 00 +T 80 08 00 00 A7 08 00 00 A0 08 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 -T 3E 07 00 00 68 07 00 00 53 07 00 00 +T 84 08 00 00 AE 08 00 00 99 08 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 -T 42 07 00 00 4C 07 00 00 61 07 00 00 +T 88 08 00 00 92 08 00 00 A7 08 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 -T 46 07 00 00 5A 07 00 00 68 07 00 00 +T 8C 08 00 00 A0 08 00 00 AE 08 00 00 R 00 00 01 00 00 04 01 00 00 08 01 00 -T 4A 07 00 00 53 07 00 00 +T 90 08 00 00 99 08 00 00 R 00 00 01 00 00 04 01 00 -T 4C 07 00 00 +T 92 08 00 00 R 00 00 01 00 -T 4C 07 00 00 3E 01 32 81 09 00 00 18 37 +T 92 08 00 00 3E 01 32 81 09 00 00 18 41 R 00 00 01 00 00 07 04 00 -T 53 07 00 00 +T 99 08 00 00 R 00 00 01 00 -T 53 07 00 00 3E 01 32 80 09 00 00 18 30 +T 99 08 00 00 3E 01 32 80 09 00 00 18 3A R 00 00 01 00 00 07 04 00 -T 5A 07 00 00 +T A0 08 00 00 R 00 00 01 00 -T 5A 07 00 00 3E 01 32 82 09 00 00 18 29 +T A0 08 00 00 3E 01 32 82 09 00 00 18 33 R 00 00 01 00 00 07 04 00 -T 61 07 00 00 +T A7 08 00 00 R 00 00 01 00 -T 61 07 00 00 3E 01 32 83 09 00 00 18 22 +T A7 08 00 00 3E 01 32 83 09 00 00 18 2C R 00 00 01 00 00 07 04 00 -T 68 07 00 00 +T AE 08 00 00 R 00 00 01 00 -T 68 07 00 00 3E 01 32 84 09 00 00 18 1B +T AE 08 00 00 3E 01 32 84 09 00 00 18 25 R 00 00 01 00 00 07 04 00 -T 6F 07 00 00 +T B5 08 00 00 R 00 00 01 00 -T 6F 07 00 00 DD 6E FE DD 66 FF E5 21 +T B5 08 00 00 DD 6E FE DD 66 FF E5 21 R 00 00 01 00 -T 77 07 00 00 E0 00 00 00 E5 21 00 00 00 00 E5 +T BD 08 00 00 E0 00 00 00 E5 21 00 00 00 00 E5 R 00 00 01 00 00 04 02 00 02 0A 06 00 -T 7E 07 00 00 CD 00 00 00 00 F1 F1 F1 11 01 00 -R 00 00 01 00 02 05 21 00 -T 87 07 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 22 00 -T 8A 07 00 00 -R 00 00 01 00 -T 8A 07 00 00 18 82 -R 00 00 01 00 -T 8C 07 00 00 +T C4 08 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 23 00 02 0A 23 00 +T CA 08 00 00 00 00 00 00 F1 F1 F1 11 01 00 3E +R 00 00 01 00 02 04 11 00 +T D3 08 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 24 00 02 09 24 00 +T D8 08 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T DA 08 00 00 +R 00 00 01 00 +T DA 08 00 00 C3 54 08 00 00 +R 00 00 01 00 00 05 01 00 +T DD 08 00 00 R 00 00 01 00 -T 8C 07 00 00 C3 C1 06 00 00 +T DD 08 00 00 C3 07 08 00 00 R 00 00 01 00 00 05 01 00 -T 8F 07 00 00 +T E0 08 00 00 R 00 00 01 00 -T 8F 07 00 00 01 04 80 DD 6E FC DD 66 FD 3E 80 +T E0 08 00 00 01 04 80 DD 6E FC DD 66 FD 3E 80 R 00 00 01 00 -T 9A 07 00 00 AC 67 ED 42 30 13 +T EB 08 00 00 AC 67 ED 42 30 1D R 00 00 01 00 -T A0 07 00 00 +T F1 08 00 00 R 00 00 01 00 -T A0 07 00 00 21 F3 00 00 00 E5 21 00 00 00 00 +T F1 08 00 00 21 F3 00 00 00 E5 21 00 00 00 00 R 00 00 01 00 00 05 02 00 02 0B 06 00 -T A7 07 00 00 E5 CD 00 00 00 00 F1 F1 11 01 00 -R 00 00 01 00 02 06 21 00 -T B0 07 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 22 00 -T B3 07 00 00 +T F8 08 00 00 E5 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 23 00 02 0B 23 00 +T FE 08 00 00 CD 00 00 00 00 F1 F1 11 01 00 3E +R 00 00 01 00 02 05 11 00 +T 07 09 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 24 00 02 09 24 00 +T 0C 09 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T 0E 09 00 00 R 00 00 01 00 -T B3 07 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD +T 0E 09 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD R 00 00 01 00 -T BE 07 00 00 46 05 09 4E 23 46 11 02 00 00 00 +T 19 09 00 00 46 05 09 4E 23 46 11 02 00 00 00 R 00 00 01 00 00 0B 03 00 -T C7 07 00 00 CD 00 00 00 00 21 02 80 E5 21 -R 00 00 01 00 02 05 13 00 -T CF 07 00 00 02 00 00 00 E5 CD 00 00 00 00 F1 -R 00 00 01 00 00 04 03 00 02 0A 1A 00 -T D6 07 00 00 F1 22 00 00 00 00 CB 7C 28 1A -R 00 00 01 00 00 06 03 00 -T DE 07 00 00 -R 00 00 01 00 -T DE 07 00 00 21 24 01 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T E5 07 00 00 F1 11 00 00 00 00 CD 00 00 00 00 -R 00 00 01 00 02 06 12 00 02 0B 02 00 -T EC 07 00 00 11 02 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 00 05 03 00 02 0A 0D 00 -T F3 07 00 00 01 00 CD 00 00 00 00 -R 00 00 01 00 02 07 22 00 -T F8 07 00 00 -R 00 00 01 00 -T F8 07 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD -R 00 00 01 00 -T 03 08 00 00 46 05 09 23 23 5E 23 56 CD -R 00 00 01 00 -T 0C 08 00 00 00 00 00 00 DD 75 F4 DD 74 F5 DD -R 00 00 01 00 02 04 17 00 -T 15 08 00 00 6E FA DD 66 FB 29 09 01 04 00 09 -R 00 00 01 00 -T 20 08 00 00 5E 23 56 CD 00 00 00 00 DD 75 F6 -R 00 00 01 00 02 08 17 00 -T 29 08 00 00 DD 74 F7 DD 4E FC DD 46 FD 21 -R 00 00 01 00 -T 33 08 00 00 04 00 CD 00 00 00 00 30 1E -R 00 00 01 00 02 07 19 00 -T 3A 08 00 00 -R 00 00 01 00 -T 3A 08 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD -R 00 00 01 00 -T 45 08 00 00 46 05 09 01 06 00 09 5E 23 56 CD -R 00 00 01 00 -T 50 08 00 00 00 00 00 00 DD 75 F8 DD 74 F9 -R 00 00 01 00 02 04 17 00 -T 58 08 00 00 -R 00 00 01 00 -T 58 08 00 00 01 64 00 DD 6E F4 DD 66 F5 A7 ED -R 00 00 01 00 -T 63 08 00 00 42 38 25 01 1E 00 DD 5E F4 DD 56 -R 00 00 01 00 -T 6E 08 00 00 F5 CD 00 00 00 00 DD 6E F6 DD 66 -R 00 00 01 00 02 06 1E 00 -T 77 08 00 00 F7 A7 ED 52 30 0E DD 4E F8 DD 46 +T 22 09 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 13 00 02 0A 13 00 +T 28 09 00 00 00 00 00 00 21 02 80 E5 21 +R 00 00 01 00 02 04 11 00 +T 2F 09 00 00 02 00 00 00 E5 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 0A 1B 00 +T 35 09 00 00 00 00 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 04 1B 00 02 09 11 00 +T 3C 09 00 00 22 00 00 00 00 CB 7C 28 2E +R 00 00 01 00 00 05 03 00 +T 43 09 00 00 +R 00 00 01 00 +T 43 09 00 00 21 24 01 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 49 09 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 50 09 00 00 11 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 05 12 00 2B 0A 01 00 +T 56 09 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T 5C 09 00 00 02 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 0C 00 +T 61 09 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 0C 00 02 09 11 00 +T 67 09 00 00 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 24 00 +T 6C 09 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T 71 09 00 00 +R 00 00 01 00 +T 71 09 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD +R 00 00 01 00 +T 7C 09 00 00 46 05 09 23 23 5E 23 56 3E +R 00 00 01 00 +T 85 09 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 18 00 02 09 18 00 +T 8A 09 00 00 00 00 00 00 DD 75 F4 DD 74 F5 DD +R 00 00 01 00 02 04 11 00 +T 93 09 00 00 6E FA DD 66 FB 29 09 01 04 00 09 +R 00 00 01 00 +T 9E 09 00 00 5E 23 56 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 18 00 +T A4 09 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 18 00 02 09 11 00 +T AB 09 00 00 F6 DD 74 F7 DD 4E FC DD 46 FD 21 +R 00 00 01 00 +T B6 09 00 00 04 00 CD 00 00 00 00 30 23 +R 00 00 01 00 02 07 1A 00 +T BD 09 00 00 +R 00 00 01 00 +T BD 09 00 00 DD 6E FA DD 66 FB 29 DD 4E 04 DD +R 00 00 01 00 +T C8 09 00 00 46 05 09 01 06 00 09 5E 23 56 3E +R 00 00 01 00 +T D3 09 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 18 00 02 09 18 00 +T D8 09 00 00 00 00 00 00 DD 75 F8 DD 74 F9 +R 00 00 01 00 02 04 11 00 +T E0 09 00 00 +R 00 00 01 00 +T E0 09 00 00 01 64 00 DD 6E F4 DD 66 F5 A7 ED +R 00 00 01 00 +T EB 09 00 00 42 38 25 01 1E 00 DD 5E F4 DD 56 +R 00 00 01 00 +T F6 09 00 00 F5 CD 00 00 00 00 DD 6E F6 DD 66 +R 00 00 01 00 02 06 1F 00 +T FF 09 00 00 F7 A7 ED 52 30 0E DD 4E F8 DD 46 R 00 00 01 00 -T 82 08 00 00 F9 21 64 00 A7 ED 42 30 13 +T 0A 0A 00 00 F9 21 64 00 A7 ED 42 30 1D R 00 00 01 00 -T 8B 08 00 00 +T 13 0A 00 00 R 00 00 01 00 -T 8B 08 00 00 +T 13 0A 00 00 R 00 00 01 00 -T 8B 08 00 00 +T 13 0A 00 00 R 00 00 01 00 -T 8B 08 00 00 21 31 01 00 00 E5 21 00 00 00 00 +T 13 0A 00 00 21 31 01 00 00 E5 21 00 00 00 00 R 00 00 01 00 00 05 02 00 02 0B 06 00 -T 92 08 00 00 E5 CD 00 00 00 00 F1 F1 11 01 00 -R 00 00 01 00 02 06 21 00 -T 9B 08 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 22 00 -T 9E 08 00 00 +T 1A 0A 00 00 E5 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 23 00 02 0B 23 00 +T 20 0A 00 00 CD 00 00 00 00 F1 F1 11 01 00 3E +R 00 00 01 00 02 05 11 00 +T 29 0A 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 24 00 02 09 24 00 +T 2E 0A 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T 30 0A 00 00 R 00 00 01 00 -T 9E 08 00 00 01 00 00 21 1E 08 22 04 06 00 00 +T 30 0A 00 00 01 00 00 21 1E 08 22 04 06 00 00 R 00 00 01 00 00 0B 03 00 -T A7 08 00 00 ED 43 06 06 00 00 11 FF FF D5 11 +T 39 0A 00 00 ED 43 06 06 00 00 11 FF FF D5 11 R 00 00 01 00 00 06 03 00 -T B0 08 00 00 FC FF D5 C5 E5 21 03 00 C1 09 EB +T 42 0A 00 00 FC FF D5 C5 E5 21 03 00 C1 09 EB R 00 00 01 00 -T BB 08 00 00 21 00 00 C1 ED 4A 4D 44 EB CD +T 4D 0A 00 00 21 00 00 C1 ED 4A 4D 44 EB CD R 00 00 01 00 -T C5 08 00 00 00 00 00 00 22 04 06 00 00 ED 43 -R 00 00 01 00 02 04 15 00 00 09 03 00 -T CC 08 00 00 06 06 00 00 C5 E5 DD 6E F6 DD 66 +T 57 0A 00 00 00 00 00 00 22 04 06 00 00 ED 43 +R 00 00 01 00 02 04 16 00 00 09 03 00 +T 5E 0A 00 00 06 06 00 00 C5 E5 DD 6E F6 DD 66 R 00 00 01 00 00 04 03 00 -T D5 08 00 00 F7 29 29 29 01 FF FF 09 EB 06 03 +T 67 0A 00 00 F7 29 29 29 01 FF FF 09 EB 06 03 R 00 00 01 00 -T E0 08 00 00 CD 00 00 00 00 EB 11 00 00 C1 09 +T 72 0A 00 00 CD 00 00 00 00 EB 11 00 00 C1 09 R 00 00 01 00 02 05 00 00 -T E9 08 00 00 EB C1 ED 4A E5 D5 21 01 00 C1 09 +T 7B 0A 00 00 EB C1 ED 4A E5 D5 21 01 00 C1 09 R 00 00 01 00 -T F4 08 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 22 +T 86 0A 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 22 R 00 00 01 00 -T FF 08 00 00 08 06 00 00 ED 43 0A 06 00 00 11 +T 91 0A 00 00 08 06 00 00 ED 43 0A 06 00 00 11 R 00 00 01 00 00 04 03 00 00 0A 03 00 -T 06 09 00 00 FF FF D5 11 FC FF D5 C5 E5 21 +T 98 0A 00 00 FF FF D5 11 FC FF D5 C5 E5 21 R 00 00 01 00 -T 10 09 00 00 03 00 C1 09 EB 21 00 00 C1 ED 4A +T A2 0A 00 00 03 00 C1 09 EB 21 00 00 C1 ED 4A R 00 00 01 00 -T 1B 09 00 00 4D 44 EB CD 00 00 00 00 22 -R 00 00 01 00 02 08 15 00 -T 22 09 00 00 08 06 00 00 ED 43 0A 06 00 00 C5 +T AD 0A 00 00 4D 44 EB CD 00 00 00 00 22 +R 00 00 01 00 02 08 16 00 +T B4 0A 00 00 08 06 00 00 ED 43 0A 06 00 00 C5 R 00 00 01 00 00 04 03 00 00 0A 03 00 -T 29 09 00 00 E5 21 FF FF DD 4E F4 DD 46 F5 09 +T BB 0A 00 00 E5 21 FF FF DD 4E F4 DD 46 F5 09 R 00 00 01 00 -T 34 09 00 00 EB 06 03 CD 00 00 00 00 EB 11 +T C6 0A 00 00 EB 06 03 CD 00 00 00 00 EB 11 R 00 00 01 00 02 08 00 00 -T 3C 09 00 00 00 00 C1 09 EB C1 ED 4A E5 D5 21 +T CE 0A 00 00 00 00 C1 09 EB C1 ED 4A E5 D5 21 R 00 00 01 00 -T 47 09 00 00 01 00 C1 09 EB 21 00 00 C1 ED 4A +T D9 0A 00 00 01 00 C1 09 EB 21 00 00 C1 ED 4A R 00 00 01 00 -T 52 09 00 00 4D 44 EB 22 0C 06 00 00 ED 43 +T E4 0A 00 00 4D 44 EB 22 0C 06 00 00 ED 43 R 00 00 01 00 00 08 03 00 -T 5A 09 00 00 0E 06 00 00 11 FF FF D5 11 FC FF +T EC 0A 00 00 0E 06 00 00 11 FF FF D5 11 FC FF R 00 00 01 00 00 04 03 00 -T 63 09 00 00 D5 C5 E5 21 03 00 C1 09 EB 21 +T F5 0A 00 00 D5 C5 E5 21 03 00 C1 09 EB 21 R 00 00 01 00 -T 6D 09 00 00 00 00 C1 ED 4A 4D 44 EB CD +T FF 0A 00 00 00 00 C1 ED 4A 4D 44 EB CD R 00 00 01 00 -T 76 09 00 00 00 00 00 00 22 0C 06 00 00 ED 43 -R 00 00 01 00 02 04 15 00 00 09 03 00 -T 7D 09 00 00 0E 06 00 00 22 10 06 00 00 ED 43 +T 08 0B 00 00 00 00 00 00 22 0C 06 00 00 ED 43 +R 00 00 01 00 02 04 16 00 00 09 03 00 +T 0F 0B 00 00 0E 06 00 00 22 10 06 00 00 ED 43 R 00 00 01 00 00 04 03 00 00 09 03 00 -T 84 09 00 00 12 06 00 00 C5 E5 21 FF 01 C1 09 +T 16 0B 00 00 12 06 00 00 C5 E5 21 FF 01 C1 09 R 00 00 01 00 00 04 03 00 -T 8D 09 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 3E +T 1F 0B 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 3E R 00 00 01 00 -T 98 09 00 00 09 CD 00 00 00 00 01 FB FF 09 DD -R 00 00 01 00 02 06 1F 00 -T A1 09 00 00 75 F8 DD 74 F9 3A 84 09 00 00 B7 +T 2A 0B 00 00 09 CD 00 00 00 00 01 FB FF 09 DD +R 00 00 01 00 02 06 21 00 +T 33 0B 00 00 75 F8 DD 74 F9 3A 84 09 00 00 B7 R 00 00 01 00 00 0A 04 00 -T AA 09 00 00 28 7D +T 3C 0B 00 00 28 7D R 00 00 01 00 -T AC 09 00 00 +T 3E 0B 00 00 R 00 00 01 00 -T AC 09 00 00 21 FF FF DD 4E F4 DD 46 F5 09 EB +T 3E 0B 00 00 21 FF FF DD 4E F4 DD 46 F5 09 EB R 00 00 01 00 -T B7 09 00 00 06 03 CD 00 00 00 00 EB 01 00 00 +T 49 0B 00 00 06 03 CD 00 00 00 00 EB 01 00 00 R 00 00 01 00 02 07 00 00 -T C0 09 00 00 C5 E5 2A 0C 06 00 00 C1 09 EB 2A +T 52 0B 00 00 C5 E5 2A 0C 06 00 00 C1 09 EB 2A R 00 00 01 00 00 07 03 00 -T C9 09 00 00 0E 06 00 00 C1 ED 4A E5 D5 21 +T 5B 0B 00 00 0E 06 00 00 C1 ED 4A E5 D5 21 R 00 00 01 00 00 04 03 00 -T D1 09 00 00 01 00 C1 09 EB 21 00 00 C1 ED 4A +T 63 0B 00 00 01 00 C1 09 EB 21 00 00 C1 ED 4A R 00 00 01 00 -T DC 09 00 00 4D 44 EB 22 10 06 00 00 ED 43 +T 6E 0B 00 00 4D 44 EB 22 10 06 00 00 ED 43 R 00 00 01 00 00 08 03 00 -T E4 09 00 00 12 06 00 00 11 FF FF D5 11 FC FF +T 76 0B 00 00 12 06 00 00 11 FF FF D5 11 FC FF R 00 00 01 00 00 04 03 00 -T ED 09 00 00 D5 C5 E5 21 03 00 C1 09 EB 21 +T 7F 0B 00 00 D5 C5 E5 21 03 00 C1 09 EB 21 R 00 00 01 00 -T F7 09 00 00 00 00 C1 ED 4A 4D 44 EB CD +T 89 0B 00 00 00 00 C1 ED 4A 4D 44 EB CD R 00 00 01 00 -T 00 0A 00 00 00 00 00 00 22 10 06 00 00 ED 43 -R 00 00 01 00 02 04 15 00 00 09 03 00 -T 07 0A 00 00 12 06 00 00 C5 E5 21 FF 01 C1 09 +T 92 0B 00 00 00 00 00 00 22 10 06 00 00 ED 43 +R 00 00 01 00 02 04 16 00 00 09 03 00 +T 99 0B 00 00 12 06 00 00 C5 E5 21 FF 01 C1 09 R 00 00 01 00 00 04 03 00 -T 10 0A 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 3E +T A2 0B 00 00 EB 21 00 00 C1 ED 4A 4D 44 EB 3E R 00 00 01 00 -T 1B 0A 00 00 09 CD 00 00 00 00 01 FB FF 09 DD -R 00 00 01 00 02 06 1F 00 -T 24 0A 00 00 75 F8 DD 74 F9 +T AD 0B 00 00 09 CD 00 00 00 00 01 FB FF 09 DD +R 00 00 01 00 02 06 21 00 +T B6 0B 00 00 75 F8 DD 74 F9 R 00 00 01 00 -T 29 0A 00 00 +T BB 0B 00 00 R 00 00 01 00 -T 29 0A 00 00 DD 6E F8 DD 66 F9 E5 DD 6E F6 DD +T BB 0B 00 00 DD 6E F8 DD 66 F9 E5 DD 6E F6 DD R 00 00 01 00 -T 34 0A 00 00 66 F7 E5 DD 6E F4 DD 66 F5 E5 21 +T C6 0B 00 00 66 F7 E5 DD 6E F4 DD 66 F5 E5 21 R 00 00 01 00 -T 3F 0A 00 00 02 00 00 00 E5 21 47 01 00 00 E5 +T D1 0B 00 00 02 00 00 00 E5 21 47 01 00 00 E5 R 00 00 01 00 00 04 03 00 00 0A 02 00 -T 46 0A 00 00 CD 00 00 00 00 F1 F1 F1 F1 F1 11 -R 00 00 01 00 02 05 05 00 -T 4F 0A 00 00 00 00 00 00 CD 00 00 00 00 11 -R 00 00 01 00 02 04 12 00 02 09 02 00 -T 55 0A 00 00 80 01 00 00 CD 40 01 00 00 7D B4 -R 00 00 01 00 00 04 02 00 00 09 01 00 -T 5C 0A 00 00 20 06 -R 00 00 01 00 -T 5E 0A 00 00 -R 00 00 01 00 -T 5E 0A 00 00 11 01 00 CD 00 00 00 00 -R 00 00 01 00 02 08 22 00 -T 64 0A 00 00 -R 00 00 01 00 -T 64 0A 00 00 21 8A 01 00 00 E5 CD 00 00 00 00 -R 00 00 01 00 00 05 02 00 02 0B 05 00 -T 6B 0A 00 00 F1 3A 80 09 00 00 B7 28 09 -R 00 00 01 00 00 06 04 00 -T 72 0A 00 00 +T D8 0B 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 04 00 02 0A 04 00 +T DE 0B 00 00 00 00 00 00 F1 F1 F1 F1 F1 11 +R 00 00 01 00 02 04 11 00 +T E6 0B 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 12 00 2B 09 01 00 +T EB 0B 00 00 00 00 00 00 CD 00 00 00 00 11 +R 00 00 01 00 02 04 01 00 02 09 11 00 +T F1 0B 00 00 80 01 00 00 3E E0 01 00 00 21 +R 00 00 01 00 00 04 02 00 29 09 01 00 +T F6 0B 00 00 E0 01 00 00 CD 00 00 00 00 7D B4 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T FD 0B 00 00 20 0B +R 00 00 01 00 +T FF 0B 00 00 +R 00 00 01 00 +T FF 0B 00 00 11 01 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 24 00 +T 05 0C 00 00 00 00 00 00 CD 00 00 00 00 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T 0A 0C 00 00 +R 00 00 01 00 +T 0A 0C 00 00 21 8A 01 00 00 E5 3E 00 00 00 00 +R 00 00 01 00 00 05 02 00 2B 0B 04 00 +T 10 0C 00 00 21 00 00 00 00 CD 00 00 00 00 F1 +R 00 00 01 00 02 05 04 00 02 0A 11 00 +T 17 0C 00 00 3A 80 09 00 00 B7 28 0E +R 00 00 01 00 00 05 04 00 +T 1D 0C 00 00 R 00 00 01 00 -T 72 0A 00 00 DD 5E F4 DD 56 F5 CD 3F 06 00 00 -R 00 00 01 00 00 0B 01 00 -T 7B 0A 00 00 +T 1D 0C 00 00 DD 5E F4 DD 56 F5 3E 71 07 00 00 +R 00 00 01 00 29 0B 01 00 +T 25 0C 00 00 21 71 07 00 00 CD 00 00 00 00 +R 00 00 01 00 00 05 01 00 02 0A 11 00 +T 2B 0C 00 00 R 00 00 01 00 -T 7B 0A 00 00 ED 4B 04 06 00 00 2A 08 06 00 00 +T 2B 0C 00 00 ED 4B 04 06 00 00 2A 08 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 82 0A 00 00 A7 ED 42 EB CD 00 00 00 00 22 -R 00 00 01 00 02 09 20 00 -T 8A 0A 00 00 14 06 00 00 7D B4 20 0A +T 32 0C 00 00 A7 ED 42 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 22 00 +T 39 0C 00 00 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 04 22 00 02 09 11 00 +T 3F 0C 00 00 14 06 00 00 7D B4 20 0B R 00 00 01 00 00 04 03 00 -T 90 0A 00 00 +T 45 0C 00 00 R 00 00 01 00 -T 90 0A 00 00 DD 36 FE 8C 01 00 00 DD 36 FF +T 45 0C 00 00 DD 36 FE 8C 01 00 00 DD 36 FF R 00 00 01 00 09 07 02 00 -T 97 0A 00 00 8C 01 00 00 18 6C -R 00 00 01 00 89 04 02 00 -T 9A 0A 00 00 +T 4C 0C 00 00 8C 01 00 00 C3 D0 0C 00 00 +R 00 00 01 00 89 04 02 00 00 09 01 00 +T 50 0C 00 00 R 00 00 01 00 -T 9A 0A 00 00 ED 4B 04 06 00 00 2A 08 06 00 00 +T 50 0C 00 00 ED 4B 04 06 00 00 2A 08 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T A1 0A 00 00 A7 ED 42 E5 0E 00 ED 5B +T 57 0C 00 00 A7 ED 42 E5 0E 00 ED 5B R 00 00 01 00 -T A9 0A 00 00 14 06 00 00 CD 00 00 00 00 E1 ED -R 00 00 01 00 00 04 03 00 02 09 03 00 -T B0 0A 00 00 4B 08 06 00 00 2A 10 06 00 00 A7 +T 5F 0C 00 00 14 06 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 02 00 +T 64 0C 00 00 00 00 00 00 CD 00 00 00 00 E1 ED +R 00 00 01 00 02 04 02 00 02 09 11 00 +T 6B 0C 00 00 4B 08 06 00 00 2A 10 06 00 00 A7 R 00 00 01 00 00 05 03 00 00 0A 03 00 -T B7 0A 00 00 ED 42 EB CD 00 00 00 00 22 -R 00 00 01 00 02 08 20 00 -T BE 0A 00 00 16 06 00 00 7D B4 20 0A +T 72 0C 00 00 ED 42 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 22 00 +T 78 0C 00 00 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 04 22 00 02 09 11 00 +T 7E 0C 00 00 16 06 00 00 7D B4 20 0A R 00 00 01 00 00 04 03 00 -T C4 0A 00 00 +T 84 0C 00 00 R 00 00 01 00 -T C4 0A 00 00 DD 36 FE 99 01 00 00 DD 36 FF +T 84 0C 00 00 DD 36 FE 99 01 00 00 DD 36 FF R 00 00 01 00 09 07 02 00 -T CB 0A 00 00 99 01 00 00 18 38 +T 8B 0C 00 00 99 01 00 00 18 42 R 00 00 01 00 89 04 02 00 -T CE 0A 00 00 +T 8E 0C 00 00 R 00 00 01 00 -T CE 0A 00 00 ED 4B 08 06 00 00 2A 10 06 00 00 +T 8E 0C 00 00 ED 4B 08 06 00 00 2A 10 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T D5 0A 00 00 A7 ED 42 E5 0E 00 ED 5B +T 95 0C 00 00 A7 ED 42 E5 0E 00 ED 5B R 00 00 01 00 -T DD 0A 00 00 16 06 00 00 CD 00 00 00 00 E1 3A -R 00 00 01 00 00 04 03 00 02 09 03 00 -T E4 0A 00 00 84 09 00 00 B7 28 4D +T 9D 0C 00 00 16 06 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 02 00 +T A2 0C 00 00 00 00 00 00 CD 00 00 00 00 E1 3A +R 00 00 01 00 02 04 02 00 02 09 11 00 +T A9 0C 00 00 84 09 00 00 B7 28 61 R 00 00 01 00 00 04 04 00 -T E9 0A 00 00 +T AE 0C 00 00 R 00 00 01 00 -T E9 0A 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 +T AE 0C 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T F0 0A 00 00 A7 ED 42 EB CD 00 00 00 00 22 -R 00 00 01 00 02 09 20 00 -T F8 0A 00 00 18 06 00 00 7D B4 20 23 +T B5 0C 00 00 A7 ED 42 EB 3E 00 00 00 00 21 +R 00 00 01 00 2B 09 22 00 +T BC 0C 00 00 00 00 00 00 CD 00 00 00 00 22 +R 00 00 01 00 02 04 22 00 02 09 11 00 +T C2 0C 00 00 18 06 00 00 7D B4 20 2D R 00 00 01 00 00 04 03 00 -T FE 0A 00 00 +T C8 0C 00 00 R 00 00 01 00 -T FE 0A 00 00 DD 36 FE A6 01 00 00 DD 36 FF +T C8 0C 00 00 DD 36 FE A6 01 00 00 DD 36 FF R 00 00 01 00 09 07 02 00 -T 05 0B 00 00 A6 01 00 00 +T CF 0C 00 00 A6 01 00 00 R 00 00 01 00 89 04 02 00 -T 06 0B 00 00 +T D0 0C 00 00 R 00 00 01 00 -T 06 0B 00 00 DD 6E FE DD 66 FF E5 21 +T D0 0C 00 00 DD 6E FE DD 66 FF E5 21 R 00 00 01 00 -T 0E 0B 00 00 B2 01 00 00 E5 21 00 00 00 00 E5 +T D8 0C 00 00 B2 01 00 00 E5 21 00 00 00 00 E5 R 00 00 01 00 00 04 02 00 02 0A 06 00 -T 15 0B 00 00 CD 00 00 00 00 F1 F1 F1 11 01 00 -R 00 00 01 00 02 05 21 00 -T 1E 0B 00 00 CD 00 00 00 00 -R 00 00 01 00 02 05 22 00 -T 21 0B 00 00 -R 00 00 01 00 -T 21 0B 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 +T DF 0C 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 23 00 02 0A 23 00 +T E5 0C 00 00 00 00 00 00 F1 F1 F1 11 01 00 3E +R 00 00 01 00 02 04 11 00 +T EE 0C 00 00 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 04 24 00 02 09 24 00 +T F3 0C 00 00 00 00 00 00 +R 00 00 01 00 02 04 11 00 +T F5 0C 00 00 +R 00 00 01 00 +T F5 0C 00 00 ED 4B 0C 06 00 00 2A 10 06 00 00 R 00 00 01 00 00 06 03 00 00 0B 03 00 -T 28 0B 00 00 A7 ED 42 E5 0E 00 ED 5B +T FC 0C 00 00 A7 ED 42 E5 0E 00 ED 5B R 00 00 01 00 -T 30 0B 00 00 18 06 00 00 CD 00 00 00 00 E1 -R 00 00 01 00 00 04 03 00 02 09 03 00 -T 36 0B 00 00 +T 04 0D 00 00 18 06 00 00 3E 00 00 00 00 21 +R 00 00 01 00 00 04 03 00 2B 09 02 00 +T 09 0D 00 00 00 00 00 00 CD 00 00 00 00 E1 +R 00 00 01 00 02 04 02 00 02 09 11 00 +T 0F 0D 00 00 R 00 00 01 00 -T 36 0B 00 00 DD 6E F8 DD 66 F9 E5 DD 4E F6 DD +T 0F 0D 00 00 DD 6E F8 DD 66 F9 E5 DD 4E F6 DD R 00 00 01 00 -T 41 0B 00 00 46 F7 DD 5E F4 DD 56 F5 CD +T 1A 0D 00 00 46 F7 DD 5E F4 DD 56 F5 3E R 00 00 01 00 -T 4A 0B 00 00 96 01 00 00 E1 ED 5B 00 00 00 00 -R 00 00 01 00 00 04 01 00 00 0B 03 00 -T 51 0B 00 00 CD 00 00 00 00 3A 83 09 00 00 B7 -R 00 00 01 00 02 05 08 00 00 0A 04 00 -T 58 0B 00 00 28 0D +T 23 0D 00 00 4A 02 00 00 21 4A 02 00 00 CD +R 00 00 01 00 29 04 01 00 00 09 01 00 +T 28 0D 00 00 00 00 00 00 E1 ED 5B 00 00 00 00 +R 00 00 01 00 02 04 11 00 00 0B 03 00 +T 2F 0D 00 00 3E 00 00 00 00 21 00 00 00 00 CD +R 00 00 01 00 2B 05 08 00 02 0A 08 00 +T 35 0D 00 00 00 00 00 00 3A 83 09 00 00 B7 28 +R 00 00 01 00 02 04 11 00 00 09 04 00 +T 3C 0D 00 00 12 R 00 00 01 00 -T 5A 0B 00 00 +T 3D 0D 00 00 R 00 00 01 00 -T 5A 0B 00 00 21 02 00 00 00 E5 21 CD 01 00 00 +T 3D 0D 00 00 21 02 00 00 00 E5 21 CD 01 00 00 R 00 00 01 00 00 05 03 00 00 0B 02 00 -T 61 0B 00 00 E5 CD 00 00 00 00 F1 F1 -R 00 00 01 00 02 06 05 00 -T 67 0B 00 00 +T 44 0D 00 00 E5 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 04 00 02 0B 04 00 +T 4A 0D 00 00 CD 00 00 00 00 F1 F1 +R 00 00 01 00 02 05 11 00 +T 4F 0D 00 00 R 00 00 01 00 -T 67 0B 00 00 11 00 00 CD 00 00 00 00 C3 -R 00 00 01 00 02 08 22 00 -T 6E 0B 00 00 00 00 00 00 -R 00 00 01 00 02 04 0C 00 -T 70 0B 00 00 +T 4F 0D 00 00 11 00 00 3E 00 00 00 00 21 +R 00 00 01 00 2B 08 24 00 +T 55 0D 00 00 00 00 00 00 CD 00 00 00 00 C3 +R 00 00 01 00 02 04 24 00 02 09 11 00 +T 5B 0D 00 00 00 00 00 00 +R 00 00 01 00 02 04 05 00 +T 5D 0D 00 00 R 00 00 01 00 -T 70 0B 00 00 CD 00 00 00 00 FA FF DD 6E 08 DD -R 00 00 01 00 02 05 16 00 -T 79 0B 00 00 66 09 DD 75 FC DD 74 FD +T 5D 0D 00 00 CD 00 00 00 00 FA FF DD 6E 0A DD +R 00 00 01 00 02 05 17 00 +T 66 0D 00 00 66 0B DD 75 FC DD 74 FD R 00 00 01 00 -T 81 0B 00 00 +T 6E 0D 00 00 R 00 00 01 00 -T 81 0B 00 00 DD 6E 0E DD 66 0F E5 DD 6E 0C DD +T 6E 0D 00 00 DD 6E 10 DD 66 11 E5 DD 6E 0E DD R 00 00 01 00 -T 8C 0B 00 00 66 0D E5 DD 6E FC DD 66 FD 01 +T 79 0D 00 00 66 0F E5 DD 6E FC DD 66 FD 01 R 00 00 01 00 -T 96 0B 00 00 00 00 CD 00 00 00 00 D2 -R 00 00 01 00 02 07 14 00 -T 9C 0B 00 00 4F 0C 00 00 +T 83 0D 00 00 00 00 CD 00 00 00 00 D2 +R 00 00 01 00 02 07 15 00 +T 89 0D 00 00 50 0E 00 00 R 00 00 01 00 00 04 01 00 -T 9E 0B 00 00 +T 8B 0D 00 00 R 00 00 01 00 -T 9E 0B 00 00 DD 4E 0C DD 46 0D DD 6E FC DD 66 +T 8B 0D 00 00 DD 4E 0E DD 46 0F DD 6E FC DD 66 R 00 00 01 00 -T A9 0B 00 00 FD 3E 02 84 67 7D E6 00 5F 7C E6 +T 96 0D 00 00 FD 3E 02 84 67 7D E6 00 5F 7C E6 R 00 00 01 00 -T B4 0B 00 00 FE 57 CD 00 00 00 00 DD 75 FE DD -R 00 00 01 00 02 07 18 00 -T BD 0B 00 00 74 FF DD 4E FC DD 46 FD A7 ED 42 +T A1 0D 00 00 FE 57 3E 00 00 00 00 21 +R 00 00 01 00 2B 07 19 00 +T A6 0D 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 02 04 19 00 02 09 11 00 +T AD 0D 00 00 FE DD 74 FF DD 4E FC DD 46 FD A7 R 00 00 01 00 -T C8 0B 00 00 01 00 02 A7 ED 42 30 16 +T B8 0D 00 00 ED 42 01 00 02 A7 ED 42 30 1B R 00 00 01 00 -T D0 0B 00 00 +T C2 0D 00 00 R 00 00 01 00 -T D0 0B 00 00 06 09 DD 5E FC DD 56 FD CD +T C2 0D 00 00 06 09 DD 5E FC DD 56 FD CD R 00 00 01 00 -T D9 0B 00 00 00 00 00 00 CD 00 00 00 00 DD 75 -R 00 00 01 00 02 04 00 00 00 09 01 00 -T E0 0B 00 00 FA DD 74 FB 18 08 +T CB 0D 00 00 00 00 00 00 3E 00 00 00 00 21 +R 00 00 01 00 02 04 00 00 29 09 01 00 +T D0 0D 00 00 00 00 00 00 CD 00 00 00 00 DD 75 +R 00 00 01 00 00 04 01 00 02 09 11 00 +T D7 0D 00 00 FA DD 74 FB 18 08 R 00 00 01 00 -T E6 0B 00 00 +T DD 0D 00 00 R 00 00 01 00 -T E6 0B 00 00 DD 36 FA 02 02 00 00 DD 36 FB +T DD 0D 00 00 DD 36 FA 02 02 00 00 DD 36 FB R 00 00 01 00 09 07 03 00 -T ED 0B 00 00 02 02 00 00 +T E4 0D 00 00 02 02 00 00 R 00 00 01 00 89 04 03 00 -T EE 0B 00 00 +T E5 0D 00 00 R 00 00 01 00 -T EE 0B 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 +T E5 0D 00 00 DD 4E FC DD 46 FD DD 6E FE DD 66 R 00 00 01 00 -T F9 0B 00 00 FF A7 ED 42 E5 79 E6 FF 6F 78 E6 +T F0 0D 00 00 FF A7 ED 42 E5 79 E6 FF 6F 78 E6 R 00 00 01 00 -T 04 0C 00 00 01 67 DD 5E FA DD 56 FB 19 4D 44 +T FB 0D 00 00 01 67 DD 5E FA DD 56 FB 19 4D 44 R 00 00 01 00 -T 0F 0C 00 00 DD 5E 08 DD 56 09 DD 6E FC DD 66 +T 06 0E 00 00 DD 5E 0A DD 56 0B DD 6E FC DD 66 R 00 00 01 00 -T 1A 0C 00 00 FD A7 ED 52 DD 5E 02 DD 56 03 19 +T 11 0E 00 00 FD A7 ED 52 DD 5E 02 DD 56 03 19 R 00 00 01 00 -T 25 0C 00 00 EB CD 00 00 00 00 E1 DD 4E FA DD -R 00 00 01 00 02 06 0E 00 -T 2E 0C 00 00 46 FB C5 06 09 DD 5E FC DD 56 FD +T 1C 0E 00 00 EB 3E 00 00 00 00 21 00 00 00 00 +R 00 00 01 00 2B 06 0D 00 02 0B 0D 00 +T 22 0E 00 00 CD 00 00 00 00 E1 DD 4E FA DD 46 +R 00 00 01 00 02 05 11 00 +T 2B 0E 00 00 FB C5 06 09 DD 5E FC DD 56 FD CD R 00 00 01 00 -T 39 0C 00 00 CD 00 00 00 00 C1 CD 30 00 00 00 -R 00 00 01 00 02 05 00 00 00 0B 01 00 -T 40 0C 00 00 DD 6E FE DD 66 FF DD 75 FC DD 74 +T 36 0E 00 00 00 00 00 00 3E 3F 00 00 00 21 +R 00 00 01 00 02 04 00 00 29 09 01 00 +T 3B 0E 00 00 3F 00 00 00 C1 CD 00 00 00 00 DD +R 00 00 01 00 00 04 01 00 02 0A 11 00 +T 42 0E 00 00 6E FE DD 66 FF DD 75 FC DD 74 FD R 00 00 01 00 -T 4B 0C 00 00 FD C3 81 0B 00 00 -R 00 00 01 00 00 06 01 00 -T 4F 0C 00 00 +T 4D 0E 00 00 C3 6E 0D 00 00 +R 00 00 01 00 00 05 01 00 +T 50 0E 00 00 R 00 00 01 00 -T 4F 0C 00 00 C3 00 00 00 00 -R 00 00 01 00 02 05 0C 00 +T 50 0E 00 00 C3 00 00 00 00 +R 00 00 01 00 02 05 05 00 T 00 00 00 00 R 00 00 02 00 T 00 00 00 00 52 65 61 64 20 6F 66 20 62 6C 6F @@ -1421,9 +1629,9 @@ T 84 09 00 00 R 00 00 04 00 T 84 09 00 00 R 00 00 04 00 -T 00 00 00 00 43 38 33 30 30 33 30 33 31 31 30 +T 00 00 00 00 43 36 45 46 30 33 30 35 30 39 32 R 00 00 05 00 -T 0B 00 00 00 34 35 32 34 34 31 00 80 CD A3 06 +T 0B 00 00 00 30 33 39 31 30 31 00 80 CD A3 06 R 00 00 05 00 T 16 00 00 00 CD AB 05 CD FD 04 18 22 00 00 00 R 00 00 05 00 diff --git a/src/fsutil/n.bat b/src/fsutil/n.bat index 14d4e49e..1cb4914d 100644 --- a/src/fsutil/n.bat +++ b/src/fsutil/n.bat @@ -60,12 +60,17 @@ link @bd.w32 @if errorlevel 1 goto failure copy bd.exe ..\bin +rem compile utils in large mode, once, for large-mode mkfs and fsck + iccz80 -S -w -ml -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 utils @if errorlevel 1 goto failure del utils.r01 as-z80 -l -o utils.s01 @if errorlevel 1 goto failure +call mklink-l mkfs +echo utils >> mkfs.lnk + iccz80 -S -w -ml -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 mkfs @if errorlevel 1 goto failure del mkfs.r01 @@ -77,6 +82,9 @@ link-z80 -f mkfs ihex2bin -l mkfs.i86 ..\..\bin\large\mkfs @if errorlevel 1 goto failure +call mklink-l fsck +echo utils >> fsck.lnk + iccz80 -S -w -ml -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 fsck @if errorlevel 1 goto failure del fsck.r01 @@ -88,6 +96,42 @@ link-z80 -f fsck ihex2bin -l fsck.i86 ..\..\bin\large\fsck @if errorlevel 1 goto failure +rem compile utils in banked mode, once, for banked-mode mkfs and fsck + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 utils +@if errorlevel 1 goto failure +del utils.r01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +call mklink-b mkfs +echo utils >> mkfs.lnk + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 mkfs +@if errorlevel 1 goto failure +del mkfs.r01 +as-z80 -l -o mkfs.s01 +@if errorlevel 1 goto failure + +link-z80 -f mkfs +@if errorlevel 1 goto failure +ihex2bin -l mkfs.i86 ..\..\bin\banked\mkfs +@if errorlevel 1 goto failure + +call mklink-b fsck +echo utils >> fsck.lnk + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 fsck +@if errorlevel 1 goto failure +del fsck.r01 +as-z80 -l -o fsck.s01 +@if errorlevel 1 goto failure + +link-z80 -f fsck +@if errorlevel 1 goto failure +ihex2bin -l fsck.i86 ..\..\bin\banked\fsck +@if errorlevel 1 goto failure + iccz80 -S -w -ml -v1 -z -A -I..\..\include\ -I..\kernel\uzi\ -DUTIL -DNATIVE -DDEBUG=1 bd -l bd @if errorlevel 1 goto failure del bd.r01 diff --git a/src/fsutil/ucp.c b/src/fsutil/ucp.c index 04d3813b..86aded38 100644 --- a/src/fsutil/ucp.c +++ b/src/fsutil/ucp.c @@ -71,7 +71,11 @@ uchar line[128+1]; uchar f_pause = 0; int xls(char *option, char *path); -int xchmod(char *path, char *modes); +int xchmod(char *modes, char *path); /* Nick reversed argument order */ +#if 1 /* Nick */ +int xchown(char *uidno, char *path); +int xchgrp(char *gidno, char *path); +#endif int xumask(char *masks); int xmknod(char *path, char *modes, char *devs, char *devs1); int xmkdir(char *path); @@ -113,6 +117,10 @@ char *help[] = { "mkdir name", "mknod name mode major minor", "chmod mode name", +#if 1 /* Nick */ + "chown decimaluid name", + "chgrp decimalgid name", +#endif "[b]get dosfilename [uzixfilename]", "[b]put uzixfilename [dosfilename]", "type|cat filename", @@ -187,6 +195,16 @@ int execute(cmd, a1, a2, a3, a4) if (*a1 && *a2) xchmod(a1, a2); } +#if 1 /* Nick */ + else if (eq(cmd, "chown")) { + if (*a1 && *a2) + xchown(a1, a2); + } + else if (eq(cmd, "chgrp")) { + if (*a1 && *a2) + xchgrp(a1, a2); + } +#endif else if (eq(cmd, "ln")) { if (*a1 && *a2) UZIXlink(a1, a2); diff --git a/src/fsutil/ucp.exe b/src/fsutil/ucp.exe index 1b4d72e757f3dfeef82742d91b8a6a4a19e12578..29b22fa1f7a9b3c8fe40b36bfff306ba4df8ed97 100644 GIT binary patch delta 53826 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 z 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 literal 0 HcmV?d00001 diff --git a/src/bin/touch.exe b/src/bin/touch.exe index a607f979711785e655f70c3e785a92e775023bb1..84db3811603fd4ae226377008bc68c8b7cf9aa8c 100644 GIT binary patch delta 18750 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 SdUYenONGKQ3&gnIN&g%AAv~V| delta 14221 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 diff --git a/src/bin/txt2chs.exe b/src/bin/txt2chs.exe new file mode 100644 index 0000000000000000000000000000000000000000..e5eb754e6de2a2998defeb509c2ffaa14f3b75a1 GIT binary patch literal 86062 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 JK~rcU`y1d7*% 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 C?7l$& delta 11746 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 KYD|JG_5T1LK;c0E diff --git a/src/bin/bmp2txt.exe b/src/bin/bmp2txt.exe new file mode 100644 index 0000000000000000000000000000000000000000..fdf4e30050f580e98b18b432dbccd4ec8800aaf7 GIT binary patch literal 98350 zcmeFa4|o(+mN#6Tt|XPDlWMRd0fPhyDh8csfC)B80_hNt#tyL)A|&WLkcnAmR-p=U zHo?wRdQ7FL5ocsqS7sJI+;^FG-IdvK9merbLT8eIjKjZi5&4&qIJMeO-+ zKl+iJG2^8S?uC?J&pc>b_3N2;*WbS-=fTZ?`OVGueJkf1_kH`@e<|hsk4-t7a0g3YbN@H$3CHIt_IWsNl`WAQdF+>W#MAn@3|pEliQ@(l zv&V|pvhyU_}L`E#d@ds3hz z8<+j%5MLTw*lgpRMCzaUyG7cxO`^09@FRi-V{g3Te>og??=71*-Y4D1aRbQ|8?W1y zh>O6GTP!fnxd~uYurKz;EB;r+aqYL1(2fpIKR~-1yao{NZg{S0m zT=;um!(;2sc>FUKjNwD+cwD#%k0ue1*RYBW-;#z$&Qv@;x)zV+H{fv(#r^FhJnAUh zHCWJvgM_M=P+dOU{Y*SQn2Sfx^>_%Bnn4K{P=m0SKJQ}a2`McL!@CmjI88ZD z6BdaQrrv@_h=4yy;W$S9|J4t_Hc+lK3AXJH&EwF@cr|_FJ;fYi61JyleuuVH*mo~Q zET(8qcGc%kE9Q)kZ{;|plW(vYLuff=F@bPmuoax_PNa`}*A{acLshP2Qp6hLHt<^M z6!y}W&u~$`PG0pyG;c)nN0j$%sy`AuEEO;SyC)*PDkvA$%L(R83xnN{s03y77CA#p zCnR=nq|3&c3Fa&H>!+c(SUGQ@g~rQ?(O}HBB7^Oy!A1ZZUmLH%ZJF^wPWz&Hu9a zeEE&4{|xdehE4SxGgCD0F(qtM@oYNAi922WRj49RZy(wwFnsOa)+&C_3SxXqE!{4tDz zDC4~SxavQTSfw45^qapje*#)Gs?>RvZ!0*gG@a+fT^$V9pxeJ&x>ob-Ry~76afeOw z4``kjRL4%uJHSdD2;Uk7Ynlc*DNFMo1AUrjK=Zz!x|#vY$VHBx%lvwBjnQ<`Vy5Rw z)ib1d1#Ob*Kicg%6|0Nql+vD{dQNHHQ*Q5os6Pg~rsh9|aCB@7KHs^SqsZaoGO!$OYAN z{?Fl{dJzuCPPg}bqku2fe*nYfcikR?NRBr(#=W;we7@{P)q94ugF{<+V_sQ~>fQ0@ zno!jLm0E?hw$=Xjr8#K-c&)sh=pxkc#8^}i)pL6eHr@4K(eRqL-|pRkZf5Q&IAOK= zA=STI^9;H@yQOP1?{3vQsQC?z+NhVB+;1={jPQbZlV@rkL-P)yV^Vv2490t-+p{y) zl-`|6M}q1_)}3y@A?iPeVNmm+^9*UOX4T&s3*X(0u@})i2lG6gKFBfjtUPaPIYv&N zzjKY|Y4z2=48fpzkCq!BVIEOB(I!XjXosUTV7&(?a=lf2o_M$e(bf>N_(yWl;$Nq@ z<0hhmhUS^P*vLF%_w2xUK)1>B9vJDHb~tdZBhaxyd=Y}m~T*zGRQX`0K#O19?jFKBP$C(UO=(c8~(^)C(pNnD*k zjHgE)!MC6;&5biB2YO1b>L1cPPVsrqkkURQx1TANg64?;JePsrNFVXSHLpv2z6TRU zw`UZi9rLuHd?&{yJAv~h(vY;W+>`Gx5jv=ONAp!FlE{HBP>UDLq>g0Hf9!zbe0?Mg8ft+=s?WM>^w%&Qm0y$N(7ZVwWX@-y033N&>wTJl-?yjXg7 zaUq4qWhiTZR6aK3e*Vcs_U$3|Su}$wP6{R{?HMRWEk@z&YXSSh02Q>QF4l=0$_1NT zG9e-Z5mMEa5rR~DWki-V|H_CQ3H<`2J|BEEa%QuhjH>vI>llqZnwRz?tvY|MZ^ruW zAnUuV`N~`bQarKyLJ0xy2GylG6LBDXWe-ND_~8lU4KFob{AWX#W>24p)t$RBLvk~NZ*uDs21m6*@)CHCl-z2cDd-G%SBHZ zWvXYKJ`~{}RY?oCkYwjgV)@b8Qdxmctt{2<9k9Y`Spteu9>FMB9n)5kV9~QO_asL5 z`Iz=f%FQ5C0l;qP{pXveGrZ_9gHY^L{s~Bs<_??9#;IPzJi+k0>bi>@HrBMLYcY5U zVZ!=$ow_uG<-cqF)cbW%UQK3q( zh-3_{S$D?6ShGF}g&LyUNvj#}lj8GU7h8**L4D6-uEv7UWr^SF52+2Dn0B+VHUi+8 z^7@^`xD7MojJw2^U1&BWFU>jLPitYLhK+ABHz-XJPQIDxxBw{6IsVR?`cs5qx`hE% z@fkn;fQlgz@H}DjMpS(pX{EH(WoQwl$5sN)r}GXSA62o?^0;C_gL8y zpxk)J>a^V+TGXR}7gRr1sR!aj9AHEo(7XrS-ksv(R};E%6of$cA6;YAS(5vaOq7sSOuR_;Nw-Mm)wwtpGn zbK;}zDb>G&__c#&!9r?>+uPstjVp*?m}xP>0>nT@jk_$Tsn9AG`Nii;P_);X=iOn& ziO;Xvb=2OWd0*CcF$VK(WE3G&#LMPCnph`4MU@Qy77Gq@Ht8%elg5{{`*-4Fw@38{ zh};0f6VSW?w|BRwn?R)b_pAPA*{IsjnsofB9sSw^ODU8z^w@GkV5}k`w8r@L`|&>hIgu!i&(r zVR(E+yFEQ9o(pHfzy&+t8e=2lk0omMyUX&MW`Y}Q>eo_T9+_^{g~n)loPLuO2I5$G zA)6s;$4z7;k>lc~Cmx2lISR`TsD!w|{B#r{7a4RsLl8BiSiNIlxDbS#eLox*H(0}t zVw?iXAwKWRSyR88=m}>tdLSnrqd^Hq5mb3j$2$pYjBpMmj?0`}%`@t&@2714Vr64R zl(Hg7)ReGs9g_x7OqpG&+tW_$xon8>^fG4lVomS%4vBgX8;GZvkpPW+iglM$R0$7A ziH~sB`Wz$35$j6mdj6MLA9@*W>h`#R3ng71WS(|A8THy@mOwh!3LbD&;?H&MTu#rjpuo*AdtbB1Lh8>QO| zdfPw=byJw8mePRn9xJcE@mjQw>l&+*QD^+!4AzEhQrP`oe8BuItLmSx3Z@q*G7*h$ zL*E*t-U)-I_gE_rRcG8HHo(XkFkcJb$7qJ=V6C(M=Dd$ zc0EWr>myXiH?2ZqhQ)5rG3sC4o;~y;;kt)$c@L&TxA)nm3eCTpX&$@n!Fz#3_3Vz# zx`6fWXI*kXM2Xu!+B91W-VG4DXD9k2;Wn7&mA*%t^b6372`{-NWj)2b%$I|A6?oW~c74 z$L$$tOuL*L)8?K$j5hC6WLUXuIf1x)6xbS2?4q z?xJY_dDVZ4P{X{A`SuhuukR4`b|x;Z<^=n9Gr_l8+eMl3{HNj!^J9jLt7xqVVoTu9 zH2HJl*dz+x7^f5Z9EGV%u>gq@mI_%e>ghn&?HQsPL1VOIU&VV=V||B|9?VTp zTm!7d0?;Getb;T?g2|ZlXzx+GPTidHV1H!SJcP~3tkYA_j;#ru0vbzk`+J&hhZbcI zvN$%0#I(q}3EJNd<8^{!+-E#(InLi1WFu?{08ylFedf2SigIycD z=Vk1RK`p@Wh8)M(A8KwIqE^}tt2YZMO+#E0eOMJ`a^ADE%{$cUfUw)iQ0)w#AT#tT zJi0xt1Q@1mzHlBMvHga3@lLkCxBIkb_nG-cTrt;I zL-PgOhIs0<=c#yP`)N$QtV)794Jv5%u$EC)$Z2!kl^jgBD@dVq_-~hQ+}_%mAl7JA38PIAJgM zdS8wc_VQ`Z!QM@yz21Sonn<4~@;SmHF~Xu#*y!w)BLE}9Flz^v5WIH}VM9&Rb5Nt+ z#B4l`qo@ZdtHi(kG|-_P>@Tk$qE=lunW19y^G9#9UR2O-u18nE(jK!~n`emB@%TI! zPDXzVSCQTk$40sau+7T>w)6?u_Kst-bdCKJb&bzioWJ_~iUVJ9;42P%#ex404q$(! z!3m=xttWDvOc|in6`KS2KAHo_kqOHwlkB~;6vbu~=8kx9f{B*lc&L}n8?ii@3^!Rq zIz@(?8CYTtNZHWH;AM2a+<28`iWhVzEBpxy5$(fyB2Y_cTTF*F*Z2iXaJW4Y$;on8 zSdbublI}mh##m;3e{T0-yq33Hl(011)m zqvS1?lX!CHUbAhQ8<#QI`Mj7Z{;-8%{nsqoft+Q~4%NIgb$6Qxch+r4c2Z>fW9uEfI_ zbITm+N}kkM*5hd>WNwU1#x)0GV!U_yjN>V>8o0^NfW<=qXkQXBE|!VjQlu3T{ZKUpte$f2^i} zHEBtVA~2y0Y>Mb5lW3nyEoME2#bU$h3bLq60fA3&mpe9Jtu(nf2}?g$H(1Sa;CU}z zG15sZB^M->IaI>xChAWi^$HA$;b1JPOb}n4qg@mR{o!6|R9I@nd`4;PI zJb6N5stiUE=y;-e6XOV$t5yxsk|}2K~fm= z7C19lOa+0{%C?rL~SYi>;5GQc9MPRJ&{U_L_-JQ#8t8#^rL$Ho= z@**wacAI=lYP)p(?f2Q_*{SEH=^cji_TmJ2Dk3M{exF@-!te)!U+Q`JgcdDm5AD3B z{dj*-NQ;gfqP{M<+7gxmNw^pp`bQ3tbywP72Tzwng!=?yj}Y#|z}*42Q**~e@~gDQ zT)}M6pUp)!PK$yzzG|d{h?B%NTX9Rf7T1l?3Ayj7tx|Sz! z;~yJBt+7<9U#xhSRlTBk^%8-J`?u?O8|s*A)$yv!bu4CF%j*c~#bbn@g)WVUsLB+# z_W{h-!FDMjdaORnRm{~3lVJuKK%w>gBz$sCe4fQ891ubcTm!0=>o5vfgo7e%EaJL& zgpFW~t1f>c!hoTl1Wc%^!M0)H;+A#AoIDBHglJ|_GmaWWGZ*2dH0C2QLmKNGjyUseMkb}`%312=qDeE35_7az(bf50& zkILAIJP*nIsLyzwWphNm=e5CYP_+63IUM?>ryu?jh94}fuGYG055prD@~Ns)lOZLX zT9cr4Xvghc?y;?cdsO`HHVn6sZZ>XR9pMD!9lLTt*gWUczmMkb+U6;# z9ZJ95-V@CY?kp+dqPco2l6T_mp!Xic9mQ`DzgfrIl3J77N^PynZEd9qK-;=JLFuw9 z-30PjJ(2k{=ldkF7Qyhrhl;2qI<9o6RSgZ9xlC!(yv zz_}a01BBZn)NVK&+DWyY7`AF2ivf*Sa09G}!|Kwl5xsF?B*y>T%luEj^y%M6P_A=1 zN{Np2fy?csMI3O&+v9@O9(mLrSx5o|0q?vK;WGRl#ILQ?KI?eva{Fo^zKb~b;smrr zS1kQ<8-19de8jlFV*=#P32>kuwTrdYhj!&7YEkjK_n=Eo$N}7)DE}yar|>(2-+BB7 z@EgJ}nQB$?{cP|#8}BTOqqKF_d%SI3t(hJi zmhBC;TBVC%D5&S4y!%W-R->06X5`RbY%L~Ih8;U_x*_hkDl%88#8}xtVEJ|%}=n0$jP6eK?F`V&-R|axdFd3ks5h)mRu$NICz8{hC1{H$| zm=p@4%2>bn*h%n=z~07TQLPsfpxE*ZqGG*m73P!5stV&U^C)n@rm>*XNXDU2ZL~TV zm2TE*1Z`QQ%-yv)LF@8WR2dIlh(;@nCx8q{wcZNjrwHPRPcSMk`?tEDHVSmuXo2JB zIJ)vG<2s-Nq6(vdp>YLI%QLS;gVf8NcojMqVUp1?Xy`%DtTg=SQW!2`FcrAMbnTJW z9bShQI2w-Yy`#F^IPgtWYR+)CpOK4CZqL2Ss_M|FM&1Ewyf30 zIzHm7D$oqn^MA{FJ~kPpL~zi&t;+Zt%4ji7e9_*~&&PNMq*aD{6kLmCodZC|Fp;@h zOc**eL>Zr!eG$Wjk;@p~o5?VkuF5ZEju?!fOT-u?wtR$-N+aJ9V-jtyn|Bnn6HjLS zJFG@`xH``0^h#p@CxuCP9V%#tro;MYL$uz99lHA6Ek)eMyoR@7w(q=zfmvCAA-WSejA%Y2OEEp>;&{p4jfmS1i%wNbDC_UUfMoJ}H+@&>-^-%a54Ysw> z#Ai`r-AJj!VUyP=i-NoH$yHS8R_K>FVhacA3Zn(11`VMm%U9{8u7(7)R8W)Fs-;X|*Ot!EoD*U+oKuctD&~QBJ>-jUo;a6 z+QnB}y4K^fW0Y4$li_Y8KK8fB0L|zve-Wp62cvLb#8Fz+4?ll+#zb&FH@poHK%^Ks zl3OwC(#?t?NHfaHq{;XagVjh@yb&SnvjTj0xfQU5??52njReB;t(b)HT#C7PlROLB zy3hC%zKFe^eo>!nf$$@}_zd&-f}$?I`nt{s^pfIZW?1zPhCfKOvR})xzZlOB|CEzR zA^O8d5YTy*av~f2al!{#rWMjHfs6H0PT=AL(&WHJh^ajk@4Y01|Ays_IK$t!0y*Iz zB`sMXy8@5e=E)h$mjf;UzK0(`0y#sbAM{|F@t+Z23=NkQ+XB*5-7`RP4UF;`j{>S~ z21dYg;Shsi=s;`^(ZfWu(;`#>%`0vEq2!$X1{yMf^@Dj!wa zVN60`P%9h7scNk#0*`EJ;aH7y&q1uINj=fzh|=k5em4M2l8X+0%Na4CXeQ|^)r5UA zsS@MSq~BBr7+Y_a)6tMN{gq#UQQ&Zuu?A;9s>2afTQTkzTZqYuktnwO7y+=UgN z@#1UkPn)xims$Ad?dB)r0D|!kEMvd%cl0heK`GKT!4r>8X~e<8Et5uil@pvcIPw;8 zTKml8wL$GODp$5E?_pR8V`gTIl&Cxul}C-2tW-1>FHNNKp;)dahc)wI&I?|J*%+z>Q;F94 zinv?uD&kh)w+p|c_?^Np1@XJ_!vqR@a&!g1Ekm2s<`G&GqBilxb~B9#Ge~!>u2x2Y z&M7A-p;CoGLnU#%Xkj56_Q)IBPu1csyzCK4KP~4issNl zcUD#f+qYkj%-P806kkoMDn+hrpCQMxEun0oJJEUGA=?!#Y88&xIEa+k2X-5@;!&+U z{*A;sO5NKJ4Xm=k6>P7SlMiy}+h&rxt0`IQ+D9o3Sd_j_jNjLCA6f6J<(Un9r8=L| zjDNWzL1>s}JTVNhQgHZSD@31`Nm*2WlG2_76YF9jx0q{uzu?3#o}$D<+9w^OiORb( zG(O1PiwJ%Y{F11H+LaV|X67tyzAy^N##6N+qZuk;U@_SdIVmx0qFhp8Dwr*;)S=Zn z_kUMx`4nxszeo(y{I=gFU9Hsd+YxN=lY`6s$dOR@6Ne44 z@^zLfCkZh%F0I12>uXH-%gL2S)_kyl^f|#+C2iD71?`T!QN7HjW@xLkRs^H!YJR)3 z%2#15g({17R6P!}K)D!|uGT`@>r~Nm@rvqv54M?{nBRws_#7!6uH{^X@gS;%e8Al1 z6-{)#&~W?BTBwnhO4~rnVl;DYGj!JGLhn7YODkK1=`P*g(N;FCHKVQQ zn$}Vq(;5%Xos7BD1uaq!)}!-P_`2EqNstoF+z1RPXPWZLHl!uUlayB;Kp=55PNc65 zCty_Q!BaS$R=*Q6-&b!yRg7ld%QA^A$AF^Xw5}6C;g9GkUDak=bYG*e=sS<{b8}j4 z#f4Ml4=fA~SNrOZA-k~xN;()vYYZ#JT%iXyVyRTmqc~qhG;=-h7ygK%be*1m1}i0D z;-zwZ#ulg&)z$8hbVtKnpYiw9`tDG*lwYLv6lO^ofrW0FZ=Gr~iau#bt?(JQTMdt; zsx%$87%2;szQuQ_MO1mBFt%CLjj%-OV%0m--vK^EB1B?m#$iyQp zFn)*}K(dbvOLBVsDCsLdCYfTUk})UC_zW3QWif6Psz-LTCN-*MjY94!xvrw%^up;I zfyA%fO!l1ZMSJV`KTf0-vMp}pkdyY3y)0B# zHqv`d`^d3biDVI@;XPgx+;HF#784i5$9{lbvX3%^6@;khtC6U*i@Ae~15hd+miAG8 zvmX4H>zRdY>wRSWGA2Qf2{Z{w)thHGj}fwmS5z8hKtki;4wYH$VDbTKq;aSgv%EEr zF|5}bkHK>XRm)VF#m)kRw8X~AT3Y(l)`aSd&_v^`VTQV3`#$2AY-1x+nSC!lIAu09 z2{P_mi?^CiwdqbQ!V|5^p#>>fcLZ2l>5f)+#}*gu?B)3!&7V{l7}ub=#I!ih{E){@ukhD@!4@sw3j)4 z$puIl6u~G^9(~hFXIWynQ+&AojPh7Hi=4`{t<<^}UaiPER<_InD02oLS;omJ%Dwy; zi&3^g3%tJqW8*iS>FdlZK1V2XO35>tTR-J^HFiIG~F|15ib7 z1?3p-osMWajS_bvQM8p;z9qQWaA89V5b9#8-abl=o4Aw#*Mu@EDp3jyGT$ZOriflP zML9Q!A<}VyU!h#cY06OEh@SjV@s37e6)~|(-j6A^VECj#MiS5HUK+Yuulx6Ejj&}Z zhKS~#{vMQMt^i zIhD^~dWlFbZO2Y(Gp%uFNu1uVYgW{QCA0jav*aN%(dlI+X>V%skUT|uq6P3#PXvk3 z;i8XAX&U9!M|hN~ zeMe9q5yTb}GDKK*bl_jKy)@?_w0vk@vM$L1TvsDi$fX9K|+ z0_jD7t*k1Dx;x~2y+rlVQF?1`uZj;!veCP{rTY|XYGM;vEH@3(`c9g|1dJjpgFdg> z+MIHCtEEoqrUv+3<;1j$s%WOfu#u+if(3QF5E}XLjG3aW7NW3oZs((kG_IjWVAZ5` zK~KOGR}L{phRTPWTCq@YI@pf>)V~bsX&u09AJtnUcy$*= z2Jr$5TO+WVsAYV2z(52=CK6h`Y|wpVYd1u$ewQP06nz-(5dec{q`uOjmXSx0vhl|y zoci*QY4Ej`E^F%<>u70*=xJTOOtzJvW zZYEDAO!{{TK&fK(zl+x%r9nmqklwI)*>x7;_x~4oqBX(a*wGQ?@6uP@8d0K5_1K`* z4C&by)fy)>1Z#fbZf-C_X za^EG$%OP6gy4D*|rlh1e=QA$rTC3xn*CBZz<-Wl78ixkXKMb{lasFXwAy8MGb~&QT z&MQj2Ebab^7)z|a6ATw(svkHUlXgs7Nn#u(ZDoRp6H*pl=I|TDVE}*+aVbZd$|JlU zkD_A1a65|4cv0o5NP4mU0pkza+t$2Nt1kFzJbbZ0R>Kd5ayWX0~c(;^-Bc+NYCzEr>2; zw5T;bYE!@X{k=%RLL;heaWc_c8P6yNb;`8Np*Ed@K~MjlB?x=9WkPco$r}~tnwtz2 zXF%mn!q8BpHl0zM&O_}fXs=%A8PH$p#DeqFe-wAT1u7Yb$$St}) z+7hHfb?c>EaEd$L1mtjsCa~!T|a_CPGP3|LN%hwU_?vc{8smdS5 z?613z$RAU54uK0XiAq{cHC@&aWNMA~=t8)q2NMAj#bsv4v?5$1bkyA?vP*B+U9Px2 zc9e8a@gOJ*oHSBAXHq<;nDRLub3VmmEZoeC!5*R>izeJ03Ryz^f8i7{_|JI5?yJDw z3C*TR8xeOTFvfIhH9d6MMQK0`K0#SM=iT7b_YiEx3E%*|dTA;>zG)ze`&_$_|5y%s zjJV?n7S5XIl-n+Ez|}zRWxQMkJvEAZJ3amAoo+T`i#zTESZqVNVa#065HW9S_{_Ye zVbr{-;evU6!$tGDh7t4HhCi9p8ivfP8$LBBHw>E@4Ii7S4WF1v4TEMv!$)h)SNF2@ zKQm!oUe%{ywM_BMXr(O9$%W;p!ViCnl<_2aTe zQbf!2-_jPn*z#L&pn=CEW<$?MZ>p$@{+6WA^N2r4xZQ*DwaQ`&adP55dMk@v>??a8 zz0FKDX)gt^X{*ks0Q#DmuRn%uE>8dcQ^2E^x^!&nu6C%~o!H|o_}~{GBNpfJFFA4l z!OB_3S9(-jcSl-F^CcQKjeo#msmgGiW>#TnL-vq+bjvk?$48MbsxKGRMA ziD>hT)@9xhv${aTp;cY;7||+y-lvC}sAipI_={zLLS|)II6uDxI;4OK?4wW&MGn5T z3^+Kz&pC5@*xymD1QTck9PK$Hyp@ooRDRJ~O#?gOZcTI-yEenQzOY9a3Q5I$u$=eL%NH2>K5{p zXd+czSxnCy_)a*DXCcI@nJQdP?4`D;(kf|HXYJo=+XemmS>UhMo!6xpS-7FHqu*ga z)V;Go9%kpjRvDQhjcCU8o z+q1Cjbz`40vZX*vc840L5;9i>cBLam!#KL@fvedQVeQi`xSK{dpRlkja5J){%;PdKE8 zg)H&mg!cOOd>!M~9|^P$0VJyXc-0qqi5doDb5eIPYaGTMr9+5%Bl4T-VrmHeF=D*C zXNyBw7?l!{Xnx}Exu$(qhq|236STsqV}mfqKBtt2rY7L3A=FpRFy|Tba3wc-_Z+Rv z*;*~=cTW}As8c7gQu9t?)hWJsa*i)cZ>BtCW{j^3Xi0>lWatbJ@m1PF{b>>m?oTkK zYu#jdn5pwqTBo=}Tas;)=9KehigF*%>BWL-gYXEy0bu(`;0{iLH<&)p>Hc)fvbL<2 z({et>&RSb-zzv_4Wu@kb`;#rJan?~zgbry!v2`r;JH+okjqIebhs;Fr#ZT=FgDh-* zMSnFWR`KUszSL>z1UmOdH(5m*ljnDUCk!-YuKx3YU2a zy25zcwb`%pliXcfQn8mU+l$O0cbB}h&EvwsFuVKM!+Gw(tvAGA2e;rNO|_sfNlq>b zEK1^}3+gf=^&8;*GC{THd0i+7%0DsC6NxvbGLS>tz!jFzu=}R#j2lT(f*^;O{g&7}H7B0mmCXJV#L{M-=q`|xpfh0W6Fovsfp&s%RBW!q&~W>BQ74l-lnI-h zsU31JkBB?i!o@Ry+h?IKSi-#=yPpf}AG_ad$_Ol)!pZlGFG^E|rRIQ!J74>u%mJ|R zhoou=GX7=5C@0+&^%%ckVxnEJ_t`HrHyI?SQ7duB4WzP6ZvKqqFt{Pz5H=wIv0R5L zF}Bv6-Ehgg0R7@m&?!EKj`0EXi!k(zKSHUYO$4PsMQI;l+@0XOieTV78Hw_wI_*d6 zQ9$4~34!;wdZ9syg*YwTSHdCwl&}2IIQ#kLoVky?W;CD|C5LSCH;n;ht&J z>Bg&L=Z;-C*3s6HEB;P=wY~Wq57M=_?AV-lMrZvO6w`OuDyQ#{vEmW&PpsfS9=mkx zS8cyS!EOB$s5o~1*!k4XFVbRkfb)Ha&-R9lpCe=rpY1){+xKCJy^PT5SN;cTbNZj? zIUKwn&mu{%s+t_K-nKJ|cY__FzQbPzoDu^zlVi|tcYG<*od0-sBF*yh4ZOm5{%9O` z>fuo8VJV@nKjxO)*WMR7a}JKf{e6Rd#@iizm(KQuXse|89oocEjyzhY-kqD&_dsq^ z2q$U;PD(mRjwhiriJUFwL>$tV^0Q&hd2}&7B>UL}ictnq(=m`9RZDV{@TsMW&-SEs zoJ+$uuR3y1&&^djQ|XWnhg8~P7bf7qZVw_tF;8fF-`w1LLUkISTeldF(bv`~{W(%5 zJe^s2{A~^$(j@fxK}f*rt6Dw(qfC=4daM!B7E}9IN~gZSov(alx+MJ z!*0}EF63HK!3muU)Zt2C0}r%8oxC zV4aS$p3%DICIO7H_kBw^3=I)2iH8mU_2gRGl(qJ}vd$*1MX^A5HqpldgJ(U1XXMc{ z-qADP8a!KLob?!Irk5cJb=sN;;{xrw0$(Gdti5j9&8xo`pHMs-o7oyX5t_lVQ21$# z1Ln{VR|}ufIRli9ZmO2%mMV*nEhqDUhy-$tn2V(9YLh-KpS?D|Sm`GxhEr|nrvQo* zCmE$}8Ldfe9c>wQI}2mvmDbC8P%~Y=Q^X z1rK>peW3M}1q$<}&kCKgt*mWQ5e~PtI^|*J-f@;YGacLGRMpM#oqe*K(m%(6s^gTd z(cylZtqS6g8yzPAf9|ec8 zraCSDT}L_oWl7=9;*%YAI#fySa^ONCl%4YOvmD)6R7dz=w;QY^d)YFZ501)rAVYh> zVTQnd%zmWYI1GZ|*M=03CG%a}%|*e}+g)HrmA=i^Dp)+!x;L~61&8Z*qK1X(L=+X= zV}HHec%~cE0*;lVNaOJc>g8sFeH6?orr52B-9sIy8t0w1^2@7(!%a8F$d&k!x6P!Hx7}|y zVqX-V{wn}n(U4zdyn2*YldcWguV?{?7G^eOYO-W%vY&yJeN->_I<6p7YdTezHMFn7 zYHID{N+T0stTO-=K`vxq;_i;t^mfWzL^httKFZrT(;aG>j-H&_mQ)H|@Ip@M7{TuRy*7VKNRW7j0t8FgT#4ccRuRbbGHuWnr+G4t81Qo^;Lw4rlUs+K*S_R9yuv_13di}eXn-=(PB#g9*jB14inX)$!gb~)85u?Pw1U3N=Y)0AiTjm@tLolqjfPnAwV&RUV|LM72d-DXg?Rppx?oo${Y_ z$BJ6rp;Ih8B@iWHofKlOFFcNu!bX&6yg}kVAh_)r&9+D<6S}fU?R~jojv9N}H z-DVm({|XO^ea44}p?wZkyFXRu(*Xo5z*CHazX6=Km@pL1kQVx@3@37GMztrfWU+Le z-}nVG!9_?-V&E!)S49^XpB+K~#0G9bQRmOap_R`r2b-sjnZ46#X2{_aWDNim(6&UtjV1q{}?OyP$ zK4U7Y6wa%-KLv$?@!lJtAP$eUh|Yh{S6O9DVY$fJxJ+e7E;iKeTZl6SBR`q=RvMpe~BlNfw8No7mEinzcCzHj&^krGCufdk{a7cwFKU zP3ZQpn;r^I2MX8Ad=d55pQT&Xl=adIk=vIL|^x6>>w-2%X=6RMbG z@yFtgIDvt7a4l*p3a^Ed!fFYIMQ!0J^cj`x$_;3C7vv~;oR*jGJ-WV_tAPL4lNegq z@jYEIj9uT5Tmbv$p!-t^(t#kT@0mA7Gj{??8+Bh4Ti!>Em6m`|7-Jnu5G>6kG|-0} zR(`SN5WedcUaNIU8AU~P3$x@4*6WkJE^YA+pgTTVQBhP;;j65ufc88u`a8{Vo6>E5 z<9m>uG-OJ0ozkp|3cn8$JQq;W-$8%MAgOO;Vt%hy*Tb@gA9g%iiM)_mL4IGW+!sk? z#3_~*70%GQrPQLrEcqfmhV#0MG{bMqKrw7MXtOhmf z=-}r-3E7qFi6h4OU$Lxks}~xsF{~E( z4=$WfWi+jMjR!J|p1VO0d8-vFR{3hO-bzJ4?qvn;Me#zkt0*y56Upq^!3sZ*A!%W1 z{H2+sF`NbHH`_}!{1cm~w4lw4O&6PV%W#Jvr-8~npc0z#wOY6Ko6kG0YH2F`Q@PeM zez`{p@$Rw4mkLf>m0i>u)#vrf-r(u3QodPEY#3f^rfMPP)Tgxn35a(CF)Vy=z?=fc z$BJ<YQD%6=_G3^f`ZB88Nlw2z44hSBRrZ}2qa{`Rys>Um9H|#VY)vc z)n~j9d5js5gl+Q}2hKJAv6hyJmY(CM>kR5&R*LAjqw(Al{KFp%5xVw-PIZnH(}5uC zP$}+D!r~1xkP{dA*b$4X1F8_^^fiptcLKr2DBM9gE_OT)DLL9&L3_}FGcwXGxO*U1 zx>29ERdf7Ig}qlTb102CMIukGx1pi5lAj4i5pqZG{+VEgHa?z6sL&Nb43;MwH7q(| zT7HD5g7E)*u+zWBv9Mf_t&3?w73IIo!mMbf#saVc(thnSUi}M4^}0hm{-&U2Ed z(y#x8GkW*qd`&Gdq_s;0+ZF+;!uSbOn|P#FRv2%y4*}U4Y#Ppo8)T)>_{Y^{4&)V( z0ZH1t$IZQDdF9OPgWv-;O$d1dj-dY7%3s5xYyvbb?3q?bIi9ygD2Miw4>k3pW{pa8oHBTBI(z}UL6d4P5earp~e)NceI z-A;+j#>I>2xK-oFmDk<9HF8Lo=OKgeU9X_zlTgj8EmRX+U{%3^f=5;`PK3oP0?$4c=TKSLCzbB0ne z+zod7X#E4gP-XlioBE4WXE%V?`xw?;z-mQQ!P|KJqka`jeGC!N7w4i*77R`eAg11# zV~a)9=Q6miYY6k)4JMrx*I9-JER7c!*Mpd91RAg`8m9BIGn~#!3m3%0%PUU z7%R0y9sPE9D{)dz)&f*I`Zrswx|!_SY^Tp2rGG}pg+$Gv(@<_J!Cf@Ce1RggBDk~TDCXaQA0xfhwb!%*KV9=ddU?U=Dl7zn{hU2; zAwm9n-A@FYbZg9QKN#J9eU*>$?!xfK*mHN|pR$%Z_6MYl+)MCKGLy;0UU@x=40KdL zP1>M^Fh22L)vTU`L4{fLG!y}L4r04^Zwus&#veeZE7Zyy!ySs04?*v=$)eA=1?-2U zt(K-QGpA83Cto$(ksxLGjH_Zvazff@shc5d{29xrg`m%MlT^SsCiSXaPN)fCqW?c_erx@>%mM+-pIHY zBG+*|eEjtB_mB6c!E!P3DGonv%*_HsNv><;UHkFP8E(KmENo7819q!zb-@YTgR<_B zbNoLKR}g5dIEIiF2l0!-4&m&nj}_-cakzdWSNL3UJt)rg1Rl;n)B72Se%R1o3&S!N&TlR9SfV%F7nmiSmcnjytGN1OMHLj#qq4InjU`ZtwJ`=8OU?<*l;|H;?sWiR;C7e3- zR8zyWL_5CIUSXOEH9gJ?nFH{R`%`6AgS{YH8|!Q(6FS@1hKn4Elq;xm2(0;|m& zEjh3;pTDG+4s{ldzxf6#R)uut_2}^PNb0kMYLKXgp42?LPv$5N|aQr49wsfEx zu=h|F?1MH5;`iP|j2;}gh*tDQ^1Rq8a&DP}AT~wXQUVuJ6qVFQe zyd##oOXE?J+AIc(u_4G$>#NGA*`xFFEx`$nEQ33Z4cn>RbW?vM&w~p^otxX>+(U6< zPy-1In*?b?L*m+n9{Ap0=FmRkSU3Oxi^Zx(FuQf{P!$fI!J6WTUM>WvhfpI-_2xfZ z2Hs5yPzEN-YICt>9|q%!B&Y{iv`rIRevSFaDhpzjQx{WV=GA$g!9UwpheOt3ceaCX z{0uWoHO&gac6dKZ>B*{wY%T<3EGe;h5x@ z`DVaTL5@6hPF-l5p+9U>aTa#m4EtiJ0Y^Lj9-WcQu$B!Lho;-e3`=*dB(_~!Y90$* zycxOVB*p7WFcSk8^W-GNBMPQyXy7}@%0`Qu7KH_J#mB#cKm*dM<=nuaV0Vmy+1KEdxK`mf@WQ97Craz^owH9X|? zk)RgF{fVx$1O5?qK&%V$z*J6#=;Z9# z>^i!W^s>o9^Se}QxwCe|I?`j7MhbhS1-Pf~qrx-N4YU-3CxV5reX+Z;!U!mw>` zL))S7NsM-Vc@!TZt(%^h8mlTR;GO%2>$N_NH!!6AlYd5oy{?Vnpv$NKv#m5*aQOD+ z(T917U$J83xYn_bF5V*A>92e-jdUHg*z9T!Q}||j1Z^yS%RpX_))};E=WrIai1&s5 zkMBck{Xx;LY3Xax1;_o2n| zKMH^c@Y{&rdi?IjZxwze_$|T@_h_BRJzD?C`_LFCqEz8M_&tYTJK>JsyY>IseP}sP zq7>^sv|~SH{Q9!{&~8K$+JS&~79zYBzW{#md(6IY9~wb|_wn?9<32Qoa{}DIe;-;5 z_bHTr2EX(84d6F~Uj#oMMNgqx{g>Q_Muln7d^`*BE5mO+#l+j?KXV@%2B|WzmK_Pe zm=u2wpS-Fv%t2CKnUq^5O)rzKE@StnB$vtGZg84ccPC-u;mrThFd3efli+E|!_!h& z2am3D+!$2^RR9_h78u1KPZ@PePG$6JEapb1Lw0ZKAHzSd@%Ep^fsAv1I9qc}Ic� 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 literal 0 HcmV?d00001 diff --git a/src/bin/cr.exe b/src/bin/cr.exe index 062bc4094a0c115ad192add36dd253124245d6c4..dccde719026f62b465a43be3ebdb542b70258e6c 100644 GIT binary patch delta 16367 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