IFIED PAGE (256 BYTES/PAGE) NUMBER OR, IF PAGE NUMBER ; IS NOT SPECIFIED, THE PROGRAM AT 100H IS CALLED. THE DEFAULT ; PARAMETERS IN THE COMMAND LINE ARE LOADED INTO THE SYSTEM ; PARAMETER BLOCKS IN LOW MEMORY (TFCB, TBUFF, ETC) AS FOR ANY ; OTHER COMMAND SO THAT THE COMMAND LINE IS PARSED AND PASSED ; TO THE PROGRAM. A SUBROUTINE CALL IS MADE, SO THE MEMORY- ; RESIDENT PROGRAM MAY RETURN TO CP/M VIA A SIMPLE RET INSTRUCTION. ; THE ONLY RESTRICTION TO THIS COMMAND IS THAT A JUMP 0 WILL BE ; INTERPRETED AS A JUMP 1. ; 6) REDUCED THE SIZE OF THE COMMAND LINE BUFFER TO 80 CHARS ; (SEE THE BUFLEN EQUATE TO CHANGE THIS) ; 7) HEXADECIMAL NUMBER INPUT ROUTINE ADDED AND DECIMAL NUMBER ROUTINE ; CHANGED TO ALLOW FOR ALTERNATE (HEX) BASE; HEX ROUTINE NOW ; RECOGNIZES THE 'NUMBASE' CHARACTER (SEE CUSTOMIZING EQUATES) AS ; A FLAG TO USE THE OTHER BASE ROUTINE. FOR INSTANCE, TO SPECIFY ; SAVE F (DEFAULT NUMBER BASE IS HEX), THE USER MAY ISSUE ; EITHER OF THE FOLLOWING COMMANDS [NUMBASE="#"]: ; SAVE F or SAVE #15 ; THE ESCAPE CHAR [#] MAY BE CHANGED BY ALTERING THE NUMBASE EQUATE. ; 8) 'SAVE' AND 'JUMP' COMMANDS CHANGED TO USE HEXADECIMAL ARGUMENT ; BY DEFAULT ; 9) ADDED 'GET' COMMAND WHICH LOADS A FILE AT A SPECIFIED PAGE ; ADDRESS. FORM OF THIS COMMAND IS: ; GET ; 10) REMOVED CLS COMMAND (as per discussion) ; 11) ADDED RAS (REMOTE ACCESS SYSTEM) EQUATE WHICH REMOVES FUNCTIONS ; TYPICALLY NOT DESIRED UNDER A REMOTE-ACCESS SYSTEM LIKE AN RBBS; ; FUNCTIONS REMOVED ARE: ; SAVE, ERA, REN, JUMP, GET ; ; MODS BY KBP 07/02/81: ; 1) ADDED WIDE EQUATE AND ROUTINE FOR WIDER DIR DISPLAY. ; 2) CHANGED COMMAND BUFFER TO TERMINATE STRING WITH 0. ; 3) ADDED CONDITIONALS FOR MINI AND HARD DISK. CHANGED ; CCPLOC CALCULATION TO ALLOW FOR SEVERAL SYSTEM LENGTHS. ; 4) ADDED EQUATE FOR DEFAULT USER NUMBER SO IT COULD BE ; OTHER THAN 0 (nice for hiding COM files in high user ; numbers made inaccessible on remote CP/M systems). ; ; THE FOLLOWING MODS MADE BY RLC 06/30/81: ; 1) ERROR IN CCPLOC FOR NON-REL OPTION CORRECTED ; 2) PROVISION OF 'BASE' CONSTANT ADDED FOR NON-ORG-0 CP/M SYSTEMS ; 3) MORE USER FLAGS ADDED: ; SPRMPT - ALLOWS USER TO EASILY CHANGE SUBMIT PROMPT ; (i.e., A$ is default) ; CPRMPT - ALLOWS USER TO EASILY CHANGE COMMAND PROMPT ; (i.e., A> is default) ; PGDFLG - ALLOWS USER TO SET TYPE COMMAND PAGING FLAG ; 4) CHANGED OPTIONS TO DIR, ERA, ETC (HUMAN ENGINEERING): ; DIR A - Both $DIR and $SYS ; DIR S - Just $SYS ; 5) MADE MINOR CODE COMPRESSION ENHANCEMENTS (FOR SPACE) ; ; THE FOLLOWING MODS MADE BY RGF 06/29/81: ; 1) CCP NOW USES THE BDOS INDICATOR TO DETERMINE IF ; A POSSIBLE SUBMIT FILE EXISTS ON THE DISK. THIS ; ELIMINATES WASTED TIME SEARCHING FOR A NON-EXIST- ; ANT SUBMIT FILE AFTER EVERY ^C ; 2) ADDED A CONDITIONAL "PGDFLT". IT WORKS THIS WAY: ; IF YOU SET PGDFLT TRUE (TO A 1), THEN YOU ; RETAIN RLC'S PAGING FEATURE WITH THE TYPE ; COMMAND. YOU CAN THEN OVERRIDE IT BY TYPING ; "TYPE /", TO SMOOTHLY VIEW THE ; FILE. ; IF YOU SET PGDFLT FALSE (TO A 0), THEN PAG- ; ING IS ONLY DONE WITH THE "/' OPTION, AND ; IS SMOOTH NORMALLY. ; 3) ADDED CLEAR SCREEN DEFINITION BYTES TO SIMPLIFY ; CARRYING THE CCP TO DIFFERENT TERMINALS. THESE ; ARE DEFINED IN EQUATES AS CLS1 AND CLS2. ALSO ; CHANGED THE CLS ROUTINE TO CONSERVE A LITTLE ; SPACE ; 4) ADDED REL EQUATE -FOR THOSE WHO ARE FAMILIAR WITH ; MODIFYING MOVCPM, THIS CAN BE USED IN CONJUNCTION ; WITH GENMOD.COM (PROVIDED BY DIGITAL RESEARCH ; IN THEIR MPM PACKAGE) TO INTEGRATE THIS CCP ; DIRECTLY INTO YOUR MOVCPM PROGRAM. ; 5) CHANGED THE FORM OF THE @ OPTION TO THE 'DIR' ; COMMAND, TO ALLOW AMBIGUOUS FILENAMES. TO SEE ; COMBINED $SYS AND $DIR FILES, TYPE ; DIR @. ; EG, ; DIR *.ASM @ ; OR ; DIR *.COM @ ; THE PRICE FOR THIS LUXURY IS THAT YOU NOW HAVE TO ; TO USE THE *.* SPECIFIER WHEN VIEWING ALL FILES: ; DIR *.* @. ; INSTEAD OF THE FORMER ; DIR @. ; NOTE THAT THE ACTUAL CHARACTER USED TO SPECIFY $SYS ; FILES IS NOW DEFINED IN AN EQUATE, FOR EASY CHANGING. ; THIS IS INTENDED FOR REMOTE CPM SYSTEMS, WHERE YOU ; DON'T ALWAYS WANT THE CALLER TO SEE $SYS FILES. NOTE ; THAT YOU CAN EFFECTIVELY DISABLE THE $SYS OPTION BY ; DEFINING THE SYS SPECIFIER AS A LOWER-CASE LETTER. ; 6) ADDED A NEW OPTION TO THE DIR COMMAND: ; DIR $ ; WILL DISPLAY ONLY $SYS FILES. CAN BE ; AN AMBIGUOUS FILE NAME. THE "$" SPECIFIER CAN BE ; CHANGED BY MODIFYING AN EQUATE. ; 7) CHANGED COMMENT FLAG FROM '*' TO ';' THROUGHOUT ; TO SIMPLIFY ADAPTATION FOR OTHER ASSEMBLERS. ; 8) ADDED TRUE/FALSE IN PLACE OF 0/1 FOR CONDITIONALS TO ; IMPROVE READABILITY ; 9) ADD CONDITIONAL 'SUPRES'. WHEN SET TRUE, USER NUMBER ; REPORTING IS SUPPRESSED FOR USER 0 ONLY, ALL OTHER ; USER NUMBERS ARE UNCHANGED. ; 10) ADDED ADDITIONAL Z80 CODE AND ASSOC. MACROS TO INCREASE ; USABLE CODE SPACE ; 11) ADDED "DFU" COMMAND, WHICH CAN BE USED TO DYNAMICALLY ; CHANGE THE USER NUMBER THAT IS SEARCHED WHEN A .COM ; FILE INVOCATION FAILS IN THE CURRENT USER AREA. NOTE ; THAT THIS REVERTS BACK TO ITS NORMAL VALUE OF USER 0 ; EACH WARM BOOT. ; 12) BREAK ROUTINE DIDN'T BREAK RELIABLY BECAUSE I/O WAS ; THRU FUNCTION 6. THE PROBLEM IS CAUSED BY THE FACT ; THAT BDOS TESTS STATUS WHENEVER IT SENDS A CHARACTER ; TO THE SCREEN, AND ACTUALLY INPUTS THE CHARACTER IF ; STATUS IS TRUE. IF THE CHAR IS NOT A CONTROL-S, BDOS ; BUFFERS IT UNTIL THE NEXT INPUT CALL, WHICH IS BY- ; PASSED BY USING FUNCTION 6. ; ; 29 JUNE, 1981 (RGF) ; ; RLC'S NOTES: ; ;**** CUSTOMIZATION PROCEDURE ***** ; To customize this CCP for CP/M, do the following: ; 1. Run SYSGEN and obtain a sysgen image of CP/M ; 2. Issue "SAVE 44 CPM.COM" to save sysgen image on disk ; 3. Assemble this CCP (with Mods); MAC or M80 MUST be used ; bnt ;CCP using BDSLOC or its equivalent, then merely set CCPLOC ;to that value as as in the following line: ; CCPLOC EQU 0CE00H ;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 ;CCPR EQU 1100H-CCPLOC ;DDT LOAD OFFSET FOR MORROW DESIGNS CCPR EQU 0a00H-CCPLOC ;DDT LOAD OFFSET Magnolia DD 2.23 ENDIF ; RAS EQU FALSE ;SET TO TRUE IF CCP IS FOR A REMOTE-ACCESS SYSTEM ; ; ;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES ; NLINES EQU 24 ;NUMBER OF LINES ON CRT SCREEN WIDE EQU TRUE ;TRUE IF WIDE DIR DISPLAY FENCE EQU '|' ;SEP CHAR BETWEEN DIR FILES ; PGDFLT EQU FALSE ;SET TO FALSE TO DISABLE PAGING BY DEFAULT PGDFLG EQU 'P' ;FOR TYPE COMMAND: PAGE OR NOT (DEP ON PGDFLT) ; THIS FLAG REVERSES THE DEFAULT EFFECT ; DRASTIC equ TRUE ;Dynamic command restriction flag location ; DRLOC equ 03eh ;location checked ; RESTRICTED equ 00 ;when (drastic)==restricted, lock out some ; ;commands MAXDRIV equ 03fh ;location that has maximum legal drive # +1 ; XEDLIST equ (DRASTIC or MAXDRIV) and (not RAS) ; MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSABLE ; SYSFLG EQU 'D' ;FOR DIR COMMAND: LIST $SYS AND $DIR ; SOFLG EQU 'S' ;FOR DIR COMMAND: LIST $SYS FILES ONLY ; SUPRES EQU TRUE ;SUPRESSES USER # REPORT FOR USER 0 ; DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES ; SPRMPT EQU '$' ;CCP PROMPT INDICATING SUBMIT COMMAND CPRMPT EQU '%' ;CCP PROMPT INDICATING USER COMMAND ; NUMBASE EQU 'H' ;CHARACTER USED TO SWITCH FROM DEFAULT ;NUMBER BASE ; SECTFLG EQU 'S' ;OPTION CHAR FOR SAVE COMMAND TO SAVE SECTORS ; ;END OF CUSTOMIZATION SECTION ; CR EQU 0DH LF EQU 0AH TAB EQU 09H ; WBOOT EQU BASE+0000H ;CP/M WARM BOOT ADDRESS UDFLAG EQU BASE+0004H ;USER NUM IN HIGH NYBBLE, DISK IN LOW BDOS EQU BASE+0005H ;BDOS FUNCTION CALL ENTRY PT TFCB EQU BASE+005CH ;DEFAULT FCB BUFFER TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER 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 ; ; ; ; @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 foobar ;make it complain ; DB 100H ;Displacement Range Error on Jump Relative ELSE DB ?DD ENDIF ENDM ; ; ; Z80 MACRO EXTENSIONS ; JR MACRO ?N DB 18H @GENDD ?N-$-1 ENDM ; JRC MACRO ?N DB 38H @GENDD ?N-$-1 ENDM ; JRNC MACRO ?N DB 30H @GENDD ?N-$-1 ENDM ; JRZ MACRO ?N DB 28H @GENDD ?N-$-1 ENDM ; JRNZ MACRO ?N DB 20H @GENDD ?N-$-1 ENDM ; DJNZ MACRO ?N DB 10H @GENDD ?N-$-1 ENDM ; LDIR MACRO DB 0EDH,0B0H ENDM ; LDED MACRO ?N DB 0EDH,05BH DW ?N ENDM ; LBCD MACRO ?N DB 0EDH,4BH DW ?N ENDM ; SDED MACRO ?N DB 0EDH,53H DW ?N ENDM ; SBCD MACRO ?N DB 0EDH,43H DW ?N ENDM ; ; END OF Z80 MACRO EXTENSIONS ; ; ; ; ;**** Section 0 **** ; ORG CCPLOC ; ENTRY: JMP CCP JMP CCP1 ; ; ;**** Section 1 **** ; BUFFERS ET AL ; ; INPUT COMMAND LINE AND DEFAULT COMMAND BUFLEN EQU 80 ;MAXIMUM BUFFER LENGTH MBUFF: DB BUFLEN ;MAXIMUM BUFFER LENGTH CBUFF: DB 0 ;NUMBER OF VALID CHARS IN COMMAND LINE CIBUFF: DB ' ' ;DEFAULT (COLD BOOT) COMMAND CIBUF: DB 0 ;COMMAND STRING TERMINATOR DS BUFLEN-15 ;TOTAL IS 'BUFLEN' BYTES (MORE OR LESS) DS 20 ;STACK AREA STACK EQU $ ;TOP OF STACK ; CIBPTR: DW CIBUFF ;POINTER TO CMD INPUT BUFF CIPTR: DW CIBUF ;CURRENT PNTR ; ; FILE TYPE FOR COMMAND COMMSG: DB 'COM' ; ; SUBMIT FILE EXECUTION RNGSUB: DB 0 ;0=$$$.SUB NOT PRESENT, ELSE $$$.SUB PRESENT ; ; ; FILE CONTROL BLOCK (FCB), ONE ; SUBFCB: DB 0 ;DISK NAME DB '$$$' ;FILE NAME DB ' ' DB 'SUB' ;FILE TYPE DB 0 ;EXTENT NUMBER DB 0 ;S1 SUBFS2: DS 1 ;S2 SUBFRC: DS 1 ;RECORD COUNT DS 16 ;DISK GROUP MAP SUBFCR: DS 1 ;CURRENT RECORD NUMBER ; ; ; FILE CONTROL BLOCK ; FCBDN: DS 1 ;DISK NAME FCBFN: DS 8 ;FILE NAME FCBFT: DS 3 ;FILE TYPE DS 1 ;EXTENT NUMBER DS 2 ;S1 AND S2 DS 1 ;RECORD COUNT FCBDM: DS 16 ;DISK GROUP MAP FCBCR: DS 1 ;CURRENT RECORD NUMBER ; ; OTHER BUFFERS if not xedlist PRFLG: DB 0 ;PRINTER FLAG (0=NO, 0FFH=YES) endif PAGCNT: DB NLINES-2 ;LINES LEFT ON PAGE IORESL: DB 0 ;I/O RESULTS TDRIVE: DB 1 ;TEMP DRIVE NUMBER TEMPDR: DB 0 CHRCNT: DB 0 ;CHAR COUNT FOR TYPE TMPUSR: DB 0 ;TEMPORARY USER NUMBER FOR COM TSELUSR: DB 0 ;TEMPORARY SELECTED USER NUMBER ; ; ; CCP BUILT-IN COMMAND TABLE ; 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: DB 'USER' DW USER DB 'DFU ' DW DFU NRCMNDS EQU ($-CMDTBL)/(NCHARS+2) DB 'DIR ' DW DIR if not xedlist DB 'LIST' DW LIST endif DB 'TYPE' DW TYPE ; IF NOT RAS ;FOR NON-RAS DB 'GO ' DW GO DB 'ERA ' DW ERA DB 'SAVE' DW SAVE DB 'REN ' DW REN DB 'GET ' DW GET DB 'JUMP' DW JUMP ENDIF ; NCMNDS EQU ($-CMDTBL)/(NCHARS+2) ; ; ;**** Section 2 **** ; CCP STARTING POINTS ; ; ; START CCP AND DON'T PROCESS DEFAULT COMMAND STORED CCP1: XRA A ;SET NO DEFAULT COMMAND 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: LXI SP,STACK ;RESET STACK PUSH B MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) RAR ;EXTRACT USER NUMBER RAR RAR RAR ANI 0FH MOV E,A ;SET USER NUMBER CALL SETUSR CALL RESET ;RESET DISK SYSTEM STA RNGSUB ;SAVE SUBMIT CLUE POP B MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) ANI 0FH ;EXTRACT DEFAULT DISK DRIVE STA TDRIVE ;SET IT JRZ NOLOG ;SKIP IF 0...ALREADY LOGGED CALL LOGIN ;LOG IN DEFAULT DISK STA RNGSUB ;SAVE BDOS '$' CLUE NOLOG: LXI D,SUBFCB ;CHECK FOR $$$.SUB ON CURRENT DISK LDA RNGSUB ;GET CLUE ORA A ;SET FLAGS ON CLUE CMA ;PREPARE FOR COMING 'CMA' CNZ SEAR1 CMA ;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT STA RNGSUB ;SET FLAG (0=NO $$$.SUB) LDA CBUFF ;EXECUTE DEFAULT COMMAND? ORA A ;0=NO JRNZ RS1 ; ; PROMPT USER AND INPUT COMMAND LINE FROM HIM RESTRT: LXI SP,STACK ;RESET STACK ; ; PRINT PROMPT (DU>) CALL CRLF ;PRINT PROMPT CALL GETDRV ;CURRENT DRIVE IS PART OF PROMPT ADI 'A' ;CONVERT TO ASCII A-P CALL CONOUT CALL GETUSR ;GET USER NUMBER ; IF SUPRES ;IF SUPPRESSING USR # REPORT FOR USR 0 ORA A JRZ RS000 ENDIF ; CPI 10 ;USER < 10? JRC RS00 SUI 10 ;SUBTRACT 10 FROM IT PUSH PSW ;SAVE IT MVI A,'1' ;OUTPUT 10'S DIGIT CALL CONOUT POP PSW RS00: ADI '0' ;OUTPUT 1'S DIGIT (CONVERT TO ASCII) CALL CONOUT ; ; READ INPUT LINE FROM USER OR $$$.SUB ; RS000: CALL REDBUF ;INPUT COMMAND LINE FROM USER (OR $$$.SUB) ; ; PROCESS INPUT LINE RS1: CALL DEFDMA ;SET TBUFF TO DMA ADDRESS CALL GETDRV ;GET DEFAULT DRIVE NUMBER STA TDRIVE ;SET IT CALL SCANER ;PARSE COMMAND NAME FROM COMMAND LINE CNZ ERROR ;ERAULT, PROCESS NUMS1: CPI NUMBASE ;CHECK AGAINST BASE SWITCH FLAG JRZ HNUM0 ; PROCESS DECIMAL NUMBER NUM0: LXI H,FCBFN ;PT TO BEGINNING OF TOKEN LXI B,1100H ;C=ACCUMULATED VALUE, B=CHAR COUNT ; (C=0, B=11) NUM1: MOV A,M ;GET CHAR CPI ' ' ;DONE IF JRZ NUM2 INX H ;PT TO NEXT CHAR SUI '0' ;CONVERT TO BINARY (ASCII 0-9 TO BINARY) CPI 10 ;ERROR IF >= 10 JRNC NUMERR MOV D,A ;DIGIT IN D MOV A,C ;NEW VALUE = OLD VALUE * 10 RLC RLC RLC ADD C ;CHECK FOR RANGE ERROR JRC NUMERR ADD C ;CHECK FOR RANGE ERROR JRC NUMERR ADD D ;NEW VALUE = OLD VALUE * 10 + DIGIT JRC NUMERR ;CHECK FOR RANGE ERROR MOV C,A ;SET NEW VALUE DJNZ NUM1 ;COUNT DOWN ; RETURN FROM NUMBER NUM2: MOV A,C ;GET ACCUMULATED VALUE RET ; ; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION NUMERR: 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 ; Especially HL, which has the 16 bit value ... -CAF ; HEXNUM: CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN HNUM0: LXI H,FCBFN ;PT TO TOKEN FOR CONVERSION LXI D,0 ;DE=ACCUMULATED VALUE MVI B,11 ;B=CHAR COUNT HNUM1: MOV A,M ;GET CHAR CPI ' ' ;DONE? JRZ HNUM3 ;RETURN IF SO CPI 'H' ;DONE IF H SUFFIX JRZ HNUM3 SUI '0' ;CONVERT TO BINARY JRC NUMERR ;RETURN AND DONE IF ERROR CPI 10 ;0-9? JRC HNUM2 SUI 7 ;A-F? CPI 10H ;ERROR? JRNC NUMERR HNUM2: INX H ;PT TO NEXT CHAR MOV C,A ;DIGIT IN C MOV A,D ;GET ACCUMULATED VALUE RLC ;EXCHANGE NYBBLES RLC RLC RLC ANI 0F0H ;MASK OUT LOW NYBBLE MOV D,A MOV A,E ;SWITCH LOW-ORDER NYBBLES RLC RLC RLC RLC MOV E,A ;HIGH NYBBLE OF E=NEW HIGH OF E, ; LOW NYBBLE OF E=NEW LOW OF D ANI 0FH ;GET NEW LOW OF D ORA D ;MASK IN HIGH OF D MOV D,A ;NEW HIGH BYTE IN D MOV A,E ANI 0F0H ;MASK OUT LOW OF E ORA C ;MASK IN NEW LOW MOV E,A ;NEW LOW BYTE IN E DJNZ HNUM1 ;COUNT DOWN ; RETURN FROM HEXNUM HNUM3: XCHG ;RETURNED VALUE IN HL MOV A,L ;LOW-ORDER BYTE IN A RET ; ; ; PT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C ; DIRPTR: LXI H,TBUFF ;PT TO TEMP BUFFER ADD C ;PT TO 1ST BYTE OF DIR ENTRY CALL ADDAH ;PT TO DESIRED BYTE IN DIR ENTRY MOV A,M ;GET DESIRED BYTE RET ; ; ; CHECK FOR SPECIFIED DRIVE AND LOG IT IN IF NOT DEFAULT ; SLOGIN: XRA A ;SET FCBDN FOR DEFAULT DRIVE STA FCBDN CALL COMLOG ;CHECK DRIVE RZ JR DLOG5 ;DO LOGIN OTHERWISE ; ; ; CHECK FOR SPECIFIED DRIVE AND LOG IN DEFAULT DRIVE IF SPECIFIED<>DEFAULT ; DLOGIN: CALL COMLOG ;CHECK DRIVE RZ ;ABORT IF SAME LDA TDRIVE ;LOG IN DEFAULT DRIVE ; DLOG5: JMP LOGIN ; ; ; ROUTINE COMMON TO BOTH LOGIN ROUTINES;ON EXIT, Z SET MEANS ABORT ; COMLOG: LDA TEMPDR ;DRIVE SPECIFIED? ORA A ;0=NO RZ DCR A ;COMPARE IT AGAINST DEFAULT LXI H,TDRIVE CMP M RET ;ABORT IF SAME ; ; ; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN; FORMAT FCBDN ; 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: XRA A ;A=0 TO START AT DRIVE SPECIFICATION BYTE SCAN1: LXI H,FCBDN ;POINT TO FCBDN CALL ADDAH ;OFFSET INTO FCB PUSH H PUSH H XRA A ;SET TEMPORARY DRIVE NUMBER TO DEFAULT STA TEMPDR CALL ADVAN ;SKIP TO NON-BLANK OR END OF LINE SDED CIPTR ;SET PTR TO NON-BLANK OR END OF LINE POP H ;GET PTR TO NEXT BYTE IN FCBDN LDAX D ;END OF LINE? ORA A ;0=YES JRZ SCAN2 SBI 'A'-1 ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER MOV B,A ;STORE NUMBER (A:=0, B:=1, ETC) IN B INX D ;PT TO NEXT CHAR LDAX D ;SEE IF IT IS A COLON (:) CPI ':' JRZ SCAN3 ;YES, WE HAVE A DRIVE SPEC DCX D ;NO, BACK UP PTR TO FIRST NON-BLANK CHAR SCAN2: LDA TDRIVE ;SET 1ST BYTE OF FCBDN AS DEFAULT DRIVE MOV M,A JR SCAN4 SCAN3: if maxdriv lda maxdriv ;check for legal drive number cmp b jc error ;don't do it if too high endif MOV A,B ;WE HAVE A DRIVE SPEC STA TEMPDR ;SET TEMPORARY DRIVE MOV M,B ;SET 1ST BYTE OF FCBDN AS SPECIFIED DRIVE INX D ;PT TO BYTE AFTER ':' ; ; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP SCAN4: MVI B,8 ;MAX OF 8 CHARS IN FILE NAME SCAN5: CALL SDELM ;DONE IF DELIMITER ENCOUNTERED - FILL JRZ SCAN9 INX H ;PT TO NEXT BYTE IN FCBDN CPI '*' ;IS (DE) A WILD CARD? JRNZ SCAN6 ;CONTINUE IF NOT MVI M,'?' ;PLACE '?' IN FCBDN AND DON'T ADVANCE DE IF SO JR SCAN7 SCAN6: MOV M,A ;STORE FILENAME CHAR IN FCBDN INX D ;PT TO NEXT CHAR IN COMMAND LINE SCAN7: DJNZ SCAN5 ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED SCAN8: CALL SDELM ;8 CHARS OR MORE - SKIP UNTIL DELIMITER JRZ SCAN10 ;ZERO FLAG SET IF DELIMITER FOUND INX D ;PT TO NEXT CHAR IN COMMAND LINE JR SCAN8 SCAN9: INX H ;PT TO NEXT BYTE IN FCBDN MVI M,' ' ;FILL FILENAME PART WITH DJNZ SCAN9 ; ; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP SCAN10: MVI B,3 ;PREPARE TO EXTRACT TYPE CPI '.' ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE JRNZ SCAN15 ;FILL FILE TYPE BYTES WITH INX D ;PT TO CHAR IN COMMAND LINE AFTER '.' SCAN11: CALL SDELM ;CHECK FOR DELIMITER JRZ SCAN15 ;FILL REST OF TYPE IF IT IS A DELIMITER INX H ;PT TO NEXT BYTE IN FCBDN CPI '*' ;WILD? JRNZ SCAN12 ;STORE CHAR IF NOT WILD MVI M,'?' ;STORE '?' AND DON'T ADVANCE COMMAND LINE PTR JR SCAN13 SCAN12: MOV M,A ;STORE CHAR IN FCBDN INX D ;PT TO NEXT CHAR IN COMMAND LINE SCAN13: DJNZ SCAN11 ;COUNT DOWN CHARS IN FILE TYPE (3 MAX) SCAN14: CALL SDELM ;SKIP REST OF CHARS AFTER 3-CHAR TYPE TO JRZ SCAN16 ; DELIMITER INX D JR SCAN14 SCAN15: INX H ;FILL IN REST OF TYP WITH MVI M,' ' DJNZ SCAN15 ; ; FILL IN EX, S1, S2, AND RC WITH ZEROES SCAN16: MVI B,4 ;4 BYTES SCAN17: INX H ;PT TO NEXT BYTE IN FCBDN MVI M,0 DJNZ SCAN17 ; ; SCAN COMPLETE -- DE PTS TO DELIMITER BYTE AFTER TOKEN SDED CIBPTR ; ; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN FILENAME.TYP POP H ;GET PTR TO FCBDN IN HL LXI B,11 ;SCAN FOR '?' IN FILENAME.TYP (C=11 BYTES) SCAN18: INX H ;PT TO NEXT BYTE IN FCBDN MOV A,M CPI '?' JRNZ SCAN19 INR B ;B<>0 TO INDICATE '?' ENCOUNTERED SCAN19: DCR C ;COUNT DOWN JRNZ SCAN18 MOV A,B ;A=B=NUMBER OF '?' IN FILENAME.TYP ORA A ;SET ZERO FLAG TO INDICATE ANY '?' 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: LXI H,CMDTBL ;PT TO COMMAND TABLE MVI C,NCMNDS ;SET COMMAND COUNTER IF DRASTIC ;check for restricted operation, such ;as when remote lda drloc cpi restricted jrnz cms1 mvi c,nrcmnds ;not so many if restricted -CAF ENDIF ;DRASTIC CMS1: LXI D,FCBFN ;PT TO STORED COMMAND NAME MVI B,NCHARS ;NUMBER OF CHARS/COMMAND (8 MAX) CMS2: LDAX D ;COMPARE AGAINST TABLE ENTRY CMP M JRNZ CMS3 ;NO MATCH INX D ;PT TO NEXT CHAR INX H DJNZ CMS2 ;COUNT DOWN LDAX D ;NEXT CHAR IN INPUT COMMAND MUST BE CPI ' ' JRNZ CMS4 RET ;COMMAND IS CCP-RESIDENT (ZERO FLAG SET) CMS3: INX H ;SKIP TO NEXT COMMAND TABLE ENTRY DJNZ CMS3 CMS4: INX H ;SKIP ADDRESS INX H DCR C ;DECREMENT TABLE ENTRY NUMBER JRNZ CMS1 INR C ;CLEAR ZERO FLAG 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: MVI A,80H ;SET SYSTEM BIT EXAMINATION PUSH PSW CALL SCANER ;EXTRACT POSSIBLE D:FILENAME.TYP TOKEN CALL SLOGIN ;LOG IN DRIVE IF NECESSARY LXI H,FCBFN ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP MOV A,M ;GET FIRST CHAR OF FILENAME.TYP CPI ' ' ;IF , ALL WILD CZ FILLQ CALL ADVAN ;LOOK AT NEXT INPUT CHAR MVI B,0 ;SYS TOKEN DEFAULT JART 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: CALL SCANER ;EXTRACT FILE NAME JNZ ERROR ;ERROR IF ANY '?' IN IT LDA TEMPDR ;SAVE CURRENT DEFAULT DISK PUSH PSW CALL SLOGIN ;LOG IN SELECTED DISK CALL SEARF ;LOOK FOR SPECIFIED FILE JRZ REN0 ;CONTINUE IF NOT FOUND CALL PRINTC DB 'File Exist','s'+80H POP PSW ;CLEAR STACK RET ;RESTART CCP REN0: LXI H,FCBDN ;SAVE NEW FILE NAME LXI D,FCBDM LXI B,16 ;16 BYTES LDIR CALL ADVAN ;ADVANCE CIBPTR CPI '=' ;'=' OK JRNZ REN4 REN1: XCHG ;PT TO CHAR AFTER '=' IN HL INX H SHLD CIBPTR ;SAVE PTR TO OLD FILE NAME CALL SCANER ;EXTRACT FILENAME.TYP TOKEN JRNZ REN4 ;ERROR IF ANY '?' POP PSW ;GET OLD DEFAULT DRIVE MOV B,A ;SAVE IT LXI H,TEMPDR ;COMPARE IT AGAINST CURRENT DEFAULT DRIVE MOV A,M ;MATCH? ORA A JRZ REN2 CMP B ;CHECK FOR DRIVE ERROR MOV M,B JRNZ REN4 REN2: MOV M,B XRA A STA FCBDN ;SET DEFAULT DRIVE LXI D,FCBDN ;RENAME FILE MVI C,17H ;BDOS RENAME FCT CALL GRBDOS RNZ REN3: CALL PRNNF ;PRINT NO FILE MSG REN4: JMP ERRLOG ; ENDIF ;RAS ; ; ;Section 5G ;Command: USER ;Function: Change current USER number ;Forms: ; USER Select specified user number; is in DEC ; USER: CALL USRNUM ;EXTRACT USER NUMBER FROM COMMAND LINE MOV E,A ;PLACE USER NUMBER IN E CALL SETUSR ;SET SPECIFIED USER RSTJMP: 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: CALL USRNUM ;GET USER NUMBER STA DFUSR ;PUT IT AWAY 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: CALL HEXNUM ;GET LOAD ADDRESS IN HL JR CALLPROG ;PERFORM CALL ; ENDIF ;RAS ; ; ;Section 5J ;Command: GO ;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 ; GO: LXI H,TPA ;Always to TPA 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: LDA FCBFN ;ANY COMMAND? CPI ' ' ;' ' MEANS COMMAND WAS 'D:' TO SWITCH JRNZ COM1 ;NOT , SO MUST BE TRANSIENT OR ERROR LDA TEMPDR ;LOOK FOR DRIVE SPEC ORA A ;IF ZERO, JUST BLANK JZ RCCPNL DCR A ;ADJUST FOR LOG IN STA TDRIVE ;SET DEFAULT DRIVE CALL SETU0D ;SET DRIVE WITH USER 0 CALL LOGIN ;LOG IN DRIVE JMP RCCPNL ;RESTART CCP COM1: LDA FCBFT ;FILE TYPE MUST BE BLANK CPI ' ' JNZ ERROR LXI H,COMMSG ;PLACE DEFAULT FILE TYPE (COM) INTO FCB LXI D,FCBFT ;COPY INTO FILE TYPE LXI B,3 ;3 BYTES LDIR LXI H,TPA ;SET EXECUTION/LOAD ADDRESS PUSH H ;SAVE FOR EXECUTION CALL MEMLOAD ;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE POP H ;GET EXECUTION ADDRESS RNZ ;RETURN (ABORT) IF LOAD ERROR ; ; ; 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: SHLD EXECADR ;PERFORM IN-LINE CODE MODIFICATION CALL DLOGIN ;LOG IN DEFAULT DRIVE CALL SCANER ;SEARCH COMMAND LINE FOR NEXT TOKEN LXI H,TEMPDR ;SAVE PTR TO DRIVE SPEC PUSH H MOV A,M ;SET DRIVE SPEC STA FCBDN MVI A,10H ;OFFSET FOR 2ND FILE SPEC CALL SCAN1 ;SCAN FOR IT AND LOAD IT INTO FCBDN+16 POP H ;SET UP DRIVE SPECS MOV A,M STA FCBDM XRA A STA FCBCR LXI D,TFCB ;COPY TO DEFAULT FCB LXI H,FCBDN ;FROM FCBDN LXI B,33 ;SET UP DEFAULT FCB LDIR LXI H,CIBUFF COM4: MOV A,M ;SKIP TO END OF 2ND FILE NAME ORA A ;END OF LINE? JRZ COM5 CPI ' ' ;END OF TOKEN? JRZ COM5 INX H JR COM4 ; ; LOAD COMMAND LINE INTO TBUFF COM5: MVI B,0 ;SET CHAR COUNT LXI D,TBUFF+1 ;PT TO CHAR POS COM6: MOV A,M ;COPY COMMAND LINE TO TBUFF STAX D ORA A ;DONE IF ZERO JRZ COM7 INR B ;INCR CHAR COUNT INX H ;PT TO NEXT INX D JR COM6 ; ; RUN LOADED TRANSIENT PROGRAM COM7: MOV A,B ;SAVE CHAR COUNT STA TBUFF CALL CRLF ;NEW LINE CALL DEFDMA ;SET DMA TO 0080 CALL SETUD ;SET USER/DISK ; ; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE EXECADR EQU $+1 ;CHANGE ADDRESS FOR IN-LINE CODE MODIFICATION CALL TPA ;CALL TRANSIENT CALL DEFDMA ;SET DMA TO 0080, IN CASE ;PROG CHANGED IT ON US CALL SETU0D ;SET USER 0/DISK CALL LOGIN ;LOGIN DISK JMP RESTRT ;RESTART CCP ; ; TRANSIENT LOAD ERROR COM8: CALL RESETUSR ;RESET CURRENT USER NUMBER ; RESET MUST BE DONE BEFORE LOGIN ERRLOG: CALL DLOGIN ;LOG IN DEFAULT DISK ERRJMP: JMP ERROR ; ; ;Section 5L ;Command: GET ;Function: To load the specified file from disk to the specified address ;Forms: ; GET Load