ansi-forth.fs 117 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377
  1. \ ansi-forth.fs
  2. \
  3. \ Copyright (c) 2009 Openmoko Inc.
  4. \
  5. \ Authors Christopher Hall <hsw@openmoko.com>
  6. \
  7. \ Redistribution and use in source and binary forms, with or without
  8. \ modification, are permitted provided that the following conditions are
  9. \ met:
  10. \
  11. \ 1. Redistributions of source code must retain the above copyright
  12. \ notice, this list of conditions and the following disclaimer.
  13. \
  14. \ 2. Redistributions in binary form must reproduce the above copyright
  15. \ notice, this list of conditions and the following disclaimer in
  16. \ the documentation and/or other materials provided with the
  17. \ distribution.
  18. \
  19. \ THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
  20. \ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. \ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. \ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
  23. \ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. \ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. \ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  26. \ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27. \ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  28. \ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  29. \ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. \ set up for running the meta compiliation
  31. only forth definitions
  32. also meta-compiler
  33. meta-compile
  34. \ possible formats:
  35. \ <colon> word <double-colon> alt-name ( -- )
  36. \ <c-o-d-e> word <double-colon> alt-name ( -- )
  37. 21
  38. constant build-number :: build-number ( -- n )
  39. code ! :: store ( x a-addr -- )
  40. ld.w %r4, [%r1]+
  41. ld.w %r5, [%r1]+
  42. ld.w [%r4], %r5
  43. NEXT
  44. end-code
  45. \ **not really correct, it will not work with 'ud' i.e.64 bit numbers
  46. : # :: number-sign ( ud1 -- ud2 )
  47. base @ um/mod ( ur uq )
  48. swap 9 over < if
  49. [ char A char 9 - 1- ] literal +
  50. then
  51. [char] 0 + hold 0 ;
  52. : #> :: number-sign-greater ( xd -- c-addr u )
  53. 2drop hld @ pad over - ;
  54. : #s :: number-sign-s ( ud1 -- ud2 )
  55. begin # 2dup or while repeat ;
  56. : ' :: tick ( "<spaces>name" -- xt )
  57. parse-word search-wordlists if exit then throw ;
  58. : ( :: paren ( "ccc<paren>" -- )
  59. [char] ) parse 2drop ; immediate
  60. code (colon) :: paren-colon-paren ( R: -- nest-sys )
  61. pushn %r0 ; save previous ip
  62. ld.w %r0, [%r2] ; ip = param address
  63. NEXT
  64. end-code
  65. compile-only
  66. code (const) :: paren-const-paren ( %r2: address -- )
  67. ld.w %r4, [%r2] ; %r4 = parameter address
  68. ld.w %r4, [%r4] ; read the constant value
  69. sub %r1, BYTES_PER_CELL
  70. ld.w [%r1], %r4
  71. NEXT
  72. end-code
  73. compile-only
  74. code (?do) :: paren-question-do-paren ( limit index -- ) ( R: -- limit index )
  75. ld.w %r4, [%r1]+ ; index
  76. ld.w %r5, [%r1]+ ; limit
  77. cmp %r4, %r5 ; equal? => skip the loop
  78. jreq qdo_l1 ; ...yes
  79. sub %sp, 1
  80. ld.w [%sp], %r5 ; limit
  81. sub %sp, 1
  82. ld.w [%sp], %r4 ; index
  83. add %r0, BYTES_PER_CELL ; skip the branch address
  84. NEXT
  85. qdo_l1:
  86. ld.w %r0, [%r0] ; branch over loop
  87. NEXT
  88. end-code
  89. code (do) :: paren-do-paren ( limit index -- ) ( R: -- limit index )
  90. ld.w %r4, [%r1]+ ; index
  91. ld.w %r5, [%r1]+ ; limit
  92. sub %sp, 1
  93. ld.w [%sp], %r5 ; limit
  94. sub %sp, 1
  95. ld.w [%sp], %r4 ; index
  96. add %r0, BYTES_PER_CELL ; skip the branch address
  97. NEXT
  98. end-code
  99. compile-only
  100. code (does>) :: paren-does-paren ( R: -- nest-sys )
  101. pushn %r0 ; save previous ip
  102. ld.w %r3, [%r2]+ ; w = param address
  103. sub %r1, BYTES_PER_CELL ; push w
  104. ld.w [%r1], %r3 ; ..
  105. ld.w %r0, [%r2] ; ip = does address
  106. NEXT
  107. end-code
  108. compile-only
  109. code (lit) :: paren-lit-paren ( -- x)
  110. ld.w %r3, [%r0]+
  111. sub %r1, BYTES_PER_CELL
  112. ld.w [%r1], %r3
  113. NEXT
  114. end-code
  115. compile-only
  116. \ (local) :: paren-local-paren ( c-addr u -- )
  117. code (+loop) :: paren-plus-loop-paren ( x -- ) ( R: stop count+x -- )
  118. ld.w %r4, [%r1]+ ; increment
  119. ld.w %r5, [%sp] ; count
  120. add %r4, %r5 ; count + increment
  121. ld.w [%sp], %r4 ; count + increment
  122. xld.w %r6, [%sp + BYTES_PER_CELL] ; stop
  123. sub %r5, %r6 ; count - stop
  124. sub %r4, %r6 ; count+increment - stop
  125. xor %r4, %r5 ; if negative then loop is complete
  126. jrlt loop_done ; ...yes, skip the branch offset
  127. ld.w %r0, [%r0] ; ...no, branch back
  128. NEXT
  129. end-code
  130. compile-only
  131. code (loop) :: paren-loop-paren ( x -- ) ( R: stop count+x -- )
  132. ld.w %r5, [%sp] ; count
  133. add %r5, 1
  134. ld.w [%sp], %r5 ; count + increment
  135. xld.w %r4, [%sp + BYTES_PER_CELL] ; stop
  136. cmp %r4, %r5 ; count == stop?
  137. jreq loop_done ; ...yes, skip the branch offset
  138. loop_continue:
  139. ld.w %r0, [%r0] ; ...no, branch back
  140. NEXT
  141. loop_done:
  142. add %sp, 2 ; drop 2 stack words
  143. add %r0, BYTES_PER_CELL ; skip branch offset
  144. NEXT
  145. end-code
  146. : (s") :: paren-s-quote-paren ( -- c-addr u )
  147. r> count ( c-addr u )
  148. 2dup + aligned ( c-addr u r-addr )
  149. >r
  150. ; compile-only
  151. code (var) :: paren-var-paren ( %r2: address -- )
  152. ld.w %r4, [%r2] ; %r4 = parameter address
  153. sub %r1, BYTES_PER_CELL
  154. ld.w [%r1], %r4
  155. NEXT
  156. end-code
  157. compile-only
  158. code * :: star ( n1|u1 n2|u2 -- n3|u3 )
  159. ld.w %r4, [%r1]+
  160. ld.w %r5, [%r1]
  161. mlt.w %r4, %r5
  162. ld.w %r4, %alr
  163. ld.w [%r1], %r4
  164. NEXT
  165. end-code
  166. \ */ :: star-slash ( n1 n2 n3 -- n4 )
  167. \ */mod nip ;
  168. \ */mod :: star-slash-mod ( n1 n2 n3 -- n4:r n5:q )
  169. code + :: plus ( n1|u1 n2|u2 -- n3|u3 )
  170. ld.w %r4, [%r1]+
  171. ld.w %r5, [%r1]
  172. add %r4, %r5
  173. ld.w [%r1], %r4
  174. NEXT
  175. end-code
  176. code +! :: plus-store ( n|u a-addr -- )
  177. ld.w %r4, [%r1]+
  178. ld.w %r5, [%r1]+
  179. ld.w %r6, [%r4]
  180. add %r5, %r6
  181. ld.w [%r4], %r5
  182. NEXT
  183. end-code
  184. : +loop :: plus-loop ( C: do-sys -- ) ( -- ) ( R: loop-sys1 -- | loop-sys2 )
  185. align
  186. postpone (+loop) compile, here swap ! ; immediate compile-only
  187. : , :: comma ( x -- )
  188. align here dup cell+ cp ! ! ;
  189. code - :: minus ( n1|u1 n2|u2 -- n3|u3 )
  190. ld.w %r5, [%r1]+
  191. ld.w %r4, [%r1]
  192. sub %r4, %r5
  193. ld.w [%r1], %r4
  194. NEXT
  195. end-code
  196. : -rot :: minus-rote ( x1 x2 x3 -- x3 x1 x2 )
  197. rot rot ;
  198. : -trailing :: dash-trailing ( c-addr u1 -- c-addr u2 )
  199. dup 1- swap 0 ?do
  200. 2dup i cr - + c@ bl xor
  201. if i - char+ unloop exit then
  202. loop drop 0 ;
  203. : . :: dot ( n -- )
  204. s>d d. ;
  205. : ." :: dot-quote ( "ccc<quote>" -- )
  206. postpone s" postpone type ; immediate compile-only
  207. : .( :: dot-paren ( "ccc<paren>" -- )
  208. [char] ) parse cr type ; immediate
  209. : .r :: dot-r ( n1 n2 -- )
  210. >r s>d r> d.r ;
  211. : .s :: dot-s ( -- )
  212. cr ." [" depth dup 0 .r ." ]: "
  213. dup 0 ?do dup i - pick . loop ." <-top"
  214. drop ;
  215. \ .vocab :: dot-vocab ( wid -- )
  216. : / :: slash ( n1 n2 -- n3 )
  217. /mod nip ;
  218. : /mod :: slash-mod ( n1 n2 -- n3:r n4:q )
  219. >r s>d r> fm/mod ;
  220. : /string :: slash-string ( c-addr1 u1 n -- c-addr2 u2 )
  221. 2dup < if 2drop 0
  222. else
  223. swap over + ( c-addr1 n u1+n )
  224. rot rot +
  225. then ;
  226. code 0< :: zero-less ( n -- flag )
  227. ld.w %r4, [%r1]
  228. or %r4, %r4
  229. jrlt set_true_flag
  230. set_false_flag:
  231. ld.w %r4, FALSE
  232. ld.w [%r1], %r4
  233. NEXT
  234. set_true_flag:
  235. ld.w %r4, TRUE
  236. ld.w [%r1], %r4
  237. NEXT
  238. end-code
  239. code 0<> :: zero-not-equals ( x -- flag )
  240. ld.w %r4, [%r1]
  241. or %r4, %r4
  242. jrne set_true_flag
  243. jp set_false_flag
  244. end-code
  245. code 0= :: zero-equals ( x -- flag )
  246. ld.w %r4, [%r1]
  247. or %r4, %r4
  248. jreq set_true_flag
  249. jp set_false_flag
  250. end-code
  251. code 0> :: zero-greater ( n -- flag )
  252. ld.w %r4, [%r1]
  253. or %r4, %r4
  254. jrgt set_true_flag
  255. jp set_false_flag
  256. end-code
  257. code 1+ :: one-plus ( n1|u1 -- n2|u2 )
  258. ld.w %r4, [%r1]
  259. add %r4, 1
  260. ld.w [%r1], %r4
  261. NEXT
  262. end-code
  263. code 1- :: one-minus ( n1|u1 -- n2|u2 )
  264. ld.w %r4, [%r1]
  265. sub %r4, 1
  266. ld.w [%r1], %r4
  267. NEXT
  268. end-code
  269. code 2! :: two-store ( x1 x2 a-addr -- )
  270. ld.w %r6, [%r1]+ ; a-addr
  271. ld.w %r5, [%r1]+ ; x2
  272. ld.w %r4, [%r1]+ ; x1
  273. ld.w [%r6]+, %r4 ; x1
  274. ld.w [%r6]+, %r5 ; x2
  275. NEXT
  276. end-code
  277. code 2* :: two-star ( x1 -- x2 )
  278. ld.w %r4, [%r1]
  279. sla %r4, 1
  280. ld.w [%r1], %r4
  281. NEXT
  282. end-code
  283. code 2/ :: two-slash ( x1 -- x2 )
  284. ld.w %r4, [%r1]
  285. sra %r4, 1
  286. ld.w [%r1], %r4
  287. NEXT
  288. end-code
  289. code 2>r :: two-to-r ( x1 x2 -- ) ( R: -- x1 x2 )
  290. ld.w %r4, [%r1]+ ; x2
  291. ld.w %r5, [%r1]+ ; x1
  292. sub %sp, 1
  293. ld.w [%sp], %r5
  294. sub %sp, 1
  295. ld.w [%sp], %r4
  296. NEXT
  297. end-code
  298. code 2@ :: two-fetch ( a-addr -- x1 x2 )
  299. ld.w %r4, [%r1] ; a-addr
  300. ld.w %r5, [%r4]+
  301. ld.w [%r1], %r5
  302. sub %r1, BYTES_PER_CELL
  303. ld.w %r5, [%r4]
  304. ld.w [%r1], %r5
  305. NEXT
  306. end-code
  307. \ 2constant :: two-constant ( x1 x2 "<spaces>name" -- )
  308. : 2drop :: two-drop ( x1 x2 -- )
  309. drop drop ;
  310. : 2dup :: two-dupe ( x1 x2 -- x1 x2 x1 x2 )
  311. over over ;
  312. \ 2literal :: two-literal ( x1 x2 -- )
  313. : 2over :: two-over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
  314. 3 pick 3 pick ;
  315. code 2r> :: two-r-from ( -- x1 x2 ) ( R: x1 x2 -- )
  316. ld.w %r4, [%sp] ; x2
  317. add %sp, 1
  318. ld.w %r5, [%sp] ; x1
  319. add %sp, 1
  320. sub %r1, BYTES_PER_CELL
  321. ld.w [%r1], %r5
  322. sub %r1, BYTES_PER_CELL
  323. ld.w [%r1], %r4
  324. NEXT
  325. end-code
  326. code 2r@ :: two-r-fetch ( -- x1 x2 ) ( R: x1 x2 -- x1 x2 )
  327. ld.w %r4, [%sp] ; x2
  328. xld.w %r5, [%sp + BYTES_PER_CELL] ; x1
  329. sub %r1, BYTES_PER_CELL
  330. ld.w [%r1], %r5
  331. sub %r1, BYTES_PER_CELL
  332. ld.w [%r1], %r4
  333. NEXT
  334. end-code
  335. \ 2rot :: two-rote ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 )
  336. code 2swap :: two-swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 )
  337. ld.w %r4, [%r1] ; x4
  338. xld.w %r5, [%r1 + BYTES_PER_CELL] ; x3
  339. xld.w %r6, [%r1 + BYTES_PER_CELL * 2] ; x2
  340. xld.w %r7, [%r1 + BYTES_PER_CELL * 3] ; x1
  341. ld.w [%r1], %r6 ; x2
  342. xld.w [%r1 + BYTES_PER_CELL], %r7 ; x1
  343. xld.w [%r1 + BYTES_PER_CELL * 2], %r4; x4
  344. xld.w [%r1 + BYTES_PER_CELL * 3], %r5; x3
  345. NEXT
  346. end-code
  347. : 2variable :: two-variable ( "<spaces>name" -- )
  348. create 0 , 0 , ;
  349. : : :: colon ( C: "<spaces>name" -- colon-sys )
  350. create
  351. ['] (colon) @ last-definition @ !
  352. ]
  353. ;
  354. \ :noname :: colon-no-name ( C: -- colon-sys ) ( S: -- xt )
  355. : ; :: semicolon ( C: colon-sys -- )
  356. postpone exit
  357. 0 compile, \ zero for see
  358. postpone [
  359. ; immediate compile-only
  360. \ ;code :: semicolon-code ( C: colon-sys -- )
  361. code < :: less-than ( n1 n2 -- flag )
  362. ld.w %r5, [%r1]+ ; n2
  363. ld.w %r4, [%r1] ; n1
  364. cmp %r4, %r5 ; n1 < n2
  365. jrlt set_true_flag_1 ; ...yes
  366. jp set_false_flag_1 ; ...no
  367. end-code
  368. : <# :: less-number-sign ( -- )
  369. pad hld ! ;
  370. code <> :: not-equals ( x1 x2 -- flag )
  371. ld.w %r5, [%r1]+ ; x1
  372. ld.w %r4, [%r1] ; x2
  373. cmp %r4, %r5 ; x1 <> x2
  374. jrne set_true_flag_1 ; ...yes
  375. jp set_false_flag_1 ; ...no
  376. end-code
  377. code = :: equals ( x1 x2 -- flag )
  378. ld.w %r5, [%r1]+ ; x1
  379. ld.w %r4, [%r1] ; x2
  380. cmp %r4, %r5 ; x1 = x2
  381. jreq set_true_flag_1 ; ...yes
  382. jp set_false_flag_1 ; ...no
  383. end-code
  384. code > :: greater-than ( n1 n2 -- flag )
  385. ld.w %r5, [%r1]+ ; n2
  386. ld.w %r4, [%r1] ; n1
  387. cmp %r4, %r5 ; n1 > n2 ?
  388. jrgt set_true_flag_1 ; ...yes
  389. set_false_flag_1:
  390. ld.w %r4, FALSE
  391. ld.w [%r1], %r4
  392. NEXT
  393. set_true_flag_1:
  394. ld.w %r4, TRUE
  395. ld.w [%r1], %r4
  396. NEXT
  397. end-code
  398. code >body :: to-body ( xt -- a-addr )
  399. ld.w %r4, [%r1] ; xt
  400. xld.w %r5, DICTIONARY_CODE_TO_PARAM_OFFSET_BYTES
  401. add %r4, %r5
  402. ld.w [%r1], %r4
  403. NEXT
  404. end-code
  405. code >code :: to-code ( name-a-addr -- xt )
  406. ld.w %r4, [%r1] ; xt
  407. xld.w %r5, DICTIONARY_CODE_TO_NAME_OFFSET_BYTES
  408. sub %r4, %r5
  409. ld.w [%r1], %r4
  410. NEXT
  411. end-code
  412. code >does :: to-does ( xt -- a-addr )
  413. ld.w %r4, [%r1] ; xt
  414. xld.w %r5, DICTIONARY_CODE_TO_DOES_OFFSET_BYTES
  415. add %r4, %r5
  416. ld.w [%r1], %r4
  417. NEXT
  418. end-code
  419. code >flags :: to-flags ( xt -- a-addr )
  420. ld.w %r4, [%r1] ; xt
  421. xld.w %r5, DICTIONARY_CODE_TO_FLAGS_OFFSET_BYTES
  422. add %r4, %r5
  423. ld.w [%r1], %r4
  424. NEXT
  425. end-code
  426. variable >in :: to-in ( -- a-addr )
  427. code >link :: to-link ( xt -- a-addr )
  428. ld.w %r4, [%r1] ; xt
  429. xld.w %r5, DICTIONARY_CODE_TO_LINK_OFFSET_BYTES
  430. add %r4, %r5
  431. ld.w [%r1], %r4
  432. NEXT
  433. end-code
  434. code >name :: to-name ( xt -- a-addr )
  435. ld.w %r4, [%r1] ; xt
  436. xld.w %r5, DICTIONARY_CODE_TO_NAME_OFFSET_BYTES
  437. add %r4, %r5
  438. ld.w [%r1], %r4
  439. NEXT
  440. end-code
  441. : >number :: to-number ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 )
  442. base @ >r 0 >r
  443. dup if
  444. over c@
  445. case
  446. [char] + of >number-skip endof
  447. [char] - of >number-skip r> drop 1 >r endof
  448. [char] % of >number-skip 2 base ! endof
  449. [char] & of >number-skip 8 base ! endof
  450. [char] # of >number-skip 10 base ! endof
  451. [char] $ of >number-skip 16 base ! endof
  452. endcase
  453. >number-digits
  454. r> r> base !
  455. if
  456. 2>r dnegate 2r>
  457. then
  458. then
  459. ;
  460. : >number-digits :: to-number-digits ( ud1 c-addr u -- ud2 c-addr+n u- )
  461. begin
  462. dup while
  463. over c@ digit? if ( ud c-addr u digit36 )
  464. dup base @ > if drop exit then
  465. rot rot ( ud digit c-addr u )
  466. 2>r >r
  467. drop base @ um* r> s>d d+
  468. 2r> ( ud*base+digit c-addr u )
  469. >number-skip
  470. else
  471. exit
  472. then
  473. repeat
  474. ;
  475. : >number-skip :: to-number-skip ( c-addr u -- c-addr+1 u-1 )
  476. 1- swap char+ swap ;
  477. code >r :: to-r ( x -- ) ( R: -- x )
  478. ld.w %r4, [%r1]+
  479. sub %sp, 1
  480. ld.w [%sp], %r4
  481. NEXT
  482. end-code
  483. : ? :: question ( a-addr -- )
  484. @ . ;
  485. code ?branch :: question-branch ( -- )
  486. ld.w %r4, [%r1]+
  487. or %r4, %r4
  488. jrne no_branch
  489. ld.w %r0, [%r0]
  490. NEXT
  491. no_branch:
  492. add %r0, BYTES_PER_CELL
  493. NEXT
  494. end-code
  495. : ?do :: question-do ( C: -- do-sys ) ( n1|u1 n2|u2 -- ) ( R: -- | loop-sys )
  496. align
  497. postpone (?do) here 0 compile, here ; immediate compile-only
  498. code ?dup :: question-dupe ( x -- 0 | x x )
  499. ld.w %r4, [%r1]
  500. or %r4, %r4
  501. jreq qdup_l1
  502. sub %r1, BYTES_PER_CELL
  503. ld.w [%r1], %r4
  504. qdup_l1:
  505. NEXT
  506. end-code
  507. : ?stack :: question-stack ( -- )
  508. depth 0< if -4 throw then \ underflow
  509. ;
  510. code @ :: fetch ( a-addr -- x )
  511. ld.w %r4, [%r1]
  512. ld.w %r4, [%r4]
  513. ld.w [%r1], %r4
  514. NEXT
  515. end-code
  516. : abort :: abort ( i*x -- ) ( R: j*x -- )
  517. quit-reset
  518. quit ;
  519. : abort" :: abort-quote ( "ccc<quote>" -- )
  520. postpone if
  521. postpone cr
  522. postpone ."
  523. postpone abort
  524. postpone then ; immediate
  525. : abs :: abs ( n -- u )
  526. dup 0 < if negate then ;
  527. : accept :: accept ( c-addr +n1 -- +n2 )
  528. over + over ( begin end+1 current )
  529. begin
  530. key dup
  531. [ctrl] m = over [ctrl] j = or 0=
  532. while
  533. ( begin end+1 current char )
  534. dup bl 127 within if
  535. ( begin end+1 current char )
  536. >r 2dup xor if
  537. r> dup emit
  538. over c!
  539. char+
  540. else
  541. r> drop
  542. then
  543. else
  544. dup [ctrl] h = over 127 = or if
  545. drop ( begin end+1 current )
  546. 2 pick over <> if
  547. char-
  548. [ctrl] h emit bl emit [ctrl] h emit
  549. then
  550. else
  551. drop
  552. then
  553. then
  554. repeat drop
  555. nip over -
  556. cr
  557. ;
  558. : again :: again ( C: dest -- ) ( -- )
  559. postpone branch compile, ; immediate compile-only
  560. : ahead :: ahead ( C: -- orig ) ( -- )
  561. align
  562. postpone branch here 0 compile, ; immediate compile-only
  563. : align :: align ( -- )
  564. here aligned cp ! ;
  565. code aligned :: aligned ( addr -- a-addr )
  566. ld.w %r4, [%r1]
  567. add %r4, BYTES_PER_CELL - 1
  568. and %r4, ~(BYTES_PER_CELL - 1) ; must be power of 2
  569. ld.w [%r1], %r4
  570. NEXT
  571. end-code
  572. \ allocate :: allocate ( u -- a-addr ior )
  573. : allot :: allot ( n -- )
  574. here + cp ! ;
  575. : also :: also ( -- )
  576. get-order ?dup if over swap 1+ set-order then ;
  577. code and :: and ( x1 x2 -- x3 )
  578. ld.w %r4, [%r1]+
  579. ld.w %r5, [%r1]
  580. and %r4, %r5
  581. ld.w [%r1], %r4
  582. NEXT
  583. end-code
  584. \ assembler :: assembler ( -- )
  585. \ at-xy :: at-x-y ( u1 u2 -- )
  586. variable base :: base ( -- a-addr )
  587. : begin :: begin ( -- )
  588. align here ; immediate compile-only
  589. code bin :: bin ( fam1 -- fam2 )
  590. ld.w %r6, [%r1] ; fam
  591. xcall FileSystem_bin
  592. ld.w [%r1], %r4 ; fam2
  593. NEXT
  594. end-code
  595. : bl :: b-l ( -- char )
  596. 32 ;
  597. : blank :: blank ( c-addr u -- )
  598. bl fill ;
  599. \ blk :: b-l-k ( -- a-addr )
  600. \ block :: block ( u -- a-addr )
  601. code branch :: branch ( -- )
  602. ld.w %r0, [%r0]
  603. NEXT
  604. end-code
  605. \ buffer :: buffer ( u -- a-addr )
  606. \ bye :: bye ( -- )
  607. code c! :: c-store ( char c-addr -- )
  608. ld.w %r4, [%r1]+
  609. ld.w %r5, [%r1]+
  610. ld.b [%r4], %r5
  611. NEXT
  612. end-code
  613. : c, :: c-comma ( char -- )
  614. here dup char+ cp ! c! ;
  615. code c@ :: c-fetch ( c-addr -- char )
  616. ld.w %r4, [%r1]
  617. ld.ub %r4, [%r4]
  618. ld.w [%r1], %r4
  619. NEXT
  620. end-code
  621. : c33 :: c-3-3 ( -- )
  622. get-order dup 0> if nip else 1+ then
  623. c33-wordlist swap set-order
  624. ;
  625. variable c33-wordlist :: c33-wordlist ( -- wid )
  626. : case :: case ( C: -- case-sys ) ( -- )
  627. 0 ; immediate compile-only
  628. : catch :: catch ( i*x xt -- j*x 0 | i*x n )
  629. sp@ >r handler @ >r rp@ handler !
  630. execute
  631. r> handler ! r> drop 0 ;
  632. code cell+ :: cell-plus ( a-addr1 -- a-addr2 )
  633. ld.w %r4, [%r1]
  634. add %r4, BYTES_PER_CELL
  635. ld.w [%r1], %r4
  636. NEXT
  637. end-code
  638. code cell- :: cell-minus ( a-addr1 -- a-addr2 )
  639. ld.w %r4, [%r1]
  640. sub %r4, BYTES_PER_CELL
  641. ld.w [%r1], %r4
  642. NEXT
  643. end-code
  644. code cells :: cells ( n1 -- n2 )
  645. ld.w %r4, [%r1] ; value
  646. sla %r4, LOG2_BYTES_PER_CELL
  647. ld.w [%r1], %r4
  648. NEXT
  649. end-code
  650. : char :: char ( "<spaces>name" -- char )
  651. bl parse drop c@ ;
  652. code char+ :: char-plus ( c-addr1 -- c-addr2 )
  653. ld.w %r4, [%r1]
  654. add %r4, 1
  655. ld.w [%r1], %r4
  656. NEXT
  657. end-code
  658. code char- :: char-minus ( c-addr1 -- c-addr2 )
  659. ld.w %r4, [%r1]
  660. sub %r4, 1
  661. ld.w [%r1], %r4
  662. NEXT
  663. end-code
  664. : chars :: chars ( n1 -- n2 )
  665. ;
  666. code close-file :: close-file ( fileid -- ior )
  667. ld.w %r6, [%r1] ; fileid
  668. xcall FileSystem_close
  669. ld.w [%r1], %r5 ; ior
  670. NEXT
  671. end-code
  672. code cmove :: c-move ( c-addr1 c-addr2 u -- )
  673. ld.w %r4, [%r1]+ ; count
  674. ld.w %r5, [%r1]+ ; dst
  675. ld.w %r6, [%r1]+ ; src
  676. or %r4, %r4
  677. jreq cmove_done
  678. cmove_loop:
  679. ld.ub %r7, [%r6]+
  680. ld.b [%r5]+, %r7
  681. xsub %r4, 1
  682. jrne cmove_loop
  683. cmove_done:
  684. NEXT
  685. end-code
  686. code cmove> :: c-move-up ( c-addr1 c-addr2 u -- )
  687. ld.w %r4, [%r1]+ ; count
  688. ld.w %r5, [%r1]+ ; dst
  689. ld.w %r6, [%r1]+ ; src
  690. or %r4, %r4
  691. jreq cmove_up_done
  692. add %r5, %r4
  693. add %r6, %r4
  694. cmove_up_loop:
  695. xsub %r5, 1
  696. xsub %r6, 1
  697. ld.ub %r7, [%r6]
  698. ld.b [%r5], %r7
  699. xsub %r4, 1
  700. jrne cmove_up_loop
  701. cmove_up_done:
  702. NEXT
  703. end-code
  704. \ code :: code ( C: "<spaces>name" -- )
  705. : cold :: cold ( i*x -- )
  706. cold-rp0 rp!
  707. cold-reset
  708. only forth definitions
  709. cr ." moko forth interpreter for S1C33 (build:"
  710. build-number 0 u.r
  711. ." )" cr
  712. quit-reset
  713. \ predefined program to run
  714. 'cold-run @ ?dup if
  715. execute
  716. then
  717. \ initial code to run
  718. cold-arg if
  719. s" forth.tst"
  720. else
  721. s" forth.ini"
  722. then
  723. r/o open-file 0= if \ ignore any errors
  724. include-file
  725. then
  726. quit
  727. ;
  728. \ like cold but no forth.ini
  729. : cold0 :: cold0 ( i*x -- )
  730. cold-rp0 rp!
  731. cold-reset
  732. only forth definitions
  733. cr ." moko forth interpreter for S33C (build:"
  734. build-number 0 u.r
  735. ." )" cr
  736. quit-reset
  737. quit
  738. ;
  739. code cold-arg :: cold-arg ( -- a-addr )
  740. xld.w %r4, initial_argument
  741. ld.w %r4, [%r4]
  742. sub %r1, BYTES_PER_CELL
  743. ld.w [%r1], %r4
  744. NEXT
  745. end-code
  746. code cold-cp0 :: cold-c-p-zero ( -- a-addr )
  747. xld.w %r4, dictionary_end
  748. sub %r1, BYTES_PER_CELL
  749. ld.w [%r1], %r4
  750. NEXT
  751. end-code
  752. code cold-last-names :: cold-last-names ( -- a-addr a-addr a-addr )
  753. xld.w %r4, c33_last_name ; name of last word
  754. sub %r1, BYTES_PER_CELL
  755. ld.w [%r1], %r4
  756. xld.w %r4, forth_last_name ; name of last word
  757. sub %r1, BYTES_PER_CELL
  758. ld.w [%r1], %r4
  759. xld.w %r4, root_last_name ; name of last word
  760. sub %r1, BYTES_PER_CELL
  761. ld.w [%r1], %r4
  762. NEXT
  763. end-code
  764. : cold-reset :: cold-reset ( i*x -- )
  765. cold-sp0 sp!
  766. 0 >in !
  767. 10 base !
  768. cold-cp0 cp !
  769. 0 current !
  770. 0 handler !
  771. pad hld !
  772. cold-rp0 rp0 !
  773. cold-sp0 sp0 !
  774. 0 source-id !
  775. false state !
  776. 0 terminal-count !
  777. cold-last-names
  778. root-wordlist !
  779. forth-wordlist !
  780. c33-wordlist !
  781. ;
  782. code cold-rp0 :: cold-r-p-zero ( -- a-addr )
  783. xld.w %r4, initial_return_pointer
  784. sub %r1, BYTES_PER_CELL
  785. ld.w [%r1], %r4
  786. NEXT
  787. end-code
  788. code cold-sp0 :: cold-s-p-zero ( -- a-addr )
  789. xld.w %r4, initial_stack_pointer
  790. sub %r1, BYTES_PER_CELL
  791. ld.w [%r1], %r4
  792. NEXT
  793. end-code
  794. code compare :: compare ( c-addr1 u1 c-addr2 u2 -- n )
  795. ld.w %r4, [%r1]+ ; count 2
  796. ld.w %r5, [%r1]+ ; address 2
  797. ld.w %r6, [%r1]+ ; count 1
  798. ld.w %r7, [%r1] ; address 1
  799. compare_loop:
  800. or %r4,%r4 ; count 2 == 0?
  801. jrne compare_l1 ; ...no
  802. or %r6,%r6 ; count 1 == 0?
  803. jrne compare_plus_one ; ...no
  804. compare_zero:
  805. ld.w %r4, 0
  806. ld.w [%r1], %r4
  807. NEXT
  808. compare_l1:
  809. or %r6,%r6 ; count 1 == 0?
  810. jreq compare_minus_one ; ...yes
  811. ld.ub %r8, [%r7]+ ; byte 1
  812. ld.ub %r9, [%r5]+ ; byte 2
  813. cmp %r8, %r9 ; counts must be equal
  814. jrgt compare_plus_one ; byte 1 > byte 2
  815. jrlt compare_minus_one ; byte 1 < byte 2
  816. sub %r4, 1
  817. sub %r6, 1
  818. jp compare_loop ; progess next
  819. compare_plus_one:
  820. ld.w %r4, 1
  821. ld.w [%r1], %r4
  822. NEXT
  823. compare_minus_one:
  824. ld.w %r4, -1
  825. ld.w [%r1], %r4
  826. NEXT
  827. end-code
  828. : compile, :: compile-comma ( xt -- )
  829. , ;
  830. : compile-only :: compile-only ( -- )
  831. last-definition @
  832. dup 0= if
  833. -22 throw
  834. then
  835. >flags @ flag-compile-only or
  836. last-definition @ >flags ! ;
  837. : constant :: constant ( C: x "<spaces>name" -- ) ( -- x )
  838. create ,
  839. ['] (const) @ last-definition @ ! ;
  840. create context :: context ( -- addr )
  841. 16 dup cells allot
  842. constant #vocs :: number-sign-vocs ( -- u )
  843. variable #order :: number-sign-order ( -- a-addr )
  844. : count :: count ( c-addr1 -- c-addr2 u )
  845. dup cell+ swap @ ;
  846. variable cp :: cp ( -- addr )
  847. : cr :: c-r ( -- )
  848. 13 emit 10 emit ;
  849. : create :: create ( "<spaces>name" -- )
  850. parse-word 2dup
  851. search-wordlists if drop cr ." duplicate definition of: " 2dup type then
  852. ( c-addr u )
  853. align \ ensure cp is aligned
  854. here last-definition ! \ the last definition cp for immediate etc.
  855. ['] (var) @ , \ code pointer
  856. 0 , \ param pointer
  857. 0 , \ does pointer
  858. 0 , \ flags
  859. 0 , \ link
  860. dup , \ name length
  861. >r here r@ cmove \ name string
  862. r> allot \ (skip over name)
  863. align \ endure aligned
  864. here last-definition @ >body ! \ set the param pointer
  865. get-current @ \ previous name address
  866. last-definition @ >link ! \ store in link
  867. last-definition @ >name \ current name address
  868. get-current ! \ current vocab points to this name
  869. ;
  870. code create-file :: create-file ( c-addr u fam -- fileid ior )
  871. ld.w %r8, [%r1]+ ; fam
  872. ld.w %r7, [%r1] ; count
  873. xld.w %r6, [%r1 + BYTES_PER_CELL] ; string
  874. xcall FileSystem_create
  875. ld.w [%r1], %r5 ; ior
  876. xld.w [%r1 + BYTES_PER_CELL], %r4 ; fd
  877. NEXT
  878. end-code
  879. \ cs-pick :: c-s-pick ( C: destu ... orig0|dest0 -- destu ... orig0|dest0 destu ) ( S: u -- )
  880. \ cs-roll :: c-s-roll ( C: origu|destu origu-1|destu-1 ... orig0|dest0 -- origu-1|destu-1 ... orig0|dest0 origu|destu )( S: u -- )
  881. : ctrl :: ctrl ( "<spaces>name" -- char )
  882. bl parse drop c@ 31 and ;
  883. variable current :: current ( -- addr )
  884. code d+ :: d-plus ( d1|ud1 d2|ud2 -- d3|ud3 )
  885. ld.w %r4, [%r1]+ ; d2-h
  886. ld.w %r5, [%r1]+ ; d2-l
  887. ld.w %r6, [%r1] ; d1-h
  888. xld.w %r7, [%r1 + BYTES_PER_CELL] ; d2-l
  889. add %r7, %r5
  890. adc %r6, %r4
  891. ld.w [%r1], %r6 ; high
  892. xld.w [%r1 + BYTES_PER_CELL], %r7 ; low
  893. NEXT
  894. end-code
  895. code d- :: d-minus ( d1|ud1 d2|ud2 -- d3|ud3 )
  896. ld.w %r4, [%r1]+ ; d2-h
  897. ld.w %r5, [%r1]+ ; d2-l
  898. ld.w %r6, [%r1] ; d1-h
  899. xld.w %r7, [%r1 + BYTES_PER_CELL] ; d2-l
  900. sub %r7, %r5
  901. sbc %r6, %r4
  902. ld.w [%r1], %r6 ; high
  903. xld.w [%r1 + BYTES_PER_CELL], %r7 ; low
  904. NEXT
  905. end-code
  906. : d. :: d-dot ( d -- )
  907. swap over dabs <# #s rot sign #> type space ;
  908. : d.r :: d-dot-r ( d n -- )
  909. >r swap over dabs <# #s rot sign #> r> over - spaces type ;
  910. \ d0< :: d-zero-less ( d -- flag )
  911. \ d0= :: d-zero-equals ( xd -- flag )
  912. \ d2* :: d-two-star ( xd1 -- xd2 )
  913. \ d2/ :: d-two-slash ( xd1 -- xd2 )
  914. \ d< :: d-less-than ( d -- flag )
  915. \ d= :: d-equals ( xd -- flag )
  916. \ d>s :: d-to-s ( d -- n )
  917. : dabs :: d-abs ( d -- ud )
  918. dup 0< if dnegate then ;
  919. : decimal :: decimal ( -- )
  920. 10 base ! ;
  921. : definitions :: definitions ( -- )
  922. get-order over set-current discard ;
  923. code delete-file :: delete-file ( c-addr u -- ior )
  924. ld.w %r7, [%r1]+ ; count
  925. ld.w %r6, [%r1] ; string
  926. xcall FileSystem_delete
  927. ld.w [%r1], %r5 ; ior
  928. NEXT
  929. end-code
  930. : depth :: depth ( -- +n )
  931. sp@ sp0 @ swap - 1 cells / ;
  932. : digit? :: digit-question ( c -- False | base36-digit True )
  933. dup [char] 0 < if drop false exit then
  934. dup [ char 9 1+ ] literal < if [char] 0 - true exit then
  935. dup [char] A < if drop false exit then
  936. dup [ char Z 1+ ] literal < if [char] A - 10 + true exit then
  937. dup [char] a < if drop false exit then
  938. dup [ char z 1+ ] literal < if [char] a - 10 + true exit then
  939. drop false ;
  940. : discard :: discard ( x1 .. xu u -- )
  941. 0 ?do drop loop ;
  942. \ dmax :: d-max ( d1 d2 -- d3 )
  943. \ dmin :: d-min ( d1 d2 -- d3 )
  944. : dnegate :: d-negate ( d -- d)
  945. invert >r invert 1 um+ r> + ;
  946. : do :: do ( C: -- do-sys ) ( n1|u1 n2|u2 -- ) ( R: -- loop-sys )
  947. align
  948. postpone (do) here 0 compile, here ; immediate compile-only
  949. \ do-vocabulary :: do-vocabulary ( -- )
  950. \ does> @ >r ( ) ( R: widnew )
  951. \ get-order swap drop ( wid1 ... widn-1 n )
  952. \ r> swap set-order
  953. \ ;
  954. : does> :: does ( C: colon-sys1 -- colon-sys2 ) ( -- ) ( R: nest-sys1 -- )
  955. last-definition @
  956. 0= if
  957. -22 throw
  958. then
  959. ['] (does>) @ last-definition @ !
  960. r> last-definition @ >does !
  961. ; compile-only
  962. code drop :: drop ( x -- )
  963. ld.w %r4, [%r1]+
  964. NEXT
  965. end-code
  966. \ du< :: d-u-less ( ud1 ud2 -- flag )
  967. : dump :: dump ( c-addr u -- )
  968. base @ >r hex 16 /
  969. 0 ?do
  970. cr dup 4 u.r space
  971. dup
  972. 2 0 do
  973. 8 0 do
  974. dup c@ 3 u.r char+
  975. loop
  976. 2 spaces
  977. loop
  978. drop 2 spaces
  979. 2 0 do
  980. 8 0 do
  981. dup c@
  982. dup 127 bl within if drop [char] . then
  983. emit char+
  984. loop
  985. 2 spaces
  986. loop
  987. loop
  988. drop
  989. r> base !
  990. ;
  991. code dup :: dupe ( x -- x x )
  992. ld.w %r4, [%r1]
  993. sub %r1, BYTES_PER_CELL
  994. ld.w [%r1], %r4
  995. NEXT
  996. end-code
  997. \ editor :: editor ( -- )
  998. \ ekey :: e-key ( -- u )
  999. \ ekey>char :: e-key-to-char ( u -- u false | char true )
  1000. \ ekey? :: e-key-question ( -- flag )
  1001. : else :: else ( C: orig1 -- orig2 ) ( -- )
  1002. postpone ahead swap postpone then ; immediate compile-only
  1003. code emit :: emit ( char -- )
  1004. ld.w %r6, [%r1]+
  1005. xcall Serial_PutChar
  1006. NEXT
  1007. end-code
  1008. code emit? :: emit-question ( -- flag )
  1009. xcall Serial_PutReady
  1010. or %r4, %r4
  1011. jreq emit_question_no_space
  1012. ld.w %r4, TRUE
  1013. emit_question_no_space:
  1014. sub %r1, BYTES_PER_CELL
  1015. ld.w [%r1], %r4
  1016. NEXT
  1017. end-code
  1018. \ empty-buffers :: empty-buffers ( -- )
  1019. : endcase :: end-case ( C: case-sys -- ) ( x -- )
  1020. postpone drop
  1021. begin
  1022. ?dup
  1023. while
  1024. postpone then
  1025. repeat
  1026. ; immediate compile-only
  1027. : endof :: end-of ( C: case-sys1 of-sys -- case-sys2 ) ( -- )
  1028. postpone else
  1029. ; immediate compile-only
  1030. \ if key is pressed, wait for second key press
  1031. \ return true if the second key is enter
  1032. : enough? :: enough-question ( -- flag )
  1033. key? if key drop key 13 = else false then ;
  1034. \ environment? :: environment-query ( c-addr u -- false | i*x true )
  1035. : erase :: erase ( addr u -- )
  1036. 0 ?do dup 0 ! cell+ loop drop ;
  1037. : evaluate :: evaluate ( i*x c-addr u -- j*x )
  1038. source-id @ >r
  1039. -1 source-id !
  1040. quit-evaluate
  1041. r> source-id ! ;
  1042. code execute :: execute ( i*x xt -- j*x )
  1043. ld.w %r2, [%r1]+ ; point to code ptr
  1044. ld.w %r3, [%r2]+ ; code / param address
  1045. jp %r3 ; execute the code
  1046. end-code
  1047. code exit :: exit ( -- ) ( R: nest-sys -- )
  1048. popn %r0 ; restore ip
  1049. NEXT
  1050. end-code
  1051. 0
  1052. constant false :: false ( -- false )
  1053. code file-position :: file-position ( fileid -- ud ior )
  1054. ld.w %r6, [%r1] ; fileid
  1055. xcall FileSystem_ltell
  1056. ld.w [%r1], %r4 ; pos
  1057. sub %r1, BYTES_PER_CELL
  1058. ld.w [%r1], %r5 ; ior
  1059. NEXT
  1060. end-code
  1061. code file-size :: file-size ( fileid -- ud ior )
  1062. ld.w %r6, [%r1] ; fileid
  1063. xcall FileSystem_lsize
  1064. ld.w [%r1], %r4 ; size
  1065. sub %r1, BYTES_PER_CELL
  1066. ld.w [%r1], %r5 ; ior
  1067. NEXT
  1068. end-code
  1069. \ file-status :: file-status ( c-addr u -- x ior )
  1070. 20 dup
  1071. create fileid-stack :: fileid-stack ( -- a-addr )
  1072. , 0 , cells allot
  1073. code filesystem-close-all :: filesystem-close-all ( -- )
  1074. xcall FileSystem_CloseAll
  1075. NEXT
  1076. end-code
  1077. code filesystem-init :: filesystem-init ( -- )
  1078. xcall FileSystem_initialise
  1079. NEXT
  1080. end-code
  1081. : fill :: fill ( c-addr u char -- )
  1082. rot rot \ char c-addr u
  1083. 0 ?do 2dup c! 1+ loop 2drop ;
  1084. \ find :: find ( c-addr -- c-addr 0 | xt 1 | xt -1 )
  1085. code flag-compile-only :: flag-compile-only ( -- u )
  1086. ld.w %r4, FLAG_COMPILE_ONLY
  1087. sub %r1, BYTES_PER_CELL
  1088. ld.w [%r1], %r4
  1089. NEXT
  1090. end-code
  1091. code flag-immediate :: flag-immediate ( -- u )
  1092. ld.w %r4, FLAG_IMMEDIATE
  1093. sub %r1, BYTES_PER_CELL
  1094. ld.w [%r1], %r4
  1095. NEXT
  1096. end-code
  1097. \ flush :: flush ( -- )
  1098. code flush-file :: flush-file ( fileid -- ior )
  1099. ld.w %r6, [%r1] ; fileid
  1100. xcall FileSystem_sync
  1101. ld.w [%r1], %r5 ; ior
  1102. NEXT
  1103. end-code
  1104. : fm/mod :: f-m-slash-mod ( d1 n1 -- n2:r n3:q )
  1105. dup 0< dup >r
  1106. if negate >r dnegate r>
  1107. then >r dup 0< if r@ + then r> um/mod r>
  1108. if swap negate swap then ;
  1109. \ forget :: forget ( "<spaces>name" -- )
  1110. cross-root-definition
  1111. : forth :: forth ( -- )
  1112. get-order dup 0> if nip else 1+ then
  1113. forth-wordlist swap set-order
  1114. ;
  1115. cross-root-definition
  1116. variable forth-wordlist :: forth-wordlist ( -- wid )
  1117. \ free :: free ( a-addr -- ior )
  1118. : get-current :: get-current ( -- wid )
  1119. current @ ;
  1120. : get-order :: get-order ( -- widn ... wid1 n )
  1121. #order @ 0 ?do
  1122. #order @ i - 1- cells context + @
  1123. loop
  1124. #order @
  1125. ;
  1126. code h! :: half-word-store ( u h-addr -- )
  1127. ld.w %r4, [%r1]+
  1128. ld.w %r5, [%r1]+
  1129. ld.h [%r4], %r5
  1130. NEXT
  1131. end-code
  1132. code h@ :: half-word-fetch ( h-addr -- u )
  1133. ld.w %r4, [%r1]
  1134. ld.uh %r4, [%r4]
  1135. ld.w [%r1], %r4
  1136. NEXT
  1137. end-code
  1138. variable handler :: handler ( -- a-addr )
  1139. : here :: here ( -- addr )
  1140. cp @ ;
  1141. : hex :: hex ( -- )
  1142. 16 base ! ;
  1143. variable hld :: hld ( -- addr )
  1144. : hold :: hold ( char -- )
  1145. hld @ char- dup hld ! c! ;
  1146. code i :: i ( -- n|u ) ( R: loop-sys -- loop-sys )
  1147. ld.w %r4, [%sp]
  1148. xsub %r1, BYTES_PER_CELL
  1149. ld.w [%r1], %r4
  1150. NEXT
  1151. end-code
  1152. : if :: if ( C: -- orig ) ( x -- )
  1153. align
  1154. postpone ?branch here 0 compile, ; immediate compile-only
  1155. : immediate :: immediate ( -- )
  1156. last-definition @
  1157. dup 0= if
  1158. -22 throw
  1159. then
  1160. >flags @ flag-immediate or
  1161. last-definition @ >flags ! ;
  1162. : include :: include ( <filename> -- )
  1163. bl parse included ;
  1164. : include-file :: include-file ( i*x fileid -- j*x )
  1165. source-id @ fileid-stack stack-push
  1166. source-id !
  1167. ;
  1168. : included :: included ( i*x c-addr u -- j*x )
  1169. r/o open-file \ fileid ior
  1170. ?dup if cr ." open error = " . drop
  1171. else include-file
  1172. then ;
  1173. code invert :: invert ( x1 -- x2 )
  1174. ld.w %r4, [%r1]
  1175. not %r4, %r4
  1176. ld.w [%r1], %r4
  1177. NEXT
  1178. end-code
  1179. code j :: j ( -- n|u ) ( R: loop-sys1 loop-sys2 -- loop-sys1 loop-sys2 )
  1180. xld.w %r4, [%sp + 3 * BYTES_PER_CELL]
  1181. xsub %r1, BYTES_PER_CELL
  1182. ld.w [%r1], %r4
  1183. NEXT
  1184. end-code
  1185. code key :: key ( -- char )
  1186. xcall Serial_GetChar
  1187. sub %r1, BYTES_PER_CELL
  1188. ld.w [%r1], %r4
  1189. NEXT
  1190. end-code
  1191. code key? :: key-question ( -- flag )
  1192. xcall Serial_InputAvailable
  1193. or %r4, %r4
  1194. jreq key_question_no_character
  1195. ld.w %r4, TRUE
  1196. key_question_no_character:
  1197. sub %r1, BYTES_PER_CELL
  1198. ld.w [%r1], %r4
  1199. NEXT
  1200. end-code
  1201. code key-flush :: key-flush ( -- )
  1202. xcall Serial_FlushInput
  1203. NEXT
  1204. end-code
  1205. \ for create to store the last definitions xt
  1206. variable last-definition :: last-definition ( -- a-addr )
  1207. \ leave :: leave ( -- ) ( R: loop-sys -- )
  1208. \ list :: list ( u -- )
  1209. : literal :: literal ( C: x -- ) ( -- x )
  1210. postpone (lit) compile, ; immediate compile-only
  1211. \ load :: load ( i*x u -- j*x )
  1212. \ locals| :: locals-bar ( "<spaces>name1" "<spaces>name2" ... "<spaces>namen" | -- ) ( xn ... x2 x1 -- )
  1213. : loop :: loop ( C: do-sys -- ) ( -- ) ( R: loop-sys1 -- | loop-sys2 )
  1214. align
  1215. postpone (loop) compile, here swap ! ; immediate compile-only
  1216. code lshift :: l-shift ( x1 u -- x2 )
  1217. ld.w %r4, [%r1]+ ; shift
  1218. ld.w %r5, [%r1] ; value
  1219. sla %r5, %r4
  1220. ld.w [%r1], %r5
  1221. NEXT
  1222. end-code
  1223. code m* :: m-star ( n1 n2 -- d )
  1224. ld.w %r4, [%r1]+
  1225. ld.w %r5, [%r1]
  1226. mlt.w %r4, %r5
  1227. ld.w %r4, %alr
  1228. ld.w [%r1], %r4
  1229. ld.w %r4, %ahr
  1230. sub %r1, BYTES_PER_CELL
  1231. ld.w [%r1], %r4
  1232. NEXT
  1233. end-code
  1234. \ m*/ :: m-star-slash ( d1 n1 +n2 -- d2 )
  1235. code m+ :: m-plus ( d1|ud1 n -- d2|ud2 )
  1236. ld.w %r4, [%r1]+ ; n
  1237. ld.w %r5, [%r1] ; d1.low
  1238. xld.w %r6, [%r1 + BYTES_PER_CELL] ; d1.high
  1239. ld.w %r7, 0
  1240. add %r5, %r4
  1241. adc %r6, %r7
  1242. xld.w [%r1 + BYTES_PER_CELL], %r6 ; d1.high
  1243. ld.w [%r1], %r5 ; d1.low
  1244. NEXT
  1245. end-code
  1246. \ marker :: marker ( "<spaces>name" -- ) ( -- )
  1247. : max :: max ( n1 n2 -- n3 )
  1248. 2dup < if swap then drop ;
  1249. : min :: min ( n1 n2 -- n3 )
  1250. 2dup swap < if swap then drop ;
  1251. : mod :: mod ( n1 n2 -- n3 )
  1252. >r s>d r> fm/mod drop ;
  1253. \ move :: move ( addr1 addr2 u -- )
  1254. \ ms :: ms ( u -- )
  1255. code negate :: negate ( n1 -- n2 )
  1256. ld.w %r4, [%r1]
  1257. not %r4, %r4
  1258. add %r4, 1
  1259. ld.w [%r1], %r4
  1260. NEXT
  1261. end-code
  1262. code nip :: nip ( x1 x2 -- x2 )
  1263. ld.w %r4, [%r1]+ ; x2
  1264. ld.w [%r1], %r4
  1265. NEXT
  1266. end-code
  1267. : of :: of ( C: -- of-sys ) ( x1 x2 -- | x1 )
  1268. postpone over
  1269. postpone =
  1270. postpone if
  1271. postpone drop
  1272. ; immediate compile-only
  1273. : only :: only ( -- )
  1274. -1 set-order ;
  1275. code open-file :: open-file ( c-addr u fam -- fileid ior )
  1276. ld.w %r8, [%r1]+ ; fam
  1277. ld.w %r7, [%r1] ; count
  1278. xld.w %r6, [%r1 + BYTES_PER_CELL] ; string
  1279. xcall FileSystem_open
  1280. ld.w [%r1], %r5 ; ior
  1281. xld.w [%r1 + BYTES_PER_CELL], %r4 ; fd
  1282. NEXT
  1283. end-code
  1284. code or :: or ( x1 x2 -- x3 )
  1285. ld.w %r4, [%r1]+
  1286. ld.w %r5, [%r1]
  1287. or %r4, %r5
  1288. ld.w [%r1], %r4
  1289. NEXT
  1290. end-code
  1291. \ cross-root-definition
  1292. \ order :: order ( -- )
  1293. \ get-order 0 ?do
  1294. \ cr 2 spaces .vocab
  1295. \ loop
  1296. \ cr [char] * emit space get-current .vocab ;
  1297. code over :: over ( x1 x2 -- x1 x2 x1 )
  1298. xld.w %r4, [%r1 + BYTES_PER_CELL]
  1299. sub %r1, BYTES_PER_CELL
  1300. ld.w [%r1], %r4
  1301. NEXT
  1302. end-code
  1303. : pad :: pad ( -- c-addr )
  1304. here 80 + ;
  1305. \ page :: page ( -- )
  1306. : parse :: parse ( char "ccc<char>" -- c-addr u )
  1307. >r
  1308. >in @ ( start )
  1309. begin
  1310. source ( start c-addr length )
  1311. >in @ ( start c-addr length index )
  1312. > while ( start c-addr )
  1313. >in @ + c@ ( start char )
  1314. r@ = if ( start )
  1315. >in @ over - ( start index-start )
  1316. swap source drop + ( count start+c-addr )
  1317. swap r> drop ( c-addr u )
  1318. 1 >in +! \ skip terminator char
  1319. exit
  1320. then
  1321. 1 >in +!
  1322. repeat
  1323. r> drop ( start c-addr )
  1324. over + ( start c-addr+start )
  1325. swap >in @ swap - ( c-addr u )
  1326. ;
  1327. : parse-word :: parse-word ( <spaces>name -- c-addr u )
  1328. begin
  1329. source ( c-addr length )
  1330. >in @ ( c-addr length index )
  1331. > while ( c-addr )
  1332. >in @ + c@ ( char )
  1333. bl = if ( )
  1334. 1 >in +!
  1335. else
  1336. bl parse exit
  1337. then
  1338. repeat
  1339. 0 ( c-addr 0 )
  1340. ;
  1341. : pick :: pick ( xu ... x1 x0 u -- xu ... x1 x0 xu )
  1342. 1+ cells sp@ + @ ;
  1343. : postpone :: postpone ( "<spaces>name" -- )
  1344. ' dup >flags @
  1345. flag-immediate and if
  1346. compile,
  1347. else
  1348. postpone literal
  1349. postpone compile,
  1350. then ; immediate compile-only
  1351. : previous :: previous ( -- )
  1352. get-order ?dup if swap drop 1- set-order then ;
  1353. : quit :: quit ( -- ) ( R: i*x -- )
  1354. rp0 @ rp!
  1355. begin postpone [
  1356. begin
  1357. refill if
  1358. ['] quit-evaluate catch ?dup
  1359. else
  1360. false
  1361. then
  1362. until ( a)
  1363. ?dup
  1364. if
  1365. cr ." error " . cr
  1366. cr source type cr
  1367. >in @ 1-
  1368. begin
  1369. dup source drop over + \ u u c-addr+u
  1370. c@ bl = and \ u flag
  1371. while
  1372. 1-
  1373. repeat
  1374. dup
  1375. begin
  1376. dup source drop over + \ u0 u u c-addr+u
  1377. c@ bl <> and \ u0 u flag
  1378. while
  1379. 1-
  1380. repeat
  1381. source drop over + c@ bl = if 1+ then
  1382. dup spaces - 1+
  1383. 0 ?do [char] ^ emit loop
  1384. then
  1385. quit-reset
  1386. again ;
  1387. : quit-evaluate :: quit-evaluate ( i*x -- j*x )
  1388. begin
  1389. parse-word ?dup if
  1390. 2dup search-wordlists
  1391. case
  1392. 0 of \ number
  1393. 2>r 0 0 2r>
  1394. >number if
  1395. -13 throw \ undefined-word
  1396. then
  1397. 2drop
  1398. state @ if
  1399. postpone literal
  1400. then
  1401. endof
  1402. 1 of \ immediate
  1403. >r 2drop r>
  1404. state @ 0= if
  1405. dup >flags @ flag-compile-only and if
  1406. -14 throw \ interpreting compile-only word
  1407. then
  1408. then
  1409. execute
  1410. endof
  1411. -1 of \ normal
  1412. >r 2drop r>
  1413. state @ if
  1414. compile,
  1415. else
  1416. execute
  1417. then
  1418. endof
  1419. endcase
  1420. else
  1421. drop exit
  1422. then
  1423. ?stack
  1424. again
  1425. ;
  1426. : quit-reset :: quit-reset ( i*x -- )
  1427. sp0 @ sp!
  1428. false state !
  1429. filesystem-close-all
  1430. fileid-stack stack-clear
  1431. 0 source-id !
  1432. key-flush
  1433. ctp-flush
  1434. button-flush
  1435. only forth definitions
  1436. ;
  1437. code r/o :: r-o ( -- fam )
  1438. xcall FileSystem_ReadOnly
  1439. sub %r1, BYTES_PER_CELL
  1440. ld.w [%r1], %r4
  1441. NEXT
  1442. end-code
  1443. code r/w :: r-w ( -- fam )
  1444. xcall FileSystem_ReadWrite
  1445. sub %r1, BYTES_PER_CELL
  1446. ld.w [%r1], %r4
  1447. NEXT
  1448. end-code
  1449. code r> :: r-from ( -- x ) ( R: x -- )
  1450. ld.w %r4, [%sp]
  1451. add %sp, 1
  1452. sub %r1, BYTES_PER_CELL
  1453. ld.w [%r1], %r4
  1454. NEXT
  1455. end-code
  1456. code r@ :: r-fetch ( -- x ) ( R: x -- x )
  1457. ld.w %r4, [%sp]
  1458. xsub %r1, BYTES_PER_CELL
  1459. ld.w [%r1], %r4
  1460. NEXT
  1461. end-code
  1462. code read-file :: read-file ( c-addr u1 fileid -- u2 ior )
  1463. ld.w %r6, [%r1]+ ; fileid
  1464. ld.w %r8, [%r1] ; count
  1465. xld.w %r7, [%r1 + BYTES_PER_CELL] ; buffer
  1466. xcall FileSystem_read
  1467. ld.w [%r1], %r5 ; ior
  1468. xld.w [%r1 + BYTES_PER_CELL], %r4 ; count2
  1469. NEXT
  1470. end-code
  1471. : read-line :: read-line ( c-addr u1 fileid -- u2 flag ior )
  1472. \ eof: 0 t 0
  1473. >r >r dup r> r> swap \ b0 b fileid u
  1474. 0 ?do \ b0 b fileid
  1475. begin
  1476. 2dup 1 swap read-file \ b0 b fileid 0/1 ior
  1477. ?dup if \ b0 b fileid 0/1 ior
  1478. >r 2drop \ b0 b
  1479. swap - \ u2
  1480. false r> \ u2 false ior
  1481. unloop exit
  1482. then
  1483. \ b0 b fileid 0/1
  1484. 0= if
  1485. drop swap - dup 0 \ u2 flag 0
  1486. unloop exit \ u2 f 0
  1487. then
  1488. \ b0 b fileid
  1489. over c@ [ctrl] m xor \ b0 b fileid f
  1490. until
  1491. \ here have a non cr character
  1492. over c@ [ctrl] j = if
  1493. drop swap - true 0
  1494. unloop exit
  1495. then
  1496. >r 1+ r> \ b0 b+1 fileid
  1497. loop
  1498. \ filled buffer without cr/lf \ b0 b' fileid
  1499. drop swap - true 0 \ u2 t 0
  1500. ;
  1501. \ recurse :: recurse ( -- )
  1502. : refill :: refill ( -- flag )
  1503. 0 >in !
  1504. source-id @ if
  1505. terminal-buffer source-id @ read-line ( u flag ior )
  1506. ?dup if
  1507. cr ." read error = " . cr \ b u2
  1508. 2drop
  1509. source-id @ close-file drop
  1510. abort" file error"
  1511. then
  1512. if
  1513. terminal-count !
  1514. true
  1515. \ cr source type \ ***DEBUG***
  1516. else
  1517. drop
  1518. source-id @ close-file drop
  1519. fileid-stack stack-pop source-id !
  1520. false
  1521. then
  1522. else \ console
  1523. ." Ok " cr
  1524. terminal-buffer accept terminal-count ! drop true
  1525. then
  1526. ;
  1527. code rename-file :: rename-file ( c-addr1 u1 c-addr2 u2 -- ior )
  1528. ld.w %r9, [%r1]+ ; count2
  1529. ld.w %r8, [%r1]+ ; name2
  1530. ld.w %r7, [%r1]+ ; count1
  1531. ld.w %r6, [%r1] ; name1
  1532. xcall FileSystem_rename
  1533. ld.w [%r1], %r5 ; ior
  1534. NEXT
  1535. end-code
  1536. : repeat :: repeat ( C: orig dest -- ) ( -- )
  1537. align
  1538. postpone again here swap ! ; immediate compile-only
  1539. code reposition-file :: reposition-file ( ud fileid -- ior )
  1540. ld.w %r6, [%r1]+ ; fileid
  1541. ld.w %r7, [%r1] ; pos
  1542. xcall FileSystem_lseek
  1543. ld.w [%r1], %r5 ; ior
  1544. NEXT
  1545. end-code
  1546. \ resize :: resize ( a-addr1 u -- a-addr2 ior )
  1547. \ resize-file :: resize-file ( ud fileid -- ior )
  1548. \ restore-input :: restore-input ( xn ... x1 n -- flag )
  1549. \ roll :: roll ( xu xu-1 ... x0 u -- xu-1 ... x0 xu )
  1550. variable root-wordlist :: root-wordlist ( -- wid )
  1551. : rot :: rote ( x1 x2 x3 -- x2 x3 x1 )
  1552. >r swap r> swap ;
  1553. code rp! :: r-p-store ( addr -- )
  1554. ld.w %r4, [%r1]+
  1555. ld.w %sp, %r4
  1556. NEXT
  1557. end-code
  1558. compile-only
  1559. variable rp0 :: r-p-zero ( -- addr )
  1560. code rp@ :: r-p-fetch ( -- addr )
  1561. ld.w %r4, %sp
  1562. sub %r1, BYTES_PER_CELL
  1563. ld.w [%r1], %r4
  1564. NEXT
  1565. end-code
  1566. code rshift :: r-shift ( x1 u -- x2 )
  1567. ld.w %r4, [%r1]+ ; shift
  1568. ld.w %r5, [%r1] ; value
  1569. srl %r5, %r4
  1570. ld.w [%r1], %r5
  1571. NEXT
  1572. end-code
  1573. : s" :: s-quote ( C: "ccc<quote>" -- ) ( -- c-addr u )
  1574. align
  1575. postpone (s")
  1576. [char] " parse ( c-addr u)
  1577. dup , \ save length
  1578. 2dup here ( c-addr u c-addr u c-addr2 )
  1579. swap cmove ( c-addr u -- )
  1580. allot drop
  1581. ; immediate compile-only
  1582. : s' :: s-apostrophe ( C: "ccc<quote>" -- ) ( -- c-addr u )
  1583. align
  1584. postpone (s")
  1585. [char] ' parse ( c-addr u)
  1586. dup , \ save length
  1587. 2dup here ( c-addr u c-addr u c-addr2 )
  1588. swap cmove ( c-addr u -- )
  1589. allot drop
  1590. ; immediate compile-only
  1591. : s>d :: s-to-d ( n -- d )
  1592. dup 0< if -1 else 0 then ;
  1593. \ save-buffers :: save-buffers ( -- )
  1594. \ save-input :: save-input ( -- xn ... x1 n )
  1595. \ scr :: s-c-r ( -- a-addr )
  1596. code search :: search ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 flag )
  1597. ld.w %r4, [%r1]+ ; u2
  1598. ld.w %r5, [%r1]+ ; c-addr2
  1599. ld.w %r6, [%r1] ; u1
  1600. xld.w %r7, [%r1 + BYTES_PER_CELL] ; c-addr1
  1601. search_loop:
  1602. cmp %r4, %r6 ; u2 > u1
  1603. jrugt search_not_found ; ...yes
  1604. ld.w %r8, %r4 ; count
  1605. ld.w %r9, %r7 ; string
  1606. ld.w %r10, %r5 ; match
  1607. search_compare:
  1608. ld.ub %r13, [%r9]+ ; get byte of string
  1609. ld.ub %r14, [%r10]+ ; get byte of match
  1610. cmp %r13, %r14
  1611. jrne search_next_position ; loop back if no match
  1612. sub %r8, 1
  1613. jrne search_compare ; loop to comare bytes
  1614. search_found:
  1615. ld.w [%r1], %r6 ; u1
  1616. xld.w [%r1 + BYTES_PER_CELL], %r7 ; c-addr1
  1617. sub %r1, BYTES_PER_CELL
  1618. ld.w %r4, TRUE
  1619. ld.w [%r1], %r4
  1620. NEXT
  1621. search_next_position:
  1622. add %r7, 1 ; next address
  1623. sub %r6, 1 ; decrement length
  1624. jp search_loop ; back for next compare
  1625. search_not_found:
  1626. sub %r1, BYTES_PER_CELL
  1627. ld.w %r4, FALSE
  1628. ld.w [%r1], %r4
  1629. NEXT ; c-addr1 u1 false
  1630. end-code
  1631. code search-wordlist :: search-wordlist ( c-addr u wid -- 0 | xt 1 | xt -1 )
  1632. ld.w %r4, [%r1]+ ; wid
  1633. ld.w %r5, [%r1] ; u = name length
  1634. xld.w %r6, [%r1 + BYTES_PER_CELL] ; c-addr = name to find
  1635. xld.w %r12, DICTIONARY_LINK_OFFSET_BYTES
  1636. add %r4, %r12 ; NAME>LINK
  1637. sw2_next:
  1638. sub %r4, %r12 ; NAME>LINK
  1639. ld.w %r4, [%r4] ; address of name
  1640. or %r4, %r4 ; or zero if end of list
  1641. jreq sw2_not_found
  1642. ;; comparison of counted strings is inlined for speed
  1643. ld.w %r7, %r4 ; address of name in dictionary
  1644. ld.w %r8, [%r7]+ ; dictionary name length
  1645. cmp %r5, %r8 ; counts must be equal
  1646. jrne sw2_next ; ...no
  1647. ld.w %r9, %r6 ; c-addr = name to find
  1648. sw2_cmp_loop:
  1649. ld.ub %r10,[%r9]+ ; get 1 byte from string 1
  1650. ld.ub %r11,[%r7]+ ; get 1 byte from string 2
  1651. cmp %r10, %r11 ; check if equal
  1652. jrne sw2_next ; ..not equal => false result
  1653. sub %r8, 1 ; decrement counter
  1654. jrne sw2_cmp_loop ; go back for more bytes
  1655. sw2_found:
  1656. ld.w %r9, %r4 ; NAME>FLAGS
  1657. xld.w %r10, DICTIONARY_FLAGS_OFFSET_BYTES
  1658. sub %r9, %r10
  1659. ld.w %r9, [%r9]
  1660. and %r9, FLAG_IMMEDIATE
  1661. jrne.d sw2_is_immediate
  1662. ld.w %r10, 1 ; immediate == 1
  1663. ld.w %r10, -1 ; nomal == -1
  1664. sw2_is_immediate:
  1665. ld.w [%r1], %r10 ; 1 (immediate) | -1 (normal)
  1666. xld.w %r9, DICTIONARY_CODE_OFFSET_BYTES
  1667. sub %r4, %r9 ; NAME>CODE
  1668. xld.w [%r1 + BYTES_PER_CELL], %r4 ; ca
  1669. NEXT
  1670. sw2_not_found:
  1671. ld.w %r4, [%r1]+ ; drop u
  1672. ld.w %r4, FALSE
  1673. ld.w [%r1], %r4 ; FALSE
  1674. NEXT
  1675. end-code
  1676. : search-wordlists :: search-wordlists ( c-addr u -- 0 | xt 1 | xt -1 )
  1677. #order @ 0 ?do
  1678. 2dup ( c-addr u c-addr u )
  1679. i cells context + @ ( c-addr u c-addr u wid)
  1680. search-wordlist ( c-addr u; 0 | xt 1 | xt -1 )
  1681. ?dup if ( c-addr u; w 1 | w -1 )
  1682. 2swap 2drop unloop exit ( w 1 | w -1 )
  1683. then ( c-addr u )
  1684. loop ( c-addr u )
  1685. 2drop 0
  1686. ;
  1687. : see :: see ( "<spaces>name" -- )
  1688. base @
  1689. '
  1690. dup @ ['] (does>) @ = if
  1691. dup >does @ \ xt does
  1692. else
  1693. dup @ ['] (colon) @ = if
  1694. dup >body @ \ xt body
  1695. else
  1696. drop
  1697. ." not a colon definition"
  1698. base ! exit
  1699. then
  1700. then
  1701. swap >flags @ ." flags = $" hex . cr
  1702. aligned
  1703. begin
  1704. dup [char] $ emit hex 1 u.r [char] : emit space
  1705. dup @ ?dup
  1706. while
  1707. dup >name count type
  1708. dup ['] (lit) = ( xt flag )
  1709. over ['] branch = or ( xt flag )
  1710. over ['] ?branch = or ( xt flag )
  1711. over ['] (do) = or ( xt flag )
  1712. over ['] (?do) = or ( xt flag )
  1713. over ['] (loop) = or ( xt flag )
  1714. over ['] (+loop) = or ( xt flag )
  1715. if
  1716. drop cell+
  1717. dup @ dup decimal space u.
  1718. [char] / emit space
  1719. [char] $ emit
  1720. hex 1 u.r \ number
  1721. else
  1722. ['] (s") = if
  1723. space
  1724. cell+ dup count type
  1725. count + aligned cell-
  1726. then
  1727. then
  1728. cr cell+
  1729. repeat drop base ! ;
  1730. : set-current :: set-current ( wid -- )
  1731. current ! ;
  1732. cross-root-definition
  1733. : set-order :: set-order ( widn ... wid1 n -- )
  1734. dup -1 = if
  1735. drop
  1736. root-wordlist dup 2
  1737. then
  1738. \ **********************VALIDATE context size*************************
  1739. dup #order !
  1740. 0 ?do i cells context + ! loop
  1741. ;
  1742. : sign :: sign ( n -- )
  1743. 0< if [char] - hold then ;
  1744. \ sliteral :: sliteral ( C: c-addr1 u -- ) ( -- c-addr1 u )
  1745. \ sm/rem :: s-m-slash-rem ( d1 n1 -- n2 n3 )
  1746. : source :: source ( -- c-addr u )
  1747. terminal-buffer drop terminal-count @ ;
  1748. variable source-id :: source-i-d ( -- 0 | -1 | fileid )
  1749. code sp! :: s-p-store ( a-addr -- )
  1750. ld.w %r1, [%r1]
  1751. NEXT
  1752. end-code
  1753. variable sp0 :: s-p-zero ( -- a-addr )
  1754. code sp@ :: s-p-fetch ( -- a-addr )
  1755. ld.w %r4, %r1
  1756. sub %r1, BYTES_PER_CELL
  1757. ld.w [%r1], %r4
  1758. NEXT
  1759. end-code
  1760. : space :: space ( -- )
  1761. bl emit ;
  1762. : spaces :: spaces ( n -- )
  1763. dup 0> if
  1764. 0 ?do space loop
  1765. else
  1766. drop
  1767. then ;
  1768. \ usage example:
  1769. \ 25 ( stack-size-in-cells )
  1770. \ dup create my-stack , 0 , cells allot
  1771. \ stack = {size(N), ptr, value1, value2, ..., valueN}
  1772. : stack-clear :: stack-clear ( stack-addr -- )
  1773. cell+ 0 swap ! ;
  1774. : stack-pop :: stack-pop ( stack-addr -- w )
  1775. cell+ >r r@ @ 1- dup 0< abort" stack underflow"
  1776. dup r@ ! 1+ cells r> + @
  1777. ;
  1778. : stack-push :: stack-push ( w stack-addr -- )
  1779. dup \ w a a
  1780. @ \ w a size
  1781. swap cell+ \ w size ptr
  1782. >r r@ @ 1+ \ w size index
  1783. swap over \ w index size index
  1784. < abort" stack overflow"
  1785. \ w index
  1786. dup r@ ! \ w index
  1787. cells r> + !
  1788. ;
  1789. variable state :: state ( -- a-addr )
  1790. code swap :: swap ( x1 x2 -- x2 x1 )
  1791. ld.w %r4, [%r1]+
  1792. ld.w %r5, [%r1]+
  1793. sub %r1, BYTES_PER_CELL
  1794. ld.w [%r1], %r4
  1795. sub %r1, BYTES_PER_CELL
  1796. ld.w [%r1], %r5
  1797. NEXT
  1798. end-code
  1799. code terminal-buffer :: terminal-buffer ( -- c-addr buffer-length )
  1800. xld.w %r4, terminal_buffer_start
  1801. sub %r1, BYTES_PER_CELL
  1802. ld.w [%r1], %r4
  1803. xld.w %r4, terminal_buffer_length
  1804. sub %r1, BYTES_PER_CELL
  1805. ld.w [%r1], %r4
  1806. NEXT
  1807. end-code
  1808. variable terminal-count :: terminal-count ( -- a-addr )
  1809. : then :: then ( C: orig -- ) ( -- )
  1810. align
  1811. here swap ! ; immediate compile-only
  1812. : throw :: throw ( k*x n -- k*x | i*x n )
  1813. handler @ rp! r> handler ! r> swap >r sp! drop r> ;
  1814. \ thru :: thru ( i*x u1 u2 -- j*x )
  1815. \ time&date :: time-and-date ( -- +n1 +n2 +n3 +n4 +n5 +n6 )
  1816. \ to :: to ( I: x "<spaces>name" -- ) ( C: "<spaces>name" -- ) ( x -- )
  1817. -1
  1818. constant true :: true ( -- true )
  1819. : tuck :: tuck ( x1 x2 -- x2 x1 x2 )
  1820. swap over ;
  1821. : type :: type ( c-addr u -- )
  1822. 0 ?do dup c@ emit char+ loop drop ;
  1823. : u. :: u-dot ( u -- )
  1824. 0 <# #s #> type space ;
  1825. : u.r :: u-dot-r ( u n -- )
  1826. >r 0 <# #s #> r> over - spaces type ;
  1827. code u< :: u-less-than ( u1 u2 -- flag )
  1828. ld.w %r5, [%r1]+ ; u2
  1829. ld.w %r4, [%r1] ; u1
  1830. cmp %r4, %r5 ; u1 < u2 ?
  1831. jrult set_true_flag_u ; ...yes
  1832. jp set_false_flag_u ; ...no
  1833. end-code
  1834. code u> :: u-greater-than ( u1 u2 -- flag )
  1835. ld.w %r5, [%r1]+ ; u2
  1836. ld.w %r4, [%r1] ; u1
  1837. cmp %r4, %r5 ; u1 > u2 ?
  1838. jrugt set_true_flag_u ; ...yes
  1839. set_false_flag_u:
  1840. ld.w %r4, FALSE
  1841. ld.w [%r1], %r4
  1842. NEXT
  1843. set_true_flag_u:
  1844. ld.w %r4, TRUE
  1845. ld.w [%r1], %r4
  1846. NEXT
  1847. end-code
  1848. code um* :: u-m-star ( u1 u2 -- ud )
  1849. ld.w %r4, [%r1]+
  1850. ld.w %r5, [%r1]
  1851. mltu.w %r4, %r5
  1852. ld.w %r4, %alr
  1853. ld.w [%r1], %r4
  1854. sub %r1, BYTES_PER_CELL
  1855. ld.w %r4, %ahr
  1856. ld.w [%r1], %r4
  1857. NEXT
  1858. end-code
  1859. code um+ :: u-m-plus ( u1 u2 -- ud )
  1860. ld.w %r4, [%r1]+
  1861. ld.w %r5, [%r1]
  1862. add %r4, %r5
  1863. ld.w [%r1], %r4
  1864. ld.w %r4, 0
  1865. adc %r4, %r4
  1866. sub %r1, BYTES_PER_CELL
  1867. ld.w [%r1], %r4
  1868. NEXT
  1869. end-code
  1870. : um/mod :: u-m-slash-mod ( ud u1 -- u2 u3 )
  1871. 2dup u<
  1872. if negate 32 0
  1873. ?do
  1874. >r
  1875. dup um+ >r >r dup um+ r> + dup r>
  1876. r@ swap >r um+ r> or
  1877. if >r drop 1+ r> else drop then
  1878. r>
  1879. loop drop swap exit
  1880. then drop 2drop -1 dup ;
  1881. code unloop :: unloop ( -- ) ( R: loop-sys -- )
  1882. add %sp, 2 ; drop 2 stack words
  1883. NEXT
  1884. end-code
  1885. : until :: until ( C: dest -- ) ( x -- )
  1886. postpone ?branch compile, ; immediate compile-only
  1887. \ unused :: unused ( -- u )
  1888. \ update :: update ( -- )
  1889. \ value :: value ( x "<spaces>name" -- ) ( -- x )
  1890. : variable :: variable ( "<spaces>name" -- ) ( -- a-addr )
  1891. create 0 , ;
  1892. \ vocabulary :: vocabulary ( name -- )
  1893. \ wordlist create , do-vocabulary ;
  1894. code w/o :: w-o ( -- fam )
  1895. xcall FileSystem_WriteOnly
  1896. sub %r1, BYTES_PER_CELL
  1897. ld.w [%r1], %r4
  1898. NEXT
  1899. end-code
  1900. : while :: while ( C: dest -- orig dest ) ( x -- )
  1901. postpone if swap ; immediate compile-only
  1902. : within :: within ( n1|u1 n2|u2 n3|u3 -- flag )
  1903. over - >r - r> u< ;
  1904. \ deprecated - do not create
  1905. \ word :: word ( char "<chars>ccc<char>" -- c-addr )
  1906. : wordlist :: wordlist ( -- wid )
  1907. align here \ addr
  1908. 0 , \ space for 1 pointer initially null
  1909. ;
  1910. cross-root-definition
  1911. : words :: words ( -- )
  1912. cr context @
  1913. begin @ ?dup
  1914. while dup space count type >code >link enough?
  1915. until drop then ;
  1916. code write-file :: write-file ( c-addr u fileid -- ior )
  1917. ld.w %r6, [%r1]+ ; fileid
  1918. ld.w %r8, [%r1]+ ; count
  1919. xld.w %r7, [%r1] ; buffer
  1920. xcall FileSystem_write
  1921. ld.w [%r1], %r5 ; ior
  1922. NEXT
  1923. end-code
  1924. create write-line-eol :: write-line-eol ( - c-addr )
  1925. 13 c, 10 c, \ EOL sequence: cr lf
  1926. 2
  1927. constant write-line-eol-size :: write-line-eol-size ( -- u )
  1928. : write-line :: write-line ( c-addr u fileid -- ior )
  1929. >r r@ \ save fileid
  1930. write-file \ output the data
  1931. ?dup if
  1932. r> drop
  1933. else
  1934. write-line-eol write-line-eol-size r> write-file
  1935. then
  1936. ;
  1937. code xor :: x-or ( x1 x2 -- x3 )
  1938. ld.w %r4, [%r1]+
  1939. ld.w %r5, [%r1]
  1940. xor %r4, %r5
  1941. ld.w [%r1], %r4
  1942. NEXT
  1943. end-code
  1944. : [ :: left-bracket ( -- )
  1945. false state ! ; immediate
  1946. : ['] :: bracket-tick ( C: "<spaces>name" -- ) ( -- xt )
  1947. ' postpone literal ; immediate compile-only
  1948. : [char] :: bracket-char ( C: "<spaces>name" -- ) ( -- char )
  1949. char postpone literal ; immediate compile-only
  1950. : [compile] :: bracket-compile ( C: "<spaces>name" -- )
  1951. -30 throw ;
  1952. : [ctrl] :: bracket-ctrl ( C: "<spaces>name" -- ) ( -- char )
  1953. ctrl postpone literal ; immediate compile-only
  1954. \ [else] :: bracket-else ( "<spaces>name" ... -- )
  1955. \ [if] :: bracket-if ( flag | flag "<spaces>name" ... -- )
  1956. \ [then] :: bracket-then ( -- )
  1957. : \ :: backslash ( "ccc<eol>"-- )
  1958. refill drop ; immediate
  1959. : ] :: right-bracket ( -- )
  1960. true state ! ;
  1961. \ end of ANSI forth + some extra items to make it work
  1962. \ ====================================================
  1963. \ Directory access functions
  1964. \ ==========================
  1965. code create-directory :: create-directory ( b u -- ior )
  1966. ld.w %r7, [%r1]+ ; count
  1967. xld.w %r6, [%r1] ; buffer
  1968. xcall FileSystem_CreateDirectory
  1969. ld.w [%r1], %r5 ; ior
  1970. NEXT
  1971. end-code
  1972. code open-directory :: open-directory ( b u -- dirid ior )
  1973. ld.w %r7, [%r1] ; count
  1974. xld.w %r6, [%r1 + 4] ; buffer
  1975. xcall FileSystem_OpenDirectory
  1976. ld.w [%r1], %r5 ; ior
  1977. xld.w [%r1 + 4], %r4 ; count2
  1978. NEXT
  1979. end-code
  1980. code close-directory :: close-directory ( dirid -- ior )
  1981. ld.w %r6, [%r1] ; dirid
  1982. xcall FileSystem_CloseDirectory
  1983. ld.w [%r1], %r5 ; ior
  1984. NEXT
  1985. end-code
  1986. code read-directory :: read-directory ( b u dirid -- u2 ior )
  1987. ld.w %r6, [%r1]+ ; dirid
  1988. ld.w %r8, [%r1] ; count
  1989. xld.w %r7, [%r1 + 4] ; buffer
  1990. xcall FileSystem_ReadDirectory
  1991. ld.w [%r1], %r5 ; ior
  1992. xld.w [%r1 + 4], %r4 ; count2
  1993. NEXT
  1994. end-code
  1995. \ Access to absolute sectors on disk
  1996. \ ==================================
  1997. \ buffer size = count * 512 bytes
  1998. code read-sectors :: read-sectors ( b count sector -- ior )
  1999. ld.w %r6, [%r1]+ ; sector
  2000. ld.w %r8, [%r1]+ ; count
  2001. xld.w %r7, [%r1] ; buffer
  2002. xcall FileSystem_AbsoluteRead
  2003. ld.w [%r1], %r5 ; ior
  2004. NEXT
  2005. end-code
  2006. \ buffer size = count * 512 bytes
  2007. code write-sectors :: write-sectors ( b count sector -- ior )
  2008. ld.w %r6, [%r1]+ ; sector
  2009. ld.w %r8, [%r1]+ ; count
  2010. xld.w %r7, [%r1] ; buffer
  2011. xcall FileSystem_AbsoluteWrite
  2012. ld.w [%r1], %r5 ; ior
  2013. NEXT
  2014. end-code
  2015. \ convenience
  2016. \ ===========
  2017. : dec. :: dec-dot ( n -- )
  2018. base @ decimal swap . base ! ;
  2019. : hex. :: hex-dot ( n -- )
  2020. base @ hex swap u. base ! ;
  2021. code delay-us :: delay-u-s ( microseconds -- )
  2022. ld.w %r6, [%r1]+ ; microseconds
  2023. xcall delay_us
  2024. NEXT
  2025. end-code
  2026. \ peripheral port access
  2027. \ ======================
  2028. \ fetch a peripheral register value
  2029. : p@ :: p-fetch ( reg-addr -- value )
  2030. 2@ \ address size
  2031. case
  2032. 32 of @ endof
  2033. 16 of h@ endof
  2034. 8 of c@ endof
  2035. endcase
  2036. ;
  2037. \ display peripheral register
  2038. : p? :: p-question ( reg-addr -- )
  2039. p@ . ;
  2040. \ store a value to a peripheral register
  2041. : p! :: p-store ( value reg-addr -- )
  2042. 2@ \ address size
  2043. case
  2044. 32 of ! endof
  2045. 16 of h! endof
  2046. 8 of c! endof
  2047. endcase
  2048. ;
  2049. \ font
  2050. \ ===
  2051. hex
  2052. create font-8x13 :: font-8x13 ( -- c-addr )
  2053. ( 0000 ) 00 c, 00 c, AA c, 00 c, 82 c, 00 c, 82 c, 00 c, 82 c, 00 c, AA c, 00 c, 00 c,
  2054. ( 0001 ) 00 c, 00 c, 00 c, 10 c, 38 c, 7C c, FE c, 7C c, 38 c, 10 c, 00 c, 00 c, 00 c,
  2055. ( 0002 ) AA c, 55 c, AA c, 55 c, AA c, 55 c, AA c, 55 c, AA c, 55 c, AA c, 55 c, AA c,
  2056. ( 0003 ) 00 c, 00 c, A0 c, A0 c, E0 c, A0 c, AE c, 04 c, 04 c, 04 c, 04 c, 00 c, 00 c,
  2057. ( 0004 ) 00 c, 00 c, E0 c, 80 c, C0 c, 80 c, 8E c, 08 c, 0C c, 08 c, 08 c, 00 c, 00 c,
  2058. ( 0005 ) 00 c, 00 c, 60 c, 80 c, 80 c, 80 c, 6C c, 0A c, 0C c, 0A c, 0A c, 00 c, 00 c,
  2059. ( 0006 ) 00 c, 00 c, 80 c, 80 c, 80 c, 80 c, EE c, 08 c, 0C c, 08 c, 08 c, 00 c, 00 c,
  2060. ( 0007 ) 00 c, 00 c, 18 c, 24 c, 24 c, 18 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2061. ( 0008 ) 00 c, 00 c, 00 c, 10 c, 10 c, 7C c, 10 c, 10 c, 00 c, 7C c, 00 c, 00 c, 00 c,
  2062. ( 0009 ) 00 c, 00 c, C0 c, A0 c, A0 c, A0 c, A8 c, 08 c, 08 c, 08 c, 0E c, 00 c, 00 c,
  2063. ( 000A ) 00 c, 00 c, 88 c, 88 c, 50 c, 50 c, 2E c, 04 c, 04 c, 04 c, 04 c, 00 c, 00 c,
  2064. ( 000B ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, F0 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2065. ( 000C ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, F0 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2066. ( 000D ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 1F c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2067. ( 000E ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 1F c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2068. ( 000F ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, FF c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2069. ( 0010 ) FF c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2070. ( 0011 ) 00 c, 00 c, 00 c, FF c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2071. ( 0012 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, FF c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2072. ( 0013 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, FF c, 00 c, 00 c, 00 c,
  2073. ( 0014 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, FF c,
  2074. ( 0015 ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 1F c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2075. ( 0016 ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, F0 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2076. ( 0017 ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, FF c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2077. ( 0018 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, FF c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2078. ( 0019 ) 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c,
  2079. ( 001A ) 00 c, 00 c, 00 c, 00 c, 0E c, 30 c, C0 c, 30 c, 0E c, 00 c, FE c, 00 c, 00 c,
  2080. ( 001B ) 00 c, 00 c, 00 c, 00 c, E0 c, 18 c, 06 c, 18 c, E0 c, 00 c, FE c, 00 c, 00 c,
  2081. ( 001C ) 00 c, 00 c, 00 c, 00 c, 00 c, FE c, 44 c, 44 c, 44 c, 44 c, 44 c, 00 c, 00 c,
  2082. ( 001D ) 00 c, 00 c, 00 c, 04 c, 04 c, 7E c, 08 c, 10 c, 7E c, 20 c, 20 c, 00 c, 00 c,
  2083. ( 001E ) 00 c, 00 c, 1C c, 22 c, 20 c, 70 c, 20 c, 20 c, 20 c, 62 c, DC c, 00 c, 00 c,
  2084. ( 001F ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 18 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2085. ( 0020 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2086. ( 0021 ) 00 c, 00 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 00 c, 10 c, 00 c, 00 c,
  2087. ( 0022 ) 00 c, 00 c, 24 c, 24 c, 24 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2088. ( 0023 ) 00 c, 00 c, 00 c, 24 c, 24 c, 7E c, 24 c, 7E c, 24 c, 24 c, 00 c, 00 c, 00 c,
  2089. ( 0024 ) 00 c, 00 c, 10 c, 3C c, 50 c, 50 c, 38 c, 14 c, 14 c, 78 c, 10 c, 00 c, 00 c,
  2090. ( 0025 ) 00 c, 00 c, 22 c, 52 c, 24 c, 08 c, 08 c, 10 c, 24 c, 2A c, 44 c, 00 c, 00 c,
  2091. ( 0026 ) 00 c, 00 c, 00 c, 00 c, 30 c, 48 c, 48 c, 30 c, 4A c, 44 c, 3A c, 00 c, 00 c,
  2092. ( 0027 ) 00 c, 00 c, 10 c, 10 c, 10 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2093. ( 0028 ) 00 c, 00 c, 04 c, 08 c, 08 c, 10 c, 10 c, 10 c, 08 c, 08 c, 04 c, 00 c, 00 c,
  2094. ( 0029 ) 00 c, 00 c, 20 c, 10 c, 10 c, 08 c, 08 c, 08 c, 10 c, 10 c, 20 c, 00 c, 00 c,
  2095. ( 002A ) 00 c, 00 c, 24 c, 18 c, 7E c, 18 c, 24 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2096. ( 002B ) 00 c, 00 c, 00 c, 00 c, 10 c, 10 c, 7C c, 10 c, 10 c, 00 c, 00 c, 00 c, 00 c,
  2097. ( 002C ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 38 c, 30 c, 40 c, 00 c,
  2098. ( 002D ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 7C c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2099. ( 002E ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 10 c, 38 c, 10 c, 00 c,
  2100. ( 002F ) 00 c, 00 c, 02 c, 02 c, 04 c, 08 c, 10 c, 20 c, 40 c, 80 c, 80 c, 00 c, 00 c,
  2101. ( 0030 ) 00 c, 00 c, 18 c, 24 c, 42 c, 42 c, 42 c, 42 c, 42 c, 24 c, 18 c, 00 c, 00 c,
  2102. ( 0031 ) 00 c, 00 c, 10 c, 30 c, 50 c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2103. ( 0032 ) 00 c, 00 c, 3C c, 42 c, 42 c, 02 c, 04 c, 18 c, 20 c, 40 c, 7E c, 00 c, 00 c,
  2104. ( 0033 ) 00 c, 00 c, 7E c, 02 c, 04 c, 08 c, 1C c, 02 c, 02 c, 42 c, 3C c, 00 c, 00 c,
  2105. ( 0034 ) 00 c, 00 c, 04 c, 0C c, 14 c, 24 c, 44 c, 44 c, 7E c, 04 c, 04 c, 00 c, 00 c,
  2106. ( 0035 ) 00 c, 00 c, 7E c, 40 c, 40 c, 5C c, 62 c, 02 c, 02 c, 42 c, 3C c, 00 c, 00 c,
  2107. ( 0036 ) 00 c, 00 c, 1C c, 20 c, 40 c, 40 c, 5C c, 62 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2108. ( 0037 ) 00 c, 00 c, 7E c, 02 c, 04 c, 08 c, 08 c, 10 c, 10 c, 20 c, 20 c, 00 c, 00 c,
  2109. ( 0038 ) 00 c, 00 c, 3C c, 42 c, 42 c, 42 c, 3C c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2110. ( 0039 ) 00 c, 00 c, 3C c, 42 c, 42 c, 46 c, 3A c, 02 c, 02 c, 04 c, 38 c, 00 c, 00 c,
  2111. ( 003A ) 00 c, 00 c, 00 c, 00 c, 10 c, 38 c, 10 c, 00 c, 00 c, 10 c, 38 c, 10 c, 00 c,
  2112. ( 003B ) 00 c, 00 c, 00 c, 00 c, 10 c, 38 c, 10 c, 00 c, 00 c, 38 c, 30 c, 40 c, 00 c,
  2113. ( 003C ) 00 c, 00 c, 02 c, 04 c, 08 c, 10 c, 20 c, 10 c, 08 c, 04 c, 02 c, 00 c, 00 c,
  2114. ( 003D ) 00 c, 00 c, 00 c, 00 c, 00 c, 7E c, 00 c, 00 c, 7E c, 00 c, 00 c, 00 c, 00 c,
  2115. ( 003E ) 00 c, 00 c, 40 c, 20 c, 10 c, 08 c, 04 c, 08 c, 10 c, 20 c, 40 c, 00 c, 00 c,
  2116. ( 003F ) 00 c, 00 c, 3C c, 42 c, 42 c, 02 c, 04 c, 08 c, 08 c, 00 c, 08 c, 00 c, 00 c,
  2117. ( 0040 ) 00 c, 00 c, 3C c, 42 c, 42 c, 4E c, 52 c, 56 c, 4A c, 40 c, 3C c, 00 c, 00 c,
  2118. ( 0041 ) 00 c, 00 c, 18 c, 24 c, 42 c, 42 c, 42 c, 7E c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2119. ( 0042 ) 00 c, 00 c, 78 c, 44 c, 42 c, 44 c, 78 c, 44 c, 42 c, 44 c, 78 c, 00 c, 00 c,
  2120. ( 0043 ) 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 40 c, 40 c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2121. ( 0044 ) 00 c, 00 c, 78 c, 44 c, 42 c, 42 c, 42 c, 42 c, 42 c, 44 c, 78 c, 00 c, 00 c,
  2122. ( 0045 ) 00 c, 00 c, 7E c, 40 c, 40 c, 40 c, 78 c, 40 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2123. ( 0046 ) 00 c, 00 c, 7E c, 40 c, 40 c, 40 c, 78 c, 40 c, 40 c, 40 c, 40 c, 00 c, 00 c,
  2124. ( 0047 ) 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 40 c, 4E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2125. ( 0048 ) 00 c, 00 c, 42 c, 42 c, 42 c, 42 c, 7E c, 42 c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2126. ( 0049 ) 00 c, 00 c, 7C c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2127. ( 004A ) 00 c, 00 c, 1F c, 04 c, 04 c, 04 c, 04 c, 04 c, 04 c, 44 c, 38 c, 00 c, 00 c,
  2128. ( 004B ) 00 c, 00 c, 42 c, 44 c, 48 c, 50 c, 60 c, 50 c, 48 c, 44 c, 42 c, 00 c, 00 c,
  2129. ( 004C ) 00 c, 00 c, 40 c, 40 c, 40 c, 40 c, 40 c, 40 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2130. ( 004D ) 00 c, 00 c, 82 c, 82 c, C6 c, AA c, 92 c, 92 c, 82 c, 82 c, 82 c, 00 c, 00 c,
  2131. ( 004E ) 00 c, 00 c, 42 c, 42 c, 62 c, 52 c, 4A c, 46 c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2132. ( 004F ) 00 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2133. ( 0050 ) 00 c, 00 c, 7C c, 42 c, 42 c, 42 c, 7C c, 40 c, 40 c, 40 c, 40 c, 00 c, 00 c,
  2134. ( 0051 ) 00 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 42 c, 52 c, 4A c, 3C c, 02 c, 00 c,
  2135. ( 0052 ) 00 c, 00 c, 7C c, 42 c, 42 c, 42 c, 7C c, 50 c, 48 c, 44 c, 42 c, 00 c, 00 c,
  2136. ( 0053 ) 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 3C c, 02 c, 02 c, 42 c, 3C c, 00 c, 00 c,
  2137. ( 0054 ) 00 c, 00 c, FE c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2138. ( 0055 ) 00 c, 00 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2139. ( 0056 ) 00 c, 00 c, 82 c, 82 c, 44 c, 44 c, 44 c, 28 c, 28 c, 28 c, 10 c, 00 c, 00 c,
  2140. ( 0057 ) 00 c, 00 c, 82 c, 82 c, 82 c, 82 c, 92 c, 92 c, 92 c, AA c, 44 c, 00 c, 00 c,
  2141. ( 0058 ) 00 c, 00 c, 82 c, 82 c, 44 c, 28 c, 10 c, 28 c, 44 c, 82 c, 82 c, 00 c, 00 c,
  2142. ( 0059 ) 00 c, 00 c, 82 c, 82 c, 44 c, 28 c, 10 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2143. ( 005A ) 00 c, 00 c, 7E c, 02 c, 04 c, 08 c, 10 c, 20 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2144. ( 005B ) 00 c, 00 c, 3C c, 20 c, 20 c, 20 c, 20 c, 20 c, 20 c, 20 c, 3C c, 00 c, 00 c,
  2145. ( 005C ) 00 c, 00 c, 80 c, 80 c, 40 c, 20 c, 10 c, 08 c, 04 c, 02 c, 02 c, 00 c, 00 c,
  2146. ( 005D ) 00 c, 00 c, 78 c, 08 c, 08 c, 08 c, 08 c, 08 c, 08 c, 08 c, 78 c, 00 c, 00 c,
  2147. ( 005E ) 00 c, 00 c, 10 c, 28 c, 44 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2148. ( 005F ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, FE c, 00 c,
  2149. ( 0060 ) 00 c, 10 c, 08 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2150. ( 0061 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2151. ( 0062 ) 00 c, 00 c, 40 c, 40 c, 40 c, 5C c, 62 c, 42 c, 42 c, 62 c, 5C c, 00 c, 00 c,
  2152. ( 0063 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2153. ( 0064 ) 00 c, 00 c, 02 c, 02 c, 02 c, 3A c, 46 c, 42 c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2154. ( 0065 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 42 c, 7E c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2155. ( 0066 ) 00 c, 00 c, 1C c, 22 c, 20 c, 20 c, 7C c, 20 c, 20 c, 20 c, 20 c, 00 c, 00 c,
  2156. ( 0067 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3A c, 44 c, 44 c, 38 c, 40 c, 3C c, 42 c, 3C c,
  2157. ( 0068 ) 00 c, 00 c, 40 c, 40 c, 40 c, 5C c, 62 c, 42 c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2158. ( 0069 ) 00 c, 00 c, 00 c, 10 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2159. ( 006A ) 00 c, 00 c, 00 c, 04 c, 00 c, 0C c, 04 c, 04 c, 04 c, 04 c, 44 c, 44 c, 38 c,
  2160. ( 006B ) 00 c, 00 c, 40 c, 40 c, 40 c, 44 c, 48 c, 70 c, 48 c, 44 c, 42 c, 00 c, 00 c,
  2161. ( 006C ) 00 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2162. ( 006D ) 00 c, 00 c, 00 c, 00 c, 00 c, EC c, 92 c, 92 c, 92 c, 92 c, 82 c, 00 c, 00 c,
  2163. ( 006E ) 00 c, 00 c, 00 c, 00 c, 00 c, 5C c, 62 c, 42 c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2164. ( 006F ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2165. ( 0070 ) 00 c, 00 c, 00 c, 00 c, 00 c, 5C c, 62 c, 42 c, 62 c, 5C c, 40 c, 40 c, 40 c,
  2166. ( 0071 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3A c, 46 c, 42 c, 46 c, 3A c, 02 c, 02 c, 02 c,
  2167. ( 0072 ) 00 c, 00 c, 00 c, 00 c, 00 c, 5C c, 22 c, 20 c, 20 c, 20 c, 20 c, 00 c, 00 c,
  2168. ( 0073 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 42 c, 30 c, 0C c, 42 c, 3C c, 00 c, 00 c,
  2169. ( 0074 ) 00 c, 00 c, 00 c, 20 c, 20 c, 7C c, 20 c, 20 c, 20 c, 22 c, 1C c, 00 c, 00 c,
  2170. ( 0075 ) 00 c, 00 c, 00 c, 00 c, 00 c, 44 c, 44 c, 44 c, 44 c, 44 c, 3A c, 00 c, 00 c,
  2171. ( 0076 ) 00 c, 00 c, 00 c, 00 c, 00 c, 44 c, 44 c, 44 c, 28 c, 28 c, 10 c, 00 c, 00 c,
  2172. ( 0077 ) 00 c, 00 c, 00 c, 00 c, 00 c, 82 c, 82 c, 92 c, 92 c, AA c, 44 c, 00 c, 00 c,
  2173. ( 0078 ) 00 c, 00 c, 00 c, 00 c, 00 c, 42 c, 24 c, 18 c, 18 c, 24 c, 42 c, 00 c, 00 c,
  2174. ( 0079 ) 00 c, 00 c, 00 c, 00 c, 00 c, 42 c, 42 c, 42 c, 46 c, 3A c, 02 c, 42 c, 3C c,
  2175. ( 007A ) 00 c, 00 c, 00 c, 00 c, 00 c, 7E c, 04 c, 08 c, 10 c, 20 c, 7E c, 00 c, 00 c,
  2176. ( 007B ) 00 c, 00 c, 0E c, 10 c, 10 c, 08 c, 30 c, 08 c, 10 c, 10 c, 0E c, 00 c, 00 c,
  2177. ( 007C ) 00 c, 00 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2178. ( 007D ) 00 c, 00 c, 70 c, 08 c, 08 c, 10 c, 0C c, 10 c, 08 c, 08 c, 70 c, 00 c, 00 c,
  2179. ( 007E ) 00 c, 00 c, 24 c, 54 c, 48 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2180. ( spare codes )
  2181. ( 007F ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2182. ( 0080 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2183. ( 0081 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2184. ( 0082 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2185. ( 0083 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2186. ( 0084 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2187. ( 0085 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2188. ( 0086 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2189. ( 0087 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2190. ( 0088 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2191. ( 0089 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2192. ( 008A ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2193. ( 008B ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2194. ( 008C ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2195. ( 008D ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2196. ( 008E ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2197. ( 008F ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2198. ( 0090 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2199. ( 0091 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2200. ( 0092 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2201. ( 0093 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2202. ( 0094 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2203. ( 0095 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2204. ( 0096 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2205. ( 0097 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2206. ( 0098 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2207. ( 0099 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2208. ( 009A ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2209. ( 009B ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2210. ( 009C ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2211. ( 009D ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2212. ( 009E ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2213. ( 009F ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2214. ( 00A0 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2215. ( 00A1 ) 00 c, 00 c, 10 c, 00 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2216. ( 00A2 ) 00 c, 00 c, 10 c, 38 c, 54 c, 50 c, 50 c, 54 c, 38 c, 10 c, 00 c, 00 c, 00 c,
  2217. ( 00A3 ) 00 c, 00 c, 1C c, 22 c, 20 c, 70 c, 20 c, 20 c, 20 c, 62 c, DC c, 00 c, 00 c,
  2218. ( 00A4 ) 00 c, 00 c, 00 c, 00 c, 42 c, 3C c, 24 c, 24 c, 3C c, 42 c, 00 c, 00 c, 00 c,
  2219. ( 00A5 ) 00 c, 00 c, 82 c, 82 c, 44 c, 28 c, 7C c, 10 c, 7C c, 10 c, 10 c, 00 c, 00 c,
  2220. ( 00A6 ) 00 c, 00 c, 10 c, 10 c, 10 c, 10 c, 00 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2221. ( 00A7 ) 00 c, 18 c, 24 c, 20 c, 18 c, 24 c, 24 c, 18 c, 04 c, 24 c, 18 c, 00 c, 00 c,
  2222. ( 00A8 ) 00 c, 24 c, 24 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2223. ( 00A9 ) 00 c, 38 c, 44 c, 92 c, AA c, A2 c, AA c, 92 c, 44 c, 38 c, 00 c, 00 c, 00 c,
  2224. ( 00AA ) 00 c, 00 c, 38 c, 04 c, 3C c, 44 c, 3C c, 00 c, 7C c, 00 c, 00 c, 00 c, 00 c,
  2225. ( 00AB ) 00 c, 00 c, 00 c, 12 c, 24 c, 48 c, 90 c, 48 c, 24 c, 12 c, 00 c, 00 c, 00 c,
  2226. ( 00AC ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 7E c, 02 c, 02 c, 02 c, 00 c, 00 c, 00 c,
  2227. ( 00AD ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2228. ( 00AE ) 00 c, 38 c, 44 c, 92 c, AA c, AA c, B2 c, AA c, 44 c, 38 c, 00 c, 00 c, 00 c,
  2229. ( 00AF ) 00 c, 00 c, 7E c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2230. ( 00B0 ) 00 c, 00 c, 18 c, 24 c, 24 c, 18 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2231. ( 00B1 ) 00 c, 00 c, 00 c, 10 c, 10 c, 7C c, 10 c, 10 c, 00 c, 7C c, 00 c, 00 c, 00 c,
  2232. ( 00B2 ) 00 c, 30 c, 48 c, 08 c, 30 c, 40 c, 78 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2233. ( 00B3 ) 00 c, 30 c, 48 c, 10 c, 08 c, 48 c, 30 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2234. ( 00B4 ) 00 c, 08 c, 10 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2235. ( 00B5 ) 00 c, 00 c, 00 c, 00 c, 00 c, 42 c, 42 c, 42 c, 42 c, 66 c, 5A c, 40 c, 00 c,
  2236. ( 00B6 ) 00 c, 00 c, 3E c, 74 c, 74 c, 74 c, 34 c, 14 c, 14 c, 14 c, 14 c, 00 c, 00 c,
  2237. ( 00B7 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 18 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2238. ( 00B8 ) 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 08 c, 18 c,
  2239. ( 00B9 ) 00 c, 20 c, 60 c, 20 c, 20 c, 20 c, 70 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2240. ( 00BA ) 00 c, 00 c, 30 c, 48 c, 48 c, 30 c, 00 c, 78 c, 00 c, 00 c, 00 c, 00 c, 00 c,
  2241. ( 00BB ) 00 c, 00 c, 00 c, 90 c, 48 c, 24 c, 12 c, 24 c, 48 c, 90 c, 00 c, 00 c, 00 c,
  2242. ( 00BC ) 00 c, 40 c, C0 c, 40 c, 40 c, 42 c, E6 c, 0A c, 12 c, 1A c, 06 c, 00 c, 00 c,
  2243. ( 00BD ) 00 c, 40 c, C0 c, 40 c, 40 c, 4C c, F2 c, 02 c, 0C c, 10 c, 1E c, 00 c, 00 c,
  2244. ( 00BE ) 00 c, 60 c, 90 c, 20 c, 10 c, 92 c, 66 c, 0A c, 12 c, 1A c, 06 c, 00 c, 00 c,
  2245. ( 00BF ) 00 c, 00 c, 10 c, 00 c, 10 c, 10 c, 20 c, 40 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2246. ( 00C0 ) 00 c, 10 c, 08 c, 00 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2247. ( 00C1 ) 00 c, 08 c, 10 c, 00 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2248. ( 00C2 ) 00 c, 18 c, 24 c, 00 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2249. ( 00C3 ) 00 c, 32 c, 4C c, 00 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2250. ( 00C4 ) 00 c, 24 c, 24 c, 00 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2251. ( 00C5 ) 00 c, 18 c, 24 c, 18 c, 18 c, 24 c, 42 c, 42 c, 7E c, 42 c, 42 c, 00 c, 00 c,
  2252. ( 00C6 ) 00 c, 00 c, 6E c, 90 c, 90 c, 90 c, 9C c, F0 c, 90 c, 90 c, 9E c, 00 c, 00 c,
  2253. ( 00C7 ) 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 40 c, 40 c, 40 c, 42 c, 3C c, 08 c, 10 c,
  2254. ( 00C8 ) 00 c, 10 c, 08 c, 00 c, 7E c, 40 c, 40 c, 78 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2255. ( 00C9 ) 00 c, 08 c, 10 c, 00 c, 7E c, 40 c, 40 c, 78 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2256. ( 00CA ) 00 c, 18 c, 24 c, 00 c, 7E c, 40 c, 40 c, 78 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2257. ( 00CB ) 00 c, 24 c, 24 c, 00 c, 7E c, 40 c, 40 c, 78 c, 40 c, 40 c, 7E c, 00 c, 00 c,
  2258. ( 00CC ) 00 c, 20 c, 10 c, 00 c, 7C c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2259. ( 00CD ) 00 c, 08 c, 10 c, 00 c, 7C c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2260. ( 00CE ) 00 c, 18 c, 24 c, 00 c, 7C c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2261. ( 00CF ) 00 c, 44 c, 44 c, 00 c, 7C c, 10 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2262. ( 00D0 ) 00 c, 00 c, 78 c, 44 c, 42 c, 42 c, E2 c, 42 c, 42 c, 44 c, 78 c, 00 c, 00 c,
  2263. ( 00D1 ) 00 c, 64 c, 98 c, 00 c, 82 c, C2 c, A2 c, 92 c, 8A c, 86 c, 82 c, 00 c, 00 c,
  2264. ( 00D2 ) 00 c, 20 c, 10 c, 00 c, 7C c, 82 c, 82 c, 82 c, 82 c, 82 c, 7C c, 00 c, 00 c,
  2265. ( 00D3 ) 00 c, 08 c, 10 c, 00 c, 7C c, 82 c, 82 c, 82 c, 82 c, 82 c, 7C c, 00 c, 00 c,
  2266. ( 00D4 ) 00 c, 18 c, 24 c, 00 c, 7C c, 82 c, 82 c, 82 c, 82 c, 82 c, 7C c, 00 c, 00 c,
  2267. ( 00D5 ) 00 c, 64 c, 98 c, 00 c, 7C c, 82 c, 82 c, 82 c, 82 c, 82 c, 7C c, 00 c, 00 c,
  2268. ( 00D6 ) 00 c, 44 c, 44 c, 00 c, 7C c, 82 c, 82 c, 82 c, 82 c, 82 c, 7C c, 00 c, 00 c,
  2269. ( 00D7 ) 00 c, 00 c, 00 c, 00 c, 42 c, 24 c, 18 c, 18 c, 24 c, 42 c, 00 c, 00 c, 00 c,
  2270. ( 00D8 ) 00 c, 02 c, 3C c, 46 c, 4A c, 4A c, 52 c, 52 c, 52 c, 62 c, 3C c, 40 c, 00 c,
  2271. ( 00D9 ) 00 c, 20 c, 10 c, 00 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2272. ( 00DA ) 00 c, 08 c, 10 c, 00 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2273. ( 00DB ) 00 c, 18 c, 24 c, 00 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2274. ( 00DC ) 00 c, 24 c, 24 c, 00 c, 42 c, 42 c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2275. ( 00DD ) 00 c, 08 c, 10 c, 00 c, 44 c, 44 c, 28 c, 10 c, 10 c, 10 c, 10 c, 00 c, 00 c,
  2276. ( 00DE ) 00 c, 00 c, 40 c, 7C c, 42 c, 42 c, 42 c, 7C c, 40 c, 40 c, 40 c, 00 c, 00 c,
  2277. ( 00DF ) 00 c, 00 c, 38 c, 44 c, 44 c, 48 c, 50 c, 4C c, 42 c, 42 c, 5C c, 00 c, 00 c,
  2278. ( 00E0 ) 00 c, 00 c, 10 c, 08 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2279. ( 00E1 ) 00 c, 00 c, 04 c, 08 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2280. ( 00E2 ) 00 c, 00 c, 18 c, 24 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2281. ( 00E3 ) 00 c, 00 c, 32 c, 4C c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2282. ( 00E4 ) 00 c, 00 c, 24 c, 24 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2283. ( 00E5 ) 00 c, 18 c, 24 c, 18 c, 00 c, 3C c, 02 c, 3E c, 42 c, 46 c, 3A c, 00 c, 00 c,
  2284. ( 00E6 ) 00 c, 00 c, 00 c, 00 c, 00 c, 6C c, 12 c, 7C c, 90 c, 92 c, 6C c, 00 c, 00 c,
  2285. ( 00E7 ) 00 c, 00 c, 00 c, 00 c, 00 c, 3C c, 42 c, 40 c, 40 c, 42 c, 3C c, 08 c, 10 c,
  2286. ( 00E8 ) 00 c, 00 c, 10 c, 08 c, 00 c, 3C c, 42 c, 7E c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2287. ( 00E9 ) 00 c, 00 c, 08 c, 10 c, 00 c, 3C c, 42 c, 7E c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2288. ( 00EA ) 00 c, 00 c, 18 c, 24 c, 00 c, 3C c, 42 c, 7E c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2289. ( 00EB ) 00 c, 00 c, 24 c, 24 c, 00 c, 3C c, 42 c, 7E c, 40 c, 42 c, 3C c, 00 c, 00 c,
  2290. ( 00EC ) 00 c, 00 c, 20 c, 10 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2291. ( 00ED ) 00 c, 00 c, 10 c, 20 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2292. ( 00EE ) 00 c, 00 c, 30 c, 48 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2293. ( 00EF ) 00 c, 00 c, 48 c, 48 c, 00 c, 30 c, 10 c, 10 c, 10 c, 10 c, 7C c, 00 c, 00 c,
  2294. ( 00F0 ) 00 c, 24 c, 18 c, 28 c, 04 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2295. ( 00F1 ) 00 c, 00 c, 32 c, 4C c, 00 c, 5C c, 62 c, 42 c, 42 c, 42 c, 42 c, 00 c, 00 c,
  2296. ( 00F2 ) 00 c, 00 c, 20 c, 10 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2297. ( 00F3 ) 00 c, 00 c, 08 c, 10 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2298. ( 00F4 ) 00 c, 00 c, 18 c, 24 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2299. ( 00F5 ) 00 c, 00 c, 32 c, 4C c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2300. ( 00F6 ) 00 c, 00 c, 24 c, 24 c, 00 c, 3C c, 42 c, 42 c, 42 c, 42 c, 3C c, 00 c, 00 c,
  2301. ( 00F7 ) 00 c, 00 c, 00 c, 10 c, 10 c, 00 c, 7C c, 00 c, 10 c, 10 c, 00 c, 00 c, 00 c,
  2302. ( 00F8 ) 00 c, 00 c, 00 c, 00 c, 02 c, 3C c, 46 c, 4A c, 52 c, 62 c, 3C c, 40 c, 00 c,
  2303. ( 00F9 ) 00 c, 00 c, 20 c, 10 c, 00 c, 44 c, 44 c, 44 c, 44 c, 44 c, 3A c, 00 c, 00 c,
  2304. ( 00FA ) 00 c, 00 c, 08 c, 10 c, 00 c, 44 c, 44 c, 44 c, 44 c, 44 c, 3A c, 00 c, 00 c,
  2305. ( 00FB ) 00 c, 00 c, 18 c, 24 c, 00 c, 44 c, 44 c, 44 c, 44 c, 44 c, 3A c, 00 c, 00 c,
  2306. ( 00FC ) 00 c, 00 c, 28 c, 28 c, 00 c, 44 c, 44 c, 44 c, 44 c, 44 c, 3A c, 00 c, 00 c,
  2307. ( 00FD ) 00 c, 00 c, 08 c, 10 c, 00 c, 42 c, 42 c, 42 c, 46 c, 3A c, 02 c, 42 c, 3C c,
  2308. ( 00FE ) 00 c, 00 c, 00 c, 40 c, 40 c, 5C c, 62 c, 42 c, 42 c, 62 c, 5C c, 40 c, 40 c,
  2309. ( 00FF ) 00 c, 00 c, 24 c, 24 c, 00 c, 42 c, 42 c, 42 c, 46 c, 3A c, 02 c, 42 c, 3C c,
  2310. decimal
  2311. 8
  2312. constant font-width :: font-width ( -- u )
  2313. 13
  2314. constant font-height :: font-height ( -- u )
  2315. \ LCD driver
  2316. \ ==========
  2317. 240
  2318. constant lcd-width-pixels :: lcd-width-pixels ( -- u )
  2319. 208
  2320. constant lcd-height-pixels :: lcd-height-pixels ( -- u )
  2321. hex 80000 decimal
  2322. constant lcd-vram :: lcd-vram ( -- u )
  2323. lcd-width-pixels 31 + 32 / 32 *
  2324. constant lcd-vram-width-pixels :: lcd-vram-width-pixels ( -- u )
  2325. lcd-height-pixels
  2326. constant lcd-vram-height-pixels :: lcd-vram-height-pixels ( -- u )
  2327. lcd-vram-width-pixels 8 /
  2328. constant lcd-vram-width-bytes :: lcd-vram-width-bytes ( -- u )
  2329. lcd-width-pixels 8 /
  2330. constant lcd-width-bytes :: lcd-width-bytes ( -- u )
  2331. lcd-vram-width-bytes lcd-vram-height-pixels *
  2332. constant lcd-vram-size :: lcd-vram-size ( -- u )
  2333. : lcd-clear-all :: lcd-clear-all ( -- )
  2334. lcd-vram lcd-vram-size 0 fill
  2335. ;
  2336. : lcd-set-all :: lcd-set-all ( -- )
  2337. lcd-vram lcd-vram-size 255 fill
  2338. ;
  2339. \ pixel code in assembler for speed
  2340. code lcd-set-pixel :: lcd-set-pixel ( x y -- )
  2341. ld.w %r6, [%r1]+ ; y
  2342. ld.w %r7, [%r1]+ ; x
  2343. ld.w %r4, %r7
  2344. xand %r4, 7 ; bit number
  2345. xld.w %r5, 0x80
  2346. srl %r5, %r4 ; r5 = bit mask
  2347. sll %r6, 5 ; y * 32 (= vram width)
  2348. srl %r7, 3 ; x /8 (= x offset)
  2349. add %r6, %r7 ; r6 = byte offset
  2350. xld.w %r4, R32_LCDC_MADD ; address of lcd memory
  2351. xld.w %r4, [%r4]
  2352. add %r4, %r6 ; r4 = byte address to be modified
  2353. ld.ub %r6, [%r4] ; or in the bit
  2354. or %r6, %r5
  2355. ld.b [%r4], %r6
  2356. NEXT
  2357. end-code
  2358. code lcd-clear-pixel :: lcd-clear-pixel ( x y -- )
  2359. ld.w %r6, [%r1]+ ; y
  2360. ld.w %r7, [%r1]+ ; x
  2361. ld.w %r4, %r7
  2362. xand %r4, 7 ; bit number
  2363. xld.w %r5, 0x80
  2364. srl %r5, %r4 ; r5 = bit mask
  2365. xor %r5, -1 ; complement
  2366. sll %r6, 5 ; y * 32 (= vram width)
  2367. srl %r7, 3 ; x /8 (= x offset)
  2368. add %r6, %r7 ; r6 = byte offset
  2369. xld.w %r4, R32_LCDC_MADD ; address of lcd memory
  2370. xld.w %r4, [%r4]
  2371. add %r4, %r6 ; r4 = byte address to be modified
  2372. ld.ub %r6, [%r4] ; and out the bit
  2373. and %r6, %r5
  2374. ld.b [%r4], %r6
  2375. NEXT
  2376. end-code
  2377. \ draw a small '+' centred at (x, y)
  2378. : lcd-set-point :: lcd-set-point ( x y -- )
  2379. 2dup lcd-set-pixel
  2380. 2dup 1+ lcd-set-pixel
  2381. 2dup 1- lcd-set-pixel
  2382. 2dup 2 + lcd-set-pixel
  2383. 2dup 2 - lcd-set-pixel
  2384. 2dup swap 1+ swap lcd-set-pixel
  2385. 2dup swap 1- swap lcd-set-pixel
  2386. 2dup swap 2 + swap lcd-set-pixel
  2387. 2dup swap 2 - swap lcd-set-pixel
  2388. 2drop ;
  2389. variable lcd-x1 :: lcd-x1 ( -- a-addr )
  2390. variable lcd-y1 :: lcd-y1 ( -- a-addr )
  2391. variable lcd-dx :: lcd-dx ( -- a-addr )
  2392. variable lcd-dy :: lcd-dy ( -- a-addr )
  2393. variable lcd-stepx :: lcd-stepx ( -- a-addr )
  2394. variable lcd-stepy :: lcd-stepy ( -- a-addr )
  2395. variable lcd-line-colour :: lcd-line-colour ( -- a-addr )
  2396. : lcd-black :: lcd-black ( -- )
  2397. true lcd-line-colour !
  2398. ;
  2399. : lcd-white :: lcd-white ( -- )
  2400. false lcd-line-colour !
  2401. ;
  2402. \ draw a line in lcd-line-colour
  2403. : lcd-line :: lcd-line ( x0 y0 x1 y1 -- )
  2404. \ Bresenham Algorithm
  2405. dup lcd-y1 ! ( x0 y0 x1 y1 )
  2406. 2 pick - ( x0 y0 x1 y1-y0 )
  2407. dup 0< if negate -1 else 1 then ( x0 y0 x1 dy stepy )
  2408. lcd-stepy ! 2* lcd-dy ! ( x0 y0 x1 )
  2409. dup lcd-x1 ! ( x0 y0 x1 )
  2410. 2 pick - ( x0 y0 x1-x0 )
  2411. dup 0< if negate -1 else 1 then ( x0 y0 dx stepx )
  2412. lcd-stepx ! 2* lcd-dx ! ( x0 y0 )
  2413. 2dup ( x0 y0 )
  2414. lcd-line-colour @ if
  2415. lcd-set-pixel
  2416. else
  2417. lcd-clear-pixel
  2418. then
  2419. lcd-dx @ lcd-dy @ 2dup > if ( x0 y0 dx dy )
  2420. swap 2/ - >r ( x0 y0 ) ( R: fraction = dy - [dx >> 1] )
  2421. begin
  2422. over lcd-x1 @ <> \ x0 <> x1
  2423. while
  2424. r@ 0< 0= if \ fraction >= 0
  2425. lcd-stepy @ + ( x0 y0+stepy )
  2426. r> lcd-dx @ - >r \ fraction -= dx
  2427. then
  2428. swap lcd-stepx @ + swap ( x0+stepx y0 )
  2429. r> lcd-dy @ + >r \ fraction += dy
  2430. 2dup ( x0 y0 )
  2431. lcd-line-colour @ if
  2432. lcd-set-pixel
  2433. else
  2434. lcd-clear-pixel
  2435. then
  2436. repeat
  2437. else ( x0 y0 dx dy )
  2438. 2/ - >r ( x0 y0 ) ( R: fraction = dx - [dy >> 1] )
  2439. swap ( y0 x0 )
  2440. begin
  2441. over lcd-y1 @ <> \ y0 <> y1
  2442. while
  2443. r@ 0< 0= if \ fraction >= 0
  2444. lcd-stepx @ + ( y0 x0+stepx )
  2445. r> lcd-dy @ - >r \ fraction -= dy
  2446. then
  2447. swap lcd-stepy @ + swap ( y0+stepy x0+stepx )
  2448. r> lcd-dx @ + >r \ fraction += dx
  2449. 2dup swap ( y0 x0 )
  2450. lcd-line-colour @ if
  2451. lcd-set-pixel
  2452. else
  2453. lcd-clear-pixel
  2454. then
  2455. repeat
  2456. then
  2457. 2drop r> drop ; ( -- )
  2458. variable lcd-x :: lcd-x ( -- a-addr )
  2459. variable lcd-y :: lcd-y ( -- a-addr )
  2460. : lcd-line-to :: lcd-line-to ( x y -- )
  2461. 2dup lcd-x @ lcd-y @ lcd-line lcd-move-to ;
  2462. : lcd-move-to :: lcd-move-to ( x y -- )
  2463. lcd-y ! lcd-x ! ;
  2464. : lcd-line-rel :: lcd-line-rel ( dx dy -- )
  2465. lcd-y @ + swap lcd-x @ + swap
  2466. 2dup lcd-x @ lcd-y @ lcd-line lcd-move-to ;
  2467. : lcd-move-rel :: lcd-move-rel ( dx dy -- )
  2468. lcd-y +! lcd-x +! ;
  2469. \ from current x-y
  2470. : lcd-box :: lcd-box ( w h -- )
  2471. 1- swap 1- swap
  2472. over lcd-x @ + lcd-y @ lcd-line-to
  2473. lcd-x @ over lcd-y @ + lcd-line-to
  2474. lcd-x @ rot - lcd-y @ lcd-line-to
  2475. lcd-x @ lcd-y @ rot - lcd-line-to
  2476. ;
  2477. \ LCD TEXT functions
  2478. \ ==================
  2479. \ move cursor to first line, first character
  2480. : lcd-home :: lcd-home ( -- )
  2481. 0 0 lcd-move-to ;
  2482. \ character based positioning
  2483. lcd-width-pixels font-width /
  2484. constant lcd-text-columns :: lcd-text-columns ( -- u)
  2485. lcd-height-pixels font-height /
  2486. constant lcd-text-rows :: lcd-text-rows ( -- u)
  2487. \ in character coordinated (0, 0) .. (lcd-last-columns - 1, lcd-text-rows - 1)
  2488. : lcd-at-xy :: lcd-at-xy ( x y -- )
  2489. font-height * swap
  2490. font-width * swap
  2491. lcd-move-to ;
  2492. : lcd-cls :: lcd-cls ( -- )
  2493. lcd-clear-all lcd-black lcd-home ;
  2494. : lcd-scroll :: lcd-scroll ( -- )
  2495. font-height lcd-vram-width-bytes * dup dup \ u u u
  2496. lcd-vram + swap \ u c-addr u
  2497. lcd-vram-size swap - \ u c-addr n
  2498. lcd-vram swap cmove \ u
  2499. lcd-vram lcd-vram-size + 1- \ u c-addr
  2500. over - swap 0 fill
  2501. ;
  2502. : lcd-scroll> :: lcd-scroll-up ( -- )
  2503. font-height lcd-vram-width-bytes * dup dup \ u u u
  2504. lcd-vram + swap \ u c-addr u
  2505. lcd-vram-size swap - \ u c-addr n
  2506. lcd-vram -rot \ u c-addr2 c-addr n
  2507. cmove> \ u
  2508. lcd-vram swap 0 fill
  2509. ;
  2510. : lcd-cr :: lcd-cr ( -- )
  2511. 0 lcd-x !
  2512. lcd-y @ font-height + dup lcd-height-pixels 1- > if
  2513. drop
  2514. lcd-scroll
  2515. else
  2516. lcd-y !
  2517. then
  2518. ;
  2519. : lcd-emit :: lcd-emit ( c -- )
  2520. lcd-x @ lcd-width-pixels 1- > if
  2521. lcd-cr
  2522. then
  2523. lcd-y @ lcd-vram-width-bytes * lcd-vram +
  2524. lcd-x @ 3 rshift + ( c c-addr )
  2525. swap ( c-addr c )
  2526. font-height * font-8x13 + ( lcd-addr font-addr )
  2527. font-height 0 ?do
  2528. 2dup c@
  2529. lcd-line-colour @ 0= if invert then
  2530. swap c!
  2531. char+ swap lcd-vram-width-bytes + swap
  2532. loop 2drop
  2533. font-width lcd-x +!
  2534. ;
  2535. : lcd-space :: lcd-space ( -- )
  2536. bl lcd-emit ;
  2537. : lcd-spaces :: lcd-spaces ( u -- )
  2538. dup 0> if
  2539. 0 ?do lcd-space loop
  2540. else
  2541. drop
  2542. then ;
  2543. : lcd-type :: lcd-type ( caddr u -- )
  2544. 0 ?do
  2545. dup c@ lcd-emit char+
  2546. loop drop ;
  2547. : lcd-." :: lcd-dot-quote ( "ccc<quote>" -- )
  2548. postpone s" postpone lcd-type ; immediate compile-only
  2549. \ LCD numeic output
  2550. \ =================
  2551. \ these are all separate functions as most test programs
  2552. \ will output results to the console (emit . u.) etc.
  2553. \ and will display on the lcd. Switching vectors around
  2554. \ will be slower.
  2555. : lcd-number :: lcd-number ( n -- )
  2556. s>d <# # # # # # # # # #> lcd-type ;
  2557. : lcd-d. :: lcd-d-dot ( d -- )
  2558. swap over dabs <# #s rot sign #> lcd-type lcd-space ;
  2559. : lcd-d.r :: lcd-d-dot-r ( d n -- )
  2560. >r swap over dabs <# #s rot sign #> r> over - lcd-spaces lcd-type ;
  2561. : lcd-.r :: lcd-dot-r ( n1 n2 -- )
  2562. >r s>d r> lcd-d.r ;
  2563. : lcd-u. :: lcd-u-dot ( u -- )
  2564. 0 <# #s #> lcd-type lcd-space ;
  2565. : lcd-u.r :: lcd-u-dot-r ( u n -- )
  2566. >r 0 <# #s #> r> over - lcd-spaces lcd-type ;
  2567. : lcd-. :: lcd-dot ( n -- )
  2568. s>d lcd-d. ;
  2569. : lcd-dec. :: lcd-dec-dot ( n -- )
  2570. base @ decimal swap lcd-. base ! ;
  2571. : lcd-hex. :: lcd-hex-dot ( n -- )
  2572. base @ hex swap lcd-u. base ! ;
  2573. \ CTP
  2574. \ ===
  2575. code ctp-flush :: c-t-p-flush ( -- )
  2576. xcall CTP_flush
  2577. NEXT
  2578. end-code
  2579. \ (-1, -1) => release
  2580. code ctp-pos :: c-t-p-pos ( -- x y )
  2581. xcall CTP_GetPosition
  2582. sub %r1, BYTES_PER_CELL
  2583. ld.w [%r1], %r4
  2584. sub %r1, BYTES_PER_CELL
  2585. ld.w [%r1], %r5
  2586. NEXT
  2587. end-code
  2588. \ as character co-ordinate: (0, 0) => top left
  2589. \ (-1, -1) => release
  2590. : ctp-char :: c-t-p-char ( -- x y )
  2591. ctp-pos dup 0< if exit then
  2592. swap font-width /
  2593. swap font-height /
  2594. ;
  2595. code ctp-pos? :: c-t-p-pos-question ( -- flag )
  2596. xcall CTP_PositionAvailable
  2597. or %r4, %r4
  2598. jreq ctp_pos_question_no_character
  2599. ld.w %r4, TRUE
  2600. ctp_pos_question_no_character:
  2601. sub %r1, BYTES_PER_CELL
  2602. ld.w [%r1], %r4
  2603. NEXT
  2604. end-code
  2605. \ Buttons
  2606. \ =======
  2607. 0
  2608. constant button-none :: button-none ( -- u )
  2609. 2
  2610. constant button-left :: button-left ( -- u )
  2611. 4
  2612. constant button-centre :: button-centre ( -- u )
  2613. 1
  2614. constant button-right :: button-right ( -- u )
  2615. 16
  2616. constant button-power :: button-power ( -- u )
  2617. code button-flush :: button-flush ( -- )
  2618. xcall Button_flush
  2619. NEXT
  2620. end-code
  2621. code button :: button ( -- u )
  2622. xcall Button_get
  2623. sub %r1, BYTES_PER_CELL
  2624. ld.w [%r1], %r4
  2625. NEXT
  2626. end-code
  2627. code button? :: button-question ( -- flag )
  2628. xcall Button_available
  2629. or %r4, %r4
  2630. jreq button_question_no_data
  2631. ld.w %r4, TRUE
  2632. button_question_no_data:
  2633. sub %r1, BYTES_PER_CELL
  2634. ld.w [%r1], %r4
  2635. NEXT
  2636. end-code
  2637. code button-poll :: button-poll ( -- u )
  2638. xcall Button_poll
  2639. sub %r1, BYTES_PER_CELL
  2640. ld.w [%r1], %r4
  2641. NEXT
  2642. end-code
  2643. \ Suspend and wait for event
  2644. \ ==========================
  2645. : wait-for-event :: wait-for-event ( -- )
  2646. \ (temperature-comp)
  2647. button?
  2648. key? or
  2649. ctp-pos? or
  2650. 0= if (halt) then
  2651. ;
  2652. code (halt) :: paren-halt ( -- )
  2653. MCLK = 48000000 ; master clock
  2654. SUSPEND_AUTO_POWER_OFF_SECONDS = 180
  2655. TIMEOUT_VALUE = (MCLK / 32 * SUSPEND_AUTO_POWER_OFF_SECONDS)
  2656. .if TIMEOUT_VALUE > 0x3fffffff
  2657. .error "SUSPEND_AUTO_POWER_OFF_SECONDS is too large"
  2658. .endif
  2659. ; xld.w %r6, 0 ; no timeout
  2660. xld.w %r6, TIMEOUT_VALUE ; have timeout
  2661. xcall suspend
  2662. NEXT
  2663. end-code
  2664. \ temperature compensation is not yet working
  2665. \ code (temperature-comp) :: temperature-comp ( -- )
  2666. \ xcall Temperature_control
  2667. \ NEXT
  2668. \ end-code
  2669. \ power off
  2670. \ =========
  2671. code power-off :: power-off ( -- )
  2672. xld.w %r4, R8_P3_IOC3
  2673. ld.b %r5, [%r4]
  2674. xoor %r5, 0x08 ; P03 as output
  2675. ld.b [%r4], %r5
  2676. xld.w %r4, R8_P3_P3D
  2677. ld.b %r5, [%r4]
  2678. xand %r5,~0x08 ; P03 = 0
  2679. ld.b [%r4], %r5
  2680. xld.w %r6, 1000
  2681. xcall delay_us
  2682. xld.w %r4, R8_P6_03_CFP
  2683. xld.w %r5, ~0xc0
  2684. ld.b [%r4], %r5 ; select P63 as GPIO
  2685. power_off_loop:
  2686. xld.w %r4, R8_P6_P6D
  2687. xld.w %r5, R8_P6_IOC6
  2688. xld.w %r6, 0x08
  2689. ld.b [%r5], %r6
  2690. ld.b [%r4], %r6
  2691. xld.w %r6, 1000
  2692. xcall delay_us
  2693. xld.w %r4, R8_P6_P6D
  2694. xld.w %r6, 0x00
  2695. ld.b [%r4], %r6
  2696. xld.w %r6, 1000
  2697. xcall delay_us
  2698. jp power_off_loop
  2699. NEXT
  2700. end-code
  2701. \ analog I/O
  2702. \ ==========
  2703. code analog-scan :: analog-scan ( -- )
  2704. xcall Analog_scan
  2705. NEXT
  2706. end-code
  2707. code battery-mv :: battery-mv ( -- u )
  2708. xcall Analog_BatteryMilliVolts
  2709. sub %r1, BYTES_PER_CELL
  2710. ld.w [%r1], %r4
  2711. NEXT
  2712. end-code
  2713. code temperature-c :: temperature-c ( -- u )
  2714. xcall Analog_TemperatureCelcius
  2715. sub %r1, BYTES_PER_CELL
  2716. ld.w [%r1], %r4
  2717. NEXT
  2718. end-code
  2719. code contrast-mv :: contrast-mv ( -- u )
  2720. xcall Analog_ContrastMilliVolts
  2721. sub %r1, BYTES_PER_CELL
  2722. ld.w [%r1], %r4
  2723. NEXT
  2724. end-code
  2725. code set-contrast-pwm :: set-contrast-pwm ( u -- )
  2726. ld.w %r6, [%r1]+
  2727. xcall Contrast_set
  2728. NEXT
  2729. end-code
  2730. code get-contrast-pwm :: get-contrast-pwm ( -- u )
  2731. xcall Contrast_get
  2732. sub %r1, BYTES_PER_CELL
  2733. ld.w [%r1], %r4
  2734. NEXT
  2735. end-code
  2736. 0
  2737. constant minimum-contrast-pwm :: minimum-contrast-pwm ( -- u)
  2738. 2048
  2739. constant nominal-contrast-pwm :: nominal-contrast-pwm ( -- u)
  2740. 4095
  2741. constant maximum-contrast-pwm :: maximum-contrast-pwm ( -- u)
  2742. \ Timer
  2743. \ =====
  2744. code timer-read :: timer-read ( -- u )
  2745. xcall Tick_get
  2746. sub %r1, BYTES_PER_CELL
  2747. ld.w [%r1], %r4
  2748. NEXT
  2749. end-code
  2750. \ FLASH
  2751. \ =====
  2752. 65536
  2753. constant flash-rom-size :: flash-rom-size ( -- u )
  2754. 256
  2755. constant flash-page-size :: flash-page-size ( -- u )
  2756. 4096
  2757. constant flash-sector-size :: flash-sector-size ( -- u )
  2758. $1fe0
  2759. constant flash-serial-number-offset :: flash-serial-number-offset ( -- u )
  2760. 32
  2761. constant flash-serial-number-length :: flash-serial-number-length ( -- u )
  2762. code flash-select-internal :: flash-select-internal ( -- )
  2763. xcall FLASH_SelectInternal
  2764. NEXT
  2765. end-code
  2766. code flash-select-external :: flash-select-external ( -- )
  2767. xcall FLASH_SelectExternal
  2768. NEXT
  2769. end-code
  2770. code flash-read :: flash-read ( b count flash-address -- f )
  2771. ld.w %r8, [%r1]+ ; flash-address
  2772. ld.w %r7, [%r1]+ ; count
  2773. ld.w %r6, [%r1] ; buffer
  2774. xcall FLASH_read
  2775. NEXT
  2776. ld.w [%r1], %r4 ; flag
  2777. end-code
  2778. code flash-verify :: flash-verify ( b count flash-address -- f )
  2779. ld.w %r8, [%r1]+ ; flash-address
  2780. ld.w %r7, [%r1]+ ; count
  2781. ld.w %r6, [%r1] ; buffer
  2782. xcall FLASH_verify
  2783. ld.w [%r1], %r4 ; flag
  2784. NEXT
  2785. end-code
  2786. \ call this before all operations below
  2787. \ it only acts for the next call and is cancelled by after any flash operation
  2788. code flash-write-enable :: flash-write-enable ( -- f )
  2789. xcall FLASH_WriteEnable
  2790. sub %r1, BYTES_PER_CELL
  2791. ld.w [%r1], %r4 ; flag
  2792. NEXT
  2793. end-code
  2794. code flash-write :: flash-write ( b count flash-address -- f )
  2795. ld.w %r8, [%r1]+ ; flash-address
  2796. ld.w %r7, [%r1]+ ; count
  2797. ld.w %r6, [%r1] ; buffer
  2798. xcall FLASH_write
  2799. ld.w [%r1], %r4 ; flag
  2800. NEXT
  2801. end-code
  2802. code flash-sector-erase :: flash-sector-erase ( flash-address -- )
  2803. ld.w %r6, [%r1] ; flash-address
  2804. xcall FLASH_SectorErase
  2805. ld.w [%r1], %r4 ; flag
  2806. NEXT
  2807. end-code
  2808. code flash-chip-erase :: flash-chip-erase ( -- flag)
  2809. xcall FLASH_ChipErase
  2810. sub %r1, BYTES_PER_CELL
  2811. ld.w [%r1], %r4 ; flag
  2812. NEXT
  2813. end-code
  2814. \ debugging
  2815. \ =========
  2816. code (brk) :: breakpoint ( -- )
  2817. xcall xdebug ;debug
  2818. xld.w %r6, bpt
  2819. xcall Debug_PutString
  2820. s1: jp s1 ;debug
  2821. bpt: .asciz "STOPPED\r\n"
  2822. .balign 4
  2823. NEXT ;debug
  2824. end-code
  2825. code (debug) :: debug ( -- )
  2826. xcall xdebug ;debug
  2827. NEXT ;debug
  2828. end-code