;DIAL.ASM V3.0 BY JEFF HAMMERSLEY ; ;CP/M - PMMI CONSOLE, STORED, AND PRESET AUTODIALING ;PROGRAM. ; ; THIS PROGRAM CONTAINS MANY FEATURES FOUND IN WARD ;CHRISTENSEN'S MODEM PROGRAM 8/6/79 AND THE ORIGINATE- ;ANSWER DEMO. PROGRAM DISTRIBUTED BY PMMI FOR THEIR ;MM103 MODEM (4/2/79). FULL CREDIT MUST BE GIVEN TO ;THESE INDIVIDUALS FOR THEIR GROUND WORK. ; ;MODIFICATION HISTORY: ; ;07/31/81 ENTERED NEW TABLE OF NUMBERS TO DIAL ; ENTERED COMMAND '?' TO PRINT TABLE. (JCG) ; ;06/23/80 CORRECTED EDITING ERRORS IN COMMENTS AND ; SET MODEM PORT NUMBERS TO PMMI STANDARD. (KBP) ; ;06/22/80 CORRECTED ERROR IN SELECTING 'A' (REQUIRES NO OFFSET) ; ALSO CLEANED UP PHONELIST, NOLONGER LEAVES 'GARBAGE' IN AREA. ; AND IT IS EASIER TO KEEP TRACK OF DATA AREA. BY HANK SZYSZKA ; ;03/08/80 RINGBACK REWRITTEN. (BY COMMITTEE DECISION, THE FANCY ; FOOTWORK PREVIOUSLY DONE TO IDENTIFY BUSY AND FAR END ; RINGING HAS BEEN REMOVED IN FAVOR OF A MORE RELIABLE, ; SIMPLE CARRIER OR TONE IDENTIFICATION). (JH) ; ;12/16/79 EXTENDED NUMBER LIST ASCII INFO. (JH) ; ;11/21/79 BASIC TIMING MODS. (JH) ; ;12/04/79 EQUATE AND LABEL FOR 20PPS DIALING (JH) ; ;09/21/79 ORIGINALLY WRITTEN BY JEFF HAMMERSLEY ; ;*********************************************************** ; EQUATES ; MCTLP EQU 0C0H ;PMMI VALUES MSNDB EQU 1 ;BIT TO TEST FOR SEND MSNDR EQU 1 ;VALUE WHEN READY MRCVB EQU 2 ;BIT TO TEST FOR RECEIVE MRCVR EQU 2 ;VALUE WHEN READY MDATP EQU 0C1H ;DATA PORT BAUDRP EQU 0C2H ;BAUD RATE OUTPUT MCTL2 EQU 0C3H ;SECOND CTL PORT ; ORIGM EQU 1DH ;8 DATA, NO PARITY, ORIG ; NUMPPS EQU 125 ;125=20PPS, 250=10PPS PULSE EQU 80H ;TIMER PULSE MASK MAKE EQU 01H ;TEL LINE MAKE (OFF HOOK) BRK EQU 00H ;TEL LINE BREAK (ON HOOK) INTER EQU 7 ;INTERDIGIT TIME CLEAR EQU 3FH ;CLEAR MODEM TO IDLE DTDET EQU 2FH ;SWITCH ON DIAL TONE DETECT DTMSK EQU 01H ;DIAL TONE MASK DTR3 EQU 07FH ;DATA TERMINAL READY (300 baud) CTSBT EQU 04H ;CLEAR TO SEND BIT BAUDRT EQU 52 ;BAUD RATE = 300 TRATE EQU 255 ;TIMER RATE = 0.1 SEC/PULSE ; ;** RINGBACK TIMING EQUATES ** ;(MAY REQUIRE OPTIMIZATION TO YOUR LOCAL OR LONG DISTANCE SITUATION) ; ;ROUTINE DIALING NATOUT EQU 200 ;# OF SEC*10 TO WAIT BEFORE GIVING NO ANSWER MESSAGE ; ;RINGBACK RBLMT EQU 70 ;# OF SEC*10 TO WAIT BEFORE GIVING NO RING HEARD MESS. RBWAIT EQU 50 ;# OF SEC*10 DELAY BEFORE REDIALING NUMBER ; ; DISCCH EQU 'D'-40H ;CTL-D DISCONNECTS MODEM RTN TO CP/M RESTAR EQU 'C'-40H ;CTL-C ABORT TO CONSOLE PHONE # ENTRY ESCTCP EQU 'E'-40H ;CTL-E RTN TO CPM WITHOUT DISCONNECT LSTCHR EQU 'P'-40H ;CTL-P TURN ON/OFF LIST DEVICE (SPEED >300 BAUD) RBKCHA EQU 'R' ;RINGBACK SEQUENCE ; TIMESH EQU 0 ;PUT 1 HERE TO PULL BIT 7 HIGH LSTDEV EQU 1 ;PUT 1 HERE IF YOU HAVE A LIST DEVICE CAPABLE ; OF SPEED >300 BAUD ; ;DEFINE ASCII CHARACTERS USED ; LF EQU 10 ;LINEFEED CR EQU 13 ;CARRIAGE RETURN BELL EQU 07 ;BELL ; ;********************************************************* ; ORG 100H ; ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=STACK FROM CP/M SHLD STACK ;..SAVE IT ; RESTRT LXI SP,STACK ;SP=MY STACK CALL START ;GO PRINT ID DB 1AH,0,0,0,0,0 ;ADM-3 SCREEN CLEAR DB 0,0,0,0,0,0 ;NULLS FOR SCREEN CLEAR DB 'DIAL PROGRAM ver 3.0' DB CR,LF,'$' ; START POP D ;GET ID MESSAGE CALL PRTMSG ;PRINT IT ; ;INITIALIZE JUMPS TO CP/M CBIOS ; CALL INITAD ; ;CHECK FOR PRIMARY OPTIONS OF EITHER X OR # LXI D,FCB+1 ;GET FIRST OPTION LDAX D CPI 'X' ;IS IT 'X' ? JZ EXAM ;YES, EXAMPLE PRINT CPI '#' ;IS IT '#' ? JZ DISCON ;YES, DISCONNECT CPI '?' ;IS IT '?' JZ PRTLST ;YES, PRINT PHONE LIST ; ;CLEAR MODEM TO IDLE MVI A,CLEAR OUT MCTL2 MVI A,BRK ;GO ON HOOK IF NOT ALREADY THERE OUT MCTLP MVI B,25 ;SET UP TIMER CALL TIMER ; ;HELP PRINT LXI D,MENU ;PRINT CTRL-CHAR. CODES CALL PRTMSG ; ;EVALUATE OPTION SELECTED ; PRIOPT: XRA A STA NFLAG ;ZERO NUMBER FLAG LXI D,FCB+1 ;GET 1ST OPTION CHAR. LDAX D ; FOUND IN FCB STA OPTION ;SAVE IT CPI 40H ;IS IT >= A JNC GTHAN ;YES (IT MAY BE A LETTER) JMP CKNUM ;NO, SEE IF A NUMBER ; GTHAN CPI 5BH ;IF <= Z THEN IT IS A LETTER JC LETTER JMP CKNUM ;SEE IF IT IS ANOTHER CHAR. > Z ; LETTER CALL ORIGMD ;GO OFF HOOK, IDENT. DIAL TONE LXI H,00 ;LOAD H-L RESET TO ZERO LDA OPTION ;GET OPTION CHAR. CPI 'A' ;IS IT AN 'A' (NO OFFSET REQ) JZ NOFFS ;YES, THE BYPASS OFFSET. LXI D,30 ;SET D-E TO OFFSET VALUE SUI 41H ;SUBTRACT 41H FROM LETTER TO GET # ; OF 30 BYTE BLOCKS TO SKIP MOV B,A ;MOVE TO B ; LOOP DAD D ;ADD OFFSET DCR B JNZ LOOP ;ADD APPROPRIATE # UNTIL DONE ; NOFFS LXI D,NUMLST ;GET PHONE NUMBER LIST ORIGIN DAD D ;ADD TO OFFSET IN H-L XCHG ;MOVE RESULT TO D-E JMP PROCS ;READ AND DIAL PRESET NUMBER ; CKNUM CALL ORIGMD ;GO OFF HOOK, IDENT. DIAL TONE LXI H,NUMBR ;LOAD H-L WITH LOCATION OF CURRENT # BUFF SHLD NBP ;SAVE IN BUFF POINTER LDA FCB+1 ;GET FIRST CHARACTER AGAIN LXI D,DBUF+2 ; CKNM CPI 'R' ;IS IT RINGBACK? JZ RINGBK ;YES CPI 2FH ;IF CHAR. >='0' JNC GT0 ;YES CPI ' ' ;IS IT A SPACE? JZ QDONE ;YES, CK IF DONE OR CONSOLE ENTRY ORA A ;IS IT BINARY 0? (END OF DBUF) JZ QDONE ;YES, DONE CPI '-' ;IS IT DASH? JZ IGN ;IGNORE JMP BDCHR ;NO, MUST BE A BAD CHAR. ; GT0 CPI 3AH ;IS IT <= 9 ? JC NUM ;YES JMP BDCHR ;MUST BE A BAD CHAR. ; NUM CALL TYPE ;PRINT DIGIT CALL DIAL ;DIAL THE DIGIT MVI A,0FFH ; FLIP NUMBER FLAG (NOTES IF ANY # DIALED) STA NFLAG ; ; IGNRE INX D ;GET ANOTHER CHAR. FROM DBUF LDAX D ; JMP CKNM ;IF FIRST CHARACTER IS A NUMBER ASSUME THAT THE REST ;ARE AND SO GO GET ANOTHER. IGN CALL TYPE ;PRINT '-' JMP IGNRE ; QDONE LDA NFLAG ;IS THIS THE FIRST CHAR. POSITION? ORA A ; IF SO, AND IT IS A BLANK, ASSUME JZ CNSLE ; THAT WE WANT CONSOLE INPUT JMP DIALE ;NO, IT ISN'T- SO STORE AN EOF CHAR. IN ; CURRENT NUMBER BUFFER ;DIALING ENDED WAIT FOR ANSWER ; CNSLE: LXI D,PMESS ;ENTER PHONE NUMBER MESSAGE CALL PRTMSG MVI D,255 ;25 SECONDS - TOTAL DIALING TIME ALLOWED ; CNSL1 CALL STAT ;CHAR. ENTERED? JNZ CNSL2 ;YES ; ;ALLOW ONLY 255 TIME ELEMENTS TO DIAL MVI B,1 CALL TIMER DCR D JZ HEXIT ;ABORT- TAKING TOO LONG TO DIAL JMP CNSL1 ; CNSL2 CALL KEYIN ; GET IT CALL SPECL ;ABORT?, REDIAL? etc. CALL TYPE ; PRINT IT ON TERMINAL CPI 2FH ; >=0 ? JNC NM0 ;YES CPI ' ' ;IGNORE SPACES JZ CNSL1 ; CPI '-' ;IGNORE DASHES JZ CNSL1 ; CPI CR ;IF 'CR', THEN END OF NUMBER JZ NEND ; JMP BDCHR ;MUST BE A BAD CHAR. ; NEND CALL CRLF ;PRINT A CRLF JMP DIALE ;END OF DIALING ; NM0 CPI 3AH ; <= 9 ? JC CSLE ;FOUND A NUM. 0-9 CPI 'R' ;RINGBACK MODE JZ RINGBK ; JMP BDCHR ;MUST BE A BAD CHAR. ; CSLE CALL DIAL ;DIAL DIGIT JMP CNSL1 ;GET ANOTHER ; ; DIAL STORED NUMBER REFERENCED BY D-E, THEN ; PRINT TRAILING INFO. PROCS: XRA A ;ZERO ACC. STA PFLAG ;ZERO PRINT FLAG LXI H,NUMBR ;GET NUM BUFF START SHLD NBP ;SAVE IN POINTER ; PRCS1 LDA PFLAG ;IS PRINT FLAG ON ?(=FFH) CPI 0FFH LDAX D ;LOAD ACC WITH 1ST CHARACTER REF. BY D-E JZ INCR ;IF PFLAG ON THEN PRINT ONLY CPI '*' ;EMPTY NUMBER SLOT JZ NONUM CPI ' ' ;BLANK? JZ INCR ;PRINT AND ADVANCE CPI '-' ;DASH? JZ INCR ;PRINT AND ADVANCE CPI '"' ;REST TO BE PRINT ONLY? JZ PSET ;YES CPI 2FH ; >=0 JNC GTH ;YES CPI '$' ;EOF ? JZ DIALE ;END OF DIALING JMP BDCHR ;MUST BE A BAD CHAR. ; DIGIT CALL TYPE ;PRINT DIGIT CALL DIAL ;DIAL IT JMP INCR1 ; GTH CPI 3AH ;<=9 ? JC DIGIT ;DIAL THE NUMBER DCX D ;ADJUST POINTER TO 1 LESS ; THAN LOC. OF 'R' CPI 'R' ;RINGBACK? JZ RBPRT ;YES JMP BDCHR ;BAD CHARACTER ; RBPRT INX D ;RINGBACK PRINT SEQ. LDAX D ;GET CHAR. CPI '"' ;NON-PRINTING JZ RBPRT CPI '$' ;END? JZ RBPR1 ;YES CALL TYPE ;PRINT IT JMP RBPRT ;GET ANOTHER ; RBPR1 MVI A,LF ; CALL TYPE JMP RINGBK ;TO RINGBACK ROUTINE ; INCR CPI '$' ;EOF CHAR.? JZ DIALE ;DIALEND CALL TYPE ; INCR1 INX D JMP PRCS1 ; NONUM LXI D,NMESS ;NO NUMBER LISTED MESSAGE CALL PRTMSG JMP HEXIT ; PSET MVI A,0FFH ;LOAD PRINT ONLY FLAG STA PFLAG JMP INCR1 ;GET NEXT CHAR.(DON'T PRINT ") ; ; GO TO ORIGINATE MODE AND IDENTIFY THE DIAL TONE ;*********************************************************** ; ORIGMD: MVI A,MAKE ;GO OFF HOOK IN ORGINATE MODE OUT MCTLP ; MVI A,DTDET ;SWITCH IN DIAL TONE DETECT FILTERS OUT MCTL2 ; WAIT FOR DIAL TONE (TIME OUT) MVI D,DTMSK ;LOAD MASK FOR DIAL TONE PRESENCE CALL WAT15 LXI D,DMESS ;DIAL TONE DETECTED MESSAGE CALL PRTMSG ;PRINT ROUTINE RET ; ; AUTO-DIAL ROUTINE ;********************************************************* ; DIAL ANI 0FH ;CONVERT TO BINARY LHLD NBP ;GET BUFF POINTER MOV M,A ;SAVE DIGIT IN BUFF INX H ;INCRE. BUFF POINTER SHLD NBP ;SAVE BUFF. POINTER ; DIALR CPI 0 ;IF 0 CONVERT TO 10 JNZ DIALS MVI A,10 ; DIALS MOV C,A ;LOAD C WITH # MVI A,NUMPPS ;SET UP TIMER PULSE RATE OUT BAUDRP ; DIALC IN BAUDRP ;WAIT IF TIMER PULSE NOT = 0 ANI PULSE JNZ DIALC ; DIALB IN BAUDRP ;WAIT UNTIL TRANSITION TO 1 FOR SYNC ANI PULSE JZ DIALB ; MKPLSE MVI A,MAKE ;START WITH A MAKE OUT MCTLP ; TIMEM IN BAUDRP ;WAIT FOR MAKE INTERVAL TO END ANI PULSE JNZ TIMEM MVI A,BRK ;BREAK OUT MCTLP ; TIMEB IN BAUDRP ;WAIT FOR BREAK PULSE INTERVAL ANI PULSE JZ TIMEB DCR C ;MORE PULSES FOR THIS DIGIT? JNZ MKPLSE ;YES ; LAST PULSE WAIT FOR INTERDIGIT TIME MVI A,MAKE OUT MCTLP MVI A,NUMPPS MVI B,INTER ;INTERDIGIT INTERVAL = 7 GEN. CALL TIMER2 RET ; BUSY: LXI D,BMESS ;PHONE BUSY MESSAGE CALL PRTMSG LXI D,NAMES2 JMP ABORT2 ; DIALE: MVI A,'$' ;PUT INTO CURRENT NUMBER BUFF. LHLD NBP ;GET BUFF POINTER MOV M,A ;SAVE EOF CHAR. ; DTRON: CALL CRLF ;PRINT A CRLF MVI A,DTR3 ;TURN ON DTR AT APPROPRIATE BAUD RATE OUT MCTL2 MVI B,1 ;WAIT FOR MODEM TO TURN ON DTR CALL TIMER ;SET UP UART MVI A,ORIGM ;8bits, No parity, orig OUT MCTLP ; ;WAIT FOR CLEAR TO SEND OR RINGTONE MVI C,NATOUT ;SET FOR X SEC MVI D,CTSBT ;CARRRIER MASK BIT ; DZ1 MVI B,1 ;SET TIMER FOR 0.1 SEC CALL TIMER IN BAUDRP ;GET STATUS STA MSTAT ;SAVE STATUS ANA D ;CARRIER ? JZ CARRIER ;YES CALL STAT ;KEYBOARD INPUT? JZ DZZ ;NO CALL KEYIN ;YES,GET IT CALL SPECL ;ABORT CHAR.? ; DZZ DCR C ;GET NEXT INTERVAL JNZ DZ1 ; JMP ABORT ;TIME EXPIRED, NO ANSWER ; OR BUSY ; CARRIER: CALL WAT15 ;ALLOW 15 SECONDS FOR CTS IN MDATP ;CLEAR OUT DATA GARBAGE ;PRINT CARRIER RECEIVED MESSAGE LXI D,CMESS CALL PRTMSG ; ;SET BAUD RATE (USUALLY 300) MVI A,BAUDRT OUT BAUDRP ; ;********************************************************** ; MAIN COMMUNICATION SECTION ;********************************************************** ; TERM CALL LOSS ;CK FOR CARRIER LOSS CALL STAT ;LOCAL CHAR KEYED? JZ TERML ;..NO, CHECK LINE CALL KEYIN ;GET CHAR CPI ESCTCP ;TIME TO END? JZ NDIS ;YES, NO DISCON CPI DISCCH ;DISCONNECT REQUEST? JZ DISCON ;YES, DO IT CPI LSTCHR ;PRINT ON LIST DEVICE ? JNZ NCHG ;NO CHANGE, CONTINUE LDA LFLAG ;YES, FLIP FLAG CMA STA LFLAG ; & SAVE IT XRA A ;CLEAR ACCUM. ; NCHG: IF TIMESH ORI 80H ;FORCE BIT 7 TO HIGH ENDIF ;TIMESH ; OUT MDATP ;SEND THE CHAR ; ;SEE IF CHAR FROM LINE ; TERML IN MCTLP ;READ STATUS ANI MRCVB ;ISOLATE BIT CPI MRCVR ;READY? JNZ TERM ;..NO, LOOP IN MDATP ;READ DATA CALL TYPE ;TYPE IT ; IF LSTDEV CALL LIST ;IF LIST DEVICE PRESENT (SPEED >300 BAUD) ENDIF ; JMP TERM ;LOOP ; ;----> DISCON: DISCONNECT THE PHONE ; DISCON XRA A ;GET DISCON VALUE OUT MCTLP ;RESET ORIG/ANSW OUT MCTL2 ;TURN OFF DTR, DO BREAK CALL ILPRT ;PRINT: DB CR,LF,'++ DISCONNECTED ++',CR,LF,0 JMP EXIT ; ;NO DISCONNECT, TYPE MSG AS REMINDER THAT PHONE'S ;OFF HOOK ; NDIS CALL ILPRT DB CR,LF,'++ DON''T FORGET - THE MODEM IS ' DB 'NOT DISCONNECTED ++',CR,LF DB 'Use "DIAL #" to Disconnect',CR,LF,0 JMP EXIT ; ;********************************************************* ; LOSS IN BAUDRP ANI CTSBT ;MASK FOR CARRIER LOSS RZ ;STILL PRESENT LXI D,CLMES ;TYPE CARRIER LOST MESSAGE CALL PRTMSG JMP HEXIT ;GO TO ABORT ; HANGP: XRA A ;GET DISCONNECT VALUE OUT MCTL2 ;TURN OFF DTR, DO BREAK OUT MCTLP ;GO ON HOOK RET ; ABORT: LXI D,NAMES ;NO ANSWER MESSAGE ; DO YOU WISH TO REDIAL? ; ABORT2 CALL HANGP MVI B,25 ;LOAD TIMER CALL TIMER ; WITH LONG PAUSE CALL PRTMSG ;PRINT THE MSG CALL KEYIN ;GET REPLY CALL TYPE CPI 'D' ;WAS A 'D' HIT? JZ REDIAL ;YES JMP EXIT ;NO,GO TO CP/M ; SPECL CPI ESCTCP ;CTL-E JMP TO CPM JZ EXIT CPI DISCCH ;CTL-D DISCONNECT,TO CPM JZ HEXIT CPI RESTAR ;CTL-C ABORT,RESTAR JZ RESTRT CPI RBKCHA ;IF R JZ RINGBK ;SET UP RINGBACK SEQUENCE CPI LSTCHR ;CTL-P CONCURRENT LIST (DEVICE SPEED >300 BAUD) RNZ ;RETURN, NO SPECIAL CHARACTER IDENTIFIED LDA LFLAG CMA ;UPDATE LIST FLAG STA LFLAG RET ; RINGBK: MVI A,'$' ;PUT INTO CURRENT # BUFFER LHLD NBP ;GET BUFF POINTER MOV M,A ;SAVE EOF CHAR. MVI D,DTMSK ;LOAD IN TONE DETECT MASK MVI C,RBLMT ;SET TIMER FOR RBLIMIT # OF SEC. CALL RBTIME ; ABORTS IF IT TAKES LONGER MVI B,25 ;WAIT 2.5 SEC CALL TIMER ; IN BAUDRP ;IS TONE STILL PRESENT ? ANA D ; JNZ RNGBK1 ; JMP BUSY ;YES, MUST BE BUSY ; RNGBK1 CALL HANGP ;HANGUP PHONE MVI B,RBWAIT ;WAIT X SEC. CALL TIMER ; JMP REDIAL ;REDIAL NUMBER ; RBTIME: MVI B,1 ; 0.1SEC TIME OUT CALL TIMER IN BAUDRP ;GET STATUS ANA D ;IS TONE PRESENT ? RZ ;YES DCR C ;GET NEXT 0.1 SEC INTERVAL JNZ RBTIME LXI D,RBMES ;NO TONE IDENTIFIED IN TIME LIMIT CALL PRTMSG ; BUT WILL CONTINUE POP D ;GET RID OF SUBROUTINE RETURN JMP RNGBK1 ;HANGUP, REDIAL, & LISTEN FOR CARRIER ; REDIAL: CALL CRLF ;PRINT A CRLF CALL ORIGMD ;LOOK FOR DIAL TONE LXI H,NUMBR ;GET START OF 'LAST' NUMBER BUFF. ; RDIAL MOV A,M ;GET DIGIT CPI '$' ;EOF CHAR. ? JZ DTRON ;DONE DIALING ADI '0' ;MAKE IT PRINTABLE CALL TYPE MOV A,M ;GET DIGIT AGAIN CALL DIALR ;DIAL DIGIT INX H ;NEXT ONE JMP RDIAL ; ; SUBROUTINE- TIMER ; reg B = # time periods to count ;*********************************************************** ; TIMER MVI A,TRATE ;RESET TO .1 SEC ; TIMER2 OUT BAUDRP ; TIMES IN BAUDRP ;CK TO SEE IF TIMER BIT IS LOW ANI PULSE JNZ TIMES ; TIMEE IN BAUDRP ;CK TO SEE IF BIT IS HIGH ANI PULSE JZ TIMEE DCR B ;ONE PERIOD DONE JNZ TIMES RET ;TOTAL TIME EXPIRED ; ; ; DIALING ENDED: CARRIER DETECT ROUTINES ;******************************************************************** ; ; TIME OUT ROUTINE (CK OF BITS vs MASK IN D ) ; WAT15: MVI C,150 ;TIMER SET FOR 15 SEC. INTERVALS ; T15 MVI B,1 ; .1 SEC TIMEOUT CALL TIMER ;TIMER WAITS .1 SEC IN BAUDRP ;TEST STATUS ANA D ;MASK WITH TEST BIT IN D RZ ;RETURN IF OFF CALL STAT JZ TS15 ;WAIT FOR INPUT CALL KEYIN CALL SPECL ;CK FOR ABORT ; TS15 DCR C ;GET NEXT .1 SEC INTERVAL JNZ T15 JMP ABORT ; ;----> INITAD: INIT'S CP/M CBIOS ADDRESSES ; ;THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS ;JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS ;IS BYPASSED WHILE ACCESSING THE CONSOLE. THIS ;IS DONE TO ALLOW CHARACTERS SUCH AS CONTROL-C ;AND CONTROL-S TO BE KEYED WHILE IN TERMINAL ;MODE, WITHOUT CP/M INTERPRETING THEM. ; INITAD LHLD 1 ;GET WARM BOOT ADDR LXI D,3 ;LENGTH OF A 'JMP' DAD D ;TO CONSOLE STAT SHLD VSTAT+1 ;MODIFY CALL DAD D ;TO CONSOLE IN SHLD VKEYIN+1 ;MODIFY CALL DAD D ;TO CONSOLE OUT SHLD VTYPE+1 ;MODIFY CALL IF LSTDEV DAD D ;TO LIST DEVICE SHLD VLIST+1 ;MODIFY CALL ENDIF RET ; CRLF MVI A,CR CALL TYPE MVI A,LF ;FALL INTO TYPE ; ;----> TYPE: TYPE VIA DIRECT CBIOS ACCESS ;WE ASSUME CBIOS MAY DESTROY SOME REGISTERS, ;SO SAVE THEM ALL. ; ;THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C ;TESTS. ; TYPE PUSH PSW ;SAVE CHAR PUSH B ;AND OTHER REGISTERS PUSH D PUSH H MOV C,A ;FOR BIOS VTYPE CALL $-$ ;ADDR SET AT INIT POP H ;RESTORE REGISTERS POP D POP B POP PSW ;..AND CHAR RET ;FROM "TYPE" ; ;PRINT ON LIST DEVICE ROUTINE IF LSTDEV ;IF LIST DEVICE IS PRESENT >300 BAUD LIST MOV C,A ;SAVE CHAR. LDA LFLAG ;GET LIST FLAG ORA A RZ ;RETURN IF OFF PUSH PSW ;SAVE CHAR. PUSH B ;AND OTHER REGISTERS PUSH D PUSH H VLIST CALL $-$ ;ADDR SET AT INIT POP H ;RESTORE REGISTERS POP D POP B POP PSW ;..AND CHAR RET ;FROM "LIST" ENDIF ; ;----> STAT: KEYBOARD STATUS ; ;SAVE ALL REGISTERS, EXCEPT A, IN CASE ;CBIOS CLOBBERS THEM. ; STAT PUSH B PUSH D PUSH H VSTAT CALL $-$ ;ADDR SET AT INIT POP H POP D POP B ORA A ;0 => NOT READY RET ; ;----> KEYIN: KEYBOARD INPUT ; ;SAVE ALL REGISTERS, EXCEPT A, IN CASE ;CBIOS CLOBBERS THEM. ; KEYIN PUSH B PUSH D PUSH H VKEYIN CALL $-$ ;ADDR SET AT INIT POP H POP D POP B ANI 7FH ;STRIP PARITY IF THERE RET ;FROM KEYIN ; ;----> ILPRT: INLINE PRINT OF MSG ; ;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE, ;BINARY 0 AS THE END. BINARY 1 MAY BE USED TO ;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE') ; ILPRT XTHL ;SAVE HL, GET HL=MSG ; ILPLP MOV A,M ;GET CHAR ORA A ;END OF MSG? JZ ILPRET ;..YES, RETURN CPI 1 ;PAUSE? JZ ILPAUS ;..YES CALL TYPE ;TYPE THE MSG ; ILPNEX INX H ;TO NEXT CHAR JMP ILPLP ;LOOP ; ;PAUSE WHILE TYPING HELP SO INFO DOESN'T ;SCROLL OFF OF VIDEO SCREENS ILPAUS CALL ILPRT ;PRINT: DB CR,LF,'PRESS RETURN TO CONTINUE' DB CR,LF,0 CALL KEYIN ;GET ANY CHAR CPI 'C'-40H ;REBOOT? JZ EXIT ;YES. JMP ILPNEX ;LOOP ; ILPRET XTHL ;RESTORE HL RET ;PAST MSG ; ;----> PRTLST: PRINTS THE PHONE LIST & GETS INPUT ; PRTLST PUSH D ;STORE REGISTERS PUSH H MVI D,0 ;STORE SKIP INCR IN D-E MVI E,31 LXI H,NUMLST;1ST CHAR OF PHONE LIST ; ; Move past phone number or skip * entry ; PRTLP1 MOV A,M ;GET CHAR FROM PHONE LIST INX H ;BUMP H-L BEFORE CHECKING CPI '@' ;IS IT EO LIST JZ PLSTX ;YES, GO TO END CPI '*' ;IS IT A BLANK JZ PRTSKP ;YES, SKIP TO NEXT LINE CPI '"' ;IS IT EO NUM JNZ PRTLP1 ;NO, GET ANOTHER CHAR ; ; Print Rest of line ; PRTLP2 MOV A,M ;GET A CHAR (BUMPED ALREADY) CPI '$' ;IS IT EO LINE JZ PRTEOL ;YES, BYPASS LAST CHAR. CALL TYPE ;PRINT IT OUT INX H JMP PRTLP2 ;GET ANOTHER CHAR. ; PRTEOL INX H ;GET READY FOR ANOTHER CHAR CALL CRLF ;EO LINE JMP PRTLP1 ;NO, GET ANOTHER LINE ; ; Handle End of List ; PLSTX: POP H ;RESTORE REGS POP D CALL ILPRT ;PRINT THIS MESSAGE DB 'Type the letter before name ',0 CALL KEYIN ;GET INPUT STA OPTION ;STORE AS FROM FCB+1 CALL CRLF ;MAKE IT NEAT JMP LETTER ;DIAL BASED ON KEYIN ; ; Skip unused line ; PRTSKP DAD D ;ADD NEXT LINE INCR JMP PRTLP1 ;GO FOR ANOTHER LINE ; ;----> PRTMSG: PRINTS MSG POINTED TO BY (DE) ; ;A '$' IS THE ENDING DELIMITER FOR THE PRINT. ;NO REGISTERS SAVED. ; PRTMSG MVI C,PRINT ;GET BDOS FNC JMP BDOS ;PRINT MESSAGE, RETURN ; HEXIT CALL HANGP ;DISCONNECT ; EXIT LHLD STACK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- TO CP/M (WARM BOOT) ; BDCHR CALL TYPE ;PRINT CHAR. CALL HANGP ;DISCONNECT CALL ILPRT ;PRINT EXIT MESSAGE DB ' :INVALID CHARACTER',CR,LF DB 'Press Return for Help, Ctrl-c if not.',cr,lf,1,0 ; EXAM MVI B,1 ;WAIT CALL TIMER CALL ILPRT DB cr,lf DB 'Commands:',cr,lf,cr,lf DB ' DIAL ',cr,lf DB ' if phone number is to be input from console',cr,lf,cr,lf DB ' DIAL ?',cr,lf DB ' for a phone listing from which you can choose',cr,lf,cr,lf DB ' DIAL 756-5553',cr,lf DB ' if the trailing number is to be dialed (spaces and',cr,lf DB ' dashes are ignored)',cr,lf,cr,lf DB ' DIAL C',cr,lf DB ' if one of 25 preset numbers is to be dialed (preset',cr,lf DB ' at time of assembly)',cr,lf,cr,lf DB ' An R which follows any number indicates that it is',cr,lf DB ' to be dialed as a ringback sequence.' DB '(One ring then dial back)',cr,lf DB ' (For preset numbers this must be entered before assembly)' DB cr,lf,cr,lf,0 JMP EXIT ; MENU: DB ' NOTE',cr,lf DB ' ======',cr,lf DB ' ctrl- D causes a disconnect and return to CP/M',cr,lf DB ' ctrl- E causes a return to CP/M without a disconnect',cr,lf DB ' ctrl- C aborts current dialing and restarts program',cr,lf IF LSTDEV DB ' ctrl- P turns list device on and off',cr,lf ENDIF DB cr,lf,cr,lf,'$' ; ; NUMLST: ; Phone Number list (capacity 25 numbers) ;Format '############"acaaaaaaaaaaaaaa$' ;CAUTION: ^----from here to here-------^ ; **MUST NOT EXCEED 30 CHARACTERS** ; (the actual # of #'s or a's doesn't matter if <30) ; ; where # = a digit, space or dash ; " = separator between number and info ; a = ascii info ; c = a char corresponding to the second ; char of tag. It should follow the " ; by one space since it prints with ; the name ; $ = eof ; * = no number character ; NA DB '304-555-1212" A:L.A. INFO $' NB DB '* $' NC DB '* $' ND DB '* $' NE DB '* $' NF DB '* $' NG DB '4517840" G:GILBERTS, THE $' NH DB '* $' NI DB '* $' NJ DB '* $' NK DB '* $' NL DB '936-1212" L:WEATHER $' NM DB '* $' NN DB '* $' NO DB '* $' NP DB '* $' NQ DB '3135887054" Q:PETERSEN, K $' NR DB '* $' NS DB '* $' NT DB '* $' NU DB '* $' NV DB '844-2525" V:LOCAL TIME $' ; The following exceed a 24 line display ; if all preceding entries are full NW DB '* $' NX DB '* $' NY DB '* $' NZ DB '* $' ; The following is the list terminator DB '@' ; DMESS DB 'Phone is off cradle ',cr,lf,'$' CMESS DB 'DATA CARRIER Received',cr,lf,bell,'$' BMESS DB bell,cr,lf,'BUSY Signal',bell,cr,lf,'$' RBMES DB bell,lf,'No Ringing Tone Detected',cr,lf,'$' NAMES DB 'NO ANSWER',cr,lf NAMES2 DB ' If you wish to redial PRESS D',cr,lf DB '$' CLMES DB cr,lf,'DATA CARRIER LOST',cr,lf,bell,'$' NMESS DB 'NO NUMBER STORED',cr,lf,'$' PMESS DB 'ENTER PHONE # (terminate with RETURN ) ',cr,lf,'$' ; ; NUMBR DB '$$$$$$$$$$$$$$$$' ;16 DIGIT BUFFER ; PFLAG DB 0 ;PRINT FLAG NFLAG DB 0 LFLAG DB 0 ;LIST FLAG MSTAT DB 0 ;MODEM STATUS OPTION DB 0 NBP DS 2 ;NUM BUFF POINTER DS 60 ;STACK AREA STACK DS 2 ;STACK POINTER ; ; BDOS EQUATES ; PRINT EQU 9 ;PRINT ROUTINE BDOS EQU 5 FCB EQU 5CH ;SYSTEM FCB DBUF EQU 80H ;CP/M DEFAULT BUFFER ; END