Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM  itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57613 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\D6



Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top

Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top
A

Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top
CD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-57613 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\B5

Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top

Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top
A

Bulletin

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000

This program implements a scrolling bulletin board display for the Synchro-Sette June 1983 issue. It uses a machine code routine embedded in the REM statement at line 10 — the bytes decode to a LDDR-based block memory copy, called via USR to scroll the display. The program builds a 24×32 string array Z$() pre-filled with alternating inverse-space patterns and checkerboard rows, then continuously scrolls rows upward by cycling through the array. Two ticker-tape style text strings A$ and B$ are scrolled horizontally across banner boxes drawn with block graphics characters. A keypress (detected via INKEY$) triggers a PAUSE 40000 hold, and the SAVE command at line 9998 uses an inverse-video character in the filename as an auto-run flag.


Program Analysis

Program Structure

The program divides into several functional phases:

  1. Initialisation (lines 20–80): Switches to FAST mode, calculates a base address offset into X, builds the 24×32 display buffer array Z$() pre-filled with alternating inverse-space and checkerboard rows, then returns to SLOW mode.
  2. Main scroll loop (lines 180–260): Cycles variable A through rows 1–22, printing each row at the screen position returned by USR 16514, creating a continuous vertical scroll effect.
  3. Subroutine at 300 (lines 300–340): Manages a counter D to phase in title text into Z$(1) at specific thresholds, then falls through to the banner/box drawing sequence once D>65.
  4. Banner display (lines 350–620): Clears the screen with scrolls and PRINT, draws a decorative box using block graphics, animates the title string sideways across row 1, and prints the “JUNE 1983” date.
  5. Horizontal text scrollers (lines 3000–3080): Scroll strings A$ and B$ character-by-character across the top and bottom banner boxes in an infinite loop.
  6. Pause handler (lines 4000–4010): On any keypress, freezes display for approximately 40 seconds before returning.

Machine Code Routine in REM

Line 10 contains a machine code routine embedded directly in the REM statement body. The bytes are:

OffsetHexMnemonicNotes
001 D6 02LD BC, 02D6hByte count = 726 (approx. 22 text rows × 33 bytes)
32A 0C 40LD HL, (400Ch)Load HL from system variable (VARS area pointer)
609ADD HL, BCAdvance HL by block count
754LD D, H
85DLD E, LDE = HL (destination)
901 B5 02LD BC, 02B5hSecond byte count
122A 0C 40LD HL, (400Ch)Reload HL from same system variable
1509ADD HL, BC
16ED B8LDDRBlock copy backwards
18C9RET

The routine performs a backwards block memory copy (LDDR) to shift a region of the display file or string array upward by one row. It is called indirectly via USR 16514 in the PRINT AT statement at lines 240 and 520 — 16514 (4002h) is the address of the second byte of the REM line’s data, i.e. the first byte of the machine code.

Display Buffer Technique

Rather than printing directly to the screen, the program maintains a 24×32 string array Z$() that acts as a software frame buffer. Each element holds one display row as a 32-character string. The main loop prints individual rows at the current screen position via PRINT AT USR 16514,0;Z$(C), where the machine code side-effect of USR provides the scroll, and the PRINT renders the next row.

Rows that are multiples of 3 are initialised (line 65) to a checkerboard pattern of alternating @ and # inverse-video pairs, providing a visual border between content rows. All other rows use the inverse-space pattern stored in Q$.

Key BASIC Idioms

  • Inverse-video strings: Q$ at line 35 is built entirely from inverse-space characters, providing a filled background row. Titles at lines 300–310 use inverse letters throughout.
  • Wrap-around counter: Lines 210 and 230 wrap B and C at the array boundaries (1–22) to achieve continuous circular scrolling without an array bounds error.
  • Horizontal scroll via substring: Lines 3000–3080 iterate N from 1 to LEN A$-28, printing A$(N TO N+27) to scroll a 28-character window across the full string one character per frame.
  • POKE 16418,0 at line 540 clears the ZX81 system variable CDFLAG (or equivalent TS1000 flag), forcing the display back to a known state after mode transitions.

Block Graphics Box Drawing

Lines 570–610 draw two decorative rectangular boxes using ZX81 block graphic characters. The top and bottom edges use ▖▄▄▄…▄▖ style sequences, the sides use and , and the corners are formed by appropriate quadrant characters. The inner box spanning rows 10–13 holds the “SYNCHRO-SETTE PRESENTS” / bulletin board title area, while the outer box spanning rows 2–21 frames the scrolling text display.

Notable Techniques

  • The D counter in the GOSUB 300 subroutine acts as a state machine: at D>1 the first title line appears; at D>24 it changes to the full bulletin board title; at D>65 execution falls through to the banner drawing code rather than returning, effectively a computed GOTO via threshold comparison.
  • The X variable computed at line 30 (PEEK 16404 + 256*PEEK 16405 - 794) calculates an offset into the display file based on the D-FILE pointer, but X is never subsequently used in the listing — it may be a remnant of an earlier version or used by the machine code to locate data.
  • The horizontal title animation at lines 460–500 prepends an extra inverse-space to R$ on each iteration while printing at column 25 down to column 11 (25 − 15 + 1 = 11), creating a slide-in effect from the right edge.

Bugs and Anomalies

  • A$ and B$ are referenced at lines 3000–3070 but never defined or loaded in the visible listing. They are presumably loaded from tape before this program runs, or the listing is incomplete.
  • The horizontal scroller loop at line 3000 uses LEN A$-28 without guarding against LEN A$<28, which would cause a negative subscript error if a short string were loaded.
  • Line 380 PRINT AT 2,0;""; prints an empty string, which serves only to position the cursor — a common ZX81 idiom but unusual when followed immediately by a FOR/PRINT loop that positions its own output.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Bulletin

