Bi-Plot Demo

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

Bi-Plot Demo is a demonstration program for the WRX16 hi-res graphics system, which splits an 8K display file into two 4K buffers (DF1 and DF2) displayed on alternating frames to create a superimposed overlay effect. The program draws axes and tick markers directly via POKE into both display buffers, then plots three mathematical curves: a sine wave (SIN(H*PI/40)) into DF1, a decaying exponential (EXP(-H/80)) into DF2, and their product into both simultaneously using machine code routines PLT1, PLT2, and PL12. Pixel coordinates are passed to the machine code via memory locations XP (16438) and PL12 (16721), with all hi-res entry points stored as named variables at lines 10–23 for readability. A low-resolution shadow of all three curves is also drawn using standard PLOT commands scaled to the bottom six lines of the display. An interactive menu (lines 600–690) lets the user switch between viewing DF1 alone, DF2 alone, both together, reversed, or normal low-res mode, with each option invoking the appropriate machine code routine.


Program Analysis

Program Structure

The program is organized into several distinct phases:

  1. Lines 1–3: REMs containing encoded WRX16 machine code (the routines called throughout the program reside here as data).
  2. Lines 4–5: Descriptive REM labels for the module and address table.
  3. Lines 10–24: Symbolic constant definitions — all machine code entry points and coordinate POKEs are assigned to named variables for clean referencing throughout.
  4. Lines 100–520: Main drawing sequence: clear both display files, draw axes, tick markers, plot three mathematical functions in hi-res and lo-res.
  5. Lines 525–710: Print an interactive menu, activate dual hi-res display, then loop on keypress to switch display modes.
  6. Lines 9990–9999: Save/startup block — saves the program, prompts the user to enable 8–16K SRAM, pauses, then auto-runs from line 10.

Machine Code Interface (WRX16 Routines)

All graphics operations are performed by calling machine code routines embedded in the REM lines via RAND USR. Pixel coordinates are passed by POKEing values into XP (address 16438, X coordinate) and YP (address 16439, Y coordinate) immediately before each call. The named entry points are:

VariableAddressFunction
HR116648Display DF1 only
HR216653Display DF2 only
HR1216658Display both DF1 and DF2 (alternating frames)
HRES16664Enter hi-res mode
NRML16672Return to normal lo-res display
CLS116681Clear display file 1
CLS216686Clear display file 2
RVRS16701Reverse hi-res displays
PLT116713Plot pixel in DF1
PLT216717Plot pixel in DF2
PL1216721Plot pixel in both DF1 and DF2
UPL116726Unplot (clear) pixel in DF1
UPL216730Unplot pixel in DF2
UP1216734Unplot pixel in both DFs
XP16438X coordinate register
YP16439Y coordinate register

Using named LET variables for machine code addresses (lines 10–24) rather than embedding raw numbers in each RAND USR call is a significant readability and maintainability technique, making the BASIC code self-documenting and easy to retarget if the routine addresses change.

Display File Layout

The WRX16 system divides an 8K hi-res display into two 4K buffers. DF1 occupies the lower 4K of the hi-res region and DF2 the upper 4K. When both are active, the hardware alternates between them on successive frames, producing a visual overlay — effectively 128×128 pixels with two independent logical layers. The horizontal axis baseline is drawn at byte offset 10240 to 10271 (line 130–160), and the corresponding row in DF2 is at offset +5984 (line 150). Vertical tick markers are placed with offsets of 2048 and 4096 bytes (lines 232–237), consistent with the 4K DF layout.

Mathematical Plotting

Three curves are plotted over H = 0 to 251 (lines 415–520):

  • F1: SIN(H*PI/40) — a sine wave covering about two full periods, plotted in DF1.
  • F2: EXP(-H/80) — a decaying exponential envelope, plotted in DF2.
  • F1 × F2: Their product (a damped sine), plotted in both DFs simultaneously via PL12.

The functions are stored as strings A$ and B$ and evaluated with VAL A$ and VAL B$ (lines 420–425). This is a classic BASIC technique for passing arbitrary expressions as first-class values, enabling the plotting loop to remain generic. The Y coordinate is scaled to 63 + 60*Z, centering the 128-pixel-tall hi-res display. A parallel lo-res shadow is plotted with standard PLOT at 1/4 horizontal resolution (lines 485–495), scaled to 27 + 15*Z for the six lower display lines.

Axes and Tick Marks

