Phoneme Editor

Phoneme Editor (ZPE) is an interactive editor for constructing and transmitting phoneme sequences to the Zebra-Talker speech synthesis peripheral.

The program maintains a buffer of up to 100 phoneme codes starting at memory address 60016, using POKE and PEEK to store and retrieve values directly in RAM. A 68-entry phoneme table is encoded as a packed string P$ of three-character codes (e.g., “EH3”, “PA0”, “AW1”), and speech output is triggered by sending phoneme bytes via OUT 191 to the hardware, with the inflection byte encoded in the upper bits.

Navigation through the phoneme sequence uses a cursor system laid out in an 8-column grid display, with keys 5/6/7/8 providing directional movement in the style of cursor keys.


Program Analysis

Program Structure

The program is organized into clearly separated subroutine blocks, with a main event loop at line 2000 and helper routines spread across several numbered regions. Execution begins at line 2000 via the GO TO 2000 at line 110. The main loop (lines 2030–2060) polls INKEY$ continuously, dispatching to a key-scan subroutine at 1500 which uses a chain of IF comparisons to branch to the appropriate editing action.

Line RangePurpose
1230–1255Display phoneme buffer on screen
1400–1460Cursor erase and redraw
1500–1530Key scan / dispatch
1550–1720Cursor movement (up/down/left/right/beginning/end)
1800–1830Screen help/key legend
2000–2060Main initialization and event loop
2110–2200Append phoneme (A key)
2300–2325Display single phoneme cell
2500–2540Delete last phoneme (D key)
2600–2670Kill all phonemes (K key)
2700–2760Replace phoneme at cursor (R key)
2800–2865Excise phoneme at cursor, shifting buffer (X key)
2900–2998Insert phoneme at cursor, shifting buffer (I key)
3005–3025Phoneme lookup in P$ table
3050–3060Invalid phoneme error message
3100–3110Print (screen copy + LPRINT listing)
3200–3265Screen listing with paged output (L key)
3300–3325LPRINT listing to printer (R key / P key)
3400–3440Speak: send phonemes to hardware via OUT 191 (S key)
9900–9920Tape save (W key)

Phoneme Table

The 68-phoneme vocabulary is stored as a single packed string P$ at line 2008, with each phoneme occupying exactly 3 characters (padded with spaces). Lookup uses the formula P$(I*3+1 TO I*3+3) or P$(W*3-2 TO W*3) (both are equivalent 1-based/0-based variants) to extract the 3-character symbol. The phoneme search subroutine at lines 3005–3025 walks all 68 entries and returns the index in I; if no match is found, I remains at 68 (the loop’s terminal value), which calling code uses as the “not found” sentinel.

Buffer and Memory Layout

Phoneme bytes are stored raw in RAM starting at address BUF=60016, above the CLEAR 59999 boundary set at line 50. This protects the buffer from being overwritten by BASIC. Each byte represents a phoneme index (0–63) or an inflection modifier byte (64+). The buffer holds up to MAXL=100 entries. POKE and PEEK are used throughout for direct manipulation.

Speech Hardware Interface

The SPEAK routine (lines 3400–3440) iterates through the buffer and sends each byte to the Zebra-Talker via OUT 191. Bytes with values 64 or above are treated as inflection prefix bytes: the inflection value is computed as (X-64)*64 and combined with the following phoneme byte before output. After the sequence, a terminator byte of 3 is sent via OUT 191,3. Each OUT call is followed by IN 191 (result stored in p), presumably to handshake or pace the hardware.

Screen Layout and Cursor System

Phonemes are displayed in a grid of 8 per row starting at screen row 1. The position of item I is calculated as row INT(I/8)+1, column 4*(I-8*INT(I/8)). The cursor is rendered as a > character in the same grid cell, and erased by printing a space in the old position. The cursor variable is initialized to -8 at startup, which means the first displayed cursor position will be at 0 after movement — this is an intentional offset to place the initial cursor before the first phoneme.

Key Bindings

  • 5 — move cursor left
  • 6 — move cursor down (next row)
  • 7 — move cursor up (previous row)
  • 8 — move cursor right
  • B — jump to beginning
  • E — jump to end
  • A — append phoneme
  • D — delete last phoneme
  • I — insert phoneme at cursor
  • K — kill (clear) all phonemes
  • R — replace phoneme at cursor
  • X — excise (delete) phoneme at cursor, shifting remainder
  • L — list phonemes to screen
  • P — print (COPY screen + LPRINT listing)
  • S — speak via hardware
  • W — save to tape
  • Q — quit (STOP)

