ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее-CATALOG061 DCHBYE55ASMЂ DCHBYE55ASM7FLIP-8/8ASMMEM-MAP ASM" !"MENU ASMA#$%&'()*+MIC-XFERASM2,-./012MIC-XFERDOC23456789ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееTED SOFTWARE 61.1 23K DCHBYE55.ASM REMOTE CONSOLE FOR DC HAYES MODEM 61.2 3K FLIP-8/8.ASM SWITCH REMOTE CONSOLE TO ORIGINATE MODE 61.3 5K TAG.ASM SET F1 BIT 61.4 9K MLIST34.ASM TYPE COMMAND W/16K BUFFER 61.5 45K MODEM926.ASM UPDATE OF CP/M USER ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееP MICROSOFT .REL FILES 61.20 1K SAP-FIX.DOC PATCHES FOR CP/M USER GROUP VOL. 19.8 61.21 5K TEXCLEAN.ASM CLEAR BIT 7 OF A TEXT FILE 61.22 2K TPA3.ASM COMPUTES SIZE OF TPA 61.23 3K Z80EXT.LIB EXTRA Z80 OPCODES THIS VOLUME WAS ASSEMBLED BY SIG/M, AееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееMLIST34 ASMC:;<=>?@ABMODEM926ASMЂCDEFGHIJKLMNOPQRMODEM926ASMЂSTUVWXYZ[\]^_`abMODEM926ASMhcdefghijklmnoMOVE6/12ASM9pqrstuvwееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееFER UTILITIES 61.11 7K MIC-XFER.ASM DATA TRANSFER BETWEEN MICROPOLIS CP/M 1.4 AND 8" SYSTEMS 61.12 7K MIC-XFER.DOC DATA TRANSFER DOCUMENTATION 61.13 3K XFER5-8.ASM TRANSFER FILES BETWEEN 5" AND 8" 61.14 3K XFER8-5.ASM TRANSFER FILES BETWEENGROUP 40.28 61.6 21K PLINK925.ASM UPDATE OF CP/M USER GROUP 19.4 61.7 2K USER-8/8.ASM REPLACES CP/M USER CMD ON REMOTE CPU 61.8 20K XMODEM32.ASM DC HAYES SUPPORT 61.9 4K PURGE.ASC REQUIRES MBASIC 61.10 20K RIBBS.ASC REQUIRES MBASIC FILE TRANSееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее USERS GROUP IN NEW JERSEY. T FILE 61.22 2K TPA3.ASM COMPUTES SIZE OF TPA 61.23 3K Z80EXT.LIB EXTRA Z80 OPCODES THIS VOLUME WAS ASSEMBLED BY SIG/M, A CPMUG: VOLUME 61 BULLETIN BOARD RELATED SOFTWARE SYSTEMS FILE TRANSFER UTILITIES CP/M UTILITIES SIZE NAME COMMENTS -CATALOG.061 CONTENTS OF CP/MUG VOLUME 61 SIG/M.LIB SUBMITTAL FORM UGFORM.LIB SUBMITTAL FORM BULLETIN BOARD RELAееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее 5" AND 8" 61.15 5K V2FORMAT.ASM VERSAFLOPPY SYSTEM CP/M UTILITIES 61.16 9K MENU.ASM CREATES MENU OF ALL .COM AND .BAS FILES 61.17 5K MEM-MAP.ASM USE TO MAP RAM/ROM 61.18 8K MOVE6/12.ASM SINGLE DRIVE COPY PROGRAM 61.19 8K RELDUMP.ASM DUMееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее;V5.5 (Revised 9/12/80) ; ; ;REMOTE CONSOLE PROGRAM FOR CP/M ;BASED ON AN ORIGINAL PROGRAM WRITTEN ;BY DAVE JAFFE, JANUARY 1979 ; ;Rewritten for PMMI modem ;by Ward Christensen, February 1979 ; ;Lobotomized for D C Hayes 80-103 ;by Bruce Ratof$DRIVE EQU 2 ;HIGHEST SUPPORTED DRIVE (0=A, 1=B, etc) MAX$USER EQU 3 ;HIGHEST SUPPORTED USER PRINTER EQU FALSE ;WANT TO RETAIN LIST DEVICE? DUAL$IO EQU TRUE ;WANT CONSOLE & MODEM? CALLBAK EQU TRUE ;WANT CALLBACK FEATURE? PSWDREQ EQU FALSE ;PASSWORD RE----------- ;CHANGE THE FOLLOWING EQUATE TO AN AREA IN YOUR ;HI MEMORY WHERE THIS PROGRAM MAY PATCH ITSELF IN. ;APPROX MEMORY REQUIREMENTS: 900 BYTES. ; DEST EQU 0F800H ;RUNNING LOCATION OF CODE ; ;CHANGE THE FOLLOWING TO YOUR LOCAL CONSOLE KEYBOARD with thanks to Bob Mathias for suggestions. ; ;01/24/80 Added routines to preserve registers when calling ; the user's CBIOS. Added conditional assembly for ; callback feature. Increased stack space to 60. ; By Keith Petersen. ; ;05/12/80OUND IN 15 SECONDS ; 5. ASKS NUMBER OF NULLS (0-9) ; 6. TYPES THE FILE "WELCOME" FROM ; DISK, ALLOWING CTL-C TO SKIP IT ; 7. ASKS FOR A PASSWORD, ALLOWING ; 5 TRIES TO GET IT RIGHT. ; 8. WHEN PASSWORD ENTERED, DROPS ; INTO CP/M. ; 9. CALLER CAN und ; like a carrier. ; by Bruce Ratoff ; ;06/08/80 Added (optional) lower-to-upper case conversion on output ; by asking extra question at signon. ; by Bruce Ratoff ; ;06/11/80 Ignore modem characters received with framing or overrun ; f, May 1980 ; ; ;I'd also like to give credit to Bill Precht ; for the "label + offset" idea allowing ; this program to relocate itself ; without using DDT to initially set it up ; ;05/06/79 Added routine to allow "callback" operation so modem ; E PASSWORD, ;LOCATED BELOW AT LABEL "PASSWD", AND THE MESSAGES ;PRINTED AT LABEL "WELCOME" AND JUST ABOVE LABEL ;"HANGUP" ; ;------------------------------------------------ ; ;THIS PROGRAM RUNS UP IN HIGH RAM. IT GETS THERE ;BY BEING MOVED THERE ;DATA PORT NUMBER. ; CONDATA EQU 05H ;LOCAL CONSOLE INPUT DATA PORT ; ;CHANGE THE FOLLOWING IF YOUR HAYES IS NOT AT 090H ;(THE OTHER PORT EQUATES ARE BASED ON THIS VALUE) ; DPORT EQU 090H ;UART DATA PORT ; ;YOU WILL LIKELY ALSO WANT TO CHANGE TH Changed modem I/O equates, ports and flags for the ; D C Hayes 80-103A. ; By Bruce Ratoff ; ;05/20/80 Put test at CARCK to force valid user/drive, as ; suggested by Keith Petersen. ; by Bruce Ratoff ; ;05/26/80 Put in "warm boot command" lLEAVE BY HANGING UP, ; (ANY TIME CARRIER IS LOST, IT ; WAITS 15 SECONDS, THEN GOES ; BACK TO STEP 1), OR THE CALLER ; MAY TYPE THE PROGRAM NAME (BYE) ; ; SYSTEM EQUATES: FALSE EQU 0 TRUE EQU NOT FALSE BDOS EQU 5 CR EQU 0DH LF EQU 0AH ; MAXerrors. This should help eliminate some of the noise ; sensitivities. ; by Bruce Ratoff ; ;09/12/80 Reset user 0/drive A in move-up logic so BYE /A works ; from other drives/users. ; by Bruce Ratoff ; ;------------------------------------- does not answer normal voice calls. By Robbin Hough ; and Keith Petersen, W8SDZ. ; ;09/24/79 Added routines to allow automatic multiple baud ; rate selection, exit to CP/M from local console, ; echo nr. of nulls selected. By Keith Petersen, ;WHEN 'BYE' IS TYPED. ; ;THE PROGRAM IN HI RAM DOES THE FOLLOWING: ; ; 1. HANGS UP THE PHONE ; 2. AWAITS RING DETECT, ALLOWS EXIT ; TO CP/M IF LOCAL KBD TYPES CTL-C ; 3. OUTPUTS CARRIER ; 4. AWAITS INCOMING CARRIER ; GOING TO STEP 1 IF NONE ; F JMP opcode back into location 0. Also, whenever ; warm boot is disabled, control-c is converted to null. ; by Bruce Ratoff ; ;06/04/80 Added keyboard input timeout to eliminate the "asleep ; at the switch" phenomenon and telco noises that soogic to force user into ; a chosen CCP command and disable warm boot on entry. ; The JMP at location 0 is replaced by a CALL, which ; is used to tell BYE to disconnect instead of doing ; warm boot. Program may re-enable warm boot by storing ;QUIRED? FASTCLK EQU TRUE ;TRUE IF 4MHZ SYSTEM CLOCK CPM2 EQU TRUE ;TRUE FOR CP/M VERSION 2.x WBCMND EQU TRUE ;TRUE TO USE WARM BOOT COMMAND WBUSER EQU 3 ;USER # FOR WARM BOOT COMMAND (MUST BE 0 IN 1.4 CP/M) WBDRV EQU 0 ;DRIVE # FOR WARM BOOT COMMAND ( LXI SP,STACK ;SET UP LOCAL STACK sub a ;force user 0, disk A sta 4 ;at next sign-in IF CPM2 mvi e,0 ;need to set user 0 in bdos mvi c,32 ;so that open succeeds on welcome file call bdos ENDIF mvi e,0 mvi c,14 ;also need drive A default ove) ; SOURCE EQU $ ;BOUNDARY MEMORY MARKER ; OFFSET EQU DEST-SOURCE ;RELOC AMOUNT ;-----------------------------------------------; ; THE FOLLOWING CODE GETS MOVED ; ; TO HI RAM LOCATED AT "DEST", ; ; WHERE IT IS EXECUTED. ; ;------------S, ; OUTPUT TO TPORT (PORT 0) ; P0BYE EQU 0 ;ON HOOK, OR DIALING BREAK P0ORIG EQU 84H ;OFF HOOK, ORIG. P0ANSW EQU 82H ;ANSWER PHONE P08BIT EQU 06H ;8 DATA BITS P0NOPY EQU 10H ;NO PARITY P0EPS EQU 01H ;EVEN PARITY SELECT P0TSB EQU 08H ;2 STOP BITS ;GO IMMEDIATELY INTO ANSWER MODE LXI H,FCB+1 ;TO OPTION MOV A,M CPI '/' ;OPTION? JNZ NOSLASH ;GOT AN OPTION - VALIDATE IT INX H ;TO OPTION BYTE MOV A,M ;GET IT CPI 'A' ;ANSWER? JZ ANSWER ;NO OPTION, OR INVALID ONE NOSLASH EQU $+OFFSET LDAX D ;GET BYTE DCX H ;BUMP POINTERS MOV M,A ;NEW HOME DCX D DCX B ;BUMP BYTE COUNT MOV A,B ;CHECK IF ZERO ORA C JNZ MVLP ;IF NOT, DO SOME MORE push h ;save jump address sub a ;force user 0, disk A sta 4 ;at next sign-in IF CPM2 m0=A, 1=B, ETC.) ; (COMMAND STRING GOES AT LABEL 'WBCSTR' NEAR ; END OF PROGRAM) TIMEOUT EQU TRUE ;TRUE IF TIMING OUT ON CONSOLE INPUT TOVALUE EQU 20*5*60 ;TIMEOUT TIME IN 20THS OF A SECOND ; ; HAYES MODEM PORT ASSIGNMENTS: ; ;HAYES MODEM PORTX IN ORDER THAT THE RELOCATION TO HI RAM XX ;XX WORK SUCCESSFULLY. FORGETTING TO XX ;XX SPECIFY '$+OFFSET' WILL CAUSE THE PRO- XX ;XX GRAM TO JMP INTO WHATEVER IS CURRENTLY XX ;XX IN LOW MEMORY, WITH UNPREDICTABLE XX ;XX RESULTS. BE CAREFUL.... XX-----------------------------------; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XX C A U T I O N : IF MODIFYING ANYTHING XX ;XX IN THIS PROGRAM FROM HERE ON: XX ;XX A-L-L LABELS MUST BE OF THE FORM: XX ;XX label EQU $+OFFSET XX ;X P0EI EQU 20H ;ENABLE INTERRUPTS P0NORM EQU P08BIT+P0NOPY ;I USE 8 BITS, NO PARITY P0110 EQU P08BIT+P0NOPY+P0TSB ;SAME W/2 STOP BITS ; ;MODEM STATUS, INPUT ON TPORT (PORT 1) ; P2RDET EQU 80H ;RING DETECT P2CTS EQU 40H ;CTS (CARRIER DETECT) ; ;HAYE CALL CARCK ;SIGNED OFF W/THIS PROG? JC HANGUP ;NOBODY THERE CALL ILPRT ;PRINT THIS MSG: DB CR,LF,'GOOD BYE, CALL AGAIN' DB CR,LF,CR,LF,0 CALL UNPATCH ;UNDO BIOS PATCHES ; ; ; NOBODY THERE, OR WE ARE DONE, SO HANG UP ; HANGUP EQU $+OFFSET vi e,0 ;need to set user 0 in bdos mvi c,32 ;so that open succeeds on welcome file call bdos ENDIF mvi e,0 mvi c,14 ;also need drive A default call bdos mvi a,0C3H ;reset boot trap/control-c trap sta 0 ret ;JUMP TO "START" (was PUSHed ab EQUATES (DPORT PREVIOUSLY DONE) ; TPORT EQU DPORT+1 ;CONTROL/STATUS PORT RPORT EQU DPORT+1 ;RATE GEN/MODEM STATUS CPORT EQU DPORT+2 ;MODEM CONTROL ; ;MODEM CONTROL COMMAND WORDS ; P3CLEAR EQU 00H ;IDLE MODE ; ; ; ;SWITCH HOOK AND MODEM COMMAND ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; ; IF CARRIER LOST, HANG UP, AWAIT RING. ; OTHERWISE, SAY GOODBYE, AND HANG UP ; START EQU $+OFFSET ; XRA A ;GET 0 STA LOSTFLG ;SHOW NO CARR. LOST ;CHECK FOR /A OPTION ON COMMAND - REQUEST TO ; ;MOVE THE MODEM INTERFACE PROGRAM UP TO HI RAM ;AND JUMP TO IT. ; MOVEUP lxi sp,80h ;set a temporary stack LXI B,PEND-START+1 ;NUMBER OF BYTES TO MOVE LXI H,DEST+PEND-START+1 ;END OF MOVED CODE LXI D,SOURCE+PEND-START ;END OF SOURCE CODE MVLPS MODEM STATUS MASKS ; P0TBMT EQU 2 ;XMIT BUFF EMPTY P0DAV EQU 1 ;DATA AVAILABLE P0RPE EQU 4 ;REC'D PARITY ERR P0ORUN EQU 10H ;OVERRUN P0FERR EQU 08H ;FRAMING ERROR ; ;BAUD RATE DIVISORS ; B110 EQU 0 ;110 BAUD B300 EQU 1 ;300 BAUD ; ORG 100H call bdos mvi a,0C3H ;reset boot trap/control-c trap sta 0 ; ;CLEAR DTR CAUSING PHONE TO HANG UP MVI A,P3CLEAR ;CLEAR.. OUT CPORT ;..DTR ; ; AWAIT RINGING ; RINGWT EQU $+OFFSET ;CHECK LOCAL KEYBOARD FOR CTL-C EXIT REQUEST. ;NOTE: MUST DO DNR A ;A=> 0 MEANS "NO" JZ PASSINT ;NO WELCOME FILE ;GOT A FILE, TYPE IT XRA A ;GET 0 STA FCBRNO ;ZERO RECORD # LXI H,100H ;GET INITIAL BUFF POINTER ;TYPE THE WELCOME FILE WELTYLP EQU $+OFFSET CALL RDBYTE ;GET A BYTE CPI 1AH ;EOF? JZ PASSINE SURE ITS CLEAR ;OUTPUT VALUE ALLOWING MODEM TO HANG UP ON ;LOSS OF CARRIER CALL CARCK ;LOOK FOR CARRIER JC HANGUP ;AWAIT ANOTHER CALLER ;NOW TEST INPUT FOR BAUD RATE CALL PATCH ;PATCH JMP TABLE CALL TSTBAUD ;SEE IF BAUD = 110 JZ WELCOME ;XT ROUTINES IMPLEMENT CALLBACK ; ; THIS ROUTINE MINIMIZES THE COMPUTER'S INTERFERENCE ; WITH NORMAL HOUSEHOLD PHONE USE BY HAVING COMPUTER ; FOLK DIAL, LET THE PHONE RING ONCE, HANG UP AND ; THEN DIAL AGAIN. WHEN THE PHONE RINGS UT ;GET Y OR N MOV C,A CALL MOUTPUT ;ECHO CPI 'N' JZ DONEOPT ;WE'RE ALREADY SET UP FOR NO LOWER CASE CPI 'Y' JNZ GETULC ;WASN'T Y OR N...RE-ASK SUB A STA ULCSW ;SET FLAG FOR NO CONVERSION DONEOPT EQU $+OFFSET CALL ILPRT DB CR,LF,0 ;PRTO REDIAL RELOOK EQU $+OFFSET IN RPORT ANI P2RDET ;RINGING AGAIN? JZ ANSWER CALL DELAY DCX H MOV A,H ORA L JNZ RELOOK JMP HANGUP ; ENDIF ;END OF CALLBACK ROUTINES ; ;SETUP MODEM ANSWER EQU $+OFFSET MVI A,P0ANSW ;TURN ON OUTIRECT INPUT BECAUSE CBIOS PATCHES ;ARE NOT DONE UNTIL CALL COMES IN. IN CONDATA ;CHECK LOCAL KBD ANI 7FH ;STRIP PARITY BIT CPI 'C'-40H ;CONTROL C? JZ 0 ;YES, --EXIT-- TO CP/M ; RINGW2 EQU $+OFFSET IN RPORT ;GET THE STATUS ANI P2RDET ;RINGINGINVALID BAUD RATE ; ;WELCOME TO THE SYSTEM ; WELCOME EQU $+OFFSET ; GETNULL EQU $+OFFSET CALL ILPRT ;PRINT THIS MSG: DB CR,LF DB 'HOW MANY NULLS DO YOU NEED? ',0 CALL MINPUT ;GET VALUE MOV C,A CALL MOUTPUT ;ECHO CHAR MOV A,C CPI '0' YES, EXIT MVI A,P0NORM ;SET FOR 1 STOP BIT, ETC. OUT TPORT MVI A,B300+P0ANSW ;SET DIVISOR OUT CPORT ;.. TO 300 RATE CALL TSTBAUD ;SEE IF BAUD = 300 JZ WELCOME ;YES, EXIT CALL UNPATCH ;RESTORE ORIG BIOS JMP TBL JMP ANSWER ;TEST MORE - ONLY ONCE IT ; ALERTS THE COMPUTER WHICH THEN WAITS FOR AND ANSWERS ; ANY RING WHICH OCCURS WITHIN THE NEXT 40 SECONDS. ; MVI L,45 ;DELAY 4.5 SECONDS FOR NEXT RING WAITNX EQU $+OFFSET CALL DELAY ;WAIT .1 SECONDS DCR L ;MORE TO GO? JNZINT THE WELCOME FILE LXI H,WELFILN ;SOURCE LXI D,FCB ;DESTINATION MVI B,13 ;LENGTH CALL MOVE ;MOVE THE NAME ;SET DMA ADDR TO 80H LXI D,80H MVI C,STDMA CALL BDOS ;OPEN THE WELCOME FILE LXI D,FCB MVI C,OPEN CALL BDOS ;DID IT EXIST? I CPORT ;..DTR MVI E,20 ANSWR1 EQU $+OFFSET CALL DELAY ;GIVE TIME TO TURN ON DCR E JNZ ANSWR1 MVI A,P0110 OUT TPORT ;ANSWER PHONE CALL DELAY ;GIVE TIME FOR ANSWER IN CONDATA ;CLEAR LOCAL KBD PORT IN DPORT ;CLEAR MODEM PORT IN DPORT ;MAK? JNZ RINGWT ;NO, WAIT ; ;THE PHONE IS RINGING, NOW WAIT UNTIL RING IS FINISHED ENDRING EQU $+OFFSET CALL DELAY ;.1 SEC DELAY FOR DEBOUNCE IN RPORT ;GET STATUS ANI P2RDET ;STILL RINGING? JZ ENDRING ;WAIT UNTIL RING FINISHED ; IF CALLBAK ;NE JC GETNULL ;BAD, RETRY CPI '9'+1 JNC GETNULL ;BAD SUI '0' ;MAKE BINARY STA NULLS ;SAVE COUNT GETULC EQU $+OFFSET CALL ILPRT DB CR,LF,'CAN YOUR TERMINAL DISPLAY LOWER CASE? ',0 MVI A,20H STA ULCSW ;FORCE CASE CONVERSION FOR NOW CALL MINP CALL DELAY ;DELAY .1 SECONDS IN RPORT ;GET THE STATUS ANI P2RDET ;STILL RINGING? JZ WAITNR ;YES, WAIT 10 MORE SECONDS DCR L ;NO RING, MAYBE WE'RE DONE JNZ WAITNRL ;NO, LOOP SOME MORE JMP HANGUP ; EXPECT EQU $+OFFSET LXI H,400 ;40 SECONDS WAITNX ;YES?...LOOP IN RPORT ;GET THE STATUS ANI P2RDET ;RINGING AGAIN? JNZ EXPECT ;NO?...ITS FOR ME! ;CALL NOT FOR COMPUTER - WAIT UNTIL RINGING DONE, THEN RESET WAITNR EQU $+OFFSET MVI L,100 ;WAIT FOR 10 SECS NO RINGING WAITNRL EQU $+OFFSET T ;YES, DONE MOV C,A ;SETUP FOR TYPE CALL MOUTPUT ;TYPE THE CHAR CALL MSTAT ;CHECK FOR.. ORA A ;CHAR TYPED? JZ WELTYLP ;..NO, LOOP CALL MINPUT ;..YES, GET CHAR CPI 'C'-40H ;CTL-C? JNZ WELTYLP ;..NO, LOOP UNTIL EOF ; ;GET THE PASSWORD ; VE ;MOVE ORIG BACK RET ; ;CALCULATE HL=CP/M'S JUMP TABLE, B=LENGTH ; TBLADDR EQU $+OFFSET LHLD 1 ;GET BIOS POINTER DCX H ;..SKIP DCX H ;..TO DCX H ;..COLD BOOT ; IF NOT PRINTER MVI B,18 ;BYTES TO MOVE ENDIF ; IF PRINTER ;RETAIN Llate drive cpi max$drive+1 ;valid drive? jc carck3 ;yes, skip this junk lda 4 ;restore whole login byte ani 0f0h ;retain user # sta 4 ;force drive to A jmp 0 ;force warm boot (punishment?) carck3 equ $+offset if cpm2 ;skip this junk if..NO, WAIT FOR C/R ;PASSWORD DIDN'T MATCH PWNMAT EQU $+OFFSET CALL ILPRT DB '++INCORRECT++',CR,LF,0 DCR D ;MORE TRIES? JNZ PASSINP ;YES JMP BADPASS ;NO, GO HANG UP ;CHARACTER MATCHED IN PASSWORD PWMAT EQU $+OFFSET INX H ;TO NEXT CHAR CPI CLK LXI B,4167 ;.05 SEC COUNT FOR 2MHZ ENDIF JMP DELAY1 ; ; ;PATCH IN THE NEW JMP TABLE (SAVING THE OLD) ; PATCH EQU $+OFFSET CALL TBLADDR ;CALC HL= CP/M JMP TABLE LXI D,VCOLDBT ;POINT TO SAVE LOCATION CALL MOVE ;MOVE IT ;NOW MOVE NEW JMPSO, RETURNS WITH CARRY CLEAR. ;IF NOT, IT WAITS FOR CARRIER FOR 15 SECS. ;IF THIS TIME RUNS OUT, IT RETURNS WITH CARRY SET. ; ; CARCK EQU $+OFFSET PUSH D MVI E,150 CARCK1 EQU $+OFFSET IN RPORT ;LOOK AT STATUS ANI P2CTS ;GET CARRIER DETECT BITPASSINT EQU $+OFFSET IF PSWDREQ MVI D,5 ;5 TRIES AT PASSWORD PASSINP EQU $+OFFSET CALL ILPRT DB CR,LF,'ENTER PASSWORD: ',0 LXI H,PASSWD ;POINT TO PASSWORD MVI E,0 ;NO MISSED LETTERS IN DPORT ;CLEAR OUT GARBAGE PWMLP EQU $+OFFSET CALL MINPp/m 2.x dependant stuff CARCK4 EQU $+OFFSET ora a ;clear carry POP D RET ; ; .1 SEC DELAY ROUTINE ; DELAY EQU $+OFFSET PUSH B IF FASTCLK LXI B,16667 ;.1 SEC COUNT FOR 4MHZ SYS CLOCK ENDIF IF NOT FASTCLK LXI B,8334 ;.1 SEC COUNT FOR cp/m 1.x lda 4 ;re-fetch login byte ani 0f0h ;isolate user # cpi max$user*16+1 ;valid user ? jc carck4 ;yes, don't change lda 4 ;refresh login byte again ani 0fh ;keep drive, zero user sta 4 jmp 0 ;force warm boot endif ;end of cCR ;END? JNZ PWMLP ;..NO, LOOP ;END OF PASSWORD. ANY MISSED CHARS? MOV A,E ;GET FLAG ORA A JNZ PWNMAT ;NOT RIGHT ENDIF ;PASSWORD CORRECT CALL ILPRT DB CR,LF,'BOOTING SYSTEM...',0 IF WBCMND MVI A,0FFH ;SET WARM BOOT FLAG (TESTED AT MOUT TABLE TO CP/M CALL TBLADDR ;CALC HL=CP/M'S JMP TABLE XCHG ;MOVE TO DE LXI H,NEWJTBL ;POINT TO NEW CALL MOVE ;MOVE IT RET ; UNPATCH EQU $+OFFSET CALL TBLADDR ;HL=CP/M'S JMP TABLE XCHG ;MOVE TO DE LXI H,VCOLDBT ;GET SAVED TABLE CALL MO JNZ CARCK2 ;IF CARRIER ON, continue with checks ;LOOP UNTIL EITHER TIME EXHAUSTED, OR ;CARRIER RETURNS CALL DELAY ;KILL .1 SEC DCR E ;COUNT DOWN TIME JNZ CARCK1 STC pop d ret CARCK2 EQU $+OFFSET lda 4 ;check disc/user # ani 0fh ;isoUT ;GET A CHAR CPI 'U'-40H ;CTL-U? JZ PASSINP ;YES, RE-GET IT CPI 60H ;LOWER CASE? JC NOTLC ;NO, ANI 5FH ;MAKE UPPER CASE ALPHA NOTLC EQU $+OFFSET CMP M ;MATCH PASSWORD? JZ PWMAT ;..YES MVI E,1 ;..NO, SHOW MISS CPI CR ;C/R? JNZ PWMLP ;2MHZ SYS CLOCK ENDIF DELAY1 EQU $+OFFSET DCX B ;COUNT DOWN DELAY TIME MOV A,B ORA C JNZ DELAY1 ;CONTINUE COUNTING TILL DONE POP B RET ; ; KDELAY EQU $+OFFSET PUSH B IF FASTCLK LXI B,8334 ;.05 SEC COUNT FOR 4MHZ ENDIF IF NOT FASTURN... RZ ;.. RETURN CPI LF ;IF A LINEFEED... RET ;RET ZERO FLAG, ELSE NOT ZERO ; ; LOSS OF CONNECTION TEST ; ;THIS ROUTINE AUTOMATICALLY HANGS UP THE ;PHONE AFTER LOSS OF CARRIER ; ;THIS ROUTINE CHECKS IF CARRIER IS STILL ;PRESENT, AND IF PUT) STA WBFLAG ENDIF JMP VWARMBT ;GO LOAD CP/M ; ;TSTBAUD ATTEMPTS TO READ A LF OR CR, RETURNS WITH ;ZERO FLAG IF THE CHARACTER READ IS ONE OF THESE TWO. ; TSTBAUD EQU $+OFFSET CALL MINPUT ;GET CHARACTER FROM MODEM CPI CR ;IF A CARRIAGE RETIST DEVICE? MVI B,15 ;DON'T MOVE LISTER JUMP ENDIF ; RET ; ;MOVE (HL) TO (DE), LENGTH IN (B) ; MOVE EQU $+OFFSET MOV A,M ;GET A BYTE STAX D ;PUT AT NEW HOME INX D ;BUMP POINTERS INX H DCR B ;DEC BYTE COUNT JNZ MOVE ;IF MORE, DO IT GO THERE MOUTP1 EQU $+OFFSET ENDIF IN TPORT ;READ MODEM STATUS ANI P0TBMT ;XMIT BUFF EMPTY? JZ MOUTPUT ;LOOP IF NOT READY MOV A,C ;GET CHAR CPI 60H ;CHECK FOR LOWER CASE JC MOUTP2 ;SKIP IF NOT LC CPI 7FH ;CHECK FOR RUBOUT JZ MOUTP2 PUSMED OUT',7,7,0 JMP NOSLASH ENDIF ; ;GOT CHAR - SEE WHICH PORT ; MINPUT2 EQU $+OFFSET IF DUAL$IO ;BOTH LOCAL AND REMOTE? CALL CONSTAT ;CHECK LOCAL CONSOLE ORA A ;CHAR? JNZ CONIN ;..YES, READ IT, RET. ENDIF ; ;LOCAL CONSOLE WASN'T READY, MP TBL XRA A ;CLEAR OUT CARRIER.. STA LOSTFLG ;..LOST FLAG JMP HANGUP ; ;READBYTE ROUTINE - USED TO READ THE ; WELCOME FILE ; RDBYTE EQU $+OFFSET MOV A,H ;TIME TO READ? ORA A ;..IF AT 100H JZ NORD ;NO READ REQ'D ;HAVE TO READ A SECTOR LRESS SUI 8 ;CCP IS 2K DOWN FROM BDOS MOV H,A MVI L,0 ;HL NOW CONTAINS CCP ENTRY ADDRESS PUSH H ;SAVE FOR LATER MVI L,7 ;POINT TO BYTE COUNT IN CCP COMMAND BUFFER XCHG ;MAKE IT DEST POINTER (DE) LXI H,WBCSTR ;POINT TO COMMAND STRING TO DROP IPUSH H ;INITIALIZE TIMEOUT COUNTER LXI H,TOVALUE SHLD TOCNT POP H ENDIF MINPUT1 EQU $+OFFSET LDA LOSTFLG ;KNOWN LOSS.. ORA A ;..OF CARRIER? CZ CHECK ;CARRIER STILL ON? ; CALL MSTAT ;ANYTHING? ORA A ; IF NOT TIMEOUT JZ MINPUT ;LOOPRET ;IF NOT,RETURN ; ;COMMON ROUTINE TO CHECK FOR CARRIER LOST, ;CALLED FROM CONSOLE STATUS, AND CONSOLE OUT ; CHECK EQU $+OFFSET CALL CARCK ;SEE IF CARRIER STILL ON RNC ;ALL OK ;CARRIER IS LOST. TYPE MESSAGE SO LOCAL CONSOLE ; SHOWS THE REASD RZ SUB A ;ELSE CONVERT IT TO A NULL ENDIF RET ; ;MODEM OUTPUT ROUTINE. OUTPUTS TO MODEM, ;THEN TO LOCAL CONSOLE ; MOUTPUT EQU $+OFFSET ;IF WE ALREADY KNOW CARRIER IS LOST, ;DON'T CHECK FOR IT AGAIN LDA LOSTFLG ;KNOWN LOSS OF CARRIER? SO READ MODEM IN DPORT ;GET DATA BYTE ANI 7FH ;DELETE PARITY JZ MINPUT ;IGNORE NULLS IF WBCMND CPI 3 ;CONTROL-C? RNZ ;NO, PASS IT THRU LDA 0 ;SEE IF WARM BOOT DISABLED CPI 0C3H ;JMP MEANS WARM BOOT OK MVI A,3 ;SO RETURN CONTROL-C AS TYPEXI D,FCB MVI C,READ CALL BDOS ORA A ;OK? MVI A,1AH ;FAKE UP EOF RNZ ;RET EOF IF BAD LXI H,80H NORD EQU $+OFFSET MOV A,M ;GET CHAR INX H ;TO NEXT RET ; ;KEYBOARD/MODEM STATUS TEST ROUTINE ; MSTAT EQU $+OFFSET ; IF DUAL$IO ;WANT LON MOV B,M ;GET BYTE COUNT INR B ;UP BY 2 TO INCLUDE COUNT AND TRAILING NULL INR B CALL MOVE ;DROP IT IN TO CCP MVI A,WBUSER*16+WBDRV ;SET LOCATION 4 (USER/DRIVE) STA 4 MOV C,A ;ALSO PASS IT TO CCP POP H ;GET BACK CCP ENTRY ADDRESS PCHL ; TILL CHAR RCD ENDIF ; IF TIMEOUT JNZ MINPUT2 CALL KDELAY ;KILL .05 SEC PUSH H LHLD TOCNT ;KNOCK DOWN TIMEOUT COUNTER DCX H SHLD TOCNT MOV A,H ORA L POP H JNZ MINPUT1 ;STILL MORE TIME...KEEP TRYING CALL ILPRT DB '+++INPUT TION BADPASS EQU $+OFFSET ;COME HERE ON BAD PASSWORD MVI A,1 ;SHOW CARRIER LOST SO STA LOSTFLG ;..WE WON'T CK AGAIN LXI SP,STACK ;ENSURE VALID STACK CALL ILPRT DB CR,LF DB '++CARRIER LOST++' DB CR,LF,' ',0 CALL UNPATCH ;RESTORE ORIG BIOS JORA A CZ CHECK ;CARRIER STILL ON? IF WBCMND LDA WBFLAG ;IS THIS FIRST WARM BOOT SINCE SIGNON? ORA A ;IF NOT, SKIP THIS STUFF JZ MOUTP1 SUB A ;TURN OFF FLAG FOR NEXT TIME STA WBFLAG MVI A,0CDH ;DISABLE WARM BOOT STA 0 LDA 7 ;GET BDOS ADD ERRORS...LEGIT CHARACTER IN DPORT ;SWALLOW CHARACTER (CLEARS P0DAV) SUB A ;RETURN FALSE (0) RET MSTAT1 EQU $+OFFSET MVI A,0FFH ;SHOW READY ORA A RET ; ;MODEM INPUT FUNCTION, CHECKS LOCAL CONSOLE FIRST ; MINPUT EQU $+OFFSET IF TIMEOUT CAL CONSOLE? CALL CONSTAT ;GET LOCAL STATUS ORA A RNZ ;RET IF LOCAL CHAR ENDIF ; IN TPORT ;GET STATUS ANI P0DAV ;DATA AVAILABLE? RZ ;RETURN IF NOT READY IN TPORT ;GET STATUS AGAIN ANI 18H ;CHECK FRAMING AND OVERRUN BITS JZ MSTAT1 ;NOH H LXI H,ULCSW ;SUBTRACT EITHER 20H OR 0 SUB M POP H MOV C,A ;FORCE ON LOCAL AS WELL AS REMOTE MOUTP2 EQU $+OFFSET OUT DPORT ;OUTPUT TO MODEM ; IF DUAL$IO ;TO LOCAL ALSO? CALL CONOUT ;SEND TO REGULAR BIOS ENDIF ; ;CHECK FOR NULLS ; EQU 5 DBUFF EQU 80H ; PMESSG EQU 9 CHRINP EQU 1 ; ORG 100H ; FLIP: MVI C,PMESSG LXI D,MESSG CALL BDOS ; FLIP1: MVI C,PMESSG LXI D,MESSG2 CALL BDOS MVI C,CHRINP CALL BDOS CPI 3 ;CTL-C? JZ 0 ;YES, EXIT TO CP/M WARM BOOT CPI 13 ;B 0 ; PEND EQU $+OFFSET ;END OF RELOCATED CODE ; ;KEEP TRACK OF LOST CARRIER WHEN TYPING ;"++CARRIER LOST++" SO WE DON'T LOOP ; LOSTFLG EQU $+OFFSET DS 1 ; ;SAVE THE CP/M JUMP TABLE HERE ; VCOLDBT EQU $+OFFSET DS 3 VWARMBT EQU $+OFFSET DS ; DB 'MSG',0 ; ILPRT EQU $+OFFSET XTHL ;SAVE HL, GET MSG PUSH B ;SAVE ILPLP EQU $+OFFSET MOV C,M ;GET CHAR CALL MOUTPUT ;OUTPUT IT INX H ;POINT TO NEXT MOV A,M ;TEST ORA A ;..FOR END JNZ ILPLP POP B ;RESTORE XTHL ;RESTORE HL, RETe-ask for ; input if invalid answer. Keith Petersen, W8SDZ. ; updated 8/8/80 to add conditional assembly for either ; PMMI or D C Hayes modem cards (BR) ; FALSE EQU 0 ;BASIC LOGIC DEFINITIONS TRUE EQU NOT FALSE ; FASTCLK EQU TRUE ;SET TRUE IF 4M POP B RET ; ; THIS IS THE JMP TABLE WHICH IS COPIED ; ON TOP OF THE ONE POINTED TO BY ; LOCATION 1 IN CP/M ; NEWJTBL EQU $+OFFSET JMP MBOOT ;BOOT TRAP JMP MBOOT ;BOOT TRAP JMP MSTAT ;MODEM STATUS TEST JMP MINPUT ;MODEM INPUT ROUTINE JMP CPI LF ;TIME FOR NULLS? RNZ ;NO, RETURN ;SEND NULLS IF REQUIRED LDA NULLS ;GET COUNT ORA A ;ANY? RZ ;..NO PUSH B MOV B,A ;SAVE COUNT MVI C,0 ;0 IS A NULL NULLP EQU $+OFFSET CALL MOUTPUT ;TYPE A NULL DCR B ;MORE? JNZ NULLP ;..YES, LO32 ; END  DS 60 STACK EQU $+OFFSET ;LOCAL STACK ; WRCON EQU 2 OPEN EQU 15 READ EQU 20 STDMA EQU 26 FCB EQU 5CH FCBRNO EQU FCB+ 3 VCONSTAT EQU $+OFFSET DS 3 VCONIN EQU $+OFFSET DS 3 VCONOUT EQU $+OFFSET DS 3 VLISTOUT EQU $+OFFSET DS 3 ; DS 60 STACK EQU $+OFFSET ;LOCAL STACK ; WRCON EQU 2 OPEN EQU 15 READ EQU 20 STDMA EQU 26 FCB EQU 5CH FCBRNO EQU FCB+ ADDR RET ;RET PAST MSG ; ;ACCESS PASSWORD (ENDS IN C/R) ; PASSWD EQU $+OFFSET DB '******' ;THE PASSWORD ITSELF DB CR ;END OF PASSWORD ;ALLOW ROOM FOR BIGGER PASSWORD TO BE ; PATCHED IN DB 0,0,0,0,0,0,0,0,0,0,0,0,0 ; ;WARM BOOT COMMAND STRHZ SYSTEM CLOCK ; PMMI EQU FALSE ;SET TRUE IF PMMI MODEM DCH EQU TRUE ;SET TRUE IF D C HAYES MODEM ; IF DCH MODCTL EQU 92H ;D C HAYES MODEM CONTROL PORT ADDRESS ENDIF ; IF PMMI MODCTL EQU 0C0H ;PMMI MODEM CONTROL PORT ADDRESS ENDIF ; BDOSMOUTPUT ;MODEM OUTPUT ROUTINE RET ;DUMMY LIST DEVICE NOP NOP ; WELFILN EQU $+OFFSET DB 0,'WELCOME ',0 ;WELCOME FILE NAME ^^^^^^^^^^^ ; NULLS EQU $+OFFSET DB 5 WBFLAG EQU $+OFFSET DB 0 TOCNT EQU $+OFFSET DW 0 ULCSW EQU $+OFFSET DOP POP B RET ; ;BOOT TRAP - BECOMES DISCONNECT IF JMP AT 0 HAS BEEN ALTERED ; MBOOT EQU $+OFFSET LDA 0 ;LOOK AT OPCODE CPI 0C3H ;IS IT STILL JMP? JZ VWARMBT ;YES, ALLOW IT JMP NOSLASH ;NO, DISCONNECT ; ; INLINE PRINT ROUTINE ; CALL ILPRT; title 'FLIP - flip originate/answer mode under "bye"' ; Originally written by Bruce Ratoff. ; ; updated 6/2/80 to uppercase message and require exactly ; control-c or return, ignoring all else. (BR) ; updated 6/6/80 to work with PMMI modem and to rFFSET PUSH B PUSH D PUSH H CALL VCONSTAT POP H POP D POP B RET ; CONIN EQU $+OFFSET PUSH B PUSH D PUSH H CALL VCONIN POP H POP D POP B RET ; CONOUT EQU $+OFFSET PUSH B PUSH D PUSH H CALL VCONOUT POP H POP D ING ; IF WBCMND WBCSTR EQU $+OFFSET DB WBCEND-WBCSTR-2 DB 'RIBBS' DB 0 WBCEND EQU $+OFFSET ENDIF ; ;THIS AREA IS USED FOR VECTORING CALLS TO THE ;USER'S CBIOS, BUT SAVING THE REGISTERS FIRST ;IN CASE THEY ARE DESTROYED. ; CONSTAT EQU $+OCARRIAGE RETURN? JNZ FLIP1 ;NO, ASK FOR ANOTHER INPUT ; ;SET MODEM FOR OFF-HOOK ORIGINATE IF PMMI MVI A,1DH ENDIF IF DCH MVI A,87H ENDIF OUT MODCTL IF FASTCLK MVI C,20 ;10 SECONDS AT 4MHZ ENDIF IF NOT FASTCLK MVI C,10 ;10 SECONDSP,STACK ;SET STACK TO LOCAL STACK AREA GETIT: MVI C,PRNF ;OUTPUT "PRESS RETURN TO START" LXI D,STRMSG CALL BDOS MVI C,CHIF ;GET CHARACTER CALL BDOS CPI CR ;CARRIAGE RETURN? JNZ GETIT ;NOPE, TRY AGAIN CALL CRLF ;KEEP IT NEAT MVI C,PRNF ;OU1979 ,BY MICROCOSM.ALL RIGHTS RESERVED.NO PART MAY BE ; REPRODUCED,TRANSMITTED,TRANSCRIBED ,STORED IN RETRIEVAL SYSTEM, OR ; TRANSLATED INTO ANY LANGUAGE OR COMPUTER LANGUAGE, IN ANY FORM OR ; BY ANY MEANS,ELECTRONIC,MECHANICAL,MAGNETIC,OPTICAL,CHEMIWILL LOSE THE CONNECTION.',13,10 DB 'IF YOUR MODEM INTERRUPTS THE PHONE LINE WHILE',13,10 DB 'REVERSING, YOU WILL LOSE THE CALL UNLESS YOU',13,10 DB 'PICK UP THE PHONE FIRST.',13,10,'$' ; MESSG2: DB 13,10,'TYPE RETURN TO SWITCH, CONTROL-C TO ABORT:KS CAN BE REMOVED. (THIS IS TO PREVENT ; POSSIBILITY OF DISK WRITES IN MEMORY-MAPPED ; DISK CONTROLLER SYSTEMS). KEITH PETERSEN, W8SDZ ; ; ORG 00100H ; ; ; BDOS EQU 5 ;BDOS ENTRY CHIF EQU 1 ;CP/M INPUT CHARACTER FUNCTION CHRF EQU 2 ;CP/M PRееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее COUNT ENDIF ; ;DELAY LOOP - NUMBER OF SECONDS IN C REGISTER CTLP: LXI H,0 ;ONE SECOND DELAY LOOP LXI D,1 ; SLO: DAD D ;DONE WITH ONE SECOND LOOP? JNC SLO ;NO, DO ANOTHER LOOP DCR C ;ONE LESS SECOND JNZ CTLP ;NOT DONE WITH COUNT ; IF PMMIWARRANTIES WITH RESPECT TO THE ; CONTENTS HEROF AND SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF ; MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. FURTHER , ; MICROCOSM RESERVES THE RIGHT TO REVISE AND TO MAKE CHANGES FROM ; TIME TCAL,MANUAL ; OR OTHERWISE, WITHOUT THE PRIOR WRITTEN PERMISSION OF MICROCOSM, ; 3055 WACO ST.,SIMI VALLEY,CALIFORNIA 93063. ; ; DISCLAIMER ; ========== ; ; MICROCOSM MAKES NO REPRESENTATION OR $' ; END ALL UNLESS YOU',13,10 DB 'PICK UP THE PHONE FIRST.',13,10,'$' ; MESSG2: DB 13,10,'TYPE RETURN TO SWITCH, CONTROL-C TO ABORT:INT CHARACTER FUNCTION PRNF EQU 9 ;CP/M PRINT CHARACTER STRING FUNCTION CR EQU 00DH ;CARRIAGE-RETURN CHARACTER LF EQU 00AH ;LINE-FEED CHARACTER ; ; ; MAP: LXI H,0 ;SET-UP STACK DAD SP ;ENTRY STACK POINTER FROM CP/M CCP SHLD OLDSP ;SAVE IT LXI ;*********************************************************************** ; MICROCOSM MEMORY MAP DISPLAY PROGRAM VERSION 1.0 (C) 1979 ;*********************************************************************** ; (revised 5/5/80) ; ; COPYRIGHT (C) ;SET PMMI MODEM CHIP SO IT CAN HANG UP ON LOSS OF CARRIER MVI A,1CH ;SET PMMI MODEM FOR ORIGINATE OUT MODCTL ENDIF JMP 0 ;EXIT TO CP/M WARM BOOT ; MESSG: DB 'IF YOU HIT RETURN, YOU HAVE 15 SECONDS TO SWITCH',13,10 DB 'TO ANSWER MODE OR YOU O TIME IN THE CONTENT HEREOF WITHOUT OBLIGATION OF MICROCOSM ; TO NOTIFY ANY PERSON OF SUCH REVISION OR CHANGES. ; ;************************************************************************ ; ;05/05/80 MODIFIED TO WAIT FOR RETURN TO START SO ; DISееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееTPUT "BLOCK LOCATION" LXI D,BLKMSG CALL BDOS LXI H,0 ;POINT TO BLOCK 0 MVI B,1 ;"ITEMS TO A LINE" COUNTER MAP1: MVI E,'M' ;INDICATE "M" FOR RAM MOV A,M ;GET FIRST BYTE OF BLOCK CMA ;INVERT IT MOV M,A ;TRY TO MODIFY MEMORY CMP M ;WAS MEMOR ;ENTRY FROM DISK DIRECTORY MVI C,8 ;LENGTH OF COMPARE PUSH H ;SAVE POINTER TO TABLE ; COMPARE1: LDAX D ;GET TRIAL NAME CHAR CMP M ;MATCH? JNZ END$COMPARE ;IF NOT, TRY NEXT ENTRY INX H ;ADVANCE POINTERS INX D DCR C ;ONEееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееLEAR LS BYTE OF MEMORY POINTER DCR B ;COUNT ITEMS TO A LINE JNZ NLINE ;SKIP IF NOT A NEW LINE MVI B,16 ;16 ITEMS TO A LINE CALL CRLF ;OUTPUT "CR/LF" CALL HEXO ;OUTPUT BLOCK ADDRESS NLINE: MVI A,' ' ;OUTPUT A SPACE CHARACTER CALL PCHAR MOV A,' COMMAND ; SORT$LOOP: LXI D,SRCH$FCB ;POINT FILE CONTROL BLOCK CALL BDOS ;USE CP/M ENTRY POINT ; ; ORA A ;TEST FOR -1 JM ASSIGN$MENU$NBR ;PRINT EMPTY RRC ;THIS IS THE SAME AS RRC ;5 "ADD A'S" RRC ANI 60H ;MASK CORRECT BICP/M DO THE WORK POP PSW ! POP B ! POP D ! POP H RET ; ; ; CRLF: MVI A,CR ;PRINT "CARRIAGE-RETURN" CALL PCHAR MVI A,LF ;PRINT "LINE-FEED" CALL PCHAR RET ; ; ; BLKMSG DB CR,LF,' 0 1 2 3 4 5 6 7 8 9 A B C D E F$' ; STRMSG DB 'REMOVEY MODIFIED? CMA ;RESTORE A REG. TO INITIALLY READ VALUE MOV M,A ;RESTORE MEMORY JNZ MAP2 ;SKIP,IF NOT RAM CMP M ;TEST IF RAM FOR SURE JZ PRINT ;YUP,IT'S RAM MAP2: MVI E,'P' ;INDICATE "P" FOR PROM MAP3: MVI A,0FFH ;ABSENCE OF MEMORY IS ALL ONE'ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееE ;GET MEMORY TYPE CHARACTER CALL PCHAR ;PRINT IT INR H ;BUMP FOR NEXT BLOCK JNZ MAP1 ;CONTINUE UNTIL LAST BLOCK CALL CRLF ;KEEP IT NEAT FOR RETURN TO CP/M LHLD OLDSP ;GET OLD STACK POINTER SPHL ;RESTORE IT RET ;STACK POINTER CONTAINS CCP'STS ADI 80H ;ADD BASE ADDRESS(0080H) MOV E,A ;PUT POINTER IN (DE) MVI D,0 ;AS 16 BIT VALUE LXI H,DIRTABLE ;POINT START OF TABLE OF ;SORTED NAMES INX D ;POINT PAST ERASE FIELD ; COMPARE$LOOP: ; PUSH D ;SAVE POINTER TO NEXT DISKS & PRESS RETURN TO START > $' ; ; OLDSP DS 2 ;ENTRY STACK POINTER VALUE FROM CP/M CCP DS 32 ;RESERVE 16 LEVEL STACK STACK EQU $ ; ; ; END S CMP M ;TEST FOR NO MEMORY JNZ PRINT ;YUP,IT'S PROM INR L ;DO CHECK ON NEXT BYTE XRA A ;CLEAR A REG. FOR 256 BYTE BLOCK COUNTER CMP L ;TEST IF BLOCK CHECK DONE JNZ MAP3 ;LOOP 256 TIMES MVI E,'.' ;INDICATE "." FOR NO MEMORY PRINT: MVI L,0 ;C; MENU PROGRAM ; FOR ; MACHINE LANGUAGE OR BASIC PROGRAMS ; ; BY ; JAMES J. FRANTZ ; MAY 31, 1979 ; ; ORG 0100H ; ; BASIC$PROG EQU 0 ;SET TO 0 FOR MACHINE ; LXI SP,STACK$AREA ;SET UP A STACK MVI C,17 ;'SEARCH FIRSTSK UPPER NIBBLE CPI 10 ;TEST IF >10 JC HEXO3 ;SKIP IF <10 ADI 7 ;ADJUST ASCII HEXO3: ADI 030H ;ADD ASCII BIAS PCHAR: PUSH H ! PUSH D ! PUSH B ! PUSH PSW MVI C,CHRF ;DO CP/M PRINT CHARACTER FUNCTION MOV E,A ;CHARACTER TO E REG. CALL BDOS ;LET STACK LOCATION ; ; ; HEXO: MOV C,H ;GET MS BYTE CALL HEXO1 ;OUTPUT MS BYTE MOV C,L ;GET LS BYTE HEXO1: MOV A,C ;GET BYTE TO BE CONVERTED RAR ! RAR ! RAR ! RAR ;ROTATE UPPER NIBBLE CALL HEXO2 ;OUTPUT UPPER NIBBLE MOV A,C HEXO2: ANI 00FH ;MA LESS CHAR TO COMPARE JNZ COMPARE1 ;KEEP TESTING END$COMPARE: POP B ;RESTORE TABLE POINTER JC INSERT$NAME ;DIRECTORY NAME GOES IN ;FRONT OF CURRENT TABLE ;ENTRY IF LOWER(CY=1) LXI H,14 ;LENGTH OF TABLE ENTRY DAD B ;(HL) TPRINTING DCR M ;BY TESTING COUNT OF FILES POP D ;GET OFFSET POINTER POP H ;GET POINTER TO LAST NAME JZ FINISH ;NO MORE TO PRINT INX D ;ADVANCE OFFSET POINTER LDA COLUMN$CNT DCR A ;SEE IF COLUMN LEFT = 0 JNZ PRINT$NAME ;PRINT ANATION JNZ SETOFFSET2 ;SAME AS OFFSET1 IF NON- ;ZERO REMAINDER DCR B ;ELSE OFFSET2=OFFSET1-1 ;: SETOFFSET2: MOV M,B ;PUT OFFSET2 IN TABLE INX H ;POINT OFFSET FOR COL 3 DCR A ;TEST FOR REMAINDER OF 1 JNZ SETOFFSET3 ;IF REMAINDERMOV A,B CMP D JNZ MOVE$UP POP H ;RECOVER POINTER MVI C,8 CALL BLOCK$MOVE ;INSERT NAME IN TABLE ; LXI H,MENU$BUFF ;POINT MENU NUMBER BLOCK MVI C,6 ;LENGTH OF MOVEK CALL BLOCK$MOVE ;INSERT TEXT IN TABLE ; MVI C,18 ;'SEARCH NEXT' ,9 ;'PRINT BUFFER' COMMAND CALL BDOS ;USE CP/M POP D ;GET OFFSET TABLE POINTER POP H ;GET NAME POINTER LDAX D ;GET OFFSET VALUE ; LXI B,14 ;EACH NAME IS 14 LONG ; MULT$14: DAD B ;ADD 14 FOR EACH OFFSET DCR A ;UNTIL OFFSET R B ;ARE SEQUENTIALLY NUMBERED JNZ NUMBER$FILES ; POP PSW ;GET FILE$COUNT FROM STACK PUSH PSW ;AND SAVE AGAIN FOR LATER ; ; ADI NBR$COL-1 MVI B,255 ;(B) ACCUMULATES QUOTIENT ;SO SET TO -1 FOR AT LEAST ;1 PASS THRU GIVES 0 O NEXT TABLE ENTRY POP D ;RECOVER TRAILER NAME POINT JMP COMPARE$LOOP ;LOOP AGAIN ; ; INSERT$NAME: LXI H,FILE$COUNT ;COUNT THE NUMBER OF FILES INR M ;TO BE DISPLAYED LHLD END$OF$TABLE ;GET POINTER TO TABLE XCHG LXI H,14 ;DISTANCECOUNTING MVI A,SCREEN$HGT ;SET FOR VIDEO DISPLAY SIZE STA LINE$COUNT ; LXI D,HEADING MVI C,9 ;BUFFER PRINTER COMMAND CALL BDOS ;CP/M PRINTS HEADING ; LXI H,DIR$TABLE - 14 ;POINT DUMMY 0TH ENTRY ; PRINT$LINE: PUSH H ;SAVE BASE AD <> 1, USE ;OFFSET3=OFFSET2-1 DCR B ;ELSE OFFSET3=OFFSET2-1Y ; SETOFFSET3: MOV M,B ;ELSE OFFSET TO COLUMN 4 ; ; REPRINT: POP PSW ;RECOVER FILE COUNT ; REPRINT1: PUSH PSW ;SAVE AGAIN FOR LATER USE STA FILE$COUNT ;SAVE FOR COMMAND JMP SORT$LOOP ; ASSIGN$MENU$NBR: LDA FILE$COUNT MOV B,A ;SAVE IN (B) PUSH PSW ;AND ON STACK MVI C,0 ;INITIAL FILE NUMBER LXI H,DIRTABLE+11 ;POINT FIRST FILE NUMBER LXI D,13 ;OFFSET TO OTHER NUMBERS ; NUMBER$FILES: MOV A= 0 JNZ MULT$14 PUSH H ;SAVE NEW NAME POINTER PUSH D ;SAVE OFFSET POINTER XCHG ;POINTER NAME TO PRINT W/(DE) MVI C,9 ;PRINT BUFFER CALL BDOS ;PRINT FILE NAME ;AND IT'S MENU NO. ; TEST$FINISH: LXI H,FILE$COUNT ;SEE IF DONE ; DIVX: INR B ; SUI NBR$COL ;DIVIDE (FILE$COUNT+3)BY ;FOUT TO GET OFFSET1 ; JP DIVX ADI NBR$COL ;SUBSTRACTED ONCE TOO MUCH ;SO ADD IT BACK ON LXI H,OFFSET1 MOV M,B ;INSERT OFFSET1 INTO TABLE INX H ;POINT OFFSET2 LOC TO MOVE DAD D ;(HL) POINT DESTINATION SHLD END$OF$TABLE ;SAVE THE NEW END OF TABLE INX H INX D MOVE$UP: DCX D DCX H LDAX D ;GET BYTE TO MOVE MOV M,A ;PUT IN NEW SPOT MOV A,C ;TEST FOR DONE CMP E ;(BC)=(DE)? JNZ MOVE$UP DRESS LXI D,OFFSET0 ;POINT OFFSET TABLE MVI A,NBR$COL ;4 COLUMN PER LINE ; PRINT$NAME: STA COLUMN$CNT ;SAVE COUNT OF COLUMNS PUSH H ;SAVE CURRENT NAME POINTER PUSH D ;SAVE OFFSET TABLE POINTER LXI D,DOUBL$SPACE ;PRINT 2 BLANKS MVI CHER 20H(ASCII ' ') USE$BLANK: ADI ' ' ;OR 20H + 10H FOR NUMERAL MOV M,A ;PUT IN TEXT STREAM MOV A,C ;GET UNITS PORTION ANI 0FH ;MASK OFF TENS PORTION ADI '0' ;CONVERT TO ASCII INX H MOV M,A DAD D ;REPEAT UNTIL ALL FILES DC,C ;PUT FILE NUMBER IN (A) ADI 1 ;INCREMENT DAA ;DECIMAL CONVERT MOV C,A ;RESAVE IN (C) RRC ;GET TENS DIGIT INTO RRC ;PROPER PLACE RRC ; RRC ANI 0FH ;ADD MASK JZ USE$BLANK ;SUPRESS LEADING ZERO BY ADI 10H ;ADD EITOTHER SAVE LINE CALL CRLF POP H ;GET BASE OF PREVIOUS LINE LXI D,14 ;ADD OFFSET DAD D JMP PRINT$LINE ; ; ; FINISH: POP H ;UNJUNK STACK ; LF$LOOP: CALL CRLF JP LF$LOOP ;OMIT THIS LINE IF DESIRED LXI D,PROMPT ;POINT INSTееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее CRLF: LXI D,CRLFMSG MVI C,9 CALL BDOS LXI H,LINE$COUNT DCR M RET ; ; CRLFMSG DB 0DH,0AH,'$' ; HEADING DB 0AH,9,9,9,' MENU',0DH,0AH,0AH,'$' ; IF BASIC$PROG ; COMMAND$NAME: DB 'BASIC ' ; LEN$CMD$NAME EQU $-COMMAND$NAME ; SPEC$TYECOVER FILE COUNTER CMP B ;FILE$ COUNT- REQUEST NO. JC REPRINT1 ;REDISPLAY MENU IF ILLEGAL ; LXI D,14 ;INC BETWEEN NAMES LXI H,DIR$TABLE-14 ;POINT DUMMY 0TH ENTRY ; FIND$NAME: DAD D ;ADD OFFSET B TIMES DCR B JNZ FIND$NAME ; ; ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее SELECTED FILE NAME MVI C,8 ;LENGTH OF FILE NAME CALL BLOCK$MOVE ; ; IF BASIC$PROG ; LXI H, SPEC$TYPE MVI C,4 CALL BLOCK$MOVE ; ENDIF ; XRA A ;NEEDS A 0 AT END STAX D ;OF COMMAND LINE ; RET ; ; ;SUBROUTINES ; BLOCK$MOVRUCTION MESSAGE MVI C,9 CALL BDOS LXI D,INPUT$BUFF MVI A,10 ;10 CHRS MAX STAX D MVI C,10 ;'READ BUFFER' COMMAND CALL BDOS ; ; ; LXI H,INPUT$BUFF+1 ;POINT TO CHR COUNTER MOV A,M ;GET IT AND SEE IF >2 CPI 3 JNC REPRINT ;NT: DB 0 ; IF BASIC$PROG ; SRCH$FCB: DB 0,'????????BAS',0 ; ENDIF ; SRCH$FCB: DB 0,'????????COM',0 ; ; DIR$TABLE: DB 255 ; STACK$AREA EQU 200*14 + 30 ; INPUT$BUFF EQU STACK$AREA ; ; ; EQUATES: ; BDOS EQU 5 NBR$COL EQU 4 CCPE: DB '.BAS' ; ENDIF ; PROMPT: DB 'ENTER MENU NUMBER & PRESS RETURN''$' ; DOUBL$SPACE: DB ' $' ; MENU$BUFF: DB ' - 0$' ; OFFSET0 DB 1 OFFSET1 DB 0,0,0 ; END$OF$TABLE: DW DIRTABLE ; FILE$COUNT: DB 0 COLUMN$CNT: DB 4 LINE$COU XCHG ;SAVE POINTER TO FILE NAME LHLD 6 ;GET BDOS ENTRY POINT LXI B,-CCP$LEN ;OFFSET TO START OF CM/M DAD B PUSH H ;SAVE CP/M ENTRY POINT ;ON STACK FOR BRANCH LXI B,8 ;OFFSET TO COMMAND BUFFER DAD B ;(HL) POINTS PLACE TO PUT ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееE: MOV A,M STAX D INX D INX H DCR C JNZ BLOCK$MOVE RET ; ASCII$CONVERT: SUI '0' ;SUBTRACT ASCII BIAS CPI 9+1 ;BE SURE IT'S NUMERIC CMC RC MOV D,A MOV A,B RLC RLC RLC ADD B RC ADD B RC ADD D MOV B,A RET ;REPRINT THE MENU MOV C,A ;COUNT OF DIGITS TO (C) MVI B,0 ; GET$MENU$NBR: INX H ;POINT ASCII DIGIT MOV A,M ;GET IT CALL ASCII$CONVERT ;CONVERT TO BINARY JC REPRINT ;RE-DISPLAY ON ERROR DCR C JNZ GET$MENU$NBR ; ; POP PSW ;RP$LEN EQU 3C06H-3400H SCREEN$SIZE EQU 24 SCREEN$HGT EQU 80 ; ; ; ; END TABLE: DB 255 ; STACK$AREA EQU 200*14 + 30 ; INPUT$BUFF EQU STACK$AREA ; ; ; EQUATES: ; BDOS EQU 5 NBR$COL EQU 4 CCUPDATE BUFFER POINTER TO INX H ;THE START OF THE COMMAND MOV M,D ;BUFF SO CP/M WILL READ ; IF BASIC$PROG ; LXI H,COMMAND$NAME ;POINT COMMAND NAME MVI C,LEN$CMD$NAME ;LENGHT OF COMMAND NAME CALL BLOCK$MOVE ; ENDIF ; POP H ;POINT ;NAME OF .COM FILE TO BE ;EXECUTED PUSH D ;SAVE POINTER TO FILE NAME XCHG ;(DE) POINTS COMMAND BUDFER ; ; ; LXI H,128 ;OFFSET TO END OF CMD BUFF ;WHERE POINTER IS STORED DAD D ;(HL) POIN TS STORAGE PLACE MOV M,E ; TITLE 'MIC-XFER - MOVE A FILE BETWEEN REGULAR CP/M AND MICROPOLIS' ; COPYRIGHT 1978,1979 BY BRUCE R. RATOFF. ALL RIGHTS RESERVED ; LAST REV 5/20/79 ; BUFFER EQU 80H ; BUFFER FOR DATA TRANSFER (CP/M DEFAULT) MBDOS EQU 3106H ; BDOS ENTRY POINT IN COPY IT TO FCB LXI B,11 CALL LDIR SHLD FILPTR ;UPDATE POINTER TO FILIST LXI D,COPMSG MVI C,9 ;ANNOUNCE WHAT WE'RE COPYING CALL BDOS LXI H,' $' SHLD HFCB+12 ;BY DROPPING '$' HERE, WE CAN PRINT STRAIGHT LXI D,HFCB+1 ; FROM FCB USING CP/MATION DRIVE STA MFCB MVI C,13 ;RESET MICROPOLIS SYSTEM CALL MBDOS LXI H,FILIST ;SCAN 'READ' SYSTEM FOR ELIGIBLE FILES, SHLD FILPTR ;DEVELOPING A LIST AT 'FILIST' AND A COUNT MVI A,1 ;AT 'NFILES' STA NFILES LXI D,DFCB MVI C,17 ;GIVE INNGTH OF MICROPOLIS CP/M SYSTEM IMAGE MSELDK EQU 3E1BH ; ADDR OF DRIVE SELECT VECTOR IN 17K SYSTEM ; BDOS EQU 5 ; BDOS ENTRY POINT IN HOST SYSTEM DFCB EQU 5CH ; FIRST DEFAULT FILE CONTROL BLOCK DFCB2 EQU 6CH ; SECOND DEFAULT FILE CONTROL BLOCK LOG JMP PGO ; ;THIS ROUTINE WILL TEST FOR BREAK AND PRINT A MESSAGE PEXIT: MVI C,11 PUSH D CALL BDOS ;CONSOLE STATUS CALL POP D RAR ;FORCE ABEND IF TRUE, ELSE JUST PRINT JNC PMESS ; ABEND: MVI A,1 ;MAKE PGO THINK IT'S FINISHED BY STA NFILEXECUTION ADDRESS LXI B,SYSLEN ;HOW MUCH TO MOVE CALL LDIR ;GO MOVE IT LXI H,MCTL ;SET UP POINTER TO MICROPOLIS CONTROLLER SHLD CONADR ;AS THE MICROPOLIS BOOT WOULD NORMALLY DO LXI H,0FFFFH ;ZAP CURRENT TRACK ON ALL MICROPOLIS DRIVES SHLD TRA 17K MIC CP/M SYSTEM MCTL EQU 0EE00H ; MICROPOLIS BOARD ADDRESS + 200H CONADR EQU 49H ; ADDRESS WHERE MICROPOLIS CP/M STORES MCTL MUNIT EQU 46H ; " " " " " UNIT # TRKTBL EQU 40H ; " " " " " TRKMOV C,A ;ADD OFFSET TO BUFFER ADDRESS MVI B,0 ;+ 1 TO SKIP DELETE FLAG IN DIRECTORY ENTRY LXI H,BUFFER+1 DAD B LXI B,11 ;MOVE NAME AND TYPE TO FILIST CALL LDIR LXI H,NFILES ;BUMP COUNT OF FILES INR M XCHG SHLD FILPTR ;UPDATE POINTER TITIAL SEARCH COMMAND CALL RDOS CPI 255 ;IF NO MATCHES AT ALL, COMPLAIN AND QUIT JZ FNFERR TOLIST: LHLD FILPTR ;HAVE A MATCH, MOVE IT INTO FILIST XCHG RRC ;COMPUTE (DIR ENTRY # MOD 4) * 32 RRC ;TO GET OFFSET INTO BUFFER RRC ANI 60H DSK EQU 4 ; WHERE CCP KEEPS CURRENT LOGGED DRIVE # ; ORG 100H START: LXI SP,HISYS-1 ;PUT STACK BELOW EXTRA SYSTEM IMAGE LDA DFCB2+1 ;LOOK AT DESTINATION SPECIFIER CPI 'M' ;MICROPOLIS? JZ MOVSYS ;THEN LEAVE POINTERS AS LOADED CPI 'I' ;IBM-FES ;ZAPPING FILE COUNT ; PMESS: MVI C,9 ;PRINT A MESSAGE CALL BDOS ; ;HERE TO COPY NEXT FILE PGO: LXI H,NFILES ;DECREMENT FILE COUNT, SEE IF ANY LEFT DCR M JZ 0 ;IF NONE LEFT, EXIT LHLD FILPTR ;POINT TO NEXT NAME IN FILIST LXI D,HFCB+1 ;KTBL ; (THIS FORCES A RECALIBRATE WHEN ACCESSED) SHLD TRKTBL+2 SHLD MRDBUF ;ZAP CURRENT TRK/SEC IN MICROPOLIS READ BUFFER SHLD MWRBUF ;AND WRITE BUFFER (FORCES A READ) LDA DFCB ;PRESERVE SOURCE DRIVE # STA HFCB LDA DFCB2 ;CARRY OVER DESTIN. # MRDBUF EQU 42F4H ; READ BUFFER IN 17K MICROPOLIS CP/M MWRBUF EQU 41E8H ; WRITE BUFFER IN 17K MICROPOLIS CP/M LOWSYS EQU 0A00H ; WHERE MOVCPM LEAVES SYSTEM IMAGE HISYS EQU 2900H ; START OF 17K MICROPOLIS CP/M SYSTEM IMAGE SYSLEN EQU 1900H ; LEO FILIST LXI D,DFCB MVI C,18 ;GIVE 'CONTINUE SEARCH' COMMAND CALL RDOS ;TO 'READ' SYSTEM CPI 255 ;END OF SEARCH? JNZ TOLIST ;NO, GO ADD IT TO LIST LXI H,FILIST ;WE HIT THE END, RESET POINTER TO FILIST SHLD FILPTR ; AND GO START COPYING A,B,C OR D' DB 13,10,' DEST-SYS MAY BE I (IBM) OR M (MICROPOLIS)' DB '$' SWPDOS: LXI H,BDOS ;SWAP READ AND WRITE DOS'S SHLD WDOS+1 LXI H,MBDOS SHLD RDOS+1 MOVSYS: LXI H,LOWSYS ;POINT TO MOVCPM SYSTEM IMAGE LXI D,HISYS ;POINT TO CORRECT ORMAT? JZ SWPDOS ;IF IBM, SWAP POINTERS LXI D,VALCMD ;ALL ELSE IS ILLEGAL, SO SQUAWK JMP ABEND VALCMD: DB 13,10,'VALID COMMAND FORMAT:' DB 13,10,'MIC-XFER SRCE-DRVE:SRCE-FILE.TYP DEST-DRVE:DEST-SYS' DB 13,10,' SRCE-DRVE AND DEST-DRVE MAY BE 'PRINT BUFFER' CALL MVI C,9 CALL BDOS LXI H,0 ;CLEAN OUT '$' SO FILE CALLS WILL WORK SHLD HFCB+12 SHLD HFCB+14 OPENI: LXI D,HFCB ;OPEN FILE ON 'READ' DOS MVI C,15 CALL RDOS INR A JNZ GOTFIL FNFERR: LXI D,FNFMSG ;KVETCH IF OPEN FAILS BЕ  KNOWN®  (THIУ  MAЩ  BЕ  DETERMINEД  BЩ Ќ INSPECTINЗ THЕ ADDRESУ JUMPERУ OО THЕ  MICROPOLIУ Ќ CONTROLLEТ BOARD¬ ANД INTERPRETINЗ THEН ACCORDINЗ Ќ TП THЕ Mееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее ;OPEN DESTINATION FILE MVI C,15 CALL WDOS INR A JNZ OOPNOK LXI D,COFMSG ;HOW CAN CREATE SUCCEED AND OPEN FAIL? JMP PEXIT COFMSG: DB 'CANNOT OPEN OUTPUT FILE$' OOPNOK: LXI D,HFCB ;READ SECTOR FROM 'READ' DOS MVI C,20 CALL RDOS ORA A ;: 1® IBM-FORMAФ CP/Н SYSTEН CONFIGUREД FOТ AФ LEASФ 28K. 2® MICROPOLIУ CP/Н SYSTEН CONFIGUREД FOТ 17K. 3® THЕ  SOURCЕ  FILЕ  'MIC-XFER.ASM§ (PROVIDEД  OО  THIУ DISK). N CLOSE$' ; LDIR: MOV A,M ;THIS BLOCK MOVE ROUTINE SIMULATES STAX D ;A Z80 'LDIR' INSTRUCTION INX H INX D DCX B MOV A,B ORA C JNZ LDIR RET ; RDOS: JMP BDOS ;POINTER TO DOS FOR READS WDOS: JMP MBDOS ;POINTER TO DOS FOR WRITES ; HF JMP PEXIT FNFMSG: DB 'FILE NOT FOUND$' GOTFIL: LXI H,HFCB+1 ;COPY NAME TO 'WRITE' FCB LXI D,MFCB+1 LXI B,11 CALL LDIR MVI B,21 SUB A ;CLEAR REST OF 'WRITE' FCB FCBZ: STAX D INX D DCR B JNZ FCBZ STA HFCB+32 ;CLEAR 'NEXT SECTOR' IN RееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееASSUME ERROR RETURN IS EOF JNZ COPDON LXI D,MFCB ;WRITE SECTOR TO 'WRITE' DOS MVI C,21 CALL WDOS ORA A ;MAKE SURE WRITE SUCCEEDS JZ OOPNOK ;IF SO, GO BACK FOR MORE LXI D,WERMSG ;ELSE KVETCH MVI C,9 CALL BDOS JMP PEXIT WERMSG: DB 'DI 4® THЕ ABILITЩ FOТ #± ANД #І TП RESIDЕ IО THЕ SAMЕ BUУ AT THE SAME TIME WITHOUT ANY HARDWARE CONFLICTS. 5®  THЕ MICROPOLIУ CONTROLLEТ ADDRESУ (BOOTSTRAР ADDRESS© Ќ MUSФ  CB: DS 33 ;FCB FOR READS MFCB: DS 33 ;FCB FOR WRITES FILPTR: DS 2 ;POINTER TO CURRENT FILE IN FILIST NFILES: DS 1 ;COUNT OF FILES IN FILIST FILIST: DS 254*11 ;LIST OF FILENAMES TO BE COPIED ; END EAD FCB LXI D,MFCB ;DELETE DESTINATION FILE MVI C,19 CALL WDOS MVI C,22 ;CREATE DESTINATION FILE LXI D,MFCB CALL WDOS INR A JNZ CREOK LXI D,CNCMSG ;KVETCH IF CREATE FAILS JMP PEXIT CNCMSG: DB 'CANNOT CREATE FILE$' CREOK: LXI D,MFCB INSTALLATION AND USE OF MIC-XFER PROGRAM ------------ --- --- -- -------- ------- SYSTEM REQUIREMENTS: IО ORDEТ TП USEТ MIC-XFER¬ THЕ FOLLOWINЗ MINIMUН CONFIGURATIOО IУ Ќ REQUIREDALL MSELDK POP PSW LXI D,OKMSG ;ANNOUNCE SUCCESSFUL COPY INR A ;OR CLOSE ERROR, DEPENDING ON RETURN JNZ PEXIT LXI D,CERMSG JMP PEXIT ;PRINT MESSAGE AND CONTINUE COPMSG: DB 13,10,'COPYING $' OKMSG: DB 'SUCCESSFUL COPY$' CERMSG: DB 'ERROR OSK WRITE ERROR$' COPDON: MVI C,16 ;CLOSE OUTPUT FILE LXI D,MFCB CALL WDOS PUSH PSW LDA MUNIT ;MOMENTARILY CHANGING UNITS WILL ASSURE XRI 1 ;THAT MICROPOLIS CP/M HAS FLUSHED ITS BUFFERS MOV C,A CALL MSELDK LDA MUNIT XRI 1 MOV C,A CICROPOLIУ MANUAL). 6®  THЕ  ADDRESУ OЖ THЕ IBM-FORMAФ CP/Н WARН STARФ VECTOТ Ќ MUSФ  BЕ  KNOWN®  (THIУ  MAЩ  BЕ  DETERMINEД  BЩ Ќ EXAMININЗ  LOCATIONУ ± ANД І IО MEMORЩ WHILЕ  THЕ Ќ DESTINATIOО DRIVE¬  ANД DIRECTIOО OЖ TRANSFEТ MAЩ BЕ SPECIFIEД IО Ќ THЕ  COMMANД  LINE®  THЕ CP/Н WILDCARDУ '?§ ANД  '*§  ARЕ  FULLЩ Ќ IMPLEMENTED¬  MAKINЗ  MULTIPLЕ FILEУ OТ EVEО WHOLE-DISЛ TRANSFERУ Ќ VERЩ EASY® MIC-XFE VALUЕ OЖ 'MCTL§ IУ FA00. 2®  EDIФ THЕ CORRECФ VALUЕ OЖ 'MCTL§ FOТ YOUТ SYSTEН INTП Ќ MIC-XFER.ASM®  THЕ  'EQU§ FOТ 'MCTL§ MAЩ BЕ FOUNД  OО Ќ LINЕ 6. 3®  WHILЕ YOХ ARЕ IО THЕ EDITOR¬ROPOLIS SYSTEM WILL BOOT UP AND SIGN ON. 3. CREATE A SYSTEM IMAGE FILE BY TYPING: A>SYSGEN SYSGEN VERS 1.4 SOURCE DRIVE NAME (OR RETURN TO SKIP) A 2500 0100 -IMIC-XFER.HEX -R -G0 A>SAVE 36 MIC-XFER.COM THIS COMPLETES INSTALLATION OF MIC-XFER IN YOUR SYSTEM. Ќ DISK¬   YOХ  MUSФ  CUSTOMIZЕ  MIC-XFER.ASН  FOТ  YOUТ  MICROPOLIУ Ќ CONTROLLER¬  ANД THEО ASSEMBLЕ IФ ANД COMBINЕ IФ WITИ  MIC17.COM® Ќ THIУ IУ DONЕ AУ FOLLOWS: 1®  DETERMINЕ  THЕ CORRECФ VALUЕ FOТ THЕ SYMBOМ ' IBM-FORMAФ SYSTEН IУ RUNNING). THЕ FIRSФ STEР IО GENERATINЗ MIC-XFEТ FOТ YOUТ SYSTEН IУ TП GEФ Б Ќ COPЩ OЖ YOUТ 17Л MICROPOLIУ SYSTEН IMAGЕ ONTП AО IBM-FORMAФ DISK® Ќ THIУ MAЩ BЕ DONE AS FOLLOWS: ASSEMBLЕ MIC-XFEТ USINЗ 'MAC'¬  THЕ 'TITLE§  STATEMENФ Ќ WILМ  BЕ ACCEPTEД PROPERLY¬  ANД NEEД NOФ BЕ COMMENTEД Ќ OUT. 4®  USINЗ  EITHEТ 'ASM§ OТ 'MAC'¬  ASSEMBLЕ  MIC-XFEТ  TП Ќ   YOХ MAЩ WANФ TП COMMENФ Ќ OUФ THЕ 'TITLE§ STATEMENФ IО LINЕ 1®  IЖ YOХ ASSEMBLЕ Ќ MIC-XFEТ USINЗ 'ASM'¬ THIУ LINЕ WILМ PRODUCЕ AО ERROR¬ Ќ BUФ THЕ CORRECФ CODЕ WILМ STILМ BЕ GENERATED®  IЖ YOХ Ќ FUNCTION COMPLETE DESTINATION DRIVE NAME (OR RETURN TO REBOOT) A>SAVE 36 MIC17.COM 4®  TRANSFEТ MIC17.COН TП THЕ IBM-FORMAФ SYSTEН BЩ TYPINЗ Ќ (FROН THE 2 USING MIC-XFER: MIC-XFEТ  WILМ  TRANSFEТ ONЕ OТ MORЕ FILEУ BETWEEО AО  IBM-FORMAФ Ќ CP/Н  SYSTEН  ANД Б MICROPOLIУ CP/Н SYSTEM®  THЕ  SOURCЕ  DRIVE¬ ЌMCTL§ IО Ќ MIC-XFER®  THIУ  MAЩ BЕ CALCULATEД BЩ ADDINЗ 200И  TП Ќ THЕ  MICROPOLIУ BOOФ ADDRESS®  FOТ EXAMPLE¬  IЖ  YOUТ Ќ MICROPOLIУ  BOOФ  ADDRESУ IУ F800¬  THEО  THЕ  CORRECФ Ќ 1. BOOT THE IBM-FORMAT SYSTEM. 2. TRANSFER CONTROL TO THE MICROPOLIS SYSTEM BY TYPING: A>DDT DDT VERS 1.4 -G THE MIC PRODUCЕ THE OBJECT FILE 'MIC-XFER.HEX'. 5. MERGE MIC-XFER.HEX WITH MIC17.COM BY TYPING: A>DDT MIC17.COM DDT VERS 1.4 NEXT PC FORMAФ  SYSTEН SHOULД WARM-BOOФ  ANД  PROMPT® Ќ TYPE: A>SAVE 36 MIC17.COM 1 NOЧ THAФ YOХ HAVЕ Б COPЩ OЖ YOUТ MICROPOLIУ CP/Н OО AО IBM-FORMAФ MICROPOLIS SYSTEM): A>DDT MIC17.COM DDT VERS 1.4 NEXT PC 2500 0100 -G THЕ  IBM-Т IУ EXECUTEД BЩ TYPING: A>MIC-XFER S:FFFFFFFF.TTT D:X WHERE: S IS THE SOURCE DRIVE FFFFFFFF IS THE AMBIGUOUS OR NON-AMBIGUOUS FILENAME routine, added CP/M 2.x f1' protect test, ; cleaned up file. (KBP) ; ;09/21/80 Added test for SYS files, moved TAG test, ; removed extra OPEN of file. (KBP) ; ; NOTE: REQUIRES 'MAC' AND SEQIO.LIB TO ASSEMBLE ; ORG 100H ; MACLIB SEQIO ;DEFIllows listing of multiple files by using ; normal CP/M ambiguous file names (i.e., ; MLIST *.ASM). Before each file is printed, ; the FILENAME.TYPE is displayed. ; ; Use CTL-S to pause, CTL-C to abort. ; Other characters are ignored. ; ; This prog MIC-XFEТ  WILМ REPORФ EACИ FILENAMЕ AУ  IФ  IУ Ќ TRANSFERRED¬  AУ WELМ AУ ANЩ ERRORУ WHICИ MAЩ OCCUR® AО ERROТ OО Ќ ONЕ  FILЕ OЖ Б MULTI-FILЕ TRANSFEТ WILМ NOФ ABORФ THЕ TRANSFEТ OЖ Ќ THЕ  REMAININЗ FILES®  EXECUTIOО MAЩ BЕ INTER Added check for '#' character ; as the last character in the file type indicat- ; ing the file was not for distribution. Routine ; issues an error message and continues. Added ; check for 'first time flag' to exit routine so ; if no file isееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее TTT IS THE AMBIGUOUS OR NON-AMBIGUOUS FILETYPE D IS THE DESTINATION DRIVE X IS THE DESTINATION SYSTEM - I=IBM-FORMAT ame it so the last ; character of the file type is #. Example: MYFILE.AS# ; ; CP/M 2.x users may use 'TAG.COM' to set the f1' attribute ; of a file, which will prevent this program from listing it. ; ; ;05/27/80 Revised to abort on attempting to ;ram allows CP/M 1.4 users to have protected ; ASCII files on a remote system, provided that the CCP ; 'REN' (rename) and 'TYPE' functions have been changed ; to some other characters and MLIST.COM has been renamed ; to TYPE.COM. To protect a file, renRUPTEД BЩ  STRIKINЗ Ќ CONTROL-C¬  WHICИ  WILМ  BЕ RECOGNIZEД AФ THЕ COMPLETIOО  OЖ  THЕ Ќ CURRENФ FILЕ TRANSFER. 3  found meeting the requested ; parameters, '++NOT FOUND++' is issued to the ; console. NOTE: This required modifying the manner ; in which 'MFFLG1' was handled. J. Seymour ; ;09/20/80 Added ILPRT routine, revised messages, added new ; abort; ; MLIST.ASM - V3.4 ; by Keith Petersen, W8SDZ ; (revised 9/21/80) ; ; This program lists any size ASCII file by name, reading ; up to 16k of the file into memory at one time, in order ; to minimize disk activity during printout. ; ; A M=MICROPOLIS FOТ EXAMPLE¬  TП TRANSFEТ ALМ '.COM§ FILEУ OО IBM-FORMAФ DRIVЕ  В Ќ TП MICROPOLIУ DRIVЕ A¬ YOХ WOULД TYPE: A>MIC-XFER B:*.COM A:M WHILЕ  EXECUTING¬  list a CP/M .COM file. TVC ; ;09/09/80 Revised check for '.COM' and '.OBJ' files so ; during attempt to list multiple files these ; would not abort the routine. Modified to ; issue an error message and continue with the ; next valid file.ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееNE MACRO LIBRARY ; START: JMP START2 ;JMP AROUND IDENT DB 'MLIST.COM ver 3.4 9/21/80' ; START2: LXI H,0 DAD SP ;GET OLD STACK SHLD OLDSTK ;SAVE IT LXI SP,STACK;SET NEW STACK LHLD 1 ;POINT TO CP/M'S JMP TABLE LXI D,3 ;READY FOR ADD DAD D POINT TO NEXT MOV A,M ;TEST ORA A ;..FOR END JNZ ILPLP MVI A,CR CALL TYPE MVI A,LF CALL TYPE XTHL ;RESTORE HL, RET ADDR RET ;RET PAST MSG ; ;TYPE CHAR IN A ; TYPE: PUSH B PUSH D PUSH H ANI 7FH ;STRIP PARITY BIT MOV E,A ;CHARADLP ;IF NOT IT'S OK TO PRINT DCX H MOV A,M ;WAS 'O', CHK NEXT CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'C' ; 'C' AS IN '.COM'? JNZ READLP ;IF NOT, IT'S OK TO PRINT CALL ILPRT ;PRINT: DB '++CAN''T LIST A .COM FILE++',0 JMP MORE ;MORE TO PRINT? ;PRINT: DB '++FILE NOT FOUND++',0 JMP EXIT ; DONE CALL ILPRT ;PRINT: DB 'DONE',0 JMP EXIT ; ;CHECK HERE FOR FILE PROTECTED BY CP/M 2.x f1' ATTRIBUTE ; CKFIL LDA MFCUR+1 ;POINT TO TAG FILE ATTR ANI 80H ;IS IT TAGGED? JZ CKFIL2 ;IF NOT, CO;CTL-S? CZ CI ;YES, GET VALUE CPI 'C'-40H ;ABORT? JZ EXITA ;YES, PRINT ABORT MSG, EXIT RET ; CSTS PUSH B PUSH D PUSH H CSTSC CALL $-$ ;CHANGED BY INIT POP H POP D POP B RET ;FROM "CSTS" ; CI PUSH B PUSH D PUSH H CIC CALL $-$ IN,,1,,16384,DSKBUF ; ;CHECK HERE FOR FILE PROTECTED BY A '#' AS THE LAST ;CHARACTER IN THE FILETYPE (EG. MLIST.AS#). ; LXI H,FCB+11 ;POINT TO LAST CHAR IN FCB MOV A,M ;GET IT ANI 7FH ;STRIP CP/M 2.x ATTR CPI '#' ;PROTECTED FILE? JZ PROXIT ;P;POINT TO CONSOLE STATUS SHLD CSTSC+1 ;MODIFY CALL ADDRESS DAD D ;POINT TO CONSOLE INPUT SHLD CIC+1 ;MODIFY CALL ADDRESS CALL ILPRT ;PRINT: DB 'MLIST ver 3.4',CR,LF DB 'CTL-S pauses, CTL-C aborts',0 LDA FCB+1 CPI ' ' ;SEE IF FILENAME THERE IF NOT, LIST DCX H MOV A,M ;WAS, CHK FIRST CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ; 'O' AS IN '.OBJ'? JNZ READLP ;IF NOT, PRINT THE FILE, IF SO CALL ILPRT ;PRINT: DB '++CAN''T LIST AN .OBJ FILE++',0 JMP MORE ;MORE TO PRINT? ; ;WRITE TH ; ;HERE WE CHECK FOR AN ATTEMPT TO LIST AN OBJECT FILE ; OBJCHK CPI 'J' ;WAS LAST CHAR AN 'J' THEN? JNZ READLP ;IF NOT, OK TO LIST DCX H MOV A,M ;MIGHT BE '.OBJ', CHK NEXT CHR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'B' ;IS IT A 'B'? JNZ READLP ;NTINUE ; PROXIT CALL ILPRT ;PRINT: DB '++FILE NOT FOR DISTRIBUTION, SORRY++',0 JMP MORE ;SEE IF ANOTHER ; CKFIL2 LDA MFCUR+10 ;POINT TO SYS FILE ATTR ANI 80H ;IS IT SYS? JZ MOVNAM ;IF NOT, CONTINUE JMP PROXIT ;SYS FILE, CAN'T PRINT IT ; ;MO;CHANGED BY INIT POP H POP D POP B RET ;FROM "CI" ; ; ;INLINE PRINT ROUTINE ; CALL ILPRT ; DB 'MSG',0 ; ILPRT MVI A,CR CALL TYPE MVI A,LF CALL TYPE XTHL ;SAVE HL, GET MSG ; ILPLP MOV A,M ;GET CHAR CALL TYPE ;OUTPUT IT INX H ;ROTECTED FILE, EXIT WITH MSG ; ;CHECK HERE FOR .COM FILE, WHICH CAN'T BE PRINTED ;EITHER ; CPI 'M' ;WAS LAST CHAR AN 'M'? JNZ OBJCHK ;IF NOT, CHK FOR '.OBJ' TYPE DCX H MOV A,M ;CHK NEXT ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ;AN 'O'? JNZ RE JNZ MORE CALL ILPRT ;PRINT: DB '++NO FILE NAME SPECIFIED++',0 JMP EXIT ; MORE: CALL MFNAME JNC CKFIL ;ANOTHER FILE FOUND, PRINT IT LDA MFFLG1 ;NOTHING FOUND, CHECK... ORA A ;... FIRST TIME FLAG JZ DONE ;AT LEAST ONE WAS FOUND CALL ILPRTE FILE TO CONSOLE ; READLP: GET DISKIN CPI EOF ;END OF FILE? JZ MORE ;YES, MORE FILES TO PRINT? CALL TYPE ;SEND CHAR TO CONSOLE CALL CSTS ;KEY PRESSED? ORA A CNZ CKKB ;CHECK WHAT KEY JMP READLP ; CKKB CALL CI ;SEE WHAT CHAR CPI 'S'-40H R,LF,0 ; ; DEFINE SOURCE FILE: ; ; INFILE = INPUT FILE MODE ; DISKIN = INTERNAL NAME ; (NUL) = DEFAULT DISK DRIVE ; 1 = FIRST DEFAULT NAME (TFCB) ; (NUL) = " " TYPE ; 16384 = BUFFER SIZE ; DSKBUF = DISK BUFFER AREA ; FILE INFILE,DISKVE FILENAME FROM FCB+1 TO FNAME MOVNAM LXI H,FCB+1 LXI D,FNAME LXI B,8 CALL MOVER ;MOVE FILETYPE FROM FCB+9 TO FNAME+9 LXI H,FCB+9 LXI D,FNAME+9 LXI B,3 CALL MOVER CALL ILPRT ;PRINT: DB CR,LF,'--> FILE: ' FNAME DB 'XXXXXXXX.XXX' DB CACTER TO E FOR CP/M MVI C,WRCON CALL BDOS POP H POP D POP B RET ; EXITA MVI C,CSTAT ;GET CONSOLE STATUS CALL BDOS ORA A ;CHARACTER WAITING? MVI C,RDCON CNZ BDOS ;YES, CLEAR CHARACTER FROM CP/M CALL ILPRT ;PRINT: DB CR,LF,'++ABORTE* * * * * ; ;PLEASE PASS ON MODS, BUGS, ETC, SO YOUR ;FIXES OR ENHANCEMENTS MAY BE SHARED BY ALL, ; TO: ; Ward Christensen ; 688 E. 154th St. #5D ; Dolton, Il. 60419 ; ; (312) 849-6279 ; ;You may send a self-addressed stamped postcard ;to EN EQU 15 SRCHF EQU 17 SRCHN EQU 18 STDMA EQU 26 BDOS EQU 5 FCB EQU 5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 ; END  SAVED HERE ; DSKBUF: DS 16384 ;16K BUFFER ; ;BDOS/CBIOS EQUATES ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CSTAT EQU 11 OPADDR, FCB>> MVI C,STDMA LXI D,80H CALL BDOS XRA A STA FCBEXT STA FCBRNO ;<> LDA MFFLG1 ORA A JZ MFN01 ;<> ;SAVE ORIG REQ LXI H,FCB LXI D,MFREQ LXI B,12 CALL MOVER LDA FCB STA MFCUR ;SH WITH 4MHZ Z80 CPU. ;SEE EQUATES FOR OTHER OPTIONS INCLUDING SYSTEM CLOCK ;FREQUENCY. ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * THIS PROGRAM DOCUMENTED IN "MODEM.DOC" * * * * * * * * * * * * * * * * * * * * * * * * * *FFLG1 ;TURN OFF 1ST TIME SW ;<> RET ;------------------------------------------------ ; ;MOVE SUBROUTINE ; MOVER MOV A,M STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVER RET ; ;MULTI-FILE ACCESS WORK AREA ; MFFLG1 DB 1 ;D++',0 ; EXIT LXI D,80H ;SET DMA ADDRESS TO NORMAL MVI C,STDMA ;FUNCTION NUMBER TO DO IT CALL BDOS ;DO IT LHLD OLDSTK ;GET OLD STACK SPHL ;RESTORE IT RET ;RETURN TO CP/M ; ;MULTI-FILE ACCESS SUBROUTINE. ALLOWS PROCESSING ;OF MULTIPLE FILEееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееAVE DISK IN CURR FCB ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D,FCB CALL BDOS ;<> JMP MFN02 ; MFN01: ;<> LXI H,MFCUR LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D * * * THIS PROGRAM WAS "MODEM.ASM" BUT IS * * TEMPORARILY NAMED "MODEM926.ASM" SO PEOPLE * * WILL REALIZE IT IS AN ENHANCEMENT OF * * THE ORIGINAL PROGRAM "MODEM.ASM" ON CP/M * * USER'S GROUP DISK 25. * * * * * * * * * * * * * * * * * * * * * 1ST TIME SW MFREQ DS 12 ;REQ NAME MFCUR DS 12 ;CURR NAME ; DS 60 ;STACK AREA STACK: EQU $ OLDSTK: DS 2 ;OLD STACK POINTER SAVED HERE ; DSKBUF: DS 16384 ;16K BUFFER ; ;BDOS/CBIOS EQUATES ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CSTAT EQU 11 OPS (I.E. *.ASM) FROM DISK. THIS ;ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH ;TIME IT IS CALLED. CARRY IS SET IF NO MORE NAMES ;CAN BE FOUND. THE ROUTINE IS COMMENTED IN PSEUDO ;CODE, EACH PSEUDO CODE STATEMENT IS IN <<...>> ; MFNAME: ;<> POP H LXI D,FCB+1 LXI B,11 CALL MOVER ;<> XRA A STA FCBEXT STA FCBRNO STA M,FCB CALL BDOS ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHN LXI D,FCB CALL BDOS ;<> MFN02: ;<> INR A STC RZ ;<> DCR A ANI 3 ADD A ADD be informed of changes/bugs as they become ;known. ; ; -------------- ; ; 09/23/77 ;ORIGINALLY WRITTEN BY WARD CHRISTENSEN ; ; 04/26/79 ;REWRITTEN BY WARD CHRISTENSEN TO COMBINE ;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD ;AND BY KEITH PETERSEN, BAUD, CAR. ON, ANSW. ENDIF ; ;IF YOU ARE USING AN EXTERNAL MODEM (NOT S-100 PLUG-IN) ;CHANGE THESE EQUATES FOR YOUR MODEM PORT REQUIREMENTS ; INITREQ EQU FALSE ;TRUE, IF MODEM PORT INIT. REQ'D INITC1 EQU 64H ;1ST INIT CHAR TO CTL PORT INITC2 EQU QUATES FOR FALSE AND TRUE TO MAKE ASSEMBLY ;OPTIONS CLEARER. REMOVED H8 PORT EQUATES (THEY CAN ;BE PUT IN EXTERNAL MODEM EQUATES). (KBP) ; ; 09/26/80 ;ADDED AUTO-DIAL AND AUTO-REDIAL LOGIC FOR D.C. HAYES ;CONDITIONAL ASSEMBLY. DO I HEAR A VOLUNTEER OR RECEIVING END TO COME UP. ADD 'H' AFTER MSG ;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO ;BE SENT. (KBP) ; ; 05/24/79 ;FIX MISSING RETURN INSTRUCTION AT END OF ;INITIALIZATION ROUTINE. (KBP) ; ; 07/01/79 ;MODIFIED PROGRAM TO ALLOW FOR NONES MODSNDB EQU 2 ;BIT TO TEST FOR SEND MODSNDR EQU 2 ;VALUE WHEN READY MODRCVB EQU 1 ;BIT TO TEST FOR RECEIVE MODRCVR EQU 1 ;VALUE WHEN READY MODDATP EQU 90H ;DATA PORT MODCTL2 EQU 91H ;SECOND CTL PORT ENDIF ; IF PMMI ORIGMOD EQU 1DH ;8 DATA, NQUATES FOR EXTERNAL MODEM (NOT S-100 PLUG-IN) ;(KBP) ; ; 12/06/79 ;CORRECTED ERROR IN HELP FILE. SAID T.110, NOW SAYS ;TO.110. BY WARD CHRISTENSEN. CORRECTED RECEIVE FILE ;ROUTINE SO TERMINAL OR ECHO MODE WORKS AFTER FILE ;TRANSFER IN QUIET MODE. MOW8SDZ, AND SUGGESTIONS ;BY JIM BELL WHICH KEITH IMPLEMENTED. SEE ;MODEM.DOC FOR ADDITIONAL HISTORICAL ;INFORMATION AND DOCUMENTATION. ; ; 05/09/79 ;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL ;OR ECHO MODEM AFTER TRANSFERRING A FILE. (WLC) ; S ENDIF ; IF ALTCPM BASE EQU 4200H ;CP/M BASE ADDRESS FOR ALTERNATE CP/M ENDIF ; PMMI EQU FALSE ;TRUE, IS PMMI MODEM ; DCH EQU TRUE ;TRUE, IS D.C. HAYES MODEM ; IF PMMI MODCTLP EQU 0C0H ;PMMI VALUES MODSNDB EQU 1 ;BIT TO TEST FOR SEND MOTO ADAPT ;THIS TO PMMI? (BRUCE R. RATOFF) ; ; ;DEFINE FALSE AND TRUE ; FALSE EQU 0 TRUE EQU NOT FALSE ; STDCPM EQU TRUE ;TRUE, IS STANDARD CP/M ALTCPM EQU FALSE ;TRUE, IS ALTERNATE CP/M FOR H8 OR TRS80 ; IF STDCPM BASE EQU 0 ;CP/M BASE ADDRES-STANDARD VERSIONS OF ;CP/M. ALL REFERENCES TO ENTRIES INTO CP/M SHOULD BE MADE ;RELATIVE TO THE VARIABLE SYMBOL CALL "BASE". FOR EXAMPLE, ;THE EQUATE TO BDOS SHOULD BE BASE+5 INSTEAD OF 5. BASE ;WILL BE SET TO 0 WHEN THE VARIABLE STDCPM IS SET TO TRUEO PARITY, ORIG ANSWMOD EQU 1EH ;8 DATA, NO PARITY, ANSW ENDIF ; ;NOTE: IF DC HAYES THEN BAUD RATE DEFAULTS TO ;300 - 1 STOP BIT. DO NOT CHANGE NEXT EQUATES IF DCH ORIGMOD EQU 86H ;OFF HOOK, 110 BAUD, CAR. ON, ORIG. ANSWMOD EQU 82H ;OFF HOOK, 110VED CHECKS FOR "H" AND ;"X" OPTIONS SO MODEM IS NOT REINITIALIZED. (KBP) ; ; 05/27/80 ;ELIMINATED CONTROL-X CANCEL OF SEND FEATURE, AT ;SUGGESTION OF WARD CHRISTENSEN. A LINE GLITCH COULD ;CAUSE PREMATURE ABORT WHEN THIS FEATURE WAS ACTIVE. ;ADDED E ; 05/22/79 ;ADD FEATURE TO MAKE RECEIVE FILE ROUTINE SAY ;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE. ;MOVE INITIAL GOBBLE GARBAGE INPUTS TO BEFORE ;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGE ;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME ;FDSNDR EQU 1 ;VALUE WHEN READY MODRCVB EQU 2 ;BIT TO TEST FOR RECEIVE MODRCVR EQU 2 ;VALUE WHEN READY MODDATP EQU 0C1H ;DATA PORT BAUDRP EQU 0C2H ;BAUD RATE OUTPUT MODCTL2 EQU 0C3H ;SECOND CTL PORT ENDIF ; IF DCH MODCTLP EQU 92H ;D. C. HAYES VALUONTROL E - NOW CORRECTLY LOOKS FOR CONTROL X). ADD ;REGISTER SAVES TO CONOUT, KEYIN AND AND KEYBOARD STATUS ;ROUTINES, AS SOME CBIOS ROUTINES CLOBBER THEM. (KBP) ; ; 08/05/79 ;ADDED D. C. HAYES MODEM SUPPORT BY JIM BELL (KBP) ; ; 08/06/79 ;ADDED E. ;(BOB MATHIAS). ; ; 07/24/79 ;MOVE INITIALIZE LOCAL STACK TO BEGINNING OF PROGRAM ;SO DEFAULT STACK IS NOT USED. ADD CONDITIONAL ASSEMBLY ;OPTION TO TERMINAL ROUTINE FOR TIMESHARE SYSTEMS. ;CORRECT ERROR IN LOCAL ABORT ROUTINE (WAS LOOKING FOR ;C64H ;2ND INIT CHAR TO CTL PORT INITC3 EQU 64H ;3RD INIT CHAR TO CTL PORT INITC4 EQU 64H ;4TH INIT CHAR TO CTL PORT ; IF NOT PMMI AND NOT DCH MODCTLP EQU 02H ;PUT YOUR MODEM CONTROL PORT HERE MODSNDB EQU 80H ;YOUR BIT TO TEST FOR SEND MODSNDR EQU 80 FORTH AD INFINITUM. ; IF NOT DCH TRMECHO IN MODCTLP ;GET STATUS ENDIF ; IF DCH TRMECHO IN MODCTL2 ;GET STATUS ENDIF ; ANI MODRCVB ;ISOLATE READY BIT CPI MODRCVR ;ARE WE READY? JZ LINECHR ;YES, READ THE CHR CALL STAT ;CHECK LOCAL KB TION ; JMP BADOPT ; * * * * * * * * * * * * * * * * * * * * * * * * TERM: TERMINAL MODE * * * * * * * * * * * * * * * * * * * * * * * * ; ;THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS ;DOWN THE LINE, AND DISPLAYS CHARACTERS ;RECEIVED FRG OPTION ;IS SELECTED: ; TIMESHR EQU FALSE ;TRUE TO MAKE BIT 7 HIGH ; ;DEFINE ASCII CHARACTERS USED ; SOH EQU 1 ;START OF HEADER EOT EQU 4 ;END OF TRANSMISSION ACK EQU 6 ;ACKNOWLEDGE BEL EQU 7 ;BELL NAK EQU 15H ;NEG ACKNOWLEDGE CAN EQU 18H ;CA;READ STATUS ENDIF ; ANI MODRCVB ;ISOLATE BIT CPI MODRCVR ;READY? JNZ TERM ;..NO, LOOP IN MODDATP ;READ DATA ANI 7FH ;STRIP PARITY BIT CALL TYPE ;TYPE IT JMP TERM ;LOOP ; * * * * * * * * * * * * * * * * * * * * * * * * TRMECHO: TEROR PHONE # AND DIAL IT IF PRESENT ENDIF ; ;GOBBLE UP GARBAGE CHARS FROM THE LINE ;PRIOR TO RECEIVE OR SEND ; IN MODDATP IN MODDATP ; ;JMP TO APPROPRIATE FUNCTION ; LDA OPTION ;GET PRIMARY OPTION ; CPI 'C' ;(COMPAT W/EARLIER JZ TRMECHO ;H ;YOUR VALUE WHEN READY MODRCVB EQU 40H ;YOUR BIT TO TEST FOR RECEIVE MODRCVR EQU 40H ;YOUR VALUE WHEN READY MODDATP EQU 03H ;YOUR MODEM DATA PORT ENDIF ;END OF EXTERNAL MODEM EQUATES ; ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS EXITCHR EQU 'E'-40H ;CTLUTURE ENHANCEMENT WILL BE TO WRITE THE ;RECEIVED DATA IN MEMORY, AND ALLOW IT TO ;BE WRITTEN TO DISK ; TERM CALL STAT ;LOCAL CHAR KEYED? JZ TERML ;..NO, CHECK LINE CALL KEYIN ;GET CHAR CPI EXITCHR ;TIME TO END? JZ CKDIS ;YES, CK DISCONN CPI DOM THE LINE. THIS MAKES IT ;SUITABLE FOR COMMUNICATION WITH TIME SHARING ;COMPUTERS, CBBS'S, OR ANOTHER PROGRAM ;RUNING "MODEM E" (ECHO MODE) ; ;TYPE THE "EXITCHR" (ORIGINALLY CTL-E) TO EXIT. ;OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONN. ; ;A FNCEL LF EQU 10 ;LINEFEED CR EQU 13 ;CARRIAGE RETURN ; ORG BASE+100H ; ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=STACK FROM CP/M SHLD STACK ;..SAVE IT LXI SP,STACK ;SP=MY STACK CALL START ;GO PRINT ID DB 'MODEM PROGRAM as of ' DB '0MINAL WITH ECHO * * * * * * * * * * * * * * * * * * * * * * * * ; ;TERMINAL PROGRAM WITH ECHO - SEE NOTES ;UNDER "TERM" ABOVE ; ;C A U T I O N DON'T RUN WITH BOTH COMPUTERS ;IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR) ;WILL BE ECHOED BACK ANDOPTION "COMPUTER") ; CPI 'E' ;TERMINAL IN ECHO JZ TRMECHO ;..MODE? ; CPI 'T' ;TERMINAL.. JZ TERM ;..MODE? ; CPI 'D' JZ DISCONN ; CPI 'S' ;SEND.. JZ SENDFIL ;..A FILE? ; CPI 'R' ;RECEIVE.. JZ RCVFIL ;..A FILE? ; ;INVALID OP-E EXIT FROM T OR C DISCCHR EQU 'D'-40H ;CTL-D DISCONNECTS MODEM T/E ; FASTCLK EQU TRUE ;TRUE FOR 4 MHZ CLOCK ; ;SOME TIME-SHARE COMPUTERS REQUIRE TERMINALS TO ;HAVE BIT 7 HIGH (MARKING), SO IN THE TERMINAL ;MODE WE FORCE IT TO HIGH IF THE FOLLOWINISCCHR ;DISCONNECT REQUEST? JZ DISCONN ;YES, DO IT IF TIMESHR ORI 80H ;FORCE BIT 7 TO HIGH ENDIF ;TIMESHR OUT MODDATP ;SEND THE CHAR ; ;SEE IF CHAR FROM LINE ; IF NOT DCH TERML IN MODCTLP ;READ STATUS ENDIF ; IF DCH TERML IN MODCTL2 X(AMPLES)? JZ EXAM ;GIVE EXAMPLES ; ;SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT. ; CALL PROCOPT ; ;INIT THE MODEM OR SERIAL PORT ; CALL INITMOD ; ;MOVE THE FILENAME FROM FCB 2 TO FCB 1 ; CALL MOVEFCB ; IF DCH CALL DIALMOD ; CHECK F9/26/80',CR,LF,'$' ; START POP D ;GET ID MESSAGE MVI C,PRINT CALL BDOS ;PRINT ID MESSAGE ; ;INITIALIZE THE JMPS TO CP/M BIOS ; CALL INITADR ; LDA FCB+1 ;GET PRIMARY OPTION CPI 'H' ;MODEM H(ELP)? JZ HELP ;..YES, GIVE HELP CPI 'X' ;MODEMJZ TRMECHO ;..NO CHAR CALL KEYIN ;GET LOCAL CHAR CPI EXITCHR ;END? JZ CKDIS ;YES, CK DISCONN, EXIT CPI DISCCHR ;DISCONN? JZ DISCONN ;..YES, DO IT. OUT MODDATP ;SEND CHAR CALL TYPE ;ECHO IT LOCALLY JMP TRMECHO ;..AND LOOP ; ;GOT CHAR FROM ABORTING++$' ; ;TIMEDOUT ON RECEIVE ; RCVSTOT LDA VSEEFLG ;VIEWING.. ORA A ;..MODE? JZ RCVSPT ;YES, PRT MSG LDA QFLG ;QUIET.. ORA A ;..MODE? JZ RCVSERR ;YES, NO MSG ; RCVSPT CALL ILPRT DB '++TIMEOUT++ ',0 ; RCVPRN LDA ERRCT ;PRINT ERROR A ;GET 0 STA ERRCT ;INIT ERROR COUNT ; RCVRPT LDA QFLG ;QUIET? ORA A JZ RCVSQ ;YES, NO STAT MSG. CALL ILPRT ;PRINT: DB 'AWAITING #',0 LDA SECTNO ;GET SECTOR # INR A ;(REAL INR LATER) CALL HEXO ;PRINT IN HEX CALL CRLF ;..THEN CRLF ; RON ERRORS. ; SENDFIL CALL OPENFIL ;OPEN THE FILE MVI E,80 ;WAIT 80 SEC.. CALL WAITNAK ;..FOR INITIAL NAK ; SENDLP CALL RDSECT ;READ A SECTOR JC SENDEOF ;SEND EOF IF DONE CALL INCRSNO ;BUMP SECTOR # XRA A ;ZERO ERROR.. STA ERRCT ;..COUNT ER DONE MVI A,NAK ;SEND.. CALL SEND ;..THE NAK LDA ERRCT ;ABORT IF.. INR A ;..WE HAVE REACHED.. STA ERRCT ;..THE ERROR.. CPI ERRLIM ;..LIMIT? JC RCVRPT ;..NO, TRY AGAIN ; ;10 ERRORS IN A ROW - ; LDA VSEEFLG ;VIEWING.. ORA A ;..FILE? RSECT ;WRITE THE SECTOR CALL INCRSNO ;BUMP SECTOR # CALL SENDACK ;ACK THE SECTOR JMP RCVLP ;LOOP UNTIL EOF ; ;GOT EOT ON SECTOR - FLUSH BUFFERS, END ; RCVEOT CALL WRBLOCK ;WRITE THE LAST BLOCK CALL SENDACK ;ACK THE SECTOR CALL CLOSFIL ;CLOSE LINE ; LINECHR IN MODDATP ;GET CHAR OUT MODDATP ;ECHO IT ANI 7FH ;STRIP PARITY BIT CALL TYPE ;TYPE IT JMP TRMECHO ;LOOP ; * * * * * * * * * * * * * * * * * * * * * * * * SENDFIL: SENDS A CP/M FILE * * * * * * * * * * * * * * * * * *OF TRANSFER? STC ;RETURN WITH CARRY.. RZ ;..SET IF EOT ; ;DIDN'T GET SOH OR EOT - ; MOV B,A ;SAVE CHAR LDA VSEEFLG ;VIEWING.. ORA A ;..MODE? JZ RCVSEH ;YES, PRT.MSG LDA QFLG ;QUIET.. ORA A ;..MODE? JZ RCVSERR ;YES, SKIP MSG RCVSEHCVSQ MVI B,10 ;10 SEC TIMEOUT CALL RECV ;GET SOH/EOT JC RCVSTOT ;TIMEOUT CPI SOH ;GET SOH? JZ RCVSOH ;..YES ; ;EARLIER VERS. OF MODEM PROG SENT SOME NULLS - ;IGNORE THEM ; ORA A ;00 FROM SPEED CHECK? JZ RCVSQ ;YES, IGNORE IT CPI EOT ;END ; SENDRPT CALL SENDHDR ;SEND A HEADER CALL SENDSEC ;SEND DATA SECTOR CALL SENDCKS ;SEND CKSUM CALL GETACK ;GET THE ACK JC SENDRPT ;REPEAT IF NO ACK JMP SENDLP ;LOOP UNTIL EOF ; ;FILE SENT, SEND EOT'S ; SENDEOF MVI A,EOT ;SEND.. CALL SEND ; JZ RCVCKQ ;YES, ASK RETRY/QUIT LDA QFLG ;QUIET.. ORA A ;..MODE? JZ RCVSABT ;ABORT ; RCVCKQ CALL CKQUIT ;RETRY/QUIT? JZ RCVSECT ;TRY AGAIN ; RCVSABT CALL CLOSFIL ;KEEP WHATEVER WE GOT CALL ERXIT DB '++UNABLE TO RECEIVE BLOCK' DB CR,LF,'++THE FILE JMP DONE ;ALL DONE ; * * * * * * * * * * * * * * * * * * * * * * * * SUBROUTINES * * * * * * * * * * * * * * * * * * * * * * * * ; ; ;----> RCVSECT: RECEIVE A SECTOR ; ;RETURNS WITH CARRY SET IF EOT RECEIVED. ; RCVSECT XRA * * * * * * ; ;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND ;IS TRANSFERRED OVER THE PHONE TO ANOTHER ;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE) ;OPTION. THE DATA IS SENT ONE SECTOR AT A ;TIME WITH HEADERS AND CHECKSUMS, AND RE- ;TRANSMISSION MOV A,B ;GET CHAR CALL HEXO ;SHOW IN HEX CALL ILPRT ;PRINT: DB 'H RCD, NOT SOH',CR,LF,0 ; ;DIDN'T GET VALID HEADER - PURGE THE LINE, ;THEN SEND NAK. ; RCVSERR MVI B,1 ;WAIT FOR 1 SEC.. CALL RECV ;..WITH NO CHARS JNC RCVSERR ;LOOP UNTIL SENDAT AS SENT ;BY ANOTHER PERSON DOING "MODEM S FN.FT". ; RCVFIL CALL ERASFIL ;ERASE THE FILE CALL MAKEFIL ;..THEN MAKE NEW CALL ILPRT ;PRINT: DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0 ; RCVLP CALL RCVSECT ;GET A SECTOR JC RCVEOT ;GOT EOT CALL W..AN EOT CALL GETACK ;GET THE ACK JC SENDEOF ;LOOP IF NO ACK JMP DONE ;ALL DONE ; * * * * * * * * * * * * * * * * * * * * * * * * RCVFIL: RECEIVE A FILE * * * * * * * * * * * * * * * * * * * * * * * * ; ;RECEIVES A FILE IN BLOCK FORM.. CALL HEXO ;..COUNT CALL CRLF JMP RCVSERR ;BUMP ERR CT, ETC. ; ;GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED ; RCVSOH MVI B,1 ;TIMEOUT = 1 SEC CALL RECV ;GET SECTOR JC RCVSTOT ;GOT TIMEOUT MOV D,A ;D=BLK # MVI B,1 ;TIMEOUT = 1 SEC CALLA ERRCT ;GET COUNT INR A ;BUMP IT STA ERRCT ;SAVE BACK CPI ERRLIM ;AT LIMIT? RC ;NOT AT LIMIT ; ;REACHED ERROR LIMIT ; LDA VSEEFLG ;VIEWING.. ORA A ;..FILE? JZ GACKV ;YES, ASK QUIT/RETRY LDA QFLG ;QUIET.. ORA A ;..MODE? JZ CSABORT ; CALL SEND ;..SECTOR # LDA SECTNO ;THEN SECTOR # CMA ;..COMPLEMENTED.. CALL SEND ;..SECTOR # RET ;FROM SENDHDR ; ;----> SENDSEC: SEND THE DATA SECTOR ; ;WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET ;SUCH THAT IF "V" (VIEW THE FILE) WAS REASE+80H ;POINT TO BUFFER RCVCHR MVI B,1 ;1 SEC TIMEOUT CALL RECV ;GET CHAR JC RCVSTOT ;TIMEOUT MOV M,A ;STORE CHAR INR L ;DONE? JNZ RCVCHR ;NO, LOOP ; ;VERIFY CHECKSUM ; MOV D,C ;SAVE CHECKSUM XRA A ;SHOW.. STA DATAFLG ;..END OF DATA COUNT IS AT "ERRLIM", THE PROGRAM ;ABORTS IF IN "QUIET" MODE, OR ASKS THE ;USER FOR QUIT/RETRY IF NOT. ; GETACK MVI B,10 ;WAIT 10 SECONDS MAX CALL RECVDG ;RECV W/GARBAGE COLLECT JC GETATOT ;TIMED OUT CPI ACK ;OK? (CARRY OFF IF =) RZ ;YES, RETLL SENDACK ;SEND THE ACK, JMP RCVSECT ;GET NEXT BLOCK ; ;SEND AN ACK FOR THE SECTOR ; SENDACK MVI A,ACK ;GET ACK CALL SEND ;..AND SEND IT RET ; ;----> SENDHDR: SEND THE SECTOR HEADER ; ;SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #) ; SENDHDR RECV ;GET CMA'D SECT # JC RCVSTOT ;TIMEOUT CMA ;CALC COMPLEMENT CMP D ;GOOD SECTOR #? JZ RCVDATA ;YES, GET DATA ; ;GOT BAD SECTOR # ; LDA VSEEFLG ;VIEWING.. ORA A ;..MODE? JZ RCVBSE ;..YES, PRT MSG LDA QFLG ;QUIET.. ORA A ;..MODE? AR CALL SEND ;SEND IT INR L ;POINT TO NEXT CHAR JNZ SENDC ;LOOP IF <100H XRA A ;SHOW NOT INTO DATA.. STA DATAFLG ;..FOR VIEW COMMAND RET ;FROM SENDSEC ; ;----> SENDCKS: SEND THE CHECKSUM ; SENDCKS MOV A,C ;SEND THE.. CALL SEND ;..CHECKSUQUESTED, ;THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT ;THE HDR OR CKSUM, OR ANY NON-FATAL MSGS. ; SENDSEC MVI A,1 ;SHOW NOW AT DATA.. STA DATAFLG ;..FOR VIEW COMMAND MVI C,0 ;INIT CKSUM LXI H,BASE+80H ;POINT TO BUFFER SENDC MOV A,M ;GET A CHMVI B,1 ;TIMEOUT LEN. CALL RECV ;GET CHECKSUM JC RCVSTOT ;TIMEOUT CMP D ;CHECKSUM OK? JNZ RCVCERR ;NO, ERROR ; ;GOT A SECTOR, IT'S A DUP IF = PREV, ; OR OK IF = 1 + PREV SECTOR ; LDA RCVSNO ;GET RECEIVED MOV B,A ;SAVE IT LDA SECTNO ;GET P FROM GETACK MOV B,A ;SAVE CHAR LDA QFLG ;QUIET.. ORA A ;..MODE? JZ ACKERR ;..YES, NO MSG MOV A,B ;GET CHAR CALL HEXO ;PRINT IN HEX CALL ILPRT ;PRINT: DB 'H RCD, NOT ACK',CR,LF,0 ; ;TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT ; ACKERR LD LDA QFLG ;QUIET.. ORA A ;..MODE? JZ SENDHNM ;YES, SKIP STATUS MSG. CALL ILPRT ;PRINT: DB 'SEND # ',0 LDA SECTNO ;PRINT.. CALL HEXO ;..SECT # CALL CRLF ;..THEN CR/LF ; SENDHNM MVI A,SOH ;SEND.. CALL SEND ;..SOH, LDA SECTNO ;THEN SEND.. JZ RCVSERR ;..YES, NO MSG ; RCVBSE CALL ILPRT ;PRINT: DB '++BAD SECTOR # IN HDR',CR,LF,0 JMP RCVSERR ;BUMP ERROR CT. ; RCVDATA MOV A,D ;GET SECTOR # STA RCVSNO ;SAVE IT MVI A,1 ;SHOW.. STA DATAFLG ;GETTING DATA MVI C,0 ;INIT CKSUM LXI H,BM RET ;FROM SENDCKS ; ;----> GETACK: GET THE ACK ON THE SECTOR ; ;RETURNS WITH CARRY CLEAR IF ACK RECEIVED. ;IF AN ACK IS NOT RECEIVED, THE ERROR COUNT ;IS INCREMENTED, AND IF LESS THAN "ERRLIM", ;CARRY IS SET AND CONTROL RETURNS. IF THE ;ERRORYES, PRT MSG LDA QFLG ;QUIET.. ORA A ;..MODE? JZ RCVSERR ;YES, NO MSG ; RCVCPR CALL ILPRT DB '++CKSUM++ ',0 JMP RCVPRN ;PRINT ERROR # ; ;PREV SECT REPEATED, DUE TO THE LAST ACK ;BEING GARBAGED. ACK IT SO SENDER WILL CATCH UP ; RECVACK CAREV CMP B ;PREV REPEATED? JZ RECVACK ;ACK TO CATCH UP INR A ;CALC NEXT SECTOR # CMP B ;MATCH? JNZ ABORT ;NO MATCH - STOP SENDER, EXIT RET ;CARRY OFF - NO ERRORS ; ;GOT CKSUM ; RCVCERR LDA VSEEFLG ;VIEWING.. ORA A ;..MODE? JZ RCVCPR ;....YES, NO MSG ; GACKV CALL CKQUIT ;SEE IF WANT TO QUIT STC ;TO SHOW NO ACK RZ ;KEEP ON TRYIN' ; CSABORT CALL ERXIT DB 'CAN''T SEND SECTOR ' DB '- ABORTING',CR,LF,'$' ; ;TIMEOUT GETTING ACK ; GETATOT LDA QFLG ;QUIET.. ORA A ;..MODE? JZ XCHG ;SAVE NEXT.. SHLD SECPTR ;..BLOCK POINTER LDA SECINBF ;BUMP THE.. INR A ;..SECTOR #.. STA SECINBF ;..IN THE BUFF CPI 16 ;HAVE WE 16? RNZ ;NO, RETURN ; ;----> WRBLOCK: WRITES A BLOCK TO DISK ; WRBLOCK LDA SECINBF ;# SECT IN BUFFER ECTORS AT A TIME. ; RDSECT LDA SECINBF ;GET # SECT IN BUFF. DCR A ;DECREMENT.. STA SECINBF ;..IT JM RDBLOCK ;EXHAUSTED? NEED MORE. LHLD SECPTR ;GET POINTER LXI D,BASE+80H ;TO DATA CALL MOVE128 ;MOVE TO BUFFER SHLD SECPTR ;SAVE BUFFER POINT FILE. ; ;IF IT EXISTS, ASK IF IT MAY BE ERASED. ; ERASFIL LXI D,FCB ;POINT TO CTL BLOCK MVI C,SRCHF ;SEE IF IT.. CALL BDOS ;..EXISTS INR A ;FOUND? RZ ;..NO, RETURN CALL ILPRT ;PRINT: DB '++FILE EXISTS, TYPE Y TO ERASE: ',0 CALL KEYIN ;GR GOT EOF ; RDBFULL STA SECINBF ;STORE SECTOR COUNT LXI H,DBUF ;INIT BUFFER.. SHLD SECPTR ;..POINTER LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. CALL BDOS ;..ADDR JMP RDSECT ;PASS SECT TO CALLER ; ;----> WRSECT: WRITE A SECTOR ; ;WRITES RXIT ;..NO, ABORT DB 'CAN''T OPEN FILE$' ; OPENOK CALL ILPRT ;PRINT: DB 'FILE OPEN, EXTENT LENGTH: ',0 LDA FCB+15 ;GET # SECTORS CALL HEXO ;PRINT IN HEX CALL ILPRT ;PRINT: DB 'H',CR,LF,0 RET ; ;----> CLOSFIL: CLOSES THE RECEIVED FILE ; ACKERR ;YES, NO MSG CALL ILPRT ;PRINT: DB 'TIMEOUT ON ACK',CR,LF,0 JMP ACKERR ; ABORT LXI SP,STACK ; ABORTL MVI B,1 ;1 SEC. W/O CHARS. CALL RECV JNC ABORTL ;LOOP UNTIL SENDER DONE MVI A,NAK ;NEGATIVE ACK CALL SEND ;TELL SENDING END CAVI C,STDMA ;SET DMA.. CALL BDOS ;..ADDR LXI D,FCB MVI C,READ CALL BDOS POP D POP B ORA A ;READ OK? JZ RDSECOK ;YES DCR A ;EOF? JZ REOF ;GOT EOF ; ;READ ERROR ; CALL ERXIT DB '++FILE READ ERROR$' ; RDSECOK LXI H,80H ;ADD LENGTH ER RET ;FROM "READSEC" ; ;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 16 ; RDBLOCK LDA EOFLG ;GET EOF FLAG CPI 1 ;IS IT SET/ STC ;TO SHOW EOF RZ ;GOT EOF MVI C,0 ;SECTORS IN BLOCK LXI D,DBUF ;TO DISK BUFFER ; RDSECLP PUSH B PUSH D MET CHAR PUSH PSW CALL TYPE ;ECHO CALL CRLF ;BACK TO START OF LINE POP PSW ANI 5FH ;MAKE UPPER CASE CPI 'Y' ;WANT ERASED? JNZ CKDIS ;QUIT IF NOT ERASE ; ;ERASE OLD FILE ; LXI D,FCB ;POINT TO FCB MVI C,ERASE ;GET BDOS FNC CALL BDOS ;DOTHE SECTOR INTO A BUFFER. WHEN 16 ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK. ; ;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF. ; WRSECT LHLD SECPTR ;GET BUFF ADDR XCHG ;TO DE FOR MOVE LXI H,BASE+80H ;FROM HERE CALL MOVE128 ;MOVE TO BUFFERCLOSFIL LXI D,FCB ;POINT TO FILE MVI C,CLOSE ;GET FUNCTION CALL BDOS ;CLOSE IT INR A ;CLOSE OK? RNZ ;..YES, RETURN CALL ERXIT ;..NO, ABORT DB 'CAN''T CLOSE FILE$' ; ;----> RDSECT: READS A SECTOR ; ;FOR SPEED, THIS ROUTINE BUFFERS UP 16 ;SLL ILPRT ;EXIT WITH ABORT MSG DB 'MODEM PROGRAM CANCELLED',CR,LF,0 JMP CKDIS ;CHECK FOR DISCONN. ; ;----> INCRSNO: INCREMENT SECTOR # ; INCRSNO LDA SECTNO ;INCR.. INR A ;..SECT.. STA SECTNO ;..NUMBER RET ; ;----> ERASFIL: ERASE THE INCOMINGOF ONE SECTOR... DAD D ;...TO NEXT BUFF XCHG ;BUFF TO DE INR C ;MORE SECTORS? MOV A,C ;GET COUNT CPI 16 ;DONE? JZ RDBFULL ;..YES, BUFF IS FULL JMP RDSECLP ;READ MORE ; REOF MVI A,1 STA EOFLG ;SET EOF FLAG MOV A,C ; ;BUFFER IS FULL, OB '++ERROR - CAN''T MAKE FILE',CR,LF DB '++DIRECTORY MUST BE FULL',CR,LF,'$' ; ;----> OPENFIL: OPENS THE FILE TO BE SENT ; OPENFIL LXI D,FCB ;POINT TO FILE MVI C,OPEN ;GET FUNCTION CALL BDOS ;OPEN IT INR A ;OPEN OK? JNZ OPENOK ;..YES CALL E THE ERASE RET ;FROM "ERASFIL" ; ;----> MAKEFIL: MAKES THE FILE TO BE RECEIVED ; MAKEFIL LXI D,FCB ;POINT TO FCB MVI C,MAKE ;GET BDOS FNC CALL BDOS ;TO THE MAKE INR A ;FF=BAD? RNZ ;OPEN OK ;DIRECTORY FULL - CAN'T MAKE FILE CALL ERXIT D ORA A ;0 MEANS END OF FILE RZ ;NONE TO WRITE MOV C,A ;SAVE COUNT LXI D,DBUF ;POINT TO DISK BUFF ; DKWRLP PUSH H PUSH D PUSH B MVI C,STDMA ;SET DMA CALL BDOS ;TO BUFFER LXI D,FCB ;THEN WRITE MVI C,WRITE ;..THE.. CALL BDOS ;..BLOCK ARIOUS ;JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS ;IS BYPASSED WHILE ACCESSING THE CONSOLE. THIS ;IS DONE TO ALLOW CHARACTERS SUCH AS CONTROL-C ;AND CONTROL-S TO BE KEYED WHILE IN TERMINAL ;MODE, WITHOUT CP/M INTERPRETING THEM. ; INITADR LHLD BAONIN POP PSW ;RESTORE CHAR ORA A ;CARRY OFF: NO ERROR RET ;FROM "RECV" ; ;----> SEND: SEND A CHARACTER TO THE MODEM ; SEND PUSH PSW ;SAVE THE CHAR ; ;CHECK IF MONITORING SENT DATA ; LDA SSEEFLG ;CHECK IF MONITORING.. ORA A ;..SENT DATA JZIVE A CHARACTER ; ;TIMEOUT TIME IS IN B, IN SECONDS. ENTRY VIA ;"RECVDG" DELETES GARBAGE CHARACTERS ON THE ;LINE. FOR EXAMPLE, HAVING JUST SENT A SECTOR, ;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED ;CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD RECEIVER. ;(E) CONTAINS THE # OF SECONDS TO WAIT. ; WAITNAK LDA VSEEFLG ;VIEWING? ORA A JZ WAITNPR ;PRINT MSG LDA QFLG ;QUIET.. ORA A ;..MODE? JZ WAITNLP ;YES, SKIP MSG ; WAITNPR CALL ILPRT ;PRINT: DB 'AWAITING INITIAL NAK',CR,LF,0 ; WASUM ; PUSH PSW ;SAVE THE CHAR ADD C ;ADD TO CHECKSUM MOV C,A ;SAVE CHECKSUM ; ;CHECK IF MONITORING REC'D DATA ; LDA RSEEFLG ;SEE RECEIVED.. ORA A ;..DATA? JZ MONIN ;..YES ; ;CHECK IF "VIEWING" AND THIS IS A DATA CHAR ; LDA VSEEFLG ;VIE POP B POP D POP H ORA A JNZ WRERR ;OOPS, ERROR LXI H,80H ;LENGTH OF 1 SECT DAD D ;HL= NEXT BUFF XCHG ;TO DE FOR SETDMA DCR C ;MORE SECTORS? JNZ DKWRLP ;..YES, LOOP XRA A ;GET A ZERO STA SECINBF ;RESET # OF SECTORS LXI H,DBUF ;RESEONOT POP PSW ;RESTORE CHAR PUSH PSW ;SAVE IT ADD C ;CALC CKSUM MOV C,A ;SAVE CKSUM ; IF NOT DCH SENDW IN MODCTLP ;GET STATUS ENDIF ; IF DCH SENDW IN MODCTL2 ;GET STATUS ENDIF ; ANI MODSNDB ;ISOLATE READY BIT CPI MODSNDR ;READY? JNZ MONOUT ;..YES ; ;CHECK IF "VIEWING" THE FILE ; LDA VSEEFLG ;GET VIEW FLAG ORA A ;TEST IT JNZ NOMONOT ;NO LDA DATAFLG ;IS THIS ORA A ;..DATA? JZ NOMONOT ;..NO. ; MONOUT POP PSW ;GET THE CHAR PUSH PSW ;SAVE IT CALL SHOW ;SHOW IT ; NOM ;BE RECEIVED. ; RECVDG EQU $ ;RECEIVE W/GARBAGE DELETE IN MODDATP ;GET A CHAR IN MODDATP ;..TOTALLY PURGE UART ; RECV PUSH D ;SAVE ; IF FASTCLK ;4MHZ? MOV A,B ;GET TIME REQUEST ADD A ;DOUBLE IT MOV B,A ;NEW TIME IN B ENDIF ; MSEC LXIITNLP MVI B,1 ;TIMEOUT DELAY CALL RECV ;DID WE GET.. CPI NAK ;..A NAK? RZ ;YES, SEND BLOCK DCR E ;80 TRIES? JZ ABORT ;YES, ABORT JMP WAITNLP ;NO, LOOP ; ;----> INITADR: INIT'S CP/M BDOS ADDRESSES ; ;THIS ROUTINE FILLS IN THE ADDRESSES OF VWING.. ORA A ;..DATA? JNZ NOMONIN ;..NO ; ;"VIEW" REQUESTED. SHOW THE CHAR IT IS DATA ; LDA DATAFLG ;GET DATA FLAG ORA A ;TEST IT JZ NOMONIN ;..OFF, NOT DATA ; MONIN POP PSW ;..IS DATA, PUSH PSW ;GET IT, CALL SHOW ;..AND SHOW IT ; NOMT BUFFER.. SHLD SECPTR ;..POINTER ; RSDMA LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. CALL BDOS ;..ADDR RET ; WRERR CALL RSDMA ;RESET DMA TO NORM. CALL ILPRT ;PRINT: DB '++ERROR WRITING FILE',CR,LF,0 JMP ABORT ;EXIT ; ;----> RECV: RECE SENDW ;..NO, WAIT POP PSW ;GET CHAR OUT MODDATP ;OUTPUT IT RET ;FROM "SEND" ; ;----> WAITNAK: WAITS FOR INITIAL NAK ; ;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING ;PROGRAM IS READY, THIS ROUTINE WAITS FOR THE ;THE FIRST TIMEOUT-NAK FROM THER.. JNZ MWTI ;..TIMEOUT DCR B ;MORE SECONDS? JNZ MSEC ;YES, WAIT ; ;MODEM TIMED OUT RECEIVING ; POP D ;RESTORE D,E STC ;CARRY SHOWS TIMEOUT RET ; ;GOT CHAR FROM MODEM ; MCHAR IN MODDATP ;READ THE CHAR POP D ;RESTORE DE ; ;CALC CHECK D,50000 ;1 SEC DCR COUNT ; IF NOT DCH MWTI IN MODCTLP ;CHECK STATUS ENDIF ; IF DCH MWTI IN MODCTL2 ;CHECK STATUS ENDIF ; ANI MODRCVB ;ISOLATE BIT CPI MODRCVR ;READY? JZ MCHAR ;GOT CHAR DCR E ;COUNT.. JNZ MWTI ;..DOWN.. DCR D ;..FOSE+1 ;GET WARM BOOT ADDR LXI D,3 ;LENGTH OF A 'JMP' DAD D ;TO CONSOLE STAT SHLD VSTAT+1 ;MODIFY CALL DAD D ;TO CONSOLE IN SHLD VKEYIN+1 ;MODIFY CALL DAD D ;TO CONSOLE OUT SHLD VTYPE+1 ;MODIFY CALL RET ; ;----> PROCOPT: PROCESS COMMAND OPTPI 52 ;>300? MVI A,5FH ;VALUE FOR >300 JC GT300 MVI A,7FH ;VALUE FOR <= 300 ; GT300 OUT MODCTL2 ;SET IT ; ;SET ORIG/ANSW IF REQUESTED ; LDA ORIGFLG ;ORIGINATE.. ORA A ;..MODE? MVI A,ORIGMOD JZ OFFHOOK ;..YES, DO IT LDA ANSWFLG ;ANSWERPOP PSW CPI CR JNZ CKDIS ;ASK AGAIN ; ;----> DISCONN: DISCONNECT THE PHONE ; DISCONN EQU $ ; IF PMMI XRA A ;GET DISCONN VALUE OUT MODCTLP ;RESET ORIG/ANSW OUT MODCTL2 ;TURN OFF DTR, DO BREAK ENDIF ; IF DCH XRA A ;GET DISCONNECT VALUTHERE WON'T BE A ' ' AFTER THE OPTION ;IF A BAUD RATE WAS SPECIFIED. ; CPI ' ' ;NO MORE OPT'NS? JZ ENDOPT ;..YES ;SET THE APPROP. OPT: STORE 0 IN IT LXI H,OPTBL ;HL = ADDR OF 'OAQDSRV' MVI B,OPTBE-OPTBL ;OPT TABLE LEN ; OPTCK CMP M ;FOUND THE MODCTLP ;OUTPUT IT NOP ! NOP! NOP ;DELAY FOR USART NOP ! NOP MVI A,INITC3 ;GET 3RD INIT CHAR OUT MODCTLP ;OUTPUT IT NOP ! NOP! NOP ;DELAY FOR USART NOP ! NOP MVI A,INITC4 ;GET 4TH INIT CHAR OUT MODCTLP ;OUTPUT IT NOP ! NOP! NOP ;DE..YES ; ;FALL INTO 'CKDIS' ; ;----> CKDIS: CHECK IF DISCONNECT REQUESTED ; ;THIS ROUTINE IS JUMPED TO AT THE END OF ;PROCESSING, AND DISCONNECTS THE PHONE IF ;'D' WAS SPECIFIED AS A SUB-OPTION. ; CKDIS LDA DISCFLG ;CHECK 'D' FLAG ORA A ;REQUESTIONS ; ;1) SAVES THE PRIMARY OPTION IN 'OPTION'; ;2) SCANS THE SUB-OPTION CHARACTERS, AND FOR ;EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN ;THE OPTION TABLE. FOR EXAMPLE, IF 'D' IS ;CODED (DISCONNECT) THEN THE 'D' STORED AT ;'DISCFLG' IS SET TO 0 LPRT DB CR,LF,'++DON''T FORGET - THE MODEM IS ' DB 'NOT DISCONNECTED++',CR,LF DB 'USE "MODEM D" TO DISCONNECT',CR,LF,0 JMP EXIT ; ENDIF ; ;----> INITMOD: INITIALIZES THE MODEM ; ;THIS ROUTINE IS USED TO INITIALIZE SERIAL ;BOARDS, OR SETUP SE OUT MODCTLP ;DISCONNECT ENDIF ; CALL ILPRT ;PRINT: DB '++DISCONNECTED++',0 JMP EXIT ; ;NO DISCONNECT, TYPE MSG AS REMINDER THAT PHONE'S ;OFF HOOK ; IF PMMI OR DCH NDIS LDA QFLG ;QUIET.. ORA A ;..MODE? JZ EXIT ;..YES, NO MSG CALL IOPTION? JNZ OPTNO ;NO, DON'T SET IT MVI M,0 ;SET THE OPTION JMP OPTLP ;GET NEXT OPTION ; OPTNO INX H ;TO NEXT DCR B ;MORE? JNZ OPTCK ;OPTION NOT IN TABLE JMP BADOPT ;SHOW BAD SUB OPTION ; ;IF "VIEW" WAS ASKED FOR, SET QUIET FLAG ; ENDOPTLAY FOR USART NOP ! NOP ENDIF ; IF PMMI CALL GETBAUD ;GET THE BAUD RATE OUT BAUDRP ;OUT BAUD RATE PORT ENDIF ;PMMI ; IF DCH CALL GETBAUD ;GET BAUD RATE ENDIF ;DCH ; IF PMMI ;SET THE MOTOROLA MODEM CHIP BIT FOR >300 IF REQ'D ; CED? ; IF PMMI OR DCH JNZ NDIS ;..NO, JUST EXIT ENDIF ; IF NOT PMMI AND NOT DCH JNZ EXIT ENDIF ; ;AWAIT C/R TO DISC. SO WE DON'T LOSE THE PHONE ; CALL ILPRT DB CR,LF,'PRESS RETURN TO DISCONNECT:',0 CALL KEYIN PUSH PSW CALL CRLF SO IT CAN BE TESTED ;LATER. ; PROCOPT LXI D,FCB+1 ;TO PRIMARY OPT. LDAX D ;GET PRIMARY STA OPTION ;SAVE IT ; OPTLP INX D ;TO SECONDARY OPTION LDAX D ;GET CHAR ; ;IF YOU MOD THIS PROGRAM FOR >7 OPTIONS, ;YOU MUST CHANGE THE FOLLOWING, SINCE ;-100 MODEM BOARDS. ;JUST RETURNS IF NO INITIALIZATION REQUIRED. ; INITMOD: ; IF INITREQ ;REQUIRE INIT? MVI A,INITC1 ;GET 1ST INIT CHAR OUT MODCTLP ;OUTPUT IT NOP ! NOP! NOP ;DELAY FOR USART NOP ! NOP MVI A,INITC2 ;GET 2ND INIT CHAR OUT JZ DONECTE ;YES, CK TERM/ECHO ; DONETC CALL ILPRT DB CR,LF,'TRANSFER COMPLETE' DB CR,LF,0 ; ;CHECK IF TERMINAL OR ECHO SUB COMMAND ;WAS SPECIFIED ; DONECTE LDA TERMFLG ;TERM? ORA A JZ TERM ;..YES LDA ECHOFLG ;ECHO? ORA A JZ TRMECHO ; LDA VSEEFLG ;VIEW.. ORA A ;..ASKED FOR? RNZ ;..NO, RET FROM 'PROCOPT' STA QFLG ;YES, NO HDR/CKSUM PRT RET ;FROM 'PROCOPT' ; ;DONE - CLOSE UP SHOP ; DONE LDA VSEEFLG ;VIEWING? ORA A JZ DONETC ;SHOW MSG LDA QFLG ;QUIET ORA A ;..MODE? .. ORA A ;..MODE? MVI A,ANSWMOD RNZ ;NEITHER ORIG NOR ANSW. ENDIF ;PMMI ; IF DCH LDA ANSWFLG ;ANSWER.. ORA A MVI B,ANSWMOD ;SET ANSWER MODE JZ INITM1 LDA ORIGFLG ;GET ORIGINATE FLAG ORA A MVI B,ORIGMOD ;SET ORIGINATE MODE JZ VED ; ;CR, LF, AND TAB ARE SHOWN. ALL OTHER ;NON-PRINTABLE CHARACTERS ARE SHOWN IN ;HEX AS (XX) ; SHOW CPI LF ;LF? JZ CTYPE ;..YES, TYPE IT CPI CR ;CR? JZ CTYPE ;..YES, TYPE IT CPI 09 ;TAB JZ CTYPE ;..YES, TYPE IT CPI ' ' ;CTL-CHR? JC JNZ BADRATE ;INVALID ; GETBAU2 MOV A,B ;GET SET UP OUT MODCTL2 ;INITIALIZE MODEM FOR STOP BITS.. RET ;..DATA BITS, ETC. ENDIF ;DCH ; IF PMMI OR DCH ; ROUTINE TO CONVERT BAUD RATE TO BINARY ; CVBIN: LXI D,FCB+9 ;TO ASCII VALUE LXI H,0 ;IENDIF ;PMMI OR DCH ; IF PMMI ;----> GETBAUD: GETS BAUD RATE FROM COMMAND ; ;THIS ROUTINE CHECKS IF A BAUD RATE HAS ;BEEN ASKED FOR, (SUCH AS MODEM T.450), ;AND IF SO, CALCULATES THE PMMI BAUD RATE ;VALUE TO BE OUTPUT. DEFAULTS TO 300. ; GETBAUTHIS MUST BE HERE** ENDIF ;NOT PMMI AND NOT DCH ; ;----> MOVEFCB: MOVES FCB(2) TO FCB ; ;I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL', ;I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER ;THAT MODEM FILENAME SEND (MODEM FN.FT S) SO THIS ;ROUTINE ; IF DCH GETBAUD LDA FCB+9 ;GET FILETYPE CPI ' ' ;DEFAULT? JNZ GETBAU1 ;NO - DO BAUD RATE STUFF MVI C,1 ;SET 300 BAUD MVI B,17H ;SET 1 STOP BIT JMP GETBAU2 ; ; CONVERT BAUD RATE TO BINARY GETBAU1 CALL CVBIN ;CONVERT TO BINARY PUSH H ;SAINITM1 LDA HOLDD ;NEITHER - GET LAST VALUE MOV B,A ;STORE IN B ; INITM1: MOV A,B ;GET MODE STA HOLDD ;SAVE VALUE MOV A,C ;GET BAUD RATE INDICATOR ORA A ;ZEBO IF 110 BAUD MOV A,B ;GET MODE JZ OFFHOOK ;DO OFFHOOK ORI 1 ;SET 300 BAUV VALUE BY 10 ; MOV B,H ;SET UP FOR MOV C,L ;MULTIPLY BY 10 DAD H ;MULTIPLY BY 2 DAD H ;X 2 = 4 DAD B ;+ 1 = 5 DAD H ;X 2 = 10 ADD L ;ADD IN DIGIT MOV L,A ;SAVE BACK JNZ DIGNC ;NO CARRY? INR H ;ADD IN CARRY ;CHECK IF DONE? DIGNC MOV NIT BINARY RESULT ; DECLP LDAX D ;GET ASCII DIGIT INX D ;TO NEXT DIGIT CPI ' ' ;BLANK ONE? JZ DECLP ;..YES, SKIP IT CPI '0' ;VALIDATE IT JC BADRATE ;ERROR CPI '9'+1 ;VALIDATE JNC BADRATE ;ERROR SUI '0' ;MAKE DIGIT BINARY ; ;MULTIPLY PRED LDA FCB+9 ;GET 'FILETYPE' CPI ' ' ;DEFAULT? MVI A,52 ;300 BAUD VALUE RZ ;NO BAUD RATE, USE 300 ; ;GOT BAUD RATE - CONVERT TO PROPER TIMER VALUE ; ;FIRST, CONVERT THE NUMBER TO BINARY ; CALL CVBIN ; ;CALCULATE THE VALUE TO OUTPUT: ; ; RAMOVES THE FILENAME FROM THE SECOND FCB ;TO THE FIRST ; MOVEFCB LXI H,FCB+16 ;FROM LXI D,FCB ;TO MVI B,16 ;LEN CALL MOVE ;DO THE MOVE XRA A ;GET 0 STA FCBSNO ;ZERO SECTOR # STA FCBEXT ;..AND EXTENT RET ; ;----> SHOW: SHOWS CHAR SENT/RECEIVE BAUD RATE MVI C,0 ;ANTICIPATE 110 BAUD MVI B,1FH ;SET 2 STOP BITS LXI D,-110 ;GET CONSTANT DAD D ;SUBTRACT MOV A,H ORA L POP H JZ GETBAU2 ;110 BAUD MVI B,17H ;SET 1 STOP BIT INR C LXI D,-300 ;GET CONSTANT DAD D MOV A,H ORA L D ENDIF ;DCH ; IF PMMI OR DCH ; ;GO OFFHOOK IN REQUESTED (ORIG/ANSW) MODE ; OFFHOOK LXI H,4000 ;DELAY AMT ; OFFDLY DCR L JNZ OFFDLY DCR H JNZ OFFDLY OUT MODCTLP ;GO OFF HOOK STA CURRMOD ;SAVE CURRENT MODE (NEEDED BY DIALMOD) RET A,E ;SEE IF PAST CPI FCB+12 ;..LAST DIGIT JNZ DECLP ;NO, LOOP RET ; ;INVALID BAUD RATE ; BADRATE CALL ERXIT DB '++INVALID BAUD RATE++$' ENDIF ;PMMI OR DCH ; ;THE FOLLOWING PROVIDES A RETURN FROM INITMOD IF NOT PMMI AND NOT DCH RET ;**625 ;250000/16 LXI B,-1 ;INIT QUOTIENT ; DIVLP INX B ;BUMP QUOTIENT DAD D ;'SUBTRACT' JC DIVLP ;LOOP 'TILL DONE ;VALIDATE THE RESULT MOV A,B ;CAN'T HAVE >255 ORA A MOV A,C ;GET ACTUAL RZ ;RET IF <256 JMP BADRATE ;INVALID ENDIF ;PMMITE = 250000/16/BAUD RATE ; ; DIVIDE BY REPETITIVE SUBTRACTION ; ------ ;COMPLEMENT THE BAUD RATE ; MOV A,H ;GET HI CMA ;COMPLEMENT MOV D,A ;SAVE MOV A,L ;GET LO CMA ;COMPLEMENT MOV E,A ;SAVE INX D ;DE=2'S COMPLEMENT ;DIVIDE LXI H,15SHOWHEX ;YES, SHOW IN HEX CPI 7FH ;DEL? JC CTYPE ;NO, TYPE THE CHAR ; SHOWHEX PUSH PSW ;SAVE THE CHAR MVI A,'(' ;TYPE.. CALL CTYPE ;..'(' POP PSW ;THEN.. CALL HEXO ;..THE CHAR MVI A,')' ;THEN.. JMP CTYPE ;..')' AND RETURN. ; ;----> CTYPULD CROSS ;OVER TO OTHER MODEM BOARDS IF SOMEBODY WILL GIVE IT A TRY. ; ;THE PHONE NUMBER IS THE LAST PARAMETER IN THE COMMAND LINE. ;FOR EXAMPLE: MODEM T 123-456-7890 ; MODEM E 123-456-7890 ; MODEM S ABCDEFGH.IJK 123-456-8790 ; MODEM R ABCDEFGH. ;BINARY 0 AS THE END. BINARY 1 MAY BE USED TO ;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE') ; ILPRT XTHL ;SAVE HL, GET HL=MSG ; ILPLP MOV A,M ;GET CHAR ORA A ;END OF MSG? JZ ILPRET ;..YES, RETURN CPI 1 ;PAUSE? JZ ILPAUSE ;..YES CALL CTYPE ;RS PUSH D PUSH H MOV C,A ;FOR BIOS VTYPE CALL $-$ ;MODIFIED AT INIT POP H ;RESTORE REGISTERS POP D POP B POP PSW ;..AND CHAR RET ;FROM "TYPE" ; ;----> STAT: KEYBOARD STATUS ; ;SAVE ALL REGISTERS, EXCEPT A, IN CASE ;CBIOS CLOBBERS THE 128 CHARACTERS ; MOVE128 MVI B,128 ;SET MOVE COUNT ; ;MOVE FROM (HL) TO (DE) LENGTH IN (B) ; MOVE MOV A,M ;GET A CHAR STAX D ;STORE IT INX H ;TO NEXT "FROM" INX D ;TO NEXT "TO" DCR B ;MORE? JNZ MOVE ;..YES, LOOP RET ;..NO, RETURN ; --R MULTIPLE ERRS. ; ;RETURNS W/ ZERO SET IF "RETRY" ASKED FOR ; CKQUIT XRA A ;ZERO.. STA ERRCT ;..ERROR COUNT CALL ILPRT ;PRINT: DB 'MULTIPLE ERRORS ENCOUNTERED. ' DB 'TYPE Q TO QUIT, R TO RETRY: ',0 CALL KEYIN ;QUIT/RETRY PUSH PSW CALL TE: TYPES VIA CP/M SO TABS ARE EXPANDED ; CTYPE PUSH B ;SAVE.. PUSH D ;..ALL.. PUSH H ;..REGS MOV E,A ;CHAR TO E MVI C,WRCON ;GET BDOS FNC CALL BDOS ;PRIN THE CHR POP H ;RESTORE.. POP D ;..ALL.. POP B ;..REGS RET ;FROM "CTYPE" ; CRLF '-40H ;REBOOT? JZ EXIT ;YES. JMP ILPNEXT ;LOOP ; ILPRET XTHL ;RESTORE HL RET ;PAST MSG ; ;----> PRTMSG: PRINTS MSG POINTED TO BY (DE) ; ;A '$' IS THE ENDING DELIMITER FOR THE PRINT. ;NO REGISTERS SAVED. ; PRTMSG MVI C,PRINT ;GET BDOS FNC TYPE THE MSG ; ILPNEXT INX H ;TO NEXT CHAR JMP ILPLP ;LOOP ; ;PAUSE WHILE TYPING HELP SO INFO DOESN'T ; SCROLL OFF OF VIDEO SCREENS ; ILPAUSE CALL ILPRT ;PRINT: DB CR,LF,'PRESS RETURN TO CONTINUE' DB CR,LF,0 CALL KEYIN ;GET ANY CHAR CPI 'CEM. ; STAT PUSH B PUSH D PUSH H VSTAT CALL $-$ ;ADDR SET AT INIT POP H POP D POP B ORA A ;0 => NOT READY RET ; ;----> KEYIN: KEYBOARD INPUT ; ;SAVE ALL REGISTERS, EXCEPT A, IN CASE ;CBIOS CLOBBERS THEM. ; KEYIN PUSH B PUSH D PU-------------- ; ; ;----> DIALMOD: DETECT PHONE # IN COMMAND LINE AND DIAL IT ; ;THIS ROUTINE (AND THE CALL TO IT) IS ENABLED ONLY WHEN 'DCH' ;IS TRUE BECAUSE I DON'T KNOW HOW TO MAKE THE OTHER MODEM ;BOARDS DIAL. MOST OF THE PHONE NUMBER LOGIC SHOYPE CALL CRLF POP PSW ANI 5FH ;MAKE UPPER CASE CPI 'R' ;RETRY? RZ ;'KEEP ON TRUCKIN' CPI 'Q' ;QUIT? JNZ CKQUIT ;NO, ASK AGAIN ORA A ;SET NON-ZERO RET ; ;----> ILPRT: INLINE PRINT OF MSG ; ;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE, MVI A,CR CALL TYPE MVI A,LF ; ;----> TYPE: TYPE VIA DIRECT CBIOS ACCESS ;WE ASSUME CBIOS MAY DESTROY SOME REGISTERS, ;SO SAVE THEM ALL. ; ;THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C ;TESTS. ; TYPE PUSH PSW ;SAVE CHAR PUSH B ;AND OTHER REGISTE JMP BDOS ;PRINT MESSAGE, RETURN ; ;----> ERXIT: EXIT PRINTING MSG FOLLOWING CALL ; ERXIT POP D ;GET MESSAGE CALL PRTMSG ;PRINT IT CALL CKDIS ;DISCONNECT? ; EXIT LHLD STACK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- TO CP/M ; ;MOV CALL NIBBL ;PRINT LEFT DIGIT POP PSW ;RESTORE RIGHT ; NIBBL ANI 0FH ;ISOLATE DIGIT CPI 10 ;IS IS <10? JC ISNUM ;YES, NOT ALPHA ADI 7 ;ADD ALPHA BIAS ; ISNUM ADI '0' ;MAKE PRINTABLE JMP TYPE ;..THEN TYPE IT ; ;----> CKQUIT: QUIT/RETRY AFTESH H VKEYIN CALL $-$ ;ADDR SET AT INIT POP H POP D POP B ANI 7FH ;STRIP PARITY IF THERE RET ;FROM KEYIN ; ;----> HEXO: HEX OUTPUT ; HEXO PUSH PSW ;SAVE FOR RIGHT DIGIT RAR ;RIGHT.. RAR ;..JUSTIFY.. RAR ;..LEFT.. RAR ;..DIGIT.. IJK 123-456-7890 ;IF NO PHONE NUMBER IS GIVEN, THIS ROUTINE RETURNS WITHOUT ;DOING ANYTHING. THE DIALER RECOGNIZES THE DIGITS 0-9 AND ;ALSO AN ASTERISK (*), WHICH CAUSES A TWO SECOND DELAY. ;THIS IS USEFUL FOR SUCH THINGS AS WAITING FOR THE SECOND ;D RET ; SKARG: MOV A,M ;SCAN PAST ONE ARGUMENT AND FOLLOWING BLANKS CPI ' ' JZ SKBLNK ;GOT BLANK...GO SKIP BLANKS INX H DCR B ;SCAN TILL STRING GONE JNZ SKARG STC ;SET CARRY ON RETURN IF END OF STRING RET ; ENDIF ;(FOR DIALING LO ;GO BACK OFF HOOK CALL DELAY ;FOR OTHER HALF PULSE TIME POP PSW ;GET BACK PULSE COUNT DCR A ;COUNT IT DOWN JNZ PULSE ;LOOP TILL DIGIT IS OUT MVI B,10 ;DELAY 500MS BETWEEN DIGITS CALL VARDLY JMP DL ;GO DO NEXT DIGIT ; VARDLY: CALL DE;SET DELAY LOOP LENGTH FOR DIALING ENDIF IF NOT FASTCLK DIALTIM EQU -1786 ENDIF ; IF DCH DIALMOD:LXI H,BASE+80H ;LOOK AT CP/M COMMAND TAIL MOV B,M ;GET BYTE COUNT INX H ;BUMP TO FIRST CHAR CALL SKBLNK ;SKIP LEADING BLANKS RC ;NOTHINCT ANI 40H JNZ GOTCARR CALL DELAY DCX D ;COUNT DOWN DELAY MOV A,D ORA E JNZ CARR CALL ILPRT ;SAY WE'RE GIVING UP DB BEL,'NO ANSWER',CR,LF,0 JMP DISCONN ;HANG UP ; GOTCARR:CALL ILPRT ;SAY WE GOT IT DB BEL,'CONNECTION ESTABLISHED' ;GIVE 2 SECOND DELAY FOR DIALTONE LXI H,DIALBUF DL: MOV A,M ;PICK UP DIGIT ORA A JZ WAITANS ;NULL MEANS FINISHED CALL TYPE ;ECHO DIGIT CPI '*' MVI B,40 ;IF STAR, DO 2 SECOND DELAY CZ VARDLY INX H ;BUMP POINTER SUI '0' ;CONVERT DIGIAL TONE IN A CENTREX SYSTEM. ;THE POUND SIGN CHARACTER (#) MAY BE USED IN PLACE OF A PHONE ;NUMBER TO RE-DIAL THE LAST-DIALED PHONE NUMBER. THIS OF COURSE ;WILL ONLY WORK IF NO OTHER PROGRAMS HAVE BEEN EXECUTED IN THE ;INTERIM. ;ALL OTHER CHARACTERSP LXI H,DIALTIM DLYLP: XTHL ;KILL LOTSA TIME XTHL DAD D ;SLOW WAY TO DO AN INX JNC DLYLP POP D POP H ;RESTORE REGS RET ;DONE ; ; COME HERE AFTER DIALING TO WAIT FOR ANSWER ; WAITANS:CALL CRLF ;SHOW NUMBER FINISHED LXI D,600 ;WELAY ;DELAY (B) TIMES 50 MS. DCR B JNZ VARDLY RET ; DELAY: PUSH H ;DELAY FOR 50 MILLISECONDS PUSH D PUSH PSW CALL STAT ;CHECK FOR CONTROL-D CNZ KEYIN CPI DISCCHR ;TO ABORT DIALING JZ DISCONN POP PSW LXI D,1 ;SET UP FOR DELAY LOOG LEFT...QUIT CALL SKARG ;ALWAYS AT LEAST ONE ARG TO SKIP RC ;NOTHING FOLLOWS...QUIT LDA OPTION ;LOOK AT MAIN OPTION TO SEE IF CPI 'T' ; IT HAS A SECOND PARAMETER JZ ONEARG ;T HAS ONLY ONE CPI 'E' ;SO DOES E JZ ONEARG CALL SKARG ;MU,CR,LF,0 LDA CURRMOD ;RESTORE WHOLE MODE BYTE OUT MODCTLP RET ;ALL DONE ; SKBLNK: MOV A,M ;SCAN PAST BLANKS IN COMMAND LINE CPI ' ' RNZ INX H DCR B JNZ SKBLNK ;CONTINUE SCAN TILL CHARS EXHAUSTED STC ;CARRY SET SAYS END OF COMMANDIT TO BINARY JNZ NOTZ ;CHANGE 0 TO 10 MVI A,10 NOTZ: JC DL ;IGNORE NON-NUMERIC CPI 11 JNC DL PULSE: PUSH PSW ;SAVE PULSE COUNT LDA CURRMOD ANI 7DH ;DROP OFF-HOOK OUT MODCTLP CALL DELAY ;FOR ONE HALF PULSE TIME ORI 80H OUT MODCTLP ARE IGNORED. (THIS INCLUDES THE DASHES ;IN THE ABOVE EXAMPLES, WHICH COULD HAVE BEEN OMITTED.) ;THE LENGTH OF THE DIAL STRING MUST BE AT LEAST 7 CHARACTERS ;TO BE RECOGNIZED, AND MAY CONSIST OF UP TO 20 CHARACTERS. ; IF FASTCLK DIALTIM EQU -3390 'LL WAIT 30 SECONDS FOR ANSWER LDA CURRMOD MOV B,A ;SAVE CURRENT MODE ANI 4 ;CHECK ORIG/ANS BIT JNZ CARR ;IF ORIG, WAIT FOR ANSWERING CARRIER MOV A,B ;IF ANS, GIVE OUR CARRIER, THEN WAIT OUT MODCTLP CARR: IN MODCTL2 ;WAIT FOR CARRIER DETE A,M DCR B JNZ CNLUP SUB A ;TAG END OF NUMBER WITH A NULL STAX D REDIAL: CALL ILPRT ;SAY WE'RE DIALING DB CR,LF,'DIALING - ',0 LDA CURRMOD ;PICK UP MODEM COMMAND BYTE ANI 8DH ;REMOVE CARRIER ENABLE OUT MODCTLP MVI B,40 CALL VARDLY ST BE R OR S, SO SKIP FILENAME RC ;QUIT IF NOTHING LEFT ONEARG: MOV A,M ;LOOK AT FIRST CHAR OF PHONE # CPI '#' ;REDIAL FLAG? JZ REDIAL ;IF SO, DON'T COPY NUMBER LXI D,DIALBUF CNLUP: STAX D ;COPY PHONE NUMBER TO DIALBUF INX D INX H MOVGIC) ; ; OPTION DB 0 ;PRIMARY OPTION ; ;DATAFLG IS USED BY THE "V" SUBCOMMAND - ;IT IS 0 WHEN A HEADER OR CKSUM IS BEING ;SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE ;SECTOR ITSELF) IS ; DATAFLG DB 0 ;AT HEADER, FIRST ; ; ;SUB-OPTION TABLE. IF ANSE FCB EQU BASE+5CH ;SYSTEM FCB FCBEXT EQU FCB+12 ;FILE EXTENT FCBSNO EQU FCB+32 ;SECTOR # FCB2 EQU BASE+6CH ;SECOND FCB END phone' DB ' (S100 modems only)',cr,lf DB ' H to print this help file' DB cr,lf,cr,lf,1 DB 'Secondary options:',cr,lf DB ' A answer mode',cr,lf DB ' O originate mode',cr,lf DB ' D disconnect after execution',cr,lf DB ' T go to terminal mode RROR COUNT HOLDD DB 86H ;HOLD AREA - LAST DC HAYES CONT CHAR. CURRMOD DB 86H ;CURRENT MODEM COMMAND BYTE ; ;FOLLOWING 3 USED BY DISK BUFFERING ROUTINES EOFLG DB 0 ;EOF FLAG (1=TRUE) SECPTR DW DBUF SECINBF DB 0 ;# OF SECTORS IN BUFFER DS 60 ;STACK ,lf,0 JMP EXIT ; ; DS 128-($ AND 127) ;FORCE NEXT SECTOR BOUNDARY DIALBUF EQU $ ;STORAGE FOR NUMBER BEING DIALED ; ; ; BDOS EQUATES (VERSION 2) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CONST EQU 11 ;CONSOLE STAT OPEN EQU 15 ;0FFH=NOT FOUND CLOrameter which if present',CR,LF DB ' is a telephone number to be automatically dialed.',CR,LF DB ' A "*" may be used to cause a 2 second pause in dialing.',CR,LF DB ' A "#" means to redial the last phone number attempted.',CR,LF DB ' All other char OPTION IS IN EFFECT, ; THE CHARACTER IS SET TO BINARY 0 ; OPTBL EQU $ ANSWFLG DB 'A' ;ANSWER MODE DISCFLG DB 'D' ;DISCONNECT WHEN DONE ECHOFLG DB 'E' ;TO ECHO AFTER XFER ORIGFLG DB 'O' ;ORIGINATE MODE QFLG DB 'Q' ;QUIET TRANSFER (NO MSGS) RSEEFLGLES, TYPE: MODEM X',cr,lf,0 JMP EXIT ; EXAM CALL ILPRT DB 'Send file, originate mode, 300 baud:',CR,LF DB ' MODEM SO fn.ft',cr,lf DB 'Send another file:',CR,LF DB ' MODEM S fn.ft',cr,lf DB 'Then send a third file at 450 baud and disconnect:' after file xfer',cr,lf DB ' E go to echo mode after file xfer',cr,lf DB ' Q quiet mode - no status msgs',cr,lf DB ' R show chars received',cr,lf DB ' S show chars sent',cr,lf DB ' V view file sent/received (no status)',cr,lf DB CR,LF,'FOR EXAMPAREA STACK DS 2 ;STACK POINTER ; ;16 SECTOR DISK BUFFER (OVERLAYS HELP MSGS) ; DBUF EQU $ ;16 SECTOR DISK BUFFER ; ;INVALID COMMAND ; BADOPT CALL TYPE CALL ILPRT ;EXIT W/ERROR DB ': INVALID OPTION ON MODEM ' DB 'COMMAND - ',CR,LF DB 'PRESSSE EQU 16 ; " " SRCHF EQU 17 ; " " SRCHN EQU 18 ; " " ERASE EQU 19 ;NO RET CODE READ EQU 20 ;0=OK, 1=EOF WRITE EQU 21 ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC MAKE EQU 22 ;0FFH=BAD REN EQU 23 ;0FFH=BAD STDMA EQU 26 ;SET DMA BDOS EQU BASE+5 REIPL EQU BAacters are ignored.' ENDIF DB cr,lf,cr,lf,1 DB 'Primary Options:',cr,lf DB ' S to send a file',cr,lf DB ' R to receive a file',cr,lf DB ' T to act as a terminal',cr,lf DB ' E to act as a computer (echo data)',cr,lf DB ' D to disconnect the DB 'R' ;SEE WHAT'S RECEIVED SSEEFLG DB 'S' ;SEE WHAT'S SENT TERMFLG DB 'T' ;TO TERM AFTER XFER VSEEFLG DB 'V' ;VIEW MESSAGES (NO HDR, ETC) OPTBE EQU $ ;END OF OPTIONS ; RCVSNO DB 0 ;SECT # RECEIVED SECTNO DB 0 ;CURRENT SECTOR NUMBER ERRCT DB 0 ;E DB CR,LF,' MODEM SD.450 fn.ft',cr,lf DB 'Act as a terminal, originate mode, at 110 baud:',cr,lf DB ' MODEM TO.110',CR,LF DB ' (Use ctl-D to disconnect)',cr,lf DB 'Receive file, answer mode, view it, 600 baud:',cr,lf DB ' MODEM RAV.600 fn.ft',crlowed by sub-options,',cr,lf DB ' and by ".xxx" to set baud rate to xxx.',CR,LF DB 'FILENAME is any valid CP/M unambiguous drive and filespec.',CR,LF DB ' It is used only for the "R" and "S" functions.',CR,LF IF DCH DB 'PHONENUM is an optional pa RETURN FOR HELP, CTL-C IF NOT',CR,LF,1,0 ; HELP CALL ILPRT DB 'Format for command is:',cr,lf,cr,lf DB 'MODEM ? FILENAME' IF DCH DB ' PHONENUM' ENDIF DB CR,LF,CR,LF DB 'Where ? is a 1 character primary option,',cr,lf DB ' which may be fol; ; MOVE.ASM ; V2.1 ; (revised 6/12/80) ; ;USED TO TRANSFER FILES FROM ONE DISK TO ANOTHER ;ON A 1 DISK SYSTEM, BY READING THE FILE INTO MEMORY. ;ISSUES ERROR MSG IF FILE WON'T FIT. ALSO USEFUL FOR ;TRANSFERRING ONE FILE TO MULTIPLE DISKS. W ANI 7FH ;ZERO OUT ATTRIBUTE MOV M,A ;RESTORE CHAR TO FCB INX H DCR B ;ONE LESS CHARACTER JNZ ZFCBLP ; ;ERASE ANY FILE BY SAME NAME LXI D,FCB MVI C,ERASE CALL BDOS ; ;MAKE THE FILE LXI D,FCB MVI C,MAKE CALL BDOS INR A JZ BADMAK, EXIT WITH ERROR MESSAGE. ; CALL ERXIT DB '++NO SUCH FILE++',CR,LF,'$' ; OPENOK LXI D,BUFF ;POINT TO BUFFER READLP PUSH D ;SAVE BUFFER ADDRESS MVI C,STDMA CALL BDOS ;READ A SECTOR LXI D,FCB MVI C,READ CALL BDOS POP D ;GET DMA ADDR O;05/27/79 MODIFY TO CHECK FOR NO FILE NAME AND TO ; ZERO OUT DISK NAME SO IT WON'T OVERULE THIS ; PROGRAM. BY KEITH PETERSEN, W8SDZ. ;08/19/79 REMOVE MACROS TO ALLOW ASSEMBLY WITH ; ASM.COM. ADD CONDITIONAL ASSEMBLY FOR CP/M ; ON H8 OR TRS-80. (KBP)DESTMSG LXI D,BASE+80H ;RESET DMA TO NORMAL MVI C,STDMA CALL BDOS CALL ILPRT DB 'C/R TO END, ',CR,LF DB 'MOUNT DEST. DISK, TYPE: A, B, C, OR D ',0 CALL GETDISK ;GET A OR B JC DESTMSG ;NEITHER, ASK AGAIN LHLD SAVEFCT ;GET SAVED COUNT SHLDSTART LDA FCB+1 ;SEE IF FILE NAME THERE CPI ' ' ;NONE? RZ ;IF NONE, RETURN TO CP/M LXI SP,STACK XRA A ;ZERO DISK NAME SO IT WON'T STA FCB ;OVERULE COMMANDS IN THIS PGM. CALL ILPRT DB 'MOVE.COM V2.1, 6/12/80' DB CR,LF,0 ; SRCMSG CALL ILPRORKS WITH ;ANY DRIVE - A, B, C, OR D. ; ;*************************************************** ;* NOTE: CHECK COMMENTS AT LABEL 'EXIT:' REGARDING * ;* REBOOT WHEN EXITING THIS PROGRAM. * ;*************************************************** ; ;07/INTER SUI 2 ;MAKE SURE CMP D ;ABOUT TO HIT BDOS? JNC READLP ;NO, LOOP ; ;FILE IS TOO BIG - EXIT PRINTING ERROR MSG. ; CALL ERXIT DB '++FILE WON''T FIT IN MEMORY++$' ; ;GOT RETURN CODE ON READ, SEE IF ERROR OR EOF ; EOF LHLD FCT ;GET SECTORRA A ;OK? JNZ EOF ;NOT OK, MUST BE EOF LHLD FCT ;LOAD SECTOR COUNT FOR FILE INX H ;BUMP IT SHLD FCT ;SAVE IT BACK LXI H,80H ;LENGTH OF 1 SECT. DAD D ;CALC NEXT BUFF ADDR XCHG ;PUT IT BACK IN DE ;OUT OF MEMORY? LDA BASE+7 ;GET BDOS PAGE PO ;08/20/79 FIX TEST TO PROTECT BDOS (WAS WRONG WHEN ; ALTCPM OPTION CHOSEN). (KBP). ;11/27/79 FIX DMA PROBLEM FOR MULTIPLE WRITES. ; ELIMINATE EXTRA PUSH-POPS. (KBP). ;12/04/79 FIX ERROR IN RESETTING DMA TO NORMAL ; (Thanks to Ward Christensen) (KBP FCT ;SAVE FOR DECREMENT ; ;INIT FOR WRITING THE FILE ; XRA A STA FCBEXT ;ZERO EXTENT # STA FCBSNO ;ZERO SECTOR # ; ;REMOVE ALL FILE ATTRIBUTES LXI H,FCB+1 ;POINT TO FILE NAME.TYPE MVI B,11 ;NUMBER OF CHARACTERS ; ZFCBLP MOV A,M ;GET CHAR T DB 'MOUNT SOURCE DISK, TYPE: A, B, C, OR D ',0 CALL GETDISK ;GET DISK NAME JC SRCMSG ;INVALID ANSWER, ASK AGAIN ; ;GOT DISK, OPEN THE INPUT FILE ; LXI D,FCB MVI C,OPEN CALL BDOS INR A ;WAS THE OPEN OK? JNZ OPENOK ;YES ; ;OPEN WAS BAD23/78 ORIGINALLY WRITTEN BY WARD CHRISTENSEN ;10/20/78 MODIFY TO WRITE MULTIPLE TIMES ; (FOR EXAMPLE TO MOVE STAT.COM TO 5 NEW DISKS) ;02/24/79 MODIFY TO STORE TO EITHER A: OR B:, AS ; MOVE IS MUCH QUICKER THAN PIP FOR PEOPLE ; WITH 2 DRIVE SYSTEMS. COUNT SHLD SAVEFCT ;SAVE IT FOR MULTIPLE WRITES ;A HAS RETURN CODE FROM READ DCR A ;EOF? JZ DESTMSG ;YES, ASK FOR DEST. DISK ; ;READ ERROR - EXIT WITH MSG ; CALL ERXIT DB '++READ ERROR++$' ; ;FILE READ INTO MEMORY. ASK FOR DEST. DISK ; ; OF FCB NAME. (KBP) ; STDCPM EQU 1 ;TRUE FOR STANDARD CP/M ALTCPM EQU 0 ;TRUE FOR H8 OR TRS-80 ; BASE SET 0 ; IF ALTCPM ;H8 OR TRS-80 BASE SET 4200H ENDIF ;ALTCPM ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE