Liara Forth, an "ANSI(ish) initial Forth" for the W65C265SXB

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
nyef
Posts: 235
Joined: 28 Jul 2013

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by nyef »

scotws wrote:
Thanks for all the improvements, though I am getting an headache for slapping my forehead with each one. :D Won't get to implement the changes until this evening, so just theoretically -
barrym95838 wrote:

Code: Select all

                tya
                eor.# 0-1

                sec
                adc.dx 00
I assume that's a CLC and not a SEC, or am I not doing the logic in my head right?
No, this is MINUS, so it negates one argument by inverting all the bits and adding one, and then adds it to the other.
scotws wrote:
I've been trying to code Liara so that there is always some form of a working system after every step, starting the point where I got the main loop going, and so far, that has worked. With EVALUATE in place, I can get rid of most of the "scaffolding code" for printing the boot strings (need .( before, of course, but that is now trivial). Next big steps will be CREATE so I can work my way to COLON and SEMICOLON after testing stuff with VARIABLE and CONSTANT. Then things should go faster.
While working on my own (not yet '02 / '816) Forth, I've been following a similar rule: Incremental changes, with a working system at all times. It can take a while to make large changes this way, but at the same time I can set it down whenever and still have something that works.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by barrym95838 »

I have made plenty of 65xx coding errors in the last 35 years, but I don't think this is one of them. Keep the sec ... it's there to finish the job of twos-complementing A, and it's cheaper than inc.a : clc ...

Mike B.
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by BigDumbDinosaur »

I don't recall seeing this anywhere in this topic, but whence the name "Liara" for your Forth implementation?
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by barrym95838 »

