home *** CD-ROM | disk | FTP | other *** search
- ZCPR-14 Customized for OMIKRON 9/27/82 HMVT
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION
- ;
- BASE EQU 0 ;BASE OF CP/M SYSTEM (SET FOR STANDARD CP/M)
- ;
- CPRLOC EQU 0CC00H ;FILL IN WITH BDOSLOC SUPPLIED VALUE
- ;
- CPRR EQU 0980H-CPRLOC ;DDT LOAD OFFSET
- ;
- RAS EQU FALSE ;SET TO TRUE IF CPR IS FOR A REMOTE-ACCESS SYSTEM
- ;AND YOU DON'T WANT TO RUN SECURE (FOO...)
- ;
- MAXDRIV EQU 0000H ;LOCATION THAT HAS MAX LEGAL DRIVE #
- ;SET IT TO ZERO TO DISABLE THIS CROCK.
- ;
- SECURE EQU FALSE ;SET TRUE FOR SECURE ENVIRONMENT...
- ;
- INPASS EQU FALSE ;SET TRUE IF RUNNING SECURE AND NOT PASS.COM
- ;
- DRUSER EQU TRUE ;TRUE TO ALLOW USER COMMAND AND RAF'S HACK.
- ;
- TYPEDIR EQU TRUE ;TRUE TO USE ZCPR TYPE/DIR FALSE= USE DIR.COM/TYPE.COM
- ;
- ;
- TWOCOL EQU FALSE ;TRUE IF TWO COL DIR INSTEAD OF FOUR
- ;
- SUBA EQU TRUE ; Set to TRUE to have $$$.SUB always on A:
- ; Set to FALSE to have $$$.SUB on the logged-in drive
- ;
- CLEVEL3 EQU TRUE ;ENABLE COMMAND LEVEL 3 PROCESSING
- ;
- ;
- ;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES
- ;
- NLINES EQU 16 ;NUMBER OF LINES ON CRT SCREEN
- ncolms equ 64 ;width of CRT screen
- WIDE EQU FALSE ;TRUE IF WIDE DIR DISPLAY
- FENCE EQU '|' ;SEP CHAR BETWEEN DIR FILES
- ;
- PGDFLT EQU TRUE ;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
- ;
- IF NOT SECURE ;SEE ALSO STUFF DEFINED UNDER SECURE EQU ABOVE.
- DEFUSR EQU 0 ;DEFAULT USER FOR COM FILES
- ENDIF ;NOT SECURE
- ;
- MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSABLE
- ;
- SYSFLG EQU 'A' ;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
- ;
- SPRMPT EQU '$' ;CPR PROMPT INDICATING SUBMIT COMMAND
- CPRMPT EQU '>' ;CPR 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 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
- 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 ****
- ;
- ORG CPRLOC
- ;
- ; ENTRY POINTS INTO ZCPR
- ;
- ; If the ZCPR is entered at location CPRLOC (at the JMP to CPR), then
- ; the default command in CIBUFF will be processed. If the ZCPR is entered
- ; at location CPRLOC+3 (at the JMP to CPR1), then the default command in
- ; CIBUFF will NOT be processed.
- ;
- ; NOTE: Entry into ZCPR in this way is permitted under this version,
- ; 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 current versions, 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 [CPRLOC + 6]), but under ZCPR this is
- ; no longer necessary, since this buffer pointer is automatically
- ; initialized in all cases.
- ;
- ENTRY:
- JMP CPR ; Process potential default command
- JMP CPR1 ; 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:
- ;
- ; (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 CPRLOC is enough
- ; to have the command processed. Again, under the current ZCPR, it is not
- ; necessary to store the pointer to CIBUFF in CIBPTR; ZCPR 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 (CPRLOC + 6).
- ;
- 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
- DB ' ZCPR V 1.4 of 03/20/82 ' ;ID FOR DISK DUMP
- DS BUFLEN-($-CIBUFF)+1 ;TOTAL IS 'BUFLEN' BYTES
- ;
- CIBPTR:
- DW CIBUFF ;POINTER TO COMMAND INPUT BUFFER
- CIPTR:
- DW CIBUF ;POINTER TO CURR COMMAND FOR
- ; ERROR REPORTING
- ;
- DS 26 ;STACK AREA
- STACK EQU $ ;TOP OF STACK
- ;
- ; FILE TYPE FOR COMMAND
- ;
- COMMSG:
- DB 'COM'
- ;
- ; SUBMIT FILE CONTROL BLOCK
- ;
- SUBFCB:
- IF SUBA ;IF $$$.SUB ON A:
- DB 1 ;DISK NAME SET TO DEFAULT TO DRIVE A:
- ENDIF
- ;
- IF NOT SUBA ;IF $$$.SUB ON CURRENT DRIVE
- DB 0 ;DISK NAME SET TO DEFAULT TO CURRENT DRIVE
- ENDIF
- ;
- 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
- ;
- ; COMMAND 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
- ;
- PAGCNT:
- DB NLINES-2 ;LINES LEFT ON PAGE
- CHRCNT:
- DB 0 ;CHAR COUNT FOR TYPE
- QMCNT:
- DB 0 ;QUESTION MARK COUNT FOR FCB TOKEN SCANNER
- ;
- ;
- ;**** Section 2 ****
- ; CPR STARTING POINTS. NOTE THAT SOME CP/M IMPLEMENTATIONS
- ; REQUIRE THE COLD START ADDRESS TO BE IN THE STARTING PAGE
- ; OF THE CPR, FOR DYNAMIC CCP LOADING. CMDTBL WAS MOVED FOR
- ; THIS REASON.
- ;
- ; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED
- ;
- CPR1:
- XRA A ;SET NO DEFAULT COMMAND
- STA CBUFF
- ;
- ; START CPR 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.
- ;
- CPR:
- 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 FROM DRIVE A:
- 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
- ;
- IF NOT SUBA ;IF $$$.SUB IS ON CURRENT DRIVE
- STA RNGSUB ;BDOS '$' CLUE
- ENDIF
- ;
- NOLOG:
- LXI D,SUBFCB ;CHECK FOR $$$.SUB ON CURRENT DISK
- RNGSUB EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG
- 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:
- ;
- IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
- CALL CNVBUF ;CAPITALIZE COMMAND LINE, PLACE ENDING 0,
- ; AND SET CIBPTR VALUE
- ENDIF
- ;
- 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 ;ERROR IF COMMAND NAME CONTAINS A '?'
- LXI D,RSTCPR ;PUT RETURN ADDRESS OF COMMAND
- PUSH D ;ON THE STACK
- LDA TEMPDR ;IS COMMAND OF FORM 'D:COMMAND'?
- ORA A ;NZ=YES
- JNZ COM ; IMMEDIATELY
- CALL CMDSER ;SCAN FOR CPR-RESIDENT COMMAND
- JNZ COM ;NOT CPR-RESIDENT
- MOV A,M ;FOUND IT: GET LOW-ORDER PART
- INX H ;GET HIGH-ORDER PART
- MOV H,M ;STORE HIGH
- MOV L,A ;STORE LOW
- PCHL ;EXECUTE CPR ROUTINE
- ;
- ; ENTRY POINT FOR RESTARTING CPR AND LOGGING IN DEFAULT DRIVE
- ;
- RSTCPR:
- CALL DLOGIN ;LOG IN DEFAULT DRIVE
- ;
- ; ENTRY POINT FOR RESTARTING CPR WITHOUT LOGGING IN DEFAULT DRIVE
- ;
- RCPRNL:
- CALL SCANER ;EXTRACT NEXT TOKEN FROM COMMAND LINE
- LDA FCBFN ;GET FIRST CHAR OF TOKEN
- SUI ' ' ;ANY CHAR?
- LXI H,TEMPDR
- ORA M
- JNZ ERROR
- JR RESTRT
- ;
- ; No File Error Message
- ;
- PRNNF:
- CALL PRINTC ;NO FILE MESSAGE
- DB 'No Fil','e'+80H
- RET
- ;
- ; CPR BUILT-IN COMMAND TABLE
- ;
- NCHARS EQU 4 ;NUMBER OF CHARS/COMMAND
- ;
- ; CPR COMMAND NAME TABLE
- ; EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS
- ;
- CMDTBL:
- ;
- IF INPASS AND SECURE
- DB 'PASS' ;ENABLE WHEEL (SYSOP) MODE
- DW PASS
- ENDIF ;INPASS AND SECURE
- ;
- IF DRUSER
- DB 'USER' ;CHANGE USER AREAS
- DW USER
- ENDIF ;DRUSER
- ;
- IF TYPEDIR
- DB 'TYPE' ;TYPE A FILE TO CON:
- DW TYPE
- DB 'DIR ' ;PULL A DIRECTORY OF DISK FILES
- DW DIR
- ENDIF ;TYPEDIR
-
- NRCMDS EQU ($-CMDTBL)/(NCHARS+2) ;PUT ANY COMMANDS THAT ARE OK TO
- ;RUN WHEN NOT UNDER WHEEL MODE
- ;IN FRONT OF THIS LABEL
- ;
- IF TYPEDIR
- DB 'LIST' ;LIST FILE TO PRINTER
- DW LIST
- ENDIF ;TYPEDIR
- ;
- IF INPASS AND SECURE
- DB 'NORM' ;DISABLE WHEEL MODE
- DW NORM
- ENDIF ;INPASS AND SECURE
- ;
- IF NOT RAS ;FOR NON-RAS
- DB '@ ' ;JUMP TO 100H
- DW GO
- DB 'ERA ' ;ERASE FILE
- DW ERA
- DB 'SAVE' ;SAVE MEMORY IMAGE TO DISK
- DW SAVE
- DB 'REN ' ;RENAME FILE
- DW REN
- DB 'DFU ' ;SET DEFAULT USER
- DW DFU
- DB 'GET ' ;LOAD FILE INTO MEMORY
- DW GET
- DB 'JUMP' ;JUMP TO LOCATION IN MEMORY
- DW JUMP
- ENDIF
- ;
- NCMNDS EQU ($-CMDTBL)/(NCHARS+2)
- ;
- ;**** Section 3 ****
- ; I/O UTILITIES
- ;
- ; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC
- ;
- ;
- ; OUTPUT <CRLF>
- ;
- CRLF:
- MVI A,CR
- CALL CONOUT
- MVI A,LF ;FALL THRU TO CONOUT
- ;
- CONOUT:
- PUSH B
- MVI C,02H
- OUTPUT:
- MOV E,A
- PUSH H
- CALL BDOS
- POP H
- POP B
- RET
- ;
- CONIN:
- MVI C,01H ;GET CHAR FROM CON: WITH ECHO
- CALL BDOSB
- ;
- ; CONVERT CHAR IN A TO UPPER CASE
- ;
- UCASE:
- CPI 60H ;LOWER-CASE '@'
- RC
- CPI 7BH ;GREATER THAN LOWER-CASE Z?
- RNC
- ANI 5FH ;CAPITALIZE
- RET
- ;
- NOECHO:
- PUSH D ;SAVE D
- MVI C,6 ;DIRECT CONSOLE I/O
- MVI E,0FFH ;INPUT
- CALL BDOSB
- POP D
- CPI 0 ;CHAR WAITING
- JRZ NOECHO ;LOOP
- RET
- ;
- LCOUT:
- PUSH PSW ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG
- PRFLG EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG
- ORA A ;0=TYPE
- JRZ LC1
- POP PSW ;GET CHAR
- ;
- ; OUTPUT CHAR IN REG A TO LIST DEVICE
- ;
- LSTOUT:
- PUSH B
- MVI C,05H
- JR OUTPUT
- ;
- LC1:
- POP PSW ;GET CHAR
- PUSH PSW
- CALL CONOUT ;SEND IT TO CON:
- POP PSW
- CPI LF ;CHECK FOR PAGING
- JRZ PAGER ;jump if LF
- ;
- colcnt: equ $+1 ;pointer to in code buffer that
- mvi a,ncolms;will be changed by next code
- dcr a ;reduce count by 1
- sta colcnt ;and put it back
- rnz ;return if not at eol
- ;
- PAGER: PUSH H
- lxi h,colcnt
- mvi m,ncolms ;reset column counter to ncolmns
- LXI H,PAGCNT
- DCR M
- JRNZ PGBAK ;JUMP IF NOT END OF PAGE
- MVI M,NLINES-2 ;REFILL COUNTER
- ;
- PGFLG EQU $+1 ;POINTER TO IN-THE-CODE BUFFER PGFLG
- MVI A,0 ;0 MAY BE CHANGED BY PGFLG EQUATE
- CPI PGDFLG ;PAGE DEFAULT OVERRIDE OPTION WANTED?
- ;
- IF PGDFLT ;IF PAGING IS DEFAULT
- JRZ PGBAK ; PGDFLG MEANS NO PAGING, PLEASE
- ELSE ;IF PAGING NOT DEFAULT
- JRNZ PGBAK ; PGDFLG MEANS PLEASE PAGINATE
- ENDIF
- ;
- CALL NOECHO ;GET CHAR BUT DON'T ECHO TO SCREEN
- CPI 'C'-'@' ;^C
- JZ RSTCPR ;RESTART CPR
- PGBAK:
- POP H ;RESTORE HL
- RET
- ;
- READF:
- LXI D,FCBDN ;FALL THRU TO READ
- READ:
- MVI C,14H ;FALL THRU TO BDOSB
- ;
- ; CALL BDOS AND SAVE BC
- ;
- BDOSB:
- PUSH B
- CALL BDOS
- POP B
- ORA A
- RET
- ;
- ; PRINT STRING (ENDING IN 0) PTED TO BY RET ADR;START WITH <CRLF>
- ;
- PRINTC:
- PUSH PSW ;SAVE FLAGS
- CALL CRLF ;NEW LINE
- POP PSW
- ;
- PRINT:
- XTHL ;GET PTR TO STRING
- PUSH PSW ;SAVE FLAGS
- CALL PRIN1 ;PRINT STRING
- POP PSW ;GET FLAGS
- XTHL ;RESTORE HL AND RET ADR
- RET
- ;
- ; PRINT STRING (ENDING IN 0) PTED TO BY HL
- ;
- PRIN1:
- MOV A,M ;GET NEXT BYTE
- ani 7FH ;strip off high graphics bit
- CALL CONOUT ;PRINT CHAR
- MOV A,M ;GET NEXT BYTE AGAIN FOR TEST
- INX H ;PT TO NEXT BYTE
- ORA A ;SET FLAGS
- RZ ;DONE IF ZERO
- RM ;DONE IF MSB SET
- JR PRIN1
- ;
- ; BDOS FUNCTION ROUTINES
- ;
- ;
- ; RETURN NUMBER OF CURRENT DISK IN A
- ;
- GETDRV:
- MVI C,19H
- JR BDOSJP
- ;
- ; SET 80H AS DMA ADDRESS
- ;
- DEFDMA:
- LXI D,TBUFF ;80H=TBUFF
- DMASET:
- MVI C,1AH
- JR BDOSJP
- ;
- RESET:
- MVI C,0DH
- BDOSJP:
- JMP BDOS
- ;
- LOGIN:
- MOV E,A ;MOVE DESIRED # TO BDOS REG
- ;
- IF MAXDRIV
- LDA MAXDRIV ;CHECK FOR LEGAL DRIVE #
- CMP E
- JC ERROR ;DON'T DO IT IF TOO HIGH
- ENDIF ;MAXDRIV
- ;
- MVI C,0EH
- JR BDOSJP ;SAVE SOME CODE SPACE
- ;
- OPENF:
- XRA A
- STA FCBCR
- LXI D,FCBDN ;FALL THRU TO OPEN
- ;
- OPEN:
- MVI C,0FH ;FALL THRU TO GRBDOS
- ;
- GRBDOS:
- CALL BDOS
- INR A ;SET ZERO FLAG FOR ERROR RETURN
- RET
- ;
- CLOSE:
- MVI C,10H
- JR GRBDOS
- ;
- SEARF:
- LXI D,FCBDN ;SPECIFY FCB
- SEAR1:
- MVI C,11H
- JR GRBDOS
- ;
- SEARN:
- MVI C,12H
- JR GRBDOS
- ;
- ; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO
- ;
- SUBKIL:
- LXI H,RNGSUB ;CHECK FOR SUBMIT FILE IN EXECUTION
- MOV A,M
- ORA A ;0=NO
- RZ
- MVI M,0 ;ABORT SUBMIT FILE
- LXI D,SUBFCB ;DELETE $$$.SUB
- ;
- DELETE:
- MVI C,13H
- JR BDOSJP ;SAVE MORE SPACE
- ;
- ; RESET USER NUMBER IF CHANGED
- ;
- RESETUSR:
- TMPUSR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TMPUSR
- MOV E,A ;PLACE IN E
- JR SETUSR ;THEN GO SET USER
- GETUSR:
- MVI E,0FFH ;GET CURRENT USER NUMBER
- SETUSR:
- MVI C,20H ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH)
- JR BDOSJP ;MORE SPACE SAVING
- ;
- ; END OF BDOS FUNCTIONS
- ;
- ;
- ;**** Section 4 ****
- ; CPR UTILITIES
- ;
- ; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK
- ;
- SETUD:
- CALL GETUSR ;GET NUMBER OF CURRENT USER
- ADD A ;PLACE IT IN HIGH NYBBLE
- ADD A
- ADD A
- ADD A
- LXI H,TDRIVE ;MASK IN DEFAULT DRIVE NUMBER (LOW NYBBLE)
- ORA M ;MASK IN
- STA UDFLAG ;SET USER/DISK NUMBER
- RET
- ;
- ; SET USER/DISK FLAG TO USER 0 AND DEFAULT DISK
- ;
- SETU0D:
- TDRIVE EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TDRIVE
- STA UDFLAG ;SET USER/DISK NUMBER
- RET
- ;
- ; INPUT NEXT COMMAND TO CPR
- ; 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:
- LDA RNGSUB ;SUBMIT FILE CURRENTLY IN EXECUTION?
- ORA A ;0=NO
- JRZ RB1 ;GET LINE FROM CONSOLE IF NOT
- LXI D,SUBFCB ;OPEN $$$.SUB
- PUSH D ;SAVE DE
- CALL OPEN
- POP D ;RESTORE DE
- JRZ RB1 ;ERASE $$$.SUB IF END OF FILE AND GET CMND
- LDA SUBFRC ;GET VALUE OF LAST RECORD IN FILE
- DCR A ;PT TO NEXT TO LAST RECORD
- STA SUBFCR ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
- CALL READ ;DE=SUBFCB
- JRNZ RB1 ;ABORT $$$.SUB IF ERROR IN READING LAST REC
- LXI D,CBUFF ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CBUFF
- LXI H,TBUFF ; FROM TBUFF
- LXI B,BUFLEN ;NUMBER OF BYTES
- LDIR
- LXI H,SUBFS2 ;PT TO S2 OF $$$.SUB FCB
- MVI M,0 ;SET S2 TO ZERO
- INX H ;PT TO RECORD COUNT
- DCR M ;DECREMENT RECORD COUNT OF $$$.SUB
- LXI D,SUBFCB ;CLOSE $$$.SUB
- CALL CLOSE
- JRZ RB1 ;ABORT $$$.SUB IF ERROR
- MVI A,SPRMPT ;PRINT SUBMIT PROMPT
- CALL CONOUT
- LXI H,CIBUFF ;PRINT COMMAND LINE FROM $$$.SUB
- CALL PRIN1
- CALL BREAK ;CHECK FOR ABORT (ANY CHAR)
- ;
- IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
- RZ ;IF <NULL> (NO ABORT), RETURN TO CALLER AND RUN
- ENDIF
- ;
- IF NOT CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED
- JRZ CNVBUF ;IF <NULL> (NO ABORT), CAPITALIZE COMMAND
- ENDIF
- ;
- CALL SUBKIL ;KILL $$$.SUB IF ABORT
- JMP RESTRT ;RESTART CPR
- ;
- ; INPUT COMMAND LINE FROM USER CONSOLE
- ;
- RB1:
- CALL SUBKIL ;ERASE $$$.SUB IF PRESENT
- CALL SETUD ;SET USER AND DISK
- MVI A,CPRMPT ;PRINT PROMPT
- CALL CONOUT
- MVI C,0AH ;READ COMMAND LINE FROM USER
- LXI D,MBUFF
- CALL BDOS
- ;
- IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED
- 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:
- LXI H,CBUFF ;PT TO USER'S COMMAND
- MOV B,M ;CHAR COUNT IN B
- INR B ;ADD 1 IN CASE OF ZERO
- CB1:
- INX H ;PT TO 1ST VALID CHAR
- MOV A,M ;CAPITALIZE COMMAND CHAR
- CALL UCASE
- MOV M,A
- DJNZ CB1 ;CONTINUE TO END OF COMMAND LINE
- CB2:
- MVI M,0 ;STORE ENDING <NULL>
- LXI H,CIBUFF ;SET COMMAND LINE PTR TO 1ST CHAR
- SHLD CIBPTR
- RET
- ;
- ; CHECK FOR ANY CHAR FROM USER CONSOLE;RET W/ZERO SET IF NONE
- ;
- BREAK:
- PUSH D ;SAVE DE
- MVI C,11 ;CSTS CHECK
- CALL BDOSB
- CNZ CONIN ;GET INPUT CHAR
- BRKBK:
- POP D
- RET
- ;
- ; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT.
- ;
- USRNUM:
- CALL NUMBER
- CPI MAXUSR+1
- RC
- ;
- ; INVALID COMMAND -- PRINT IT
- ;
- ERROR:
- CALL CRLF ;NEW LINE
- LHLD CIPTR ;PT TO BEGINNING OF COMMAND LINE
- ERR2:
- MOV A,M ;GET CHAR
- CPI ' '+1 ;SIMPLE '?' IF <SP> OR LESS
- JRC ERR1
- PUSH H ;SAVE PTR TO ERROR COMMAND CHAR
- CALL CONOUT ;PRINT COMMAND CHAR
- POP H ;GET PTR
- INX H ;PT TO NEXT
- JR ERR2 ;CONTINUE
- ERR1:
- CALL PRINT ;PRINT '?'
- DB '?'+80H
- CALL SUBKIL ;TERMINATE ACTIVE $$$.SUB IF ANY
- JMP RESTRT ;RESTART CPR
- ;
- ; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
- ;
- SDELM:
- LDAX D
- ORA A ;0=DELIMITER
- RZ
- CPI ' ' ;ERROR IF < <SP>
- JRC ERROR
- RZ ;<SP>=DELIMITER
- CPI '=' ;'='=DELIMITER
- RZ
- CPI 5FH ;UNDERSCORE=DELIMITER
- RZ
- CPI '.' ;'.'=DELIMITER
- RZ
- CPI ':' ;':'=DELIMITER
- RZ
- CPI ';' ;';'=DELIMITER
- RZ
- CPI '<' ;'<'=DELIMITER
- RZ
- CPI '>' ;'>'=DELIMITER
- RET
- ;
- ; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
- ;
- ADVAN:
- LDED CIBPTR
- ;
- ; SKIP STRING PTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING
- ; OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN)
- ;
- SBLANK:
- LDAX D
- ORA A
- RZ
- CPI ' '
- RNZ
- INX D
- JR SBLANK
- ;
- ; ADD A TO HL (HL=HL+A)
- ;
- ADDAH:
- ADD L
- MOV L,A
- RNC
- INR H
- RET
- ;
- ; EXTRACT DECIMAL NUMBER FROM COMMAND LINE
- ; RETURN WITH VALUE IN REG A;ALL REGISTERS MAY BE AFFECTED
- ;
- NUMBER:
- CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN
- LXI H,FCBFN+10 ;PT TO END OF TOKEN FOR CONVERSION
- MVI B,11 ;11 CHARS MAX
- ;
- ; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
- ;
- NUMS:
- MOV A,M ;GET CHARS FROM END, SEARCHING FOR SUFFIX
- DCX H ;BACK UP
- CPI ' ' ;SPACE?
- JRNZ NUMS1 ;CHECK FOR SUFFIX
- DJNZ NUMS ;COUNT DOWN
- JR NUM0 ;BY DEFAULT, 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 <SP>
- 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
- ;
- 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 NUMBASE ;DONE IF NUMBASE 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:
- TEMPDR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TEMPDR
- 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 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
- ;
- ; ENTRY POINTS:
- ; SCANER - LOAD TOKEN INTO FIRST FCB
- ; SCANX - LOAD TOKEN INTO FCB PTED TO BY HL
- ;
- SCANER:
- LXI H,FCBDN ;POINT TO FCBDN
- SCANX:
- 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
- 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:
- 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:
- XRA A ;A=0
- STA QMCNT ;INIT COUNT OF NUMBER OF QUESTION MARKS IN FCB
- MVI B,8 ;MAX OF 8 CHARS IN FILE NAME
- CALL SCANF ;FILL FCB FILE NAME
- ;
- ; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP
- ;
- MVI B,3 ;PREPARE TO EXTRACT TYPE
- CPI '.' ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE
- JRNZ SCAN15 ;FILL FILE TYPE BYTES WITH <SP>
- INX D ;PT TO CHAR IN COMMAND LINE AFTER '.'
- CALL SCANF ;FILL FCB FILE TYPE
- JR SCAN16 ;SKIP TO NEXT PROCESSING
- SCAN15:
- CALL SCANF4 ;SPACE FILL
- ;
- ; 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
- ;
- LDA QMCNT ;GET NUMBER OF QUESTION MARKS
- ORA A ;SET ZERO FLAG TO INDICATE ANY '?'
- RET
- ;
- ; SCANF -- SCAN TOKEN PTED TO BY DE FOR A MAX OF B BYTES; PLACE IT INTO
- ; FILE NAME FIELD PTED TO BY HL; EXPAND AND INTERPRET WILD CARDS OF
- ; '*' AND '?'; ON EXIT, DE PTS TO TERMINATING DELIMITER
- ;
- SCANF:
- CALL SDELM ;DONE IF DELIMITER ENCOUNTERED - <SP> FILL
- JRZ SCANF4
- INX H ;PT TO NEXT BYTE IN FCBDN
- CPI '*' ;IS (DE) A WILD CARD?
- JRNZ SCANF1 ;CONTINUE IF NOT
- MVI M,'?' ;PLACE '?' IN FCBDN AND DON'T ADVANCE DE IF SO
- CALL SCQ ;SCANNER COUNT QUESTION MARKS
- JR SCANF2
- SCANF1:
- MOV M,A ;STORE FILENAME CHAR IN FCBDN
- INX D ;PT TO NEXT CHAR IN COMMAND LINE
- CPI '?' ;CHECK FOR QUESTION MARK (WILD)
- CZ SCQ ;SCANNER COUNT QUESTION MARKS
- SCANF2:
- DJNZ SCANF ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED
- SCANF3:
- CALL SDELM ;8 CHARS OR MORE - SKIP UNTIL DELIMITER
- RZ ;ZERO FLAG SET IF DELIMITER FOUND
- INX D ;PT TO NEXT CHAR IN COMMAND LINE
- JR SCANF3
- ;
- ; FILL MEMORY POINTED TO BY HL WITH SPACES FOR B BYTES
- ;
- SCANF4:
- INX H ;PT TO NEXT BYTE IN FCBDN
- MVI M,' ' ;FILL FILENAME PART WITH <SP>
- DJNZ SCANF4
- RET
- ;
- ; INCREMENT QUESTION MARK COUNT FOR SCANNER
- ; THIS ROUTINE INCREMENTS THE COUNT OF THE NUMBER OF QUESTION MARKS IN
- ; THE CURRENT FCB ENTRY
- ;
- SCQ:
- LDA QMCNT ;GET COUNT
- INR A ;INCREMENT
- STA QMCNT ;PUT COUNT
- RET
- ;
- ; CMDTBL (COMMAND TABLE) SCANNER
- ; ON RETURN, HL PTS TO ADDRESS OF COMMAND IF CPR-RESIDENT
- ; ON RETURN, ZERO FLAG SET MEANS CPR-RESIDENT COMMAND
- ;
- CMDSER:
- LXI H,CMDTBL ;PT TO COMMAND TABLE
- ;
- IF SECURE
- MVI C,NRCMDS
- LDA WHEEL ;SEE IF NON-RESTRCTED
- CPI RESTRCT
- JRZ CMS1 ;PASS IF RESTRCTED
- ENDIF ;SECURE
- ;
- MVI C,NCMNDS ;SET COMMAND COUNTER
- 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 <SP>
- CPI ' '
- JRNZ CMS4
- RET ;COMMAND IS CPR-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 ****
- ; CPR-Resident Commands
- ;
- ;
- ;Section 5A
- ;Command: DIR
- ;Function: To display a directory of the files on disk
- ;Forms:
- ; DIR <afn> Displays the DIR files
- ; DIR <afn> S Displays the SYS files
- ; DIR <afn> A Display both DIR and SYS files
- IF TYPEDIR ;SOME OF THIS CODE IS UNWANTED
- ;
- 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 <SP>, ALL WILD
- CZ FILLQ
- CALL ADVAN ;LOOK AT NEXT INPUT CHAR
- MVI B,0 ;SYS TOKEN DEFAULT
- JRZ DIR2 ;JUMP; THERE ISN'T ONE
- CPI SYSFLG ;SYSTEM FLAG SPECIFIER?
- JRZ GOTSYS ;GOT SYSTEM SPECIFIER
- CPI SOFLG ;SYS ONLY?
- JRNZ DIR2
- MVI B,80H ;FLAG SYS ONLY
- GOTSYS:
- INX D
- SDED CIBPTR
- CPI SOFLG ;SYS ONLY SPEC?
- JRZ DIR2 ;THEN LEAVE BIT SPEC UNCHAGNED
- POP PSW ;GET FLAG
- XRA A ;SET NO SYSTEM BIT EXAMINATION
- PUSH PSW
- DIR2:
- POP PSW ;GET FLAG
- DIR2A:
- ;DROP INTO DIRPR TO PRINT DIRECTORY
- ; THEN RESTART CPR
- ;
- ; DIRECTORY PRINT ROUTINE; ON ENTRY, MSB OF A IS 1 (80H) IF SYSTEM FILES EXCL
- ;
- ENDIF ;DIRPR THE FOLLOWING CODE IS NEEDED BY ERA
- DIRPR:
- MOV D,A ;STORE SYSTEM FLAG IN D
- MVI E,0 ;SET COLUMN COUNTER TO ZERO
- PUSH D ;SAVE COLUMN COUNTER (E) AND SYSTEM FLAG (D)
- MOV A,B ;SYS ONLY SPECIFIER
- STA SYSTST
- CALL SEARF ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRANCE)
- CZ PRNNF ;PRINT NO FILE MSG;REG A NOT CHANGED
- ;
- ; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN
- ;
- DIR3:
- JRZ DIR11 ;DONE IF ZERO FLAG SET
- DCR A ;ADJUST TO RETURNED VALUE
- RRC ;CONVERT NUMBER TO OFFSET INTO TBUFF
- RRC
- RRC
- ANI 60H
- MOV C,A ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
- MVI A,10 ;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT
- CALL DIRPTR
- POP D ;GET SYSTEM BIT MASK FROM D
- PUSH D
- ANA D ;MASK FOR SYSTEM BIT
- SYSTST EQU $+1 ;POINTER TO IN-THE-CODE BUFFER SYSTST
- CPI 0
- JRNZ DIR10
- POP D ;GET ENTRY COUNT (=<CR> COUNTER)
- MOV A,E ;ADD 1 TO IT
- INR E
- PUSH D ;SAVE IT
- ;
- IF TWOCOL
- ANI 01H ;OUTPUT <CRLF> IF 2 ENTRIES PRINTED IN LINE
- ENDIF ;TWOCOL
- ;
- IF NOT TWOCOL
- TWOPOK EQU $+1 ;FOR APPLE PATCHING
- ANI 03H ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
- ENDIF ;NOT TWOCOL
- ;
- PUSH PSW
- JRNZ DIR4
- CALL CRLF ;NEW LINE
- JR DIR5
- DIR4:
- CALL PRINT
- ;
- IF WIDE
- DB ' ' ;2 SPACES
- DB FENCE ;THEN FENCE CHAR
- DB ' ',' '+80H ;THEN 2 MORE SPACES
- ENDIF
- ;
- IF NOT WIDE
- DB ' ' ;SPACE
- DB FENCE ;THEN FENCE CHAR
- DB ' '+80H ;THEN SPACE
- ENDIF
- ;
- DIR5:
- MVI B,01H ;PT TO 1ST BYTE OF FILE NAME
- DIR6:
- MOV A,B ;A=OFFSET
- CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE NAME
- ANI 7FH ;MASK OUT MSB
- CPI ' ' ;NO FILE NAME?
- JRNZ DIR8 ;PRINT FILE NAME IF PRESENT
- POP PSW
- PUSH PSW
- CPI 03H
- JRNZ DIR7
- MVI A,09H ;PT TO 1ST BYTE OF FILE TYPE
- CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE TYPE
- ANI 7FH ;MASK OUT MSB
- CPI ' ' ;NO FILE TYPE?
- JRZ DIR9 ;CONTINUE IF SO
- DIR7:
- MVI A,' ' ;OUTPUT <SP>
- DIR8:
- CALL CONOUT ;PRINT CHAR
- INR B ;INCR CHAR COUNT
- MOV A,B
- CPI 12 ;END OF FILENAME.TYP?
- JRNC DIR9 ;CONTINUE IF SO
- CPI 09H ;END IF FILENAME ONLY?
- JRNZ DIR6 ;PRINT TYP IF SO
- MVI A,'.' ;PRINT DOT BETWEEN FILE NAME AND TYPE
- CALL CONOUT
- JR DIR6
- DIR9:
- POP PSW
- DIR10:
- CALL BREAK ;CHECK FOR ABORT
- JRNZ DIR11
- CALL SEARN ;SEARCH FOR NEXT FILE
- JR DIR3 ;CONTINUE
- DIR11:
- POP D ;RESTORE STACK
- RET
- ;
- ; FILL FCB @HL WITH '?'
- ;
- FILLQ:
- MVI B,11 ;NUMBER OF CHARS IN FN & FT
- FQLP:
- MVI M,'?' ;STORE '?'
- INX H
- DJNZ FQLP
- RET
- ;
- ;Section 5B
- ;Command: ERA
- ;Function: Erase files
- ;Forms:
- ; ERA <afn> Erase Specified files and print their names
- ;
- IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM
- ;
- ERA:
- CALL SCANER ;PARSE FILE SPECIFICATION
- CPI 11 ;ALL WILD (ALL FILES = 11 '?')?
- JRNZ ERA1 ;IF NOT, THEN DO ERASES
- CALL PRINTC
- DB 'All','?'+80H
- CALL CONIN ;GET REPLY
- CPI 'Y' ;YES?
- JNZ RESTRT ;RESTART CPR IF NOT
- CALL CRLF ;NEW LINE
- ERA1:
- CALL SLOGIN ;LOG IN SELECTED DISK IF ANY
- XRA A ;PRINT ALL FILES (EXAMINE SYSTEM BIT)
- MOV B,A ;NO SYS-ONLY OPT TO DIRPR
- CALL DIRPR ;PRINT DIRECTORY OF ERASED FILES
- LXI D,FCBDN ;DELETE FILE SPECIFIED
- JMP DELETE ;RESTART CPR AFTER DELETE
- ;
- ENDIF ;RAS
- ;
- ;Section 5C
- ;Command: LIST
- ;Function: Print out specified file on the LST: Device
- ;Forms:
- ; LIST <ufn> Print file (NO Paging)
- ;
- IF TYPEDIR
- LIST:
- MVI A,0FFH ;TURN ON PRINTER FLAG
- JR TYPE0
- ENDIF ;TYPEDIR
- ;
- ;Section 5D
- ;Command: TYPE
- ;Function: Print out specified file on the CON: Device
- ;Forms:
- ; TYPE <ufn> Print file
- ; TYPE <ufn> P Print file with paging flag
- ;
- IF TYPEDIR ;IF TYPEDIR IS TRUE...
- TYPE:
- XRA A ;TURN OFF PRINTER FLAG
- ;
- ; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
- ;
- TYPE0:
- STA PRFLG ;SET FLAG
- ;
- CALL SCANER ;EXTRACT FILENAME.TYP TOKEN
- JNZ ERROR ;ERROR IF ANY QUESTION MARKS
- CALL ADVAN ;GET PGDFLG IF IT'S THERE
- STA PGFLG ;SAVE IT AS A FLAG
- JRZ NOSLAS ;JUMP IF INPUT ENDED
- INX D ;PUT NEW BUF POINTER
- XCHG
- SHLD CIBPTR
- NOSLAS:
- CALL SLOGIN ;LOG IN SELECTED DISK IF ANY
- CALL OPENF ;OPEN SELECTED FILE
- JZ TYPE4 ;ABORT IF ERROR
- CALL CRLF ;NEW LINE
- MVI A,NLINES-1 ;SET LINE COUNT
- STA PAGCNT
- mvi a,ncolms ;set colm count
- sta colcnt
- LXI H,CHRCNT ;SET CHAR POSITION/COUNT
- MVI M,0FFH ;EMPTY LINE
- MVI B,0 ;SET TAB CHAR COUNTER
- TYPE1:
- LXI H,CHRCNT ;PT TO CHAR POSITION/COUNT
- MOV A,M ;END OF BUFFER?
- CPI 80H
- JRC TYPE2
- PUSH H ;READ NEXT BLOCK
- CALL READF
- POP H
- JRNZ TYPE3 ;ERROR?
- XRA A ;RESET COUNT
- MOV M,A
- TYPE2:
- INR M ;INCREMENT CHAR COUNT
- LXI H,TBUFF ;PT TO BUFFER
- CALL ADDAH ;COMPUTE ADDRESS OF NEXT CHAR FROM OFFSET
- MOV A,M ;GET NEXT CHAR
- ANI 7FH ;MASK OUT MSB
- CPI 1AH ;END OF FILE (^Z)?
- RZ ;RESTART CPR IF SO
- ;
- ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
- ;
- CPI CR ;IS CHAR A CR?
- JRNZ NOCR ;NO
- MVI B,0 ;YES, RESET TAB COUNT
- NOCR: CPI ' ' ;CONTROL CODE?
- JRC NOPRT ;DON'T BUMP CHARACTER COUNT
- INR B ;INCREMENT CHAR COUNT
- NOPRT: CPI TAB ;TAB?
- JRZ LTAB ;YES, EXPAND IT
- CALL LCOUT ;PRINT IT
- JR TYPE2L
- LTAB:
- MVI A,' ' ;<SP>
- CALL LCOUT
- INR B ;INCR POS COUNT
- MOV A,B
- ANI 7
- JRNZ LTAB
- ;
- ; CONTINUE PROCESSING
- ;
- ;
- TYPE2L:
- CALL BREAK ;CHECK FOR ABORT
- JRZ TYPE1 ;CONTINUE IF NO CHAR
- CPI 'C'-'@' ;^C?
- RZ ;RESTART IF SO
- JR TYPE1
- TYPE3:
- DCR A ;NO ERROR?
- RZ ;RESTART CPR
- TYPE4:
- JMP ERRLOG
- ENDIF ;TYPEDIR
- ;
- ;Section 5E
- ;Command: SAVE
- ;Function: To save the contents of the TPA onto disk as a file
- ;Forms:
- ; SAVE <Number of Pages> <ufn>
- ; Save specified number of pages (start at 100H)
- ; from TPA into specified file; <Number of
- ; Pages> is in DEC
- ; SAVE <Number of Sectors> <ufn> S
- ; Like SAVE above, but numeric argument specifies
- ; number of sectors rather than pages
- ;
- IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM
- ;
- SAVE:
- CALL NUMBER ;EXTRACT NUMBER FROM COMMAND LINE
- MOV L,A ;HL=PAGE COUNT
- MVI H,0
- PUSH H ;SAVE PAGE COUNT
- CALL EXTEST ;TEST FOR EXISTENCE OF FILE AND ABORT IF SO
- MVI C,16H ;BDOS MAKE FILE
- CALL GRBDOS
- POP H ;GET PAGE COUNT
- JRZ SAVE3 ;ERROR?
- XRA A ;SET RECORD COUNT FIELD OF NEW FILE'S FCB
- STA FCBCR
- CALL ADVAN ;LOOK FOR 'S' FOR SECTOR OPTION
- INX D ;PT TO AFTER 'S' TOKEN
- CPI SECTFLG
- JRZ SAVE0
- DCX D ;NO 'S' TOKEN, SO BACK UP
- DAD H ;DOUBLE IT FOR HL=SECTOR (128 BYTES) COUNT
- SAVE0:
- SDED CIBPTR ;SET PTR TO BAD TOKEN OR AFTER GOOD TOKEN
- LXI D,TPA ;PT TO START OF SAVE AREA (TPA)
- SAVE1:
- MOV A,H ;DONE WITH SAVE?
- ORA L ;HL=0 IF SO
- JRZ SAVE2
- DCX H ;COUNT DOWN ON SECTORS
- PUSH H ;SAVE PTR TO BLOCK TO SAVE
- LXI H,128 ;128 BYTES PER SECTOR
- DAD D ;PT TO NEXT SECTOR
- PUSH H ;SAVE ON STACK
- CALL DMASET ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE)
- LXI D,FCBDN ;WRITE SECTOR
- MVI C,15H ;BDOS WRITE SECTOR
- CALL BDOSB ;SAVE BC
- POP D ;GET PTR TO NEXT SECTOR IN DE
- POP H ;GET SECTOR COUNT
- JRZ SAVE1 ;CONTINUE IF NO WRITE ERROR
- JR PRNLE ;GO PRINT ERROR AND RESET DMA
- SAVE2:
- LXI D,FCBDN ;CLOSE SAVED FILE
- CALL CLOSE
- INR A ;ERROR?
- JRNZ SAVE3 ;PASS IF OK
- ;
- ; PRNLE IS ALSO USED BY MEMLOAD FOR TPA FULL ERROR
- ;
- PRNLE: CALL PRINTC ;DISK OR MEM FULL
- DB 'Ful','l'+80H
- ;
- SAVE3: JMP DEFDMA ;SET DMA TO 0080 AND RESTART CPR
- ; OR RETURN TO MLERR
- ;
- ; Test File in FCB for existence, ask user to delete if so, and abort if he
- ; choses not to
- ;
- EXTEST:
- CALL SCANER ;EXTRACT FILE NAME
- JNZ ERROR ;'?' IS NOT PERMITTED
- CALL SLOGIN ;LOG IN SELECTED DISK
- CALL SEARF ;LOOK FOR SPECIFIED FILE
- LXI D,FCBDN ;PT TO FILE FCB
- RZ ;OK IF NOT FOUND
- PUSH D ;SAVE PTR TO FCB
- CALL PRINTC
- DB 'Delete File','?'+80H
- CALL CONIN ;GET RESPONSE
- POP D ;GET PTR TO FCB
- CPI 'Y' ;KEY ON YES
- JNZ RSTCPR ;RESTART IF NO, SP RESET EVENTUALLY
- PUSH D ;SAVE PTR TO FCB
- CALL DELETE ;DELETE FILE
- POP D ;GET PTR TO FCB
- RET
- ;
- ENDIF ;RAS
- ;
- ;Section 5F
- ;Command: REN
- ;Function: To change the name of an existing file
- ;Forms:
- ; REN <New ufn>=<Old ufn> Perform function
- ;
- IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM
- ;
- REN:
- CALL EXTEST ;TEST FOR FILE EXISTENCE AND RETURN
- ; IF FILE DOESN'T EXIST; ABORT IF IT DOES
- LDA TEMPDR ;SAVE CURRENT DEFAULT DISK
- PUSH PSW ;SAVE ON STACK
- 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 <unum> Select specified user number;<unum> is in DEC
- ;
- IF DRUSER ;IF DRIVE/USER CODE OK...
- USER:
- CALL USRNUM ;EXTRACT USER NUMBER FROM COMMAND LINE
- MOV E,A ;PLACE USER NUMBER IN E
- SUSER: CALL SETUSR ;SET SPECIFIED USER
- ENDIF ;DRUSER
- RSTJMP:
- JMP RCPRNL ;RESTART CPR
- ;
- ;Section 5H
- ;Command: DFU
- ;Function: Set the Default User Number for the command/file scanner
- ; (MEMLOAD)
- ; Note: When under SECURE mode, this will select the second
- ; user area to check for programs (normally user 15).
- ;
- ;Forms:
- ; DFU <unum> Select Default User Number;<unum> is in DEC
- ;
- IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM
- DFU:
- CALL USRNUM ;GET USER NUMBER
- STA DFUSR ;PUT IT AWAY
- JR RSTJMP ;RESTART CPR (NO DEFAULT LOGIN)
- ENDIF ;NOT RAS
- ;
- ;Section 5I
- ;Command: JUMP
- ;Function: To Call the program (subroutine) at the specified address
- ; without loading from disk
- ;Forms:
- ; JUMP <adr> Call at <adr>;<adr> 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 <parameters like for COMMAND>
- ;
- 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:
- ; <command>
- ;
- COM:
- LDA FCBFN ;ANY COMMAND?
- CPI ' ' ;' ' MEANS COMMAND WAS 'D:' TO SWITCH
- JRNZ COM1 ;NOT <SP>, SO MUST BE TRANSIENT OR ERROR
- LDA TEMPDR ;LOOK FOR DRIVE SPEC
- ORA A ;IF ZERO, JUST BLANK
- JZ RCPRNL
- DCR A ;ADJUST FOR LOG IN
- STA TDRIVE ;SET DEFAULT DRIVE
- CALL SETU0D ;SET DRIVE WITH USER 0
- CALL LOGIN ;LOG IN DRIVE
- ;
- IF DRUSER ;DRIVE/USER HACKERY OK?
- CALL USRNUM ;GET USER #, IF ANY
- MOV E,A ;GET IT READY FOR BDOS
- LDA FCBFN ;SEE IF # SPECIFIED
- CPI ' '
- JRNZ SUSER ;SELECT IF WANTED
- ENDIF ;DRUSER
- ;
- JMP RCPRNL ;RESTART CPR
- 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
- ; (NO RETURN IF ERROR OR TOO BIG)
- 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:
- 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
- LXI H,FCBDN+10H ;PT TO 2ND FILE NAME
- CALL SCANX ;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-1
- COM4:
- INX H
- MOV A,M ;SKIP TO END OF 2ND FILE NAME
- ORA A ;END OF LINE?
- JRZ COM5
- CPI ' ' ;END OF TOKEN?
- JRNZ COM4
- ;
- ; LOAD COMMAND LINE INTO TBUFF
- ;
- COM5:
- MVI B,-1 ;SET CHAR COUNT
- LXI D,TBUFF ;PT TO CHAR POS
- DCX H
- COM6:
- INR B ;INCR CHAR COUNT
- INX H ;PT TO NEXT
- INX D
- MOV A,M ;COPY COMMAND LINE TO TBUFF
- STAX D
- ORA A ;DONE IF ZERO
- JRNZ 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 CPR
- ;
- ;Section 5L
- ;Command: GET
- ;Function: To load the specified file from disk to the specified address
- ;Forms:
- ; GET <adr> <ufn> Load the specified file at the specified page;
- ; <adr> is in HEX
- ;
- IF NOT RAS ;NOT FOR REMOTE-ACCESS SYSTEM
- ;
- GET:
- CALL HEXNUM ;GET LOAD ADDRESS IN HL
- PUSH H ;SAVE ADDRESS
- CALL SCANER ;GET FILE NAME
- POP H ;RESTORE ADDRESS
- JNZ ERROR ;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
- ; OTHER ERROR, EXIT DIRECTLY TO MLERR.
- ;
- MEMLOAD:
- SHLD LOADADR ;SET LOAD ADDRESS
- CALL GETUSR ;GET CURRENT USER NUMBER
- STA TMPUSR ;SAVE IT FOR LATER
- 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:
- CALL SLOGIN ;LOG IN SPECIFIED DRIVE IF ANY
- CALL OPENF ;OPEN COMMAND.COM FILE
- JRNZ MLA1 ;FILE FOUND - LOAD IT
- ;
- IF SECURE
- ;
- ; IF SECURE ENABLED, SEARCH CURRENT DRIVE, CURRENT USER, THEN
- ; CURRENT DRIVE, USER 15 IF A WHEEL ONLY, THEN CURRENT DRIVE,
- ; USER ZERO. IF STILL NOT FOUND, REPEAT ON DRIVE A:.
- ;
- DFLAG EQU $+1 ;MARK IN-THE-CODE VARIABLE
- MVI A,0 ;HAVE WE CHECKED THIS DRIVE ALREADY?
- ORA A
- JRNZ MLA0 ;PASS IF SO TO GO TO DRIVE A:
- LDA WHEEL ;USER 15 PROGS ALLOWED?
- CnI RESTRCT
- JRZ MLA00 ;PASS IF NOT
- PUSH B ;PUSH BC
- LDA DFUSR ;LOAD DEFAULT USER (NORMALLY 15)
- MOV B,A ;PUT IT IN B
- LDA TSELUSR ;CHECK CURR USER
- DFUSR EQU $+1 ;DEFAULT USER LOCATION
- CPI DEFUSR ;USER 15? (OR OTHER DEFAULT USER AREA)
- MOV A,B ;ASSUME NOT
- POP B ;RESTORE BC
- JRNZ SETTSE ;GO TRY IF NOT
- MLA00: ;SS IF NOT
- TSELUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE
- MVI A,0 ;GET CURR USER
- ORA A ;IS IT 0?
- JRZ MLA0 ;NO MORE CHOICES IF SO
- STA DFLAG ;MAKE DFLAG NON-ZERO IF NOT
- XRA A ; AND TRY USER 0
- SETTSE:
- ENDIF ;SECURE
- ;
- IF NOT SECURE
- DFUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE
- MVI A,DEFUSR ;GET DEFAULT USER
- TSELUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE
- CPI DEFUSR ;CHECK FOR THE USER AREA..
- JRZ MLA0 ;..EQUAL DEFAULT, AND JUMP IF SO
- ENDIF ;NOT SECURE
- ;
- STA TSELUSR ;PUT DOWN NEW ONE
- MOV E,A
- CALL SETUSR ;GO SET NEW USER NUMBER
- JR MLA ;AND TRY AGAIN
- ;
- ; ERROR ROUTINE TO SELECT DRIVE A: IF DEFAULT WAS ORIGINALLY SELECTED
- ;
- MLA0:
- LXI H,TEMPDR ;GET DRIVE FROM CURRENT COMMAND
- XRA A ;A=0
- ;
- IF SECURE
- STA DFLAG ;ALLOW A: SEARCH
- ENDIF ;SECURE
- ;
- ORA M
- JNZ MLERR ;ERROR IF ALREADY DISK A:
- MVI M,3 ;SELECT DRIVE C:
- ;
- IF NOT SECURE
- JR MLA
- ENDIF ;NOT SECURE
- ;
- IF SECURE
- LDA TMPUSR ;GO TO 'CURRENT' USER CODE
- JR SETTSE
- ENDIF ;SECURE
- ;
- ; FILE FOUND -- PROCEED WITH LOAD
- ;
- MLA1:
- LOADADR EQU $+1
- LXI H,TPA
- ML2:
- MVI A,ENTRY/256-1 ;GET HIGH-ORDER ADR OF JUST BELOW CPR
- CMP H ;ARE WE GOING TO OVERWRITE THE CPR?
- JRC ML4 ;ERROR IF SO
- PUSH H ;SAVE ADDRESS OF NEXT SECTOR
- XCHG ;... IN DE
- CALL DMASET ;SET DMA ADDRESS FOR LOAD
- LXI D,FCBDN ;READ NEXT SECTOR
- CALL READ
- POP H ;GET ADDRESS OF NEXT SECTOR
- JRNZ ML3 ;READ ERROR OR EOF?
- LXI D,128 ;MOVE 128 BYTES PER SECTOR
- DAD D ;PT TO NEXT SECTOR IN HL
- JR ML2
- ;
- ML3:
- DCR A ;LOAD COMPLETE
- JZ RESETUSR ;IF ZERO, OK, GO RESET CORRECT USER #
- ; ON WAY OUT, ELSE FALL THRU TO PRNLE
- ;
- ; TPA FULL
- ;
- ML4: CALL PRNLE ;PRINT MSG AND RESET DEF DMA
- ;
- ; TRANSIENT LOAD ERROR
- ;
- MLERR:
- ;NOTE THAT THERE IS AN EXTRA RETURN ADDRESS ON
- ; THE STACK. IT WILL BE TOSSED WHEN ERROR EXITS
- ; TO RESTRT, WHICH RELOADS SP.
- CALL RESETUSR ;RESET CURRENT USER NUMBER
- ; RESET MUST BE DONE BEFORE LOGIN
- ERRLOG:
- CALL DLOGIN ;LOG IN DEFAULT DISK
- JMP ERROR ;FLAG ERROR
- ;
- ;
- ;Section: 5M
- ;PASS: Enable wheel mode.
- ;NORM: Disable wheel mode.
- ;
- ; Type PASS <password> <cr> to CP/M prompt to enter wheel mode.
- ; This code can be replaced with PST's PASS.ASM which gives many
- ; nice little options like no keyboard echo, etc.
- ;
- IF INPASS ;WE WANT TO USE THIS CODE, NOT PASS.COM
- PASS:
- LXI H,PASSWD ;SET UP POINTERS
- LXI D,CIBUFF+NCHARS+1
- MVI B,PRGEND-PASSWD ;B= LENGTH
- CKPASS: LDAX D ;TRIAL PW TO A
- CMP M ;CHECK FOR MATCH
- JNZ COM ;NOPE.. LOOK FOR PASS.COM
- INX H ;INCREMENT COUNTER
- INX D
- DJNZ CKPASS ;CONTINUE IF MORE
- MVI A,TRUE ;WHEEL=TRUE
- PWOUT: STA WHEEL
- JMP RESTRT
- ;
- NORM:
- MVI A,RESTRCT
- JR PWOUT
- ;
- PASSWD:
- DB 'YOURPW' ;YOUR PASSWORD
- PRGEND: EQU $ ;END OF PASSWORD
- ;
- ENDIF ;INPASS
- ;
- END
-