;CBBS V3.5.0 CBBSOPER.ASM - OPERATOR FUNCTIONS ;12/03/81 15:42:22 (EXCEPT MESSAGE KILL) ; ; LINKS TO CBBSKILL ; ; O O O O O O O O O O O O ; O O O O O O O ; CBBS 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 ; ; ;MODS LOG: (THRU 3.2 MOVED TO "HISTORY") ; ;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033" ; ;-----> VALIDATE CE FUNCTION ; ;FORMAT FILENAME ;11/11/78 NOTE SIGNIFICANT MODS TO THIS ; ROUTINE, TO HANDLE A: AND B: NAMES ; CEFNC XRA A STA CEFCB ;SO STAT WILL GO TO A: ; ;PUT "R" IN "WHERE FROM" IN CASE "NAME" COMMAND, ;I.E. RE-LOG IN. ; LXI H,SUBJ ;WHERE 'CITY' STORED MVI M,'R' INX H MVI M,',' INX H MVI M,CR ; LXI H,ANSWER ; ;SCAN FOR ' ' AFTER COMMAND ; CESKB MOV A,M CPI CR ;NO ' ' (E.G. STAT CMD) JZ CECR ; YES CPI ' ' INX H JNZ CESKB ; ;POINTING TO FILENAME OR DISK:FILENAME (OR END OF LINE) ; XRA A ;DEFAULT TO STA CEFCB ; LOGGED IN DISK MOV A,M ;JUST "DIR "? CPI CR JZ CECR INX H ;CHECK FOR ':' MOV A,M DCX H CPI ':' ;DISK REQUESTED? JNZ CECR ; NO ;PUT DISK INTO FCB MOV A,M ;GET DISK SUI 'A'-1 ;MAKE BINARY (A=1, ETC) STA CEFCB ;STORE IN FCB INX H ;SKIP TO ':' INX H ;SKIP ':' ;POINTING TO FILENAME CECR MVI B,8 ;FILENAME LEN LXI D,CEFN ;POINT TO FILENAME CALL CEFMN ;FORMAT NAME MVI B,3 ;FILETYPE LEN LXI D,CEFT ;POINT TO FILETYPE CALL CEFMN ;FORMAT TYPE ; ;FOR CHAR STRING MATCH IN FILE TYPE COMMAND, ;SAVE A POINTER TO THE COMMA, AND SAVE THE ;LAST CHAR SCANNED. IF A COMMA, THEN WE ;ARE DOING STRING MATCH IN THE FILE TYPING. ; MOV A,M ;GET COMMA (MAYBE) STA STRFLG ;SAVE CHAR INX H ;SKIP COMMA SHLD STRPTR ;SAVE POINTER (MAYBE) ; ;LOOK UP THE COMMAND ; LXI H,CEFTAB ;FUNCTION TABLE CALL CELOOK JMP WHATM ; ;====> LOOK UP COMMAND ; HL POINTS TO TABLE. RETURNS ONLY IF NOT FOUND ; CELOOK LXI D,ANSWER ;COMMAND MVI B,4 CELKLP LDAX D CMP M JNZ CELNO INX D INX H DCR B JNZ CELKLP ; ;FOUND, EXECUTE IT ; CELGOT MOV E,M ;GET LO ADDR INX H MOV D,M ;GET HI POP H ;DUMP RETURN ADDR XCHG PCHL ;TO COMMAND ; ;NOT FOUND - SKIP IT, TRY NEXT ; CELNO INX H DCR B JNZ CELNO INX H ;SKIP INX H ; ADDR MOV A,M ORA A RZ ;NOT FOUND JMP CELOOK ; ;-----> TYPE A FILE ; CETYPE LXI H,CEFCB LDA ANSWER+4 ;%07/11/81 MOD CPI 'H' JZ CETFH CPI 'K' JZ CETFK CALL TYPEF JMP FUNCT ; ;TYPE FILE, BUT ONLY LINES WITH "]" ; CETFH CALL TYPEFH JMP FUNCT ; ;TYPE FILE, LINES WITH ], AND THE NEXT 2 LINES ; CETFK CALL TYPEFK JMP FUNCT ; ;-----> ERASE A FILE ; CEERA LXI H,CEFN MOV A,M CPI '?' JZ CENOTF DCX H ;BACK TO DISK # CALL SETRD ;SETUP JC CENOTF ;NOT FOUND LXI D,FCB MVI C,ERASE CALL BDOS CALL ILPRT DB '++ERASED',0 JMP FUNCT ; ;-----> DIR FUNCTION ; CEDIR LXI H,CEFCB LXI D,FCB MVI B,12 CALL MOVE ;SET UP NAME MVI A,'?' ;FIND ALL STA FCBEXT ; EXTENTS 01; DELETED FOLLOWING 2 LINES 01; CALL ILPRT 01; DB '--NAME--TYP X SEC',CR,LF,0 LXI H,' ' ;INIT # SHLD CEDIRN ; OF FILES MVI A,'0' STA CEDIRN+2 03;MODS: LDA FCB+1 ;IF FCB CPI ' ' ; IS ' ' JNZ CENQ ; THEN LXI H,FCB+1 ; MAKE MVI A,'?' ; IT MVI B,11 ; ALL CEDIRQ MOV M,A ; '?' INX H DCR B JNZ CEDIRQ ; CENQ MVI C,SRCHF ;SEARCH FIRST 03;END JMP CEDIRF ; CEDIRL MVI C,SRCHN ;SEARCH NEXT CEDIRF LXI D,FCB CALL BDOS ;ANY? INR A JZ CEDIRE ;END DCR A ANI 3 ;ISOLATE # IN SECTOR ADD A ADD A ADD A ;MULTIPLY BY 32 ADD A ADD A ADI 81H ;LOC'N IN BUFFER MOV L,A MVI H,0 PUSH H ;SAVE NAME POINTER LXI D,11 DAD D ;POINT TO EXT MOV A,M ;GET EXTENT MVI M,' ' ;STORE A SPACE ADI '0' ;GET EXTENT INX H MOV M,A ;SAVE EXTENT INX H MVI M,0 ;ZERO AS END OF NAME POP H ;RESTORE NAME POINTER ;DON'T PRINT DETAIL IF COMMAND WAS 'DIRN' LDA ANSWER+3 CPI 'N' JZ CEDNOP ;NO PRINT CALL TYPEM0 ;TYPE NAME CALL SPACE MOV A,M ;GET REC COUNT CALL PRDEC ;PRINT IN DECIMAL 03;MODS: cedire LDA TABCOL CPI 45 JNC CEDCRLF CALL SPACE CALL SPACE JMP CEDNOP CEDCRLF CALL CRLF CEDNOP LXI H,CEDIRN+2 ;IGINALLY LOGGED IN DISK ; POP D MVI C,LGINDK CALL BDOS JMP FUNCT 03;END ; ;----> 'NOTE' FUNCTION - WRITES NOTES TO 'CRLF 03 ORA A ; ONLY IF NOT 03 CNZ CRLF ; IN COLUMN 0 LDA ANSWER+3 ;DIRN? CPI 'N' JZ CEDIRI LDA CEDIRN+1 CPI ' ' JNZ CEDIRI LDA CEDIRN+2 CPI '4' JC FUNCT ;ONLY 0-3, DON'T TELL HOW MANY CEDIRI CALL ILPRT CEDIRN DB ' 0' ;MODIFIED DB ' Files',0 JMP FUNCT ; IF BULL ; ;-----> ADD MESSAGE TO BULLETIN FILE ; CEBULL LXI H,BULFL ;POINT TO FILENAME CALL SETRD ;SEE IF IT EXISTS JC CEBNF ;NO FILE EXISTS CEBQ CALL GETVAR DB 'Y/N: WANT TO ERASE PREVIOUS ' DB 'BULLETIN(S)',0 DW ANSWER 02 DW 00 ;HELP MSG # DB 1 ;LEN LDA ANSWER CPI 'N' JZ CEBNF CPI 'Y' JNZ CEBQ ;RE-ASK LXI D,FCB MVI C,ERASE CALL BDOS CEBNF LXI H,BULFL ;POINT TO FILENAME CALL EXTEND ;EXTEND THE FILE LXI H,BULLIN ;'---- BULLETIN----' CALL WRLINE CALL ILPRT DB CR,LF DB 'ENTER BULLETIN LINE, C/R WHEN DONE.' DB CR,LF,'FOR A BLANK LINE,' DB 'TYPE 1 SPACE, THEN C/R' DB CR,LF,0 ;SHOW UPDATING DISK MVI A,1 STA DKUPSW STA CTLKSW ;ALSO DISABLE CTL-K CEBULI CALL GETVARN DB 0 ;NO MSG DW ANSWER 02 DW 00 ;HELP MSG # DB 60 ;LEN LDA ANSWER CPI CR JZ CEBEND ;END OF BULLETIN LXI H,ANSWER CALL WRLINE JMP CEBULI ; ;END OF BULLETIN ; CEBEND LXI H,BULLIN CALL WRLINE ;PUT A ']' (END OF QUESTION) IN THE FILE, SO IF ;THE USER CONTROL-C'S THE BULLETIN, IT WILL SKIP ;TO THE NEXT BULLETIN MESSAGE (IF THERE IS ONE) MVI A,']' CALL WRBYTE CALL WRCRLF CALL WREOF ;EOF, CLOSE FILE JMP FUNCT ENDIF ; ;----> STAT 03;MODS REWRITTEN TO BE "UNIVERSAL" ; ;STAT FUNCTION - DETERMINES SIZE OF ALL LOGGED IN DISKS ; CP/M 1.4 AND 2.2 COMPATIBLE. ; CESTAT MVI C,INQDISK CALL BDOS ;GET, AND PUSH H ; SAVE CURRENT DISK MVI C,GETLGIN CALL BDOS ;FIND WHICH DISKS LOGGED IN MOV C,A ;C=LOGIN VECTOR MVI B,1 ;B=NEXT DISK TO TRY MVI D,'A' ;CURRENT DISK BEING TRIED CESTDK PUSH B ;SAVE DISK, ETC PUSH D MOV A,C ;GET LOGIN VECTOR ANA B ;TEST FOR 1 DISK JZ CESTNLI ;NOT LOGGED IN ;SELECT THE DISK MOV A,D ;GET ASCII CALL TYPE ;TYPE IT MVI A,':' ;THEN ':' CALL TYPE MOV A,D SUI 'A' ;MAKE IT ACCEPTABLE TO BDOS MOV E,A MVI C,LGINDK ;LOGIN THE DISK CALL BDOS ;LOG IN THE DISK ; ;GET THE SIZE OF THE DISK ; MVI C,GETVERS CALL BDOS ;GET VERSION MOV A,L ORA A JNZ CEST22 ;IT IS 2.2 ; ;THIS IS 1.4, SO GET PARM BLOCK FROM THE FRONT OF BDOS ; LHLD BDOS+1 ;GET ADDR LXI D,36H ;OFFSET TO PARM DAD D MOV A,M ;GET BLOCK SHIFT FACTOR INX H INX H MOV E,M ;GET DISK SIZE MVI D,0 JMP CESTCAL ; CEST22 MVI C,GETPARM CALL BDOS ;GET DISK PARM ADDR INX H INX H MOV A,M INX H INX H INX H MOV E,M INX H MOV D,M CESTCAL XCHG INX H ;FUDGE HL TO # OF BITS IN MAP PUSH PSW ;SAVE ALLOCATION BLOCK SIZE PUSH H ;SAVE # BITS MVI C,INQALC CALL BDOS ;GET ALLOCATION POP D ;GET BIT MAP COUNT LXI B,0 ;INIT # K FREE CESTB80 MVI A,80H ;INIT MASK CESTBIT PUSH PSW ;SAVE MASK ANA M ;FREE? JNZ CESTNB ;NO BIT INX B ;COUNT THE BIT CESTNB DCX D ;COUNT DOWN # BITS MOV A,D ORA E JZ CESTASC ;DONE, COMPUTE IN ASCII POP PSW ;GET MASK ORA A ;NO CARRY RAR ;RIGHT 1 BIT, JNC CESTBIT ;LOOP IF SAME BYTE INX H ;TO NEXT BYTE JMP CESTB80 ; ;DONE, BC = #K FREE, COMPUTE IN ASCII ; CESTASC POP PSW ;DUMP THE BIT MASK LXI H,CESTFRE MVI A,' ' MOV M,A INX H MOV M,A INX H MOV M,A INX H MVI M,'0' ;IN CASE '0' K FREE ; ;NOW, MULTIPLY THE # OF BITS THAT WERE 0, ; BY THE # OF K PER BIT ; POP PSW ;GET BLOCK SHIFT MOV D,B MOV E,C ;MOVE COUNT TO DE XCHG ;THEN TO HL SUI 3 ;IS IT 1K? JZ CESTASB ;YES CESTINK DAD H ;DOUBLE # OF BITS FREE DCR A ;COUNT DOWN JNZ CESTINK CESTASB XCHG CESTASL MOV A,D ;DOWN TO ORA E ; 0 LEFT? JZ CESTPRT ; YES, PRINT IT PUSH H ;SAVE POINTER CALL ADD1 ;ADD 1 IN ASCII DCX D ;DCR COUNT POP H JMP CESTASL ; CESTPRT CALL ILPRT CESTFRE DB ' K Free',0DH,0AH,0 ; ;DISK NOT LOGGED IN, OR DONE PROCESSING. TRY NEXT ONE ; CESTNLI POP D POP B INR D ;BUMP PRINTABLE DISK MOV A,B ;GET MASK ADD A ;SHIFT LEFT MOV B,A JNC CESTDK ;PROCESS NEXT DISK ; ;RESTORE ORIGINALLY LOGGED IN DISK ; POP D MVI C,LGINDK CALL BDOS JMP FUNCT 03;END ; ;----> 'NOTE' FUNCTION - WRITES NOTES TO 'NOTES' FILE ; WHICH ARE THEN TYPED VIA 'TYPE NOTES' COMMAND ; AND ERASED VIA 'ERA NOTES' COMMAND ; CENOTE if twitck call twitst jz whatm ;don't let twits lda twitsw ;enter memos ora a jnz whatm mvi a,1 sta dkupsw sta ctlksw ;no control k allowed endif ; LXI H,NOTEFL ;POINT TO FILENAME CALL EXTEND ;EXTEND (OR CREATE) MVI A,']' CALL WRBYTE ; LDA ANSWER+4 ;IS THIS "NOTEN" CPI 'N' ; I.E. NOTES JZ CENOTEN ; WITHOUT HEADER? ; LXI H,COMFRM ;WRITE 'FROM:', CALL WRVAR LXI H,FNAME CALL WRVARC ;FIRST NAME "," ; IF CLOCK CALL WRTIME ENDIF CENOTEN CALL WRCRLF ; CENLP CALL GETVARN ;07/19/81 FORMERLY GETVAR DB ':',0 ;07/11/81 FORMERLY HAD CR,LF DW ANSWER ;READ IN HERE 02 DW 0 ;HELP MSG # DB 60 ;LINE LENGTH LDA ANSWER ;END? CPI CR JZ CENEND ;YES, END LXI H,ANSWER CALL WRLINE ;WRITE LINE TO DISK JMP CENLP ;LOOP UNTIL C/R ENTERED ; ;END OF CE NOTE FUNCTION - CLOSE FILE ; CENEND CALL WREOF ;CLOSE JMP FUNCT 03;MODS: ; ;====> HOLD COMMAND PREVENTS PHONE HANGUP ; HOLD LDA HOLDFLG XRI 1 STA HOLDFLG JNZ HOLDNO CALL ILPRT DB 'Will',0 JMP HOLDMSG ; HOLDNO CALL ILPRT DB 'Won''t',0 HOLDMSG CALL ILPRT DB ' time out',0 JMP FUNCT 03;END ; ;----> DUMP COMMAND - USE CTL-K TO ABORT ; CEDUMP LXI D,CEFN ;TO ASCII HEX CALL RDHEX ;TO HL ; ;DUMP A LINE AT A TIME, ABORT ON CTL-K ; CEDULN MOV A,H CALL HEX MOV A,L CALL HEXB PUSH H CEDUNHC MOV A,M INX H CALL HEX CALL CTLCKS JZ FUNCT MOV A,L ANI 3 CZ SPACE MOV A,L ANI 0FH JNZ CEDUNHC POP H CALL CEDUAST CEDUASC MOV A,M ani 7fh ;mask off bit 7 CPI ' ' JC CEDUPER CPI 7FH JC CEDUNP CEDUPER MVI A,'.' ;NON PRINTABLE CEDUNP CALL TYPE CALL CTLCKS JZ FUNCT INX H MOV A,L ANI 0FH JNZ CEDUASC CALL CEDUAST CALL CRLF JMP CEDULN ; CEDUAST MVI A,'*' JMP TYPE ; ;====> PRINT ROUTINE, CAUSES TYPING TO ECHO TO LIST ; CEPRINT LDA PRINTSW XRI 1 STA PRINTSW JZ CEPRNO CALL ILPRT DB 'On',0 JMP FUNCT ; CEPRNO CALL ILPRT DB 'OFF',0 JMP FUNCT ; ;----> ENTR COMMAND - ENTER A BYTE INTO MEMORY ; ; ENTR ADDR.DATA, DATA = 1 BYTE ONLY ; CEENTR LXI D,CEFT CALL RDHEX ;GET DATA MOV B,L ;SAVE IT LXI D,CEFN ;TO ADDR CALL RDHEX MOV A,M ;GET OLD VALUE CALL HEX MOV M,B ;STORE NEW JMP FUNCT ; ;====> CESLOW ; TO SLOW DOWN TYPING ; WHEN TESTING CBBS LOCALLY ; CESLOW LDA TYPDLY+2 ;GET TYPING DELAY ADI 8 ANI 18H STA TYPDLY+2 JMP FUNCT ; ;HEX READ ROUTINE, DE POINTS TO ASCII. ;TERMINATES WITH ' ' OR CR. ; RDHEX LXI H,0 ;INIT ADDR RDHI LDAX D INX D CPI ' ' ;END? RZ ;START DUMPING CPI CR RZ CPI '0' ;CONV ASCII TO HEX JC WHATM CPI '9'+1 JC RDHNUM CPI 'A' JC WHATM CPI 'F'+1 JNC WHATM SUI 7 RDHNUM SUI '0' DAD H DAD H DAD H DAD H ADD L MOV L,A JMP RDHI ; ;FILE NOT FOUND ; CENOTF CALL ILPRT DB 'No: ',0 LXI H,CEFN MVI B,0 CALL TYPEM JMP FUNCT ; ;FORMAT NAME - PAD W/SPACES. LEN IN B ; CEFMN MOV A,M CPI CR ;END? JZ CEFEND CPI ',' ;START OF STRING? JZ CEFEND INX H CPI '.' JZ CEFEND CPI '*' JZ CEFQM ;FILL W/'?' STAX D INX D DCR B JNZ CEFMN MOV A,M ;AT '.'? CPI '.' RNZ ;NO INX H ;SKIP '.' RET ; ;END OF INPUT FIELD, PAD W/' ' ; CEFEND MVI A,' ' STAX D INX D DCR B JNZ CEFEND RET ; ;GOT "*", PAD WITH '?' ; CEFQM MVI A,'?' STAX D INX D DCR B JNZ CEFQM MOV A,M ;AT '.'? CPI '.' RNZ INX H RET ; ; ;-----> WORK AREA FOR CE FUNCTIONS ; CEFCB DS 1 ;DISK (A=1, ETC) CEFN DS 8 ;FILENAME CEFT DS 3 ;FILETYPE DB 0 ;END OF NAME, FOR PRINTING ; IF BULL CEBULPW DB 'BULOK' ;BULLETIN FUNCTION PASSWORD CEBULPL EQU $-CEBULPW ;PASSWORD LENGTH ENDIF ; ;10/17/81 MODS TO SUPPORT CONTINUING A MSG IN MSG ENTRY ; CECONT MVI A,1 STA MCONT ;SHOW CONTINUED JMP ENTER ;THEN GO TO MSG ENTRY ; ;10/17/81 END ; ; ;HEX WITH SPACE ; HEXB CALL HEX JMP SPACE ; ;HEX PRINT ROUTINE ; HEX PUSH PSW RAR RAR RAR RAR CALL NIBBL pop psw nibbl ani 0fh adi 90h daa aci 40h daa jmp type ; ceftab db 'DIR ' DW CEDIR DB 'DIRN' DW CEDIR DB 'ERA ' DW CEERA DB 'STAT' DW CESTAT DB 'XCPM' DW 0 DB 'NOTE' DW CENOTE DB 'NAME' DW GETFN DB 'DUMP' DW CEDUMP DB 'ENTR' DW CEENTR 02 DB 'PURG' 02 DW PURGE 03 DB 'HOLD' 03 DW HOLD 04 DB 'PRIN' 04 DW CEPRINT DB 'SLOW' DW CESLOW DB 'CONT' DW CECONT ; DB 0 ;END OF FUNCTION TABLE ; LINK CBBSKILL