MAX-COM BBS

Products: MAXCOM
Developer(s): Larry Kenny
Date: 1994
Type: Diskette
Platform(s): TS 2068
Tags: BBS

Combines a modem terminal and a dial-in bulletin board in one program, with every transfer going straight to disk, so a file is not limited by free memory. It needs a TS2068 with the Larken disk interface (LKDOS) and a modem, either the 2050 or a Z-SIO RS232 interface with a 300/1200 baud modem. It has not been converted for tape. The main menu offers terminal mode, BBS mode, Xmodem receive and send, UART setup (8/1/N or 7/1/E at 300 or 1200 baud), a choice of 128-, 512- or 1024-byte Xmodem blocks, the message bases, a disk catalog, a duplex toggle, a capture buffer saved to a disk file, an auto-dialer that pulse-dials through the modem, and hang-up.

Transfers can be sent with or without a Spec-Term compatible header, and a received BASIC or code file can be given its start address and length; files larger than 65,535 bytes are supported. In BBS mode the program waits for a ring, answers, and shows a split screen with the session in one window and a list of callers in the other. Callers log on with a name and password, or as GUEST, and their priority level decides whether they may download (level 2) or upload (level 3). Their commands are CATALOG, GOTO (change drive), ULOAD, DLOAD, PRINTFILE, MESSAGES, STATUS, HELP, TALK (chat with the sysop, & to return) and BYE. A level-5 caller gets a sysop menu that can merge BASIC, erase files, and peek or poke memory.

There are two message bases, GENERAL MESSAGES and FILE INFORMATION, each a 310-line, 32-column string array on disk (GENER.A$ and FILES.A$). Callers can leave messages, read all of them or only those addressed to them, and delete messages addressed to them. At the end of each call the caller’s name, uploads, downloads and messages are added to a user log, U-List.A$, so a printer is not needed.

Files on the Disk

  • MaxCom.B1, the main program; it loads the machine code MOCOD.C1 at 57800.
  • MEDIT.B1, a small editor that prints and replaces single lines of GENER.A$.
  • MOVE.B1, the Larken File Move and Rename utility, “customized by Jack Dohany”, with Move .C1.
  • ARTSTU.B1, the start of an Art Studio menu; only its drive and catalog options are written.
  • Logon screens: Logon.CT (the one the program shows, a Chicago Area Timex Users Group banner), LogonA.CT and LogonI.CT (keyboard-picture banners for the “LARKEN 2068 ZX-81 BBS” and “MAXCOM 2068 ZX-81 BBS”), TSNUG.CT (a banner for the ZXir QLive Alive! BBS of the Timex/Sinclair North American User Groups) and CoCo.CT (a Glenside Color Computer BBS banner).
  • Help files for callers: Comand.CT (the command list), NewUsr.CT (new users), and Files.CT with a copy as Files.Cm (file transfers, LKDOS file names and naming conventions for uploads).
  • onceup.CT, a bulletin: “Sorry, Edgar!”, a parody of Poe’s The Raven about a computer error message.
  • Ibm.Cf, the IBM character set, and the Tasword interface code taswi.Cs, taswi.Ct and taswi.Cx.
  • L.B1, Bob Swoger’s LogiCall V6.0L3 loader (1995), added to the disk later.

The command list, file transfer help, new users help and “Sorry, Edgar” are also included as text files.

Provenance

The program reads “>> MAX-COM << By Larry Kenny 940125”, a version dated 25 January 1994. Larken Electronics sold MAXCOM for LKDOS. This copy comes from a disk labelled “Maxeom” that was set up as a working board, so its general message base is empty and the file-information base holds only a note asking uploaders to describe their files.

What’s Missing

  • The operating manual that came with the package is not on the disk.
  • The user log U-List.A$ is not on the disk; the sysop’s Init User Log option creates it.

The disk also held the board’s user list and a member mailing list. Those files have been left out of the download, and the user names, passwords and login strings written into MaxCom.B1 itself have been blanked, so no disk image is included.

Related Products

Full-featured modem software that links the modem to the disk, allowing uploads or downloads of files larger than 100K.

Related Articles

Updates on David Lassov’s BBS software development.
BBS software available from RMG. Larry Kenny working on desktop publishing system and is PC-based marketing plotter, engraver, router/miller.
More notes on the improvements to a TS2068-based BBS.
MAXCOM is 300/1200 baud Terminal/Remote BBS software… It is 2 programs in one meant to be used with the LKDOS operating system.

