ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее-ACPMUG °6ACATALOG ¶ EDVDM ДOCEXPLAIN ДOCMAILLISTДOCЂ MAILLISTДOCRANDY ДOCBLOAD БSM) !"ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее MAILLIST.DOC DOCUMENTAION ON CACHE MAILLIST PROGRAMS RANDY.DOC COMMENTS ON XREFASM.ASM 6.1 6K BLOAD.ASM TARBELL TAPE MITS 3.1 BASIC CSAVE TO ASCII 6.2 34K CCOS1.ASM CACHE CASETTE OPERATING SYSTEM 6.3 2K CKSUM.ASM CHECKSUMS CP/M FILES 6.4 ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееSAVED FILES 6.19 2K TMAP.ASM MAP OF TAPE WITH TSAVED FILES 6.20 5K TSAVE.ASM CP/M FILE TO TARBELL TAPE WITH CHECKSUM 6.21 58K XREFASM.ASM CP/M COMPATIBLE ASSEMBLER PRODUCES XREF TABLES. (CP/M ASSEMBLER WILL NOT ASSMBLE THIS WITHOUT EXTENееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееCCOS1 БSMЂ#$%&'()*+,-./012CCOS1 БSMЂ3456789:;<=>?@ABCCOS1 БSMCDCKSUM БSM EFCOMPARE БSM(GHIJKCUTTER БSMuLMNOPQRSTUVWXYZIDUMP БSM[\]MAINT ВASB^_`abcdefES AND CONTROL REMOTE COMPUTERS VIA MODEM 6.9 3K PONG.ASM VDM PONG GAME. THIS FILE IS FAULTY AND WILL BE RE-RELEASED ASAP 6.10 1K PREFMT.BAS MAILLIST MODULE 6.11 3K PURGE.ASM DISKETTE DIRECTORY PURGE 6.12 1K QUICKIE.BAS MAILLIST MODULE 5K COMPARE.ASM COMPARES TWO CP/M FILES 6.5 15K CUTTER.ASM SEEMS TO BE VDM TO CASETTE PROGRAM, BUT DOCUMENTATION STILL AWAITED 6.6 3K IDUMP.ASM INTERPRETED FILE DUMP 6.7 9K MAINT.BAS MAILLIST MODULE 6.8 13K MODEM.ASM PROGRAM TO SEND AND RECEIVE FILееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееSIVE MODS TO RE-LABEL WHERE RESERVED WORDS WERE USED, AND VERY LARGE NUMBER OF 8-BIT IMMEDIATE OPERATIONS WITH 16 BIT EXPRESSIONS.) VOLUME 6 CHICAGO AREA COMPUTER HOBBIEST EXCHANGE SOFTWARE NUMBER SIZE NAME COMMENTS CATALOG.6 CONTENTS OF CP/M VOLUME 6 EDVDM.DOC ED.COM PATCH TO CHANGE LINES OF P COOMAND. SEE EXPLAIN.DOC EXPLAIN.DOC COMMENTS ON CERTAIN PROGRAMS MODEM БSMbghijklmnopqrsееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее6.13 8K REPORT.BAS MAILLIST MODULE 6.14 6K SIZE.ASM GIVES SIZE OF CP/M FILE 6.15 5K SLOAD.ASM LOADER MODULE OF CCOS1 6.16 7K SORT.ASM MAILLIST MODULE 6.17 4K TISQ.ASM TIMES SQUARE (NEWSCASTER) LETTERS TO VDM 6.18 5K TLOAD.ASM TARBELL LOADER FOR TееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееFROM WARD CHRISTENSEN: HERE IS HOW TO MODIFY THE CPM ED.COM PAGE (P) COMMAND FOR OTHER THAN 24 LINE DISPLAYS. FOR EXAMPLE, IF YOU HAVE A VDM, YOU WOULD LIKE 15 LINES, NOT 23, TO BE SHOWN. DDT ED.COM DDT VERSION 1.3 NEXT PC 1500 0100 -LC95 C OF AS A SKELETAL PROGRAM WHICH YOU ALWAYS EDIT AND CHANGE BEFORE USING. RANDY.DOC - DOCUMENTATION ON XREFASM, CCOS, ETC. REPORT.BAS - SEE 'MAILLIST.DOC' FOR DETAILS SIZE.ASM - PRINTS SIZE OF A CP/M FILE IN 'K' BY BOB VAN VALZAH SLOAD.ASMXAMPLE). IDUMP.ASM - INTERPRETED FILE DUMP. FORMAT: IDUMP XXXXX.YYY MAILLIST.DOC - DOCUMENTATION ON COMPUTER CLUB MAILING LIST PROGRAMS: MAINT.BAS REPORT.BAS PREFMT.BAS SORT.ASM MAINT.BAS - SEE MAILLIST.DOC FILE FOR DETAILS MODEM.ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее READS THE KEYBOARD AND SENDS WHAT IT READ). FOR TWO PEOPLE TO TALK TO EACH OTHER, ONE MUST TYPE MODEM C - THE OTHER MUST TYPE MODEM T PONG.ASM - VDM PONG GAME, KEYBOARD AGAINST COMPUTER. BY BOB VAN VALZAH PURGE.ASM - PURGE INVALID DIRECTORY BYTE OF DIFFERENCE IS FOUND. STOPS AT FIRST UNEQUAL COMPARE. NOTE THAT WHEN PIPPING A COM FILE, PIP PUTS A 1AH AT THE LAST BYTE OF THE FILE, THEREFORE COMPARE WILL FIND THIS DIFFERENCE AS BYTE DISPLACEMENT 80H IN THE LAST SECTOR. FORMAT: COMP96 0C95 MVI M,17 0C97 -AC95 0C95 MVI M,F 0C97 -^C A>SAVE 20 EDP.COM THAT'S ALL THERE IS TO IT. IF YOU HAVE A VDM, YOU WOULD LIKE 15 LINES, NOT 23, TO BE SHOWN. DDT ED.COM DDT VERSION 1.3 NEXT PC 1500 0100 -LC95 CE BRIEFLY: MODEM S XXXXX.YYY SEND A FILE MODEM R XXXXX.YYY RECEIVE A FILE MODEM T OPERATE AS A TERMINAL MODEM C OPERATE AS A COMPUTER (WITHIN THE CONTEXT OF THIS PROGRAM, A 'TERMINAL' IS A 'DUMB' DEVICE WHICH TAKES CHARACTERS FROM THASM - PROGRAM TO SEND AND RECEIVE PROGRAMS VIA MODEMS. USES FULL HANDSHAKING AND CHECKSUMING, 10 ERROR RETRIES, ETC. ALSO INCLUDES CODE FOR SIMPLE KEYBOARD TO KEYBOARD COMMUNICATIONS. SEE COMMENTS IN MODEM.ASM FOR OPERATING DETAILS. HERE THEY ARBRIEF DOCUMENTATION OF FILES ON THIS DISK BLOAD.ASM - READS A TARBELL TAPE OF MITS 8K 3.1 BASIC PROGRAMS AND TURNS IT INTO A SOURCE FILE. FORMAT: BLOAD XXXXXXXXX.YYY (SUPPLY YOUR OWN NAME) CCOS1.ASM - TARBELL/VDM CASSETTE OPERATING SYSTEM FROM ENTRIES AUTOMATICALLY. SUGGEST CAREFUL USE AND TESTING ON SCRATCH DISK. QUICKIE.BAS - USED WITH MAILING LIST SYSTEM WHEN YOU NEED A 'QUICKIE' PROGRAM TO READ THE FILE, LOOK AT AND/OR CHANGE SOMETHING, AND WRITE THE RECORDS BACK. MAY BE THOUGHTARE XXXXX.YYY AAAAA.BBB FULL DISK SPECIFICATIONS ALLOWED, SUCH AS: COMPARE A:TEST.ASM B:TEST.ASM CUTTER.ASM - SEE RANDY.DOC FOR DETAILS EDVDM.DOC - SHOW HOW TO MODIFY THE ED COMMAND P SUBCOMMAND TO DISPLAY 15 LINES, NOT 23 (FOR A VDM, FOR EееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееE KEYBOARD, AND SENDS THEM DOWN THE LINE, AND WHEN IT RECIEVES A CHARACTER FROM THE LINE, OUTPUTS IT TO THE DISPLAY (OR TTY OR WHATEVER YOU HAVE). A COMPUTER IS A SMARTER DEVICE IN THAT IT ECHOS EVERY CHARACTER IT RECEIVES. IN SENDING, IT JUSTEN 2 DIFFERENT PEOPLE WONDER IF THEY HAVE THE SAME VERSION OF A FILE - THEY BOTH RUN CKSUM AGAINST THEIR COPIES, THEN COMPARE RESULTS. FORMAT: CKSUM XXXXXX.YYY COMPARE.ASM - COMPARES 2 CP/M FILES. PRINTS SECTOR AND BYTE DISPLACEMENT WHERE FIRST CACHE, THE CHICAGO AREA COMPUTER HOBBYISTS EXCHANGE. CCOS - CACHE CASSETTE OPERATING SYSTEM CKSUM.ASM - CHECKSUMS ANY CP/M FILE PRINTING A CHECKSUM BYTE FOR EACH 256 BYTES. SOMEWHAT OBSOLETED BY COMPARE.ASM FOR COMPARING 2 FILES, BUT USEFUL WH - WHEN YOU SAVE A PROGRAM USING CCOS, SLOAD IS USED TO LOAD IT AS AN ASM FILE UNDER CP/M FORMAT: SLOAD XXXXXX.ASM SORT.ASM - SEE 'MAILLIST.DOC' FOR DETAILS TISQ.ASM - TIMES SQUARE DEMO (BIG CHARS) FOR THE VDM. BY BOB VAN VALZAH TLOAD.ASM - nique is simple, and is not for- giving of misspelled names. The algorithm, in BASIC this is: KEY=0 FOR I=1 TO LEN(KEY$) STEP 2 KEY = 2*KEY + ASC(MID$(KEY$,I,1)) NEXT I KEY = KEY- FILE.SIZE*INT(KEY/FILE.SIZE) IF KEY = 0 THEN KEY = 1 ----------------------------------------- As currently implemented, the file consists of 512, 128 byte (1 sector) records. It was originally thought that 1 sector records would be required because of the sort program written in assembler. However, the sortееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееumber of records in the file, and the remainder is used as a record number. When adding, if the record is already in use, the file is sequentially read from that point until an open record is found. When retrieving, the record randomized to is read, e file (by last name, zip, etc.) for report purposes. 4) A program to print: Alphabetic master listings Mailing labels (usually in Zip sequence) Name tags for meeting use. The programs on this disk fulfill these LOAD TAPES SAVED WITH 'TSAVE' COMMAND FORMAT: TLOAD XXXXXX.YYY TMAP.ASM - MAP TARBELL TAPES SAVED WITH TSAVE. PRESS ANY CHAR TO STOP EXECUTION OF TMAP TSAVE.ASM - PROGRAM TO SAVE CP/M FILES ON TARBELL TAPE. SAVES THEM IN 4K BLOCKS WITH A CHECKSways have to be read. Also, random writing would have to read modify, and write sectors because of the sector overlap. For speed of access during maintenance, the file is written using a randomizing or hashing technique on the person's name. T program was eventually written to be independent of file length. Note that 128 is still a very good value, because of the efficiency of BASIC/E only having to read 1 sector per record. If the record length was say, 150 bytes, then 2 sectors would alFILENAME: MAILLIST.DOC, 09/17/77 by Ward Christensen ------------------------------------------------------------ DOCUMENTATION FILE FOR THE COMPUTER CLUB MAILING LIST PROGRAMS WRITTEN IN BASIC-E. -------------------------------------------------------and the name is matched. If it is not the right name, the file is read sequentially until the a record with a matching name is found. You may press 'DEL' (or rubout) to stop the scan in case, for instance, you misspelled the name. Note that the techneeds. 1) PREFMT.BAS preformats the required size file 2) MAINT.BAS maintains the mailing list 3) SORT.ASM sorts the file, producing an index file 4) REPORT.BAS prints listings labels and name tags. -------------------------UM. FORMAT: TSAVE XXXXXX.YYY OR TSAVE XXXXXX.YYY ? TO READ/VERIFY AFTER SAVING. XREFASM.ASM - CROSS REFERENCE ASSEMBLER. SEE RANDY.DOC FOR DETAILS. he algorithm is as follows: A variable is initialized to 0. Then, every other letter in the person's name (1, 3, 5 ... n) is, one at a time, added into the variable. The variable is doubled between each addition. Then, the result is divided by the n a mailing list consist of the following requirements: 1) A file of names with sufficient information about each member. 2) A maintenance program to add, change, and delete records. 3) A sort program to change the order of th THESE PROGRAMS ARE BEING PROVIDED THROUGH THE COURTESY OF THE AUTHOR FOR THE SOLE USE OF HOBBYIST COMPUTER CLUBS IN MAINTAINING THEIR MAILING LISTS. ------------------------------------------------------ The needs of a computer club in maintaining------------------------------------------------------ The file currently has the following fields in the record: SORT: A 4 byte field on which the file is sorted, to be in alpha sequence. This means that you do not store the file as 'lastname,fiuch as to correct a misspelled field value. FORMAT: C fieldname newvalue EXAMPLE: C NAME J. SMITH The field name can be abbreviated. The table of field names in the program will be searched until the first 'n' letters of a name match the 'n'TENANCE PROGRAM-------------------- This program maintains the file. It has the following commands implemented to do so: MACRO: Allows issuing a string of up to 10 commands, over and over. Useful for doing such things as scanning the file fo When adding a person, BASIC/E will not accept a totally blank input, so 1 blank must be keyed when ORGANIZATION is not present. STREET: The street address CITY: The city AND state. Since BASIC will not allow a comma in an input line, simplyd a particular record in the file by record number. It is not frequently needed. FORMAT: READ recno EXAMPLE: READ 20 DUMP: This command sequentially dumps the file from a given starting record number. Press DEL to stop the dumping. FORMAd. Currently used: G Group (another computer club) M Magazine H Hobbyist V Vendor These are arbitrary values, however the REPORT program, when printing name tags for a meeting, will not print tags for type G or type M. -----------------rstname' which is very 'computeristic' and 'impersonal'. instead, you key in the name in it's natural form, then use the 4 byte SORT field for sorting. For example, if the name is James R. Smith, then the sort field would be keyed in as SMIT. lable. FIND: This is the ONLY command which accesses the file thru the randomizing routine. FORMAT: FIND name where name is the exactly spelled name of a person in the file. EXAMPLE: FIND WARD CHRISTENSEN The name is arithmetically hashed tr a certain field value, then changing the value, and doing it over and over. FORMAT: MACRO You will be prompted for input. When running in MACRO mode, a DEL from the keyboard will stop execution HELP: Prints a summary of the commands avai use a space after the city, such as: CHICAGO IL I originally considered putting STATE as a separate field, but BASIC/E files use quotes around each field, and separate fields by commas. Thereore, a 2 byte state field would take 5 bytes. T: DUMP recno EXAMPLE: DUMP 155 C: This command is used to change the contents of a field in the record most recently read into memory. It can change an entire field by replacing it with a new value, or can do a character string replacement s---PREFORMAT PROGRAM-------------------- This program preformats the file. It writes records with a '0' flag byte, i.e. empty records. From then on, the Maint program is used to add, change, and delete members of the file. ------------------MAIN NAME: The person's 'natural' name, i.e. first name first. Remember BASIC won't allow commas, so don't key in J. SMITH, JR. but rather J. SMITH JR. ORGANIZATION: This field is normally blank, but is provided when a 4-line address is required. o a record number. The file is scanned from that record number forward (wraps from end to beginning) until a matching name is found. You can press DEL at any time to stop the scan and return to command mode. READ: This command is used to rea (312) 555-1212 COMPUTER: A 5 byte field used to keep track of the computer owned, such as A8800, IMSAI, DGZ80, etc. PAID: A 2 byte field showing when membership is again due, in the form YYMM such as 7809 TYPE: A 1 byte 'type of member' fielThere just wasn't sufficient room in a 128 byte record. (Although recall that I now realize the record length does not have to be restricted to 128 bytes. ZIP: 5 byte numeric zip code PHONE: 10 digits, with parenthesis, spaces, and dash, as: letters in the field name used in the C command. N is therefore a sufficient abbreviation for NAME, but C will find CITY and not COMPUTER, so use CO for COMPUTER. FORMAT: C fieldname /oldvalue/newvalue/ EXAMPLE: C N /TIANSON/TENSEN/ The abon in the command, and all records matching are deleted. It is suggested the printer be turned on before issuing the PURGE command to keep an 'audit trail' of who was purged. FORMAT: PURGE yymm EXAMPLE: PURGE 7709 END: Used to end execution. d to actually write the name to disk. This allows using the C and LIST command to verify and change the contents of the record before writing it to disk. Also, see "CHANGING A NAME" below. There is one problem when adding records to the file, with the leftmost byte of the field. FORMAT: ? fieldname value EXAMPLE: ? CO ALTAIR The contents of each field read will be displayed whether or not it matches. Use DEL to stop the scan. F: This command (Find) works like C except that the ford BACK to disk, and is used following a FIND or READ command. Npote that if used after an ADD command, you will overlay the wrong record. You must use WRITE after ADD. FORMAT: UPDATE FREE: Used to determine how much memory is left during td for each field. If a field is blank, you cannot just press C/R because BASIC/E will give you a WARNING II message. Therefore, put in 1 space the press return. If you want to stop the ADD function, such as if you realize you made a mistakeve example would change WARD CHRISTIANSON to WARD CHRISTENSEN. The closing '/' is optional. LIST: Used to list the contents of the record most recently read into memory. FORMAT: LIST ?: This command is used to scan the disk from the curren being added is lost. A 'lot' of code could be added to add up the lengths of each field, plus 1 for the flag, plus 3 for each field (the quotes around the value, plus the comma separating values) but I just decided not to bother. ERASE: This c and that is that you cannot add a record which exceeds the record length. BASIC/E will unforgivingly issue an ER error and drop you back into CP/M. Due to the preallocation of the file, however, this is not serious as only the record currentlyield read from disk is scanned for a match at each position in the field, not just the first. For example, if everyone in the club having a Z-80 computer has a 'Z' somewhere in their COMPUTER field, but it differs from user to user (such as DGZ8he running of the MAINT program. Used during program development to see if room remained to add more function PURGE: Used to purge the file of records whose memberships have expired. The file is scanned for a matching date (PAID field) as give and don't want to go back and change it with the C function, type QUIT in response to any input. FORMAT: ADD You will be prompted for the input. NOTE the record is only built in a matrix in memory, and that the WRITE function must be executet position (the last record number read) for any field matching a value placed in the command. Only the first 'n' characters of the field on disk are matched, where 'n' is the number of characters given in the command. The match always starts ommand will erase the record most recently read. The record will still remain in memory such that a WRITE command could be used to write it back to disk, as would be required with a name change. FORMAT: ERASE UPDATE: This command writes a recommand is used to randomize and write a record to disk. It is used after the ADD command, or when changing someones name. See "CHANGING A NAME" below. FORMAT: WRITE ADD: This command is used to add a new name to the file. You will be prompte0, IMSZ8, Z2, etc.) then you could find someone with a Z80 by saying: F CO Z FORMAT: F fieldname charstring EXAMPLE: F STATE IL NOTE this runs 'lots' slower than '?' because of multiple comparisons being done on each field. WRITE: This cControl-C can also be used, as the file doesn't have to be closed, because it is pre-allocated. CHANGING A NAME: Since the file is written by randomizing the name field, you cannot simply FIND someone, use C to change their name, and UPDATE the ue EXAMPLE: POSITION ZIP 60419 In the first example, the file is positioned to the 55th record in the index table. In the second example, the file is sequentially read (from whatever position is currently is at) until a zip matching 60419 isame and computer double width) and the title of the report. Also the program prints CHR$(11) (Vertical Tab) to eject the paper to a new page. If you do not have this feature, you will have to insert the proper number of null print statements to causeassembler program which reads the mailing list, extracting the first 5 characters of a specified field, and doing a memory-resident bubble sort of the field and it's correspoiding record number. It then writes an ASCII file of just the record numbers. umbers (output from the SORT program), and causes the file to be read into memory. FORMAT: INDEX filename EXAMPLE: INDEX NAME.FIL POSITION: Positions the file to a particular record relative to the INDEX file which has been read. Used to s, mailing labels, and name tags. The listings can be either 130 columns wide, or can be printed with 2 lines for each person, on 8.5 wide paper. Name tags and Labels may be printed 3-up or 4-up, with variable width and height labels. It is currentrecord. Why? Next time you want to find them, you will type FIND newname and will randomize to it. However, the name is stored under the randomizing of the OLD name. Therefore, after changing a name, issue an ERASE to get rid of the old record operate correctly. The program prompts you with 'press linefeed' which then allows you time to turn on the sense switch. When it sees the linefeed on the keyboard port, it starts the listing. When the listing is complete, it awaits a 'del' from th an eject to the next page. Some printers may require CHR$(12) (Forms Feed) instead. Since there is not currently a way to turn on the printer from BASIC/E, this program requires a CBIOS with manual printer control, such as thru a sense switch, to It is currently set up for 3 byte record numbers, but may be easily changed for 4 byte record numbers. (Comments in SORT.ASM show how). The file of record numbers is then used in the REPORT program to process the file in the sequence asked for. The restart a listing, or to scan for starting the listing in the middle. It can position either by record number, or by the contents of the field sorted upon. FORMAT: POSITION recno EXAMPLE: POSITION 55 or FORMAT: POSITION fieldname fieldvally written for a Centronics 101 with the feature of expanding the width of characters when you print CHR$(14). If you do not have this facility, the program will have to be changed. Note this affects only the printing of name tags (which print the n, then WRITE to re-randomize the new name and write the record. This works because ERASE doesn't change the contents of the record maintained in the matrix in memory. --------------------SORT PROGRAM-------------------- The sort program is an e keyboard before continuing. This again gives you time to turn off the sense switch controlling the printer. The commands currently implemented in the program are: HELP: Prints a summary of commands available. INDEX: Names the file of record nly implemented are as follows: 1. SORT 2. NAME 3. ORGANIZATION 4. STREET 5. CITY 6. ZIP 7. PHONE 8. COMPUTER 9. PAID 10. TYPE --------------------REPORT PROGRAM-------------------- The report program is used to produce listingindex file is read into a table rather than accessed sequentially, for speed. FORMAT: SORT infilename outfilename fieldnumber EXAMPLE: SORT CACHE.FIL NAME 1 Note that 'outfilename' can be any valid CP/M file name. The field numbers current found. You may find it useful to use the first format to get 'close' because positioning by record number is fast, then use the position by field value until the exact one is found. NOTE that it is somewhat meaningless to POSITION on a field ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееBELS: This initiates the printing of mailing labels. It uses the settings of WIDTH, LENGTH, and UP to determine the physical format. A typical label is printed as follows: FERN P. DOCK 7709 HENWAY CORPORATION BOX 1234 FERNWOOD OH 12132 columns wide if width > 79. Other than being less than or greater than 80, the setting of width does not effect the output of the PRINT function. FORMAT: PRINT WIDTH: Sets print width. The meaning of the width depends upon the function be width of each field within the width allowed in the report program, or else the TAB to the next field will cause an extra line to be printed. This will offset the line counter, and may cause the program to print a page which is too long. med: If the first 2 letters of the last name are JR, then the scan continues again to the left. Then, the last few characters of the 'first name' are checked to see if they are any of the common double word last names, such as ' VAN' or ' DE' owhich is not the sort field, as the field being positioned upon is not read in order. NOTE if you stop the listing, then want to restart it from the beginning, you must issue POSITION 1 to start over again. TITLE: This command is used to suppln index has been read or not, and the current settings of: WIDTH, LENGTH, etc. FORMAT: CHECK UP: This is used to cause printing of LABELS or name TAGS 3-UP or 4-UP. (UP referring to how many labels are printed side-by-side. The program has 345 (What's a HENWAY? about 3 pounds). Note the PAID date is printed in the upper right of the label. FORMAT: LABELS CHECK: This function checks the setting of the various variables, such as what record you are positioned to, whether aing asked for: TAGS or LABELS - the WIDTH setting is the actual number of characters wide the labels are. PRINT - the WIDTH setting determines the report width but only as to whether width is <80 or >79. FORMAT: WIDTH nn EXAMPLE: WIDTH 36ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееr ' DI' or ' MC'. If so, scanning continues again. You might have to change this algorithm depending upon the names you encounter, such as 3 word names (VAN DER HEIDE) or VON, or the myriad of names I have not yet dreamed of. FORMAT: TAGS LAy a title for the listing. FORMAT: TITLE any character string EXAMPLE: TITLE SEPTEMBER MEETING ALPHA LISTING PRINT: This command is used to initiate the printing of a listing. The listing will be either: 72 columns wide if width < 80, or not been generalized to handle 1-up or 2-up. FORMAT: UP n EXAMPLE: UP 3 3 or 4 are the only values supported. END: Causes ending of program execution. --------------------MISC. COMMENTS-------------------- Use abbreviations to keep them the last name: The name is scanned from the back until a space is found. The part of the name to the right of the space is now considered the last name, and the part to the left the first name. Then, certain 'reasonableness' tests are perfor LENGTH: Sets the length of the gummed labels used for the LABELS or TAGS function. Default is 6 lines long. FORMAT: LENGTH nn EXAMPLE: LENGTH 5 TAGS: Initiates the printing of name tags. An algorithm is used to split the first name froA note about xrefasm This is a CP/M compatable assembler that has one or two bugs.It does give a complete cross referance listing and library.It will not take multiple statements per line.Also the lables may be only six characters in length. It doe MVI A,' ' CALL STORE ;SPACE AFTER LINE # RET ; ;SUBROUTINE TO ADD BC TO HL ;AND COUNT DECIMAL # TIMES ; SBT PUSH D MVI D,'0' SBTLP PUSH H ;SAVE FOR RESTORE DAD B ;'SUBTRACT' JNC NOSBT ;COULDN'T SBTTRACT INR D ;INCR DECIMAL VALUE INX S ;SAVE TOKEN # PUSH D ;SAVE OUTPUT POINTER KEY10 PUSH H ;SAVE START OF TOKEN KEY20 MOV A,M ;GET CHAR INX H ;POINT TO NEXT ORA A ;SET COND JP KEY20 ;KEEP GOING DCR C ;RIGHT TOKEN? POP D ;GET START OF TOKEN ADDR JNZ KEY10 ;NOT RIGHT ONE ; ;ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееRROR WRERR LXI D,WRERM MVI C,PRINT CALL BDOS JMP 0 WRERM DB 'WRITE ERROR$' ; ENDIF ;TARBELL INPUT TBIN IN 6EH ANI 10H JNZ TBIN IN 6FH RET ; ;CONVERT LINE $ FROM BINARY TO ASCII ; BIASC PUSH B MOV C,M ;GET LO ORD INX H MOV B,MKEYWD ;IT IS A TOKEN ;STORE CHAR CALL STORE JMP CHAR ; CRLF MVI A,13 CALL STORE MVI A,10 CALL STORE MOV A,M ;GET NEXT LINE ADDR INX H ORA M INX H JNZ LINE ;GET NEXT LINE ; IF NOT TEST ; ;ALL DONE - WRITE LAST BLOCK, CLOSE FILE s have list on and off psuedo ops.It also seems to be able to assemble Z-80 op codes.The main bug is that you have to give it all three parameters (such as ASM TEST.AAB) and you may not use 'X' for printout on crt as it takes this as disk 'X'. 'Z' is POP H ;GET INPUT POINTER JMP CHAR ; ;ROUTINE TO STORE OUTPUT, WRITE FULL BUFFER ; STORE PUSH PSW ! PUSH B ! PUSH D ! PUSH H MOV E,A MVI C,WRCON CALL BDOS ;PRINT CHAR POP H ! POP D ! POP B ! POP PSW ; IF NOT TEST STAX D ;SAVE THE CHAR IGOT TOKEN ; XCHG ;TOKEN TO H,L POP D ;GET OUTPUT ADDR ; ;MOVE TOKEN TO OUTPUT ; KEY30 MOV A,M ;GET CHAR OF TOKEN ANI 7FH ;DELETE HI BIT CALL STORE ;STORE IT MOV A,M ;GET CHAR INX H ;POINT TO NEXT ORA A ;END OF TOKEN? JP KEY30 ;..NO ;BLOAD - ;PROGRAM TO READ TARBELL 8K BASIC 3.1 TAPES ;AND CREATE A SOURCE FILE TEST EQU 0H ;5/17/77 WRITTEN ORG 100H JMP START ;SKIP ID DB '(BLOAD 5/17/77)','Z'-40H START EQU $ ; IF NOT TEST MVI C,DELT CALL DKFNC ;ERASE OLD FILE MVI C, ;GET HI ORD INX H ;SKIP HI ORD PUSH H MOV H,B MOV L,C XRA A ;ZERO STA ZSFLG ;ZERO SUPPRESS FLAG LXI B,-10000 CALL SBT LXI B,-1000 CALL SBT LXI B,-100 CALL SBT LXI B,-10 CALL SBT MOV A,L ORI '0' CALL STORE POP H POP B ; MVI A,'Z'-40H ;EOF CHAR CALL STORE MVI C,WRITE CALL DKFNC ORA A JNZ WRERR MVI C,CLOSE CALL DKFNC ; ENDIF JMP 0 ; ;PROCESS KEYWORD ; KEYWD PUSH H ;SAVE INPUT POINTER LXI H,TABLE ;POINT TO KEYWORD TABLE SUI 7FH ;FUDGE MOV C,AO.K. Dont worry about the set errors when you try to assemble itself.Use the CP/M assembler to do the assembly. all three parameters (such as ASM TEST.AAB) and you may not use 'X' for printout on crt as it takes this as disk 'X'. 'Z' is NR E ;BUMP RNZ PUSH B MVI C,WRITE CALL DKFNC ;WRITE A SECTOR POP B MVI E,80H ;RE-INIT BUFFER ADDR ; ENDIF RET IF NOT TEST ; ;DISK FUNCTIONS - FNC IS IN C ; DKFNC PUSH H PUSH D LXI D,FCB CALL BDOS POP D POP H RET ;WRITE EX H ORA A JNZ RD3 DCR D JNZ RDLP ;CONVERT AND WRITE LXI D,80H ;OUTPUT BUFFER ADDR LXI H,BUFF INX H ;SKIP NEXT INX H ;..ADDR LINE CALL BIASC ;CONV LINE # CHAR MOV A,M ;GET A CHAR INX H ;POINT TO NEXT ORA A JZ CRLF ;END OF LINE JM MAKE CALL DKFNC INR A JZ WRERR ENDIF ; LXI H,BUFF ;READ FILE INTO MEMORY FROM TAPE RESET MVI A,10H OUT 6EH INIT CALL TBIN CPI 0E6H JZ INIT ;SKIP DOUBLE SYNC STA 7300H ;SHOW CHAR BEING LOADED RD3 MVI D,3 RDLP CALL TBIN MOV M,A INP ;DELETE INX SP ;SAVED HL JMP SBTLP NOSBT POP H ;RESTORE VALUE MOV A,D ;GET DIGIT POP D CPI '0' ;IF NOT ZERO JZ CKZER ;IS ZERO - CK '0' SUPPRESS ;NOT ZERO - TURN OFF ZERO SUPPRESS FLAG STA ZSFLG JMP STORE ;STORE THE CHAR ;IT IS A ZERO -* * * * * * * * N O T E * * * * * * * * * ALL THE INPUT/OUTPUT (I/O) ROUTINES * * IN CCOS ARE GROUPED TOGETHER JUST * * BELOW THIS NOTE. YOU NEED ONLY * * CHANGE THESE ROUTINES TO MAKE CCOS * * WORK FOR YOUR I/O. * * * CCOS ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееN','D'+128 DB 'FO','R'+128 DB 'NEX','T'+128 DB 'DAT','A'+128 DB 'INPU','T'+128 DB 'DI','M'+128 DB 'REA','D'+128 DB 'LE','T'+128 DB 'GOT','O'+128 DB 'RU','N'+128 DB 'I','F'+128 DB 'RESTOR','E'+128 DB 'GOSU','B'+128 DB 'RETUR','N'+1E TABLE JMP KEYIN ;PRIMARY KEYBOARD INPUT JMP TYPE ;PRIMARY OUTPUT JMP ALTO1 ;ALT OUT 1 JMP ALTO2 ;ALT OUT 2 JMP TTYO ;TTY OUTPUT JMP DSPLY ;VDM OUT (ONLY) JMP QCHEK ;HI SPEED (NO WAIT) CTL-Q CHK JMP XO ;HEX OUTPUT FROM A JMP XOB ;HEX OUT DB 'SI','N'+128 DB 'TA','N'+128 DB 'AT','N'+128 DB 'PEE','K'+128 DB 'LE','N'+128 DB 'STR','$'+128 DB 'VA','L'+128 DB 'AS','C'+128 DB 'CHR','$'+128 DB 'LEFT','$'+128 DB 'RIGHT','$'+128 DB 'MID','$'+128 DB 0 ;END OF TABLE ZSFLG D CHECK FOR ZERO SUPPRESS CKZER LDA ZSFLG ;GET THE FLAG ORA A ;SET COND CODE MVI A,'0' JNZ STORE RET ;NO STORE IF SUPPRESSED ; ; BDOS EQUATES (VERSION 2) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 OPEN EQU 15 ;0FFH=NOT FOUND CLOSE EQU 16 ; " ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее28 DB 'RE','M'+128 DB 'STO','P'+128 DB 'OU','T'+128 DB 'O','N'+128 DB 'NUL','L'+128 DB 'WAI','T'+128 DB 'POK','E'+128 DB 'PRIN','T'+128 DB 'DE','F'+128 DB 'CON','T'+128 DB 'LIS','T'+128 DB 'CLEA','R'+128 DB 'DLOA','D'+128 DB 'DS FROM A W/BLANK JMP TINTI ;TAPE INIT FOR INPUT JMP TINTO ;TAPE INIT FOR OUTPUT JMP TPIN ;TAPE IN JMP TPOUT ;TAPE OUT JMP TPINC ;TAPE IN, CKSUM W/B JMP TPOTC ;TAPE OUT, CKSUM W/B *---> TTY OUTPUT NULL COUNT NULLS DB 1 ;1+# OF NULLS AFTER C/R B 0 ;ZERO SUPPRESS FLAG BUFF EQU $ ;READ PROGRAM IN HERE END 100H  DB 'AS','C'+128 DB 'CHR','$'+128 DB 'LEFT','$'+128 DB 'RIGHT','$'+128 DB 'MID','$'+128 DB 0 ;END OF TABLE ZSFLG D" SRCHF EQU 17 ; " " SRCHN EQU 18 ; " " DELT 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 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH TABLE DB 'E ORG 04000H ;ORG FOR CPM *---> DEFINE LOCATION OF READ/WRITE WORK AREA WORKA EQU 05800H ;FILE WORK AREA, SYMBOL TBL *--> FOLLOWING IS A JMP TABLE TO MAJOR * CCOS INPUT/OUTPUT ROUTINES, ETC. JMP CCOS ;CCOS STARTUP, NO FILE INIT JMP INIT ;INIT FIL8 DB '>'+128 DB '='+128 DB '<'+128 DB 'SG','N'+128 DB 'IN','T'+128 DB 'AB','S'+128 DB 'US','R'+128 DB 'FR','E'+128 DB 'IN','P'+128 DB 'PO','S'+128 DB 'SQ','R'+128 DB 'RN','D'+128 DB 'LO','G'+128 DB 'EX','P'+128 DB 'CO','S'+128AV','E'+128 DB 'NE','W'+128 DB 'TAB','('+128 DB 'T','O'+128 DB 'SPC','('+128 DB 'F','N'+128 DB 'THE','N'+128 DB 'NO','T'+128 DB 'STE','P'+128 DB '+'+128 DB '-'+128 DB '*'+128 DB '/'+128 DB '^'+128 DB 'AN','D'+128 DB 'O','R'+12- THE CACHE CASSETTE OPERATING SYSTEM * A MODIFICATION OF PROCESSOR TECHNOLOGY PKG 1 * *---> DEFINE VDM INFORMATION VDMST EQU 0E000H ;<---VDM START ADDR CURS EQU 0FA00H ;<---VDM CURSOR POINTER IOBYT EQU CURS-1 ;I/O BYTE VDMEP EQU 0E4H ;PAGE AFTER VDUT W/CHECKSUM TPOTC PUSH 6 XRA B MOV B,A POP 6 *---> TARBELL OUTPUT TPOUT PUSH 6 CALL QCHEK ;ALLOW CTL-Q EXIT IN TBSP ;READ TARBELL STATUS PORT ANI TBOSB ;ISOLATE READY BIT CPI TBOSV ;READY? JNZ TPOUT+1 ;..NO POP 6 ;GET BYTE OUT TBDPOUTINE FROM B OUT8 MOV A,B JMP TYPE *---> TTY OUTPUT ROUTINE - SENDS * L/F, NULLS AFTER C/R TTYO PUSH PSW IN TTOSP ;GET STAT ANI TTOSB ;GET BIT CPI TTOSV ;READY? JNZ TTYO+1 ;NO POP PSW ;GET CHAR OUT TTODP ;OUTPUT CPI 13 ;C/R? RNZ NPUT DATA PORT *---> TTY OUTPUT PORT DEFINITION TTOSP EQU 0 ;TTY STATUS PORT TTOSB EQU 80H ;TTY STATUS BIT TTOSV EQU 0 ;TTY OUT READY VALUE TTODP EQU 1 ;TTY OUTPUT DATA PORT *---> ALT OUTPUT PORT EQU'S AO1SP EQU 4 ;ALT OUT 1 STATUS PORT AO1SB EQU 2ADY? JNZ ALTO2+1 ;LOOP TILL READY POP PSW OUT AO2DP ;OUTPUT DATA CPI 13 ;C/R? RNZ ;RET IF NOT C/R MVI A,10 ;GET LINEFEED JMP ALTO2 ;OUTPUT LINEFEED *--TARBELL CASSETTE I/O ROUTINES---* TBSP EQU 6EH ;TARBELL STAT PORT TBISB EQU 10H ;TARBE*---> KEYBOARD INPUT ROUTINE TO B REG IN8 CALL KEYIN ;INPUT TO A MOV B,A ;MOVE TO B RET *---> KEYBOARD INPUT ROUTINE TO A REG KEYIN CALL KEYST JNZ ALTIN ;TRY ALTERNATE INPUT KBIN IN KEYDP ;READ KBD DATA PORT ANI 7FH ;DEL PARITY CPI 'Q'-40H ;CM VDMP EQU 0E0H ;VDM PORT *---> MISCELLANEOUS EQUATES STOP EQU 'X'-40H ;KEYBOARD INPUT VALUE * (CTL-X) TO STOP LISTING HOLD EQU 1BH ;HOLD SCROLL (ESCAPE) CHAR *---> KEYBOARD (PRIMARY INPUT) EQUATES KEYSP EQU 0 ;KEYBOARD STATUS PORT KEYSB E C/R * ONLY IF 10H BIT ON IN IOBYTE * I.W. 'IOBYTE 11' CAUSES OUTPUT W/ L/F ALTO1 PUSH PSW IN AO1SP ;READ STAT ANI AO1SB ;GET READY BIT CPI AO1SV ;READY? JNZ ALTO1+1 ;LOOP TILL READY POP PSW OUT AO1DP ;OUTPUT DATA CPI 13 ;C/R? RNZ ;RET IF NOT MVI A,10 ;GET L/F CALL TTYO ;OUTPUT L/F LDA NULLS ;GET NULL COUNT PUSH B ;SAVE BC MOV B,A ; SAVE NULL COUNT NULLO MVI A,7FH CALL TTYO DCR B ;MORE NULLS? JNZ NULLO POP B RET ;FROM TTYO *---> ALT OUTPUT 1 SENDS L/F AFTER ;ALT OUT 1 STATUS BIT AO1SV EQU 2 ;ALT OUT 1 STAT READY VALUE AO1DP EQU 5 ;ALT OUT 1 DATA PORT *---> ALT OUTPUT PORT EQU'S AO2SP EQU 4 ;ALT OUT 2 STATUS PORT AO2SB EQU 2 ;ALT OUT 2 STATUS BIT AO2SV EQU 2 ;ALT OUT 2 STAT READY VALUE AO2DP EQU 5 ;ALTLL INPUT READY BIT TBISV EQU 0 ;TARBELL IN READY VALUE TBOSB EQU 20H ;TARBELL OUTPUT READY BIT TBOSV EQU 0 ;TARBELL OUT READY VALUE TBDP EQU 6FH ;TARBELL DATA PORT START EQU 3CH ;TARBELL START BYTE SYNC EQU 0E6H ;TARBELL SYNC BYTE *---> TARBELL OUTPONTROL Q? JZ QUIT ;..YES - RET TO CCOS RET *---> 'QUIT' CHECK ROUTINE * ABORTS IF CTL-Q HAS BEEN TYPED, * OTHERWISE JUST RETURNS * (LIKE HI-SPEED CTL-C CHK IN BASIC) QCHEK CALL KEYST ;CHECK STATUS CZ KBIN ;READ CHR IF READY RET *---> OUTPUT RQU 1 ;KEYBOARD STATUS BIT KEYSV EQU 0 ;VALUE WHEN READY KEYDP EQU 1 ;KEYBOARD INPUT PORT *---> ALTERNATE INPUT (KEY, MODEM) EQUATES AISP EQU 4 ;ALT INP STATUS PORT AISB EQU 1 ;ALT INP STATUS BIT AISV EQU 1 ;ALT INP STAT READY VALUE AIDP EQU 5 ;ALT I;RET IF NOT C/R * SEND L/F IF IOBYTE 10H BIT IS ON LDA IOBYT ANI 10H MVI A,10 ;GET L/F CNZ ALTO1 MVI A,13 ;RESTORE C/R RET *---> ALT OUTPUT 2 SENDS L/F AFTER C/R ALTO2 PUSH PSW IN AO2SP ;READ STAT ANI AO2SB ;GET READY BIT CPI AO2SV ;RE ;ISOLATE ALT INP FLAG JZ KEYIN ;GO TO PRIMARY IF NO ALT IN AISP ;READ ALT INP STATUS BYTE ANI AISB ;ISOLATE READY BIT CPI AISV ;CHECK ALT IN STAT VALUE JNZ KEYIN ;GO TO PRIMARY IF NO DATA IN AIDP ;READ ALT INP DATA PORT RET ;..AND RETURN OUT 2 DATA PORT *---> KEYBOARD STATUS CHECK ROUTINE KEYST IN KEYSP ;READ KB STATUS ANI KEYSB ;AND WITH STATUS BIT CPI KEYSV ;ZERO INDICATOR IF READY RET ;..THEN RETURN *---> ALTERNATE INPUT DEV INPUT RTN ALTIN LDA IOBYT ;GET I/O BYTE ANI 40H ;OUTPUT TARBELL DATA PORT RET *---> TARBELL INPUT W/CHECKSUM TPINC CALL TPIN PUSH 6 XRA B ;CALC CKSUM MOV B,A ;PUT BACK TO B POP 6 RET *---> TARBELL INPUT TPIN CALL QCHEK ;ALLOW CTL-Q EXIT IN TBSP ;TARBELL STATUS PORT ANI TBISB ;ISOLATMVI M,1 INX H LXI B,SYMT ;END OF INBUF ADDR MOV A,C CALL CLER ;CLEAR REMAINDER OF INPUT BUFF LXI H,IBUF-1 MOV M,E RET DEL CPI 7FH ;DELETE CHAR? JNZ CHAR MOV A,E ;<> CPI 2 ;<> JZ NEXT DCX H DCR E BSPA MVI B,08H ;ECHO BA JNZ VDMUP POP D LXI H,VDMST+3C0H SHLD CURS MVI M,' ' INX H CALL BLANK POP H CALL KBIN ;READ KB, NO WAIT CPI HOLD ;HOLD CHAR? RNZ CALL KEYIN ;READ CHAR CPI 'B' ;<--BASIC? JZ 0 ;<-C-A-U-T-I-O-N JMP 0!! RET BLANK MVI M,' ' ;' ELL RESET OUT TBSP ;OUT STAT PORT LXI B,5 ;FILENAME LENGTH LXI H,FBUF ;FILENAME ADDR CALL SET1 ;VDM ADDR TINTL CALL TPIN CMP M JZ TINTM INR B ;BUMP NOT = COUNT TINTM CPI ' ' ;' PRINTABLE? JC TINTI ;-DON'T PRT IF BAD ORA A JM TINTI ;HI ;LINE NUMBER? JC LINE ;..YES CALL VALC ;GET COMMAND VALUES CALL COMM ;LOOKUP/EXECUTE COMMAND *---> RETURN FROM COMMAND EXECUTION EOR CALL CRLF JMP CCOS *---> 'QUIT' MESSAGE QUITM DW 'QU' DW 'IT' DB 13 *---> READ INPUT LINE INTO INBUF REAI M,' ' ;' BKSP: DELETE CURSOR DCX H ;..BACK UP, JMP SVCUR ;..THEN STORE CURSUR NOTBS MOV M,A ;SAVE INCOMING CHAR INX H ;BUMP POINTER CKEOS MOV A,H ;CHECK END OF SCREEN CPI VDMEP ;END OF SCRN? JZ SCRUP ;SCROLL UP IF AT END ANI VDMEP-1 ;OTHERWE READY BIT CPI TBISV ;READY? JNZ TPIN ;..NO IN TBDP ;READ TARBELL DATA RET *---> TARBELL OUTPUT INITIALIZE * WRITES START, SYNC, FILE NAME TINTO MVI A,START CALL TPOUT MVI A,SYNC CALL TPOUT MVI B,5 LXI H,FBUF ;POINT TO FILE NAME CAL,3 ;GET RESET CHAR OUT 4 MVI A,15H ;GET CONTROL VALUE OUT 4 *---> REPL FOLLOWING JMP W/ CALL TO FURTHER * INITIALIZATION CODE YOU MAY NEED JMP QUIT ;DUMMY JMP TO ALLOW PATCH QUIT XRA A OUT VDMP ;RESET VDM STA IOBYT ;RESET I/O BYTE LXI INX H MOV A,L ANI 3FH JNZ BLANK RET *---> ENTRY POINT, CLEAR FILE TABLE FIRST INIT MVI C,INSP-FILE0 ;FILE TABLE LENGTH XRA A ;A=0 LXI H,FILE0 ;POINT TO FILE TABLE INIT2 MOV M,A INX H DCR C JNZ INIT2 *---> INIT SERIAL I/O PORT MVI A BIT ON - BAD CALL DSPLY INX H DCR C JNZ TINTL DCR B RM JMP TINTI *---> OUTPUT ROUTINE, TO VDM + ALTERNATES 1, * AND/OR 2 AND/OR TTY ACCORDING TO IOBYTE TYPE PUSH B ;SAVE BC MOV C,A ;CHAR TO C * OUTPUT TO VDM CALL DSPLY LDA IOBYD LXI H,IBUF SHLD ADDS MVI E,2 NEXT CALL IN8 MOV A,B CPI 'X'-40H ;CTL-X? (DELETES LINE) JNZ CR CALL CRLF JMP READ CR CPI 13 JNZ DEL MOV M,A ;STORE C/R MOV A,E CPI 2 ;NO DATA IN LINE? JZ READ ;JMP IF C/R AND NO DATA READ INX H ISE JUST ORI VDMEP-4 ;..ENSURE ON VDM MOV H,A ;MOVE BACK SVCUR SHLD CURS CURON MVI M,' ' POP H RET ISCR CALL BLANK JMP CKEOS SCRUP PUSH D LXI H,VDMST LXI D,VDMST+40H VDMUP LDAX D MOV M,A INX H INX D MOV A,D CPI VDMEP ;PAST VDM?L SET1 ;ENSURE VDM OK TIOL MOV A,M ;GET FILE NAME BYTE CALL TPOUT ;OUT TO TARBELL CALL DSPLY ;..AND VDM INX H DCR B ;DONE? JNZ TIOL ;NO RET *---> TARBELL INITIALIZE FOR INPUT * READS UNTIL FILE NAME MATCH FOUND TINTI EQU $ MVI A,10H ;TARBSP,AREA+18 ;INIT STACK LXI H,VDMST SHLD CURS LXI H,QUITM CALL SCRN CALL CRLF *---> PRIMARY ENTRY POINT W/O CLEARING FILES CCOS LXI SP,AREA+18 CALL READ ;READ INPUT LIST INX H ;SKIP LENGTH BYTE MOV A,M ;LOAD 1ST CHAR OF COMMAND CPI '9'+1V A,B ;GET IOBYTE ANI 4 ;TTY OUTPUT? MOV A,C ;GET CHAR CNZ TTYO ;TTY OUTPUT MOV A,C ;GET CHAR POP B ;RESTORE BC RET DSPLY PUSH H ;SAVE HL LHLD CURS ;GET CURSOR CPI 0DH ;C/R? JZ ISCR ;..YES CPI 'H'-40H ;BACKSPACE? JNZ NOTBS ;..NO MVT ;GET I/O BYTE MOV B,A ;SAVE IN B * OUTPUT ALTERNATE 1? ANI 1 ;ALT 1 OUTPUT? MOV A,C CNZ ALTO1 ;ALT OUTPUT 1 * OUTPUT ALTERNATE 2? MOV A,B ;GET IOBYTE ANI 2 ;ALT 2 OUTPUT? MOV A,C ;CHAR TO A CNZ ALTO2 ;ALT OUTPUT 2 * OUTPUT TO TTY? MOCKSPACE CHAR CALL OUT8 JMP NEXT CHAR CPI ' ' ;' JC NEXT CPI 80H ;<> JNC NEXT MOV B,A CALL OUT8 ;ECHO MOV M,A MOV A,E ;<> TO ENSURE LINE CPI 80 ;<> ..IS < 80 LONG JZ BSPA INX H INR E JMP NEXT ,'0'-1 BID12 INR M SUB B JNC BID12 ADD B INX H RET VCHK LDA ABUF ORA A JZ WHAT RET *---> DUMP DUMP CALL VCHK MVI A,10H STA SCNT DUMS CALL CRLF LDA BBUF+1 CALL HOUT LDA BBUF CALL HOTB LDA SCNT DUM1 STA DCNT LHLD BBUF VAL2A DCR C JM WHAT STAX D INX D JMP VAL2 VAL3 MVI A,' ' ;' VAL4 DCR C JM DONE STAX D INX D JMP VAL4 DONE CALL SBL2 CMC RNC VAL5 LXI D,ABUF CALL ALPS MOV A,B CPI NL CMC RC LXI B,ABUF CALL AHEX RC SHLD BBUF LXI H, A,M ;GET DATA MVI M,0C9H ;STORE 'RET' OP CODE * BBUF NOW = D3 PP C9 JMP BBUF ;GO 'OUT PP, RET' *---> ROUTINE TO SET I/O BYTE SETIO CALL CRLF LXI H,IOBYT ;POINT TO IOBYTE MOV C,M ;GET OLD IOBYTE LXI D,ISMSG ;'IS ' LDA ABUF ;CHECK PARM ORA T BLK1 MVI B,' ' ;' CALL OUT8 RET ACHK LHLD BBUF LDA BBUF+3 CMP H JNZ ACH1 LDA BBUF+2 CMP L JNZ ACH1 STC ACH1 INX H SHLD BBUF RET SCRN MOV B,M MVI A,0DH CMP B RZ CALL OUT8 INX H JMP SCRN BINH LXI H,HCON BINH2 MOV B,ATCH - BUMP D TO END INCA INX D DCR C JNZ INCA INR C RET *---> ROUTINE TO ZERO A BUFFER ZBUF XRA A LXI D,ABUF+12 MVI B,12 ZBU1 DCX D STAX D DCR B JNZ ZBU1 RET *---> CHECK COMMAND VALUES VALC CALL ETRA JC WHAT RET ETRA LXI H,0 * BLANK AN AREA UNTIL L=A CLER CMP L RZ MVI M,' ' ;' INX H JMP CLER CRLF MVI B,0DH CALL OUT8 RET ;RET W/ NO LF OR DEL *---> EXEC COMMAND EXEC CALL VCHK ;CHECK VALUE CALL CRLF ;C/R LHLD BBUF ;GET ADDR PCHL ;EXEC PROG *---> OUTPUTD H DAD D DAD H SUI '0' CPI 0AH CMC RC MOV E,A MVI D,0 DAD D INX B JMP ADE1 AHEX LXI H,0 AHE1 LDAX B ORA A RZ DAD H DAD H DAD H DAD H CALL AHS1 CPI 10H CMC RC ADD L MOV L,A INX B JMP AHE1 AHS1 SUI '0' ABUF CALL NORM CALL SBLK CMC RNC LXI D,ABUF+4 CALL ALPS MOV A,B CPI 5 CMC RC LXI B,ABUF+4 CALL AHEX RC SHLD BBUF+2 LXI H,ABUF+4 CALL NORM ORA A RET ADEC LXI H,0 ADE1 LDAX B ORA A RZ MOV D,H MOV E,L DAD H DAA ;NONE? JZ IOBTY ;TYPE 'IS XX' LXI D,IOMSG ;GET 'WAS ' MSG LDA BBUF ;GET NEW MOV M,A ;STORE IOBTY XCHG ;MSG ADDR TO HL CALL SCRN ;OUTPUT MSG MOV A,C ;GET OLD IOBYTE JMP HOUT ;OUTPUT IN HEX, RETURN IOMSG DW 'WA' ;'WAS ' MSG DW 'S ' ;S' RAR RAR RAR RAR CALL BIN1 MOV M,A INX H MOV A,B CALL BIN1 MOV M,A RET BIN1 ANI 0FH ADI '0' CPI '9'+1 RC ADI 07H RET BIND LXI H,HCON MVI B,100 CALL BID1 BIND2 MVI B,10 CALL BID1 ADI '0' MOV M,A RET BID1 MVI M SHLD BBUF+2 SHLD FBUF CALL ZBUF LXI H,IBUF-1 VAL1 INX H MOV A,M CPI ' ' ;' CMC RNC JNZ VAL1 SHLD PNTR CALL SBLK CMC RNC CPI '/' ;START OF FILE NAME? JNZ VAL5 LXI D,FBUF MVI C,NL VAL2 INX H MOV A,M CPI '/' JZ VAL3 COMMAND: OUT PORT VAL OUTPU CALL VCHK ;CHECK VALUE CALL CRLF ;C/R * BBUF = PP 00 VV 00 (PP=PORT, VV=VALUE) LXI H,BBUF ;POINT TO PP MOV B,M ;B=PORT MVI M,0D3H ;STORE 'OUT' OP CODE INX H MOV M,B ;STORE OUTPUT ADDR INX H ;POINT TO DATA MOVCPI 0AH RC SUI 07H RET HOUT CALL BINH HOUT1 LXI H,HCON MOV B,M CALL OUT8 INX H MOV B,M CALL OUT8 RET *---> HEX OUT W/BLANK. BC, HL CLOBBERED HOTB CALL HOUT CALL BLK1 RET CALL BIND CALL HOUT1 INX H MOV B,M CALL OUT8 REHR MOV C,A CALL SEAR LDAX D MOV L,A INX D LDAX D MOV H,A RZ INX D DCR B JNZ COMS INR B RET *---> COMPARE RTN, DE TO HL, LENGTH IN C SEAR LDAX D CMP M JNZ INCA INX H INX D DCR C JNZ SEAR RET *---> COMPARE DIDN'T MA DB 13 ;C/R END OF MSG ISMSG DW 'IS' ;'IS ' DB ' ' ;' DB 13 ;END OF MSG *---> COMMAND LOOKUP ROUTINE COMM LXI D,CTAB MVI B,NCOM ;<--- MAX # OF COMMANDS MVI A,4 STA NCHR CALL COMS JNZ WHAT PCHL ;EXECUTE COMMAND COMS LHLD HCON LDA NCMOV A,M DUM2 CALL HOTB CALL QCHEK ;ALLOW CTL-Q CALL ACHK RC LDA DCNT DCR A JNZ DUM1 JMP DUMS *---> PAGE COMMAND PAGE CALL VCHK LDA ABUF+4 ORA A JZ WHAT LHLD BBUF XCHG LHLD BBUF+2 MVI B,0 PAG1 MOV A,E MOV A,D CPI -1 LDAINX H JMP LMOV RMOV LDAX D DCX D CMP C RZ MOV M,A DCX H JMP RMOV LODM MOV B,M INX H MOV C,M INX H MOV D,M INX H MOV E,M RET STOM MOV M,E DCX H MOV M,D DCX H MOV M,C DCX H MOV M,B RET COM0 MVI B,1 MVI C,4 ORR CALL VCHK CALL ENTS JC WHAT CALL CRLF RET ENTS CALL CRLF CALL READ LXI H,IBUF SHLD PNTR ENT1 CALL ZBUF CALL SBLK JC ENTS CPI '/' RZ CALL ALPS MOV A,B CPI 3 CMC RC LXI B,ABUF CALL AP LDAX D MOV B,M MOV M,A MOV A,B STAX D INX D INX H DCR C JNZ SWAP LDA ABUF ORA A JZ FOOT LHLD BBUF SHLD BOFP SHLD EOFP MOV A,L ORA H JZ FIL35 MVI M,1 FIL35 XRA A STA MAXL JMP FOOT FOUT LDA IBUF+4 CPI 'S' MVI CMA INR A MOV D,H MOV E,L CALL ADR XCHG CALL LMOV MVI M,1 SHLD EOFP ZER0 LHLD INSP MVI M,13 INX H LXI D,IBUF-1 MVI C,1 CALL LMOV JMP EOR FIND LXI H,ABUF+3 FIN0 SHLD ADDS FIN1 LHLD BTA FEF POP H POP PSW FSE15 LXI D,8 DAD D XCHG DCR B RZ ; JMP FSE10 FSE20 POP H POP PSW JNZ FSE15 LXI D,-5 DAD D MOV A,D ORA A RET *---> 'WHAT' ERROR MESSAGE PRINT WHAT CALL CRLF WHA1 LXI H,EMES MESS CALX D JNZ PAG2 PAG2 MOV M,A INX H INX D DCR B JNZ PAG1 RET *---> FILE COMMAND FILE CALL CRLF LDA FBUF ORA A JZ FOUT CALL FSEA XCHG JNZ TEST LDA ABUF ORA A JZ WHA1 LDA FEF ORA A JNZ ROOM LXI H,EMES1 JMP MESS TEST LCK SHLD ADDS LXI D,MAXL+3 CALL COM0 JNC INSR INX H CALL LODM LXI H,MAXL+3 CALL STOM LXI D,IBUF-1 LHLD EOFP MVI C,1 CALL LMOV MOV M,C SHLD EOFP JMP EOR INSR CALL FIN1 MVI C,2 JZ AHEX RC MOV A,L LHLD BBUF MOV M,A CALL ACH1 JMP ENT1 *---> SOURCE FILE LINE INPUT ROUTINE LINE MVI C,4 LXI H,IBUF-1 LICK INX H MOV A,M CPI '0' JC WHAT CPI '9'+1 JNC WHAT DCR C JNZ LIC,MAXFL ;MAX FILES JZ FOUL FOOT MVI C,1 FOUL LXI H,FILE0 MOV A,C FINE STA FOCNT PUSH H LXI D,NMLEN DAD D MOV A,M ORA A JNZ FOOD INX H ADD M INX H JNZ FOOD INX SP INX SP INX H INX H JMP FEET FOOD POP H MVI C,NMLEN FAOFP FI1 CALL EO1 XCHG LHLD ADDS XCHG MVI A,4 CALL ADR CALL COM0 RC RZ FI2 MOV A,M CALL ADR JMP FI1 EOF INX H EO1 MVI A,1 CMP M RNZ JMP EOR ADR ADD L MOV L,A RNC INR H RET LMOV LDAX D INX D CMP C RZ MOV M,A L SCRN JMP EOR EMES DB 'W' DB 'H' DB 'A' DB 'T' DB '?' DB 13 EMES1 DB 'F' DB 'U' DB 'L' DB 'L' DB 13 EMES2 DB 'N' DB 'O' DB ' ' DB 'N' DB 'O' DB 13 *---> ENTR COMMAND ENTDA ABUF ORA A JZ SWAPS LHLD BBUF MOV A,H ORA L JZ SWAPS LXI H,EMES2 JMP MESS ROOM LHLD FREAD XCHG LXI H,FBUF PUSH D MVI C,NMLEN MOV23 MOV A,M STAX D INX D DCR C JMP PATCH PRET POP D SWAPS LXI H,FILE0 MVI C,NMLEN+8 SW EQUL DCR C EQUL MOV B,M DCX H MVI M,2 SHLD INSP LDA IBUF-1 DCR C JZ LT SUB B JZ ZER0 JC GT LT LHLD EOFP MOV D,H MOV E,L CALL ADR SHLD EOFP MVI C,2 CALL RMOV JMP ZER0 GTLL HOTB POP H RET FSEA XRA A STA FEF MVI B,MAXFL LXI D,FILE0 FSE10 LXI H,FBUF MVI C,NMLEN CALL SEAR PUSH PSW PUSH D LDAX D ORA A JNZ FSE20 INX D LDAX D ORA A JNZ FSE20 XCHG LXI D,-6 DAD D SHLD FREAD MOV A,D SST MOV B,M CALL OUT8 DCR C INX H JNZ FAST CALL FOOL CALL FOOL CALL CRLF FEET LXI D,4 DAD D LDA FOCNT DCR A JNZ FINE RET FOOL CALL BLK1 INX H MOV A,M DCX H PUSH H CALL HOUT POP H MOV A,M INX H INX H PUSH H CAA A CO1 LDAX D SBB M JZ CO2 INR B CO2 DCX D DCX H DCR C JNZ CO1 DCR B RET MVI C,4 LDAX D SUI 1 JMP CO1+1 NORM CALL LODM XRA A CMP B RZ NOR1 CMP E CNZ STOM RNZ MOV E,D MOV D,C MOV C,B MVI B,'0' JMP NOR1 * ---YP3 CALL ASBL CNZ ERRR MOV A,L RRC CC ERRR RAL CPI 8 CNC ERRR TY31 RLC RAL RAL TY32 MOV B,A LDAX D ADD B CPI 76H CZ ERRR JMP TYP1 TYP4 CALL ASBL TYP4A CNZ ERRR MOV A,L CPI 8 CNC ERRR LDAX D CPI 40H JZ TY41 CPI Z MLAB XCHG SHLD TABA LDA ASPC ;<> FOR COMS MOD MOV M,A INX H LDA ASPC+1 ;<> FOR COMS MOD MOV M,A LXI H,NOLA INR M OPC CALL ZBUF CALL SBLK JC OERR CALL ALPS CPI ' ' ;' JC OPCD JNZ OERR JMP OPCD LCHK LHLD PNTR DELT *** CALL FIND SHLD INSP LXI H,ABUF+7 MOV A,M ORA A JNZ DEL1 LXI H,ABUF+3 DEL1 SHLD ADDS XCHG LXI H,MAXL+3 CALL COM0 LHLD DELP JC NOVR SHLD EOFP MVI M,1 XCHG LHLD BOFP XCHG MVI B,13 DCX H DEL2 MOV A,L SUB E MRG2 JM DAT2 RPO CPI 5 JC RES2 JNZ EASS CALL TYS6 JMP ACO1 RES2 CALL ASBL MOV B,H MOV C,L LHLD BBUF+2 DAD B SHLD BBUF+2 RES21 XRA A JMP OCN2 DAT2 CALL TYS5 DAT21 XRA A MVI C,1 JMP OCN1 ORG2 CALL ASBL LDA OBUF+18 CPI ' LL CLER MVI C,13 CALL LMOV MOV M,C XCHG SHLD APNT LDA PASI ORA A JNZ ASM2 CALL PAS1 JMP ASM1 ASM2 CALL PAS2 LXI H,OBUF CALL AOUT JMP ASM1 AOUT LDA AERR ORA A JNZ AOU1 AOU2 LDA OBUF+18 CPI ' ' ;' RZ AOU1 LXI H,OBUF > LIST COMMAND MODIFIED TO ACCEPT * ENDING LINE NUMBER ALSO LIST CALL CRLF LXI H,-1 ;DFLT ENDING ADDR LDA ABUF+4 ;GET 'TO' LINE NUMBER ORA A ;ANYTHING ENTERED? JZ LNOTO ;..NO 'TO' LINE LXI H,ABUF+7 CALL FIN0 ;FIND LINE LNOTO PUSH H ;SAVE ENDPC LDA IBUF CPI ' ' ;' RZ JMP EQUS EQU1 CALL ASCN LDA IBUF CPI ' ' ;' JZ ERRM EQUS XCHG LHLD TABA MOV M,E ;<> FOR COMS MOD INX H MOV M,D ;<> FOR COMS MOD JMP AOU2 RES1 CALL ASCN MOV B,H MOV C,L JMP RES21 JMP OP2MOV A,M CPI ' ' ;' RZ CPI ':' RNZ INX H SHLD PNTR RET PSU1 CALL SBLK LDAX D ORA A JZ ORG1 JM DAT21 JPO EQU1 CPI 5 JC RES1 JNZ EASS ACO1 MVI C,2 XRA A JMP OCN1 ORG1 CALL ASCN LDA OBUF+18 CPI ' ' ;' RNZ SHLD ASOV A,H SBB D MVI A,13 JC DEL4 DCR B DCX H CMP M JNZ DEL2 DCX H MOV A,L SUB E MOV A,H SBB D JC DEL5 CMP M INX H INX H JZ DEL3 DEL2A INX H DEL3 CALL LODM LXI H,MAXL+3 CALL STOM RET DEL4 CMP B DEL5 XCHG JNZ DEL2A' ;' RNZ XCHG LHLD ASPC XCHG SHLD ASPC MOV A,L SUB E MOV E,A MOV A,H SBB D MOV D,A LHLD BBUF+2 DAD D SHLD BBUF+2 RET TYP1 CALL AST0 RET TYP2 CALL ASBL CNZ ERRR MOV A,L ORA A JZ TY31 CPI 2 CNZ ERRR JMP TY31 TCALL CRLF CALL SCRN RET PAS1 CALL ZBUF STA PASI LXI H,IBUF SHLD PNTR MOV A,M CPI ' ' ;' JZ OPC CPI '*' RZ CALL SLAB JC OP5 JZ ERRD CALL LCHK JNZ OP5 MVI C,5 LXI H,ABUF MLAB MOV A,M STAX D INX D INX H DCR C JN ADDR CALL FIND POP D ;RESTORE END ADDR LIS1 INX H CALL SCRN CALL CRLF CALL EOF CALL QCHEK ;ALLOW CTL-Q EXIT MOV A,D ;END ADDR CMP H ;DONE? JNZ LIS1 ;CONTINUE? MOV A,E CMP L JNZ LIS1 RET * ---> DELT COMMAND DELT CALL VCHK ;*** PAS2 LXI H,OBUF LDA ASPC+1 CALL BINH+3 INX H LDA ASPC CALL BINH+3 SHLD OIND CALL ZBUF LXI H,IBUF SHLD PNTR MOV A,M CPI ' ' ;' JZ OPC CPI '*' RZ CALL SLAB JC ERRL CALL LCHK JNZ ERRL JMP OPC PSU2 LDAX D ORA A JZ OSM5 STA AERR XRA A STA NOLA ASM3 STA PASI LHLD BBUF SHLD ASPC LHLD BOFP SHLD APNT ASM1 LHLD APNT LXI SP,AREA+18 MOV A,M CPI 1 JZ EASS XCHG INX D LXI H,OBUF MVI A,25 ;<> LOAD OBUF LENGTH ADD L ;<> A= '>IBUF-5' CA STA MAXL RET NOVR CALL FI1 CZ FI2 XCHG LHLD DELP MVI C,1 CALL LMOV SHLD EOFP MVI M,1 RET *---> ASSM COMMAND ASSM CALL VCHK LDA ABUF+4 ORA A JNZ ASM4 LHLD BBUF SHLD BBUF+2 ASM4 LDA IBUF+4 CPI 'E' JNZ ASM5 XRA A A0C7H MOV A,L JZ TY31 JM TY32 JMP TY31 TY41 DAD H DAD H DAD H ADD L STAX D CALL MPNT CALL ASCN CNZ ERRR MOV A,L CPI 8 CNC ERRR JMP TY32 TYP5 CPI 6 CZ TY56 CALL AST0 TYS5 CALL ASBL INR A CPI 2 CNC ERRV MOV A,L JASPC ORA A RZ LDA TEMP XCHG PCHL OERR LXI H,ERRO MVI C,3 JMP OCN0 PSEU LXI H,ABUF+4 MOV A,M ORA A JNZ OERR LDA PASI ORA A JZ PSU1 JMP PSU2 SLAB CPI 'A' RC CPI 'Z'+1 CMC RC CALL ALPS LXI H,ABUF SHLD ADDS 'I' DB 0EEH DW 'OR' DB 'I' DB 0F6H DW 'CP' DB 'I' DB 0FEH DW 'IN' DB 0 DB 0DBH DW 'OU' DB 'T' DB 0D3H DW 'MV' DB 'I' DW 6 DW 'JM' DW 'P' DB 0C3H DW 'CA' DW 'LL' DB 0CDH DW 'LX' DW 'I' DB 1 DW 'LD' DW 'ALL CRLF MVI A,1 JMP ASM3 SBLK LHLD PNTR SBL1 MOV A,M CPI ' ' ;' RNZ SBL2 INX H SHLD PNTR JMP SBL1 COND LXI H,ABUF+1 SHLD HCON MVI B,2 CALL COPC RET OTAB DW 'OR' DB 'G' DW 0 DW 'EQ' DW 'U' DB 1 DW 'DB' DW 0 DB 0FFERR ADI 0C0H MOV D,A MVI B,3 LDA ABUF MOV C,A CPI 'R' MOV A,D JZ OP1 MOV A,C INR D INR D CPI 'J' JZ OPAD CPI 'C' JNZ OERR INR D INR D OPAD MOV A,D OP4 LXI H,TYP6 OP5 MVI C,3 OCNT STA TEMP *** MODIFIED 'CHECK OPCODE LE9 DB 0 DW 'IN' DB 'R' DB 4 DW 'DC' DB 'R' DB 5 DW 'MO' DB 'V' DB 40H DW 'AD' DB 'D' DB 80H DW 'AD' DB 'C' DB 88H DW 'SU' DB 'B' DB 90H DW 'SB' DB 'B' DB 98H DW 'AN' DB 'A' DB 0A0H DW 'XR' DB 'A' DB 0AMP TYP1 TY56 CALL ASBL CNZ ERRR MOV A,L CPI 8 CNC ERRR DAD H DAD H DAD H LDAX D ADD L MOV E,A MPNT LHLD PNTR MOV A,M CPI ',' INX H SHLD PNTR JNZ ERRS MOV A,E RET TYP6 CPI 1 JNZ TY6 CALL TY56 ANI 8 CNZ ERRR MODB 0 DB 38H DB 0 COPC LHLD ADDS LDAX D ORA A JZ COP1 MOV C,B CALL SEAR LDAX D RZ INX D JMP COPC COP1 INR A INX D RET OPCD LXI H,ABUF SHLD ADDS LXI D,OTAB MVI B,4 CALL COPC JZ PSEU DCR B CALL COPC JZ OP1 INR A' DB 3AH DW 'ST' DW 'A' DB 32H DW 'SH' DW 'LD' DB 22H DW 'LH' DW 'LD' DB 2AH DB 0 *@320 DW 'NZ' DB 0 DW 'Z' DB 8 DW 'NC' DB 10H DW 'C' DB 18H DW 'PO' DB 20H DW 'PE' DB 28H DB 'P' DB 0 DB 30H DB 'M' H DW 'DS' DW 0 DB 3 DW 'DW' DW 0 DB 5 DW 'EN' DW 'D' DB 6 DB 0 DW 'HL' DB 'T' DB 76H DW 'RL' DB 'C' DB 7 DW 'RR' DB 'C' DB 0FH DW 'RA' DB 'L' DB 17H DW 'RA' DB 'R' DB 1FH DW 'RE' DB 'T' DB 0C9H DW 'NGTH' ROUTINE *** MOD'D BECAUSE NO '<' AND '>' FUNCTIONS *** AVAILABLE IN THIS ASSEMBLER LXI D,ABUF MOV A,E ADD B MOV E,A MOV A,D ACI 0 MOV D,A LDAX D ORA A JNZ OERR OCN0 LDA PASI OCN1 MVI B,0 XCHG OCN2 LHLD ASPC DAD B SHLD 8H DW 'OR' DB 'A' DB 0B0H DW 'CM' DB 'P' DB 0B8H DW 'RS' DB 'T' DB 0C7H DB 0 DW 'AD' DB 'I' DB 0C6H DW 'AC' DB 'I' DB 0CEH DW 'SU' DB 'I' DB 0D6H DW 'SB' DB 'I' DB 0DEH DW 'AN' DB 'I' DB 0E6H DW 'XR' DBV A,E ANI 0F7H TY6 CALL AST0 TYS6 CALL ASBL MOV A,L MOV D,H CALL AST0 MOV A,D CALL TYP1 RET AST0 LHLD BBUF+2 MOV M,A INX H SHLD BBUF+2 LHLD OIND INX H INX H CALL BINH+3 SHLD OIND RET EASS LDA PASI ORA A JNZ EOR CB CALL COPC OP1 LXI H,TYP1 OP2 MVI C,1 JZ OCNT CALL COPC LXI H,TYP2 JZ OP2 CALL COPC LXI H,TYP3 JZ OP2 DCR B CALL COPC LXI H,TYP4 JZ OP2 CALL COPC LXI H,TYP5 MVI C,2 JZ OCNT INR B CALL COPC JZ OP4 CALL COND JNZ O DW 'HL' DB 0F9H DW 'PC' DW 'HL' DB 0E9H DB 0 DW 'ST' DW 'AX' DB 2 DW 'LD' DW 'AX' DB 10 DB 0 DW 'PU' DW 'SH' DB 0C5H DW 'PO' DW 'P' DB 0C1H DW 'IN' DW 'X' DB 3 DW 'DC' DW 'X' DB 0BH DW 'DA' DW 'D' DB CM' DB 'A' DB 2FH DW 'ST' DB 'C' DB 37H DW 'DA' DB 'A' DB 27H DW 'CM' DB 'C' DB 3FH DW 'EI' DB 0 DB 0FBH DW 'DI' DB 0 DB 0F3H DW 'NO' DW 'P' DB 0 DW 'XC' DW 'HG' DB 0EBH DW 'XT' DW 'HL' DB 0E3H DW 'SP' DCR B JNZ SLA1 INR B LXI D,RTAB CALL COPC JNZ SLA1 MOV L,A MVI H,0 JMP SLA2 SLA1 LDA NOLA MOV B,A LXI D,SYMT ;<----- ONLY REFERENCE ORA A ;..TO THE SYMBOL TABLE JZ SLA3 MVI A,LLAB STA NCHR CALL COMS SLA2 STC CMC RET XO MOV A,L JMP XO VDONE LXI H,VMSG *---> LINER - MESSAGE OUTPUT W/ C/R LINER CALL SCRN ;OUTPUT TO C/R JMP TYPE ;OUTPUT FINAL C/R VMSG DW 'A-' DW 'OK' DB 13 RET1 MVI A,13 JMP TYPE *---> PRINT COMMAND PRINT CALL RET1 LHLD FILE0+5 PNLP CX2 ANI 0FH CPI 10 JC X2B ADI 7 X2B ADI 30H JMP TYPE *---> HEX OUTPUT SUBROUTINE XO PUSH 6 CALL X1 POP 6 JMP X2 *---> RENUM COMMAND RENUM CALL CRLF LXI H,0 SHLD BBUF SHLD BBUF+2 LHLD FILE0+5 RELP MOV A,M DCR A JZ RPRT CALL SEND CPI '+' JZ ASC1 CPI '-' JNZ ASC2 STA SIGN ASC1 LDA OPRI CPI 2 JZ ERRS MVI A,2 STA OPRI JMP NXT2 ASC2 MOV C,A LDA OPRI ORA A JZ ERRS MOV A,C CPI '$' JNZ ASC3 INX H SHLD PNTR LHLD ASPC JMP AVAL ASC3 CPI '''' ,M DCR A JZ VDONE INR A MOV B,A ;B = LINE COUNT CALL QCHEK ;CHECK FOR CTL-Q INX H DCR B MVI C,4 ;LINE # COUNT VNUM MOV A,M CPI '9'+1 JNC VBAD CPI '0' JC VBAD CALL TYPE INX H DCR B DCR C JNZ VNUM MVI A,' ' ;' CALL TYPEVI A,'R' ERRR1 LXI H,0 STA OBUF+18 RET ERRS MVI A,'S' ERRS1 STA OBUF+18 LXI H,0 JMP SEN1 ERRU MVI A,'U' JMP ERRS1 ERRV MVI A,'V' JMP ERRR1 ERRM MVI A,'M' STA OBUF+18 CALL AOU1 RET ERRA MVI A,'A' JMP ERRS1 ERRO MVI A,'O' ERRO1 SSLA3 INR A ORA A RET RTAB DB 'A' DB 7 DB 'B' DB 0 DB 'C' DB 1 DB 'D' DB 2 DB 'E' DB 3 DB 'H' DB 4 DB 'L' DB 5 DB 'M' DB 6 DB 0 ALPS MVI B,0 ALP1 STAX D INR B MOV A,B CPI 0BH RNC INX D INX H SHLD PNTR ,A STAX B INX H DCX D INX B MOV A,C CPI 0DH JNZ REMVL POP D MVI D,0 DAD D LXI D,-5 DAD D JMP RELP RPRT LXI B,0 SHLD FILE0+7 LHLD FILE0+5 RLOOP MOV A,M DCR A JZ RNDUN ORA A MOV A,C INR A DAA MOV C,A MOV A,B QCHEK ;ALLOW CTL-Q EXIT * BUMP LINE # LXI D,BBUF+1 ;POINT TO 10'S DIGIT REIN LDAX D INR A STAX D CPI 10 JNZ REEND XRA A STAX D INX D JMP REIN REEND LXI D,BBUF+3 MOV C,M INX H PUSH B LXI B,FILE0+9 REMVL LDAX D ORI '0' MOV MJNZ ASC5 LXI D,0 MVI C,3 ASC4 INX H SHLD PNTR MOV A,M CPI 13 JZ ERRA CPI '''' JNZ SSTR INX H SHLD PNTR MOV A,M CPI '''' JNZ AVAL1 SSTR DCR C JZ ERRA MOV D,E MOV E,A JMP ASC4 ASC5 CPI '0' JC ERRA CPI '9'+1 JNC ALAB V0005 XRA A ORA B JP V0010 JMP VBAD V0010 MOV A,M CPI ' ' ;' JC CHECK ANI 80H JNZ VBAD INX H DCR B JZ VBAD JMP V0010 CHECK CPI 13 JNZ VBAD INX H DCR B JNZ VBAD DCR D JNZ VLINE CALL RET1 JMP V1 VBAD MOV A,H CALL TA OBUF+18 LDA PASI ORA A RZ MVI C,3 ERO1 XRA A CALL AST0 DCR C JNZ ERO1 RET ERRL MVI A,'L' JMP ERRO1 ERRD MVI A,'D' STA OBUF+18 CALL AOU1 JMP OPC PATCH INX H JNZ MOV23 JMP PRET * HEX SUBROUTINES X1 RAR RAR RAR RAR MOV A,M CPI '0' RC CPI ':' JC ALP1 CPI 'A' RC CPI 'Z'+1 JC ALP1 RET ASBL CALL SBLK ASCN LXI H,0 SHLD OPRD INR H SHLD OPRI-1 NXT1 LHLD PNTR DCX H CALL ZBUF STA SIGN NXT2 INX H MOV A,M CPI ' '+1 JC SEND CPI ',' JZ ACI 0 DAA MOV B,A MOV E,M MVI D,0 DAD D JMP RLOOP RNDUN MOV A,B CALL XO MOV A,C CALL XO LXI H,RMSG JMP LINER RMSG DW ' L' ;' DW 'IN' DW 'ES' DB 13 *---> VERIFY COMMAND VERIF CALL CRLF LHLD FILE0+5 V1 MVI D,12 VLINE MOV AND LDA OPRI ORA A JNZ ERRS LHLD OPRD SEN1 MOV A,H LXI D,TEMP ORA A RET NUMS CALL ALPS DCX D LDAX D LXI B,ABUF CPI 'H' JZ NUM2 CPI 'D' JNZ NUM1 XRA A STAX D NUM1 CALL ADEC RET NUM2 XRA A STAX D CALL AHEX RET ERRR M CALL NUMS JC ERRA AVAL XCHG AVAL1 LHLD OPRD XRA A STA OPRI LDA SIGN ORA A JNZ ASUB DAD D ASC7 SHLD OPRD JMP NXT1 ASUB MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A JMP ASC7 ALAB CALL SLAB JZ AVAL JC ERRA JMP ERRU SEALL QCHEK ;ALLOW CTL-Q EXIT MOV A,M DCR A ;EOF? RZ ;..YES LXI D,5 DAD D PLOOP MOV A,M CALL TYPE MOV A,M INX H CPI 13 JNZ PLOOP JMP PNLP *---> HEX OUTPUT W/BLANK XOB CALL XO MVI A,' ' ;' JMP TYPE *---> OBJECT SAVE ROUTINE TO ELP EQU INSP ;DELT LINE POSITION APNT EQU INSP ;ASSEMBLE LINE POINTER ASCR EQU 13 ;ASCII C/R HCON DS 2 ;HEX BYTE WORK AREA ADDS EQU HCON ;FIND ADDRESS FBUF DS NMLEN ;FILE NAME BUFFER FREAD DS 2 ;FREE ADDR IN DIRECTORY FEF DS 1 ;FREE ENTRY FOUND FLAGB 'C' DW EXEC DB 'F' DB 'I' DB 'L' DB 'E' DW FILE DB 'L' DB 'I' DB 'S' DB 'T' DW LIST DB 'D' DB 'E' DB 'L' DB 'T' DW DELT DB 'A' DB 'S' DB 'S' DB 'M' DW ASSM DB 'P' DB 'A' DB 'G' DB 'E' DW PAGE DB 'R' ALL XO CALL TPINC MOV E,A CALL XO JMP OLCON OLNO LHLD BBUF LXI D,-1 OLCON PUSH H ;PGM START OLRD CALL TPINC MOV M,A INX H CALL QDEHL JNZ OLRD CALL TPIN ;CKSUM XRA B JNZ BADCS LDA IBUF+5 CPI 'X' RZ POP H RET BADCS LXI HN * * THE 'COMM' ROUTINE STATEMENT* * 'MVI A,NCOM' IS BIG ENOUGH * * FOR ALL THE COMMANDS YOU * * HAVE. * * * * * * * * * * * * * * * * * *@3C0 * PROCESSOR TECH WORK AREA ORG WORKA ;TO WORK AREA LLAB EQU 5 ;LABEL LENGTSMOVE RET SLP0 INX H SHLD BBUF SLLP CALL TPINC MOV M,A CALL DSPLY MOV A,M INX H CPI 13 JZ SLINE JMP SLLP *---> SET - SET CURSOR SO NO SCROLL SET1 LDA CURS+1 ;GET PAGE ANI VDMEP-1 ;ENSURE ORI VDMEP-4 ;..ON VDM STA CURS+1 ;STORE BTARBELL OSAVE CALL RET1 CALL TINTO LHLD BBUF+2 INX H XCHG LHLD BBUF MVI B,0 ;CKSUM * OUTPUT START, END ADDRESS MOV A,H CALL TPOTC MOV A,L CALL TPOTC MOV A,D CALL TPOTC MOV A,E CALL TPOTC OSLP MOV A,M CALL TPOTC INX H CA 'U' DW RENUM DB 'V' DB 'E' DB 'R' DB 'I' DW VERIF DB 'P' DB 'R' DB 'I' DB 'N' DW PRINT DB 'I' DB 'O' DB 'B' DB 'Y' DW SETIO ;SET I/O BYTE DB 'O' DB 'U' DB 'T' DB ' ' ;' DW OUTPU * * * * * * * * * * * * * * * * * DB 'E' DB 'N' DB 'U' DW RENUM DB 'S' DB 'L' DB 'O' DB 'A' DW SLOAD DB 'S' DB 'S' DB 'A' DB 'V' DW SSAVE DB 'O' DB 'L' DB 'O' DB 'A' DW OLOAD DB 'O' DB 'S' DB 'A' DB 'V' DW OSAVE DB 'R' DB 'E' DB 'N' DB,CSMSG CALL LINER POP H RET CSMSG DW 'CK' DW 'SU' DB 'M' DB 13 QDEHL MOV A,H CMP D RNZ MOV A,L CMP E RET *---> TARBELL SOURCE SAVE ROUTINE SSAVE CALL RET1 CALL TINTO LHLD FILE0+5 MVI B,0 ;CKSUM SSLIN CALL SET1 ;CURSOR MOVH NL EQU 5 NMLEN EQU 5 MAXFL EQU 6 ;MAX NUMBER OF FILES FILE0 DS NMLEN ;FILE NAME BOFP DS 2 ;BEGIN. OF FILE POINTER EOFP DS 2 ;END OF FILE POINTER MAXL DS 4 ;MAX LINE NUMBER FILTB DS 40+NL+NL+NL+NL+NL ;5 MORE FILES INSP DS 2 ;ISRT LINE POSITION DACK CPI VDMEP-1 ;BOTTOM LINE? RC ;NO MVI A,VDMEP-4 STA CURS+1 ;BACK TO VDM TOP RET * * * * * COMMAND TABLE * * * * * CTAB DB 'D' DB 'U' DB 'M' DB 'P' DW DUMP DB 'E' DB 'N' DB 'T' DB 'R' DW ENTR DB 'E' DB 'X' DB 'E' DLL QDEHL JNZ OSLP MOV A,B CALL TPOUT ;CKSUM RET *---> TARBELL OBJECT LOAD OLOAD CALL RET1 CALL TINTI MVI B,0 ;CKSUM LDA IBUF+5 CPI 'N' JZ OLNO CALL TPINC MOV H,A CALL XO CALL TPINC MOV L,A CALL XOB CALL TPINC MOV D,A C ADD YOUR OWN COMMANDS HERE * * * * * * * * * * * * * * * * * * JUST PUT IN A 4 BYTE ASCII * * COMMAND, FOLLOWED BY IT'S 2 * * BYTE ADDRESS, WITH THE LOW * * BYTE OF THE ADDRESS FIRST, * * THEN THE HIGH BYTE. BE SURE* * THE NUMBER OF COMMANDS IINE CALL SET1 ;CURSOR CALL TPINC MOV M,A DCR A JNZ SLP0 SHLD FILE0+7 CALL TPIN PUSH H XRA B JNZ BADCS POP H LHLD BBUF ;START OF LAST LINE LXI D,FILE0+9 ;HI LINE # ADDR MVI C,4 SMOVE MOV A,M STAX D INX H INX D DCR C JNZ A,M CALL TPOTC INX H DCR A JNZ SSLP MOV A,B CALL TPOUT RET SSLP MOV A,M CALL TPOTC CALL DSPLY MOV A,M INX H CPI 13 JZ SSLIN JMP SSLP *---> TARBELL SOURCE LOAD ROUTINE SLOAD CALL RET1 CALL TINTI LHLD FILE0+5 MVI B,0 SL FOCNT EQU FEF ;OUTPUT COUNTER ABUF DS 12 ;ASCII BUFFER BBUF DS 4 ;BINARY BUFFER SCNT DS 1 AERR EQU SCNT ;ASSM ERR PRT SWITCH DCNT DS 1 ;DUMP ROUTINE COUNTER NCOM EQU 20 ;NUMBER OF COMMANDS TABA DS 2 ;SYMBOL TABLE END ADDR ASPC DS 2 ;ASSEMBLER PROB,A ;SAVE CHAR READ CALL READ2 CMP B ;SAME? JZ COMPARE ; ;UNEQUAL COMPARE ; LXI D,UNEQ$MSG CALL PRINT$MESSAGE LHLD SECTOR$COUNT CALL PRINT$HEX$HL LXI D,BYTE$MSG CALL PRINT$MESSAGE LDA BUFAD1 ;GET FIRST BUFF ADDR SUI 80H ;SUBTRACT BEQU 16 ; " " SRCHF EQU 17 ; " " SRCHN EQU 18 ; " " DELT 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 BDOS EQU 5 FCB EQU 5CH ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее ; ;10/01/77 ORIGINALLY WRITTEN ; ORG 100H CALL START ;PRINT ID MESSAGE DB 'COMPARE.COM AS OF 10/01/77',0DH,0AH,'$' START POP D CALL PRINT$MESSAGE ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=CP/M'S STACK SHLD STACK ;SAVE IT LXI SP,STAC EOF CALL ERXIT DB 0DH,0AH,'++EOF$' XOB PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW CALL NIBBL MVI A,' ' CALL TYPE RET NIBBL ANI 0FH CPI 10 JC ISNUM ADI 7 ISNUM ADI '0' TYPE PUSH B PUSH D PUSH H MOV E,A MVI C,WRCON GRAM COUNTER PASI DS 1 ;ASSEMBLER PASS INDICATOR NCHR DS 1 ;LENGTH OF STR FOR COMPARE PNTR DS 2 ;LINE POINTER NOLA DS 1 ;NUMBER OF LABLES SIGN DS 1 ;SIGN STORAGE FOR SCAN OPRD DS 2 ;OPERAND STORAGE OPRI DS 1 ;OPERAND FOUND INDICATOR TEMP DS 1 OINDееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее;CHECKSUM ANY CP/M FILE ORG 100H JMP START ID DB 'CKSUM AS OF 7/20/77',0DH,0AH,'$' ;INIT LOCAL STACK START LXI H,0 DAD SP SHLD STACK LXI SP,STACK ;PRINT ID MESSAGE LXI D,ID MVI C,PRINT CALL BDOS ;OPEN THE FILE LXI D,FCB MVI C,OPEN K ;USE MY OWN ; ;MOVE THE SECOND FCB SO OPENING THE FIRST ;WON'T WIPE IT OUT ; CALL MOVE$FCB ; ;OPEN BOTH FILES, EXITING IF EITHER DOESN'T EXIST ; CALL OPEN$FILES ; ;READ EACH FILE 1 BYTE AT A TIME, COMPARING THEM ; COMPARE CALL READ1 MOV CALL BDOS POP H POP D POP B RET ;FILE READ FREAD LXI D,FCB MVI C,READ CALL BDOS RET ;PROG SHOULD CHECK STAT DS 30 STACK DS 2 ; ; BDOS EQUATES (VERSION 3) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 OPEN EQU 15 ;0FFH=NOT FOUND CLOSE DS 2 ;OUTPUT ADDRESS AREA DS 18 ;STACK POINTER AREA OBUF DS 25 ;HEX ASM OBJECT OUTPUT DS 5 ;LINE # GOES HERE IBUF DS 83 ;INPUT BUFFER SYMT EQU $ ;START OF SYMBOL TABLE END ; * * * * * * * * * * * * * * * * * * * * * * * * ; * ; COMPARE.ASM * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * ; ;USED TO COMPARE 2 CP/M PROGRAMS ON DISK ; ;IF SENSE SWITCH A8 (01H) UP, PRINTS FILE 1 ;AS IT IS BEING READ LOOP PUSH B ;SAVE DIGIT COUNT CALL FREAD ORA A JNZ CKERR LXI H,80H XRA A CKSLP ADD M INR L JNZ CKSLP CALL XOB POP B DCR B JNZ LOOP JMP LINE ;NON-ZERO DISK RETURN CODE CKERR DCR A JZ EOF CALL ERXIT DB '*++DISK READ ERROR$' CALL BDOS INR A JNZ LINE CALL ERXIT DB '++FILE NOT FOUND$' ERXIT POP D ;GET MSG MVI C,PRINT CALL BDOS EXIT LHLD STACK SPHL ;RESTORE STACK RET ;OPENED OK LINE MVI A,0DH CALL TYPE MVI A,0AH CALL TYPE MVI B,16 ;# OF HEX PER LINEIAS CALL XO ;PRINT IN HEX EXIT LHLD STACK ;GET CP/M'S STACK SPHL ;RESTORE IT RET ;..AND RETURN ; ERXIT POP D ;GET MESSAGE CALL PRINT$MESSAGE JMP EXIT ; UNEQ$MSG: DB 0DH,0AH,'++FILES UNEQUAL IN SECTOR $' BYTE$MSG: DB 'AT BYTE $' ; * * CBIOS EQU SYSSIZ*1024-512 ; * SELDSK EQU CBIOS+1BH ; * SETTRK EQU SELDSK+3 ; * SETSEC EQU SETTRK+3 ; * SETDMA EQU SETSEC+3 ; * RDSEC EQU SETDMA+3 ; * WRSEC EQU RDSEC+3 ; * ; * * * * * * * * * * * * * * * * * * * * * * * * HLD BUFAD2 XCHG ;TO DE MVI C,STDMA PUSH B ;SAVE CHAR FROM FILE 1 CALL BDOS LXI D,FCB2 MVI C,READ CALL BDOS POP B ORA A JNZ EOF$FILE$2 NO$READ$2: LHLD BUFAD2 MOV A,M ;GET CHAR INX H ;POINT TO NEXT SHLD BUFAD2 ;SAVE BACK RET ISNUM ADI 7 ISNUM ADI '0' JMP TYPE ; OPEN$FILES: LXI D,FCB MVI C,OPEN CALL BDOS INR A ;OPEN OK? JNZ FILE$1$OPEN CALL ERXIT DB '++CAN''T OPEN FILE 1 ',0DH,0AH,'$' FILE$1$OPEN: LXI D,FCB2 MVI C,OPEN CALL BDOS INR A RNZ CALL * * * * * ; * ;BDOS/CBIOS EQUATES (VERSION 5) * ; * RDCON EQU 1 ; * WRCON EQU 2 ; * PRINT EQU 9 ; * OPEN EQU 15 ;0FFH=NOT FOUND * CLOSE EQU 16 ; " " * SRCHF EQU 17 ; " " * SRCHN EQU 18 ; " " * ERASE EQU 19 ;NO RET CO SHOWHEX MVI A,'(' CALL TYPE MOV A,L ;GET CHAR CALL XO MVI A,')' SHOWA CALL TYPE MOV A,L ;GET CHAR RET SHOWIT MOV A,L ;GET CHAR JMP SHOWA RET ; ;GOT EOF ON FILE 1 - SHOULD GET EOF ON FILE 2 ; EOF$FILE$1: MVI A,1 ;GET FLAG STA EOF * * * * * * * * * * * * * * * * * * * * * * ; * ; SUBROUTINES * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * PRINT$MESSAGE: MVI C,PRINT JMP BDOS ;PRINT, RETURN ; PRINT$HEX$HL: MOV A,H CALL XO MOV A,L CALL XO MVI XIT DB '(HEX) SECTORS',0DH,0AH,'$' MATCH$MSG: DB 0DH,0AH,'FILES MATCH, LENGTH IS $' ; MOVE$FCB: LXI H,FCB2 LXI D,FCB+16 MVI B,16 ;FCB LENGTH MOVEIT LDAX D MOV M,A INX D INX H DCR B JNZ MOVEIT RET ; DS 40 ;STACK AREA STACK DS 2; EOF$FILE$2: ;SHOULD HAVE EOF ON 1, THUS EOF$FLAG SHOULD BE ON LDA EOF$FLAG ORA A ;ON? JNZ A$OK CALL ERXIT DB 0DH,0AH,'++EOF ON FILE 2 BEFORE FILE 1$' A$OK LXI D,MATCH$MSG CALL PRINT$MESSAGE LHLD SECTOR$COUNT CALL PRINT$HEX$HL CALL ER ERXIT DB '++CAN''T OPEN FILE 2',0DH,0AH,'$' ; READ1: LHLD BUFAD1 ;TIME TO READ? DCR H ;AT 100H? JNZ NO$READ$1 ; ;PHYSICALLY READ FILE 1 ; LXI H,80H ;BUFFER ADDR SHLD BUFAD1 XCHG ;TO D,E MVI C,STDMA CALL BDOS LXI D,FCB MVI C,READE * DELT EQU ERASE ; * 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 ; * BDOS EQU 5 ; * FCB EQU 5CH ; * SYSSIZ EQU 24 ;SYSTEM SIZE * $FLAG CALL READ2 ;SHOULD NOT RETURN CALL ERXIT DB 0DH,0AH,'++EOF ON FILE 1, NOT FILE 2$' ; READ2: LHLD BUFAD2 ;GET SECOND BUFF MOV A,L ;GET ADDR CPI (BUF2+128) AND 0FFH ;END? JNZ NO$READ$2 ; ;DO PHYSICAL READ ON FILE 2 ; LXI H,BUF2 SA,' ' ;FALL INTO 'TYPE' ; TYPE: PUSH B PUSH D PUSH H MOV E,A ;AS REQ'D BY CP/M MVI C,WRCON CALL BDOS POP H POP D POP B RET ; XO PUSH PSW ;HEX OUT RAR RAR RAR RAR CALL NIBBL ;LEFT NIBBL POP PSW NIBBL ANI 0FH CPI 10 JC SECTOR$COUNT: DW 0 EOF$FLAG: DB 0 ;=1 IF EOF FILE 1 FCB2 DB 0,'XXXXXXXXYYY',0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BUFAD1 DW 80H+128 ;INIT TO READ FIRST BUFAD2 DW BUF2+128 ;LIKEWISE BUF2 DS 128 ; ; * * * * * * * * * * * * * * * * * * *? MOV A,L ;RESTORE CHAR FOR RET RZ ;RET IF NO PRINT REQ ;SHOW THE CHARACTER CPI 0DH ;C/R? JZ SHOWIT CPI 0AH ;L/F? JZ SHOWIT CPI 9 ;TAB? JZ SHOWIT CPI ' ' ;PRINTABLE? JC SHOWHEX ;HEX IF NOT PRINTABLE CPI 7FH JC SHOWIT ;SHOW IN HEXD CALL BDOS ORA A ;OK? JNZ EOF$FILE$1 LHLD SECTOR$COUNT INX H SHLD SECTOR$COUNT NO$READ$1: LHLD BUFAD1 MOV A,M ;GET CHAR INX H ;POINT TO NEXT SHLD BUFAD1 ; ;REQUEST TO PRINT? ; MOV L,A ;SAVE CHAR IN 0FFH ;READ SSW ANI 1 ;PRINT ORG 0F000H ; CUTS SOURCE ; R.J.S. 08/27/77 ; START MOV A,A INIT JMP STRTA RETRN JMP COMND FOPEN JMP BOPEN FCLOS JMP PCLOS RDBYT JMP RTBYT WRBYT JMP WTBYT RDBLK JMP RTAPE WRBLK JMP WTAPE ; SOUT LDA OPORT AOUT JMP OUTPR SINP LDA IPORT AINP LHLD DFLTS SHLD IPORT COMN1 EQU $ XRA A OUT TAPPT ; ; COMMAND MODE ; ; PROCESS COMANDS ; COMND LXI SP,SYSTP CALL PROMPT CALL GCLIO CALL COPRC JMP COMND ; READS COMMAND LINE GCLIO EQU $ LXI H,INLIN-1 MVI M,7 INX H SHLD INPTR SCREEN ADDR VDADD LDA NCHAR MOV C,A VDAD2 LDA LINE VDAD MOV L,A LDA BOT ADD L RRC RRC MOV L,A ANI 3 ADI VDMEM1 MOV H,A MOV A,L ANI 0C0H ADD C MOV L,A RET ; ROUTINT TO REMOVE CURSOR CREM CALL VDADD MOV A,M ANI 07FH MOVIPRT JMP ERRO1 ERROT EQU $ PUSH H LHLD UOPRT ERRO1 EQU $ MOV A,L ORA H JNZ DISP1 JMP STRTD ; ; VDMO1 EQU $ PUSH H PUSH D PUSH B ; LDA ESCFL ORA A JNZ ESCS MOV A,B ANI 7FH MOV B,A JZ GOBK LXI H,TBL CALL TSRCH GOBH H XRA A ARET2 STA ESCFL RET ; RET PRESENT SCREEN PARAMETERS IN BC CURET LXI H,NCHAR MOV B,M INX H MOV C,M JMP ARET1 ; ; START UP SYSTEM ; STRTA XRA A MOV C,A LXI H,DFLTS CLERA MOV M,A INX H INR C JNZ CLERA ; DETERMINE DEFAURAS1 EQU $ MVI M,' ' INX H MOV A,H CPI 0D0H JC ERAS1 STC PHOME EQU $ MVI A,0 STA LINE STA NCHAR RNC ERAS3 OUT DSTAT STA BOT RET CLIN2 EQU $ LDA OPORT ORA A RNZ CLINE CALL VDADD LDA NCHAR CLIN1 CPI 64 RNC MVI M,' ' EQU $ ; PUSH H LXI H,ITAB IOPRC ANI 3 RLC ADD L MOV L,A JMP DISPT ; OUTPR EQU $ PUSH H LXI H,OTAB JMP IOPRC ; KREA1 EQU $ IN STAPT CMA ANI KDR RZ IN KDATA RET ; SREA1 EQU $ IN STAPT ANI SDR RZ IN SDATA ANI 7FCFL RET ; PROCESS ESCAPE SEQUENCE ESCS CALL CREM CALL ESCSP JMP GOBACK ESCSP LDA ESCFL CPI -1 JZ SECOND ; PROCESS THIRD CHR OF ESC SEQUENCE LXI H,ESCFL MVI M,0 CPI 2 JC SET1X JZ SET1Y CPI 8 JZ STSPD CPI 9 JC OCHAR RNZ ; T M,A RET ; ROUTINE TO BACKKSPACE PBACK CALL PLEFT CALL VDADD MVI M,' ' RET ; PROCESS CARRIAGE RETURN PCR CALL CLINE JMP PCUR ; PROCESS LF PLF LDA LINE INR A ANI 15 JNZ CUR JMP SROL ; SET1 ESCAPE PROCESS FLAG PESC MVI A,-1 STA ESACK EQU $ CALL VDADD MOV A,M ORI 80H MOV M,A LHLD SPEED-1 INR L XRA A TIMER DCX H CMP H JNZ TIMER GOBK POP B POP D POP H RET ; NEXT EQU $ INX H INX H ; TSRCH MOV A,M ORA A JZ CHAR CMP B INX H JNZ NEXT PUSH H LT PORTS IN SENSE MOV B,A ANI 3 STA DFLTS+1 ORA A JNZ STRTB LXI SP,SYSTP CALL PERSE STRTB EQU $ LXI H,0 CPI 3 JZ STRTC SHLD UOPRT STRTC EQU $ MOV A,B RAR RAR ANI 3 STA DFLTS CPI 3 JZ STRTD SHLD UIPRT STRTD EQU $ INX H INR A JMP CLIN1 ; ROUT TO MOVE CURSOR UP 1 LINE PUP LDA LINE DCR A JMP CURSC ; MOVE CUR LEFT 1 PLEFT LDA NCHAR DCR A PCUR EQU $ ANI 03FH STA NCHAR RET ; CURSOR RIGHT 1 PRIT LDA NCHAR INR A JMP PCUR ; ROUTINE TO CALCULATE H RET ; SEROT EQU $ IN STAPT RAL JC SEROT MOV A,B OUT SDATA RET ; PARIT EQU $ IN STAPT CMA ANI PDR RZ IN PDATA RET ; PAROT EQU $ IN STAPT ANI PXDR JNZ PAROT MOV A,B OUT PDATA RET ; ERRIT EQU $ PUSH H LHLD UAB ABSOLUTE TO VALUE IN REG B SET1X MOV A,B JMP PCUR ; SET1 CUR TO LINE "B" SET1Y MOV A,B JMP CURSC ; PROC SECOND CHR OF ESC SEQUENCE SECOND MOV A,B CPI 3 JZ CURET CPI 4 JNZ ARET2 ARET MOV B,H MOV C,L ARET1 POP H POP D PUSH B PUS1 LDA BOT INR A ANI 0FH JMP ERAS3 ;INCREMENT LINE COUNTER IF NECESSARY OK LDA NCHAR INR A ANI 03FH STA NCHAR RNZ PDOWN EQU $ LDA LINE INR A CURSC ANI 0FH CUR STA LINE RET ;ERASE LINE PERSE LXI H,VDMEM MVI M,80H+' ' INX H ECALL CREM XTHL JMP DISPT ; CHAR EQU $ MOV A,B CPI 7FH RZ ; OCHAR CALL VDADD MOV M,B LDA NCHAR CPI 63 JC OK LDA LINE CPI 15 JNZ OK ; END OF SCREEN-ROLL UP 1 SCROLL XRA A STA NCHAR SROL MOV C,A CALL VDAD XRA A CALL CLIN MVI M,80 GCLI1 EQU $ MVI M,' ' INX H DCR A JNZ GCLI1 GCLIN CALL SINP JZ GCLIN ANI 7FH JZ STRTD MOV B,A CPI CR JZ CLIN2 CPI LF RZ LHLD INPTR CPI 7FH JNZ GCLI2 MVI B,BACKS DCX H MVI A,'G'-40H CMP M JNZ GCLI3 MOV XCHG ERR2 MVI M,'?' LDA OPORT ORA A JZ COMND CALL CRLF MVI B,'?' CALL SOUT JMP COMND ; NFIL MVI M,0 INX H DCR B JNZ NFIL CPI '/' MVI A,1 JNZ DEFLT INX D CALL SCHR SUI '0' DEFLT EQU $ ANI 1 MVI A,TAPE1 JNZ STUNT R DCR C RZ JMP SCHR1 ; SCONV CALL SBLK JZ ERR1 ; ASCII TO BINARY SHEX LXI H,0 SHE1 LDAX D CPI 20H RZ CPI '/' RZ CPI ':' RZ HCONV DAD H DAD H DAD H DAD H CALL HCOV1 JNC ERR1 ADD L MOV L,A INX D JMP SHE1 HCOV1 SUI 48Z NCOM POP H ORA A RET NCOM INX D INX D INX D POP H JMP FDCOM ; SET1 UP TO PROCESS INPUT LINE STUP EQU $ LXI H,INLIN SHLD INPTR LDA OPORT ORA A RNZ CALL CREM MVI C,1 JMP VDAD2 ; COMMAND TABLE COMTAB EQU $ DB 'DU' DW D ENLOP CALL CRLF MVI B,':' CALL SOUT CALL GCLIO CALL STUP XCHG ENLO1 MVI C,3 CALL SCHR1 JZ ENLOP CPI '/' JZ COMND CALL SHEX CPI ':' JZ ENLO3 MOV A,L POP H MOV M,A INX H PUSH H JMP ENLO1 ENLO3 XTHL INX D JMP ENLO1 ET1TY DB 'N=' DW SET1NU DB 'CR' DW SET1CR DB 0 ; OUT A CR FOLLOWED BY PROMPT PROMPT CALL CRLF MVI B,'>' JMP SOUT CRLF MVI B,LF CALL SOUT MVI B,CR CALL SOUT LDA NUCNT MOV C,A NULOT DCR C RM XRA A CALL OUTH JMP NULOT ; SCB,A GCLI2 EQU $ MOV M,B INX H GCLI3 EQU $ SHLD INPTR CONT CALL SOUT JMP GCLIN ; FIND AND PROCESS COMAND COPRC EQU $ CALL STUP XCHG LXI H,START PUSH H CALL SCHR JZ ERR1 XCHG LXI D,COMTAB CALL FDCOM CZ FDCOU DISPO EQU $ JZ HBOUT MOV A,H CMP D JC DLP1A MOV A,L CMP E JNC COMND DLP1A EQU $ POP B INX H DCR C JNZ DLP1 JMP DLOOP ; OUT HL AS HEX 16 BIT VALUE ADOUT MOV A,H CALL HEOUT MOV A,L HBOUT CALL HEOUT CALL SINP JZ BOUT ANI 7FH JZ COMND CPI 10 RC SUI 7 CPI 10H RET ; PSCAN EQU $ CALL SBLK RZ CALL SHEX RET ; ; DUMP COMMAND ; DUMP EQU $ CALL SCONV PUSH H CALL PSCAN POP D XCHG DLOOP CALL CRLF CALL ADOUT CALL BOUT MVI C,16 DLP1 MOV A,M PUSH B CALLUMP DB 'EN' DW ENTER DB 'EX' DW EXEC DB 'GE' DW TLOAD DB 'SA' DW TSAVE DB 'XE' DW TXEQ DB 'CA' DW TLIST DB 'SE' DW SET1 DB 'CU' DW CUSET1 DB 0 ; DISPLAY DRIVER COMMAND TABLE TBL DB CLEAR DW PERSE DB UP DW PUP DB; EXECUTE COMMAND EXEC CALL SCONV EXEC1 EQU $ PUSH H LXI H,START RET ; NAMEO EQU $ LXI H,THEAD NAME CALL SBLK MVI B,6 NAME1 LDAX D CPI ' ' JZ NFIL CPI '/' JZ NFIL MOV M,A INX D INX H DCR B JNZ NAME1 ; ERROR HANDLER ERR1 AN OVER UP TO 12 CHARS LOOKINF FOR BLANK SBLK MVI C,12 SBLK1 LDAX D CPI BLANK JZ SCHR INX D CPI '=' JZ SCHR DCR C JNZ SBLK1 RET ; SCAN PAST UP TO 10 BLANK CHARS FO A NON BLANK CHAR SCHR MVI C,10 SCHR1 LDAX D CPI SPACE RNZ INX D ERR2 INX D XCHG ; GOES TO CONTENTS HL DISPT EQU $ MOV A,M INX H MOV H,M MOV L,A DISP1 EQU $ XTHL MOV A,L RET ; ; FDCOU EQU $ LXI D,CUTAB FDCOM LDAX D ORA A RZ PUSH H CMP M INX D JNZ NCOM INX H LDAX D CMP M JN CPI ' ' JNZ BOUT WTLP1 CALL SINP JZ WTLP1 BOUT MVI B,' ' JMP SOUT HEOUT MOV C,A RRC RRC RRC RRC CALL HEOU1 MOV A,C HEOU1 ANI 0FH ADI 48 CPI 58 JC OUTH ADI 7 OUTH MOV B,A JMP SOUT ; ENTR COMMAND ENTER CALL SCONV PUSH H ITAB DW KREA1 DW SREA1 DW PARIT DW ERRIT ; SECONDARY COMMAND TABLE FOR SET1 SETAB DB 'TA' DW TASPD DB 'S=' DW DISPD DB 'I=' DW SET1IN DB 'O=' DW SET1OT DB 'CI' DW SET1CI DB 'CO' DW SET1CO DB 'XE' DW SET1XQ DB 'TY' DW S DOWN DW PDOWN DB LEFT DW PLEFT DB RIGHT DW PRIT DB HOME DW PHOME DB CR DW PCR DB LF DW PLF DB BACKS DW PBACK DB ESC DW PESC DB 0 ; OUTPUT DEVICE TABLE OTAB DW VDMO1 DW SEROT DW PAROT DW ERROT ; INPUT DEVICE TABLE AR STUNT STA FNUMF RET ; XEQ & GET TXEQ DB 3EH TLOAD XRA A PUSH PSW LXI H,DHEAD CALL NAME LXI H,0 CALL PSCAN TLOA2 XCHG LXI H,DHEAD MOV A,M ORA A JNZ TLOA3 LXI H,THEAD TLOA3 PUSH H CALL ALOAD POP H CALL RTAPE JC TAERR PTAP1 POP D MOV A,D ORA E LHLD BLOCK XCHG JNZ RTAP LHLD LOADR RTAP PUSH D RTAP2 EQU $ CALL DCRCT JZ RTOFF CALL RHED1 JC TERR JZ RTAP2 ; ERROR RET TERR XRA A STC JMP RTOF1 TOFF MVI B,1 CALL DELAY RTOFF XRA A RTOF1 OUT TA CALL LFCB RZ ORA A INR A MVI M,0 RZ ; INX H INX H MOV A,M CALL PLOAD PUSH B LXI H,BLKOF DAD B ORA A JZ EOFW ; PUSH H MOV M,A INX H MVI M,0 INX H MOV M,E INX H MOV M,D MOV H,B MOV L,C CALL WFBLK POP H CALL NLOOP CALL NAOUT JMP COMN1 ERRM DB 'ERROR !' ; CAT COMMAND TLIST EQU $ CALL NAMEO CALL CRLF LLIST CALL ALOAD MVI B,1 CALL TON LIST1 CALL RHEAD JC COMN1 JNZ LIST1 CALL NAOUT JMP LLIST ; ALOAD LXI H,FNUMF LDA TSPD ORA M INR D WT1 POP PSW STAX D ORA A INR M RNZ ; CALL PHEAD JMP WFBLK ; PHEAD CALL PLOAD PUSH B LXI H,BLKOF-1 DAD B LXI B,256 CALL PSTOR POP H RET PSTOR INX H MOV M,C INX H MOV M,B INX H MOV M,E INX H MOV M,D RET I H,COMND CALL PSCAN PUSH H LXI H,THEAD CALL FDCOU JZ CUSE2 DCX D MVI M,0 CUSE2 EQU $ MOV A,M STAX D INX D INX H MOV A,M STAX D INX D POP H XCHG MOV M,E INX H MOV M,D RET ; CUTTER TAPE ROUTINES ; BOPEN PUSH H CCALL NAOUT POP PSW ORA A RZ LDA HTYPE ORA A JM TAERR LDA THEAD+5 ORA A JNZ TAERR LHLD XEQAD JMP EXEC1 ; SAVE PROGRAMS ON CASSET1TE TSAVE EQU $ CALL NAMEO CALL SCONV PUSH H CALL SCONV XTHL PUSH H CALL PSCAN SHLD LOADRV A,M PUSH H INX H CALL PLOAD POP H ORA A JNZ GTBYT ; RDNBLK PUSH D PUSH H INX H CALL PHEAD CALL RFBLK JC TERE2 POP H MOV A,E ORA D JZ EOFER MOV M,E INX H MVI M,0 DCX H MOV A,E POP D ; GTBYT DCR A MOV M,A IEOFW XRA A MOV M,A INX H MOV M,A POP H JMP WFBLK ; LFCB LXI H,FCBAS RAR ANI 1 STA FNUMF JZ LFCB1 LXI H,FCBA2 LFCB1 EQU $ MOV A,M ORA A STC RET ; READ TAPE BYTE RTBYT CALL LFCB RZ INR A JM TEREO MVI M,-1 INX H MO RET ; NAOUT MVI D,8 LXI H,THEAD-1 CALL NLOOP CALL BOUT LHLD LOADR CALL ADOUT LHLD BLOCK CALL ADOUT JMP CRLF NLOOP MOV A,M ORA A JNZ CHRLI MVI A,' ' CHRLI EQU $ CALL OUTH INX H DCR D JNZ NLOOP RET ; SET1 COMMAND SET1 CPLOAD INX H MOV C,M INX H MOV B,M INX H MOV E,M INX H MOV D,M RET ; RFBLK CALL GTUNT RTAPE PUSH D MVI B,3 CALL TON IN TDATA PTAP1 PUSH H CALL RHEAD POP H JC TERR JNZ PTAP1 PUSH H LXI D,THEAD CALL DHCMP POP H JNZ ALL LFCB JNZ TERE2 MVI M,1 INX H MOV M,A INX H MOV M,A LXI D,FBUF1 LDA FNUMF ADD D MOV D,A UBUF POP B ORA A JMP PSTOR ; ERROR RETURNS TERE2 POP H TERE1 POP D TEREO XRA A STC RET EOFER DCR A STC POP D RET ; ; PCLOS POP H POP D PUSH H MOV A,E SUB L MOV L,A MOV A,D SBI 0 SUB H MOV H,A INX H SHLD BLOCK PUSH H CALL ALOAD LXI H,THEAD CALL WHEAD POP D POP H JMP WTAP1 ; OUTPUT ERROR AND HEADER TAERR CALL CRLF MVI D,6 LXI H,ERRM NX H MOV A,M INR M ADD E MOV E,A JNC RT1 INR D RT1 LDAX D ORA A RET ; WRITE BYTE WTBYT CALL LFCB RZ INR A RZ MVI M,0FEH INX H INX H MOV A,B PUSH PSW PUSH H ; CALL PLOAD POP H MOV A,M ADD E MOV E,A JNC WT1 ET1OT EQU $ STA OPORT RET SET1CI EQU $ SHLD UIPRT RET SET1CO EQU $ SHLD UOPRT RET SET1TY EQU $ STA HTYPE RET SET1XQ EQU $ SHLD XEQAD RET SET1NU EQU $ STA NUCNT RET SET1CR EQU $ STA IGNCR RET CUSET1 EQU $ CALL NAMEO LXALL SBLK JZ ERR1 PUSH D CALL SCONV XTHL LXI D,SETAB CALL FDCOM JMP DISPO ; TAPE SPEED TASPD EQU $ ORA A JZ SET1SP MVI A,32 SET1SP STA TSPD RET STSPD EQU $ MOV A,B DISPD EQU $ STA SPEED RET SET1IN EQU $ STA IPORT RET SPPT POP D RET DCRCT EQU $ XRA A MOV B,A ORA D JNZ DCRC2 ORA E RZ MOV B,E MOV E,D RET DCRC2 EQU $ DCR D ORA A RET ; RHEAD MVI B,10 RHEA1 CALL STAT RC IN TDATA ORA A JNZ RHEAD DCR B JNZ RHEA1 SOHL CALL TAPIN RCNI 3 ;TIME TO SPACE? CZ SPACE ;..YES MOV A,E ;GET ADDR AGAIN ANI 0FH ;END OF LINE? JNZ CHAR ;END OF HEX, PRINT ASCII POP D ;GET DATA ADDR CALL AST ;PRINT '*' ASCIC LDAX D ;GET CHAR CPI ' ' ;PRINTABLE? JC PER ;..NO CPI 'Z'+1 JC OK PER LINE DS 1 BOT DS 1 SPEED DS 1 ESCFL DS 1 TSPD DS 1 INPTR DS 2 NUCNT DS 1 IGNCR DS 1 DS 10 ; THEAD DS 5 DS 1 HTYPE DS 1 BLOCK DS 2 LOADR DS 2 XEQAD DS 2 HSPR DS 3 HLEN EQU $-THEAD BLKOF EQU BLOCK-THEAD DHEAD DS HLEN CUTAB DS 6*4 FNUA,M INX H MOV H,M MOV L,A ; WTAP1 EQU $ PUSH H WTAP2 EQU $ CALL DCRCT JZ TOFF CALL WTBL JMP WTAP2 WRTAP PUSH PSW WRWAT IN TAPPT ANI TTBE JZ WRWAT POP PSW OUT TDATA DOCRC EQU $ SUB C MOV C,A XRA C CMA SUB C MOV C,A INR A ;OPEN OK? JZ OPNER ;READ SECTOR, DUMP IN HEX RDLP LXI D,FCB MVI C,READ CALL BDOS ORA A ;READ OK? JNZ RDER ;NO, CHECK EOF ;DUMP IN HEX LXI D,80H ;POINT TO BUFFER LHLD ADDR ;GET ADDR TO PRINT DAD D ;BUMP BY 128 SHLD ADDR ;SAVE FOR PORT ASSIGNMENTS ; STAPT EQU 0 SDATA EQU 1 PDATA EQU 2 KDATA EQU 1 DSTAT EQU 0E0H TAPPT EQU 0EAH TDATA EQU 0EBH SENSE EQU 0FFH SCD EQU 1 SDSR EQU 2 SPE EQU 4 SFE EQU 8 SOE EQU 16 SCTS EQU 32 SDR EQU 64 STBE EQU 128 KDR EQU 1 PDR EQU 2 P CPI 1 JC SOHL JNZ RHEAD LXI H,THEAD MVI B,HLEN RHED1 EQU $ MVI C,0 RHED2 EQU $ CALL TAPIN RC MOV M,A INX H CALL DOCRC DCR B JNZ RHED2 ; CALL TAPIN XRA C RZ LDA IGNCR INR A RET ; STAT IN TAPPT ANI TDR RNZ CAееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееMF DS 1 FCBAS DS 7 FCBA2 DS 7 FBUF1 DS 2*256 DS 1 INLIN DS 80 USARE EQU $ VDMEM1 EQU 0E0H ;FOR THIS ASSM END E DS 1 BLOCK DS 2 LOADR DS 2 XEQAD DS 2 HSPR DS 3 HLEN EQU $-THEAD BLKOF EQU BLOCK-THEAD DHEAD DS HLEN CUTAB DS 6*4 FNU RET ; WHEAD EQU $ CALL WTON MVI D,50 NULOP XRA A CALL WRTAP DCR D JNZ NULOP MVI A,1 CALL WRTAP MVI B,HLEN WTBL MVI C,0 WLOOP MOV A,M CALL WRTAP DCR B INX H JNZ WLOOP MOV A,C JMP WRTAP DHCMP MVI B,5 DHLOP LDAX D CMP M NEXT SECTOR LINE MOV A,H ;GET ADDR CALL XO ;TYPE IN HEX MOV A,L ;GET LO ADDR CALL XOB ;TYPE, SPACE PUSH D ;SAVE DATA ADDR FOR ASCII CHAR LDAX D ;GET CHAR INX D ;POINT TO NEXT INX H ;INCR ADDRESS CALL XO ;PRINT IN HEX MOV A,E ;GET ADDR AXDR EQU 4 TFE EQU 8 TOE EQU 16 TDR EQU 64 TTBE EQU 128 SOK EQU 1 TAPE1 EQU 80H TAPE2 EQU 40H ; ; SYSTEM GLOBAL EREA ; ORG START+800H SYSRAM EQU $ SYSTP EQU SYSRAM+3FFH ; UIPRT DS 2 UOPRT DS 2 DFLTS DS 2 IPORT DS 1 OPORT DS 1 NCHAR DS 1LL SINP JZ STAT ANI 7FH JNZ STAT STC RET TAPIN CALL STAT RC TREDY IN TAPPT ANI TFE+TOE IN TDATA RZ STC RET WFBLK CALL GTUNT WTAPE EQU $ PUSH H CALL WHEAD POP H LXI D,BLKOF DAD D MOV E,M INX H MOV D,M INX H MOV ;IDUMP - INTERPRETED FILE DUMP ;MOD. PUT L/F AFTER C/R 10/29/77 ORG 100H ;TO TPA ;INIT PRIVATE STACK LXI H,0 DAD SP SHLD STACK LXI SP,STACK ;IS THERE AN FCB? LDA FCB+1 CPI ' ' JZ NOFCB ;OPEN FILE LXI D,FCB MVI C,OPEN CALL BDOS ET ; ; END ; VDMEM EQU 0E000H DOWN EQU 1AH UP EQU 17H LEFT EQU 01H RIGHT EQU 13H CLEAR EQU 0BH HOME EQU 0EH MODE EQU 03 ;CONTROL C FOR RANDY BACKS EQU 5FH LF EQU 10 CR EQU 13 BLANK EQU ' ' SPACE EQU BLANK CX EQU 'X'-40H ESC EQU 1BH ; ; RNZ DCR B RZ INX H INX D JMP DHLOP GTUNT EQU $ LDA FNUMF ORA A LDA TSPD JNZ GTUN2 ADI TAPE2 GTUN2 ADI TAPE2 RET WTON MVI B,4 TON EQU $ OUT TAPPT DELAY LXI D,0 DLOP1 DCX D MOV A,D ORA E JNZ DLOP1 DCR B JNZ DELAY R MVI A,'.' ;PRINT '.' FOR UNPRINTABLE OK CALL TYPE ;TYPE CHAR INX D MOV A,E ;END OF LINE? ANI 0FH JNZ ASCIC ;MORE ASCII CHARS CALL AST ;PRINT '*' MVI A,13 ;GET ASCII C/R CALL TYPE MVI A,10 ;GET ASCII L/F CALL TYPE ;END OF SECTOR? MOV A MONTH" PRINT "END END OF PROGRAM" PRINT PRINT "NOTE 1: PRESS DEL TO STOP" PRINT "NOTE 2: ? MATCHES STARTING IN COL. 1" PRINT "NOTE 3: F SCANS ENTIRE FIELD" PRINT GOTO 100 REM FIND RECORD 1000 KEY$=MID$(C$,6,99) GOSUB 8700 IF$(REC.LENG) DIM FIELD.NAME$(FIELD.COUNT) DIM RECORD$(FIELD.COUNT) DIM MAC.COMD$(11) REM READ FIELD NAMES DATA SORT,NAME,ORG,STREET,CITY,ZIP,\ PHONE,COMPUTER,PAID,TYPE FOR I = 1 TO FIELD.COUNT READ FIELD.NAME$(I) NEXT I REM MAIN PROCESUT W/BLANK XOB CALL XO ;SPACE SPACE MVI A,' ' JMP TYPE ;READ ERROR - CHECK FOR EOF RDER DCR A ;WAS IT 1? JNZ RDERR ;NO, GENUINE READ ERROR ;EOF REACHED JMP EXIT NOFCB LXI D,MSG1 JMP ERXIT OPNER LXI D,MSG2 JMP ERXIT RDERR LXI D,MSG3 ;READND (NAME) SEE NOTE 1" PRINT "READ (REC #)" PRINT "DUMP (REC #) SEE NOTE 1" PRINT "C (FIELD NAME) (VALUE) CHANGE" PRINT "LIST" PRINT "? (FIELD NAME) (VALUE) SEE NOTE 2" PRINT "F (FIELD NAME) (VALUE) SEE NOTE 3" PRINT "WRITE RANDOMIZE AееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееA,E ;GET ADDR ANI 7FH ;ISOLATE JZ RDLP ;READ SECTOR JMP LINE ;SUBROUTINES ; ;TYPE ASTERISK AST MVI A,'*' ;TYPE CHAR IN A TYPE PUSH B PUSH D PUSH H MOV E,A ;SET UP MVI C,WRCON ;WRITE CALL BDOS ;CONSOLE ;CHECK FOR ABORT MVI C,CONST ;HEN 1200 IF LEFT$(C$,2)="C " THEN 1300 IF C$="LIST" THEN 1400 IF LEFT$(C$,2)="? " THEN 1500 IF LEFT$(C$,2)="F "THEN 1600 IF C$="WRITE" THEN 1700 IF C$="ADD" THEN 1800 IF C$="ERASE" THEN 1900 IF C$="UPDATE" THEN GOSUB 9100:GOTO 100 IF C$="SING LOOP 100 IF INP(KB) = ABORT THEN MAC.COUNT = 0 IF MAC.COUNT > 0 THEN 8100 INPUT "COMMAND--->";C$ IF C$="MACRO" THEN 8000 110 IF C$="HELP" THEN 200 IF LEFT$(C$,5)="FIND " THEN 1000 IF LEFT$(C$,5)="READ " THEN 1100 IF LEFT$(C$,5)="DUMP " T ERROR JMP ERXIT ERXIT MVI C,PRINT CALL BDOS ;PRINT MESSAGE EXIT LHLD STACK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- DS 30 ;STACK AREA STACK DS 2 ;STACK POINTER MSG1 DB 'NO FILE$' MSG2 DB 'NO SUCH FILE$' MSG3 DB 'READ ERR$' ADND WRITE" PRINT" (USE AFTER ADD)" PRINT "ADD ADD A NEW RECORD" PRINT "ERASE ERASES CURRENT RECORD" PRINT "FREE HOW MUCH SPACE FREE IN MEM" PRINT "UPDATE REWRITES CURRENT RECORD" PRINT "PURGE YYDD PURGE FILE FOR REM CACHE MAILING LIST MAINTENANCE PROGRAM PRINT "MAINT VERSION 1.3" FILE.NAME$="CACHE.FIL" FILE.SIZE = 512 REC.LENG = 128 KB = 1 :REM KEYBOARD INPUT ABORT = 255 :REM KB VALUE TO ABORT FIELD.COUNT = 10 :REM # FIELDS IN RECORD FILE FILE.NAMEREAD CONSOLE STATUS CALL BDOS DCR A ;CHAR TYPED? JZ EXIT POP H POP D POP B RET ;HEX OUTPUT XO PUSH PSW ;SAVE CHAR RAR RAR RAR RAR CALL NIBBL POP PSW NIBBL ANI 0FH CPI 10 JC HEXNU ADI 7 HEXNU ADI '0' JMP TYPE ;HEX OUTPFREE" THEN PRINT FRE:GOTO 100 IF LEFT$(C$,6)="PURGE " THEN 9200 IF C$="END" THEN 9999 199 PRINT "INVALID COMMAND ";C$ MAC.COUNT = 0 GOTO 100 REM GIVE HELP 200 PRINT "SUBSTITUTE PROPER VALUES ";\ "FOR THOSE IN PARENTHESES." PRINT PRINT "FIREAD 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 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH ;SYSTEM FCB DR DW -128 ;ADDR PRINTED -128 ; ; BDOS EQUATES (VERSION 2) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CONST EQU 11 ;CONSOLE STATUS OPEN EQU 15 ;0FFH=NOT FOUND CLOSE EQU 16 ; " " SRCHF EQU 17 ; " " SRCHN EQU 18 ; " " ERASE EQU 19 ;NO RET CODE FLAG = 0 THEN\ PRINT "NO RECORD FOUND" :\ GOTO 100 GOSUB 9000 GOTO 100 REM READ BY RECORD NUMBER 1100 KEY=VAL(MID$(C$,6,99)) IF KEY < 1 OR KEY > 512 THEN \ PRINT "INVALID KEY":GOTO 100 GOSUB 8800 IF FLAG = 1 THEN\ GOSUB 9000 GOTOT FIND RECORD 8750 FLAG = 0 :REM SHOW NOT FOUND RETURN REM PHYSICAL READ RECORD # IN KEY 8800 READ #1,KEY;FLAG IF FLAG=0 THEN RETURN READ #1,KEY;\ FLAG,\ RECORD$(1),\ RECORD$(2),\ RECORD$(3),\ RECORD$(4),\ RECORD$(5),\ RECORD$ GOTO 100 NEXT I GOTO 1510 REM FIND VALUE IN FILE FOR PARTICULAR FIELD 1600 FIND.FLAG = 1 GOTO 1505 REM RANDOMLY WRITE A RECORD 1700 KEY$=RECORD$(2) GOSUB 8900 :REM CALCULATE KEY 1710 PRINT KEY READ #1,KEY;FLAG IF FLAG = 0 THEN\ GOSUB 9ION 1320 IF RIGHT$(FIELD.VALUE$,1)="/" THEN \ FIELD.VALUE$ = LEFT$(FIELD.VALUE$,\ LEN(FIELD.VALUE$)-1) FIELD.VALUE$=MID$(FIELD.VALUE$,2,99) FOR I=LEN(FIELD.VALUE$) TO 1 STEP -1 IF MID$(FIELD.VALUE$,I,1)="/" THEN \ FROM$=LEFT$(FIELD.VALUE$,I REM MACRO COMMANDS 8100 C$=MAC.COMD$(MAC.NO) MAC.NO = MAC.NO + 1 IF C$<>"END" THEN \ GOTO 110 MAC.COUNT = MAC.COUNT -1 IF MAC.COUNT = 0 THEN 8020 MAC.NO = 1 GOTO 8100 REM READ RECORD K$ 8700 GOSUB 8900 :REM CALCULATE KEY TRIES = 0 :REMFOUND":\ GOTO 100 IF INP(KB)=ABORT THEN 100 KEY=KEY+1 IF KEY>FILE.SIZE THEN\ KEY=1:\ MAC.COUNT = 0 GOSUB 8800 IF FLAG = 0 THEN 1510 PRINT KEY,RECORD$(FIELD.NO) IF FIND.FLAG = 1 THEN 1550 IF LEFT$(RECORD$(FIELD.NO),LENGTH)\ =FIEL 100 REM DUMP FILE 1200 KEY=VAL(MID$(C$,6,99)) IF KEY<1 OR KEY>FILE.SIZE THEN \ PRINT "INVALID KEY":\ GOTO 100 1210 GOSUB 8800 IF FLAG = 1 THEN GOSUB 9000 IF INP(KB)=ABORT THEN 100 KEY = KEY + 1 IF KEY >FILE.SIZE THEN \ KEY = 1 :\ ="QUIT" THEN 100 NEXT I GOSUB 9000 GOTO 100 REM ERASE A RECORD 1900 IF KEY < 1 OR KEY > FILE.SIZE THEN 199 PRINT #1,KEY;0,RECORD$(2) PRINT "DELETED" GOTO 100 REM INIT MACRO PROCESSING 8000 INPUT "NUMBER OF TIMES TO REPEAT";MAC.COUNT FOR I100:\ GOTO 100 KEY = KEY + 1 IF KEY > FILE.SIZE THEN \ KEY = 1 :\ MAC.COUNT = 0 IF INP(KB) = ABORT THEN 100 GOTO 1710 REM INPUT A NEW RECORD (ADD) 1800 FOR I=1 TO FIELD.COUNT PRINT FIELD.NAME$(I);" "; INPUT RECORD$(I) IF RECORD$(I)-1):\ TO$=MID$(FIELD.VALUE$,I+1,99) NEXT I TEMP$=RECORD$(FIELD.NO) FOR I=1 TO LEN(TEMP$)-LEN(FROM$)+1 IF MID$(TEMP$,I,LEN(FROM$))=FROM$ THEN 1330 NEXT I PRINT "NOT FOUND" GOTO 100 1330 RECORD$(FIELD.NO)="" IF I=1 THEN 1340 RECORD$(FIE ALLOW UP TO 100 TRIES 8710 GOSUB 8800 IF FLAG = 1 AND KEY$=NAME$ THEN RETURN IF FLAG =1 THEN PRINT KEY;NAME$ TRIES = TRIES + 1 IF INP(KB)=ABORT THEN 8750 KEY = KEY + 1 IF KEY > FILE.SIZE THEN \ KEY = 1 IF TRIES < 100 THEN 8710 REM CAN'D.VALUE$ THEN\ GOSUB 9000:\ GOTO 100 GOTO 1510 REM SCAN THE FIELD FOR THE VALUE 1550 TEMP$=RECORD$(FIELD.NO) IF LENGTH > LEN(TEMP$) THEN 1510 FOR I=1 TO 1+LEN(TEMP$)-LENGTH IF MID$(TEMP$,I,LENGTH)\ =FIELD.VALUE$ THEN\ GOSUB 9000:\ MAC.COUNT = 0 GOTO 1210 REM SCAN FILE FOR MATCHING FIELD 1300 GOSUB 8910 PRINT "FIELD WAS: ";RECORD$(FIELD.NO) IF LEFT$(FIELD.VALUE$,1)="/" THEN 1320 RECORD$(FIELD.NO)=FIELD.VALUE$ 1310 GOSUB 9000 GOTO 100 REM FIELD CHANGE BY CHAR SUBSTITUT=1 TO 10 INPUT "MACRO COMMAND";MAC.COMD$(I) IF MAC.COMD$(I)="END" THEN 8010 NEXT I MAC.COMD$(11)="END" 8010 INPUT "OK TO START";ANS$ IF LEFT$(ANS$,1)="Y" THEN \ MAC.NO = 1 :\ GOTO 100 8020 MAC.COUNT = 0 PRINT "MACRO ABORTED" GOTO 100 = 0 1505 GOSUB 8910 :REM GET NO. ,VALUE PRINT "SCANNING FROM ";\ KEY;"FOR ";FIELD$;\ "=";FIELD.VALUE$ NUMBER.SCANNED = 0 LENGTH = LEN(FIELD.VALUE$) 1510 NUMBER.SCANNED = NUMBER.SCANNED + 1 IF NUMBER.SCANNED = FILE.SIZE THEN\ PRINT "NOT LD.NO)=LEFT$(TEMP$,I-1) 1340 RECORD$(FIELD.NO)=RECORD$(FIELD.NO)+TO$+\ MID$(TEMP$,I+LEN(FROM$),99) GOTO 1310 REM PRINT RECORD 1400 IF FLAG = 0 THEN\ PRINT "NO RECORD":\ GOTO 100 GOSUB 9000 GOTO 100 REM SCAN FILE FOR VALUE 1500 FIND.FLAG(6),\ RECORD$(7),\ RECORD$(8),\ RECORD$(9),\ RECORD$(10) REM SET VARIABLE NAMES FROM RECORD$(N) 8850 SORT$=RECORD$(1) NAME$=RECORD$(2) ORG$=RECORD$(3) STREET$=RECORD$(4) CITY$=RECORD$(5) ZIP$=RECORD$(6) PHONE$=RECORD$(7) COM$=REORT EQU 1 INIT$REQD EQU 1 ;MODEM INIT. REQ'D? INIT$CHAR$1 EQU 3 ;FIRST INIT CHAR TO CTL PORT INIT$CHAR$2 EQU 15H ;2ND INIT CHAR TO CTL PORT ERROR$LIMIT EQU 10 ;MAX ALLOWABLE ERRORS EXIT$CHAR EQU 'E'-40H ;CHAR TO EXIT FROM T OR C ORG 100H CALL STARееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее BP=BP-1 FIELD$=LEFT$(C$,BP) FIELD.NO = 0 FOR I=1 TO FIELD.COUNT IF LEFT$(FIELD.NAME$(I),BP)=FIELD$ THEN\ FIELD.NO = I NEXT I IF FIELD.NO=0 THEN\ PRINT "NO SUCH FIELD ";FIELD$:\ GOTO 100 FIELD.VALUE$=MID$(C$,BP+2,99) FIELD$=FIELD.N/77 FIRST WRITTEN BY WARD CHRISTENSEN ;09/25/77 FIRST TESTING COMPLETE ;09/26/77 ADD ERROR$LIMIT EQU ;10/01/77 CHANGE EXIT$CHAR FROM CTL-C TO ; CTL-E FOR USE W/TIMESHARING COMPUTERS ;10/10/77 CORRECT TO SEND ANY LENGTH FILE ; MODEM$CTL$PORT EQU 4 PRINTER." INPUT"STARTING, ENDING RECORD";STARTING,ENDING FOR I=STARTING TO ENDING READ #1,I;FLAG IF FLAG=0 THEN 9210 READ #1,I;FLAG,SO$,NA$,OR$,ST$,CI$,ZI$,PH$,CO$,PA$,TY$ IF PA$<>DEL.DATE$ THEN 9210 PRINT "DELETED ";PA$;" ";NA$ FLAG=0 PCORD$(8) PAID$=RECORD$(9) TYPE$=RECORD$(10) RETURN REM KEY CALCULATING ROUTINE - INPUT IN KEY$ 8900 KEY=0 FOR I=1 TO LEN(KEY$) STEP 2 KEY=2*KEY+(15 AND ASC(MID$(KEY$,I,1))) NEXT I KEY = KEY-FILE.SIZE*INT(KEY/FILE.SIZE) KEY = INT(KEY+.1) ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееAME$(FIELD.NO) RETURN REM RECORD PRINT ROUTINE 9000 PRINT PRINT "RECORD #";KEY;" ";RECORD$(1) :REM SORT PRINT RECORD$(2) :REM NAME PRINT RECORD$(3) :REM ORG PRINT RECORD$(4) :REM STREET PRINT RECORD$(5);" ";RECORD$(6) PRINT RECORD$(7);";";\ MODEM$SEND$MASK EQU 2 SEND$READY EQU 2 ;VALUE WHEN READY MODEM$RECV$MASK EQU 1 RECV$READY EQU 1 ;BIT ON WHEN READY MODEM$DATA$PORT EQU 5 KEY$CTL$PORT EQU 0 ;KEYBOARD STATUS KEY$READY$MASK EQU 2 KEY$READY EQU 2 ;VALUE WHEN KEYBOARD READY KEY$DATA$PRINT #1,I;FLAG,SO$,NA$,OR$,ST$,CI$,ZI$,PH$,CO$,PA$,TY$ IF INP(1)=255 THEN 100 9210 NEXT I PRINT "END OF PURGE" GOTO 100 9999 END  IF KEY = 0 THEN KEY = 1 PRINT "RANDOMIZED TO ";KEY RETURN REM EXTRACT FIELD NAME, VALUE FROM C$ 8910 C$=MID$(C$,3,99) BP=0 REM FIND BLANK AFTER FIELD NAME FOR I=LEN(C$) TO 1 STEP -1 IF MID$(C$,I,1)=" " THEN BP=I NEXT I IF BP<2 THEN 199 ;MODEM ROUTINE - SEND, RECV, COMPUTER, TERMINAL ; * * * * * * * * * * * * * * * * * * * * ;SENSE SWITCH CONTROLS: * ; * ; A12 UP TO DISPLAY INCOMING DATA * ; A13 UP TO DISPLAY OUTGOING DATA * ; * * * * * * * * * * * * * * * * * * * * ; ;09/23$(4),\ RECORD$(5),\ RECORD$(6),\ RECORD$(7),\ RECORD$(8),\ RECORD$(9),\ RECORD$(10) RETURN REM FILE PURGE BY DATE 9200 PRINT "FILE PURGE ROUTINE:" DEL.DATE$=MID$(C$,7,99) PRINT "PURGING DATE '";DEL.DATE$;"'" PRINT:PRINT "TURN ON RECORD$(8);";";\ RECORD$(9);";";\ RECORD$(10) PRINT RETURN REM WRITE RECORD(KEY) 9100 IF KEY < 1 OR KEY > FILE.SIZE THEN\ PRINT "INVALID KEY FOR WRITE":\ GOTO 100 PRINT #1,KEY;1,RECORD$(1),\ RECORD$(2),\ RECORD$(3),\ RECORDT ;GO PRINT ID DB 'MODEM PROGRAM AS OF ' DB '10/10/77',13,10,'$' ;FLAG FOR GENERATING TEST CODE TO USE KEYBOARD ;TO ECHO ACK/NAK WHILE TESTING: TEST EQU 0 ;GENERATE TEST CODE ; ;DEFINE ASCII CHARACTERS USED SOH EQU 1 EOT EQU 4 ACK EQU 6 NAK EQ SENDC MOV A,M CALL SEND INX H MOV A,H CPI 1 ;DONE WITH SECTOR? JNZ SENDC ;SECTOR SENT, SEND CKSUM MOV A,C ;GET CKSUM CALL SEND ;GET ACK ON SECTOR MVI B,4 ;WAIT 4 SECONDS MAX CALL RECV JNC SNTO ;NO TIMEOUT ;TIMED OUT WAITING FOR ACK LXI D,MSG$BAUD CALL PRINT$MESSAGE IF INIT$REQD MVI A,INIT$CHAR$1 OUT MODEM$CTL$PORT MVI A,INIT$CHAR$2 OUT MODEM$CTL$PORT ENDIF ;GET THE SPEED XRA A ;GET A ZERO CALL SEND ;SEND A CHAR XRA A ;GET ZERO CALL SEND ;SEND AGAIN ;WAIT, TICPI 'C' JZ COMPUTER CPI 'T' JZ TERMINAL ;INVALID OPTION CALL ERXIT ;EXIT W/ERROR DB '++INVALID OPTION ON MODEM COMMAND - ',CR,LF DB 'MUST BE ONE OF THE FOLLOWING:',CR,LF DB 'MODEM SEND FILENAME',CR,LF DB 'MODEM RECV FILENAME',CR,LF DB 'MZERO RECORD # RET ; ;*****************SEND FILE*************** ; SEND$FILE: CALL OPEN$FILE ;OPEN THE FILE LXI D,OPENM CALL PRINT$MESSAGE SENDB XRA A ;GET A ZERO STA ERRCT ;ZERO ERROR COUNT ;READ SECTOR, SEND IT CALL READ$SECTOR LDA SECTIN MODEM$DATA$PORT OUT MODEM$DATA$PORT ;ECHO CALL TYPE ;TYPE IT JMP COMPUTER ; ;**************TERMINAL**************** ; ;SEE NOTES UNDER 'COMPUTER' ; TERMINAL: IN KEY$CTL$PORT ANI KEY$READY$MASK CPI KEY$READY JNZ TRECV ;NOTHING FROM KEU 15H LF EQU 10 CR EQU 13 ; START POP D ;GET ID MESSAGE MVI C,PRINT CALL BDOS ;PRINT ID MESSAGE ;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 INIT$PORT ;GOBBLE UP GA: MOV A,B ;GET COUNT CPI 0F5H ;110 BAUD = F0, JC BAUD$110 ;300 BAUD = FA ;BAUD RATE 300 LXI D,MSG$300 INIT$PRINT: CALL PRINT$MESSAGE RET ;FROM INIT$PORT BAUD$110: LXI D,MSG$110 JMP INIT$PRINT MSG$BAUD DB 'BAUD RATE IS $' MSG$110 DB '1MING TO DETERMINE BAUD RATE LXI B,0 ;INIT COUNT INIT$WAIT: IN MODEM$CTL$PORT ANI MODEM$SEND$MASK CPI SEND$READY JZ INIT$WAIT$END DCR C JNZ INIT$WAIT DCR B JNZ INIT$WAIT CALL ERXIT DB '++TIME OUT DETERMINING BAUD RATE$' INIT$WAIT$ENDODEM COMPUTER',CR,LF DB 'MODEM TERMINAL',CR,LF DB ' ABBREV. ALLOWED: S R C T$' ; ;****************COMPUTER**************** ; ;TERMINAL-TERMINAL W/ECHO SENT BY THIS PROGRAM ;'EXIT$CHAR' TYPED TO RE-BOOT ;IF ONE COMPUTER IS IN COMPUTER MODE, ;THENO ;INCR SECT NO. INR A STA SECTNO ;SEND OR REPEAT SECTOR REPTB LXI D,SECTMSG CALL PRINT$MESSAGE LDA SECTNO CALL HEXO CALL CRLF MVI A,SOH CALL SEND LDA SECTNO CALL SEND LDA SECTNO CMA CALL SEND MVI C,0 ;INIT CKSUM LXI H,80H YBOARD IN KEY$DATA$PORT ANI 7FH CPI EXIT$CHAR ;TIME TO END? JZ EXIT OUT MODEM$DATA$PORT TRECV IN MODEM$CTL$PORT ANI MODEM$RECV$MASK CPI RECV$READY JNZ TERMINAL IN MODEM$DATA$PORT CALL TYPE JMP TERMINAL ;INIT SERIAL PORT INIT$PORT: RBAGE CHARS FROM THE LINE MVI B,1 ;TIMEOUT DELAY CALL RECV MVI B,1 CALL RECV ; LDA FCB+1 ;GET OPTION (S R C T) PUSH PSW ;SAVE OPTION CALL MOVE$FCB ;MOVE FROM 6C TO 5C POP PSW ;GET OPTION CPI 'S' JZ SEND$FILE CPI 'R' JZ RECV$FILE 10',CR,LF,'$' MSG$300 DB '300',CR,LF,'$' ;MOVE FCB (SECOND OPERAND ON COMMAND) ; TO NORMAL FCB LOCATION MOVE$FCB: LXI H,FCB LXI D,FCB+16 MVI B,16 MOVE$LOOP: LDAX D MOV M,A INX D INX H DCR B JNZ MOVE$LOOP XRA A ;GET 0 STA FCB+32 ;E, CHECK KEYBOARD MVI C,CONST ;CHECK STATUS CALL BDOS ORA A ;READY? JZ COMPUTER ;..NO MVI C,RDCON CALL BDOS ;GET CHAR CPI EXIT$CHAR ;END? JZ EXIT ;YES, EXIT OUT MODEM$DATA$PORT ;SEND CHAR JMP COMPUTER ;GOT CHAR FROM LINE LINE$CHAR: OTHER SHOULD BE IN TERMINAL MODE. ;AT NO TIME SHOULD BOTH BE IN COMPUTER ;MODE BECAUSE LINE ERRORS WILL BE PING-PONGED ;BACK AND FORTH AD INFINITUM. COMPUTER: IN MODEM$CTL$PORT ANI MODEM$RECV$MASK CPI RECV$READY JZ LINE$CHAR ;NOTHING FROM LIN CALL TOUT ;PRINT 'TIMEOUT', ERRCT DATERR LDA ERRCT INR A STA ERRCT CPI ERROR$LIMIT JC REPTB ;REPEAT SECTOR ;SECTOR SEND NO GOOD AFTER 10 TRIES CALL ERXIT DB 'CAN''T SEND SECTOR ' DB '- ABORTING',13,10,'$' SECTMSG DB 'SENDING SECTOR $' ;T IT EXIT LHLD STACK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- TO CP/M ; - - - - - - - - - - - - - - - ;MODEM RECV RECV PUSH D ;SAVE MSEC LXI D,0BBBBH ;1 SEC DCR COUNT IF NOT TEST MWTI IN MODEM$CTL$PORT ANI MODEM$RECV$MASK CPI RE INR A ;CALC NEXT SECTOR # CMP B ;MATCH? JNZ DO$ACK ;GOT NEW SECTOR - WRITE IT LXI D,FCB MVI C,WRITE CALL BDOS ORA A JNZ WRITE$ERROR LDA RECVD$SECT$NO STA SECTNO ;UPDATE SECTOR # DO$ACK MVI A,ACK CALL SEND JMP RECV$LOOP ; WRITE$EXO CALL CRLF MVI B,5 ;5 SEC TIMEOUT CALL RECV JNC RHNTO ;NO TIMEOUT RECV$HDR$TIMEOUT: CALL TOUT ;PRINT TIMEOUT RECV$SECT$ERR: ;PURGE THE LINE OF INPUT CHARS MVI B,1 ;1 SEC W/NO CHARS CALL RECV JNC RECV$SECT$ERR ;LOOP UNTIL SENDER DONE LL - CAN'T MAKE FILE CALL ERXIT DB '++ERROR - CAN''T MAKE FILE',0DH,0AH DB '++DIRECTORY MUST BE FULL',0DH,0AH,'$' ; ; S U B R O U T I N E S ; ;OPEN FILE OPEN$FILE LXI D,FCB MVI C,OPEN CALL BDOS INR A ;OPEN OK? RNZ ;GOOD OPEN CALL ERXI0DH,0AH,'$' ; RECV$SECTOR: MOV A,D ;GET SECTOR # STA RECVD$SECT$NO MVI C,0 ;INIT CKSUM LXI H,80H ;POINT TO BUFFER RECV$CHAR: MVI B,1 ;1 SEC TIMEOUT CALL RECV ;GET CHAR JC RECV$HDR$TIMEOUT MOV M,A ;STORE CHAR INR L ;DONE? JNZ RECV$CHANO TIMEOUT SENDING SECTOR SNTO CPI ACK ;ACK RECIEVED? JZ SENDB ;..YES, SEND NEXT SECT ;ACK NOT RECIEVED CALL HEXO ;TYPE CHR IN HEX LXI D,ERR1 CALL PRINT$MESSAGE JMP DATERR ;GO TO DATA ERROR ERR1 DB 'H RECEIVED, NOT ACK',13,10,'$' OPENM DB 'FIOSE CALL BDOS INR A JNZ XFER$CPLT CALL ERXIT DB '++ERROR CLOSING FILE$' ; ERASE$OLD$FILE: LXI D,FCB MVI C,SRCHF ;SEE IF IT EXISTS CALL BDOS INR A ;FOUND? RZ ;NO, RETURN LXI D,EXIST CALL PRINT$MESSAGE MVI C,RDCON CALL BDOS CERROR: CALL ERXIT DB '++ERROR WRITING FILE',0DH,0AH,'$' ; RECV$CKSUM$ERR: LXI D,ERR3 CALL PRINT$MESSAGE JMP RECV$SECT$ERR ERR3 DB '++BAD CKSUM ON SECTOR' DB 0DH,0AH,'$' ; GOT$EOT: MVI A,ACK ;ACK THE EOT CALL SEND LXI D,FCB MVI C,CL MVI A,NAK CALL SEND ;SEND NAK LDA ERRCT INR A STA ERRCT CPI ERROR$LIMIT JC RECV$HDR CALL ERXIT DB '++UNABLE TO GET VALID HEADER',0DH,0AH,'$' RMSG DB 'WAITING FOR SECTOR #$' ;GOT CHAR - MUST BE SOH RHNTO CPI SOH JZ GOT$SOH ORA A ;00 T DB 'CAN''T OPEN FILE$' ; - - - - - - - - - - - - - - - PRINT$MESSAGE: MVI C,PRINT JMP BDOS ;PRINT MESSAGE, RETURN ; - - - - - - - - - - - - - - - ;EXIT PRINTING MESSAGE FOLLOWING 'CALL ERXIT' ERXIT POP D ;GET MESSAGE CALL PRINT$MESSAGE ;PRINR ;VERIFY CHECKSUM MOV D,C ;SAVE CHECKSUM MVI B,1 ;TIMEOUT CALL RECV ;GET CHECKSUM JC RECV$HDR$TIMEOUT CMP D ;CHECK JNZ RECV$CKSUM$ERR ; ;GOT A SECTOR, WRITE IF = 1+PREV SECTOR ; LDA RECVD$SECT$NO MOV B,A ;SAVE IT LDA SECTNO ;GET PREVLE OPEN',13,10,'$' ; ;**************RECEIVE FILE**************** ; RECV$FILE: CALL ERASE$OLD$FILE CALL MAKE$NEW$FILE RECV$LOOP: XRA A ;GET 0 STA ERRCT ;INIT ERROR COUNT RECV$HDR: LXI D,RMSG CALL PRINT$MESSAGE LDA SECTNO INR A CALL HPI 'Y' JNZ 0 ;REBOOT IF NOT ERASE CALL CRLF ;ERASE OLD FILE LXI D,FCB MVI C,ERASE CALL BDOS RET EXIST DB '++FILE EXISTS, TYPE Y TO ERASE:$' ; MAKE$NEW$FILE: LXI D,FCB MVI C,MAKE CALL BDOS INR A ;FF=BAD RNZ ;OPEN OK ;DIRECTORY FULK # MVI B,1 CALL RECV ;GET CMA'D SECT # JC RECV$HDR$TIMEOUT CMA CMP D ;GOOD SECTOR #? IF TEST JMP RECV$SECTOR ENDIF JZ RECV$SECTOR ;GOT BAD SECTOR # LXI D,ERR2 CALL PRINT$MESSAGE JMP RECV$SECT$ERR ERR2 DB '++BAD SECTOR # IN HDR',FROM SPEED CHECK? JZ RECV$HDR CPI EOT JZ GOT$EOT ;DIDN'T GET SOH - CALL HEXO LXI D,ERRSOH CALL PRINT$MESSAGE JMP RECV$SECT$ERR ERRSOH DB 'H RECEIVED, NOT SOH',0DH,0AH,'$' GOT$SOH: MVI B,1 CALL RECV JC RECV$HDR$TIMEOUT MOV D,A ;D=BCV$READY JZ MCHAR ;GOT CHAR ENDIF IF TEST MWTI IN KEY$CTL$PORT ;READ KEYBOARD ANI KEY$READY$MASK CPI KEY$READY JZ MCHAR ENDIF DCR E ;COUNT DOWN JNZ MWTI ;FOR TIMEOUT DCR D JNZ MWTI DCR B ;DCR # OF SECONDS JNZ MSEC ;MODEM TIMED Oееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее LXI D,ERR1 CALL PRINT$MESSAGE EOTERR LDA ERRCT INR A STA ERRCT CPI ERROR$LIMIT JC SEOT CALL ERXIT DB 'NO ACK RECIEVED ON EOT$',10,13 FSENTM DB 13,10,'FILE SENT, SENDING EOT''S',10,13,'$' ;TIMEOUT ON EOT EOTTOT CALL TOUT JMP EOTERR ; CHAR ROUTINE SEND PUSH PSW ;CHECK IF MONITORING OUTPUT IN 0FFH ANI 20H JZ NO$MON$OUTPUT POP PSW PUSH PSW CALL SHOW NO$MON$OUTPUT: POP PSW PUSH PSW ADD C ;CALC CKSUM MOV C,A SENDW IN MODEM$CTL$PORT ANI MODEM$SEND$MASK CPI SEND$RееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееUT HEXO PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW NIBBL ANI 0FH CPI 10 JC ISNUM ADI 7 ISNUM ADI '0' JMP TYPE ; - - - - - - - - - - - - - - - ;FILE READ ROUTINE READ$SECTOR: LXI D,FCB MVI C,READ CALL BDOS ORA A RZ DCRUT RECEIVING POP D ;RESTORE D,E STC ;CARRY SHOWS TIMEOUT RET ;GOT MODEM CHAR IF NOT TEST MCHAR IN MODEM$DATA$PORT ENDIF IF TEST MCHAR IN KEY$DATA$PORT ANI 7FH ;DEL PARITY FROM KEYBOAREAD ENDIF POP D ;RESTORE DE ;CALC CHECKSUM PUSH SECTOR NUMBER ERRCT DB 0 ;ERROR COUNT ; ; BDOS EQUATES (VERSION 2) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CONST EQU 11 ;CONSOLE STAT OPEN EQU 15 ;0FFH=NOT FOUND CLOSE EQU 16 ; " " SRCHF EQU 17 ; " " SRCHN EQU 18 ; " " ERASE EQU 19 ;NO RREAD ERROR RDERR CALL ERXIT DB '++FILE READ ERROR$' ; - - - - - - - - - - - - - - - ;DONE - CLOSE UP SHOP XFER$CPLT: CALL ERXIT DB 13,10,'TRANSFER COMPLETE$' DS 40 ;STACK AREA STACK DS 2 ;STACK POINTER RECVD$SECT$NO DB 0 SECTNO DB 0 ;CURRENTEADY JNZ SENDW POP PSW ;GET CHAR OUT MODEM$DATA$PORT RET ; - - - - - - - - - - - - - - - ;SHOW CHAR RECEIVED OR SENT SHOW CPI 0AH ;LF? JZ TYPE CPI 0DH JZ TYPE CPI 09 ;TAB JZ TYPE CPI ' ' JC SHOWHEX CPI 7FH JC TYPE SHOWHEX PUSHееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее A ;EOF? JNZ RDERR ;EOF XRA A STA ERRCT LXI D,FSENTM ;FILE SENT MESSAGE CALL PRINT$MESSAGE SEOT MVI A,EOT CALL SEND MVI B,5 ;WAIT 5 SEC FOR TIMEOUT CALL RECV JC EOTTOT ;EOT TIMEOUT CPI ACK JZ XFER$CPLT ;ACK NOT RECIEVED CALL HEXOPSW ADD C MOV C,A ;CHECK IF MONITORING INPUT IN 0FFH ANI 10H JZ NO$MON$INPUT POP PSW PUSH PSW CALL SHOW ;CHAR RECEIVED NO$MON$INPUT: POP PSW ;TURN OFF CARRY TO SHOW NO TIMEOUT ORA A RET ; - - - - - - - - - - - - - - - ;MODEM SENDET 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 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH ;SYSTEM FCB - - - - - - - - - - - - CRLF MVI A,13 CALL TYPE MVI A,10 ; - - - - - - - - - - - - - - - TYPE PUSH PSW PUSH B PUSH D PUSH H MOV E,A MVI C,WRCON CALL BDOS POP H POP D POP B POP PSW RET ; - - - - - -