--- title: "ISTUG-BBS" id: 51899 type: "computer_media" slug: "istug-bbs" url: "http://localhost/computer_media/istug-bbs/" markdown_url: "http://localhost/computer_media/istug-bbs.md" published_at: "2023-08-16T01:42:21+00:00" modified_at: "2026-04-01T10:29:49+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A fully-featured BASIC bulletin board system supporting remote callers via modem, with message storage, sysop chat, quick scan, and a password-protected editor." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Indiana Sinclair Timex User Group" slug: "indiana-sinclair-timex-user-group" taxonomy: "post_tag" url: "http://localhost/tag/indiana-sinclair-timex-user-group/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Paul Holmgren" slug: "paul-holmgren" taxonomy: "indiv" url: "http://localhost/indiv/paul-holmgren/" - name: "Willie Jones" slug: "willie-jones" taxonomy: "indiv" url: "http://localhost/indiv/willie-jones/" genre: - name: "BBS" slug: "bbs" taxonomy: "genre" url: "http://localhost/type/bbs/" media_type: "Program" programmers: - name: "Paul Holmgren" slug: "paul-holmgren" taxonomy: "indiv" url: "http://localhost/indiv/paul-holmgren/" - name: "Willie Jones" slug: "willie-jones" taxonomy: "indiv" url: "http://localhost/indiv/willie-jones/" download_url: "https://archive.org/download/timex-sinclair-software-archive/ISTUG-BBS (1987)(Holmgren, Paul and Jones, Willie)(US)(TS2068)(Cassette).zip" mediadate: "1987" related_products: - id: 36978 title: "I.S.T.U.G. TS2068 BBS" type: "product" url: "http://localhost/product/i-s-t-u-g-ts2068-bbs/" related_content: - id: 24793 title: "Indiana Sinclair-Timex Users Group (ISTUG)" type: "usergroup" url: "http://localhost/usergroup/indiana-sinclair-timex-users-group/" media_type_tags: "BBS" --- ISTUG-BBS is a bulletin board system written entirely in BASIC for the unexpanded TS2068, allowing remote callers to read and leave messages, chat with the sysop, and scan bulletins via a modem connection. The program uses machine code routines at fixed addresses (26724 for receive, 26766 for transmit, and 26715 for status polling) to handle serial communication through port 115, with modem control via port 119 (CODE “w”). Message storage uses a DIM m$(41,600) string array holding up to 40 messages of 600 characters each, with a parallel DIM d$(560) array for 14-character date/time stamps. The sysop editor, entered by pressing SYMBOL SHIFT, supports reading, deleting, writing, and saving the message base to tape using SAVE “BBSmsgbase” DATA m$(). The system clock is read from the three-byte frame counter at addresses 23672–23674 and converted to hours/minutes for time-on-line tracking. *** ## Program Analysis ### Program Structure The program is organized as a collection of named subroutines, with line numbers stored in BASIC variables rather than hard-coded into `GO TO` and `GO SUB` statements. The initialization block at line `1760`–`1820` assigns all major entry points to variables: - `nl` = 30 (send newline) - `sm` = 41 (send message, also doubles as the message count limit) - `beep` = 70 (audible beep) - `menu` = 250 (main menu) - `cls` = 360 (clear screen) - `con` = 540 (continue/press enter prompt) - `ret` (dynamic return address, set before branching) The main execution flow starts at line `10` with `GO TO VAL "1760"`, runs initialization, then enters the sysop editor at `1490`. Normal callers enter at line `170` after an incoming call is detected. The program uses `ON ERR GO TO` extensively for both error recovery and as a flow-control mechanism (e.g., redirecting to the menu on input errors). ### Machine Code Interface Serial communication is handled entirely through three machine code routines at fixed RAM addresses, initialized at line `1790`: | Variable | Address | Purpose | | --- | --- | --- | | `rcv` | 26724 | Receive one character; returns ASCII code via USR | | `xmt` | 26766 | Transmit one character; called before each `OUT 115,c` | | 26715 | (literal) | Poll modem status; returns 0, 1, 2, or 3 for TX/RX ready flags | Characters are received with `CHR$ USR rcv` and transmitted by first calling `RANDOMIZE USR xmt` then `OUT 115,CODE c$`. The modem control register is accessed via port `mc` (CODE “w” = 119). A form-feed character (ASCII 12) is sent over the modem via `OUT 115,12` at line `360` to clear the caller’s terminal screen. ### Message Storage The message base uses a two-dimensional string array `DIM m$(41,600)` declared at line `1800`, where slot 41 (`sm`) is reserved as a scratch/metadata record. Each message record is structured as: - Columns 1–31: “TO: ” header with recipient name - Columns 33–64: “From: ” header with sender name - Column 65 onward: message body text (up to 534 characters) - A `CHR$ 3` (ETX) byte marks the end of the message body Date/time stamps are stored in a separate flat string `d$` with 14-character slots per message (indexed as `d$(y*14-13 TO y*14)`). The entire message base is saved to tape with `SAVE "BBSmsgbase" DATA m$()` from the sysop editor. ### Clock and Timing The system clock is read from the frame counter at addresses 23672–23674 (the standard three-byte ticker) at line `1180`, converted to hours and minutes, and compared against the session start time stored in `temp`. The clock can be set by the sysop via the “E” editor command, which POKEs new values back into 23672–23674 at lines `1855`–`1860`. Midnight rollover is handled at line `1180` with a day counter increment. ### Sysop Editor The sysop editor is entered by pressing SYMBOL SHIFT from most program states (detected as `INKEY$=" STEP "` — the token representation of that key combination). It is protected by `ON ERR RESET` at line `1470`, which resets error handling to prevent callers from accidentally or intentionally entering the editor via error conditions. The editor flag `ed` is set to `NOT PI` (i.e., 0, false) for normal operation and to a non-zero value when the sysop is active, allowing the same code paths (message writing, quick scan) to behave differently for the sysop. ### Data Transmission Loop Sending a string stored in `p$` is handled by the subroutine at line `50`, which iterates character by character, calling the transmit machine code routine and then `OUT 115` for each. A special case exists in the message display loop at line `490`: when a `CHR$ 3` (ETX) is encountered in the message body, transmission stops early, preventing garbage after the message terminator from being sent to the caller. ### Input Handling and Backspace Several input loops implement a software backspace by detecting `CHR$ 8` from the caller and decrementing the loop index `x` by 2 (one for the current position, one for the `NEXT x` increment). This pattern appears in name input (line `980`), message addressing (line `620`), and message body input (line `670`). ### Notable Techniques and Idioms - `VAL "number"` is used extensively in `GO TO` and `GO SUB` as a memory optimization, avoiding storage of integer line-number literals. - `SGN PI` is used as a constant 1 throughout (since `PI > 0`, `SGN PI = 1`), saving token space over the literal `1`. - `NOT PI` evaluates to 0 (false), used to initialize boolean-style flags like `ed`. - The `ret` variable acts as a computed return address: it is set to a target line number before calling a subroutine, and the subroutine ends with `GO TO ret`, enabling reuse of single routines from multiple call sites without nesting `GO SUB`. - The bulletin, menu text, logon screen, and user list are all stored as `DATA` statements and sent via a generic `READ`/`GO SUB sm` loop at line `1070`, with the first `DATA` value being the item count. - Line `600` uses `LET m$(y,LEN d$)=CHR$ PI` — `LEN d$` is 560 (14×40), and `CHR$ PI` is `CHR$ 3` since `INT PI = 3`, pre-placing an ETX terminator. ### Bugs and Anomalies - At line `430`, the loop `FOR x=SGN x TO PI` uses `SGN x` as the start value. Since `x` is carried over from prior usage, this is not always 1; if `x` happened to be 0 the loop would start at 0, potentially writing outside the intended 1–3 character input buffer `c$=" "`. - At line `550`, `GO TO VAL "550"` creates an infinite tight loop with no timeout or escape path for the caller; only an error or disconnect can break out of the “press ENTER” prompt if the caller does not send a carriage return. - The variable `sm` is used both as the subroutine entry point for “send message” (line 41) and as the message array size limit (41), creating a naming collision that is intentional but potentially confusing. - Line `1550` does `LET ed=nl` before jumping to the leave-message routine. Since `nl` is the line number 30, this sets `ed` to 30 rather than a true/false flag, which the message-writing code at line `600` interprets as truthy, redirecting to the sysop message path — this appears intentional for sysop-mode message leaving. ## Source Code ``` 0 REM CODE FLASH w NEW O<>CODE FLASH w NEW \ >=CODE FLASH w NEW ( POKE FLASH sO AND CONTINUE AND 8 POKE FLASH w NEW \ >=CODE FLASH w NEW ( POKE y OPEN #s<>CODE FLASH w NEW \ >=CODE FLASH w NEW ( POKE STR$ !$!,T]USR ] OR *K\\>) GO SUB LEN LPRINT >PEEK PLOT #>XPEEK LIST #>PEEK REM STR$ z GO SUB LEN LPRINT +s( RANDOMIZE <>> OPEN #w>" OPEN #w>@ OPEN #w>{ OPEN #w>7 OPEN #w<> \* PEH SOFTWARE 1986 10 GO TO VAL "1760" 20 REM send a nl= NEW LINE 30 POKE 23692,255: PRINT : RANDOMIZE USR xmt: OUT 115,CODE l$: RETURN 40 REM PRINT TO caller 50 GO SUB nl: PRINT p$;: FOR x=SGN PI TO LEN p$: RANDOMIZE USR xmt: OUT 115,CODE p$(x): NEXT x: RETURN 60 REM BEEP 70 FOR x=9 TO 2 STEP -SGN PI: BEEP .2,15: NEXT x: RETURN 80 REM test FOR sysop access 90 IF IN mc<128 THEN GO TO VAL "1160" 100 IF INKEY$="c" OR INKEY$="C" THEN GO TO VAL "810" 110 IF INKEY$=" STEP " THEN GO TO VAL "1470" 120 GO TO ret 130 REM CLOSE # modem 140 GO SUB VAL "1710": IF ed THEN LET ed=NOT PI 150 OUT mc,34: OUT mc,ed 160 REM test FOR IN call 170 GO SUB VAL "1200": PRINT AT 17,27;t$(2): LET ret=VAL "180": GO TO VAL "110" 180 IF IN mc=5 THEN GO TO 170 190 REM start/set on LINE time 200 RANDOMIZE USR 26834: PAUSE ret: ON ERR GO TO VAL "1160": GO SUB beep: LET temp=hr*60+min: LET l$=CHR$ 13: RANDOMIZE USR 26788: LET p$="Hello"+l$+"Hello is this 2 lines Y/N": GO SUB sm 210 LET c$=CHR$ USR rcv: GO SUB nl: IF c$="y" OR c$="Y" THEN GO TO VAL "930" 220 IF c$="n" OR c$="N" THEN LET l$=CHR$ 10: RANDOMIZE USR 26782: GO TO VAL "930" 230 GO TO 210 240 REM menu 250 RESTORE VAL "1260": ON ERR GO TO VAL "1670": GO SUB cls: GO SUB VAL "1070" 260 LET p$="(C,G,L,Q,R,T,U)? ": GO SUB sm: LET c$=CHR$ USR rcv: PRINT c$: GO SUB nl 270 IF c$="c" OR c$="C" THEN GO TO VAL "810" 280 IF c$="g" OR c$="G" THEN GO TO VAL "1120" 290 IF c$="l" OR c$="L" THEN GO TO VAL "580" 300 IF c$="q" OR c$="Q" THEN LET p$="use CONTROL C to Abort Scan.": GO SUB sm: GO TO VAL "760" 310 IF c$="r" OR c$="R" THEN GO SUB nl: GO TO VAL "420" 320 IF c$="t" OR c$="T" THEN GO SUB VAL "1200": GO SUB sm: GO TO VAL "260" 330 IF c$="u" OR c$="U" THEN GO TO VAL "1100" 340 GO TO VAL "260" 350 REM CLS SCREEN$ ,12=FF 360 CLS : OUT 115,12: RETURN 370 REM FORMAT & READ header 380 LET p1=32: LET p2=64: FOR x=5 TO p2: IF m$(y,x)=l$ AND x<=32 THEN LET p1=x: LET x=39 390 IF m$(y,x)=l$ AND x<=64 THEN LET p2=x: LET x=64 400 NEXT x: LET p$="Message :"+STR$ y+" "+d$(y*14-13 TO y*14)+l$+m$(y, TO p1)+m$(y,33 TO p2): RETURN 410 REM READ msg 420 LET p$="Message 1 to 40, Menu=0 >? ": GO SUB sm: LET c$=" ": ON ERR GO TO menu 430 FOR x=SGN x TO PI: LET c$(x)=CHR$ USR rcv: IF c$(2)=l$ OR c$(PI)=l$ THEN GO TO VAL "460" 440 IF (c$(x)<"0") OR (c$(x)>"9") THEN GO TO VAL "420" 450 NEXT x: IF LEN c$>2 THEN GO TO VAL "420" 460 GO SUB nl: LET y=VAL c$: IF NOT y THEN GO TO menu 470 IF y>=sm OR m$(y,1)=" " THEN GO TO VAL "1700" 480 GO SUB 370: LET p$=p$+m$(y,65 TO ) 490 GO SUB cls: PRINT ''"Working": FOR x=SGN PI TO LEN p$: LET c=CODE p$(x): IF c=3 THEN GO TO VAL "520" 500 RANDOMIZE USR xmt: OUT 115,c 510 NEXT x: LET x=x-SGN PI 520 GO SUB nl: PRINT p$( TO x): LPRINT " READ msg. "+STR$ y: GO TO VAL "420" 530 REM con= CONTINUE 540 GO SUB nl: LET p$="Press when ready": GO SUB sm 550 IF CHR$ USR rcv=l$ THEN GO TO ret 560 GO TO VAL "550" 570 REM leave message 580 GO SUB cls: LET p$="Is this message for Sysop Y/N>": GO SUB sm: LET c$=CHR$ USR rcv: IF c$="y" OR c$="Y" THEN GO TO VAL "1740" 590 GO SUB nl: FOR y=SGN PI TO VAL "40": IF m$(y,1)<>" " THEN NEXT y: GO TO VAL "1680" 600 LET m$(y,LEN d$)=CHR$ PI: IF ed THEN GO TO VAL "1610" 610 LPRINT "Left msg. #";y: LET p$="Who gets Mess. "+STR$ y+"?": GO SUB sm: GO SUB nl: LET m$(y)="TO: ": FOR x=5 TO 31 620 LET m$(y,x)=CHR$ USR rcv: IF m$(y,x)=CHR$ 8 AND x>=5 THEN LET x=x-2: NEXT x 630 IF m$(y,x)=l$ THEN GO TO VAL "650" 640 PRINT m$(y,x);: NEXT x: LET m$(y,x)=l$ 650 LET m$(y,33 TO )="From: "+n$: LET p$="Input Message (534 chars max).. to save.": GO SUB sm: GO SUB nl 660 LET ret=VAL "700": FOR x=CODE "A" TO VAL "599" 670 LET c=USR rcv: IF c=8 AND (x>=65) THEN LET x=x-2: NEXT x 680 LET m$(y,x)=CHR$ c: PRINT CHR$ c;: IF c=3 THEN GO TO VAL "710" 690 GO TO 90 700 NEXT x 710 LET p3=x: LET p$="Message"+(" full and" AND x>=VAL "599")+" saved.": GO SUB sm: GO SUB VAL "740": IF ed THEN LET ed=p3: GO TO VAL "1750" 720 GO TO VAL "790" 730 REM FORMAT date/time 740 GO SUB VAL "1200": LET d$(y*14-13 TO y*14)=p$: RETURN 750 REM Quick scan 760 LET ret=VAL "770": FOR y=SGN PI TO 40: IF m$(y,1)<>" " THEN GO SUB 370: GO SUB sm: IF NOT ed THEN GO TO 90 770 IF IN 115=3 THEN GO TO VAL "260" 780 NEXT y: IF ed THEN GO TO VAL "1650" 790 LET ret=menu: GO TO con 800 REM chat 810 LET p$="Paging sysop....": GO SUB sm: FOR x=SGN x TO VAL "144": IF INKEY$="" THEN PRINT ".";: RANDOMIZE USR xmt: OUT 115,46: BEEP .1,15: NEXT x: LET p$="Sorry, all we found were cobwebs": GO SUB sm: LPRINT "Tried chat": PAUSE CODE "c": GO TO menu 820 GO SUB cls: LET p$=n$+"entering chat mode": GO SUB sm: GO SUB nl: POKE VAL "23658",ed: PRINT "SYMBL SHIFT/ STEP TO LEAVE CHAT." 830 IF INKEY$=" STEP " THEN GO TO VAL "1470" 840 LET p1=ed: LET p2=ed 850 LET x=USR 26715: LET p2=x AND (x=1 OR x=3): LET p1=x AND (x=2 OR x=3) 860 IF p1 THEN LET c=USR rcv: PRINT CHR$ c;: IF c=CODE l$ THEN PRINT '">"; 870 IF p2 AND INKEY$<>"" THEN GO TO 890 880 GO TO 830 890 IF p2 THEN LET c$=INKEY$: PRINT c$;: OUT 115,CODE c$: FOR x=NOT PI TO PI: NEXT x: IF c$=CHR$ 13 THEN RANDOMIZE USR xmt: OUT 115,62 900 IF INKEY$<>"" THEN GO TO 900 910 GO TO 830 920 REM send logon SCREEN$ 930 RESTORE VAL "1290": GO SUB cls: GO SUB VAL "950": LET ret=VAL "1050": GO TO con 940 REM send bulletin 950 RESTORE VAL "1330": GO SUB cls: GO SUB VAL "1070" 960 REM INPUT callers name 970 GO SUB beep: LET p$="Who's calling?"+l$: GO SUB sm: LET n$=" ": RANDOMIZE USR xmt: OUT 115,5: FOR x=SGN x TO LEN n$ 980 LET n$(x)=CHR$ USR rcv: IF n$(x)=CHR$ 8 AND (x>=2) THEN LET x=x-2: NEXT x 990 IF x": GO SUB sm: LET c$=CHR$ USR rcv 1040 IF c$="n" OR c$="N" THEN GO TO VAL "970" 1050 GO SUB nl: GO SUB 1200: LPRINT n$'p$( TO 14): GO TO menu 1060 REM send SCREEN$ DATA 1070 READ y: LET ret=VAL "1080": FOR y=SGN PI TO y: READ p$: GO SUB sm: GO TO 90 1080 NEXT y: RETURN 1090 REM user LIST 1100 RESTORE VAL "1370": GO SUB cls: GO SUB VAL "1070": LET ret=menu: GO TO con 1110 REM quit BBS 1120 GO SUB cls 1130 RESTORE VAL "1430": GO SUB VAL "1070" 1140 LET c$=CHR$ USR rcv: IF c$="n" OR c$="N" THEN GO TO menu 1150 READ p$: GO SUB sm: GO SUB VAL "1200": GO SUB sm: LPRINT p$'': OUT mc,64: OUT mc,0 1160 OUT mc,0: GO TO VAL "140" 1170 REM timer 1180 LET time=VAL "((PEEK 23672+256*PEEK 23673+65536*PEEK 23674)/3600)": LET hr=INT (time/60): LET min=INT (time-hr*60): IF hr>=24 THEN LET hr=NOT PI: LET dy=dy+SGN PI: GO SUB VAL "1850" 1190 RETURN 1200 GO SUB 1180: LET time=INT ((hr*60+min)-temp) 1210 LET p1=INT (time/60): LET p2=INT (time-(p1*60)): IF p1<0 THEN LET p1=p1+24 1220 LET c=SGN PI: GO SUB 1240: LET c=2: LET p1=hr: LET p2=min: GO SUB 1240 1230 LET p$=STR$ mo+"-"+STR$ dy+"-"+STR$ yr+";"+t$(2)+" Online "+t$(1)+l$: RETURN 1240 LET t$(c)=("0" AND LEN STR$ p1=SGN PI)+STR$ p1+":"+("0" AND LEN STR$ p2=SGN PI)+STR$ p2: RETURN 1250 REM menu DATA 1260 DATA 10," I.S.T.U.G.'s TIMEX-BOARD","","hat","oodby","eave a Message" 1270 DATA "uick Scan messages","ead message","ime on","sers list","" 1280 REM logon DATA 1290 DATA 11," WELCOME TO I.S.T.U.G.'s BBS","-------------------------------","using an unexpanded Timex 2068","","Settings:","Duplex: Full Word Size: 7","Parity: Even Stop Bits: 1","" 1300 DATA "","Open 24hrs a day, 7 days a week","" 1310 DATA "" 1320 REM bull DATA 1330 DATA 8,"Mad Programmer: Paul Holmgren","Igor Sysop: Willie Jones","","**** >>> -Bullentin- <<< **** " 1340 DATA "","Keep your Modem's warm and stay","tuned to the I.S.T.U.G. BBs","" 1350 DATA "" 1360 REM user DATA 1370 DATA 8,"" 1380 DATA "" 1390 DATA "" 1400 DATA "" 1410 DATA "","If we missed you please leave","Sysop a mess. and you will be","added to our list" 1420 REM quit DATA 1430 DATA 8,"","The Indiana Sinclair Timex","","Users Group hopes you enjoyed" 1440 DATA "","our little Bulletin Board.","","Are you ready to leave Y/N >","Goodby. Hanging up now" 1450 DATA "" 1460 REM edit 1470 ON ERR RESET 1480 LET p$="Commander Sysop taking control, Please Stand By": GO SUB sm 1490 CLS : PRINT "SYSOP EDITOR"''"C heck Time"'"D elete a msg."'"E stablish correct time"'"H ang up"'"L eave a msg."'"M ain Menu"'"Q uick Scan Msg. base"'"R ead Msg."'"S ave messages"''"(C,D,E,H,L,M,Q,R,S)" 1500 POKE VAL "23658",VAL "8": PAUSE ed: LET c$=INKEY$ 1510 IF c$="C" THEN GO SUB VAL "1200": PRINT p$( TO 14): GO TO VAL "1650" 1520 IF c$="D" THEN INPUT "DELETE msg. #?: ";x: PRINT "Msg. # ";x;" deleted": LET m$(x)="": LET p$="": GO SUB VAL "740": GO TO VAL "1650" 1530 IF c$="E" THEN GO SUB VAL "1840" 1540 IF c$="H" THEN GO TO VAL "1120" 1550 IF c$="L" THEN LET ed=nl: GO TO VAL "590" 1560 IF c$="M" THEN GO TO menu 1570 IF c$="Q" THEN LET ed=nl: GO TO VAL "750" 1580 IF c$="R" THEN INPUT " READ Msg. #? ";y: CLS : GO SUB VAL "370": PRINT p$'m$(y,CODE "A" TO ): GO TO VAL "1650" 1590 IF c$="S" THEN LET m$(sm)=d$: SAVE "BBSmsgbase" DATA m$() 1600 GO TO VAL "1490" 1610 CLS : LET ed=NOT PI: INPUT " SYMBL SHIFT/ STEP TO STOP :"'"Msg. TO ? ";p$: LET m$(y)="To :"+p$+l$: LET m$(y,CODE "!" TO )="From : Sysop Willie"+l$: GO SUB VAL "740": GO SUB VAL "370": PRINT p$: LET p$="" 1620 INPUT LINE c$: IF c$=" STEP " THEN GO TO VAL "1640" 1630 LET p$=p$+c$+l$: PRINT c$: IF LEN p$<=VAL "535" THEN GO TO VAL "1620" 1640 LET m$(y,CODE "A" TO )=p$+CHR$ PI: PRINT 1650 LET ed=NOT PI: PRINT " NEXT ?": PAUSE ed: GO TO VAL "1490" 1660 REM error trapped messages 1670 ON ERR RESET : LET p$="Sorry "+n$+" A bug has Bit you.": GO SUB sm: GO SUB beep: GO TO menu: REM ?=control g=Beep 1680 IF ed THEN PRINT "I,m full, delete something first": GO TO VAL "1650" 1690 LET p$="Message base full right now."+l$+"Please try later": LPRINT '" I'm full. Do something. SOS"'': GO SUB sm: GO TO con 1700 LET ret=VAL "420": LET p$="Sorry no message "+STR$ y+". Try again": GO SUB sm: GO TO con 1710 REM idle SCREEN$ 1720 CLS : PRINT AT VAL "7",VAL "7";"The I.S.T.U.G. BBS";AT VAL "10",PI+PI;"Scanning Phone LINE "'''''''" PEH SOFTWARE: 10-11-86": RETURN 1730 REM LPRINT sysop msg 1740 GO SUB cls: LET y=sm: LET m$(y)="": LET ed=y: GO TO VAL "650" 1750 LPRINT n$;m$(sm,CODE "A" TO ed): LET ed=NOT PI: GO TO menu 1760 REM init, 40 msg. base 1770 PAPER NOT PI: BORDER NOT PI: INK VAL "9": CLS 1780 PRINT '" STEP from most modes will GO TO SYSOP edit menu" 1790 LET rcv=VAL "26724": LET xmt=VAL "26766": DIM t$(2,5): LET temp=PI: LET mc=CODE "w" 1800 LET nl=VAL "30": LET sm=VAL "41": LET beep=VAL "70": LET menu=VAL "250": LET cls=VAL "360": LET con=VAL "540": LET l$=CHR$ 13: DIM m$(sm,VAL "600"): LET ed=NOT PI 1810 INPUT "Add a message base? ";p$: IF p$="y" OR p$="Y" THEN PRINT "Start Message Base Tape.": LOAD "" DATA m$() 1820 LET d$=m$(sm): GO TO VAL "1490" 1830 REM FORMAT & POKE clock 1840 INPUT "Month 1-12 ";mo,"Day 1-31 ";dy,"Hour 00-23 ";hr,"Minute ";min,"Year 86 ";yr 1850 LET x=VAL "(hr*3600+min*60)*60": LET y=INT (x/65536): POKE 23674,y 1860 LET p1=x-y*65536: LET x=INT (p1/256): POKE 23673,x: POKE 23672,p1-x*256: RETURN 1870 REM SAVE 1880 CLEAR : SAVE "bbs" LINE PI: GO TO VAL "1760" ```