Notable Techniques

The INSERT operation (lines 2965–2980) shifts phonemes upward in memory using a downward-counting FOR loop (STEP -1) to avoid overwriting data before it is copied — a standard in-place shift algorithm. Similarly, EXCISE (lines 2815–2825) shifts phonemes downward using a forward loop. The listing and LPRINT routines compute an INF (inflection) accumulator for bytes above 63, displaying the combined inflection-plus-phoneme value in the output columns.

Bugs and Anomalies

The subroutine at line 2300 contains a FOR loop header but its body jumps immediately to RETURN at line 2325 — the loop is effectively never used as a loop; instead, the code falls through from the FOR into the display and return logic. The variable E at line 2310 (PEEK(E+I)) is never initialized, making that path potentially unreliable; however line 2300 is only reached as a fall-through from line 2195 where I and W are already set, and execution goes directly to 2315, bypassing 2310. The GO TO 2990 at line 3265 (end of the LIST routine) jumps into the middle of the INSERT routine’s cleanup code (lines 2990–2998: CLS, help, display, cursor) — this appears intentional as a shared “redraw screen” block rather than a bug. The phoneme lookup subroutine starts at line 3005 but line 3000 does not exist; the GO SUB 3000 calls throughout the program therefore transfer to line 3005, which is a well-known BASIC technique for jumping to the nearest following line.

Off-by-One in String Indexing

Two slightly different index formulas are used to access P$. The display routine at line 1236 uses W*3-2 TO W*3 where W=1+PEEK(...) (1-based), while the list routines at lines 3225 and 3312 use W*3+1 TO W*3+3 where W=PEEK(...) (0-based). Both correctly address the same 3-character phoneme slot, just expressed differently. The +INF column in the listing output adds the inflection accumulator to the raw byte value, providing the synthesizer’s effective parameter.

Content

Appears On

Related Products

Unlimited vocabulary voice synthesizer uses the Votrax SC-01 phoneme synthesizer with 4 programmable pitch levels and automatic inflection. It produces...
Unlimited vocabulary including: words, letters, symbols and numbers. Talking is as simple as typing “TESTING 1 2 3”. Requires 16K...

Related Articles

Related Content

Image Gallery

Phoneme Editor

