home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / wimpforth_2 / !WimpForth / fkernel < prev    next >
Encoding:
Text File  |  1996-03-21  |  55.1 KB  |  3,111 lines

  1. \ ANS Forth kernel for ARM 3 machines  Martin Läuter
  2.  
  3. decimal
  4. here: coldstart 0 , \ branch to cold, will be patched later
  5. here: memtotal  0 , \ total memory available
  6. here: retstack  0 , \ desired return stack size
  7. here: datstack  0 , \ desired data stack size
  8. here: filebuff  0 , \ desired file buffer size
  9. here: commline  0 , \ commandline address
  10.  
  11. here: thisfile
  12. 0 , ," FKERNEL" 
  13.  
  14. vocabulary forth
  15. \ Hash-value for " FORTH" is &10
  16.  
  17. forth definitions meta
  18.  
  19. label dovar
  20.   stmfd sp !, { tos }
  21.   bic tos, link, # &fc000003
  22.   next c; meta
  23.  
  24. label docon
  25.   stmfd sp !, { tos }
  26.   bic link, link, # &fc000003
  27.   ldr tos, [ link ]
  28.   next c;
  29.  
  30. assembler dovar meta constant dovar  
  31. assembler docon meta constant docon  
  32.  
  33. labcreate docol
  34.   stmfd rp !, { ip }
  35.   bic ip, link, # &fc000003
  36. next c;
  37.  
  38. labcreate dodoes
  39.   stmfd sp !, { tos }
  40.   mov tos, r0
  41.   stmfd rp !, { ip }
  42.   bic ip, link, # &fc000003
  43. next c;
  44.  
  45. labcreate dovalue
  46.   stmfd sp !, { tos }
  47.   bic link, link, # &fc000003
  48.   ldr tos, [ link ]
  49. next c;
  50.  
  51. labcreate dovalue!
  52.   bic link, link, # &fc000003
  53.   str tos, [ link, # -8 ]
  54.   ldmfd sp !, { tos }
  55. next c;
  56.  
  57. labcreate dovalue+!
  58.   bic link, link, # &fc000003
  59.   ldr r0, [ link, # -12 ]
  60.   add r0, tos, r0
  61.   str r0, [ link, # -12 ]
  62.   ldmfd sp !, { tos }
  63. next c;
  64.  
  65. labcreate do2value
  66.   stmfd sp !, { tos }
  67.   bic link, link, # &fc000003
  68.   ldr tos, [ link ]
  69.   ldmfd tos, { tos, link }
  70.   stmfd sp !, { link }
  71. next c; meta
  72.  
  73. variable lp
  74.  
  75. labcreate dolocal
  76.   stmfd sp !, { tos }
  77.   bic link, link, # &fc000003
  78.   ldr tos, [ link ]
  79.   ldr r0, lp
  80.   ldr tos, [ r0, tos ]
  81. next c;
  82.  
  83. labcreate dolocal!
  84.   bic link, link, # &fc000003
  85.   ldr r0, [ link, # -8 ]
  86.   ldr r1, lp
  87.   str tos, [ r1, r0 ]
  88.   ldmfd sp !, { tos }
  89. next c;
  90.  
  91. labcreate dolocal+!
  92.   bic link, link, # &fc000003
  93.   ldr r0, [ link, # -12 ]
  94.   ldr r1, lp
  95.   ldr r0, [ r1, r0 ]!
  96.   add tos, tos, r0
  97.   str tos, [ r1 ]
  98.   ldmfd sp !, { tos }
  99. next c;
  100.  
  101. labcreate docolp
  102.   ldr r0, lp
  103.   stmfd rp !, { r0, ip }
  104.   str rp, lp
  105.   bic ip, link, # &fc000003
  106.   ldr r0, [ ip ], # 4
  107.   and r1, r0, # &ff
  108.   sub rp, rp, r1, lsl # 2
  109.   mov r0, r0, lsr # 8
  110.   and s r0, r0, # &ff
  111.   0<> if
  112.     begin
  113.       stmfd rp !, { tos }
  114.       ldmfd sp !, { tos }
  115.       sub s r0, r0, # 1
  116.     0= until
  117.   then
  118. next c; meta
  119.  
  120. variable defer-list
  121. variable loadfile      thisfile loadfile !-t
  122.  
  123. code exitp
  124.   ldr rp, lp
  125.   ldmfd rp !, { r0, ip }
  126.   str r0, lp
  127. next c;
  128.  
  129. code unnestp
  130.   ldr rp, lp
  131.   ldmfd rp !, { r0, ip }
  132.   str r0, lp
  133. next c;
  134.  
  135. code exit      ( -- )
  136.   ldmfd rp !, { ip }
  137. next c;
  138.  
  139. code unnest    ( -- ) \ Same as EXIT
  140.   ldmfd rp !, { ip }
  141. next c;
  142.  
  143. code lit
  144.   stmfd sp !, { tos }
  145.   ldmfd ip !, { tos, pc }
  146. c;
  147.  
  148. code execute   ( cfa -- )  \ Execute the word whose CFA is on the stack.
  149.   mov r0, tos
  150.   ldmfd sp !, { tos }
  151.   mov pc, r0 c;
  152.  
  153. code noop      ( -- ) \  Does nothing  (No-Operation)
  154. next c;
  155.  
  156. code pause
  157.   mov r0, r0
  158. next c;
  159.  
  160. code branch    ( -- ) \ an unconditional branch
  161.   ldr ip, [ ip ]
  162. next c;
  163.  
  164. code ?branch   ( f -- )  \ branch if f is zero
  165.   teq tos, # 0
  166.   ldmfd sp !, { tos }
  167.   ldmfd ne ip !, { r0, pc } 
  168.   ldr ip, [ ip ]
  169. next c;
  170.  
  171. code _begin
  172. next c;
  173.  
  174. code _until
  175.   teq tos, # 0
  176.   ldmfd sp !, { tos }
  177.   ldmfd ne ip !, { r0, pc }
  178.   ldr ip, [ ip ]
  179. next c;
  180.  
  181. code _again
  182.   ldr ip, [ ip ]
  183. next c;
  184.  
  185. code _while
  186.   teq tos, # 0
  187.   ldmfd sp !, { tos }
  188.   ldmfd ne ip !, { r0, pc }
  189.   ldr ip, [ ip ]
  190. next c;
  191.  
  192. code _repeat
  193.   ldr ip, [ ip ]
  194. next c;
  195.  
  196. code _then
  197. next c;
  198.  
  199. code _case
  200. next c;
  201.  
  202. code _endcase
  203.   ldmfd sp !, { tos }
  204. next c;
  205.  
  206. code _of
  207.   mov r0, tos
  208.   ldmfd sp !, { tos }
  209.   cmp r0, tos
  210.   ldr ne ip, [ ip ]
  211.   next ne
  212.   ldmfd sp !, { tos }
  213.   ldmfd ip !, { r0, pc } c;
  214.  
  215. code _endof   ( -- ) \ an unconditional branch
  216.   ldr ip, [ ip ]
  217. next
  218. c;
  219.  
  220. code (do)      ( lim sta -- ) \ Primitive form of DO 
  221.   mov r3, tos
  222.   ldmfd sp !, { r1, tos }
  223.   ldr r2, [ ip ], # 4
  224.   add r1, r1, # &80000000
  225.   sub r0, r3, r1
  226.   stmfd rp !, { r0, r1, r2 }
  227. next c;
  228.  
  229. code (?do)     ( lim sta -- ) \ Primitive form of ?DO
  230.   mov r3, tos
  231.   ldmfd sp !, { r1, tos }
  232.   cmp r3, r1
  233.   ldr ne r2, [ ip ], # 4
  234.   add ne r1, r1, # &80000000
  235.   sub ne r0, r3, r1
  236.   stmfd ne rp !, { r0, r1, r2 }
  237.   next ne
  238.   ldr ip, [ ip ]
  239. next c;
  240.  
  241. code unloop    ( -- )  \ Clean up Return Stack so we can EXIT from DO-loop.
  242.   add rp, rp, # 12
  243. next c;
  244.  
  245. code (loop)    ( -- )  \ Primitive form of LOOP
  246.   ldr r0, [ rp ]
  247.   add s r0, r0, # 1
  248.   str vc r0, [ rp ]
  249.   ldr vc ip, [ ip ]
  250.   next vc
  251.   add rp, rp, # 12
  252.   ldmfd ip !, { r0, pc } c;
  253.  
  254. code (+loop)   ( n -- )  \ Primitive form of +LOOP
  255.   ldr r0, [ rp ]
  256.   add s r0, r0, tos
  257.   ldmfd sp !, { tos }
  258.   str vc r0, [ rp ]
  259.   ldr vc ip, [ ip ]
  260.   next vc
  261.   add rp, rp, # 12
  262.   ldmfd ip !, { r0, pc } c;
  263.  
  264. code bounds    ( n1 n2 --- n3 n4 )  \ Calculate limits used in DO-loop
  265.   mov r0, tos
  266.   ldr tos, [ sp ]
  267.   add r0, tos, r0
  268.   str r0, [ sp ]
  269. next c;
  270.  
  271. code i         ( -- n ) \ get the current index of the innermost loop
  272.   stmfd sp !, { tos }
  273.   ldr tos, [ rp ]
  274.   ldr r0, [ rp, # 4 ]
  275.   add tos, tos, r0
  276. next c;
  277.  
  278. code j         ( -- n ) \ get the index of the second most inner loop.
  279.   stmfd sp !, { tos }
  280.   ldr tos, [ rp, # 12 ]
  281.   ldr r0, [ rp, # 16 ]
  282.   add tos, tos, r0
  283. next c;
  284.  
  285. code leave       ( -- )
  286.   add rp, rp, # 12
  287.   ldr ip, [ rp, # -4 ]
  288. next c;
  289.  
  290. code ?leave    ( f -- )
  291.   orr s tos, tos, tos
  292.   ldmfd sp !, { tos }
  293.   next eq
  294.   add rp, rp, # 12
  295.   ldr ip, [ rp, # -4 ]
  296. next c;
  297.  
  298. variable sp0
  299. variable rp0
  300. variable hld
  301. variable base
  302. variable handler
  303. variable msg
  304. variable dp
  305.  
  306. code here
  307.   stmfd sp !, { tos }
  308.   ldr tos, dp
  309. next c;
  310.  
  311. code allot
  312.   ldr r0, dp
  313.   add r0, r0, tos
  314.   str r0, dp
  315.   ldmfd sp !, { tos }
  316. next c;
  317.  
  318. code compile,
  319.   ldr r0, dp
  320.   str tos, [ r0 ], # 4
  321.   str r0, dp
  322.   ldmfd sp !, { tos }
  323. next c;
  324.  
  325. code ,
  326.   ldr r0, dp
  327.   str tos, [ r0 ], # 4
  328.   str r0, dp
  329.   ldmfd sp !, { tos }
  330. next c;
  331.  
  332. code c,
  333.   ldr r0, dp
  334.   strb tos, [ r0 ], # 1
  335.   str r0, dp
  336.   ldmfd sp !, { tos }
  337. next c;
  338.  
  339. code w,
  340.   ldr r0, dp
  341.   strb tos, [ r0 ], # 1
  342.   mov tos, tos, lsr # 8
  343.   strb tos, [ r0 ], # 1
  344.   str r0, dp
  345.   ldmfd sp !, { tos }
  346. next c;
  347.  
  348. code compile
  349.   ldr r0, dp
  350.   ldmfd ip !, { r1, link }
  351.   str r1, [ r0 ], # 4
  352.   str r0, dp
  353.   mov pc, link c;
  354.  
  355. code align
  356.   ldr r0, dp
  357.   mov r1, # 0
  358.   begin
  359.     tst r0, # 3
  360.   0<> while
  361.     strb r1, [ r0 ], # 1
  362.   repeat
  363.   str r0, dp
  364. next c;
  365.  
  366. code aligned
  367.   add tos, tos, # 3
  368.   bic tos, tos, # 3
  369. next c;
  370.  
  371. labcreate m0cfa
  372.   ldr r0, lp
  373.   stmfd rp !, { r0, op, ip }
  374.   str rp, lp
  375.   bic ip, link, # &fc000003
  376.   mov op, tos
  377.   ldmfd sp !, { tos }
  378.   ldr r0, [ ip, # 4 ]!
  379.   and r1, r0, # &ff
  380.   sub rp, rp, r1, lsl # 2
  381.   mov s r0, r0, lsr # 8
  382.   0<> if
  383.     begin
  384.       stmfd rp !, { tos }
  385.       ldmfd sp !, { tos }
  386.       sub s r0, r0, # 1
  387.     0= until
  388.   then
  389.   add ip, ip, # 4
  390. next c;
  391.  
  392. labcreate m1cfa
  393.   ldr r0, lp
  394.   ldr r1, [ ip ], # 4
  395.   stmfd rp !, { r0, op, ip }
  396.   add op, r1, op
  397.   str rp, lp
  398.   bic ip, link, # &fc000003
  399.   ldr r0, [ ip ], # 4
  400.   and r1, r0, # &ff
  401.   sub rp, rp, r1, lsl # 2
  402.   mov s r0, r0, lsr # 8
  403.   0<> if
  404.     begin
  405.       stmfd rp !, { tos }
  406.       ldmfd sp !, { tos }
  407.       sub s r0, r0, # 1
  408.     0= until
  409.   then
  410. next c; meta
  411.  
  412. code exitm
  413.   ldr rp, lp
  414.   ldmfd rp !, { r0, op, ip }
  415.   str r0, lp
  416. next c;
  417.  
  418. code unnestm
  419.   ldr rp, lp
  420.   ldmfd rp !, { r0, op, ip }
  421.   str r0, lp
  422. next c;
  423.  
  424. code ^base
  425.   stmfd sp !, { tos }
  426.   mov tos, op
  427. next c;
  428.  
  429. labcreate (iv@)
  430.   stmfd sp !, { tos }
  431.   bic r0, link, # &fc000003
  432.   ldr r0, [ r0 ]
  433.   ldr tos, [ r0, op ]
  434. next c;
  435.  
  436. labcreate (iv!)
  437.   bic r0, link, # &fc000003
  438.   ldr r0, [ r0, # -8 ]
  439.   str tos, [ r0, op ]
  440.   ldmfd sp !, { tos }
  441. next c;
  442.  
  443. labcreate (iv+!)
  444.   bic r0, link, # &fc000003
  445.   ldr r0, [ r0, # -12 ]
  446.   ldr r1, [ r0, op ]
  447.   add tos, tos, r1
  448.   str tos, [ r0, op ]
  449.   ldmfd sp !, { tos }
  450. next c;
  451.  
  452. labcreate (iv[]@)
  453.   bic r0, link, # &fc000003
  454.   ldr r0, [ r0 ]
  455.   add r0, r0, op
  456.   ldr tos, [ r0, tos, lsl # 2 ]
  457. next c;
  458.  
  459. labcreate (iv[]!)
  460.   bic r0, link, # &fc000003
  461.   ldr r0, [ r0, # -8 ]
  462.   add r0, r0, tos, lsl # 2
  463.   ldmfd sp !, { r1, tos }
  464.   str r1, [ r0, op ]
  465. next c;
  466.  
  467. labcreate (iv[]+!)
  468.   bic r0, link, # &fc000003
  469.   ldr r0, [ r0, # -12 ]
  470.   add r0, r0, tos, lsl # 2
  471.   ldmfd sp !, { r2, tos }
  472.   ldr r1, [ r0, op ]!
  473.   add r1, r1, r2
  474.   str r1, [ r0 ]
  475. next c;
  476.  
  477. labcreate doobj
  478.   stmfd sp !, { tos }
  479.   bic tos, link, # &fc000003
  480.   add tos, tos, # 4
  481. next c;  
  482.   
  483. code ((findm))
  484.   ldmfd sp !, { r0 }
  485.   begin
  486.     ldr tos, [ tos ]
  487.     teq tos, # 0
  488.     next eq
  489.     ldr r1, [ tos, # 4 ]
  490.     cmp r0, r1
  491.   0= until
  492.   add tos, tos, # 8
  493.   stmfd sp !, { tos }
  494.   mvn tos, # 0
  495. next c;
  496.  
  497. code hash       ( ad cnt -- hash )
  498.   ldmfd sp !, { r0 }
  499.   mov r1, tos
  500.   mov tos, # 0
  501.   begin
  502.     ldrb r2, [ r0 ], # 1
  503.     eor tos, r2, tos, lsl # 1
  504.     sub s r1, r1, # 1
  505.   0= until
  506. next c;
  507.  
  508. code init-locals
  509.   ldr r0, lp
  510.   stmfd rp !, { r0 }
  511.   str rp, lp
  512.   ldr r0, [ ip ], # 4
  513.   and r1, r0, # &ff
  514.   sub rp, rp, r1, lsl # 2
  515.   mov r0, r0, lsr # 8
  516.   and s r0, r0, # &ff
  517.   0<> if
  518.     begin
  519.       stmfd rp !, { tos }
  520.       ldmfd sp !, { tos }
  521.       sub s r0, r0, # 1
  522.     0= until
  523.   then
  524. next c;
  525.  
  526. code unparms
  527.   ldr rp, lp
  528.   ldmfd rp !, { r0 }
  529.   str r0, lp
  530. next c;
  531.  
  532. code _localalloc
  533.   sub rp, rp, tos
  534.   bic rp, rp, # 3
  535.   mov tos, rp
  536. next c;
  537.  
  538. code drop      ( n -- )
  539.   ldmfd sp !, { tos }
  540. next c;
  541.  
  542. code dup       ( n -- n n )
  543.   stmfd sp !, { tos }
  544. next c;
  545.  
  546. code swap      ( n1 n2 -- n2 n1 )
  547.   ldr r0, [ sp ]
  548.   str tos, [ sp ]
  549.   mov tos, r0
  550. next c;
  551.  
  552. code over      ( n1 n2 -- n1 n2 n1 )
  553.   stmfd sp !, { tos }
  554.   ldr tos, [ sp, # 4 ]
  555. next c;
  556.  
  557. code rot       ( n1 n2 n3 -- n2 n3 n1 )
  558.   mov r0, tos
  559.   ldmfd sp !, { r1, tos }
  560.   stmfd sp !, { r0, r1 }
  561. next c;
  562.  
  563. code -rot      ( n1 n2 n3 -- n3 n1 n2 )
  564.   ldmfd sp !, { r0, r1 }
  565.   stmfd sp !, { r1, tos }
  566.   mov tos, r0
  567. next c;
  568.  
  569. code ?dup      ( n -- 0 | n n )
  570.   orr s tos, tos, tos
  571.   stmfd ne sp !, { tos }
  572. next c;
  573.  
  574. code nip       ( n1 n2 -- n2 )
  575.   add sp, sp, # 4
  576. next c;
  577.  
  578. code tuck      ( n1 n2 -- n2 n1 n2 )
  579.   ldmfd sp !, { r0 }
  580.   stmfd sp !, { r0, tos }
  581. next c;
  582.  
  583. code pick      ( nk ... n0 k -- nk ... n0 nk )
  584.   ldr tos, [ sp, tos, lsl # 2 ]
  585. next c;
  586.  
  587. code depth     ( -- n )
  588.   stmfd sp !, { tos }
  589.   adr tos, sp0
  590.   ldr tos, [ tos ]
  591.   sub tos, tos, sp
  592.   mov tos, tos, asr # 2
  593. next c;
  594.  
  595. code sp@       ( -- n ) \ Push the address of the top element on the stack (prior to push).
  596.   stmfd sp !, { tos }
  597.   mov tos, sp
  598. next c;
  599.  
  600. code sp!       ( n -- ) \ Set the parameter stack pointer to specified value.
  601.   mov sp, tos
  602.   ldmfd sp !, { tos }
  603. next c;
  604.  
  605. code rp@       ( -- ad ) \ Push the address of the top element of the return stack
  606.                            \ onto the parameter stack.
  607.   stmfd sp !, { tos }
  608.   mov tos, rp
  609. next c;
  610.  
  611. code rp!       ( ad -- )  \ Set the return stack pointer to ad.
  612.   mov rp, tos
  613.   ldmfd sp !, { tos }
  614. next c;
  615.  
  616. code >r        ( n -- )
  617.   stmfd rp !, { tos }
  618.   ldmfd sp !, { tos }
  619. next c;
  620.  
  621. code r>        ( -- n )
  622.   stmfd sp !, { tos }
  623.   ldmfd rp !, { tos }
  624. next c;
  625.  
  626. code r@        ( -- n )
  627.   stmfd sp !, { tos }
  628.   ldr tos, [ rp ]
  629. next c;
  630.  
  631. code dup>r     ( n -- n )
  632.   stmfd rp !, { tos }
  633. next c;
  634.  
  635. code r>drop    ( -- )
  636.   add rp, rp, # 4
  637. next c;
  638.  
  639. code 2>r       ( d -- )
  640.   mov r0, tos
  641.   ldmfd sp !, { r1, tos }
  642.   stmfd rp !, { r0, r1 }
  643. next c;
  644.  
  645. code 2r>       ( -- d )
  646.   ldr r0, [ rp, # 4 ]
  647.   stmfd sp !, { r0, tos }
  648.   ldr tos, [ rp ], # 8
  649. next c;
  650.  
  651. code 2r@       ( -- d )
  652.   ldr r0, [ rp, # 4 ]
  653.   stmfd sp !, { r0, tos }
  654.   ldr tos, [ rp ]
  655. next c;
  656.  
  657. code @         ( ad -- n )   \ Fetch a 32 bit value from addr
  658.   ldr tos, [ tos ]
  659. next c;
  660.  
  661. code !         ( n ad -- )   \ Store value n into the address addr
  662.   mov r0, tos
  663.   ldmfd sp !, { r1, tos }
  664.   str r1, [ r0 ]
  665. next c;
  666.  
  667. code +!        ( n ad -- )
  668.   mov r1, tos
  669.   ldmfd sp !, { r0, tos }
  670.   ldr r2, [ r1 ]
  671.   add r2, r2, r0
  672.   str r2, [ r1 ]
  673. next c;
  674.  
  675. code c@        ( ad -- c ) \ Fetch an 8 bit value from addr.  Fill high part with zeros.
  676.   ldrb tos, [ tos ]
  677. next c;
  678.  
  679. code c!        ( c ad -- ) \ Store the least significant 8 bits of char at the specified addr
  680.   mov r0, tos
  681.   ldmfd sp !, { r1, tos }
  682.   strb r1, [ r0 ]
  683. next c;
  684.  
  685. code c+!       ( c ad -- )
  686.   mov r1, tos
  687.   ldmfd sp !, { r0, tos }
  688.   ldrb r2, [ r1 ]
  689.   add r2, r2, r0
  690.   strb r2, [ r1 ]
  691. next c;
  692.  
  693. code na@       ( ad -- n )   \ Fetch a 32 bit value from non-aligned addr
  694.   ldrb r0, [ tos ]
  695.   ldrb r1, [ tos, # 1 ]
  696.   add r0, r0, r1, lsl # 8
  697.   ldrb r1, [ tos, # 2 ]
  698.   add r0, r0, r1, lsl # 16
  699.   ldrb r1, [ tos, # 3 ]
  700.   add tos, r0, r1, lsl # 24
  701. next c;
  702.  
  703. code na!       ( n ad -- )   \ Store value n into the non-aligned address addr
  704.   mov r0, tos
  705.   ldmfd sp !, { r1, tos }
  706.   strb r1, [ r0 ], # 1
  707.   mov r1, r1, lsr # 8
  708.   strb r1, [ r0 ], # 1
  709.   mov r1, r1, lsr # 8
  710.   strb r1, [ r0 ], # 1
  711.   mov r1, r1, lsr # 8
  712.   strb r1, [ r0 ], # 1
  713. next c;
  714.  
  715. code call@     ( ad -- cfa )
  716.   ldr r0, [ tos ], # 8
  717.   mov r1, r0, lsr # 25
  718.   cmp r1, # 117
  719.   mov ne tos, r0
  720.   next ne 
  721.   mov r0, r0, lsl # 8
  722.   mov r0, r0, asr # 6
  723.   add tos, tos, r0
  724. next c;
  725.  
  726. code w@        ( ad -- n )   \ Fetch a 16 bit value from addr
  727.   ldrb r0, [ tos ]
  728.   ldrb r1, [ tos, # 1 ]
  729.   add tos, r0, r1, lsl # 8
  730. next c;
  731.  
  732. code sw@        ( ad -- n )   \ Fetch a 16 bit value from addr
  733.   ldrb r0, [ tos ]
  734.   ldrb r1, [ tos, # 1 ]
  735.   add tos, r0, r1, lsl # 8
  736.   mov tos, tos, lsl # 16
  737.   mov tos, tos, asr # 16
  738. next c;
  739.  
  740. code w!        ( n ad -- )   \ Store 16 bit value n into the address addr
  741.   mov r0, tos
  742.   ldmfd sp !, { r1, tos }
  743.   strb r1, [ r0 ]
  744.   mov r1, r1, lsr # 8
  745.   strb r1, [ r0, # 1 ]
  746. next c;
  747.  
  748. code w+!       ( n ad -- )
  749.   mov r1, tos
  750.   ldmfd sp !, { r0, tos }
  751.   ldrb r3, [ r1 ]
  752.   ldrb r2, [ r1, # 1 ]
  753.   add r2, r3, r2 lsl # 8 ]
  754.   add r2, r2, r0
  755.   strb r2, [ r1 ] 
  756.   mov r2, r2, lsr # 8
  757.   strb r2, [ r1, # 1 ]
  758. next c;
  759.  
  760. 4 constant cell
  761.  
  762. code cells     ( n1 -- n2 )
  763.   mov tos, tos, lsl # 2
  764. next c;
  765.  
  766. code cells+    ( n1 n2 -- n3 )
  767.   ldmfd sp !, { r0 }
  768.   add tos, r0, tos, lsl # 2
  769. next c;
  770.  
  771. code cells-    ( n1 n2 -- n3 )
  772.   ldmfd sp !, { r0 }
  773.   sub tos, r0, tos, lsl # 2
  774. next c;
  775.  
  776. code cell+     ( n1 -- n2 )
  777.   add tos, tos, # 4
  778. next c;
  779.  
  780. code cell-     ( n1 -- n2 )
  781.   sub tos, tos, # 4
  782. next c;
  783.  
  784. code +cells    ( n1 n2 -- n3 )
  785.   ldmfd sp !, { r0 }
  786.   add tos, tos, r0, lsl # 2
  787. next c;
  788.  
  789. code -cells    ( n1 n2 -- n3 )
  790.   ldmfd sp !, { r0 }
  791.   sub tos, tos, r0, lsl # 2
  792. next c;
  793.  
  794. code move      ( from to count -- )
  795.   mov s r3, tos
  796.   ldmfd sp !, { r0, r1, tos } \ to from
  797.   next eq
  798.   sub r2, r0, r1
  799.   cmp r2, r3
  800.   u>= if
  801.     begin
  802.       ldrb r2, [ r1 ], # 1
  803.       strb r2, [ r0 ], # 1
  804.       sub s r3, r3, # 1
  805.     0= until
  806.     next
  807.   else
  808.     add r0, r0, r3
  809.     add r1, r1, r3
  810.     sub r0, r0, # 1
  811.     sub r1, r1, # 1
  812.     begin
  813.       ldrb r2, [ r1 ], # -1
  814.       strb r2, [ r0 ], # -1
  815.       sub s r3, r3, # 1
  816.     0= until
  817.     next
  818.   then c;
  819.  
  820. code fill      ( ad cnt c -- )
  821.   mov r0, tos
  822.   ldmfd sp !, { r1, r2, tos }
  823.   teq r1, # 0
  824.   next eq
  825.   begin
  826.     strb r0, [ r2 ], # 1
  827.     sub s r1, r1, # 1
  828.   0= until
  829. next c;
  830.  
  831. 32 constant bl
  832.  
  833. : erase        ( ad cnt -- )
  834.     0 fill ;
  835.  
  836. : blank        ( ad cnt -- )
  837.     bl fill ;
  838.  
  839. code cmove     ( from to count -- ) \ moves block of memory beginning at from !!! traditional !!!
  840.   mov s r3, tos
  841.   ldmfd sp !, { r0, r1, tos } \ count, to from
  842.   next eq
  843.   begin
  844.     ldrb r2, [ r1 ], # 1
  845.     strb r2, [ r0 ], # 1
  846.     sub s r3, r3, # 1
  847.   0= until
  848. next c;
  849.  
  850. code cmove>    ( from to count -- ) \ moves block of memory beginning at from+count-1 !!! traditional !!!
  851.   mov s r3, tos
  852.   ldmfd sp !, { r0, r1, tos } \ count, to from
  853.   next eq
  854.   add r0, r0, r3
  855.   add r1, r1, r3
  856.   sub r0, r0, # 1
  857.   sub r1, r1, # 1
  858.   begin
  859.     ldrb r2, [ r1 ], # -1
  860.     strb r2, [ r0 ], # -1
  861.     sub s r3, r3, # 1
  862.   0= until
  863. next c;
  864.  
  865. code and       ( n1 n2 -- n3 )
  866.   ldmfd sp !, { r0 }
  867.   and tos, tos, r0
  868. next c;
  869.  
  870. code or        ( n1 n2 -- n3 )
  871.   ldmfd sp !, { r0 }
  872.   orr tos, tos, r0
  873. next c;
  874.  
  875. code xor       ( n1 n2 -- n3 )
  876.   ldmfd sp !, { r0 }
  877.   eor tos, tos, r0
  878. next c;
  879.  
  880. code invert    ( n1 -- n2 )
  881.   mvn tos, tos
  882. next c;
  883.  
  884. code lshift    ( n1 n2 -- n3 )
  885.   ldmfd sp !, { r0 }
  886.   mov tos, r0, lsl tos
  887. next c;
  888.  
  889. code rshift    ( n1 n2 -- n3 )
  890.   ldmfd sp !, { r0 }
  891.   mov tos, r0, lsr tos
  892. next c;
  893.  
  894. -1 constant true
  895.  0 constant false
  896.  
  897. code incr      ( ad -- )
  898.   ldr r0, [ tos ]
  899.   add r0, r0, # 1
  900.   str r0, [ tos ]
  901.   ldmfd sp !, { tos }
  902. next c;
  903.  
  904. code decr      ( ad -- )
  905.   ldr r0, [ tos ]
  906.   sub r0, r0, # 1
  907.   str r0, [ tos ]
  908.   ldmfd sp !, { tos }
  909. next c;
  910.  
  911. code on        ( ad -- )
  912.   mvn r0, # 0
  913.   str r0, [ tos ]
  914.   ldmfd sp !, { tos }
  915. next c;
  916.  
  917. code off       ( ad -- )
  918.   mov r0, # 0
  919.   str r0, [ tos ]
  920.   ldmfd sp !, { tos }
  921. next c;
  922.  
  923. code toggle    ( ad byte -- )
  924.   mov r0, tos
  925.   ldmfd sp !, { r1, tos }
  926.   ldrb r2, [ r1 ]
  927.   eor r2, r2, r0
  928.   strb r2, [ r1 ]
  929. next c;
  930.  
  931. code +         ( n1 n2 -- n3 )
  932.   ldmfd sp !, { r0 }
  933.   add tos, tos, r0
  934. next c;
  935.  
  936. code -         ( n1 n2 -- n3 )
  937.   ldmfd sp !, { r0 }
  938.   sub tos, r0, tos
  939. next c;
  940.  
  941. code negate    ( n1 -- n2 )
  942.   rsb tos, tos, # 0
  943. next c;
  944.  
  945. code abs       ( n1 -- n2 )
  946.   eor s tos, tos, tos, asr # 32
  947.   adc tos, tos, # 0
  948. next c;
  949.  
  950. 0 constant 0
  951. 1 constant 1
  952.  
  953. code 2*        ( n1 -- n2 )
  954.   mov tos, tos, lsl # 1
  955. next c;
  956.  
  957. code 2/        ( n1 -- n2 )
  958.   mov tos, tos, asr # 1
  959. next c;
  960.  
  961. code u2/       ( n1 -- n2 )
  962.   mov tos, tos, lsr # 1
  963. next c;
  964.  
  965. code 1+        ( n1 -- n2 )
  966.   add tos, tos, # 1
  967. next c;
  968.  
  969. code 1-        ( n1 -- n2 )
  970.   sub tos, tos, # 1
  971. next c;
  972.  
  973. code d2*       ( d1 -- d2 )
  974.   ldr r0, [ sp ]
  975.   add s r0, r0, r0
  976.   adc tos, tos, tos
  977.   str r0, [ sp ]
  978. next c;
  979.  
  980. code d2/       ( d1 -- d2 )
  981.   ldmfd sp !, { r0 }
  982.   mov s tos, tos, asr # 1
  983.   mov r0, r0, rrx
  984.   stmfd sp !, { r0 }
  985. next c;
  986.  
  987. code um*       ( u1 u2 -- d )
  988.   ldmfd sp !, { r0 }
  989.   mov r2, r0, lsr # 16
  990.   mov r1, tos, lsr # 16
  991.   eor r0, r0, r2, lsl # 16
  992.   eor tos, tos, r1, lsl # 16
  993.   mul r4, r1, r2     \ hi
  994.   mul r3, tos, r0    \ lo
  995.   mul r2, tos, r2
  996.   mul r1, r0, r1
  997.   add s r0, r0, r1
  998.   add cs r4, r4, # &10000
  999.   add s r3, r3, r0, lsl # 16
  1000.   adc tos, r4, r0, lsr # 16
  1001.   stmfd sp !, { r3 }
  1002. next c;
  1003.  
  1004. code word-split ( u -- lo hi )
  1005.   mov r0, tos, lsl # 16
  1006.   mov r0, r0, lsr # 16
  1007.   stmfd sp !, { r0 }
  1008.   mov tos, tos, lsr # 16
  1009. next c;
  1010.  
  1011. code word-join ( lo hi -- n )
  1012.   ldmfd sp !, { r0 }
  1013.   add tos, r0, tos, lsl # 16
  1014. next c;
  1015.  
  1016. code 0=        ( n -- f )
  1017.   sub s tos, tos, # 1
  1018.   sbc tos, tos, tos
  1019. next c;
  1020.  
  1021. code 0<>       ( n -- f )
  1022.   orr s tos, tos, tos
  1023.   mvn ne tos, # 0
  1024. next c;
  1025.  
  1026. code 0<        ( n -- f )
  1027.   mov tos, tos, asr # 32
  1028. next c;
  1029.  
  1030. code 0>        ( n -- f )
  1031.   sub tos, tos, # 1
  1032.   mvn tos, tos, asr # 32
  1033. next c;
  1034.  
  1035. code =         ( n1 n2 -- f )
  1036.   ldmfd sp !, { r0 }
  1037.   cmp s r0, tos
  1038.   mvn eq tos, # 0
  1039.   mov ne tos, # 0
  1040. next c;
  1041.  
  1042. code <>        ( n1 n2 -- f )
  1043.   ldmfd sp !, { r0 }
  1044.   sub s tos, r0, tos
  1045.   mvn ne tos, # 0
  1046. next c;
  1047.  
  1048. code <         ( n1 n2 -- f )
  1049.   ldmfd sp !, { r0 }
  1050.   cmp r0, tos
  1051.   mvn lt tos, # 0
  1052.   mov ge tos, # 0
  1053. next c;
  1054.  
  1055. code >         ( n1 n2 -- f )
  1056.   ldmfd sp !, { r0 }
  1057.   cmp tos, r0
  1058.   mvn lt tos, # 0
  1059.   mov ge tos, # 0
  1060. next c;
  1061.  
  1062. code u<        ( u1 u2 -- f )
  1063.   ldmfd sp !, { r0 }
  1064.   sub s tos, r0, tos
  1065.   sbc tos, tos, tos
  1066. next c;
  1067.  
  1068. code u>        ( u1 u2 -- f )
  1069.   ldmfd sp !, { r0 }
  1070.   sub s tos, tos, r0
  1071.   sbc tos, tos, tos
  1072. next c;
  1073.  
  1074. code du<       ( ud1 ud2 -- f )
  1075.   ldmfd sp !, { r0, r1, r2 }
  1076.   sub s r2, r2, r0
  1077.   sbc s r1, r1, tos
  1078.   sbc tos, r2, r2
  1079. next c;
  1080.  
  1081. code umin      ( u1 u2 -- u3 )
  1082.   ldmfd sp !, { r0 }
  1083.   cmp tos, r0
  1084.   mov cs tos, r0
  1085. next c;
  1086.  
  1087. code min       ( n1 n2 -- n3 )
  1088.   ldmfd sp !, { r0 }
  1089.   cmp tos, r0
  1090.   mov gt tos, r0
  1091. next c;
  1092.  
  1093. code umax      ( u1 u2 -- u3 )
  1094.   ldmfd sp !, { r0 }
  1095.   cmp tos, r0
  1096.   mov cc tos, r0
  1097. next c;
  1098.  
  1099. code max       ( n1 n2 -- n3 )
  1100.   ldmfd sp !, { r0 }
  1101.   cmp tos, r0
  1102.   mov lt tos, r0
  1103. next c;
  1104.  
  1105. code 0max      ( n1 -- n2 )
  1106.   cmp tos, # 0
  1107.   mov lt tos, # 0
  1108. next c;
  1109.  
  1110. code between   ( n lo hi -- f ) \ true if lo<=n<=hi
  1111.   mov r2, tos
  1112.   mov tos, # 0
  1113.   ldmfd sp !, { r0, r1 }
  1114.   cmp r1, r2
  1115.   next gt
  1116.   cmp r0, r1
  1117.   mvn le tos, # 0
  1118. next c;
  1119.  
  1120. code within    ( n lo hi -- f ) \ true if lo<=n<hi
  1121.   mov r2, tos
  1122.   mov tos, # 0
  1123.   ldmfd sp !, { r0, r1 }
  1124.   cmp r1, r2
  1125.   next ge
  1126.   cmp r0, r1
  1127.   mvn le tos, # 0
  1128. next c;
  1129.  
  1130. code 2@        ( ad -- d )
  1131.   ldmfd tos, { r0, r1 }
  1132.   mov tos, r0
  1133.   stmfd sp !, { r1 }
  1134. next c;
  1135.  
  1136. code 2!        ( d ad -- )
  1137.   mov r2, tos
  1138.   ldmfd sp !, { r0, r1, tos }
  1139.   stmea r2, { r0, r1 }
  1140. next c;
  1141.  
  1142. code 2drop     ( d -- )
  1143.   add sp, sp, # 4
  1144.   ldmfd sp !, { tos }
  1145. next c;
  1146.  
  1147. code 2dup      ( d -- d d )
  1148.   ldr r0, [ sp ]
  1149.   stmfd sp !, { r0, tos }
  1150. next c;
  1151.  
  1152. code 2swap     ( d1 d2 -- d2 d1 )
  1153.   ldmfd sp !, { r0, r1, r2 }
  1154.   stmfd sp !, { r0 }
  1155.   stmfd sp !, { r2, tos }
  1156.   mov tos, r1
  1157. next c;
  1158.  
  1159. code 2over     ( d1 d2 -- d1 d2 d1 )
  1160.   ldr r0, [ sp, # 8 ]
  1161.   stmfd sp !, { r0, tos }
  1162.   ldr tos, [ sp, # 12 ]
  1163. next c;
  1164.  
  1165. code 2rot      ( d1 d2 d3 -- d2 d3 d1 )
  1166.   ldmfd sp !, { r0, r1, r2, r3, r4 }
  1167.   stmfd sp !, { r0, r1, r2 }
  1168.   stmfd sp !, { r4, tos }
  1169.   mov tos, r3
  1170. next c;
  1171.  
  1172. code d+        ( d1 d2 -- d3 )
  1173.   ldmfd sp !, { r0, r1, r2 }
  1174.   add s r0, r0, r2
  1175.   adc tos, tos, r1
  1176.   stmfd sp !, { r0 }
  1177. next c;
  1178.  
  1179. code d-        ( d1 d2 -- d3 )
  1180.   ldmfd sp !, { r0, r1, r2 }
  1181.   sub s r0, r2, r0
  1182.   sbc tos, r1, tos
  1183.   stmfd sp !, { r0 }
  1184. next c;
  1185.  
  1186. code dnegate   ( d1 -- d2 )
  1187.   ldmfd sp !, { r0 }  
  1188.   rsb s r0, r0, # 0
  1189.   rsc tos, tos, # 0
  1190.   stmfd sp !, { r0 }
  1191. next c;
  1192.  
  1193. code dabs      ( d1 -- d2 )
  1194.   tst tos, # &80000000
  1195.   next eq
  1196.   ldmfd sp !, { r0 }
  1197.   rsb s r0, r0, # 0
  1198.   rsc tos, tos, # 0
  1199.   stmfd sp !, { r0 }
  1200. next c;
  1201.  
  1202. code s>d       ( n -- d )
  1203.   stmfd sp !, { tos }
  1204.   mov tos, tos, asr # 32
  1205. next c;
  1206.  
  1207. code m*        ( n1 n2 -- d )
  1208.   ldmfd sp !, { r0 }
  1209.   eor r5, r0, tos
  1210.   tst r0, # &80000000
  1211.   rsb ne r0, r0, # 0
  1212.   tst tos, # &80000000
  1213.   rsb ne tos, tos, # 0
  1214.   mov r2, r0, lsr # 16
  1215.   mov r1, tos, lsr # 16
  1216.   eor r0, r0, r2, lsl # 16
  1217.   eor tos, tos, r1, lsl # 16
  1218.   mul r4, r1, r2     \ hi
  1219.   mul r3, tos, r0    \ lo
  1220.   mul r2, tos, r2
  1221.   mul r1, r0, r1
  1222.   add s r0, r2, r1
  1223.   add cs r4, r4, # &10000
  1224.   add s r3, r3, r0, lsl # 16
  1225.   adc tos, r4, r0, lsr # 16
  1226.   tst r5, # &80000000
  1227.   0<> if 
  1228.     rsb s r3, r3, # 0
  1229.     rsc tos, tos, # 0
  1230.   then
  1231.   stmfd sp !, { r3 }
  1232. next c;
  1233.  
  1234. code *         ( n1 n2 -- n3 )
  1235.   ldmfd sp !, { r0 }
  1236.   mul tos, r0, tos
  1237. next c;
  1238.  
  1239. label division
  1240.   add s r1, r1, r1
  1241.   adc s r0, tos, r0, lsl # 1
  1242.   sub cc r0, r0, tos
  1243.   adc s r1, r1, r1
  1244.   adc s r0, tos, r0, lsl # 1
  1245.   sub cc r0, r0, tos
  1246.   adc s r1, r1, r1
  1247.   adc s r0, tos, r0, lsl # 1
  1248.   sub cc r0, r0, tos
  1249.   adc s r1, r1, r1
  1250.   adc s r0, tos, r0, lsl # 1  \ 4
  1251.   sub cc r0, r0, tos
  1252.   adc s r1, r1, r1
  1253.   adc s r0, tos, r0, lsl # 1
  1254.   sub cc r0, r0, tos
  1255.   adc s r1, r1, r1
  1256.   adc s r0, tos, r0, lsl # 1
  1257.   sub cc r0, r0, tos
  1258.   adc s r1, r1, r1
  1259.   adc s r0, tos, r0, lsl # 1
  1260.   sub cc r0, r0, tos
  1261.   adc s r1, r1, r1
  1262.   adc s r0, tos, r0, lsl # 1  \ 8
  1263.   sub cc r0, r0, tos
  1264.   adc s r1, r1, r1
  1265.   adc s r0, tos, r0, lsl # 1
  1266.   sub cc r0, r0, tos
  1267.   adc s r1, r1, r1
  1268.   adc s r0, tos, r0, lsl # 1
  1269.   sub cc r0, r0, tos
  1270.   adc s r1, r1, r1
  1271.   adc s r0, tos, r0, lsl # 1
  1272.   sub cc r0, r0, tos
  1273.   adc s r1, r1, r1
  1274.   adc s r0, tos, r0, lsl # 1  \ 12
  1275.   sub cc r0, r0, tos
  1276.   adc s r1, r1, r1
  1277.   adc s r0, tos, r0, lsl # 1
  1278.   sub cc r0, r0, tos
  1279.   adc s r1, r1, r1
  1280.   adc s r0, tos, r0, lsl # 1
  1281.   sub cc r0, r0, tos
  1282.   adc s r1, r1, r1
  1283.   adc s r0, tos, r0, lsl # 1
  1284.   sub cc r0, r0, tos
  1285.   adc s r1, r1, r1
  1286.   adc s r0, tos, r0, lsl # 1  \ 16
  1287.   sub cc r0, r0, tos
  1288.   adc s r1, r1, r1
  1289.   adc s r0, tos, r0, lsl # 1
  1290.   sub cc r0, r0, tos
  1291.   adc s r1, r1, r1
  1292.   adc s r0, tos, r0, lsl # 1
  1293.   sub cc r0, r0, tos
  1294.   adc s r1, r1, r1
  1295.   adc s r0, tos, r0, lsl # 1
  1296.   sub cc r0, r0, tos
  1297.   adc s r1, r1, r1
  1298.   adc s r0, tos, r0, lsl # 1  \ 20
  1299.   sub cc r0, r0, tos
  1300.   adc s r1, r1, r1
  1301.   adc s r0, tos, r0, lsl # 1
  1302.   sub cc r0, r0, tos
  1303.   adc s r1, r1, r1
  1304.   adc s r0, tos, r0, lsl # 1
  1305.   sub cc r0, r0, tos
  1306.   adc s r1, r1, r1
  1307.   adc s r0, tos, r0, lsl # 1
  1308.   sub cc r0, r0, tos
  1309.   adc s r1, r1, r1
  1310.   adc s r0, tos, r0, lsl # 1  \ 24
  1311.   sub cc r0, r0, tos
  1312.   adc s r1, r1, r1
  1313.   adc s r0, tos, r0, lsl # 1
  1314.   sub cc r0, r0, tos
  1315.   adc s r1, r1, r1
  1316.   adc s r0, tos, r0, lsl # 1
  1317.   sub cc r0, r0, tos
  1318.   adc s r1, r1, r1
  1319.   adc s r0, tos, r0, lsl # 1
  1320.   sub cc r0, r0, tos
  1321.   adc s r1, r1, r1
  1322.   adc s r0, tos, r0, lsl # 1  \ 28
  1323.   sub cc r0, r0, tos
  1324.   adc s r1, r1, r1
  1325.   adc s r0, tos, r0, lsl # 1
  1326.   sub cc r0, r0, tos
  1327.   adc s r1, r1, r1
  1328.   adc s r0, tos, r0, lsl # 1
  1329.   sub cc r0, r0, tos
  1330.   adc s r1, r1, r1
  1331.   adc s r0, tos, r0, lsl # 1
  1332.   sub cc r0, r0, tos
  1333.   adc s r1, r1, r1
  1334.   adc s r0, tos, r0, lsl # 1  \ 32
  1335.   sub cc r0, r0, tos
  1336.   adc tos, r1, r1
  1337.   mov pc, link c;
  1338.  
  1339. code um/mod    ( ud un -- urem uquot )
  1340.   ldmfd sp !, { r0, r1 }
  1341.   cmp r0, tos
  1342.   b cs 1 $
  1343.   rsb s tos, tos, # 0
  1344.   b eq 1 $
  1345.   bl division
  1346.   stmfd sp !, { r0 }
  1347.   next
  1348. 1 $:
  1349.   mvn tos, # 0
  1350.   stmfd sp !, { tos }
  1351. next c;
  1352.  
  1353. code sm/rem
  1354.   ldmfd sp !, { r0, r1 }
  1355.   mov s r3, r0
  1356.   0< if
  1357.     rsb s r1, r1, # 0
  1358.     rsc r0, r0, # 0
  1359.   then
  1360.   mov s r2, tos
  1361.   rsb pl tos, tos, # 0
  1362.   b eq 1 $
  1363.   bl division
  1364.   teq r0, # 0
  1365.   0<> if
  1366.     eor s r3, r3, r2
  1367.       rsb mi tos, tos, # 0
  1368.       rsb mi r0, r0, # 0
  1369.     cmp r2, # 0
  1370.       rsb mi r0, r0, # 0
  1371.   else
  1372.     eor s r3, r3, r2
  1373.     rsb mi tos, tos, # 0
  1374.   then
  1375.   stmfd sp !, { r0 }
  1376.   next
  1377. 1 $:
  1378.   mvn tos, # 0
  1379.   stmfd sp !, { tos }
  1380. next c;
  1381.  
  1382. code fm/mod
  1383.   ldmfd sp !, { r0, r1 }
  1384.   mov s r3, r0
  1385.   0< if
  1386.     rsb s r1, r1, # 0
  1387.     rsc r0, r0, # 0
  1388.   then
  1389.   mov s r2, tos
  1390.   rsb pl tos, tos, # 0
  1391.   b eq 1 $
  1392.   bl division
  1393.   teq r0, # 0
  1394.   0<> if
  1395.     cmp r2, # 0
  1396.       rsb mi r0, r0, # 0
  1397.     eor s r3, r3, r2
  1398.       rsb mi tos, tos, # 0
  1399.       sub mi r0, r2, r0
  1400.       sub mi tos, tos, # 1
  1401.   else
  1402.     eor s r3, r3, r2
  1403.     rsb mi tos, tos, # 0
  1404.   then
  1405.   stmfd sp !, { r0 }
  1406.   next
  1407. 1 $:
  1408.   mvn tos, # 0
  1409.   stmfd sp !, { tos }
  1410. next c;
  1411.  
  1412. : /mod
  1413.     >r s>d r> fm/mod ;
  1414.  
  1415. : /
  1416.     /mod nip ;
  1417.  
  1418. : mod          ( n1 n2 -- rem )
  1419.     /mod drop ;
  1420.  
  1421. : */mod        ( n1 n2 n3 -- rem quot )
  1422.     >r m* r> fm/mod ;
  1423.  
  1424. : */           ( n1 n2 n3 -- quot )
  1425.     */mod nip ;
  1426.  
  1427. : mu/mod       ( ud u -- rem dquot )
  1428.     >r 0  r@  um/mod  r>  swap  >r um/mod r> ;
  1429.  
  1430. : ad>of ( to from -- off )
  1431.     8 + - 2 rshift &ffffff and ;
  1432.  
  1433. create pocket         260 allot
  1434. create cur-file       260 allot
  1435. create temp$          260 allot
  1436.  
  1437. 12 constant #vocs
  1438.  
  1439. create context        #vocs cells allot
  1440.  
  1441. variable current
  1442. variable last
  1443. variable voc-link
  1444. 0  value source-id
  1445.   create filebuf        260 allot
  1446.   create tib            260 allot
  1447.   create (source)   here 0 , tib ,
  1448. constant #tib
  1449. variable >in
  1450. variable state
  1451. variable warning       -1 warning !-t
  1452. variable caps          -1 caps !-t
  1453.  
  1454. code source
  1455.   adr r2, (source)
  1456.   ldmfd r2, { r0, r1 }
  1457.   stmfd sp !, { r1, tos }
  1458.   mov tos, r0
  1459. next c;
  1460.  
  1461. labcreate dovoc
  1462.   bic link, link, # &fc000003
  1463.   add link, link, # 8
  1464.   str link, context
  1465. next c;
  1466.  
  1467. : pad
  1468.     here 260 + ;
  1469.  
  1470. code count     ( ad -- ad+1 cnt )
  1471.   add tos, tos, # 1
  1472.   stmfd sp !, { tos }
  1473.   ldrb tos, [ tos, # -1 ]
  1474. next c;
  1475.  
  1476. code wcount    ( ad -- ad+2 cnt )
  1477.   add r0, tos, # 2
  1478.   stmfd sp !, { r0 }
  1479.   ldrb tos, [ r0, # -2 ]
  1480.   ldrb r0, [ r0, # -1 ]
  1481.   add tos, tos, r0, lsl # 8
  1482. next c;
  1483.  
  1484. code lcount    ( ad -- ad+4 cnt )
  1485.   add tos, tos, # 4
  1486.   stmfd sp !, { tos }
  1487.   ldr tos, [ tos, # -4 ]
  1488. next c;
  1489.  
  1490. code zcount    ( ad -- ad len )
  1491.   stmfd sp !, { tos }
  1492.   bic r0, tos, # 3
  1493.   ldr r1, [ r0 ]
  1494.   mov r2, # 1
  1495.   orr r2, r2, # &100
  1496.   orr s r2, r2, r2, asl # 16
  1497.   sbc s r3, tos, r0
  1498.   orr gt r1, r1, r3, asl # 15
  1499.   orr gt r1, r1, r3, asl # 14
  1500.   orr pl r1, r1, # &ff
  1501. 1 $:
  1502.   sub s r3, r1, r2
  1503.   eor cs r3, r3, r1
  1504.   bic cs s r3, r2, r3
  1505.   ldr eq r1, [ r0, # 4 ]!
  1506.   b eq 1 $
  1507.   tst r1, # &ff
  1508.   add ne r0, r0, # 1  
  1509.   tst ne r1, # &ff00
  1510.   add ne r0, r0, # 1  
  1511.   tst ne r1, # &ff0000
  1512.   add ne r0, r0, # 1
  1513.   sub tos, r0, tos
  1514. next c;
  1515.  
  1516. \ : place
  1517. \     swap 255 min 0max swap 2dup c! 1+ swap move ;
  1518.  
  1519. code place     ( from cnt to -- ) \ Move "cnt" characters from "from" to "to" + 1
  1520.                                   \ with preceeding count byte at "to".
  1521.   mov r3, tos
  1522.   ldmfd sp !, { r0, r1, tos }
  1523.   strb r0, [ r3 ], # 1
  1524.   orr s r0, r0, r0
  1525.   next eq
  1526.   begin
  1527.     ldrb r2, [ r1 ], # 1
  1528.     strb r2, [ r3 ], # 1
  1529.     sub s r0, r0, # 1
  1530.   0= until
  1531. next c;
  1532.  
  1533. \ : place+
  1534. \     >r 255 min 0max 255 r@ c@ - min r> 2dup 2>r
  1535. \     count + swap move 2r> c+! ;
  1536.  
  1537. code +place     ( from cnt to -- ) \ append text to counted string
  1538.   mov r3, tos
  1539.   ldrb r4, [ r3 ]
  1540.   ldmfd sp !, { r0, r1, tos }
  1541.   add r2, r4, r0
  1542.   strb r2, [ r3 ], # 1
  1543.   add r3, r3, r4
  1544.   orr s r0, r0, r0
  1545.   next eq
  1546.   begin
  1547.     ldrb r2, [ r1 ], # 1
  1548.     strb r2, [ r3 ], # 1
  1549.     sub s r0, r0, # 1
  1550.   0= until
  1551. next c;
  1552.  
  1553. code -trailing ( ad len -- ad len' )
  1554.   ldr r0, [ sp ]
  1555.   begin
  1556.     sub s tos, tos, # 1
  1557.   b cc 1 $
  1558.     ldrb r1, [ r0, tos ]
  1559.     teq r1, # 32
  1560.   0<> until
  1561. 1 $: add tos, tos, # 1
  1562. next c;
  1563.  
  1564. code -nulls    ( ad len -- ad len' )
  1565.   ldr r0, [ sp ]
  1566.   begin
  1567.     sub s tos, tos, # 1
  1568.   b cc 1 $
  1569.     ldrb r1, [ r0, tos ]
  1570.     teq r1, # 0
  1571.   0<> until
  1572. 1 $: add tos, tos, # 1
  1573. next c;
  1574.  
  1575. code /string   ( ad len c -- ad' len' )
  1576.   ldmfd sp !, { r0, r1 }
  1577.   cmp tos, # 0
  1578.   0>= if
  1579.     cmp r0, tos
  1580.     mov ls tos, r0
  1581.   then
  1582.   add r1, r1, tos
  1583.   sub tos, r0, tos
  1584.   stmfd sp !, { r1 }
  1585. next c;
  1586.  
  1587. code upc       ( c -- c' )
  1588.   tst tos, # 64
  1589.   next eq
  1590.   cmp tos, # 192
  1591.   bic cs tos, tos, # 32
  1592.   next cs
  1593.   cmp tos, # ascii {
  1594.   bic cc tos, tos, # 32
  1595. next c;
  1596.  
  1597. code upper     ( ad len -- )
  1598.   mov r0, tos
  1599.   ldmfd sp !, { r1, tos }
  1600.   begin
  1601.     ldrb r3, [ r1 ]
  1602.     tst r3, # 64
  1603.     b eq 1 $    
  1604.     cmp r3, # 192
  1605.     bic cs r3, r3, # 32
  1606.     b cs 1 $
  1607.     cmp r3, # ascii {
  1608.     bic cc r3, r3, # 32
  1609. 1 $:
  1610.     strb r3, [ r1 ], # 1
  1611.     sub s r0, r0, # 1
  1612.   0= until
  1613. next c;
  1614.  
  1615. code ?uppercase ( ad -- ad )
  1616.   adr r0, caps
  1617.   ldr r0, [ r0 ]
  1618.   teq r0, # 0
  1619.   next eq
  1620.   mov r1, tos
  1621.   ldrb r0, [ r1 ], # 1
  1622.   teq r0, # 0
  1623.   0<> if
  1624.     begin
  1625.       ldrb r3, [ r1 ]
  1626.       tst r3, # 64
  1627.       b eq 1 $    
  1628.       cmp r3, # 192
  1629.       bic cs r3, r3, # 32
  1630.       b cs 1 $
  1631.       cmp r3, # ascii {
  1632.       bic cc r3, r3, # 32
  1633. 1 $:
  1634.       strb r3, [ r1 ], # 1
  1635.       sub s r0, r0, # 1
  1636.     0= until
  1637.   then
  1638. next c;
  1639.  
  1640. defer outpause ' noop is outpause
  1641.  
  1642. code OS_WriteC  ( c -- )
  1643.   mov r0, tos
  1644.   swi " OS_WriteC"
  1645.   ldmfd sp !, { tos }
  1646. next c;
  1647.  
  1648. variable #out
  1649.  
  1650. : _emit
  1651.     OS_WriteC outpause 1 #out +! ;
  1652. defer emit ' _emit is emit
  1653.  
  1654. code %_key?   ( -- f )
  1655.   stmfd sp !, { tos }
  1656.   mov r0, # &c6
  1657.   mov r1, # 0
  1658.   mov r2, # &ff
  1659.   swi " OS_Byte"
  1660.   teq r1, # 0
  1661.   0= if
  1662.     mov r0, # &b1
  1663.     mov r2, # &ff
  1664.     swi " OS_Byte"
  1665.     rsb r1, r1, # &ff
  1666.     mov r0, # &80
  1667.     swi " OS_Byte"
  1668.     add tos, r1, r2, lsl # 8
  1669.     next
  1670.   then
  1671.   mov r0, # 5
  1672.   swi " OS_Args"
  1673.   sub s tos, r2, # 1
  1674.   sbc tos, tos, tos
  1675. next c;  
  1676. : _key? pause  %_key? ;
  1677. defer key? ' _key? is key?
  1678.  
  1679. code %_key     ( -- c )
  1680.   stmfd sp !, { tos }
  1681.   swi " OS_ReadC"
  1682.   mov tos, r0
  1683.   next cc
  1684.   cmp r0, # 27
  1685.   next ne
  1686.   mov r0, # 126
  1687.   swi " OS_Byte"
  1688. next c;
  1689.  
  1690. : _key
  1691.     begin key? until
  1692.     %_key ;
  1693. defer key  ' _key is key
  1694.  
  1695. : _beep
  1696.     7 emit ;
  1697. defer beep   ' _beep is beep
  1698.  
  1699. 0 value accept-cnt                      \ current count of chars accepted
  1700. : _accept      ( a1 n1 -- n2 )
  1701.     0 swap 0
  1702.     ?do     drop
  1703.       i to accept-cnt \ save in case we need it
  1704.       key
  1705.       case
  1706.         8 of i 1 <           \ if input is empty
  1707.              if 0            \ do nothing but
  1708.                beep          \ beep at user
  1709.              else 1-         \ decrement address 1
  1710.                -1 8 emit bl emit 8 emit
  1711.              then                            endof
  1712.        27 of dup c@ emit 1+ 1                endof
  1713.        13 of i leave                         endof
  1714.              dup emit
  1715.              2dup swap c!    \ place the character
  1716.              swap 1+ swap    \ bump the address
  1717.              1 swap          \ loop increment
  1718.       endcase
  1719.       i 1+ swap       \ in case loop completes
  1720.    +loop nip ;
  1721.  
  1722. defer accept ' _accept is accept
  1723.  
  1724. code OS_WriteN
  1725.   mov r1, tos
  1726.   ldmfd sp !, { r0, tos }
  1727.   swi " OS_WriteN"
  1728. next c;
  1729.  
  1730. : _type
  1731.     0max dup #out +! OS_WriteN outpause ;
  1732. defer type ' _type is type
  1733.  
  1734. code os_newline ( -- )
  1735.   swi " OS_NewLine"
  1736. next c;
  1737.  
  1738. : _cr
  1739.     OS_NewLine #out off ;
  1740. defer cr   ' _cr is cr
  1741.  
  1742. : _cls #out off ;
  1743. defer cls  ' _cls is cls
  1744.  
  1745. : _?cr ( n -- ) #out @ + ( lmargin ) 50 > if cr then ;
  1746. defer ?cr  ' _?cr is ?cr
  1747.  
  1748. code os_exit
  1749.   mov r0, tos
  1750.   ldmfd sp !, { r1, r2 }
  1751.   swi " OS_Exit"
  1752. next c;
  1753.  
  1754. : _bye
  1755.     ."  Leaving.." cr
  1756.     0 &58454241 0 os_exit ;
  1757. defer bye  ' _bye is bye
  1758.  
  1759. : _console ;
  1760. defer console ' _console is console
  1761.  
  1762. &c0 constant r/w
  1763. &40 constant r/o
  1764. : bin ;
  1765.  
  1766. code OS_Find ( fileid/name reason -- handle | false )
  1767.   ldmfd sp !, { r1 }
  1768.   mov r0, tos
  1769.   swi x " OS_Find"
  1770.   mov vs tos, # 0
  1771.   mov vc tos, r0
  1772. next c;
  1773.  
  1774. : open-file   ( ad len fam -- fileid ior )
  1775.     >r over + 0 swap c! r> OS_Find dup 0= ;
  1776.  
  1777. : close-file  ( fileid -- ior )
  1778.     0 OS_Find ;
  1779.  
  1780. code read-file   ( ad len fileid -- bytesread ior )
  1781.   ldmfd sp !, { r1, r2 }
  1782.   mov r3, r1
  1783.   mov r5, r1
  1784.   mov r1, tos
  1785.   mov r0, # 4
  1786.   swi x " OS_GBPB"
  1787.   mov vc tos, # 0
  1788.   mvn vs tos, # 0
  1789.   sub r5, r5, r3
  1790.   stmfd sp !, { r5 }
  1791. next c;
  1792.  
  1793. code create-file ( ad len fam -- fileid ior )
  1794.   ldmfd sp !, { r0, r1 }
  1795.   mov r2, # 0
  1796.   strb r2, [ r0, r1 ]
  1797.   mov r0, # &83
  1798.   swi x " OS_Find"
  1799.   mov vc tos, # 0
  1800.   mvn vs tos, # 0
  1801.   stmfd sp !, { r0 }
  1802. next c;
  1803.  
  1804. code delete-file ( ad len -- ior )
  1805.   mov r0, # 6
  1806.   ldmfd sp !, { r1 }
  1807.   mov r2, # 0
  1808.   strb r2, [ r1, tos ]
  1809.   swi x " OS_File"
  1810.   mov vc tos, # 0
  1811.   mvn vs tos, # 0
  1812. next c;
  1813.  
  1814. code write-file ( ad len fileid -- ior )
  1815.   mov r0, # 2
  1816.   mov r1, tos
  1817.   ldmfd sp !, { r3, tos }
  1818.   mov r2, tos
  1819.   swi x " OS_GBPB"
  1820.   mov vc tos, # 0
  1821.   mvn vs tos, # 0
  1822. next c;
  1823.  
  1824. : write-line ( ad len fileid -- ior )
  1825.     dup>r write-file 10 sp@ 1 r> write-file nip or ;
  1826.  
  1827. 16384 value iblen               \ current input buffer length
  1828. 16384 value ibfull              \ full buffer size, used to restore IBLEN
  1829.     0 value inbuf               \ input buffer address
  1830.     0 value instart
  1831.     0 value inlength
  1832.     0 value outbuf
  1833.     0 value outlen
  1834.     0 value cur-handle
  1835.  
  1836. : _readl
  1837.     inlength 0> 0=
  1838.     if inbuf ibfull cur-handle read-file
  1839.       if r>drop 0 -1 exit then
  1840.       dup to iblen to inlength
  1841.       inbuf to instart
  1842.     then
  1843.     instart inlength 2dup &0a scan dup>r
  1844.     nip - outlen umin tuck outbuf swap cmove
  1845.     dup 1+ dup +to instart negate +to inlength
  1846.     dup +to outbuf dup negate +to outlen r> ;
  1847.  
  1848. : read-line ( ad len fileid -- len flag ior )
  1849.     to cur-handle to outlen to outbuf
  1850.     inlength 0> 0= iblen ibfull < and
  1851.     if 0 0 0 exit then
  1852.     _readl
  1853.     iblen ibfull < or 0=
  1854.     if _readl drop + then
  1855.     true 0 ;
  1856.  
  1857. code OS_File
  1858.   mov r0, tos
  1859.   ldmfd sp !, { r1, r2, r3, r4, r5, tos }
  1860.   swi x " OS_File"
  1861. next c;
  1862.  
  1863. : save-file   ( ad len filename -- )
  1864.     1+ >r
  1865.     bounds 0 &ff8 r>
  1866.     10 OS_File ;
  1867.  
  1868. : _getxy #out @ 0 ;
  1869.  
  1870. : _getcolrow  60 0
  1871. ;
  1872.  
  1873. : tone 2drop
  1874. ;
  1875.  
  1876. : beep! 2drop
  1877. ;
  1878.  
  1879. code digit     ( c base -- n f )
  1880.   ldr r0, [ sp ]
  1881.   sub s r0, r0, # 48
  1882.   u>= if 
  1883.     cmp r0, # 10
  1884.     b cc 1 $
  1885.     cmp r0, # 17
  1886.     u>= if 
  1887.       sub r0, r0, # 7
  1888. 1 $:  cmp r0, tos
  1889.       u< if
  1890.         str r0, [ sp ]
  1891.         mvn tos, # 0
  1892.         next
  1893.       then 
  1894.     then 
  1895.   then
  1896.   mov tos, # 0
  1897. next c;
  1898.  
  1899. code >number   ( ud ad len -- ud ad len )
  1900.   teq tos, # 0
  1901.   0<> if
  1902.     ldmfd sp !, { r0, r1, r2 } \ ad hi lo
  1903.     adr r3, base
  1904.     ldr r3, [ r3 ]
  1905.     begin
  1906.       ldrb r4, [ r0 ], # 1
  1907.       sub s r4, r4, # 48
  1908.       b cc 1 $
  1909.       cmp r4, # 9
  1910.       > if
  1911.         sub r4, r4, # 7
  1912.         cmp r4, # 10
  1913.         b cc 1 $            
  1914.       then
  1915.       cmp r4, r3
  1916.       b ge 1 $
  1917.       mov r5, r2, lsl # 16
  1918.       mov r5, r5, lsr # 16
  1919.       mla r4, r5, r3, r4     \ lolo * base + digit
  1920.       mov r2, r2, lsr # 16
  1921.       mul r5, r2, r3         \ hilo * base
  1922.       mul r2, r1, r3         \ hi   * base
  1923.       add r5, r5, r4, lsr # 16
  1924.       add r1, r2, r5, lsr # 16
  1925.       mov r4, r4, lsl # 16
  1926.       mov r4, r4, lsr # 16
  1927.       add r2, r4, r5, lsl # 16
  1928.       sub s tos, tos, # 1
  1929.     0= until
  1930. 1 $: sub r0, r0, # 1
  1931.     stmfd sp !, { r0, r1, r2 }
  1932.   then
  1933. next c;
  1934.  
  1935. 0 value double?
  1936. -1 value dp-location
  1937.  
  1938. : _number?
  1939.     false to double?                \ initially not a double #
  1940.     -1 to dp-location
  1941.     over c@ [char] - = over and dup>r
  1942.     if      1 /string
  1943.     then    0 0 2swap >number
  1944.     over c@ [char] . =               \ next char is a '.'
  1945.     if      dup 1- to dp-location
  1946.             1 /string >number
  1947.             true to double?         \ mark as a double number
  1948.     then    nip 0=
  1949.     r>
  1950.     if      >r dnegate r>
  1951.     then    ;
  1952.  
  1953. : ?missing    ( f -- )
  1954.     abort" is undefined" ;
  1955.  
  1956. : (number)    ( ad -- d )
  1957.     count _number? 0= ?missing ;
  1958.  
  1959. defer number    ' (number) is number
  1960.  
  1961. : space
  1962.     bl emit ;
  1963.  
  1964. 128 constant spcs-max
  1965.  
  1966. create spcs &20202020
  1967. dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t 
  1968. dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t
  1969. dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t
  1970. dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t dup ,-t     ,-t
  1971.  
  1972. : spaces     ( n -- )
  1973.     begin dup 0>
  1974.     while dup spcs-max min spcs over type -
  1975.     repeat drop ;
  1976.  
  1977. : _gotoxy drop
  1978.     #out @ - dup 0> if dup spaces then drop ;
  1979.  
  1980. : hex       16 base ! ;
  1981. : decimal   10 base ! ;
  1982. : binary     2 base ! ;
  1983. : octal      8 base ! ;
  1984.  
  1985. code hold    ( c -- )
  1986.   adr r0, hld
  1987.   ldr r1, [ r0 ]
  1988.   strb tos, [ r1, # -1 ]!
  1989.   str r1, [ r0 ]
  1990.   ldmfd sp !, { tos }
  1991. next c;
  1992.  
  1993. : <#
  1994.     pad hld ! ;
  1995.  
  1996. : #>
  1997.     2drop hld @ pad over - ;
  1998.  
  1999. : sign
  2000.     0< if [char] - hold then ;
  2001.  
  2002. : #            ( d -- d' )
  2003.     base @ mu/mod rot 9 over <
  2004.     if 7 + then [char] 0 + hold ;
  2005.  
  2006. : #s           ( d -- 0 0 )
  2007.     begin # 2dup or 0= until ;
  2008.  
  2009. : (d.)         ( d -- ad len )
  2010.     tuck dabs <# #s rot sign #> ;
  2011.  
  2012. : d.           ( d -- )
  2013.     (d.) type space ;
  2014.  
  2015. : d.r          ( d len -- )
  2016.     >r (d.) r> over - spaces type ;
  2017.  
  2018. : .     s>d d. ;
  2019. : .r    >r s>d r> d.r ;
  2020. : u.    0 d. ;
  2021. : u.r   0 swap d.r ;
  2022. : h.    base @ swap hex u. base ! ;
  2023. : ?     @ . ;
  2024.  
  2025. code word     ( char -- ad )
  2026.   adr r0, (source)
  2027.   ldmfd r0, { r1, r4 }
  2028.   adr r0, >in
  2029.   ldr r3, [ r0 ]  \ r0= >in
  2030.   add r2, r4, r3
  2031.   sub s r1, r1, r3
  2032.   mov le r1, # 0
  2033.   > if
  2034.     cmp tos, # 32
  2035.     0= if
  2036.       begin
  2037.         ldrb r5, [ r2 ], # 1
  2038.         cmp r5, tos
  2039.       <= while
  2040.         sub s r1, r1, # 1
  2041.       0= until
  2042.         mov r6, r2
  2043.         mov r5, r6
  2044.         b 1 $
  2045.       then
  2046.       sub r6, r2, # 1    \ r6= start of word
  2047.       add tos, tos, # 1
  2048.       begin
  2049.         sub s r1, r1, # 1
  2050.       0<> while
  2051.         ldrb r5, [ r2 ], # 1
  2052.         cmp r5, tos
  2053.       u< until
  2054.         sub s r5, r2, # 1    \ r5= end of word
  2055.       then
  2056.       mov eq r5, r2
  2057.     else
  2058.       begin
  2059.         ldrb r5, [ r2 ], # 1
  2060.         cmp r5, tos
  2061.       0= while
  2062.         sub s r1, r1, # 1
  2063.       0= until
  2064.         mov r6, r2
  2065.         mov r5, r6
  2066.         b 1 $
  2067.       then
  2068.       sub r6, r2, # 1    \ r6= start of word
  2069.       begin
  2070.         sub s r1, r1, # 1
  2071.       0<> while
  2072.         ldrb r5, [ r2 ], # 1
  2073.         cmp r5, tos
  2074.       0= until
  2075.         sub s r5, r2, # 1    \ r5= end of word
  2076.       then
  2077.       mov eq r5, r2
  2078.     then
  2079. 1 $:
  2080.     sub r1, r2, r4       \ update >in
  2081.     str r1, [ r0 ] 
  2082.     sub r1, r5, r6
  2083.     cmp r1, # 255
  2084.     mov gt r1, # 255
  2085.   then
  2086.   adr r0, pocket         \ r1= count
  2087.   mov tos, r0
  2088.   strb r1, [ r0 ], # 1
  2089.   teq r1, # 0
  2090.   0<> if
  2091.     begin
  2092.       ldrb r5, [ r6 ], # 1
  2093.       strb r5, [ r0 ], # 1
  2094.       sub s r1, r1, # 1   
  2095.     0= until
  2096.   then
  2097.   strb r1, [ r0 ]
  2098. next c;
  2099.  
  2100. code skip      ( ad len c -- ad' len' )
  2101.   ldmfd sp !, { r0, r1 }
  2102.   teq r0, # 0
  2103.   0<> if
  2104.     begin
  2105.       ldrb r2, [ r1 ], # 1
  2106.       cmp r2, tos
  2107.       b ne 1 $
  2108.       sub s r0, r0, # 1
  2109.     0= until
  2110.     add r1, r1, # 1
  2111. 1 $:
  2112.     sub r1, r1, # 1
  2113.   then
  2114.   mov tos, r0
  2115.   stmfd sp !, { r1 }
  2116. next c;
  2117.  
  2118. code scan      ( ad len c -- ad' len' )
  2119.   ldmfd sp !, { r0, r1 }
  2120.   teq r0, # 0
  2121.   0<> if
  2122.     begin
  2123.       ldrb r2, [ r1 ], # 1
  2124.       cmp r2, tos
  2125.       b eq 1 $
  2126.       sub s r0, r0, # 1
  2127.     0= until
  2128.     add r1, r1, # 1
  2129. 1 $:
  2130.     sub r1, r1, # 1
  2131.   then
  2132.   mov tos, r0
  2133.   stmfd sp !, { r1 }
  2134. next c;
  2135.  
  2136. code wskip c;
  2137. code wscan c;
  2138.  
  2139. code lskip      ( ad len c -- ad' len' )
  2140.   ldmfd sp !, { r0, r1 }
  2141.   teq r0, # 0
  2142.   0<> if
  2143.     begin
  2144.       ldr r2, [ r1 ], # 1
  2145.       cmp r2, tos
  2146.       b ne 1 $
  2147.       sub s r0, r0, # 1
  2148.     0= until
  2149.     add r1, r1, # 1
  2150. 1 $:
  2151.     sub r1, r1, # 1
  2152.   then
  2153.   mov tos, r0
  2154.   stmfd sp !, { r1 }
  2155. next c;
  2156.  
  2157. code lscan      ( ad len c -- ad' len' )
  2158.   ldmfd sp !, { r0, r1 }
  2159.   teq r0, # 0
  2160.   0<> if
  2161.     begin
  2162.       ldr r2, [ r1 ], # 1
  2163.       cmp r2, tos
  2164.       b eq 1 $
  2165.       sub s r0, r0, # 1
  2166.     0= until
  2167.     add r1, r1, # 1
  2168. 1 $:
  2169.     sub r1, r1, # 1
  2170.   then
  2171.   mov tos, r0
  2172.   stmfd sp !, { r1 }
  2173. next c;
  2174.  
  2175. code -skip      ( ad len c -- ad' len' )
  2176.   ldmfd sp !, { r0, r1 }
  2177.   teq r0, # 0
  2178.   0<> if
  2179.     begin
  2180.       ldrb r2, [ r1 ], # -1
  2181.       cmp r2, tos
  2182.       b ne 1 $
  2183.       sub s r0, r0, # 1
  2184.     0= until
  2185.     sub r1, r1, # 1
  2186. 1 $:
  2187.     add r1, r1, # 1
  2188.   then
  2189.   mov tos, r0
  2190.   stmfd sp !, { r1 }
  2191. next c;
  2192.  
  2193. code -scan      ( ad len c -- ad' len' )
  2194.   ldmfd sp !, { r0, r1 }
  2195.   teq r0, # 0
  2196.   0<> if
  2197.     begin
  2198.       ldrb r2, [ r1 ], # -1
  2199.       cmp r2, tos
  2200.       b eq 1 $
  2201.       sub s r0, r0, # 1
  2202.     0= until
  2203.     sub r1, r1, # 1
  2204. 1 $:
  2205.     add r1, r1, # 1
  2206.   then
  2207.   mov tos, r0
  2208.   stmfd sp !, { r1 }
  2209. next c;
  2210.  
  2211. code compare   ( ad1 len1 ad2 len2 -- -1 | 0 | 1 )
  2212.   ldmfd sp !, { r1, r2, r3 }
  2213.   cmp r2, tos
  2214.     mov cc tos, r2
  2215.   begin
  2216.     ldrb r2, [ r1 ], # 1
  2217.     ldrb r4, [ r3 ], # 1
  2218.     cmp r2, r4
  2219.     b ne 1 $
  2220.     sub s tos, tos, # 1
  2221.   0= until
  2222.   next
  2223. 1 $:
  2224.   mov lt tos, # 1
  2225.   mvn gt tos, # 0
  2226. next c;
  2227.  
  2228. CODE SEARCH     ( ad1 len1 ad2 len2 -- ad3 len3 flag )
  2229.   ldmfd sp !, { r0, r1, r2 }
  2230.   sub sp, sp, # 8
  2231.   teq tos, # 0
  2232.   mvn eq tos, # 0
  2233.   next eq
  2234. 1 $:
  2235.     cmp r1, tos
  2236.   b lt 2 $
  2237.     mov r3, # 0
  2238. 3 $:
  2239.     ldrb r4, [ r2, r3 ]
  2240.     ldrb r5, [ r0, r3 ]
  2241.     cmp r5, r4
  2242.     add ne r2, r2, # 1
  2243.     sub ne r1, r1, # 1
  2244.   b ne 1 $
  2245.     add r3, r3, # 1
  2246.     cmp r3, tos
  2247.   b ne 3 $
  2248.     stmfd sp, { r1, r2 }
  2249.     mvn tos, # 0
  2250.   next
  2251. 2 $:
  2252.   mov tos, # 0
  2253. next c;
  2254.  
  2255. : parse       ( char -- ad len )
  2256.     >r source >in @ /string
  2257.     2dup r> scan nip -
  2258.     dup 1+ >in +! ;
  2259.  
  2260. : .(
  2261.     [char] ) parse type ; immediate
  2262.  
  2263. : \
  2264.     source >in ! drop ; immediate
  2265.  
  2266. : >body
  2267.     cell+ ;
  2268.  
  2269. : body>
  2270.     cell- ;
  2271.  
  2272. : l>name
  2273.     5 - ;
  2274.  
  2275. : n>link
  2276.     5 + ;
  2277.  
  2278. : >name
  2279.     9 - ;
  2280.  
  2281. : name>
  2282.     9 + ;
  2283.  
  2284. : >view
  2285.     8 - ;
  2286.  
  2287. : view>
  2288.     8 + ;
  2289.  
  2290.   1 value    #threads
  2291. 512 constant maxthreads
  2292.  31 constant name-max-chars
  2293.  
  2294. : vlink>voc     ( voc-link-field -- voc-address )
  2295.     cell+ ;
  2296.  
  2297. : voc>vlink     ( voc-address -- voc-link-field )
  2298.     cell - ;
  2299.  
  2300. : voc#threads   ( voc-address -- #threads )
  2301.     2 cells - @ ;
  2302.  
  2303. : vcfa>voc      ( vocabulary-cfa -- voc-address )
  2304.     >body 2 cells+ ;
  2305.  
  2306. : voc>vcfa      ( voc-address -- vocabulary-cfa )
  2307.     2 cells - body> ;
  2308.  
  2309.  
  2310. code "#hash     ( a1 n1 #threads -- n2 )
  2311.   ldmfd sp !, { r0, r1 }
  2312.   mov r3, # 0
  2313.   begin
  2314.     ldrb r2, [ r1 ], # 1
  2315.     eor r3, r2, r3, lsl # 1
  2316.     sub s r0, r0, # 1
  2317.   0= until
  2318.   sub tos, tos, # 1
  2319.   and tos, tos, r3
  2320.   mov tos, tos, lsl # 2
  2321. next c;
  2322.  
  2323. code nfa-count        ( ad -- ad' len )
  2324.   ldrb r0, [ tos ]
  2325.   and r0, r0, # 63
  2326.   sub tos, tos, r0
  2327.   stmfd sp !, { tos }
  2328.   mov tos, r0
  2329. next c;
  2330.  
  2331. code search-1wordlist ( ad len wid -- 0 | cfa f )
  2332.   ldmfd sp !, { r0, r1 }
  2333.   teq r0, # 0
  2334.   mov eq tos, # 0
  2335.   begin
  2336.     begin
  2337.       ldr ne tos, [ tos ]
  2338.       teq ne tos, # 0
  2339.       next eq
  2340.       ldrb r3, [ tos, # -5 ]
  2341.       and r3, r3, # 31
  2342.       cmp r3, r0
  2343.     0= until
  2344.     sub r2, tos, # 5
  2345.     sub r2, r2, r3
  2346.     begin
  2347.       sub s r3, r3, # 1
  2348.     u>= while
  2349.       ldrb r4, [ r2, r3 ]
  2350.       ldrb r5, [ r1, r3 ]
  2351.       cmp r4, r5
  2352.     0<> until                  2swap
  2353.   again
  2354.     then
  2355.   add r2, tos, # 4
  2356.   stmfd sp !, { r2 }
  2357.   ldrb r3, [ tos, # -5 ]
  2358.   and s r3, r3, # &80
  2359.   mov ne tos, # 1
  2360.   mvn eq tos, # 0
  2361. next c;
  2362.  
  2363. : search-wordlist      ( addr len wid -- 0 | cfa flag )
  2364.     >r 2dup r@ voc#threads "#hash r> + search-1wordlist ;
  2365.  
  2366. : (find)       ( string -- string FALSE | cfa flag )
  2367.     dup c@ 0= if 0 exit then
  2368.     context
  2369.     begin   dup @                   \ while not at end of list
  2370.     while   dup 2@ <>               \ and not the same vocabulary
  2371.                                     \ as NEXT time
  2372.       if over count name-max-chars min
  2373.         2 pick @ search-wordlist ?dup
  2374.         if      2swap 2drop EXIT then    \ found it, so we're done searching
  2375.       then  cell+                   \ step to next vocabulary
  2376.     repeat  drop
  2377.     FALSE  ;
  2378.  
  2379. defer find        ' (find) is find
  2380.  
  2381. : defined
  2382.     bl word ?uppercase find ;
  2383.  
  2384. : immediate
  2385.     last @ 128 toggle ;
  2386.  
  2387. : hide
  2388.     last @ n>link @
  2389.     current @
  2390.     last @ nfa-count
  2391.     current @ 2 cells- @
  2392.     "#hash + ! ;
  2393.  
  2394. : reveal
  2395.     last @ n>link
  2396.     current @
  2397.     last @ nfa-count
  2398.     current @ 2 cells- @
  2399.     "#hash + ! ;
  2400.  
  2401. : literal
  2402.     compile lit , ; immediate
  2403.  
  2404. : char
  2405.     bl word 1+ c@ ;
  2406.  
  2407. : [char]
  2408.     char [compile] literal ; immediate
  2409.  
  2410. : '
  2411.     defined 0= ?missing ;
  2412.  
  2413. : [']
  2414.     ' [compile] literal ; immediate
  2415.  
  2416. : [compile]
  2417.     ' compile, ; immediate
  2418.  
  2419. : postpone
  2420.     defined dup 0= ?missing
  2421.     0< if compile compile then
  2422.     compile, ; immediate
  2423.  
  2424. defer \n->crlf     ' 2drop is \n->crlf
  2425.  
  2426. : ,"
  2427.     [char] " parse here >r dup c,
  2428.     dup allot r@ 1+ swap move 0 c, align r> count \n->crlf ;
  2429.  
  2430. code (("))        ( -- c-string )
  2431.   stmfd sp !, { tos }
  2432.   ldmfd rp !, { tos }
  2433.   mov r0, tos
  2434.   ldrb r1, [ r0 ], # 5
  2435.   add r0, r1, r0
  2436.   bic r0, r0, # 3
  2437.   stmfd rp !, { r0 }
  2438. next c;
  2439.  
  2440. : (c")
  2441.     ((")) ;
  2442.  
  2443. : c"
  2444.     compile (c") ," ; immediate
  2445.  
  2446. : (s")
  2447.     ((")) count ;
  2448.  
  2449. : s"
  2450.         state @
  2451.         if      compile (s")  ,"
  2452.         else    [char] " word
  2453.                 temp$ over c@ 1+ move
  2454.                 temp$ count
  2455.         then ; immediate
  2456.  
  2457. : (.")
  2458.     ((")) count type ;
  2459.  
  2460. : ."
  2461.     compile (.") ," ; immediate
  2462.  
  2463. : catch       ( cfa -- flag )
  2464.     sp@ >r
  2465.     lp @ >r
  2466.     handler @ >r
  2467.     rp@ handler !
  2468.     execute
  2469.     r> handler !
  2470.     r> r> 2drop 0 ;
  2471.  
  2472. : throw        ( n -- )
  2473.     ?dup
  2474.     if handler @ rp!
  2475.       r> handler !
  2476.       r> lp !
  2477.       r> swap >r sp! drop
  2478.       r>
  2479.     then ;
  2480.  
  2481. : abort
  2482.     -1 throw ;
  2483.  
  2484. : (abort")
  2485.     ((")) swap
  2486.     if msg !
  2487.       -2 throw
  2488.     then drop ;
  2489.  
  2490. : abort"
  2491.     compile (abort") ," ; immediate
  2492.  
  2493. : ?exec
  2494.     state @ abort" execution only" ;
  2495.  
  2496. : ?comp
  2497.     state @ 0= abort" compilation only" ;
  2498.  
  2499. : ?pairs
  2500.     xor abort" conditionals not paired" ;
  2501.  
  2502. : >mark
  2503.     here 0 , ;
  2504.  
  2505. : >resolve
  2506.     here swap ! ;
  2507.  
  2508. : <mark
  2509.     here ;
  2510.  
  2511. : <resolve
  2512.     , ;
  2513.  
  2514. : ahead
  2515.     >mark 2 ; immediate
  2516.  
  2517. : if
  2518.     ?comp compile ?branch >mark 2 ; immediate
  2519.  
  2520. : else
  2521.     ?comp 2 ?pairs compile branch >mark
  2522.     swap >resolve 2 ; immediate
  2523.  
  2524. : then
  2525.     ?comp 2 ?pairs compile _then >resolve ; immediate
  2526.  
  2527. : endif
  2528.     ?comp 2 ?pairs >resolve ; immediate
  2529.  
  2530. : begin
  2531.     compile _begin
  2532.     ?comp <mark 1 ; immediate
  2533.  
  2534. : until
  2535.     ?comp 1 ?pairs
  2536.     compile _until <resolve ; immediate
  2537.  
  2538. : again
  2539.     ?comp 1 ?pairs
  2540.     compile _again <resolve ; immediate
  2541.  
  2542. : while
  2543.     ?comp
  2544.     compile _while >mark 2
  2545.     2swap ; immediate
  2546.  
  2547. : repeat
  2548.     ?comp
  2549.     1 ?pairs
  2550.     compile _repeat <resolve
  2551.     2 ?pairs >resolve ; immediate
  2552.  
  2553. : do
  2554.     ?comp
  2555.     compile (do) >mark 3 ; immediate
  2556.  
  2557. : ?do
  2558.     ?comp
  2559.     compile (?do) >mark 3 ; immediate
  2560.  
  2561. : loop
  2562.     ?comp
  2563.     3 ?pairs
  2564.     compile (loop) dup cell+ <resolve
  2565.     >resolve ; immediate
  2566.  
  2567. : +loop
  2568.     ?comp
  2569.     3 ?pairs
  2570.     compile (+loop) dup cell+ <resolve
  2571.     >resolve ; immediate
  2572.  
  2573. : case
  2574.     compile _case
  2575.     ?comp 0 ; immediate
  2576.  
  2577. : of
  2578.     ?comp
  2579.     compile _of >mark 4 ; immediate
  2580.  
  2581. : endof
  2582.     ?comp
  2583.     4 ?pairs
  2584.     compile _endof >mark
  2585.     swap >resolve 5 ; immediate
  2586.  
  2587. : endcase
  2588.     ?comp
  2589.     compile _endcase
  2590.     begin ?dup
  2591.     while 5 ?pairs >resolve
  2592.     repeat ; immediate
  2593.  
  2594. : link,
  2595.     align here over @ , swap ! ;
  2596.  
  2597. : call! ( to from -- )
  2598.     dup>r ad>of &eb000000 or r> ! ;
  2599.  
  2600. : call,
  2601.     here cell allot call! ;
  2602.  
  2603. variable loadline
  2604. variable ?loading
  2605.  
  2606. : "name,        ( a1 n1 -- )    \ align and compile name a1,n1 at here
  2607.     name-max-chars min align
  2608.     dup 0= abort" Need a NAME to create!"
  2609.     2>r
  2610.     caps @
  2611.     if      2r@ upper
  2612.     then    3 2r@ nip 3 and - allot \ pre-align for name length
  2613.     2r@ current @ search-wordlist
  2614.     if      warning @
  2615.             if      cr ?loading @
  2616.                     if      ." From file: " cur-file count type
  2617.                             ."  word: "
  2618.                     then    2r@ type ."  isn't unique "
  2619.             then    drop
  2620.     then    2r> >r here r@ move r@ allot here last ! r> c, ;
  2621.  
  2622. : view,         ( -- )          \ compile the view field
  2623.     ?loading @
  2624.     if      loadline @ ,  else    -1 ,  then    ;
  2625.  
  2626. : _"header      ( a1 n1 -- )    \ build a hashed header from a1,n1
  2627.     name-max-chars min 2dup 2>r "name, view,
  2628.     current @ dup  2r> rot voc#threads "#hash + link, ;
  2629.  
  2630. defer "header   ' _"header is "header
  2631.  
  2632. : memory-total
  2633.     [ memtotal ] literal @ ;
  2634.  
  2635. : ?memchk       ( n1 -- )       \ test to see if we have enough memory
  2636.     here +  memory-total ibfull - 512 -  U> abort" Out of memory!" ;
  2637.  
  2638. : _header       ( -<name>- )    \ build a header, but check available memory
  2639.     2000 ?memchk
  2640.     bl word count "header ;
  2641.  
  2642. defer header        ' _header is header
  2643.  
  2644. : create
  2645.     header dovar call, ;
  2646.  
  2647. variable csp
  2648.  
  2649. : !csp
  2650.     sp@ csp ! ;
  2651.  
  2652. : ?csp
  2653.     sp@ csp @ xor abort" stack changed" ;
  2654.  
  2655. : (;code)
  2656.     r> last @ name> call! ;
  2657.  
  2658. : does>         ( -- )
  2659.     compile (;code)
  2660.     &e3ce03ff , \ bic r0, link, # &fc000003
  2661.     dodoes here ad>of
  2662.     &eb000000 or , ; immediate
  2663.  
  2664. : ]
  2665.     state on ;
  2666.  
  2667. : [
  2668.     state off ; immediate
  2669.  
  2670. : _: 
  2671.     header hide !csp docol call, ] ;
  2672.  
  2673. : :noname
  2674.     align here !csp docol call, ] ;
  2675.  
  2676. defer :           ' _: is :
  2677.  
  2678. : ;
  2679.     ?comp ?csp
  2680.     reveal compile unnest [compile] [ ; immediate
  2681.  
  2682. : recurse
  2683.     ?comp last @ name> compile, ; immediate
  2684.  
  2685. : constant
  2686.     header docon call, , ;
  2687.  
  2688. : variable
  2689.     create 0 , ;
  2690.  
  2691. : defer
  2692.     header &e51ff004 , compile noop
  2693.     here defer-list @ , defer-list ! compile noop ;
  2694.  
  2695. : definitions
  2696.     context @ current ! ;
  2697.  
  2698. defer boot  ' noop is boot
  2699.  
  2700. : 2constant
  2701.     create , , ;code also assembler
  2702.     bic link, link, # &fc000003
  2703.     ldmfd link, { r0, r1 }
  2704.     stmfd sp !, { r1, tos }
  2705.     mov tos, r0
  2706.     next c; previous drop
  2707.  
  2708. : 2variable
  2709.     variable 0 , ;
  2710.  
  2711. code @(ip)
  2712.   stmfd sp !, { tos }
  2713.   ldr r0, [ rp ]
  2714.   ldr tos, [ r0 ], # 4
  2715.   str r0, [ rp ]
  2716. next c;
  2717.  
  2718. code >is
  2719.   add tos, tos, # 4
  2720. next c;
  2721.  
  2722. : (is)
  2723.     @(ip) >is ! ;
  2724.  
  2725. : is
  2726.     state @
  2727.     if compile (is) ' compile,
  2728.     else ' >is !
  2729.     then ; immediate
  2730.  
  2731. : value
  2732.     header
  2733.     dovalue call,  ,  dovalue! call,  dovalue+! call, ;
  2734.  
  2735. : to
  2736.     ' cell+ cell+
  2737.     state @
  2738.     if , exit
  2739.     then execute ; immediate
  2740.  
  2741. : +to
  2742.     ' cell+ cell+ cell+
  2743.     state @
  2744.     if , exit
  2745.     then execute ; immediate
  2746.  
  2747. : &of
  2748.     ' cell+
  2749.     state @
  2750.     if compile lit , then ; immediate
  2751.  
  2752. : query
  2753.     0 to source-id tib dup 256 accept
  2754.     (source) 2!
  2755.     >in off ;
  2756.  
  2757. : ?stack
  2758.     depth 0< abort" stack underflow" ;
  2759.  
  2760. : _number,
  2761.     double? 0=
  2762.     if drop then
  2763.     state @
  2764.     if double? 0=
  2765.       if [compile] literal
  2766.       else swap [compile] literal [compile] literal
  2767.       then
  2768.     then ;
  2769.  
  2770. defer number,
  2771. ' _number, is number,
  2772.  
  2773. : _interpret
  2774.     begin
  2775.       bl word dup c@
  2776.     while
  2777.       ?uppercase find ?dup
  2778.       if state @ =
  2779.         if compile, else execute ?stack then
  2780.       else number number,
  2781.       then
  2782.     repeat drop ;
  2783.  
  2784. defer interpret
  2785. ' _interpret is interpret
  2786.  
  2787. : evaluate
  2788.     source 2>r >in @ >r source-id >r
  2789.     (source) 2! >in off
  2790.     -1 to source-id
  2791.     interpret
  2792.     r> to source-id
  2793.     r> >in ! 2r> (source) 2! ;
  2794.  
  2795. : wait
  2796.     key 27 =
  2797.     if ." ok" abort then ;
  2798.  
  2799. : start/stop
  2800.     key? if wait wait then ;
  2801.  
  2802. : refill
  2803.     source-id ?dup
  2804.     if 1+
  2805.       if 1 loadline +!
  2806.         tib dup 260
  2807.         source-id read-line abort" read error"
  2808.         if (source) 2! >in off true exit then
  2809.         2drop
  2810.       then false exit
  2811.     then cr query true ;
  2812.  
  2813. : linkfile
  2814.     ?loading @
  2815.     if loadfile link,
  2816.       count here place
  2817.       here c@ 2 + aligned allot
  2818.     else drop
  2819.     then ;
  2820.  
  2821. variable echo
  2822. defer stack-check    ' noop is stack-check
  2823. variable start-line
  2824.  
  2825. : >line
  2826.     1- 0max ?dup
  2827.     if 0 do refill drop loop
  2828.     then ;
  2829.  
  2830. : (fload)
  2831.     start-line @ >line start-line off
  2832.     begin refill
  2833.     while echo @
  2834.       if cr source type start/stop then
  2835.       interpret stack-check
  2836.     repeat ;
  2837.  
  2838. create openbuf 260 allot
  2839.  
  2840. : _"open
  2841.     2dup 2>r openbuf place
  2842.     openbuf count r/o open-file dup 0=
  2843.     ?loading @ 0= or
  2844.     if 2r@ cur-file place then
  2845.     2r> pocket place ;
  2846.  
  2847. defer "open      ' _"open is "open
  2848.  
  2849. : $open
  2850.     count "open ;
  2851.  
  2852. code file-position ( fileid -- ud ior )
  2853.   mov r0, # 0
  2854.   mov r1, tos
  2855.   swi x " OS_Args"
  2856.   mov vc tos, # 0
  2857.   mvn vs tos, # 0
  2858.   stmfd sp !, { r0, r2 }
  2859. next c;
  2860.  
  2861. code reposition-file ( ud fileid -- ior )
  2862.   mov r1, tos
  2863.   ldmfd sp !, { r0, r2 }
  2864.   mov r0, # 1
  2865.   swi x " OS_Args"
  2866.   mov vc tos, # 0
  2867.   mvn vs tos, # 0
  2868. next c;
  2869.  
  2870. code file-size ( fileid -- ud ior )
  2871.   mov r0, # 2
  2872.   mov r1, tos
  2873.   swi x " OS_Args"
  2874.   mov vc tos, # 0
  2875.   mvn vs tos, # 0
  2876.   mov r0, # 0
  2877.   stmfd sp !, { r0, r2 }
  2878. next c;
  2879.  
  2880. code resize-file ( ud fileid -- ior )
  2881.   mov r1, tos
  2882.   ldmfd sp !, { r0, r2 }
  2883.   mov r0, # 3
  2884.   swi x " OS_Args"
  2885.   mov vc tos, # 0
  2886.   mvn vs tos, # 0
  2887. next c;
  2888.  
  2889. : include-file
  2890.     loadfile @ cell+ >r                 ?loading @ >r
  2891.     loadline @ >r                       >in @ >r
  2892.     source-id dup>r swap                to source-id
  2893.     source 2>r                          filebuf 0 (source) 2!
  2894.     ?loading on                         pocket ?uppercase linkfile
  2895.     loadline off
  2896.     dup 0>
  2897.     if dup file-position 2drop inlength -
  2898.       0 rot reposition-file drop
  2899.     else drop
  2900.     then
  2901.     ibfull to iblen  0 to inlength
  2902.     ['] (fload) catch
  2903.     source-id close-file drop
  2904.     ibfull to iblen  0 to inlength
  2905.     2r> (source) 2!                     r> to source-id
  2906.     throw
  2907.     r> >in !                            r> loadline !
  2908.     r> ?loading !                       align
  2909.     r> linkfile
  2910.     ?loading @
  2911.     if loadfile @ cell+
  2912.       count 255 min cur-file place
  2913.       source nip >in !
  2914.     then ;
  2915.  
  2916. : included
  2917.     "open abort" file not found"
  2918.     include-file ;
  2919.  
  2920. : fload
  2921.     bl word count included ;
  2922.  
  2923. : include
  2924.     bl word count included ;
  2925.  
  2926. : ok
  2927.     cur-file count included ;
  2928.  
  2929. : ((
  2930.     begin bl word dup @ &ffffff and
  2931.       &292902 <>
  2932.     while c@ 0=
  2933.       if refill 0= abort" missing ))" then
  2934.     repeat drop ; immediate
  2935.  
  2936. : \s
  2937.     2r> 2drop [compile] \ ; immediate
  2938.  
  2939. defer edit-error  ' noop is edit-error
  2940.  
  2941. : _reset-stacks
  2942.     sp0 @ sp! ;
  2943.  
  2944. defer reset-stacks  ' _reset-stacks is reset-stacks
  2945.  
  2946. : _message
  2947.     base @ >r decimal cr ." Error: "
  2948.     pocket count type space
  2949.     dup -2 =
  2950.     if drop msg @ count type
  2951.     else ." Error #" .
  2952.     then ?loading @
  2953.     if cr ." File: " loadfile @ cell+ count type
  2954.       ."  at line: " loadline ?
  2955.       edit-error
  2956.     then r> base ! ;
  2957.  
  2958. defer message       ' _message is message
  2959.  
  2960. variable .smax      8 .smax !-t
  2961.  
  2962. : .s
  2963.     ?stack depth .smax @ min dup
  2964.     if ." [" depth 1- 1 .r ." ] "
  2965.       begin dup pick 1 .r base @ 16 =
  2966.         if ." h" then
  2967.         space 1- dup 0=
  2968.       until
  2969.     else ."  empty "
  2970.     then drop ;
  2971.  
  2972. : query-interpret
  2973.     query space interpret ;
  2974.  
  2975. : quit  ( -- )
  2976.     rp0 @ rp!
  2977.     begin   [compile] [
  2978.       ?loading off
  2979.       begin   cr ['] query-interpret catch  ?dup 0=
  2980.       while   state @ 0=
  2981.         if      ."  ok"  depth .smax @ min 0
  2982.           ?do  [char] . emit  loop
  2983.         then
  2984.       repeat
  2985.       dup 1+  ( no message on abort )
  2986.       if  console message  then
  2987.       reset-stacks
  2988.     again ;
  2989.  
  2990. : docmdtail
  2991.     [ commline ] literal @
  2992.     255 bl scan 2dup 0 scan nip - evaluate ;
  2993.  
  2994. defer commandline    ' docmdtail is commandline
  2995.  
  2996. : cold
  2997.     ['] boot catch 0=
  2998.     if ['] commandline catch ?dup
  2999.       if dup 1+
  3000.         if message then
  3001.         sp0 @ sp!
  3002.       then quit
  3003.     then bye ;
  3004.  
  3005. code largest    ( a1 n1 --- a2 n2 )
  3006.   ldr r0, [ sp ]
  3007.   mov r1, # 0
  3008.   mov r2, r0
  3009.   begin
  3010.     ldr r3, [ r0 ], # 4
  3011.     cmp r3, r1
  3012.       sub hi r2, r0, # 4
  3013.       mov hi r1, r3
  3014.     sub s tos, tos, # 1
  3015.   u<= until
  3016.   str r2, [ sp ]
  3017.   mov tos, r1
  3018. next c;
  3019.  
  3020. \ : dump          ( ad len -- )
  3021. \     base @ >r hex
  3022. \     0 do   cr dup 6 .r space  16 0 do   dup c@ 3 .r 1+   loop
  3023. \     16 +loop   drop  r> base ! ;
  3024.  
  3025. code op@
  3026.   stmfd sp !, { tos }
  3027.   mov tos, op
  3028. next c;
  3029.  
  3030. code op!
  3031.   mov op, tos
  3032.   ldmfd sp !, { tos }
  3033. next c;
  3034.  
  3035. code +ov? ( n1 n2 -- f )
  3036.   ldmfd sp !, { r0 }
  3037.   add s r0, r0, tos
  3038.   mov tos, # 0
  3039.   sub vs tos, tos, # 1
  3040. next c;
  3041.  
  3042. code Wimp_CreateMenu
  3043.   mov r1, tos
  3044.   ldmfd sp !, { r2, r3, tos }
  3045.   swi " Wimp_CreateMenu"
  3046. next c;
  3047.  
  3048. code Wimp_SlotSize ( next cur -- free next cur )
  3049.   mov r0, tos
  3050.   ldmfd sp !, { r1 }
  3051.   swi " Wimp_SlotSize"
  3052.   stmfd sp !, { r1, r2 }
  3053.   mov tos, r0
  3054. next c;
  3055.  
  3056. code OS_Heap ( misc ^blk ^heap reason -- r3 r2 f )
  3057.   mov r0, tos
  3058.   ldmfd sp !, { r1, r2, r3 }
  3059.   swi x " OS_Heap"
  3060.   mvn vs tos, # 0
  3061.   mov vc tos, # 0
  3062.   stmfd sp !, { r2, r3 }
  3063. next c;
  3064.  
  3065. 0 local l0
  3066. 1 local l1
  3067. 2 local l2
  3068. 3 local l3
  3069. 4 local l4
  3070. 5 local l5
  3071. 6 local l6
  3072. 7 local l7
  3073.  
  3074. : .id ( nfa -- )
  3075.     nfa-count type space ;
  3076.  
  3077. init-assembler
  3078. here &8000 ad>of &ea000000 or coldstart !-t
  3079.   swi " OS_GetEnv"
  3080.   adr r2, memtotal
  3081.   str r1, [ r2 ]
  3082.   adr r2, commline
  3083.   str r0, [ r2 ]
  3084.   adr r0, filebuff
  3085.   ldr r2, [ r0 ]
  3086.   adr r0, ' ibfull >body-t
  3087.   str r2, [ r0 ]
  3088.   sub rp, r1, r2                \ rp=RAM limit
  3089.   adr r0, ' inbuf >body-t
  3090.   str rp, [ r0 ]
  3091.   adr r0, rp0
  3092.   str rp, [ r0 ]
  3093.   adr r2, retstack
  3094.   ldr r2, [ r2 ]
  3095.   sub sp, rp, r2
  3096.   adr r0, sp0
  3097.   str sp, [ r0 ]
  3098.   add sp, sp, # 4
  3099.   mov tos, # 0
  3100.   mov r0, # 10                  \ set base to decimal
  3101.   adr r1, base
  3102.   str r0, [ r1 ]
  3103.   b ' cold a;                   \ goto cold colon definition
  3104. 1024 retstack !-t
  3105. 1024 datstack !-t
  3106. 16384 filebuff !-t
  3107.  
  3108.  
  3109. dovoc  resolves <vocabulary>
  3110. ' scan resolves scan
  3111.