Noodlings of a Forth beginner #523
Replies: 6 comments 18 replies
-
Looks nice and tidy! |
Beta Was this translation helpful? Give feedback.
-
Rather than spam topics, I'll post my noodlings here. Here's a Game of Life I ported to durex and just about noodled into paste: 1
\ conway's game of life.
\ for durexforth on the c64.
\ also tested with gforth.
marker ---life---
( see line 1 ) value tests
$ffff 0< constant 16bit
: \( tests if cr hex here u. latest
u. decimal depth . postpone .(
else '.' emit postpone ( then ;
\( syntax )
: ?\ ( 10) if postpone \ then ;
: \c 16bit 0= ?\ ; immediate \ c64
: \g 16bit ?\ ; immediate \ gforth
: \t tests 0= ?\ ; immediate \ testing
: !! ( 10) 0= abort" fail" '.' emit ;
: d= ( 41) rot = -rot = and ;
: t= ( 61) >r rot >r d= r> r> = and ;
\ ( 41) means ( a b c d -- e )
\t 1 !! 2 3 + 5 = !! \ test assert
\t 1 2 1 2 d= !! 1 2 3 1 2 3 t= !!
\( mach )
\c -1 $d40e ! $80 $d412 c! \ init sid
\c : noise ( 01) $d41b c@ \ and read
\c $d41b c@ 8 lshift or ;
\c : lcg ( 11) $7abd * $1b0f + ;
\c : v ( 00) ---life--- v ;
\g : lcg ( 11) $5851f42d4c957f2d *
\g $14057b7ef767814f + ;
\g : noise ( 01) utime + here + lcg ;
\( pure )
: nop ( 00) ;
: pow2 ( 11) 1 swap lshift ;
: %max ( 11) -1 1 rshift 50 */ ;
: lif ( 11) if '#' else '.' then ;
: near ( 12) 2 + dup 3 - ;
: rule ( cur nbors -- next )
2 - ?dup if nip 1 = 1 and then ;
\t 8 pow2 256 = !!
\t \c 25 %max $3fff = !!
\t 6 near 8 5 d= !! \ neighbor bounds
\t 1 2 rule 1 = !! 0 3 rule 1 = !!
\t 1 3 rule 1 = !! 1 5 rule 0 = !!
\( vals )
\ call a life cell a 'lif'.
\ x mod wid, y mod hgt would simulate
\ repeating grid, but 2div 1mul * 11
\ indexes per lif per gen, too much.
0 value wlog \ so restrict to pow2
0 value x& \ dimens and precalc
0 value y& \ bitmasks to mod with.
0 value bck \ already drawn grid.
0 value frn \ next grid to draw.
' nop value 'draw \ exec'd on store.
( lif x y -- lif x y )
: life! ( wlog hlog bck frn -- )
to frn to bck 2dup + pow2 frn
swap 0 fill pow2 1- to y&
dup to wlog pow2 1- to x& ;
\t : 84p! 3 2 pad pad 32 + life! ;
\t 84p! y& 3 = !! x& 7 = !! wlog 3 = !!
\( basic )
: cols ( 02) x& 1+ 0 ;
: rows ( 02) y& 1+ 0 ;
: flip ( 00) frn bck to frn to bck ;
: ?cr ( 10) if cr then ;
\g : ?home ( 10) ?cr ;
\c : ?home ( 10) if 19 emit then ;
: put ( lif x y -- lif x y )
2dup or 0= ?home >r
2dup 0= ?cr lif emit r> ; \ to 'draw
\t 84p! cols 8 0 d= !! rows 4 0 d= !!
\t bck pad = !! flip frn pad = !!
\t 1 2 3 put 1 2 3 t= !!
\( index )
: offs ( x y -- offset )
>r x& and r> y& and wlog lshift or ;
: bck@ ( 21) offs bck + c@ ;
: frn! ( 30) 'draw execute
offs frn + >r 1 and r> c! ;
\ 1 lif = 1 byte. i wrote bit-addr'ed
\ ver but it was slooow. todo asm?
\t 84p! 2 3 offs 26 = !!
\t -5 11 offs 27 = !!
\t 1 2 3 frn! flip 2 3 bck@ 1 = !!
\( store )
: seeded ( density seed1 -- seed2 )
rows do cols do lcg 2dup u>
i j frn! loop loop nip ;
: pct ( 10) %max noise seeded drop ;
: step ( 00) flip rows do cols do
i j bck@ 0 j near do j near do
i j bck@ + loop loop over - rule
i j frn! loop loop ;
\t 84p! 50 %max 42 seeded drop flip
\t \g 1 0 bck@ !! 0 0 bck@ 0= !!
\t \c 0 1 bck@ !! 1 1 bck@ 0= !!
\t step flip .( todo )
\( user )
: glider ( 00) 1 1 0 frn! 1 2 1 frn!
1 0 2 frn! 1 1 2 frn! 1 2 2 frn! ;
create buf 9 1+ pow2 allot
: buf! ( 20) 2dup + pow2
buf + buf life! ;
: small ( 00) 3 3 buf! ;
: wide ( 00) 5 3 buf! ;
: medium ( 00) 4 4 buf! ;
: big ( 00) 5 4 buf! ;
\g : kik ( 01) 0 ;
\c : kik ( 01) 0 key? if key + then ;
: go ( 00) begin step kik until ;
: gens ( 10) 0 ?do step kik
if unloop exit then loop ;
\( intro )
\g (
: help ."
conway's game of life.
some words and phrases
help [this text] v [edit program]
words [everything available]
small medium big
20 pct glider 3 gens go
examples to try
small glider 5 gens
big 33 pct go
" ;
\g )
\( ok. key?) \t key drop
small glider ' put to 'draw
\c help
\g 5 gens big 33 pct go |
Beta Was this translation helpful? Give feedback.
-
Continuing a Youtube comment thread. Ultimately the branch proves faster than futzing with computing addresses and the like. hex
marker ---
: v [ 0 lda,# tax, ] --- v ;
: rvs c7 c! ;
: rndf d41b c@ 80 < ;
: tri IF a9 9b ELSE df 97 THEN ;
: one dup rvs rndf tri emit emit ;
: row 0= #40 0 DO 0= one LOOP ;
: go 0 BEGIN row AGAIN ;
-1 d40e ! 80 d412 c! \ sid3 noise
0c d021 c! 15 d018 c! \ bg, gfx cset
go Context from the video: this prints a pattern of triangles I think resembles a mountain range. It derives from 10print but I'd like to call it "Ian Mountains" after the original author. |
Beta Was this translation helpful? Give feedback.
-
A couple noodles today, the first is definitely more practical. : .name name>string type space ;
:noname more .name 1 ;
: words page literal dowords ;
:noname ( xt nt -- xt 1 )
2dup swap execute
IF more .name ELSE drop THEN 1 ;
: wordset ( xt -- ) ( xt: nt -- flag )
page literal dowords drop ;
\ nametoken range predicates (v4)
: nt parse-name find-name ;
nt does> nt -branch nt :noname
: mine? literal < ;
: asm? literal literal within ;
: base? dup mine? swap asm? or 0= ;
: mywords ['] mine? wordset ;
: asmwords ['] asm? wordset ;
: basewords ['] base? wordset ;
hide mine? hide asm? hide base?
The second one started with the thought that the extra load/store pair in : cmv, tuck + lda,x + sta,x ;
: mv, 2dup lsb cmv, msb cmv, ;
: nipdup [ 1 0 mv, ] ; \ ab-bb
: drpdup [ 0 1 mv, ] ; \ ab-aa
: >nipdup> [ 2 1 mv, ] ; \ abc-bbc
: >drpdup> [ 1 2 mv, ] ; \ abc-aac
: drpovr [ 0 2 mv, ] ; \ abc-aba
: >nip>tck [ 2 0 mv, ] ; \ abc-cbc
: nipovr nipdup drpovr ; \ abc-aca
: >nip> >nipdup> nipdup drop ;
: nipnip >nip>tck 2drop ;
: ovrswp [ dex, ] drpdup >drpdup> ;
: 2pck [ dex, 0 3 mv, ] ;
: 3dup 2pck 2pck 2pck ; I started to write |
Beta Was this translation helpful? Give feedback.
-
I was thinking about transient compile-time-only constants and came up with this, haven't tested it yet: latest
( ... main program ... )
here 4000 allot
: eq create , immediate
does> @ postpone literal ;
40 eq w 25 eq h 1000 eq wh
( ... more constants ... )
to here
( ... use w h wh ... )
to latest |
Beta Was this translation helpful? Give feedback.
-
I wrote these fast, control-code-safe printing loops for my editor: : 1em [ w lda,(y) $a1 cmp,# 10 bcs,
$7f cmp,# 4 bcs, bl cmp,# 2 bcs,
'?' lda,# iny, $e716 jmp, ] ;
: 39em [ lsb lda,x w sta,
msb lda,x w 1+ sta, 0 ldy,# ]
1em [ 39 cpy,# -7 bne, ] ;
: lines 1- 0 ?DO 39em 1em 40 + LOOP
39em drop ; It's fun to use them to browse through memory: : at-xy xr ! yr ! $e50c sys ;
: bb dup 0 0 at-xy 25 lines
999 + 0 22 at-xy ;
$2e2e 0 bb The $2e2e on the bottom of the stack shows up as two dots near the beginning of zeropage. Press [down]bb[return] to continue paging forward. |
Beta Was this translation helpful? Give feedback.
-
As requested, here's my
compare
from #520. See the standard.And tests:
For anyone interested. Probably not suitable for inclusion in durexForth as-is.
Not sure if this should be added to #428? Probably relevant at least.
Beta Was this translation helpful? Give feedback.
All reactions