L-Systems

Developer(s): Gregory Harder
Date: 1987
Type: Cassette
Platform(s): TS 1000
Tags: Demo

This program generates L-System fractal curves by iteratively applying production rules to an axiom string, then interpreting the resulting string as turtle-graphics drawing commands. The generator supports a configurable number of directions (stored in arrays C and D for cosine and sine values), multiple production rules, and a user-adjustable stack depth for saving turtle state (position arrays X, Y, and direction array D). A key feature is the “QUIK” display mode, controlled by a POKE to address 21826, which sets the display margin to 31+8*N, providing a speed/visibility tradeoff between FAST and SLOW modes. Machine code routines are called via USR at addresses 19526, 19616, 19627, and 19649 to handle tasks including position updates, string concatenation, and stack-depth calculation. The menu system (line 2000) supports viewing, reversing the display, copying to printer, saving the screen, rerunning, or stopping, with screen save using a DIM B$ array as a buffer.


Program Analysis

Program Structure

The program is organized into clearly delineated REM-labeled sections, with line numbers grouped by function:

Line RangeSectionPurpose
10–100DRAW CURVEIterates A$, dispatches on each character via GOSUB CODE C$*10
420–598Turtle primitivesUPDATE POSITION, turn left/right, stack push/pop, U-turn
600–900CURVE SIZE / displayBounding-box scan, scale factor computation, menu display
1000–1040ERRORString/stack overflow handler
2000–2230MENUInteractive menu: view, reverse, copy, save, run, stop
4000–4930START / INPUTAll user prompts, data generation loop, trig table setup
9990–9995BootstrapSAVE and startup message

L-System Data Generation

The axiom is held in A$. Lines 4700–4800 run a two-level loop: the outer loop counts generation levels (N), and the inner loop (lines 4710–4790) scans every character of the current A$, checks it against each rule letter in K$, and appends either the matching rule string R$(I, TO ) or the literal character to an accumulator S$. After each full pass, S$ replaces A$ via a machine code copy routine. R$ is then freed with DIM R$(Z,Z) to reclaim memory before drawing begins.

Turtle Graphics Dispatch

The drawing loop at lines 10–90 uses the idiom GOSUB CODE C$*10 to jump to a line number derived from the ASCII code of each character in A$. Each character maps to a BASIC subroutine:

  • Line 430: F — step forward (update T, U from C(J), S(J))
  • Line 490: turn left (increment J, wrap modulo D)
  • Line 500: identical to 430 — effectively another forward alias
  • Line 530: stack pop (restore T, U, J from X, Y, D arrays)
  • Line 550: turn right (decrement J, wrap)
  • Line 560: stack push (save T, U, J; increment stack pointer S)
  • Line 570: U-turn (add D/2 to J, wrap)

When C$="F", the actual LPRINT (used here as a drawing primitive in QUIK mode) is conditional on USR 19526, which handles the low-level plot. The scaled displacements F*(T-V) and F*(U-W) are passed via POKEs to addresses 16380–16381 for the machine code routine.

QUIK Display Mode

The program introduces a “QUIK” mode by POKEing address 21826 (the system variable controlling the display file margin) with the value 31+8*N, where N is user-supplied. A value of 31 gives full SLOW-mode display; larger values progressively suppress display refresh, approaching FAST mode speed. This is an undocumented technique that allows partial display updates without fully suppressing the screen, giving a visible but accelerated rendering.

Machine Code Routines

Four USR addresses are used, each serving a distinct role:

AddressPurpose
19526Plot/draw step — executes the actual pixel draw and returns flag
19616String append — used in data generation to build S$
19627String copy — copies S$ back to A$ after each generation
19649Stack depth query — returns maximum safe stack size L for DIM X/Y/D
21845Keypress read — used at line 4580 to wait for R, C, or any key

The machine code is embedded in the REM statements at lines 0–3, which is the standard technique for storing binary data in BASIC programs of this era.

Variable Conventions and Initialization

Line 4010 sets T=NOT PI, which evaluates to 0 (since PI is non-zero and NOT of any non-zero number is 0 in this dialect). Line 4020 sets J=PI/PI, giving 1. These are used as the constants 0 and 1 throughout, avoiding literal digits where possible — a minor obfuscation and memory-saving technique. The variable Z is set to J (i.e., 1) at line 4120, and O is set to T (i.e., 0) at line 4090, serving as named zero/one aliases for array base indices and coordinates.

Bounding Box and Scaling

Lines 600–700 perform a dry run of the turtle over A$ to compute the bounding box (Q=Xmax, R=Ymax, V=Xmin, W=Ymin). The scale factor F is then set to the smaller of 191/(R-W) and 255/(Q-V), fitting the curve to the display area with correct aspect ratio. This two-pass approach (size scan then draw) ensures the curve is always centered and maximally scaled.

Menu and Screen Save

The menu at line 2000 uses INKEY$ polling (line 2050–2060) restricted to codes “1”–”6″. Option 4 (Save Screen) prompts for a filename via INPUT S$ and executes SAVE S$,S — saving the screen memory block. A DIM B$ array is used as a screen buffer proxy in the QUIK-mode LPRINT calls, which write display data directly to the B$ storage area in memory.

