home *** CD-ROM | disk | FTP | other *** search
- TITLE 'ZCPR Version 1.0'
- ;
- ; CP/M Z80 Command Processor Replacement (CPR) Version 1.0
- ; CCPZ CREATED AND 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
- ; ZCPR VERSION 1.0 CREATED FROM CCPZ VERSION 4.0 BY RLC IN
- ; A COORDINATED EFFORT WITH CCP-GROUP
- ;
- ; ZCPR is a group effort by CCP-GROUP, whose active membership involved
- ; in this project consists of the following:
- ; RLC - Richard Conn
- ; RGF - Ron Fowler
- ; KBP - Keith Peterson
- ; FJW - Frank Wancho
- ; The following individual also provided a contribution:
- ; SBB - Steve Bogolub
- ;
- ;
- ;******** Structure Notes ********
- ;
- ; This CPR 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 CPR
- ;
- ; 1 Buffers
- ;
- ; 2 CPR Starting Modules
- ; CPR1 CPR RESTRT RSTCPR RCPRNL
- ; 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
- ; RESETUSR GETUSR SETUSR
- ;
- ; 4 CPR Utilities
- ; SETUD SETU0D UCASE REDBUF CNVBUF
- ; BREAK USRNUM ERROR SDELM ADVAN
- ; SBLANK ADDAH NUMBER NUMERR HEXNUM
- ; DIRPTR SLOGIN DLOGIN COMLOG SCANER
- ; CMDSER
- ;
- ; 5 CPR-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
- ;
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- ; CUSTOMIZATION EQUATES
- ;
- ; The following equates may be used to customize this CPR 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)
- ;
- ; CPRLOC - Base Page Address of CPR; 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 CPR commands that are considered harmful in a Remote-
- ; Access environment; use under Remote-Access Systems (RBBS) for
- ; security purposes
- ;
- REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION
- ;
- BASE EQU 0 ;BASE OF CP/M SYSTEM (SET FOR STANDARD CP/M)
- ;
- IF REL
- CPRLOC EQU 0 ;MOVCPM IMAGE
- ELSE
- ;
- ; If REL is FALSE, the value of CPRLOC 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:
- ;
- ;MSIZE EQU 56 ;SIZE OF MEM IN K-BYTES
- ;BIOSEX EQU 0 ;EXTRA # K-BYTES IN BIOS
- ;CPRLOC EQU 3400H+(MSIZE-20-BIOSEX)*1024 ;CPR ORIGIN
- ;
- ; The second way is to obtain the origin of your current
- ; CPR using BDSLOC or its equivalent, then merely set CPRLOC
- ; to that value as as in the following line:
- ;
- CPRLOC EQU 0BD00H ;FILL IN WITH BDOSLOC SUPPLIED VALUE
- ;
- ; Note that you should only use one method or the other.
- ; Do NOT define CPRLOC twice!
- ;
- ; The following gives the required offset to load the CPR 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
- ; CPR in YOUR CP/M system; several systems (Morrow Designs, P&T, Heath
- ; Org-0 to name a few) have the CPR located at a non-standard address in
- ; the SYSGEN Image
- ;
- ;CPRR EQU 0980H-CPRLOC ;DDT LOAD OFFSET
- CPRR EQU 1100H-CPRLOC ;DDT LOAD OFFSET FOR MORROW DESIGNS
- ENDIF
- ;
- RAS EQU FALSE ;SET TO TRUE IF CPR IS FOR A REMOTE-ACCESS SYSTEM
- ;
- ; 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 ZCPR 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 ZCPR perform the same type of
- ; function as CCP (look for the $$$.SUB file on A:), but the problem with
- ; 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 ZCPR (the $$$.SUB File).
- ; ZCPR 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
- ; ZCPR 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.
- ;
- 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 ZCPR. 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
- ; ZCPR command. All the user program need do is to store the command line and
- ; set the character count; ZCPR 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 ZCPR through CPRLOC [NOTE: The C register MUST contain
- ; a valid User/Disk Flag (see location 4) at this time.]
- ;
- CLEVEL3 equ TRUE ;ENABLE COMMAND LEVEL 3 PROCESSING
- ;
- ;
- ;*** 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 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
- ;
- 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
- ;
- DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES
- ;
- 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 ZCPR 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 CPR, 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 ZCPR, this is
- ; no longer the case. The CIBPTR (Command Input Buffer PoinTeR) is located
- ; to be compatable with such programs (provided they determine the buffer
- ; length from the byte at MBUFF [CPRLOC + 6]), but under Version 4.x of ZCPR
- ; this is no longer necessary. ZCPR Version 4.x automatically initializes
- ; this buffer pointer 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 CCPZ Version 4.0, 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
- DS BUFLEN-($-CIBUFF)+1 ;TOTAL IS 'BUFLEN' BYTES
- ;
- CIBPTR:
- DW CIBUFF ;POINTER TO COMMAND INPUT BUFFER
- CIPTR:
- DW CIBUF ;CURRENT POINTER
- ;
- 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
- ;
- ; 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:
- DB 'DIR '
- DW DIR
- DB 'LIST'
- DW LIST
- DB 'TYPE'
- DW TYPE
- DB 'USER'
- DW USER
- DB 'DFU '
- DW DFU
- ;
- 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 ****
- ; CPR STARTING POINTS
- ;
- ; 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
- ;
- ;**** 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
- JMP UCASE ;CAPITALIZE
- ;
- 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 ;OUTPUT TO CON:
- POP PSW
- CPI LF ;CHECK FOR PAGING
- JZ PAGER
- 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
- 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
- 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
- ;
- ; CONVERT CHAR IN A TO UPPER CASE
- ;
- UCASE:
- CPI 61H ;LOWER-CASE A
- RC
- CPI 7BH ;GREATER THAN LOWER-CASE Z?
- RNC
- ANI 5FH ;CAPITALIZE
- 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
- 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
- ;
- 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
- ;
- 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
- ANI 03H ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
- 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
- CALL DELETE
- RET ;REENTER CPR
- ;
- ENDIF ;RAS
- ;
- ;Section 5C
- ;Command: LIST
- ;Function: Print out specified file on the LST: Device
- ;Forms:
- ; LIST <ufn> Print file (NO Paging)
- ;
- LIST:
- MVI A,0FFH ;TURN ON PRINTER FLAG
- JR TYPE0
- ;
- ;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
- ;
- 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
- 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 ;RESET TAB COUNT?
- JRZ TABRST
- CPI LF ;RESET TAB COUNT?
- JRZ TABRST
- CPI TAB ;TAB?
- JRZ LTAB
- CALL LCOUT ;OUTPUT CHAR
- INR B ;INCREMENT CHAR COUNT
- JR TYPE2L
- TABRST:
- CALL LCOUT ;OUTPUT <CR> OR <LF>
- MVI B,0 ;RESET TAB COUNTER
- 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
- ;
- ; PAGING ROUTINES
- ; PAGER COUNTS DOWN LINES AND PAUSES FOR INPUT (DIRECT) IF COUNT EXPIRES
- ; PAGSET SETS LINES/PAGE COUNT
- ;
- PAGER:
- PUSH H
- LXI H,PAGCNT ;COUNT DOWN
- 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 CONIN ;GET CHAR TO CONTINUE
- CPI 'C'-'@' ;^C
- JZ RSTCPR ;RESTART CPR
- PGBAK:
- POP H ;RESTORE HL
- RET
- ;
- ;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
- JRNZ SAVE3 ;WRITE ERROR?
- JR SAVE1 ;CONTINUE
- SAVE2:
- LXI D,FCBDN ;CLOSE SAVED FILE
- CALL CLOSE
- INR A ;ERROR?
- JRNZ SAVE4
- SAVE3:
- CALL PRNLE ;PRINT 'NO SPACE' ERROR
- SAVE4:
- CALL DEFDMA ;SET DMA TO 0080
- RET ;RESTART CPR
- ;
- ; 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
- 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
- ;
- USER:
- CALL USRNUM ;EXTRACT USER NUMBER FROM COMMAND LINE
- MOV E,A ;PLACE USER NUMBER IN E
- CALL SETUSR ;SET SPECIFIED USER
- RSTJMP:
- JMP RCPRNL ;RESTART CPR
- ;
- ;Section 5H
- ;Command: DFU
- ;Function: Set the Default User Number for the command/file scanner
- ; (MEMLOAD)
- ;Forms:
- ; DFU <unum> Select Default User Number;<unum> is in DEC
- ;
- DFU:
- CALL USRNUM ;GET USER NUMBER
- STA DFUSR ;PUT IT AWAY
- JR RSTJMP ;RESTART CPR (NO DEFAULT LOGIN)
- ;
- ;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
- 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
- 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
- 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
- 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 CPR
- ;
- ; TRANSIENT LOAD ERROR
- ;
- COM8:
- POP H ;CLEAR RETURN ADDRESS
- 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 <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
- 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
- ;
- MEMLOAD:
- CALL MLOAD ;USER MEMORY LOAD SUBROUTINE
- PUSH PSW ;SAVE RETURN STATUS
- CALL RESETUSR ;RESET USER NUMBER
- POP PSW ;GET RETURN STATUS
- RET
-
- ;
- ; MEMORY LOAD SUBROUTINE
- ; EXIT POINTS ARE A SIMPLE RETURN WITH THE ZERO FLAG SET IF NO ERROR,
- ; A SIMPLE RETURN WITH THE ZERO FLAG RESET (NZ) IF MEMORY FULL, OR A JMP TO
- ; COM8 IF COM FILE NOT FOUND
- ;
- MLOAD:
- 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
- ;
- ; ERROR ROUTINE TO SELECT USER 0 IF ALL ELSE FAILS
- ;
- DFUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE
- MVI A,DEFUSR ;GET DEFAULT USER
- TSELUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE
- CPI DEFUSR ;SAME?
- JRZ MLA0 ;JUMP IF
- STA TSELUSR ;ELSE 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
- ORA M
- JNZ COM8 ;ERROR IF ALREADY DISK A:
- MVI M,1 ;SELECT DRIVE A:
- JR MLA
- ;
- ; FILE FOUND -- PROCEED WITH LOAD
- ;
- MLA1:
- LOADADR EQU $+1 ;MEMORY LOAD ADDRESS (IN-LINE CODE MOD)
- LXI H,TPA ;SET START ADDRESS OF MEMORY LOAD
- ML2:
- MVI A,ENTRY/256-1 ;GET HIGH-ORDER ADR OF JUST BELOW CPR
- CMP H ;ARE WE GOING TO OVERWRITE THE CPR?
- JRC PRNLE ;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
- RZ ;OK IF ZERO, ELSE FALL THRU TO PRNLE
- ;
- ; LOAD ERROR
- ;
- PRNLE:
- CALL PRINTC
- DB 'Ful','l'+80H
- MVI A,1 ;SET NON-ZERO TO INDICATE ERROR
- ORA A ;SET FLAG
- RET
- ;
- END
-