The horizontal axis is drawn in both DFs by POKEing 255 (all bits set) into each byte of the appropriate scan line (lines 130–160). The vertical axis is drawn using the PL12 routine with X fixed at 4, stepping Y from 0 to 127 (lines 170–210). Tick marks along the vertical axis use a bitmask of 60 (binary 00111100) POKEd at four DF offsets (lines 220–240). Horizontal tick marks are applied to DF2 (top axis) and DF1 (bottom axis) using PLT2 and PLT1 respectively across J=2 to 6 and J+59 (lines 250–330).

Interactive Menu and Mode Switching

After plotting, line 525 POKEs 0 into address 16418, then the program prints a full-screen menu using a single large PRINT AT string (line 530). The loop at lines 600–690 waits for a keypress (with a flush at line 610 to discard any held key) and dispatches to the appropriate mode-switch routine. Keys 1–5 each invoke a different RAND USR call; key 6 restores normal display and halts. Any unrecognized key simply re-enters the wait loop at line 610.

Startup and Save Block

Lines 9990–9999 form a self-contained save and launch sequence. The program saves itself (line 9991), prints a prompt requiring the user to confirm that 8–16K SRAM expansion is present (line 9993), pauses for approximately 200 seconds (PAUSE 4E4, line 9994), clears the screen, and then issues RUN (line 9999) to restart from line 10, bypassing the save block entirely on subsequent runs.

