;CBBS V3.5.0 FILE CBBS.ASM - MAINLINE ;01/03/82 16:02:40 Put in new .asm date, cbbssub2 mod'd ;12/04/81 08:50:41 Set CBBSCHI=FALSE ;LINKS TO CBBSFUNC.ASM ; VERS EQU 3 ;PRINTED AT SIGNON MODIF EQU 5 ;(9 MAX) LEV EQU 0 ;(9 MAX) ; ; O O O O O O O O O O ; O O O O O O ; O O O O O O O O .ASM ; O O O O O O ; O O O O O O O O O O ; ;--------------------------------------- ; ; O O O O O O O O O O O ; OO O O O O O ; O O O O O O O O O ; O OO O O O O ; O O O O O O O O O O ; ;_THIS PROGRAM MUST BE ASSEMBLED WITH ; "LINKASM.COM" WHICH HANDLES THE "LINK" ; PSEUDO-OPS AT THE END OF EACH FILE, ; WHICH LINKS TO THE NEXT .ASM FILE ; ---------------- ; ;"CBBS"(R) COMPUTERIZED BULLETIN BOARD SYSTEM (R) ;IS COPYRIGHT (C) WARD CHRISTENSEN, 1978, 1979, 1980, 1981 ; ; 01/26/78 ;ORIGINALLY WRITTEN, SITTING HOME SNOWBOUND ;BY WARD CHRISTENSEN ; ;ALL COMMENTS REGARDING MODIFICATION are recorded ;in "HISTORY" files. HISTORY.DOC contains the comments ;for modifications for ALL .ASM files thru version 3.2; ; ;At times, modifications are indicated in the margin by ;a number, corresponding to the number in the HIST... file. ;This idea was later abandoned as being "too much house- ;keeping". ; ;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033" ; ORG 100H FALSE EQU 0 TRUE EQU NOT FALSE ; 02 FAST EQU FALSE ;RUNNING CBBS UNDER "FAST"? 04 CCOUNT EQU 35 ;MAX COMMENT LINES/CALL 04 ECOUNT EQU 7 ;MAX MSGS ENTERED/CALL 05 TEST EQU true ;TEST VERSION FOR NON-MODEM ; ;ALTERNATIVE TO "TEST" IS LOAD.SUB 10 CBBSCHI EQU FALSE ;WANT DRIVE DESELECT? (0C OUT FC) ; REINIT EQU true ;SET TRUE IF SYS NOT RELOADED ; EACH TIME IT IS RUN NOTIFY EQU TRUE ;NOTIFY FROM "NEXT" FILE? LINE2 EQU FALSE ; CLOCKC EQU FALSE ;COMPU-TIME CLOCK? (FILE CBBSCLKC.ASM) CLOCKS EQU false ;SCITRONICS CLOCK? (FILE CBBSCLKS.ASM) CLOCK EQU CLOCKC OR CLOCKS ;HAVE HARDWARE CLOCK? ; TTY EQU false ;IS THERE A LOG TTY? KBUFPG EQU 08 ;8 PAGE, 2K FOR KILLING ;---- ; ;NOTE THE ONLINE BULLETIN ADD ISN'T THAT GREAT - ;(THAT'S A NICE WAY OF SAYING "TERRIBLE") ;WE SUGGEST MAINTAINING THE BULLETIN WITH THE ;CP/M EDITOR, THUS BULL EQU FALSE ; BULL EQU FALSE ;ONLINE BULLETIN ADD? ; ---------------- 03;START OF MODS ;DIVISOR FOR # OF MSG FILES. LAST 2 DIGITS ;OF MSG FILE ARE DIVIDED BY THIS #. THEREFORE: ; 2 MEANS 50 FILES ; 3 34 FILES ; 4 25 FILES ; 5 20 FILES ..ETC. ; FILEDIV EQU 2 ;50 MSG FILES IN CBBS/CHICAGO 03;END OF MODS ; TTYST EQU 80H ;STATUS BIT (JZ WAIT LOOP) TTYSP EQU 0 ;TTY STATUS PORT TTYDP EQU 1 ;TTY DATA PORT SSW EQU 3 ;SENSE SWITCH PORT REMOTE EQU 0ffH ;SSW ON FOR REMOTE EJECT EQU FALSE ;EJECT TTY EVERY 60 LINES? TWITCK EQU TRUE ;ABORT IF INVALID USER NAME UKILL EQU 1 ;TRUE, USER CAN KILL OWN MSGS ; HAYES EQU FALSE ;HAVE HAYES MODEM? IDS EQU FALSE ;HAVE IDS MODEM? PMMI EQU false ;HAVE PMMI MODEM? SERMODM EQU true ;HAVE SERIAL MODEM? ; B450600 EQU TRUE ;450, 600 BAUD (PMMI, IDS ONLY) ; CR EQU 0DH LF EQU 0AH EOF EQU 1AH TAB EQU 09H ; ; --------> NOTE THE FOLLOWING <--------- ; ;THE FOLLOWING ADDRESS IS O-U-T-S-I-D-E ;OF THIS PROGRAM. IT IS A BYTE WHICH CONTAINS ;A CONTINUALLY RUNNING LINE COUNT FOR THE ;LOGGING TTY. IT NEED NOT BE INITIALIZED, ;BECAUSE THE COUNTER WILL EVENTUALLY REACH 60, ;AND GET IN SYNC. THE COUNTER IS N-O-T REF- ;ERENCED IF EITHER 'EJECT' OR 'TTY' IS FALSE. ; ;TTYLCT EQU 0EFF0H ;IN PROM BOARD'S RAM AREA ; JMP START ; ;IF CLOCK BOARD, DEFINE CURRENT YEAR SO IT ;MAY BE EASILY PATCHED AT YEAR CHANGE (THEY ;BECOME THE 4TH AND 5TH BYTES OF THE .COM FILE) ; IF CLOCKC ;Computime doesn't keep year. Y1 DB '8' ;DEFINE CURRENT.. Y2 DB '2' ;..YEAR PRINTED ENDIF ; DB '< Copyright (C) 1981, Ward Christensen >' DB '[01/03/82 16:02:40]' DB 1AH ;^Z TO ALLOW "TYPE CBBS.COM" ; START LXI SP,STACK CALL INIT ;SET UP I/O JMP ADDRESSES ; ;PICK UP THE PHONE, CHECK FOR CARRIER FOR 15 SEC. ; 05 IF NOT TEST IN SSW ;READ SSW ANI 80H ;REMOTE? CNZ CONNECT (EXITS IF NO CARRIER) endif ; ;PRINT VERSION ; MVI B,6 ;SEND 6.. CALL NULLP ;..NULLS CALL ILPRT DB 'CBBS(R) ' DB '0'+VERS,'.' DB '0'+MODIF,'.' DB '0'+LEV DB CR,LF,0 ; ;PRINT DATE/TIME ; IF CLOCK MVI A,1 ;DISABLE.. STA CTLCSW ;..CTL-C MVI B,6 ;DO 6 NULLS.. CALL NULLP ;..BEFORE TIME CALL PRTIME ;PRINT DATE,TIME LXI H,LGINTIM CALL RDTIME ;SAVE LOGIN TIME XRA A ;SHOW CTL-C.. STA CTLCSW ;..ENABLED ENDIF ; ;09/13/81 MODS TO WRITE DATE/TIME TO HARD-COPY LOG ; IF CLOCK AND TTY MVI A,50 STA COL ;FORCE C/R AFTER DATE/TIME LXI H,ANSWER ;WHERE "RDTIME" STORED DATE/TIME LOGTIME PUSH H MOV A,M CALL LOG POP H INX H MOV A,M ORA A JNZ LOGTIME MVI A,CR CALL LOG ENDIF ;09/13/81 END ; ;CHECK FOR CTL-C, TO SAVE OPENING WELCOME FILE ; WELL1 CALL CTLCWT ;WAIT 3/4 SEC, THEN TRY LXI H,WELCOM ;POINT TO FILENAME CNZ TYPEF ;TYPE THE WELCOME FILE ; ;TYPE BULLETIN FILE IF IT EXISTS ; NOWEL CALL CRLF ; ;CHECK FOR CTL-C, TO SAVE OPENING BULLETIN FILE ; CALL CTLCWT ;WAIT 3/4 SEC FOR CTL-C LXI H,BULFL ;POINT TO FILE CNZ TYPEF ;TYPE IF NO CTL-C ; ;IF THIS IS THE USERS FIRST TIME ON THE SYSTEM, ;PROCESS THE FILE 'FIRSTIME' WHICH SUPPLIES ;SOME INFO ON THE SYSTEM'S USAGE. ;07/15/81 ^K COMES HERE NOW IF CTLKSW SET TO 4. ; ASKT1 MVI A,CR ;BLANK 'WHERE FROM' FIELD STA SUBJ ;..IN CASE IT'S NOT ENTERED. MVI A,0FFH ;ALLOW.. STA CASE ;..LOWER CASE CALL GETVAR DB CR,LF DB 'Y/N: IS THIS YOUR FIRST TIME ON CBBS',0 DW ANSWER 06 DW 1 ;HELP MSG # DB 9 ;MAX ANSWER LEN ; ;LOOK AT FIRST CHAR IN BUFFER (INSTEAD OF THE ONE ;IN 'ANSWER', TO SEE IF LOWER CASE WAS ENTERED ; LDA FIRSTCH ;GET UN-TRANSLATED 1ST CHAR CPI 60H ;LOWER CASE? JNC T1LC ;IT IS LOWER CASE MOV B,A ;SAVE CHAR MVI A,05FH ;SET UPPER CASE STA CASE MOV A,B ;GET CHAR T1LC ANI 5FH ;MAKE UPPER CASE STA T1FLAG ;"REMEMBER" IF 1ST TIME CPI 'N' JZ GETFN CPI 'Y' JNZ ASKT1 ; ;IF UPPER CASE, ASK IF LOWER CASE CAN BE HANDLED ; LDA CASE INR A ;ZERO => LOWER CASE CNZ QCASE ;SEE IF CAN HANDLE LOWER CASE ; ;ASK WHERE CALLING FROM ; WHERE CALL GETVARN DB CR,LF ; DB '(Optional) ',CR,LF DB 'What city,state/prov. are you calling from',0 DW SUBJ ;TEMP STORE IT HERE 06 DW 0 ;NO HELP MSG # DB 30 ;MAX LEN LXI H,TIME1 ;POINT TO FILENAME CALL INTQF ;INTERPRET THE QUESTION FILE ; ;GET CALLER'S NAME ; GETFN CALL GETVAR ;GET THE NAME DB 'What is your FIRST name',0 DW FNAME 06 DW 2 ;HELP MSG # DB 19 ;MAX LEN LDA FNAME CPI 'A' ;FORCE ALPHA JC GETFN CPI 'Z'+1 JNC GETFN GETLN CALL GETVAR 01 DB '(Press return to return to "first name" ' 01 DB 'question)',CR,LF DB 'What is your LAST name',0 DW LNAME ;READ LAST NAME 06 DW 2 ;HELP MSG # DB 19 ;MAX LEN LDA LNAME CPI CR JZ GETFN 06 CPI '-' 06 JZ GETFN CPI 'A' ;FORCE ALPHA JC GETLN CPI 'Z'+1 JNC GETLN ; ;MAKE SURE FIRST + LAST NOT > 20 CHARS ; LXI H,FNAME CALL COUNTC0 ;INIT B=0, COUNT CHARS LXI H,LNAME CALL COUNTC MOV A,B ;GET COUNT CPI 20 ;+ 1 SPACE BETWEEN JC CKNOK ;CHECK IF NAME OK CALL ILPRT DB 'Sorry, first name + last name ' DB 'may not be > 19 long',CR,LF,0 JMP GETFN ; ;IF FIRST TIME USER, ASK IF NAME SPELLED OK. ; ;EXPERIENCED USERS DON'T NEED THIS QUESTION, ;AS THEY SHOULD KNOW CTL-U, DEL, ETC EDITING. ; CKNOK LDA T1FLAG ;1ST TIME? CPI 'N' JZ LOGIN ;NOT 1ST TIME CALL ILPRT DB 'Hi, ',0 LXI H,FNAME CALL TYPEMCR ;TYPE FIRST NAME MVI A,' ' CALL TYPE LXI H,LNAME CALL TYPEMCR ;TYPE LAST NAME 01 CALL GETVARN DB CR,LF DB 'Y/N Did I get your name right',0 DW ANSWER 06 DW 0 ;NO HELP MSG # DB 9 ;MAX ANSWER LEN LDA ANSWER 01 ANI 5FH ;UPPER CASE CPI 'N' JZ GETFN CPI 'Y' JNZ CKNOK CALL ILPRT DB '(NOTE: correcting done only if ' DB 'this is your first time)',CR,LF,0 ; ;LOG: (DATE TIME [IF THERE IS A CLOCK BOARD]) ;(CALLER #),(FIRST NAME),(LAST NAME),(WHERE FROM) ; LOGIN CALL ILPRT DB CR,LF DB 'Logging ',0 ;name to disk...',0 lxi h,fname call typemcr mvi a,' ' call type lxi h,lname call typemcr call ilprt db ' to disk ....',0 MVI A,1 STA DKUPSW ;SET DISK UPDATE IN PROGRESS STA CTLKSW ;DISALLOW CTL-K ;GET THE CALLER # FROM FILE "NEXT" ; (FORMAT IS: NNNNN(CR)(LF)CCCCC(CR)(LF) 04;AAAAA(CR)(LF)MMMMM(CR)(LF)(CTL-Z) ; WHERE NNNNN IS NEXT MSG #, CCCCC IS CALLER #, ; AAAAA IS THE # OF ACTIVE MESSAGES 04;MMMMM IS MAX ACTIVE MSGS). CALL RDNEXT ;SAVE CALLER # SO IT CAN BE LOGGED LXI H,87H ;FROM, LXI D,CALLERN ;..TO, MVI B,6 ;..LENGTH CALL MOVE ;MOVE INCL. C/R LXI H,LOGFL ;POINT TO FILENAME CALL EXTEND ;EXTEND THE FILE ; 09 CALL WRCRLF ;CRLF BEFORE ; ;WRITE DATE AND TIME TO LOG FILE IF CLOCK CALL WRTIME ENDIF ;CLOCK ; LXI H,CALLERN CALL WRVARC ;WRITE CALLER #, LXI H,SPEED ;WRITE BAUD RATE CALL WRVARC ;(1, 3, 4, OR 6) CALL WRNAME ;"FN LN," LXI H,SUBJ ;AND 'WHERE FROM'. CALL WRVARC ; 09;NOP THE CALL WRCRLF, SO THE E.T. WILL FOLLOW. ; CALL WRCRLF CALL WREOF ;CLOSE FILE CALL CRLF XRA A ;GET 0 STA DKUPSW ;NOT UPDATING DISK ;09/13/81 KILL INSTR PER LEWIS MOSELEY, ; 'CAUSE TWITS COULD ^K PAST NAME CHECK ; STA CTLKSW ;ALLOW CTL-K ; ;EDIT 01 PULLED CODE OUT OF HERE, MOVED TO ;"STATSUB" AT END OF CBBS.ASM ; 01 CALL ILPRT 01 DB 'You are',0 01 CALL STATSUB ;PRINT CALLER, MSG, MSGS ; ;WRITE BACK FILE W/MSG # AND CALLER # ; XRA A STA FCBRNO ;BACK TO SECTOR 0 LXI D,FCB MVI C,WRITE CALL BDOS ;WRITE BACK ORA A ;WAS IT OK? 06;MODS: JNZ NXERR LXI D,FCB MVI C,CLOSE CALL BDOS INR A ;returns -1 on error JZ NXERR ; ;12/09/78 ADD NOTIFY TEST ; IF NOT NOTIFY JMP FUNCT ENDIF ; IF NOTIFY JMP CKMSGS ENDIF ; NXERR CALL ILPRT 06;END OF MODS DB '++Error writing caller #',CR,LF,0 JMP TELLUS ; IF NOTIFY ; ;LOOK IN "NEXT" FILE FOR A MSG TO THIS CALLER ; CKMSGS CALL RDNEXT ;PRIME BUFFER CKNLP CALL RDBYTE JC FUNCT ;NO MSGS CPI '[' ;NAME HDR? JNZ CKNLP ;MATCH THE NAME LXI H,FNAME CALL MATCH JNZ CKNLP LXI H,LNAME CALL MATCH JNZ CKNLP ; ;OK, NAME MATCHED. ; CALL CRLF CKNTLP CALL RDBYTE JC FUNCT CPI ']' ;END OF MSG? JZ CKNSY CALL TYPE JMP CKNTLP ; ;CHECK NAME FOR SYSTEM FUNCTION: ; ; / HANG UP ON THE CALLER ; * FLAG AS "TWIT" (NO KILL, ENTER) ; $ KEEP TRACK OF LAST CALL (not implemented) ; CKNSY CALL RDBYTE CPI '/' JZ DISC ;DISCONNECT CPI '*' JZ TWITSET CPI '+' ;IF '+', CONTINUE (TO ALLOW JZ CKNLP ; INDIVIDUAL + "*.*". CPI '$' ; ;NOTE REMOVE THE FOLLOWING ';' WHEN 'LASTUSE' ;FUNCTION IS DEFINED ; ; JZ LASTUSE JMP FUNCT TWITSET MVI A,1 STA TWITSW JMP FUNCT ; ;MATCH A NAME AGAINST THE FILE ; MATCH CALL RDBYTE JC FUNCT CPI '*' ;MATCH ANY? JZ MATCHOK CPI ',' ;DELIM? JZ MATCHCR ;YES CMP M ;CHAR MATCH? RNZ ;..NO INX H JMP MATCH ; ;OK, SKIP TO NEXT DELIM ; MATCHOK CALL RDBYTE JC FUNCT CPI ',' ;DELIM? RZ ;YES JMP MATCHOK ; ;MATCH THE C/R AT END OF NAME ; MATCHCR MOV A,M CPI 0DH RET ;ZERO SET IF OK ENDIF ;NOTIFY ; ;"#" COMMAND (STATS) ; 01 STATS CALL ILPRT 01 DB 'Next',0 01 CALL STATSUB ;PRINT 01 JMP FUNCT ; ;TYPE CALLER #, HI MSG #, # OF MSGS. ;CALLED AT LOGON, AND BY # (STATS) FUNCTION. ; 01 STATSUB CALL ILPRT DB ' caller ',0 CALL RDNEXT ;GET "NEXT" TO 80H LXI H,87H ;POINT TO NUMBER 01; FOLLOWING COMMENTED OUT - WAS IN ERROR ; PUSH H ;FOR MOVE CALL TYPEMCR ; CALL CRLF ; ;INCREMENT CALLER # (NOP ON # COMMAND, BECAUSE ;ITS NOT WRITTEN BACK) ; LXI H,8BH ;TO UNITS DIGIT CALL ADD1 ; ;TYPE THE NEXT MESSAGE NUMBER ; CALL ILPRT DB '; next msg =',0 LXI H,80H ;POINT TO NUMBER 07 PUSH H ;SAVE POINTER CALL TYPEMCR ; CALL CRLF ; ;TYPE # OF ACTIVE MESSAGES ; CALL ILPRT DB ';',0 LXI H,8EH CALL TYPEMCR CALL ILPRT DB ' active msgs.',CR,LF,0 07;MODS: ; ;SAVE HI MSG # FOR "R;-" ; POP H ;MSG # POINTER LXI D,MSGNO MVI B,5 CALL MOVE 07;END ; RET ; link cbbsfunc ; ; ; autosc lxi h,inbuf fndcr mov a,h inx h cpi cr jnz fndcr lxi d,scstr mvi b,10 call mvlnm lxi d,lname call mvlnm5 lxi d,frmstr call mvlnm5 lxi d,lname call mvlnm5 dcx h mvi a,cr cmp m jz gfnc inx h mov m,a gfnc jmp funct ; mvlnm5 mvi b,5 mvlnm dcx h mov a,m cpi cr jz mvlp inx h mvlp ldax d mov m,a cpi cr inx h inx d rz djnz mvlp ret ; scstr db ';s;30,t='cr,0 frmstr db ';f=',cr,0 ; LINK CBBSFUNC ;NEXT .ASM FILE