T/S Tinyboard BBS

Authors

Publication

Pub Details

Date

Pages

See all articles from CATS v4 n2

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 of Cincinnatti TSUG. 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

Products

 

Image Gallery

Source Code

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

Scroll to Top