Notable Techniques and Observations

  • Use of VAL on string-stored expressions (A$, B$) as a functional abstraction for the plotting loop.
  • All machine code entry points named with LET at the top of the program — acts as a symbol table.
  • Direct memory POKE for horizontal line drawing is faster than looping through plot routines for bulk fills.
  • The POKE to address 16418 at line 525 likely signals a display mode register within the WRX16 system.
  • The lo-res shadow plot (lines 485–495) uses INT(H/4)+1 to downsample the 252-step hi-res X range to the 63-column lo-res display.
  • FAST mode is engaged at line 105 for the drawing phase but the display is not returned to SLOW before the menu — the WRX16 display driver manages its own refresh independently of the CPU speed flag.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM  GOSUB #                                <> DIM  NEXT Y▛# ( CLEARLEN  PAUSE W4 CLEAR▞█)4 5 4UORND NEW▘****▜# <>5ATN RND/▒)4 ▌ASN <=RND;# GOSUB ###▙"" GOSUB # GOSUB #7E£RND)L▙;Y2 GOSUB #Y PRINT ▘▛▒LN [P]▝LN [>]▝LN 4▝<>5[A]RND#[8]▝  
   2 REM 5Y /▒5Y▘/▀5 NEW▘6[X]RNDLN [C]INKEY$ <>5[A]RNDTAN LN [C]INKEY$ <>5▟▝TAN  5 4/▀5 K▘ (Q "##< GOSUB [K]TAN 5▜RND▘4 #LEN █#/ GOSUB A4/-AK/>LN #INKEY$ / RUN A4/?AK/"LN #INKEY$ / RUN  CLEARACS VCHR$ /▖ CLEARACS V[-] GOSUB #QRNDY█X[(] AND [H]:##ACS UACS .ACS UACS .ACS UACS .I ;## NEW▛W▘ ▒ACS ▝ACS )X4£ CLEARACS V#C▖ACS AT /▝ACS ▟( FOR #TAN LN F? CLEAR#OUORND[S]C IF Y2 GOSUB #TAN                                                                                                                                                                                                                 
   3 REM                                                                                                                                                                                                                                                                                [C]INKEY$ WAIT[8]INKEY$ NXBT[6]INKEY$ RSBT[2]INKEY$ STBT[)]INKEY$ BTLP#INKEY$ GADR#INKEY$ PLBC#INKEY$ PLT*#INKEY$ UNPL#INKEY$ PLOT#INKEY$ UP12#INKEY$ UPL2#INKEY$ UPL1#INKEY$ PL12#INKEY$ PLT2#INKEY$ PLT1XINKEY$ RVRSQINKEY$ LDIRLINKEY$ CLS*IINKEY$ CLS2DINKEY$ CLS14INKEY$ NRML/INKEY$ HRES+INKEY$ SMOD>INKEY$ HR12$INKEY$ HR-2▒INKEY$ HR-1<=RNDDP-3USR RNDDP-2ATN RNDDP-1[X]RNDMODE[J]RNDDP-A[E]RNDDP-0[A]RNDDPLY▙RNDDUMYVRNDCDFGQRNDCOORORNDFRMS£RNDDFILF?SLOW[H]:ERRB  
   4 REM WRX16-V2D DUAL HIRES
   5 REM NAMES 44A4-4494
  10 LET HR1 =16648
  11 LET HR2 =16653
  12 LET HR12=16658
  13 LET HRES=16664
  14 LET NRML=16672
  15 LET CLS1=16681
  16 LET CLS2=16686
  17 LET RVRS=16701
  18 LET PLT1=16713
  19 LET PLT2=16717
  20 LET PL12=16721
  21 LET UPL1=16726
  22 LET UPL2=16730
  23 LET UP12=16734
  24 LET XP  =16438
  25 LET YP  =16439
 100 REM [G][R][E][Y][P][L][O][T]█[D][E][M][O]
 105 FAST
 108 REM CLEAR BOTH DF"S
 110 RAND USR CLS1
 120 RAND USR CLS2
 130 FOR I=10240 TO 10271
 135 REM H-LINE, DF1
 140 POKE I,255
 145 REM H-LINE,DF2
 150 POKE I+5984,255
 160 NEXT I
 165 REM V-LINE, BOTH DF"S
 170 POKE XP,4
 180 FOR I=0 TO 127
 190 POKE YP,I
 200 RAND USR PL12
 210 NEXT I
 215 REM V-MARKERS
 220 FOR I=10080 TO 8192 STEP -192
 230 POKE I,60
 232 POKE I+2048,60
 235 POKE I+4096,60
 237 POKE I+6144,60
 240 NEXT I
 245 REM H-MARKERS
 250 FOR I=4 TO 244 STEP 10
 260 POKE XP,I
 270 FOR J=2 TO 6
 280 POKE YP,J
 290 RAND USR PLT2
 300 POKE YP,J+59
 310 RAND USR PLT1
 320 NEXT J
 330 NEXT I
 340 REM LO-RES AXES
 350 FOR I=0 TO 63
 360 PLOT I,12
 370 PLOT I,27
 375 IF I>12 AND I<43 THEN PLOT 0,I
 380 NEXT I
 390 REM  PLOT CURVES
 395 REM F1:SINE CURVE
 400 LET A$="SIN (H*PI/40)"
 405 REM F2:DECAYING EXPONENTIAL
 410 LET B$="EXP (-H/80)"
 415 FOR H=0 TO 251
 420 LET Z1=VAL A$
 425 LET Z2=VAL B$
 430 POKE XP,H+4
 435 REM FUNCTION NO. 1 (DF 1)
 440 POKE YP,63+60*Z1
 445 RAND USR PLT1
 450 REM FUNCTION NO.2 (DF 2)
 455 POKE YP,63+60*Z2
 460 RAND USR PLT2
 465 REM FCTN.1 * FCTN.2 (BOTH)
 470 POKE YP,63+60*Z1*Z2
 475 RAND USR PL12
 480 REM LO-RES PLOTTING
 485 PLOT INT (H/4)+1,27+15*Z1
 490 PLOT INT (H/4)+1,27+15*Z2
 495 PLOT INT (H/4)+1,27+15*Z1*Z2
 520 NEXT H
 525 POKE 16418,0
 530 PRINT AT 17,0;"[,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][,,][▒][1][:]█[D][I][S][P][L][A][Y]█[D][F][1]██[2][:]█[D][I][S][P][L][A][Y]█[D][F][2][▒][▒][3][:]█[D][I][S][P][L][A][Y]█[B][O][T][H]█[D][I][S][P][L][A][Y]█[F][I][L][E][S]█[▒][▒][4][:]█[R][E][V][E][R][S][E]█[H][I][G][H]█[-]█[R][E][S]█[D][I][S][P][L][A][Y][S][▒][▒][5][:]█[R][E][T][U][R][N]█[T][O]█[N][O][R][M][A][L]█[L][R]█[D][I][S][P][L][A][Y][▒][▒][6][:]█[Q][U][I][T]█[T][O]█[B][A][S][I][C]██████████████[▒][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~][~~]"
 600 RAND USR HR12
 610 IF INKEY$ <>"" THEN GOTO 610
 620 LET Z$=INKEY$ 
 630 IF Z$="" THEN GOTO 620
 640 IF Z$="1" THEN RAND USR HR1
 650 IF Z$="2" THEN RAND USR HR2
 660 IF Z$="3" THEN RAND USR HR12
 670 IF Z$="4" THEN RAND USR RVRS
 680 IF Z$="5" THEN RAND USR NRML
 690 IF Z$<>"6" THEN GOTO 610
 700 RAND USR NRML
 710 STOP
 9990 LET S$="BIPLOT"
 9991 SAVE S$
 9992 PRINT S$
 9993 PRINT ,,"BE SURE THAT 8-16K SRAM ENABLED,THEN PRESS ANY KEY TO START DEMO"
 9994 PAUSE 4E4
 9995 CLS
 9996 PRINT "PLEASE WAIT ABOUT 75 SECONDS...."
 9997 PAUSE 200
 9998 CLS
 9999 RUN 

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

Scroll to Top