--- title: "T/S Tinyboard BBS" type: "article" slug: "t-s-tinyboard-bbs" url: "http://localhost/article/t-s-tinyboard-bbs/" markdown_url: "http://localhost/article/t-s-tinyboard-bbs.md" published_at: "2022-10-07T12:22:51+00:00" modified_at: "2026-08-02T18:56:25+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "T/S TINYBOARD was begun as an experiment in how the MODEM works. The first step in the beginning was to find out about the hardware inside the Westridge MODEM. The controlling chip is an 8251 USART. Further information about the 8251 can be found in the Intel 8080 Users Manual. The software in its present…" category: - name: "CATS Newsletter" slug: "cats-newsletter" taxonomy: "category" url: "http://localhost/category/periodicals/cats-newsletter/" post_tag: - name: "BBS" slug: "bbs" taxonomy: "post_tag" url: "http://localhost/tag/bbs/" - name: "Best of Timex/Sinclair 2068 Articles and Documents" slug: "ts2068best" taxonomy: "post_tag" url: "http://localhost/tag/ts2068best/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" - name: "Type-in program" slug: "type-in-program" taxonomy: "post_tag" url: "http://localhost/tag/type-in-program/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Lucy Gordon" slug: "lucy-gordon" taxonomy: "indiv" url: "http://localhost/indiv/lucy-gordon/" - name: "Mark Fisher" slug: "mark-fisher" taxonomy: "indiv" url: "http://localhost/indiv/mark-fisher/" - name: "Randy Gordon" slug: "randy-gordon" taxonomy: "indiv" url: "http://localhost/indiv/randy-gordon/" publication_r: id: 35941 title: "CATS Newsletter" type: "periodical" url: "http://localhost/periodical/cats-newsletter/" authors: "Mark Fisher" authors_r: - name: "Mark Fisher" slug: "mark-fisher" taxonomy: "indiv" url: "http://localhost/indiv/mark-fisher/" volume: "4" issue: "2" issues_articles: - id: 39613 title: "CATS v4 n2" type: "issue" url: "http://localhost/issue/cats-v4-n2/" pages: "4" pubdate: "May 1986" archive_link: false article_media: - id: 56447 title: "Tinyboard" type: "computer_media" url: "http://localhost/computer_media/tinyboard/" --- T/S TINYBOARD was begun as an experiment in how the MODEM works. The first step in the beginning was to find out about the hardware inside the Westridge MODEM. The controlling chip is an 8251 USART. Further information about the 8251 can be found in the Intel 8080 Users Manual. The software in its present state is fully operational, even though it is crude. I hope by releasing it to public domain many improvements will be made. All of the present controls may not be to the sysop’s liking. It is written in BASIC with named variables for all modules so modification should be fairly easy. Using the program is fairly easy. It has been tested for many weeks here in Cincinatti. The first thing you see when you LOAD is the Flashware logo, followed by messages that ask whether you want to LOAD a message base and logon bulletin. Since you are just starting, the answer to both of these questions is no. The program will then immediately go to auto-answer mode. From there, the sysop can exit to Edit mode by pressing NOT (symbol-S). Operation of the program can be monitored at all times by watching the screen. Some of the original research on this hardware came from [Randy Kuhn](http://localhost/indiv/randy-kuhn/) of [Cincinnatti TSUG](http://localhost/usergroup/timex-sinclair-users-group-of-cincinnati/). It is his basic aut-answer routine. Many people have told me that I shouldn’t release the program to public domain, but rather sell it. I feel that in order to survive we are going to have to help each other. Make any changes you want to in the software – but if you make significant improvements please post them to me so that we all may benefit. If anyone puts it up full time let me know – I would like to call. ### Mark Fisher’s Revision I’m not sure the Randy and Lucy would recognise their creation in this listing; I’ve changed almost every line number in an attempt to clarify the program’s flow. Major changes include: 1. I have pulled the Send and Recieve routines out into subroutines, rather than repeat them over and over in the program. Since there is an ON ERR return to the Quit routine if a glitch occurs in transmission, unused RETURN values could be left in the machine stack, causing a crash. To avoid this, I established FN b, which calculates a value for the variable RET. Rather than GO SUB, I GO TO Intake and return via GO TO RET. 2. The message base may be browsed through the Read menu, allowing listing messages by sender, addressee, or number. I would like to implement a variable length message base to conserve memory (or, store the messages on disk). 3. The Timer routine has been greatly streamlined and incorporated into the Main Menu title. 4. Line 9025 loads AERCO print driver code. Modify or omit as needed for your system. If you omit it, don’t forget to modify line 9810 as well. I wish I could say that this version has been thoroughly tested. I have used it extensively between two Westridge MODEMs in my home, and it works well. It has also been used through phone lines to a 2068 with no problems, and a 1000 with a few glitches. An attempt to access it from a MacIntosh failed. Have fun! If you can start up a CATS version of Tinyboard, let me know. All we need is a member that can afford to leave his MODEM hooked to a line for some fixed part of a day on a regular basis. I think the club could even be persuaded to loan a MODEM to the member that volunteers to be the sysop. ### BASIC Listing — TS2068 Program: TINYBOARD ``` 1 CLEAR 64000: LET t$="*********************************** * T/S Tinyboard ** by Flashware * * (c) 1986 ** Randy/Lucy Gordon * * TSUG Cincinatti, OH ***********************************" 10 LET t$=t$+" Edited by Mark Fisher, CATS" 20 DEF FN b()=1+PEEK 23621+256*PEEK 23622: REM current line+1 30 GO TO 9000 400 REM ***** Newline ***** 410 RANDOMIZE USR output 420 OUT 115,13 430 RETURN 500 REM ***** Send ***** 510 POKE 23692,255 520 FOR x=1 TO LEN p$ 530 RANDOMIZE USR output 540 OUT 115,CODE p$(x) 550 IF p$(x)>=" " THEN PRINT p$(x); 560 NEXT x 570 RETURN 600 REM ***** intake word ***** 610 LET c$="": ON ERR GO TO quit 620 LET v$=CHR$ USR input: PRINT v$; 630 IF v$=CHR$ 13 THEN PRINT : GO TO ret 640 LET c$=c$+v$: GO TO 620 700 REM ***** timer ***** 710 LET time=INT ((PEEK 23672+256*PEEK 23673+256*256*PEEK 23674)/60): LET hr=INT (time/3600): LET min=INT ((time-hr*3600)/60) 720 LET x$=(STR$ hr+" hr, "+STR$ min+" min, "+STR$ (time-(hr*3600+min*60))+" sec") 730 RETURN 1000 REM ***** Autoans ***** 1010 OUT 119,34 1020 OUT 119,0: REM Hangs up 1030 REM ansloop 1040 LET a=IN 119 1050 IF CODE INKEY$=195 THEN GO TO edit 1060 IF a=5 THEN GO TO ansloop 1070 FOR x=1 TO 5: BEEP .1,40: NEXT x 1080 OUT 119,2 1090 OUT 119,34: REM MODEM seek tone 1100 PAUSE 300 2000 REM ***** Warmstart ***** 2010 FOR x=7 TO 0 STEP -1: BORDER x: BEEP .1,x: NEXT x: OUT 119,64: OUT 119,123: OUT 119,55: POKE 23674,0: POKE 23673,0: POKE 23672,0: REM set online timer 2020 PAUSE 30: FOR x=1 TO 30: RANDOMIZE USR output: OUT 115,0: NEXT x 2030 IF IN 119<128 THEN GO TO quit 2040 LET p$=CHR$ 26+CHR$ 31+CHR$ 28: GO SUB send: REM clear rec. screen 2050 FOR x=1 TO 5: GO SUB n1: PRINT : NEXT x 2060 LET p$=t$: GO SUB send: REM send logon bulletin 2070 FOR x=1 TO 5: GO SUB n1: PRINT : NEXT x 2080 LET p$="Please enter full name and date:"+CHR$ 5: GO SUB send: GO SUB n1 2090 LET ret=FN b(): GO TO intake 2100 LET u$=c$+CHR$ 13: LPRINT c$+" "; 2500 REM ***** inputcom ***** 2510 RESTORE 2520: GO SUB timer 2520 DATA "T/S Tinyboard Main Menu","Time on = "+x$,"(R)ead Messages","(L)eave Message","(C)hat mode","(G)oodbye"," ","Choice ?:" 2530 FOR p=1 TO 8: GO SUB n1: READ p$: GO SUB send: PRINT 2540 NEXT p 2550 LET ret=FN b(): GO TO intake 2560 IF c$="R" OR c$="r" THEN GO TO read 2570 IF c$="L" OR c$="l" THEN GO TO leave 2580 IF c$="C" OR c$="c" THEN GO TO chat 2590 IF c$="G" OR c$="g" THEN GO TO quit 2600 GO TO inputcom 3000 REM ****** Read Messages ***** 3010 GO SUB n1: GO SUB n1: RESTORE 3020 3020 DATA STR$ c+" message"+("s" AND c<>1)+" on Tinyboard.","Last message left was #"+STR$ y1," ","(num) Read mssg (num)","(S)ender list","(A)ddressee list","(M)enu","Select one:"+CHR$ 5 3030 FOR p=1 TO 8: GO SUB n1: READ p$: GO SUB send: PRINT : NEXT p 3040 LET ret=FN b(): GO TO intake 3050 IF c$="S" OR c$="s" THEN GO TO read+400 3060 IF c$="A" OR c$="a" THEN GO TO read+600 3070 IF c$="M" OR c$="m" THEN GO TO inputcom 3080 FOR x=1 TO LEN c$: IF CODE c$(x)<48 OR CODE c$(x)>57 THEN GO TO read 3090 NEXT x: IF LEN c$=0 THEN GO TO inputcom 3100 LET y=VAL c$: IF y<1 OR y>c THEN GO TO read 3110 LET p$="Message number: "+STR$ y: GO SUB n1: GO SUB send: GO SUB n1 3120 FOR v=1 TO 1000: POKE 23692,255 3130 IF CODE m$(y,v)=3 THEN LET v=1000: NEXT v: GO TO read 3140 PRINT m$(y,v);: RANDOMIZE USR output: OUT 115,CODE m$(y,v) 3150 IF v>64 THEN NEXT v 3160 IF (v>32 AND CODE m$(y,v)=13) THEN LET v=64: GO SUB n1 3170 IF (v<32 AND CODE m$(y,v)=13) THEN LET v=32 3180 NEXT v 3190 GO SUB n1 3200 GO TO read 3400 REM ***** List Senders ***** 3410 FOR p=1 TO c: LET p$=STR$ p: GO SUB send: FOR v=38 TO 64 3420 LET p$=m$(p,v): GO SUB send: IF m$(p,v)=CHR$ 13 THEN GO TO 3440 3430 NEXT v 3440 PRINT : NEXT p 3450 LET p$="Choose a (num) or (M)enu": GO SUB send: LET ret=FN b(): GO TO intake 3460 GO TO 3070 3600 REM ***** List Addressees ***** 3610 FOR p=1 TO c: LET p$=STR$ p: GO SUB send: FOR v=4 TO 32 3620 LET p$=m$(p,v): GO SUB send: IF m$(p,v)=CHR$ 13 THEN GO TO 3640 3630 NEXT v 3640 PRINT : NEXT p 3650 GO TO 3450 4000 REM ***** Leave Message ***** 4010 LET y1=y1+1: IF y1>20 THEN LET y1=1 4020 DIM l$(1000) 4030 GO SUB n1: LET p$="Message to: ": GO SUB send: LET ret=FN b(): GO TO intake 4040 LET l$(TO 32)="To: "+c$+CHR$ 13: LET p$="From: "+u$: LET l$(33 TO 64)=p$: GO SUB send 4050 GO SUB n1: PRINT : LET p$="Input message (900 chrs max)..(Ctrl-C to SAVE, Ctl-D to abort)": PRINT : GO SUB n1 4060 GO SUB send: PRINT : GO SUB n1: GO SUB n1 4070 ON ERR GO TO quit: FOR v=65 TO 1000: POKE 23692,255: LET m1=USR input: REM ctl-C= 03H = ETX, Ctl-D=04=EOT 4080 LET l$(v)=CHR$ m1: PRINT l$(v);: IF m1=3 THEN LET v=1000 4090 IF m1=4 THEN LET y1=y1-1: GO TO inputcom 4100 NEXT v: PRINT : LET m$(y1)=l$ 4110 LET c=c+1: IF c>20 THEN LET c=20 4120 GO TO inputcom 5000 REM ***** chat ***** 5010 ON ERR GO TO quit: LET k=0 5020 PRINT : GO SUB n1: LET p$="Paging sysop ..................": GO SUB send: PRINT : GO SUB n1 5030 FOR i=1 TO 128: IF INKEY$<>"" THEN GO TO 5060 5040 LET p$=".": GO SUB send: BEEP .1,10 5050 NEXT i: LET p$="The sysop is not available.....": FOR x=1 TO 10: BEEP .1,1: NEXT x: GO SUB n1: GO SUB send: PRINT : GO SUB n1: GO TO inputcom 5060 GO SUB n1: PRINT : LET p$="You are now in chat mode"+CHR$ 13+"Ctl-C to exit": FOR x=1 TO 10: BEEP .1,x/2: NEXT x: GO SUB n1 5070 CLS : PRINT "You are in chat mode with"'u$''"Symbl Shift/NOT to escape...." 5080 IF k=3 OR CODE INKEY$=195 THEN GO TO inputcom: REM 195=not 5090 POKE 23692,255 5100 LET a=USR statchk 5110 IF (a=2 OR a=3) THEN LET k=USR input: PRINT CHR$ k;: IF k=13 THEN PRINT ")"; 5120 IF (a=1 OR a=3) AND INKEY$<>"" THEN GO SUB 5140 5130 GO TO 5080 5140 LET p$=INKEY$: GO SUB send: IF CODE p$=13 THEN PRINT ")"; 5150 RETURN 7000 REM **** Quit Message base **** 7010 ON ERR RESET 7020 GO SUB timer: LPRINT ": ";x$ 7030 PAUSE 30: CLS : RANDOMIZE USR output: OUT 115,28: RANDOMIZE USR output: OUT 115,31 7040 GO SUB n1: CLS : PAUSE 10 7050 LET p$="Connect time was "+x$+".": GO SUB send: PRINT : GO SUB n1: LET p$="Thank you for calling the T/S Tinyboard...Hang up now" 7060 GO SUB send 7070 PAUSE 120 7080 OUT 119,64: OUT 119,0: OUT 119,0 7090 PAUSE 60: CLS : FOR x=60 TO 1 STEP -5: BEEP .1,x: NEXT x: GO TO autoans 8000 REM ***** edit ***** 8010 CLS : PRINT "Sysop Editor"''"(R)ead Messages"''"(D)elete Messages"''"(L)eave Messages"''"(Q)uit Editor"''"(S)ave Message Base" 8020 LET i$=INKEY$ 8030 IF i$="" THEN GO TO 8020 8040 IF i$="r" OR i$="R" THEN INPUT "Message #? ";x: PRINT "Message #";x'm$(x)'"End of Message": PAUSE 0: GO TO edit 8050 IF i$="d" OR i$="D" THEN INPUT "Delete message #? ";x: INPUT STR$ x+" Are you sure? (y/n) ";i$: IF i$="y" THEN GO SUB 8400 8060 IF i$="l" OR i$="L" THEN GO SUB 8600 8070 IF i$="q" OR i$="Q" THEN CLS : GO TO autoans 8080 IF i$="s" OR i$="S" THEN GO SUB save+20 8090 GO TO edit 8400 REM ***** Delete message ***** 8410 FOR i=x TO 19: LET m$(i)=m$(i+1): NEXT i: LET m$(20)=l$ 8420 LET c=c-1: IF c<0 THEN LET y1=0 8430 LET y1=c 8440 RETURN 8600 REM **** Leave message ***** 8610 LET c=c+1: IF c>20 THEN LET c=20 8620 LET y1=y1+1: IF y1>20 THEN LET y1=1 8630 PRINT "Message #";y1: FOR x=1 TO 1000: PAUSE 0: LET m$(y1,x)=INKEY$: PRINT m$(y1,x);: IF CODE INKEY$=195 THEN LET m$(y1,x)=CHR$ 3: RETURN 8640 NEXT x: RETURN 9000 REM ***** initialization ***** 9010 REM 20 message base 9020 PAPER 0: INK 7: BORDER 0: CLS 9025 LET p=64261: POKE 26704,INT (p/256): POKE 26703,p-(INT (p/256)*256): LOAD ""CODE 9030 LET y1=0: LET y=y1: LET c=y 9040 DIM y(2): DIM l$(1000): DIM m$(20,1000): LET m$(1)="No messages found....."+CHR$ 3 9050 LET n1=400 9060 LET send=500 9070 LET intake=600 9080 LET timer=700 9090 LET autoans=1000 9100 LET ansloop=1030 9110 LET warmstart=2000 9120 LET inputcom=2500 9130 LET read=3000 9140 LET leave=4000 9150 LET chat=5000 9160 LET quit=7000 9170 LET edit=8000 9180 LET mc=9500 9190 LET title=9700 9200 LET save=9800 9210 LET statchk=64000 9220 LET input=64100 9230 LET output=64200 9240 GO SUB title: GO SUB mc 9250 FOR x=1 TO 3: BEEP .1,25+x: NEXT x: INPUT "Do you wish to load a message base ? ";x$: IF x$="y" OR x$="Y" THEN PRINT #1;"2 Part load...": PAUSE 100: LOAD "" DATA m$(): LOAD "" DATA y(): LET y1=y(1): LET c=y(2) 9260 INPUT "Do you wish to load a logon bulletin? ";x$: IF x$="y" OR x$="Y" THEN PRINT #1;"Start logon tape (with data as t$)...": LOAD "" DATA t$() 9270 PRINT ''''''''"(NOT) from most modes will exit to sysop control mode.": BEEP .1,35: BEEP .1,38: PAUSE 180 9280 PRINT "Now going to Autoanswer mode": FOR x=1 TO 3: BEEP .1,10+x: PAUSE 180: CLS : GO TO autoans 9500 REM ***** code loader ***** 9510 RESTORE 9520: FOR x=64000 TO 64008: READ n: POKE x,n: NEXT x 9520 DATA 175,219,119,230,3,79,6,0,201 9530 RESTORE 9540: FOR x=64100 TO 64132: READ n: POKE x,n: NEXT x 9540 DATA 219,119,230,128,200,175,219,119,230,2,40,244,219,115,6,0,79,219,119,230,126,200,175,219,119,230,1,40,244,121,211,115,201 9550 RESTORE 9560: FOR x=64200 TO 64212: READ n: POKE x,n: NEXT x 9560 DATA 219,119,230,128,200,175,219,119,230,1,40,244,201 9570 RETURN 9700 REM ***** titles ***** 9710 CLS : PRINT t$: CIRCLE 123,80,20: RESTORE 9760: PLOT 127,103: FOR i=1 TO 11: READ x,y: DRAW x,y: NEXT i 9720 FOR i=1 TO 9: READ x,y: BEEP x,y: IF i=3 THEN PAUSE 4 9730 IF i=6 THEN PAUSE 8 9740 NEXT i 9750 RETURN 9760 DATA 20,0,-5,-20,-15,0,-5,-10,-8,0,-6,-17,0,23,6,0,4,9,6,0,2,15,.2,10,.2,5,.2,2,.2,10,.2,5,.2,2,.2,10,.2,5,.2,2,.2,5,.2,10,.2,10 9800 REM ***** save ***** 9810 CLEAR : SAVE "Tinyboard" LINE 0: SAVE "prt"CODE 64256,1111: PRINT "rewind and VERIFY": VERIFY "": GO TO 9000 9820 INPUT "Data SAVE name ? ";x$: SAVE x$ DATA m$(): LET y(1)=y1: LET y(2)=c: SAVE x$ DATA y(): RETURN 9900 REM ***** utilities ***** 9905 REM ** Renumber ** 9910 INPUT "Look for? ";l"Stop at? ";s"Start new from? ";n"All OK? (y/n) ";x$ 9915 IF x$<>"y" THEN GO TO 9910 9920 IF s>9900 THEN LET s=9900 9925 LET x=26710 9930 IF PEEK x*256+PEEK (x+1)<1 THEN GO TO 9960 9940 IF PEEK x*256+PEEK (x+1)=s THEN STOP 9945 POKE x,INT (n/256) 9950 POKE x+1,n-(PEEK x*256) 9955 LET n=n+10 9960 LET x=x+PEEK (x+2)+256*PEEK (x+3)+4 9965 GO TO 9930 ```