ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееAPMOD777ASMЂ APMOD777ASMЂ !APMOD777ASMЂ"#$%&'()*+,-./01APMOD777ASMЂ23456789:;<=>?@AAPMOD777ASMKBCDEFGHIJKеAPMOD777BAKlLMNOPQRSTUVWXYMODEM LIBjZ[\]^_`abcdefgAPMOD777HISnhijklmnopqrstuAUD EQU 'R'-40H ;CHANGE BAUD RATE ON FLY EXITCHR EQU '\'-40H ; ^\ = EXIT WITHOUT DISCONNECT SAVECHR EQU 'W'-40H ; ^W = SAVE FILE CHARACTER SAVSGN EQU '|' ;PRINT ON LINES OF SAVEFILE DISCCHR EQU 'L'-40H ; ^L = DISCONNECT ; ENDIF ;modo; ; Code starts... ; ;---------------------------------------------------------------------------- ; MACLIB MODEM ;CONTAINS CMDLINE, INBUF, INLNCOMP, ;DIR, AND MFACCESS ROUTINES ; TRUE EQU 0FFH FALSE EQU 0 ; DBUFSIZ EQU 16 ;BUFFER SIZE INееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееCARDS SUPRSER EQU TRUE ;SET TRUE FOR APPLE SUPER SERIAL CARD FOURMHZ EQU FALSE ;SET TRUE FOR 4 MHZ SIXMHZ EQU TRUE ;SET TRUE FOR 6 MHZ ; IF NOT MODOUT ; MSLT EQU 2 ;PRIMARY MODEM SLOT CHGBAUD EQU 'P'-40H ;CHANGE BAUD RATE ON THE FLY. EXITCHееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееICATED ; THIS IS USED IN DELAYS SO THAT THEY RUN PROPERLY. ; ; EITHER DCHAYESMM, COMCARD, OR SUPRSER SHOULD BE TRUE BUT NOT BOTH ; SET EITHER COMCARD OR SUPRSER TO TRUE IF YOU HAVE AN EXTERNAL MODEM ; SUCH AS A D-CAT CONNECTED WITH A SERIAL CARD. ; KBYTES MODOUT EQU FALSE ;SET FALSE FOR NORMAL MODEM USE SELMODE EQU FALSE ;SET FALSE FOR NOT SELECT MODE (PARITY ETC) ; ;EITHER MICROSOFT OR APPLI-CARD SHOULD BE TRUE BUT NOT BOTH ; IF YOU HAVE A APPLI-CARD THEN YOUR PROCESSOR SPEED SHOULD BE INDееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееR EQU 'E'-40H ; ^E = EXIT WITHOUT DISCONNECT SAVECHR EQU 'Y'-40H ; ^Y = SAVE CHARACTER SAVSGN EQU ':' ;PRINT ON LINES OF SAVEFILE DISCCHR EQU 'D'-40H ; ^D = DISCONNECT ; ENDIF ;not modout ; IF MODOUT ; MSLT EQU 5 ;SECONDARY MODEM SLOT CHGB; ; APMOD777.ASM ; ; Last update 2/8/83 ; ; NOTE: All comments and revision messages have been moved to ; APMOD777.HIS ; ; ;---------------------------------------------------------------------------- ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееSET DCHAYESMM TO TRUE IF YOU HAVE A DC HAYES MICRO MODEM MICROSOFT EQU FALSE ;SET TRUE FOR MICRO SOFT VERSION APPLICARD EQU TRUE ;SET TRUE FOR APPLICARD VERSION DCHAYESMM EQU FALSE ;SET TRUE FOR DCHAYES COMCARD EQU FALSE ;SET TRUE FOR COMMUNICATIONS ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееut ; IF MICROSOFT IF COMCARD PORT EQU 0E08EH+(MSLT*10H) ;MODEM BASE PORT ADDRESS ENDIF IF DCHAYESMM PORT EQU 0E086H+(MSLT*10H) ;MODEM BASE PORT ADDRESS ENDIF IF SUPRSER PORT EQU 0E088H+(MSLT*10H) ;SUPER SERIAL CARD 6551 PORT T ;value of send bit when ready IN$MODDATP lda MODDATP ! RET ;in modem data port ANI$MODRCVB ANI MODRCVB ! RET ;bit to test for receive ready CPI$MODRCVR CPI MODRCVR ! RET ;value of receive bit when ready JMP$INITMOD JMP INITMOD ;to initialize port, i7 ; COMMAND TO POKE 1 BYTE IN THE APPLE ; ENDIF ; WAITCTS EQU 180 ;(255max) number of seconds X .20 to wait for computer ;tone after auto-dial function, 255 MAX. ; ERRLIM EQU 10 ;NUMBER OF TIMES TO RETRY ;SEND/RECEIVE ERRORS BEFORE QUIT BR MODDATP EQU PORT+0 ;MODEM DATA PORT MODCTL2 EQU PORT+2 ;2ND MODEM CONTROL PORT BAUDRP EQU PORT+3 ;BAUD RATE PORT ORIGMOD EQU 8eH ;ORIGINATE MODE ANSWMOD EQU 8aH ;ANSWER MODE ; BRKBYT EQU 60H ;VALUE USED TO SIMULATE BREAK FRMER EQU 2H ;FRA A MONITOR WITHOUT RE-ASSEMBLING ;THE PROGRAM. ; BAKUPBYTE: DB FALSE ;true=make .BAK file XPRFLG: DB false ;true=no menu, false=print menu SAVCCP: DB TRUE ;true=do not overwrite CCP CRFLAG: DB 0 ;CONTINUOUS REDIAL FLAG ; IF MICROSOFT ; FASTITY ERROR MASK ERRCDMSK EQU 70H ;MASK FOR ALL BITS EXCEPT ERROR CODES ; ENDIF IF APPLICARD RDBYTE EQU 0FFE0H ;READ A BYTE FROM APPLE (A = BYTE) WRBYTE EQU 0FFE3H ;WRITE A BYTE TO APPLE (C = BYTE) RDWORD EQU 0FFE6H ;READ 2 BYTES FROM APPLE (DE = ENDIF ENDIF IF APPLICARD IF COMCARD PORT EQU 0C08EH+(MSLT*10H) ;MODEM BASE PORT ADDRESS ENDIF IF DCHAYESMM PORT EQU 0C086H+(MSLT*10H) ;MODEM BASE PORT ADDRESS ENDIF IF SUPRSER PORT EQU 0C088H+(MSLT*10H) ;SUPER SERIAL CARCTER EXTCHR EQU '^'-40H ; ^^ = SEND NXT CHR SOH EQU 1 ; START OF HEADER EOT EQU 4 ; END OF TEXT ACK EQU 6 ; ACKNOWLEDGE NAK EQU 15H ; NOT ACKNOWLEDGE CRC EQU 'C' ;USED TO RQST CRC INSTEAD OF CKSUM BDNMCH EQU 75H ; BAD NAME MATCH OKNMCH EQU ACKCHR EQU 'B'-40H ; ^B = TRANSMIT "BREAK" WITH MM ][ TRANCHR EQU 'T'-40H ; ^T = TRANSFER CHARACTER CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE EOFCHAR EQU 'Z'-40H ; ^Z = END OF FILE XOFF EQU 'S'-40H ; ^S = XOFF CHARACTER XON EQU 'Q'-40H ; ^Q = XON CHARAMING ERROR MASK, (DISABLE FRAMMING ERROR) ORUNER EQU 4H ;OVERRUN ERROR MASK PARER EQU 1H ;PARITY ERROR MASK ERRCDMSK EQU 7H ;MASK FOR ALL BITS EXCEPT ERROR CODES ; ENDIF IF DCHAYESMM + COMCARD ; ; Hayes MM][ equates ; MODCTLP EQU PORT ;MCLK: DB FALSE ;4 MHz or plus NOTE: 4meg+ cards ARE availible IN$MODCTLP lda MODCTLP ! RET ;in modem control port OUT$MODDATP sta MODDATP ! RET ;out modem data port ANI$MODSNDB ANI MODSNDB ! RET ;bit to test for send ready CPI$MODSNDR CPI MODSNDR ! REBYTES) WRWORD EQU 0FFE9H ;WRITE 2 BYTES TO APPLE (DE = BYTES) RDNBYTS EQU 0FFECH ;READ N BYTES (DE = COUNT, HL = BUFFER) WRNBYTS EQU 0FFEFH ;WRITE N BYTES (DE = COUNT, HL = BUFFER) PEEK1BYTE EQU 6 ; COMMAND TO PEEK 1 BYTE IN THE APPLE POKE1BYTE EQU D 6551 PORT ENDIF ENDIF IF SUPRSER MODCTLP EQU PORT+1 ;MODEM CONTROL PORT MODSNDB EQU 10H ;MODEM SEND BIT (XMIT BUFF EMPTY) MODSNDR EQU 10H ;MODEM SEND READY MODRCVB EQU 8 ;MODEM RECEIVE BIT (DAV) MODRCVR EQU 8 ;MODEM RECEIVE READYK ; OKAY NAME MATCH LF EQU 10 ; LINEFEED CR EQU 13 ;CARRIAGE RETURN BELL EQU 7 ; BELL CHARACTER ; BOTTRAM SET LAST+100H AND 0FF00H ; ORG 100H ; ; JMP START ; ;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO ;THEY CAN BE PATCHED BYCONTROL PORT BAUDRP EQU MODCTL2 ;BAUD RATE PORT ORIGMOD EQU 8eH ;ORIGINATE MODE ANSWMOD EQU 8aH ;ANSWER MODE ; BRKBYT EQU 60H ;VALUE USED TO SIMULATE BREAK FRMER EQU 10H ;FRAMING ERROR MASK ORUNER EQU 20H ;OVERRUN ERROR MASK PARER EQU 40H ;PARODEM CONTROL PORT MODSNDB EQU 2 ;MODEM SEND BIT (XMIT BUFF EMPTY) MODSNDR EQU 2 ;MODEM SEND READY MODRCVB EQU 1 ;MODEM RECEIVE BIT (DAV) MODRCVR EQU 1 ;MODEM RECEIVE READY MODDATP EQU PORT+1 ;MODEM DATA PORT MODCTL2 EQU PORT-1 ;2ND MODEM f necessary OUT$MODCTLP sta MODCTLP ! RET ;out modem control port IN$BAUDRP lda BAUDRP ! RET ;in baudrate port OUT$BAUDRP sta BAUDRP ! RET ;out baudrate port OUT$MODCTL2 sta MODCTL2 ! RET ;out modem control port #2 ; ENDIF IF APPLICARD OT MODOUT ; DB cr,lf,'APMODEM 7.77 as of 11/25/82',cr,lf DB 'Originally Written by Ward Christensen',cr,lf DB 'Rev. For Appli-Card.',cr,lf,'$' ; ENDIF ; IF MODOUT ; DB cr,lf,'MODOUT 1.0 as of 4/17/82',cr,lf DB 'Based on Modem 7 as origin-398-3937' DB 'R=ARTY ROSS 924-7851' DB 'S=DON SCHMEIDER 356-2413' DB 'T=TELANET 343-0753' DB 'U=TIMNET 292-4050' DB 'V=TELINK 926-0181' DB 'W=RICK OBER 292-3838' DB 'X=BRUCE RATNITMOD JMP INITMOD ;to initialize port, if necessary OUT$MODCTLP JMP WR$MODCTLP ;out modem control port IN$BAUDRP JMP RD$BAUDRP ;in baudrate port OUT$BAUDRP JMP WR$BAUDRP ;out baudrate port OUT$MODCTL2 JMP WR$MODCTL2 ;out modem control port #2 CALL POKE POP D RET ;PEEK AT 1 BYTE IN THE APPLE ;ENTRY: DE = ADDRESS ;EXIT: A = DATA PEEK: PUSH B MVI C,PEEK1BYTE CALL WRBYTE CALL WRWORD CALL RDBYTE POP B RET ;POKE 1 BYTE INTO THE APPLE ;ENTRY: DE = ADDRESS ;EXIT: A enet 1-312-938-0500' DB 'E=NAPY BBS 1-312-420-7995' DB 'F=Niaug 1-312-295-6926' DB 'G=Hyde Park RCPM1-312-955-4493' DB 'H=Logan Square 1-312-252-2136' DB 'I=IBMPC RussLane1-312-251-0168' DB 'J=Jim Mills 1-312-469-2597' IF FOURMHZ FASTCLK: DB TRUE ;4 MHZ ENDIF IF SIXMHZ FASTCLK: DB 6 ;6 MHz ENDIF ; IN$MODCTLP JMP RD$MODCTLP ;in modem control port OUT$MODDATP JMP WR$MODDATP ;out modem data port ANI$MODSNDB ANI MODSNDB ! RET ;bit to test fORT WR$MODCTLP: PUSH D LXI D,MODCTLP CALL POKE POP D RET ;READ THE MODEM DATA PORT RD$MODDATP: PUSH D LXI D,MODDATP CALL PEEK POP D RET ;WRITE THE MODEM DATA PORT WR$MODDATP: PUSH D LXI D,MODDATP CALL POKE POP D RET OFF 1-201-272-1874' DB 'Y=CALOYANNIDES 1-714-993-4441' DB 'Z= ' DB 0 ; end ; IF APPLICARD ;READ THE MODEM CONTROL PORT RD$MODCTLP: PUSH D LXI D,MODCTLP CALL PEEK POP D RET ;WRITE THE MODEM CONTROL P ; ENDIF ; ;************************************************************** ;Ringback not recommended for MODOUT thru local HOST unless * ;it is a local call. Delays are variable thru WATS lines,etc. * ;*******************************************= DATA POKE: PUSH B MOV B,A MVI C,POKE1BYTE CALL WRBYTE CALL WRWORD MOV C,B CALL WRBYTE POP B RET ENDIF ; START: LXI H,0 DAD SP ;GET CP/M'S STACK SHLD STACK ;SAVE IT LXI SP,STACK ;START LOCAL STACK ; CALL START1 ; IF N DB 'K=Tymnet 1-312-368-4700' DB 'L=NEI 1-312-949-6189' DB 'M=AIMS 1-312-789-0499' DB 'N=IBMPCUG 1-312-836-0426' DB 'O=Grdn Grve 1-714-534-1547' DB 'P=APPLE GRAM 1-214-261-7368' DB 'Q=ALLENTOWN 1-215or send ready CPI$MODSNDR CPI MODSNDR ! RET ;value of send bit when ready IN$MODDATP JMP RD$MODDATP ;in modem data port ANI$MODRCVB ANI MODRCVB ! RET ;bit to test for receive ready CPI$MODRCVR CPI MODRCVR ! RET ;value of receive bit when ready JMP$I ;READ THE BAUD RATE PORT RD$BAUDRP: PUSH D LXI D,BAUDRP CALL PEEK POP D RET ;WRITE THE MODEM BAUD RATE PORT WR$BAUDRP: PUSH D LXI D,BAUDRP CALL POKE POP D RET ;WRITE THE CONTROL PORT 2 WR$MODCTL2: PUSH D LXI D,MODCTL2RETURN TO COMMAND MODE. LAST DB MUST BE DB 0. UP TO ; 26 NUMBERS ARE ALLOWED. ; NUMBLIB: ; '----5---10---15---20---25---30' DB 'A=Palatine RCPM 1-312-359-8080' DB 'B=Chicago CBBS 1-312-545-8086' DB 'C=Tech RBBS 1-313-846-6127' DB 'D=Tel******************* ; ; PHONE NUMBER LIBRARY TABLE FOR DIALING FROM LIBRARY ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-TIME. ; EACH DB MUST BE 30 CHARACTERS LONG FOR PROPER OPERATION. ; A 'DB 0' INDICATES NO DIALING, PROGRAM WILL DISCONNECT ; AND ally',cr,lf DB 'Written by Ward Christensen.',cr,lf,'$' ; ENDIF ; START1: POP D ;GET ADDRESS OF ABOVE MESSAGE MVI C,PRINT ; 9 CALL BDOS CALL INITADR ;INITIALIZE ADDRESSES MVI A,TRUE ; 0FFH STA NFILFLG CMA ; 0 STA SAVEFLG LXI H,BOTTR ORA A ;EXACT? MVI A,0 STA EXACFL ;CLR FOR NEXT TIME MOV A,B ;RESTORE JNZ NOTOG CPI EXITCHR ;^E OR ^\ ? JNZ S2 CALL CRLF ;ADD CRLF TO AVOID DISPLAY CONFUSION JMP INQUIR ;SEE IF WRITE FILE NEEDED, RETURN TO MENU S2: CPI DISCCHR ;^D? JZ NDIF ; IF MODOUT ; CPI 'L' ;DISCONNECT ; ENDIF ; JZ DISCON1 ;YES, DISCONNECT & GO MENU JMP MENU ;NO OPTION SPEC'D, GO MENU ; ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE ; DSKSAVE: LDA NFILFLG ;NEW FILE FLAG CPI TRUE ;OFFH? (TRUE=NOUFF CALL CRLF LXI D,CMDBUF+2 CALL ILCOMP DB 'PASWD1',0 ;PUT 6 CHAR PASSWORD HERE DB 0,0,0,0 ;ROOM FOR LONGER PASSWORD OR ACCOUNT NO. JNC PASOK CALL ILCOMP DB 'PASWD2',0 ;SECOND PASSWORD OR ACCOUNT NO. DB 0,0,0,0 ;RESERVED SPACE FIX ORA A ; @7.5 MVI A,ANSWMOD ; @7.5 STA UARTCTLB ; @7.5 JNZ TERM2 ; @7.5 MVI A,ORIGMOD ; @7.5 STA UARTCTLB ; @7.5 TERM2: CALL STAT ;KEYPRESS? JZ TERML ;NO, CHECK LINE CALL KEYIN ;GET CHAR FROM KBD mov b,a ;save char lda locflg ;lo GO TO IT CPI ' ' ;NO OPTION SPEC'D? JZ MENU ;TRUE, GO MENU CPI 'M' ;MENU ASKED FOR? JZ MENU2 ;YES, GO MENU CALL JMP$INITMOD CALL MOVEFCB MVI A,FALSE STA NFILFLG CALL IN$MODDATP ;GOBBLE UP GARBAGE.. CALL IN$MODDATP ;..CHARACTERS ON LINEAM ;CLEAR BUFFER COUNTER SHLD HLSAVE ; ;The routine GETPAS provides a password protection for this ;program. This is probably necessary because a caller could make ;long distance calls to anyplace unless a routine is added to ;restrict calls to a cnd ;only if a SAVE file was established. ; INQUIR: LDA SAVEFLG CPI TRUE JNZ MENU CALL CRLF CALL ILPRT DB 'Write Temporary Memory File to Disk ?',cr,lf DB 'WRT writes to disk,RET returns with save continued',cr,lf DB 'All else scratches RMAL TERMINAL MODE) JZ TERM ;YES LDA FCB+1 ;FIRST CHAR OF FILENAME CPI ' ' ;FILE SPEC'D JNZ GOODNM ;YES, GOOD NAME MVI A,TRUE ;0FFH STA NFILFLG ; CMA ; 0 STA SAVEFLG ; JMP TERM ; ; ;The following routine flashes a reminder message if aJNC PASOK CALL ILCOMP DB 'PASWD3',0 ;PASSWORD THREE OR ACCOUNT NO DB 0,0,0,0 ;RESERVED SPACE JNC PASOK ;ENTER MORE PASSWORDS HERE IF REQUIRED JMP EXIT ; ENDIF ; ;HERE IS THE LOCATION TO SAVE THE PASSWORD AND TO WRITE IT TO ;A RECORD cal echo? cpi false jz ckchar ;no, check special mov a,b ;get char call type ;char to console cpi cr ;was it a carriage return? jnz ckchar ;no, check special characters mvi a,lf ;yes, we need a local linefeed call type ckchar: LDA EXACFL LDA OPTION ;PROCESS MAIN OPTION CPI 'E' ;ECHO MODE? JZ TRMECHO ;YES CPI 'T' ;TERMINAL MODE? JZ DSKSAVE ;YES CPI 'S' ;SEND A FILE? JZ SENDFIL ;YES CPI 'R' ;RECEIVE A FILE? JZ RCVFIL ;YES ; IF NOT MODOUT ; CPI 'D' ;DISCONNECT? ; Eertain call area or to 7 digits. ;Provision has been made for 3 passwords. An alternate is to use the ;UDRPASWD.ASM program if you need only one password. ; ; IF MODOUT ; GETPAS: CALL ILPRT DB 'Enter Password',cr,lf,0 LXI D,CMDBUF CALL INBsavefile.',cr,lf,0 JMP COMD ; GOODNM: CALL ERASFIL CALL MOVE2 LXI D,FCB3 MVI C,MAKE CALL BDOS LXI D,FCB3 MVI C,OPEN CALL BDOS LXI H,BOTTRAM SHLD HLSAVE MVI A,FALSE STA NFILFLG TERM: LDA UARTFLG ; @7.61 sta origsav ; @MODEM75.5 START2: LDA OPTION ;GET MAIN OPTION CPI 'X' ;EXPERT FLAG? JNZ RESTART ;NO LDA XPRFLG ;FLIP... CMA ;...XPR... STA XPRFLG ;...FLAG JMP MENU ;GO MENU RESTART: LDA OPTION ;GET MAIN OPTION CPI 'C' ;CALL (DIAL) FUNCTION? JZ DIALPL ;YES,FILE. ROUTINE TO BE ADDED LATER along with numbers called. ; PASOK: CALL PROCOPT ;PROCESS CONTROL OPTIONS LDA UARTFLG ; @7.61 ORA A ; @7.5 MVI A,ANSWMOD ; @7.5 STA UARTCTLB ; @7.5 JNZ START2 ; @7.5 MVI A,ORIGMOD ; @7.5 STA UARTCTLB ; @7.DISCON1 ;YES, DISCONNECT & RETURN TO MENU CPI EXTCHR ;^^? JZ EXTFLG ;YES, SET FLAG FOR NXT CHAR CPI TRANCHR ;TEST FOR TRANSFER REQUEST (^T) CZ TRANSFER ;SEND-A-FILE (BLIND SEND) JZ TERM ;LOOP CPI BRKCHR ;^B? JZ BREAK ;SEND BREAK CPI CHGBAUDSIRED (SEE COMMENT IN "INTDSKSV" ;ABOVE). ; INMODEM: LDA FASTCLK ORA A LXI B,1250 JZ TIMERL ; IF MICROSOFT LXI B,2500 ENDIF IF APPLICARD LXI B,250 ;APPLI-CARD IS 1/10 BECAUSE OF APPLE OVERHEAD ENDIF ; TIMERL: CALL IN$MODCTLP PUT THEM IN.. INX H ;..BOTTRAM. CALL TYPE DCR D JZ CTRLQ LDA LASTBYT2 MOV M,A INX H CALL TYPE CTRLQ: MVI A,XON ;SEND START CHARACTER.. CALL OUT$MODDATP ;..TO REMOTE COMPUTER. RET BREAK: PUSH D ;SAVE IT LXI D,0 ;ZERO IT MVI A,BRKBYSH PSW ;save char cklst: lda lstflg ;check for... cpi false ;...LST: active jz cksav ;no, so check save pop psw ;get char push psw ;save again push b push d push h mov e,a ;char to E mvi c,lstout call bdos ;out to LST: pop h ;everythPUSH PSW LDA SAVCCP ORA A JZ SUB2 POP PSW SBI 8 ;..PAGE BELOW CCP .. SUB2: DCR A ;..OR BDOS HAS BEEN .. CMP H ;..REACHED AND DISKSAVE IS NEEDED. JNZ TERM ;NO PROBLEM - GO BACK TO NORMAL ROUTINE CALL ILPRT DB cr,lf,'Memory save buffer fulSEND A CTRL-S TO STOP.. CALL OUT$MODDATP ;..REMOTE COMPUTER OUTPUT. MVI D,0 ;D IS THE BUFFER COUNT CALL INMODEM ;GET LAST BYTES SENT.. STA LASTBYT1 ;..AFTER CTRL-S. CALL INMODEM ;ADD MORE CALLS TO INMODEM.. STA LASTBYT2 ;..AND STA LASTBYT# IF Y ;^P? PUSH PSW PUSH H CZ NEWBAUD ;ASK FOR NEW BAUD RATE POP H POP PSW JZ TERML CPI SAVECHR ;^Y?... JNZ NOTOG LDA NFILFLG ;DO NOT ALLOW SAVE IF.. CPI TRUE ;..THIS FLAG IS SET. JZ TERML LDA SAVEFLG ;...YES, ^Y... CMA ;...SO TOGGLE. CPI FALSE JZ NOSAVEB POP PSW MOV M,A INX H SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG.. ;..GET HL WHEN ENTERING VIA 'RET' CMD. PUSH D MOV D,A COLONB: CPI LF ;IF NO FRONT PANEL, THEN.. JNZ BRK1 ;..TYPE ":" AFTER EACH LINE FEED.. MVI T ;GET BREAK VALUE CALL OUT$MODCTLP ;HIT MODEM WITH IT LXI B,450 ;BREAK DELAY COUNTER FOR SLOW CLOCK CALL DELAY JZ BRK2 BRK1: CPI 0 ;CHECK FOR NULLS JZ BRK1 ;DON'T PROCESS THEM ANI 7FH ;STRIP PARITY CALL TYPE PUSH PSW LDA SAVEFLG ing back except pop d pop b ;character cksav: LDA SAVEFLG CPI FALSE JZ NOSAVE POP PSW ;now get char MOV M,A INX H SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG.. ;..MUST GET HL WHEN ENTERING VIA 'RET' CMD. COLON: CPI LF ;LF?... JNZ Nl',cr,lf,BELL,0 JMP TERM ; ;THIS SUBROUTINE WILL LOOP UNTIL THE MODEM RECEIVES A CHARACTER ;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET ;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED, ;BUT MORE MAY BE STORED IF DEOU ARE.. ;..LOSING BYTES WHEN MEMORY IS FULL. PUSH D CALL NUMREC1 CALL WRTDSK ;WRITE THE RECORDS POP D LXI H,BOTTRAM INR D DCR D ;TEST BUFFER COUNT FOR ZERO JZ CTRLQ LDA LASTBYT1 ;GET THE LAST BYTES THAT WERE.. MOV M,A ;..SAVED AND .. STA SAVEFLG ;...SAVE FLAG JMP TERML EXTFLG: MVI A,TRUE STA EXACFL JMP TERML NOTOG: CALL OUT$MODDATP TERML: CALL IN$MODCTLP CALL ANI$MODRCVB CALL CPI$MODRCVR JNZ TERM CALL IN$MODDATP ANI 7FH ;STRIP PARITY JZ TERM CALL TYPE PUA,':' ;..WHEN MEMORY SAVE ACTIVE. CALL TYPE JMP BRK1 ;@ NOSAVEB: POP PSW ;RESTORE IT JMP BRK1 BRK2: LDA parctlb ;GET MODEM CONTROL BYTE CALL OUT$MODCTLP POP D LHLD HLSAVE ;LAST ADDRESS WRITTEN IF DATA BEING SAVED LDA 7 ;CHECK TO SEE IF.. H ;..REACHED AND DISKSAVE IS NEEDED. CZ INTDSKSV JMP TERM NOSAVE: POP PSW ;old char, clear stack JMP TERM ; ; Some local flags ; locflg: db false lstflg: db false SAVEFLG: DB FALSE LASTBYT1: DB 0 LASTBYT2: DB 0 INTDSKSV: MVI A,XOFF ;OCOLON ;..TYPE ":" AFTER EACH LINE FEED.. MVI A,SAVSGN ;..WHEN MEMORY SAVE ACTIVE. CALL TYPE NOCOLON: LDA 7 ;CHECK TO SEE IF.. PUSH PSW LDA SAVCCP ORA A POP PSW JZ SUB1 SBI 8 ;..PAGE BELOW CCP .. SUB1: DCR A ;..OR BDOS HAS BEEN.. CMPCALL ANI$MODRCVB CALL CPI$MODRCVR JZ GETBYTE DCX B MOV A,B ORA C JNZ TIMERL RET GETBYTE: CALL IN$MODDATP INR D RET NUMRECS: MVI M,EOFCHAR INX H LXI D,127 DAD D NUMREC1: LXI D,-(BOTTRAM) DAD D MOV A,L ;DIVIDE HL BY 128..TFLG ;IF FIRST TIME THRU.. ORA A ;..SCAN THE COMMAND LINE.. CNZ TNMBUF ;..FOR MULTIPLE NAMES. CALL SENDFN ;SENDS FILE NAME TO RECEIVER JNC SENDC2 ;CARRY SET MEANS NO MORE FILES. MVI A,'B' ;STOP BATCH.. STA BATCHFLG ;..MODE OPTION. MVI A,EOT ; ;..DRIVE NO. INTACT. INX H ;WILL INITIALIZE AN FCB.. MVI B,11 ;..POINTED TO BY HL-REG. FILLS 1ST POS LOOP10: MVI M,' ' ;..WITH 0, NEXT 11 WITH.. INX H ;..WITH BLANKS, AND LAST.. DCR B ;..21 WITH NULLS. JNZ LOOP10 MVI B,21 LOOP11: MVI M,0 IOS POP PSW ! POP H ! POP D ! POP B RET MOVE2: LXI H,FCB3 CALL INITFCBS LXI H,FCB LXI D,FCB3 MVI B,12 CALL MOVE RET ; ;FILE TRANSFER ROUTINE - CALLED WITH ;CONTROL-T FROM TERMINAL ROUTINE. ;TRANSFER MAY BE CANCELLED WHILE SENDING BY US CALL ANI$MODRCVB CALL CPI$MODRCVR JZ LINECHR CALL STAT JZ TRMECHO CALL KEYIN CPI EXITCHR JZ MENU CPI CHGBAUD ;SAME ROUTINE AS IN TERMINAL MODE PUSH PSW CZ NEWBAUD POP PSW CPI CHGBAUD JZ TRMECHO CALL OUT$MODDATP CALL TYPE NU CALL SEND80C CPI EOFCHAR ;END OF FILE - OMIT IF OBJECT.. JZ RETURNS ;..CODE IS TO BE SENT. CPI CAN ;CANCELLATION? JZ TRANCAN JMP READMR RETURNS: CALL ILPRT DB cr,lf,'<< File transfer completed >>',cr,lf,BELL,0 JMP RETURN RETURNU: C ORA A RAL ;..TO GET THE.. MOV L,H ;..NUMBER OF SECTORS MVI H,0 PUSH PSW DAD H POP PSW MVI A,0 ADC L MOV L,A ;RETURNS WITH NUMBER OF.. RET ;..128 BYTE RECORDS IN HL. WRTDSK: LXI D,BOTTRAM NEXTWRT: MVI C,STDMA CALL BDOSRT PUSALL BDOS RET READ80: LXI D,FCB4 MVI C,READ CALL BDOS RET SEND80C: MVI B,80H LXI H,80H SENDCH1: MOV A,M CALL MODOUTA CPI EOFCHAR RZ CALL STAT ;TEST TO SEE IF ORA A ;CANCELLATION REQUESTED JZ SKIP12 CALL KEYIN CPI CAN RZ SNX H DCR B JNZ LOOP11 RET GETNAME: CALL ILPRT DB cr,lf,'Enter file name to be transferred - C/R TO QUIT: ',0 LXI D,CMDBUF CALL INBUFF CALL CRLF RET MOVE4: LXI D,CMDBUF LXI H,FCB4 CALL CPMLINE RET OPEN4: LXI D,FCB4 MVI C,OPEN CING CONTROL-X. ; TRANSFER: PUSH H ! PUSH D ! PUSH B ! PUSH PSW LXI H,FCB4 CALL INITFCBS ;INITIALIZES FCBS POINTED.. LXI H,FCB+16 ;..TO BY HL REG. CALL INITFCBS GET: CALL GETNAME LDA CMDBUF+2 ;WAS FILE ENTERED CPI 20H JZ TRANSL2 CALL MOJMP TRMECHO LINECHR: CALL IN$MODDATP CALL OUT$MODDATP CALL TYPE JMP TRMECHO ; ;SEND A CP/M FILE ; SENDFIL: LDA BATCHFLG ;CHECK IF MULTIPLE FILE.. ORA A ;..MODE IS SET. JNZ SENDC1 MVI A,TRUE ;INDICATE BATCH SEND STA SENDFLG LDA FSALL ILPRT DB cr,lf,'<< File transfer unsuccessful >>',cr,lf,BELL,0 JMP RETURN TRANCAN: CALL ILPRT DB cr,lf,cr,lf,'<< Transfer cancelled >>',cr,lf,BELL,0 RETURN: POP PSW ! POP B ! POP D ! POP H RET INITFCBS: ;ENTRY AT +2 WILL LEAVE.. MVI M,0H D LXI D,FCB3 MVI C,WRITE CALL BDOSRT POP D XCHG PUSH D LXI D,128 DAD D POP D XCHG DCX H MOV A,H ORA L JNZ NEXTWRT RET CLOSE3: LXI D,FCB3 MVI C,CLOSE CALL BDOS RET BDOSRT: PUSH B ! PUSH D ! PUSH H ! PUSH PSW CALL BDKIP12: INX H DCR B JNZ SENDCH1 RET MODOUTA: PUSH PSW MODOUTL: CALL IN$MODCTLP CALL ANI$MODSNDB CALL CPI$MODSNDR JNZ MODOUTL POP PSW CALL OUT$MODDATP CALL TYPE RET FCB4: DS 33 ; ;TERMINAL ECHO MODE ; TRMECHO: CALL IN$MODCTLP,BELL,0 CALL KEYIN CALL UCASE CALL TYPE ;ECHO RESPONSE CALL CRLF CPI 'A' JZ GET CPI 'R' JZ RETURN JMP TRANSL2 CONTIN: LXI D,80H MVI C,STDMA CALL BDOS READMR: CALL READ80 CPI 1 ;END OF FILE JZ RETURNS CPI 2 ;BAD READ JZ RETURVE4 CALL OPEN4 CPI 0FFH ;RETURN WITH 0FFH MEANS JNZ CONTIN ;FILE DOES NOT EXIST TRANSL1: CALL ILPRT DB cr,lf,'<< File does not exist >>',cr,lf,0 TRANSL2: CALL ILPRT DB 'Type "R" to return to modem',cr,lf DB 'Type "A" to re-enter name: 'FINAL XFER END CALL SEND JMP DONE SENDC1: LDA FCB+1 CPI ' ' JZ BLKFILE SENDC2: CALL CNREC ;GET NUMBER OF RECORDS CALL OPENFIL MVI E,80 CALL WAITNAK SENDLP: CALL RDSECT JC SENDEOF CALL INCRSNO XRA A STA ERRCT SENDRPT: CALL SENDHDlf,0 GNAMELP: CALL HSNAK JC GNAMELP CALL GETNM ;GET THE NAME CPI EOT ;IF EOT, THEN NO MORE FILES JZ NOMRNMG ORA A ;CLEAR CARRY RET NOMRNMG: STC RET GETNM: PUSH H GETNM1: MVI C,0 ;INIT CHECKSUM LXI H,FCB+1 NAMELPG: MVI B,5 CALL S IT SENDFN: LDA QFLG ORA A JZ SWNAK CALL ILPRT DB 'Awaiting name NAK',cr,lf,0 SWNAK: MVI E,80 CALL WAITNLP MVI A,ACK ;GOT NAK, SEND ACK CALL SEND LXI H,FILECT DCR M JM NOMRNM LHLD NBSAVE ;GET FILE NAME.. LXI D,FCB ;..IN FCB MVI..MODE OPTION. JMP DONE RCVC1: LDA FCB+1 ;MAKE SURE FILE IS NAMED CPI ' ' JZ BLKFILE JMP RCVC3 RCVC2: CALL CKCPM2 CALL CKBAKUP RCVC3: CALL ERASFIL CALL MAKEFIL LDA BATCHFLG ORA A JNZ RCVC4 ;DON'T PRINT MSG IF LDA QFLG ;..IN QUIET AND.. CMP D ;..FROM RECEIVER. JZ NAMEOK SCKSER: MVI A,BDNMCH ;BAD NAME-TELL RECEIVER CALL SEND LDA QFLG ORA A JZ SKCSER1 CALL ILPRT DB 'Checksum error',cr,lf,0 SKCSER1: MVI E,80 ;DO HANDSHAKING OVER CALL WAITNLP ;DON'T PRINT "AWAITING NAZ S5 ;NO, SO SKIP POP PSW SBI 8 ;YEP, BDOS-8 PUSH PSW ;H NEEDS IT S5: POP H ;MOVE IT OVER TO H LDA 6 ;GET TOPRAM (LO BYTE) MOV L,A ;GIVE IT TO L ; ;SUBTRACT DE FROM HL WITH CARRY ; MOV B,E ;E TO B MOV A,L ;L TO A SBB B ;SUBTRACT B FROMR CALL SENDSEC LDA CRCFLG ORA A CZ SENDCRC CNZ SENDCKS CALL GETACK JC SENDRPT JMP SENDLP SENDEOF: MVI A,EOT CALL SEND CALL GETACK JC SENDEOF JMP DONE ; ;RECEIVE A FILE ; RCVFIL: XRA A ;DEFAULT TO CRC MODE STA CRCFLG LDA;SEND NAME ANI 7FH ;STRIP HIGH ORDER BIT SO CP/M 2.. CALL SEND ;..WON'T SEND R/O FILE DESIGNATION. LDA QFLG ;SHOW NAME IF.. ORA A ;..QFLG NOT SET. MOV A,M CNZ TYPE ACKLP: PUSH B ;SAVE CKSUM MVI B,1 ;WAIT FOR RECEIVER.. CALL RECV ;..TO ACKN B,12 CALL MOVE SHLD NBSAVE CALL SENDNM ;SEND IT ORA A ;CLEAR CARRY RET NOMRNM: MVI A,EOT CALL SEND STC RET SENDNM: PUSH H SENDNM1: MVI D,11 ;COUNT CHARS IN NAME MVI C,0 ;INIT CHECKSUM LXI H,FCB+1 ;ADDRESS NAME NAMLPS: MOV A,M MULTI ORA A ; JZ RCVFST ; RCVC4: CALL ILPRT DB 'File open, ready to receive',cr,lf,0 RCVFST: LDA CRCFLG ORA A MVI A,NAK JNZ RCVFIL2 MVI A,CRC ; RCVFIL2: CALL SEND LDA CRCFLG ORA A JNZ RCVNAKM ;IF IN CRC MODE CALL ILPRT DB 'CRK" MSG MVI A,ACK CALL SEND JMP SENDNM1 NAMEOK: MVI A,OKNMCH ;GOOD NAME-TELL RECEIVER CALL SEND POP H RET GETFN: LXI H,FCB CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE LDA QFLG ORA A JZ GNAMELP CALL ILPRT DB 'Awaiting file name',cr, A (E FROM L) MOV E,A ;DUMP A IN E JNC S4 ;IF NO CARRY THEN S4 DCR D ;YES CARRY, DROP HI BYTE OF DE ONE S4: MOV B,D ;D TO B MOV A,H ;H TO A SBB B ;SUBTRACT B FROM A (D FROM H) MOV D,A ;PUT A IN D XCHG ;AND FLIP DE OVER TO HL RET ;THAT' BATCHFLG ;CHECK IF MULT.. ORA A ;..FILE MODE. JNZ RCVC1 MVI A,FALSE ;FLAG WHERE TO RETURN.. STA SENDFLG ;..FOR NEXT FILE TRANS. CALL GETFN ;GET THE FILE NAME. JNC RCVC2 ;CARRY SET MEANS NO MORE FILES. MVI A,'B' ;STOP BATCH.. STA BATCHFLG ;OWLEDGE.. POP B ;..GETTING LETTER. JC SCKSER CPI ACK JNZ ACKLP INX H ;NEXT CHAR DCR D JNZ NAMLPS MVI A,EOFCHAR ;TELL RECEIVER END OF NAME CALL SEND LDA QFLG ORA A CNZ CRLF MOV D,C ;SAVE CHECKSUM MVI B,1 CALL RECV ;GET CHECKSUMNES ; GETSPC: ;SETUP HL & DE FOR SUBTRACTION LHLD HLSAVE ;GET BUFFER POINTER XCHG ;GIVE IT TO DE LDA 7 ;GET TOPRAM (HI BYTE) PUSH PSW ;SAVE IT LDA SAVCCP ;IF WE'RE WATCHING OUT FOR THE CCP... ORA A ;...THEN WE'VE GOTTA ADJUST THE COUNT JC in Effect ',cr,lf,0 JMP RCVLP RCVNAKM: CALL ILPRT DB 'Checksum in Effect',cr,lf,0 RCVLP: CALL RCVSECT JC RCVEOT CALL WRSECT CALL INCRSNO CALL SENDACK JMP RCVLP RCVEOT: CALL WRBLOCK CALL SENDACK CALL CLOSFIL JMP DONE ; ;SUBROUTIRECV ;GET CHAR JNC GETNM3 LDA QFLG ORA A JZ GETNM2 CALL ILPRT DB 'Time out receiving filename',cr,lf,0 GETNM2: JMP GCKSER GETNM3: CPI EOT ;IF EOT, THEN NO MORE FILES JZ GNRET CPI EOFCHAR ;GOT END OF NAME JZ ENDNAME MOV M,A ;PUT NAME I;R/O ATTRIB MOV A,M ANI 7FH ;STRIP R/O ATTRIB MOV M,A INX H ;SYS ATTRIB MOV A,M ANI 7FH MOV M,A LXI D,FCB MVI C,30 ;SET NEW ATTRIBS IN DIR CALL BDOS ; ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE ; PLANCHG: LXI H,FCB ;CHAOV A,M CPI 20H JNZ SCANLP1 SCANLP2: INX H ;EAT EXTRA SPACES DCR B JZ DNSCAN MOV A,M CPI 20H JZ SCANLP2 SHLD BGNMS ;SAVE START OF NAMES IN CMDBUF INR B DCX H SCANLP3: INX H DCR B JZ DNSCAN MOV A,M CPI 20H JNZ SCANLP3 LD ;..SINCE IT MIGHT BE DAMAGED.. LDA QFLG ;..BY TOO MANY CHARS. ORA A JZ GCKSER1 CALL ILPRT DB 'Checksum error',cr,lf,0 GCKSER1: CALL HSNAK ;DO HANDSHAKING OVER JC GCKSER1 JMP GETNM1 GNRET: POP H RET HSNAK: MVI A,NAK ;SEND NAK UNTIL.. LL BDOS CPI 0FFH RZ ADD A ! ADD A ;MULT A-REG BY.. ADD A ! ADD A ;..32 TO FIND.. ADD A ;..NAME IN DMA. LXI H,80H ADD L MOV L,A ;HL POINTS TO DIR NAME LXI D,9 DAD D ;POINT TO R/O ATTRIB BYTE MOV A,M ANI 80H ;TEST MSB JNZ MKCHG ;IF FOUND DCR M JNZ TNLP1 LXI H,NAMEBUF ;SAVE START OF BUFFER SHLD NBSAVE LDA FILECT CPI 65 ;NO MORE THAN 64 TRANSFERS RC MVI A,64 ;ONLY X'FER FIRST 64 STA FILECT RET ; ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE) ;AFTER LAN FCB LDA QFLG ;TYPE IT IF NO QFLG ORA A MOV A,M CNZ TYPE PUSH B ;SAVE CKSUM MVI A,ACK ;ACK GETTING LETTER CALL SEND POP B INX H ;GET NEXT CHAR MOV A,L ;DON'T LET NOISE... CPI 7FH ;..CAUSE OVERFLOW.. JZ GCKSER ;..INTO PROGRAM AREA. TRTOBUF: LHLD BGNMS MVI B,0 LXI D,FCBBUF+2 TBLP: MOV A,M CPI 20H JZ TRBFEND STAX D INX H INX D INR B ;COUNT CHARS IN NAME JMP TBLP TRBFEND: INX H MOV A,M ;EAT EXTRA SPACES CPI 20H JZ TRBFEND SHLD BGNMS LXI H,FCBBUF+1 ;PUTA NAMECT ;COUNTS NAMES INR A STA NAMECT SCANLP4: INX H ;EAT SPACES DCR B JZ DNSCAN MOV A,M CPI 20H JZ SCANLP4 JMP SCANLP3 DNSCAN: MVI M,20H ;SPACE AFTER LAST CHAR POP H RET ; ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT ; CALL SEND ;..RECEIVING ACK. CALL CKABORT ;DON'T GET HUNG UP HERE MVI B,2 ;WAIT 2 SECONDS.. CALL RECV ;..IN RECEIVE. CPI ACK ;IF ACK,RETURN WITH.. RZ ;..CARRY CLEAR. STC RET TNMBUF: MVI A,FALSE ;CALL FROM SENDFIL ONLY ONCE. STA FSTFLG SSET, MAKE CHANGE INX H ;CHECK SYSTEM ATTRIB BYTE MOV A,M ANI 80H RZ ;NOT $SYS OR $R/O DCX H MKCHG: LXI D,-8 DAD D ;POINT HL TO FILENAME + 1 LXI D,FCB+1 ;MOVE DIR NAME TO FCB.. MVI B,11 ;..WITHOUT CHANGING DRIVE. CALL MOVE LXI H,FCB+9 ST NAME ; SCAN: PUSH H LXI H,NAMECT MVI M,0 LXI H,CMDBUF+1 ;FIND END OF CMD LINE.. MOV C,M ;..AND PUT SPACE THERE. MVI B,0 LXI H,CMDBUF+2 DAD B MVI M,20H LXI H,CMDBUF+1 MOV B,M INR B INR B SCANLP1: INX H DCR B JZ DNSCAN M JMP NAMELPG ENDNAME: LDA QFLG ORA A CNZ CRLF MOV A,C ;SEND CHECKSUM CALL SEND MVI B,1 CALL RECV ;CHECKSUM GOOD? CPI OKNMCH ;YES IF OKNMCH SENT.. JZ GNRET ;..ELSE DO OVER. GCKSER: LXI H,FCB ;CLEAR FCB (EXCEPT DRIVE).. CALL INITFCBS+2 # CHARS BEFORE NAME MOV M,B RET ; ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'. ; CKCPM2: MVI C,12 CALL BDOS ORA A ;RETURN 0 MEANS CP/M 1 RZ MVI C,STDMA LXI D,80H CALL BDOS MVI C,SRCHF ;SEARCH FOR FILE LXI D,FCB CAILE.. ANI 80H ;..DON'T SEND JNZ TNLP2 LHLD NBSAVE ;GET NAME LXI D,FCB ;MOVE IT TO FCB XCHG MVI B,12 CALL MOVE XCHG SHLD NBSAVE ;ADDR OF NEXT NAME LXI H,FILECT ;COUNT FILES FOUND INR M JMP TNLP2 ; NEXTNM: LXI H,NAMECT ;COUNT NAMES TA FILECT CALL SCAN LXI H,NAMEBUF SHLD NBSAVE ;SAVE ADDR OF 1ST NAME TNLP1: CALL TRTOBUF LXI H,FCB LXI D,FCBBUF CALL CPMLINE ;PARSE NAME TO CP/M FORMAT TNLP2: CALL MFNAME ;SEARCH FOR NAMES (* FORMAT) JC NEXTNM LDA FCB+10 ;IF CP/M 2 $SYS FNGE NAME TO TYPE "BAK" LXI D,6CH MVI B,9 ;MOVE DRIVE AND NAME (NOT TYPE) CALL MOVE LXI H,75H ;START OF TYPE IN FCB2 MVI M,'B' INX H MVI M,'A' INX H MVI M,'K' LXI D,6CH MVI C,ERASE ;ERASE ANY PREV BACKUPS CALL BDOS LXI H,6CH ;FCB2 S, NO MSG RCVDERRP: CALL ILPRT DB cr,lf,0 LDA ERRCDE ;GET RECEIVE ERR CODE ANI FRMER ;WAS THERE A FRAMING ERROR? JZ RCVDERR2 ;NO, GO CHECK FOR OVERRUN CALL ILPRT DB '<< Framing error >>',0 CALL RCVDERR5 ;PRINT # OF ERROR RCVDERR2: LDA ERRLDA VSEEFLG ORA A JZ RCVSEH LDA QFLG ORA A JZ RCVSERR RCVSEH: MOV A,B CALL CRLF CALL HEXO CALL ILPRT DB 'H recv''d, not SOH',cr,lf,0 RCVSERR: MVI B,1 CALL RECV JNC RCVSERR MVI A,NAK CALL SEND LDA ERRCT INR A STA ERRCT CPOR CODE LDA QFLG ORA A JZ RCVSQ CALL ILPRT DB cr,'Awaiting # ',0 PUSH H ;SAVE IT LHLD SECTNO ;GET SECTOR NUMBER INX H ;BUMP IT CALL DECOUT ;PRINT SECTOR NUMBER IN DECIMAL CALL ILPRT DB ' (', 0 CALL DHXOUT ;16 BIT HEX CONVERSION & OU LDA ERRCDE ;GET RECEIVE ERROR CODE ANA A ;IS IT ZERO? JZ RCVERR2 ;YES, NO RECEIVE ERROR POP PSW ;RESTORE CHAR TRANSMITTED STC ;SET CARRY ON TO INDICATE AN ERROR RET RCVERR2: POP PSW ;RESTORE CHAR TRANSMITTED RET ; ;----> RCVDERR: Checks JNC RCVSQ3 ;got a char, go see if SOH CALL ILPRT DB cr,lf,'<< Switching to CHECKSUM mode >>',cr,lf,0 MVI A,'C' ;turn off... STA CRCFLG ;...CRC mode. MVI A,NAK ;send NAK to tell sender checksum CALL SEND ;...is in effect & to start sending. JMDR FIELD SHOULD.. MVI M,0 ;..0 FOR RENAME. LXI D,FCB MVI C,23 ;RENAME CALL BDOS RET CKBAKUP: LDA BAKUPBYTE ORA A RZ MVI C,SRCHF LXI D,FCB CALL BDOS INR A RZ ;FILE NOT FOUND JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE ; ;MULTI-FA JZ RCVSPT LDA QFLG ORA A JZ RCVSERR RCVSPT: CALL ILPRT DB cr,lf,'<< Timeout >>',0 RCVPRN: LDA ERRCT CALL HEXO CALL CRLF JMP RCVSERR ; ;----> RCVERR: ; Checks for framing, overrun, and parity errors. Parity errors ; cannot be detecteI ERRLIM JC RCVRPT LDA VSEEFLG ORA A JZ RCVCKQ LDA QFLG ORA A JZ RCVSABT RCVCKQ: CALL CKQUIT JZ RCVSECT RCVSABT: CALL CLOSFIL CALL ERXIT DB cr,lf,'<< Unable to receive block - Aborting >>',cr,lf,'$' RCVSTOT: LDA VSEEFLG ORA TPUT CALL ILPRT DB 'H)',0 MOV A,L ;ONLY LOW BYTE USED BY PROGRAM POP H ;RESTORE IT ; ;----> RCVSQ: ; If CRC is in effect, there is only a 3 second wait ; for the first SOH. If the SOH is not received within ; 3 seconds, then a NAK is sent whifor a receive error and displays appropriate error ; message. Then goes to RCVSERR to purge the line and send a NAK. ; RCVDERR: LDA VSEEFLG ;VIEWING ORA A ;...MODE? JZ RCVDERRP ;YES,..PRT MSG LDA QFLG ;QUIET... ORA A ;...MODE? JZ RCVSERR ;YEP RCVSECT ;go start receiving sector ; RCVSQ2: MVI B,7 ;10 IN ORIG PROG CALL RECV JC RCVSTOT ; RCVSQ3: CALL RCVERR ;CHECK FOR ERRORS JC RCVDERR ;JUMP IF THERE WAS AN ERROR CPI SOH JZ RCVSOH ORA A JZ RCVSQ CPI EOT STC RZ MOV B,A ILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP ;FIXED BY MARK ZEIGER 8/17/80 ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND ; MFNAME: MFACCESS ;A MACRO IN MACROS.LIB ; RCVSECT: XRA A STA ERRCT RCVRPT: XRA A ;ZERO ACCUM STA ERRCDE ;CLEAR RECEIVE ERRd unless the parity option has been selected. ; 1.Error code (ERRCDE) was set in RECV routine. ; 2.ERRCDE=0 for no errors, ERRCDE<>0 for errors. ; 3.If there is an error, routine returns with carry flag set. ; RCVERR: PUSH PSW ;SAVE CHAR TRANSMITTED CVSQ2 ;yes, go get next SOH XRA A ;turn off... STA FIRSTME ;...first soh recvd switch LDA CRCFLG ;CRC in... ORA A ;...effect? JNZ RCVSQ2 ;no, do long wait for first SOH MVI B,3 ;wait for upto 3 seconds CALL RECV ;get a character from modem ch tells the sender ; to use checksum checking instead of CRC. This allows ; automatic compatability with versions of XMODEM that ; do not implement Cyclic Redundancy Checking(CRC). ; RCVSQ: LDA FIRSTME ;first SOH... ORA A ;...been received? JZ RCDE ;GET RECEIVE ERR CODE ANI ORUNER ;WAS THERE AN OVERRUN JZ RCVDERR3 ;NO, GO CHECK FOR PARITY ERROR CALL ILPRT DB '<< Overrun error >>',0 CALL RCVDERR5 RCVDERR3: LDA ERRCDE ;GET RECEIVE ERR CODE ANI PARER ;WAS THERE A PARITY ERROR? JZ RCpe ''Y'' to erase: ',BELL,0 CALL KEYIN PUSH PSW CALL TYPE POP PSW CALL UCASE CPI 'Y' JNZ MENU CALL CRLF NOASK: LXI D,FCB MVI C,ERASE CALL BDOS RET BLKFILE: CALL ILPRT ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE" DB cr,lf RET SENDSEC: MVI A,1 STA DATAFLG MVI C,0 CALL CLRCRC LXI H,80H SENDC: MOV A,M CALL SEND INR L JNZ SENDC XRA A STA DATAFLG RET SENDCKS: MOV A,C CALL SEND RET SENDCRC: CALL FINCRC MOV A,D CALL SEND MOV A,E CALL SENRCVDATA LDA VSEEFLG ORA A JZ RCVBSE LDA QFLG ORA A JZ RCVSERR RCVBSE: CALL ILPRT DB cr,lf,'<< Bad sector # in Header >>',cr,lf,0 JMP RCVSERR RCVDATA: MOV A,D STA RCVSNO MVI A,1 STA DATAFLG MVI C,0 CALL CLRCRC ;clear crc counteI B,1 CALL RECV JNC ABORTW MVI A,' ' CALL SEND CALL ILPRT DB cr,lf,'Routine cancelled',cr,lf,BELL,0 MVI A,'B' ;TURN MULTI-FILE MODE.. STA BATCHFLG ;..OFF SO ROUTINE ENDS. JMP DONETCE INCRSNO: PUSH H LHLD SECTNO ;GET SECTOR NUMBER IG ORA A JZ RCVSERR RCVCPR: CALL ILPRT DB '<< Cksum error >>',0 JMP RCVPRN RECVACK: CALL SENDACK JMP RCVSECT SENDACK: MVI A,ACK CALL SEND RET SENDHDR: LDA QFLG ORA A JZ SENDHNM CALL ILPRT DB cr,'Sending # ',0 PUSH H LHLD VDERR4 ;NO, GO PURGE LINE CALL ILPRT DB '<< Parity error >>',0 CALL RCVDERR5 RCVDERR4: JMP RCVSERR ;GO PURGE LINE, SEND NAK ; ;Display the number of the error, do a carriage return and line feed. ; RCVDERR5: LDA ERRCT ;GET ERROR NUMBER CALL PI ERRLIM RC LDA VSEEFLG ORA A JZ GACKV LDA QFLG ORA A JZ CSABORT GACKV: CALL CKQUIT STC RZ CSABORT: CALL ERXIT DB cr,lf,'Can''t send sector -- Aborting',cr,lf,'$' GETATOT: LDA QFLG ORA A JZ ACKERR CALL ILPRT DB cr,lf,'TiD XRA A RET GETACK: MVI B,7 ;10 IN ORIG PROG CALL RECVDG JC GETATOT CPI ACK RZ MOV B,A LDA QFLG ORA A JZ ACKERR MOV A,B CALL CRLF CALL HEXO CALL ILPRT DB 'H Recv''d, not ACK',cr,lf,0 ACKERR: LDA ERRCT INR A STA ERRCT Cr LXI H,80H RCVCHR: MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR MOV M,A INR L JNZ RCVCHR LDA CRCFLG ORA A JZ RCVCRC MOV D,C XRA A STA DATAFLG MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CNX H ;BUMP IT SHLD SECTNO ;STORE IT MOV A,L POP H RET ERASFIL: LDA BATCHFLG ;DON'T ASK FOR ERASE.. ORA A ;..IN MULTI-FILE MODE,.. JZ NOASK ;..JUST DO IT. LXI D,FCB MVI C,SRCHF CALL BDOS INR A RZ CALL ILPRT DB 'File exists -- TySECTNO ;GET SECTOR NUMBER CALL DECOUT ;PRINT IT IN DECIMAL CALL ILPRT DB ' (',0 CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT CALL ILPRT DB 'H)',0 POP H SENDHNM: MVI A,SOH CALL SEND LDA SECTNO CALL SEND LDA SECTNO CMA CALL SEND HEXO ;DISPLAY IT CALL CRLF ;DO cr, lf RET RCVSOH: MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR MOV D,A MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR CMA CMP D JZ meout on ACK',cr,lf,0 JMP ACKERR CKABORT: LDA VSEEFLG ORA A JZ CKABGO LDA QFLG ORA A RZ CKABGO: CALL STAT RZ CALL KEYIN CPI CAN RNZ ABORT: LXI SP,STACK ABORTL: MVI B,1 CALL RECV JNC ABORTL MVI A,CAN CALL SEND ABORTW: MV JC RCVDERR DCR E JNZ RCVCRC2 CALL CHKCRC ORA A JZ CHKSNUM LDA VSEEFLG ORA A JZ RCVCRER LDA QFLG ORA A JZ RCVSERR RCVCRER: CALL ILPRT DB cr,lf,'<< CRC error >>',0 JMP RCVPRN RCVCERR: LDA VSEEFLG ORA A JZ RCVCPR LDA QFLHECK FOR RECEIVE ERROR JC RCVDERR CMP D JNZ RCVCERR CHKSNUM: LDA RCVSNO MOV B,A LDA SECTNO CMP B JZ RECVACK INR A CMP B JNZ ABORT RET RCVCRC: MVI E,2 ;nr of crc bytes RCVCRC2: MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ,'<< No file specified >>',cr,lf,BELL,0 JMP MENU MAKEFIL: LXI D,FCB MVI C,MAKE CALL BDOS INR A RNZ CALL ERXIT DB 'Error - Can''t make file',cr,lf DB 'Directory must be full',cr,lf,'$' ; CNREC: MVI C,FILSIZ ;COMPUTE FILE SIZE FUNCTION Icrc request? JZ WAITCRC ;yes, go set crc flag DCR E JZ ABORT JMP WAITNLP WAITCRC: CALL ILPRT DB 'CRC request received',cr,lf,0 XRA A STA CRCFLG RET INITADR: LHLD 1 LXI D,3 DAD D SHLD VSTAT+1 DAD D SHLD VKEYIN+1 DAD D SHLhaving just sent a sector, calling ;RECVDG will delete any line noise induced characters LONG before the ;ACK/NAK would be received. ; RECVDG: EQU $ CALL IN$MODDATP CALL IN$MODDATP RECV: PUSH D LDA FASTCLK ORA A JZ MSEC MOV A,B ADD A MPRINT DB ' (',0 CALL DHXOUT CALL ILPRT DB 'H) sectors',cr,lf,0 RET CLOSFIL: LXI D,FCB MVI C,CLOSE CALL BDOS INR A RNZ CALL ERXIT DB '<< Can''t close file >>$' RDSECT: LDA SECINBF DCR A STA SECINBF JM RDBLOCK LHLD SECPTR JZ MONOUT LDA VSEEFLG ORA A JNZ NOMONOT LDA DATAFLG ORA A JZ NOMONOT MONOUT: POP PSW PUSH PSW CALL SHOW NOMONOT: POP PSW PUSH PSW CALL UPDCRC ;calc crc ADD C MOV C,A SENDW: CALL IN$MODCTLP CALL ANI$MODSNDB CALL CPI$MODSNDR A A RZ MOV C,A LXI D,DBUF DKWRLP: PUSH H PUSH D PUSH B MVI C,STDMA CALL BDOS LXI D,FCB MVI C,WRITE CALL BDOS POP B POP D POP H ORA A JNZ WRERR LXI H,80H DAD D XCHG DCR C JNZ DKWRLP XRA A STA SECINBF LXI H,DBUFN CP/M 2.x LXI D,FCB ;POINT TO FILE CONTROL BLOCK CALL BDOS LHLD FCB+33 ;GET RECORD COUNT SHLD RCNT ;STORE IT LXI H,0 ;ZERO HL SHLD FCB+33 ;RESET RANDOM RECORD IN FCB RET ; OPENFIL: LXI D,FCB MVI C,OPEN CALL BDOS INR A JNZ OPENOK E JNZ MWTI DCR D JNZ MWTI DCR B JNZ MSEC POP D STC RET MCHAR: CALL IN$MODCTLP ;GET ERROR-STATUS BYTE ANI ERRCDMSK ;MASK OUT ALL EXCEPT ERROR BITS (4-6) STA ERRCDE ;SAVE THE ERROR CODE MCHAR1: CALL IN$MODDATP POP D PUSH PSW CAOV B,A ; MSEC: IF MICROSOFT LXI D,15000 ;60% OF ORIG 50000 ENDIF IF APPLICARD LXI D,1500 ;1/10 OF MICROSOFT BECAUSE OF THE APPLE OVERHEAD ENDIF ; CALL CKABORT MWTI: CALL IN$MODCTLP CALL ANI$MODRCVB CALL CPI$MODRCVR JZ MCHAR DCR LXI D,80H CALL MOVE128 SHLD SECPTR RET RDBLOCK: LDA EOFLG CPI 1 STC RZ MVI C,0 LXI D,DBUF RDSECLP: PUSH B PUSH D MVI C,STDMA CALL BDOS LXI D,FCB MVI C,READ CALL BDOS POP D POP B ORA A JZ RDSECOK DCR A JZ REOF JNZ SENDW POP PSW CALL OUT$MODDATP RET WAITNAK: LDA VSEEFLG ORA A JZ WAITNPR LDA QFLG ORA A JZ WAITNLP WAITNPR: CALL ILPRT DB 'Awaiting initial NAK',cr,lf,0 WAITNLP: CALL CKABORT MVI B,1 CALL RECV CPI NAK RZ CPI CRC ; SHLD SECPTR RET WRERR: MVI C,CAN CALL SEND CALL ERXIT DB '<< Error writing file >>',cr,lf,'$' ; ;----> RECV: Receive a character ; ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage ;characters on the line. For example, CALL ERXIT DB '<< Can''t open file >>$' OPENOK: LDA BATCHFLG ORA A JNZ OPENOK1 LDA QFLG ORA A RZ OPENOK1: CALL ILPRT DB 'File open, size: ',0 LHLD RCNT ;GET RECORD COUNT CALL DECOUT ;PRINT NUMBER OF SECTORS IN DECIMAL CALL ILPRT ;LL UPDCRC ;calc crc ADD C MOV C,A LDA RSEEFLG ORA A JZ MONIN LDA VSEEFLG ORA A JNZ NOMONIN LDA DATAFLG ORA A JZ NOMONIN MONIN: POP PSW PUSH PSW CALL SHOW NOMONIN: POP PSW ORA A RET SEND: PUSH PSW LDA SSEEFLG ORA A SECPTR LXI D,80H MVI C,STDMA CALL BDOS JMP RDSECT ; WRSECT: LHLD SECPTR XCHG LXI H,80H CALL MOVE128 XCHG SHLD SECPTR LDA SECINBF INR A STA SECINBF CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS RNZ WRBLOCK: LDA SECINBF OR CALL ERXIT DB '<< File read error >>$' RDSECOK: LXI H,80H DAD D XCHG INR C MOV A,C CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS JZ RDBFULL JMP RDSECLP REOF: MVI A,1 STA EOFLG MOV A,C RDBFULL: STA SECINBF LXI H,DBUF SHLD D VTYPE+1 JMP JMP$INITMOD RET PROCOPT: LXI D,FCB+1 LDAX D STA OPTION OPTLP: INX D LDAX D CPI ' ' JZ ENDOPT LXI H,OPTBL MVI B,OPTBE-OPTBL OPTCK: CMP M JNZ OPTNO CPI 'O' ; @7.61 JNZ OPTCK1 ; @7.61 XRA A ; @7.61 STA UARi d,-450 ;get constant dad d ;subtract mov a,h ora l pop h jz getbau2 ;450 baud lda parctlb mov b,a ;set parity and data word inr c lxi d,-300 ;get constant dad d mov a,h ora l jnz badrate ;invalid baud rate getb JNZ MENU ;..AFTER X'FER. CALL CRLF JMP TERM INITMOD: SETBAUD: LDA ANSWFLG ;IF ANSWER OR ORIGINATE MODE.. ORA A ;..IS NOT REQUESTED OR NO.. JNZ SKIPB1 ;..BAUDRATE SPECIFIED, THEN.. CALL GETBAUD ;..ROUTINE RETURNS WITH CHANGE.. JMP FIXBAUD SSAGE.. MVI B,8 ;..BELOW. CALL MOVE INX D ;PUT FILE TYPE AFTER.. MVI B,3 ;..SKIPPING ONE SPACE.. CALL MOVE ;..BELOW. CALL ILPRT FTRNMSG: DB cr,lf,' transferred',cr,lf,lf,0 ;12 SPACES NMSTRNS: LDA FCB ;SAVE DRIVE NO. STA DISKDCR L JNZ OFFDLY DCR H JNZ OFFDLY CALL out$modctl2 RET getbaud: lda fcb+9 ;get filetype cpi ' ' ;default jz getbau3 ;force 300 baud lda fcb+9 cpi 0 ;is it zero jnz getbau1 ;no - do baud rate stuff getbau3 mvi c,1 if disconnect when thru ORA A JNZ DONETCE ;no, don't disconnect DONETCB: CALL ILPRT DB cr,lf,'>> Press RETURN to disconnect :',BELL,0 MVI C,RDCON CALL BDOS ;wait for response CPI 0DH ;carriage return JNZ DONETCB ;nope CALL ILPRT DB crTFLG ; @7.61 JMP OPTCK2 ; @7.61 OPTCK1: CPI 'A' ; @7.61 JNZ OPTCK2 ; @7.61 MVI A,0FFH ; @7.61 STA UARTFLG ; @7.61 OPTCK2: MVI M,0 ; @7.61 JMP OPTLP OPTNO: INX H DCR B JNZ OPTCK JMP BADOPT ENDOPT: LDA CRCFLG ORA A JNZ ENDOPT2 : MVI A,' ' ;FORCE 300 BAUD STA FCB+9 SKIPB4: CALL GETBAUD fixbaud: lda answflg ;answer.. ora a mvi b,answmod ;set answermode jz initm1 lda origflg ;get orginate flag ora a mvi b,origmod ;set originate mode jz initm1 lda;..OF BAUD. IF OPT REQUESTED,.. SKIPB1: LDA ORIGFLG ;..A BLANK FORCES 300 BAUD.. ORA A ;..ELSE A 0 FROM NEWBAUD.. jnz skipb2 ;..FORCES 300 BAUD. CALL GETBAUD JMP FIXBAUD SKIPB2: LDA FCB+9 CPI 0 JZ SKIPB3 CPI ' ' RZ JMP SKIPB4 SKIPB3NO LXI H,FCB ;BLANK OUT FILE CONTROL BLOCKS CALL INITFCBS LDA DISKNO ;PUT DRIVE NUMBER BACK STA FCB LXI H,RESTSN ;RESTORE SECTORE NUMBERS.. LXI D,SECTNOB ;..FOR NEW FILE TRANSFER. MVI B,SECTNOE-SECTNOB ;ROUTINE ALSO DONE IN MENU. CALL MOVE ;set 300 baud lda parctlb mov b,a ;set parity and data word jmp getbau2 getbau1 call cvbin ;convert to binary push h ;save baud rate mvi c,0 ;anticipate 450 baud lda parctlb mov b,a ;set parity and data word lx,lf,'<< Disconnected >>',cr,lf,0 CALL DISCONNT ;hang-up the phone JMP EXIT ;go to CP/M DONETCE: MVI A,CRC STA CRCFLG ;TURN OFF CRC OPTION MVI A,0FFH STA FIRSTME ;SET FIRST TIME FLAG LDA TERMFLG ;SEE IF RETURN TO.. ORA A ;..TERMINAL MODE.. LDA OPTION CPI 'R' JNZ BADOPT ;crc only allowed for recv ENDOPT2: LDA VSEEFLG ORA A RNZ STA QFLG RET DONE: LDA BATCHFLG ORA A JNZ DONETCC LDA QFLG ORA A JZ NMSTRNS LXI H,FCB+1 ;PUT FILE NAME IN.. LXI D,FTRNMSG ;..SPACES IN ME modctlb ;neither - get last value mov b,a ; initm1: mov a,b ;get mode sta modctlb ;save value mov a,c ;get baud rate indicator ora a ;zero if 450 baud mov a,b ;get mode jz offhook ori 1 ;set 300 baud OFFHOOK: LXI H,4000 OFFDLY: NFILFLG ;..USED IN TERMINAL ROUTINE. CMA STA SAVEFLG ;STOP MEMORY SAVE IN TERM ROUTINE. LDA VSEEFLG ORA A JZ DONETC LDA QFLG ORA A JZ DONETCA DONETC: CALL ILPRT DB cr,lf,'All transfers completed',cr,lf,BELL,0 DONETCA: LDA DISCFLG ;see LDA SENDFLG ;GOES TO EITHER SEND OR.. ORA A ;..RECEIVE FILE, DEPENDING.. JNZ SENDFIL ;..UPON WHICH ROUTINE SET.. JMP RCVFIL ;..THE FLAG IN MULTI-FILE MODE. DONETCC: MVI A,TRUE ;INDICATE NO FILES BEING.. STA FSTFLG ;RESET MULTIFILE TRANS STA au2 mov a,b ;get setup sta modctlp ;initialize modem for stop bits... ret ;...data bits, etc cvbin LXI D,FCB+9 LXI H,0 DECLP: LDAX D INX D CPI ' ' JZ DECLP CPI '0' JC BADRATE CPI '9'+1 JNC BADRATE SUI '0' MOV B,H MOV C,L ? JC ENTNUM ;NO, ASK FOR NUMBER LXI H,CMDBUF+6 ;POINT TO NUMBER TO DIAL JMP DIAL10 ;CHECK IF LIB #, & DIAL DIALPL0: LXI B,500 CALL DELAY; DELAY .5 SEC FOR A TOTAL HANGUP CALL DISCONNT CALL ILPRT DB CR,LF,'Waiting for dI 'Q' JNZ CKQUIT ORA A RET ; ILPRT: XTHL ILPLP: MOV A,M ORA A JZ ILPRET CALL CTYPE INX H JMP ILPLP ILPRET: XTHL RET ; PRTMSG: MVI C,PRINT JMP BDOS ; ERXIT: POP D CALL PRTMSG CALL ILPRT DB BELL,0 LDA BATCHFLG ORA A JNVI C,WRCON CALL BDOS POP H POP D POP B RET CRLF: PUSH PSW MVI A,CR CALL TYPE MVI A,LF CALL TYPE POP PSW RET TYPE: PUSH PSW PUSH B PUSH D PUSH H MOV C,A VTYPE: CALL $-$ POP H POP D POP B POP PSW RET STAT: PUSH B ; CLEAR EQU 3FH ;IDLE MODE MAKEM EQU 1 ;TELE LINE MAKE (OFF HOOK) BRKM EQU 0 ;TELE LINE ON HOOK (BREAK DURING DIALING) DTMSK EQU 1 ;DIAL TONE MASK RBLMT EQU 70 ;# OF SEC*10 TO WAIT BEFORE GIVING NO RING HEARG MSG RBWAIT EQU 50 ;# OF SEC*10 DELAY BEF CALL NIBBL POP PSW NIBBL: ANI 0FH CPI 10 JC ISNUM ADI 7 ISNUM: ADI '0' JMP TYPE ; ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN ;NO QUESTIONS ASKED, JUST QUIT ; CKQUIT: LDA BATCHFLG ORA A JNZ CKQTASK ;ASK FOR RETRY DAD H DAD H DAD B DAD H ADD L MOV L,A JNZ DIGNC INR H DIGNC: MOV A,E CPI FCB+12 JNZ DECLP ret BADRATE: CALL ERXIT DB '<< Invalid baud rate >>$' MOVEFCB: LXI H,FCB+16 LXI D,FCB MVI B,16 CALL MOVE XRA A STA FCBSNO STMODOUT D to disconnect when finished.',cr,lf ; ENDIF ; IF NOT MODOUT ; DB 'use MODEM D to disconnect when finished.',cr,lf ; ENDIF ; DB 'This reminder will not be repeated on return.',cr,lf,0 EXIT: LXI D,80H MVI C,STDMA CALL BDOS Z DONETCE MVI A,'Q' ;RESET QFLG STA QFLG JMP ABORT ;ABORT OTHER COMPUTER EXIT0: LDA LINFLG ;SKIP MESSAGE IF LINE NOT CONNECTED ORA A JZ EXIT CALL ILPRT DB BELL,'<< Outgoing line still Connected >>',BELL,CR,LF ; IF MODOUT ; DB 'use PUSH D PUSH H VSTAT: CALL $-$ POP H POP D POP B ORA A RET KEYIN: PUSH B PUSH D PUSH H VKEYIN: CALL $-$ POP H POP D POP B RET UCASE: CPI 61H ;CHANGES LOWER CASE CHARACTER.. RC ;..IN A-REG TO UPPER CASE. CPI 7BH RNC ANI ORE REDIALING NUMBER ; DIALPL: mvi a,'A' sta answflg ;restore answer flag after CAL XRA A ; 0 STA CRFLAG ;CONTINUOUS REDIAL FLAG dpl1: LXI H,CMDBUF+1 ;POINT # OF CHARS IN BUFF MOV A,M ;GET # OF CHARS CPI 4 ;4 OR MORE CHARS TYPED BEFORE INR A ;RESET ZERO FLG RET CKQTASK: XRA A STA ERRCT CALL ILPRT DB 'Multiple errors encountered.',cr,lf DB 'Type Q to quit, R to retry :',BELL,0 CALL KEYIN PUSH PSW CALL CRLF POP PSW CALL UCASE ;INSTEAD OF "ANI 5FH" CPI 'R' RZ CPA FCBEXT RET SHOW: CPI lf JZ CTYPE CPI CR JZ CTYPE CPI 9 JZ CTYPE CPI ' ' JC SHOWHEX CPI 7FH JC CTYPE SHOWHEX: PUSH PSW MVI A,'(' CALL CTYPE POP PSW CALL HEXO MVI A,')' CTYPE: PUSH B PUSH D PUSH H MOV E,A M LHLD STACK SPHL LDA SAVCCP ORA A JZ 0 ;WARM BOOT RET MOVE128: MVI B,128 MOVE: MOV A,M STAX D INX H INX D DCR B JNZ MOVE RET ; ;DIALING ROUTINES TAKEN (AND GREATLY MODIFIED) FROM PMMI MANUAL. ; ;MODEM CONTROL COMMAND WORDS XOUT: - double precision hex output routine. ; DHXOUT: PUSH H PUSH PSW MOV A,H ;GET MS BYTE CALL HEXO ;OUTPUT HIGH ORDER BYTE MOV A,L ;GET LS BYTE CALL HEXO ;OUTPUT LOW ORDER BYTE POP PSW POP H RET HEXO: PUSH PSW RAR RAR RAR RAR 5FH RET DECOUT: PUSH PSW PUSH B PUSH D PUSH H LXI B,-10 LXI D,-1 DECOU2: DAD B INX D JC DECOU2 LXI B,10 DAD B XCHG MOV A,H ORA L CNZ DECOUT MOV A,E ADI '0' CALL CTYPE POP H POP D POP B POP PSW RET ; ;----> DHial tone',CR,LF,0 MVI A,ORIGMOD-1 ;OFF HOOK, NO CARRIER CALL OUT$MODCTL2 LXI B,2000 ;WAIT 2.0 SECONDS FOR DIAL TONE CALL DELAY CALL CRLF STC CMC RET ; DIALPL1: CALL CRLF STC CMC RET ; ;This is all LDA FASTCLK ;4Mhz CLOCK? ORA A JZ NOTFAST ;NO CALL DELAY0 ;YES, SO DELAY TWICE ; LDA FASTCLK ;6MHZ CLOCK ? CPI 6 CZ DELAY0 ;YES, SO DELYA THREE TIMES ; NOTFAST: CALL DELAY0 POP PSW RET DELAY0: PUSH B PUSH D INR B ;BUMP B FOR LXI D,CMDBUF+1 ;POINT TO BUFFER XCHG ;HL POINTS TO CMDBUF+1 MOV M,B ;STORE # OF BYTES IN A TABLE ENTRY XCHG ;RESTORE REG. INX D ;POINT TO FIRST CHAR POSITION IN BUFFER CALL MOVE ;MOVE TABLE ENTRY TO BUFFER DIALLPX: LDA CMDBUF+1 MOV E,A ; A,CR ;CR STAX D ;store it MVI A,LF ;LF INX D ;bump pointer STAX D ;store LF INX D ;bump pointer RET SPACES: MVI A,20H ;space STAX D ! INX D ; 1 STAX D ! INX D ; 2 STAX D ! INX D ; 3 RET ENTNUM2: MVI A,'$' STAX D MVI C,PRINT a,8fh ;restore modctlb sta modctlb MVI A,3 ; CALL OUT$MODCTLP ;RESET ACIA lda parctlb ; CALL OUT$MODCTLP ;set parity and data word MVI A,ORIGMOD-79H ; CALL OUT$MODCTL2 ;HANGUP PUSH B MVI B,8 ;wait for MM][ to disconnect CALL TIM;MAKE NEXT LETTER (A-Z) INR E ;COUNT UP DCR C ;COUNT DOWN JZ DIALLPX ;NOT A LETTER JMP DIAL11 ;LOOP LIBSET: LXI H,NUMBLIB ;PHONE NUMBER LIBRARY LXI B,30 ;LENGTH OF LIBRARY ENTRY MOV A,E ;NUMBER OF TIMES TO ADD 30 TO HL ORA A ;SET FLAGS J the set-up for the print at entnum2. ; ENTNUM: MVI C,13 ;number of lines to move LXI H,NUMBLIB ;address of source memory LXI D,DBUF ;address of target memory CALL NEWLINE ;start with CRLF STAX D ;+LF INX D ;and bump it ENTNUM1: MVI B,30 ER IF NULL MVI C,PRINT ; 9 PUSH PSW ;SAVE A AND FLAGS CZ BDOS POP PSW ;RESTORE A AND FLAGS POP D ;RESTORE DE REGISTERS JZ BORTIT ;ABORT ; ; DIAL A DIGIT, CHECK KBD FOR ABORT ; PUSH D CALL DIAL ;DIAL IT POP D CALL STAT ; KEYPRESS? ONUMBER OF CHARS IN BUFF LXI H,CMDBUF+2 ;POINT FIRST CHAR ; ; ROUTINE TO PRINT 'BADLIB' MESSAGE AND ABORT IF NULL ENCOUNTERED ; DIALLP2: MOV A,M ;GET FIRST # FROM BUFFER ORA A ;SET FLAGS PUSH D ;SAVE DE REGISTERS LXI D,BADLIB ;BAD LIBRARY NUMB LXI D,DBUF ;point to table of numbers to print CALL BDOS CALL CRLF CALL ILPRT DB 'Enter number or library letter - RETURN when finished,',CR,LF DB 'CTRL-X cancels while dialing: ',0 LXI D,CMDBUF CALL INBUFF DIALLP1: LDA CMDBUF+1 ORA A ;ER POP B RET ; TIMER: PUSH B ;SAVE # OF .1 SEC INTERVALS LXI B,100 ;100 MILL. CALL DELAY POP B ;GET COUTNER BACK DCR B ;CHECK FOR DONE JNZ TIMER ;NO RET ;YES ; ;DELAY - Wait for number of Milliseconds in BC ; DELAY: PUSH PSW Z DIAL13 DIAL12: MOV A,M ;GET FIRST CHAR OF SELECTED LIB ENTRY ORA A ;SET FLAGS JZ DIALLP2 ;SEND BADLIB MSG DAD B ;INCREMENT HL BY 30 DCR E ;COUNTDOWN JNZ DIAL12 ;NOT THERE YET, LOOP DIAL13: MVI B,30 ;NUMBER OF CHARACTERS TO GET FROM TABLE ;number of bytes to move CALL MOVE ;move to buffer CALL SPACES ;2 entries + 3 spaces = 63 characters MVI B,30 CALL MOVE CALL NEWLINE DCR C ;number of lines to print JZ ENTNUM2 JMP ENTNUM1 NEWLINE: ;puts CR-LF at memory pointed by DE MVIRA A ;SET FLAGS CNZ KEYIN ;YES, GO GET IT CPI CAN ; ^X? JZ BORTIT ;YES, ABORT INX H ;BUMP POINTER mvi b,1 ;wait one time unit call timer DCR E ;COUNT DOWN CHARS IN BUFF JNZ DIALLP2 ;NOT DONE, LOOP JZ DIALDN ;DIALING DONE DISCONNT: mvi CONNECT, AAND WAIT FOR TONE POP H MVI B,'A' ;FIRST LETTER OF ALPHABET MVI E,0 ;COUNTS NUMBER OF LETTERS TO MATCH MVI C,26 ;NUMBER OF LETTERS IN ALPHABET MOV A,M ;GET CHAR BUFFER DIAL11: CMP B ;NUMBER FROM TABLE? JZ LIBSET INR B NULL MEANS WAS TYPED JZ BORTIT ;ABORT DIALING, RETURN TO MENU LXI H,CMDBUF+2 ;FIRST TYPED CHAR OF NUMBER TO DIAL ; ; ENTER THIS ROUTINE WITH HL POINTING TO NUMBER TO DIAL ; DIAL10: PUSH H CALL DIALPL0; DISCONNECT, RE LATER DCR DELAY1: MVI E,126 ;DELAY COUNT FOR .1 MILL @ 2 Mhz DELAY2: DCR E ;COUNT JNZ DELAY2 ;...DOWN DCR C ;MORE? JNZ DELAY1 ;YES DCR B ;NO, MORE IN HI BYTE? JNZ DELAY1 ;YES POP D ; POP B ;NO RET BORTIT: CALL DISCONNT JMP MENUPT CHECKNM: LDA FCB+1 ;CHECK ON THE PRIMARY OPTION CPI 'E' ;RETURN IF ECHO OPTION RZ CPI 'M' ;RETURN TO MENU RZ CPI 'C' RZ CPI 'T' JZ TERMSEL CPI 'S' JZ CKFILE CPI 'R' JNZ BDOPT LDA BATCHFLG ;IF MULT FILE MODE, THEN.. ORA A POP D ;RESET.. POP B ;..STACK JMP DISCON1 ;DISCONNECT HANGP: MVI A,CLEAR CALL OUT$MODCTL2 MVI A,0 CALL OUT$MODCTLP RET DIALDN: CALL CRLF MVI C,WAITCTS ;wait time for cts (25.5 SEC MAX) CALL WAIT MVI C,WAITCTS ;DO IT AGAIN FOR MZ DIALS MVI A,10 ;CONVERT ZERO TO 10 PULSES DIALS: MOV E,A DIALC: MVI A,ORIGMOD-79H ;ON HOOK FOR 61-msec PULSE CALL OUT$MODCTL2 LXI B,61 CALL DELAY MVI A,ORIGMOD+1 ;OFF HOOK FOR 39-msec PULSE CALL OUT$MODCTL2 LXI B,39 CALL DELAY Dhoice jmp dpl1 ;and this is for CAL A CONMADE: MVI A,ORIGMOD+1 CALL OUT$MODCTL2 CALL ILPRT DB CR,LF,'Connection established - Select options: ',BELL,0 MVI A,TRUE ;SET LINFLG FOR CONNECTION MADE STA LINFLG DILAGN1: CALL STAT ;KEYPRESS? ;HANGUP, REDIAL, & LISTEN FOR CARRIER ; ;Timeout routine - secs*10 in C ; WAIT: PUSH B LXI B,120 CALL DELAY ;WAIT .12 SECONDS POP B CALL IN$MODDATP CALL IN$MODCTLP ANI 04H ;CARRIER DETECT? RZ ;YES PUSH B ;SAVE.. PUSH D ;..ACTIVE ; ;AUTO DIALER ; DIAL: CALL TYPE ;PRINT WHATEVER CHARACTER, DASHES, ETC. CPI 30H RC ;DIGIT MUST BE AT LEAST 0.. CPI 'R' ;COULD IT BE A RINGBACK CHARACTER JNZ DIAL1 ;NO? - JUMP PUSH PSW ;SAVE ACCUMULATOR & FLAGS MOV A,E ;GET # OF CHAR LCHO IT CALL UCASE ;ANI 5FH CALL CRLF ;NEW LINE CPI 'N' ;REDIAL? JZ MENU ;NO, GO MENU CPI 'Y' ;REDIAL? JZ DILAGN0 ;YES, REDIAL CPI 'C' ;CONTINUOUS REDIAL? JNZ DILAGN ;INVALID RESPONSE, ASK AGAIN XRA A ! CMA ;0FFH STA CRFLAG ;CONTINUOUS RORE DELAY CALL WAIT JNC CONMADE ;CONNECTION MADE CALL DISCONNT DILAGN: LDA CRFLAG ;CONTINUOUS REDIAL FLAG ORA A JNZ DILAGN0 CALL ILPRT DB CR,LF,'No answer after time-out. Redial? (Y/N/C): ',BELL,0 CALL KEYIN ;GET RESPONSE CALL TYPE ;ECR E ;DONE WITH DIGIT? JNZ DIALC ;NO LXI B,600 ;YES, DO 600-msec INTERDIGIT DELAY JMP DELAY RINGBK: POP PSW ;TO GET IT OFF THE STACK LDA CMDBUF+1 ;GET # OF CHAR IN BUFFER SUI 01 ;SUBTRACT 1 TO AVOID THE RINGBACK CHAR STA CMDBUF+1 ;STORE ORA A ;SET FLAGS JNZ GETCMD ;KEY PRESSED, GO GET OPTIONS MVI A,BELL CALL TYPE ;RING BELL mvi b,5 call timer jmp dilagn1 ; ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH ; SETFCB: LXI D,CMDBUF LXI H,FCB CALL CPMLINE CALL PROCOREG'S CALL STAT ;KEYPRESS? ORA A ;SET FLAGS CNZ KEYIN ;YES, GET CHAR CPI CAN ;^X? JZ WAIT1 ;YES, DISCONNECT, JMP TO MENU POP D ;RESTORE.. POP B ;..REGS DCR C ;COUNT-DOWN JNZ WAIT STC ;SET CARRY TO INDICATE MASK NOT SET RET WAIT1:EFT INTO ACC. CPI 01H ;IS THIS THE LAST CHARACTER? JZ RINGBK ;IF SO, IT MUST BE RINGBACK CHAR - DO RINGBACK POP PSW ;EVERYTHING BACK AS IT WAS DIAL1: CPI 3AH RNC ;..AND NOT MORE THAN 9 ANI 0FH ;STRIP ASCII -- COULD ALSO DO SUI 30H ('0') JNEDIAL FLAG DILAGN0: MVI B,100 ;10 second wait for hayes reset CALL TIMER ;else busy tone may be sensed as dialtone lxi h,cmdbuf+1 ;we need to see if menu choice was made mov a,m ;or was CAL A typed cpi 4 jc DIALlp1 ;this is for menu cJMP DILAGN ;YES, MUST BE BUSY RNGBK1: CALL HANGP ;HANG UP THE PHONE MVI B,RBWAIT ;WAIT X SEC CALL TIMER CALL DIALPL0 ;GO OFF HOOK & LISTEN FOR DIAL TONE JNC DIALLPX ;GO REDIAL NUMBER JMP DILAGN ;NO DIAL TONE HEARD RBTIME: CALL CRLF JMP RNGBK1THE NEW VALUE MVI D,DTMSK ;LOAD TONE DETECT MASK MVI C,RBLMT ;SET TIMER FOR RBLMT NUMBER OF SECONDS CALL WAIT JC RBTIME ;JUMP IF NO RING DETECTED MVI B,25 ;WAIT 2.5 SEC CALL TIMER CALL IN$BAUDRP ;IS TONE STILL PRESENT? ANA D JNZ RNGBK1 ;..RECV OPT DOES NOT NEED.. RZ ;..NAME. JMP CKFILE BDOPT: CALL ILPRT DB CR,LF,'++Bad Option++',CR,LF,0 JMP REENT CKFILE: LDA FCB+17 ;IF OPTION THAT NEEDS FILE NAME,.. CPI ' ' ;..THEN CHECK TO SEE IF NAME.. RNZ ;..EXISTS. IF NOT.. REENT: CCAL - Dial number',CR,LF DB ' CPM - Exit to CP/M without disconnect',CR,LF DB ' DEL - Erase present file (from terminal mode)',CR,LF DB ' DIR - List directory (may specify drive)',CR,LF DB ' DSC - Disconnect but stay in MODEM DCRC: EQU $ ;Update CRC Accumulator using byte in (A). PUSH PSW PUSH B PUSH H MVI B,8 MOV C,A LHLD CRCVAL ; UPDLOOP: MOV A,C RLC MOV C,A MOV A,L RAL MOV L,A MOV A,H RAL MOV H,A JNC SKIPIT MOV A,H ;The generator is X^16 + X BAUD RATE JNZ CONNEWB ;GOES TO THE ESTABLISHED ROUTINE - RETURN TO MAIN CALL CRLF ;PROGRAM IS DONE THERE. JMP SETBAUD CONNEWB: CPI 30H ;MAKE SURE IT'S.. JC LOOP5 ;..A DIGIT, ELSE.. CPI 3AH ;..DON'T ACCEPT IT. JNC LOOP5 MOV M,A MOV C,A OR NEW FILE TRANSFER. MVI B,SECTNOE-SECTNOB CALL MOVE LXI H,RESTROPT ;RESTORE OPTION TABLE LXI D,OPTBL MVI B,OPTBE-OPTBL CALL MOVE MVI A,0 STA MFFLG1 ;RESET MFACCESS ROUTINE.. CMA ;..AND MULTI TRANS IN CASE.. STA FSTFLG ;..OF ABORT. ;gned & coded by Paul Hansknecht, June 13, 1981 * ;* * ;* Copyright (c) 1981, Carpenter Associates * ;* Box 451 * ;* Bloomfield Hills, MI 48013 * ;* 313/855-3074 * ;* * ;* This program may be freely reproducedALL ILPRT ;..DO EVERYTHING OVER. DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0 LXI D,CMDBUF CALL INBUFF JMP SETFCB TERMSEL: LDA FCB+17 CPI ' ' JNZ SAVAGN MVI A,FALSE STA SAVEFLG MVI A,TRUE STA NFILFLG CMA RET SAKIPIT: DCR B ;and XOR 05H for XOR 21H in the adjacent code. JNZ UPDLOOP SHLD CRCVAL POP H POP B POP PSW RET ; FINCRC: EQU $ ; Finish CRC calc for outbound message. PUSH PSW XRA A CALL UPDCRC CALL UPDCRC PUSH H LHLD CRCVAL MOV ^12 + X^5 + 1 XRI 10H ;as recommended by CCITT. MOV H,A ;An alternate generator which is often MOV A,L ;used in synchronous transmission protocols XRI 21H ;is X^16 + X^15 + X^2 + 1. This may be MOV L,A ;used by substituting XOR 80H for XOR 10H S CALL TYPE ;ECHO THE CHARACTER ENTERED INX H JMP LOOP5 ; ;**************************************************************** ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20 * ;* 8080 Mnemonics * ;* * ;* These subroutines MENU1: ; IF MODOUT ; CALL ILPRT DB CR,LF DB '>MODOUT< ^W=toggle savefile ^\=return to Host ',cr,lf,0 ; ENDIF ; LDA XPRFLG ;TEST IF MENU SHOULD BE SHOWN ORA A JNZ COMD ;IF FLAG SET TRUE ; MENU2: CALL ILPRT DB CR,LF DB ' for non-profit use. * ;* * ;**************************************************************** ; ; ENTRY CLRCRC,UPDCRC,FINCRC,CHKCRC ; CLRCRC: EQU $ ;Reset CRC Accumulator for a new message. PUSH H LXI H,0 SHLD CRCVAL POP H RET ; UPVAGN: MVI A,FALSE STA NFILFLG RET NEWBAUD: CALL ILPRT DB 'Enter New Baudrate, (300-450) : ',0 LXI H,FCB+9 MVI M,0 ;PUTS A ZERO IN FIRST POSITION SO AS TO LOOP5: CALL KEYIN ;FORCE THE DEFAULT OPTION OF 300 BAUD. CPI CR ;CARRIAGE RET ENTERSD,H MOV E,L POP H POP PSW RET ; CHKCRC: EQU $ ; Check CRC bytes of received message. PUSH H LHLD CRCVAL MOV A,H ORA L POP H RZ MVI A,0FFH RET ; CRCVAL: DW 0 ; MENU: LXI H,RESTSN ;RESTORE SECTORE NUMBERS.. LXI D,SECTNOB ;..F error bits, all burst errors of length 16 or * ;* less, 99.9969% of all 17-bit error bursts, and 99.9984% * ;* of all possible longer error bursts. (Ref: Computer * ;* Networks, Andrew S. Tanenbaum, Prentiss-Hall, 1981) * ;* * ;* Desiwill compute and check a true 16-bit * ;* Cyclic Redundancy Code for a message of arbitrary length. * ;* * ;* The use of this scheme will guarantee detection of all * ;* single and double bit errors, all errors with an odd * ;* number ofprogram',CR,LF DB ' HLP - Show Secondary options',CR,LF DB ' LOC - Toggle local echo on/off',cr,lf DB ' LOG - Log new disk and/or drive',CR,LF DB ' LST - Toggle LST: device on/off',cr,lf DB ' OFF - Exit to CP/M with phoneL.. POP H ;..TO CHAR IN A-REG. JC MENU1 ;CARRY SET = NO MATCH DOOPT: PUSH H ;LOAD ORIGINAL FCB WITH TRANSFER.. CALL SETFCB ;..CMDS AND GO TO BEGINNING OF.. POP H ;..PROGRAM. WILL FOLLOW SAME LOGIC.. JMP RESTART ;..AS IF PROGRAM WERE CALLED WI,CURDSK ;CURRENT DISK FUNCTION CALL BDOS ADI 41H ;MAKE ASCII CALL TYPE CALL ILPRT ;command line prompt to be "A-]" DB '-]',0 GETCMD: LXI D,CMDBUF ;ENTER COMMAND CALL INBUFF LXI D,CMDBUF+2 ;POINT TO COMMAND ; IF SELMODE ; CA echo',CR,LF DB ' ? - Display current status',cr,lf,0 ; JMP COMD ; OPTLST: CALL CRLF CALL ILPRT DB 'These options are useable in TERMINAL mode',cr,lf,cr,lf DB ' ^T = send ASCII file without checks',cr,lf DB ' ^S = XOFF c ILCOMP DB 'DSC',0 ;DISCONNECT PHONE JNC DISCON1 CALL ILCOMP DB 'WRT',0 ;WRITE TEMP FILE TO DISK JNC WRTFIL CALL ILCOMP DB 'XPR',0 ;TOGGLE EXPERT MODE JNC XPRMODE CALL ILCOMP DB 'DEL',0 ;DELETE CURRENT SAVE FILE JNC NEWFILE CALLVE or SEND modes:',cr,lf,lf DB ' O = Originate',cr,lf DB ' A = Answer',cr,lf DB ' Q = Quiet (suppresses echo to CRT)',cr,lf DB ' P = Parity select: 0=Even 1=Odd',cr,lf DB ' B = Batch mode',cr,lf DB ' C = CRC disconnect',CR,LF ; IF SELMODE ; DB ' PAR - Select Data and Parity Mode',cr,lf ; ENDIF ; DB ' RET - Return to terminal mode - no data loss.',CR,LF DB ' WRT - Write file to disk (from terminal mode)',CR,LF DB ' XPR - TogSET DISK READ/WRITE STATUS JNC LOGNEW CALL ILCOMP DB 'CPM',0 ;GOTO CPM, NO DISCONNECT JNC EXIT0 CALL ILCOMP DB 'OFF',0 ;Goto CPM with disconnect JNC DISCON2 CALL ILCOMP DB 'HLP',0 ;SHOW SECONDARY LISTINGS JNC OPTLST CALL ILCOMP DLL ILCOMP DB 'PAR',0 JNC SETPAR ; ENDIF ; call ilcomp db '?',0 ;Show status jnc sstat call ilcomp db 'LOC',0 ;Toggle local echo jnc loctogl call ilcomp db 'LST',0 ;Toggle LST: device jnc lsttogl CALL ILCOMP DB 'LOG',0 ;REharacter',cr,lf DB ' ^Q = XON character',cr,lf DB ' ^^ = force send of next character',cr,lf DB ' ^Z = end of file',cr,lf DB ' ^B = Send 450ms Break',cr,lf ; IF MODOUT ; DB ' ^L = disconnect phone & return to HOS ILCOMP DB 'CAL',0 ;CALL NUMBER JC NXTOPT2 MVI A,20H ;FOOL THE SYSTEM... STA CMDBUF+4 ;..CMDBUF SO THAT IT.. JMP DOOPT ;..LOOKS AT OPTION FOR DIAL NXTOPT2: PUSH H LDA CMDBUF+2 LXI H,COMPLIST CALL COMPARE ;COMPARES LIST POINTED TO BY HOption',cr,lf,0 ; COMD: CALL CRLF LDA SAVEFLG ;IF FILESAVE ACTIVE... CPI FALSE ; JZ S3 ; CALL ILPRT ;...THEN FORCE BUFFER SHOW DB 'Buffer (',0 CALL GETSPC ;GET FREE SPACE CALL DECOUT ;RESULT BACK IN HL CALL ILPRT DB ') ',0 S3: MVI Cgle expert mode (Menu on/off)',CR,LF DB ' M - Show this Menu',CR,LF DB ' S - Send CP/M file',CR,LF DB ' R - Receive CP/M file',CR,LF DB ' T - Terminal mode (optional file name)',CR,LF DB ' E - Terminal mode withB 'DIR',0 ;LIST DIRECTORY JNC DIR CALL ILCOMP DB 'RET',0 JC NXTOPT1 ;CARRY SET = NO MATCH RET1: LDA ORIGSAV STA ORIGFLG LHLD HLSAVE ;RETURN TO TERMINAL.. JMP TERM ;..MODE WITH SAVE OPTION.. ;..IF PREVIOUSLY ENABLED. ; NXTOPT1: CALL ' ^E = return to MODEM program',cr,lf DB ' ^Y = toggle savefile on/off',cr,lf DB ' ^P = change baud rate on the fly',cr,lf ; ENDIF ; DB ' [Baud rates are 300,and 450]',cr,lf,lf DB 'These options are used with RECIET CP/M',cr,lf DB ' ^\ = return to MODEM program',cr,lf DB ' ^W = toggle savefile on/off',cr,lf DB ' ^R = change baud rate on fly',cr,lf ; ENDIF ; IF NOT MODOUT ; DB ' ^D = disconnect phone & return to CP/M',cr,lf DBTH.. ;..CP/M COMMAND LINE. sstat: call ilprt db cr,lf,'LST device :',0 lda lstflg ;check for LST:... cpi false ;...active jz lstn ;nope call ilprt db 'On',0 ;yes, show LST: active jmp sloc lstn: call ilprt db 'Off',0 sloc: call iy, 1 Stop',CR,LF,0 AGAIN: CALL ILPRT DB CR,LF,'Enter Choice (A - H): ',0 CALL KEYIN CALL TYPE PUSH PSW CALL CRLF CALL UCASE CPI 'A' JZ PARIA CPI 'B' JZ PARIB CPI 'C' JZ PARIC CPI 'D' JZ PARID CPI 'E' JZ PARIE CPI 'F'NEWFILE: LDA FCB3+1 CPI ' ' JZ MENU1 ;IF NO FILE, DON'T ERASE LXI D,FCB3 MVI C,ERASE CALL BDOSRT MVI A,TRUE ;DO NOT ALLOW TERMINAL.. STA NFILFLG ;..SAVE SINCE NO FILE.. CMA ;..SPECIFIED. STA SAVEFLG LXI H,FCB3 CALL INITFCBS JMP Mcall ilprt db cr,lf,'Local Echo is now ',0 lda locflg cma sta locflg cpi false jz lo1 call ilprt db 'On',cr,lf,0 jmp comd lo1: call ilprt db 'Off',cr,lf,0 jmp comd lsttogl: call ilprt db cr,lf,'LST device is now ',0 lda lstfLID: RET COMPLIST: DB 5, 'S', 'R', 'T', 'E', 'M' ; IF SELMODE ; SETPAR: CALL ILPRT DB CR,LF DB 'Select Mode from the following:',CR,LF,CR,LF DB ' A. 7 Data, Even Parity, 2 Stop',CR,LF DB ' B. 7 Data, Odd Parity, 2 Stop',CR,LF DB ' E IT... MVI C,CURDSK ;...OTHERWISE GET CURRENT DISK CALL BDOS ; ADI 41H ;MAKE IT ASCII S6: PUSH PSW ;SAVE IT CALL TYPE S7: CALL ILPRT DB CR,LF,'Hit return when ready...',0 CALL KEYIN ;GET CONSOLE RESPONSE CPI CR ;IS IT A ? JNZ S7lprt db cr,lf,'Local Echo :',0 lda locflg ;check for local... cpi false ;...echo active jz locn ;no call ilprt db 'On',0 ;yep jmp ssav locn: call ilprt db 'Off',0 ssav: call ilprt db cr,lf,'Save Buffer :',0 lda saveflg cpi false FLG CMA STA SAVEFLG LXI H,BOTTRAM ;RESET BUFFER COUNTER SHLD HLSAVE LXI H,FCB3 CALL INITFCBS ;BLANK OUT FCB SO WRITTEN FILE.. JMP MENU1 ;..CAN'T BE ERASED. XPRMODE: LDA XPRFLG CMA STA XPRFLG JMP MENU1 COMPARE: MOV B,M ;COMPARES AENU1 WRTFIL: LDA NFILFLG CPI TRUE JZ MENU1 LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED CPI ' ' JZ MENU1 LHLD HLSAVE CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN.. CALL WRTDSK ;..IN THE INTDSKSV ROUTINE. CALL CLOSE3 MVI A,TRUE STA NFILlg cma sta lstflg cpi false jz ls1 call ilprt db 'On',cr,lf,0 jmp comd ls1: call ilprt db 'Off',cr,lf,0 jmp comd SHOBUF: CALL CRLF CALL GETSPC ;GET FREE SPACE CALL DECOUT ;RESULT BACK IN HL CALL ILPRT DB ' Bytes free in buffeC. 7 Data, Even Parity, 1 Stop',CR,LF DB ' D. 7 Data, Odd Parity, 1 Stop',CR,LF DB ' E. 8 Data, No Parity, 2 Stop',CR,LF DB ' F. 8 Data, No Parity, 1 Stop',CR,LF DB ' G. 8 Data, Even Parity, 1 Stop',CR,LF DB ' H. 8 Data, Odd Parit ;NOPE, ASK AGAIN MVI C,RSET ;GET RESET FUNCTION CALL BDOS POP PSW ;GET DISK BACK SUI 41H ;JUST THE DRIVE CODE MOV E,A MVI C,SELCT ;GET SELECT FUNCTION CALL BDOS ;DO IT CALL CRLF JMP COMD ;ALL DONE DIR: CALL DIRLST JMP COMD jz savn call ilprt db 'Active',0 jmp sbuf savn: call ilprt db 'Inactive',0 sbuf: call ilprt DB cr,lf,'Buffer has ',0 CALL GETSPC ;GET FREE SPACE CALL DECOUT ;show it in decimal CALL ILPRT DB ' bytes free',cr,lf,0 jmp comd loctogl: -REG WITH LIST.. COMPLP: INX H ;..ADDRESSED BY HL. FIRST ELEMENT.. CMP M ;..OF LIST MUST BE NUMBER OF ELEMENTS.. JZ VALID ;..BEING COMPARED. RETURNS WITH.. DCR B ;..CARRY SET IF A-REG DOES NOT.. JNZ COMPLP ;.. CONTAIN AN ELEMENT IN LIST. STC VAR,LF,'>> HOST Outgoing <<' ; ENDIF ; DB 'Line DISCONNECTED',CR,LF DB 'Returning to CP/M',CR,LF,BELL,0 JMP EXIT ; LOGNEW: CALL ILPRT DB CR,LF,'Insert disk for drive ',0 LDA CMDBUF+6 ;LOOK FOR SPECIFIED DRIVE CPI 20H JNZ S6 ;YEP, SO USr',CR,LF,0 JMP COMD DISCON1: CALL DISCONNT CALL ILPRT DB CR,LF,'<< Disconnected >>',CR,LF,BELL,0 MVI A,FALSE STA LINFLG JMP INQUIR ;CHECK FOR FILE SAVE ACTIVE, RETURN TO MENU DISCON2: CALL DISCONNT CALL ILPRT ; IF MODOUT ; DB C JZ PARIF CPI 'G' JZ PARIG CPI 'H' JZ PARIH JMP AGAIN ; PARIA: MVI A,01H JMP PARICOM PARIB: MVI A,05H JMP PARICOM PARIC: MVI A,09H JMP PARICOM PARID: MVI A,0DH JMP PARICOM PARIE: MVI A,11H JMP PARICOM PARIF: MVI A,15H JMP PARееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееB 0FFH ;first SOH received switch(it is zero after 1rst SOH) ; CMDBUF: DB 80H,0 DS 80H BADLIB: DB CR,LF,'++Bad library number called++',CR,LF,'$' HLSAVE: DB 2 ACSAVE: DB 1 DISKNO: DS 1 SENDFLG: DS 1 NBSAVE: DS 2 BGNMS: DS 2 FILECT: DS 1 N; ;******************************************************* ; ILCOMP: INLNCOMP ;A MACRO IN MACROS.LIB ; INBUFF: INBUF ;A MACRO IN "MACROS.LIB" ; ;IF ABOVE ROUTINE DOES NOT LET YOU EDIT IN A PROPER MANNER, ;THEN THE MACRO MAY BE SUBSTITUTED FOR THE F; LAST END 100H IZ EQU 35 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 FCBRNO EQU FCB+32 FCB2 EQU 6CH INITIALLY CALLED. ; RESTROPT: ;MUST BE IN SAME ORDER AS TABLE ABOVE ; DB 'A','D','O','Q','R','S','V','T','C','0','1','B' ; RESTSN: DB 0,0,0,0,0,0 DW DBUF DB 0,0,0,0,0 ; SECTNOB: EQU $ RCVSNO: DB 0 SECTNO: DW 0 ERRCT: DB 0 ERRCDE: DB 0ICOM PARIG: MVI A,19H JMP PARICOM PARIH: MVI A,1DH PARICOM: CALL OUT$MODCTLP STA parctlb JMP PASOK ; ENDIF ; ;******************************************************* ;Start Data Parity Stop Value for OUT$MODCTLP ; ; 1 7 even 2 ....*1024) ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS.. ;..ABOVE PROGRAM CODE. ; ;BDOS EQUATES ; RDCON EQU 1 WRCON EQU 2 LSTOUT EQU 5 PRINT EQU 9 RDBUF EQU 10 CONST EQU 11 RSET EQU 13 SELCT EQU 14 OPEN EQU 15 CLOSE EQU 16 SRCHF EAMECT: DS 1 ORIGSAV: DS 1 ;SAVE ORIGFLAG FOR RET MODCTLB: DB 8fH parctlb: db 15h uartflg: db 0ffh UARTCTLB: DB 8fH ; @7.5 (was previously ORIGMOD) DS 050H STACK: DS 2 FCB3: DS 33 FCBBUF: DS 15 DBUF: EQU $ NAMEBUF: EQU DBUF+(DBUFSIZOLLOWING ROUTINE: ; ;INBUFF: ; MVI C,RDBUF ; CALL BDOSRT ; RET ;BUT BE CAREFUL OF CONTROL-C CPMLINE: CMDLINE ;A MACRO IN "MACROS.LIB" ; DIRLST: DIRLIST ;A MACRO IN "MACROS.LIB" ; NFILFLG: DB FALSE ;NORMALLY SET TO FALSE. ALLOWS WRITE TO.. ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее EOFLG: DB 0 SECPTR: DW DBUF SECINBF: DB 0 MAXEXT: DB 0 RCNT: DW 0 DATAFLG: DB 0 EXACFL: DB 0 SECTNOE: EQU $ ; BADOPT: CALL ILPRT DB 'Invalid option',CR,LF,BELL,0 JMP MENU ; FSTFLG: DB TRUE LINFLG: DB FALSE DSKSAV: DS 2 FIRSTME: D........ 01h ; 1 7 odd 2 ............ 05h ; 1 7 even 1 ............ 09h ; 1 7 odd 1 ............ 0Dh ; 1 8 none 2 ............ 11h ; 1 8 none 1 ............ 15h ; 1 8 even 1 ............ 19h ; 1 8 odd 1 ............ 1Dh QU 17 SRCHN EQU 18 ERASE EQU 19 READ EQU 20 WRITE EQU 21 MAKE EQU 22 REN EQU 23 CURDSK EQU 25 STDMA EQU 26 FILSIZ EQU 35 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 FCBRNO EQU FCB+32 FCB2 EQU 6CH Y: DB '0' ;EVEN PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES OPARITY: DB '1' ;ODD PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES BATCHFLG: DS 1 ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-.. OPTBE: EQU $ ;..FILE XFER WHEN PROGRAM ;..MEMORY IN TERMINAL MODE. ; OPTION: DB 0 OPTBL: EQU $ ANSWFLG: DB 'A' DISCFLG: DB 'D' ORIGFLG: DB 'O' QFLG: DB 'Q' RSEEFLG: DB 'R' SSEEFLG: DB 'S' VSEEFLG: DB 'V' TERMFLG: DB 'T' CRCFLG: DB 'C' ;use CRC instead of cksum EPARIT; ; APMOD777.HIS history file ; ; Last update 11/25/82 ; ; ;The OUT MODEM program is an update of MODEM75.ASM with ;changes as noted. See also MODEMOUT.DOC. It is designed to be ;used as a second modem program,his routine is some ; what long in code it is a "boiler plate" routine insuring ; that the MicroModem is always initialized as follows: Upon ; first entering the program primary baudrate (for an unmodi- ; s not off the hook now until ; the user dictates the selection. Thanks to Mark Pulver for ; his great ambitions for Apple R/CPM materials, and Elliot Jolesch ; and Chris Neal for their inspiration of the idea. ; OUTINES FOUND IN THE POTOMAC MICRO-MAGIC MODEM ;MANUAL WHICH MAY BE USED IF YOU HAVE A PMMI MODEM BOARD. ; ;THE ADDITIONAL ROUTINES ARE COPYRIGHTED (1980) BY: ; ;Mark M. Zeiger and James K. Mills ;198-01B 67th Ave. 824 Jordan Place ;Flushing, N.Y.efault drive and to log in a new disk. ; Thanks to Sidney Bratkovich for sharing his thoughts. Distributed ; as APMOD773.DIF for use with APMOD77X.ASM and the SSED routine. ; ; Mark J. Pulver (312) 789-0499 ; ff. "?" to show a status ; display of local echo, LST device, capture buffer, and bytes ; free in buffer. Minor cosmetic changes to messages. ; Moved all revisions messages to APMOD775.HIS ; ; Mark J. Pulver - AIMS (312) 789-0499 ; ;10but if compiled with the ;equate for MODOUT equal to FALSE it will be a normal ;modem program. I suppose it could be called MODEM77. I ;suggest that future changes be made using the DIF method with ;MODOUT1.ASM as the base file for features to be ;addMI ; in respect to features. Also cleaned out respective routines. ; Fixed logic problem at NOCOLON with respect to savccp on/off. ; Modified command line cosmetics, repaired kludging to command ; line search for xprt mode. MODEM R NAM.TYP, -David Howard (214)620-7751 ; ;09/12/82 Time for some general housecleaning. Stripped out FRONTPAN, ; PMMIBYTE, and IMSAIBYTE. It's my guess that an Apple will never ; have a front panel, and the MM][ will always look like a PM 11365 Rockford, IL 61108 ;(212) 454-6985 (815) 398-0579 ; ;Modified routines Copyrighted (1982) by ; ;Hal Walchli, W3TWI ;1329 Foxboro Drive ;Monroeville, Pa. 15146 ;(412) 372-3674 ; ;Permission is granted to use, but not to sell, these rout AIMS 300-450 baud ; ;6-6-82 Re-wrote INITMOD to provide more consistent initialization of ; the DC Hayes MicroModem ][. The routine used is essentially ; the one that I used in APMDM72. While t/02/82 Rewrote the DIAL routine to prevent phone from being off the ; hook, while decisions were being made as to desired phone ; number in library. Some GTE systems time out too quickly if ; user doesn't dial soon. Phone ied that are not wanted for normal modem use as the file ;is getting quite long. [Hal Walchli,W3TWI] ; ; ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY. ;IT ALSO INCORPORATES R MODEM S NAM.TYP, etc. ; now work as originally intended. Added BUF command, and buffer ; sense logic to COMD, to show buffer status. Added LOG command, ; use LOG to log a new disk into the current drive, or LOG x to ; change the current duld be redialed. All ; worked well if a menu choice was made instead. Also made ; some cosmetic and time out value changes. ; MJP ; ;10/17/82 Added 3 new commands. LOC to toggle local echo on/off. ; LST to toggle LST device on and oines. ; ;2/8/83 (WLS) ; ADDED CONDITIONAL ASSEMBLY FOR THE PCPI APPLI-CARD ; ;11/25/82 - Fixed an obscure bug in the DILAGN0 routine. If "Y" or ; "C" was the response to "...Redial...", and ; was used, then library entry "C" wo fied modem 300), originate mode, 8 data bits, and one stop ; bit. Any of these parameters can be changed at will. Once ; changed the new parameters are in effect until they are ; changed again or hang up. PARIT in DONETCE caused a computer that was ;in answer mode (but not explicitly by command option) to switch ;to originate mode thus causing the two ends to no longer communicate ;with each other. Also added SAVCCP byte and code to prevent ;overwritinLF to the NEWBAUD ;message. ; R.L.Berg ; ;4/08/82 - Added modifications of MODEM75.FIX with minor changes ;and that of MODEM76 by R. Ratoff. Changed directory to XXXX to ;minimize CRCK problems with souce code copies. Added 'HLP' option ;for heak is sent. ; ; Changed the code in the the dialing routine, starting at ; DIALPL, to that which was used in APMDM72. This is necessary ; to work with the changes at INITMOD. Also corrected various ; equaquate for WAITCTS to a smaller ;number. Seems to take up to 40 seconds on some calls. [HEW] ; ; 3/01/82 - ;Added INQUIR routine to give notice ;and the option to write the temporary file to disk. I forgot it ;too many times. Anything but WRT or RET w in here too. ; ; -Mark J. Pulver (312)/789-0499 ; ;04/29/82 Changes at TERM, START1 and OPTCK marked by ; @7.61 ;fix a bug that causes abort at the end of a file transfer if ;the ogiginate 'O' or the answer 'A' chaAt hang up the modem will be ; returned to originate mode, primary baudrate but the parity ; will and bit configuration will remain as last used. If you ; wish to have it default back to 8 data bits one stop bits that would make this ;listing too long if included here. ;Major changes are:deleted XPRT for automenu, added notice to print ;saved file, added OFF function, changed necessary characters for ;use as outmodem, disconnect warning on return to CP/M, lp on secondary commands. ; ;3/18/82 Initial issue of this program for use with a remote ;HOST computer system running CPM with BYE. ;This program will allow a second modem board (PMMI) to be used to make ;an outgoing call. See MODEM77.DOC for detailtes to function properly with the MicroModem. ; ; Bill Cook ; 201-767-0176 ; ;5/10/82 - Re-worked routines for the Apple with a Hayes MM ][. ; Preserved all previous modifications/adill cause loss of the ;savefile. [HEW] ; ;2/20/82 Changes at TERM and START1 marked by ; @7.5 fix a ;long standing bug in MODEM7x that causes abort at the end of a ;batch file transfer or an attempt to transfer a non-existent ;file. The call to NOracter was not entered ;after the 'T' term character when switching between term and ;menu. Now the ogiginate or answer character has to only be ;entered once when comunications is first established. Also ;changed the MACLIB mico to MODEM75. Added CR, ; change the MVI A,PARCTLB in the dialing routine to MVI A,15H. ; ; Changed the "Break Key" to ^B to avoid conflict with certain ; 80 column boards. Also corrected the code so that a 450 ; millisecond brerevised Menu. ;Added HLP routine,added Data & parity selection all modes(for Univac), ;password for modout use. [Hal Walchli,W3TWI-HEW] ; ;03/05/82 Increased the 25 second 'wait' after autodial to a longer ;time by repeating cycle and changing e (PMMI dial, etc). Baud ; rate change now for 110-300, or 300-450 with modified ; MM ][. Kept library list for local callers, (312 area). ; Thanks to Dav Holle for his time spent on APMODEM70, a ; lot of that code isditions, with ; the exception of autoselect on parity due to the MM ]['s ; lack of a parity byte. Code does support the MODOUT ; option. Cleaned up file from floating code that would ; never be used in an Apple sys,g of the CCP at the users option. R. L. Plouffe ; ;1/23/82 The following changes have been made in this version. ; RLP ; ;Extensive cleanup of the file including colons after all labels ;for easier search with screen editor for the purpse of the parity feature will slow ; transfers slightly due to the extra (parity) bit being sent with ; each character. Also this is the only program that I KNOW OF that ; actually sends, or sets up the PMMI to receive, the parity bit. ; Both ehen MODEM7 has specified a CRC ;transmission. (John Mahr) ; ;11/21/81 Fixed code so byte received is on same line when ; messages "XXH RCD, NOT SOH" or "XXH RCD, NOT ACK" ; are displayed. Also changed stack size to 50H. ; (P.L.Kelley) however, the "n" will simply be ignored. This is because ;routine DIALPL checks for a command length >= 4 as a signal to ;skip the library display, but the menu routine, after ;recognizing CAL, sets the length to 1 so the L in CAL doesn't ;look like ode (for ctl-E,ctl-D) (WDE) ; ;07/05/81 Added BRR ctrl char chgs, my number list (Bill Earnest) ; ;06/05/81 Deleted some unneeded messages in the dial routines. (Bob Clyne) ; ;05/31/81 Added detection of framing, overrun, and parity errors for ; R9/81 Changed receive sector routine so that on the first ;time through when CRC is being used, it only waits 3 seconds ;to receive the SOH after sending the initial 'C'. If a ;character is not received within 3 seconds, then a NAK is ;sent and this proses of debug. ;Also set file capture mode so as not to overwite the CCP and ;changed EXIT to return to the CCP instead of doing warm boot. ; ;TERML routine fix: ;Added Rick Kawala's fix so that fewer framing errors will occur ;with hosts that send o. 'C' is ;sent in place of the initial NAK. This signals the sender ;(XMODEM54 or equiv.) that CRC is in effect. The sending ;program will repalce the checksum with the CRC 2 bytes. ;CRC will give better than a 99.99% probability that there ;are no d ; ;10/18/81 Added CRC option. This is another secondary option ;that is specified by giving a 'C'. ; MODEM RC.600 fn.ft ; MODEM ROC.300 fn.ft etc. ; note: cannot have more than 6 secondary options. ;When the file receive cmd. specifies CRC, the ltran illegal secondary option. ; The following kludge repairs this defect. In routine ;DIALPL, two lines above label DIALPL0, change CMDBUF+5 to ;CMDBUF+6. Also, in routine GETCMD, three lines above label ;NXTOPT2, change MVI A,1 to MVI A,20H and chaeceive file routine. (A modified version of the routines in ; MODEM V2.06) ; ; Added provisions to send and receive either even or odd parity ; bit with PMMI modem in the 'S'end or 'R'eceive file modes - resets ; to no parity in other modes. Uogram switches to CHECKSUM mode. The sending ;of the NAK causes XMODEM or MODEM to start sending the file ;using checksum checking. This allows the CRC MODEM7 program ;to be used with versions of XMODEM, MODEM, and MODEM7 that ;do not use CRC, even wut characters with high bit set. ; ;CAL command fix: ; All versions of MODEM7 including MODEM73 are supposed to be ;able to accept "CAL n" (where n is either a library letter or ;a phone-number string) as a valid form of the CAL command. In ;fact,ata errors. Code copied from MODEM213, thanks to ;John Mahr and Paul Hansknecht for the implementation. (WDE) ; ;10/11/81 Add first NAK to RCVFIL to speed up start ;Removed monitor scroll from good block messages ;CTL-^ forces send of next char in T mr is used, ;you have to type an extra blank: CAL 000-0000, whereas ;with library numbers one blank only must be typed: CAL A. ; ;12/16/81 Removed stack imbalance bug at COLONB by adding ; a JMP BRK1. Change is marked by ;@ R. L. Plouffe ; ;10/2nge the next line ;from STA CMDBUF+1 to STA CMDBUF+4. This makes the command ;look to the option processor like "CA n", and since A is a ;legal secondary option (which in this case is never used) the ;line passes muster. If an actual telephone numbends must be set to the same parity for it to work. Parity ; is invoked by adding a '0' (ASCII) for even parity or a '1' (ASCII) ; for odd parity to the 'S'end or 'R'eceive command string eg. R0.600. ; ; Changed timing for sending 'B'reak in the tA INX H ;ADDRESS COUNT CMP M ;COMPARE COUNT TO MAXIMUM JC ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR XCHG ;RESTORE BUFFER POINTER TO HL MOV M,B ;PUT INPUTTED CHARACTER IN BUFFER MOV A,B ;OUTPUT IT CALL CONOUT INX H ;BUMP POINTER J OUTPUTS BELL IF INPUT GREATER THAN BUFFER ; 2) CMDLINE - PARSES A CP/M BUFFER INTO FORMAT SAME AS ; CP/M COMMAND LINE. ; 3) INLNCOMP - COMPARES STRINGS FOLLOWING CALL TO 'ILCOMP' ; TO STRING ADDRESSED BY DE REGS. ; 4) MULTNAME - Mher phone is ringing ; though so it is a little shakey. ; ; Put in routines to calculate file sizes and sector numbers in ; decimal. ; ; Put in code to transmit a "BREAK" with a PMMI for use with ; computers which use BREAK instead of ContRL-H WILL BACKSPACE.. JZ DELETE ;..OVER DELETED CHAR. CPI 'U'-40H ;IS IT A CTRL-U JZ INBUFO ;OUTPUT # CR LF AND START OVER CPI 'R'-40H ;CTRL-R RETYPES LINE JZ RETYPE CPI 'E'-40H JZ PCRLF CPI 20H ;NO CONTROL CHARACTERS OTHER.. JC INBUFA ;ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееerminal mode. ; ; Changed the code so that the 'M'enu command works from the keyboard ; even when in XPR (expert) mode. ; ; Added display of hex in addition to decimal numbers for file length ; and sector numbers. ; ; Removed provision foONIN1,CONOUT1,NOUCASE,CTLRLP LOCAL CONSTAT,CONST1,CONINLP PUSH PSW PUSH H PUSH B PUSH D ;DE REGISTERS MUST BE PUSHED LAST START CALL CLEAR ;CLEAR THE BUFFER AREA POP D ;GET ADDRESS OF BUFFER ON RETRIES PUSH D ;RESTORE STACK XRA A INULTI-FILE FILE ACCESS ROUTINE FROM ; CP/M USERS GROUP. ; 5) DIRLIST - LISTS DIRECTORY INBUF MACRO ;NO PARAMETERS USED. LOCAL START,INBUFO,INBUFA,DELETE,NODEL,ALERT LOCAL INBUFLT,CLEAR,CLEARL,INBUFR,RETYPE,BKSPC,PCRLF LOCAL CONIN,CONOUT,Crol S to suspend ; output. Control P is now the baudrate change request key ; and Control @ is the BREAK key.. (Bob Clyne) ; ;12/18/80 Changed disconnect timing. ; ;10/26/80 Minor revision to allow 25-second 'wait' after PMMI ; autodial -- l..THAN ABOVE ALLOWED. MOV B,A ;SAVE INPUTTED CHARACTER XCHG ;SAVE HL IN DE POP H ;GET ADDRESS OF BUFFER IN HL PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT BYTE INR M ;INCREASE COUNT BYTE DCX H ;ADDRESS MAXIMUM MOV A,M ;PUT MAXIMUM IN ;MACROS LIBRARY FOR CP/M ROUTINE SIMULATION 10/15/80 ;CONTAINS: ; 1) INBUF - DUPLICATES READ BUFFER ROUTINE ; SAME AS CP/M FUNCTION 10, BUT DOES ; NOT USE CTRL-C (REASON FOR ROUTINE). ; DOES ALLOW CONTROLS U, R, E, AND H (BACKSPACE). ;r remote cancel of file transfers in the 'S'end ; and 'R'eceive modes to prevent line noise from aborting a transfer. ; (Bob Clyne) ; ;02/15/81 Patched in the ringback routines from DIAL6/23. It doesn't ; seem to be able to recognize when the otX D ;ADDRESS COUNT FIELD STAX D ;INITIALIZE WITH A ZERO IN COUNT BYTE INX D XCHG ;ADDRESS FIRST BUFFER BYTE WITH HL INBUFA CALL CONIN CPI 0DH ;IS IT A RETURN? JZ INBUFR ;IF SO, THEN RETURN CPI 7FH ;IS IT A DELETE? JZ DELETE CPI 8 ;CTееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееonger time required for Chicago CBBS*. Jim Mills. ; * CBBS is a trademark of Ward Christensen and Randy Suess. ; ;---------------------- ; End of history file * ;----------------------MP INBUFA ;GET NEXT CHARACTER DELETE XCHG ;SAVE BUFFER POINTER IN DE POP H ;ADDRESS BEGINNING OF BUFFER PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT FIELD MOV B,A ;SAVE DELETE CHAR - 7FH OR 08H MOV A,M SUI 1 ;DECREASE COUNT MOV M,A JIVE MVI C,8 CALL TRANS CPI 0DH JZ DONE TYPE2 POP H ;SECOND TYPE STARTS IN 25TH BYTE. PUSH H LXI B,25 DAD B MVI C,3 CALL TRANS DONE POP H PUSH H INX H ;POINT TO FIRST CHAR OF FIRST NAME IN FCB. CALL SCAN ;CHECK FOR * (AMBIGUOAX # CHARACTERS IN LINE ;IN DE, NUMBER OF CHARS IN LINE IN DE+1, LINE STARTS IN DE+2) INTO FCB ;ADDRESSED BY HL REGISTERS. THE FCB SHOULD BE AT LEAST 33 BYTES IN LENGTH. ;THE COMMAND LINE BUFFER MUST HAVE A MAXIMUM LENGTH OF AT LEAST ONE MORE ;THAN THE INBUFO MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT JMP START RETYPE POP D PUSH D INX D ;POINT TO CURRENT NUMBER.. LDAX D ;..OF CHARACTERS. MOV B,A MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A, SPACE, THEN START OF.. JZ NAME2 ;..SECOND FILENAME. TYPE1 POP H ;FILETYPE MUST BE AFTER.. PUSH H ;..EIGHTH BYTE OF NAME. LXI B,9 DAD B MVI C,3 ;TRANSFER TYPE OF FIRST FILE CALL TRANS CPI 0DH JZ DONE NAME2 LDAX D ;EAT MULTIPLE SPACE CP/M.. CPI 7BH ;..DOES THE SAME. JNC NOUCASE ANI 5FH NOUCASE POP B ! POP D ! POP H RET CONIN1 LHLD 1 LXI D,6 DAD D PCHL CONSTAT PUSH H ! PUSH D ! PUSH B CALL CONST1 POP B ! POP D ! POP H RET CONST1 LHLD 1 LXI D,3 DAD D PC NODEL ;DON'T DELETE PAST BEGINING OF BUFFER. XCHG ;RESTORE BUFFER POINTER TO HL DCX H ;POINT TO LAST BYTE INPUTTED MOV A,B ;GET BACK EITHER 7FH OR 08H MOV B,M ;GET CHARACTER BEING DELETED MVI M,20H ;RESTORE BLANK CPI 8 JZ BKSPC MOV A,H B PUSH D PUSH H CALL INIT ;FILLS FCBS WITH BLANKS AND NULLS XCHG ;GET START OF COMMAND LINE IN HL. INX H ;ADDRESS # BYTES IN CMD LINE. MOV E,M ;LOAD DE PAIR WITH # BYTES. MVI D,0 INX H DAD D ;POINT TO BYTE AFTER LAST CHAR.. MV GREATEST NUMBER OF CHARACTERS THAT WILL BE NEEDED. LOCAL CMDLINE, DEFDR, DONE, DRIVE, FILL1, FILL, FILL2, INIT, INITL1 LOCAL INITL2, INITL3, INITL4, NAME1, NAME2, SCAN, TRANS, TSTNAM LOCAL TSTTYP, TSTTYPL, TYPE1, TYPE2, NAME2C PUSH PSW PUS0AH CALL CONOUT MOV A,B ;TEST IF ZERO INPUT ORA A JZ INBUFA CTLRLP INX D LDAX D CALL CONOUT DCR B JNZ CTLRLP JMP INBUFA ALERT MVI A,7 CALL CONOUT DCR M XCHG JMP INBUFA PCRLF MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOCES.. CPI 20H ;..BETWEEN NAMES. JNZ NAME2C INX D JMP NAME2 LDAX D CPI 0DH ;TEST IF FIRST NAME.. JZ DONE ;..ONLY AND THEN SPACE. NAME2C POP H ;SECOND NAME STARTS IN 16TH BYTE. PUSH H ;POINT HL TO THIS BYTE. LXI B,16 DAD B CALL DRCHL CONOUT PUSH H ! PUSH D ! PUSH B ! PUSH PSW CALL CONOUT1 POP PSW ! POP B ! POP D ! POP H RET CONOUT1 LHLD 1 LXI D,9 DAD D MOV C,A PCHL ENDM CMDLINE MACRO ;NO PARAMETERS USED ;LOADS A COMMAND LINE ADDRESSED BY DE REGISTERS (MB ;ECHO CHAR IF 7FH CALL CONOUT JMP INBUFA ;GET NEXT CHARACTER NODEL INR M ;DON'T LEAVE COUNT NEGATIVE XCHG ;RESTORE POINTER TO HL JMP INBUFA BKSPC CALL CONOUT ;TRUE ERASE IF 08H MVI A,20H CALL CONOUT MVI A,8 CALL CONOUT JMP INBUFA I M,0DH ;..IN CMD LINE AND STORE DELIMITER. POP H ;RESTORE HL AND DE. POP D PUSH D PUSH H INX D ;ADDRESS START OF COMMAND. INX D CALL DRIVE NAME1 MVI C,8 ;TRANSFER FIRST FILENAME TO FCB. CALL TRANS CPI 0DH JZ DONE CPI 20H ;IFX H ;POINT TO FIRST.. INX H ;..BUFFER BYTE. MVI A,20H CLEARL MOV M,A INX H DCR B JNZ CLEARL RET CONIN PUSH H ! PUSH D ! PUSH B CONINLP CALL CONSTAT ORA A JZ CONINLP CALL CONIN1 CPI 61H ;CHANGE TO UPPER.. JC NOUCASE ;..CASE SINUT JMP INBUFA INBUFR MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT POP D POP B POP H POP PSW RET CLEAR POP D ;ACCOUNTS FOR CALL POP H ;ADDRESS BUFFER IN HL PUSH H ;RESTORE.. PUSH D ;..STACK MOV B,M ;SAVE MAXIMUM IN B INUS NAMES). POP H PUSH H LXI B,17 ;POINT TO FIRST CHAR OF SECOND NAME IN FCB. DAD B CALL SCAN POP H POP D POP B POP PSW RET ; =============>>> SUBROUTINES <<=============== INIT PUSH H ;INITIALIZES FCB WITH 1 NULL (FOR FIRST DRIXI D,?P ENDIF CALL BDOS POP H POP D POP B ENDM ; ;------------------------------------------------ ; ; MULTI-FILE ACCESS SUBROUTINE ; ;THE ROUTINE IS COMMENTED IN PSEUDO CODE, ;EACH PSEUDO CODE STATEMENT IS IN <<...>> ; MFNAME: ;<> CPM STDMA,80H XRA A ! STA FCBEXT ;<> LDA MFFLG1 ! ORA A ! JNZ MFN01 ; <> MVI A,1 ! STA MFFLG1 ; <> MOVE FCB,MFREQ,12 ;SAVE ORIG REQ LDA FCB ! STA MFCUR ;SAVE DееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееX D MVI B,3 CALL MOVE CALL ILPRT PRNTNAME DB ' ',' ',' ', ' | ', 0 ;8,1,3 SPACES LDA NAMECT INR A STA NAMECT ANI 03H ORA A CZ CRLF NEXTSR LXI D,SRCHFCB MVI C,SRCHN ;DO NEXT SEARCH CALL BDOS CPI 0FFH JZ DIRDONE JM> POP H ! MOVE ,FCB+1,11 ;<> XRA A ! STA FCBEXT ! STA FCBRNO ;FIX BY M.Z. ;<> RET ; ;MULTI-FILE ACCESS WORK AREA ; MFFLG1 DB 0 ;1ST TIME SW MFREQ DS 12 ;REQ NAME MFCUR DS 12 ;CURR NAME ;----------ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее LXI D,80H MVI C,STDMA CALL BDOS XRA A STA NAMECT ;CR AFTER 4 NAMES LXI D,SRCHFCB MVI C,SRCHF ;DO FIRST SEARCH CALL BDOS CPI 0FFH JZ NOFILE DIRLP CALL GETADD LXI D,15 ;OFFSET FOR RECORD COUNT DAD D MOV A,M ORA A JZ NEXTSR ;NISK IN CURR FCB ; <> MOVE MFREQ,FCB,12 CPM SRCHF,FCB ;<> JMP MFN02 MFN01: ; <> MOVE MFCUR,FCB,12 CPM SRCHF,FCB ; <> MOVE MFREQ,FCB,12 CPM SRCHN,FCB ;<> MFN02: ;<> INR A ! STC ! JNZ MFFIX1 ! STA MFFLG1 ! RET ;FIX BY M.Z. MFFIX1: ;<> DCR A ! ANI 3 ! ADD A ADD A ! ADD A ! ADD A ! ADD A ADI 81H ! MOV L,A ! MVI H,0 PUSH H ;SAVE NAME POINTER MOVE ,MFCUR+1,11 ; and to log in a new disk. ; T choice was made instead. Also made ; some cosmetic and time out value changes. ; MJP ; ;10/17/82 Added 3 new commands. LOC to toggle local echo on/off. ; LST to toggle LST device on and off. "?" to show a status ; display of local ecbut if compiled with the ;equate for MODOUT equal to FALSE it will be a normal ;modem program. I suppose it could be called MODEM77. I ;suggest that future changes be made using the DIF method with ;MODOUT1.ASM as the base file for features to be ;add;09/12/82 Time for some general housecleaning. Stripped out FRONTPAN, ; PMMIBYTE, and IMSAIBYTE. It's my guess that an Apple will never ; have a front panel, and the MM][ will always look like a PMMI ; in respect to features. Also cleaned out dictates the selection. Thanks to Mark Pulver for ; his great ambitions for Apple R/CPM materials, and Elliot Jolesch ; and Chris Neal for their inspiration of the idea. ; -David Howard (214)620-7751 ; 11365 Rockford, IL 61108 ;(212) 454-6985 (815) 398-0579 ; ;Modified routines Copyrighted (1982) by ; ;Hal Walchli, W3TWI ;1329 Foxboro Drive ;Monroeville, Pa. 15146 ;(412) 372-3674 ; ;Permission is granted to use, but not to sell, these routhanks to Sidney Bratkovich for sharing his thoughts. Distributed ; as APMOD773.DIF for use with APMOD77X.ASM and the SSED routine. ; ; Mark J. Pulver (312) 789-0499 ; AIMS 300-450 baud ho, LST device, capture buffer, and bytes ; free in buffer. Minor cosmetic changes to messages. ; Moved all revisions messages to APMOD775.HIS ; ; Mark J. Pulver - AIMS (312) 789-0499 ; ;10/02/82 Rewrote the DIAL routine to prevent phone ed that are not wanted for normal modem use as the file ;is getting quite long. [Hal Walchli,W3TWI] ; ; ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY. ;IT ALSO INCORPORATES Rrespective routines. ; Fixed logic problem at NOCOLON with respect to savccp on/off. ; Modified command line cosmetics, repaired kludging to command ; line search for xprt mode. MODEM R NAM.TYP, MODEM S NAM.TYP, etc. ; now work as originallBLY FOR THE PCPI APPLI-CARD ; ;11/25/82 - Fixed an obscure bug in the DILAGN0 routine. If "Y" or ; "C" was the response to "...Redial...", and ; was used, then library entry "C" would be redialed. All ; worked well if a menuines. ; ;8/18/84 (SMS) ; Note an error in the subtraction routine near label ; GETSPC: gives incorrect value for buffer space message. ; Couldn't edit the file to get at it (file ; too large for my editor) ; ;2/8/83 (WLS) ; ADDED CONDITIONAL ASSEMde it is a "boiler plate" routine insuring ; that the MicroModem is always initialized as follows: Upon ; first entering the program primary baudrate (for an unmodi- ; fied modem 300), originate mode, 8 data bits, /82 Changes at TERM and START1 marked by ; @7.5 fix a ;long standing bug in MODEM7x that causes abort at the end of a ;batch file transfer or an attempt to transfer a non-existent ;file. The call to NOPARIT in DONETCE caused a computer that was ;in ater when switching between term and ;menu. Now the ogiginate or answer character has to only be ;entered once when comunications is first established. Also ;changed the MACLIB mico to MODEM75. Added CR,LF to the NEWBAUD ;message. ; R.L.Berg ; ;ing routine to MVI A,15H. ; ; Changed the "Break Key" to ^B to avoid conflict with certain ; 80 column boards. Also corrected the code so that a 450 ; millisecond break is sent. ; ; Changed the code in tity selection all modes(for Univac), ;password for modout use. [Hal Walchli,W3TWI-HEW] ; ;03/05/82 Increased the 25 second 'wait' after autodial to a longer ;time by repeating cycle and changing equate for WAITCTS to a smaller ;number. Seems to w for 110-300, or 300-450 with modified ; MM ][. Kept library list for local callers, (312 area). ; Thanks to Dav Holle for his time spent on APMODEM70, a ; lot of that code is in here too. ; ; and one stop ; bit. Any of these parameters can be changed at will. Once ; changed the new parameters are in effect until they are ; changed again or hang up. At hang up the modem will be ; returue of this program for use with a remote ;HOST computer system running CPM with BYE. ;This program will allow a second modem board (PMMI) to be used to make ;an outgoing call. See MODEM77.DOC for details that would make this ;listing too long if incl4/08/82 - Added modifications of MODEM75.FIX with minor changes ;and that of MODEM76 by R. Ratoff. Changed directory to XXXX to ;minimize CRCK problems with souce code copies. Added 'HLP' option ;for help on secondary commands. ; ;3/18/82 Initial isshe the dialing routine, starting at ; DIALPL, to that which was used in APMDM72. This is necessary ; to work with the changes at INITMOD. Also corrected various ; equates to function properly with the MicroModem. ; take up to 40 seconds on some calls. [HEW] ; ; 3/01/82 - ;Added INQUIR routine to give notice ;and the option to write the temporary file to disk. I forgot it ;too many times. Anything but WRT or RET will cause loss of the ;savefile. [HEW] ; ;2/20 -Mark J. Pulver (312)/789-0499 ; ;04/29/82 Changes at TERM, START1 and OPTCK marked by ; @7.61 ;fix a bug that causes abort at the end of a file transfer if ;the ogiginate 'O' or the answer 'A' character was not entered ;after the 'T' term characned to originate mode, primary baudrate but the parity ; will and bit configuration will remain as last used. If you ; wish to have it default back to 8 data bits one stop bit ; change the MVI A,PARCTLB in the dialuded here. ;Major changes are:deleted XPRT for automenu, added notice to print ;saved file, added OFF function, changed necessary characters for ;use as outmodem, disconnect warning on return to CP/M, revised Menu. ;Added HLP routine,added Data & parect on parity due to the MM ]['s ; lack of a parity byte. Code does support the MODOUT ; option. Cleaned up file from floating code that would ; never be used in an Apple sys, (PMMI dial, etc). Baud ; rate change no; Bill Cook ; 201-767-0176 ; ;5/10/82 - Re-worked routines for the Apple with a Hayes MM ][. ; Preserved all previous modifications/additions, with ; the exception of autoselnswer mode (but not explicitly by command option) to switch ;to originate mode thus causing the two ends to no longer communicate ;with each other. Also added SAVCCP byte and code to prevent ;overwriting of the CCP at the users option. R. L. Plouutines in ; MODEM V2.06) ; ; Added provisions to send and receive either even or odd parity ; bit with PMMI modem in the 'S'end or 'R'eceive file modes - resets ; to no parity in other modes. Use of the parity feature will slow ; transfers the NAK causes XMODEM or MODEM to start sending the file ;using checksum checking. This allows the CRC MODEM7 program ;to be used with versions of XMODEM, MODEM, and MODEM7 that ;do not use CRC, even when MODEM7 has specified a CRC ;transmission. (Jofix: ; All versions of MODEM7 including MODEM73 are supposed to be ;able to accept "CAL n" (where n is either a library letter or ;a phone-number string) as a valid form of the CAL command. In ;fact, however, the "n" will simply be ignored. This is;John Mahr and Paul Hansknecht for the implementation. (WDE) ; ;10/11/81 Add first NAK to RCVFIL to speed up start ;Removed monitor scroll from good block messages ;CTL-^ forces send of next char in T mode (for ctl-E,ctl-D) (WDE) ; ;07/05/81 Added BR 000-0000, whereas ;with library numbers one blank only must be typed: CAL A. ; ;12/16/81 Removed stack imbalance bug at COLONB by adding ; a JMP BRK1. Change is marked by ;@ R. L. Plouffe ; ;10/29/81 Changed receive sector routine so that on theffe ; ;1/23/82 The following changes have been made in this version. ; RLP ; ;Extensive cleanup of the file including colons after all labels ;for easier search with screen editor for the purposes of debug. ;Also set file capture mode so as econdary option ;that is specified by giving a 'C'. ; MODEM RC.600 fn.ft ; MODEM ROC.300 fn.ft etc. ; note: cannot have more than 6 secondary options. ;When the file receive cmd. specifies CRC, the ltr. 'C' is ;sent in place of the initial NAK. This hn Mahr) ; ;11/21/81 Fixed code so byte received is on same line when ; messages "XXH RCD, NOT SOH" or "XXH RCD, NOT ACK" ; are displayed. Also changed stack size to 50H. ; (P.L.Kelley) ; ;10/18/81 Added CRC option. This is another s because ;routine DIALPL checks for a command length >= 4 as a signal to ;skip the library display, but the menu routine, after ;recognizing CAL, sets the length to 1 so the L in CAL doesn't ;look like an illegal secondary option. ; The following klR ctrl char chgs, my number list (Bill Earnest) ; ;06/05/81 Deleted some unneeded messages in the dial routines. (Bob Clyne) ; ;05/31/81 Added detection of framing, overrun, and parity errors for ; Receive file routine. (A modified version of the ro first ;time through when CRC is being used, it only waits 3 seconds ;to receive the SOH after sending the initial 'C'. If a ;character is not received within 3 seconds, then a NAK is ;sent and this program switches to CHECKSUM mode. The sending ;ofnot to overwite the CCP and ;changed EXIT to return to the CCP instead of doing warm boot. ; ;TERML routine fix: ;Added Rick Kawala's fix so that fewer framing errors will occur ;with hosts that send out characters with high bit set. ; ;CAL command signals the sender ;(XMODEM54 or equiv.) that CRC is in effect. The sending ;program will repalce the checksum with the CRC 2 bytes. ;CRC will give better than a 99.99% probability that there ;are no data errors. Code copied from MODEM213, thanks to F+4. This makes the command ;look to the option processor like "CA n", and since A is a ;legal secondary option (which in this case is never used) the ;line passes muster. If an actual telephone number is used, ;you have