Spirograph simulates the Spirograph geometric drawing toy by computing parametric curves based on the radii of a fixed gear, a moving gear, and the pen-hole distance from the center of the moving gear. The drawing routine is implemented entirely in the ZX81 floating-point calculator language combined with machine code, operating on up to 23 of the 32 addressable calculator memory slots (accessed by manipulating the MEM system variable). A “QUICK” display mode is provided as an alternative to SLOW and FAST modes: by POKEing address 21332 with a non-zero value, the routine alternates between the plotting and hi-res display routines so the pattern builds visibly faster than SLOW mode. The program uses USR calls to machine code entry points at addresses 19400 (HR) and 21103 (SPIRO), with LPRINT used unconventionally to pass the five parameters (A, B, F, M, R) to the machine code drawing routine. Four built-in demos are provided, each drawing a pair of mirrored spirograph curves with positive and negative moving-gear radii.
Program Analysis
Program Structure
The program is organized into several functional regions identified by line number ranges:
| Line Range | Purpose |
|---|---|
| 0–5 | REM blocks containing embedded machine code and data |
| 10 | Entry point — GOTO 9000 |
| 1000–1170 | Demo selection menu, ink color choice, display mode selection |
| 2100–2440 | Four demo routines, each drawing a mirrored pair of spirograph curves |
| 7999–8010 | General-purpose draw subroutine using variables A, B, F, M, R |
| 9000–9210 | Initialization and introductory text/documentation screens |
| 9300–9330 | Post-draw wait-for-keypress and CLS helper |
| 9400–9450 | Prompt and read a single keypress into Q$ |
| 9500–9540 | Any-key-to-continue helper |
| 9900–9920 | SAVE routine for the program file |
Machine Code Integration
Three machine code entry points are established as named integer variables at lines 9000–9002:
HR = 19400— a hi-res display or screen refresh routineSPIRO = 21103— the core spirograph drawing engineQUICK = 21332— a single-byte flag controlling the “quick” display mode
The machine code itself resides in the REM lines (lines 0, 1, 2, 5), a standard technique for storing binary data in BASIC programs without it being executed as BASIC. The program notes that the drawing routine is written entirely in the ZX81 floating-point calculator language combined with machine code.
USR Call Idiom
Throughout the program, IF USR HR THEN ... is used as a conditional wrapper around nearly every display or action statement. USR HR calls the hi-res display machine code routine and returns a value; if the return value is non-zero (true), the THEN clause executes. This allows the machine code to gate all screen output, presumably switching between the pixel display buffer and the normal character display as needed. This is the “yet another method of kinda-seeing the display while drawing in FAST mode” referenced in the program description.
Parameter Passing via LPRINT
The spirograph drawing routine receives its five parameters through an unconventional use of LPRINT:
IF USR SPIRO THEN LPRINT A,B,F,M,R
Here LPRINT is not actually sending output to a printer; instead the machine code at address SPIRO intercepts the printed values as its input. This is a known technique on this platform where the printer output stream can be redirected or consumed by machine code. The five parameters are: A (X center), B (Y center), F (fixed gear radius), M (moving gear radius), R (pen-hole distance from center of moving gear).
QUICK Display Mode
A third display mode beyond SLOW and FAST is implemented via a flag byte at address 21332 (variable QUICK). POKEing this address with any non-zero value enables “quick” mode, which alternates between the plotting routine and the hi-res display routine so the pattern is visible as it draws, faster than SLOW mode but with some visual artifact. It is disabled by POKEing 21332 with zero. Lines 1005 and 9005 initialize this flag to 0; line 1150 sets it to 1 when the user selects option 3.
Demo Dispatch
Demo selection uses a computed GOTO at line 1170:
GOTO 2000+100*Q1
With Q1 in the range 1–4, this jumps to lines 2100, 2200, 2300, or 2400. Each demo draws two curves — one with a positive moving-gear radius and one with a negative value — creating mirror-image patterns. After drawing, each demo GOSUBs 9300 to wait for a keypress, then returns to the main menu at line 1000.
Calculator Memory Usage
The introductory text (lines 9090–9100) explains that the ZX81 floating-point calculator supports up to 32 memory slots (codes C0–DF for store, E0–EF for recall), accessible by manipulating the MEM system variable. The program uses 23 of these slots in its machine code drawing routine, and instructs users to restore MEM to MEMBOT on exit.
Key Input Handling
Two input subroutines are used throughout:
- Lines 9400–9450: Displays a prompt banner, spins on
INKEY$until a key is pressed, stores result inQ$, then clears and redraws the title stringA$. - Lines 9500–9540: Displays an “ANY KEY” banner and waits similarly, used for paging through informational screens.
The prompt banners use alternating \,, and \~~ block graphic characters to create a decorative border effect around the prompt text. The PAUSE 0 / INKEY$ spinning loop idiom (IF INKEY$="" THEN GOTO ...) is used rather than INPUT to capture single keypresses without requiring ENTER.
Title String
Variable A$ (set at line 9004) holds a decorative header string consisting of alternating block graphic characters flanking the text “SPIROGRAM SCRAM”. This string is redisplayed after each menu interaction to maintain a consistent screen header. The word “SCRAM” likely refers to a hardware expansion board (the “SCRAM board” mentioned at line 9910).
RAND (RANDOMIZE) for Paper/Ink Color
Lines 1090 and 1095 use RAND (with and without an argument of 31) to set ink/paper colors when the user selects white-on-black or black-on-white display. On this platform, RAND with certain arguments can affect display attributes via the machine code environment, which is a non-standard use gated behind IF USR HR THEN.
Anomalies and Notes
- Line 9300 uses
IF USR HR THEN RUN— callingRUNinside a conditional is unusual; this likely resets some display state via the machine code rather than restarting the program, sinceRUNhere would normally clear all variables. - Line 9007 similarly uses
IF USR HR THEN RUNin the initialization sequence, suggesting the machine code intercepts or modifies the behavior ofRUNin this context. - The SAVE line (9900) saves the file with a filename that includes
[P], consistent with the auto-run mechanism for this platform. - Lines 2100–2440 use
REMlabels (e.g.,REM DEMO ONE) purely for documentation; they have no effect on execution.
Content
Image Gallery
Source Code
0 REM [C]█[1][9][8][7]█[S][M][C]##▘ ""LN RUN ##[P]#Y2 GOSUB #<>5▟▝TAN PRINT # RETURN,C▌LN [*]RNDINT / LET TAN 6-RNDLN #? FASTLN LN + LPRINT TAN LN [H]RND PRINT LN [4]RND7LN [H]RND# LET #TAN 7# RETURN#C▀ RETURN;""6-RNDTAN A ##▞▌ACS 9ACS =( IF ,,▘ 4,,TAN 7LN [T]RNDLN [4]RNDLN ,,INKEY$ ##ACS ZACS ZACS Z##STR$ LN STR$ RND LET J NEW▛W#TAN Y3[)]K▌LN [*]RNDINT (Y[Z][(]SQR LN [*]RNDINT 25 6AT ZA4##<▘ COPY*Q GOSUB [K]TAN NEXT Y▞# ( CLEARLEN LIST W4 CLEAR▞"" CLEARACS ##C▝▞[K])4 5 4##INKEY$ ▌ASN #INKEY$ ;# GOSUB ###9 SLOWE£RND ###) RUN ▙;Y2 GOSUB #Y PRINT ▘▛▝ CLEARACS ##CODE [P]▝LN [>]▝LN 4▝<>5GINKEY$ #[8]▝ CLEARACS #▚/▖ CLEARACS #LEN E£RND▘9 GOSUB PIF FOR 5 █;6#INKEY$ FOR GOSUB [K]LN F?<>5GINKEY$ TAN 7LN [T]RNDLN [4]RND##LN ▞INKEY$ VAL 7LN [H]RNDAT LN STR$ RND#TAN 2 COPY/▝2 STR$ 7LN [T]RNDLN ,,INKEY$ SGN GOSUB ##ZLN LET RND##?( CLEARACS .*PI▌4▝▞▒▛( CLEAR#TAN Y COPY/▘[J]MVAL Z CLEARACS #[:]7LN [T]RNDLN ,,INKEY$ # RETURN,4"7 GOSUB ##ZLN [T]RNDLN ,,INKEY$ ## GOSUB RND#ZVAL #[)]-▘K▖ GOSUB #- COPY4▝- FAST##MSQR Z LET [(]2▘K▖ GOSUB #2 COPY4▝2 ##MINT Z#[W]S▞##- /▝2 GOSUB #SGN Z6PEEK Z#[B]3#A 6STR$ ZAT VAL Y[Z][(] PRINT UVAL Z# LET CLEARACS ##4▌LN SGN INKEY$ /▀LN ##UPEEK Z#▞ USTR$ Z##,,#MSTR$ Z GOSUB #SGN ZUUSR Z# GOSUB PIS▒#MSTR$ Z GOSUB #INT ZAT #▙##▄#5CHR$ ZOUUSR Z[Y]4[N] GOSUB ##ZTAN Y COPY/▘[J]MVAL Z7LN [T]RNDLN [4]RNDVAL 7LN [H]RND#I 6INT Z#6SGN ZAT Y▘ PRINT VAL VAL EINT Z GOSUB #SGN Z▞▌VAL ACS EACS .( IF [R] GOSUB #6INT Z GOSUB #SGN ZAT ACS GACS 1( IF ;6SGN Z GOSUB #INT ZAT #ACS <[~~]##ACS +[£]#Y[Z][(]S,, PRINT UVAL Z# LET LN SGN INKEY$ AT LET W RETURNASN S[O]TAN Y▘MINT ZLN COS RNDCOS LN [H]RNDMINT ZLN TAN RNDCOS 7LN [T]RNDLN [4]RND[S]S▀#INKEY$ #LN (INKEY$ #INKEY$ LN (INKEY$ #PI GOSUB #SQR Z[)]W PRINT 7LN [T]RND[S]K▀#INKEY$ # GOSUB #ABS Z[(]W4▘XSGN # GOSUB #USR ZUPEEK Z#USGN Z#[B]LN INPUT RND6CHR$ ZUABS Z#USGN Z#[B]LN INPUT RND6**Z£TAN LN +#4*UINT Z#5 4▘ /#J#7"#[L]4 RUN +4 INPUT TAN USTR$ ZECHR$ Z GOSUB #**Z6 AND Z GOSUB #>=Z PRINT FAST GOSUB # LPRINT C#UPEEK ZLN INKEY$ STR$ VAL #3ZACS <( IF AT ACS .*( CLS#SGN 7 FAST[B] GOSUB # LPRINT C▌#J#/ NEXT UABS ZLN INKEY$ Y,,[(]#VAL ,*ZACS 1( IF AT ACS +3( CLS>▘4 E>=Z,,6>=Z FOR E AND Z,,6 AND Z LET X4[A]5INT ZP4[?]TAN UUSR Z RETURN▒4▖,J/NOT UPEEK ZLN INKEY$ VAL ,3ZACS +( IF AT ACS 1*( CLS#UABS ZJ NEW▛C$#,VAL ?ACS 0( CLSAT ACS ▖( UNPLOT #/[E]E(RND#[T]COS RETURN█4▌LN [*]RNDINT ▘VAL LN PAUSE ,,AT FOR / GOTO PRINT SCROLL FAST:RND▟#LN ##7 FAST▞▌[J]#( CLEARSGN LPRINT LET TAN LN SCROLLRND#?( CLEARLN ##K▀Y▟>LN COS RNDTAB SQR #TAN LN SCROLLRND FASTAT LN 4+ FASTLN ##AT FAST##LN PLOT ;LN [~~]+ LPRINT / STEP LN SCROLLRND#▞ / SLOW###Y[Z][(]STR$ VAL PRINT LN SGN INKEY$ LET AT SGN TAN 2 COPY/▝2 STR$ LN C#SGN USTR$ Z#UPEEK Z5SGN Z PRINT FASTLN [D]#+C▞WLN [J]#/ RUN UUSR Z# LPRINT LET F FASTLN [D]#+C▞£LN [J]#/ RUN USTR$ Z# LPRINT UABS Z PRINT FASTLN [D]#+C▞XLN [J]#/ RUN UUSR Z# LPRINT LET 7LN [D]#+COS $LN [J]#/ SAVE LN 7?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 CLSLN ##/SGN 76-RNDLN #?LN [B]:##▘▘COS CLEARACS V#""( RAND $4 PLOT .#[N]4 INPUT TAN 7# RETURN#4,,LN OR #LN RUN #/L7# RETURN,C> RETURN;CG RETURN#C# RETURNAT C# RETURNTAB C#/# GOSUB #AT Z# NEW LIST LEN ( RETURNRNDCODE [O]#ATN [J]#/STR$ #LEN ▒#[J]# GOSUB #AT ZTAN ▞ COPY7# RETURN#COS RETURN,4▖Y▖/" RETURN;4VAL ▖# RETURN▀ASN SQR #M""Z/ STOP GOSUB #AT Z/SQR 7LN [T]RND## RETURN[T]ABS =INKEY$ # RETURNRNDABS "INKEY$ GOSUB #AT Z/[?]7LN [H]RND NEWZ GOSUB #AT Z[T]#K GOTO Y▒█#/ NEW6-RNDLN #? FAST CLEARACS ▘#CODE STR$ .LN SAVE < LPRINT FAST#[L]C£,VAL STR$ LN K#SGN AT <"/ LIST LPRINT /CODE 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 #AT Z PRINT YZ[)]>=[J]#LN RUN # LET VAL M<=Z[B]*[B]**- ACS >#5 2; FASTACS TLN STR$ RNDSGN U""Z RETURN▖ASN # RETURN▝C# RETURN▘CFY▒ PRINT STR$ , PRINT U""Z[B]4"U<=ZACS #C▖ LET J/▘ LET #)4 ;SGN LET <X4 TO AT ££ GOSUB #AT ZTAN U<=Z RETURNASEXP RETURN[A]KASN FAST5 2; FOR LPRINT /AT U<=Z▛ 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 COS RNDY*C▀LN [H]RND) WEAT Z FAST GOSUB #AT Z GOSUB #£RND< PRINT ▞4,VAL STR$ LN ##SGN AT <( PRINT LET X4 GOSUB LPRINT 6AT ZTAN LN COS RNDCATN LN [H]RNDW PRINT #Y""CHR$ ▒( UNPLOT ## LET /LEN 7LN [T]RNDLN ,,INKEY$ LN [4]RNDTAN Y COPY/▘[J]MVAL Z CLEARACS #[:]LN ## GOSUB #NOT ZE-RNDLN ## GOSUB # OR ZE-RND7LN [T]RNDLN ,,INKEY$ GOSUB #<=ZE#Z FAST GOSUB ##ZE OR Z FASTLN £PI LPRINT 6#ZENOT Z FASTLN £PI LPRINT 6#ZE<=ZLN £PI LPRINT 6#ZTAN LN +#4.UINT Z5 4##▘4 ,,▘ STEP * GOSUB [K]▞4F#( UNPLOT X4 DIM TAN USGN Z RETURN C##UPEEK Z#VAL Y[Z][(]VAL PRINT WVAL LN LET RNDSGN Y▒[S]4*UABS Z[<] RETURN▒S?#▘4 GOSUB PI# LET AT #LEN ▒#/ OR #?( CLEAR2 COPYS▘0 LET AT VAL LN SGN INKEY$ AT #▞ UABS Z##▀[B] GOSUB PIPIK[U]AT ▌USQR Z[S]4[L]USQR Z#EPEEK ZY COPY[W]4▘8# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT £ LPRINT 94 LIST 5INT ZP4▟TAN LN +#40UINT Z5 COPYR##▘4 GOSUB PI▘ STEP * GOSUB [S]▞47#( UNPLOT X4 CONT TAN USQR Z RETURN[Z]C##UPEEK Z#VAL Y[Z][(]VAL PRINT XVAL LN LET RNDSGN Y▒[S]4-UABS Z[<] RETURN▒S:#▘4 ,,# LET AT #LEN ▒#/ AND #?( CLEAR2 COPYS▘0 LET AT VAL LN SGN INKEY$ AT #▞ UABS Z##▀[B] GOSUB PIPIK[V]AT ▖USGN Z RETURN C▀[S]4[I]USGN Z#EPEEK ZY COPY[W]4▘8# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT £ LPRINT 94 LIST 5INT ZPTAB ▗#TAN LN +#4*UINT Z#5 COPYR▞4#[B]ACS -F( CLS[8]4 POKE 14 INPUT TAN USGN Z#UPEEK Z#VAL Y[Z][(]VAL PRINT £LN LET RND#?( CLEAR2 COPYS▘0 LET AT VAL LN SGN INKEY$ AT UABS Z£[T]4 STEP AT ▌# RETURN COPYC▒USQR Z##[U]KSQR GOSUB #SGN Z#INKEY$ #USTR$ Z# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT ▌ LPRINT H4 LIST 5INT ZP4[B]TAN LN +#41UINT Z#5 4[B]▞4ACS 27( CLS▘ S[B] FAST GOSUB PI LPRINT 4 INPUT 14 CONT TAN USGN Z#UABS Z#VAL Y[Z][(]VAL PRINT $LN LET RNDY,,[(]##▛( CLEAR2 COPYS▘0 LET AT VAL LN SGN INKEY$ AT UPEEK Z$[T]4>=AT ▌# RETURN COPYC▒USQR Z##[U]KATN USGN Z#UPEEK Z#USTR$ Z# FASTVAL Y[Z][(]2 LN SGN INKEY$ AT ▌ LPRINT H4 LIST 5INT ZP4[6]TAN 7# RETURN0K▌LN [*]RNDINT 1 RETURNGK RUN CHR$ 0TAN LN ▝##ACS 4ACS 4ACS 4ACS 4LN ▝#█#7# RETURN"#TAN 7# RETURN"TAB SQR #7#ACS #C▝CHR$ RND) 77 FAST▞▒A # FOR ;( CLEAR FOR 5 S; FOR LPRINT 7LN =#>4▌76-RNDTAN </ PAUSE 7LN [H]RND RETURN4) ▞SSTR$ LN [*]RNDINT .▘4 ,,# RETURNS**CHR$ /#TAN 7LN [H]RND RETURN4K SCROLLLN [4]RND[B]***- #5 Y;6**Z SCROLLLN [T]RND GOSUB # AND ZTAN LN ##Y[Z][(]K▝CHR$ RND##ACS WACS 1ACS WACS 1ACS WACS 1ACS GOTO 6>=Z#J NEW▛WM#RND) STOPZ GOSUB #**ZY▒ PRINT #>~~VAL #U#RND RETURN▌S)JLEN ,,[B]##: C:3ACS ;( CLS/▛#[J]ACS )*( CLS[Q]#7<#>#[Q]#FLN ##<AT ▀ LET XTAB ACS #TAN LN COS RNDTAB SQR #E>=Z) STOPZ▞▒VAL ,#7<,#LN ##F<AT ( LET TAN CLEARACS #EXP LN ##E-RND# RETURN,4$7 GOSUB ##Z FASTLN [4]# LPRINT LN [T]RND#~~PIVAL 5ORND##[S]C UNPLOT CLEAR[-]#M#RNDLN £#AT LN [4]#U#RND CLEAR[Y]O4 CLSTAN LN COS RNDY C▀LN [H]RNDM#RNDTAN 1""AT Y▖PEEK CLS0LN ###["]INKEY$ GOSUB ##INKEY$ <<7# RETURN#C*STR$ LN [H]RND#LN ▞INKEY$ ▖SGN ##ACS [W],LEN █>#<( POKE TAN ▞4[J]##ACS [W]>#<( RUN TAN E-RND# RETURN;C# RETURN#C▌LN [*]RNDINT + LPRINT 6-RND▘ TAN TO RETURN THENC▌LN [*]RNDINT ) FAST SCROLL )""#STR$ RETURN LLIST ASN ## RETURN SCROLLASN [:]RND RETURN LOAD ASN ▛# RETURN LIST ASN 3# RETURN PAUSE ASN ## RETURN PRINT ASN ## RETURN PLOT ASN [Y]INKEY$ RETURN RUN ASN ▟INKEY$ RETURN SAVE ASN PEEK # RETURN RAND ASN ## RETURN CLSASN ;INKEY$ RETURN UNPLOT ASN TAB INKEY$ RETURN CLEARASN ▗INKEY$ RETURN RETURNASN [*]RND RETURN COPYASN /# RETURN LPRINT 4[9]SGN )[J]#STR$ 7# RETURNXC##7# RETURN#C[<] RETURN;4 PLOT # RETURNAASN [▒]# RETURNBASN [B]INKEY$ RETURNCASN [B]PI RETURNDASN SCROLLINKEY$ RETURNIASN ## RETURNLASN [5]# RETURNPASN ## RETURNRASN [T]# RETURNS42F#7 RETURNDASN ## RETURNEASN ▞# RETURNMASN 8# RETURNPASN [1]# RETURNSASN ##/# RETURNTASN ## RETURNUASN F# RETURNW4UF#7 RETURNDASN ## RETURNLASN "# RETURNRASN ▟# RETURNUASN LEN #/57#7# RETURN#C; RETURN;4 PLOT # RETURNCASN [F]PI RETURNDASN FOR INKEY$ RETURNRASN [X]# RETURNTASN ###SQR #
1 REM FAST SAVE LOAD ##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 ##Y▀X4 CLEAR GOSUB #▌TAB ##ACS 5>=##USR ##TAN PEEK COPYY-X4 CLEAR<= RETURNY:X4 CLEAR#[(]####PEEK COPYY9X4 CLEAR<= RETURNY0X4 CLEARF7RTAN ▘ █VAL LN ##AT ▌TAB [=]#▀ GOSUB #LN ##LN SQR #$LN ## CLEAR FAST LET #:[E]LN ##LN SQR ##LN ##LN SQR ##LN ## CLEAR FAST LET ##LN ##7.#[N]4 PLOT TAN LN LLIST # RETURNHASN ▌#STR$ VAL PRINT LN LLIST ▒) ▝LN Z# LET M#RND RETURNS4£5 46#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 1#6#RND SCROLL RETURN#C~~ RETURN0S SCROLL RETURNAK CONT / LET LN 1#/SIN AT LPRINT )WRNDSTR$ GOSUB [K][J]E#RND GOSUB ##RND▚7.##[N]#4 RUN M#RNDF#M#RND LPRINT )4 LN [)]# GOSUB ##RND GOSUB ##RNDE#RNDLN [)]#/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 [4]#( CLSTAN - =PEEK COPY# RETURNRNDK)2 LN [4]#LN #?ABS [A]▀#[B]4 SCROLL/ SCROLL2 PEEK COPYLN [4]##[B]C PRINT LN [N]#04CHR$ LN [N]## RETURN[E]4EXP LN [N]##LN [N]#STR$ PEEK COPYLN [N]##SGN 7.#[N]4 PAUSE TAN FASTLN LLIST # RETURNHASN [=]# PRINT STR$ VAL 5WRNDLN [X]#AT SGN /£-▝LN Z# LET LPRINT 6-RND/ THEN5WRND,[Y]4 GOSUB 7<"#[L]4 PRINT LET LPRINT E#RND FAST RETURNS4:5 4 6#RNDLN [X]#AT #▟# RETURNV4/E(RND6#RNDLN [X]#AT FASTLN ▟# LPRINT FLN [1]=SGN LPRINT ##▞ RETURN#4▌5,,RND/ LLIST SCROLL RETURN#4?E#RND/SIN SCROLL RETURN#4▌LN 1#/[X] RETURN0 AND POKE ▝ RETURNAABS POKE ▝/ REM LET ▘4 5WRNDLN [X]#U#RND RETURNCODE 4▖YC/▞ RETURN#4▝YP INPUT █M#RND▞;5WRND#NOT 7( CLSY#E#RND GOSUB ##RNDSTR$ FAST;LN TO # LPRINT Y-LN TO # LPRINT Y=LN TO #Y#NOT #[;]#NOT ##LN 4+LN <=+TAN ***
2 REM [6][4][-][C][O][L]█[P][R][I][N][T]## LIST LIST LIST LIST LIST LIST LIST LIST WWWW LIST LIST LIST LIST #### LIST LIST LIST LIST ???? LIST LIST LIST LIST LIST SQR 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 M; FOR LPRINT U<=Z NEW█UAT Z?▞▒VAL PRINT ,#CGS0 NEW LIST PRINT # NEW?# LET [K]#<STR$ )4 ;SGN LET AT ( STOPAT £ GOSUB #AT ZTAN ACS ZACS ZACS ZACS Z PRINT # NEW LIST />=S~~ACS BACS BACS BACS B/ATN NEW?/ REM
5 REM [S][P][I][R][O][G][R][A][M]##LN PRINT "[B]LN ,,INKEY$ #SGN INKEY$ TO RETURN THEN FASTTAB SQR # SCROLL RETURN LPRINT 4 SAVE LOAD [4][4][4][4][4][4]O▞▌/▖ TO LN [4]RNDVAL SCROLLLN #?AT ( POKE LPRINT 6-RNDE,RND63RND LOAD CONT B DIM B FOR GOTO ▀M ▝▘ FOR I▝HN RAND ▝[7]H?H?/H CONT DIM ▌[5]? REM ▖B CONT DIM ?B?▖8H DIM ▖ FOR ▌B8ACS ▝▌ CONT DIM ?[4] GOTO 1 GOTO 0 REM [4] CONT DIM ▌[5]? GOTO ▖H1▘0O LOAD INPUT LOAD ▖ GOSUB LIST ▖? GOSUB LOAD ▖ INPUT LIST ▖▀LN ▝EXP ▝ PAUSE NEXT ▖ LET POKE ▖? LET NEXT ▖ PAUSE POKE ▖▀SGN ▝ABS ▝ NEW GOSUB ? LET ?8 SCROLL INPUT ? PAUSE ?8 PRINT M 6 PLOT M 2 PRINT K[S]# ▀N = PLOT K[S]Z ▀N ~~K COPY8ASN DJ▝▝▝ FOR [5]▀ACS N ▒O▘ #[W]=OLN #?K2Y [B]C[?] CLEARACS #▚LN F?<>5GINKEY$ ▘ LIST "#[L]4 CLSLN 7?# SCROLL#LN [*]RNDINT £
10 GOTO 9000
1000 IF USR HR THEN PRINT "[W]HICH DEMO?",,,,,,,,"1. 128,96,38,18,18";TAB 0;" 128,128,38,-18,-18",,,,,,,"2. 128,96,37,18,18";TAB 0;" 128,96,37,-18,-18"
1005 POKE QUICK,0
1010 IF USR HR THEN PRINT ,,,,"3. 128,96,39,18,18";TAB 0;" 128,96,39,-18,-18"
1020 IF USR HR THEN PRINT ,,,,"4. 128,96,51,15,15";TAB 0;" 128,96,51,-21,-21"
1025 IF USR HR THEN PRINT ,,,,"5. [Q]UIT"
1030 GOSUB 9400
1040 IF CODE Q$<CODE "1" OR CODE Q$>CODE "5" THEN GOTO 1000
1045 IF Q$="5" THEN IF USR HR THEN RETURN
1047 IF Q$="5" THEN STOP
1050 LET Q1=VAL Q$
1060 IF USR HR THEN PRINT "1. [B]LACK INK ON WHITE PAPER.",,,,,,,"2. [W]HITE INK ON BLACK PAPER."
1070 GOSUB 9400
1080 IF Q$<>"1" AND Q$<>"2" THEN GOTO 1060
1090 IF USR HR THEN RAND
1095 IF Q$="2" THEN IF USR HR THEN RAND 31
1100 IF USR HR THEN PRINT "1. [S][L][O][W] MODE",,,,,,,,"2. [F][A][S][T] MODE",,,,,,,,"3. [Q][U][I][C][K] MODE"
1110 GOSUB 9400
1120 IF Q$<>"1" AND Q$<>"2" AND Q$<>"3" THEN GOTO 1100
1130 IF Q$="1" THEN SLOW
1140 IF Q$="2" THEN FAST
1150 IF Q$="3" THEN POKE QUICK,1
1160 IF USR HR THEN CLS
1170 GOTO 2000+100*Q1
2100 REM [D][E][M][O]█[O][N][E]
2110 IF USR SPIRO THEN LPRINT 128,96,38,18,18
2120 IF USR SPIRO THEN LPRINT 128,96,38,-18,-18
2130 GOSUB 9300
2140 GOTO 1000
2200 REM [D][E][M][O]█[T][W][O]
2210 IF USR SPIRO THEN LPRINT 128,96,37,18,18
2220 IF USR SPIRO THEN LPRINT 128,96,37,-18,-18
2240 GOSUB 9300
2250 GOTO 1000
2300 REM [D][E][M][O]█[T][H][R][E][E]
2310 IF USR SPIRO THEN LPRINT 128,96,39,18,18
2320 IF USR SPIRO THEN LPRINT 128,96,39,-18,-18
2330 GOSUB 9300
2340 GOTO 1000
2400 REM [D][E][M][O]█[F][O][U][R]
2410 IF USR SPIRO THEN LPRINT 128,96,51,15,15
2420 IF USR SPIRO THEN LPRINT 128,96,51,-15,-15
2430 GOSUB 9300
2440 GOTO 1000
7998 STOP
7999 REM ▞▞▞▞[D][R][A][W]█[S][P][I][R][O][G][R][A][M]▚▚▚▚
8000 IF USR SPIRO THEN LPRINT A,B,F,M,R
8010 RETURN
9000 LET HR=19400
9001 LET SPIRO=21103
9002 LET QUICK=21332
9003 LET KEY=9500
9004 LET A$=",,~~,,~~,,~~,,~~,,[S][P][I][R][O][G][R][A][M]█[S][C][R][A][M],,~~,,~~,,~~,,~~"
9005 POKE QUICK,0
9006 IF USR HR THEN CLS
9007 IF USR HR THEN RUN
9008 IF USR HR THEN RAND
9010 IF USR HR THEN PRINT ;;A$
9020 IF USR HR THEN PRINT ,,,,;,"[S][P][I][R][O][G][R][A][M] WILL DRAW INTRICATE PATTERNS SIMILAR IN DESIGN TO PIC-TURES MADE WITH A SPIROGRAPH."
9030 IF USR HR THEN PRINT ,,,,"[I]N ORDER TO OPERATE [S][P][I][R][O][G][R][A][M] FIVE PARAMETERS HAVE TO BE SPECI- FIED, THESE ARE;"
9040 IF USR HR THEN PRINT ,,,,"[A] - X CENTER OF DIAGRAM";TAB 0;"[B] - Y CENTER OF DIAGRAM";TAB 0;"[F] - RADIUS OF FIXED GEAR";TAB 0;"[M] - RADIUS OF MOVING GEAR";TAB 0;"[R] - DISTANCE OF PEN HOLE FROM CENTER OF MOVING GEAR"
9050 IF USR HR THEN PRINT ,,,,"[T]HE METHOD OF USING [S][P][I][R][O][G][R][A][M] IS SIMILAR TO THE [S][H][R][E][B] [G][R][O][U][P] 2 COMMANDS;",,,,,"""[I][F] [U][S][R] [S][P][I][R][O] [T][H][E][N] [L][P][R][I][N][T] [A],[B],[F],[M],[R]"""
9060 IF USR HR THEN PRINT ,,,,"[H]OWEVER, YOU CAN NOT USE IT IN A CONCATATED FORM.";TAB 0,,,,"[A]NY ERROR REPORTS YOU MIGHT GET HAVE THE SAME MEANING AS WITH [S][H][R][E][B]. [U]SE ""[B][R][E][A][K]"" TO STOPTHE DRAWING PROGRAM."
9070 GOSUB KEY
9080 IF USR HR THEN PRINT "[T]HE DRAWING ROUTINE IS ENTIRELY IN FLOATING POINT CALCULATOR LANGUAGE AND [M].[C]., SO IF YOU DO ABORT THERE IS NO WAY TO CON- TINUE AFTERWARDS."
9090 IF USR HR THEN PRINT ,,,,"[A]N INTERESTING FACT WHICH MIGHTNOT BE GENERALLY KNOWN IS THAT YOU CAN ACTUALLY CONTROL UP TO 32 CALCULATOR MEMORIES ON THE [Z][X]81. [T]HE CODES FOR THESE RANGE FROM [C]0 TO [D][F] (STORE) AND [E]0 TO [E][F] (RECALL). [A]LL THE EXTRA SLOTS CAN BE ACCESSED BY CHANGING THESYSTEM VARIABLE [M][E][M]."
9100 IF USR HR THEN PRINT ,,,,"[H]OWEVER, BE SURE TO RESTORE [M][E][M] TO [M][E][M][B][O][T] WHEN YOU EXIT YOUR ROUTINE. [T]HIS PROGRAM USES 23 MEMORIES."
9110 IF USR HR THEN PRINT ,,,,"[I] HAVE ADDED A DISPLAY OPTION WHICH YOU MIGHT ALSO FIND INTER- ESTING. [T]HIS OPTION IS AN ALTERNATIVE TO [F][A][S][T] MODE. [I]T WILL AL- LOW YOU TO WATCH THE DRAWING OF THE [S][P][I][R][O][G][R][A][M]AT A FASTER RATE THAN [S][L][O][W] MODE."
9120 IF USR HR THEN PRINT ,,,,"[I]T OPERATES BY ALTERNATING BETWEEN THE PLOTTING AND [H][I]-[R][E][S] DIS- PLAY ROUTINES. [T]HE RESULT IS NOT THE BEST, BUT AT LEAST YOU CAN WATCH SOMETHING."
9130 GOSUB KEY
9140 IF USR HR THEN PRINT "[Y]OU CAN TURN ON THIS DISPLAY OPTION BY [P][O][K][E]ING ADDRESS 21332 WITH ANY NUMBER. [T]URN IT OFF BY [P][O][K][E]ING 21332 WITH ZERO."
9145 IF USR HR THEN PRINT ,,,,"[S][P][I][R][O][G][R][A][M] IS A PROGRAM WRITTEN FOR THE [S][P][E][C][T][R][U][M] COMPUTER APPEAR-ING IN VOL.2 NO.10 OF [Z][X] [C][O][M][P][U][T][I][N][G]. [M]ODIFIED BY [G].[C]. [H]ARDER."
9150 GOSUB KEY
9160 IF USR HR THEN PRINT "1. [R]UN DEMO.";TAB 0;"2. [Q]UIT"
9170 GOSUB 9400
9180 IF Q$="1" THEN GOTO 1000
9190 IF Q$="2" THEN IF USR HR THEN RETURN
9200 IF Q$="2" THEN STOP
9210 GOTO 9160
9300 IF USR HR THEN RUN
9310 IF INKEY$ ="" THEN GOTO 9310
9320 IF USR HR THEN CLS
9330 RETURN
9400 IF USR HR THEN PRINT ;;AT 184,00;",,~~,,~~,,~~,,~~,,~~[E][N][T][E][R]█[N][U][M][B][E][R],,~~,,~~,,~~,,~~,,~~"
9410 LET Q$=INKEY$
9420 IF Q$="" THEN GOTO 9410
9430 IF USR HR THEN CLS
9440 IF USR HR THEN PRINT A$;,AT 16,0;
9450 RETURN
9500 IF USR HR THEN PRINT ;;AT 184,0;"~~,,~~,,~~,,~~,,~~,,~~,,~~[A][N][Y]█[K][E][Y]~~,,~~,,~~,,~~,,~~,,~~,,"
9510 IF INKEY$ ="" THEN GOTO 9510
9520 IF USR HR THEN CLS
9530 IF USR HR THEN PRINT A$;,AT 16,0;
9540 RETURN
9900 SAVE "A:SPIRO,[P]"
9910 PRINT "[S][P][I][R][O] LOADED, ENABLE SCRAM BOARD THENPRESS A KEY"
9920 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.