Source Code

  10 REM \01\D6\02\2A\0C\40\09\54\5D\01\B5\02\2A\0C\40\09\ED\B8\C9
  20 FAST 
  30 LET X=PEEK 16404+256*PEEK 16405-794
  35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 DIM Z$(24,32)
  50 FOR N=1 TO 22
  60 LET Z$(N)=Q$
  65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##"
  70 NEXT N
  80 SLOW 
 180 LET D=0
 190 LET A=1
 200 LET B=A+1
 205 GOSUB 300
 210 IF B=23 THEN LET B=1
 220 LET C=A-1
 230 IF C=0 THEN LET C=22
 240 PRINT AT USR 16514,0;Z$(C)
 250 LET A=C
 260 GOTO 200
 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % "
 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D"
 320 LET D=D+1
 330 IF D>65 THEN GOTO 350
 340 RETURN 
 350 FOR N=1 TO 20
 360 SCROLL 
 370 NEXT N
 380 PRINT AT 2,0;"";
 390 FOR N=1 TO 20
 400 PRINT Q$
 410 NEXT N
 420 LET R$="% "+Z$(1)
 430 FOR N=0 TO 6
 440 PRINT AT 1,0+N;R$
 450 NEXT N
 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% "
 470 FOR N=1 TO 15
 480 PRINT AT 1,25;R$
 490 LET R$="% "+R$
 500 NEXT N
 510 FOR N=1 TO 10
 520 PRINT AT USR 16514,0;Q$
 530 NEXT N
 540 POKE 16418,0
 550 PRINT AT 22,0;Q$
 560 PRINT AT 23,0;Q$
 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' "
 580 FOR N=1 TO 30
 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.."
 600 NEXT N
 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: "
 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3"
3000 FOR N=1 TO LEN A$-28
3010 PRINT AT 3,2;A$(N TO N+27)
3020 IF INKEY$<>"" THEN GOSUB 4000
3030 NEXT N
3040 FOR N=1 TO LEN B$-28
3050 PRINT AT 20,2;B$(N TO N+27)
3060 IF INKEY$<>"" THEN GOSUB 4000
3070 NEXT N
3080 GOTO 3000
4000 PAUSE 40000
4010 RETURN 
9998 SAVE "BULLETI%N"
9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top
C\ED\B8\C9 20 FAST 30 LET X=PEEK 16404+256*PEEK 16405-794 35 LET Q$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % " 40 DIM Z$(24,32) 50 FOR N=1 TO 22 60 LET Z$(N)=Q$ 65 IF N/3=INT (N/3) THEN LET Z$(N)="\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##\@@\##" 70 NEXT N 80 SLOW 180 LET D=0 190 LET A=1 200 LET B=A+1 205 GOSUB 300 210 IF B=23 THEN LET B=1 220 LET C=A-1 230 IF C=0 THEN LET C=22 240 PRINT AT USR 16514,0;Z$(C) 250 LET A=C 260 GOTO 200 300 IF D>1 THEN LET Z$(1)="% % % % % %S%Y%N%C%H%R%O%-%S%E%T%T%E% %P%R%E%S%E%N%T%S% % % % % " 310 IF D>24 THEN LET Z$(1)="%T%H%E% %S%Y%N%C%H%R%O%-%S%E%T%T%E% %B%U%L%L%E%T%I%N% %B%O%A%R%D" 320 LET D=D+1 330 IF D>65 THEN GOTO 350 340 RETURN 350 FOR N=1 TO 20 360 SCROLL 370 NEXT N 380 PRINT AT 2,0;""; 390 FOR N=1 TO 20 400 PRINT Q$ 410 NEXT N 420 LET R$="% "+Z$(1) 430 FOR N=0 TO 6 440 PRINT AT 1,0+N;R$ 450 NEXT N 460 LET R$="% %B%U%L%L%E%T%I%N% % %B%O%A%R%D% " 470 FOR N=1 TO 15 480 PRINT AT 1,25;R$ 490 LET R$="% "+R$ 500 NEXT N 510 FOR N=1 TO 10 520 PRINT AT USR 16514,0;Q$ 530 NEXT N 540 POKE 16418,0 550 PRINT AT 22,0;Q$ 560 PRINT AT 23,0;Q$ 570 PRINT AT 10,6;"\ .\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\. ";AT 11,6;"\ :";AT 11,24;"\: ";AT 12,6;"\ :";AT 12,24;"\: ";AT 13,6;"\ '\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\' " 580 FOR N=1 TO 30 590 PRINT AT 2,N;"\''";AT 4,N;"\..";AT 19,N;"\''";AT 21,N;"\.." 600 NEXT N 610 PRINT AT 3,1;"\ :";AT 3,30;"\: ";AT 20,1;"\ :";AT 20,30;"\: " 620 PRINT AT 7,14;"%J%U%N%E";AT 16,14;"%1%9%8%3" \n3000 FOR N=1 TO LEN A$-28 \n3010 PRINT AT 3,2;A$(N TO N+27) \n3020 IF INKEY$<>"" THEN GOSUB 4000 \n3030 NEXT N \n3040 FOR N=1 TO LEN B$-28 \n3050 PRINT AT 20,2;B$(N TO N+27) \n3060 IF INKEY$<>"" THEN GOSUB 4000 \n3070 NEXT N \n3080 GOTO 3000 \n4000 PAUSE 40000 \n4010 RETURN \n9998 SAVE "BULLETI%N" \n9999 GOTO 0

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

People

No people associated with this content.

Scroll to Top