;CBBS V3.5.0 CBBSENT2.ASM - MSG ENTRY, PART 2 ;08/02/81 13:22:04 ; LINKS TO CBBSRTRV ; ; O O O O O O O O O O ; O OO O O O O ; CBBS O O O O O O O .ASM ; O O OO O O ; O O O O O O O O O ; ;FILE CONTAINS MESSAGE ENTRY SUBFUNCTIONS: ; (A)bort ; (C)ontinue ; (D)elete ; (E)dit ; (G)et msg ; (H)elp ; (I)nsert ; (L)ist ; (R)e-type ; (S)ave. ; ; e(X)pert mode may also be switched, but this ; is a function of GETVAR, not msg entry. ; ;====> HISTORICAL COMMENTS SINCE 3.3 TO "HISTORY.033" ; ; -------- ; ;COME HERE FOR ENTER MODE SUBCOMMANDS, ;OR IF CTL-K TYPED DURING MSG ENTRY ; ENCOMD: 01 LXI SP,STACK LHLD LINEAD MVI M,0 ;SET END OF MSG LDA EXPERT ORA A JNZ ENREQ ; ENASIST CALL ILPRT DB CR,LF DB 'Enter 1 letter: then press return.' DB CR,LF DB '(A)bort, (C)ontinue, (D)elete, ' DB '(E)dit, (G)et msg, (H)elp,',CR,LF DB '(I)nsert, (L)ist, (R)e-type',CR,LF DB '(S)ave <--- (DO THIS WHEN ' DB 'YOU HAVE FINISHED) ',0 ENREQ LDA INBUF ;STACKED ANS? CPI CR CNZ CRLF ;YES, CRLF CALL GETVAR DB CR,LF,'A,C,D,E,G,H,I,L,R,S:',0 DW ANSWER 02 DW -1 ;HELP MSG # (PASS BACK "?") DB 8 ;MAX LEN (ALLOW "CONTINUE") LDA ANSWER CPI '?' ! JZ ENASIST CPI CR ! JZ ENASIST CPI 'A' ! JZ VABORT CPI 'C' ! JZ ENCONT CPI 'D' ! JZ ENDEL CPI 'E' ! JZ ENEDIT CPI 'G' ! JZ ENGET CPI 'H' ! JZ ENHELP CPI 'I' ! JZ ENISRT CPI 'L' ! JZ ENLIST CPI 'R' ! JZ ENRETYP CPI 'S' ! JZ ENSAVE ; JMP ENCOMD ;BAD - ASK AGAIN ; ;'C' SUBCOMMAND: CONTINUE ENTERING (UNLESS FULL) ; ENCONT LDA MSGBF+15*64 ;TO LAST LINE ORA A ;0 => EMPTY JZ ENLOOP ;OK, ROOM FOR MORE JMP ENFULL ;IT'S FULL, CAN'T CONTINUE ; ;DELETE A LINE ; ENDEL LDA INBUF ;LINE # ALREADY GIVEN? CPI CR ;BUFFERED ANSWER? JNZ ENDEL2 ;YES. CALL ILPRT DB 'Delete ',0 ENDEL2 CALL ENGETL ;GET LINE # JZ ENCOMD ;NO LINE ENDELP MVI M,0 ;KILL THE LINE MOV A,C ;GET LINE # CPI 16 ;DONE? JZ ENDEND ;..YES XCHG ;MOVE UP.. LXI H,64 ;..1 LINE push b lxi b,64 ; MOV B,L ;B=64 DAD D ;DE=PREV, HL=NELINES, MUST GET EOM. ldir xchg pop b inr c jmp endelp ; ; CALL RDBYTE ; JC ENGEOF ; CPI 7 ; JZ ENGEOF ENDEND CALL ILPRT DB '++Deleted++',CR,LF,0 ; ;fix up the hi line number AND POINTER ; LHLD LINEAD ;HI LINE PTR LXI D,-64 DAD D SHLD LINEAD ; LXI H,LINO+1 ;TO ASCII # 03;MODS CALL SUB1 LXI H,HILINE+1 CALL SUB1 03;END JMP ENCOMD ; ;'I' SUBCOMMAND: INSERT A LINE ; ENISRT LDA MSGBF+15*64 ;ALREADY 16 LINES? ORA A JNZ ENFULL ;YES, FULL LDA INBUF ;LINE # ALREADY GIVEN? CPI CR ;BUFFERED ANSWER? JNZ ENIS2 ;YES. CALL ILPRT DB 'Insert before ',0 ENIS2 CALL ENGETL ;GET LINE # JZ ENCOMD ;NO LINE ;C = BINARY LINE #, HL = ADDR SHLD ENISAD ;SAVE ADDRESS FOR INPUT LXI B,MSGBF+15*64 ;PAST 2ND LAST LINE LXI D,MSGBF+16*64 ;PAST LAST LINE ; ;MOVE THE LINES APART TO MAKE ROOM FOR INSERT ;THIS IS A "TOP DOWN" (BACKWARDS) MOVE. ; ENISMV DCX B ;BACK.. DCX D ;..UP 1 LDAX B STAX D ;SEE IF DONE MOV A,B ;PAGES MATCH? CMP H ;AT LINE? JNZ ENISMV ;NO, LOOP MOV A,C ;LOW MATCH CMP L JNZ ENISMV ; CALL GETVARN DB 'Type the inserted line',CR,LF,0 ENISAD DW $-$ 02 DW 16 ;HELP MSG # DB 60 ; ;INCREMENT HI ADDR, LINE #, BECAUSE OF THE ;INSERTED LINE ; LXI H,LINO+1 CALL ADD1 ;BUMP IN ASCII 03 LXI H,HILINE+1 03 CALL ADD1 ;BUMP HI LINE # LHLD LINEAD LXI D,64 DAD D SHLD LINEAD JMP ENCOMD ; ;TYPE HELP FILE FOR ENTER FUNCTION ; ENHELP LXI H,ENHLFL ;'ENTRHELP' CALL INTQF ;INTERPRET THE QUESTION FILE JMP ENCOMD ; ;LIST THE MESSAGE ; ENLIST LDA INBUF ;LINE # ALREADY GIVEN? CPI CR ;BUFFERED ANSWER? JNZ ENLIS2 ;YES. CALL ILPRT DB 'Starting ',0 ENLIS2 CALL ENGETL ;GET LINE # JZ ENCOMD ;NO LINE # MOV A,C ;GET LINE # LXI B,'00' ENLIS3 INR C DCR A JNZ ENLIS3 ;BC NOW HAS ASCII NUMBER, MAY REQUIRE DECIMAL ADJUST MOV A,C CPI '9'+1 JC ENLIS4 INR B ;CARRY SUI 10 ;ADJUST MOV C,A ENLIS4 LXI D,64 ENLINE MOV A,M ;END? ORA A JZ ENCOMD ;DONE MOV A,B CALL TYPE MOV A,C CALL TYPE MVI A,' ' CALL TYPE CALL CTLCKS JZ ENREQ PUSH H PUSH B CALL TYPEMCR CALL CRLF POP B POP H DAD D INR C MOV A,C CPI '9'+1 JC ENLINE LXI B,'01' ;'10' REVERSED JMP ENLINE ; ;'G' SUBCOMMAND: GET AN EXISTING MESSAGE ; ENGET LXI H,MSGNO ;SAVE.. LXI D,SAVMSG ;..CURR.. MVI B,5 ;..MSG # CALL MOVE CALL GETVAR DB CR,LF DB 'MSG #: to get (C/R if none) ',0 DW ANSWER 02 DW 16 ;HELP MSG # DB 5 ;MSG # LEN LDA ANSWER ;JUST.. CPI CR ;..CR? JZ ENCOMD ; CALL JUSTA ;RIGHT JUSTIFY INTO 'MSGNO' JC ENGET ;BAD NUMBER CALL SETMSGN ;SETUP FILENAME LXI H,MSGFN ;POINT TO 'MESSAGE ',MSGNO CALL SETRD ;SET UP TO READ JC ENGNSM ;NO SUCH MSG FILE ; ;SCAN FOR BELL HDR ; ENGBEL CALL RDBYTE JC ENGNSM ;NO SUCH MSG CPI 7 ;HDR? JNZ ENGBEL ; ;GOT HDR, SEE IF RIGHT ONE ; LXI H,MSGNO ;GOT BELL,.. MVI B,5 ;..MATCH MSG ENGSRM CALL RDBYTE JC ENGNSM CMP M JNZ ENGBEL ;NOT IT, GET NEXT INX H DCR B ;=, CONTINUE JNZ ENGSRM ; ;GOT THE MESSAGE. READ IT IN. ; CALL RDBYTE ;EAT ',' MVI B,4 ;TYPE THRU 4 COMMAS ; ;ECHO THE PREV HDR ; ENGHDR CALL RDBYTE JC ENGNSM PUSH PSW CALL TYPE POP PSW CPI ',' JNZ ENGHDR DCR B JNZ ENGHDR CALL CRLF ; ;SKIP THE PASSWORD ; ENGSKP CALL RDBYTE JC ENGBAD ;BAD MSG CPI LF JNZ ENGSKP ; ;POINTING TO MSG, READ IT IN ; LXI H,'00' SHLD HILINE INR H SHLD LINO LXI H,MSGBF MVI B,16 ;MAX # LINES SHLD LINEAD ENGLIN LHLD LINEAD CALL RDBYTE MOV M,A JC ENGEOF CALL ENGTAB ;A TAB? CPI 7 ;NEXT MSG HDR? JZ ENGEOF INX H ENGCHR CALL RDBYTE JC ENGBAD MOV M,A CALL ENGTAB ;TAB? CPI LF JZ ENGEOL ;END OF LINE? INX H ;TO NEXT MOV A,L ANI 3FH ;TO NEXT LINE? JNZ ENGCHR SHLD LINEAD ;SAVE LINE ADDR DCX H MVI M,LF DCX H MVI M,CR PUSH B LXI H,LINO CALL TYPEM0 CALL ILPRT DB ' truncated.',CR,LF,0 POP B ; ;SKIP REMAINDER OF TRUNCATED LINE ; ENGSKT CALL RDBYTE JC ENGEOF CPI LF JNZ ENGSKT LHLD LINEAD DCX H ; ;GOT LINEFEED, SKIP TO END OF LINE ; ENGEOL INX H MOV A,L ANI 3FH ;TO NEXT LINE? JNZ ENGEOL SHLD LINEAD MVI M,0 ;SHOW END LHLD LINO SHLD HILINE LXI H,LINO+1 CALL ADD1 ;BUMP ASCII # DCR B ;MORE LINES? JNZ ENGLIN ;YES ; ;HAVE READ 16 LINES, MUST GET EOM. ; CALL RDBYTE JC ENGEOF CPI 7 JZ ENGEOF ENGTR CALL ILPRT DB '++Msg truncated++',CR,LF,0 ; ;GOT EOF - FIXUP THINGS ; ENGEOF LHLD LINEAD INR B LXI D,64 ENG0 MVI M,0 DAD D DCR B JNZ ENG0 LXI H,HILINE CALL TYPEMCR CALL ILPRT DB ' line(s).',CR,LF,0 CALL ENGRSM ;RESTORE MSG # JMP ENCOMD ; ;RESTORE OLD MSG # ; ENGRSM LXI H,SAVMSG LXI D,MSGNO MVI B,5 CALL MOVE RET ; ;TEST FOR A TAB ; ENGTAB CPI 9 ;TAB? RNZ ;NO ENGTABL MVI M,' ' ;GOT TAB.. INX H ;..EXPAND IT MOV A,L ANI 7 JNZ ENGTABL DCX H MVI A,' ' RET ; ;NO SUCH MSG ; ENGNSM CALL ILPRT DB '++Msg not found++',CR,LF,0 ENGRET: 01 CALL ILPRT DB 'Returning to msg entry.',CR,LF,0 CALL ENGRSM JMP ENCLR ;CLR MSG, START OVER ; ENGBAD CALL ILPRT DB '++Error: can''t read msg.',cr,lf,0 JMP ENGRET ; ;'E' SUBCOMMAND: EDIT LINE: /OLD/NEW/ ; ENEDIT CALL ENGETL ;GET LINE # JZ ENCOMD SHLD ENMAD ;SAVE POINTER ENEDITR CALL ILPRT DB 'Line was:',CR,LF,0 LHLD ENMAD CALL TYPEMCR CALL CRLF ENEDT2 CALL GETVARN DB 'Enter: the corrections or ? for help',0 DW ANSWER 02 DW -1 ;HELP MSG # DB 60 LDA ANSWER CPI CR JZ ENCOMD CPI '?' JNZ EDCMP CALL ILPRT DB 'This function does a character ' DB 'string substitution edit.',CR,LF DB 'Type: /old string/new string/',CR,LF DB 'New string may be null (//).',CR,LF DB 'When the line is correct, just ' DB 'press return',CR,LF,0 JMP ENEDT2 ; ;TRY TO MATCH CHAR STRINGS ; EDCMP LHLD ENMAD ;GET ADDR MVI C,63 ;# OF COMPARES TO MAKE EDNEXT PUSH H ;SAVE BUFF PTR LXI D,ANSWER LDAX D ;GET DELIM MOV B,A ;SAVE IT EDCOMP INX D LDAX D ;GET NEXT CMP B ;DELIM? JZ EDMAT ;MATCH CPI CR ;END? JZ EDBAD ;BAD DELIM CMP M INX H JZ EDCOMP ; ;NO MATCH - TRY NEXT 'WINDOW' OF LINE ; EDNMAT POP H ;RESTORE LINE ADDR MOV A,M CPI CR JZ EDBAD INX H ;MOVE 1 CHAR AHEAD DCR C ;MORE TO FIND? JNZ EDNEXT EDBAD MOV A,B ;DELIM CALL TYPE CALL ILPRT DB ': not found - ' DB 'Type ? for help',CR,LF,0 JMP ENEDITR ; ;'FROM' STRING MATCHED. NOW: ;DE= START OF 'TO' FIELD ;HL= REST OF ORIGINAL LINE ;STK= START OF DELETED STRING ; ;MOVE REST OF STRING TO WORK BUFFER EDMAT PUSH D MVI C,CR ;MOVE END DELIMITER LXI D,80H ;RECEIVING FIELD CALL MOVEC POP D ;GET 'TO' FIELD POP H ;GET START OF DELETED INX D ;SKIP DELIMITER ;MOVE THE NEW FIELD TO THE BUFFER EDMV1 LDAX D ;GET NEW CHAR MOV M,A CMP B ;DELIM? JZ EDMV1D ;MOVE DONE CPI CR JZ EDMV1D ;NO ENDING DELIM. INX D INX H CALL EDCKS JMP EDMV1 ;NEW FIELD IS MOVED TO LINE, NOW COPY.. EDMV1D LXI D,80H ;..REMAINDER OF LINE EDMV2 LDAX D MOV M,A CPI CR JZ EDMV2D ;ALL DONE INX H INX D CALL EDCKS ;CHECK SIZE JMP EDMV2 ;MOVE ALL DONE. PRINT NEW LINE EDMV2D LHLD ENMAD CALL TYPEMCR CALL CRLF LDA EXPERT ORA A JNZ ENEDT2 CALL ILPRT DB 'Continue changes (C/R when done)' DB CR,LF,0 JMP ENEDT2 ; ;CHECK IF LINE TOO LONG ; EDCKS MOV A,L ANI 63 RNZ DCX H ;BACK UP 1 MVI M,CR ;PUT END XCHG ;END TO DE POP H ;KILL RETURN ADDR LXI H,-63 ;POINT HL TO DAD D ; FRONT CALL TRUNC ;TRUNCATE TO SPACE CALL ILPRT DB '++Truncated to:' DB CR,LF,0 JMP EDMV2D ; ;----> MOVE (HL) TO (DE), STOP WHEN MOVED CHR=(C) ; MOVEC MOV A,M STAX D INX D INX H CMP C JNZ MOVEC RET ; ;-----> SUBROUTINE TO GET VALID LINE # ; ENGETL LDA MSGBF ORA A JNZ ENGETL2 CALL ILPRT DB 'Message is empty',CR,LF,0 XRA A ;SHOW RET ; NOT FOUND ; ENGETL2 CALL GETVAR DB 'Line#: (C/R if none)',0 DW ANSWER 02 DW 16 ;HELP MSG # DB 2 LXI H,0 ;0 => NO LINE # ENTERED LDA ANSWER CPI CR ;JUST C/R? RZ ;YES, RET. CALL GETNUM ;GET NUMBER ENTERED MOV A,H ;MUST BE 0 ORA A JNZ ENBADN MOV A,L ;1<=N<=16 ORA A JZ ENBADN CPI 17 JC ENNOK ;NUMBER IS OK ENBADN CALL ILPRT DB '++No such line #++' DB CR,LF,CR,LF,0 JMP ENGETL ; ;NUMBER IS OK - CALC IT'S ADDRESS ; ENNOK MOV C,L ;SAVE BINARY # IN C DAD H ;X2 DAD H DAD H DAD H DAD H DAD H ;X64 LXI D,MSGBF-64 ;START DAD D ;CALC LINE ADDR ;MAKE SURE IT'S AN EXISTING LINE MOV A,M ORA A ;EMPTY? JZ ENBADN RET ;FROM LINE # INPUT ; ;-----> REENTER A LINE ; ENRETYP CALL ILPRT DB 'Retype ',0 CALL ENGETL ;GET LINE # JZ ENCOMD ;NO LINE ENTERED PUSH H ;SAVE ADDR CALL ILPRT DB 'Line was:',CR,LF,0 POP H SHLD ENMAD ;SAVE FOR GETVAR CALL TYPEMCR CALL CRLF CALL GETVARN DB 'New line: (C/R to keep old)',CR,LF,0 DW ANSWER 02 DW 16 ;HELP MSG # DB 60 ;LEN LDA ANSWER CPI CR JZ ENCOMD ;MOVE LINE LHLD ENMAD XCHG LXI H,ANSWER MVI C,CR ;END DELIM CALL MOVEC JMP ENCOMD ; ENMAD DW $-$ ;MODIFIED ; ABORTM DB 'ABORT',CR ; LINK CBBSRTRV ;NEXT .ASM FILE