CP/M MACRO ASSEM 2.0 #001 CCPZ Version 4.1 TITLE 'CCPZ Version 4.1' ; ; CP/M CONSOLE COMMAND PROCESSOR (CCP) REVISION 4.1 ; FOR Z80-BASED CP/M 2.X SYSTEMS ; ; ORIGINAL CCP DISASSEMBLED BY ???? ; ORIGINAL CCP DISASSEMBLED FURTHER BY RLC ; ORIGINAL CCP COMMENTED BY RLC ; CUSTOMIZED FOR ARIES-II BY RLC ; FURTHER MODIFIED BY RGF AS V2.0 ; FURTHER MODIFIED BY RLC AS V2.1 ; FURTHER MODIFIED BY KBP AS V2.2 ; FURTHER MODIFIED BY RLC AS V2.4 (V2.3 SKIPPED) ; FURTHER MODIFIED BY RLC AS V2.5 ; FURTHER MODIFIED BY RLC AS V2.6 ; FURTHUR MODIFIED BY SBB AS V2.7 ; FURTHER MODIFIED BY RLC AS V2.8 ; FURTHER MODIFIED BY RLC AS V2.9 ; FURTHER MODIFIED BY RLC AS V3.0 ; FURTHER MODIFIED BY RLC AS V3.1 ; FURTHER MODIFIED BY RLC AS V4.0 ; SBB V4.1 11/27/81 ; ;******** REFER TO CCPZ-VXX.NOT FILE FOR REVISION HISTORY ******** ; ;******** STRUCTURE NOTES ******** ; ; THIS CCP IS DIVIDED INTO A NUMBER OF MAJOR SECTIONS. THE FOLLOWING ; IS AN OUTLINE OF THESE SECTIONS AND THE NAMES OF THE MAJOR ROUTINES ; LOCATED THEREIN. ; ; SECTION FUNCTION/ROUTINES ; ------- ----------------- ; ; -- OPENING COMMENTS, EQUATES, AND MACRO DEFINITIONS ; ; 0 JMP TABLE INTO CCP ; ; 1 BUFFERS ; ; 2 CCP STARTING MODULES ; CCP1 CCP RESTRT RSTCCP RCCPNL ; PRNNF ; ; 3 UTILITIES ; CRLF CONOUT CONIN LCOUT LSTOUT ; READF READ BDOSB PRINTC PRINT ; GETDRV DEFDMA DMASET RESET BDOSJP ; LOGIN OPENF OPEN GRBDOS CLOSE ; SEARF SEAR1 SEARN SUBKIL DELETE ; WRITE CREATE RESETUSR GETUSR SETUSR ; ; 4 CCP UTILITIES ; SETUD SETU0D UCASE REDBUF CNVBUF ; BREAK USRNUM ERROR SDELM ADVAN ; SBLANK ADDAH NUMBER NUMERR HEXNUM CP/M MACRO ASSEM 2.0 #002 CCPZ Version 4.1 ; DIRPTR SLOGIN DLOGIN COMLOG SCANER ; CMDSER ; ; 5 CCP-RESIDENT COMMANDS AND FUNCTIONS ; 5A DIR DIRPR FILLQ ; 5B ERA ; 5C LIST ; 5D TYPE PAGER ; 5E SAVE ; 5F REN ; 5G USER ; 5H DFU ; 5I JUMP ; 5J GO ; 5K COM CALLPROG ERRLOG ERRJMP ; 5L GET MEMLOAD PRNLE ; ; 0000 = FALSE EQU 0 FFFF = TRUE EQU NOT FALSE ; ; CUSTOMIZATION EQUATES ; ; THE FOLLOWING EQUATES MAY BE USED TO CUSTOMIZE THIS CCP FOR THE USER'S ; SYSTEM AND INTEGRATION TECHNIQUE. THE FOLLOWING CONSTANTS ARE PROVIDED: ; ; REL - TRUE IF INTEGRATION IS TO BE DONE VIA MOVCPM ; - FALSE IF INTEGRATION IS TO BE DONE VIA DDT AND SYSGEN ; ; BASE - BASE ADDRESS OF USER'S CP/M SYSTEM (NORMALLY 0 FOR DR VERSION) ; THIS EQUATE ALLOWS EASY MODIFICATION BY NON-STANDARD CP/M (EG,H89) ; ; CCPLOC - BASE PAGE ADDRESS OF CCP; THIS VALUE CAN BE OBTAINED BY RUNNING ; THE BDOSLOC PROGRAM ON YOUR SYSTEM, OR BY SETTING THE ; MSIZE AND BIOSEX EQUATES TO THE SYSTEM MEMORY SIZE IN ; K-BYTES AND THE "EXTRA" MEMORY REQUIRED BY YOUR BIOS ; IN K-BYTES. BIOSEX IS ZERO IF YOUR BIOS IS NORMAL SIZE, ; AND CAN BE NEGATIVE IF YOUR BIOS IS IN PROM OR IN ; NON-CONTIGUOUS MEMORY. ; ; RAS - REMOTE-ACCESS SYSTEM; SETTING THIS EQUATE TO TRUE DISABLES ; CERTAIN CCP COMMANDS THAT ARE CONSIDERED HARMFUL IN A REMOTE- ; ACCESS ENVIRONMENT; USE UNDER REMOTE-ACCESS SYSTEMS (RBBS) FOR ; SECURITY PURPOSES ; 0000 = REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION ; 0000 = BASE EQU 0 ;BASE OF CP/M SYSTEM (SET FOR STANDARD CP/M) ; IF REL CCPLOC EQU 00000H ;NORMAL VALUE. ELSE ; ; IF REL IS FALSE, THE VALUE OF CCPLOC MAY BE SET IN ONE ; OF TWO WAYS. THE FIRST WAY IS TO SET MSIZE AND BIOSEX ; AS DESCRIBED ABOVE USING THE FOLLOWING THREE LINES: CP/M MACRO ASSEM 2.0 #003 CCPZ Version 4.1 ; 0040 = MSIZE EQU 64 ;SIZE OF MEM IN K-BYTES 0002 = BIOSEX EQU 2 ;EXTRA # K-BYTES IN BIOS BD00 = CCPLOC EQU 0BD00H ;LOCATION FOR 56K SYSTEM. ; ; THE SECOND WAY IS TO OBTAIN THE ORIGIN OF YOUR CURRENT ; CCP USING BDSLOC OR ITS EQUIVALENT, THEN MERELY SET CCPLOC ; TO THAT VALUE AS AS IN THE FOLLOWING LINE: ; ;CCPLOC EQU 0BD00H ;FILL IN WITH BDOSLOC SUPPLIED VALUE ; ; NOTE THAT YOU SHOULD ONLY USE ONE METHOD OR THE OTHER. ; DO NOT DEFINE CCPLOC TWICE! ; ; THE FOLLOWING GIVES THE REQUIRED OFFSET TO LOAD THE CCP INTO THE ; CP/M SYSGEN IMAGE THROUGH DDT (THE ROFFSET COMMAND); NOTE THAT THIS ; VALUE CONFORMS WITH THE STANDARD VALUE PRESENTED IN THE CP/M REFERENCE ; MANUALS, BUT IT MAY NOT NECESSARILY CONFORM WITH THE LOCATION OF THE ; CCP IN YOUR CP/M SYSTEM; SEVERAL SYSTEMS (MORROW DESIGNS, P&T, HEATH ; ORG-0 TO NAME A FEW) HAVE THE CCP LOCATED AT A NON-STANDARD ADDRESS IN ; THE SYSGEN IMAGE. ; ;CCPR EQU 0980H-CCPLOC ;DDT LOAD OFFSET 5400 = CCPR EQU 1100H-CCPLOC ;DDT LOAD OFFSET FOR MORROW DESIGNS ;CCPR EQU 0E00H-CCPLOC ;DDT LOAD OFFSET FOR APPLE SOFTCARD 56K ENDIF ; 0000 = RAS EQU FALSE ;SET TO TRUE IF CCP IS FOR A REMOTE-ACCESS SYSTEM ; ; *** NOTE TO APPLE SOFTCARD USERS *** ; ; IN THEIR INFINITE (?) WISDOM (???), MICROSOFT DECIDED THAT THE WAY TO ; GET A TWO-COLUMN DIRECTORY DISPLAY INSTEAD OF FOUR-COLUMN (NARROW 40-COL ; SCREEN, REMEMBER) WAS TO HAVE THEIR BIOS POKE CCP EVERY TIME IT WAS ; LOADED. NATURALLY, THAT WILL TURN INTO A RANDOM POKE ON ANY NON-STANDARD ; CCP, LIKE THIS ONE. THE BEST WAY TO GET THIS CCP UP ON THE APPLE IS TO ; LOAD IT INTO CPM56.COM, AT LOCATION 0E00H IN THE IMAGE. THE BIOS CODE ; THAT POKES THE CCP CAN ALSO BE MODIFIED AT THAT TIME. THE POKE IS DONE ; BY "STA 0C8B2H", FOUND AT 24FEH IN THE CPM56 IMAGE. TO ELIMINATE THE ; POKE FOREVER, CHANGE THE "STA" TO "LDA" BY CHANGING THE CONTENTS OF ; LOCATION 24FEH FROM 32H TO 3AH. IF YOU WANT A TWO-COLUMN DISPLAY, SET ; THE TWOCOL SWITCH BELOW TO A VALUE OF TRUE. ; 0000 = TWOCOL EQU FALSE ;TRUE IF TWO COL DIR INSTEAD OF FOUR ; ; THE FOLLOWING IS PRESENTED AS AN OPTION, BUT IS NOT GENERALLY USER-CUSTOMIZ- ; ABLE. A BASIC DESIGN CHOICE HAD TO BE MADE IN THE DESIGN OF CCPZ CONCERNING ; THE EXECUTION OF SUBMIT FILES. THE ORIGINAL CCP HAD A PROBLEM IN THIS SENSE ; IN THAT IT ALWAYS LOOKED FOR THE SUBMIT FILE FROM DRIVE A: AND THE SUBMIT ; PROGRAM ITSELF (SUBMIT.COM) WOULD PLACE THE $$$.SUB FILE ON THE CURRENTLY ; LOGGED-IN DRIVE, SO WHEN THE USER WAS LOGGED INTO B: AND HE ISSUED A SUBMIT ; COMMAND, THE $$$.SUB WAS PLACED ON B: AND DID NOT EXECUTE BECAUSE THE CCP ; LOOKED FOR IT ON A: AND NEVER FOUND IT. ; ; AFTER MUCH DEBATE IT WAS DECIDED TO HAVE CCPZ PERFORM THE SAME TYPE OF ; FUNCTION AS CCP (LOOK FOR THE $$$.SUB FILE ON A:), BUT THE PROBLEM WITH CP/M MACRO ASSEM 2.0 #004 CCPZ Version 4.1 ; SUBMIT.COM STILL EXISTS. HENCE, RGF DESIGNED SUPERSUB AND RLC TOOK HIS ; SUPERSUB AND DESIGNED SUB FROM IT; BOTH PROGRAMS ARE SET UP TO ALLOW THE ; SELECTION AT ASSEMBLY TIME OF CREATING THE $$$.SUB ON THE LOGGED-IN DRIVE ; OR ON DRIVE A:. ; ; A FINAL DEFINITION OF THE INDIRECT COMMAND FILE ($$$.SUB OR SUBMIT ; FILE) IS PRESENTED AS FOLLOWS: ; ; "AN INDIRECT COMMAND FILE IS ONE WHICH CONTAINS ; A SERIES OF COMMANDS EXACTLY AS THEY WOULD BE ; ENTERED FROM A CP/M CONSOLE. THE SUBMIT COMMAND ; (OR SUB COMMAND) READS THIS FILES AND TRANSFORMS ; IT FOR PROCESSING BY THE CCPZ (THE $$$.SUB FILE). ; CCPZ WILL THEN EXECUTE THE COMMANDS INDICATED ; EXACTLY AS IF THEY WERE TYPED AT THE CONSOLE." ; ; HENCE, TO PERMIT THIS TO HAPPEN, THE $$$.SUB FILE MUST ALWAYS ; BE PRESENT ON A SPECIFIC DRIVE, AND A: IS THE CHOICE FOR SAID DRIVE. ; WITH THIS FACILITY ENGAGED AS SUCH, INDIRECT COMMAND FILES LIKE: ; ; DIR ; A: ; DIR ; ; CAN BE EXECUTED, EVEN THOUGH THE CURRENTLY LOGGED-IN DRIVE IS CHANGED ; DURING EXECUTION. IF THE $$$.SUB FILE WAS PRESENT ON THE CURRENTLY ; LOGGED-IN DRIVE, THE ABOVE SERIES OF COMMANDS WOULD NOT WORK SINCE THE ; CCPZ WOULD BE LOOKING FOR $$$.SUB ON THE LOGGED-IN DRIVE, AND SWITCHING ; LOGGED-IN DRIVES WITHOUT MOVING THE $$$.SUB FILE AS WELL WOULD CAUSE ; PROCESSING TO ABORT. ; FFFF = SUBA EQU TRUE ; SET TO TRUE TO HAVE $$$.SUB ALWAYS ON A: ; SET TO FALSE TO HAVE $$$.SUB ON THE LOGGED-IN DRIVE ; ; THE FOLLOWING FLAG ENABLES EXTENDED PROCESSING FOR USER-PROGRAM SUPPLIED ; COMMAND LINES. THIS IS FOR COMMAND LEVEL 3 OF CCPZ. UNDER THE CCPZ VERSION ; 4.0 PHILOSOPHY, THREE COMMAND LEVELS EXIST: ; ; (1) THAT COMMAND ISSUED BY THE USER FROM HIS CONSOLE AT THE '>' PROMPT ; (2) THAT COMMAND ISSUED BY A $$$.SUB FILE AT THE '$' PROMPT ; (3) THAT COMMAND ISSUED BY A USER PROGRAM BY PLACING THE COMMAND INTO ; CIBUFF AND SETTING THE CHARACTER COUNT IN CBUFF ; ; SETTING CLEVEL3 TO TRUE ENABLES EXTENDED PROCESSING OF THE THIRD LEVEL OF ; CCPZ COMMAND. ALL THE USER PROGRAM NEED DO IS TO STORE THE COMMAND LINE AND ; SET THE CHARACTER COUNT; CCPZ WILL INITIALIZE THE POINTERS PROPERLY, STORE ; THE ENDING ZERO PROPERLY, AND CAPITALIZE THE COMMAND LINE FOR PROCESSING. ; ONCE THE COMMAND LINE IS PROPERLY STORED, THE USER EXECUTES THE COMMAND LINE ; BY REENTERING THE CCPZ THROUGH CCPLOC [NOTE: THE C REGISTER MUST CONTAIN ; A VALID USER/DISK FLAG (SEE LOCATION 4) AT THIS TIME.] ; FFFF = CLEVEL3 EQU TRUE ;ENABLE COMMAND LEVEL 3 PROCESSING ; ; ;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES ; CP/M MACRO ASSEM 2.0 #005 CCPZ Version 4.1 0018 = NLINES EQU 24 ;NUMBER OF LINES ON CRT SCREEN FFFF = WIDE EQU TRUE ;TRUE IF WIDE DIR DISPLAY 007C = FENCE EQU '|' ;SEP CHAR BETWEEN DIR FILES ; FFFF = PGDFLT EQU TRUE ;SET TO FALSE TO DISABLE PAGING BY DEFAULT 0050 = PGDFLG EQU 'P' ;FOR TYPE COMMAND: PAGE OR NOT (DEP ON PGDFLT) ; THIS FLAG REVERSES THE DEFAULT EFFECT ; 000F = MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSABLE ; 0041 = SYSFLG EQU 'A' ;FOR DIR COMMAND: LIST $SYS AND $DIR ; 0053 = SOFLG EQU 'S' ;FOR DIR COMMAND: LIST $SYS FILES ONLY ; FFFF = SUPRES EQU TRUE ;SUPRESSES USER # REPORT FOR USER 0 ; 0000 = DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES ; 0024 = SPRMPT EQU '$' ;CCP PROMPT INDICATING SUBMIT COMMAND 003E = CPRMPT EQU '>' ;CCP PROMPT INDICATING USER COMMAND ; 0048 = NUMBASE EQU 'H' ;CHARACTER USED TO SWITCH FROM DEFAULT ; NUMBER BASE ; 0053 = SECTFLG EQU 'S' ;OPTION CHAR FOR SAVE COMMAND TO SAVE SECTORS ; ; END OF CUSTOMIZATION SECTION ; 000D = CR EQU 0DH 000A = LF EQU 0AH 0009 = TAB EQU 09H ; 0000 = WBOOT EQU BASE+0000H ;CP/M WARM BOOT ADDRESS 0004 = UDFLAG EQU BASE+0004H ;USER NUM IN HIGH NYBBLE, DISK IN LOW 0005 = BDOS EQU BASE+0005H ;BDOS FUNCTION CALL ENTRY PT 005C = TFCB EQU BASE+005CH ;DEFAULT FCB BUFFER 0080 = TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER 0100 = TPA EQU BASE+0100H ;BASE OF TPA ; ; ; MACROS TO PROVIDE Z80 EXTENSIONS ; MACROS INCLUDE: ; $-MACRO ;FIRST TURN OFF THE EXPANSIONS ; ; JR - JUMP RELATIVE ; JRC - JUMP RELATIVE IF CARRY ; JRNC - JUMP RELATIVE IF NO CARRY ; JRZ - JUMP RELATIVE IF ZERO ; JRNZ - JUMP RELATIVE IF NO ZERO ; DJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO ; LDIR - MOV @HL TO @DE FOR COUNT IN BC ; LXXD - LOAD DOUBLE REG DIRECT ; SXXD - STORE DOUBLE REG DIRECT ; ; CP/M MACRO ASSEM 2.0 #006 CCPZ Version 4.1 ; ; @GENDD MACRO USED FOR CHECKING AND GENERATING ; 8-BIT JUMP RELATIVE DISPLACEMENTS ; @GENDD MACRO ?DD ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS IF (?DD GT 7FH) AND (?DD LT 0FF80H) DB 100H ;DISPLACEMENT RANGE ERROR ON JUMP RELATIVE ELSE DB ?DD ENDIF ENDM ; ; ; Z80 MACRO EXTENSIONS ; JR MACRO ?N ;;JUMP RELATIVE DB 18H @GENDD ?N-$-1 ENDM ; JRC MACRO ?N ;;JUMP RELATIVE ON CARRY DB 38H @GENDD ?N-$-1 ENDM ; JRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY DB 30H @GENDD ?N-$-1 ENDM ; JRZ MACRO ?N ;;JUMP RELATIVE ON ZERO DB 28H @GENDD ?N-$-1 ENDM ; JRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO DB 20H @GENDD ?N-$-1 ENDM ; DJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO DB 10H @GENDD ?N-$-1 ENDM ; LDIR MACRO ;;LDIR DB 0EDH,0B0H ENDM ; LDED MACRO ?N ;;LOAD DE DIRECT DB 0EDH,05BH DW ?N ENDM ; LBCD MACRO ?N ;;LOAD BC DIRECT DB 0EDH,4BH CP/M MACRO ASSEM 2.0 #007 CCPZ Version 4.1 DW ?N ENDM ; SDED MACRO ?N ;;STORE DE DIRECT DB 0EDH,53H DW ?N ENDM ; SBCD MACRO ?N ;;STORE BC DIRECT DB 0EDH,43H DW ?N ENDM ; ; END OF Z80 MACRO EXTENSIONS ; ; ;**** SECTION 0 **** ; BD00 ORG CCPLOC ; ; ENTRY POINTS INTO CCPZ ; ; IF THE CCPZ IS ENTERED AT LOCATION CCPLOC (AT THE JMP TO CCP), THEN ; THE DEFAULT COMMAND IN CIBUFF WILL BE PROCESSED. IF THE CCPZ IS ENTERED ; AT LOCATION CCPLOC+3 (AT THE JMP TO CCP1), THEN THE DEFAULT COMMAND IN ; CIBUFF WILL NOT BE PROCESSED. ; ; NOTE: ENTRY INTO CCPZ IN THIS WAY IS PERMITTED UNDER CCPZ VERSION 4.0, ; BUT IN ORDER FOR THIS TO WORK, CIBUFF AND CBUFF MUST BE INITIALIZED PROPERLY ; AND THE C REGISTER MUST CONTAIN A VALID USER/DISK FLAG (SEE LOCATION 4: THE ; MOST SIGNIFICANT NYBBLE CONTAINS THE USER NUMBER AND THE LEAST SIGNIFICANT ; NYBBLE CONTAINS THE DISK NUMBER). ; ; SOME USER PROGRAMS (SUCH AS SYNONYM3) ATTEMPT TO USE THE DEFAULT ; COMMAND FACILITY. UNDER THE ORIGINAL CCP, IT WAS NECESSARY TO INITIALIZE ; THE POINTER AFTER THE RESERVED SPACE FOR THE COMMAND BUFFER TO POINT TO ; THE FIRST BYTE OF THE COMMAND BUFFER. UNDER VERSION 4.X OF CCPZ, THIS IS ; NO LONGER THE CASE. THE CIBPTR (COMMAND INPUT BUFFER POINTER) IS LOCATED ; TO BE COMPATIBLE WITH SUCH PROGRAMS (PROVIDED THEY DETERMINE THE BUFFER ; LENGTH FROM THE BYTE AT MBUFF [CCPLOC + 6]), BUT UNDER VERSION 4.X OF CCPZ ; THIS IS NO LONGER NECESSARY. CCPZ VERSION 4.X AUTOMATICALLY INITIALIZES ; THIS BUFFER POINTER IN ALL CASES. ; ENTRY: BD00 C304BE JMP CCP ; PROCESS POTENTIAL DEFAULT COMMAND BD03 C300BE JMP CCP1 ; DO NOT PROCESS POTENTIAL DEFAULT COMMAND ; ;**** SECTION 1 **** ; ; BUFFERS ET AL ; ; INPUT COMMAND LINE AND DEFAULT COMMAND ; ; THE COMMAND LINE TO BE EXECUTED IS STORED HERE. THIS COMMAND LINE ; IS GENERATED IN ONE OF THREE WAYS: ; CP/M MACRO ASSEM 2.0 #008 CCPZ Version 4.1 ; (1) BY THE USER ENTERING IT THROUGH THE BDOS READLN FUNCTION AT ; THE DU> PROMPT [USER INPUT FROM KEYBOARD] ; (2) BY THE SUBMIT FILE FACILITY PLACING IT THERE FROM A $$$.SUB ; FILE ; (3) BY AN EXTERNAL PROGRAM OR USER PLACING THE REQUIRED COMMAND ; INTO THIS BUFFER ; ; IN ALL CASES, THE COMMAND LINE IS PLACED INTO THE BUFFER STARTING AT ; CIBUFF. THIS COMMAND LINE IS TERMINATED BY THE LAST CHARACTER (NOT CARRIAGE ; RETURN), AND A CHARACTER COUNT OF ALL CHARACTERS IN THE COMMAND LINE ; UP TO AND INCLUDING THE LAST CHARACTER IS PLACED INTO LOCATION CBUFF ; (IMMEDIATELY BEFORE THE COMMAND LINE AT CIBUFF). THE PLACED COMMAND LINE ; IS THEN PARSED, INTERPRETED, AND THE INDICATED COMMAND IS EXECUTED. ; IF CLEVEL3 IS PERMITTED, A TERMINATING ZERO IS PLACED AFTER THE COMMAND ; (OTHERWISE THE USER PROGRAM HAS TO PLACE THIS ZERO) AND THE CIBPTR IS ; PROPERLY INITIALIZED (OTHERWISE THE USER PROGRAM HAS TO INIT THIS PTR). ; IF THE COMMAND IS PLACED BY A USER PROGRAM, ENTERING AT CCPLOC IS ENOUGH ; TO HAVE THE COMMAND PROCESSED. AGAIN, UNDER CCPZ VERSION 4.X, IT IS NOT ; NECESSARY TO STORE THE POINTER TO CIBUFF IN CIBPTR; CCPZ WILL DO THIS FOR ; THE CALLING PROGRAM IF CLEVEL3 IS MADE TRUE. ; ; WARNING: THE COMMAND LINE MUST NOT EXCEED BUFLEN CHARACTERS IN LENGTH. ; FOR USER PROGRAMS WHICH LOAD THIS COMMAND, THE VALUE OF BUFLEN CAN BE ; OBTAINED BY EXAMINING THE BYTE AT MBUFF (CCPLOC + 6). ; 0050 = BUFLEN EQU 80 ;MAXIMUM BUFFER LENGTH MBUFF: BD06 50 DB BUFLEN ;MAXIMUM BUFFER LENGTH CBUFF: BD07 00 DB 0 ;NUMBER OF VALID CHARS IN COMMAND LINE CIBUFF: BD08 2020202020 DB ' ' ;DEFAULT (COLD BOOT) COMMAND CIBUF: BD17 00 DB 0 ;COMMAND STRING TERMINATOR BD18 2020434350 DB ' CCPZ-V4.1 of 11/27/81 ' ;FOR DUMP IDENTIFICATION BD31 DS BUFLEN-($-CIBUFF)+1 ;TOTAL IS 'BUFLEN' BYTES ; CIBPTR: BD59 08BD DW CIBUFF ;POINTER TO COMMAND INPUT BUFFER CIPTR: BD5B 17BD DW CIBUF ;PTR TO CURR CMD FOR ERROR REPORTING ; BD5D DS 26 ;STACK AREA BD77 = STACK EQU $ ;TOP OF STACK ; ; FILE TYPE FOR COMMAND ; COMMSG: BD77 434F4D DB 'COM' ; ; SUBMIT FILE CONTROL BLOCK ; SUBFCB: IF SUBA ;IF $$$.SUB ON A: BD7A 01 DB 1 ;DISK NAME SET TO DEFAULT TO DRIVE A: ENDIF CP/M MACRO ASSEM 2.0 #009 CCPZ Version 4.1 ; IF NOT SUBA ;IF $$$.SUB ON CURRENT DRIVE DB 0 ;DISK NAME SET TO DEFAULT TO CURRENT DRIVE ENDIF ; BD7B 242424 DB '$$$' ;FILE NAME BD7E 2020202020 DB ' ' BD83 535542 DB 'SUB' ;FILE TYPE BD86 00 DB 0 ;EXTENT NUMBER BD87 00 DB 0 ;S1 SUBFS2: BD88 DS 1 ;S2 SUBFRC: BD89 DS 1 ;RECORD COUNT BD8A DS 16 ;DISK GROUP MAP SUBFCR: BD9A DS 1 ;CURRENT RECORD NUMBER ; ; COMMAND FILE CONTROL BLOCK ; FCBDN: BD9B DS 1 ;DISK NAME FCBFN: BD9C DS 8 ;FILE NAME FCBFT: BDA4 DS 3 ;FILE TYPE BDA7 DS 1 ;EXTENT NUMBER BDA8 DS 2 ;S1 AND S2 BDAA DS 1 ;RECORD COUNT FCBDM: BDAB DS 16 ;DISK GROUP MAP FCBCR: BDBB DS 1 ;CURRENT RECORD NUMBER ; ; OTHER BUFFERS ; PAGCNT: BDBC 16 DB NLINES-2 ;LINES LEFT ON PAGE CHRCNT: BDBD 00 DB 0 ;CHAR COUNT FOR TYPE ; ; CCP BUILT-IN COMMAND TABLE ; 0004 = NCHARS EQU 4 ;NUMBER OF CHARS/COMMAND ; ; CCP COMMAND NAME TABLE ; EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS ; CMDTBL: BDBE 44495220 DB 'DIR ' BDC2 9BC1 DW DIR BDC4 4C495354 DB 'LIST' BDC8 77C2 DW LIST BDCA 54595045 DB 'TYPE' BDCE 7BC2 DW TYPE BDD0 55534552 DB 'USER' CP/M MACRO ASSEM 2.0 #010 CCPZ Version 4.1 BDD4 D2C3 DW USER BDD6 44465520 DB 'DFU ' BDDA DCC3 DW DFU ; IF NOT RAS ;FOR NON-RAS BDDC 474F2020 DB 'GO ' BDE0 E9C3 DW GO BDE2 45524120 DB 'ERA ' BDE6 4CC2 DW ERA BDE8 53415645 DB 'SAVE' BDEC 14C3 DW SAVE BDEE 52454E20 DB 'REN ' BDF2 73C3 DW REN BDF4 47455420 DB 'GET ' BDF8 87C4 DW GET BDFA 4A554D50 DB 'JUMP' BDFE E4C3 DW JUMP ENDIF ; 000B = NCMNDS EQU ($-CMDTBL)/(NCHARS+2) ; ; ;**** SECTION 2 **** ; CCP STARTING POINTS ; ; START CCP AND DON'T PROCESS DEFAULT COMMAND STORED ; CCP1: BE00 AF XRA A ;SET NO DEFAULT COMMAND BE01 3207BD STA CBUFF ; ; START CCP AND POSSIBLY PROCESS DEFAULT COMMAND ; ; NOTE ON MODIFICATION BY RGF: BDOS RETURNS 0FFH IN ; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY ; FILE NAME CONTAINS A '$' IN IT. THIS IS NOW USED AS ; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH ; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES. ; CCP: BE04 3177BD LXI SP,STACK ;RESET STACK BE07 C5 PUSH B BE08 79 MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) BE09 1F RAR ;EXTRACT USER NUMBER BE0A 1F RAR BE0B 1F RAR BE0C 1F RAR BE0D E60F ANI 0FH BE0F 5F MOV E,A ;SET USER NUMBER BE10 CD4CBF CALL SETUSR BE13 CD06BF CALL RESET ;RESET DISK SYSTEM BE16 3229BE STA RNGSUB ;SAVE SUBMIT CLUE FROM DRIVE A: BE19 C1 POP B BE1A 79 MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) BE1B E60F ANI 0FH ;EXTRACT DEFAULT DISK DRIVE BE1D 3260BF STA TDRIVE ;SET IT CP/M MACRO ASSEM 2.0 #011 CCPZ Version 4.1 BE20 JRZ NOLOG ;SKIP IF 0...ALREADY LOGGED BE22 CD0BBF CALL LOGIN ;LOG IN DEFAULT DISK ; IF NOT SUBA ;IF $$$.SUB IS ON CURRENT DRIVE STA RNGSUB ;BDOS '$' CLUE ENDIF ; NOLOG: BE25 117ABD LXI D,SUBFCB ;CHECK FOR $$$.SUB ON CURRENT DISK BE29 = RNGSUB EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION BE28 3E00 MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG BE2A B7 ORA A ;SET FLAGS ON CLUE BE2B 2F CMA ;PREPARE FOR COMING 'CMA' BE2C C425BF CNZ SEAR1 BE2F 2F CMA ;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT BE30 3229BE STA RNGSUB ;SET FLAG (0=NO $$$.SUB) BE33 3A07BD LDA CBUFF ;EXECUTE DEFAULT COMMAND? BE36 B7 ORA A ;0=NO BE37 JRNZ RS1 ; ; PROMPT USER AND INPUT COMMAND LINE FROM HIM ; RESTRT: BE39 3177BD LXI SP,STACK ;RESET STACK ; ; PRINT PROMPT (DU>) ; BE3C CDA9BE CALL CRLF ;PRINT PROMPT BE3F CDFBBE CALL GETDRV ;CURRENT DRIVE IS PART OF PROMPT BE42 C641 ADI 'A' ;CONVERT TO ASCII A-P BE44 CDB0BE CALL CONOUT BE47 CD4ABF CALL GETUSR ;GET USER NUMBER ; IF SUPRES ;IF SUPPRESSING USR # REPORT FOR USR 0 BE4A B7 ORA A BE4B JRZ RS000 ENDIF ; BE4D FE0A CPI 10 ;USER < 10? BE4F JRC RS00 BE51 D60A SUI 10 ;SUBTRACT 10 FROM IT BE53 F5 PUSH PSW ;SAVE IT BE54 3E31 MVI A,'1' ;OUTPUT 10'S DIGIT BE56 CDB0BE CALL CONOUT BE59 F1 POP PSW RS00: BE5A C630 ADI '0' ;OUTPUT 1'S DIGIT (CONVERT TO ASCII) BE5C CDB0BE CALL CONOUT ; ; READ INPUT LINE FROM USER OR $$$.SUB ; RS000: BE5F CD6EBF CALL REDBUF ;INPUT COMMAND LINE FROM USER (OR $$$.SUB) ; ; PROCESS INPUT LINE ; CP/M MACRO ASSEM 2.0 #012 CCPZ Version 4.1 RS1: ; IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED BE62 CDCFBF CALL CNVBUF ;CAPITALIZE COMMAND LINE, PLACE ENDING 0, ; AND SET CIBPTR VALUE ENDIF ; BE65 CDFFBE CALL DEFDMA ;SET TBUFF TO DMA ADDRESS BE68 CDFBBE CALL GETDRV ;GET DEFAULT DRIVE NUMBER BE6B 3260BF STA TDRIVE ;SET IT BE6E CDE7C0 CALL SCANER ;PARSE COMMAND NAME FROM COMMAND LINE BE71 C4F6BF CNZ ERROR ;ERROR IF COMMAND NAME CONTAINS A '?' BE74 118ABE LXI D,RSTCCP ;PUT RETURN ADDRESS OF COMMAND BE77 D5 PUSH D ;ON THE STACK BE78 3ADEC0 LDA TEMPDR ;IS COMMAND OF FORM 'D:COMMAND'? BE7B B7 ORA A ;NZ=YES BE7C C2EEC3 JNZ COM ; IMMEDIATELY BE7F CD79C1 CALL CMDSER ;SCAN FOR CCP-RESIDENT COMMAND BE82 C2EEC3 JNZ COM ;NOT CCP-RESIDENT BE85 7E MOV A,M ;FOUND IT: GET LOW-ORDER PART BE86 23 INX H ;GET HIGH-ORDER PART BE87 66 MOV H,M ;STORE HIGH BE88 6F MOV L,A ;STORE LOW BE89 E9 PCHL ;EXECUTE CCP ROUTINE ; ; ENTRY POINT FOR RESTARTING CCP AND LOGGING IN DEFAULT DRIVE ; RSTCCP: BE8A CDD3C0 CALL DLOGIN ;LOG IN DEFAULT DRIVE ; ; ENTRY POINT FOR RESTARTING CCP WITHOUT LOGGING IN DEFAULT DRIVE ; RCCPNL: BE8D CDE7C0 CALL SCANER ;EXTRACT NEXT TOKEN FROM COMMAND LINE BE90 3A9CBD LDA FCBFN ;GET FIRST CHAR OF TOKEN BE93 D620 SUI ' ' ;ANY CHAR? BE95 21DEC0 LXI H,TEMPDR BE98 B6 ORA M BE99 C2F6BF JNZ ERROR BE9C JR RESTRT ; ; NO FILE ERROR MESSAGE ; PRNNF: BE9E CDE3BE CALL PRINTC ;NO FILE MESSAGE BEA1 4E6F204669 DB 'No Fil','e'+80H BEA8 C9 RET ; ;**** SECTION 3 **** ; I/O UTILITIES ; ; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC ; ; ; OUTPUT ; CP/M MACRO ASSEM 2.0 #013 CCPZ Version 4.1 CRLF: BEA9 3E0D MVI A,CR BEAB CDB0BE CALL CONOUT BEAE 3E0A MVI A,LF ;FALL THRU TO CONOUT ; CONOUT: BEB0 C5 PUSH B BEB1 0E02 MVI C,02H OUTPUT: BEB3 5F MOV E,A BEB4 E5 PUSH H BEB5 CD0500 CALL BDOS BEB8 E1 POP H BEB9 C1 POP B BEBA C9 RET ; CONIN: BEBB 0E01 MVI C,01H ;GET CHAR FROM CON: WITH ECHO BEBD JR BDOSB ; LCOUT: BEBF F5 PUSH PSW ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG BEC1 = PRFLG EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION BEC0 3E00 MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG BEC2 B7 ORA A ;0=TYPE BEC3 JRZ LC1 BEC5 F1 POP PSW ;GET CHAR ; ; OUTPUT CHAR IN REG A TO LIST DEVICE ; LSTOUT: BEC6 C5 PUSH B BEC7 0E05 MVI C,05H BEC9 JR OUTPUT LC1: BECB F1 POP PSW ;GET CHAR BECC F5 PUSH PSW BECD CDB0BE CALL CONOUT ;OUTPUT TO CON: BED0 F1 POP PSW BED1 FE0A CPI LF ;CHECK FOR PAGING BED3 CAFBC2 JZ PAGER BED6 C9 RET ; READF: BED7 119BBD LXI D,FCBDN ;FALL THRU TO READ READ: BEDA 0E14 MVI C,14H ;FALL THRU TO BDOSB ; ; CALL BDOS AND SAVE BC ; BDOSB: BEDC C5 PUSH B BEDD CD0500 CALL BDOS BEE0 C1 POP B BEE1 B7 ORA A BEE2 C9 RET CP/M MACRO ASSEM 2.0 #014 CCPZ Version 4.1 ; ; PRINT STRING (ENDING IN 0) PTED TO BY RET ADR;START WITH ; PRINTC: BEE3 F5 PUSH PSW ;SAVE FLAGS BEE4 CDA9BE CALL CRLF ;NEW LINE BEE7 F1 POP PSW ; PRINT: BEE8 E3 XTHL ;GET PTR TO STRING BEE9 F5 PUSH PSW ;SAVE FLAGS BEEA CDF0BE CALL PRIN1 ;PRINT STRING BEED F1 POP PSW ;GET FLAGS BEEE E3 XTHL ;RESTORE HL AND RET ADR BEEF C9 RET ; ; PRINT STRING (ENDING IN 0) PTED TO BY HL ; PRIN1: BEF0 7E MOV A,M ;GET NEXT BYTE BEF1 CDB0BE CALL CONOUT ;PRINT CHAR BEF4 7E MOV A,M ;GET NEXT BYTE AGAIN FOR TEST BEF5 23 INX H ;PT TO NEXT BYTE BEF6 B7 ORA A ;SET FLAGS BEF7 C8 RZ ;DONE IF ZERO BEF8 F8 RM ;DONE IF MSB SET BEF9 JR PRIN1 ; ; BDOS FUNCTION ROUTINES ; ; ; RETURN NUMBER OF CURRENT DISK IN A ; GETDRV: BEFB 0E19 MVI C,19H BEFD JR BDOSJP ; ; SET 80H AS DMA ADDRESS ; DEFDMA: BEFF 118000 LXI D,TBUFF ;80H=TBUFF DMASET: BF02 0E1A MVI C,1AH BF04 JR BDOSJP ; RESET: BF06 0E0D MVI C,0DH BDOSJP: BF08 C30500 JMP BDOS ; LOGIN: BF0B 5F MOV E,A BF0C 0E0E MVI C,0EH BF0E JR BDOSJP ;SAVE SOME CODE SPACE ; OPENF: CP/M MACRO ASSEM 2.0 #015 CCPZ Version 4.1 BF10 AF XRA A BF11 32BBBD STA FCBCR BF14 119BBD LXI D,FCBDN ;FALL THRU TO OPEN ; OPEN: BF17 0E0F MVI C,0FH ;FALL THRU TO GRBDOS ; GRBDOS: BF19 CD0500 CALL BDOS BF1C 3C INR A ;SET ZERO FLAG FOR ERROR RETURN BF1D C9 RET ; CLOSE: BF1E 0E10 MVI C,10H BF20 JR GRBDOS ; SEARF: BF22 119BBD LXI D,FCBDN ;SPECIFY FCB SEAR1: BF25 0E11 MVI C,11H BF27 JR GRBDOS ; SEARN: BF29 0E12 MVI C,12H BF2B JR GRBDOS ; ; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO ; SUBKIL: BF2D 2129BE LXI H,RNGSUB ;CHECK FOR SUBMIT FILE IN EXECUTION BF30 7E MOV A,M BF31 B7 ORA A ;0=NO BF32 C8 RZ BF33 3600 MVI M,0 ;ABORT SUBMIT FILE BF35 117ABD LXI D,SUBFCB ;DELETE $$$.SUB ; DELETE: BF38 0E13 MVI C,13H BF3A JR BDOSJP ;SAVE MORE SPACE ; WRITE: BF3C 0E15 MVI C,15H BF3E C3DCBE JMP BDOSB ; CREATE: BF41 0E16 MVI C,16H BF43 JR GRBDOS ; ; RESET USER NUMBER IF CHANGED ; RESETUSR: BF46 = TMPUSR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION BF45 3E00 MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TMPUSR BF47 5F MOV E,A ;PLACE IN E BF48 JR SETUSR ;THEN GO SET USER GETUSR: CP/M MACRO ASSEM 2.0 #016 CCPZ Version 4.1 BF4A 1EFF MVI E,0FFH ;GET CURRENT USER NUMBER SETUSR: BF4C 0E20 MVI C,20H ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH) BF4E JR BDOSJP ;MORE SPACE SAVING ; ; END OF BDOS FUNCTIONS ; ; ;**** SECTION 4 **** ; CCP UTILITIES ; ; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK ; SETUD: BF50 CD4ABF CALL GETUSR ;GET NUMBER OF CURRENT USER BF53 87 ADD A ;PLACE IT IN HIGH NYBBLE BF54 87 ADD A BF55 87 ADD A BF56 87 ADD A BF57 2160BF LXI H,TDRIVE ;MASK IN DEFAULT DRIVE NUMBER (LOW NYBBLE) BF5A B6 ORA M ;MASK IN BF5B 320400 STA UDFLAG ;SET USER/DISK NUMBER BF5E C9 RET ; ; SET USER/DISK FLAG TO USER 0 AND DEFAULT DISK ; SETU0D: BF60 = TDRIVE EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION BF5F 3E00 MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TDRIVE BF61 320400 STA UDFLAG ;SET USER/DISK NUMBER BF64 C9 RET ; ; CONVERT CHAR IN A TO UPPER CASE ; UCASE: BF65 FE61 CPI 61H ;LOWER-CASE A BF67 D8 RC BF68 FE7B CPI 7BH ;GREATER THAN LOWER-CASE Z? BF6A D0 RNC BF6B E65F ANI 5FH ;CAPITALIZE BF6D C9 RET ; ; INPUT NEXT COMMAND TO CCP ; THIS ROUTINE DETERMINES IF A SUBMIT FILE IS BEING PROCESSED ; AND EXTRACTS THE COMMAND LINE FROM IT IF SO OR FROM THE USER'S CONSOLE ; REDBUF: BF6E 3A29BE LDA RNGSUB ;SUBMIT FILE CURRENTLY IN EXECUTION? BF71 B7 ORA A ;0=NO BF72 JRZ RB1 ;GET LINE FROM CONSOLE IF NOT BF74 117ABD LXI D,SUBFCB ;OPEN $$$.SUB BF77 D5 PUSH D ;SAVE DE BF78 CD17BF CALL OPEN BF7B D1 POP D ;RESTORE DE BF7C JRZ RB1 ;ERASE $$$.SUB IF END OF FILE AND GET CMND BF7E 3A89BD LDA SUBFRC ;GET VALUE OF LAST RECORD IN FILE CP/M MACRO ASSEM 2.0 #017 CCPZ Version 4.1 BF81 3D DCR A ;PT TO NEXT TO LAST RECORD BF82 329ABD STA SUBFCR ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB BF85 CDDABE CALL READ ;DE=SUBFCB BF88 JRNZ RB1 ;ABORT $$$.SUB IF ERROR IN READING LAST REC BF8A 1107BD LXI D,CBUFF ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CBUFF BF8D 218000 LXI H,TBUFF ; FROM TBUFF BF90 015000 LXI B,BUFLEN ;NUMBER OF BYTES BF93 LDIR BF95 2188BD LXI H,SUBFS2 ;PT TO S2 OF $$$.SUB FCB BF98 3600 MVI M,0 ;SET S2 TO ZERO BF9A 23 INX H ;PT TO RECORD COUNT BF9B 35 DCR M ;DECREMENT RECORD COUNT OF $$$.SUB BF9C 117ABD LXI D,SUBFCB ;CLOSE $$$.SUB BF9F CD1EBF CALL CLOSE BFA2 JRZ RB1 ;ABORT $$$.SUB IF ERROR BFA4 3E24 MVI A,SPRMPT ;PRINT SUBMIT PROMPT BFA6 CDB0BE CALL CONOUT BFA9 2108BD LXI H,CIBUFF ;PRINT COMMAND LINE FROM $$$.SUB BFAC CDF0BE CALL PRIN1 BFAF CDE5BF CALL BREAK ;CHECK FOR ABORT (ANY CHAR) ; IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED BFB2 C8 RZ ;IF (NO ABORT), RETURN TO CALLER AND RUN ENDIF ; IF NOT CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED JRZ CNVBUF ;IF (NO ABORT), CAPITALIZE COMMAND ENDIF ; BFB3 CD2DBF CALL SUBKIL ;KILL $$$.SUB IF ABORT BFB6 C339BE JMP RESTRT ;RESTART CCP ; ; INPUT COMMAND LINE FROM USER CONSOLE ; RB1: BFB9 CD2DBF CALL SUBKIL ;ERASE $$$.SUB IF PRESENT BFBC CD50BF CALL SETUD ;SET USER AND DISK BFBF 3E3E MVI A,CPRMPT ;PRINT PROMPT BFC1 CDB0BE CALL CONOUT BFC4 0E0A MVI C,0AH ;READ COMMAND LINE FROM USER BFC6 1106BD LXI D,MBUFF BFC9 CD0500 CALL BDOS ; IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED BFCC C35FBF JMP SETU0D ;SET CURRENT DISK NUMBER IN LOWER PARAMS ENDIF ; IF NOT CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED CALL SETU0D ;SET CURRENT DISK NUMBER IF LOWER PARAMS ; AND FALL THRU TO CNVBUF ENDIF ; ; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET PTR FOR PARSING ; CNVBUF: BFCF 2107BD LXI H,CBUFF ;PT TO USER'S COMMAND CP/M MACRO ASSEM 2.0 #018 CCPZ Version 4.1 BFD2 46 MOV B,M ;CHAR COUNT IN B BFD3 04 INR B ;ADD 1 IN CASE OF ZERO CB1: BFD4 23 INX H ;PT TO 1ST VALID CHAR BFD5 7E MOV A,M ;CAPITALIZE COMMAND CHAR BFD6 CD65BF CALL UCASE BFD9 77 MOV M,A BFDA DJNZ CB1 ;CONTINUE TO END OF COMMAND LINE CB2: BFDC 3600 MVI M,0 ;STORE ENDING BFDE 2108BD LXI H,CIBUFF ;SET COMMAND LINE PTR TO 1ST CHAR BFE1 2259BD SHLD CIBPTR BFE4 C9 RET ; ; CHECK FOR ANY CHAR FROM USER CONSOLE;RET W/ZERO SET IF NONE ; BREAK: BFE5 D5 PUSH D ;SAVE DE BFE6 0E0B MVI C,11 ;CSTS CHECK BFE8 CDDCBE CALL BDOSB BFEB C4BBBE CNZ CONIN ;GET INPUT CHAR BRKBK: BFEE D1 POP D BFEF C9 RET ; ; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT. ; USRNUM: BFF0 CD42C0 CALL NUMBER BFF3 FE10 CPI MAXUSR+1 BFF5 D8 RC ; ; INVALID COMMAND -- PRINT IT ; ERROR: BFF6 CDA9BE CALL CRLF ;NEW LINE BFF9 2A5BBD LHLD CIPTR ;PT TO BEGINNING OF COMMAND LINE ERR2: BFFC 7E MOV A,M ;GET CHAR BFFD FE21 CPI ' '+1 ;SIMPLE '?' IF OR LESS BFFF JRC ERR1 C001 E5 PUSH H ;SAVE PTR TO ERROR COMMAND CHAR C002 CDB0BE CALL CONOUT ;PRINT COMMAND CHAR C005 E1 POP H ;GET PTR C006 23 INX H ;PT TO NEXT C007 JR ERR2 ;CONTINUE ERR1: C009 CDE8BE CALL PRINT ;PRINT '?' C00C BF DB '?'+80H C00D CD2DBF CALL SUBKIL ;TERMINATE ACTIVE $$$.SUB IF ANY C010 C339BE JMP RESTRT ;RESTART CCP ; ; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET ; SDELM: C013 1A LDAX D CP/M MACRO ASSEM 2.0 #019 CCPZ Version 4.1 C014 B7 ORA A ;0=DELIMITER C015 C8 RZ C016 FE20 CPI ' ' ;ERROR IF < C018 JRC ERROR C01A C8 RZ ;=DELIMITER C01B FE3D CPI '=' ;'='=DELIMITER C01D C8 RZ C01E FE5F CPI 5FH ;UNDERSCORE=DELIMITER C020 C8 RZ C021 FE2E CPI '.' ;'.'=DELIMITER C023 C8 RZ C024 FE3A CPI ':' ;':'=DELIMITER C026 C8 RZ C027 FE3B CPI ';' ;';'=DELIMITER C029 C8 RZ C02A FE3C CPI '<' ;'<'=DELIMITER C02C C8 RZ C02D FE3E CPI '>' ;'>'=DELIMITER C02F C9 RET ; ; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK ; ADVAN: C030 LDED CIBPTR ; ; SKIP STRING PTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING ; OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN) ; SBLANK: C034 1A LDAX D C035 B7 ORA A C036 C8 RZ C037 FE20 CPI ' ' C039 C0 RNZ C03A 13 INX D C03B JR SBLANK ; ; ADD A TO HL (HL=HL+A) ; ADDAH: C03D 85 ADD L C03E 6F MOV L,A C03F D0 RNC C040 24 INR H C041 C9 RET ; ; EXTRACT DECIMAL NUMBER FROM COMMAND LINE ; RETURN WITH VALUE IN REG A;ALL REGISTERS MAY BE AFFECTED ; NUMBER: C042 CDE7C0 CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN C045 21A6BD LXI H,FCBFN+10 ;PT TO END OF TOKEN FOR CONVERSION C048 060B MVI B,11 ;11 CHARS MAX ; ; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER ; CP/M MACRO ASSEM 2.0 #020 CCPZ Version 4.1 NUMS: C04A 7E MOV A,M ;GET CHARS FROM END, SEARCHING FOR SUFFIX C04B 2B DCX H ;BACK UP C04C FE20 CPI ' ' ;SPACE? C04E JRNZ NUMS1 ;CHECK FOR SUFFIX C050 DJNZ NUMS ;COUNT DOWN C052 JR NUM0 ;BY DEFAULT, PROCESS NUMS1: C054 FE48 CPI NUMBASE ;CHECK AGAINST BASE SWITCH FLAG C056 JRZ HNUM0 ; ; PROCESS DECIMAL NUMBER ; NUM0: C058 219CBD LXI H,FCBFN ;PT TO BEGINNING OF TOKEN C05B 010011 LXI B,1100H ;C=ACCUMULATED VALUE, B=CHAR COUNT ; (C=0, B=11) NUM1: C05E 7E MOV A,M ;GET CHAR C05F FE20 CPI ' ' ;DONE IF C061 JRZ NUM2 C063 23 INX H ;PT TO NEXT CHAR C064 D630 SUI '0' ;CONVERT TO BINARY (ASCII 0-9 TO BINARY) C066 FE0A CPI 10 ;ERROR IF >= 10 C068 JRNC NUMERR C06A 57 MOV D,A ;DIGIT IN D C06B 79 MOV A,C ;NEW VALUE = OLD VALUE * 10 C06C 07 RLC C06D 07 RLC C06E 07 RLC C06F 81 ADD C ;CHECK FOR RANGE ERROR C070 JRC NUMERR C072 81 ADD C ;CHECK FOR RANGE ERROR C073 JRC NUMERR C075 82 ADD D ;NEW VALUE = OLD VALUE * 10 + DIGIT C076 JRC NUMERR ;CHECK FOR RANGE ERROR C078 4F MOV C,A ;SET NEW VALUE C079 DJNZ NUM1 ;COUNT DOWN ; ; RETURN FROM NUMBER ; NUM2: C07B 79 MOV A,C ;GET ACCUMULATED VALUE C07C C9 RET ; ; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION ; NUMERR: C07D C3F6BF JMP ERROR ;USE ERROR ROUTINE - THIS IS RELATIVE PT ; ; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE ; RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED ; HEXNUM: C080 CDE7C0 CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN HNUM0: CP/M MACRO ASSEM 2.0 #021 CCPZ Version 4.1 C083 219CBD LXI H,FCBFN ;PT TO TOKEN FOR CONVERSION C086 110000 LXI D,0 ;DE=ACCUMULATED VALUE C089 060B MVI B,11 ;B=CHAR COUNT HNUM1: C08B 7E MOV A,M ;GET CHAR C08C FE20 CPI ' ' ;DONE? C08E JRZ HNUM3 ;RETURN IF SO C090 FE48 CPI 'H' ;DONE IF H SUFFIX C092 JRZ HNUM3 C094 D630 SUI '0' ;CONVERT TO BINARY C096 JRC NUMERR ;RETURN AND DONE IF ERROR C098 FE0A CPI 10 ;0-9? C09A JRC HNUM2 C09C D607 SUI 7 ;A-F? C09E FE10 CPI 10H ;ERROR? C0A0 JRNC NUMERR HNUM2: C0A2 23 INX H ;PT TO NEXT CHAR C0A3 4F MOV C,A ;DIGIT IN C C0A4 7A MOV A,D ;GET ACCUMULATED VALUE C0A5 07 RLC ;EXCHANGE NYBBLES C0A6 07 RLC C0A7 07 RLC C0A8 07 RLC C0A9 E6F0 ANI 0F0H ;MASK OUT LOW NYBBLE C0AB 57 MOV D,A C0AC 7B MOV A,E ;SWITCH LOW-ORDER NYBBLES C0AD 07 RLC C0AE 07 RLC C0AF 07 RLC C0B0 07 RLC C0B1 5F MOV E,A ;HIGH NYBBLE OF E=NEW HIGH OF E, ; LOW NYBBLE OF E=NEW LOW OF D C0B2 E60F ANI 0FH ;GET NEW LOW OF D C0B4 B2 ORA D ;MASK IN HIGH OF D C0B5 57 MOV D,A ;NEW HIGH BYTE IN D C0B6 7B MOV A,E C0B7 E6F0 ANI 0F0H ;MASK OUT LOW OF E C0B9 B1 ORA C ;MASK IN NEW LOW C0BA 5F MOV E,A ;NEW LOW BYTE IN E C0BB DJNZ HNUM1 ;COUNT DOWN ; ; RETURN FROM HEXNUM ; HNUM3: C0BD EB XCHG ;RETURNED VALUE IN HL C0BE 7D MOV A,L ;LOW-ORDER BYTE IN A C0BF C9 RET ; ; PT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C ; DIRPTR: C0C0 218000 LXI H,TBUFF ;PT TO TEMP BUFFER C0C3 81 ADD C ;PT TO 1ST BYTE OF DIR ENTRY C0C4 CD3DC0 CALL ADDAH ;PT TO DESIRED BYTE IN DIR ENTRY C0C7 7E MOV A,M ;GET DESIRED BYTE CP/M MACRO ASSEM 2.0 #022 CCPZ Version 4.1 C0C8 C9 RET ; ; CHECK FOR SPECIFIED DRIVE AND LOG IT IN IF NOT DEFAULT ; SLOGIN: C0C9 AF XRA A ;SET FCBDN FOR DEFAULT DRIVE C0CA 329BBD STA FCBDN C0CD CDDDC0 CALL COMLOG ;CHECK DRIVE C0D0 C8 RZ C0D1 JR DLOG5 ;DO LOGIN OTHERWISE ; ; CHECK FOR SPECIFIED DRIVE AND LOG IN DEFAULT DRIVE IF SPECIFIED<>DEFAULT ; DLOGIN: C0D3 CDDDC0 CALL COMLOG ;CHECK DRIVE C0D6 C8 RZ ;ABORT IF SAME C0D7 3A60BF LDA TDRIVE ;LOG IN DEFAULT DRIVE ; C0DA C30BBF DLOG5: JMP LOGIN ; ; ROUTINE COMMON TO BOTH LOGIN ROUTINES; ON EXIT, Z SET MEANS ABORT ; COMLOG: C0DE = TEMPDR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION C0DD 3E00 MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TEMPDR C0DF B7 ORA A ;0=NO C0E0 C8 RZ C0E1 3D DCR A ;COMPARE IT AGAINST DEFAULT C0E2 2160BF LXI H,TDRIVE C0E5 BE CMP M C0E6 C9 RET ;ABORT IF SAME ; ; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN; ; FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP); ; ON INPUT, CIBPTR PTS TO CHAR AT WHICH TO START SCAN; ; ON OUTPUT, CIBPTR PTS TO CHAR AT WHICH TO CONTINUE AND ZERO FLAG IS RESET ; IF '?' IS IN TOKEN ; SCANER: C0E7 AF XRA A ;A=0 TO START AT DRIVE SPECIFICATION BYTE SCAN1: C0E8 219BBD LXI H,FCBDN ;POINT TO FCBDN C0EB CD3DC0 CALL ADDAH ;OFFSET INTO FCB C0EE E5 PUSH H C0EF E5 PUSH H C0F0 AF XRA A ;SET TEMPORARY DRIVE NUMBER TO DEFAULT C0F1 32DEC0 STA TEMPDR C0F4 CD30C0 CALL ADVAN ;SKIP TO NON-BLANK OR END OF LINE C0F7 SDED CIPTR ;SET PTR TO NON-BLANK OR END OF LINE C0FB E1 POP H ;GET PTR TO NEXT BYTE IN FCBDN C0FC 1A LDAX D ;END OF LINE? C0FD B7 ORA A ;0=YES C0FE JRZ SCAN2 C100 DE40 SBI 'A'-1 ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER C102 47 MOV B,A ;STORE NUMBER (A:=0, B:=1, ETC) IN B C103 13 INX D ;PT TO NEXT CHAR CP/M MACRO ASSEM 2.0 #023 CCPZ Version 4.1 C104 1A LDAX D ;SEE IF IT IS A COLON (:) C105 FE3A CPI ':' C107 JRZ SCAN3 ;YES, WE HAVE A DRIVE SPEC C109 1B DCX D ;NO, BACK UP PTR TO FIRST NON-BLANK CHAR SCAN2: C10A 3A60BF LDA TDRIVE ;SET 1ST BYTE OF FCBDN AS DEFAULT DRIVE C10D 77 MOV M,A C10E JR SCAN4 SCAN3: C110 78 MOV A,B ;WE HAVE A DRIVE SPEC C111 32DEC0 STA TEMPDR ;SET TEMPORARY DRIVE C114 70 MOV M,B ;SET 1ST BYTE OF FCBDN AS SPECIFIED DRIVE C115 13 INX D ;PT TO BYTE AFTER ':' ; ; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP ; SCAN4: C116 0608 MVI B,8 ;MAX OF 8 CHARS IN FILE NAME SCAN5: C118 CD13C0 CALL SDELM ;DONE IF DELIMITER ENCOUNTERED - FILL C11B JRZ SCAN9 C11D 23 INX H ;PT TO NEXT BYTE IN FCBDN C11E FE2A CPI '*' ;IS (DE) A WILD CARD? C120 JRNZ SCAN6 ;CONTINUE IF NOT C122 363F MVI M,'?' ;PLACE '?' IN FCBDN AND DON'T ADVANCE DE IF SO C124 JR SCAN7 SCAN6: C126 77 MOV M,A ;STORE FILENAME CHAR IN FCBDN C127 13 INX D ;PT TO NEXT CHAR IN COMMAND LINE SCAN7: C128 DJNZ SCAN5 ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED SCAN8: C12A CD13C0 CALL SDELM ;8 CHARS OR MORE - SKIP UNTIL DELIMITER C12D JRZ SCAN10 ;ZERO FLAG SET IF DELIMITER FOUND C12F 13 INX D ;PT TO NEXT CHAR IN COMMAND LINE C130 JR SCAN8 SCAN9: C132 23 INX H ;PT TO NEXT BYTE IN FCBDN C133 3620 MVI M,' ' ;FILL FILENAME PART WITH C135 DJNZ SCAN9 ; ; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP ; SCAN10: C137 0603 MVI B,3 ;PREPARE TO EXTRACT TYPE C139 FE2E CPI '.' ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE C13B JRNZ SCAN15 ;FILL FILE TYPE BYTES WITH C13D 13 INX D ;PT TO CHAR IN COMMAND LINE AFTER '.' SCAN11: C13E CD13C0 CALL SDELM ;CHECK FOR DELIMITER C141 JRZ SCAN15 ;FILL REST OF TYPE IF IT IS A DELIMITER C143 23 INX H ;PT TO NEXT BYTE IN FCBDN C144 FE2A CPI '*' ;WILD? C146 JRNZ SCAN12 ;STORE CHAR IF NOT WILD C148 363F MVI M,'?' ;STORE '?' AND DON'T ADVANCE COMMAND LINE PTR C14A JR SCAN13 CP/M MACRO ASSEM 2.0 #024 CCPZ Version 4.1 SCAN12: C14C 77 MOV M,A ;STORE CHAR IN FCBDN C14D 13 INX D ;PT TO NEXT CHAR IN COMMAND LINE SCAN13: C14E DJNZ SCAN11 ;COUNT DOWN CHARS IN FILE TYPE (3 MAX) SCAN14: C150 CD13C0 CALL SDELM ;SKIP REST OF CHARS AFTER 3-CHAR TYPE TO C153 JRZ SCAN16 ; DELIMITER C155 13 INX D C156 JR SCAN14 SCAN15: C158 23 INX H ;FILL IN REST OF TYP WITH C159 3620 MVI M,' ' C15B DJNZ SCAN15 ; ; FILL IN EX, S1, S2, AND RC WITH ZEROES ; SCAN16: C15D 0604 MVI B,4 ;4 BYTES SCAN17: C15F 23 INX H ;PT TO NEXT BYTE IN FCBDN C160 3600 MVI M,0 C162 DJNZ SCAN17 ; ; SCAN COMPLETE -- DE PTS TO DELIMITER BYTE AFTER TOKEN ; C164 SDED CIBPTR ; ; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN FILENAME.TYP ; C168 E1 POP H ;GET PTR TO FCBDN IN HL C169 010B00 LXI B,11 ;SCAN FOR '?' IN FILENAME.TYP (C=11 BYTES) SCAN18: C16C 23 INX H ;PT TO NEXT BYTE IN FCBDN C16D 7E MOV A,M C16E FE3F CPI '?' C170 JRNZ SCAN19 C172 04 INR B ;B<>0 TO INDICATE '?' ENCOUNTERED SCAN19: C173 0D DCR C ;COUNT DOWN C174 JRNZ SCAN18 C176 78 MOV A,B ;A=B=NUMBER OF '?' IN FILENAME.TYP C177 B7 ORA A ;SET ZERO FLAG TO INDICATE ANY '?' C178 C9 RET ; ; CMDTBL (COMMAND TABLE) SCANNER ; ON RETURN, HL PTS TO ADDRESS OF COMMAND IF CCP-RESIDENT ; ON RETURN, ZERO FLAG SET MEANS CCP-RESIDENT COMMAND ; CMDSER: C179 21BEBD LXI H,CMDTBL ;PT TO COMMAND TABLE C17C 0E0B MVI C,NCMNDS ;SET COMMAND COUNTER CMS1: C17E 119CBD LXI D,FCBFN ;PT TO STORED COMMAND NAME C181 0604 MVI B,NCHARS ;NUMBER OF CHARS/COMMAND (8 MAX) CMS2: CP/M MACRO ASSEM 2.0 #025 CCPZ Version 4.1 C183 1A LDAX D ;COMPARE AGAINST TABLE ENTRY C184 BE CMP M C185 JRNZ CMS3 ;NO MATCH C187 13 INX D ;PT TO NEXT CHAR C188 23 INX H C189 DJNZ CMS2 ;COUNT DOWN C18B 1A LDAX D ;NEXT CHAR IN INPUT COMMAND MUST BE C18C FE20 CPI ' ' C18E JRNZ CMS4 C190 C9 RET ;COMMAND IS CCP-RESIDENT (ZERO FLAG SET) CMS3: C191 23 INX H ;SKIP TO NEXT COMMAND TABLE ENTRY C192 DJNZ CMS3 CMS4: C194 23 INX H ;SKIP ADDRESS C195 23 INX H C196 0D DCR C ;DECREMENT TABLE ENTRY NUMBER C197 JRNZ CMS1 C199 0C INR C ;CLEAR ZERO FLAG C19A C9 RET ;COMMAND IS DISK-RESIDENT (ZERO FLAG CLEAR) ; ;**** SECTION 5 **** ; CCP-RESIDENT COMMANDS ; ; ;SECTION 5A ;COMMAND: DIR ;FUNCTION: TO DISPLAY A DIRECTORY OF THE FILES ON DISK ;FORMS: ; DIR DISPLAYS THE DIR FILES ; DIR S DISPLAYS THE SYS FILES ; DIR A DISPLAY BOTH DIR AND SYS FILES ; DIR: C19B 3E80 MVI A,80H ;SET SYSTEM BIT EXAMINATION C19D F5 PUSH PSW C19E CDE7C0 CALL SCANER ;EXTRACT POSSIBLE D:FILENAME.TYP TOKEN C1A1 CDC9C0 CALL SLOGIN ;LOG IN DRIVE IF NECESSARY C1A4 219CBD LXI H,FCBFN ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP C1A7 7E MOV A,M ;GET FIRST CHAR OF FILENAME.TYP C1A8 FE20 CPI ' ' ;IF , ALL WILD C1AA CC44C2 CZ FILLQ C1AD CD30C0 CALL ADVAN ;LOOK AT NEXT INPUT CHAR C1B0 0600 MVI B,0 ;SYS TOKEN DEFAULT C1B2 JRZ DIR2 ;JUMP; THERE ISN'T ONE C1B4 FE41 CPI SYSFLG ;SYSTEM FLAG SPECIFIER? C1B6 JRZ GOTSYS ;GOT SYSTEM SPECIFIER C1B8 FE53 CPI SOFLG ;SYS ONLY? C1BA JRNZ DIR2 C1BC 0680 MVI B,80H ;FLAG SYS ONLY GOTSYS: C1BE 13 INX D C1BF SDED CIBPTR C1C3 FE53 CPI SOFLG ;SYS ONLY SPEC? C1C5 JRZ DIR2 ;THEN LEAVE BIT SPEC UNCHAGNED C1C7 F1 POP PSW ;GET FLAG CP/M MACRO ASSEM 2.0 #026 CCPZ Version 4.1 C1C8 AF XRA A ;SET NO SYSTEM BIT EXAMINATION C1C9 F5 PUSH PSW DIR2: C1CA F1 POP PSW ;GET FLAG DIR2A: ;DROP INTO DIRPR TO PRINT DIRECTORY ; THEN RESTART CCP ; ; DIRECTORY PRINT ROUTINE; ON ENTRY, MSB OF A IS 1 (80H) IF SYSTEM FILES EXCL ; DIRPR: C1CB 57 MOV D,A ;STORE SYSTEM FLAG IN D C1CC 1E00 MVI E,0 ;SET COLUMN COUNTER TO ZERO C1CE D5 PUSH D ;SAVE COLUMN COUNTER (E) AND SYSTEM FLAG (D) C1CF 78 MOV A,B ;SYS ONLY SPECIFIER C1D0 32EBC1 STA SYSTST C1D3 CD22BF CALL SEARF ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRANCE) C1D6 CC9EBE CZ PRNNF ;PRINT NO FILE MSG;REG A NOT CHANGED ; ; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN ; DIR3: C1D9 JRZ DIR11 ;DONE IF ZERO FLAG SET C1DB 3D DCR A ;ADJUST TO RETURNED VALUE C1DC 0F RRC ;CONVERT NUMBER TO OFFSET INTO TBUFF C1DD 0F RRC C1DE 0F RRC C1DF E660 ANI 60H C1E1 4F MOV C,A ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY) C1E2 3E0A MVI A,10 ;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT C1E4 CDC0C0 CALL DIRPTR C1E7 D1 POP D ;GET SYSTEM BIT MASK FROM D C1E8 D5 PUSH D C1E9 A2 ANA D ;MASK FOR SYSTEM BIT C1EB = SYSTST EQU $+1 ;POINTER TO IN-THE-CODE BUFFER SYSTST C1EA FE00 CPI 0 C1EC JRNZ DIR10 C1EE D1 POP D ;GET ENTRY COUNT (= COUNTER) C1EF 7B MOV A,E ;ADD 1 TO IT C1F0 1C INR E C1F1 D5 PUSH D ;SAVE IT ; IF TWOCOL ANI 01H ;OUTPUT IF 2 ENTRIES PRINTED IN LINE ENDIF ; IF NOT TWOCOL C1F2 E603 ANI 03H ;OUTPUT IF 4 ENTRIES PRINTED IN LINE ENDIF ; C1F4 F5 PUSH PSW C1F5 JRNZ DIR4 C1F7 CDA9BE CALL CRLF ;NEW LINE C1FA JR DIR5 DIR4: C1FC CDE8BE CALL PRINT CP/M MACRO ASSEM 2.0 #027 CCPZ Version 4.1 ; IF WIDE C1FF 2020 DB ' ' ;2 SPACES C201 7C DB FENCE ;THEN FENCE CHAR C202 20A0 DB ' ',' '+80H ;THEN 2 MORE SPACES ENDIF ; IF NOT WIDE DB ' ' ;SPACE DB FENCE ;THEN FENCE CHAR DB ' '+80H ;THEN SPACE ENDIF ; DIR5: C204 0601 MVI B,01H ;PT TO 1ST BYTE OF FILE NAME DIR6: C206 78 MOV A,B ;A=OFFSET C207 CDC0C0 CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE NAME C20A E67F ANI 7FH ;MASK OUT MSB C20C FE20 CPI ' ' ;NO FILE NAME? C20E JRNZ DIR8 ;PRINT FILE NAME IF PRESENT C210 F1 POP PSW C211 F5 PUSH PSW C212 FE03 CPI 03H C214 JRNZ DIR7 C216 3E09 MVI A,09H ;PT TO 1ST BYTE OF FILE TYPE C218 CDC0C0 CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE TYPE C21B E67F ANI 7FH ;MASK OUT MSB C21D FE20 CPI ' ' ;NO FILE TYPE? C21F JRZ DIR9 ;CONTINUE IF SO DIR7: C221 3E20 MVI A,' ' ;OUTPUT DIR8: C223 CDB0BE CALL CONOUT ;PRINT CHAR C226 04 INR B ;INCR CHAR COUNT C227 78 MOV A,B C228 FE0C CPI 12 ;END OF FILENAME.TYP? C22A JRNC DIR9 ;CONTINUE IF SO C22C FE09 CPI 09H ;END IF FILENAME ONLY? C22E JRNZ DIR6 ;PRINT TYP IF SO C230 3E2E MVI A,'.' ;PRINT DOT BETWEEN FILE NAME AND TYPE C232 CDB0BE CALL CONOUT C235 JR DIR6 DIR9: C237 F1 POP PSW DIR10: C238 CDE5BF CALL BREAK ;CHECK FOR ABORT C23B JRNZ DIR11 C23D CD29BF CALL SEARN ;SEARCH FOR NEXT FILE C240 JR DIR3 ;CONTINUE DIR11: C242 D1 POP D ;RESTORE STACK C243 C9 RET ; ; FILL FCB @HL WITH '?' ; CP/M MACRO ASSEM 2.0 #028 CCPZ Version 4.1 FILLQ: C244 060B MVI B,11 ;NUMBER OF CHARS IN FN & FT FQLP: C246 363F MVI M,'?' ;STORE '?' C248 23 INX H C249 DJNZ FQLP C24B C9 RET ; ;SECTION 5B ;COMMAND: ERA ;FUNCTION: ERASE FILES ;FORMS: ; ERA ERASE SPECIFIED FILES AND PRINT THEIR NAMES ; IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM ; ERA: C24C CDE7C0 CALL SCANER ;PARSE FILE SPECIFICATION C24F FE0B CPI 11 ;ALL WILD (ALL FILES = 11 '?')? C251 JRNZ ERA1 ;IF NOT, THEN DO ERASES C253 CDE3BE CALL PRINTC C256 416C6CBF DB 'All','?'+80H C25A CDBBBE CALL CONIN ;GET REPLY C25D CD65BF CALL UCASE ;CAPITALIZE C260 FE59 CPI 'Y' ;YES? C262 C239BE JNZ RESTRT ;RESTART CCP IF NOT C265 CDA9BE CALL CRLF ;NEW LINE ERA1: C268 CDC9C0 CALL SLOGIN ;LOG IN SELECTED DISK IF ANY C26B AF XRA A ;PRINT ALL FILES (EXAMINE SYSTEM BIT) C26C 47 MOV B,A ;NO SYS-ONLY OPT TO DIRPR C26D CDCBC1 CALL DIRPR ;PRINT DIRECTORY OF ERASED FILES C270 119BBD LXI D,FCBDN ;DELETE FILE SPECIFIED C273 CD38BF CALL DELETE C276 C9 RET ;REENTER CCP ; ENDIF ;RAS ; ;SECTION 5C ;COMMAND: LIST ;FUNCTION: PRINT OUT SPECIFIED FILE ON THE LST: DEVICE ;FORMS: ; LIST PRINT FILE (NO PAGING) ; LIST: C277 3EFF MVI A,0FFH ;TURN ON PRINTER FLAG C279 JR TYPE0 ; ;SECTION 5D ;COMMAND: TYPE ;FUNCTION: PRINT OUT SPECIFIED FILE ON THE CON: DEVICE ;FORMS: ; TYPE PRINT FILE ; TYPE P PRINT FILE WITH PAGING FLAG ; TYPE: CP/M MACRO ASSEM 2.0 #029 CCPZ Version 4.1 C27B AF XRA A ;TURN OFF PRINTER FLAG ; ; ENTRY POINT FOR CCP LIST FUNCTION (LIST) ; TYPE0: C27C 32C1BE STA PRFLG ;SET FLAG C27F CDE7C0 CALL SCANER ;EXTRACT FILENAME.TYP TOKEN C282 C2F6BF JNZ ERROR ;ERROR IF ANY QUESTION MARKS C285 CD30C0 CALL ADVAN ;GET PGDFLG IF IT'S THERE C288 3205C3 STA PGFLG ;SAVE IT AS A FLAG C28B JRZ NOSLAS ;JUMP IF INPUT ENDED C28D 13 INX D ;PUT NEW BUF POINTER C28E EB XCHG C28F 2259BD SHLD CIBPTR NOSLAS: C292 CDC9C0 CALL SLOGIN ;LOG IN SELECTED DISK IF ANY C295 CD10BF CALL OPENF ;OPEN SELECTED FILE C298 CAF8C2 JZ TYPE4 ;ABORT IF ERROR C29B CDA9BE CALL CRLF ;NEW LINE C29E 3E17 MVI A,NLINES-1 ;SET LINE COUNT C2A0 32BCBD STA PAGCNT C2A3 21BDBD LXI H,CHRCNT ;SET CHAR POSITION/COUNT C2A6 36FF MVI M,0FFH ;EMPTY LINE C2A8 0600 MVI B,0 ;SET TAB CHAR COUNTER TYPE1: C2AA 21BDBD LXI H,CHRCNT ;PT TO CHAR POSITION/COUNT C2AD 7E MOV A,M ;END OF BUFFER? C2AE FE80 CPI 80H C2B0 JRC TYPE2 C2B2 E5 PUSH H ;READ NEXT BLOCK C2B3 CDD7BE CALL READF C2B6 E1 POP H C2B7 JRNZ TYPE3 ;ERROR? C2B9 AF XRA A ;RESET COUNT C2BA 77 MOV M,A TYPE2: C2BB 34 INR M ;INCREMENT CHAR COUNT C2BC 218000 LXI H,TBUFF ;PT TO BUFFER C2BF CD3DC0 CALL ADDAH ;COMPUTE ADDRESS OF NEXT CHAR FROM OFFSET C2C2 7E MOV A,M ;GET NEXT CHAR C2C3 E67F ANI 7FH ;MASK OUT MSB C2C5 FE1A CPI 1AH ;END OF FILE (^Z)? C2C7 C8 RZ ;RESTART CCP IF SO ; ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION ; C2C8 FE0D CPI CR ;RESET TAB COUNT? C2CA JRZ TABRST C2CC FE0A CPI LF ;RESET TAB COUNT? C2CE JRZ TABRST C2D0 FE09 CPI TAB ;TAB? C2D2 JRZ LTAB C2D4 CDBFBE CALL LCOUT ;OUTPUT CHAR C2D7 04 INR B ;INCREMENT CHAR COUNT C2D8 JR TYPE2L TABRST: CP/M MACRO ASSEM 2.0 #030 CCPZ Version 4.1 C2DA CDBFBE CALL LCOUT ;OUTPUT OR C2DD 0600 MVI B,0 ;RESET TAB COUNTER C2DF JR TYPE2L LTAB: C2E1 3E20 MVI A,' ' ; C2E3 CDBFBE CALL LCOUT C2E6 04 INR B ;INCR POS COUNT C2E7 78 MOV A,B C2E8 E607 ANI 7 C2EA JRNZ LTAB ; ; CONTINUE PROCESSING ; TYPE2L: C2EC CDE5BF CALL BREAK ;CHECK FOR ABORT C2EF JRZ TYPE1 ;CONTINUE IF NO CHAR C2F1 FE03 CPI 'C'-'@' ;^C? C2F3 C8 RZ ;RESTART IF SO C2F4 JR TYPE1 TYPE3: C2F6 3D DCR A ;NO ERROR? C2F7 C8 RZ ;RESTART CCP TYPE4: C2F8 C3E9C4 JMP ERRLOG ; ; PAGING ROUTINES ; PAGER COUNTS DOWN LINES AND PAUSES FOR INPUT (DIRECT) IF COUNT EXPIRES ; PAGSET SETS LINES/PAGE COUNT ; PAGER: C2FB E5 PUSH H C2FC 21BCBD LXI H,PAGCNT ;COUNT DOWN C2FF 35 DCR M C300 JRNZ PGBAK ;JUMP IF NOT END OF PAGE C302 3616 MVI M,NLINES-2 ;REFILL COUNTER ; C305 = PGFLG EQU $+1 ;POINTER TO IN-THE-CODE BUFFER PGFLG C304 3E00 MVI A,0 ;0 MAY BE CHANGED BY PGFLG EQUATE C306 FE50 CPI PGDFLG ;PAGE DEFAULT OVERRIDE OPTION WANTED? ; IF PGDFLT ;IF PAGING IS DEFAULT C308 JRZ PGBAK ; PGDFLG MEANS NO PAGING, PLEASE ELSE ;IF PAGING NOT DEFAULT JRNZ PGBAK ; PGDFLG MEANS PLEASE PAGINATE ENDIF ; C30A CDBBBE CALL CONIN ;GET CHAR TO CONTINUE C30D FE03 CPI 'C'-'@' ;^C C30F CA8ABE JZ RSTCCP ;RESTART CCP PGBAK: C312 E1 POP H ;RESTORE HL C313 C9 RET ; ;SECTION 5E ;COMMAND: SAVE ;FUNCTION: TO SAVE THE CONTENTS OF THE TPA ONTO DISK AS A FILE CP/M MACRO ASSEM 2.0 #031 CCPZ Version 4.1 ;FORMS: ; SAVE ; SAVE SPECIFIED NUMBER OF PAGES (START AT 100H) ; FROM TPA INTO SPECIFIED FILE; IS IN DEC ; SAVE S ; LIKE SAVE ABOVE, BUT NUMERIC ARGUMENT SPECIFIES ; NUMBER OF SECTORS RATHER THAN PAGES ; IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM ; SAVE: C314 CD42C0 CALL NUMBER ;EXTRACT NUMBER FROM COMMAND LINE C317 F5 PUSH PSW ;SAVE IT C318 CDE7C0 CALL SCANER ;EXTRACT FILENAME.TYPE C31B C2F6BF JNZ ERROR ;MUST BE NO '?' IN IT C31E CDC9C0 CALL SLOGIN ;LOG IN SELECTED DISK C321 119BBD LXI D,FCBDN ;DELETE FILE IN CASE IT ALREADY EXISTS C324 D5 PUSH D C325 CD38BF CALL DELETE C328 D1 POP D C329 CD41BF CALL CREATE ;MAKE NEW FILE C32C JRZ SAVE3 ;ERROR? C32E AF XRA A ;SET RECORD COUNT FIELD OF NEW FILE'S FCB C32F 32BBBD STA FCBCR C332 F1 POP PSW ;GET PAGE COUNT C333 6F MOV L,A ;HL=PAGE COUNT C334 2600 MVI H,0 C336 E5 PUSH H C337 CD30C0 CALL ADVAN ;LOOK FOR 'S' FOR SECTOR OPTION C33A 13 INX D ;PT TO AFTER 'S' TOKEN C33B E1 POP H C33C FE53 CPI SECTFLG C33E JRZ SAVE0 C340 1B DCX D ;NO 'S' TOKEN, SO BACK UP C341 29 DAD H ;DOUBLE IT FOR HL=SECTOR (128 BYTES) COUNT SAVE0: C342 SDED CIBPTR ;SET PTR TO BAD TOKEN OR AFTER GOOD TOKEN C346 110001 LXI D,TPA ;PT TO START OF SAVE AREA (TPA) SAVE1: C349 7C MOV A,H ;DONE WITH SAVE? C34A B5 ORA L ;HL=0 IF SO C34B JRZ SAVE2 C34D 2B DCX H ;COUNT DOWN ON SECTORS C34E E5 PUSH H ;SAVE PTR TO BLOCK TO SAVE C34F 218000 LXI H,128 ;128 BYTES PER SECTOR C352 19 DAD D ;PT TO NEXT SECTOR C353 E5 PUSH H ;SAVE ON STACK C354 CD02BF CALL DMASET ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE) C357 119BBD LXI D,FCBDN ;WRITE SECTOR C35A CD3CBF CALL WRITE C35D D1 POP D ;GET PTR TO NEXT SECTOR IN DE C35E E1 POP H ;GET SECTOR COUNT C35F JRNZ SAVE3 ;WRITE ERROR? C361 JR SAVE1 ;CONTINUE SAVE2: CP/M MACRO ASSEM 2.0 #032 CCPZ Version 4.1 C363 119BBD LXI D,FCBDN ;CLOSE SAVED FILE C366 CD1EBF CALL CLOSE C369 3C INR A ;ERROR? C36A JRNZ SAVE4 SAVE3: C36C CDDFC4 CALL PRNLE ;PRINT 'NO SPACE' ERROR SAVE4: C36F CDFFBE CALL DEFDMA ;SET DMA TO 0080 C372 C9 RET ;RESTART CCP ; ENDIF ;RAS ; ;SECTION 5F ;COMMAND: REN ;FUNCTION: TO CHANGE THE NAME OF AN EXISTING FILE ;FORMS: ; REN = PERFORM FUNCTION ; IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM ; REN: C373 CDE7C0 CALL SCANER ;EXTRACT FILE NAME C376 C2F6BF JNZ ERROR ;ERROR IF ANY '?' IN IT C379 3ADEC0 LDA TEMPDR ;SAVE CURRENT DEFAULT DISK C37C F5 PUSH PSW C37D CDC9C0 CALL SLOGIN ;LOG IN SELECTED DISK C380 CD22BF CALL SEARF ;LOOK FOR SPECIFIED FILE C383 JRZ REN0 ;CONTINUE IF NOT FOUND C385 CDE3BE CALL PRINTC C388 46696C6520 DB 'File Exist','s'+80H C393 F1 POP PSW ;CLEAR STACK C394 C9 RET ;RESTART CCP REN0: C395 219BBD LXI H,FCBDN ;SAVE NEW FILE NAME C398 11ABBD LXI D,FCBDM C39B 011000 LXI B,16 ;16 BYTES C39E LDIR C3A0 CD30C0 CALL ADVAN ;ADVANCE CIBPTR C3A3 FE3D CPI '=' ;'=' OK C3A5 JRNZ REN4 REN1: C3A7 EB XCHG ;PT TO CHAR AFTER '=' IN HL C3A8 23 INX H C3A9 2259BD SHLD CIBPTR ;SAVE PTR TO OLD FILE NAME C3AC CDE7C0 CALL SCANER ;EXTRACT FILENAME.TYP TOKEN C3AF JRNZ REN4 ;ERROR IF ANY '?' C3B1 F1 POP PSW ;GET OLD DEFAULT DRIVE C3B2 47 MOV B,A ;SAVE IT C3B3 21DEC0 LXI H,TEMPDR ;COMPARE IT AGAINST CURRENT DEFAULT DRIVE C3B6 7E MOV A,M ;MATCH? C3B7 B7 ORA A C3B8 JRZ REN2 C3BA B8 CMP B ;CHECK FOR DRIVE ERROR C3BB 70 MOV M,B C3BC JRNZ REN4 REN2: CP/M MACRO ASSEM 2.0 #033 CCPZ Version 4.1 C3BE 70 MOV M,B C3BF AF XRA A C3C0 329BBD STA FCBDN ;SET DEFAULT DRIVE C3C3 119BBD LXI D,FCBDN ;RENAME FILE C3C6 0E17 MVI C,17H ;BDOS RENAME FCT C3C8 CD19BF CALL GRBDOS C3CB C0 RNZ REN3: C3CC CD9EBE CALL PRNNF ;PRINT NO FILE MSG REN4: C3CF C3E9C4 JMP ERRLOG ; ENDIF ;RAS ; ;SECTION 5G ;COMMAND: USER ;FUNCTION: CHANGE CURRENT USER NUMBER ;FORMS: ; USER SELECT SPECIFIED USER NUMBER; IS IN DEC ; USER: C3D2 CDF0BF CALL USRNUM ;EXTRACT USER NUMBER FROM COMMAND LINE C3D5 5F MOV E,A ;PLACE USER NUMBER IN E C3D6 CD4CBF CALL SETUSR ;SET SPECIFIED USER RSTJMP: C3D9 C38DBE JMP RCCPNL ;RESTART CCP ; ;SECTION 5H ;COMMAND: DFU ;FUNCTION: SET THE DEFAULT USER NUMBER FOR THE COMMAND/FILE SCANNER ; (MEMLOAD) ;FORMS: ; DFU SELECT DEFAULT USER NUMBER; IS IN DEC ; DFU: C3DC CDF0BF CALL USRNUM ;GET USER NUMBER C3DF 32A6C4 STA DFUSR ;PUT IT AWAY C3E2 JR RSTJMP ;RESTART CCP (NO DEFAULT LOGIN) ; ;SECTION 5I ;COMMAND: JUMP ;FUNCTION: TO CALL THE PROGRAM (SUBROUTINE) AT THE SPECIFIED ADDRESS ; WITHOUT LOADING FROM DISK ;FORMS: ; JUMP CALL AT ; IS IN HEX ; IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM ; JUMP: C3E4 CD80C0 CALL HEXNUM ;GET LOAD ADDRESS IN HL C3E7 JR CALLPROG ;PERFORM CALL ; ENDIF ;RAS ; ;SECTION 5J ;COMMAND: GO CP/M MACRO ASSEM 2.0 #034 CCPZ Version 4.1 ;FUNCTION: TO CALL THE PROGRAM IN THE TPA WITHOUT LOADING ; LOADING FROM DISK. SAME AS JUMP 100H, BUT MUCH ; MORE CONVENIENT, ESPECIALLY WHEN USED WITH ; PARAMETERS FOR PROGRAMS LIKE STAT. ALSO CAN BE ; ALLOWED ON REMOTE-ACCESS SYSTEMS WITH NO PROBLEMS. ; ;FORM: ; GO ; IF NOT RAS ;ONLY IF RAS ; C3E9 210001 GO: LXI H,TPA ;ALWAYS TO TPA C3EC JR CALLPROG ;PERFORM CALL ; ENDIF ;END OF GO FOR RAS ; ;SECTION 5K ;COMMAND: COM FILE PROCESSING ;FUNCTION: TO LOAD THE SPECIFIED COM FILE FROM DISK AND EXECUTE IT ;FORMS: ; ; COM: C3EE 3A9CBD LDA FCBFN ;ANY COMMAND? C3F1 FE20 CPI ' ' ;' ' MEANS COMMAND WAS 'D:' TO SWITCH C3F3 JRNZ COM1 ;NOT , SO MUST BE TRANSIENT OR ERROR C3F5 3ADEC0 LDA TEMPDR ;LOOK FOR DRIVE SPEC C3F8 B7 ORA A ;IF ZERO, JUST BLANK C3F9 CA8DBE JZ RCCPNL C3FC 3D DCR A ;ADJUST FOR LOG IN C3FD 3260BF STA TDRIVE ;SET DEFAULT DRIVE C400 CD5FBF CALL SETU0D ;SET DRIVE WITH USER 0 C403 CD0BBF CALL LOGIN ;LOG IN DRIVE C406 C38DBE JMP RCCPNL ;RESTART CCP COM1: C409 3AA4BD LDA FCBFT ;FILE TYPE MUST BE BLANK C40C FE20 CPI ' ' C40E C2F6BF JNZ ERROR C411 2177BD LXI H,COMMSG ;PLACE DEFAULT FILE TYPE (COM) INTO FCB C414 11A4BD LXI D,FCBFT ;COPY INTO FILE TYPE C417 010300 LXI B,3 ;3 BYTES C41A LDIR C41C 210001 LXI H,TPA ;SET EXECUTION/LOAD ADDRESS C41F E5 PUSH H ;SAVE FOR EXECUTION C420 CD91C4 CALL MEMLOAD ;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE ;(NO RETURN IF ERROR OR TOO BIG) C423 E1 POP H ;GET EXECUTION ADDRESS ; ; CALLPROG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED ; PROGRAM;ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION ; ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE ; CALLPROG: C424 2279C4 SHLD EXECADR ;PERFORM IN-LINE CODE MODIFICATION C427 CDD3C0 CALL DLOGIN ;LOG IN DEFAULT DRIVE C42A CDE7C0 CALL SCANER ;SEARCH COMMAND LINE FOR NEXT TOKEN CP/M MACRO ASSEM 2.0 #035 CCPZ Version 4.1 C42D 21DEC0 LXI H,TEMPDR ;SAVE PTR TO DRIVE SPEC C430 E5 PUSH H C431 7E MOV A,M ;SET DRIVE SPEC C432 329BBD STA FCBDN C435 3E10 MVI A,10H ;OFFSET FOR 2ND FILE SPEC C437 CDE8C0 CALL SCAN1 ;SCAN FOR IT AND LOAD IT INTO FCBDN+16 C43A E1 POP H ;SET UP DRIVE SPECS C43B 7E MOV A,M C43C 32ABBD STA FCBDM C43F AF XRA A C440 32BBBD STA FCBCR C443 115C00 LXI D,TFCB ;COPY TO DEFAULT FCB C446 219BBD LXI H,FCBDN ;FROM FCBDN C449 012100 LXI B,33 ;SET UP DEFAULT FCB C44C LDIR C44E 2108BD LXI H,CIBUFF COM4: C451 7E MOV A,M ;SKIP TO END OF 2ND FILE NAME C452 B7 ORA A ;END OF LINE? C453 JRZ COM5 C455 FE20 CPI ' ' ;END OF TOKEN? C457 JRZ COM5 C459 23 INX H C45A JR COM4 ; ; LOAD COMMAND LINE INTO TBUFF ; COM5: C45C 0600 MVI B,0 ;SET CHAR COUNT C45E 118100 LXI D,TBUFF+1 ;PT TO CHAR POS COM6: C461 7E MOV A,M ;COPY COMMAND LINE TO TBUFF C462 12 STAX D C463 B7 ORA A ;DONE IF ZERO C464 JRZ COM7 C466 04 INR B ;INCR CHAR COUNT C467 23 INX H ;PT TO NEXT C468 13 INX D C469 JR COM6 ; ; RUN LOADED TRANSIENT PROGRAM ; COM7: C46B 78 MOV A,B ;SAVE CHAR COUNT C46C 328000 STA TBUFF C46F CDA9BE CALL CRLF ;NEW LINE C472 CDFFBE CALL DEFDMA ;SET DMA TO 0080 C475 CD50BF CALL SETUD ;SET USER/DISK ; ; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE ; C479 = EXECADR EQU $+1 ;CHANGE ADDRESS FOR IN-LINE CODE MODIFICATION C478 CD0001 CALL TPA ;CALL TRANSIENT C47B CDFFBE CALL DEFDMA ;SET DMA TO 0080, IN CASE ;PROG CHANGED IT ON US C47E CD5FBF CALL SETU0D ;SET USER 0/DISK CP/M MACRO ASSEM 2.0 #036 CCPZ Version 4.1 C481 CD0BBF CALL LOGIN ;LOGIN DISK C484 C339BE JMP RESTRT ;RESTART CCP ; ;SECTION 5L ;COMMAND: GET ;FUNCTION: TO LOAD THE SPECIFIED FILE FROM DISK TO THE SPECIFIED ADDRESS ;FORMS: ; GET LOAD THE SPECIFIED FILE AT THE SPECIFIED PAGE; ; IS IN HEX ; IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM ; GET: C487 CD80C0 CALL HEXNUM ;GET LOAD ADDRESS IN HL C48A E5 PUSH H ;SAVE ADDRESS C48B CDE7C0 CALL SCANER ;GET FILE NAME C48E E1 POP H ;RESTORE ADDRESS C48F JRNZ ERRJMP ;MUST BE UNAMBIGUOUS ; ; FALL THRU TO MEMLOAD ; ENDIF ;RAS ; ; LOAD MEMORY WITH THE FILE WHOSE NAME IS SPECIFIED IN THE COMMAND LINE ; ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD ; ; EXIT BACK TO CALLER IF NO ERROR. IF COM FILE TOO BIG OR MEMORY ; FULL, EXIT TO MLERR. ; MEMLOAD: C491 22C0C4 SHLD LOADADR ;SET LOAD ADDRESS C494 CD4ABF CALL GETUSR ;GET CURRENT USER NUMBER C497 3246BF STA TMPUSR ;SAVE IT FOR LATER C49A 32A8C4 STA TSELUSR ;TEMP USER TO SELECT ; ; MLA IS A REENTRY POINT FOR A NON-STANDARD CP/M MODIFICATION ; THIS IS THE RETURN POINT FOR WHEN THE .COM (OR GET) FILE IS NOT FOUND THE ; FIRST TIME, DRIVE A: IS SELECTED FOR A SECOND ATTEMPT. ; MLA: C49D CDC9C0 CALL SLOGIN ;LOG IN SPECIFIED DRIVE IF ANY C4A0 CD10BF CALL OPENF ;OPEN COMMAND.COM FILE C4A3 JRNZ MLA1 ;FILE FOUND - LOAD IT ; ; ERROR ROUTINE TO SELECT USER 0 IF ALL ELSE FAILS ; C4A6 = DFUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE C4A5 3E00 MVI A,DEFUSR ;GET DEFAULT USER C4A8 = TSELUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE C4A7 FE00 CPI DEFUSR ;SAME? C4A9 JRZ MLA0 ;JUMP IF SO C4AB 32A8C4 STA TSELUSR ;ELSE PUT DOWN NEW ONE C4AE 5F MOV E,A C4AF CD4CBF CALL SETUSR ;GO SET NEW USER NUMBER C4B2 JR MLA ;AND TRY AGAIN ; CP/M MACRO ASSEM 2.0 #037 CCPZ Version 4.1 ; ERROR ROUTINE TO SELECT DRIVE A: IF DEFAULT WAS ORIGINALLY SELECTED ; MLA0: C4B4 21DEC0 LXI H,TEMPDR ;GET DRIVE FROM CURRENT COMMAND C4B7 AF XRA A ;A=0 C4B8 B6 ORA M C4B9 JRNZ MLERR ;ERROR IF ALREADY DISK A: C4BB 3601 MVI M,1 ;SELECT DRIVE A: C4BD JR MLA ; ; FILE FOUND -- PROCEED WITH LOAD ; MLA1: C4C0 = LOADADR EQU $+1 ;MEMORY LOAD ADDRESS (IN-LINE CODE MOD) C4BF 210001 LXI H,TPA ;SET START ADDRESS OF MEMORY LOAD ML2: C4C2 3EBC MVI A,ENTRY/256-1 ;GET HIGH-ORDER ADR OF JUST BELOW CCP C4C4 BC CMP H ;ARE WE GOING TO OVERWRITE THE CCP? C4C5 JRC PRNLE ;ERROR IF SO C4C7 E5 PUSH H ;SAVE ADDRESS OF NEXT SECTOR C4C8 EB XCHG ;... IN DE C4C9 CD02BF CALL DMASET ;SET DMA ADDRESS FOR LOAD C4CC 119BBD LXI D,FCBDN ;READ NEXT SECTOR C4CF CDDABE CALL READ C4D2 E1 POP H ;GET ADDRESS OF NEXT SECTOR C4D3 JRNZ ML3 ;READ ERROR OR EOF? C4D5 118000 LXI D,128 ;MOVE 128 BYTES PER SECTOR C4D8 19 DAD D ;PT TO NEXT SECTOR IN HL C4D9 JR ML2 ; ML3: C4DB 3D DCR A ;LOAD COMPLETE C4DC CA45BF JZ RESETUSR ;IF ZERO, OK, GO RESET CORRECT USER ;# ON WAY OUT, ELSE FALL THROUGH TO PRNLE ; ; LOAD ERROR ; PRNLE: C4DF CDE3BE CALL PRINTC C4E2 46756CEC DB 'Ful','l'+80H ; ; TRANSIENT LOAD ERROR ; MLERR: C4E6 CD45BF CALL RESETUSR ;RESET CURRENT USER NUMBER ; RESET MUST BE DONE BEFORE LOGIN ERRLOG: C4E9 CDD3C0 CALL DLOGIN ;LOG IN DEFAULT DISK ERRJMP: C4EC C3F6BF JMP ERROR ; C4EF END