From a385171c9ff4e4527e70ec6b9cea72c04e2b6865 Mon Sep 17 00:00:00 2001 From: "drohne235@googlemail.com" Date: Sat, 23 Apr 2011 21:02:22 +0000 Subject: [PATCH] =?UTF-8?q?-=20Integration=20von=20PropForth=20in=20TriOS?= =?UTF-8?q?=20-=20Systemstart:=20Code=20f=C3=BCr=20alle=20drei=20Chips=20k?= =?UTF-8?q?ommen=20jetzt=20aus=20den=20EEPROMS=20-=20Bellatrix:=20PASM-Loa?= =?UTF-8?q?der=20-=20Bellatrix:=20Multiscreen-Version=20(3=20unabh=C3=A4ng?= =?UTF-8?q?ige=20Screens)=20-=20Bellatrix:=20Egalisierte=20Steuerzeichen?= =?UTF-8?q?=20f=C3=BCr=20bessere=20Nebenl=C3=A4ufigkeit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/flash/belflash.binary | Bin 320 -> 6432 bytes bin/flash/regflash.binary | Bin 696 -> 32588 bytes bin/sd-card-basic/SYSTEM/adm.lib | 90 ++++ bin/sd-card-basic/SYSTEM/admtest.bin | Bin 7944 -> 7944 bytes bin/sd-card-basic/SYSTEM/ari.lib | 55 ++ bin/sd-card-basic/SYSTEM/basic.bin | Bin 8452 -> 8456 bytes bin/sd-card-basic/SYSTEM/basics.mod | 485 ++++++++++++++++++ bin/sd-card-basic/SYSTEM/bel.lib | 77 +++ bin/sd-card-basic/SYSTEM/beltest.bin | Bin 4288 -> 4288 bytes bin/sd-card-basic/SYSTEM/charmap.bin | Bin 1924 -> 1924 bytes bin/sd-card-basic/SYSTEM/cog.lib | 74 +++ bin/sd-card-basic/SYSTEM/debug.mod | 65 +++ bin/sd-card-basic/SYSTEM/eram.bin | Bin 8512 -> 8512 bytes bin/sd-card-basic/SYSTEM/error.txt | 40 ++ bin/sd-card-basic/SYSTEM/flash.bin | Bin 7164 -> 7164 bytes bin/sd-card-basic/SYSTEM/fterm.bin | Bin 2264 -> 2264 bytes bin/sd-card-basic/SYSTEM/hplay.bin | Bin 3944 -> 3948 bytes bin/sd-card-basic/SYSTEM/hplay.mod | 155 ++++++ bin/sd-card-basic/SYSTEM/hss.lib | 60 +++ bin/sd-card-basic/SYSTEM/key.lib | 17 + bin/sd-card-basic/SYSTEM/keycode.bin | Bin 1896 -> 1896 bytes bin/sd-card-basic/SYSTEM/perplex.bin | Bin 4792 -> 4792 bytes bin/sd-card-basic/SYSTEM/ramtest.bin | Bin 3992 -> 3992 bytes bin/sd-card-basic/SYSTEM/rom.bin | Bin 3976 -> 3976 bytes bin/sd-card-basic/SYSTEM/rom.mod | 206 ++++++++ bin/sd-card-basic/SYSTEM/scr.lib | 69 +++ bin/sd-card-basic/SYSTEM/sd0.lib | 176 +++++++ bin/sd-card-basic/SYSTEM/sfx.lib | 93 ++++ bin/sd-card-basic/SYSTEM/sfxtool.bin | Bin 6052 -> 6052 bytes bin/sd-card-basic/SYSTEM/splay.bin | Bin 2960 -> 2960 bytes bin/sd-card-basic/SYSTEM/splay.mod | 116 +++++ bin/sd-card-basic/SYSTEM/sysconf.bin | Bin 4416 -> 4416 bytes bin/sd-card-basic/SYSTEM/time.bin | Bin 5412 -> 5412 bytes bin/sd-card-basic/SYSTEM/tools.mod | 152 ++++++ bin/sd-card-basic/SYSTEM/v1.mod | 325 ++++++++++++ bin/sd-card-basic/SYSTEM/vga.bel | Bin 5704 -> 6432 bytes bin/sd-card-basic/SYSTEM/wav.lib | 54 ++ bin/sd-card-basic/SYSTEM/words.mod | 16 + bin/sd-card-basic/SYSTEM/wplay.bin | Bin 3260 -> 3260 bytes bin/sd-card-basic/SYSTEM/wplay.mod | 93 ++++ bin/sd-card-basic/SYSTEM/yplay.bin | Bin 3212 -> 3212 bytes bin/sd-card-basic/bel.sys | Bin 5704 -> 6432 bytes bin/sd-card-basic/reg.sys | Bin 9128 -> 9172 bytes bstl.exe | Bin 186880 -> 0 bytes doku/Thumbs.db | Bin 18944 -> 36352 bytes doku/TriOS.rtf | 51 -- flash/administra/admflash.spin | Bin 152770 -> 152764 bytes flash/bellatrix/PASD_AsmDebugDemo.spin | 89 ++++ flash/bellatrix/PasDebug.spin | 355 +++++++++++++ flash/bellatrix/belflash.spin | Bin 20458 -> 91282 bytes flash/bellatrix/logo-hive-8x2.dat | Bin 0 -> 1024 bytes flash/bellatrix/logo-hive-8x2/dat.rtf | 275 ++++++++++ .../bellatrix/logo-hive-8x2/logo-hive-8x2.dat | Bin 0 -> 1024 bytes flash/bellatrix/vga-keyb.spin | Bin 0 -> 94800 bytes flash/bellatrix/vga-vid.spin | Bin 0 -> 55312 bytes flash/regnatix/regflash.spin | Bin 33426 -> 583394 bytes forth/adm.lib | 90 ++++ forth/ari.lib | 55 ++ forth/basics.mod | 485 ++++++++++++++++++ forth/bel.lib | 77 +++ forth/cog.lib | 74 +++ forth/debug.mod | 65 +++ forth/error.txt | 40 ++ forth/hplay.mod | 155 ++++++ forth/hss.lib | 60 +++ forth/key.lib | 17 + forth/rom.mod | 206 ++++++++ forth/scr.lib | 69 +++ forth/sd0.lib | 176 +++++++ forth/sfx.lib | 93 ++++ forth/splay.mod | 116 +++++ forth/tools.mod | 152 ++++++ forth/v1.mod | 325 ++++++++++++ forth/wav.lib | 54 ++ forth/words.mod | 16 + forth/work/bload.f | 23 + forth/wplay.mod | 93 ++++ installation.rtf | 223 ++++++++ license.spin | Bin 8346 -> 0 bytes readme.txt => lizenz.txt | 0 logbuch.rtf | 13 +- make.bat | 16 +- system/regnatix/ios.spin | Bin 208308 -> 210122 bytes system/regnatix/regime.spin | Bin 80182 -> 80292 bytes system/regnatix/regime.txt | 9 +- 85 files changed, 5830 insertions(+), 60 deletions(-) create mode 100644 bin/sd-card-basic/SYSTEM/adm.lib create mode 100644 bin/sd-card-basic/SYSTEM/ari.lib create mode 100644 bin/sd-card-basic/SYSTEM/basics.mod create mode 100644 bin/sd-card-basic/SYSTEM/bel.lib create mode 100644 bin/sd-card-basic/SYSTEM/cog.lib create mode 100644 bin/sd-card-basic/SYSTEM/debug.mod create mode 100644 bin/sd-card-basic/SYSTEM/error.txt create mode 100644 bin/sd-card-basic/SYSTEM/hplay.mod create mode 100644 bin/sd-card-basic/SYSTEM/hss.lib create mode 100644 bin/sd-card-basic/SYSTEM/key.lib create mode 100644 bin/sd-card-basic/SYSTEM/rom.mod create mode 100644 bin/sd-card-basic/SYSTEM/scr.lib create mode 100644 bin/sd-card-basic/SYSTEM/sd0.lib create mode 100644 bin/sd-card-basic/SYSTEM/sfx.lib create mode 100644 bin/sd-card-basic/SYSTEM/splay.mod create mode 100644 bin/sd-card-basic/SYSTEM/tools.mod create mode 100644 bin/sd-card-basic/SYSTEM/v1.mod create mode 100644 bin/sd-card-basic/SYSTEM/wav.lib create mode 100644 bin/sd-card-basic/SYSTEM/words.mod create mode 100644 bin/sd-card-basic/SYSTEM/wplay.mod delete mode 100644 bstl.exe delete mode 100644 doku/TriOS.rtf create mode 100644 flash/bellatrix/PASD_AsmDebugDemo.spin create mode 100644 flash/bellatrix/PasDebug.spin create mode 100644 flash/bellatrix/logo-hive-8x2.dat create mode 100644 flash/bellatrix/logo-hive-8x2/dat.rtf create mode 100644 flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat create mode 100644 flash/bellatrix/vga-keyb.spin create mode 100644 flash/bellatrix/vga-vid.spin create mode 100644 forth/adm.lib create mode 100644 forth/ari.lib create mode 100644 forth/basics.mod create mode 100644 forth/bel.lib create mode 100644 forth/cog.lib create mode 100644 forth/debug.mod create mode 100644 forth/error.txt create mode 100644 forth/hplay.mod create mode 100644 forth/hss.lib create mode 100644 forth/key.lib create mode 100644 forth/rom.mod create mode 100644 forth/scr.lib create mode 100644 forth/sd0.lib create mode 100644 forth/sfx.lib create mode 100644 forth/splay.mod create mode 100644 forth/tools.mod create mode 100644 forth/v1.mod create mode 100644 forth/wav.lib create mode 100644 forth/words.mod create mode 100644 forth/work/bload.f create mode 100644 forth/wplay.mod create mode 100644 installation.rtf delete mode 100644 license.spin rename readme.txt => lizenz.txt (100%) diff --git a/bin/flash/belflash.binary b/bin/flash/belflash.binary index f26984f4b952bcb2fa131b5e2a855757606d224c..e5348913866ba14c0cf602caec2bd69fe60d9186 100644 GIT binary patch literal 6432 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 brtZkEnEr;6**%TF;#aD8@-E^d_|@{ii45wE delta 265 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 151 _cnip ; + +\ u*/mod ( u1 u2 u3 -- u4 u5 ) u5 = (u1*u2)/u3, u4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: u*/mod +: u*/mod rot2 um* rot um/mod ; + +\ u*/ ( u1 u2 u3 -- u4 ) u4 = (u1*u2)/u3 Uses a 64bit +\ intermediate result. +ifnot: u*/ +: u*/ rot2 um* rot um/mod nip ; + +\ sign ( n1 n2 -- n3 ) n3 is the xor of the sign bits of +\ n1 and n2 +ifnot: sign +: sign xor 80000000 and ; + +\ */mod ( n1 n2 n3 -- n4 n5 ) n5 = (n1*n2)/n3, n4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: */mod +: */mod 2dup sign >r abs rot dup r> sign >r abs rot abs + um* rot um/mod r> if negate swap negate swap then ; + +\ */ ( n1 n2 n3 -- n4 ) n4 = (n1*n2)/n3. Uses a 64bit +\ intermediate result. +ifnot: */ +: */ */mod nip ; + +\ /mod ( n1 n2 -- n3 n4 ) \ signed divide & mod n4 = n1/n2, +\ n3 is the remainder +ifnot: /mod +: /mod 2dup sign >r abs swap abs swap u/mod r> if negate swap + negate swap then ; + +\ * ( n1 n2 -- n1*n2) n1 multiplied by n2 +ifnot: * +: * um* drop ; + +\ / ( n1 n2 -- n1/n2) n1 divided by n2 +ifnot: / +: / /mod nip ; + +\ rnd ( -- n1 ) n1 is a random number from 00 - FF +ifnot: rnd +: rnd cnt COG@ 8 rshift cnt COG@ xor FF and ; + + diff --git a/bin/sd-card-basic/SYSTEM/basic.bin b/bin/sd-card-basic/SYSTEM/basic.bin index 0b8fe7c9ea914b1d642dc4383e7f6b28f3125a25..e9f5b2d95ab72e55eabe671348589a8d0e38acaf 100644 GIT binary patch delta 287 zcmW;HF;Bu!6b0aW+jr=z3l1bA1++0S4rl_VrmL)s>JK2PiH4{N3=S$Rnn>d2!mluq zGN_9VEUYXp&d$!p!9$1dG+Q*{mqa#xgXD5c1oGqN1p#!^)M*tK=Wfm@n)A delta 282 zcmW;EKQBXJ6bA5f`o7QY%TnS>aa|NKwZfI#+)+AO>kBlwgFk5`?O>p>bZD#wpQF7J zVPL6*NenDzvz^7`4!v2c>)TRdt zi|mS4I<0nk*gf9f?6k7(!l;nOsA>X6N(ZP$T1OCRV)Aqd1hpN`em>9UIgQ}|JW{M` fGJ_zEe-%26=s diff --git a/bin/sd-card-basic/SYSTEM/basics.mod b/bin/sd-card-basic/SYSTEM/basics.mod new file mode 100644 index 0000000..aa7be0a --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/basics.mod @@ -0,0 +1,485 @@ +fl + +hex + +: mod:basics ; + +\ Copyright (c) 2010 Sal Sanci +\ Anpassung für Hive-System 2011 dr235 + +\ ------------------------------------------------------ BASICS + +\ this words needs to align with the assembler code +: _stptr 5 _cv ; +: _sttop 2e _cv ; + +\ _words ( cstr -- ) +: _words lastnfa + begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= + until 2drop cr ; + +\ words name ( -- ) prints the words in the forth dictionary +: words parsenw _words ; + +\ .long ( n -- ) emit 8 hex digits +: .long dup 10 rshift .word .word ; + +\ st? ( -- ) prints out the stack +: st? ." ST: " _stptr COG@ 2+ dup _sttop < + if _sttop swap - 0 + do _sttop 2- i - COG@ .long space loop + else drop + then cr ; + +\ variable ( -- ) skip blanks parse the next word and create +\ a variable, allocate a long, 4 bytes +: variable + lockdict create $C_a_dovarl w, 0 l, forthentry freedict ; + +\ constant ( x -- ) skip blanks parse the next word and create +\ a constant, allocate a long, 4 bytes +: constant + lockdict create $C_a_doconl w, l, forthentry freedict ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +: waitpeq _execasm2>0 1E0 _cnip ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ (forget) ( cstr -- ) wind the dictionary back to the word +\ which follows - caution +: (forget) dup +if + find if + pfa>nfa nfa>lfa dup here W! W@ wlastnfa W! + else .cstr 3f emit cr then +else drop then ; + +\ forget ( -- ) wind the dictionary back to the word which +\ follows - caution +: forget parsenw (forget) ; + +\ free ( -- ) display free main bytes and current cog longs +: free dictend W@ here W@ - . ." bytes free - " par + coghere W@ - . ." cog longs free" cr ; + +\ ifnot: name ( -- ) - bedingte compilierung; wenn name schon +\ im wörterbuch vorhanden, wird bis zum nächsten semikolon +\ der eingabestrom ignoriert +: ifnot: parsenw nip find if begin key 3B = until + key drop then ; +\ bei konstrukte, die keine doppelpunkdefinition sind, muss der +\ block mit diesem Wort abgeschlossen werden +: :; ; + +\ --------------------------------------------------------- BUS + +\ bin ( -- ) - umschaltung auf duales zahlensystem +\ : bin 2 base W! ; +\ +---------------------------- /hs +\ |+--------------------------- /wr +\ ||+-------------------------- busclk +\ |||+------------------------- hbeat +\ ||||+------------------------ al +\ |||||+----------------------- /bel +\ ||||||+---------------------- /adm +\ |||||||+--------------------- /ram2 +\ ||||||||+-------------------- /ram1 +\ ||||||||| +--------- a0..10 +\ ||||||||| | +\ ||||||||| | +- d0..7 +\ |||||||||+---------++------+ +\ 00000000000000000000000000000000 +\ bin 00000111111111111111111100000000 constant dinp hex +\ bin 00000111111111111111111111111111 constant dout hex +\ bin 00000010000000000000000000000000 constant boff hex +\ bin 00000100011110000000000000000000 constant _s1 hex +\ bin 00000000001110000000000000000000 constant _b1 hex +\ bin 00000010001110000000000000000000 constant _b2 hex +\ bin 00000110001110000000000000000000 constant _b3 hex +\ bin 00000000010110000000000000000000 constant _a1 hex +\ bin 00000010010110000000000000000000 constant _a2 hex +\ bin 00000110010110000000000000000000 constant _a3 hex +\ bin 00001000000000000000000000000000 constant ?hs hex + +8000000 constant ?hs + +: [inp] \ ( -- ) bus eingabe + 7FFFF00 dira COG! ; \ dinp + +: [out] \ ( -- ) bus ausgabe + 7FFFFFF dira COG! ; \ dout + +: [off] \ ( -- ) bus aus + 2000000 dira COG! 0 outa COG! ; \ boff + +: [end] \ ( -- ) buskommunikation beendet + 4780000 outa COG! [inp] ; \ _s1 + +: [hs=1] \ ( -- ) wartet auf hs = 1 + ?hs dup waitpeq ; + +: [hs=0] \ ( -- ) warten auf hs = 0 + 0 ?hs waitpeq ; + +: [s!] \ ( c ctrl -- ) sende 8 bit an einen slave + [out] [hs=1] swap ff and or outa COG! [hs=0] [end] ; + +: [s@] \ ( ctrl -- c ) empfängt 8 bit von einem slave + [inp] [hs=1] outa COG! [hs=0] ina COG@ ff and [end] ; + +: [b!] \ ( c -- ) sende 8 bit an bellatrix + 2380000 [s!] ; \ _b2 + +: [a!] \ ( c -- ) sende 8 bit an administra + 2580000 [s!] ; \ _a2 + +: [b@] \ ( -- c ) empfängt 8 bit von bellatrix + 6380000 [s@] ; \ _b3 + +: [a@] \ ( -- c ) empfängt 8 bit von administra + 6580000 [s@] ; \ _a3 + +: <8 \ ( -- ) + 8 lshift ; + +\ [b.l!] ( 32b -- ) - long an bellatrix senden +: [b.l!] + dup 18 rshift [b!] + dup 10 rshift [b!] + dup 8 rshift [b!] + [b!] ; + +\ [b.l@] ( -- 32b ) - long von bellatrix einlesen +: [b.l@] + [b@] <8 + [b@] or <8 + [b@] or <8 + [b@] or ; + +\ [a.s@] ( -- ) - einen cstring von administra empfangen +\ und im pad speichern +: [a.s@] + [a@] pad 2dup C! 1+ swap + 0 do dup [a@] swap C! 1+ loop drop ; + +\ [a.s!] ( cstr -- ) - einen cstring an administra senden +: [a.s!] + dup C@ dup [a!] \ ( -- cstr len ) len senden + 0 do \ ( cstr len -- cstr ) + 1+ dup C@ [a!] \ ( cstr -- cstr+1 ) zeichen senden + loop drop ; \ ( cstr -- ) + +\ [a.w@] ( -- 16b ) - 16bit-wert von administra einlesen +: [a.w@] + [a@] <8 [a@] or ; + +\ [a.l!] ( 32b -- ) - long an administra senden +: [a.l!] + dup 18 rshift [a!] + dup 10 rshift [a!] + dup 8 rshift [a!] + [a!] ; + +\ [a.l@] ( -- 32b ) - long von administra einlesen +: [a.l@] + [a@] <8 + [a@] or <8 + [a@] or <8 + [a@] or ; + +wvariable b[lock] \ nummer der semaphore für den + \ zugriff auf die bus-hardware + +\ b[ ( -- ) bus belegen; wartet bis semaphore freigegeben ist +: b[ begin b[lock] W@ lockset -1 <> until [inp] ; + +\ ]b ( -- ) bus freigeben +\ ! busclk bleibt auf ausgabe, da dieses signal sonst +\ kein definierten pegel besitzt ! +: ]b [off] b[lock] W@ lockclr drop ; + +\ administra-kommandoformate + +: b[a! b[ [a!] ; +: b[a!a! b[ [a!] [a!] ; +: adm:fkt! b[a! ]b ; \ ( fkt -- ) +: adm:fkt!b@ b[a! [a@] ]b ; \ ( fkt -- b ) +: adm:fkt!b! b[a!a! ]b ; \ ( b fkt -- ) +: adm:fkt!b!b@ b[a!a! [a@] ]b ; \ ( b fkt -- b ) +: adm:fkt!s@ b[a! [a.s@] ]b ; \ ( fkt -- ) +: adm:fkt!s!b@ b[a! [a.s!] [a@] ]b ; \ ( s fkt -- b ) +: adm:fkt!b!l@ b[a!a! [a.l@] ]b ; \ ( b fkt -- l ) + +\ ----------------------------------------------------- SD0.LIB + +\ marker-funktionen + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm:dmset ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; + +\ dateisystem-funktionen + +\ adm:volname ( -- ) - name des volumes im pad ablegen +: adm:volname 0C adm:fkt!s@ ; + +\ adm:mount ( -- err ) - medium mounten +: adm:mount 01 adm:fkt!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +: adm:unmount 18 adm:fkt!b@ ; + +\ adm:checkmounted ( -- t/f ) +: adm:checkmounted 0D adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +: adm:diropen 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +: adm:nextfile b[ 3 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +: adm:fattrib 0B adm:fkt!b!l@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis öffnen +: adm:chdir 16 adm:fkt!s!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus der geöffneten datei lesen +: adm:getc 06 adm:fkt!b@ ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +: adm:eof 1E adm:fkt!b@ ; + +\ adm:open ( cstr modus -- err ) - datei öffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +: adm:open b[ 4 [a!] [a!] [a.s!] [a@] ]b ; + +\ adm:close ( -- ) - datei schließen +: adm:close 05 adm:fkt!b@ ; + +\ ----------------------------------------------------- SCR.LIB + +\ [dscr] ( scrnr -- ) display-screen setzen +: [dscr] 0 [b!] 59 [b!] [b!] ; + +\ [wscr] ( scrnr -- ) schreib-screen setzen +: [wscr] 0 [b!] 58 [b!] [b!] ; + +\ [key?] ( -- c ) - ungekapselte tastaturstatusabfrage +: [key?] 0 [b!] 1 [b!] [b@] ; + +\ [key] ( -- c ) - ungekapselte tastaturabfrage +: [key] 0 [b!] 2 [b!] [b@] ; + +\ [emit] ( c -- ) - ungekapselte zeichenausgabe +: [emit] emit? if emit then ; + +\ ----------------------------------------------------- TOOLS + +\ cls ( -- ) - screen löschen +: cls 01 emit ; + +\ .tab ( -- ) - tabulator +: .tab 09 emit ; + +\ .err ( err -- ) - fehlermeldung ausgeben +\ 0 no error +\ 1 fsys unmounted +\ 2 fsys corrupted +\ 3 fsys unsupported +\ 4 not found +\ 5 file not found +\ 6 dir not found +\ 7 file read only +\ 8 end of file +\ 9 end of directory +\ 10 end of root +\ 11 dir is full +\ 12 dir is not empty +\ 13 checksum error +\ 14 reboot error +\ 15 bpb corrupt +\ 16 fsi corrupt +\ 17 dir already exist +\ 18 file already exist +\ 19 out of disk free space +\ 20 disk io error +\ 21 command not found +\ 22 timeout +\ 23 parameter error +: .err dup if ERR then drop ; + +\ .pad ( -- ) - ausgabe eines strings im pad +: .pad pad .cstr ; + +\ .vname ( -- ) - ausgabe des namens der eingelegten sd-card +: .vname adm:volname .pad ; + +\ mount ( -- ) - sd-card mounten +: mount adm:mount .err ." Medium : " .vname cr ; + +\ unmount ( -- ) - sd-card unmounten +: unmount adm:unmount .err ; + +\ mount? ( -- ) - test ob medium mounted ist +\ wird als exception gewertet +: mount? adm:checkmounted 0= if 1 .err then ; + +\ padbl ( -- ) fills this cogs pad with blanks +: padbl pad padsize bl fill ; + +\ .entry ( -- st ) - einen verzeichniseintrag ausgeben +: .entry + adm:nextfile 13 adm:fattrib if 0F emit else space then + dup if .pad .tab then ; + +\ .len ( st -- st ) - dateilänge ausgeben +: .len dup if 0 adm:fattrib . then ; + +\ lscnt ( cnt1 st -- cnt2 st ) - spaltenformatierung für ls +\ cnt - spaltenzähler, st - flag verzeichnisende +: lscnt + swap 1+ dup 4 = if cr drop 0 else .tab then swap ; + +\ lsl ( -- ) - verzeichnis anzeigen, long-format +: lsl mount? + adm:diropen begin .entry .len cr 0= until padbl ; + +\ ls ( -- ) - verzeichnis in spalten anzeigen +: ls mount? + adm:diropen 0 begin .entry lscnt 0= until drop padbl cr ; + +\ cd name ( -- ) - verzeichnis wechseln +: cd mount? parsenw adm:chdir .err ; + +\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geöffnete datei schließen +: close adm:close .err ; + +\ dload name - datei compilieren; log im gleichen screen +\ load name - datei compilieren; log screen 3 +\ sys name - datei aus sys compilieren; log screen 3 +\ die datei wird in der nächsten freien cog compiliert +\ fl ist für load nicht nötig und bringt in dem kontext +\ die cog-zuordnung durcheinander + +: (load) + begin adm:getc emit adm:eof until ; + +: (dload) + open cogid nfcog iolink + (load) + cogid iounlink close ; + +: (sload) + open cogid 3 dup b[ [wscr] ]b iolink + (load) + cogid dup b[ [wscr] ]b iounlink close ; + +: load + ." Loading... " (sload) ; + +: dload + (dload) ; + +: sys + 2 adm:dmset 1 adm:dmact ." Loading... " (sload) 2 adm:dmact ; + +\ ------------------------------------------------- SPIN-LOADER + +\ (spin) ( cstr -- ) - c" reg.sys" (spin) +: (spin) + dup C@ 1+ + 0 do + dup i + C@ + ldvar 1+ i + C! + loop drop + 1 ldvar C! +; + +\ spin name ( -- ) - spinobjekt "name" starten +: spin + parsenw (spin) ; + +\ regime ( -- ) - startet dir trios-cli "regime" +: regime + 0 adm:dmact + c" reg.sys" (spin) ; + +\ ----------------------------------------------------- DRV:INT + + +wvariable icog \ nummer der drv:int-cog +wvariable lcog \ nummer interaktiven cog + +\ xint ( n -- ) io von cog n auf drv:int umschalten +: xint icog W@ ioconn ; + +\ [cogscr] ( nr -- ) - umschaltung screen + cog +: [cogscr] + dup 2dup lcog W! xint [dscr] [wscr] ; + +\ =n ( n1 n2 -- n1 n1=n2 ) +: =n 2dup = swap drop ; + +\ [esc] ( -- ) - manager für esc-funktionen im drv:int +: [esc] + begin [key?] until [key] + 71 =n if 1b [emit] then \ esc - q : esc-char/quit + 31 =n if 1 [cogscr] then \ esc - 1 : cog-screen 0 + 32 =n if 2 [cogscr] then \ esc - 2 : cog-screen 1 + 33 =n if 3 [cogscr] then \ esc - 3 : cog-screen 2 + 62 =n if lcog W@ cogreset then \ esc - b : break (cog) + 72 =n if reboot then \ esc - r : reset (chip) + drop ; \ esc - esc : pause + +\ drv:int ( -- ) treiber für bellatrix-terminal +\ diese cog fragt in einer endlosschleife ab, ob zeichen +\ versendet oder empfangen werden sollen. um die zeichenausgabe +\ zu beschleunigen, findet ausgabe und eingabe in einem +\ verhältnis von 512:1 statt. per esc-code können spezielle +\ funktionen im driver ausgelöst werden. +: drv:int + \ name und typ der cog einstellen + cogid dup cogstate 10 swap C! c" drv:int" over + cognumpad ccopy + 20 delms 0D emit \ verzögertes cr für prompt + begin + \ input --> vga/video + 200 0 do key? \ eingabezeichen vorhanden? + if key b[ [b!] ]b then loop \ cog ---> bel.vga + \ output <-- keyboard + b[ [key?] \ tastenstatus bellatrix? + if [key] dup 1b = if drop [esc] else [emit] thens ]b + 0 until ; + +\ ----------------------------------------------------- SYSINIT + +: start \ ( -- ) initialisierung hive + locknew b[lock] W! \ b-semaphore + 0 dup cogstate 10 swap C! c" drv:ldr" over + cognumpad ccopy + 5 dup icog W! c" drv:int" swap cogx 1 b[ [cogscr] ]b ; +: _ob onboot ; +: onboot _ob start ; + + + diff --git a/bin/sd-card-basic/SYSTEM/bel.lib b/bin/sd-card-basic/SYSTEM/bel.lib new file mode 100644 index 0000000..0034988 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/bel.lib @@ -0,0 +1,77 @@ + +hex + +ifnot: lib:bel +: lib:bel ; + +\ kommandoformate + +ifnot: bel:fkt! \ ( fkt -- ) +: bel:fkt! b[ 0 [b!] [b!] ]b ; + +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; + +ifnot: bel:fkt!b!l@ \ ( b fkt -- l ) +: bel:fkt!b!l@ b[ 0 [b!] [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b!l! \ ( l b fkt -- ) +: bel:fkt!b!l! b[ 0 [b!] [b!] [b!] [b.l!] ]b ; + +ifnot: bel:fkt!l@ \ ( fkt -- l ) +: bel:fkt!l@ b[ 0 [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ chipmanagment-funktionen + +ifnot: bel:wscr \ ( scrnr -- ) - schreibscreen setzen +: bel:wscr 58 bel:fkt!b! ; + +ifnot: bel:dscr \ ( scrnr -- ) - displayscreen setzen +: bel:dscr 59 bel:fkt!b! ; + +ifnot: bel:getcol \ ( colnr -- col ) - farbe abfragen +: bel:getcol 5A bel:fkt!b!l@ ; + +ifnot: bel:setcol \ ( col colnr -- ) - farbe setzen +: bel:setcol 5B bel:fkt!b!l! ; + +ifnot: bel:getresx \ ( -- resx ) - abfrage x-auflösung +: bel:getresx 5C bel:fkt!l@ ; + +ifnot: bel:getresy \ ( -- resy ) - abfrage y-auflösung +: bel:getresy 5D bel:fkt!l@ ; + +ifnot: bel:getcols \ ( -- cols ) - abfrage textspalten +: bel:getcols 5E bel:fkt!b@ ; + +ifnot: bel:getrows \ ( -- rows ) - abfrage textzeilen +: bel:getrows 5F bel:fkt!b@ ; + +ifnot: bel:getcogs \ ( -- cogs ) - abfrage belegte cogs +: bel:getcogs 60 bel:fkt!b@ ; + +ifnot: bel:getspec \ ( -- spec ) - abfrage codespezifikation +: bel:getspec 61 bel:fkt!l@ ; + +ifnot: bel:getver \ ( -- ver ) - abfrage codeversion +: bel:getver 62 bel:fkt!l@ ; + +ifnot: bel:load \ ( cstr -- ) - bellatrix-code laden +: bel:load + 52 adm:open .err \ datei öffnen + b[ + 0 [b!] 63 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilänge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schließen +; + + + + diff --git a/bin/sd-card-basic/SYSTEM/beltest.bin b/bin/sd-card-basic/SYSTEM/beltest.bin index d4412ca785915fc8bad194ac49a46044f35dba3d..2c185066162ea6aa9406c98ddcefa1af2742f8b8 100644 GIT binary patch delta 487 zcmY+9yGjE=6ozwl=ZrgQVn|3ftGO622`LneW*MX61;kFQL{J1FMT`ccf{hj_?1Dm= zLJ%8kL6E40jTSaOfQ6Swu(V3$*)w|5n z(bx|%&shj6&if=fh4fRbn)*2OG{%?#V5uowP?H!@7nlhp^YP=VbFVE6C9Mq7$62!R zj+PFF`Zfm0mZ;@cbdP79C=ey0LL3lB#3^w`ToPBr9q~xKG~UFGHe_Qc3sQ5fyJoJ@ zHFw?ST3|?>beeroz!CRIxHZ%9Z^kg}!R)Ad=SJ6rDpD1t~CG$Tiyq^#MSW W{){H%a@b2-Qh*jW*z@Tl@$Tt)>916%}lr6QZ$~W^na3*Ps%m;;`kvPoQ6j2*vVCoq`c>l4&3h(2`3y27|JMraZ=ce4sdVu}_KY=DV4klkEh-icQfWQD?m`hlm3MlgjVT(wJIZK*1j zBA5t%uz(X3&^EXkO}p79UG3N14hoes%->wEM12W35kv}031S|IA9G^GCkcCKZn=A9 KHuIW3D5gIV>>W4& diff --git a/bin/sd-card-basic/SYSTEM/cog.lib b/bin/sd-card-basic/SYSTEM/cog.lib new file mode 100644 index 0000000..14c242e --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/cog.lib @@ -0,0 +1,74 @@ + +hex + +ifnot: lib:cog +: lib:cog ; + +\ cog special register + +ifnot: ctra 1F8 wconstant ctra :; +ifnot: ctrb 1F9 wconstant ctrb :; +ifnot: frqa 1FA wconstant frqa :; +ifnot: frqb 1FB wconstant frqb :; +ifnot: phsa 1FC wconstant phsa :; +ifnot: phsb 1FD wconstant phsb :; +ifnot: vcfg 1FE wconstant vcfg :; +ifnot: vscl 1FF wconstant vscl :; + +\ this words needs to align with the assembler code + +ifnot: _faddrmask : _faddrmask 1 _cv ; +ifnot: _flongmask : _flongmask 2 _cv ; +ifnot: _stptr : _stptr 5 _cv ; +ifnot: _sttos : _sttos 7 _cv ; +ifnot: _treg1 : _treg1 8 _cv ; +ifnot: _treg2 : _treg2 9 _cv ; +ifnot: _treg3 : _treg3 a _cv ; +ifnot: _treg4 : _treg4 b _cv ; +ifnot: _treg5 : _treg5 c _cv ; +ifnot: _treg6 : _treg6 d _cv ; +ifnot: _stbot : _stbot e _cv ; +ifnot: _sttop : _sttop 2e _cv ; +ifnot: _rsbot : _rsbot _sttop ; + +\ waitcnt ( n1 n2 -- n1 ) \ wait until n1, add n2 to n1 +ifnot: waitcnt +: waitcnt _execasm2>1 1F1 _cnip ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +ifnot: waitpeq +: waitpeq _execasm2>0 1E0 _cnip ; + +\ waitpne ( n1 n2 -- ) \ wait until state n1 is not equal +\ to ina anded with n2 +ifnot: waitpne +: waitpne _execasm2>0 1E8 _cnip ; + +\ lockret ( n1 -- ) deallocate a lock, previously allocated +\ via locknew +ifnot: lockret +: lockret 5 hubop 2drop ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +ifnot: locknew +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ cog+ ( -- ) add a forth cog +ifnot: cog+ +: cog+ (cog+) ; + +\ (cog-) ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: (cog-) +: (cog-) nfcog cogstop ; + +\ cog- ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: cog- +: cog- (cog-) ; + + + + diff --git a/bin/sd-card-basic/SYSTEM/debug.mod b/bin/sd-card-basic/SYSTEM/debug.mod new file mode 100644 index 0000000..937129d --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/debug.mod @@ -0,0 +1,65 @@ + +hex + +ifnot: mod:debug +: mod:debug ; + +\ keycode ( -- ) - anzeige der tastaturcodes +ifnot: keycode +: keycode + begin + 0 key? if + drop key dup dup ." code : " emit ." : " . cr 1B = + then until ; + +\ +\ Noisy reset messages +\ +\ print out a reset message to the console +\ (rsm) ( n -- ) n is the last status +\ 0011FFFF - stack overflow +\ 0012FFFF - return stack overflow +\ 0021FFFF - stack underflow +\ 0022FFFF - return stack underflow +\ 8100FFFF - no free cogs +\ 8200FFFF - no free main memory +\ 8400FFFF - fl no free main memory +\ 8500FFFF - no free cog memory +\ 8800FFFF - eeprom write error +\ 9000FFFF - eeprom read error + +: (rsm) state W@ 2 and 0= swap +\ process the last status + dup 0= if c" ok" else + dup FF11 = if c" DST OVER" else + dup FF12 = if c" RST OVER" else + dup FF21 = if c" DST LOW" else + dup FF22 = if c" RST LOW" else + dup 8001 = if c" COGs OUT" else + dup 8002 = if c" hMEM OUT" else + dup 8003 = if c" ROM WR" else + dup 8004 = if c" FL" else + dup 8005 = if c" cMEM OUT" else + dup 8006 = if c" ROM RD" else + c" ?" + thens + rot if + lockdict cr c" ERR : " .cstr swap . .cstr cr freedict + else 2drop then ; +: onreset (rsm) 4 state orC! ; + +\ .byte ( n1 -- ) +: .byte <# # # #> .cstr ; + +\ [if (dumpb) +: (dumpb) cr over .addr space dup .addr _ecs bounds ; ] + +\ [if (dumpm) +: (dumpm) cr .word _ecs ; ] + +\ [if (dumpe) +: (dumpe) tbuf 8 bounds do i C@ .byte space loop 2 spaces tbuf 8 bounds do i C@ dup bl < if drop 2e then emit loop ; ] + +\ dump ( adr cnt -- ) uses tbuf +[if dump +: dump (dumpb) do i (dumpm) i tbuf 8 cmove (dumpe) 8 +loop cr ; ] diff --git a/bin/sd-card-basic/SYSTEM/eram.bin b/bin/sd-card-basic/SYSTEM/eram.bin index 8a5d7335323300aa781775ecfa9bb91111c921b2..7b637aab141ef7f3f425dac29fee1bd8cd437c0a 100644 GIT binary patch delta 309 zcmYkzF-rqM5C!13$j<0^~q?PF$V+#0tOcbPqY8t8*FK7DpO&djA@rE8}ma{!Gu zCy8oYHLDs&{j2F-B{H3pf3vh1oE6V+iok$|^hj^?Nk259*aF*hL>F{zJznUGT?Lq@ z4ce13ZpGrA{X+t5smHwr2wfR%2kg55L&rNZ-lO3y*1cUoo8{00r_|+Q#5bc?`lX}< vTvC?qhP^_4O~Pf96!NrrN}eSN``X~giQ(y1siR&var&3@MJ5C@64HdXZnqP!{Bl^p(?rFFmKo!olBBW3hV@AOGu^g~M;*r9zorJi;e(g(W; zus|Esk^(M8Iy^JQy9%o0?;o_d>fL`dE z>f^vU4boPrJGK=`xuznis#q8awWV59Yol@O<>{mhSy|Pk+VapMg{K}1NhgcYuCZA-90g{63@|#^*I~ak?b8Jpvfn`8)2fH>zaxycA zBar3F;S3}@ITXc}7~4DcvT=zsb~l``;9%ntW3=F7<5HS@kYl=_01E?y7!b<f@882&sj?gCRQmUMhg}&$qFJ(S#=mKSb;Pk+VapMg{EUrkhgcXDCZA-90g{63@|#^*I~ak?b8Jpvfn`8)2fH>zaxycA zBar3F;S3}@ITXbe7~4DcvT=zsb~l``;9%ntW3=F7<5HM>kYl=_3=0E;A`oi>u_+K+ zZ_ebL$0V$nYg)*_Dq31%!TX1ciAA@>;>2Vrp0k#wtU8PqtUw|Kh%;Dqj2O*WWsDdt gSXgC1LO>P=s|*9Ht}&1$0+ta4lY*NSc<=B503XRLmH+?% diff --git a/bin/sd-card-basic/SYSTEM/fterm.bin b/bin/sd-card-basic/SYSTEM/fterm.bin index fb27b4243aa1c43f96c5e366695bad3a5373a88e..51166a88a56934aaa62bd7337972a10bec2479bb 100644 GIT binary patch delta 188 zcmca1ctenlVapMg{7Dnp+88+|_LgUEWny614a5h5_%aaR1>)yGtjx^7;0wg*K-><* z3z<0>_5<-XAe(`Ofk6t0t$;X$MTB7)3kSn#ApQWv0<1teAXWilTOjTO;^B$zEl(fl delta 189 zcmca1ctenlVapMg{3#RJ+89qv>@Ckc$i%>K42UlP@iid61H{jOSc#c|!3T)bfVd5a z7cg@$>;vMfK=ywimSkaIums{@77>P}EF27{fcQNS^RoiwfLIxbZGgBJh~EIQ#>DwDfd z?z1W}vhk}<&SMP{QUS6QjDUn95QBv`Ut$ddsncZdXWTM*Cwq4;2MYrO9}tTGu@n&N z0I?YmI{%$h<~wgFi5a+FzB-~Fhl}zF%VA%;Uf8efQW@cbu000YiFKz$; delta 259 zcmaDO_d<@JVapMg{5%1M4E`wsEsQfZ^0zZFs!yKIq{*l<`5;puquOR+<}yY`waHy9 z_gR%0+4$8b=dlI}sR3CEMnFOlh{3{}FR_M!)M>K!Gj5o?lf64vgoS}Y5{Tu2SQCi# zf!Gv??SZ%&h?fHKejvUN#6MX$7{pmQ81z^f7$ShU2#6;E@fubUhJQeDWi}254QS;%7kY$_^CUype;Inc0+8e)2_b5oI%0c_T&(RxruID$l@bXbj|wfcc_e LQgHJ}?h0lAb9*jd diff --git a/bin/sd-card-basic/SYSTEM/hplay.mod b/bin/sd-card-basic/SYSTEM/hplay.mod new file mode 100644 index 0000000..2916ebe --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/hplay.mod @@ -0,0 +1,155 @@ + +hex + +ifnot: mod:hplay +: mod:hplay ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; + +\ hss-funktionen + +ifnot: hss:load \ ( cstr -- err ) - hss-datei laden +: hss:load dup if 64 adm:fkt!s!b@ then ; + +ifnot: hss:play \ ( -- ) - datei im puffer abspielen +: hss:play 65 adm:fkt! ; + +ifnot: hss:stop \ ( -- ) - player stop +: hss:stop 66 adm:fkt! ; + +ifnot: hss:reg \ hreg ( regnr -- 16b ) +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +ifnot: hss:vol \ hvol ( vol -- ) - lautstärke 0..15 +: hss:vol 6A adm:fkt!b! ; + +\ keyboard-funktionen + +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; + +\ steuerzeichen + +ifnot: scr:cls \ ( -- ) - screen löschen +: scr:cls 01 bel:char ; + +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; + +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; + +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; + +\ sd0-funktionen + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ metafunktionen + +\ hload name ( -- ) - hss-datei in player laden + +ifnot: hload +: hload mount? parsenw hss:load .err ; + +ifnot: .hset +: .hset \ ( shift -- ) - eine registersatz ausgeben + 5 0 do dup i + hss:reg .word space loop drop ; + +ifnot: .hreg +: .hreg \ ( -- ) - register ausgeben + 14 0 do i .hset cr 5 +loop ; + +ifnot: fadeout +: fadeout \ ( -- ) - sound langsam ausblenden + f 0 do e i - hss:vol 50 delms loop ; + +ifnot: end? +: end? \ ( cnt -- flag ) - abfrage nach cnt wiederholungen + 4 hss:reg = ; + +ifnot: hwait +: hwait \ ( -- flag ) - wartet auf songende oder taste + begin 50 delms key? 2 end? or until key drop ; + +ifnot: hreg.. +: hreg.. \ ( -- ) - fortlaufende anzeige register + scr:curoff scr:cls begin scr:home .hreg 2 end? until + scr:curon fadeout hss:stop ; + +ifnot: (hplay) +: (hplay) \ ( cstr -- ) + ." Datei : " dup .cstr hss:load .err f hss:vol hss:play + hwait fadeout hss:stop 100 delms cr ; + +\ hplay name ( -- ) - datei abspielen +ifnot: hplay +: hplay + hload hss:play ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ hdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur hss-dateien sein! +ifnot: hdirplay +: hdirplay + decimal files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (hplay) loop padbl hex ; + +: (hp) ." play : " dup .cstr hss:load .err ; + +ifnot: playliste +: playliste + c" kw.hss" (hplay) + c" genes.hss" (hplay) + c" greenpuz.hss" (hplay) + c" hssintro.hss" (hplay) + c" kali766.hss" (hplay) + c" machine.hss" (hplay) + c" metroid.hss" (hplay) + c" mrboss.hss" (hplay) + c" mrevil.hss" (hplay) + c" raind.hss" (hplay) + c" sytrus.hss" (hplay) + c" tbellsp1.hss" (hplay) ; + diff --git a/bin/sd-card-basic/SYSTEM/hss.lib b/bin/sd-card-basic/SYSTEM/hss.lib new file mode 100644 index 0000000..33db039 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/hss.lib @@ -0,0 +1,60 @@ + +hex + +ifnot: lib:hss +: lib:hss ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +\ hss-funktionen + +\ ( cstr -- err ) - hss-datei laden +ifnot: hss:load +: hss:load dup if 64 adm:fkt!s!b@ then ; + +\ ( -- ) - datei im puffer abspielen +ifnot: hss:play +: hss:play 65 adm:fkt! ; + +\ ( -- ) - player stop +ifnot: hss:stop +: hss:stop 66 adm:fkt! ; + +\ ( -- ) - player pause +ifnot: hss:pause +: hss:pause 67 adm:fkt! ; + +\ hreg ( regnr -- 16b ) +\ 0 iEndFlag iRowFlag iEngineC iBeatC iRepeat Player +\ 5 iNote iOktave iVolume iEffekt iInstrument Kanal 1 +\ 10 iNote iOktave iVolume iEffekt iInstrument Kanal 2 +\ 15 iNote iOktave iVolume iEffekt iInstrument Kanal 3 +\ 20 iNote iOktave iVolume iEffekt iInstrument Kanal 4 +\ +\ iEndFlag Repeat oder Ende wurde erreicht +\ iRowFlag Trackerzeile (Row) ist fertig +\ iEngineC Patternzähler +\ iBeatC Beatzähler (Anzahl der Rows) +\ iRepeat Zähler für Loops +ifnot: hss:reg +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +\ hvol ( vol -- ) - lautstärke 0..15 +ifnot: hss:vol +: hss:vol 6A adm:fkt!b! ; + diff --git a/bin/sd-card-basic/SYSTEM/key.lib b/bin/sd-card-basic/SYSTEM/key.lib new file mode 100644 index 0000000..45204a5 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/key.lib @@ -0,0 +1,17 @@ + +hex + +ifnot: lib:key +: lib:key ; + +\ kommandoformate +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ keyboard-funktionen +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; +ifnot: key:code \ ( -- code ) - tastencode abfragen +: key:code 2 bel:fkt!b@ ; +ifnot: key:spec \ ( -- spec ) - spezialtasten abfragen +: key:spec 4 bel:fkt!b@ ; diff --git a/bin/sd-card-basic/SYSTEM/keycode.bin b/bin/sd-card-basic/SYSTEM/keycode.bin index 30efc09948837888fe94f4fc23fd08124344596c..9ffd612e80e10a73bc2a716ae69ab6465efdd711 100644 GIT binary patch delta 212 zcmaFC_kxd&VapMg{96;*JQ-ys2F$6qWM*Kn2Vz$s_6FiuAWjG3LLgoX#MgoNBM=L+ zFfeGda4>iRaRQLt1;k5$_y`c+V-aC6VC7&41>!0op2Z531LAc+d>n`+*cceffp`fU z3qw(2Zc1ixwxJ%7!N9<iPaXgUS3B-$m_%IOPWf5V}XXRiB0pdy^p2-T71LCznd<=-i*%%ngfOs(* z3qw(2Zc1ixwxJ%7!N9<n+a diff --git a/bin/sd-card-basic/SYSTEM/perplex.bin b/bin/sd-card-basic/SYSTEM/perplex.bin index 4ffdd3dec49909e05f74aed2f0da399ddc7bf382..d94e47c81d0c2547c4d8a70064eaa606aaea1b75 100644 GIT binary patch delta 308 zcmdm?x!DbhZEzI@Pm>C%60P!LqUIE0rfcOXyp95kp76t|r zAoc^|JRt61;b2$>#Cw74=RnNJ%D|uq#MZ1L485!z44Z)XIuL&ciZQY=FmMC03J{k9 z@f9FuWM^S0O3Y2kEY3F612PyG7&e#lOky&#U}BXqVzgiZldNEp6GWP_>M~le0*MqL X&S2FAtC3}3)iVaN*f-npS26|xj@{`!ojc56k}jxVBi8`WgspA z;>$qHz|O)@l$e{6S)6UC2V?+6Hkb2EVlp*l)n&9`1rjMhoWZJV#AwDUYs6^53??~P ZWf@rYjDdU+Fkci*3U0RNuViLq008K7G(rFX diff --git a/bin/sd-card-basic/SYSTEM/ramtest.bin b/bin/sd-card-basic/SYSTEM/ramtest.bin index 1352cfd16b45fd9c2d7d4b3538e09a7c7bc3b93c..576fcda8abcc4f47f2065cc35a72662e2b702494 100644 GIT binary patch delta 281 zcmW;CyJ`Ya6a~<8opbJ}1X4r?E2pr~G~xrFjbM@3ilrb33Wh`kC17V4>?~{sECROL z$jlEY@e6{T|6rFo`&z8cJ`d0JTus3bPp$`@Q!2TxsEtbcziMiR7psL_S%1hcuH$gz zCv&(+6GK8r&5*M3<$u_LS`;m!8Z@8{T^Payc5s0kJTlQUhv^l1=u6nb39cNYtc0lp zbMOQ=*uxndP4o#{%{1+g2XC|Yd=`a>{O?FJ)F?~5psJyJ@;$|5Nz$q+hyjcwjUN_= RBvVAw;+Q>}?Yj?i>mOJcG0^}3 delta 282 zcmbOsKSQ34VapMg`~@4?3>X<@CYv+PW|Y}{nXw4OabxxXlKsrzfMgqs6;R?Ji!eyy zDytKaBf-W6;wZBNRc+2;-@;gL&&pkm909~}K%4@^c|g1hh_3+gJ0Rv`VPMc; z;b3qB;#eTN9f%hK@j)QI%_72}%gVtJ1jOY)Je?IN2gIv^_y`b-vN14}0P#XL7KWn4 z+?34XY(qUDgMooz^L$PxCOcDBF(XD(R&_=TRv?iA#2KvWMvP`4VG9mcF$Pu*V<1a_ XRSYBvWQl-fM8TxsW(A%KW<~}8Wd?~rF>*m8s=zj-2CU*>uy28OLbyc>wm0`YYqeh9>}%nS_fK%5A~jX*q`nS)^` z5MKbYe*v)w3j>1*5c{!+Ff3r?~rF>*m8s=-(@0OU*>Km28IJbdE3j>2O5c{%-FwAG+U^oKAFM*ho6(|S9vOsJG#O*-*42Xp{{(Z`*Z_297 vXu%33Qh+#vRoRHqj8(*l(Sn0jgn?DX7|0R<^F_g=;ASD_D(21IY=1cb#XKJ7 diff --git a/bin/sd-card-basic/SYSTEM/rom.mod b/bin/sd-card-basic/SYSTEM/rom.mod new file mode 100644 index 0000000..9a91eda --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/rom.mod @@ -0,0 +1,206 @@ + +\ ACHTUNG: Diese Modifikation nicht bei einer Installation im +\ HI-EEPROM verwenden! + +hex +[if mod:rom +: mod:rom ; ] + +\ constant ( x -- ) skip blanks parse the next word and create a constant, allocate a long, 4 bytes +[if constant +: constant lockdict create $C_a_doconl w, l, forthentry freedict ; ] + +\ +\ CONFIG PARAMETERS BEGIN +\ +40 wconstant fsps \ a page size which works with 32kx8 & 64kx8 eeproms + \ and should work with larger as well. + + +8000 constant fsbot \ file-system bottom: the start adress in eeprom for the file system + + \ file system top: the end address of the file system + \ uncomment the line for your comfiguration +\ 8000 constant fstop \ the end address for the file system with one 24LC256 32k eeprom +10000 constant fstop \ the end address for the file system with one 24LC512 64k eeprom +\ 20000 constant fstop \ the end address for the file system with two 24LC512 64k eeprom +\ 30000 constant fstop \ the end address for the file system with 3 24LC512 64k eeprom +\ 40000 constant fstop \ the end address for the file system with 4 24LC512 64k eeprom +\ 50000 constant fstop \ the end address for the file system with 5 24LC512 64k eeprom +\ 60000 constant fstop \ the end address for the file system with 6 24LC512 64k eeprom +\ 70000 constant fstop \ the end address for the file system with 7 24LC512 64k eeprom + +\ NOTE IF you have DEMOBOARD or any system with 32K EEPROM, you will step on your spin image +\ when you write to the EEPROM. You can still use it (if you are tricky), but KNOW WHAT YOUR DOING!!! + +\ +\ CONFIG PARAMETERS END +\ + + +\ lasti? ( -- t/f ) true if this is the last value of i in this loop +[if lasti? +: lasti? _rsptr COG@ 2+ COG@ 1- _rsptr COG@ 3 + COG@ = ; ] + +\ padbl ( -- ) fills this cogs pad with blanks +[if padbl +: padbl pad padsize bl fill ; ] +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ EW@ ( eeAddr -- n1 ) +[if EW@ +: EW@ t0 2 eereadpage if 8006 ERR then t0 W@ ; ] + +\ EC@ ( eeAddr -- c1 ) +[if EC@ +: EC@ EW@ FF and ; ] + +\ (fspa) ( addr1 -- addr2) addr2 is the next page aligned address after addr1 +: (fspa) fsps 1- + fsps 1- andn ; + +\ (fsnext) ( addr1 -- addr2 t/f) addr - the current file address, addr2 - the next addr, t/f - true if we have +\ gone past the end of the eeprom. t0 -length of the current file +\ t1 - length of the file name (char) +: (fsnext) t0 W@ t1 C@ + 2+ 1+ + (fspa) dup fstop >= ; + + +\ (fswr) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to write, addr2 - the address to write from +\ n1 - the number of bytes to write +: (fswr) dup >r rot dup r> + fstop 1- > if A0 ERR then rot2 eewritepage if 88 ERR then ; + +\ (fsrd) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to read, addr2 - the address of the read buffer +\ n1 - the number of bytes to read +: (fsrd) dup >r rot dup r> + fstop 1- > if C0 ERR then rot2 eereadpage if 90 ERR then ; + +\ (fsfree) ( -- n1 ) n1 is the first location in the file system, -1 if there are none +: (fsfree) -1 fsbot begin +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) t0 W@ FFFF = if nip dup -1 else (fsnext) then +until drop ; + +\ (fsfind) ( cstr -- addr ) find the last file named cstr, addr is the eeprom address, 0 if not found +: (fsfind) fsbot 0 >r begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + over t1 cstr= if r> drop dup >r then + (fsnext) + then +until 2drop r> ; + +\ (fslast) ( -- addr ) find the last file, 0 if not found +: (fslast) 0 fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + nip dup + (fsnext) + then +until drop ; + +\ fsclear ( -- ) +: fsclr padbl fsbot 400 + fsbot do i pad fsps (fswr) 2e emit fsps +loop -1 fsbot EW! ; +: fsclear -1 fsbot EW! ; + +\ fsfree ( -- ) +: fsfree (fsfree) dup -1 = if 0 else fstop swap - then . ." bytes free in fs" cr ; + +\ fsls ( -- ) list the files +: fsls cr fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + dup .addr space t0 W@ .addr space t1 .cstr cr + (fsnext) + then +until fstop swap - cr . ." bytes free in files system" cr cr ; + +\ (fsread) ( cstr -- ) +: (fsread) (fsfind) dup if +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) + t1 C@ + 2+ 1+ t0 W@ bounds do + ibound i - fsps >= if + i pad fsps (fsrd) pad fsps bounds + do i C@ emit loop i fsps 1- + seti + else + i EC@ emit + then + loop +else drop then padbl ; + +\ fsread ( -- ) filename +: fsread parsenw dup if (fsread) else drop then ; + +\ (fsload) ( ctsr -- ) +: (fsload) cogid nfcog iolink (fsread) d emit d emit cogid iounlink ; + +\ fsload filename ( -- ) send the file to the next free forth cog +: fsload parsenw dup if (fsload) else drop then ; + +\ (fsk) ( n1 -- n2) +: (fsk) 8 lshift key or ; + +\ fswrite filename ( -- ) writes a file until ... followed immediately by a cr is encountered +: fswrite (fsfree) dup -1 <> parsenw dup rot and if +\ set the file length to 0, copy in the file name + 0 pad W! dup C@ 2+ 1+ pad + swap pad 2+ ccopy +\ find the first free page + 0 swap key (fsk) (fsk) (fsk) +\ ( eaddr1 n1 addr2 n2 ) eaddr - start of file in the eeprom, n1 - bytes written so far, addr2 - next addr in the pad, +\ n2 - a 4 byte key buffer + begin +\ check to see if we have a ... at the end of a line + 2E2E2E0D over = if + -1 + else +\ get a key from the key buffer, write it the the pad + swap over 18 rshift dup dup d = if drop cr else emit then over C! 1+ tuck pad - fsps = if +\ we have a page worth of data, write it out + nip rot2 2dup + pad fsps (fswr) fsps + rot pad swap + then +\ get another key + (fsk) 0 + then + until +\ any keys left? + drop pad - dup 0> if +\ write the leftover, not a full page + >r 2dup + pad r> dup >r (fswr) r> + + else + drop + then +\ write the length of FFFF for the next file + 2dup + FFFF swap (fspa) dup fstop 1- < if EW! else 2drop then +\ subtract the length of the filename +1, and the 2 bytes which are the length of the file, and update the length of the file + over 2+ EC@ 2+ 1+ - swap EW! +else 2drop clearkeys then padbl +; + +\ fsdrop ( -- ) deletes last file +: fsdrop (fslast) dup -1 = if drop else FFFF swap EW! then ; + + diff --git a/bin/sd-card-basic/SYSTEM/scr.lib b/bin/sd-card-basic/SYSTEM/scr.lib new file mode 100644 index 0000000..a879692 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/scr.lib @@ -0,0 +1,69 @@ + +hex + +ifnot: lib:scr +: lib:scr ; + +\ kommandoformate +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl! \ ( ctrl -- ) +: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl!b@ \ ( ctrl -- b@ ) +: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ; +ifnot: bel:ctrl!b!b! \ ( b b ctrl -- ) +: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ; + +\ einfache steuerzeichen +ifnot: scr:cls \ ( -- ) - screen löschen +: scr:cls 01 bel:char ; +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:scrlu \ ( -- ) - screen nach oben scrollen +: scr:scrlu 06 bel:char ; +ifnot: scr:scrld \ ( -- ) - screen nach unten scrollen +: scr:scrld 07 bel:char ; +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; + +\ screen-funktionen +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; +ifnot: scr:char \ ( char -- ) - zeichensatz direkt ausgeben +: scr:char 6 bel:fkt!b! ; + +\ parametrisierte steuerzeichen +ifnot: scr:setcur \ ( cur -- ) - cursorzeichen setzen +: scr:setcur 01 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:getx \ ( -- x ) - cursor position x abfragen +: scr:getx 04 bel:ctrl!b@ ; +ifnot: scr:gety \ ( -- y ) - cursor position y abfragen +: scr:gety 05 bel:ctrl!b@ ; +ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:eline \ ( row -- ) - endzeile scrollbereich +: scr:eline 08 bel:ctrl!b! ; +ifnot: scr:sinit \ ( -- ) - +: scr:sinit 09 bel:ctrl! ; +ifnot: scr:tabset \ ( pos nr -- ) - tabulatorposition setzen 0..7 +: scr:tabset 0A bel:ctrl!b!b! ; diff --git a/bin/sd-card-basic/SYSTEM/sd0.lib b/bin/sd-card-basic/SYSTEM/sd0.lib new file mode 100644 index 0000000..8cf2e49 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/sd0.lib @@ -0,0 +1,176 @@ + +hex + +ifnot: lib:sd0 +: lib:sd0 ; + +\ ------------------------------------ lib:sd0 + +\ kommandoformate + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +ifnot: adm:fkt!l! \ ( l fkt -- ) +: adm:fkt!l! b[ [a!] [a.l!] ]b ; + +ifnot: adm:fkt!l@ \ ( fkt -- l ) +: adm:fkt!l@ b[ [a!] [a.l@] ]b ; + +ifnot: adm:fkt!b!l! \ ( l b fkt -- ) +: adm:fkt!b!l! b[ [a!] [a!] [a.l!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!s!b@ \ ( s b fkt -- b ) +: adm:fkt!b!s!b@ b[ [a!] [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!s!s!b@ \ ( s s fkt -- b ) +: adm:fkt!s!s!b@ b[ [a!] [a.s!] [a.s!] [a@] ]b ; + +\ dateisystem-funktionen + +\ adm:mount ( -- err ) - medium mounten +ifnot: adm:mount +: adm:mount + 01 adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:open ( cstr modus -- err ) - datei öffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +ifnot: adm:open +: adm:open + 04 adm:fkt!b!s!b@ ; + +\ adm:close ( -- ) - datei schließen +ifnot: adm:close +: adm:close + 05 adm:fkt!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus datei lesen +ifnot: adm:getc +: adm:getc + 06 adm:fkt!b@ ; + +\ adm:putc ( c -- ) - ein zeichen in datei schreiben +ifnot: adm:putc +: adm:putc + 07 adm:fkt!b! ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +ifnot: adm:eof +: adm:eof + 1E adm:fkt!b@ ; + +\ adm:getblk ( adr cnt -- ) - datenblock aus datei lesen + +\ adm:putblk ( adr cnt -- ) - datenblock in datei schreiben + +\ adm:seek ( pos -- ) - position in datei setzen +: adm:seek + 0A adm:fkt!l! ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +ifnot: adm:fattrib +: adm:fattrib + 0B adm:fkt!b!l@ ; + +\ adm:volname ( -- ) - name des volumes im pad ablegen +ifnot: adm:volname +: adm:volname + 0C adm:fkt!s@ ; + +\ adm:checkmounted ( -- t/f ) +ifnot: adm:checkmounted +: adm:checkmounted + 0D adm:fkt!b@ ; + +\ adm:checkopen ( -- t/f ) +ifnot: adm:checkopen +: adm:checkopen + 0E adm:fkt!b@ ; + +\ adm:checkused ( -- used ) - anzahl benutzte sektoren +ifnot: adm:checkused +: adm:checkused + 0F adm:fkt!l@ ; + +\ adm:checkfree ( -- free ) - anzahl freie sektoren +ifnot: adm:checkfree +: adm:checkfree + 10 adm:fkt!l@ ; + +\ adm:newfile ( cstr -- ) - neue datei erstellen +ifnot: adm:newfile +: adm:newfile + 11 adm:fkt!s!b@ ; + +\ adm:newdir ( cstr -- ) - neues verzeichnis erstellen +ifnot: adm:newdir +: adm:newdir + 12 adm:fkt!s!b@ ; + +\ adm:del ( cstr -- ) - datei/verzeichnis löschen +ifnot: adm:del +: adm:del + 13 adm:fkt!s!b@ ; + +\ adm:rename ( cstr1.fn1 cstr2.fn2 -- ) +ifnot: adm:rename +: adm:rename + 14 adm:fkt!s!s!b@ ; + +\ adm:chattrib ( cstr1.fn cstr2.attrib -- ) +ifnot: adm:chattrib +: adm:chattrib + 15 adm:fkt!s!s!b@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis öffnen +ifnot: adm:chdir +: adm:chdir + 16 adm:fkt!s!b@ ; + +\ adm:format ( cstr.label -- ) - medium formatieren +ifnot: adm:format +: adm:format + 17 adm:fkt!s!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +ifnot: adm:unmount +: adm:unmount + 18 adm:fkt!b@ ; + +\ marker-funktionen + +ifnot: adm:dmact \ ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ .err ; +ifnot: adm:dmset \ ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; +ifnot: adm:dmclr \ ( dmnr -- ) - marker löschen +: adm:dmclr 1C adm:fkt!b! ; +ifnot: adm:dmput \ ( dm dmnr -- ) - marker schreiben +: adm:dmput 1D adm:fkt!b!l! ; + diff --git a/bin/sd-card-basic/SYSTEM/sfx.lib b/bin/sd-card-basic/SYSTEM/sfx.lib new file mode 100644 index 0000000..3c01222 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/sfx.lib @@ -0,0 +1,93 @@ + +hex + +ifnot: lib:sfx +: lib:sfx ; + +\ kommandoformen + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!64b! \ ( ptr b fkt -- ) +: adm:fkt!b!64b! b[ [a!] [a!] + 31 0 do dup i + C@ [a!] loop drop ]b ; + +\ sfx-funktionen + +\ sfx:fire( chan slot -- ) - sfx abspielen +\ slot - $00..$0f nummer der freien effektpuffer +\ slot - $f0..f5 vordefinierte effektslots +\ chan - 0/1 stereokanal +\ vordefinierte effekte +\ &f0 - warnton +\ $f1 - signalton +\ $f2 - herzschlag schnell +\ $f3 - herzschlag langsam +\ $f4 - telefon +\ $f5 - phaser :) +\ $f6 - pling +\ $f7 - on +\ $f8 - off +ifnot: sfx:fire +: sfx:fire 6B adm:fkt!b!b! ; + +\ ( ptr slot -- ) - sfx setzen +\ slot - $00..$0f nummer der freien effektpuffer +\ ptr - zeiger auf 32 byte effektdaten +\ +\ struktur der effektdaten: +\ +\ [wav ][len ][freq][vol ] grundschwingung +\ [lfo ][lfw ][fma ][ama ] modulation +\ [att ][dec ][sus ][rel ] hüllkurve +\ [seq ] (optional) +\ +\ [wav] wellenform +\ 0 sinus (0..500hz) +\ 1 schneller sinus (0..1khz) +\ 2 dreieck (0..500hz) +\ 3 rechteck (0..1khz) +\ 4 schnelles rechteck (0..4khz) +\ 5 impulse (0..1,333hz) +\ 6 rauschen +\ [len] tonlänge $0..$fe, $ff endlos +\ [freq] frequenz $00..$ff +\ [vol] lautstärke $00..$0f +\ +\ [lfo] low frequency oscillator $ff..$01 +\ [lfw] low frequency waveform +\ $00 sinus (0..8hz) +\ $01 fast sine (0..16hz) +\ $02 ramp up (0..8hz) +\ $03 ramp down (0..8hz) +\ $04 square (0..32hz) +\ $05 random +\ $ff sequencer data (es folgt eine sequenzfolge [seq]) +\ [fma] frequency modulation amount +\ $00 no modulation +\ $01..$ff +\ [ama] amplitude modulation amount +\ $00 no modulation +\ $01..$ff +\ [att] attack $00..$ff +\ [dec] decay $00..$ff +\ [sus] sustain $00..$ff +\ [rel] release $00..$ff +ifnot: sfx:setslot +: sfx:setslot + 6C adm:fkt!b!64b! ; + +\ sfx:keyoff ( chan -- ) - release-phase einleiten +ifnot: sfx:keyoff +: sfx:keyoff + 6D adm:fkt!b! ; + +\ sfx:stop ( chan -- ) +ifnot: sfx:stop +: sfx:stop + 6E adm:fkt!b! ; + diff --git a/bin/sd-card-basic/SYSTEM/sfxtool.bin b/bin/sd-card-basic/SYSTEM/sfxtool.bin index aee8e47e2e0159fabeaa6349eaa8f101a7045a70..4bb86b0e33c920594b956ab4256079d52daeae10 100644 GIT binary patch delta 376 zcmYMsyGjE=6b9fkn>mx+CCPdvthiAVV;5GUlMG%edtV_45h5|fO9Z==+Snwef=ymP z6H5z03&D5r0j#VnzRf2q5X%!+Kcl6+{t#faYF1Af4hL_Xx802R1|CwPS+_-s=dwwdS@ zI&cdwJVhC0(-zd=T;T>+a0e<*v;|zfPsC$;E~~Bu<~SO!C{cWT9p3 z?(^7v+gLnX6h=nLQ97g4916pTD%3cPIsx(W3MR$D=p9r1Z{h`E91g1b%XM(`1!ts< k5L$B%A1n!;6FiS~%^QC5da-0?HV37?oT$h82h*$8F9MT4uK)l5 delta 378 zcmYMvyG{Z@6b9fk%bsB+z=D8?alI^RrCEc{I`Puj`wAM9O+H=m=&MYGHws|E2bB!WE0{qr`LLGeR^3!z7Bs6wHDPt8fVSFo1XXfoZnLhXW?M zg%)(-jkDxPi}v9Jni4yBfIe`PD1cVfq^sjPx# diff --git a/bin/sd-card-basic/SYSTEM/splay.bin b/bin/sd-card-basic/SYSTEM/splay.bin index b67287a1592a501571c6db585887e843d586bd2c..ebdce7cd69d1041ee3b9d37cdf527ceed4a740a9 100644 GIT binary patch delta 252 zcmbOrK0%y~VapMgeAkU^Mof(AlP#HY1k@PVxV18YgjgzL1{=5Ljyh^2v87l_S)*b#`mfw&!rHv;i#Abt(RtgIXi%0O(z%D|8U#C1SC4~TcL ziZF1oaWLouaR?BXumRAU%$)Za*-*Z+(ky%}l=0E9VQnGh3MQinDK<8;V>@N7TmlWb0V_A6 z?6?AtS^WN;_dH(8ODVcOsEkVF~C zLJ4Znf(~?H2WNP~8zdWKLX(Mxuz@4oIZk0^P#FfWQrKV*C-^`=gujrar89RYt7)aY vbo`h6Xze;zh0TZyW3F1F!KNi_J*Z;yKj1dlB(D8m@nA^=jrnO~tqb}AkUJ-f diff --git a/bin/sd-card-basic/SYSTEM/splay.mod b/bin/sd-card-basic/SYSTEM/splay.mod new file mode 100644 index 0000000..eb6e485 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/splay.mod @@ -0,0 +1,116 @@ + +\ achtung: vor verwendung muss der administra-code mit sidcog +\ geladen werden: +\ sys tools.f +\ sys splay.f <--- sid-player laden +\ aload admsid.adm <--- administra-code mit sidcog laden +\ splay xyz.dmp <--- sid-datei abspielen + + +hex + +ifnot: mod:splay +: mod:splay ; + +\ kommandoformen + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- err ) +: adm:fkt!s! b[ [a!] [a.s!] [b@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:aload +: adm:aload + 60 adm:fkt!s! ; + +\ tools + +ifnot: aload +: aload + mount? parsenw dup + if 1 adm:dmact adm:aload 0 else drop 23 then .err ; + +\ sid-funktionen + +ifnot: sid:play +: sid:play \ ( cstr -- err ) + 9E adm:fkt!s!b@ ; + +ifnot: sid:stop +: sid:stop \ ( -- ) + 9F adm:fkt! ; + +ifnot: sid:status +: sid:status \ ( -- status ) + A1 adm:fkt!b@ ; + +ifnot: sid:mute +\ 1 - sid1 +\ 2 - sid2 +\ 3 - sid1 & sid2 +: sid:mute \ ( sidnr -- ) + A3 adm:fkt!b! ; + +\ send? ( -- t/f ) +ifnot: send? +: send? + begin 50 delms key? dup if key drop then sid:status 0= or + until ; + +\ (splay) ( cstr -- ) +ifnot: (splay) +: (splay) \ ( cstr -- ) + ." Datei : " dup .cstr cr sid:play .err + send? sid:stop 3 sid:mute adm:close drop ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ splay name.dmp ( -- ) - sid-datei abspielen +ifnot: splay +: splay + parsenw (splay) ; + +\ sdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur sid-dateien sein! +ifnot: sdirplay +: sdirplay + files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (splay) loop padbl ; + +ifnot: smute +: smute + sid:stop 3 sid:mute ; + \ No newline at end of file diff --git a/bin/sd-card-basic/SYSTEM/sysconf.bin b/bin/sd-card-basic/SYSTEM/sysconf.bin index 6c3d330af401e7ded7280fbe8ee49aac77b9054b..7b60532260a149602427032e318e4bf2cd6f6a48 100644 GIT binary patch delta 216 zcmX@0bU=xXVapMg{O*lxk63xN8QWXGu?fpFnz9LNZ~n@9ow+`og@GX!h?9Z16o~7A zxD$vc1Mztv{t3jwtPBjsKP01|IHqXu$#|Sy`1Q gH}Hyx0l6v+tft052{u+0#uQc)Ad7wTZr&DV0IHuT-v9sr delta 232 zcmW;By$b5K-0TN!0l z{sBccJ`Ar<@A@1PhlHfvQSFts^2T~n%x5ndi3>|clJ1i)%CMmlHNk-aOke>^IKdmj zOk_fpHEP2cy#WvI@BzP!QcY?!f;D)O=nPkQK-ovMg0oL0r{1+&{Z2aN)ZI!TuM{oL miUMP7XmZvRIW|mD(AXfhGN>RMzY`VxKe7LY+`T?k1bqRIuq#Ud diff --git a/bin/sd-card-basic/SYSTEM/time.bin b/bin/sd-card-basic/SYSTEM/time.bin index bc4b92feaed2ba42b302e34821a82f768b1817ee..b0fe325b450dc07887c179e352d1bbfab9a3c26d 100644 GIT binary patch delta 204 zcmZ3YwM2`JVapMge1(l{O}v>4SQr?V0r46j-Uq}dfcO#+^RY58SO9Sl5ElV)4=V@5 zDj+@xWWNStRyGC(RUo!!6JeOh#=)=+h;IY&Z=e_}I|Bnh5NiN&B@o{LV%E(cc@>z2 zb#qM%8CaD|ODuT*a51symRN91RuK$0uwY_UGh(!00h6pC(v;PV(Sj97qyTXSs~K2U Roq^Td7|3GZyh^Z=8336cB8>n5 delta 205 zcmZ3YwM2`JVapMgeC3U7O}v?FSQr>K0`YDjJ_y9ef%qa2^RhB9m;-Sj5ElY*H!BCj zN+3P}WWNGp7B&V36(F`_6JeOZ#=)=^h;IS$FQ6C;I|BnB5UT@m1rT2cVwTMxc@>z2 zwR24i8CaD|ODuT*a51symROvatRfh$Z^~-MXu%33Qh+#v)y#;|j8)x;(Sn0joq^Td U7|0R<^F_g=;O5nWmCTF`01i4MjsO4v diff --git a/bin/sd-card-basic/SYSTEM/tools.mod b/bin/sd-card-basic/SYSTEM/tools.mod new file mode 100644 index 0000000..4d74e6f --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/tools.mod @@ -0,0 +1,152 @@ + +hex + +ifnot: mod:tools +: mod:tools ; + +\ kommandoformen +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +ifnot: adm:dmact \ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:load +: adm:load + 60 adm:fkt!s! ; + +\ bel-funktionen + +\ bel:load ( cstr -- ) - bellatrix-code laden +\ achtung: die gesamte loader-operation ist eine atomare +\ operation über alle drei propellerchips, kann also auch +\ nicht aufgetrennt werden! +ifnot: bel:load +: bel:load + 52 adm:open .err \ datei öffnen + b[ + 0 [b!] 63 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilänge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schließen +; + +\ ------------------------------------ mod:tools + +ifnot: aload +: aload \ name ( -- ) - administra-code laden + mount? parsenw dup + if adm:load 0 else drop 23 then .err ; + +ifnot: bload +: bload \ name ( -- ) - bellatrix-code laden + mount? parsenw dup + if bel:load 0 else drop 23 then .err ; + +ifnot: .dmstatus \ ( dm -- ) - ausgabe marker-status +: .dmstatus -1 = if ." frei" else ." gesetzt" then cr ; + +ifnot: dm? +: dm? + ." [root] : " 0 adm:dmget .dmstatus + ." [sys ] : " 1 adm:dmget .dmstatus + ." [usr ] : " 2 adm:dmget .dmstatus + ." [ A ] : " 3 adm:dmget .dmstatus + ." [ B ] : " 4 adm:dmget .dmstatus + ." [ C ] : " 5 adm:dmget .dmstatus ; + +\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen +ifnot: open +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geöffnete datei schließen +ifnot: close +: close + adm:close .err ; + +\ (cat) ( -- ) - alle zeichen der geöffneten datei ab +\ lesemarke auf ausgabekanal bis zum eof ausgeben +ifnot: (cat) +: (cat) begin adm:getc emit adm:eof until ; + +\ cat name ( -- ) - datei "name" komplett ausgeben +ifnot: cat +: cat open (cat) close ; + +\ nextline ( -- ) - ausgabe der nächsten textzeile aus der +\ geöffneten datei +ifnot: nextline +: nextline + begin adm:getc dup emit 0d = adm:eof or until ; + +\ nextlines ( n -- ) - ausgabe von n zeilen +ifnot: nextlines +: nextlines + 0 do adm:eof 0= if nextline then loop ; + +\ less name ( -- ) - zeilenweise ausgabe der datei +ifnot: less +: less + open begin 10 nextlines key 71 = adm:eof or until close ; + +\ #C ( c1 -- ) prepend the character c1 to the number +\ currently being formatted +ifnot: #C +: #C -1 >out W+! pad>out C! ; + +\ .cogch ( n1 n2 -- ) print as x(y) +ifnot: .cogch +: .cogch <# 29 #C # 28 #C drop # #> .cstr ; + +\ j ( -- n1 ) the second most current loop counter +ifnot: j +: j _rsptr COG@ 5 + COG@ ; + +\ cog? ( -- ) +ifnot: cog? +: cog? + 8 0 do ." Cog:" i dup . ." #io chan:" + dup cognchan . cogstate C@ + dup 4 and if version W@ .cstr then + dup 10 and if i cognumpad version W@ C@ over C@ - + spaces .cstr then + 14 and if i cogio i cognchan 0 do + i 4* over + 2+ W@ dup 0= if drop else + space space j i .cogch ." ->" io>cogchan .cogch + then + loop +drop then cr loop ; + +\ jede erweiterung legt ein wort als startmarke +\ nmit folgendem namen an: +\ mod:xxx - softwaremodule +\ drv:xxx - treiber +\ lib:xxx - bibliotheken +\ so kann mit den folgenden kommandos eine schnelle liste der +\ vorhandenen erweiterungen abgerufen und mit forget +\ aus dem system entfernt werden + +\ mod? ( -- ) - anzeige der module +ifnot: mod? +: mod? c" mod:" _words ; + +\ lib? ( -- ) - anzeige der bibliotheken +ifnot: lib? +: lib? c" lib:" _words ; + diff --git a/bin/sd-card-basic/SYSTEM/v1.mod b/bin/sd-card-basic/SYSTEM/v1.mod new file mode 100644 index 0000000..7b0b8cd --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/v1.mod @@ -0,0 +1,325 @@ + +: mod:vortrag ; + +24 constant rows +64 constant cols + +wvariable lcol 7 lcol W! + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; + +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +: lcol@ lcol W@ ; \ ( -- col ) + +: lines \ ( n -- ) + 0 do cr loop ; + +: waitkey + scr:curoff cr key drop scr:bs scr:bs scr:bs scr:curon ; + +: nextpage + scr:curoff scr:pos1 lcol@ spaces ." -->" key drop scr:bs scr:bs scr:bs scr:curon ; + +: .head \ ( -- ) + 4 scr:setcol scr:pos1 lcol@ spaces ; + +: .bullet \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ spaces 0f emit space ; + +: .number \ ( n -- n ) + 0 scr:setcol scr:pos1 lcol@ spaces dup . 1+ + 2e emit space ; + +: .line \ ( -- ) + cr 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +: .sub \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +wvariable xpos 1 xpos W! +wvariable ypos 1 ypos W! + +: pos! \ ( x y -- ) + ypos W! xpos W! ; + +: pos@ \ ( -- x y ) + xpos W@ ypos W@ ; + +: nextline + ypos W@ 1+ ypos W! ; + +: move \ ( x y -- ) + 1 delms pos@ scr:sety scr:setx ; + + +: btop0 \ ( -- ) + move 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot0 \ ( -- ) + move 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: btop1 \ ( -- ) + move 2 spaces 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot1 \ ( -- ) + move 2 spaces 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: bmid0 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit nextline + move 91 emit ." " 95 emit 90 emit aa emit nextline ; + +: bmid1 \ ( -- ) + move a9 emit 90 emit 94 emit ." COG " 91 emit nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid2 \ ( -- ) + move a9 emit 90 emit 94 emit ." SER " + 95 emit 90 emit bb emit ." [TERMINAL]" nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid3 \ ( -- ) + move a9 emit 90 emit 94 emit ." VGA " + 95 emit 90 emit bb emit ." [BELLATRIX]" nextline + move ba emit 90 emit 94 emit ." KBD " 91 emit nextline ; + +: bmid4 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit + ." Zeichenausgabekanal (emit)" nextline + move 91 emit ." " 95 emit 90 emit aa emit + ." Zeicheneingabekanal (key)" nextline ; + +: cog0 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid0 bbot0 ; + +: cog1 \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid1 bbot1 ; + +: cog3 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid4 bbot0 ; + +: cogext \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid2 bbot1 ; + +: cogint \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid3 bbot1 ; + +: drvser + 0 scr:setcol 2dup cog0 swap a + swap cogext ; + +: drvint + 0 scr:setcol 2dup cog0 swap a + swap cogint ; + +: p0 + 0 scr:sline cls 5 lines + 14 1c scr:curoff scr:logo won c" woodz.wav" wav:start drop + key drop scr:curon wav:stop woff ; + +: i1 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr waitkey + .bullet ." Forth-Diamond: Master & Slaves = PropForth" waitkey cr + .sub ." Nachteil: Programmierung aller Treiber in Forth" waitkey cr + .bullet ." Forth-Spin: Forth mit SPIN-Interface" waitkey cr + .sub ." Vorteil: Nutzung fertiger Treiber" waitkey + .sub ." Nachteil: hoher Ressourcenverbrauch" waitkey cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr cr + nextpage ; + +: i2 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr waitkey + .bullet ." Nachteile:" cr cr + .sub ." Spin --> Compiler noch auf Host" cr waitkey + .bullet ." Vorteile:" cr cr + .sub ." Code ist schon vorhanden (TriOS)" waitkey + .sub ." Gegenseitige Befruchtung von Forth & TriOS" waitkey + .sub ." Maximale Ressourcen für Forth im Master" waitkey + .sub ." Spin-Code kann später auch durch Forth ersetzt werden" cr + nextpage ; + +: i3 + 0 scr:sline cls 3 lines + .head ." Ablauf der Implementierung" cr waitkey + .bullet ." Ausgangslage: " cr cr + .sub ." Forth mit Terminalzugriff" cr waitkey + .bullet ." Plan:" cr cr + .sub ." 1. Busroutine um auf Slaves zuzugreifen" waitkey + .sub ." 2. Integration VGA/Keyboard/SD-Card" waitkey + .sub ." 3. Autostart" cr cr + nextpage ; + + +: p1 + 0 scr:sline cls 1 lines + .head ." Buszugriff" cr cr + .bullet ." ! ( n adr -- ) store - Wert im RAM speichern" cr + .bullet ." @ ( adr -- n ) fetch - Wert aus RAM lesen" cr waitkey + .bullet ." c! c@ p! p@ - Abwandlungen der Grundform" cr waitkey + .bullet ." s! ( c adr -- ) - Byte an Slave senden" cr + .bullet ." s@ ( adr -- c ) - Byte von Slave empfangen" cr waitkey + .bullet ." b! ( c -- ) - Byte an Bellatrix senden" cr + .bullet ." b@ ( -- c ) - Byte von Bellatrix empfangen" cr + .bullet ." a! ( c -- ) - Byte an Administra senden" cr + .bullet ." a@ ( -- c ) - Byte von Administra empfangen" cr cr + .head ." Beispiele :" cr cr + .bullet ." 01 b! - Bildschirm löschen" waitkey + .bullet ." : cls 01 b! ; " waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr + nextpage ; + +: p2 + 0 scr:sline cls 5 lines + .head ." IO-Kanäle/Pipes" cr waitkey + 9 8 cog3 key drop + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p3 + 0 scr:sline cls 5 lines + .head ." Serieller Treiber" cr cr + 9 8 drvser + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p4 + 0 scr:sline cls 5 lines + .head ." VGA/Keyboard-Treiber" cr cr + 9 8 drvser + 9 c drvint + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p5 + 0 scr:sline cls 5 lines + .head ." Treiber: VGA" cr cr + 9 8 drvint cr + .line ." : drv-vga " + .line ." begin" + .line ." key?" + .line ." if key b! then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p6 + 0 scr:sline cls 5 lines + .head ." Treiber: Keyboard" cr cr + 9 8 drvint cr + .line ." : drv-key" + .line ." begin" + .line ." bel:keystat" + .line ." if bel:key emit then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p7 + 0 scr:sline cls 5 lines + .head ." Treiber: Gesamt" cr cr + 9 8 drvint cr + .line ." : drv:int" + .line ." begin" + .line ." \ input --> vga/video" + .line ." 200 0 do key?" + .line ." if key b[ [b!] ]b then loop" + .line ." \ output <-- keyboard" + .line ." b[ [key?]" + .line ." if [key] [emit] then ]b" + .line ." 0 until ;" + cr cr + nextpage ; + +: p8 + 0 scr:sline cls 5 lines + .head ." Semaphoren" cr waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr waitkey + .bullet ." : bel:key bon 0 b! 2 b! b@ boff ;" cr waitkey + .bullet ." [ ... ]" cr waitkey + .bullet ." b[ ... ]b" cr waitkey + .bullet ." : bel:key b[ 0 b! 2 b! b@ ]b ;" cr waitkey + .bullet ." : bel:key b[ 0 [b!] 2 [b!] [b@] ]b ;" cr waitkey + .bullet ." : bel:key 2 0 b[ [b!] [b!] [b@] ]b ;" cr cr + cr cr + nextpage ; + +: run + begin p0 i1 i2 i3 p1 p2 p3 p4 p5 p6 p7 p8 0 until ; + diff --git a/bin/sd-card-basic/SYSTEM/vga.bel b/bin/sd-card-basic/SYSTEM/vga.bel index e130ef297160fff645abb30fe16a927c30d02790..e5348913866ba14c0cf602caec2bd69fe60d9186 100644 GIT binary patch delta 2558 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 diff --git a/bin/sd-card-basic/SYSTEM/wav.lib b/bin/sd-card-basic/SYSTEM/wav.lib new file mode 100644 index 0000000..4198e23 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/wav.lib @@ -0,0 +1,54 @@ + +hex + +ifnot: lib:wav +: lib:wav ; + +\ kommandoformen + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!l@l@ \ ( fkt -- l l ) +: adm:fkt!l@l@ b[ [a!] [a.l@] [a.l@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ wav:leftvol ( vol -- ) +ifnot: wav:leftvol +: wav:leftvol + 99 adm:fkt!b! ; + +\ wav:rightvol ( vol -- ) +ifnot: wav:rightvol +: wav:rightvol + 9A adm:fkt!b! ; + +\ wav:pause ( -- ) +ifnot: wav:pause +: wav:pause + 9B adm:fkt!b@ drop ; + +\ wav:position ( -- len pos ) +ifnot: wav:position +: wav:position + 9C adm:fkt!l@l@ ; + diff --git a/bin/sd-card-basic/SYSTEM/words.mod b/bin/sd-card-basic/SYSTEM/words.mod new file mode 100644 index 0000000..c0165f3 --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/words.mod @@ -0,0 +1,16 @@ + +fl + +\ _words ( cstr -- ) prints the words in the forth dictionary starting with cstr, 0 prints all +: _words lastnfa +begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= +until 2drop cr ; + +\ words ( -- ) prints the words in the forth dictionary, if the pad has another string following, with that prefix +: words parsenw _xwords ; + +: t1 1000 0 do i . loop ; +: t2 1000 0 do ." test " loop ; diff --git a/bin/sd-card-basic/SYSTEM/wplay.bin b/bin/sd-card-basic/SYSTEM/wplay.bin index 0687f5426df8d9e06cc0a79af3773dc94eb00f64..8f21c84d1674b7c86a88643fcc16261764e80e4a 100644 GIT binary patch delta 236 zcmdlZxkr+XVapMg{CykQ{FoUvCWkWT2&gl#@o8rQ3DH!>3^qQk$rqVD7}YjQv7|B9 z%d;>rr~kHh1MBq+;qQHiJ8G zCpz@R&P9?lu~5;h_m*9e_f2gsjs=aV1Py3G z4~8&?37p{xA0Q?&*&rJRxcA_J4=+woS{c*<7fuQrT;LA6PBaHk*JwLkJML~-E^ep( sm!)jhxh8Bz99VFzA{uN}ge}7=w*CWtgDv8E6;~o$l40Y1J93bMeg|?VyZ`_I diff --git a/bin/sd-card-basic/SYSTEM/wplay.mod b/bin/sd-card-basic/SYSTEM/wplay.mod new file mode 100644 index 0000000..faf878f --- /dev/null +++ b/bin/sd-card-basic/SYSTEM/wplay.mod @@ -0,0 +1,93 @@ + +hex + +ifnot: mod:wplay +: mod:wplay ; + +\ kommandoformate + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ adm-funktionen + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + + +\ metafunktionen + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +\ wend? ( -- t/f ) +ifnot: wend? +: wend? + begin 50 delms key? dup if key drop then wav:status 0= or until ; + +\ (wplay) ( cstr -- ) +ifnot: (wplay) +: (wplay) \ ( cstr -- ) + ." Datei : " dup .cstr cr wav:start .err wend? wav:stop ; + +\ wplay name ( -- ) +ifnot: wplay +: wplay + won parsenw (wplay) woff ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ wdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur wav-dateien sein! +ifnot: wdirplay +: wdirplay + won files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (wplay) loop padbl woff ; diff --git a/bin/sd-card-basic/SYSTEM/yplay.bin b/bin/sd-card-basic/SYSTEM/yplay.bin index 68c980695e80eb48a2ee9e1d0577543ed7f8fdeb..5a68c772f9fdfc2b575f48c70b7637a0737fa2ea 100644 GIT binary patch delta 248 zcmW;F%?bfg6bJBguY2x{Vl_6h8Rc_BMv5d#DdiDtlm#I*N_ITJ?54;g*wJ_co`i)` z9zpq=#qZzws^cZSq^9d#ElU^OmLeDQb{qMr-G;y_x$_T9JCh`MnKPGMf delta 249 zcmeB??2%++*m8s=|Mo^UdnQKJ&2CK78Cf+M*m%_^KVr6JRGX~8V$GK>UY=gF%XwgTauMfgu`*OM!SQ5U*zy zVPItAU{C{MZy?TQ1Iht$JrK_T;+H_|!44E-XJIHx%uUHG&NkF5O5FUM^(~XVDXS5q z1uKw90pbi+BO^vLRz;u?Gniy!RRl=@`5df@46Me+K$ZwtMifj6ZWiIJU}j_h0B!*% AZvX%Q diff --git a/bin/sd-card-basic/bel.sys b/bin/sd-card-basic/bel.sys index e130ef297160fff645abb30fe16a927c30d02790..e5348913866ba14c0cf602caec2bd69fe60d9186 100644 GIT binary patch delta 2558 zcma)8Z)_aZ5ue@Ly<4w$FE)hajIp^O2N~6M%_+NiS2_0CiNl2y5+Fq>HH|TA>m1pT z0BWI}v+oqgxqvD`j!G`&!+r==B7qc(P*L@cBNA0MZBiAfRSX5>#HnP^xiYOw9lGc3 zyxoiCr2bG#v-4)&{Co48_s({U6*J+?hr-h{H4v?n`fYJ-e_D<5?}-wO1_fvg0qjKD zk2HpKA|${h()+mn5a|y{A0b@|HA9sIum)+pB*3%CUqm{N^tvR$L0N(0)dKtnsap}? zC8Rfzii%`Hl?u?HO7JaJfURl`q}AT!pKD)9*3TBLx>C`a-;uZAe#g3{&FS5^y&bsw z9V#T9t8&s2kdHNOYnN7VfMi7Kkmz0(e3%ZMvQr9d;2_#4Up~y zxErcmfGPmMT7d_kNZuchdZ_sz1g?9{oy@)^m~x0S#I*uF4Wcj*558dNDt(mjD*ZkQ zsB{kzm?$za$i%%&`~edmW8x20`UvS&>BHo4l|Dp%q|)7FpGtR;K9xR5o>1unq+g}q zBTuSyr^1P~NVg~)rV?+%<*f==D>nG@9Vpi!-JUxmZVYi^jUu?6xy$0M<_2z8JPYwA zsMB7uJLq=W#Sv-OxlBaUv|yCe21wZWh25#+r7>00h0UQxZ6L0IvCze7n%J1NJ0|QN<6}Fb;YZQP8jRA%dFoEF zUhB%W2fJl$b407xN&S{HxoohjHWM-aB#JTCLJ)&kT5c+M*KL`#TC?%FLWfe?lFSdb zBC8(Cg+m)n4b6m??VZM}7$1wmC8;h^BF&t)+ibgy$#RL7P~uP|(iJh_E!==^V|XT}$V&4KWUa8-ijWhD_KImwuKcw#q3)+JVD^YA#766T`*g z@&Uy9yA0~X4C*rs>W>-Je`8Spn}k&QHIY>MFH)su?jo|9=_jh1*+;^}4QCE1UQ4=l zM;18}73=-Rk;KBtaH8~Eg+Zpk@LZj*$1iKC#}w1kG1sc)#;zXj2DksitCC5Y`GkGLIX|(Lj%DqNBWNSO&+vq;Uz1yxP5cHi zEvj&+Ry)5C!ufoPci&fHHy6f<>y|^U$cFd!j@9(Bc=fA@Y%4={D?@faL-v;pS&Jci zl9&kX+YH)w5n5V6Xz7%K6FHQ^czBhTqY7N=fBS@nXn@C9Hd|5Dvd%v<+7f=jQ}&cR zuLypz|2KipP{C%40mWZM2>&$-*HbmIl^+PN_evqDB(Bd|oe%!?A@kw%j7QM>;4lf5 zW%0l;z67Qcs|*U^G4UsM`A96Vfi?(Vsw_#O!Qb?~NMLS| z-&=f{5}YXwm%NdgvLl$pvr$Tk(r=U$Nqp&v5uNpH#ZC;Tww}#D-l1QSgd+!V zx+@Q-FvJ-tu`!0PGQQ0vWOF0ju#qAX;dSxOSn6W4HmY50(k@1gG)w<{X&9rYyp)Gp z_qS>X^tnGq`TnO`FEkHn&!N!7KO6(tD+q8QAVCN6M+AV!DHN?2Ax~k^xjO$@(K_^L zak}YKm(E|yTZb0&mq*v-_n7PQDd8KZIbAAB!lFZ^Z_=~;arYJeb@w&t_wH-y#k@?% zFYV?oTxxdFuWiBI%PqNVe8S4FxY!ny+x7!h;1#S#-u6 zq1-14<(BBQYh}lsJ%_IpE$)hWGy&Us)q_X|BmqTM=c_* z@rAKxr}4iKesnOCKe;=bzi*a;{1+>Wm0}_7Lc=@9lzp7=_kR|pTuFTcp##We!10(UXH{Ji%h_^HK)-Mpt>h7E1at!8fI%Lk6yPf8 zHvzu^ZUe@6KPqt{Fs7 z!4}Wpa^@SXs~OS7Xj~DdUm*^+RC719piDOrR;C+Co=i6o>`>03yh9ru`nE%x9Quw- z8^}(X){|W_eU&uJbUk@jrgdbuOl!#=nZ6=1oC0u53|zn!gIWk!I!l?dcr(9ZPl#82 z61HCpyp)d+T6;c7ysOVK#7z{wf?-sym?6T};h3tbd^tl3`Vxh~zC;mW`x3=uRbQe+ zZP5sx)=ni#RpM%84-OmU)%KR4t+C1k_*Lpw{*3|M`qLhXwXp(L4X8 z>(?xNsM=l|O(aSmiN5(>&QaY0N6f=K_pxtCh|_Uf1m-?##!TcNy@U!E6fi$84EX=8 zgq?;*q#G8dU~0KMiK!>-A0Uy=;muG624C2^$6ATBb+%JwDs)M8OwMZl%e28(1dCq^ zSmK1Y0}e!qD=TsxQP^B5pwNZv#% zyW3INi5Ux&L1}(7;1t)+zeh~d+1ejak+;Is`2&IqjoJ|Z@wyw$7_x_!E z?xIb>yIOEO-5x5?NN$|)chk{yTcjTDs7-&TL`e94ebBkzVFB1|&-$-P*b?(#>z!Y& z&1nJrn(%|BK}@tTS|myY!Uj2SAadQWcB$8wtJi&6%t?JDtw$kO1acj%+FPY|1Sf9z zSZ!a`HGi9W7|3#VTL7UNoQE#t3FujjQ5Q;?M^KWYDQj% zi0`4+HaeOznNj`3YE;`4M3E-nh<<$0h~D!a9xxevg|Jw^S&7)J8Ah=tHyGc?pPMYc z*Ux~C@ICVbc4)>%@sNN~mQr>|I3^C6ca0>igu)CwWZF2}d@Pgf7TB!cX0y$Pm86F= zHJ7`_q|1yo*^l_Fi88UvUHsX8l$kVK*CwK(<#QX=vz?K8R(+J zE1(NY2j5)0i^0D?NOi|AC||~RxI^V?SB$Wh=xPS19a diff --git a/bin/sd-card-basic/reg.sys b/bin/sd-card-basic/reg.sys index 7bd5079cf95d3848d32c1a856ea72609e2618210..a93f83e2b328b52b729d25ec7686ac86bf88253b 100644 GIT binary patch delta 4931 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 delta 4884 zcmai24RBP|6~1?K@5|e_o9rgp{6R=UP((n5_wtsv6!|Bh1d9kN7$BRxgiYK?f&qi2 z-M4^UM5Yv;sMs0D5oV++3>9gejyhr7|( z_MGqBd(S)P+P z6X*w0A+m<-45{SF5F@Wbvam|V0*k{z@^j!RAX1`|Jtc%Z0UU!qSP~|SO2g!6DIqVF zGBQ{iBsFD(M1l2XK{7U?lB4B>oG%a3<$K=y^|Af*O*XrMX11SHjH%R&D#m>LP7huD zS~1!vQH%ihQ^mN&BxcSSAJW3#o##HLRHmlWO!~NDn3Ve{FJuEc_)FmC{b>R}jh&8F zG!(FQq)9Yu&Hh@O6f5-E*2$tGduN(FwVzO1F{~hl%?nzw3EOXBi&39q#DeVNiwI)6 ziP8PU>~!E#Cl5Fd=W!uVK)O>352Oy+ne^yNO`*J+rGEj^Ajue({u#*ClGL(v8f1zj z5ti-;u_P&D>2)A8CAos7SAoovB*fB7K$;{8v-E6`W=Tp|+5lN5Nvf2k$AhhuteB;% z?Tm9uk_MIzg8W&Ma^_qFc}J3Q%=s6{2a=3s&PO1BmqcUE+aRA-YK6%D2h4c`>~lF( z&zu)Q&Ph_koTDJ;D^nu#3g#R@3`7o9GUp)>E=d)0?gt4*T&Hmt}n2K zu5wd>PP!Jqb)_YZagp&9RAZaCUyQi1!06&o-YhSjJ3AOr_rsH@gxeCVi7g{ow6upN zO~qJAGrOL^pxK9;G;1T~%%#bMVwA!DY;MsU7(+Cv7&p7W3eHH)rkQOIh!K-t19gi~ zqf&iTsFn}4$}~ZG9&F7{8LF6r)npz*ivP3XI74TMv`zlv1l+(F^6W*GY7Qd?eaL;V|EZ zXDWs|!p8_cd4$IVzh;EX^%E_o=nB6Qv22$PCV2*M>0rVLkGbLE38GTzFGZs8Rv~0A zweKsQ7|9h41yPK#+>a)=)h8Ar=gig;Xw}oybJP6)=HokHsE45{Z|H2s?CBJr93n?qWQml^I(2O-u5TXDmsC6m8%v-jeH<7VeC^xg%z7`)58q_k$?(ym0~P{5f* z;CxjN5xX*q`vVi<^ET+k&}(UC?;|-siKJpg5Mc-=gqu6iSb4L1v~*m}3RGHLX2n?E z=^(}cW}WtCxnGpl&0pG+#KY?UuJZQvW;K1V7Sc-;DINMq4Bn@COTGtmus8x>vg0C0%gxfXel+h#ncKEvB`ZJW0* zkjf$6egozXc345xk2#%3c$@zoo$>;+%T8pS9%?2r&JQQDyv=>7x;oruTC+NR>venz z#~WWuA9VjwePgPL+I;b>J?06k;9Pc`POUcHMED|fGHdm)78lw=VQc42I{I#&`UJHK zBu7V62*1%_KGT4aapAftQGt&U-h@uoeZ+xGMh7?e?)JQKp2~YthJ6<17Q#iXXES@y z)nQHW8xqLX#%g{$aus&}h@IH{Hr^y^UDxGJBljy z%nPzZ?10Iesnx=p3BL)OB-!fA*c!o>AEtRh`7ZSq^$6hxn%-u@bwjr+ zRF!t(pftOm)x@fsEv@@j|4Q9b6N8rTZ0Ed$I+~g>e%if$%&1heolmF$`P;3 zI#cn-;&j|PJ_C;DQGPw;b8;8;Yuq-acH5kVR@K>fD|X2WpUvhJ)l;&F+qSAc6dP%U zb3&B@n~4=2W*2_lH)==wn{dWOJ(}FlYj2vd#Phi%?^6_CI$tvEQ&a*zg@8|)J6^l| zR(GK8D%$QoUbie2*PQic4>6Ox{l{B0-BKi^c#PI_QDHVPb)Qhlic>cgLpjP zw4}@qc(=K2F?`*cQBO0wsF_JWh}I=qnP~;OeRpA=AgDV0i2qr*_=GLy({%p^HikOLc z*AX7?78z~G&FR&Gz5RnIKyNGZj`yNAofHcP26=0%p__40%?(bVz~Y8TxF=s0IBIhj zj~!Ek^mVff6U_u~?=kxlqIksY@6F&cTzgj&$}dJ<+M zSMY8z)?4C)DUkK_fW&D>*B~H0pD>PqPAw}csNMdBL#v~f#?Zbtv&>UkdVrU Ud4{Fn;bAV8!%#J1fQvT$zn^1XiU0rr diff --git a/bstl.exe b/bstl.exe deleted file mode 100644 index dab87ecf1f74a5240f89ccebf1852ad0db757e9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186880 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 literal 20458 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 diff --git a/flash/bellatrix/logo-hive-8x2.dat b/flash/bellatrix/logo-hive-8x2.dat new file mode 100644 index 0000000000000000000000000000000000000000..109ef59595746f4b507ce708e2ec1d52d6d6a8bf GIT binary patch literal 1024 zcmb`F!3o1K3`GUG7PL^ns~b8%SJ40l^?kQVYB!{pD*PmpB@6q>?2i_?SgUSsYh5g= zS%g`Y^skuKtdP^vt?>NWqR{WB+C54>q`7?(7?qXhKFIJmlQh@QJ~{15bN=i*ZQL@w zqCl<7oT%r**4L(lStk{Zqd16IlGaIzLC-obau4ey;Tjv;TPG~O%mP~R6@z;tryQmG zA4lPq(B4L^6x0`~HER!w*>SLqV-zvHWk literal 0 HcmV?d00001 diff --git a/flash/bellatrix/logo-hive-8x2/dat.rtf b/flash/bellatrix/logo-hive-8x2/dat.rtf new file mode 100644 index 0000000..e758f9d --- /dev/null +++ b/flash/bellatrix/logo-hive-8x2/dat.rtf @@ -0,0 +1,275 @@ +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}} +{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20 char y=0, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=1 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0003_3333_3300_0000\par + LONG %%0033_3000_3330_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3000\par + LONG %%3300_0000_0000_3000\par + LONG %%3000_0000_0000_3300\par + LONG %%3000_0000_0000_3300\par + LONG %%3300_0000_0000_3000\par + LONG %%3300_0000_0003_3000\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_3000_0333_0000\par + LONG %%0033_3333_3330_0000\par + LONG %%0333_0000_0333_0000\par +char y=0, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=3 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par +char y=0, x=4 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3000_0000_0000_3333\par + LONG %%3000_0000_0000_3333\par +char y=0, x=5 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par +char y=0, x=6 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3333_3000_0000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%0000_0033_3333_0033\par + LONG %%3333_0003_3333_0033\par +char y=0, x=7 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0033_3000_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0003_3000_0000_0000\par + LONG %%0333_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=1 \par + LONG %%3330_0000_0033_3000\par + LONG %%3300_0000_0003_3333\par + LONG %%3300_0000_0003_3300\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3330\par + LONG %%0000_0000_0000_0333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0033_3333\par + LONG %%0000_0000_3330_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0033_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0000_0333_3033\par + LONG %%0000_0000_0003_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=3 \par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=4 \par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=5 \par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0033_3333\par + LONG %%3333_3333_3333_3333\par + LONG %%3333_3333_3333_3330\par + LONG %%3333_3333_3333_3300\par + LONG %%3333_3333_3333_3000\par + LONG %%3333_3333_3330_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=6 \par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_0033_3333_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3000_0000_0033\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=7 \par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +} + \ No newline at end of file diff --git a/flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat b/flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat new file mode 100644 index 0000000000000000000000000000000000000000..109ef59595746f4b507ce708e2ec1d52d6d6a8bf GIT binary patch literal 1024 zcmb`F!3o1K3`GUG7PL^ns~b8%SJ40l^?kQVYB!{pD*PmpB@6q>?2i_?SgUSsYh5g= zS%g`Y^skuKtdP^vt?>NWqR{WB+C54>q`7?(7?qXhKFIJmlQh@QJ~{15bN=i*ZQL@w zqCl<7oT%r**4L(lStk{Zqd16IlGaIzLC-obau4ey;Tjv;TPG~O%mP~R6@z;tryQmG zA4lPq(B4L^6x0`~HER!w*>SLqV-zvHWk literal 0 HcmV?d00001 diff --git a/flash/bellatrix/vga-keyb.spin b/flash/bellatrix/vga-keyb.spin new file mode 100644 index 0000000000000000000000000000000000000000..5333e3a05164177a015a01f9cc70a545a0bc6284 GIT binary patch literal 94800 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 xrI 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 Q)iZ{_oyLVf$h(RE4}w-@ApigX literal 0 HcmV?d00001 diff --git a/flash/bellatrix/vga-vid.spin b/flash/bellatrix/vga-vid.spin new file mode 100644 index 0000000000000000000000000000000000000000..bd9321d64adf629901a1ff0f72dbea7ffcf022ae GIT binary patch literal 55312 zcmeI5OOqVOamOd*o5POq!3Q0DSO-ZDWC8*}P$UJ5mPk;P7$I2-k)rKT*c-qCSb)UK zSUf2C@qK*s*U%?iMXh%X<9LYs}~?ukCF<-F$EJ-ezxed2?y=#^%k<7n`>? zZ*AU*JD+UsZtiVv#nlI!$8r5Et{=yzXVLQOn{UR|_yxopo1e!w*EV;e&!f2dUi7-Y zIf&ler^UJW_G>ZPrFgv+_kJAT)8<~ht_KF^5D@Oh^{s%j7kw@SJ`dyiVf5GwOr!}%gFKeB&l!C*;Qu%v{KMvHwC4)! zpKP87l)VAo;c(~N3Di47D>UqR^mr090kcQLcn^aPXaqff*zP>}oAqczv>gnsR9ez^Jm<`*N(%UP7yIivFKZ}PQf^v65(xYg2M-_KtiEW>Ge zg2n&mc=67k*EOy$g%(_h|8K;9Y%2ElLP*u)_;h9SjgX>zU5IO}@ALSN)N=haWbiQV z-;7U^dgTA^v7J5|Ec(+yEAJ0|fN(eZ+#2pZ3W-HC@5g7s6QlRwpBy_0qSJ8}J1$N*LYxbTGez~O`pz3&9A_BQXvUqV{OhrP`N_KLs z$vNH$+KQIn9DJg)82@OH+k;_ruWsdtH;zZVJn;T3M!XReKG=M|V7|`^dY@)w+V*%l zMeBQm)<8dE_tVx>CS2c+J22g5kMZ<5CQA#YCt zdaqS_;q$H1L!N7AO`U6VKj^`V-or*~EOK-+zF$J|ZM3uxbv1gFtF++U3b`^(dH*1! z;*;Udc96=CgEr6#jR020;rLX?_i3|tt%>5v&&eapl$1}*e^saz(Y4fkY z*ZVH-Eo(*lr7hiVDZa1A+P=5>*I#a4`;TA#XZ+v1b|wD){g-=Td+>aP>+6G$-)lwo zMqZ^`vTF8Pz8}1JI&g!QuZK-6+cDzzPpBD?mH9o^|=4t0V`rU&jlz%fd>Kq zcKl@?Dq#>oJ_$>7Jz4^hHKC=qF>T+mVY#y5kw8_&Szvm5pec6v$?*(I&xHIAc#}iZ zyvP|T27{*VWt#}i>)8oDUYcmL6mQ#f=6f?)I4@tX2JYX8e#XY{meZt}J*7E2 zAa?0VddIh*^I zs*-A^NLr6FioI@FA#oBy%z~i-$Ao)qsWm!F>m8{9V!29$b5;VIqyes2Q}?1r@+adGaFk!pimeq^dl&Yl-LJ;DmE`>d zEx)j|?I{(B-MXvN`i-sHYheL-VFP3hXpc3Py^}5ykz?7|Ge?VM-(;(?o9{;7+wro_ z`F$70HNB4py}{zs5BUHq`<_}6@x~aPSkB+12anzn&!=r`Esyvl>yo@&itn!Zq(_mO zhwXST{>r)HFWC3Uma=%z8v7_uTYl`7;81Dz&kA4LC#aUb9MoaNFNXhUsB`u0Ebb2R z29_6!!w>AVJZ9uy@szSaXN7a=yOe%iQna+q*h0lZvNo1rYcW0OHV8~dZhjTtJJhNXgLRJ9PN1(@&IlR){qEFs}#EONsOg$^`BfYco5Mz=TEeU2MKlT9X|>=B@;k? z-SF%oY2{vu@Aa@TSQ~6z9ZzZ|S=+%l?7=DqGSf(a`&GnO4MEhLzrnTlftLpG(l_ib=4F;DFbPEJI~Up8ZzmtEGWRbo$ubLuMuC^3#^m+c;_GN>vE#CxQXo^!~Cr zOFa`EQ4I;Reuv`$miFv~aa}6%a8_+4r_X=Gu_%ZZ1YY`YV4XDa}2syYb!C@R-QiC`0nC&9~yyn3{W=Ka2Z#S@Op4 zwB&m;yU*fJa9S?7A0C`v*cHZ9oKJuB(R+1*17?gUDrOsY**uop{AtlD_uJg+)#G?t zqidGzk513g9;fEG7Ziae+QaPASvz@1yE6%1(=0ubI@P%0H5iWf0FA97f#It`Ytu}$ za<7`pwO@(0+sm+=x}R5N?xUIKHs6W1&i7jC_XqjyeS<81qu_hH=O^CvAcBFh*lvCh zqY`^4--JFw8K7f}v|gb{*iq~Uu}W47p(}XiiffUAtZTGCz@CxELwW>@wvs)3*d?!R z;Fxy7T>N$g+wg5!%O0j_Z>$zJYrJjo&CPfWV5okQm1x;(dpvXD289y>(tuSd=>$|f z4(yC%@m$EEDv6;ja;f`Yi>rLKa}iI)QTyR|2}JJl3Dm-R!m443Xz?j^`tOgeRjC>1 zNMfR^?Xk@RJ~`;RX0_D|_wGsVzl>nJwMV)g_WOEBFqA1}rS&Mwc_EJ}FREv_8}$rn z2e^mN_k7S&#kzO|(DXZ%#e^qFw(Qj9K|{qUc}pd}<(g66N2k2wy%*Jwx#OKRk+k1# zK8`sa#7o|&d|}V5hC-aco+sb>uUxscqG`qS_sZma9JuJ)dc7nLR}>)c(w4)$g`snO z%U4zGB`dG@*h{#;TyJp%>1V;8tW`1HJ&NXfE@+x^fYdSD%VBNZzW45#Ctcy=en>x= zh7gE~Vdgsrm##FU|{BpDr>s!`jKqXh3Dig}yCKV93qP6PNYa_s>*z>>6|udZshz<@HP^p|bV@@ftJw8xuRLMR!AtNcRyX6DQZ->~Yjty&$s8TCi ztiiICg~YPtYL5FnG%7y{%QxeWB3MPI<@bA=8p|64Ew2XkwYylio%$qwW3AQe>Yy#~ z^!%U`%JKNy@jJA9C;FD2blu8Wy2Tn=%CAqjC6+g1{QbZeT1~yS;q4HYWlY?*G?r?y z21l~TrES8ZK)v&uS7vcDCg6zXjXfz_`@|7@YSrwRrvKp>%Q=X>?^+v`y0es)R1(%vQ;nywL(j&ilKUI_Mu zh-&__X#rQ)aF!MPeqoP!YGyyAgtZM{0-c`A^K3&Ssgzd41I|P^<X@>^x|_1u&0d*uD#jce1OokmOQ)ligU zoExWId&)JW9!YtdHQZ@EbMxeUto^c~E!OpC@@72A0JZCER-H>&gIhh)%l`z9L_r@1 z7nN%!k4&^KX=>wg+NzfDR`Fid;(KxxJZFv+vcpD(!KRC%V_Eqjsw6881}ph4t4Ggrne ztuueRN^4rFV_%%zM);C-W0zx%(B5Xtr)|(WcV;+|&S6^6m>eE#{Ulno@9ltxifEvB~xe#_Wy%`EKO4_4eKD&49EH|kUt+T68r|2EpI|%B5!pKLcFGsET&>x0Xm=W} z1+B8;_Xi;@+9N|(EpL|17u{jVodszHevfu)kXP68B=ej^mExC4tdgpgot8auf z;FVAr$~tp6yn9tiD@g@oN=i~}*;Okk=2pf&`(bx1kIBQMSo!bAedX$wjg_r-b5m_g z%6~6riC0?df}c`y%N%3bRU4TfgwMM)W5@{G;7bp$dTKnC~K(xtC%M-4$lfxyT5*(31!VZb3af# zHXc~yD`ClA|E?t+6G#I2_g> z;@y5Wao1?VHg|fi9>?Oy(ZTWc8VPEt;F$a%@U-@T=Fj`I?5$9>D&w{UlR=aKcZr-sQe!)HuebL-BrY-PpqH2i4` z!N^2CewFgIP8y~uS8Ja~gmP;zpQg;(NOcU+a%@_o%^wbbJ&Zl0srQ#7)#WNQHL~xI zBNa&H*V>y!TIv-X=^zQfb zU2@9a>r{KP4|>jz43;yye&TqYKiG1@vs9hvT3UGyOW)_RL!#Qe?}yKz=M{AFFY8gy8tiSXo-pOFf6TMk?C)RoNfIUI($Rl_R3$WCie4{O1`geIL&}A+Dc! zt6`jmgAEXDX1-?jT3^Y8>Lq$=9lz3exU^`!Ty6N(VR>&nf?}o@<#e77G{@^T7@M1ZazNZ{bt|({Yq>d1nX~0) z4|C|UhBjj>EO}vHrR4h5^>)}9(&ZeyGe66IscLBFNAkDg6qU1j zY5m2QxjdY@==**r5@qFk5cY|CL_2tuIvXFmgm*cv#s#OE#^qW%MQ_=;U74j^=dT`n zwpdPNZ`aG~ys*=W7VM)j!~T9+sdYUW-i2|iX^HWChFNfT)xqX`?K>{F$Ku_bx5KJT zM1US4H=oCKOApV-nCzlQt1*f9T)ur5RQ7+K72Hp#)2p{J=3RQInhDLhoF@|Q-FN-= zmru*3tY6^&bTb8c zMz^d@DyfDhh;DV8Qcj>3Uen8`}-WztF?~ zqsUeOk@GIrN?z+Dnak6$M9uHp7r!llvP45So!}WWMBi>rSzNGG#pOF7?%}ajYyJ|;$byPFc z>y`KLl3cHKG4yj>;Zf^zxmI~kKkFwFZtrT0t7?0)zbKFuKdKby!ODA6Q0qzqAhYs* z6f5QQnNH>G=&|IypTuM=r)gQg8DnEt=XH??A@ify!1AdX@=$PyGi0@gDa+(~))JGs z>oLX1=CK2V&X*(hp=<*Wp6%i3EAo8a`(oD^TdJq5z+RcN5+Y-(4pG1E!fA6*+GjWP zM;zZB&*6iZ!~5|&f0yI;X*j!o+^4)l9zw-W(Jy|Gd{SYUVv8my}ygW zBWnI`#66$hLB^8|vU14cO8=CZ5{LSFJR?`X)$OJ}Da-yO=1*M}Ij5r`2dBIoa%CTw z{MhY*cakD@BfXoi^E%Br`P|ZkWzUBiyYXzK)mMT$x^m0@yJz#x@Cyv0<(t*KT1}DvT9zT-4Tbq53uOgn_G+)Da3OQ3rwG~}z0XrnMB`qM z-n}U(@aQnOuKv4R+VSuY;kih4%_;V?h`9sJEB(Z)KOtqex8Hq?^?|2UkrAu>34PsZ6)OM_-SdM6N6X! ze6Z`K-@c?~<}@Aru|UkzZ<$&o{5f^?-QyxfdU)Ao*+8{e&PyUaPGIRkFb`o zGt zulEIc9s~UOD=j3k!>;-aNpE82otpaW2Yv}6_sdux{n`#QcoK4`N^N}e=R?$B+i0A} zHWE0h=Hb^L{d@#=Sw8>O;k-FKK#w;6UQ>l%gy6h7`XgDp{n_o14e>5^?GsR^PBuZm zV3nB#VOy_~RAn%0&U?9aT$^!L@}={GY9H%j&JxNK;znf&yyL5uE+~IAL?IKm#+qv_v1TB5%15nvh zR~nKspFV_VGu@YOat`TnATK@}k*uh&*Ew|5Y9{_;*lQ$7er{Q5itnS9o@&!;3$$a5 z$=sc_)NU~~jnQC!k?O;s&fE)Is1qL^MY}%5?e)6`CaIm?TbnVQ8?*PFVf(wBheu0$ z>NYR-Zi-tzmqKe-fTY<`td7XYII~g0PWkT1Z$euqw>O8JtjF`*cm^=nZTUdE?Yp70 zR;l%&n6vriKIMDPIORnVM2`X`^s}IWXDb?%c&)uY3#?2p^pu^17k{n6>cvOh1p%zY zf!YtA>o+HFigeb<8{_Yiw<)aF(6+T`ro!*!aEi(=^M1`X;B9$JWX^PGVg})5!A9X*~N- z4MA9{7B<(`|%w)NzY>3r@WKiVEVfK_^zGTIy*zfLL12`gX%~QxMu;|^Z)IN zy-YoEbNPxgA4kEVrEyd%Cv_ZK%HH^T9p8IV78sw^iaN$~d}j^jV<=z79Wa+Sygc%m zTLYEHpSM40b=nwoEIq9u$oU#BwofV(b!&e%_g(jA_Taa% z2j|LL@0Mq*p3!ec?dKx5{!Y+}k=WV=eSVUMpYDfhTKEu znPBF`sV?K$z7gM1omKDLubIV~KJD}RWv->(Vee;M*k7makh55xMg+jVEwu{JfPH5u zp&DS$%jBt|c0ZkJ?hk@)Sy8uZpPqTHnQI%JrmQaWeCsMgOY407%6dF=xBY4(8{{I& zc&6R;t1I?uxhhZ0X{-56*VCTi)T67kr)NNQb$?xbrEtos#~uwcSCzCjj`K9k zo;?~G#?tqeei@Vbir=1bHOCk#nM3{dN=gM<=BEQJsfLl2Qdei;jz`iNc6lES5~uq) zqTY$y?P*<9(aK^Pzco73`uk&k`$@~hzP!@OkIw=Zo`A$kWe(YuuICy(RE0Hl>Woe$ zuCKKcwK$aH^{!h@O)2B|h?BQR6O}4H{l#>|3X>V}6OiqgI>l=GOt0SBE^aTA8`q&g zQ%*B0S3l~jvQCcYB>fv$V6QU>cm~RKDw4E!i;9PKHoHDk)5e%?$B864s_#y}o4Wl| zRua;=z#pvu*L7zSt&#s8ujGdAzYooZiD^ zgv1#y8knW6&I-rYZrdNtm?Al`My6Ul%O_FFNMZW9jIo|A(HrX=`-6HS{_~*0gF(jN z&f}m762~>w&d8~3E|lT9U@9%;BRr3HB3PcxUPA$_y3eo`$CIPUhw}H&Te-lJ*8aZb z5#H*#FX5W-rua&b@P&r`x09EQ!r ztI`<_Er#`H$M;m~Bcs5RMscDAzOSQRdok0rRlG}#yzG>)^nsi^Si>Ru@SCT(_Kjnn zdd{5i@G$!1UFIbJFMmCCz7AvRG&I$Ft3CtW@b7&(LAJnV^dZXA%2-I!4KJ`09}g=n zYa34%p?^eCoKPUiNtpT6Wk&b;Z8?WphRaW144RmC?u3NwpU4Pvel;vGXDRigeV*k) zURjUlY@46^u+$}7voGbxtY}+2T*kzvihhWubqS6q(0={Oz<{DAphMsPD{E#I_PoG@mzpIZ~0&b<`N{ z{?vN1DHT3>Y97WmEX|{^F3ugYLY7f}UB9(v_VPs&i^MSVU7UZY)1?@JU%euCgXP7m z&c6MtRu1ak_nQ99roPk9@b4O@jY3OmX->+9Fo)he`m&RETPd>4fdBj%vVt*h zP5S=L%eO4+By$b@+Du7C59JD*^lq=lnUb=f{bJ=6bM3T;)JeJe_{0-WH@0%xZ zAs_YGlcHYV*EF2=y~T^@BdOQ69)BL=g{SSzsIqKhEWy-S){L;n(91hLOr5_i+f7}U zd0lIR_S*dmgVQmzGv10eGRroXwM#r&%)yxZ$`9y;WmOM@_bP7(U$^Ih8H4t{htZn@Mmp*bPHJW+TThYc8gEMSA%9Y*8%C_ConrwjN(^ zPhtb-S=dY9EC+!Hk&3W}mG zV~UnZsbsrne(Su@S`!juwY<=dyqP!&#s1N)KKvejIx6MB4vS+J0kku=u5X-(2i0cI9s~`WpK5mCyiG zI1~y!lJD;pkLCYkp^;MO@j%0C($_=j_w&W+S(#Vz`*88DTwjh)=+ixEJ^J*=fd_w* z|KPsU#Y4IKNS@(J@1fV%hWqF-Frar%2;kDx>1%Oj%j;Dg*zsbFKMDkAL`G1q&2ZH%` z2TB0SKMila6bRoA5}8s1P#z8MJ{_RnT-;i`zt|h}(RcD6e2)6T@$U-k@8k+_zYBxUi&9|g*DftHumJ9y(udHzJ&0q%LW_(A&hsnokKH9Z|*+#P!S z;#@FL_t(_~aThm{pB_~p^Vm)s&S__?~xOgQ}0y_9_psbesM9Q2FvU4K8p2=G( zX@pN4pk9?W)hyQ*p9to^6RaG`|NS#LLmB9tm>Q>p*7${ zL)%fyEBQlx*A}m(-*^s<3q8WOsd>JTyWq+bf%AOeCcyspK}VrHaEd$n{a8vtPbrQd zPl`>wf4H>0%Fknc;Il*F&pV6HqZ*$KG(^kMLbTvBLmzF2;`s}Cg4SsppgTbyyb1oc zZ$2Kl{)yZrRboi{0!6v#NFW|A{-^v=JI|%d7enojm#rqAcNZT>ou7!bpp~$6|3368 zu08MpDQ^?ffQ2Aco66I0~(Mxg|2!sv?t(=*j4EU zMv3=b`3)QWa`Dsf&f9YRTG|HQB4s?9!bSo&DmS3quJr%i#fJktcy%x2^Kt=rT6S(< za!I?k#3}jz_fqrzpvjIzz8^^~p{G`E-<>U?)GXkE6Tu&7^<j5vgzq|NI zG}5ko-WmMUoyBeW1zV^#5K{k+{DBA5(m@~T6|I7;75s#rzALq%r*qqnTC@h$gtQ5d zgbz;!4F;|~7VcCz=W}vC^dWc>Iuv!@l+Qb2oo+3A2G85;8DL_paVj6ed^y1SPVOkA z4+co@O+bPk(Gd%z=b`8ge1k6PKRy#ZaZUcd8|neq-dOU2YL;h1S!jsI!q-RgQO)pL zpg^mVzo5CHnZTjwJ>VY;RP{#jTRl_Mpn3*4dnWJva_A5A8!+?!S${zNoaV2jtx6HJ zg}8Yrzfl)FDfACom>Lv*G^q4Q-bBlu4ez7WdALBaq1*%Nqo3D=MzDG>q%KJ4OTjce z7VQzB;}2FY_yr0_wUogKjhycqm{xOi{*>$+SWNKd~VsCc;eUarya*F!x! z!drMp|Gy_C-;-jIJY3ovXiTjcoB~}Co+%_)r=7t@ zq18H~MBO)}{6q16G1k;y>IbV_sW+q40j(9*?E#kl2S*&pwZi(Fv=TB8X!`q^+yV8~ zlL%4|NZN`W@eCA~w?&T-5=wqMz|nWWJ8_%zeZ}S7<@-0ImVB}Jvsh#H3S16PT;&9w z5};mNXer1Stl856cX=(K(~gYQ*vbR>rTqo3z8Gpz&V}y{OHCNs>K6hR&*{GaGmwqL z0iWoJTF*y|zl!Gh7kL|c?F(uD9kC#&SFd9a4)lfo(UJ1k(sr~3b^`y=7w|y9H%H)n za!+7?EhRiEK|bM0s`Suj1c#Bg_JtGK8$whKL5{=-E6CNm0__j-1~}Ypdz4WR zZhzSl#R}UBh~R9dOQ{Na`Q)T{0T8dWZ z{Vic9^c7<-=A5R(IFS!5pw}MoHmrtnHE8(t&?ex)VnzF7dkWhE34bD`VN0MZ zq4DsxM!r}c6eSk%2JmnqH6!*w-w2*CC=Ml(eC*9TXGHC27Y))I3UDM(1+`b6t<37;H`pd;}0PFkirNI<3@0O z&K&c5*`%Hdnb zy`M|_{yBM9Apyeep(N@-55AOEpf>#->O;vlgL51Gmi%^0+Ine1>f-I5`Q-bT(K=|CAjua!n<+HdG8`^pVw~2 z-n=no=mG32#;D*5c#1!q^#~MCdvr&10q@oPMvqWG#$NCk0tG@0F_uDYFKmYL@6CZT z*`nWz4|rcV@#`jSg>^%G0@mo|U=`qzpdGBA-=B!x`)a9kd9UX8^`#7RcBb5h2a9in z7i-o{Sl1W762BFe8vdo7n~3Q+*0$dZmegk;)H>g2+f!+iw(Wb7TIgeX8CKHKKKy|b z!^{-!#P;mmWFbKWs}61oVnA@$qsSeg;%*h6_opul&4 zXRCG$y@B2RomlX@g*K+WK~&-*pXVj>?d$6HtT{oAW0ersI zK5q#I&im1*g7WZcwO(8Nck%hoU+=HZaH{su@AuOI%Q|jE`_g*gZT|NaT5wIIocyD+ zq<;Mx84Q@Q^}i)GYyIcN0qR$I9qT={BqzgB%QHNtOjWVq5_m`l(eKN8;;^&{f+K>R#te-Cdu zuKIg<%YHaU3U}w+ft^G?#i{tBIs>gbNaw~hO9MF_p=B6F`R&SEhS{uL>5YDe|K6R@ zZvBsW@XkV^94hORLy(xXx4@v@} zLJ6~!h->P+?~y!3^jh7!R5ob^RFS$}koRRaebtJVQmit8B zZt+2+mhh2bg??!?EX|bD%$zuWrgI}`RZQO_>6d0H)Tb@#VkA80!9Z)y;h+pNXi4jk z%fn0`jG8&~sJUEk3*BpB`?}ya%!-1qkj?T+_)p{ch|i&&hXXfaU6!r}0KY(H=e`}! zG%HOs@&?!%6Rp*w91i2`I>ttAn%{)Ts^(2XhRENDhC`oXe&C73D);0!x$teVd11Cz zqshq5TJ>{%$cDjeiOTG}I57Ajq5dFRg)@{G9i@wFI@5@26*a$bY?7xe(|2D%o zunxVP#+TY%UlX4JmKQz|YJWp8^LWtFx+aaep?F4~V0;_dJ1Eui6Qqn(j&+0Dr4Zk; zaz|`}4tNWBqM*9!7sWsF7GVc<<`%vJy{0dOO0bxp%74v|W&fckmG2emxAOL(aMhgW zp-oyNGlq~Gg8bBzA*U|QAq!Rq)VU@j7|`sVNaZz=OIT~z?JuOQn3+L@^5!6&za6Ag zBe0~>+;=J2ucbynhb=^2_rdTh(+T1K)3CGAg!ae&-<@^(EgJ;_I+eCBEJl}`jLY{Vj*zBz2zJCmpqgA-`1d% zoe%$WX$v`FZXIFlP{IN6O8mn{LE8c=Y2H{;2>c(nxt(TAA!8jOGEe?+78kL)lJlydH(LmPwO&@NIWU(APeA9E z>9t+N2C1K@*5;jIGy{(czAn7(;Ek+DgQE>4T@6ej*Yj8~Vlj3Rd;qHd;f($}qH~es zuh~AZ1n?kXYn~2TPjLo%UPcb2OoI1b4A?~;K-&*I8|1mcV~5T}W+LX(kue47RPJXR zY|Au@7^{B4mGpnFEq=53Sng;%oo}A+`?}a)<$E2iYOZ*w0lqMOLf}aAABaEH6}N|W z<9uzHQ#!8E;s#!YW)MA>U+_dU*BL7SFZQ{r5@Tqygb+uYP-nMJ!j-!!Pys{Y{F-CXbM70qoGWO86q8}KUkN3eFtzW$E zbX*@xN=yfGVVd!CL;Pcmqb)t5Au#Sc5Z-?&w9wf{^=`ixYW+(75YvSpN;;{pqHhFf zF^yBJr7@1W^aU^HG|t!HK`x<%VaIHCa`5da?VxSmc8qk;c8{*B*O$^$M=_L4#aK*N zT~CF~X^g9Gh%9+I-xxhu7;g#v&V%{uLk)=f!B0}17xL+>XOLqMREar(BhwqA$762} zu{Nx@MTG5{{C_b>*zxcS+5u5zc+S*VQ{Oo!gxH@(qqxHCg}@9N6Kw_6OYQV%J`ZwC zU&JpMYYuT^k9WYS#{({4nL&Y7KB=GH@|rvfYSNON4n7dPFZixlpZ*J>tmS}J`o(ub zc0T0#-vlyXQ;JbarAga#Q9p{cmc9`?5390+zKPqV836%8Zb5d>C8Yt<*snmF*cXPx z#eNlhO!cdFWyQi6ygARV4>LI-;-Oi^?+o6oW*=hDDrjQ14p12%K}^+_`WK1lpvC_p zrPK!ncQI#`FsMIRhBJgYytgDWb7z1yr#D`i>jD8QP}N_CzU9hEtZPFQ0hUr%ICA|1 zbOv*hv7-bc-tin#tXG46VegciLm$D>7$xhPS(P)avVgV8qt*66hhg-CJM;LS{RCyEtZ-iT5$=(`fA#AxA!|7}XRv|*4Qn$i~{kNsI znv2O2XST#>3Y!>?y~S}`eOvIwx5nwBFx8VGcdK;OiCH928KCG)p7Nf58W(G*E z8!_tDxa`{^cgP~r*a18$j9lSApZ|mS`Xj*|BTUEv2|FEuBQ+kY@%8Isj~)-Lh}Yc0 z8$-?rw9|MC09`e>#^cXh-!3;oT~d}D#cJrM+dlzco)?9!7sqgG=_nfR5maN2F-M1$jrbVdZ!ZO1J5F-4Dp>`3S`y+ zs|ihm2=9FB>B&aS@stjYq|gS%d_UdF66UAtIS>B1x+7qp9G%OA?#TyyhSG{V(n_(+ zd=+E|#8{^cm1|IF0lL+&pih`}4befi0a`=#CFP}DQ_#zC8&xBR`pG5JoEUSVtu?kH z^vi!KExq`M`F5}ZtOfSDv=60@1&{{-e#dwod%pil-o-b1Kng*tmoy{$a7|(YhzekB z#YOsaeOOt57#1{BfR1s?SX&i;^V^9${y^FD^zimM-_u&k96=kRe#J#_m-0}|5#(^# zWl&rF+!sSs=*FN4(|tO0^95Hnh^# zJipDcw!`QMF>mUl={3M92IpU|vfh{Sg-k|RBeoOktRDp{cT1}@_|^t?sNNtzuHeCgFApE>R+Q(DJw zBMZYE1^64^i@))?Xu`MUKX%vJxsXouTA@2YgjKvKy+b^x4aOJ{BNasd za!w&%e=fTHqV<;EPvvjU8gTFr{y3JRu1d#TzmDusss8iaC+@7q!+z_}1wTQDV)hI^ zs;8NeX^b^t(2QuW()c18daTzaE$y{}X9vvb$GEnJWoh$CxyA0z;O!U?JjuRtZrADq z8^I@1KNRx4FVUn}8`r{GY%Ms7fi+O;oa*0Ak#lb~5wZIAAaNLJU_Y_L3+Zi)3*p@X z8qRj{<0Pt|F}A?mJ8-J`UAVF>mb8j)=5s3atwkK5ieLQ6jG| z+k;v2uutNAzS4a$^uLZ>cZ5UjI%jP~sNsC_j#w*eVGV?@Ysk^s;H^-*V+~pG4KQvz z&nKm+;&UuF-nYuyuJhE)vaw8RpMqx;JUCc|R6ebaQ0+mUBJ?@m$k+zIf}iR6GloR3 zGOrt1JMb6dnUplwQOA(j0jAWB>mpD8CV!}(tx(?s{%e{!nXifr`~azZA`*sNk-!h- znoBLx`!Ph(HS z;6E)cwGq`t5N%#N)NRrE{evZYikcx0ZZ@o}dJ; zf!Pw?bhYGac!Rz1Than=aZAsOH?(vbZ@#5b-7}AWZK*L!qrL`Dha#l{m3(VEx8H1s zZ*75zlEpI#b55BD<9W9Ue5$~r^k!A8ko&yh{{7F;`{AI)pa6g>+fxZU)y(@lt z@YackF*^$?rJj`CO*YUB9u6!o&swDXhx+NA$36!&nr}r=KT9iKf{mDhueNzEd{|@P zeGdE(1)CaUp#7or`D>W=FX9^J^g+2SMAMZErg$KJ3smNQ6STfLE%XhwLcmg7Pnp)% zF6x-cr;4w8P?mL-zk##Wbr0a4XB0QD=U9cYzL93!#7W*!%m!c#AA(j^WhGM8pX1E zRfOF=*zY(Ge_!GmJV6i7eJqskA~XC+^p<86!w#{wJJL63Zk(V(yK-0T27L0dGRWNz zdxya3luhIqf2^^=Zfq*T*p4Z1!T7hVK+$+@owPbyNRRLquoLB0b z^4z9!U)uT}+~;vf-j3Bc1fw%@y?RiALju370(*513Hs@$m89=7=%$}Ui*2)BLjP9b z3XKPpI4)QbY7a!tpfOjetE`2;SQ+MguGX^(G4rxY+tm^V*@O-V5H)`S{BKL#_%vu2yaBa=IQS<~G#Pg>}`LwrVEmCZS5& z1#_!NU>n)kRQ~dKb?hFjMBv!i|ALNOmFi{e*%kU@EsLM|I)zp$mMcWVu)Ee3ClP+#CNJ3!7*h$!l5t@OdL&H`Q+qsH2r_Xk{}zMteT>?f=9j))Lr_84v92{EXFQDv;* zcqLaVh3M&lSbQywXZaniZ!V{?TxzjGpRNtPdPCZTJ=%3H0KGxf9do8o41{@-80Xp|wvaP(uLZy4g!8mbX%A@dFJJ+6hY}r&?u#sNHWc*X)3^rII@T*t z7?F3-pC57wuh|>$D!7Q(?=9b$+dGeUS%>%SwXKAC>~@E?#c~6ftG4ZOVV=Dk!@SBW zGCg!mg*mpE6CllyUR}qbGKJg*-SrA{LCRJ39VLa;>WbTQzq}+{KV-5=K%71yBn%f5GpjbcZS-Kb{ zQ8z(r!b@8V2A>~JgXUX0+aS>3K4b(^R=2~fs78s8o<@ir#SCRGmKOU zL1pw>XJS=iVRac9LCbU&88Z7?WcNtEHTsBiN;EGXZ?A&y5;ZAl0spH&FG(1Ah0xD0 zVOC!}l9LT$%SE`9 z+;+0ud2oVtQ^335A3~h_U5;ktGwr|?c^h~Ecd+L=&yNzZu15)Ebm8ouP5Vw1ViP(VMdG~{r{GC)X0BoA+`WshQ)N zP(NcLp)L6@<+_;X&dYVHan<=ao0=LL2i&l#AK20=mqtUHaT;qPr2?n}YyDb$jMX%0 z$$M()J9)B+`0FY?$hmR+&UG0#z_PlmnJ5Pq_gT``C zoB+rJ+rFAjPoujb=Vmp3XD+_4tk3za4`zQ5cfP!K2RjA$pNrU?{lQ9maK|;r8#15P zPG`jV4_@2G?)iH3L}0|6K5nONy_ZRNJi837xZf5OV*C*s>6rygg2 zc-(w`%wQLB?9Hawf_LzS{ArzdlHyiZdWQM4&@#?j=QC#NFROJyJ*u~KuIxx^D9x66 zJs)H+qgb)S{sO;5Ge@@8YaB&s2T>#!K495-#;VFbb@2hc{pf__UY-4}iN+?qZyl zYJK(|yY`lGI^KtzuPoG6SFomSO)b=F9_*McT|F;9<*GLZ{YdQq&Vs(gtP3&+R^c?i z-Ow8OEaMct(&s6rNk7dy3}cD9?Y^vIz%r)Wx47jf>Varg&18WNU4@p6d69ntXQ(zu z-UFZEyJV;0GT!g!;&J>SZKNf$^{ivgn3&UD9bn&9!5_868-g3?gFq353tz&+M~q9< z>%9w~YLzynzK6v%#zeM7q^Z{iw11U0r1Vy7><>06v}YB_#5nsv%*QMDh*7NaT`kT~ z))DXTL*Ysw9llCoMZSFLeNNAGOQ^LMH zHD&Q)v66N2#cJy;=3zPPaX+Z2xc%616!`M`p}HM>HTR8GdhT;K zq%ikF&eN8fmg!=8xI|mKK5jLQ>0|F=?M>rtRzLD;Rs7n#F+xjmVL2O_D9Dqe7jK{D zR~k(Vqq;FHskX>r#CH(yI`1wSX&XvhpjIc~A+9(6U84<`0S~@TIxlu(%;2{V)y^72 zJ3)h-3LjzRVry-cwsGpZ#341}St;z`<;3HURb{%gXJ317zE$Ljyn>k`;0pGBQ}{(! zTCX}UoN`LgOyHE-P<4DwsF2PW$@Bx?+Q zevIW+`-Rm(UM-Y1zwM+ou^dYry;oTSZ?1I;yoeL3z*E5B zYAbPlpAZzt$6qPkrmj=El9C@dQPn9}>GN{CzYtuk=G~RrOSySdPK#YF+o}XvHBD~+ zEL}@-MTxz#gDH35I@PsStE6@ime5)`jJUAs68mZ+8wfkstl|Tfw6RKo-wxDMvo7)( zEhh1m_L=v?H?RPOy{mMF>8EqYp;D}uF>`TyPdQ$+&J|)WMxiq?pTIXdv3{Ta98od3~xO2hkkg-qX6X9x}VHP;y zp47>+EYRlo1Q+O9=tGWCRLj2@=4y~l8FZy)v%(^Lx4geE_Dc5{22`G$l0x*bw2gdN zj|)}%+kM7k8mX4kJJ5U{hNt*2)t~{IM&EG#$zbVyNOK|vO6Az!D(`$o{(nPw3%m08 zK3Loq4|=YDHIppJ0&tab=#(GiS>rDRKPMGNm#IgZ(n0Z%wwS98R-rs_q1GYQ1My6M zst0Icv3nA-+NlQ=+AF~Y?xFQ%tq{ZaT7IP!V*XBlds-pJsA>hhQ%frZXsQ)(y-uw# z?W12zD_DG{6tLH+R-l9^9eB0cY`_PiUX|3KneQL z>LCyViVx;SD->HkjPu9!N8Sogi&!eysmlKDat=~t#66*t?zYnw(n)3pV#+N zoO->C@1<=H@(GI+=nfgO^oq41pI99hmx$|}^E-G^o}N&xtaL=wj9QO65nfc#dgu3{ z0QpL5%%M|UCe<3gRgK@6^V`!Jf&RU`vh{0?xxU$|S|i3OrCrxvdy+6kxm2$N$%J0v zRq(UyDsR>w+Eh=M0QU7kx)G(+6NRwjy`HcO>x8(n?xu`L5?ZUPt>aa&y309Ynb2_-*8S5R%YvJW9;q;-wb;;2S~bB8*gB=hySM%Swd_Seh)O7-i4L9CT+lqB!!F` zG#ZCm!})TE2IJ0SDS0Gi=nvwQ3!aG_>W_PZxE5x`0$vm+UrC<;Q^&ITD)4a*KprxB z%~Eg5p11d9&NYo3^EqgtGqU+9TP)*$=QVvOb>ZWeM@`CiUi8s_NAKn}X+7b;eH%5Y z)Pgd)?wqkgTQa>$Ybs%l@1Z8mZke-#0N=uQTGO6z5UjpZ{tLn49VvBf@s|7{ZZxMQ zI&Ttuhq%7-@3bX1WG}Y8p)J(Ckc&NOSvYn3mvZMc@9zXG0 z0w}AuM0XnnPB@B-Yb^avTQUdxdKLhrnWN0F2mPfh`#pW9ngcpVv+$6!fb&392Vxft zUHMNvsF85!BkV1Q>}-XAUmpCI0vQ@^e}Io)h{EH%nghRo_YmTbXIxjW~xN((-k)q-2I>d&Qm4&Q)!(>QpqVG9t+o^Anr z`#GOgsBlnh0rU*=2bdwP^GLeSzS@3|V=(fY^I4^>n7=4v3z}vuk~pVTV`ZRSRer}x zdC&5`zAaV-ehvPYe@#8tw{`CM^0sVui8W|8{HaAKMPU z-!A)#H<%fKXV~Qlp3RHF!@!-7<@$KgM9}V!hF=)j9W34*KI}I=mh18aIRWf_@Rmz- zYb_JDUX|sWLT!v0f0UkJ6ap)TR&%_CQs?`$?FF#>b8b_e{?DiAxYeaqweY4mOUKu3 zsR%sTR!v`}oICzTz|1_~qehEDo#VeYxkZ-`PdOhw3zyX^~Z4VD) z_fi=RSSbIh!BJyvvd_xx2%{ML2Ck+!YPJ1rR>2lpdBstIR;6F_aa4o<=5W<~%AKG8 zG-{i_H-6`e|Hkoyr>o$o21iY|j3wsq9?ORBDUCKaQWqeuf~om3Q3I!QFm=_U+Fs4& zqg>!w{+g18)y|u{k_h6r{Jjc}YH(D!Md_0{S|fdD+GEt2zWlxMJF8&pN~5*VXmNz~ zD~ZnOoI4|#oNfJ7qIKMR{hmZ94~D2EvMW&j#~~66Zq{d5IU1f_lbj2zB1O4tvi=Ug zUI~Pk@*ne?t4IOn*|lwez;%AechSfqa!E8JFXYI8f8ssm@kIBW535{1lM=@gt^HKK z55;E+>vMd5Mmv!Ar?nuisq@Ulo95+U%{Q`V@I0K0{Wz)v@3Tj`5*ql4vFKq*XWleg z{zsw2b7^yEx%UPmuzqhee*tIaAZrGFNcq5T{f)u9M5Y5`yuk74@}%!lJ*E4=Ct+M$ zd?>$fNXEx)nUO7Mvw~R>vTI_v-cEL=LYAVdR2kG^odXVCK zfNFaYq)D+JvLB##FhdgNmtGDtLCmOA-q*P&=w-z{?m}kYT-=rXq@Yib>jFCB3>C~o zA=gh&8NuF4Iv=ADReNb}A6f(L`gnK)Izi{StcK$}4(Fd%!3?kz@^R2M%mGr~(KpgP z#R>JTw)lp;r&>_?+so2=SD@jPkDx)ySp5BfMXP6UHj82nEllx+J@QpzfLG+7(mKYR zF!#5Ied4B!5#=T7%D9EZ4(ABp5>7!j-KsR3;$~;I+1RCM*i=q8-&QGxTasB)q>oUwlgWFlB#k%SNeI28CXqb|H6)^=W3O$1uoz*)-Yd}$O6tc~OO`+$(USK!u)uj)(L_Q_Q znJUxdVRDE^HDC@NP0aJLXNms8C-`>2Ch2K=2>9p+VDLBk4g6E@!!%+{hw(PQ`h>`r; z!~KT??kyyxfW0?Ohs!_#tg7O!nKfv-SHQ8QgO26qQXzOjq!45P`!oJx@WcQO^i(Ru zu%~GdM{pGSI^>`}6=E!q&n*oQNkxV_cF$x9;@A83WI<^VLsA;VcQ%Cv^>tB<1!CCJ z0DCj4$9pWllpgU}HGGToDAVA^+55j-%E1)ulrE_@+7qArdl?<8m9p(-d**)U?cQ11 zurHRqR=$}FkLA)fQ+6@hR{wg;e$~-;Q+Or~Ee7MabbTI1Zx}Q9^v^MPd-2hr0dEXr zNQ_MNeUJX-8c5$<54NR0;_cAiq<`?gu$JIG$;`*)o+h`)Q2P_tG5GJj6*KrakG6$;)K|>l51(jGG#n@ zxK|(2LQ)FYd((8-P6}8o5XY7d4pA!zr-06J^%>1#H;kGTAQp&U zi+}AIpN-=lPd#0P{lkAD*oW_-xYytF@D8YBI;bb^cO<`|9_}q}E#4nVWcOr&*-Xp_ za1IJHlRhmxyniy_{Y@8&(xF_7Pn-4AVK2i+XsN|u9pAf*A=1It8pzCb0&U|5OE(kUK2D&2{wWTB*#vQJCY zx(t*mwbWv-HnnW6q=Bt7rr7rd9T-#1qnP>ust*x)$mtZK5iuR$ z_0f#97)nf=w1zT`)=wLbm57b;Ij5SmO0h&bjL|F}(Xo8sbo}yYMqiIL#!x)E#m{}( zT^_o{ZS7CHxOUQGihi(Y$1-YR`PJx0C?)#w`6kehZCwxjSUc%4M!)z}AeKKr{bDE{ z{o?1Boqlm!`_nJ3o%9%^pJqFjWUr(@Q=3O99_{$dryFXxJi3!@?N2w>Jcnj42aI9; z%E>u&CdbLNc{gPzrW4~q@<|Ner`qMASlrhBREuk$L%DdC5t*Bq@Au{x=lCqTCJ7KY z!)U$Psk%tn%R|el7Wb#`REy3_^A{4QMAqT+8TsU6pIdF0==wLg7r{iMm5_Y_7u zN9VA_<W`dpdZ`19{RENIrLMn zxkS73jb41&V+}stF5~FsNJdocv+Pn|6ImaD4&yrWP^{J~nMXp@2dlXrC%V(Ke4i#B z5LPgyP<+|T%UN1p9{cC@sXr~fR?Lw_UE7MCd|5j7GD@<@c|m%%0g6Y>@YK>U)O2~M z8QR*PhM{iKVoV}+<^%gAV7=gTp&+n`_yQ#K@Qj|hTz(|kHON*8vmYreL>YEnuO=;- z)=COr9*R!2xIdkzTC@uFmF9J*zdM`yX|0!^`e}>TPyMt-t582kVaOp|RqmM$ZheI^ z&;E2acfAQR|I-@$tTEipp*HsQ(DmIX;;p?n)9k^1=Cr;odtO-`pF;60by|k<9BR5e zG)~*vUy{=n%%>$zkvf&w4|ZaKoW(TFY59@ZVvm+Nlrl~8vVpdjjiz~9*G1dBC39$e zFi0!Bx$hI&QjT&O=kl6D@o1Zt2{dI*mxs1#Tl>>AZNVH`VkNikfP)-mtTIH*HkR0& zmLJI)D=V*MC>~YIrAgn*L)CIy`_s4FmN}G$g?%y1^E`DdEaWMt^ldo<%2GOp;?XvK zPHIwC_51SBHg0QwYR0vnmwr4Em+vWNJ^G~)s<>7{nW7`hS$bYhId3oe9$ICh?Nqmtu^C+51@M;t#lyQo()Fx1rZCxit*@p8`lzfoB zoy%xG?#wxwP{t{n)=3IqW?5y=)=A+MZ*wTEp3Oz=Xn^8THasOIsTcTtc_!cKXbx8#v@L(N5dC4!T)7SejvHp}&pj zMJsW>%;_FE3Q6gtzsqzH?-8o)M+$N3It&vM9?GwVWM4~+w^Nk`i& z^^^3xiAROFP>ef|(i+|KAd%uB$B}i6Q9h*$F~@b6<61Iq?VR6fZQNOVwbQ3lXnUfg zphMYTi~Tw6i_4_YiJ6}JKX`QZdF$ColsN7ce|x;8bLxPkyo6uGCEpwSE@7-MFV)%e zefxMR<`63x;4;hrBDO;A8l$tvJG4LnQqV_)J%^Vr2M?`wT5j6*?c*VjQ#@WmhJ1O} zD(0;zUQ$RgFX^34;idN^8dYa6pl!5mh%3aLVtMJIj6CM(Bl45SOKQ^qNqGpr=I{<- zrZP=0Ago>NvtKKA7zZEK;iVX}7U$20y^66GU$f??@L$IHJ7?=#QkYZtFX5bP4(s}) zJSmJ6$7yl)Qv>JZo1Wfdig(h|Qar3@AO^<2J&J4gG}kqRG2=KSJ}uF^w~S%0{(3SN z@M`g`Cuxut#6kJn!?(tH6q4#S{XHdFp_a>m^Ieg&nmD((wRk^}80gr%L%@yxD&t)t zDc<$>CgOd!BClKATD)WL`~7p+@iN{OlHy%|ZzA6Htj`)YWpA+60k;ihEvd9`1EST?hBX z0)ETTLMsMz;oJ$d3X+-7NSqYF}~;H8T`z6UW(_qmK4XR<^25IXU~waew6Tw zvBrV;6Y<(~mW?s1zsK0TOW;-z(#g(95`t;q<{_TqE&P!kxw+Fn7U{>{0yf;f@(ZtSvxFF&LhV;c*&+ z0Zv~$hI)ykacn*nS!c-@i~Kzwn}FnF6HjVj6L8jn%@{`(n~3t_G40nWF;>Z|I58TD|5hE67@qQ^R!CrXZ9tSGU2#Gl3^+jrDeub6dkycO zX!P%T`oTF}E#2={qx;Z|vA7(13KcbXPk-z05K(rS0#W?$#;>nTLHL+-drkWW=_w zpJimri4lvn_!Kynuz0dp9@cbaTMS7fM)93#yp_j}F`OQFi|Zp!EY_Y%*2zP&F2`ai zz4EZ8QON*FaTc!UV62R@0H+7WLTx_2;&lovk>V)6_VA@#7DG~u#dqf5tR$Z?oE|uf z>myDqmxU7ZR(Z|A8drJ6uj^6$FW98f!BEFqF5uGUcAQo zh?AVxv_uVFBcv2-^Hvs)Nhl%r#ah5ginWt-SOG8MN}mHeQDB`XF{W2@cnthp#+btC zgDs1T6jR94B=4m%m|uHRsdG}A@ku-Z>Rc?1;b}UHv`(}_TTeV#9L=2h?m%Hb;^}Nl4_Y zaAyv0mH4V0Z|s+I@%{$S#>A8<$;&+IQ;u>jz$_(lZho`Wx<{3?F5vW$l7Im#A;_cr z;T$$8#|`t56q3q@{+=Thiu21X8@D%jhT2j$rTn}M=CV`-%7+YQU0b#-l;7MrYNdm( z55xLDJ|~U+Z%^h`AHK8HhXLX|%3of2$E@q7Qyu#sk+N3izmrG?pZK)4cRkAMo>YLO zx*osgQC(qQUfS=-nYf#qdm7U=rMj+OolE(g>WqYO9V{uYaOYCLM0rB(;R&%W;=*Ez zdpGl`m4^H(#}vE;c#3Z=rGpSJilg<95}+A3S2{=sQr6NP(b3=`=X6f*34CSWNK}U*|aDSQ@*m+Oc$eXAZtfnq>V_vLicBY_62V zbRdmWF3^+7=f+e#F3|Ol*kLH=gZSPwCtPMe_;927Af`i!6XIBIEcyQLoD+7ID;iE@ zwKg^8`Qq6n`k%S01>87$|CdX>H3d7xWeIar zaC+c!stv@GmE`y>`r2by_OPp*c|*odeAC147gkW>foikK|H6(IrEjQ>*on@EWy@$-yWva#sJbkEG0gM zItN!JJjHN&;3}?<*zoXmwDiuOi=G@`ukPVX^(5;0mHYvMa+lU_VUJ;N9BUR%KkV6h zOISP=Ev8=dG!8vWeS5iw;j0XXDdaH>=23;cMcCooQr?q>v3n)zP#(uAG6vauR;tb8 zsXjF`KWV(SI=N|x>HGX-Y50Rk+dN-dahyvpXY~}4%B}t$=d+k*C0bpE_{_Zxp5L+5 zwUmcvi**lkBbgrMRd2_Tl>YIZIb2YpKl7T#B_`&iIlt4|bp0fDt*s+_t@UMCq0tsE z>sSdIbB=E*4}@c%3?5p1mQI=O9^dN7!9r5bwfClZH{~VbtjAuqtgEM#VBVsJl(6l+ zczI7^YoHZ#^GR8&6U$uWKS`;-Cvg^V=QH`=s)ok``_&MMIFj$vX7ylq*+&Aul{OqHY(lLx8qsF zb9yGV3xkd2%!%x;%wBqHgHe;^pNRV7xp@2tQK9__U#<`>CDkfk?c0wgV^gO(YGaw zv(^q%?Pn6=jEJ`W6Y0>yKfu0t?M``OPkM2b@{^uUSQ=@S?x!QLKBJg*_~o_mb0nH* ze>jb*wLTipmT4=EdW!Y^N~h0LA{Z-d+jiF0Kl&0PAB?P6FC~9ol1shsMcQ>|tNOp4`omCMqAD`vOhifD^QrcV`&uTarwMVA3Q1ZR)9n;lFks1LoQLj?|5w!W}Wti z^PAhwS!2firRdsLk-a!Nteo>`(CquoyxZ-Q?I3ZK-I8o$RSf1qSoVJ>P zRV}JZkN*nfM9Z{mYRc3S9gI-aVz*}l_CC3^2NlixOwZx@1%WOKVOj67K@-FpN#iNpL+bD`!fPk-~-ZZ4$Kr+h!(etkC76+ zV&ANLb40p*afaVlJ*8UoqRmX|$#-k=ZwQ9k~ zuwF}v`#f((^Nj+eFy>O;qPwU`}&_7bx z_9?{${KsSY#Mt1Q=%L2}x+49?5G~>RC6AWRWB4(Lq&VZA3Tio7()J<8{P>-`juZ>I zSKp>)a>SgyXvh1MKTUhtv#y^9)#mK6oYQ6ePKjzg>f-DJbVlpZqs~02ci%>~diF;9 z(N;%o*GQ<>IC#6TwoaeYv)uFytUXr!p?(BQjA=d3rwDU8tT*_TyhFV)20PWKE!XzE zl-;XZuG&hy6ym}2r7T6pFyuW;u}0saC;xd|WP6q312fFW60eW(5%ZtNXR+_f_e;Jj zpU3cH9!#;;(*kXiJtepGu@S7TS7vfAi`0I7{kCE3;gC81q|s~~`K%9Da|G6Qex_gK zyr<vKJF(R%!OpEwyNFtE&xd&MEU~3X2|K0x zDb^^pJ^9b$BHOE!LtlyC~|mAus!%{VFAt~Jyk}3{e_qXQ?E)-Etf#5}OV-Y_3pyfBAq5{K zhCk(pA{XY_r8&2}7m(Y0t>}J$WUi5vgr^_DJ#<9|~7Ik=WF8$yZ~kQqRgf zkwQ|QNbeHACHN)G!GD1r@38`CXHjRDU}grlv(@Y1tCXVT7|U0PK0XnCn#)}tUwsm- zIZq)eclouHc`W6w*bC)bwjU)vE!|IRAcZ!Sf46NP6rW>!9u7SBH}SWDiNjI-=<%?Q zqdZ8dehhVx6FnZg9Q;*lC$+FE4g1_i`g+=3kJdharMwt8faNU*c>HzG)sX>`uP4KE z;@#Gia@n@($$EUe?RqkB40+Q^Dx%}q;gU}+Kjl{*FY9@$gruCyE1yquxGCqZ$NtvY zLts1oM^coWV);mQ;#1)ytQ}&RoX))C@ey}4ga=AUu^!~TX`Z?q+*B)XejBZ=&o7pz zVEqqed`oIhah1nY8uv&cDOaU;r}&EPAP=uYN7Xw)WE;6Er6@VZ=c`u|nYfs)Vtoq9 za+Thj;;DR3PI6VB8Hoq73+?m42WYh~HT%G~oi!E;(`y+q#UdOasX&uv^=pbw7+R&!Q9F*?Nc31W{-5*Yk`eBIvw(3tWy!Due z?m?Yi_}WhW0_o^SG$&2lwTps~JR6Kb7k}@#HL@ zSbYS^nVyFx^f4|{NXkX}doB-M7A~q6pT=HA+cghu`NZ;&MulvNz%ltRFXE$_wlO5- zr1;Jpe#-e@As|14@7vbr?Hj+7*1(ZWUyWCfSGRL6#d4#ixIRnuVwvh?epN`Z{j{*j zab?&kHwAsocWv9tko+e({I=Pw+W%HTWbWDQ@xYQ(U>?RQ&RvE*R^!kYewQ&{wDU zBeAKluE(7+1#wz1M(TA&>lQOU9bO9l`J^ln;fW`Cx&!J7Mf?q>1PRjv;$Ln_x;NoG04^3kzy(eq)qwR!O#PZ#MZJ%&UdGQgh0PifoN z;X{5R=ib-zB(_Z_#Wbe%viziR6|WpQ)P8&X6rXb!LsG8FYZ&LPl&iKgkG3Y?ZfEQ# z<|LnY)%VY5SS-heE01?|M6HnQTwDr$oNMzDwZ?#SmXPmS*$XY3_bZo-wo#y%0+;e9*7TiG(<(d9rf4CH1QxQO}r4~t)is&<*GW--|bxS5h&{GD)p-KQh~{i0h_KlesBjO(E)CyMSFw#fK zx!IDQ?qJrf!cmu zr!=J8=*tAMhp-M}S{jrxo=oTnl8`73y#D?Sr)ApWNiGfTJpDeqE4JMsk{Y(h%2L+V z|Gc_-E2LXSwuzs9-ZAi^Sx@6ql|Rkptfl6|PL@ZaUtpVQ58HSey;qFZ+MkZR)92(n zo@D<@MnpDWs0~$mTD)L!d|UT;$d#RM?L1qjnGOLGtzEb?&)(%ycxCNkU6tY|NXaYl z;Kx^O#&G8RF4fiF+TC2#$%pHStv+7Pm1Vs=Tv}^=F1fVNUev6uA1CcdY`<1?zom~x z%=Do{kG&Bvro}9MA0KB^Jx`8;>3O#C&)e^1e}(_p%Sr9THhcWB*X{fK924+qj4AK8 z=ksfXpO7@d&nwD|2P?jpQiVFVNAzY-=Dpb7Fgj^7-s|f#!@ho6-Dk!bBE7~K>lhzX z7AyyRD?IY!>^QJLJED@JkT^0X+*KuIPi%RsHTqX$7wV`~KegR=4?Y2A;K&n}6WOM@ z-)Y;aTYJhDx!jkn$8zH7d8Es;LORPrNR%#K2V9P0EydO5OIHsIN{;F`cHETsJ~7kR z?qlv_r`p=%uyT8sqy`;X*$OA+0% zR{b27ur#n&oK2M$2)ID09QDGYI5{ z6!JJnq}&XI6%K}zRha&4>2dJaJSw9OkJ5bGw$^LW*u4}oH3!{l+Howumb9J zV~W&XolRV_-xl9x%=%ACxam2@v-Bj7*nVl5Fp6d=zgPZTsM>|y#XE+N0!(7G1ha&z zepvy?^{BPeN#1XZ@e&qF_eSgO>svY+(cnNCV!ZU!&CS0zfhjXEi%Cwaumi1J%HS5o4m zajnGpFbi{vk1mUKtK}&j4YSET_RQL>QkYZRRMO#nz3y6` z(suGvO4D)8G&et^%uP4Xax>pff()-KLKt@Ln)j-@xGpQ_2h(@7Cskf#uJ~7(O;i=T%fZ<3W+oS zaURt))DjQ$*-3(gHz7!DIM)+*sr9cME{iT^j3QMk>pih zIy7@&zI=GLgBeD_dIYHRB&39=9_#wIDfgj|ztuYbYrCvdkOf}?zd4)v;CgbF^R-G@ z0>6>@kH1@v^peWJmE<1Fxn&;ppOiSPr&L<0 zptRY3>HfFJv!&9LNL}X^AW;=L^=UrDCV#rfS-7jO?iPwK36 zK9nd6<|Gg0Gv_QdPdfG7bPGu%()J#?C2v3P%RZ=nX@jA4M02bh_;&I@JXb!MLw!#Ybv^))RQ~XbSeyeh<}0UmZJi(tMTCp6rQ>++y{LNK5N|kt61Q zr}XYo2lZdiNRcmL7I#{P7`d1f5=tzEyhqBFX~dE&L5yv$6yDxADNJ>$ zf^D^!Vvpy36Ynff4(OBjz}kB9TTE~AlEvY^#N(ey=Hjt@vjp+ueV4f{hNRpU-ysD( zn7mh_Pv5b^txDRs5AP~&jw(kw5lclrD=EWBr=A^DE8@wl8S;kZOx8X3yTm;`jA6wacGBKv&b?nry03rQK22(e@7)wQ`|s zb|iVka%zbqOZQ8hbTw1qV=Tp&?gD*JG79QMWVg*fNi`car{!8`*GI#67P)>b<5K{4 zJ^iZL^%jz9S9_0gQ-+?>crVl1gkgJ8hUh;@>sg0(syCUd^>i+Y^`vJUU;gQ^nOC);puSUqqoBe&CK zjI6EY?m2$7UJZRF>ybQ@e%JA^)*Omp#eN?l*go*>x!-9ml+GT0 z1NM&LeqC*Q(41jM&6fT+AD_eKbVH zP@9DmG>pAZsq(c!D*NEyFe}e@>*|+YHm2u3bUoLcJZq*~TE_fwj$>?FTk%#8y>dBL zSm$vllNdKO*+cy_=c5-3cvExwN71XS$e;jgGa-?fS{+UJ7I)>hE|7DCj_hqFq zCD!VTG5PhLrQRSZ+$+x1GlQ{LpR8VQL#MqV^Yh7&-PS5fM_$;}9S-1!dN!_&#PswW z;$HcF1IDIaDNhIBp654c=2{9VMCfApzS`y!K>B?rDP&+lRq+H@zF7C;r zP}E|@aEVio&v-B8H*!Lc`DE6$j&WA4JqFs(z!6JVvsUC;ey68^C4v%HT{#??2qEwnvdhXenuRwN{V(Akv_xcjB*YY=y&3 zor6VQAhI>v;DvPWFMGB3{G;d4c222fv;$UlfAKf@-@A~Pb|2Vn(hi4@y@Fx zUbKu1_n9+CZrZbkq^aesT%(NNDN(+sw2=DbR$pcgWJel|IH#pWd+f;!JxfBO zXUS{gbTypyl9rbFT)m`Z8~HfrP%E1U5|7i}^sr+#xxCD49tZ0f+(IH3$Iz!axg_~L z#z(ZtJ?d(^4`%E2M!n>5`_9sCsU^w3+oAEdD~s^1#FVgt{7K_^kImOz3+P1`%SUY}L+!af84dDhc`l9> z9!oADMz>ES${x-drgSS8dQz(6j2mJ{`Tj4LGCB>N_*UpSM~C&NY7to8_M#*qrTgou zhkVd;^>nRlmv;Fl#7fT$uy#>?l_0FBz=;a2GHTk6R7sJ(d|GQoMUOq9`p>7<+S3<1 zbG6c<%KOj6hP0|dbwt}y=-#5`u8Z3{-(P39;9mJ$?WCYprr6%F8sg`Yr+KgP402E3 zd)n`%S8e^+;6d|w$%EDVo;R-ZRsj-cdFh)|Gmk^gJ>=;=5wh*mcs=>kv}XDu>#(>t ztL&x29`wm!fR+fOH?_#Lm+`o+4Yh3TfeYK$Of2{3lUgGz_Mn&7eS5JZpWP}vz9)M} zd?}wcTt&?E)Zu}5sf(>%Q_1>aGOkGt=jm!)e@{r9n?(dB>|4e6OW&!!gnxhKe+O*k z_-Q|XiKsuQ*pd=0VfPwkwVi$AdFuxfbH^?jZFCc8-46B@m4hVfuT-AbVH>EieajH9 zyJx-{OQyZSwPzW0=Ih-h=Msuq2oFAa+k;=iSdUq0QfD1rS*>^kvEMf1G^Q%4X*~{) zwqy57bnm^sVW-jwpX8-J<0#hF%NvI;eyiF!nTL{ffU_doa#Bx!JeChiB()r z&oX66@$|1oQQj5Xp6`vtd&F%Saw>tGwc&W2--KlQQHJY3$!m*o)}{_hNqA zn-)E-Z;-N7`oiktIhNP6xOxJ|Gtq`Tm5y>4?oczQvKL?f9ORJmx-ac*H&f0ovGwK!UE33_rXRtp+gpP(^ES2jq zz2j*!?zRRAU$jQaHPWRH6vscs~kRQh;-T>f(EhZd^V<@>fDerwBj^LkpYNLa7#CFV(4 zi@76_Va&iOo>``hIgbO>I$B6de|wL#D?`ue@>;BI+(N>zy(mNUpXBvy8~rWTNLPzB zJqJm3_`$HYdHkd!kM?(#@qC=}XCWyEcy*A59&J*}P$>e{~jjXk~LYq1A1YWPk@=h*#0eSFA3*`9e??B1Zo za!4O9;ixXlpNE<}omSFiy?A+(#uB|wwCqz4wN?+S#Y_}(ptbRyjUBs}@+_ixxovM% z*Y@qyt&zMsEAPowJ;#w_IZR4EyUOBT@wlU@|Z{#sH zrXsi2_1($S{q1C(kuUQ6eGStVUp;kbs<(XIxi2f`4rHztD;`+F@|(T#bf;#4$B;C> z8Q&pZEi`*o(wsd zseOKIyPa_N#LGIAQ;XVgF)7i*b7Wn8b#0v;AJ}%B%Gq{alr{B<^|7|TG`UwL8ppP` zrwO!TtNnb~i*-cK?pC2g%iWHMoj&_}Y4Ww$n;n z(bbD_Z*x4S^;*4_QbDfmJ_hO=ZlaQJv`>tJ{$YeN8_?KWcaq;(T{a)i*4*P|HK^( zl(*Yh`93`%{rlvP2TOc!*P;C2S2y=et zwZKL`lNF1t;BVLZkG{GCD<^85W7RG{f)=pL;szBlX;z3I_2==MGt#C@d@v9n#-E3rnV0{N-69c=5} zwr+h}uc~zfs>h614~@~*lL|i04>A^=(j0YUFSQ1=Hr6JE(KD?9%h4*>Z_g%uH0&Xk zLrUj#Si`toVky?UH|*HJ5j@|uyg7UJj$OHZ{;5^&E}+oKxa1oRdrrBz5!eIot(EDR;%E zFy~Nthg9Zu%mFcf+CH%K-0!p&(x$(!u(PPM$3d@AX6jG3m6gqnQMSqpA*ZfKi^Lkj zN+9;@IhGjQwEj>T^|Xkds7gqxKX^qxo09NUviC%*V<#`}&`&tF^;1yO=V>jZN}o(_ z*7iW~{Y-Y}dO28hSazJM(kC9b-6Od7DxHPcC(obnYFgRa^hj@@!6GroY7PR-P;GN!waG zer)d!$aTiXmA;jG?TW!w0;m`{8(!~k3Ngc_!&E{?S#HLaDMm$Hxa zoKwpwQ=Tr?6;v@Ko#lw{P;v>!`%dMO80+a}?^Zgsy3gpfCuVL{i`h^^ktZxidYmzK zuf#Rm8aunSsJn+6ys$pAYyIPBwf2fwhbG#QU2v7&v(eu*P*gf{=;ZR8b8#o-UgZ0QXguGwJ@6rw@8)$7M_2HD8W2AiF}1>x za>~Jw+u8bjub%RkOMq{iv>f7bnBQZWG8cPtsQXX8J4E#WC6+-#CjH8gbNRTE!4z9L zjwmC<@0E_i9uCCY-r0<5Yy4d4DB`^Io%61*dn^ZQnYmtq?>lR}{N2dch&5DzO&*!w zgDVY{;wq=|m4=FObcLT78~N`m{Ny-^@09U#Wr1QmdB1bqm8^?rgQk6B*6I1k8ry!? z_{LNAhVb(7DM$3ZqARd-Y^}vjXyd$JDGk_@zR?xk*L-vHf^RPBoS)tL)E(px9!jPM zvX$D+!}RpRP8-QV7^!TF9`BheQEv@IpVK${M}la*toA;TDC`qi{X2KXwP)Eh`V%1O z*eYDpZj9T9)GqXz!=wG_$*tHGutuf<+x}GI=MROFz0P6pvl4*4>nSUNYkhe+5-cCc z9_Yv_n3GHG$&1cfSV$@}_TIGIq%uQ{_2uQdD|~wKa-TKzJ$cu1&p7`c$o$r-(SFOn z3d!=X-rE%Zt&{ad*}LN3aXZhasqVsztLj$Eo7P`p8SYr}{ltuwr+;;a%@ooCv~6g}!pvdbLlV6;kA<-s{45D`hqXtDzow8{Q(8`fI0J`Sk5i@#@V% zI~%-XN3HQcG-^*@W4mu)73xnTkJ;KK_Dm#=9%W)J}@(n%zR!=oaA?XM$y-R&r zf}eYweL1e(Drf5SZTD{L%yIEVvEY@Eb1eUs_^5P0<*%Mp**5KoGrGfQwGCaaJfM6o zKKP(E?$w3@ePi$ay}CL(9|k>g(s5p-r$>=ma(W7u>llB!xId9XvJqdxr&XA%?}O|R z!ggseUBz>^O8kU8-IL2ws{34q{VWcLc`;Iv<$ONyyjG3M=8%-n^84eQmiiUQt~eZg zYrbdY#BXQ$ZVtcgTHv-T%Jzj!q16+6Zr(zW)l+>{xfevMhyWU?*x`fwYu*3u{2F2PVAa;{bS#IZ^WVag)q_0YzoR)QGr z#h1rok)DfvMmFIKnW163EdJ(Myih9b6*Abgo}|}^g50FPJl|Mz8Z9J79%3(;SWjVw>s(4pdeZmc zS%d9kfIsh7+6vOOj~@W<-ycQfG;Q18o_uV%hkR)181oWKj8W9%Rb9;8UZ|{iYFRXhW^_YYJVV_=Cg_`|xF7 zjTAHjwN0vz5Iq539Zh6Xt0o!KM*$M`QMg0yIiEgCXCDZ~_F)XB_l$Jrvpw-2Vr|;0 zmPdl)6Ukb8AQ;D)o5*%Y&hYDIvh{kX;kk@O_M6qAE2i4}*X=Ta_JjiHMO!>QmKsh( z%K%fy@_o{9T)4es1!P#H`pRkpa^h<#H%F&=8cjz77Lw{Tdykrenk4_ubxj|gMt{H8 zT#xRjQ0J^N=wsj+>nu5+OiWu^=lCAKlT(BAYz4pVtie^}B&T;yaj;hNHuQzO2UQ>L#j>@z>LO}dMb->cYW%*W;5Ifn-s@yB1W z=gAUf_`Y=N&fu?yc@(VEi($@@%)Hfop9NN z_7sDBwW99!dJnOlpzg7#?kL*3VqUV0?bcc?le@*(>elPAO01bt`RtOUrljKD72R_ZHi$4M`iT>nw$i zs`*hzXMR)+lYCL8`Piz(UNKgyuPuhgTJAl|d6;w{E^5PX>#cp(IFog=ZPAst=E;C} zFPDp0Px#&%<|U70PV%vMYb@cx<~?ter#VS6B=yzeJCsbq@xHzG>#lIEwG_0|sYJ;Y z4{U2~EdqSB9+_>kwT=0SylQFW&9k$l$8jDv-x;i|2T8fwdqR%!>R1<7uS4r&)nA?6 z;$m78yO!1-uE*}>bl6_M)ZBR%Va>^__1{yLs}kXK(*Ad45e z;zTk$4p0>?YzEb{&}2)E2wbS1ER&JC7wd z_qanWBkVY-`>T_VwR`kHEUa?lOUZd?RZH6_@=uN0-CslQEore`yTR2wb&wcp#i?oy zY3*Cp(u!lTu8`hno3>LX;J?jz`tbG|5}NDqzJ>V##XsxiDGIgPq37+tjoU?hZUw;_lNS|9Y-X%=zTDL?^%}4;KG-7 zDl6!^HaObm++nM;eOnQ0_4qeSrCBT ztonT5(;j;>a;H9)NU0NF=d{1Q&=oN;BpngOcUI#9Mt}IW<=ePjbAG2>M#FaspsIro5#M!i0!tecu!A0_MzyXSuf~3-WzOh z?!ny^U5J<;A*uJqE8;S?+urZgmgA(&;9C-kZMz3&>|R<2dA27-h?j9{OyzmAmmW2A zeu4FzF5|G_nz$qk|GR{%9+rx9=@pONygBr3q{7vhBbUUI6!wygt1(B30{zDvJ2LB9 zC$7`pvhFQf<*U;+Y_6XfMiwpC=@3tS`4pD)o<#I&@F{z+4(}}ZU)JM9-Yz}2TwCXN zJpW8*$N@<`W&E1wlPUaEBf(RS&&#nCCuG}?yrtuJ@;ckk%5O)!qOYZ{6S2iPKgfS> zw@+g$>(JwbqIKw{SnpU##(89z`iOGeXT>Cxue$Bfw<}E_fgwXi(1X}N@fCH%6!1w z6^WjX)u>#6q*^vylh0BuXRmXe*JqBqAD`Zm4E_%*j~{x?J6q4Y?OgYpvLX@d66>r6 zz8XVVIV)Y|^4E5siq>|hr@tI~fIVbmr_vn#cFqh2%j4U;aDq0Umt;ckmu+5vq&6>H zuWIu)c?WZPH=Aftx6$(p+(<4*mGndwLavfUO6$_ z_LY3*zJ zG{=;^liOG3pAnMUR$k4qt3Ew!{CaBlGS*{zXWKq~m2-vXBh;;f`nYGjjnwgZf~P5` zrAqkoctYcCZ=LyW$`vVOQmq8pqenc~8goSoJKo!l_0*-D#`B4#Hg&9nJ5o&gTms49 zlM?;n`yQ9*Ts$BJkDPdn-!1)~;*WTzWWue@16TfyrA|r{a&WH^cg=CdHjcPsxwW$J zK<2UM@2%qHqTgQTq7#xzHLoavmS6I#b#o9R`?soP`yCEzS=#M3cq;q2?hD-x&$5^- zRdf7~-zj0gr+-3@p?$GEdLZk99-Si-EVn#?PZbjRRIgU$Q}_e5_JPjZytCW`=+9zx z@5!D%pUPf9e_ZYW^o{KN^X0G?koIJp!uiw7L32yhl;+@b@U8j7CHIMXG9}au{KWS9cI;e27+Uznc z1a|stZ6kWDi@}NC*wG5B1@{|MyH9^Wokv5)XG=-hhFQB4p?m9dk-%Tir5>CQ)kbSk zm-OMT_Gc37ItuFHHaOdBE+4%tNyyNAEpp!~$D2IX*K3b`G;8TG>U=5Q@vGr`I$t{X z-?(4ZyW+dOy?9e>qvl?vkjZ}~Un2J*G}8QgS%F^9f6r^dZdJk8wAd-NwRAs)z7A@q zc&Be}d-hnoztdqShv%|({ZPCRmh=0T)BU#05yNlKA*m0a-yi3I6nA@B3;Dk7iQnGx z-L#%{&?v_Zv2XkK_#6~Mk3A}VxTF$x?I5j5q4*xLJ0Ejo)0A zDE*acCS7HDQ%dwx9pYGsq_MZELK z)6Ozu*|ysqFRT?)^{C!%hO-CNkCqYjb~&Zn7ysO?ywh+mOHnt&9V5=Rr+xQ4 z{}nkVhcc)9Oyr^6nkBB_X=NugH?3DJpxp?)Uz}mPV*&N{BI}E%zMdgG=v$R_de8jh zQVtt)q?cEDe3O}}Iiylf9rYby+V3=`thrsS@_PvVRCN7MqVw4{izVB_ z>8rdCSeuH~sV|z@6ON<$MCgz&?B`^*!619LUP+>CSnhZrBV=TvAmfcC#(2b&A>I94 zA?=>6%M5Ud)iJm^*I`$VgT=SaJsHI34;%Y`cC-cGMsfbSnauVWarLOh za=jDxg74a1jOj7&Sy~5a)5qGeww~4}rvmA0G5K27XkuOSGx?7U`zaeV#t$hZ@^^&g*{B?4- zht*gqB-J}BB9dKu|gyc)ES|0|_8GEF^x%z5@mI5wPQ>O<#UPp|48x~NSd1%B1*XyY`wOGwe=iB22a_Kb?9@9%nxQoJUpNLgCTksLyEm}g-!krwj=+QS`*@{ zpRWl&WT%oR68nMJJF`{J3bE8f|FW*W5|7-}-AWSQKI1q(U!(0>HBzIOeCSB5mV5-w zMBUJ89HTouBin)J(!}TBw58FT%aMMa5iBX*d);WQTv4{a?>zmLX3TAE9s|45j2@P} zd#Rs-7)H$~)s<%Sux{_AG@xd=(u@{QdR4+!|B;9tX;_Poojsn<8ii=Dys?O$p7yc8 z(J_d^q=(_*#@;Jos+W&da~&3CqSvXmM-p9sDsz&Ln@1da@~!1c%dyyN@Ob#+=-P5q zdgXDf&S(Wl%D3Tq9`B}nt2+cgZxqASe1Dt_)* zaadim*rqp_f$fJa?hV~`>_iInl=dKZlxWM<`uw|LS4fr^<7`jjHC`4&ie+A5lS{^6 z=MrPBoo)FTB=1=cy(fqDm={5oDDk|>xY~AUw9;lNrBZ~r&Kzm<^Ppl23`nsw;+j0- zNlCbu%S%gXq;A9s?Z~YAR@#Z3YSG?p)ygrIJuZOnS%(V%DdqxPZxR=vz1zwKF_lv; zI8WBDuM2ei_(F0>NdJ&c5@fynE7by&(>`M`*4BT1rrzG4bBLABsT8ix;;Qr*$&sM>2^w6&)CqeoM>DpQ%<=EoW$N+ zy!+BrzFU&Bo?H|tNF~vb^H+Qs6bx*8le6N;-}uS8^O1u7AF~w2hhx z+!VMa=O*|}b5@3dzs9*qAqCB(*EP7Q{Yo3`KOBE*_)fIdKabc8J)OWyKCeB!aO{OO zJzb8y!}S%frM$MC5uQNtvi}af7kJUPj=Vdr*A!CFYkIvIyoNmG_;aP#NOS)?^^o`E zWOMc2125%z4IEKNuPG$UYhewd-)7!T+fMtV-hF!;+LPC|SFc%K%6Sc5)%VqG=szYl zG^__ESNY%T=CwZl8lqm?H$Ot_8Mr9rGVEimJH;Vyhc?#d1bCbaK#)wg;t_mhP8p2ywa=H9(fz_5n4t??b!u3xf3}m(-;LZDil*v*mxvm+e`Q z9jrKHnGy&4Qm8w(SV*Z10y=S9hF+GC_Wawn2J6jR8kF(jKPh7=*UJoOwJRkl z+Hd9No^Uq!N>`?l1FanRny7p?<+RC5C zwpwDTy|<4(w9+9;hn8b{YN`I?;oxa=tZV%ojG03j=!hqyUcWb|^U1ISjSoq^e*YOc zGWV)dZ;JTaOf8R00i67T)wk`|>*2(t5NEbj&M`cGr-c8${-*BE`N0N{y=wUhE%#NV zY{8bc-VKj+_1qJrr_KP!)`%4J89nx06|t=}uNPtIIU3MYvD?nV>F%;uGLi50Lp|72 zH`Uu)Z#(&PNA?BZ9NpcMbL#C6-F}Y}jOFY+AV(Q(JmQ{oxKn8!VoyB1c5Cm`8Kk!O z@8iRetHMaRO|M!~hBoI4W2LcgI_ljMDZ!XXqm8X7{!r?8HOv*Ao@ETQ(N#TX*xJQR z?@ElST@e`*f%}OJDUk=((ftcz$_oAzt>h7D~i`K~3!=BJ}qB-{$ zU&^N~ZF}nQSc6h8Tg~)PW-9q)OtL!O!8|8n*>;aX^q%FlV9&UAd$P3G*wht0`6=cWOOFGw>0yn$M*({;=cC(8KKj=s zA1Opq-@ff#|qZL%LeUPKP1aDeq2VfB-_I1VQ6G~_plHsJ|uc5QfQKvAMn4u z=Z&wjgZWj}*AKTUlgoCXL3VUhRX%HSXnb5&gu?QM^hYRhJ(19+|iC2u+)> zY&9^qiQSUU*RLiGW5E-`rRKT32G;J&uQiwRt}lF9uW755XFh9Kvgv7g%#(Ue9ou$} zt@Yls+Ke#^`lM3vq&ugj$9Vok{#mj5fIi&cwN{3e*SLCXgJ5^1eTC8`|J`{G>Xc4x zFQM-XblZV_>t~+WUs_%0o_=mw`qI!__{8q0!dvKul>GUw&aJ*5X8zr8$K0ZKEqy=O z3W}-CCN92rn8R94>c^O7&(Rj+F620OBD)lvu__0&rG9*I`c*lkH#nr&5E7RGelO>b zIQv8{q744pd}{YE(v$OJmI3qa^5@m&Aei3yFtxV9cb(~$i{hW^!P{+3NY}qJD}&{s zcgv<<26$s~x&1m*-&eXF|E}P357|c1f0u0`unMZ&6C9qCdMjem{@ml#vXXnorFT^C z*mxfI{>#mhmn>b(@uR=x*0|daEpGLPM~5v%$@FLIEIqqcX9tOkxc4>A=yVfmgIiOL zoi*^p8pf-odpW%2yha;UcC6y_&F+|VEO&1t9S=f`<+@kUeQ`T5$d z&Zm~EF=qU|Wb4f2cx?4&Z9g8FSB)7@r&X)g;hyms9c7;~8tjFP$>f6-V>(uJZ z-r){b>_E`*_e%rN?-uvNc$7)U7wJ7Vm)mbBQ znag35{pYdne&4XWJb9I;Ui(>Q&M|!H<$Xy$qu;BfJ}P$e%7n5sWCdUP_UN-1b?yn2 z>d(Ems_m;^8+n$bhOfRUD_3iuI}BdL+N5#Tab5PZ-lV6jH{tE6-ow_I1t|Lr^bNZ|4u7QFn_z486lLdH zy~KH>h~0Ux?-)NdTXva-Qlv6?t`}_d%4l+hCJtOosC%WuIg&>GRdu zV`{V7yo=l+f!kKSHv(45_>pY0^Ch)6LfU5-A?3a5eB?Agq)UZ+$Xb?V=6g(mk-rSewZ2C%2+nUzoJQYy86Zd2;J zx9>ImE%u(ezR8L0E{fIj`(__DNoa3ZFA1l%CnZJIe8#i`zukIyr<@ zwaBEmHIB23UcEIHd7lHH zUAU;VG`B~(2k14T_Px2WcAxO{`?}$>>zHt7Yg)+5@toA0MIX*&`-+6_tmVGFpY+uF z7R;yn8SInv<>9RKCpOEP-g1~j@-+)t<33D3JpMiOf6Bev&C8@_tBCiBjWfnOv{HL+ zp25DAnv?C8D|1~%9fru$<#kFGJ94V z_RK=jQ|y_ST!xfe>8<8r^X2)RTIpV?Tnkus?{BA7uYDc!ZH;BAm!6M(V*SDk>(ft) zt#9$tO?3gQV@ubAU8~toZB58C^V41wTzyo2wmgkAYP3=1%f;=WUMz ztxjDl-7?i$YhHG3YnnwwdEmYsjvZAXtgtzTZslf_d)iBZXC;cIXzHJaG9 zHFg*em2@XLHU&s$uh^GqE_sbB%XGpIktPsV~uXgt+>M;4_LE= zH?5(bVs%I<>ZN9LeXLw}O*Zy&yFIe6SaaQ@TF=;B8OQtOr5f+|fqCzYycTlU`uK{+ zx7*S4v*tgWcV=~BwXoe1hx_k)nP0^HbgYKk8od8<+1kNjE2QefvQUP{x7ziMc<%l) zOB3obX4&>kPGvT+yJV=>2c|h}*ScU0*wH9!`YxsvuC-|&V@;x`zwT3LZq?n|HZ0l2 znxQ?V@=hy>%guO~-qUpR_6Wy4(edV9N#G3Y}DHDU&YVKn$>KT zPxE=9v83my*4`lZ&YxoN_N3d|aqF^*+%F;Ag~vXA7*`$I_eo)HwX7Sh+>63_2^&~! zaeZ6!y0b|(P%AH`+W{||sm;}vep1Bas_h-%S&P!Ev1-l=jrFXmmq#sIF26fmjXTn~ ztNVk^d|_NP);dTpiCR5N@@bE(-^U%@?Sjv2m0rc<UO}*BPvzyt)qrEr#FwD7Skp zW}OgAxo0=HHBb5R8Sffxdc=;q`$x0;u$P7W7;CN8E%`<5Ww(vQ3acZdo7Y{vYFQuH zTrTc_Pi!o(XQOiLyEXRutD0Uq`^D~acYRl!kynxUIrB*>uYCTqg5A))t(_lw-!rb= zKd03{W9^8L#z^I6&~I4lKeaV0rJuwvx1!n0x5gZ#$5qRRNqZ@e_3X;F)zebGgp;Ye zCVSkKcIg=e%*Vs?^_HgF*3EBs^pSb3(PiB~z{|PT({*K^l}WwMq{cyHlZK2DwU9ab#?PwwOO6fV0iQUD*j!YOM9$L*wJ7+ET0uZnA1pd;l z0?Z-3VduT>XRE!-me^qYHnDUj9}Vk7QRDF|r5r04pSFHmS~H(h;w{4B)Xb~#XkF4+ z>y^bnZ^n3W*nD)$-hqHrW8J_jD}kxyV$%AgD3R@%1m6=m##`X~W%RAR+vT2Jv-s1` zPwI`vm=VAolD@rUYefvN>F*m`W>w0bK56Z#A5yC2eeJRm?z8Y(jy<)&?V{q2*wtxv(}E zF%2yTBh7`i!H8*SIT&d!tPMs?L(9QPb75^TVj5ZwMw$z2gAvovaxl_dSR0I(hL(eo z=EB-w#5A-Vj5HV41|z1S@jF^U&gOTRK+F-;q zv>c2y7uE(NrlI9vq`9y*7%>ek2P4gewZVvKXgL^ZF02hkOhe1TNONIrFk%{74n~>_ zYl9Kf&~h-+Tv!{7n1+^vk>y<)&?V{q2*wtxv(}EF%2yTBh7`i!H8*S zIT&d!tPMs?L(9QPb75^TVj5ZwMw$z2gAvovaxl_dSR0I(hL(eo=EB-w#5A-Vj5HV4 z1|z1S@jF^U&gOTRK+F-;qv>c2y7uE(NrlI9v zq`9y*7%>ek2P4gewZVvKXgL^ZF02hkOhe1TNONIrFk%{74n~>_Yl9Kf&~h-+Tv!{7 zn1+^vk>y<)&?V{q2*wtxv(}EF%2yTBh7`i!H8*SIT&d!tPMs?L(9QP zb75^TVj5chJu>>G`BU@9M)R1j{XLSJPeUIGMw$z2gAvovaxl_dSR0I(hL+1S`nBy# zZZ|iZ$E}2(Wvlt~C?5}NVxgbdXRmqDJZ%n}pRDgXY_^-D=2>%Q-_PvGq&+@u4(#`# z{n~9H|6oU^_Uq4W+Qv-RIz8yIrRABW#y?lji6L)O`#Wk*?fa+Z>*fo~^Ez?7XpSw{ z9>c`KyJo-MwZE4}W;#lkKQvD)q#vy;&YFGuyl(j0R$9B1W*z<&JL4ldE9Y^`a)$EW zn^_6+no7l;YJKQL-%rd@~l)Z*rPhA^L6sHgThXm*-^TB;JE zR2DhiN!qd!df(2-VLY|ep0zpJZd1BWs`^Z`9bB=vJ{m2ju!9$t-V@8`qFf@cTg`{P zoZ{;Dth7)D|DSVt`kQijy_ZW|{W`hq*J-y}u6KQ_;@@szuguD)W>FI>uc!9^d#eSf z&Cjg{C4gG9UL8;=Of@Q{(NjD|86zwX`-)i==e94q)h)_>3NPn>opkmYbZgw3R?Dy2 zXPuB=S*hjLLAUAaggZ=es>j!?|3N?WZgZvmMhkjkwH$5QnDKnri6_PVVROq$ch@X) zotR+XT>iV3X7m8r3b`gDhOIW9Ej#0p#kpgD$!o~R(63}Yhpy%Cjnqqv6?F?|oX%Ru ztLM4RIwy_T*2ypWv6ERmhzoUN*dn8DgTbVEWwm`-JO|cWKCvr)Zm&prOnFK&{$H`b zE|+z4(6_Oo|lrJf6e-Acmv0+|8Z*lI()!amQQ$x$nmKi1L<@m^~mrN zQIp28W2AMbjVaq#zvo{@J2TDFiKUtCxE~LQe7Lk6b9hk2|;O%+8MvzqicdV56tz0l+$u%S8FJwMy{B`e^js z{>kZaOY|f9d#g(0;iKb65*Yt!(M*RkH6w*5oxO`n`X*zMJGy&q5C zuZ&8Pw%T+YSuXdi4LY#@&n?dw>%nh1YWoJXJ*Xkxww}n8dQ0XZcVmSAgO)mLuQb^b zy$>Fc1{egY%7-4XRUG12i?pqs)QFUrZ zCwAn8>C$-n#LoJuwVriSyKBt3XF(lGEdsap-tNpRgWq1RWA#?5WggPLZmsis)@Kcg zZ&7X!j4F@%Fy=e4vc#D2c}sZRF%jxWjvI`JX?)XW7`~vh^7&hBZ9@n?u7ho$#-;SE zQ||qq!Tpry77OMk{CA#F$mxN!)s9Ut*MO8DG^8iZ2~CV?@`6D0#d$irAuRs|FWYS! zXAik~Dv|2pXUkeEw4f+Gu=3i&a}n@Aa2%;WXw$u38TWeuPT6Wa$1laj?F@KzOA&r+ zYR}QaOpVI_&d9BowyxFpi6C|GKJvWKlXLr?*Uk*fxT_iVAF7@45e8zxIODP9wLhXt z=U~jmN4l{Mf6eoQd{hBT@E+2~TI;aI3|AUGr*;KnC~r~R+Tca36L!D9?1z1&@sacV z(Tn#7JYr#5!*c4AUMJ=AJ;R*lb;3nE)TQk+xUgyGyiUmd(Q%jc>!lh!ixi<+LMBMHhtiuU@e0RnlA^P~mTNE`?OzeCdthGx!Rr*#tJ2&} z;qccm&8n9`$hl8_ow>?+cIiDe_uf8txK6%OndkiWJtP0^voDw<%xA-E>-)7B557Df z5yIE~+fw4mV!9zK;$zGLtD2a{8L2&6hvd)?`p`(Fa_YCgAh_;q>oA_{=kYA>N4;(` z>!FwBAzrbNvxnv7zIw_z7B!=y>&iOx`+Wx6t@jyeJ|X$|>%;-_JO(^%oKuc%opAf@ zcn&SwF&~ukdS1=YA9W_DYtKUKu^L(+lqAx+XsqT|y6X3;?F>rROGc0JhcWVf zIUJqWllqm5#=zXFa$3A)_AusskC&D-7j$>kyHkdpnP2A`~ys`;V#xNUh#=GATFDp??}DO(<%P7~_4 zw?fOqn3pCVUA$f>oE>FP+)B8I^Tmblo?f>AJn4J@;h zWyiyg!j8g@xaa3}5lNrwNYpi^6#fy@&~h-+Tv!{7n1+^vk>y<)&?V{ zq2*wtxv(}EF%2yTBh7`i!H8*SIT&d!tPMs?L(9QPb75^TVj5ZwMw$z2gAvovaxl_d zSR0I(hL(eo=EB-w#5A-Vj5HV41|z1S@jF^U& zgOTRK+F-;qv>c2y7uE(NrlI9vq`9y*7%>ek2P4gewZVvKXgL^ZF02hkOhe1TNONIr zFk%{74n~>_Yl9Kf&~h-+Tv!{7n1+^vk>y<)&?V{q2*wtxv(}EF%2yT zBh7`i!H8*SIT&d!tPMs?L(9QPb75^TVj5ZwMw$z2gAvovaxl_dSR0I(hL(eo=EB-w z#5A-Vj5HV41|z1S@jF^U&gOTRK+F-;qv>c2y z7uE(NrlI9vq`9y*7%>ek2P4gewZVvKXgL^ZF02hkOhe1TNONIrFk%{74n~>_Yl9Kf z&~h-+Tv!{7n1+^vk>y<)&?V{q2*wtxv(}EF%2yTBh7`i!H8*SIT&d! ztPMs?L(9QPb75^TVj5ZwMw$z2gAvovaxl_dSR0I(hL(eo=EB-w#5A-Vj5HV41|z1S z@jF^U&gOTRK+F-;qv>c2y7uE(NrlI9vq`9y* z7%>ek2P4gewZVvKXgL^ZF02hkOhe1TNONIrFk%{74n~>_Yl9Kf&~h-+Tv!{7n1+^v zk>y<)&?V{q2*wtxv(}EF%2yTBh7`i!H8*SIT&d!tPMs?L(9QPb75^T zVj5ZwMw$z2gAvovaxl_dSR0I(hL(eo=EB-w#5A-Vj5HV41|z1SCF?HNWG}zrF=B ze|U>6sGR(`xzjvq?l=EvCe6d<3;X|#$#d0}OLVxNQN*lO~m{WWP&yQlW|wE4+&&rII7qo=0X zZQeD_etQ(Qa%}R%tmnC%F|{-I+T*9DpS0KDdbAQ#izCHwY@wdou>%Vcf6v-85yr8d ziStvKrxqsCHfgWiw`*RtaUfQtX1D!D+K=tp1JkASP3#CXXO=g#PKfK&j;Gj@9l-ul zE!?*whjt#~dE3rI&L_-twsEX@b)(PK-`shtU` zCnilzzhmDiU0{lkb}Y;@OTTmJUwvptP-5LYdF%-DndRWL%}pwUGm}%9IA6r&6cU3M zmRH2NZ}f2#+;UmIv=lwHbfGMsx5sg==izCauN1?{`I)&jL3pXOKCoD(_6zAbY}ut0 z9kfKa)KLO`k~tjEhIJ*YN;LczY~jda@N-^SijOTn^GoOtv)Yg>ZQpV*wGdKXVeK9g zY${nIQj&7|y`>yw=;wGj?Ay7>;c;8~$-JwU#Lkr<)8xFSt$@)_J z;%D`1OsY?)pQw+ijYdm|5MNpfr(|u*YS{bclhpJ~F1o~Z{LbKU^Obo?Xoui6J#M}; zPxeu(xof&f^R@kY*nDdq)NRw=Hq9G$29DtP8*MxJUF%3^K{vgKGo=Jx)keG$Qe@hMH}OT z_9|TW#VijuP5!#2`Pk05Wof~F?d%9j59zySpPb*DEgh7~BO=?U;0$ird0$(O5bu{38hGN`d&V0Ckh9NC zf){<);`-da@hj&xl`YEXrk!!WWrK0iefvW`a_OS9P$np853S4eyY_fKE9D#Z16sH2 z`nxSFw=AR{j9_y(igH2eKeGRBQ#n@HE6C$4e4GI+A4lB2Pzn!cIdR)gmh4uF^rW~^ z{+uqa6S+KwH7teV_L;^j!_-dN5i%qO#iE!WJ1#F!YLOnl&FF>0bS#s?A~mKZfUjo`3G>c_mXM(acPSYyFFtbm7>#hjWDc&ePjbi(_ zGF-{ehmL72d@~ca;e=WMq!wp7H-%op{>U3)Ey!!3I(c7<@|{ouyV2>e+0%HqV(%-| zLnDeo4+78f)fzj;(|WKO)iczL+JaA>#(-fGziFDm**K7bPr2>`ho5hR?blYrnr#3= zbd@*$vZ*b{Ip}kO&TzEJ&p#xrt*=rSc0|G;*pATx6_GE1CH&H0J46p@N-1FKD@Q(b zSd+U;BS|IE3}EFT;ciKvqc)YeTP3dDHL*F>a>Y^}yzO*(C8Yt(1`0@jCdwPfwI}$@ z@aer=O{MIX0@CFi z6p?GD+;z?2L(jB$-QF;Q$FW(Y5Tt15(WmUZKDUoA#PT+Qa@f2ZOKRrV$L?9%rHGWv zD2WBGta+5lB7Q4NBg`2=!y{^K-_2nBisKPCC-_#kZa&lhvxR?3G;!zYNq+a_e!g}3 zsCj7My0rqyP0!Gp&AWpf>U2PQSm)Ac*PaKwpumXa<^Gi2p9WVEuLzD?tOL>(_V)Vy0SG<&P(Aeq|2SGbbhNy*FIi2VF`=0*K8Kv-c2fc`E zgtfVlIg|g>h0cDqP{XmQhShgsyuK9R;$orpF_~4gY9jw~Da3kdpjrM+Vji<-a#|7G zC5}srK@MoIZJXvGFB?^+^J1F?2<8kw59ghHxpatEqE?>)9c2(?$VJEVWI%2I1HUy+ zbpoxqzBH(DzGN*0AM2|}oP}IF9E^WkOF)Y+3#x1 151 _cnip ; + +\ u*/mod ( u1 u2 u3 -- u4 u5 ) u5 = (u1*u2)/u3, u4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: u*/mod +: u*/mod rot2 um* rot um/mod ; + +\ u*/ ( u1 u2 u3 -- u4 ) u4 = (u1*u2)/u3 Uses a 64bit +\ intermediate result. +ifnot: u*/ +: u*/ rot2 um* rot um/mod nip ; + +\ sign ( n1 n2 -- n3 ) n3 is the xor of the sign bits of +\ n1 and n2 +ifnot: sign +: sign xor 80000000 and ; + +\ */mod ( n1 n2 n3 -- n4 n5 ) n5 = (n1*n2)/n3, n4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: */mod +: */mod 2dup sign >r abs rot dup r> sign >r abs rot abs + um* rot um/mod r> if negate swap negate swap then ; + +\ */ ( n1 n2 n3 -- n4 ) n4 = (n1*n2)/n3. Uses a 64bit +\ intermediate result. +ifnot: */ +: */ */mod nip ; + +\ /mod ( n1 n2 -- n3 n4 ) \ signed divide & mod n4 = n1/n2, +\ n3 is the remainder +ifnot: /mod +: /mod 2dup sign >r abs swap abs swap u/mod r> if negate swap + negate swap then ; + +\ * ( n1 n2 -- n1*n2) n1 multiplied by n2 +ifnot: * +: * um* drop ; + +\ / ( n1 n2 -- n1/n2) n1 divided by n2 +ifnot: / +: / /mod nip ; + +\ rnd ( -- n1 ) n1 is a random number from 00 - FF +ifnot: rnd +: rnd cnt COG@ 8 rshift cnt COG@ xor FF and ; + + diff --git a/forth/basics.mod b/forth/basics.mod new file mode 100644 index 0000000..aa7be0a --- /dev/null +++ b/forth/basics.mod @@ -0,0 +1,485 @@ +fl + +hex + +: mod:basics ; + +\ Copyright (c) 2010 Sal Sanci +\ Anpassung für Hive-System 2011 dr235 + +\ ------------------------------------------------------ BASICS + +\ this words needs to align with the assembler code +: _stptr 5 _cv ; +: _sttop 2e _cv ; + +\ _words ( cstr -- ) +: _words lastnfa + begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= + until 2drop cr ; + +\ words name ( -- ) prints the words in the forth dictionary +: words parsenw _words ; + +\ .long ( n -- ) emit 8 hex digits +: .long dup 10 rshift .word .word ; + +\ st? ( -- ) prints out the stack +: st? ." ST: " _stptr COG@ 2+ dup _sttop < + if _sttop swap - 0 + do _sttop 2- i - COG@ .long space loop + else drop + then cr ; + +\ variable ( -- ) skip blanks parse the next word and create +\ a variable, allocate a long, 4 bytes +: variable + lockdict create $C_a_dovarl w, 0 l, forthentry freedict ; + +\ constant ( x -- ) skip blanks parse the next word and create +\ a constant, allocate a long, 4 bytes +: constant + lockdict create $C_a_doconl w, l, forthentry freedict ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +: waitpeq _execasm2>0 1E0 _cnip ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ (forget) ( cstr -- ) wind the dictionary back to the word +\ which follows - caution +: (forget) dup +if + find if + pfa>nfa nfa>lfa dup here W! W@ wlastnfa W! + else .cstr 3f emit cr then +else drop then ; + +\ forget ( -- ) wind the dictionary back to the word which +\ follows - caution +: forget parsenw (forget) ; + +\ free ( -- ) display free main bytes and current cog longs +: free dictend W@ here W@ - . ." bytes free - " par + coghere W@ - . ." cog longs free" cr ; + +\ ifnot: name ( -- ) - bedingte compilierung; wenn name schon +\ im wörterbuch vorhanden, wird bis zum nächsten semikolon +\ der eingabestrom ignoriert +: ifnot: parsenw nip find if begin key 3B = until + key drop then ; +\ bei konstrukte, die keine doppelpunkdefinition sind, muss der +\ block mit diesem Wort abgeschlossen werden +: :; ; + +\ --------------------------------------------------------- BUS + +\ bin ( -- ) - umschaltung auf duales zahlensystem +\ : bin 2 base W! ; +\ +---------------------------- /hs +\ |+--------------------------- /wr +\ ||+-------------------------- busclk +\ |||+------------------------- hbeat +\ ||||+------------------------ al +\ |||||+----------------------- /bel +\ ||||||+---------------------- /adm +\ |||||||+--------------------- /ram2 +\ ||||||||+-------------------- /ram1 +\ ||||||||| +--------- a0..10 +\ ||||||||| | +\ ||||||||| | +- d0..7 +\ |||||||||+---------++------+ +\ 00000000000000000000000000000000 +\ bin 00000111111111111111111100000000 constant dinp hex +\ bin 00000111111111111111111111111111 constant dout hex +\ bin 00000010000000000000000000000000 constant boff hex +\ bin 00000100011110000000000000000000 constant _s1 hex +\ bin 00000000001110000000000000000000 constant _b1 hex +\ bin 00000010001110000000000000000000 constant _b2 hex +\ bin 00000110001110000000000000000000 constant _b3 hex +\ bin 00000000010110000000000000000000 constant _a1 hex +\ bin 00000010010110000000000000000000 constant _a2 hex +\ bin 00000110010110000000000000000000 constant _a3 hex +\ bin 00001000000000000000000000000000 constant ?hs hex + +8000000 constant ?hs + +: [inp] \ ( -- ) bus eingabe + 7FFFF00 dira COG! ; \ dinp + +: [out] \ ( -- ) bus ausgabe + 7FFFFFF dira COG! ; \ dout + +: [off] \ ( -- ) bus aus + 2000000 dira COG! 0 outa COG! ; \ boff + +: [end] \ ( -- ) buskommunikation beendet + 4780000 outa COG! [inp] ; \ _s1 + +: [hs=1] \ ( -- ) wartet auf hs = 1 + ?hs dup waitpeq ; + +: [hs=0] \ ( -- ) warten auf hs = 0 + 0 ?hs waitpeq ; + +: [s!] \ ( c ctrl -- ) sende 8 bit an einen slave + [out] [hs=1] swap ff and or outa COG! [hs=0] [end] ; + +: [s@] \ ( ctrl -- c ) empfängt 8 bit von einem slave + [inp] [hs=1] outa COG! [hs=0] ina COG@ ff and [end] ; + +: [b!] \ ( c -- ) sende 8 bit an bellatrix + 2380000 [s!] ; \ _b2 + +: [a!] \ ( c -- ) sende 8 bit an administra + 2580000 [s!] ; \ _a2 + +: [b@] \ ( -- c ) empfängt 8 bit von bellatrix + 6380000 [s@] ; \ _b3 + +: [a@] \ ( -- c ) empfängt 8 bit von administra + 6580000 [s@] ; \ _a3 + +: <8 \ ( -- ) + 8 lshift ; + +\ [b.l!] ( 32b -- ) - long an bellatrix senden +: [b.l!] + dup 18 rshift [b!] + dup 10 rshift [b!] + dup 8 rshift [b!] + [b!] ; + +\ [b.l@] ( -- 32b ) - long von bellatrix einlesen +: [b.l@] + [b@] <8 + [b@] or <8 + [b@] or <8 + [b@] or ; + +\ [a.s@] ( -- ) - einen cstring von administra empfangen +\ und im pad speichern +: [a.s@] + [a@] pad 2dup C! 1+ swap + 0 do dup [a@] swap C! 1+ loop drop ; + +\ [a.s!] ( cstr -- ) - einen cstring an administra senden +: [a.s!] + dup C@ dup [a!] \ ( -- cstr len ) len senden + 0 do \ ( cstr len -- cstr ) + 1+ dup C@ [a!] \ ( cstr -- cstr+1 ) zeichen senden + loop drop ; \ ( cstr -- ) + +\ [a.w@] ( -- 16b ) - 16bit-wert von administra einlesen +: [a.w@] + [a@] <8 [a@] or ; + +\ [a.l!] ( 32b -- ) - long an administra senden +: [a.l!] + dup 18 rshift [a!] + dup 10 rshift [a!] + dup 8 rshift [a!] + [a!] ; + +\ [a.l@] ( -- 32b ) - long von administra einlesen +: [a.l@] + [a@] <8 + [a@] or <8 + [a@] or <8 + [a@] or ; + +wvariable b[lock] \ nummer der semaphore für den + \ zugriff auf die bus-hardware + +\ b[ ( -- ) bus belegen; wartet bis semaphore freigegeben ist +: b[ begin b[lock] W@ lockset -1 <> until [inp] ; + +\ ]b ( -- ) bus freigeben +\ ! busclk bleibt auf ausgabe, da dieses signal sonst +\ kein definierten pegel besitzt ! +: ]b [off] b[lock] W@ lockclr drop ; + +\ administra-kommandoformate + +: b[a! b[ [a!] ; +: b[a!a! b[ [a!] [a!] ; +: adm:fkt! b[a! ]b ; \ ( fkt -- ) +: adm:fkt!b@ b[a! [a@] ]b ; \ ( fkt -- b ) +: adm:fkt!b! b[a!a! ]b ; \ ( b fkt -- ) +: adm:fkt!b!b@ b[a!a! [a@] ]b ; \ ( b fkt -- b ) +: adm:fkt!s@ b[a! [a.s@] ]b ; \ ( fkt -- ) +: adm:fkt!s!b@ b[a! [a.s!] [a@] ]b ; \ ( s fkt -- b ) +: adm:fkt!b!l@ b[a!a! [a.l@] ]b ; \ ( b fkt -- l ) + +\ ----------------------------------------------------- SD0.LIB + +\ marker-funktionen + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm:dmset ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; + +\ dateisystem-funktionen + +\ adm:volname ( -- ) - name des volumes im pad ablegen +: adm:volname 0C adm:fkt!s@ ; + +\ adm:mount ( -- err ) - medium mounten +: adm:mount 01 adm:fkt!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +: adm:unmount 18 adm:fkt!b@ ; + +\ adm:checkmounted ( -- t/f ) +: adm:checkmounted 0D adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +: adm:diropen 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +: adm:nextfile b[ 3 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +: adm:fattrib 0B adm:fkt!b!l@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis öffnen +: adm:chdir 16 adm:fkt!s!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus der geöffneten datei lesen +: adm:getc 06 adm:fkt!b@ ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +: adm:eof 1E adm:fkt!b@ ; + +\ adm:open ( cstr modus -- err ) - datei öffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +: adm:open b[ 4 [a!] [a!] [a.s!] [a@] ]b ; + +\ adm:close ( -- ) - datei schließen +: adm:close 05 adm:fkt!b@ ; + +\ ----------------------------------------------------- SCR.LIB + +\ [dscr] ( scrnr -- ) display-screen setzen +: [dscr] 0 [b!] 59 [b!] [b!] ; + +\ [wscr] ( scrnr -- ) schreib-screen setzen +: [wscr] 0 [b!] 58 [b!] [b!] ; + +\ [key?] ( -- c ) - ungekapselte tastaturstatusabfrage +: [key?] 0 [b!] 1 [b!] [b@] ; + +\ [key] ( -- c ) - ungekapselte tastaturabfrage +: [key] 0 [b!] 2 [b!] [b@] ; + +\ [emit] ( c -- ) - ungekapselte zeichenausgabe +: [emit] emit? if emit then ; + +\ ----------------------------------------------------- TOOLS + +\ cls ( -- ) - screen löschen +: cls 01 emit ; + +\ .tab ( -- ) - tabulator +: .tab 09 emit ; + +\ .err ( err -- ) - fehlermeldung ausgeben +\ 0 no error +\ 1 fsys unmounted +\ 2 fsys corrupted +\ 3 fsys unsupported +\ 4 not found +\ 5 file not found +\ 6 dir not found +\ 7 file read only +\ 8 end of file +\ 9 end of directory +\ 10 end of root +\ 11 dir is full +\ 12 dir is not empty +\ 13 checksum error +\ 14 reboot error +\ 15 bpb corrupt +\ 16 fsi corrupt +\ 17 dir already exist +\ 18 file already exist +\ 19 out of disk free space +\ 20 disk io error +\ 21 command not found +\ 22 timeout +\ 23 parameter error +: .err dup if ERR then drop ; + +\ .pad ( -- ) - ausgabe eines strings im pad +: .pad pad .cstr ; + +\ .vname ( -- ) - ausgabe des namens der eingelegten sd-card +: .vname adm:volname .pad ; + +\ mount ( -- ) - sd-card mounten +: mount adm:mount .err ." Medium : " .vname cr ; + +\ unmount ( -- ) - sd-card unmounten +: unmount adm:unmount .err ; + +\ mount? ( -- ) - test ob medium mounted ist +\ wird als exception gewertet +: mount? adm:checkmounted 0= if 1 .err then ; + +\ padbl ( -- ) fills this cogs pad with blanks +: padbl pad padsize bl fill ; + +\ .entry ( -- st ) - einen verzeichniseintrag ausgeben +: .entry + adm:nextfile 13 adm:fattrib if 0F emit else space then + dup if .pad .tab then ; + +\ .len ( st -- st ) - dateilänge ausgeben +: .len dup if 0 adm:fattrib . then ; + +\ lscnt ( cnt1 st -- cnt2 st ) - spaltenformatierung für ls +\ cnt - spaltenzähler, st - flag verzeichnisende +: lscnt + swap 1+ dup 4 = if cr drop 0 else .tab then swap ; + +\ lsl ( -- ) - verzeichnis anzeigen, long-format +: lsl mount? + adm:diropen begin .entry .len cr 0= until padbl ; + +\ ls ( -- ) - verzeichnis in spalten anzeigen +: ls mount? + adm:diropen 0 begin .entry lscnt 0= until drop padbl cr ; + +\ cd name ( -- ) - verzeichnis wechseln +: cd mount? parsenw adm:chdir .err ; + +\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geöffnete datei schließen +: close adm:close .err ; + +\ dload name - datei compilieren; log im gleichen screen +\ load name - datei compilieren; log screen 3 +\ sys name - datei aus sys compilieren; log screen 3 +\ die datei wird in der nächsten freien cog compiliert +\ fl ist für load nicht nötig und bringt in dem kontext +\ die cog-zuordnung durcheinander + +: (load) + begin adm:getc emit adm:eof until ; + +: (dload) + open cogid nfcog iolink + (load) + cogid iounlink close ; + +: (sload) + open cogid 3 dup b[ [wscr] ]b iolink + (load) + cogid dup b[ [wscr] ]b iounlink close ; + +: load + ." Loading... " (sload) ; + +: dload + (dload) ; + +: sys + 2 adm:dmset 1 adm:dmact ." Loading... " (sload) 2 adm:dmact ; + +\ ------------------------------------------------- SPIN-LOADER + +\ (spin) ( cstr -- ) - c" reg.sys" (spin) +: (spin) + dup C@ 1+ + 0 do + dup i + C@ + ldvar 1+ i + C! + loop drop + 1 ldvar C! +; + +\ spin name ( -- ) - spinobjekt "name" starten +: spin + parsenw (spin) ; + +\ regime ( -- ) - startet dir trios-cli "regime" +: regime + 0 adm:dmact + c" reg.sys" (spin) ; + +\ ----------------------------------------------------- DRV:INT + + +wvariable icog \ nummer der drv:int-cog +wvariable lcog \ nummer interaktiven cog + +\ xint ( n -- ) io von cog n auf drv:int umschalten +: xint icog W@ ioconn ; + +\ [cogscr] ( nr -- ) - umschaltung screen + cog +: [cogscr] + dup 2dup lcog W! xint [dscr] [wscr] ; + +\ =n ( n1 n2 -- n1 n1=n2 ) +: =n 2dup = swap drop ; + +\ [esc] ( -- ) - manager für esc-funktionen im drv:int +: [esc] + begin [key?] until [key] + 71 =n if 1b [emit] then \ esc - q : esc-char/quit + 31 =n if 1 [cogscr] then \ esc - 1 : cog-screen 0 + 32 =n if 2 [cogscr] then \ esc - 2 : cog-screen 1 + 33 =n if 3 [cogscr] then \ esc - 3 : cog-screen 2 + 62 =n if lcog W@ cogreset then \ esc - b : break (cog) + 72 =n if reboot then \ esc - r : reset (chip) + drop ; \ esc - esc : pause + +\ drv:int ( -- ) treiber für bellatrix-terminal +\ diese cog fragt in einer endlosschleife ab, ob zeichen +\ versendet oder empfangen werden sollen. um die zeichenausgabe +\ zu beschleunigen, findet ausgabe und eingabe in einem +\ verhältnis von 512:1 statt. per esc-code können spezielle +\ funktionen im driver ausgelöst werden. +: drv:int + \ name und typ der cog einstellen + cogid dup cogstate 10 swap C! c" drv:int" over + cognumpad ccopy + 20 delms 0D emit \ verzögertes cr für prompt + begin + \ input --> vga/video + 200 0 do key? \ eingabezeichen vorhanden? + if key b[ [b!] ]b then loop \ cog ---> bel.vga + \ output <-- keyboard + b[ [key?] \ tastenstatus bellatrix? + if [key] dup 1b = if drop [esc] else [emit] thens ]b + 0 until ; + +\ ----------------------------------------------------- SYSINIT + +: start \ ( -- ) initialisierung hive + locknew b[lock] W! \ b-semaphore + 0 dup cogstate 10 swap C! c" drv:ldr" over + cognumpad ccopy + 5 dup icog W! c" drv:int" swap cogx 1 b[ [cogscr] ]b ; +: _ob onboot ; +: onboot _ob start ; + + + diff --git a/forth/bel.lib b/forth/bel.lib new file mode 100644 index 0000000..0034988 --- /dev/null +++ b/forth/bel.lib @@ -0,0 +1,77 @@ + +hex + +ifnot: lib:bel +: lib:bel ; + +\ kommandoformate + +ifnot: bel:fkt! \ ( fkt -- ) +: bel:fkt! b[ 0 [b!] [b!] ]b ; + +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; + +ifnot: bel:fkt!b!l@ \ ( b fkt -- l ) +: bel:fkt!b!l@ b[ 0 [b!] [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b!l! \ ( l b fkt -- ) +: bel:fkt!b!l! b[ 0 [b!] [b!] [b!] [b.l!] ]b ; + +ifnot: bel:fkt!l@ \ ( fkt -- l ) +: bel:fkt!l@ b[ 0 [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ chipmanagment-funktionen + +ifnot: bel:wscr \ ( scrnr -- ) - schreibscreen setzen +: bel:wscr 58 bel:fkt!b! ; + +ifnot: bel:dscr \ ( scrnr -- ) - displayscreen setzen +: bel:dscr 59 bel:fkt!b! ; + +ifnot: bel:getcol \ ( colnr -- col ) - farbe abfragen +: bel:getcol 5A bel:fkt!b!l@ ; + +ifnot: bel:setcol \ ( col colnr -- ) - farbe setzen +: bel:setcol 5B bel:fkt!b!l! ; + +ifnot: bel:getresx \ ( -- resx ) - abfrage x-auflösung +: bel:getresx 5C bel:fkt!l@ ; + +ifnot: bel:getresy \ ( -- resy ) - abfrage y-auflösung +: bel:getresy 5D bel:fkt!l@ ; + +ifnot: bel:getcols \ ( -- cols ) - abfrage textspalten +: bel:getcols 5E bel:fkt!b@ ; + +ifnot: bel:getrows \ ( -- rows ) - abfrage textzeilen +: bel:getrows 5F bel:fkt!b@ ; + +ifnot: bel:getcogs \ ( -- cogs ) - abfrage belegte cogs +: bel:getcogs 60 bel:fkt!b@ ; + +ifnot: bel:getspec \ ( -- spec ) - abfrage codespezifikation +: bel:getspec 61 bel:fkt!l@ ; + +ifnot: bel:getver \ ( -- ver ) - abfrage codeversion +: bel:getver 62 bel:fkt!l@ ; + +ifnot: bel:load \ ( cstr -- ) - bellatrix-code laden +: bel:load + 52 adm:open .err \ datei öffnen + b[ + 0 [b!] 63 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilänge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schließen +; + + + + diff --git a/forth/cog.lib b/forth/cog.lib new file mode 100644 index 0000000..14c242e --- /dev/null +++ b/forth/cog.lib @@ -0,0 +1,74 @@ + +hex + +ifnot: lib:cog +: lib:cog ; + +\ cog special register + +ifnot: ctra 1F8 wconstant ctra :; +ifnot: ctrb 1F9 wconstant ctrb :; +ifnot: frqa 1FA wconstant frqa :; +ifnot: frqb 1FB wconstant frqb :; +ifnot: phsa 1FC wconstant phsa :; +ifnot: phsb 1FD wconstant phsb :; +ifnot: vcfg 1FE wconstant vcfg :; +ifnot: vscl 1FF wconstant vscl :; + +\ this words needs to align with the assembler code + +ifnot: _faddrmask : _faddrmask 1 _cv ; +ifnot: _flongmask : _flongmask 2 _cv ; +ifnot: _stptr : _stptr 5 _cv ; +ifnot: _sttos : _sttos 7 _cv ; +ifnot: _treg1 : _treg1 8 _cv ; +ifnot: _treg2 : _treg2 9 _cv ; +ifnot: _treg3 : _treg3 a _cv ; +ifnot: _treg4 : _treg4 b _cv ; +ifnot: _treg5 : _treg5 c _cv ; +ifnot: _treg6 : _treg6 d _cv ; +ifnot: _stbot : _stbot e _cv ; +ifnot: _sttop : _sttop 2e _cv ; +ifnot: _rsbot : _rsbot _sttop ; + +\ waitcnt ( n1 n2 -- n1 ) \ wait until n1, add n2 to n1 +ifnot: waitcnt +: waitcnt _execasm2>1 1F1 _cnip ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +ifnot: waitpeq +: waitpeq _execasm2>0 1E0 _cnip ; + +\ waitpne ( n1 n2 -- ) \ wait until state n1 is not equal +\ to ina anded with n2 +ifnot: waitpne +: waitpne _execasm2>0 1E8 _cnip ; + +\ lockret ( n1 -- ) deallocate a lock, previously allocated +\ via locknew +ifnot: lockret +: lockret 5 hubop 2drop ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +ifnot: locknew +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ cog+ ( -- ) add a forth cog +ifnot: cog+ +: cog+ (cog+) ; + +\ (cog-) ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: (cog-) +: (cog-) nfcog cogstop ; + +\ cog- ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: cog- +: cog- (cog-) ; + + + + diff --git a/forth/debug.mod b/forth/debug.mod new file mode 100644 index 0000000..937129d --- /dev/null +++ b/forth/debug.mod @@ -0,0 +1,65 @@ + +hex + +ifnot: mod:debug +: mod:debug ; + +\ keycode ( -- ) - anzeige der tastaturcodes +ifnot: keycode +: keycode + begin + 0 key? if + drop key dup dup ." code : " emit ." : " . cr 1B = + then until ; + +\ +\ Noisy reset messages +\ +\ print out a reset message to the console +\ (rsm) ( n -- ) n is the last status +\ 0011FFFF - stack overflow +\ 0012FFFF - return stack overflow +\ 0021FFFF - stack underflow +\ 0022FFFF - return stack underflow +\ 8100FFFF - no free cogs +\ 8200FFFF - no free main memory +\ 8400FFFF - fl no free main memory +\ 8500FFFF - no free cog memory +\ 8800FFFF - eeprom write error +\ 9000FFFF - eeprom read error + +: (rsm) state W@ 2 and 0= swap +\ process the last status + dup 0= if c" ok" else + dup FF11 = if c" DST OVER" else + dup FF12 = if c" RST OVER" else + dup FF21 = if c" DST LOW" else + dup FF22 = if c" RST LOW" else + dup 8001 = if c" COGs OUT" else + dup 8002 = if c" hMEM OUT" else + dup 8003 = if c" ROM WR" else + dup 8004 = if c" FL" else + dup 8005 = if c" cMEM OUT" else + dup 8006 = if c" ROM RD" else + c" ?" + thens + rot if + lockdict cr c" ERR : " .cstr swap . .cstr cr freedict + else 2drop then ; +: onreset (rsm) 4 state orC! ; + +\ .byte ( n1 -- ) +: .byte <# # # #> .cstr ; + +\ [if (dumpb) +: (dumpb) cr over .addr space dup .addr _ecs bounds ; ] + +\ [if (dumpm) +: (dumpm) cr .word _ecs ; ] + +\ [if (dumpe) +: (dumpe) tbuf 8 bounds do i C@ .byte space loop 2 spaces tbuf 8 bounds do i C@ dup bl < if drop 2e then emit loop ; ] + +\ dump ( adr cnt -- ) uses tbuf +[if dump +: dump (dumpb) do i (dumpm) i tbuf 8 cmove (dumpe) 8 +loop cr ; ] diff --git a/forth/error.txt b/forth/error.txt new file mode 100644 index 0000000..17013b3 --- /dev/null +++ b/forth/error.txt @@ -0,0 +1,40 @@ + +Reset-Fehlercodes: + +0011FFFF - stack overflow +0012FFFF - return stack overflow +0021FFFF - stack underflow +0022FFFF - return stack underflow +8100FFFF - no free cogs +8200FFFF - no free main memory +8400FFFF - fl no free main memory +8500FFFF - no free cog memory +8800FFFF - eeprom write error +9000FFFF - eeprom read error + +.err-Fehlercodes: + +0 no error +1 fsys unmounted +2 fsys corrupted +3 fsys unsupported +4 not found +5 file not found +6 dir not found +7 file read only +8 end of file +9 end of directory +10 end of root +11 dir is full +12 dir is not empty +13 checksum error +14 reboot error +15 bpb corrupt +16 fsi corrupt +17 dir already exist +18 file already exist +19 out of disk free space +20 disk io error +21 command not found +22 timeout +23 parameter error diff --git a/forth/hplay.mod b/forth/hplay.mod new file mode 100644 index 0000000..2916ebe --- /dev/null +++ b/forth/hplay.mod @@ -0,0 +1,155 @@ + +hex + +ifnot: mod:hplay +: mod:hplay ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; + +\ hss-funktionen + +ifnot: hss:load \ ( cstr -- err ) - hss-datei laden +: hss:load dup if 64 adm:fkt!s!b@ then ; + +ifnot: hss:play \ ( -- ) - datei im puffer abspielen +: hss:play 65 adm:fkt! ; + +ifnot: hss:stop \ ( -- ) - player stop +: hss:stop 66 adm:fkt! ; + +ifnot: hss:reg \ hreg ( regnr -- 16b ) +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +ifnot: hss:vol \ hvol ( vol -- ) - lautstärke 0..15 +: hss:vol 6A adm:fkt!b! ; + +\ keyboard-funktionen + +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; + +\ steuerzeichen + +ifnot: scr:cls \ ( -- ) - screen löschen +: scr:cls 01 bel:char ; + +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; + +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; + +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; + +\ sd0-funktionen + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ metafunktionen + +\ hload name ( -- ) - hss-datei in player laden + +ifnot: hload +: hload mount? parsenw hss:load .err ; + +ifnot: .hset +: .hset \ ( shift -- ) - eine registersatz ausgeben + 5 0 do dup i + hss:reg .word space loop drop ; + +ifnot: .hreg +: .hreg \ ( -- ) - register ausgeben + 14 0 do i .hset cr 5 +loop ; + +ifnot: fadeout +: fadeout \ ( -- ) - sound langsam ausblenden + f 0 do e i - hss:vol 50 delms loop ; + +ifnot: end? +: end? \ ( cnt -- flag ) - abfrage nach cnt wiederholungen + 4 hss:reg = ; + +ifnot: hwait +: hwait \ ( -- flag ) - wartet auf songende oder taste + begin 50 delms key? 2 end? or until key drop ; + +ifnot: hreg.. +: hreg.. \ ( -- ) - fortlaufende anzeige register + scr:curoff scr:cls begin scr:home .hreg 2 end? until + scr:curon fadeout hss:stop ; + +ifnot: (hplay) +: (hplay) \ ( cstr -- ) + ." Datei : " dup .cstr hss:load .err f hss:vol hss:play + hwait fadeout hss:stop 100 delms cr ; + +\ hplay name ( -- ) - datei abspielen +ifnot: hplay +: hplay + hload hss:play ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ hdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur hss-dateien sein! +ifnot: hdirplay +: hdirplay + decimal files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (hplay) loop padbl hex ; + +: (hp) ." play : " dup .cstr hss:load .err ; + +ifnot: playliste +: playliste + c" kw.hss" (hplay) + c" genes.hss" (hplay) + c" greenpuz.hss" (hplay) + c" hssintro.hss" (hplay) + c" kali766.hss" (hplay) + c" machine.hss" (hplay) + c" metroid.hss" (hplay) + c" mrboss.hss" (hplay) + c" mrevil.hss" (hplay) + c" raind.hss" (hplay) + c" sytrus.hss" (hplay) + c" tbellsp1.hss" (hplay) ; + diff --git a/forth/hss.lib b/forth/hss.lib new file mode 100644 index 0000000..33db039 --- /dev/null +++ b/forth/hss.lib @@ -0,0 +1,60 @@ + +hex + +ifnot: lib:hss +: lib:hss ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +\ hss-funktionen + +\ ( cstr -- err ) - hss-datei laden +ifnot: hss:load +: hss:load dup if 64 adm:fkt!s!b@ then ; + +\ ( -- ) - datei im puffer abspielen +ifnot: hss:play +: hss:play 65 adm:fkt! ; + +\ ( -- ) - player stop +ifnot: hss:stop +: hss:stop 66 adm:fkt! ; + +\ ( -- ) - player pause +ifnot: hss:pause +: hss:pause 67 adm:fkt! ; + +\ hreg ( regnr -- 16b ) +\ 0 iEndFlag iRowFlag iEngineC iBeatC iRepeat Player +\ 5 iNote iOktave iVolume iEffekt iInstrument Kanal 1 +\ 10 iNote iOktave iVolume iEffekt iInstrument Kanal 2 +\ 15 iNote iOktave iVolume iEffekt iInstrument Kanal 3 +\ 20 iNote iOktave iVolume iEffekt iInstrument Kanal 4 +\ +\ iEndFlag Repeat oder Ende wurde erreicht +\ iRowFlag Trackerzeile (Row) ist fertig +\ iEngineC Patternzähler +\ iBeatC Beatzähler (Anzahl der Rows) +\ iRepeat Zähler für Loops +ifnot: hss:reg +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +\ hvol ( vol -- ) - lautstärke 0..15 +ifnot: hss:vol +: hss:vol 6A adm:fkt!b! ; + diff --git a/forth/key.lib b/forth/key.lib new file mode 100644 index 0000000..45204a5 --- /dev/null +++ b/forth/key.lib @@ -0,0 +1,17 @@ + +hex + +ifnot: lib:key +: lib:key ; + +\ kommandoformate +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ keyboard-funktionen +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; +ifnot: key:code \ ( -- code ) - tastencode abfragen +: key:code 2 bel:fkt!b@ ; +ifnot: key:spec \ ( -- spec ) - spezialtasten abfragen +: key:spec 4 bel:fkt!b@ ; diff --git a/forth/rom.mod b/forth/rom.mod new file mode 100644 index 0000000..9a91eda --- /dev/null +++ b/forth/rom.mod @@ -0,0 +1,206 @@ + +\ ACHTUNG: Diese Modifikation nicht bei einer Installation im +\ HI-EEPROM verwenden! + +hex +[if mod:rom +: mod:rom ; ] + +\ constant ( x -- ) skip blanks parse the next word and create a constant, allocate a long, 4 bytes +[if constant +: constant lockdict create $C_a_doconl w, l, forthentry freedict ; ] + +\ +\ CONFIG PARAMETERS BEGIN +\ +40 wconstant fsps \ a page size which works with 32kx8 & 64kx8 eeproms + \ and should work with larger as well. + + +8000 constant fsbot \ file-system bottom: the start adress in eeprom for the file system + + \ file system top: the end address of the file system + \ uncomment the line for your comfiguration +\ 8000 constant fstop \ the end address for the file system with one 24LC256 32k eeprom +10000 constant fstop \ the end address for the file system with one 24LC512 64k eeprom +\ 20000 constant fstop \ the end address for the file system with two 24LC512 64k eeprom +\ 30000 constant fstop \ the end address for the file system with 3 24LC512 64k eeprom +\ 40000 constant fstop \ the end address for the file system with 4 24LC512 64k eeprom +\ 50000 constant fstop \ the end address for the file system with 5 24LC512 64k eeprom +\ 60000 constant fstop \ the end address for the file system with 6 24LC512 64k eeprom +\ 70000 constant fstop \ the end address for the file system with 7 24LC512 64k eeprom + +\ NOTE IF you have DEMOBOARD or any system with 32K EEPROM, you will step on your spin image +\ when you write to the EEPROM. You can still use it (if you are tricky), but KNOW WHAT YOUR DOING!!! + +\ +\ CONFIG PARAMETERS END +\ + + +\ lasti? ( -- t/f ) true if this is the last value of i in this loop +[if lasti? +: lasti? _rsptr COG@ 2+ COG@ 1- _rsptr COG@ 3 + COG@ = ; ] + +\ padbl ( -- ) fills this cogs pad with blanks +[if padbl +: padbl pad padsize bl fill ; ] +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ EW@ ( eeAddr -- n1 ) +[if EW@ +: EW@ t0 2 eereadpage if 8006 ERR then t0 W@ ; ] + +\ EC@ ( eeAddr -- c1 ) +[if EC@ +: EC@ EW@ FF and ; ] + +\ (fspa) ( addr1 -- addr2) addr2 is the next page aligned address after addr1 +: (fspa) fsps 1- + fsps 1- andn ; + +\ (fsnext) ( addr1 -- addr2 t/f) addr - the current file address, addr2 - the next addr, t/f - true if we have +\ gone past the end of the eeprom. t0 -length of the current file +\ t1 - length of the file name (char) +: (fsnext) t0 W@ t1 C@ + 2+ 1+ + (fspa) dup fstop >= ; + + +\ (fswr) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to write, addr2 - the address to write from +\ n1 - the number of bytes to write +: (fswr) dup >r rot dup r> + fstop 1- > if A0 ERR then rot2 eewritepage if 88 ERR then ; + +\ (fsrd) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to read, addr2 - the address of the read buffer +\ n1 - the number of bytes to read +: (fsrd) dup >r rot dup r> + fstop 1- > if C0 ERR then rot2 eereadpage if 90 ERR then ; + +\ (fsfree) ( -- n1 ) n1 is the first location in the file system, -1 if there are none +: (fsfree) -1 fsbot begin +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) t0 W@ FFFF = if nip dup -1 else (fsnext) then +until drop ; + +\ (fsfind) ( cstr -- addr ) find the last file named cstr, addr is the eeprom address, 0 if not found +: (fsfind) fsbot 0 >r begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + over t1 cstr= if r> drop dup >r then + (fsnext) + then +until 2drop r> ; + +\ (fslast) ( -- addr ) find the last file, 0 if not found +: (fslast) 0 fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + nip dup + (fsnext) + then +until drop ; + +\ fsclear ( -- ) +: fsclr padbl fsbot 400 + fsbot do i pad fsps (fswr) 2e emit fsps +loop -1 fsbot EW! ; +: fsclear -1 fsbot EW! ; + +\ fsfree ( -- ) +: fsfree (fsfree) dup -1 = if 0 else fstop swap - then . ." bytes free in fs" cr ; + +\ fsls ( -- ) list the files +: fsls cr fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + dup .addr space t0 W@ .addr space t1 .cstr cr + (fsnext) + then +until fstop swap - cr . ." bytes free in files system" cr cr ; + +\ (fsread) ( cstr -- ) +: (fsread) (fsfind) dup if +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) + t1 C@ + 2+ 1+ t0 W@ bounds do + ibound i - fsps >= if + i pad fsps (fsrd) pad fsps bounds + do i C@ emit loop i fsps 1- + seti + else + i EC@ emit + then + loop +else drop then padbl ; + +\ fsread ( -- ) filename +: fsread parsenw dup if (fsread) else drop then ; + +\ (fsload) ( ctsr -- ) +: (fsload) cogid nfcog iolink (fsread) d emit d emit cogid iounlink ; + +\ fsload filename ( -- ) send the file to the next free forth cog +: fsload parsenw dup if (fsload) else drop then ; + +\ (fsk) ( n1 -- n2) +: (fsk) 8 lshift key or ; + +\ fswrite filename ( -- ) writes a file until ... followed immediately by a cr is encountered +: fswrite (fsfree) dup -1 <> parsenw dup rot and if +\ set the file length to 0, copy in the file name + 0 pad W! dup C@ 2+ 1+ pad + swap pad 2+ ccopy +\ find the first free page + 0 swap key (fsk) (fsk) (fsk) +\ ( eaddr1 n1 addr2 n2 ) eaddr - start of file in the eeprom, n1 - bytes written so far, addr2 - next addr in the pad, +\ n2 - a 4 byte key buffer + begin +\ check to see if we have a ... at the end of a line + 2E2E2E0D over = if + -1 + else +\ get a key from the key buffer, write it the the pad + swap over 18 rshift dup dup d = if drop cr else emit then over C! 1+ tuck pad - fsps = if +\ we have a page worth of data, write it out + nip rot2 2dup + pad fsps (fswr) fsps + rot pad swap + then +\ get another key + (fsk) 0 + then + until +\ any keys left? + drop pad - dup 0> if +\ write the leftover, not a full page + >r 2dup + pad r> dup >r (fswr) r> + + else + drop + then +\ write the length of FFFF for the next file + 2dup + FFFF swap (fspa) dup fstop 1- < if EW! else 2drop then +\ subtract the length of the filename +1, and the 2 bytes which are the length of the file, and update the length of the file + over 2+ EC@ 2+ 1+ - swap EW! +else 2drop clearkeys then padbl +; + +\ fsdrop ( -- ) deletes last file +: fsdrop (fslast) dup -1 = if drop else FFFF swap EW! then ; + + diff --git a/forth/scr.lib b/forth/scr.lib new file mode 100644 index 0000000..a879692 --- /dev/null +++ b/forth/scr.lib @@ -0,0 +1,69 @@ + +hex + +ifnot: lib:scr +: lib:scr ; + +\ kommandoformate +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl! \ ( ctrl -- ) +: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl!b@ \ ( ctrl -- b@ ) +: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ; +ifnot: bel:ctrl!b!b! \ ( b b ctrl -- ) +: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ; + +\ einfache steuerzeichen +ifnot: scr:cls \ ( -- ) - screen löschen +: scr:cls 01 bel:char ; +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:scrlu \ ( -- ) - screen nach oben scrollen +: scr:scrlu 06 bel:char ; +ifnot: scr:scrld \ ( -- ) - screen nach unten scrollen +: scr:scrld 07 bel:char ; +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; + +\ screen-funktionen +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; +ifnot: scr:char \ ( char -- ) - zeichensatz direkt ausgeben +: scr:char 6 bel:fkt!b! ; + +\ parametrisierte steuerzeichen +ifnot: scr:setcur \ ( cur -- ) - cursorzeichen setzen +: scr:setcur 01 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:getx \ ( -- x ) - cursor position x abfragen +: scr:getx 04 bel:ctrl!b@ ; +ifnot: scr:gety \ ( -- y ) - cursor position y abfragen +: scr:gety 05 bel:ctrl!b@ ; +ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:eline \ ( row -- ) - endzeile scrollbereich +: scr:eline 08 bel:ctrl!b! ; +ifnot: scr:sinit \ ( -- ) - +: scr:sinit 09 bel:ctrl! ; +ifnot: scr:tabset \ ( pos nr -- ) - tabulatorposition setzen 0..7 +: scr:tabset 0A bel:ctrl!b!b! ; diff --git a/forth/sd0.lib b/forth/sd0.lib new file mode 100644 index 0000000..8cf2e49 --- /dev/null +++ b/forth/sd0.lib @@ -0,0 +1,176 @@ + +hex + +ifnot: lib:sd0 +: lib:sd0 ; + +\ ------------------------------------ lib:sd0 + +\ kommandoformate + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +ifnot: adm:fkt!l! \ ( l fkt -- ) +: adm:fkt!l! b[ [a!] [a.l!] ]b ; + +ifnot: adm:fkt!l@ \ ( fkt -- l ) +: adm:fkt!l@ b[ [a!] [a.l@] ]b ; + +ifnot: adm:fkt!b!l! \ ( l b fkt -- ) +: adm:fkt!b!l! b[ [a!] [a!] [a.l!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!s!b@ \ ( s b fkt -- b ) +: adm:fkt!b!s!b@ b[ [a!] [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!s!s!b@ \ ( s s fkt -- b ) +: adm:fkt!s!s!b@ b[ [a!] [a.s!] [a.s!] [a@] ]b ; + +\ dateisystem-funktionen + +\ adm:mount ( -- err ) - medium mounten +ifnot: adm:mount +: adm:mount + 01 adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gültige datei +\ st = 1 - dateiname im pad gültig +\ bei gültigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:open ( cstr modus -- err ) - datei öffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +ifnot: adm:open +: adm:open + 04 adm:fkt!b!s!b@ ; + +\ adm:close ( -- ) - datei schließen +ifnot: adm:close +: adm:close + 05 adm:fkt!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus datei lesen +ifnot: adm:getc +: adm:getc + 06 adm:fkt!b@ ; + +\ adm:putc ( c -- ) - ein zeichen in datei schreiben +ifnot: adm:putc +: adm:putc + 07 adm:fkt!b! ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +ifnot: adm:eof +: adm:eof + 1E adm:fkt!b@ ; + +\ adm:getblk ( adr cnt -- ) - datenblock aus datei lesen + +\ adm:putblk ( adr cnt -- ) - datenblock in datei schreiben + +\ adm:seek ( pos -- ) - position in datei setzen +: adm:seek + 0A adm:fkt!l! ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +ifnot: adm:fattrib +: adm:fattrib + 0B adm:fkt!b!l@ ; + +\ adm:volname ( -- ) - name des volumes im pad ablegen +ifnot: adm:volname +: adm:volname + 0C adm:fkt!s@ ; + +\ adm:checkmounted ( -- t/f ) +ifnot: adm:checkmounted +: adm:checkmounted + 0D adm:fkt!b@ ; + +\ adm:checkopen ( -- t/f ) +ifnot: adm:checkopen +: adm:checkopen + 0E adm:fkt!b@ ; + +\ adm:checkused ( -- used ) - anzahl benutzte sektoren +ifnot: adm:checkused +: adm:checkused + 0F adm:fkt!l@ ; + +\ adm:checkfree ( -- free ) - anzahl freie sektoren +ifnot: adm:checkfree +: adm:checkfree + 10 adm:fkt!l@ ; + +\ adm:newfile ( cstr -- ) - neue datei erstellen +ifnot: adm:newfile +: adm:newfile + 11 adm:fkt!s!b@ ; + +\ adm:newdir ( cstr -- ) - neues verzeichnis erstellen +ifnot: adm:newdir +: adm:newdir + 12 adm:fkt!s!b@ ; + +\ adm:del ( cstr -- ) - datei/verzeichnis löschen +ifnot: adm:del +: adm:del + 13 adm:fkt!s!b@ ; + +\ adm:rename ( cstr1.fn1 cstr2.fn2 -- ) +ifnot: adm:rename +: adm:rename + 14 adm:fkt!s!s!b@ ; + +\ adm:chattrib ( cstr1.fn cstr2.attrib -- ) +ifnot: adm:chattrib +: adm:chattrib + 15 adm:fkt!s!s!b@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis öffnen +ifnot: adm:chdir +: adm:chdir + 16 adm:fkt!s!b@ ; + +\ adm:format ( cstr.label -- ) - medium formatieren +ifnot: adm:format +: adm:format + 17 adm:fkt!s!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +ifnot: adm:unmount +: adm:unmount + 18 adm:fkt!b@ ; + +\ marker-funktionen + +ifnot: adm:dmact \ ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ .err ; +ifnot: adm:dmset \ ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; +ifnot: adm:dmclr \ ( dmnr -- ) - marker löschen +: adm:dmclr 1C adm:fkt!b! ; +ifnot: adm:dmput \ ( dm dmnr -- ) - marker schreiben +: adm:dmput 1D adm:fkt!b!l! ; + diff --git a/forth/sfx.lib b/forth/sfx.lib new file mode 100644 index 0000000..3c01222 --- /dev/null +++ b/forth/sfx.lib @@ -0,0 +1,93 @@ + +hex + +ifnot: lib:sfx +: lib:sfx ; + +\ kommandoformen + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!64b! \ ( ptr b fkt -- ) +: adm:fkt!b!64b! b[ [a!] [a!] + 31 0 do dup i + C@ [a!] loop drop ]b ; + +\ sfx-funktionen + +\ sfx:fire( chan slot -- ) - sfx abspielen +\ slot - $00..$0f nummer der freien effektpuffer +\ slot - $f0..f5 vordefinierte effektslots +\ chan - 0/1 stereokanal +\ vordefinierte effekte +\ &f0 - warnton +\ $f1 - signalton +\ $f2 - herzschlag schnell +\ $f3 - herzschlag langsam +\ $f4 - telefon +\ $f5 - phaser :) +\ $f6 - pling +\ $f7 - on +\ $f8 - off +ifnot: sfx:fire +: sfx:fire 6B adm:fkt!b!b! ; + +\ ( ptr slot -- ) - sfx setzen +\ slot - $00..$0f nummer der freien effektpuffer +\ ptr - zeiger auf 32 byte effektdaten +\ +\ struktur der effektdaten: +\ +\ [wav ][len ][freq][vol ] grundschwingung +\ [lfo ][lfw ][fma ][ama ] modulation +\ [att ][dec ][sus ][rel ] hüllkurve +\ [seq ] (optional) +\ +\ [wav] wellenform +\ 0 sinus (0..500hz) +\ 1 schneller sinus (0..1khz) +\ 2 dreieck (0..500hz) +\ 3 rechteck (0..1khz) +\ 4 schnelles rechteck (0..4khz) +\ 5 impulse (0..1,333hz) +\ 6 rauschen +\ [len] tonlänge $0..$fe, $ff endlos +\ [freq] frequenz $00..$ff +\ [vol] lautstärke $00..$0f +\ +\ [lfo] low frequency oscillator $ff..$01 +\ [lfw] low frequency waveform +\ $00 sinus (0..8hz) +\ $01 fast sine (0..16hz) +\ $02 ramp up (0..8hz) +\ $03 ramp down (0..8hz) +\ $04 square (0..32hz) +\ $05 random +\ $ff sequencer data (es folgt eine sequenzfolge [seq]) +\ [fma] frequency modulation amount +\ $00 no modulation +\ $01..$ff +\ [ama] amplitude modulation amount +\ $00 no modulation +\ $01..$ff +\ [att] attack $00..$ff +\ [dec] decay $00..$ff +\ [sus] sustain $00..$ff +\ [rel] release $00..$ff +ifnot: sfx:setslot +: sfx:setslot + 6C adm:fkt!b!64b! ; + +\ sfx:keyoff ( chan -- ) - release-phase einleiten +ifnot: sfx:keyoff +: sfx:keyoff + 6D adm:fkt!b! ; + +\ sfx:stop ( chan -- ) +ifnot: sfx:stop +: sfx:stop + 6E adm:fkt!b! ; + diff --git a/forth/splay.mod b/forth/splay.mod new file mode 100644 index 0000000..eb6e485 --- /dev/null +++ b/forth/splay.mod @@ -0,0 +1,116 @@ + +\ achtung: vor verwendung muss der administra-code mit sidcog +\ geladen werden: +\ sys tools.f +\ sys splay.f <--- sid-player laden +\ aload admsid.adm <--- administra-code mit sidcog laden +\ splay xyz.dmp <--- sid-datei abspielen + + +hex + +ifnot: mod:splay +: mod:splay ; + +\ kommandoformen + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- err ) +: adm:fkt!s! b[ [a!] [a.s!] [b@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:aload +: adm:aload + 60 adm:fkt!s! ; + +\ tools + +ifnot: aload +: aload + mount? parsenw dup + if 1 adm:dmact adm:aload 0 else drop 23 then .err ; + +\ sid-funktionen + +ifnot: sid:play +: sid:play \ ( cstr -- err ) + 9E adm:fkt!s!b@ ; + +ifnot: sid:stop +: sid:stop \ ( -- ) + 9F adm:fkt! ; + +ifnot: sid:status +: sid:status \ ( -- status ) + A1 adm:fkt!b@ ; + +ifnot: sid:mute +\ 1 - sid1 +\ 2 - sid2 +\ 3 - sid1 & sid2 +: sid:mute \ ( sidnr -- ) + A3 adm:fkt!b! ; + +\ send? ( -- t/f ) +ifnot: send? +: send? + begin 50 delms key? dup if key drop then sid:status 0= or + until ; + +\ (splay) ( cstr -- ) +ifnot: (splay) +: (splay) \ ( cstr -- ) + ." Datei : " dup .cstr cr sid:play .err + send? sid:stop 3 sid:mute adm:close drop ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ splay name.dmp ( -- ) - sid-datei abspielen +ifnot: splay +: splay + parsenw (splay) ; + +\ sdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur sid-dateien sein! +ifnot: sdirplay +: sdirplay + files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (splay) loop padbl ; + +ifnot: smute +: smute + sid:stop 3 sid:mute ; + \ No newline at end of file diff --git a/forth/tools.mod b/forth/tools.mod new file mode 100644 index 0000000..4d74e6f --- /dev/null +++ b/forth/tools.mod @@ -0,0 +1,152 @@ + +hex + +ifnot: mod:tools +: mod:tools ; + +\ kommandoformen +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +ifnot: adm:dmact \ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:load +: adm:load + 60 adm:fkt!s! ; + +\ bel-funktionen + +\ bel:load ( cstr -- ) - bellatrix-code laden +\ achtung: die gesamte loader-operation ist eine atomare +\ operation über alle drei propellerchips, kann also auch +\ nicht aufgetrennt werden! +ifnot: bel:load +: bel:load + 52 adm:open .err \ datei öffnen + b[ + 0 [b!] 63 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilänge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schließen +; + +\ ------------------------------------ mod:tools + +ifnot: aload +: aload \ name ( -- ) - administra-code laden + mount? parsenw dup + if adm:load 0 else drop 23 then .err ; + +ifnot: bload +: bload \ name ( -- ) - bellatrix-code laden + mount? parsenw dup + if bel:load 0 else drop 23 then .err ; + +ifnot: .dmstatus \ ( dm -- ) - ausgabe marker-status +: .dmstatus -1 = if ." frei" else ." gesetzt" then cr ; + +ifnot: dm? +: dm? + ." [root] : " 0 adm:dmget .dmstatus + ." [sys ] : " 1 adm:dmget .dmstatus + ." [usr ] : " 2 adm:dmget .dmstatus + ." [ A ] : " 3 adm:dmget .dmstatus + ." [ B ] : " 4 adm:dmget .dmstatus + ." [ C ] : " 5 adm:dmget .dmstatus ; + +\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen +ifnot: open +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geöffnete datei schließen +ifnot: close +: close + adm:close .err ; + +\ (cat) ( -- ) - alle zeichen der geöffneten datei ab +\ lesemarke auf ausgabekanal bis zum eof ausgeben +ifnot: (cat) +: (cat) begin adm:getc emit adm:eof until ; + +\ cat name ( -- ) - datei "name" komplett ausgeben +ifnot: cat +: cat open (cat) close ; + +\ nextline ( -- ) - ausgabe der nächsten textzeile aus der +\ geöffneten datei +ifnot: nextline +: nextline + begin adm:getc dup emit 0d = adm:eof or until ; + +\ nextlines ( n -- ) - ausgabe von n zeilen +ifnot: nextlines +: nextlines + 0 do adm:eof 0= if nextline then loop ; + +\ less name ( -- ) - zeilenweise ausgabe der datei +ifnot: less +: less + open begin 10 nextlines key 71 = adm:eof or until close ; + +\ #C ( c1 -- ) prepend the character c1 to the number +\ currently being formatted +ifnot: #C +: #C -1 >out W+! pad>out C! ; + +\ .cogch ( n1 n2 -- ) print as x(y) +ifnot: .cogch +: .cogch <# 29 #C # 28 #C drop # #> .cstr ; + +\ j ( -- n1 ) the second most current loop counter +ifnot: j +: j _rsptr COG@ 5 + COG@ ; + +\ cog? ( -- ) +ifnot: cog? +: cog? + 8 0 do ." Cog:" i dup . ." #io chan:" + dup cognchan . cogstate C@ + dup 4 and if version W@ .cstr then + dup 10 and if i cognumpad version W@ C@ over C@ - + spaces .cstr then + 14 and if i cogio i cognchan 0 do + i 4* over + 2+ W@ dup 0= if drop else + space space j i .cogch ." ->" io>cogchan .cogch + then + loop +drop then cr loop ; + +\ jede erweiterung legt ein wort als startmarke +\ nmit folgendem namen an: +\ mod:xxx - softwaremodule +\ drv:xxx - treiber +\ lib:xxx - bibliotheken +\ so kann mit den folgenden kommandos eine schnelle liste der +\ vorhandenen erweiterungen abgerufen und mit forget +\ aus dem system entfernt werden + +\ mod? ( -- ) - anzeige der module +ifnot: mod? +: mod? c" mod:" _words ; + +\ lib? ( -- ) - anzeige der bibliotheken +ifnot: lib? +: lib? c" lib:" _words ; + diff --git a/forth/v1.mod b/forth/v1.mod new file mode 100644 index 0000000..7b0b8cd --- /dev/null +++ b/forth/v1.mod @@ -0,0 +1,325 @@ + +: mod:vortrag ; + +24 constant rows +64 constant cols + +wvariable lcol 7 lcol W! + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; + +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +: lcol@ lcol W@ ; \ ( -- col ) + +: lines \ ( n -- ) + 0 do cr loop ; + +: waitkey + scr:curoff cr key drop scr:bs scr:bs scr:bs scr:curon ; + +: nextpage + scr:curoff scr:pos1 lcol@ spaces ." -->" key drop scr:bs scr:bs scr:bs scr:curon ; + +: .head \ ( -- ) + 4 scr:setcol scr:pos1 lcol@ spaces ; + +: .bullet \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ spaces 0f emit space ; + +: .number \ ( n -- n ) + 0 scr:setcol scr:pos1 lcol@ spaces dup . 1+ + 2e emit space ; + +: .line \ ( -- ) + cr 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +: .sub \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +wvariable xpos 1 xpos W! +wvariable ypos 1 ypos W! + +: pos! \ ( x y -- ) + ypos W! xpos W! ; + +: pos@ \ ( -- x y ) + xpos W@ ypos W@ ; + +: nextline + ypos W@ 1+ ypos W! ; + +: move \ ( x y -- ) + 1 delms pos@ scr:sety scr:setx ; + + +: btop0 \ ( -- ) + move 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot0 \ ( -- ) + move 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: btop1 \ ( -- ) + move 2 spaces 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot1 \ ( -- ) + move 2 spaces 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: bmid0 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit nextline + move 91 emit ." " 95 emit 90 emit aa emit nextline ; + +: bmid1 \ ( -- ) + move a9 emit 90 emit 94 emit ." COG " 91 emit nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid2 \ ( -- ) + move a9 emit 90 emit 94 emit ." SER " + 95 emit 90 emit bb emit ." [TERMINAL]" nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid3 \ ( -- ) + move a9 emit 90 emit 94 emit ." VGA " + 95 emit 90 emit bb emit ." [BELLATRIX]" nextline + move ba emit 90 emit 94 emit ." KBD " 91 emit nextline ; + +: bmid4 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit + ." Zeichenausgabekanal (emit)" nextline + move 91 emit ." " 95 emit 90 emit aa emit + ." Zeicheneingabekanal (key)" nextline ; + +: cog0 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid0 bbot0 ; + +: cog1 \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid1 bbot1 ; + +: cog3 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid4 bbot0 ; + +: cogext \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid2 bbot1 ; + +: cogint \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid3 bbot1 ; + +: drvser + 0 scr:setcol 2dup cog0 swap a + swap cogext ; + +: drvint + 0 scr:setcol 2dup cog0 swap a + swap cogint ; + +: p0 + 0 scr:sline cls 5 lines + 14 1c scr:curoff scr:logo won c" woodz.wav" wav:start drop + key drop scr:curon wav:stop woff ; + +: i1 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr waitkey + .bullet ." Forth-Diamond: Master & Slaves = PropForth" waitkey cr + .sub ." Nachteil: Programmierung aller Treiber in Forth" waitkey cr + .bullet ." Forth-Spin: Forth mit SPIN-Interface" waitkey cr + .sub ." Vorteil: Nutzung fertiger Treiber" waitkey + .sub ." Nachteil: hoher Ressourcenverbrauch" waitkey cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr cr + nextpage ; + +: i2 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr waitkey + .bullet ." Nachteile:" cr cr + .sub ." Spin --> Compiler noch auf Host" cr waitkey + .bullet ." Vorteile:" cr cr + .sub ." Code ist schon vorhanden (TriOS)" waitkey + .sub ." Gegenseitige Befruchtung von Forth & TriOS" waitkey + .sub ." Maximale Ressourcen für Forth im Master" waitkey + .sub ." Spin-Code kann später auch durch Forth ersetzt werden" cr + nextpage ; + +: i3 + 0 scr:sline cls 3 lines + .head ." Ablauf der Implementierung" cr waitkey + .bullet ." Ausgangslage: " cr cr + .sub ." Forth mit Terminalzugriff" cr waitkey + .bullet ." Plan:" cr cr + .sub ." 1. Busroutine um auf Slaves zuzugreifen" waitkey + .sub ." 2. Integration VGA/Keyboard/SD-Card" waitkey + .sub ." 3. Autostart" cr cr + nextpage ; + + +: p1 + 0 scr:sline cls 1 lines + .head ." Buszugriff" cr cr + .bullet ." ! ( n adr -- ) store - Wert im RAM speichern" cr + .bullet ." @ ( adr -- n ) fetch - Wert aus RAM lesen" cr waitkey + .bullet ." c! c@ p! p@ - Abwandlungen der Grundform" cr waitkey + .bullet ." s! ( c adr -- ) - Byte an Slave senden" cr + .bullet ." s@ ( adr -- c ) - Byte von Slave empfangen" cr waitkey + .bullet ." b! ( c -- ) - Byte an Bellatrix senden" cr + .bullet ." b@ ( -- c ) - Byte von Bellatrix empfangen" cr + .bullet ." a! ( c -- ) - Byte an Administra senden" cr + .bullet ." a@ ( -- c ) - Byte von Administra empfangen" cr cr + .head ." Beispiele :" cr cr + .bullet ." 01 b! - Bildschirm löschen" waitkey + .bullet ." : cls 01 b! ; " waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr + nextpage ; + +: p2 + 0 scr:sline cls 5 lines + .head ." IO-Kanäle/Pipes" cr waitkey + 9 8 cog3 key drop + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p3 + 0 scr:sline cls 5 lines + .head ." Serieller Treiber" cr cr + 9 8 drvser + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p4 + 0 scr:sline cls 5 lines + .head ." VGA/Keyboard-Treiber" cr cr + 9 8 drvser + 9 c drvint + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p5 + 0 scr:sline cls 5 lines + .head ." Treiber: VGA" cr cr + 9 8 drvint cr + .line ." : drv-vga " + .line ." begin" + .line ." key?" + .line ." if key b! then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p6 + 0 scr:sline cls 5 lines + .head ." Treiber: Keyboard" cr cr + 9 8 drvint cr + .line ." : drv-key" + .line ." begin" + .line ." bel:keystat" + .line ." if bel:key emit then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p7 + 0 scr:sline cls 5 lines + .head ." Treiber: Gesamt" cr cr + 9 8 drvint cr + .line ." : drv:int" + .line ." begin" + .line ." \ input --> vga/video" + .line ." 200 0 do key?" + .line ." if key b[ [b!] ]b then loop" + .line ." \ output <-- keyboard" + .line ." b[ [key?]" + .line ." if [key] [emit] then ]b" + .line ." 0 until ;" + cr cr + nextpage ; + +: p8 + 0 scr:sline cls 5 lines + .head ." Semaphoren" cr waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr waitkey + .bullet ." : bel:key bon 0 b! 2 b! b@ boff ;" cr waitkey + .bullet ." [ ... ]" cr waitkey + .bullet ." b[ ... ]b" cr waitkey + .bullet ." : bel:key b[ 0 b! 2 b! b@ ]b ;" cr waitkey + .bullet ." : bel:key b[ 0 [b!] 2 [b!] [b@] ]b ;" cr waitkey + .bullet ." : bel:key 2 0 b[ [b!] [b!] [b@] ]b ;" cr cr + cr cr + nextpage ; + +: run + begin p0 i1 i2 i3 p1 p2 p3 p4 p5 p6 p7 p8 0 until ; + diff --git a/forth/wav.lib b/forth/wav.lib new file mode 100644 index 0000000..4198e23 --- /dev/null +++ b/forth/wav.lib @@ -0,0 +1,54 @@ + +hex + +ifnot: lib:wav +: lib:wav ; + +\ kommandoformen + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!l@l@ \ ( fkt -- l l ) +: adm:fkt!l@l@ b[ [a!] [a.l@] [a.l@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ wav:leftvol ( vol -- ) +ifnot: wav:leftvol +: wav:leftvol + 99 adm:fkt!b! ; + +\ wav:rightvol ( vol -- ) +ifnot: wav:rightvol +: wav:rightvol + 9A adm:fkt!b! ; + +\ wav:pause ( -- ) +ifnot: wav:pause +: wav:pause + 9B adm:fkt!b@ drop ; + +\ wav:position ( -- len pos ) +ifnot: wav:position +: wav:position + 9C adm:fkt!l@l@ ; + diff --git a/forth/words.mod b/forth/words.mod new file mode 100644 index 0000000..c0165f3 --- /dev/null +++ b/forth/words.mod @@ -0,0 +1,16 @@ + +fl + +\ _words ( cstr -- ) prints the words in the forth dictionary starting with cstr, 0 prints all +: _words lastnfa +begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= +until 2drop cr ; + +\ words ( -- ) prints the words in the forth dictionary, if the pad has another string following, with that prefix +: words parsenw _xwords ; + +: t1 1000 0 do i . loop ; +: t2 1000 0 do ." test " loop ; diff --git a/forth/work/bload.f b/forth/work/bload.f new file mode 100644 index 0000000..8eee6eb --- /dev/null +++ b/forth/work/bload.f @@ -0,0 +1,23 @@ + +fl + +hex + +\ metafunktionen + +: (bload) \ ( cstr -- ) - belatrix-code laden + + 52 adm:open .err \ datei öffnen + b[ + 0 [b!] 63 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilänge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schließen +; + +: bload \ name ( -- ) - bellatrix-code laden + parsenw (bload) ; + diff --git a/forth/wplay.mod b/forth/wplay.mod new file mode 100644 index 0000000..faf878f --- /dev/null +++ b/forth/wplay.mod @@ -0,0 +1,93 @@ + +hex + +ifnot: mod:wplay +: mod:wplay ; + +\ kommandoformate + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ adm-funktionen + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + + +\ metafunktionen + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +\ wend? ( -- t/f ) +ifnot: wend? +: wend? + begin 50 delms key? dup if key drop then wav:status 0= or until ; + +\ (wplay) ( cstr -- ) +ifnot: (wplay) +: (wplay) \ ( cstr -- ) + ." Datei : " dup .cstr cr wav:start .err wend? wav:stop ; + +\ wplay name ( -- ) +ifnot: wplay +: wplay + won parsenw (wplay) woff ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ wdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis dürfen nur wav-dateien sein! +ifnot: wdirplay +: wdirplay + won files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (wplay) loop padbl woff ; diff --git a/installation.rtf b/installation.rtf new file mode 100644 index 0000000..9aed852 --- /dev/null +++ b/installation.rtf @@ -0,0 +1,223 @@ +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}} +{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20\par +1. Installation des Grundsystems\par +2. Forth im \'dcberblick\par +3. Regime im \'dcberblick\par +\par +\par +\par +\par +\ul\b 1. Installation des Grundsystems:\par +\ulnone\b0\par +1. Flashen der drei EEPROMS:\par +\par +\\flash\\administra\\admflash.spin\tab --> Administra\par +\\flash\\bellatrix\\belflash.spin\tab --> Bellatrix\par +\\flash\\regnatix\\regflash.spin\tab --> Regnatix\par + \par +2. Der Schalter bleibt ab jetzt auf Regnatix stehen. Ein Terminalprogramm (ich verwende Tera Term) starten und 57600 Baud auf die Schnittstelle vom Hive einstellen. Nach einem Reset meldet sich das Propforth im Terminal. Datei "system\\basics.f" in einem Editor \'f6ffnen, alles markieren, kopieren und im Terminal einf\'fcgen. Der Quelltext wird jetzt im Forth compiliert. \par +\par +3. Im Terminalfenster, aso im Forth, dass Kommendo "saveforth" eingeben. Damit wird das gesamte Forthsystem mit der gerade neu compilierten Erweiterungen wieder im EEPROM als Image gespeichert. \par +\par +Nach einem Reset sollte sich das Forth jetzt komplett mit seinem Prompt sowohl auf dem angeschlossenen VGA-Monitor, als auch im Terminal melden. Im Prinzip ben\'f6tigen wir nun das Terminalprogramm nicht mehr und k\'f6nnen direkt am Hive arbeiten. Sp\'e4ter, wenn man in Forth programmiert, ist die vorhandene Terminalschnittstelle aber manchmal sehr n\'fctzlich.\par +\par +\ul\b Erstellung einer Forth-SDCard:\par +\ulnone\b0\par +Im Prinzip kann jede normale FAT16/32 Karte verwendet werden. Lange Dateinamen werden nicht verwendet, Unterverzeichnisse sind kein Problem. Es ist sinnvoll, alle Dateien aus dem Verzeichnis "bin\\sd-card-basic\\" auf die SD-Karte zu kopieren.\par +\par +Das Verzeichnis "system" hat eine besondere Bedeutung: Hier sollten sich die Tools, Erweiterungen und Bibliotheken befinden. Mit dem Kommando "sys name.f" kann aus jedem anderen Verzeichnis ohne Wechsel die Datei name.f geladen und compiliert werden.\par +\par +\ul\b Systemstart:\par +\ulnone\b0\par +Beim Systemstart wird immer das Forth aus dem EEPROM gestartet. So kann, wie mit den klassischen Homecomputern, sofort unkompliziert programmiert werden. Neben dem Forth gibt es im TriOS noch ein in Spin programmiertes Betriebssystem, welches sich dem Benutzer durch den Kommandointerpreter Regime pr\'e4sentiert. Aus dem Forth kann diese mit dem Kommando "regime" gestartet werden. Im Gegenzug kann im laufenden Regime mit dem Kommando "forth" wieder zur integrierten Programmiersprache gewechselt werden.\par +\par +\ul\b 2. Forth im \'dcberblick:\ulnone\b0\par +\par +Einige n\'fctzliche Kommandos befinden sich in dem Modul tools.mod. In den meisten F\'e4llen ist es sinnvoll dieses Modul mit der Befehlssequenz "sys tools.mod saveforth" fest im Forth einzubinden.\par +\par +\b Wichtige Tastencodes:\par +\b0\par +[ESC]-1\tab\tab Screen 1, COG 1\par +[ESC]-2 \tab Screen 2, COG 2\par +[ESC]-3 \tab Screen 3, COG 3\par +[ESC]-b \tab Break, Reset der aktuellen COG\par +[ESC]-r \tab\tab Reset, Neustart Regnatix\par +\par +\b Wichtige Kommandos:\par +\b0\par +load \tab - Datei laden und comilieren, Ausgabe Screen 3\par +dload \tab - wie load, aber Ausgabe aktueller Screen\par +sys \tab - Datei aus sys-Verzeichnis laden und compilieren\par +ls \tab - Dateiliste\par +lsl \tab - Dateiliste- Long-Format\par +cd \tab - in Verzeichniss wechseln\par +mount \tab - SD-Card einbinden\par +unmount \tab - SD-Card freigeben\par +words \tab - Anzeige W\'f6terbuch\par +mod? \tab - (tools.mod) Anzeige compilierter Erweiterungen\par +lib? \tab - (tools.mod) Anzeige compilierter Bibliotheken\par +cog? \tab - (tools.mod) Anzeige COG-Liste\par +cat \tab - (tools.mod) Ausgabe einer Textdatei\par +less \tab - (tools.mod) Zeilenweise Textausgabe\par +dm? \tab - (tools.mod) Anzeige der Systemverzeichnisse\par +regime\tab\tab - CLI starten\par +aload \tab - Adminsitra-Code laden\par +bload \tab - Bellatrix-Code laden\par +spin \tab - Spin-Programm starten\par +\par +\b Wichtige Dateien:\par +\b0\par +Die Dateien *.mod und *.lib enthalten ganz normale Forth-Quelltexte. Damit hat man schnell eine \'dcbersicht \'fcber die grobe Funktion dieser Quellen: Lib's sind halt reine Sammlungen von Worten zu einer bestimmten Funktionsgruppe und MOD's sind mehr oder weniger fertige und abgeschlossene Programme. Ein Beispiel:\par +\par +Die Datei hss.lib enth\'e4lt Worte um die HSS-Funktionen von Administra anzusprechen. Mit diesen Funktionen kann man nun ein Modul (Programm) wie einen HSS-Soundplayer schreiben.\par +\par +Im Gegensatz dazu die Datei splay.mod: Mit diesem Modul wird ein HSS-Soundplayer ins System eingef\'fcgt, welcher Funktionen aus der hss.lib verwendet. \par +\par +Die Datei ben\'f6tigt man aber mehr oder weniger nur zur Entwicklung, ein fertiges Modul wie splay.mod enth\'e4lt dann schon die die entsprechenden HSS-Worte die ben\'f6tigt werden. \par +\par +Die ifnot: ... Anweisung sorgt dabei daf\'fcr, dass keine Funktionen doppelt in das W\'f6rterbuch compiliert werden. Das ist quasi ein verteiltes und fein granuliertes Konzept analog zu einer DLL. Die Forth-Version funktioniert dabei aber im Gegensatz zu DLL's nicht auf Bibliotheks-, sondern auf Funktionsebene. \par +\par +*.mod \tab Module, Forth-Erweiterungen f\'fcr das System\par +*.lib \tab Bibliotheken, grundlegende Wortsammlungen\par +*.adm \tab Administra-Code (z.Bsp. admsid.adm f\'fcr SIDCog-Code)\par +*.bel \tab Bellatrix-Code\par +*.bin\tab Spin-Code, im Normalfall zur Ausf\'fchrung in Regnatix\par +\par +basics.f \tab - (mod:basics) Hive-Core f\'fcr PropForth\par +ari.lib \tab\tab - (lib:ari) Zus\'e4tzliche arithmetische Funktionen\par +cog.lib \tab - (lib:cog) Zus\'e4tzliche COG-Funktionen\par +adm.lib \tab - (lib:adm) Administra-Chipmanagment-Funktionen\par +hss.lib \tab - (lib:hss) Bibliothek f\'fcr Hydra-Sound-System\par +sfx.lib \tab\tab - (lib:sfx) Soundeffekt-Bibliothek\par +wav.lib \tab - (lib:wav) Wave-Soundbibliothek\par +\par +bel.lib \tab\tab - (lib:bel) Bellatrix-Chipmanagment-Funktionen\par +key.lib \tab - (lib:key) Tastatur-Bibliothek\par +scr.lib \tab\tab - (lib:scr) Screen-Bibliothek\par +sd0.lib \tab - (lib:sd0) SD-Card-Bibliothek\par +\par +debug.f \tab - N\'fctzliche Worte zur Fehlersuche und Entwicklung\par +rom.f \tab - EEPROM-Dateisystem\par +tools.f \tab\tab - N\'fctzliche Tools (cat, less, dm?...)\par +hplay.f \tab - HSS-Player\par +wplay.f \tab - WAV-Player\par +splay.f \tab - SID-Player\par +\par +Administra-Codedateien im SYS-Verzeichnis:\par +\par +admled.adm \tab Testprogramm - HBeat-LED blinken lassen\par +admsid.adm \tab SidCog-Version (wird von splay ben\'f6tigt)\par +admsys.adm \tab Standardcode f\'fcr ADM mit SD/HSS/WAV\par +admym.adm \tab Yamaha-Soundchip-Version\par +aterm96.adm \tab Mini-OS f\'fcr Administra (Testzwecke)\par +\par +\b Reset-Fehlercodes:\par +\b0\par +0011FFFF - stack overflow\par +0012FFFF - return stack overflow\par +0021FFFF - stack underflow\par +0022FFFF - return stack underflow\par +8100FFFF - no free cogs\par +8200FFFF - no free main memory\par +8400FFFF - fl no free main memory\par +8500FFFF - no free cog memory\par +8800FFFF - eeprom write error\par +9000FFFF - eeprom read error\par +\par +\b .err-Fehlercodes:\par +\b0\par +0 no error\par +1 fsys unmounted\par +2 fsys corrupted\par +3 fsys unsupported\par +4 not found\par +5 file not found\par +6 dir not found\par +7 file read only\par +8 end of file\par +9 end of directory\par +10 end of root\par +11 dir is full\par +12 dir is not empty\par +13 checksum error\par +14 reboot error\par +15 bpb corrupt\par +16 fsi corrupt\par +17 dir already exist\par +18 file already exist\par +19 out of disk free space\par +20 disk io error\par +21 command not found\par +22 timeout\par +23 parameter error\par +\par +\ul\b 3. Regime im \'dcberblick\par +\par +\ulnone\b0 Da wir ja drei verschiedene Teilsystem in unserem Computer haben, muss Regime wissen, f\'fcr welchen Chip eine ausf\'fchrbare Datei bestimmt ist. Den Typ ausf\'fchrbarer Dateien kann Regime automatisch anhand der Dateinamenserweiterung unterscheiden:\par +\par +*.bin\tab Regnatix-Code\par +*.bel\tab Bellatrix-Code\par +*.adm\tab Administra-Code\par +\par +Dabei gen\'fcgt es, den Namen ohne Erweiterung einzugeben. Dennoch kann es vorkommen, das man eine normale Spin-Datei mit einer beliebigen Erweiterung gespeichert hat. Diese Datei kann man dann mit den Kommandos rload, aload oder bload ganz gezielt in einen Chip laden.\par +\par + \tab\tab - bin/adm/bel-datei wird gestartet\par +mount\tab\tab\tab\tab - SD-aufwerk mounten\par +unmount\tab\tab\tab - SD-Laufwerk freigeben\par +dir wh\tab\tab\tab\tab - Verzeichnis anzeigen\par +type \tab\tab\tab - Anzeige einer Textdatei\par +aload \tab\tab\tab - Administra-Code laden\par +bload \tab\tab\tab - Bellatrix-Code laden\par +rload \tab\tab\tab - Regnatix-Code laden\par +del \tab\tab\tab - Datei l\'f6schen\par +cls\tab\tab\tab\tab - Bildschirm l\'f6schen\par +free\tab\tab\tab\tab - Anzeige des freien Speichers auf SD-Card\par +attrib ashr\tab\tab - Dateiattribute \'e4ndern\par +cd \tab\tab\tab - Verzeichnis wechseln\par +mkdir \tab\tab\tab - Verzeichnis erstellen\par +rename \tab - datei/verzeichnis umbenennen\par +format \tab\tab - SD-Laufwerk formatieren\par +reboot\tab\tab\tab\tab - Hive neu starten\par +sysinfo\tab\tab\tab\tab - Systeminformationen\par +color <0..7>\tab\tab\tab - Farbe w\'e4hlen\par +cogs\tab\tab\tab\tab - Belegung der COG's anzeigen\par +dmlist\tab\tab\tab\tab - Anzeige der Verzeichnis-Marker\par +dm \tab\tab - Marker-Verzeichnis wechseln\par +dmset \tab\tab - Marker setzen\par +dmclr \tab\tab - Marker l\'f6schen\par +forth\tab\tab\tab\tab - Forth starten\par +\par +Marker:\par +r\tab - Marker f\'fcr Root-Verzeichnis\par +s\tab - Marker f\'fcr System-Verzeichnis\par +u\tab - Marker f\'fcr User-Verzeichnis\par +a/b/c\tab - Benutzerdefinierte Verzeichnismarker\par +\par +Die r, s, u-Marker werden vom System automatisch gesetzt und intern verwendet.\par +\par +RAMDISK:\par +\par +xload \tab\tab\tab - Datei von SD-Laufwerk in RAM laden\par +xsave \tab\tab\tab - Datei aus RAM auf SD-Laufwerk speichern\par +xdir\tab\tab\tab\tab - Verzeichnis im RAM anzeigen\par +xrename \tab - Datei im RAM umbenennen\par +xdel \tab\tab\tab - Datei im RAM l\'f6schen\par +xtype \tab\tab\tab - Textdatei im RAM anzeigen\par +\par +EXTERNE KOMMANDOS:\par +\par +Die meisten Kommandozeilentools zeigen mit dem Parameter /? eine Liste der Optionen an.\par +\par +sysconf \tab - Systemeinstellungen\par +hplay\tab\tab - HSS-Player\par +wplay\tab\tab - WAV-Player\par +splay\tab\tab - SID-Player\par +yplay\tab\tab - Yamaha-Soundchip-Player\par +sfxtool\tab\tab - HSS-Soundeffekte erstellen\par +\par +vga.bin\tab\tab - VGA 1024 x 768 Pixel, 64 x 24 Zeichen\par +htext.bin\tab - VGA 1024 x 768 Pixel, 128 x 48 Zeichen\par +tv.bin\tab\tab - TV-Textmodus 40 x 13 Zeichen\par +\par +} + \ No newline at end of file diff --git a/license.spin b/license.spin deleted file mode 100644 index 6f1fc2e125a81d6f9bda85ab0aac83df2d35f20f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8346 zcmds+OHW%@5XX;LR;|=U7hQC5g-T1LLezE_p-Kb{al*s34QW@E0RwJ=jcf>csNc4q zp{uIx|2N~|+-n0Vi-;Co**=ds^PV{~*MI-@F1<^iq>oZz-|f^*C+Rf3Or3P5agh$w zpJ}Myw!V95JGIh6`Z1kr@1-7KUhDf{4BykdZY3)qEU5)y- zyPF2W57i@^2h{_^P+UQ=n-+y(*|-4zGhu-9fnn?$XML?_OdU}z(i35PB^nE(*fzpzu^*$J?rr@nBGY=my>nje}+pqDf4g;nAHdplVZCbV=eYJPf}2GIYO zC)YLh51&I1lf0q(>$xjT@#UyhSIxMOTjWC6-Kyk3VhXPt84TGSyyaY1C|7&(evpXGR@49S=sVB_no6uB8bd{;$cJWopS9crzZ(eLGNIp-%Ivf)O_KyNjBEOyw~6 zz1MyJ4J&4uB3Eyj&k>o_eIv`b)Dz5n&EuNe=jJ-0X4*kdkr#6X&F%1^9+&B}dz2y4 z+~*cg0)MK)L#wk2s9GWpoq zmDe@RhIG15ZPd`c^jHuB@kupCB>kdque3SU(3!d*sD_9<_nIoqsxY?=U*?Rn_qVRO zZH<=epsb+}H)^YIZR#yUOLp5<7NCM|X$_zDcMl#F`xZ6c6MQ&s0`rWjz`J?y#V_vF zoq1dT`*K{fHY{&)^U#4sZf3^KN=~I$f1{b-6yD(5+!Q%U$gGg&Ub#%j+#53(GWA(1DYl*}385p>SRp4XApC0+tX<$PJ?lklc*3l(o&L*t8wH}HJ-2yp=_fo-;zXvH>9Sclq zGUEx!+^bw0+)3HTvh)|SCvTfM1nx z&=(=$z^qS4;j(h8V>`F`$Z~Ml;x2zf2Y1QCUDFO7w8wtJJGg<>w&ADM-oCG0EQzOw zhr5@#CuQ#}XV>Z}e9Zqt@VA`R9N^wZCIJ7{5##Yhd=ihu89aGr;vbe_$=lu+VT;O! zo)7NY7I#TMbkNqj@tQQ>vZ|?_o?FGtN?mLG1Ju;cu4b!(Th+>}AlPAl*0RKNjlr|6 znyalH$I%qrmgYZe#Va!A%$^B;OSs5&{QCrrny`U&TVrrn^vnxgzKK@q+8RzOIb4x(Bq;YSaUcux2q33 zSP%X-^kjLLO*>enS<>vJ7D5N~O$|u|-F0CDD`z*v85%$%{8#8&MhhD@%hI}SvC*<{ zY?^N9k~Z~O7i_jJ*1{%O8kOp{*62ubZyIv%KqT3#0F17p&hjIozi* zRs0pr1H}_MpjTwaHIHTSeU~JB+dVnF6n>mG_Am1lF_G;t9bt|o{L}lDh=9y3{}j|D k7n;KF(WC1lPEKORQ*QgX4(``mw%c|L{#K5+30G \bin\flash bstc -L %libpath% -b -O a .\flash\administra\admflash.spin move admflash.binary %flash% + bstc -L %libpath% -b -O a .\flash\bellatrix\belflash.spin -move belflash.binary %flash% +copy belflash.binary %flash% +rename belflash.binary vga.bel +move vga.bel %sd-sys% + bstc -L %libpath% -b -O a .\flash\regnatix\regflash.spin move regflash.binary %flash% @@ -27,8 +31,8 @@ bstc -L %libpath% -b -O a .\system\regnatix\regime.spin rename regime.binary reg.sys move reg.sys %sd% -bstc -L %libpath% -b -O a .\system\bellatrix\vga-text-1024x768-pix-64x24-zeichen\vga.spin -rename vga.binary bel.sys +bstc -L %libpath% -b -O a .\flash\bellatrix\belflash.spin +rename belflash.binary bel.sys move bel.sys %sd% REM ---------------------------------------------------------------- @@ -109,6 +113,12 @@ bstc -L %libpath% -b -O a .\system\regnatix\yplay.spin rename yplay.binary yplay.bin move yplay.bin %sd-sys% +REM ---------------------------------------------------------------- +REM Forthdateien kopieren + +copy .\forth\*.* %sd-sys% + + REM ---------------------------------------------------------------- REM Zusatzdateien kopieren diff --git a/system/regnatix/ios.spin b/system/regnatix/ios.spin index a59e44ff4a10f31f4dd85514bd6a4f1972edddc8..b1e54dd833898de5a7a753bc68ccd78eb7897bd1 100644 GIT binary patch delta 2025 zcmb7EO-x)>6h8NeW;#49&<@WjZJ89YVoUi^lNw{{40M1(9botyW&mM8p_u7ZG#X=4 z8h5&?H+m8mP1}WWWiV~>8h-+_Q|qE8hJ_|3CT`q;t1jBc^X{E@=P^*Dd3kyFo!@)D z@0@e!_8Vrfv8&d~5P9={*1mE3n5Tk*Cu2dvwAcNXVKK;VMrz00~Ia;B8?WQ74SRkX$CE(>+`UL7jQw;$pvMr7fP9rA2FX&2j%$-*()Tq7o<>F`DEI}A~X8FXA! z|7Vd3jGT(#dZ#&>K@_@Rk|ih9GikE89JJT&BtaHZP3HQ2944iRNkEsZX|Zd(z`8I^ zSXdGE;=>4=W7>8nYzIkuz3|1vaxL8u^5Z+r2q&PMX=CJH+OFw@9>#HKTZPZVNmF7B z&a&qamoo-@eHo40AE$$lc9njr>59OhT%S06V|5}gF1r2d;`#6jN?q=2x&Oe1SEqq- zH?dJ(3){tGvbfG>FPaEO^>aJI$9TKxxaxbjflGo zm`$3#FPdp8f!AB}+(m!#5?F+HnGtUp`1i~<1}K_Do8BM5Z{4s*=;|k;mL61MywXF4 z$Ca*CVu&&wXgR+R;$5UWeHidfem^gRuO>0<{4|Q=LTOF$ygIm_PHX+$34B@WjkjJU z;x>kyd=|0HySPK-r5{4X>HvKY7=Y;T^oh z%R8@5^VB|%&GkFP%!!MC4(6zR0S~EMm0knHAnCM^dnFi%R9_G)4t+X;t7SadKAw1F zi(?PX6dlEnoa-sHgl`$CVSo|cFTYOUVP`6XPYc6VaWrV=zG!k*Coxv8N+}h6IqGsT zBP^$F8aqlx#j&BSF>zGh`6WP)&tfgHjpf{Y6`v|MOc_Im4G)&o#nGaz??e*~WHI90 zn#bq-dNop1*bt4bzJgX3aKH1+>v+6mRGho*Ms>8A6%{nPgx?!n%;3@GXGOglGNejy1@Vd delta 679 zcmZ8dQAm?f6h8Ni)*8Qawnn%n2`-wn?4O%%gQ!h$AxX6#M`>|IoXKho?e2Pr?XHK#7;leQjsJf>Tg}VHgLC&yDVF z|HDES)QivU^6%ePjlpR+A*&7Cs(K&=CPes3!N(Vi#@gq?J;pyC@j9e{KdKz&%@@JD z8)dOkX3JlhN#$`ozy{St?<|bd!wkCb=dnuf^BC+3LkObM(1dQ7h8oo6Z6jHEdg)gV zN9buD*QqasH(8ACB=C^%oW*ZQk2C1n5wcq;H;rA?sNkwCyV3q%be^mGxcR_IW)*LV z_#~cVs@Wl%siS~?@?_C17A|6+CX{Q8GDYkZPpW7z1;q6X%}dxVUY^Hvi*`V3y_Yep zwR&DLQ^O$*By{s)6zeDQ?eTL{lk62}y-)K(0tT9G%6W z(o&>=Kem?;g}AWe{>>DH0sic#Urf$oKa+z-Df6B6P}4+%((`DD&1>=}MJ#Q#5FTn? skh@qeN%o)lpz@N;Pz#u#l?v-5YaZXIfJqflSasagiDM#l9hYAH1|e{@LjV8( diff --git a/system/regnatix/regime.spin b/system/regnatix/regime.spin index 4529811a3831bf602334ef7a565a5c8ad51e0874..92d08dcd07673ac7a7d6899377bfdad7530500e9 100644 GIT binary patch delta 539 zcmaiwKS/{=dV!1Efz`I%<8L4#-`f?8@wwJy4dUQ2qdaQ;cW+$EQgAx&cpl0uLm zwm67`&nnW2n;_CF4jqD1=N3w~7Tm?Z89GSm`K7ozeb0~Q{a&8uJ-Tx5UAqsz`61Uu z`@4TvawTB0{w*fsYY(%328HgHB)uVvhUf{*sfR6TdP@Z=QpW!Ad|X6C9e}F6M&*@& z1I>fw=`iYA3Hcd6Ce#qBGZpSBvm!PkA#BWU-*R)2-cg=X7*|J7nycVuj`8`4`7(^4 zuPIAQ+>@iL_!w>MI*S(gu53)?vj?#iJYJ9;9md+iCigmY4`)j+b3WB2&f$22t8w9$ zw~SS8ZyH`6xn?NnHW}A>Q)w+YjpMXLCM`Q57pF%dCMKaJBwk`Cp`!kYA@_0^V@c&f zW7?t=WqIgY@&z7QypU@Mm)g_zAl==KT1lh;1@KGlgkoi#I9})VqGsv;wFE5{!|wYW zavc&v={`jEWfv@UwJT=vT=?yKF4#mMH(#Z;flvvs{B-Z@9YcHir&=4bN4U#xz z3L$T328SwciWCkyI9UTC2qii@Na-jT>XZ(}yX)nbxcz?bd*6GH_r3kgZ69!3U%c?I zi$=@)Mmn`Z1k06)hP8KLbPf!jF8?A9})Zjw_5!Hr( zy*mLsh=!rKIBd=dXVy$!mU48OL{dn>f*J%Ld+N+ZRAL?|I~+czuHkE}WaG6((S6_a z@9ylRrck~6s;h~_PhqfsmR~yFJ6MtjEDwu+{az8j#`ulefJ=5~>G6MJT>K>ytHy`e zQY)VC20$nwFuam@!T3W-*$Es#G+AZ%@1)1!2Qir{GJO4;r!TC*@M5~FAH>Hr%X3yU z>v}{Q=`8VrTE?#GwbiZqeA+Bjt@nSg-9}qG&*sz1b1nscUSH_*ox+dh*ocD9o%XvKXOPF4r!2CD|sUhR) znt;~E1f-^Dd{|X0CLo{K9;+Yvt*g|VGSqiGYR6w}9ZuT4l#T>MI$?`~&E`dX>iBwe g2}d2prsdqcvD - in das entsprechende marker- dmset - setzt den entsprechenden marker auf das aktuelle verzeichnis dmclr - marker löschen +forth - forth starten marker: -r - root-verzeichnis -s - system-verzeichnis -u - user-verzeichnis -a/b/c - benutzerdefinierte verzeichnismarker +r - root-verzeichnis +s - system-verzeichnis +u - user-verzeichnis +a/b/c - benutzerdefinierte verzeichnismarker r, s, u-marker werden vom system automatisch gesetzt und intern verwendet.