Source Code

   10 REM \:: COPYRIGHT (C) 1984 \::
   20 REM \:: ZEBRA SYSTEMS, INC.\::
   30 REM \:: ALL RIGHTS RESERVED\::
   40 REM \:: ZPE VER. 1.2 FEB.84\::
   45 POKE 23658,8: REM UPPERCASE
   47 INK 7: PAPER 1: BORDER 1: CLS 
   50 CLEAR 59999
  110 GO TO 2000
 1230 IF LENGTH=0 THEN RETURN 
 1231 FOR I=1 TO LENGTH
 1234 LET W=1+(PEEK (I+BUF-1))
 1235 IF W<0 THEN RETURN 
 1236 LET D$=P$(W*3-2 TO W*3)
 1240 PRINT AT INT (I/8)+1,4*(I-8*INT (I/8));" ";D$;
 1250 NEXT I
 1255 RETURN 
 1400 REM ERASE OLD CURSOR
 1405 LET D$=" "
 1410 LET C=CURSOR
 1415 GO SUB 1450
 1430 REM SHOW NEW CURSOR
 1435 LET D$=">"
 1440 LET C=NCURSOR
 1445 GO SUB 1450
 1447 RETURN 
 1450 REM CURSOR
 1455 PRINT AT INT (C/8)+1,4*(C-8*INT (C/8));D$;
 1460 RETURN 
 1500 REM KEY SCAN
 1505 IF D$="5" THEN GO TO 1610
 1506 IF D$="6" THEN GO TO 1570
 1507 IF D$="7" THEN GO TO 1550
 1508 IF D$="8" THEN GO TO 1590
 1509 IF D$="B" THEN GO TO 1630
 1510 IF D$="E" THEN GO TO 1645
 1511 IF D$="Q" THEN STOP 
 1512 IF D$="A" THEN GO TO 2100
 1513 IF D$="D" THEN GO TO 2500
 1514 IF D$="K" THEN GO TO 2600
 1515 IF D$="R" THEN GO TO 2700
 1516 IF D$="X" THEN GO TO 2800
 1517 IF D$="I" THEN GO TO 2900
 1518 IF D$="P" THEN GO TO 3100
 1519 IF D$="S" THEN GO TO 3400
 1520 IF D$="L" THEN GO TO 3200
 1521 IF D$="W" THEN GO TO 9900
 1530 RETURN 
 1550 REM UP
 1555 IF CURSOR<9 THEN GO TO 1700
 1560 LET NCURSOR=CURSOR-8
 1565 GO TO 1720
 1570 REM DOWN
 1575 IF CURSOR>=LENGTH-8 THEN GO TO 1700
 1580 LET NCURSOR=CURSOR+8
 1585 GO TO 1720
 1590 REM RIGHT
 1595 IF CURSOR=LENGTH THEN GO TO 1700
 1600 LET NCURSOR=CURSOR+1
 1605 GO TO 1720
 1610 REM LEFT
 1615 IF CURSOR=1 THEN GO TO 1720
 1620 LET NCURSOR=CURSOR-1
 1625 GO TO 1720
 1630 REM BEGINNING
 1635 LET NCURSOR=1
 1640 GO TO 1720
 1645 REM END
 1650 LET NCURSOR=LENGTH
 1655 GO TO 1720
 1700 REM INVALID REQUEST
 1710 LET NCURSOR=CURSOR
 1720 RETURN 
 1800 REM SCREEN HELP
 1810 PRINT AT 15,0;"(5)LEFT (6)DOWN (7)UP (8)RIGHT"
 1815 PRINT AT 16,0;"(B)EGINNING (E)ND (P)RINT";
 1816 PRINT AT 17,0;"(A)DD (D)ELETE (I)NSERT (K)ILL";
 1817 PRINT AT 18,0;"(R)EPLACE E(X)CISE (Q)UIT";
 1818 PRINT AT 19,0;"(L)IST (S)PEAK ";
 1830 RETURN 
 1900 STOP 
 2000 REM MAIN
 2001 LET CURSOR=-8
 2002 LET LENGTH=0
 2003 LET BUF=60016
 2005 DIM T$(3)
 2007 DIM P$(68*3)
 2008 LET P$="EH3EH2EH1PA0DT A2 A1 ZH AH2I3 I2 I1 M  N  B  V  CH SH Z  AW1NG AH1OO1OO L  K  J  H  G  F  D  S  A  AY Y1 UH3AH P  O  I  U  Y  T  R  E  W  AE AE1AW2UH2UH1UH O2 O1 IU U1 THVTH ER EH E1 AW PA1STPIN0IN1IN2IN3"
 2010 REM SOFTSTART
 2011 LET MAXL=100
 2012 GO SUB 1230
 2014 GO SUB 1800
 2015 LET NCURSOR=CURSOR
 2021 GO SUB 1430
 2030 LET D$=INKEY$
 2035 IF D$="" THEN GO TO 2030
 2040 GO SUB 1500
 2043 GO SUB 1400
 2050 LET CURSOR=NCURSOR
 2060 GO TO 2030
 2110 REM APPEND
 2115 IF LENGTH=MAXL THEN GO TO 2180
 2120 PRINT AT 20,0;"ENTER PHONEME CODE       "
 2125 INPUT T$
 2126 IF T$="   " THEN GO TO 2185
 2130 GO SUB 3000
 2150 IF I<68 THEN GO TO 2190
 2155 GO SUB 3050
 2160 GO TO 2120
 2180 PRINT AT 20,0;"BUFFER FULL. HIT ENTER     ";
 2182 INPUT T$
 2183 RETURN 
 2185 PRINT AT 20,0;"                              ";
 2186 RETURN 
 2190 POKE BUF+CURSOR,I
 2191 LET LENGTH=LENGTH+1
 2192 LET NCURSOR=LENGTH
 2193 LET W=I+1
 2194 LET I=NCURSOR
 2195 GO SUB 2315
 2196 GO SUB 1400
 2197 LET CURSOR=NCURSOR
 2200 GO TO 2120
 2300 FOR I=1 TO LENGTH
 2310 LET W=PEEK (E+I)
 2315 LET D$=P$(W*3-2 TO W*3)
 2320 PRINT AT INT (I/8)+1,4*(I-8*INT (I/8));" ";D$;
 2325 RETURN 
 2500 REM DELETE
 2505 IF LENGTH=0 THEN RETURN 
 2510 LET D$="   "
 2515 LET I=LENGTH
 2520 GO SUB 2320
 2525 LET LENGTH=LENGTH-1
 2530 LET NCURSOR=LENGTH
 2535 GO SUB 1400
 2540 RETURN 
 2600 REM KILL
 2605 PRINT AT 20,0;"DELETE ALL PHONEMES (Y/N)"
 2610 INPUT D$
 2615 IF D$="Y" THEN GO TO 2650
 2620 GO SUB 2185
 2625 RETURN 
 2650 LET LENGTH=0
 2655 LET NCURSOR=LENGTH
 2660 CLS 
 2665 GO SUB 1800
 2670 RETURN 
 2700 REM REPLACE
 2705 IF LENGTH=0 THEN RETURN 
 2710 LET W=1+PEEK (BUF-1+CURSOR)
 2712 LET D$=P$(W*3-2 TO W*3)
 2715 PRINT AT 20,0;"REPLACE > ";D$;" < WITH? ";
 2720 INPUT T$
 2722 GO SUB 3000
 2735 IF I=68 THEN GO TO 2715
 2737 POKE BUF+CURSOR-1,I
 2740 LET D$=T$
 2745 GO SUB 2185
 2747 LET I=CURSOR
 2750 GO SUB 2320
 2755 GO SUB 1400
 2760 RETURN 
 2800 REM EXCISE
 2805 IF LENGTH=0 THEN RETURN 
 2810 LET BUF=60016
 2815 FOR I=BUF+CURSOR-1 TO BUF+LENGTH-1
 2820 POKE I,PEEK (I+1)
 2825 NEXT I
 2830 LET LENGTH=LENGTH-1
 2835 CLS 
 2840 GO SUB 1800
 2845 GO SUB 1230
 2850 IF CURSOR>LENGTH THEN LET CURSOR=LENGTH
 2855 LET NCURSOR=CURSOR
 2860 GO SUB 1400
 2865 RETURN 
 2900 REM INSERT
 2910 IF LENGTH<MAXL THEN GO TO 2930
 2915 PRINT AT 20,0;"BUFFER FULL. HIT ENTER";
 2920 INPUT T$
 2925 RETURN 
 2930 PRINT AT 20,0;"ENTER 3 LETTER CODE";
 2932 INPUT T$
 2935 IF T$="" THEN GO TO 2185
 2940 GO SUB 3000
 2945 IF I<68 THEN GO TO 2960
 2950 GO SUB 3050
 2952 GO SUB 2185
 2955 GO TO 2930
 2960 LET PHONEME=I
 2965 FOR I=BUF+LENGTH-1 TO BUF+CURSOR-1 STEP -1
 2970 POKE I+1,PEEK I
 2975 NEXT I
 2980 POKE I+1,PHONEME
 2985 LET LENGTH=LENGTH+1
 2990 CLS 
 2992 GO SUB 1800
 2994 GO SUB 1230
 2996 GO SUB 1400
 2998 RETURN 
 3005 FOR I=0 TO 67
 3010 IF T$=P$((I*3)+1 TO (I*3)+3) THEN GO TO 3020
 3015 NEXT I
 3025 RETURN 
 3050 PRINT AT 20,0;"INVALID PHONEME. HIT ENTER.";
 3055 INPUT T$
 3060 RETURN 
 3100 REM PRINT
 3105 COPY 
 3110 GO TO 3300
 3200 REM LIST
 3205 LET INF=0
 3210 CLS 
 3211 PRINT "REF-SYM-CHR-DEC-+INF"
 3212 LET J=0
 3215 FOR I=1 TO LENGTH
 3220 LET W=PEEK (BUF+I-1)
 3222 IF W>63 THEN LET INF=(W-65)*64
 3225 LET D$=P$(W*3+1 TO W*3+3)
 3227 LET W1=W: IF W<32 THEN LET W1=63
 3230 PRINT I;"  ";D$;"   ";CHR$ W1;"   ";W;"   ";W+INF
 3235 LET J=J+1
 3240 IF J<>18 THEN GO TO 3260
 3243 LET J=0
 3245 PRINT "HIT ENTER TO CONTINUE.";
 3250 INPUT T$
 3255 CLS 
 3260 NEXT I
 3262 PRINT "HIT ENTER TO CONTINUE.";
 3263 INPUT T$
 3265 GO TO 2990
 3300 REM LLIST
 3302 LPRINT "REF-SYM-CHR-DEC-+INF"
 3303 LET INF=0
 3305 FOR I=1 TO LENGTH
 3310 LET W=PEEK (BUF+I-1)
 3311 IF W>63 THEN LET INF=(W-65)*64
 3312 LET D$=P$(W*3+1 TO W*3+3)
 3313 LET W1=W: IF W<32 THEN LET W1=63
 3315 LPRINT I;"  ";D$;"   ";CHR$ W1;"   ";W;"   ";W+INF
 3320 NEXT I
 3325 RETURN 
 3400 REM SPEAK
 3402 LET INF=0
 3405 FOR I=(BUF) TO (BUF+LENGTH)
 3410 LET X=PEEK (I)
 3415 IF X<64 THEN GO TO 3425
 3420 LET INF=(X-64)*64
 3422 GO TO 3430
 3425 OUT 191,INF+X
 3426 LET p=IN 191
 3430 NEXT I
 3433 OUT 191,3
 3434 LET p=IN 191
 3440 RETURN 
 9900 REM TAPE SAVE
 9910 SAVE "ZPE" LINE 0
 9920 RETURN 
   10 REM \:: COPYRIGHT (C) 1984 \::
   20 REM \:: ZEBRA SYSTEMS, INC.\::
   30 REM \:: ALL RIGHTS RESERVED\::
   40 REM \:: ZPE VER. 1.2 FEB.84\::
   45 POKE 23658,8: REM UPPERCASE
   47 INK 7: PAPER 1: BORDER 1: CLS 
   50 CLEAR 59999
  110 GO TO 2000
 1230 IF LENGTH=0 THEN RETURN 
 1231 FOR I=1 TO LENGTH
 1234 LET W=1+(PEEK (I+BUF-1))
 1235 IF W<0 THEN RETURN 
 1236 LET D$=P$(W*3-2 TO W*3)
 1240 PRINT AT INT (I/8)+1,4*(I-8*INT (I/8));" ";D$;
 1250 NEXT I
 1255 RETURN 
 1400 REM ERASE OLD CURSOR
 1405 LET D$=" "
 1410 LET C=CURSOR
 1415 GO SUB 1450
 1430 REM SHOW NEW CURSOR
 1435 LET D$=">"
 1440 LET C=NCURSOR
 1445 GO SUB 1450
 1447 RETURN 
 1450 REM CURSOR
 1455 PRINT AT INT (C/8)+1,4*(C-8*INT (C/8));D$;
 1460 RETURN 
 1500 REM KEY SCAN
 1505 IF D$="5" THEN GO TO 1610
 1506 IF D$="6" THEN GO TO 1570
 1507 IF D$="7" THEN GO TO 1550
 1508 IF D$="8" THEN GO TO 1590
 1509 IF D$="B" THEN GO TO 1630
 1510 IF D$="E" THEN GO TO 1645
 1511 IF D$="Q" THEN STOP 
 1512 IF D$="A" THEN GO TO 2100
 1513 IF D$="D" THEN GO TO 2500
 1514 IF D$="K" THEN GO TO 2600
 1515 IF D$="R" THEN GO TO 2700
 1516 IF D$="X" THEN GO TO 2800
 1517 IF D$="I" THEN GO TO 2900
 1518 IF D$="P" THEN GO TO 3100
 1519 IF D$="S" THEN GO TO 3400
 1520 IF D$="L" THEN GO TO 3200
 1521 IF D$="W" THEN GO TO 9900
 1530 RETURN 
 1550 REM UP
 1555 IF CURSOR<9 THEN GO TO 1700
 1560 LET NCURSOR=CURSOR-8
 1565 GO TO 1720
 1570 REM DOWN
 1575 IF CURSOR>=LENGTH-8 THEN GO TO 1700
 1580 LET NCURSOR=CURSOR+8
 1585 GO TO 1720
 1590 REM RIGHT
 1595 IF CURSOR=LENGTH THEN GO TO 1700
 1600 LET NCURSOR=CURSOR+1
 1605 GO TO 1720
 1610 REM LEFT
 1615 IF CURSOR=1 THEN GO TO 1720
 1620 LET NCURSOR=CURSOR-1
 1625 GO TO 1720
 1630 REM BEGINNING
 1635 LET NCURSOR=1
 1640 GO TO 1720
 1645 REM END
 1650 LET NCURSOR=LENGTH
 1655 GO TO 1720
 1700 REM INVALID REQUEST
 1710 LET NCURSOR=CURSOR
 1720 RETURN 
 1800 REM SCREEN HELP
 1810 PRINT AT 15,0;"(5)LEFT (6)DOWN (7)UP (8)RIGHT"
 1815 PRINT AT 16,0;"(B)EGINNING (E)ND (P)RINT";
 1816 PRINT AT 17,0;"(A)DD (D)ELETE (I)NSERT (K)ILL";
 1817 PRINT AT 18,0;"(R)EPLACE E(X)CISE (Q)UIT";
 1818 PRINT AT 19,0;"(L)IST (S)PEAK ";
 1830 RETURN 
 1900 STOP 
 2000 REM MAIN
 2001 LET CURSOR=-8
 2002 LET LENGTH=0
 2003 LET BUF=60016
 2005 DIM T$(3)
 2007 DIM P$(68*3)
 2008 LET P$="EH3EH2EH1PA0DT A2 A1 ZH AH2I3 I2 I1 M  N  B  V  CH SH Z  AW1NG AH1OO1OO L  K  J  H  G  F  D  S  A  AY Y1 UH3AH P  O  I  U  Y  T  R  E  W  AE AE1AW2UH2UH1UH O2 O1 IU U1 THVTH ER EH E1 AW PA1STPIN0IN1IN2IN3"
 2010 REM SOFTSTART
 2011 LET MAXL=100
 2012 GO SUB 1230
 2014 GO SUB 1800
 2015 LET NCURSOR=CURSOR
 2021 GO SUB 1430
 2030 LET D$=INKEY$
 2035 IF D$="" THEN GO TO 2030
 2040 GO SUB 1500
 2043 GO SUB 1400
 2050 LET CURSOR=NCURSOR
 2060 GO TO 2030
 2110 REM APPEND
 2115 IF LENGTH=MAXL THEN GO TO 2180
 2120 PRINT AT 20,0;"ENTER PHONEME CODE       "
 2125 INPUT T$
 2126 IF T$="   " THEN GO TO 2185
 2130 GO SUB 3000
 2150 IF I<68 THEN GO TO 2190
 2155 GO SUB 3050
 2160 GO TO 2120
 2180 PRINT AT 20,0;"BUFFER FULL. HIT ENTER     ";
 2182 INPUT T$
 2183 RETURN 
 2185 PRINT AT 20,0;"                              ";
 2186 RETURN 
 2190 POKE BUF+CURSOR,I
 2191 LET LENGTH=LENGTH+1
 2192 LET NCURSOR=LENGTH
 2193 LET W=I+1
 2194 LET I=NCURSOR
 2195 GO SUB 2315
 2196 GO SUB 1400
 2197 LET CURSOR=NCURSOR
 2200 GO TO 2120
 2300 FOR I=1 TO LENGTH
 2310 LET W=PEEK (E+I)
 2315 LET D$=P$(W*3-2 TO W*3)
 2320 PRINT AT INT (I/8)+1,4*(I-8*INT (I/8));" ";D$;
 2325 RETURN 
 2500 REM DELETE
 2505 IF LENGTH=0 THEN RETURN 
 2510 LET D$="   "
 2515 LET I=LENGTH
 2520 GO SUB 2320
 2525 LET LENGTH=LENGTH-1
 2530 LET NCURSOR=LENGTH
 2535 GO SUB 1400
 2540 RETURN 
 2600 REM KILL
 2605 PRINT AT 20,0;"DELETE ALL PHONEMES (Y/N)"
 2610 INPUT D$
 2615 IF D$="Y" THEN GO TO 2650
 2620 GO SUB 2185
 2625 RETURN 
 2650 LET LENGTH=0
 2655 LET NCURSOR=LENGTH
 2660 CLS 
 2665 GO SUB 1800
 2670 RETURN 
 2700 REM REPLACE
 2705 IF LENGTH=0 THEN RETURN 
 2710 LET W=1+PEEK (BUF-1+CURSOR)
 2712 LET D$=P$(W*3-2 TO W*3)
 2715 PRINT AT 20,0;"REPLACE > ";D$;" < WITH? ";
 2720 INPUT T$
 2722 GO SUB 3000
 2735 IF I=68 THEN GO TO 2715
 2737 POKE BUF+CURSOR-1,I
 2740 LET D$=T$
 2745 GO SUB 2185
 2747 LET I=CURSOR
 2750 GO SUB 2320
 2755 GO SUB 1400
 2760 RETURN 
 2800 REM EXCISE
 2805 IF LENGTH=0 THEN RETURN 
 2810 LET BUF=60016
 2815 FOR I=BUF+CURSOR-1 TO BUF+LENGTH-1
 2820 POKE I,PEEK (I+1)
 2825 NEXT I
 2830 LET LENGTH=LENGTH-1
 2835 CLS 
 2840 GO SUB 1800
 2845 GO SUB 1230
 2850 IF CURSOR>LENGTH THEN LET CURSOR=LENGTH
 2855 LET NCURSOR=CURSOR
 2860 GO SUB 1400
 2865 RETURN 
 2900 REM INSERT
 2910 IF LENGTH<MAXL THEN GO TO 2930
 2915 PRINT AT 20,0;"BUFFER FULL. HIT ENTER";
 2920 INPUT T$
 2925 RETURN 
 2930 PRINT AT 20,0;"ENTER 3 LETTER CODE";
 2932 INPUT T$
 2935 IF T$="" THEN GO TO 2185
 2940 GO SUB 3000
 2945 IF I<68 THEN GO TO 2960
 2950 GO SUB 3050
 2952 GO SUB 2185
 2955 GO TO 2930
 2960 LET PHONEME=I
 2965 FOR I=BUF+LENGTH-1 TO BUF+CURSOR-1 STEP -1
 2970 POKE I+1,PEEK I
 2975 NEXT I
 2980 POKE I+1,PHONEME
 2985 LET LENGTH=LENGTH+1
 2990 CLS 
 2992 GO SUB 1800
 2994 GO SUB 1230
 2996 GO SUB 1400
 2998 RETURN 
 3005 FOR I=0 TO 67
 3010 IF T$=P$((I*3)+1 TO (I*3)+3) THEN GO TO 3020
 3015 NEXT I
 3025 RETURN 
 3050 PRINT AT 20,0;"INVALID PHONEME. HIT ENTER.";
 3055 INPUT T$
 3060 RETURN 
 3100 REM PRINT
 3105 COPY 
 3110 GO TO 3300
 3200 REM LIST
 3205 LET INF=0
 3210 CLS 
 3211 PRINT "REF-SYM-CHR-DEC-+INF"
 3212 LET J=0
 3215 FOR I=1 TO LENGTH
 3220 LET W=PEEK (BUF+I-1)
 3222 IF W>63 THEN LET INF=(W-65)*64
 3225 LET D$=P$(W*3+1 TO W*3+3)
 3227 LET W1=W: IF W<32 THEN LET W1=63
 3230 PRINT I;"  ";D$;"   ";CHR$ W1;"   ";W;"   ";W+INF
 3235 LET J=J+1
 3240 IF J<>18 THEN GO TO 3260
 3243 LET J=0
 3245 PRINT "HIT ENTER TO CONTINUE.";
 3250 INPUT T$
 3255 CLS 
 3260 NEXT I
 3262 PRINT "HIT ENTER TO CONTINUE.";
 3263 INPUT T$
 3265 GO TO 2990
 3300 REM LLIST
 3302 LPRINT "REF-SYM-CHR-DEC-+INF"
 3303 LET INF=0
 3305 FOR I=1 TO LENGTH
 3310 LET W=PEEK (BUF+I-1)
 3311 IF W>63 THEN LET INF=(W-65)*64
 3312 LET D$=P$(W*3+1 TO W*3+3)
 3313 LET W1=W: IF W<32 THEN LET W1=63
 3315 LPRINT I;"  ";D$;"   ";CHR$ W1;"   ";W;"   ";W+INF
 3320 NEXT I
 3325 RETURN 
 3400 REM SPEAK
 3402 LET INF=0
 3405 FOR I=(BUF) TO (BUF+LENGTH)
 3410 LET X=PEEK (I)
 3415 IF X<64 THEN GO TO 3425
 3420 LET INF=(X-64)*64
 3422 GO TO 3430
 3425 OUT 191,INF+X
 3426 LET p=IN 191
 3430 NEXT I
 3433 OUT 191,3
 3434 LET p=IN 191
 3440 RETURN 
 9900 REM TAPE SAVE
 9910 SAVE "ZPE" LINE 0
 9920 RETURN 

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

People

No people associated with this content.

Scroll to Top