Quote:
The name, BTW, comes from the German folk song "Es waren zwei Königskinder" (https://de.wikipedia.org/wiki/Es_waren_ ... nigskinder) about two children of a king who really liked each other, but could never meet because the water was too deep.
Mike B.
scotws
Posts: 576
Joined: 07 Jan 2013
Location: Just outside Berlin, Germany
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by scotws »

BigDumbDinosaur wrote:
I don't recall seeing this anywhere in this topic, but whence the name "Liara" for your Forth implementation?
It's a reference to the computer game Mass Effect. Tali Forth morphed from just liking the name into being named for Tali'Zorah vas Normandy (http://masseffect.wikia.com/wiki/Tali'Zorah_nar_Rayya) - it fit, because she's a quarian, who have to make due with minimal resources, like the little 65c02 BYO breadboard computer it first ran on. When it came time for a bigger, better Forth for the 65816, the obvious choice was Liara T'Soni (http://masseffect.wikia.com/wiki/Liara_T'Soni), an asari (blue women with weird heads), because their technology is far more powerful and advanced.

The fourth installment of Mass Effect named Andromeda (https://www.masseffect.com/) is out the end of March. I'll probably be too busy playing the game with the kids for few weeks to do much other stuff - but might gain a new name for a future Forth :D .
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by BigDumbDinosaur »

scotws wrote:
It's a reference to the computer game Mass Effect...When it came time for a bigger, better Forth for the 65816, the obvious choice was Liara T'Soni (http://masseffect.wikia.com/wiki/Liara_T'Soni)...
Ah-so! I'm not a follower of science fiction or play computer games, so I am ignorant of these strange women and their universe. My place in the cosmos is during the time when my ancestors, armed with spiky tails and powerful jaws, ruled the earth—before that damned meteorite blew the hell out of everything. :evil:
x86?  We ain't got no x86.  We don't NEED no stinking x86!
scotws
Posts: 576
Joined: 07 Jan 2013
Location: Just outside Berlin, Germany
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by scotws »

To prepare for the COMPILE, code that will allow native compiling of words based on their length, I've created a word named WORDS&SIZES that adds the size of CFA+PFA - a word's "code" in bytes - to the output. The idea here is to be able to provide a threshold value up to words will be compiled in native code (with $0 for "never" and $FFFF for "always"). So far, COMPILE, only does brutish subroutine compiling, so high-level words are going to be shorter, but far slower, now than later. Still, this is the very first data on word length:

Code: Select all

d.r 39  d. 27  ud.r 27  ud. 15  .r 42  u.r 30  u. 18  */mod 12  */ 18  /mod 12  / 18  fm/mod 72  sm/rem 67  while 15  until 6  repeat 12  else 21  then 9  if 12  .( 11  ( 11  drop 4  dup 4  swap 5  ! 11  @ 4  over 6  bounds 9  digit? 59  >r 7  r> 7  r@ 8  2drop 6  here 6  execute 10  rot 8  -rot 8  nip 2  tuck 8  \ 4  accept 131  , 11  source-id 6  parse-name 100  refill 50  find-name 86  0 7  1 7  2 7  number 131  >number 92  true 7  false 7  = 11  <> 11  0= 11  < 19  > 19  0< 11  0> 10  0<> 11  1+ 1  1- 1  + 7  - 10  2* 3  c! 15  c@ 11  c, 13  +! 15  and 6  or 6  xor 6  char 23  invert 5  negate 6  max 18  min 18  ' 27  variable 12  constant 25  depth 14  source 12  >in 7  state 7  abs 8  2dup 10  name>string 16  create 114  does> 12  >body 3  allot 40  : 33  ; 24  compile, 18  begin 6  again 21  branch 6  0branch 6  latestxt 15  latestnt 7  [ 2  ] 5  postpone 53  immediate 8  compile-only 8  literal 17  [char] 6  ['] 6  sliteral 74  s" 17  ." 20  cells 3  evaluate 46  base 7  pad 11  . 30  type 32  .s 71  space 6  spaces 12  bl 7  <# 9  # 26  sign 13  #s 8  hold 13  #> 14  cr 6  name>int 8  ? 6  quit 63  parse 50  abort 71  abort" 28  count 14  um* 94  m* 31  * 7  um/mod 80  ud/mod 27  d+ 17  s>d 15  d>s 4  dnegate 19  dabs 6  page 12  unused 11  hex 5  decimal 5  bell 6  wordsize 18  dump 38  words 60  words&sizes 67  cold 123  bye 3
The formatting sucks, of course, I'll figure something better out later. The words from DROP to BYE are hard-coded in the Dictionary, everything after that (that is, at the beginning of this list) is compiled out of high-level Forth code. The RTS instruction is not included in the tally, because native coding will strip it out. R> and >R will be two bytes shorter each because of they'll be a special case in the native compile routine (they're used so often it will be worth it).

Still, some interesting stuff already. NUMBER is amazingly long at 131 bytes, which is the same size as ACCEPT that does all kinds of input filtering.

The word WORDSIZE ( nt -- u ) gives the code size of individual words, so I can experiment on the command line. It's all still very much early days, but the good news is that I can get a feeling for how large stuff is now.
scotws
Posts: 576
Joined: 07 Jan 2013
Location: Just outside Berlin, Germany
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by scotws »

Since Liara is supposed to be fast, we need to cut down the number of JSR/RTS jumps because of their brutal 12 cycle penalty (which is sort of ironic in a STC Forth, but there you go). To figure out how many JSR which word has, I've written a little tool (https://github.com/scotws/LiaraForth/bl ... counter.py) that makes use of the fact that each word in Liara has a xt_word marker to the start of the CFA/PFA and a z_word at the end: It looks for JSR/JMP/JMP.I (that's JMP (ADDR) in tranditional format) and counts then. The list of offenders in pre-alpha looks like this:

Code: Select all

xt_fmmod       : 19 jsr --> 228 cycles
xt_smrem       : 11 jsr --> 132 cycles
xt_dots        : 10 jsr --> 120 cycles
xt_dot         : 10 jsr --> 120 cycles
xt_udmod       :  8 jsr -->  96 cycles
xt_accept      :  8 jsr -->  96 cycles
xt_wordsnsizes :  7 jsr -->  84 cycles
xt_words       :  7 jsr -->  84 cycles
xt_postpone    :  6 jsr -->  72 cycles
xt_at-xy       :  6 jsr -->  72 cycles
xt_hash        :  5 jsr -->  60 cycles
xt_cold        :  5 jsr -->  60 cycles
xt_marker      :  4 jsr -->  48 cycles
xt_dump        :  4 jsr -->  48 cycles
xt_tonumber    :  3 jsr -->  36 cycles
xt_to          :  3 jsr -->  36 cycles
xt_tick        :  3 jsr -->  36 cycles
xt_sliteral    :  3 jsr -->  36 cycles
xt_quit        :  3 jsr -->  36 cycles
xt_dotquote    :  3 jsr -->  36 cycles
xt_abortq      :  3 jsr -->  36 cycles
xt_abort       :  3 jsr -->  36 cycles
xt_squote      :  2 jsr -->  24 cycles
xt_question    :  2 jsr -->  24 cycles
xt_page        :  2 jsr -->  24 cycles
xt_mstar       :  2 jsr -->  24 cycles
xt_does        :  2 jsr -->  24 cycles
xt_constant    :  2 jsr -->  24 cycles
xt_bracketchar :  2 jsr -->  24 cycles
xt_zbranch     :  1 jsr -->  12 cycles
xt_variable    :  1 jsr -->  12 cycles
xt_type        :  1 jsr -->  12 cycles
xt_star        :  1 jsr -->  12 cycles
xt_spaces      :  1 jsr -->  12 cycles
xt_refill      :  1 jsr -->  12 cycles
xt_numbermore  :  1 jsr -->  12 cycles
xt_number      :  1 jsr -->  12 cycles
xt_literal     :  1 jsr -->  12 cycles
xt_lessnumber  :  1 jsr -->  12 cycles
xt_hashs       :  1 jsr -->  12 cycles
xt_evaluate    :  1 jsr -->  12 cycles
xt_defer       :  1 jsr -->  12 cycles
xt_dabs        :  1 jsr -->  12 cycles
xt_create      :  1 jsr -->  12 cycles
xt_colon       :  1 jsr -->  12 cycles
xt_char        :  1 jsr -->  12 cycles
xt_branch      :  1 jsr -->  12 cycles
xt_brackettick :  1 jsr -->  12 cycles
xt_2variable   :  1 jsr -->  12 cycles
So far, there are few surprises. FM/MOD, SM/REM und UD/MOD are not optimized yet, but simple lists of JSR jumps. .S and . (DOT) are "scaffolding" versions that will be replaced by the real thing once I'm out of ALPHA. MARKER definitely needs work. AT-XY looks scary, but those are subroutine jumps to PUT_CHR that would otherwise just be hidden in a loop.

Which shows why this tool is rather limited: If I have a loop that calls JSR once and then run that loop 1000 times, it would only show up once. Still, it's nice to see that the list is rather short, and when I'm further on, each word will have to justify its jumps.
scotws
Posts: 576
Joined: 07 Jan 2013
Location: Just outside Berlin, Germany
Contact:

Re: Liara Forth, an "ANSI(ish) initial Forth" for the W65C26

Post by scotws »

Liara Forth is now in ALPHA at https://github.com/scotws/LiaraForth . Yippie! This means that most of the stuff is there, and lots of things actually do what they are supposed to. If you load the included S28 file and jump to $00:5000, it should work -- this is the version that works in RAM. WORDS gives us:

Code: Select all

see dump within d.r d. ud.r ud. .r u.r */mod */ mod /mod / action-of is defer@ defer! while until repeat else then if .( ( drop dup swap ! @ over bounds digit? >r r> r@ 2drop here execute 2swap 2over rot -rot nip tuck ?dup \ key key? accept , source-id parse-name refill find-name 0 1 2 number >number true false = <> 0= < > 0< 0> 0<> 1+ 1- + - 2* c! c@ c, +! lshift and or xor rshift char invert negate max min move ' variable constant value to depth source >in state abs 2dup name>string create does> >body defer allot : ; compile, begin again branch 0branch /string -trailing latestxt latestnt [ ] postpone immediate compile-only native-compile literal [char] ['] sliteral s" ." cells evaluate output input nc-limit base pad . emit u. type .s space spaces bl <# # sign #s hold #> erase fill cr name>int int>name ? quit parse abort abort" count cmove cmove> um* m* * um/mod ud/mod sm/rem fm/mod d+ d- 2>r 2r> s>d d>s dnegate dabs 2variable 2r@ at-xy page unused hex decimal char+ cell+ chars bell pick wordsize marker do ?do (do) (?do) i j recurse exit leave loop +loop (+loop) unloop words words&sizes align aligned find word cold bye 
Under the hood, it's a mess. However, native compile does work, and you can use the value NC-LIMIT to determine up to which size words should be natively compiled. Currently, it uses Tali Forth's system of an NC flag to allow native compile, but that doesn't make sense, so I'll be rewriting the whole friggin' Dictionary to have two types of exceptions: Force Native Compile (FN, like (DO)) and Never Native Compile (NN). Also, instead of one Dictionary as a linked list, I'll be creating 15 linked lists depending on the length of the word to speed things up (PARSE-NAME returns the length anyway, might as well use it for speed). Then, once we have that and a whole bunch of clean-ups, I'll call the thing BETA and first completely rewrite Tali Forth with the same new design so both can be further developed in lock-step (multitasking, etc).

That's going to take a while, though. Starting Thursday, the kids and I are going to be helping our new best friend Sara Ryder colonize the Andromeda galaxy (https://www.youtube.com/watch?v=KsHHiWqgbw8 if you really want to know), which is going to take a few weeks, and then I'll probably get kicked out of the house to get the garden ready ...
Post Reply