Notable Idioms and Anomalies

  • GOTO VAL "4E3" and similar — using VAL of a string representation of a line number is a standard memory optimization, avoiding storage of a large integer literal.
  • IF USR H THEN ... — used extensively as a conditional execution guard; since H=20000 and the machine code at that address presumably always returns non-zero (or zero to suppress output in FAST mode), this gates SLOW-mode-only output.
  • Line 4470: IF VAL "D/2-INT(D/2)" THEN GOTO VAL "4460" — enforces that D is even, required because the U-turn primitive adds D/2 to J.
  • Line 4750–4760: The inner-rule lookup uses NEXT I inside an IF — a classic ZX BASIC technique to break out of a FOR loop early by exhausting the loop variable.
  • Line 2020 and 4150: POKE VAL "21826",VAL "31" resets the margin to normal before menu display, ensuring readable output before switching back to QUIK mode.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   0 REM [C][O][R][E]█[V][3][.][0][1]## GOSUB #                                <> DIM LN F? CLEAR#OUORND[S]C IF TAN LN [M]RNDY2 GOSUB #<>5▟▝TAN  CLEARACS #▚/▖ CLEARACS #LEN LN [M]RND<>5<>RNDTAN  NEXT  CLEARACS  #: NEXT Y▘4▒ CLEARACS #LEN : PRINT Y▘# ( CLEAR▟W4 CLEAR▞"" CLEARACS ##C▝▞[K])4 5 4<>5:INKEY$ /▒)4 ▌ASN 1INKEY$ ;# GOSUB ###[:]"" GOSUB # E£RND) RUN ▙;Y2 GOSUB #Y PRINT ▘▛▝ CLEARACS ##CODE [P]▝LN [>]▝LN  NEW#<>5<>RND#[8]▝ PRINT # RETURN,C▝INT / LET TAN  SCROLLLN #? FASTLN LN + LPRINT TAN  SCROLLLN #?#[B]:LN #INKEY$  PRINT LN #INKEY$ 7LN #INKEY$ # LET #TAN  SCROLL RETURN#C▀ RETURN;""6-RNDTAN  TO / PAUSE Y3[)]K▝INT (Y[Z][(]SQR INT 2LN #INKEY$ LN #INKEY$ / INPUT LN #INKEY$ /[H]LN #INKEY$ / SLOW5  6 RETURNZA4##<▘ COPY*Q  GOSUB [K]TAN A ##▞▌ACS 9ACS =( IF ,,▘ 4,,TAN LN [~~]INKEY$ ##ACS ZACS ZACS Z##STR$ LN [J]INKEY$  LET J NEW▛W#TAN LN [>]INKEY$ ##LN #INKEY$ VAL LN #INKEY$ AT LN [J]INKEY$ #TAN 2 COPY/▝2 STR$ LN [*]INKEY$ SGN  GOSUB # UNPLOT ZLN CODE INKEY$ ##?( CLEARACS .*PI▌4▝▞▒▛( CLEAR#TAN Y COPY/▘[J] CLEARACS #[:]MWRNDLN [*]INKEY$ # RETURN,4▛ GOSUB # UNPLOT ZLN [*]INKEY$ ## GOSUB # UNPLOT Z6 UNPLOT ZVAL #[)]-▘K▖ GOSUB #- COPY4▝-  FAST# CLEAR#Y LET [(]2▘K▖ GOSUB #2 COPY4▝2  CLEAR#X#[W]S▞##- /▝2  GOSUB #ZRND84▘96INKEY$ RND#[B]3#A 6#RNDAT VAL Y[Z][(] CLEAR#W CLEARACS ##4▌LN  IF INKEY$ /▀LN 7# CLEAR#INKEY$ ▞  CLEAR###,, CLEAR## GOSUB #ZRND CLEAR#PI GOSUB PIS▛ CLEAR## GOSUB #XRNDAT #▙##▄# CLEARO#UPIRND CLEAR[Y]#4[U]TAN LN #INKEY$ LN 4+ LOAD K LET $[M]H?▖O#[~~]+▞(## FOR 5  ACS TACS 3K▘; FOR D FOR ( POKE TAN Y COPY/▘[J]MWRND CLEARACS #[-]7LN [>]INKEY$ 5[+]▘6#RNDI 6#RND#6INKEY$ RND GOSUB # UNPLOT Z GOSUB ##RND FASTLN #INKEY$  LPRINT #6#RND6#RNDLN #INKEY$ CBLN #INKEY$ LN #INKEY$ M#RNDLN #INKEY$ C;LN #INKEY$ LN AT PI GOSUB ##RND TO LN #INKEY$ LN AT PI CLEARACS #CHR$  GOSUB ##RNDE#RND FASTEINKEY$ RND GOSUB ##RND▞▞ACS EACS .( IF  GOSUB #6INKEY$ RND FOR E#RND▞▞ACS EACS .( IF  GOSUB #6#RND GOSUB ##RNDLN PEEK PIU#RND##ACS +[£] PRINT ACS <[0]MRNDRNDEINKEY$ RND GOSUB ##RNDLN PEEK PIU#RND##ACS +[£]MZRND##ACS <[0]AT # CLEARACS ##C)E#RND#[P]C▞F6#RND/? CLEARACS #[-]Y[Z][(]S▞ CLEAR#WLN  IF INKEY$  LPRINT F#[P]4█TAN  CLEARQX▘LN #INKEY$ COS LN #INKEY$ MXRNDLN #INKEY$ COS LN [>]INKEY$ LN #INKEY$ [S]S▀#INKEY$ #LN ▜INKEY$ #INKEY$ LN ▜INKEY$ #PI GOSUB #YRND[)]W PRINT LN #INKEY$ [S]K▀#INKEY$ # GOSUB #RNDRND[(]W4▘XSGN # GOSUB #PIRND CLEAR#INKEY$  CLEAR#ZLN ▜INKEY$ LN CODE INKEY$ 6#RND CLEAR## CLEAR#RND CLEAR#ZLN ▜INKEY$ LN CODE INKEY$ 6#RND CLEAR##TAN  GOSUB ##RNDE#RND CLEAR##[J]R*( UNPLOT M#RND CLEAR##[J]▌C▖R*( UNPLOT J CLEAR##▌TAN #[A] FOR ##J[A][K]# FOR TAN #VAL ▘4 ##,,#LN ###AT ( LET [J][5]/ SLOWLN ACS #4*) 4544▘ STEP * GOSUB [K]▞4F#( UNPLOT  CLEARPX4 REM TAN LN R# FAST[B] GOSUB # LPRINT C: FASTVAL STR$ LN ##Y COPYSGN AT  LPRINT F/ FOR  CLEAR[A]#LN ## CLEARPX4<>TAN VAL 5  )4 ;( CLEAR FOR E#RND; FASTE#RND;SGN AT TAN #VAL ▘4 ##[B] GOSUB PI#LN ###AT ( LOAD [J]###LN ACS #4*) COPYR5 TO R▘ STEP * GOSUB [S]▞47#( UNPLOT  CLEARPX4 REM TAN LN R#LN [T]# FAST[B] GOSUB # LPRINT C: FASTVAL STR$ LN SQR #Y COPYSGN AT  LPRINT F/ FOR  CLEAR[A]#LN SQR # CLEARPX4 AND TAN LN ACS #4+5 COPYR▞4#[B]ACS -F( CLS[8]4 POKE  CLEARPX4 GOTO TAN LN R##▖U#RNDVAL  PRINT  FASTSTR$ INKEY$ # PRINT  FAST[B] GOSUB # LPRINT C+#[4]# LET #ACS * PRINT #J[A]# LET  PRINT [K]#▞ COPYF/ SLOW#[4]### LET #ACS *[4] PRINT #J[A]# LET [K]#SGN  LPRINT ▘4  FOR ,, FOR ,, LET AT ([Y] CLEARPX4[L]TAN LN ACS #4-5 4[B]▞4ACS 27( CLSYS[W]4 NEXT  CLEARPX4 FOR TAN LN R##▖U#RND FOR VAL  PRINT  FASTSTR$ # PRINT  FAST[B] GOSUB # LPRINT C+#[4]# LET #ACS 3 PRINT #J[A]# LET  PRINT [K]#▞ COPY7/ SLOW#[4]### LET #ACS 3[4] PRINT #J[A]# LET [K]#SGN  LPRINT ▘4  FOR ,, FOR ,, LET AT ([Z] CLEARPX4[L]TAN ###Y[Z][(]STR$ VAL  PRINT LN  IF INKEY$  LET AT SGN TAN 2 COPY/▝2 STR$ LN <>#SGN  CLEAR##UINKEY$ RND5ZRND PRINT  FASTLN  RETURN#+C▞WLN ▖#/ RUN  CLEAR#PI LPRINT  LET F FASTLN  RETURN#+C▞£LN ▖#/ RUN  CLEAR## LPRINT URNDRND PRINT  FASTLN  RETURN#+C▞XLN ▖#/ RUN  CLEAR#PI LPRINT  LET 7LN  RETURN#+COS $LN ▖#/ SAVE ##[A]##J##J[6][N]#)4 ;( LOAD TAN LN ACS #4+5 4▘ /#J#7YS[W]4 RUN  CLEARPX4 GOTO TAN LN R#▖J FAST[B] GOSUB # LPRINT C: FASTVAL STR$ LN ##Y COPYSGN AT  LPRINT F/ REM U#RNDJLN ## CLEARPX4 AND TAN A$( LN [J]INKEY$  FAST TO  FAST5[X]#6-RNDLN 0)AT  GOSUB #-RNDK▝INT 6777# RETURN▝4 PLOT 7#Y""[>]S LOAD 77#Y4[)]S SCROLL77 CLEAR#X▞ SGN TAN LN [>]INKEY$ ##Y4[)]MYRNDLN #INKEY$  SCROLLM[X]# SCROLL RETURN$4SIN ##INKEY$ VAL [J]# FOR  GOSUB PI FOR AT TAN LN  RAND # PRINT LN AT # LET ▞# FASTC0 RETURN,4[E] SCROLL RETURNA▞[A]C£ RETURNO▞[Q]C▞ RETURNX▞[I]4[*]LN #INKEY$ 4 CLS#M## LPRINT UYRNDINKEY$ :4VAL  PRINT STR$ YS[U]4▖SGN -4STR$ ,#>7< CLEARPYATN <#( REM  FOR  LPRINT ,, FOR  LET AT MYRND CLEARPX4 OR TAN Y /▝Y>M[4]#LN  RAND #4[S]LN AT #UYRNDINKEY$ :4VAL  PRINT STR$ YS[U]4▖SGN -4STR$ # PRINT ,# LET >7< CLEARPYATN <#( SCROLL FOR  LPRINT ,, FOR  LET AT MYRND CLEARPX4CHR$ TAN 7# RETURN0K▝INT 1 RETURNGK IF CHR$ 0TAN LN [U]##ACS 4ACS 4ACS 4ACS 4LN [U]#█#7# RETURN"#TAN  SCROLL RETURN"TAB 9#7#ACS #C▝CHR$ RND)  77 FAST▞▒## FOR ;( CLEAR FOR 5 S; FOR  LPRINT TAN LN  STEP #7LN TAN #>4▀## </ POKE ##[B]4## CLEAROY CLEARACS Y#4/7#[B]C LET ACS #4?▞ COPY[B]*S▖ACS // SAVE #J[5][Q]# FOR F CLEARPZ CLEARACS Z#""#[B]4▀#/ LIST ACS #""▞ COPY[B]ACS 3S▖ACS (/ RUN #J[5][Q]#TAN VAL #Y,,[(]#ACS )S▌( IF AT /[P]AT ##ACS ;S/( IF  CLEAR#WLN ## CLEAROY CLEARACS Y#""7 CLEAR#W##/[-] CLEARACS #CHR$ ##VAL ACS ;( UNPLOT AT ** CLEARACS #[-] CLEAR#WVAL Y,,[(]#[J]#ACS >ACS <ACS ▘W( RUN ACS >ACS <ACS ▘WK RUN ACS .ACS ,,XACS .ACS ;X4 RAND #AT Y,,#[(]ACS ;+( CLSACS ,,+K CLS#PIACS <ACS ▘( IF PIACS ;ACS .( IF #TAN LN [~~]INKEY$ VAL  PRINT LN 1+Y▒LN 1+LN R0LN LN +LN [B]:Y▛[)]# GOSUB ##RND LET AT #ACS UACS UACS U5YRND#7#7#LN CODE INKEY$  FASTVAL LN #INKEY$ MINKEY$ RNDLN #INKEY$ LN  STEP ##LN #INKEY$ TAB *# FOR ▘▛ ,,6#RND GOSUB ##RND GOSUB PI6PIRNDAT SGN  CLEARACS #[-] CLEAR##Y▒[)]#/▝:▒STR$ VAL EPIRND#F6PIRNDMWRND CLEARACS ##TAB [A]▝##LN =# CLEARPINKEY$ ASN [A]▝AT  LPRINT [B])4  GOSUB ## RETURN3COS URNDRNDMYRNDMZRND$ FOR 4COS E#RND6PIRND/[Y]LN #INKEY$ ##▘▘COS  CLEARACS V#""( RAND $4 PLOT .#[N]4 INPUT TAN  SCROLL RETURN#4,,LN ,,#LN 0#/K SCROLL RETURN,C> RETURN;CG RETURN#C# RETURNAT C# RETURNTAB C#/# GOSUB # RETURNZ# NEW LIST LEN ( RETURNRNDCODE  FAST#ATN  STEP #/CHR$ #LEN ▒#[J]# GOSUB # RETURNZTAN ▞ COPY SCROLL RETURN#COS  RETURN,4▖Y▖/" RETURN;4LEN ▖# RETURN▀ASN 9#M CLSZ/ SLOW GOSUB # RETURNZ/SGN LN #INKEY$ ## RETURN[T]ABS [▒]INKEY$ # RETURNRNDABS ▙INKEY$  GOSUB # RETURNZ TO /[)]LN #INKEY$  NEWZ GOSUB # RETURNZ[T]#K GOTO Y▒█#/ NEWLN #? CLEARACS ▘#CODE STR$ .LN  SAVE <#[L]C OR ,VAL STR$ LN ##SGN AT <"/ LIST  RETURN""4▖Y"/U PRINT  NEW# RETURNRNDK▛ LET  CLEARACS ▘LEN /G CLEARACS ▘#C~~[J] CLEARACS ▘▚LN [/]#/▖ CLEARACS ▘LEN  LET LN #,,~~ PRINT VAL  NEW#LN [/]#AT ▀ LET  RETURN█S LET  CLEARACS ▘▚[J] GOSUB # RETURNZ PRINT YZ[)]>= STEP #LN 0# LET VAL M#RND[B]*[B]**- ACS >#5 2; FASTACS TLN [J]INKEY$ SGN U CLSZ RETURN▖ASN ▐# RETURN▝CPI RETURN▘CEY▒ PRINT STR$ , PRINT U CLSZ[B]4~~ CLEARACS ##C▖ LET J/▘ LET #)4 ;SGN  LET <X4 STEP AT ££ GOSUB # RETURNZTAN U#RND RETURNASINT  RETURN[A]KACS  FAST5 2; FOR  LPRINT /TAB U#RND▛ FAST5 0S LET A,/ GOSUB  CLEARACS ##Y[S]C▝Y[C][S]SQR ## NEW▛▙#VAL ) 45 5ACS SACS SACS S# GOSUB [K]F#( UNPLOT AT TAN ▘ ""LN 0## NEW# PRINT  SCROLLLN 0) AND #$ASN 9#7 FAST▞▌[J]#7( UNPLOT SGN  LET TAN LN AT INKEY$ #?( CLEARLN ##SQR Y▟>TAN LN AT INKEY$ ##LN 4+ FASTLN ## LPRINT LN  PLOT ;#[~~]+LN AT INKEY$ #▞ / REM <>#  PRINT LN  SCROLL▝2"" CLEARACS ##C▝2[K]5 4[J]PEEK  CLSLN #?ABS ▐▒<= CLS*K CLS-4▞▒#<= CLS3K CLS# NEW█PEEK  CLSACS )( PAUSE 7+4 FOR <= CLS3K CLS14PEEK Y▖PEEK  CLS LET  RETURN GOSUB ASN ▛▝#STR$ RNDLN #INKEY$ Y*C▀LN #INKEY$ )  WE RETURNZ FAST GOSUB # RETURNZ GOSUB #£RND< PRINT ▞4,VAL STR$ LN [/]#SGN AT <( PRINT  LET X4 GOSUB  LPRINT 6 RETURNZTAN LN #INKEY$ CATN LN #INKEY$ W PRINT #Y""CHR$ ▒( UNPLOT ## LET /LEN )[(]RNDLN #INKEY$ C>STR$ LN #INKEY$ #LN #INKEY$ ▖SGN ,LEN █><( RAND TAN ▞4[J]><( UNPLOT TAN  TO  FAST SCROLLLN (PI#;#A$ SCROLL SCROLL FASTLN #?LN  SAVE <VAL  SCROLLLN #?LN  SAVE <##,,AT  FAST.,#.,#,, FOR #7#7 LPRINT  FASTLN [2],,SGN  LPRINT 6-RNDSTR$ LN #?LN  SAVE < FOR SGN  GOSUB [K]TAN 5##6-RNDLN 0)7#7#"#F#77LN #▌TAN  TO  FASTLN ##LN [,,]##;# TO  FASTLN ##/ PLOT FMRLSPT      [N]# TO  FAST5##6-RNDLN 0)76[Z]##7#PI#7VAL  FAST#▘▛ 5[M]# GOSUB [L] LPRINT C▛STR$ LN #▌SGN .FAT "#[L]4 SLOWE[Z]##7#7# RETURNS4▘▀.#[N]4 POKE  LPRINT 6-RNDTAN                                                                                GOSUB # UNPLOT Z# RETURN COPY4▖▞[Z]/▞ RETURN""4▝▞ Y[Z][(] GOSUB # UNPLOT ZTAN LN  IF INKEY$ )[4] .#[N]4 CLSTAN LN [~~]INKEY$  GOSUB # UNPLOT ZLN #INKEY$ M## CLEARACS #CHR$ LN ##VAL  PRINT LN CODE INKEY$ #2 COPY LET AT STR$ VAL  PRINT LN ## LET AT LN ##SGN #E9RND##GC THENLN [X]▛#:£)VAL ##M# CLEARACS #CHR$ /ATN  CLEARQW COPY CLEARACS #[-]/£ CLEARQW / POKE  CLEARO CLEAR CLEARP UNPLOT LN ## CLEAR#W CLEARACS ##4[E]LN  IF INKEY$ /[9] CLEARO CLEAR/ REM  CLEARO UNPLOT / PLOT  CLEARO UNPLOT / STEP  CLEARP CLEAR/ PLOT  CLEARP CLEAR/CHR$  CLEARP UNPLOT / PLOT  CLEARP UNPLOT /ATN    TO  RETURN;CM RETURN#C▝INT + LPRINT ▘  ##  TO  RETURN THENC▝INT ) FAST SCROLL);#STR$ :(),#▞  FOR  GOSUB [5]C▌77 REM P##7# FOR VAL TAN SGN ):#STR$ :?) FOR # SCROLL# SCROLL RETURN#CSQR  RETURN;4 RUN F#7 RETURN$C▘#/INT :▌)[.]#F#7/VAL :▖)[G]#/ POKE FF#77:▀)[U]#/[M]YX:  GOSUB [T]77#:▀)[(]#/[6]C GOTO PID=PIR>#9#D9#D9#M9#P9#S9#9#D NEW#LD#R[<]#U##9#G##P0#S##9#C[W]#DTAB #EATN #R##1ABS #2 INPUT #3 SAVE #4▝#5▛#6 CLEAR#7 DIM #8 NEXT #[:]#X█#A##B OR INKEY$ C CONT PID(PIF CONT #I##L▚#P##R:#S##T##U▖#W##$##9# LPRINT ## LLIST :# SCROLL## LOAD [=]# LIST >=# PAUSE [)]# PRINT [D]# PLOT  FOR INKEY$  RUN ACS RND SAVE ## RAND 8# CLS[0]INKEY$  UNPLOT  LOAD INKEY$  CLEARSGN RND RETURN[Z]RND COPY[:]#9#                   
   1 REM  FAST SAVE  LOAD [V][.][2][.][0]##LN  SCROLL▝ SCROLLLN #?LN  SAVE <#[K]C+ RETURN/K) TO  RETURN#COS  SCROLL RETURNSCOS  RETURNVCOS  RETURNCODE COS  RETURNHCOS # POKE ▝, RETURN,C▖ RETURNCODE 4▝AT TAN .CHR$ 1**W,,X4 UNPLOT TAN  FOR 5  .▘▘ LN [+]#:~~LN [+]#:#LN [+]#▘ CONT ▀LN [+]#▘(BLN [+]#TAN ▘▘COS ( RETURN$4 CLS.#[N]4 NEXT TAN ▞▛ACS 5>=,,#USR  SAVE #Y▀X4 CLEAR GOSUB #▌TAB >=#ACS 5>=,,#USR  SAVE #TAN PEEK  COPYY-X4 CLEAR<= RETURNY:X4 CLEAR#1##£#PEEK  COPYY9X4 CLEAR<= RETURNY0X4 CLEARF7RTAN ▘ █VAL  LN  AND #AT ▌TAB 5#▀ GOSUB #LN  AND #LN ##$LN  AND # CLEAR FAST LET #:[E]LN  AND #LN ###LN  AND #LN ###LN  AND # CLEAR FAST LET ##LN  AND #7.#[N]4 PLOT   TAN LN ## RETURNHASN [>]#STR$ VAL  PRINT LN  LLIST ▒) ▝LN ATN # LET M#RND RETURNS4£5 4 6#RND5 //) RETURNV4>E(RND6#RND FOR E=RND[B] GOSUB #6#RND/O RETURNCODE C▌5,,RND/ CONT  SCROLL RETURN,C£ RETURN0 AND  POKE ▝ RETURNAABS  POKE ▝/ LOAD LN [E]#6#RND SCROLL RETURN#C~~ RETURN0S SCROLL RETURNAK CONT / LET LN [E]#/SIN AT  LPRINT )WRNDSTR$  GOSUB [K][J]E#RND GOSUB ##RND▚7.##[N]#4 RUN M#RNDF#M#RND LPRINT )4 LN 2# GOSUB ##RND GOSUB ##RNDE#RNDLN 2#/0    F#[J]E#RND GOSUB ##RND▚7.##[N]#4 RUN [T]C▝INT =LN  LLIST ▒LN ▛▝TAN <= RETURN*S CLS: £<= RETURN*K IF #LEN  FOR ACS <TAN 2 ▞▒LN H#( CLSTAN - =PEEK  COPY# RETURNRNDK)2 LN H#LN #?ABS [A]▀#[B]4 SCROLL/ SCROLL2 PEEK  COPYLN H##[B]C PRINT LN RND#04CHR$ LN RND## RETURN[E]4EXP LN RND##LN RND#STR$ PEEK  COPYLN RND##SGN 7.#[N]4 PAUSE TAN  FASTLN ## RETURNHASN 5# PRINT STR$ VAL 5WRNDLN ##AT SGN /£-▝LN ATN # LET  LPRINT 6-RND/ THEN5WRND,[Y]4 GOSUB 7<"#[L]4 PRINT  LET  LPRINT E#RND FAST RETURNS4:5 4 6#RNDLN ##AT #:# RETURNV4/E(RND6#RNDLN ##AT  FASTLN :# LPRINT FLN [1]=SGN  LPRINT ##▞ RETURN#4▌5,,RND/ LLIST  SCROLL RETURN#4?E#RND/SIN  SCROLL RETURN#4▌LN [E]#/[X] RETURN0 AND  POKE ▝ RETURNAABS  POKE ▝/ REM  LET ▘4 5WRNDLN ##U#RND RETURNCODE 4▖YC/▞ RETURN#4▝YP INPUT █M#RND▞;5WRND#NOT 7( CLSY#E#RND GOSUB ##RNDSTR$  FAST;LN ## LPRINT Y-LN ## LPRINT Y=LN ##Y#NOT #A#NOT ##LN 4+LN <=+TAN 
   2 REM [6][4][-][C][O][L] PRINT ## LIST  LIST  LIST  LIST  LIST  LIST  LIST  LIST WWWW LIST  LIST  LIST  LIST #### LIST  LIST  LIST  LIST ???? LIST  LIST  LIST  LIST  LIST  LIST  LIST  LIST WWWWWWWWWWWW####WWWW????WWWW#[9]#[9]#[9]#[9] LIST  LIST  LIST  LIST #[9]#[9]#[9]#[9] LIST  LIST  LIST  LIST  ##RND RNDRNDRND [4]E##[:][E]  ##[▒]#▙## RND8  ▖   ##PI# #  6##CODE #PI4 ▜PIPI#PI#█ ▒▖#[8]▒   ▝▖▒▖▝  LIST  ##RND#RND#  #USR [Y]▜#   #4I44#  E# INPUT #E   ▙▙##CC  RND[8]RNDRND#▖▒ RND█  ▖▖▒     £# (-,,,,0(█▜[£]▜▜▜[:]█ LIST ▖~~▝▖▒:  LIST [:]▙▜▙[~~]▜█ LIST >-,2>>(█[:][▒][£]▙[~~]▜ LIST (=/0,,= LIST █[:]PIPI8C/((=E8##▜█ ▖[~~] IF [A][6][8]  RND[8][6] NEW[E][A]  COS [C]ATN [E][E]ATN   #▜[~~][▒][▒]#  TAB [6][A][E][E]LEN    STEP ▜ASN [:][▒] NEW   LLIST ▜EXP ▜▜▜  RND[8][~~][E][A]#£ [C][C] GOTO [E][E][E]   SLOWRND### SLOW  #4A6[6]#▖ [C][C]ASN ATN [E][E]  ▜▜▜▜▜ LLIST   [4] REM  INPUT [I][E][E]  ""[G][E][E][E][E]  RND[8][E][E][E]#  ""[G][E]ASN [£][▒]▒ RND[A][E][E][A]PI7 ""[G][E]COS [C][C]  #▚#86ATN    SLOW####PI  [4][E][E][E][E]#  [4][E][E][E]##  [4][E][E][E] INPUT [E]  [4][E]##[E][E]  [4][E]##PIPI▖  STEP IPI#[▒] INPUT   FAST5▐O; FOR  LPRINT U#RND NEW█U RETURNZ?▞▒VAL  PRINT ,#CGS0 NEW LIST  PRINT # NEW?# LET [K]#<STR$ )4 ;SGN  LET AT ( STOPAT £ GOSUB # RETURNZTAN ACS ZACS ZACS ZACS Z PRINT # NEW LIST />=S~~ACS BACS BACS BACS B/ATN  NEW?/ REM 
   3 REM [Q][U][I][C][K]## PRINT VAL STR$  FASTEORNDFY#[8][P]#4▀*/▝#R#6ORNDSQR LN [V]▝ GOSUB #9RND69RND#LEN ▝ GOSUB PIUBRND[O][P]#▞"5VRNDACS ▚4▒ACS #ACS LEN COS ▌ R5BRNDZACS (( RETURN## RETURN RETURN[3]▞3[Q][4]3#PEEK  COPYE£RNDACS  UNPLOT  CLEARQC3LN [>]▝ GOSUB #▘▘;Y PRINT LN [P]▝FLN [>]▝TAN E9RND##GC▒LN [X]▛#▞ #TAN ▘  TAN 
  10 GOSUB VAL "4E3"
  20 REM [D][R][A][W]█[C][U][R][V][E]
  30 FOR I=Z TO LEN A$
  40 LET C$=A$(I)
  50 GOSUB CODE C$*10
  60 IF C$="F" THEN IF USR 19526 THEN LPRINT F*(T-V),F*(U-W)
  70 IF C$="M" OR C$="P" THEN POKE 16380,F*(T-V)
  80 IF C$="M" OR C$="P" THEN POKE 16381,F*(U-W)
  90 NEXT I
 100 GOTO VAL "2E3"
 420 REM [U][P][D][A][T][E]█[P][O][S][I][T][I][O][N]
 430 LET T=T+C(J)
 440 LET U=U+S(J)
 450 RETURN
 490 LET J=J+Z
 494 IF J>D THEN LET J=Z
 498 RETURN
 500 GOTO VAL "430"
 530 IF NOT S THEN GOTO VAL "1E3"
 534 LET S=S-Z
 538 LET T=X(S)
 542 LET U=Y(S)
 546 LET J=D(S)
 548 RETURN
 550 LET J=J-Z
 552 IF NOT J THEN LET J=D
 556 RETURN
 560 IF S>L THEN GOTO VAL "1E3"
 562 LET X(S)=T
 564 LET Y(S)=U
 566 LET D(S)=J
 567 LET S=S+Z
 568 RETURN
 570 LET J=J+D/2
 580 IF J>D THEN LET J=J-D
 590 RETURN
 600 REM [C][U][R][V][E]█[S][I][Z][E]
 610 FOR I=Z TO LEN A$
 620 LET C$=A$(I)
 630 GOSUB CODE C$*10
 640 IF C$<>"F" AND C$<>"M" THEN GOTO 690
 650 IF T>Q THEN LET Q=T
 660 IF U>R THEN LET R=U
 670 IF T<V THEN LET V=T
 680 IF U<W THEN LET W=U
 690 NEXT I
 700 LET F=VAL "191/(R-W)"
 710 IF VAL "255/(Q-V)"<F THEN LET F=VAL "255/(Q-V)"
 720 LET J=Z
 730 LET T=O
 740 LET U=O
 750 POKE VAL "16380",F*(T-V)
 760 POKE VAL "16381",F*(U-W)
 770 IF USR H THEN CLS
 780 IF USR H THEN CLEAR
 790 IF USR H THEN PRINT "[N]ORMAL OR [R]EVERSE?([N]/[R])"
 800 INPUT Q$
 810 IF Q$="N" THEN IF USR H THEN RAND 
 820 IF Q$="R" THEN IF USR H THEN RAND VAL "31"
 830 IF USR H THEN PRINT AT O,O;"[L]OOKAT [D][A][T][A]$?([Y]/[N])    [L]ENGTH OF [D][A][T][A]$=";LEN A$
 840 INPUT Q$
 850 IF USR H THEN RUN 
 860 IF Q$<>"Y" THEN GOTO VAL "890"
 870 IF USR H THEN PRINT ;,A$;;"[A][N][Y]█[K][E][Y]";,
 880 IF USR H THEN PAUSE VAL "6E4"
 890 IF USR H THEN CLS
 900 RETURN
 1000 REM [E][R][R][O][R]
 1010 CLS
 1020 PRINT "CAN""T DRAW CURVE.",,,"STRING OR STACK ERROR-MUST REDO."
 1030 IF USR H THEN RETURN
 1040 STOP
 2000 REM [M][E][N][U]
 2010 DIM A$(VAL "50",VAL "8")
 2020 POKE VAL "21826",VAL "31"
 2030 IF USR H THEN LPRINT S$;O,O,A$
 2040 IF USR H THEN PRINT AT O,O;" 1. [V]IEW",,,," 2. [R]EVERSE",,,," 3. [C]OPY",,,," 4. [S]AVE SCREEN",,,," 5. [R]UN",,,," 6. [S]TOP"
 2050 LET S$=INKEY$ 
 2060 IF CODE S$<CODE "1" OR CODE S$>CODE "6" THEN GOTO VAL "2050"
 2070 IF USR H THEN LPRINT S$;O,O,A$
 2080 IF S$="1" THEN IF USR H THEN PAUSE VAL "6E4"
 2090 IF S$="2" THEN IF USR H THEN RAND VAL "31"
 2100 IF S$="3" THEN IF USR H THEN COPY
 2110 IF S$="4" THEN GOSUB VAL "2150"
 2120 IF S$="5" THEN RUN 
 2130 IF S$="6" THEN STOP
 2140 GOTO VAL "2030"
 2150 DIM B$(VAL "10",VAL "6")
 2160 IF USR H THEN LPRINT S$;O,O,B$
 2170 IF USR H THEN PRINT AT O,O;"[S]AVE NAME?"
 2180 IF USR H THEN CLEAR
 2190 INPUT S$
 2200 IF USR H THEN LPRINT S$;O,O,B$
 2210 IF USR H THEN SAVE S$,S
 2220 IF USR H THEN RUN 
 2230 RETURN
 4000 REM [S][T][A][R][T]
 4010 LET T=NOT PI
 4020 LET J=PI/PI
 4030 LET H=VAL "2E4"
 4040 FOR I=T TO T
 4050 LET F=T
 4060 LET U=T
 4070 LET V=T
 4080 LET W=T
 4090 LET O=T
 4100 LET Q=T
 4110 LET R=T
 4120 LET Z=J
 4130 LET S=J
 4140 LET K$=""
 4150 POKE VAL "21826",VAL "31"
 4160 IF USR H THEN CLS
 4170 IF USR H THEN CLEAR
 4180 REM [I][N][P][U][T][S]
 4190 IF USR H THEN PRINT ;,AT VAL "176",O;"[L]-[S][Y][S][T][E][M][S] A PROGRAM FOR GENERATING FRACTAL CURVES BY [G].[C]. [H]ARDERFROM AN ALGORITHM BY [D]. [S]AUPE IN ""[T]HE [S]CIENCE OF [F]RACTAL [I]MAGES"" ";TAB O;"[C]URVE TITLE: ";
 4200 INPUT A$
 4210 IF USR H THEN PRINT A$;TAB O;" ";TAB O;"0 LEVEL [A][X][I][O][M] STRING: ";
 4220 INPUT A$
 4230 IF A$="" THEN GOTO VAL "4220"
 4240 IF USR H THEN PRINT A$;TAB O;"[N]O. OF PRODUCTION RULES: ";
 4250 INPUT N
 4260 IF USR H THEN PRINT N
 4270 FOR I=Z TO N
 4280 IF USR H THEN PRINT "[O]NE LETTERCODE  FOR PRODUCTION RULE ";I;": ";
 4290 INPUT S$
 4300 IF S$="" OR LEN S$>Z THEN GOTO VAL "4290"
 4310 LET K$=K$+S$
 4320 IF USR H THEN PRINT S$
 4330 NEXT I
 4340 IF USR H THEN PRINT "[C]HARACTER LENGTH OF LONGEST PRODUCTION RULE: ";
 4350 INPUT M
 4360 DIM R$(N,M)
 4370 IF USR H THEN PRINT M;TAB O;" ";TAB O;TAB VAL "17";"[C][O][D][E]   [R][U][L][E]"
 4380 FOR I=Z TO N
 4390 IF USR H THEN PRINT "PRODUCTION RULE ";I;": ";K$(I);" -> ";
 4400 INPUT S$
 4410 IF S$="" OR LEN S$>M THEN GOTO VAL "4400"
 4420 LET R$(I, TO )=S$
 4430 IF USR H THEN PRINT S$
 4440 NEXT I
 4450 IF USR H THEN PRINT TAB O;" ";TAB O;"[N]O. OF DIRECTIONS (MUST BE EVEN): ";
 4460 INPUT D
 4470 IF VAL "D/2-INT (D/2)" THEN GOTO VAL "4460"
 4480 DIM C(D)
 4490 DIM S(D)
 4500 IF USR H THEN PRINT D;TAB O;"[N]O. OF LEVELS: ";
 4510 INPUT M
 4520 IF USR H THEN PRINT M;TAB O;"[N] VALUE FOR [Q][U][I][K] MODE;([M][A][R][G][I][N])=31+8*[N]: ";
 4530 INPUT N
 4540 IF USR H THEN PRINT N
 4550 POKE VAL "21826",VAL "31+8*N"
 4560 IF USR H THEN RUN 
 4570 IF USR H THEN PRINT AT VAL "184",O;"[R] = RUN   :   [C] = COPYSCREEN : ANY OTHER KEY TO GENERATE [D][A][T][A]$"
 4580 LET B=USR VAL "21845"
 4590 IF NOT B THEN GOTO VAL "4580"
 4600 IF B=CODE "R" THEN RUN 
 4610 IF B<>CODE "C" THEN GOTO VAL "4640"
 4620 IF USR H THEN CLEAR
 4630 IF USR H THEN COPY
 4640 IF USR H THEN PRINT TAB O;" ";TAB O;;"███[S][T][A][N][D][B][Y][,]█[G][E][N][E][R][A][T][I][N][G]█[D][A][T][A][$][.]███";,
 4650 IF USR H THEN PAUSE VAL "300"
 4660 FAST
 4670 IF NOT USR H THEN CLS
 4680 REM [C][R][E][A][T][E]█[D][A][T][A][$]
 4690 LET S$=""
 4700 FOR N=Z TO M
 4710 FOR K=Z TO LEN A$
 4720 LET C$=A$(Z)
 4730 FOR I=Z TO LEN K$
 4740 IF C$<>K$(I) THEN NEXT I
 4750 IF I>LEN K$ THEN IF USR 19616 THEN LPRINT C$,S$
 4760 IF I<=LEN K$ THEN IF USR 19616 THEN LPRINT R$(I, TO ),S$
 4770 NEXT K
 4780 IF USR 19627 THEN LPRINT S$,A$
 4790 LET S$=""
 4800 NEXT N
 4810 DIM R$(Z,Z)
 4820 IF A$="" THEN GOTO VAL "1E3"
 4830 REM [C][L][E][A][N]█[U][P]█[D][A][T][A][$]
 4840 LET L=USR 19649
 4850 IF NOT L THEN GOTO VAL "4890"
 4860 DIM X(L)
 4870 DIM Y(L)
 4880 DIM D(L)
 4890 FOR I=Z TO D
 4900 LET C(I)=COS (2*PI*(I-Z)/D)
 4910 LET S(I)=SIN (2*PI*(I-Z)/D)
 4920 NEXT I
 4930 GOTO VAL "600"
 9990 SAVE "L-SYSTM[S]"
 9995 PRINT "[L][-][S][Y][S][T][E][M][S]█[L][O][A][D][E][D]",,,"ENABLE SCRAM THEN RUN "

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top