Source Code

   10 REM  >> MAX-COM <<
   12 REM  By Larry Kenny 940125
   15 LET o$="BLANK": GO SUB 8095: REM Init Msg Base 
   20 CLS : PRINT AT VAL "4",VAL "8";">>  MAX-COM  <<"'TAB VAL "8";">> MAIN MENU <<": GO SUB VAL "8700": GO TO VAL "45"      
   22 LET m$=("8/1/N" AND PEEK 63814<115)+("7/1/E" AND PEEK 63814>115)
   25 PRINT AT NOT PI,NOT PI;"MODE MENU  DUPL ----  XMOD ";: GO SUB VAL "550"
   26 PRINT "UART ";M$;" "; FLASH (1 AND PEEK BUF=1)+(0 AND PEEK BUF=0);"BUFF"; FLASH 0;" ----  LINE";
   27 GO SUB 190: PLOT 1,159: DRAW 253,0
   31 GO SUB 1750: GO SUB 1250: RANDOMIZE USR h: GO TO PEEK DRV: RETURN 
   45 GO SUB 22
   50 PRINT AT 7,0;'"Terminal Mode","Enter BBS mode"''"Receive File","Send File"''"Uart Setup","Xmodem Type"''"Message Base",
   55 PRINT "Catalog Drv ";PEEK Drv;''"Duplex Toggle","Buffer ";("Open" AND PEEK BUF=0)+("Close" AND PEEK BUF=1)''"Auto Dialer","Hangup Phone"
   58 PRINT #RND;"       Press any Key"
   60 LET c$=INKEY$: GO SUB 190: IF c$="" THEN GO TO 60
   65 INPUT ;: IF CODE c$(1)>96 THEN LET c$=CHR$ (CODE c$-CODE " ")
   71 IF c$="T" THEN GO TO VAL "1e3"
   74 IF c$="U" THEN GO TO VAL "1500"
   75 IF c$="H" THEN BEEP VAL ".05",VAL "50": BEEP VAL ".1",VAL "50": OUT STT,NOT PI: GO TO VAL "45"
   78 IF c$="Q" THEN RANDOMIZE USR h: LOAD "L.B1"
   79 IF c$="X" THEN GO SUB VAL "500"
   80 IF c$="C" AND PEEK BUF=VAL "0" THEN GO TO VAL "1400"
   81 IF c$="A" THEN GO TO VAL "400"
   82 IF c$="M" THEN GO TO VAL "8e3"
   83 IF c$="B" THEN GO TO VAL "8500"
   85 IF c$="D" THEN GO SUB VAL "1700": BEEP VAL ".1",VAL "10"
   86 IF c$="R" OR c$="S" OR c$="E" THEN GO TO VAL "88"
   87 GO TO VAL "58"
   88 IF PEEK BUF<>NOT PI THEN INPUT "  CLOSE BUFFER FIRST "; LINE a$: GO TO VAL "58"
   90 IF c$="R" THEN GO SUB VAL "2000": GO TO VAL "1010"
   91 IF c$="S" THEN GO SUB VAL "2500": GO TO VAL "1010"
   92 IF c$="E" THEN GO TO VAL "250"
   98 GO TO VAL "58"
   99 REM Msg Search
  100 LET or=r
  103 LET v=CODE d$(r,1): IF v=130 THEN LET r=r+CODE d$(r,3)
  105 IF v=140 THEN LET r=r+CODE d$(r,3): IF CODE d$(r,1)=140 THEN GO TO 105
  108 GO TO 150
  110 FOR a=or+1 TO er: IF d$(a,1)<>CHR$ 130 THEN NEXT a
  115 LET r=a
  120 RETURN 
  150 IF d$(r,1)=CHR$ 130 THEN RETURN 
  160 GO TO 110
  190 LET a=IN STT: PRINT AT 1,26;("  ON " AND a>127)+(" OFF " AND a<128);" :": RETURN 
  250 REM >> AUTO ANSWER MODE <<
  260 IF d$(SGN PI,VAL "16" TO VAL "20")="BLANK" THEN INPUT "Message base is Undefined "; LINE a$: GO TO VAL "8e3" 
  300 RANDOMIZE USR 61036: GO SUB VAL "22": RANDOMIZE USR h: OPEN #VAL "5","w0": RANDOMIZE USR h: INPUT #NOT PI,INT PI,NOT PI,VAL "23",VAL "20": RANDOMIZE USR h: CLEAR NOT PI
  301 LET t=PEEK VAL "23693": PAPER SGN PI: INK VAL "7": RANDOMIZE USR h: OPEN #VAL "6","w1": RANDOMIZE USR h: INPUT #SGN PI,INT PI,VAL "24",VAL "31",VAL "20": RANDOMIZE USR h: CLEAR SGN PI: POKE VAL "23693",t
  302 GO SUB VAL "2950": LET a$=d$(SGN PI,SGN PI)
  303 PRINT #VAL "5";"  AUTO ANSWER MODE": PRINT #VAL "6"; "--BBS CALLERS--"
  305 GO SUB VAL "190": RANDOMIZE USR Init: OUT STT,NOT PI: OUT STT,VAL "34": OUT STT,NOT PI: BEEP .05,30
  315 LET a=IN STT
  320 IF INKEY$="m" THEN RANDOMIZE USR VAL "61033": GO TO VAL "20"
  325 IF a=VAL "5" THEN GO TO VAL "315"
  330 OUT STT,VAL "2": PAUSE VAL "20": OUT STT,VAL "34"
  340 PRINT #VAL "5";"   RING IN !!"'': PAUSE VAL "150": OUT STT,VAL "183"
  350 FOR a=SGN PI TO VAL "10": PAUSE VAL "60": IF IN STT>VAL "127" THEN GO TO VAL "390"
  360 NEXT a: GO TO VAL "305"
  390 GO SUB VAL "190": POKE VAL "23739",VAL "255": ON ERR GO TO VAL "9e3": POKE VAL "23673",VAL "200": POKE VAL "23674",VAL "255": POKE VAL "23545",NOT PI: RANDOMIZE USR TRAP: GO TO VAL "3e3"
  400 REM >> 2050 Auto dialer <<
  405 RANDOMIZE USR init: OUT STT,NOT PI: INPUT "Phone Number ";a$: PRINT #RND;"Dialing ";a$: OUT STT,VAL "2": PAUSE VAL "40"
  410 FOR a=SGN PI TO LEN a$: PAUSE VAL "30"
  420 LET x=VAL a$(a): IF x=NOT PI THEN LET x=VAL "10"
  430 FOR b=1 TO x: OUT STT,0: FOR t=1 TO 4: NEXT t
  440 OUT STT,2: FOR t=1 TO 2: NEXT t: NEXT b: NEXT a
  450 FOR a=SGN PI TO LEN a$*VAL "150": IF IN STT>VAL "127" THEN PAUSE 50: IF IN STT>VAL "127" THEN OUT STT,VAL "183": BEEP .1,VAL "10": BEEP .1,VAL "20": PRINT #RND;"CONNECT": GO TO VAL "1001"
  455 IF INKEY$<>" " THEN NEXT a
  460 OUT STT,NOT PI: PRINT #RND; FLASH SGN PI;"No Answer or Busy ": BEEP .3,VAL "5": BEEP .3,VAL "1": PAUSE CODE "d": GO TO VAL "20"
  500 REM >> Xmodem selection <<
  510 INPUT #m;"Standard  Xmodem (1)"'"512  Byte Xmodem (2)"'"1024 Byte Xmodem (3) ?"; LINE a$ : IF a$<"1" OR a$>"3" THEN GO TO VAL "510"
  520 IF a$="1" THEN POKE Time,VAL "1": LET s=VAL "128"
  530 IF a$="2" THEN POKE Time,VAL "3": LET s=VAL "512"
  540 IF a$="3" THEN POKE Time,VAL "4": LET s=VAL "1024"
  550 RANDOMIZE USR h: POKE xsiz,s: PRINT AT NOT PI,VAL "27";s;" ";AT NOT PI,VAL "31";" :": BEEP .1,VAL "10": RETURN 
  999 REM >> TERMINAL EMULATOR <<
 1000 IF IN STT<128 THEN RANDOMIZE USR Init
 1001 RANDOMIZE USR 100: OPEN #5,"w0": RANDOMIZE USR 100: INPUT #0,3,0,31,21: RANDOMIZE USR 100: OPEN #6,"w0"
 1002 POKE BBS,0: POKE VAL "63821",NOT PI: RANDOMIZE USR 100: CLEAR 0: PRINT AT 0,5;"TERM"''
 1005 GO SUB 190: LET m=0: LET m1=5: INPUT ;: POKE VAL "63841",NOT PI
 1010 LET t=USR TERM: PRINT AT 0,0;"  ": PRINT AT 0,0;t: IF t=28 THEN PRINT #7;CHR$ 19;: RANDOMIZE USR 100: CLEAR 0: PRINT #7;CHR$ 17;: GO TO 1010
 1020 IF t=0 THEN ON ERR RESET : GO TO 20
 1030 IF t=1 AND PEEK BBS=1 THEN GO SUB 2950: GO TO 4000
 1040 IF t=7 THEN PRINT #0;"CONTROL": GO TO 1010
 1050 IF t=3 THEN INPUT ;: GO TO 1010
 1060 IF t=4 THEN BEEP .05,25: BEEP .05,30: GO SUB 1700
 1064 IF t=5 THEN GO TO 1200
 1070 IF t=8 THEN RESTORE 1100: GO TO 1095
 1075 IF t=10 THEN RESTORE 1110: GO TO 1095
 1080 IF t=11 THEN RESTORE 1120: GO TO 1095
 1085 IF t=9 THEN RESTORE 1130: GO TO 1095
 1086 IF t=15 THEN INPUT "Ascii Send - Name? ";f$: IF LEN f$>2 THEN LET m1=7: GO SUB 5300
 1090 LET m1=5: GO TO 1010
 1095 READ A$: FOR a=SGN PI TO LEN a$: PRINT #VAL "7";a$(a);: NEXT a: GO TO 1010
 1100 DATA ""
 1110 DATA ""
 1120 DATA ""
 1130 DATA ""
 1200 IF PEEK BUF=0 THEN BEEP .1,-20: GO TO 1010
 1210 POKE BUFO,NOT PEEK BUFO
 1230 BEEP .1,0: GO SUB 1250: GO TO 1010
 1250 PRINT AT 1,16;(" ON " AND PEEK BUFO=1)+("OFF " AND PEEK BUFO=0): RETURN 
 1400 INPUT "Drive # ";a$: IF a$="" THEN GO TO VAL "1420": IF VAL a$>VAL "4" THEN GO TO VAL "1400"
 1410 POKE Drv,VAL a$: RANDOMIZE USR CODE "d": GO TO VAL a$
 1420 INPUT "String ? ";c$
 1430 CLS : RANDOMIZE USR 100: CAT c$,
 1440 PAUSE NOT PI: GO TO VAL "20"
 1499 REM >> Uart Setup <<
 1500 CLS : PRINT "Select Parameters"''
 1520 PRINT '"1   8/1/N  at  300 Baud"'"2   7/1/E  at  300 Baud"'"3   8/1/N  at 1200 Baud"'"4   7/1/E  at 1200 Baud"
 1530 PRINT '''"'Use 8/1/N for all normal Usage'"
 1540 INPUT "Select 1 - 4 ";a
 1550 IF a=VAL "1" THEN LET baud=VAL "111"
 1560 IF a=VAL "2" THEN LET baud=VAL "123"
 1570 IF a=VAL "3" THEN LET baud=VAL "110"
 1580 IF a=VAL "4" THEN LET baud=VAL "122"
 1590 IF a>VAL "4" THEN GO TO VAL "1540"
 1600 POKE BaudL,baud
 1610 PRINT AT a+VAL "2",VAL "4"; OVER VAL "1"; FLASH VAL "1";"                   "
 1620 BEEP VAL ".1",VAL "10": PAUSE VAL "60": GO TO VAL "20"
 1700 POKE Echo,NOT PEEK Echo
 1750 PRINT AT VAL "0",VAL "16";("HALF" AND PEEK Echo<>VAL "0")+("FULL" AND PEEK Echo=VAL "0"): RETURN 
 1999 REM >> Xmodem Receive <<
 2000 IF m=NOT PI THEN RANDOMIZE USR CODE "d": CLEAR NOT PI: PRINT #VAL "5"''
 2005 PRINT #m1;''"--- XMODEM RECEIVE ---": POKE Vbig,VAL "0"
 2010 PRINT #m1;"Enter name of file using an LKDOS type File Name "
 2020 INPUT #m;"File Name - ";f$
 2025 IF LEN f$>VAL "9" THEN PRINT #m1;"File Name too long !!": GO TO VAL "2020"
 2030 IF LEN f$<VAL "3" THEN RETURN 
 2050 RANDOMIZE USR mdos: OPEN #10,f$+" OUT "
 2055 IF PEEK BBS THEN LET a$="U> "+f$: LET y$=y$+a$: PRINT #VAL "6";a$
 2060 INPUT #m;"Spec-Term header type file ? ";a$: IF a$(1)="n" OR a$(1)="N" THEN POKE xtype,0: GO TO 2080
 2070 POKE xtype,VAL "255": GO TO VAL "2100"
 2080 INPUT #m;'"Enter (B)asic  or (C)ode ? ";a$: GO SUB 5400: IF a$(1)="B" THEN POKE head,VAL "0": GO TO VAL "2090"
 2082 IF a$="C" THEN POKE head,INT PI
 2084 INPUT #m;'"Enter Start of Code ";a$: INPUT #m;("Code Start is ";a$;" ? ");i$: IF i$="n" OR i$="N" THEN GO TO 2084
 2085 RANDOMIZE USR CODE "d": POKE head+13,VAL a$: GO TO VAL "2092"
 2090 RANDOMIZE USR 100: POKE head+VAL "13",VAL "32768":
 2092 INPUT #m;'"Enter Lenth of file ";a$: INPUT #m;("Lenth is ";a$;" ? ");i$: IF i$="n" OR i$="N" THEN GO TO 2090
 2093 IF VAL a$>VAL "65535" THEN POKE Vbig,SGN PI: GO TO VAL "2100"
 2094 RANDOMIZE USR 100: POKE head+11,VAL a$
 2096: RANDOMIZE USR 100: POKE head+15,VAL a$
 2100 PRINT #m1;'"START TRANSMISSION NOW "
 2110 PAUSE CODE "d": PRINT #5;USR Xrecv
 2120 IF PEEK XERR<>24 THEN RANDOMIZE USR mdos: CLOSE #VAL "10": PRINT #m1;"Transfer Complete !": RETURN 
 2140 BEEP SGN PI,VAL "-10": PRINT #m1;"! TRANSFER ABORTED !": RETURN 
 2499 REM >> Xmodem Transmit <<
 2500 IF m=NOT PI THEN RANDOMIZE USR CODE "d": CLEAR NOT PI: PRINT #VAL "5"''
 2505 PRINT #m1;'"=== XMODEM TRANSMIT ==="
 2510 POKE VAL "23728",SGN PI: INPUT #m;"Enter File Name ";f$: IF LEN f$<VAL "2" THEN PRINT #m1;''"ABORTED !": RETURN 
 2512 RANDOMIZE USR mdos: OPEN #10,f$+" IN ": IF PEEK VAL "23728"=VAL "10" THEN PRINT "No file": PRINT #m1;"! FILE NOT FOUND ": GO TO 2510
 2516 IF PEEK BBS THEN LET a$="D> "+f$: LET y$=y$+a$: PRINT #VAL "6";a$
 2520 INPUT #m;'"Send header with file ? ";a$: GO SUB 5400: IF a$="N" THEN POKE xtype,0: GO TO 2526
 2525 POKE xtype,VAL "255"
 2528 PRINT #m1;'"File Length is ";PEEK (head+11)+256*PEEK (head+12)
 2530 IF PEEK head=VAL "3" THEN PRINT #m1;"Code starts at ";PEEK (head+13)+256*PEEK (head+14)
 2535 PRINT #m1;''"TRANSMIT WILL START IN 5 SECONDS"
 2540 PAUSE VAL "500": PRINT #5;USR Tranx
 2550 POKE VAL "23729",VAL "0"
 2560 PRINT #m1;''"File Transfer Complete ":
 2580 RETURN 
 2950 PRINT AT 0,5; FLASH 1;"BBS ": POKE ECHO,3: LET m=7: LET m1=7: RETURN 
 2999 REM >> LOGON SECTION <<
 3005 PRINT AT NOT PI,VAL "5"; FLASH SGN PI;"BBS ": POKE ECHO,INT PI: POKE BBS,SGN PI: LET m=VAL "7": LET m1=VAL "7": LET A$="1": GO SUB VAL "520"
 3010 INPUT #m;''"Press Enter "; LINE a$
 3100 RANDOMIZE USR 100: GO TO sys: LET f$="Logon.CT": GO SUB 5300
 3120 PRINT #m1: INPUT #m;"Enter Name - "; LINE a$: GO SUB VAL "5400": LET c$=a$
 3130 PRINT #m;"Your Name Is ";c$;" ?(y/N) ";
 3140 LET a$=INKEY$#m: IF a$="" THEN GO TO 3140
 3150 IF a$="Y" OR a$="y" THEN GO TO 3160
 3155 GO TO 3120
 3160 GO SUB 5400: LET n$=c$: PRINT #m: PRINT #6;n$: LET y$=n$
 3170 REM : LET Pr=4: GO TO 3900: REM Bypass
 3200 PRINT #m1;"One moment Please": RANDOMIZE USR CODE "d": MERGE "USERS.B9": RESTORE 3400
 3210 READ x$: READ p$: READ Pr
 3220 IF x$="END" THEN PRINT #m;    "SORRY NAME NOT FOUND !!": LET a$="B": GO TO VAL "3120": GO TO VAL "4028"
 3230 IF x$<>n$ THEN GO TO 3210
 3250 LET a=1: IF n$="GUEST" THEN GO TO 3900
 3260 INPUT #m;"PASSWORD - "; LINE a$: GO SUB VAL "5400"
 3270 IF p$=a$ THEN GO TO 3900
 3280 LET a=a+1: IF a=4 THEN GO TO 9000
 3290 GO TO 3260
 3400 REM "NAME","PASSWORD",PRIORITY
 3401 REM  removed: personal data
 3402 REM  removed: personal data
 3404 REM  removed: personal data
 3405 REM  removed: personal data
 3406 REM  removed: personal data
 3407 REM  removed: personal data
 3408 REM  removed: personal data
 3409 REM  removed: personal data
 3410 REM  removed: personal data
 3411 REM  removed: personal data
 3412 REM  removed: personal data
 3413 REM  removed: personal data
 3414 REM  removed: personal data
 3499 DATA "END","END",1
 3500 REM COMMANDS
 3520 DATA ">>>> MAIN MENU COMMANDS <<<<","CATALOG GOTO ULOAD DLOAD PRINTFILE","MESSAGES STATUS HELP TALK BYE"
 3550 DATA " ","( B C D H G M T P S U ?)"," ","END"
 3900 IF n$="GUEST" THEN RANDOMIZE USR 100: GO TO sys: LET f$="NewUsr.CT": GO SUB 5300
 3999 REM >> COMMANDS LOOP <<
 4000 ON ERR GO TO 9000: RESTORE 3500: POKE BBS,1: POKE ECHO,3: PRINT #m1: PRINT AT 4,0;: RANDOMIZE USR 100: POKE 16024,49407
 4005 READ a$: IF a$<>"END" THEN PRINT #m1;a$: GO TO 4005
 4010 REM >> Command entry
 4015 RANDOMIZE USR 100: GO TO PEEK drv: POKE 23673,128: POKE 23674,252: REM time out =  80 min
 4018 INPUT #m;"Command > "; LINE a$: IF a$="" THEN GO TO 4000
 4020 IF INKEY$=CHR$ 226 THEN LET a$="T": GO TO 4050
 4025 LET a$=a$(1): PRINT #m1: IF CODE A$>96 THEN LET A$=CHR$ (CODE A$-32)
 4027 IF a$="?" THEN RANDOMIZE USR 100: GO TO sys: LET f$="Comand.CT": GO SUB 5300: GO TO 4010
 4028 IF a$="B" THEN PRINT #m1;"THANKS FOR CALLING...": POKE 23545,6: GO TO 9000
 4030 IF a$="C" THEN INPUT #m;"Enter search$ (or CR) "; LINE a$: PRINT #m1;"CATALOG of DRIVE ";PEEK Drv: RANDOMIZE USR 100: OPEN #2,"W2": RANDOMIZE USR Mdos: CAT a$,: RANDOMIZE USR 100: CLOSE #2: INPUT #m;"Press Enter to Continue"; LINE a$: GO TO 4010
 4032 IF A$<>"S" THEN GO TO 4038
 4035 PRINT #m1;'"CURRENT SYSTEM STATUS"'"DISK DRIVES 0 thru 4 Available"'"CURRENT DISK DRIVE = ";PEEK drv';"XMODEM PROTOCALL = ";("Standard 128" AND PEEK (xsiz+1)=0)+("XMODEM 512" AND PEEK (xsiz+1)=2)+("XMODEM 1024" AND PEEK (xsiz+1)=4)
 4036 INPUT #m;"Change Xmodem Protocal ? y/n "; LINE a$: IF a$="Y" OR a$="y" THEN GO SUB 500: GO TO 4035
 4037 GO TO 4000
 4038 IF a$<>"G" THEN GO TO 4045
 4040 INPUT #m;"Which Drive 0 thru 4? "; LINE a$
 4042 IF a$>="0" AND a$<="4" THEN RANDOMIZE USR 100: GO TO VAL a$: POKE Drv,VAL a$: GO TO 4045
 4044 PRINT #m1;"Sorry Drive not available !!"
 4045 IF a$="M" THEN LET RET=4000: GO TO 5500
 4050 IF a$="T" THEN PRINT #m1;"Type '&";: PAUSE 10: PRINT #m1;"' to return to BBS ": BEEP 1,5: BEEP 2,10: GO TO 1005
 4055 REM IF (a$="U" OR a$="D") AND (PEEK drv=Sys AND Pr<5) THEN PRINT #m1;"NO FILE TRANSFERS USING SYSTEM DRIVE !!": GO TO 4000
 4060 IF a$<>"U" THEN GO TO 4070
 4062 IF Pr<3 THEN PRINT #m1;"Uploads not authorised !": GO TO 4000
 4065 GO SUB VAL "2e3": GO TO VAL "4e3"
 4070 IF a$<>"D" THEN GO TO 4080
 4072 IF Pr<VAL "2" THEN PRINT #m1;"You are not allowed Downloads !": GO TO VAL "4e3"
 4075 GO SUB VAL "2500": GO TO VAL "4e3"
 4080 IF a$<>"P" THEN GO TO 4120
 4090 INPUT #m;"Enter File Name to Print - "; LINE f$: IF a$="" THEN GO TO VAL "4e3"
 4092 PRINT #m1;"Press 'Z' to quit"
 4093 GO SUB 5300
 4100 IF a=VAL "10" THEN PRINT #m1;"FILE NOT FOUND !": GO TO 4000
 4110 PRINT #m1;"-----  End of file -----"
 4120 IF a$<>"H" THEN GO TO 4180
 4125 PRINT #m1;"---- SELECT HELP TOPIC ----"
 4130 PRINT #m;"(N)ew Users Manual"'"(F)ile Transfer Instructions"'"(G)oto Main Menu"
 4135 INPUT #m;"Press   N, F, or G "; LINE a$: RANDOMIZE USR CODE "d": GO TO Sys
 4140 IF a$="G" OR a$="g" THEN GO TO VAL "4e3"
 4142 IF a$="F" OR a$="f" THEN LET f$="Files.CT": GO TO VAL "4093"
 4143 IF a$="N" OR a$="n" THEN LET f$="NewUsr.CT": GO TO VAL "4093"
 4150 GO TO VAL "4135"
 4200 REM *Add New commands here*
 4205 REM 
 4800 REM >> Sysop commands <<
 4805 IF pr<5 OR a$<>"!" THEN GO TO 4000
 4810 PRINT #m1;">> Sysop Menu <<"''  "Merge Basic    Erase File"'"Ram Peek       Poke ram"'"Change Name    Quit sysop menu"
 4815 INPUT #m;"Command -"; LINE a$: GO SUB VAL "5400": IF a$="Q" THEN GO TO VAL "4e3"
 4820 IF a$="M" THEN PRINT #m1;"MERGE";: GO SUB VAL "5450": IF f$<>"" THEN RANDOMIZE USR CODE "d": MERGE f$
 4825 IF a$="E" THEN PRINT #m1;"ERASE";: GO SUB VAL "5450": IF f$<>"" THEN RANDOMIZE USR CODE "d": ERASE f$,
 4828 IF a$<>"R" THEN GO TO VAL "4840"
 4830 INPUT #m;"Start Addr "; LINE s$: INPUT #m;"End "; LINE e$: INPUT #m;("ST= ";s$;"  EN= ";e$;" ";); LINE a$: IF a$="n" OR a$="N" THEN GO TO VAL "4840"
 4834 FOR a=VAL s$ TO VAL e$: PRINT #m1;a;"   ";PEEK a;"   ";: IF PEEK a>=32 THEN PRINT #m1;CHR$ PEEK a: NEXT a
 4835 IF INKEY$#m<>"Z" THEN PRINT #m1: NEXT a
 4840 IF a$="P" THEN INPUT #m;"Addr -"; LINE s$: INPUT #m;"Byte -"; LINE e$: INPUT #m;("Poke ";VAL s$;",";VAL e$;"  ?"); LINE a$: IF a$="Y" THEN POKE VAL s$,VAL e$
 4850 IF a$="C" THEN INPUT #m;"New Name"; LINE n$: PRINT #m1;n$
 5000 GO TO VAL "4810"
 5299 REM PRINT FILE
 5310 POKE VAL "23728",SGN PI: PRINT #m1;USR Mdos: PRINT F$;
 5340 LET a=PEEK VAL "23728": RETURN 
 5399 REM Capitalize
 5405 IF NOT LEN a$ THEN RETURN 
 5410 FOR a=1 TO LEN a$
 5425 IF CODE A$(a)>96 THEN LET A$(a)=CHR$ (CODE A$(a)-32)
 5430 NEXT a
 5435 RETURN 
 5455 INPUT #m;"File name "; LINE f$: RANDOMIZE USR CODE "d": OPEN #VAL "2","W2": RANDOMIZE USR mdos: CAT f$,: RANDOMIZE USR CODE "d": CLOSE #2: INPUT #m;("Name is -";f$;" ? "); LINE a$: IF a$="Y" OR a$="y" THEN RETURN 
 5460 LET f$="": RETURN 
 5499 REM >> Message Area <<
 5500 IF RET=VAL "8e3" THEN CLS 
 5503 PRINT #m1;''"   MESSAGE BASE MENU"'">>> ";d$(1,16 TO 32);" AREA <<<"
 5505 PRINT #m1;'"(E)nter Message"'"(R)ead all Messages"'"(Y)our messages Only"'"(L)oad new message base"'"(G)oto Main Menu"
 5510 INPUT #m;"Choice "; LINE a$: GO SUB VAL "5400": PRINT #m1
 5520 IF a$="E" THEN GO TO VAL "6e3"
 5540 IF a$="R" THEN GO TO VAL "7e3"
 5550 IF a$="Y" THEN GO TO 7500
 5560 IF a$="G" THEN GO TO RET
 5565 IF RET=8000 THEN GO TO VAL "5500"
 5570 IF a$="L" THEN GO TO 5580
 5575 GO TO 5500
 5580 PRINT #m1;"1  -  GENERAL MESSAGES"'"2  -  FILE INFORMATION BASE"'"3  -  RETURN TO MESSAGE MENU" 
 5585 LET f$=" ": INPUT #m;"Select 1 2 or 3 "; LINE a$: IF a$="3" THEN GO TO VAL "5500"
 5590 LET f$=("GENER" AND a$="1")+("FILES" AND a$="2"): IF LEN f$<>5 THEN GO TO 5585
 5592 PRINT #m1;"One moment please"
 5595 GO SUB 9600
 5597 POKE 23728,100: RANDOMIZE USR 100: LOAD f$+".A$" DATA d$()
 5598 IF PEEK VAL "23728"=VAL "101" THEN PRINT #m;"Sorry that message base is not available"
 5600 GO TO 5500
 5999 REM >> Enter a Message
 6010 LET MX=VAL d$(1,8 TO 10)
 6012 IF VAL d$(1, TO 3)=MX THEN PRINT #m1;"MESSAGE BASE FULL": GO TO 5500
 6015 LET rd=VAL d$(1,1 TO 3): LET fr=rd
 6020 LET d$(rd,1)=CHR$ 130: LET d$(rd,2)=CHR$ VAL d$(1,4 TO 7): LET y$=y$+" M>"+d$(1,4 TO 7)
 6025 INPUT #m;"To "; LINE a$: GO SUB VAL "5400": LET d$(rd,8 TO 19)=a$
 6030 INPUT #m;"Subject (12 Chars) "; LINE d$(rd,20 TO 32): LET rd=rd+1
 6035 PRINT #m1;"Enter Message in 32 Column lines"'"Press CR at start of line to end"'">";: FOR a=1 TO 32: PRINT #m1;"-";: NEXT a: PRINT #m1;"<"
 6037 IF RET=8000 THEN GO TO 6500
 6038 POKE ECHO,0
 6040 PRINT #m1;">";: FOR a=1 TO 32
 6045 IF INKEY$#m<>"" THEN GO TO 6045
 6050 LET a$=INKEY$#m: IF a$="" THEN GO TO 6050
 6055 IF CODE a$=13 THEN PRINT #m1: GO TO 6080
 6057 IF CODE a$<>12 THEN GO TO 6065
 6060 IF a>1 THEN LET a=a-1: PRINT #m1;CHR$ 8;
 6062 GO TO 6045
 6065 LET d$(rd,a)=a$: PRINT #m1;a$;
 6070 NEXT a: PRINT #m1
 6080 IF CODE a$=13 AND a=1 THEN GO TO 6100
 6090 IF RD=MX THEN PRINT #m1;"MESSAGE BASE FULL !": GO TO 6100
 6095 LET rd=rd+1: GO TO 6040
 6100 LET d$(1,1 TO 3)=STR$ rd: LET d$(fr,3)=CHR$ (rd-fr)
 6105 LET a=VAL d$(1,4 TO 7): LET a=a+1: LET d$(1,4 TO 7)=STR$ a
 6110 POKE Echo,3: GO TO 5500
 6500 REM >> Sysop Enter Message
 6540 FOR a=1 TO 32
 6545 IF INKEY$<>"" THEN GO TO 6545
 6550 LET a$=INKEY$: IF a$="" THEN GO TO 6550
 6555 IF CODE a$=13 THEN GO TO 6580
 6560 IF CODE a$=12 AND a>1 THEN LET a=a-1: PRINT CHR$ 8;" ";CHR$ 8;: GO TO 6545
 6565 LET d$(rd,a)=a$: PRINT a$;
 6570 NEXT a:
 6580 PRINT : IF CODE a$=13 AND a=1 THEN GO TO 6100
 6590 IF RD=MX THEN PRINT #m1;"MESSAGE BASE FULL !": GO TO VAL "6100"
 6595 LET rd=rd+1: GO TO 6540
 6600 GO TO 6100
 6700 FOR b=1 TO LEN a$: IF CODE a$(b)<48 OR CODE a$(b)>58 THEN LET mn=1: RETURN 
 6710 NEXT b: LET mn=VAL a$: RETURN 
 6999 REM ** READ ALL MESSAGES **
 7004 PRINT #m1;d$(1,16 TO 32)
 7005 PRINT #m1;"Messages 1 to ";(VAL d$(1,4 TO 7))-1;" Active"
 7006 LET er=VAL d$(1,1 TO 3): LET r=VAL "2"
 7008 INPUT #m;"Enter Msg# to Start (or CR) "; LINE a$: IF LEN a$<VAL "1" THEN GO TO 7020
 7010 GO SUB VAL "6700": IF mn=VAL "1" THEN GO TO 7020
 7012 PRINT #m1;"One Moment Please"
 7015 GO SUB 100: IF r>=er THEN GO TO 7105
 7016 IF mn>CODE d$(r,2) THEN GO TO 7015
 7020 IF d$(r,1)=CHR$ 130 THEN GO TO 7030
 7022 GO SUB 100
 7025 IF r>=er THEN GO TO 7105
 7030 PRINT #m1;'"Message # ";CODE d$(r,2)'"TO - ";d$(r,8 TO 19)'"SUBJ - ";d$(r,20 TO 32)
 7032 INPUT #m;"( 'Q' to Quit, 'S' to Skip ) "; LINE a$: IF a$="Q" OR a$="q" THEN GO TO 5500
 7033 IF a$="S" OR a$="s" THEN GO TO 7022
 7040 LET r=r+1: IF CODE d$(r,1)>128 OR r>=er THEN GO TO 7100
 7050 PRINT #m1;d$(r): GO TO 7040
 7100 IF r<er THEN GO TO 7020
 7200 INPUT #m;'"----- End of Messages -----"; LINE a$:
 7210 GO TO 5500
 7499 REM ** CALLERS MESSAGES **
 7504 PRINT #m1;"Searching message base ..."
 7505 DIM s$(12): LET s$=n$: LET er=VAL d$(1,1 TO 3): LET r=VAL "2"
 7510 IF d$(r,1)=CHR$ 130 THEN GO TO 7515
 7512 GO SUB 100
 7515 IF r>=er THEN GO TO 7200
 7520 LET fr=r: IF d$(r,8 TO 19)<>s$ THEN GO TO 7512
 7530 PRINT #m1;'"Message # ";CODE d$(r,2)'"TO - ";d$(r,8 TO 19)'"SUBJ - ";d$(r,20 TO 32)
 7540 LET r=r+1: IF CODE d$(r,1)>=128 OR r>=er THEN GO TO 7600
 7550 PRINT #m1;d$(r): GO TO 7540
 7600 LET lr=r-1: IF N$<>"GUEST" THEN INPUT #m;"Kill Message "; LINE a$: IF a$="Y" OR a$="y" THEN GO SUB 7620
 7605 INPUT #m;"'S' to Stop, CR to contine"; LINE a$: IF a$="S" OR a$="s" THEN GO TO 5500
 7610 GO TO 7800
 7620 LET d$(fr,1)=CHR$ 140: FOR a=fr+1 TO lr: LET d$(a,1)=CHR$ 139: NEXT a: GO TO 7510
 7800 IF r<er THEN GO TO 7510
 7810 GO TO 7200
 7900 REM * COUNT CALLER MSG'S *
 7903 DIM s$(12): LET s$=n$: LET n=0
 7905: FOR a=1 TO VAL d$(1,1 TO 3): IF d$(a,1)<>CHR$ 130 THEN GO TO 7950
 7910 IF s$=d$(a,8 TO 19) THEN LET n=n+1
 7950 NEXT a: PRINT #m1;N;" Message(s) for you ": RETURN 
 7999 REM >> Sysop Message enter
 8000 CLS : PRINT "   MESSAGE BASE CONTROL": RANDOMIZE USR CODE "d": GO TO SYS: GO SUB VAL "8090"
 8010 PRINT '"Load Message Base"''"Save Message Base"''"Read/Write Messages"''"Create Message Base"''"Init User Log"''"View User Log"''"Goto Main Menu"
 8020 INPUT "Choice ";a$: GO SUB VAL "5400": CLS : GO SUB VAL "8090"
 8030 IF a$="L" THEN PRINT "LOAD...": RANDOMIZE USR CODE "d": CAT ".A$",: INPUT "FILE NAME (5 chrs) ";a$: GO SUB VAL "5400": RANDOMIZE USR CODE "d": LOAD a$+".A$" DATA d$(): GO TO VAL "8e3"
 8040 IF a$="S" THEN PRINT "SAVE...": RANDOMIZE USR CODE "d": CAT ".A$",: INPUT ("Ok to save ";f$;" ?");a$: IF a$="Y" OR a$="y" THEN RANDOMIZE USR CODE "d": SAVE f$ DATA d$(): GO TO VAL "8e3"
 8045 IF a$="I" THEN INPUT "Ok to Init ?";a$: IF a$="y" OR a$="Y" THEN DIM d$(VAL "9600"): LET d$(SGN PI TO VAL "4")="5": RANDOMIZE USR CODE "d": SAVE "U-List.A$" DATA d$(): LET a$="L": GO TO VAL "8030"
 8046 IF a$="V" THEN PRINT USR CODE "d": PRINT "U-List.A$": LET a$="L": GO TO VAL "8e3"
 8050 IF a$="R" THEN CLS : LET RET=VAL "8e3": LET N$=Y$: LET m=NOT PI: LET m1=VAL "2": GO TO VAL "5500"
 8060 IF a$="G" THEN GO TO VAL "20"
 8070 IF a$="C" THEN INPUT "NEW BASE NAME";o$: GO SUB VAL "8095"
 8075 GO TO VAL "8e3"
 8090 LET f$=d$(SGN PI,VAL "16" TO VAL "20")+".A$": PRINT AT VAL "2",NOT PI;" Message base in memory is -"'"  >> ";d$(SGN PI,VAL "16" TO VAL "32");" <<"'': RETURN 
 8095 LET SIZ=VAL "310": DIM d$(SIZ,VAL "32"): LET d$(SGN PI,SGN PI TO INT PI)="2": LET d$(SGN PI,VAL "4" TO VAL "7")="1": LET d$(SGN PI,VAL "8" TO VAL "10")=STR$ SIZ: LET d$(SGN PI,VAL "16" TO VAL "32")=o$: RETURN 
 8500 REM >> Buffer Open/Close
 8505 IF PEEK BUF=NOT PI THEN GO TO VAL "8550"
 8510 INPUT "CLOSE BUFFER FILE  ";a$: IF a$="n" OR a$="N" THEN GO TO VAL "20"
 8520 RANDOMIZE USR Mdos: CLOSE #10: POKE BUF,NOT PI: POKE BUFO,NOT PI: GO TO VAL "20"
 8550 INPUT "OPEN BUFFER (y/n) ";a$: IF a$="n" OR a$="N" THEN GO TO VAL "20"
 8560 INPUT "File Name ";a$: GO SUB VAL "5400": RANDOMIZE USR Mdos: OPEN #10,a$+" OUT "
 8570 POKE BUF,SGN PI: GO TO VAL "20"
 8700 REM >> Define Variables <<
 8705 LET Y$="SYSOP": LET STT=119: LET DTT=115: LET Sys=0: REM Sys drive
 8710 LET Mdos=59000: LET INIT=61000: LET TRANX=61003: LET XRECV=61006: LET Term=61009: LET TRAP=61027
 8715 LET MV=63800: LET Xsiz=MV: LET FLEN=MV+2: LET XERR=MV+12: LET BAUDL=MV+14: LET XTYPE=MV+15: LET ECHO=MV+17: LET BUF=MV+44: LET BUFO=MV+45: LET Vbig=MV+47: LET BBS=MV+48: LET HEAD=63960
 8720 LET Time=MV+19: POKE Time,1
 8725 LET h=CODE "d": LET s=CODE "  ": LET m1=5: LET m=0: LET drv=23550
 8750 RETURN 
 9000 REM >> Error Trap <<
 9002 POKE 23544,PEEK 23545
 9005 RANDOMIZE USR 61036: OUT STT,0: ON ERR RESET : REM Error trap
 9010 POKE VAL "23300",NOT PI: POKE VAL "23728",NOT PI: RANDOMIZE USR CODE "d": CLOSE #VAL "2": GO SUB VAL "9300"
 9025 GO SUB 9600: RANDOMIZE USR CODE "d": LOAD "U-List.A$" DATA d$()
 9030 LET s=VAL d$(VAL "1" TO VAL "4")
 9035 FOR a=VAL "1" TO LEN y$: LET d$(s)=y$(a): LET s=s+1: NEXT a: LET d$(s)=CHR$ VAL "13": LET d$(VAL "1" TO VAL "4")=STR$ (s+VAL "1")
 9040 RANDOMIZE USR CODE "d": SAVE "U-List.A$" DATA d$(): LET y$=" "
 9200 IF PEEK VAL "23544"=NOT PI THEN GO TO VAL "9230"
 9205 GO SUB VAL "9700": GO TO VAL "305"
 9210 REM Error Forced Sys Reset
 9240 RANDOMIZE USR 61036: CLEAR : GO SUB VAL "8700": OUT STT,NOT PI
 9250 RANDOMIZE USR CODE "d": CLOSE #VAL "2": GO SUB VAL "9700": GO TO VAL "300"
 9600 RANDOMIZE USR 100: GO TO sys: LET o$=d$(1,16 TO 20)+".A$": RANDOMIZE USR 100: SAVE o$ DATA d$(): RETURN : REM Save old M-base
 9700 RANDOMIZE USR CODE "d": GO TO sys: RANDOMIZE USR CODE "d": LOAD "GENER.A$" DATA d$(): RETURN 
 9899 STOP 
 9900 REM >> Load Maxcom <<
 9910 CLEAR VAL "57799": LET h=CODE "d": RANDOMIZE USR h: LOAD "MOCOD.C1"CODE VAL "57800": POKE VAL "63814",CODE "o": RANDOMIZE USR h: POKE VAL "8218",VAL "57544": RANDOMIZE USR VAL "59e3": OPEN #PI,"LP"
 9920 RANDOMIZE USR h: OPEN #VAL "7","W2"
 9930 RANDOMIZE USR h: POKE VAL "63800",VAL "128"
 9940 LET st=CODE "w": LET dt=CODE "s": POKE VAL "61040",dt: POKE VAL "61043",dt: POKE VAL "61046",st: POKE VAL "61049",st: POKE VAL "23658",NOT PI: RUN 
 9950 REM >> SAVE MAXCOM <<
 9960 CLEAR : RANDOMIZE USR CODE "d": SAVE "MaxCom.B1" LINE VAL "9900"
 9970 RANDOMIZE USR CODE "d": SAVE "MOCOD.C1"CODE VAL "57800",VAL "63220-57800"

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