home *** CD-ROM | disk | FTP | other *** search
- * SYSTEM SEGMENT: SYS.RCP
- * SYSTEM: ARIES-1
- * CUSTOMIZED BY: RICHARD CONN
-
- *
- * PROGRAM: SYSRCP.ASM
- * AUTHOR: RICHARD CONN
- * VERSION: 1.0
- * DATE: 3 FEB 84
- * PREVIOUS VERSIONS: NONE
- *
- VERSION EQU 10
-
- *
- * SYSRCP is a resident command processor for ZCPR3. As with
- * all resident command processors, SYSRCP performs the following functions:
- *
- * 1. Assuming that the EXTFCB contains the name of the
- * command, SYSRCP looks to see if the first character
- * of the file name field in the EXTFCB is a question
- * mark; if so, it returns with the Zero Flag Set and
- * HL pointing to the internal routine which prints
- * its list of commands
- * 2. The resident command list in SYSRCP is scanned for
- * the entry contained in the file name field of
- * EXTFCB; if found, SYSRCP returns with the Zero Flag
- * Set and HL pointing to the internal routine which
- * implements the function; if not found, SYSRCP returns
- * with the Zero Flag Reset (NZ)
- *
-
- *
- * Global Library which Defines Addresses for SYSRCP
- *
- MACLIB Z3BASE ; USE BASE ADDRESSES
- MACLIB SYSRCP ; USE SYSRCP HEADER
-
- ;
- CTRLC EQU 'C'-'@'
- TAB EQU 09H
- LF EQU 0AH
- FF EQU 0CH
- CR EQU 0DH
- CTRLX EQU 'X'-'@'
- ;
- 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
- FCB1 EQU TFCB ;1st and 2nd FCBs
- FCB2 EQU TFCB+16
- TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER
- TPA EQU BASE+0100H ;BASE OF TPA
- DIRBUF EQU BASE+4000H ;DIR BUFFER (MANY ENTRIES PERMITTED)
- PAGCNT EQU DIRBUF-100H ;PAGE COUNT BUFFER
- OLDFCB EQU PAGCNT+1 ;OLD FCB BUFFER
- CPBLOCKS EQU 32 ;USE 4K FOR BUFFERING OF COPY
- ;
- $-MACRO ;FIRST TURN OFF THE EXPANSIONS
- ;
- ; MACROS TO PROVIDE Z80 EXTENSIONS
- ; MACROS INCLUDE:
- ;
- ; 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
- ;
- ; @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,?DD ;Displacement Range Error on Jump Relative
- ELSE
- DB ?DD
- ENDIF ;;RANGE ERROR
- ENDM
- ;
- ;
- ; Z80 MACRO EXTENSIONS
- ;
- JR MACRO ?N ;;JUMP RELATIVE
- IF I8080 ;;8080/8085
- JMP ?N
- ELSE ;;Z80
- DB 18H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- ;
- JRC MACRO ?N ;;JUMP RELATIVE ON CARRY
- IF I8080 ;;8080/8085
- JC ?N
- ELSE ;;Z80
- DB 38H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- ;
- JRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY
- IF I8080 ;;8080/8085
- JNC ?N
- ELSE ;;Z80
- DB 30H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- ;
- JRZ MACRO ?N ;;JUMP RELATIVE ON ZERO
- IF I8080 ;;8080/8085
- JZ ?N
- ELSE ;;Z80
- DB 28H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- ;
- JRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO
- IF I8080 ;;8080/8085
- JNZ ?N
- ELSE ;;Z80
- DB 20H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- ;
- DJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
- IF I8080 ;;8080/8085
- DCR B
- JNZ ?N
- ELSE ;;Z80
- DB 10H
- @GENDD ?N-$-1
- ENDIF ;;I8080
- ENDM
- *
- * SYSTEM Entry Point
- *
- org rcp ; passed for Z3BASE
-
- db 'Z3RCP' ; Flag for Package Loader
- *
- * **** Command Table for RCP ****
- * This table is RCP-dependent!
- *
- * The command name table is structured as follows:
- *
- * ctable:
- * DB 'CMNDNAME' ; Table Record Structure is
- * DW cmndaddress ; 8 Chars for Name and 2 Bytes for Adr
- * ...
- * DB 0 ; End of Table
- *
- cnsize equ 4 ; NUMBER OF CHARS IN COMMAND NAME
- db cnsize ; size of text entries
- ctab:
- db 'H ' ; Help for RCP
- dw clist
- ctab1:
- ;
- IF CPON
- db 'CP ' ; Copy
- dw copy
- ENDIF ;CPON
- ;
- IF DIRON
- db 'DIR ' ; Directory
- dw dir
- ENDIF ;DIRON
- ;
- IF ECHOON
- db 'ECHO' ; Echo
- dw echo
- ENDIF
- ;
- IF ERAON
- db 'ERA ' ; Erase
- dw era
- ENDIF ;ERAON
- ;
- IF LTON AND LISTON
- db 'LIST' ; List
- dw list
- ENDIF ;LTON AND LISTON
- ;
- IF NOTEON
- db 'NOTE' ; Note-Comment-NOP Command
- dw note
- ENDIF
- ;
- IF PEEKON
- db 'P ' ; Peek into Memory
- dw peek
- ENDIF ;PEEKON
- ;
- IF POKEON
- db 'POKE' ; Poke Values into Memory
- dw poke
- ENDIF ;POKEON
- ;
- IF PROTON
- db 'PROT' ; Protection Codes
- dw att
- ENDIF ;PROTON
- ;
- IF REGON
- db 'REG ' ; Register Command
- dw regcmd
- ENDIF ;RSETON
- ;
- IF RENON
- db 'REN ' ; Rename
- dw ren
- ENDIF ;RENON
- ;
- IF LTON
- db 'TYPE' ; Type
- dw type
- ENDIF ;LTON
- ;
- IF WHLON
- db 'WHL ' ; Wheel
- dw whl
- db 'WHLQ' ; Wheel Query
- dw whlmsg
- ENDIF ;WHLON
- ;
- db 0
- *
- * BANNER NAME OF RCP
- *
- rcp$name:
- db 'SYS '
- db (version/10)+'0','.',(version mod 10)+'0'
- db RCPID
- db 0
-
- *
- * Command List Routine
- *
- clist:
- lxi h,rcp$name ; print RCP Name
- call print1
- lxi h,ctab1 ; print table entries
- mvi c,1 ; set count for new line
- clist1:
- mov a,m ; done?
- ora a
- rz
- dcr c ; count down
- jrnz clist1a
- call crlf ; new line
- mvi c,4 ; set count
- clist1a:
- lxi d,entryname ; copy command name into message buffer
- mvi b,cnsize ; number of chars
- clist2:
- mov a,m ; copy
- stax d
- inx h ; pt to next
- inx d
- dcr b
- jnz clist2
- inx h ; skip to next entry
- inx h
- push h ; save ptr
- lxi h,entrymsg ; print message
- call print1
- pop h ; get ptr
- jmp clist1
- *
- * Console Output Routine
- *
- conout:
- push h ; save regs
- push d
- push b
- push psw
- ani 7fh ; mask MSB
- mov e,a ; char in E
- mvi c,2 ; output
- call bdos
- pop psw ; get regs
- pop b
- pop d
- pop h
- ;
- ; This simple return doubles for the NOTE Command (NOP) and CONOUT Exit
- ; NOTE Command: NOTE any text
- ;
- NOTE:
- ret
- *
- * Print String (terminated in 0 or MSB Set) at Return Address
- *
- print:
- xthl ; get address
- call print1
- xthl ; put address
- ret
- *
- * Print String (terminated in 0 or MSB Set) pted to by HL
- *
- print1:
- mov a,m ; done?
- inx h ; pt to next
- ora a ; 0 terminator
- rz
- call conout ; print char
- rm ; MSB terminator
- jmp print1
- *
- * CLIST Messages
- *
- entrymsg:
- db ' ' ; command name prefix
- entryname:
- ds cnsize ; command name
- db 0 ; terminator
-
- *
- * **** RCP Routines ****
- * All code from here on is RCP-dependent!
- *
-
- ;
- ;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
- ;Notes:
- ; The flag SYSFLG defines the letter used to display both DIR and
- ; SYS files (A in the above Forms section)
- ; The flag SOFLG defines the letter used to display only the SYS
- ; files (S in the above Forms section)
- ; The flag WIDE determines if the file names are spaced further
- ; apart (WIDE=TRUE) for 80-col screens
- ; The flag FENCE defines the character used to separate the file
- ; names
- ;
- IF DIRON
- DIR:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WDIR
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE ;SAVE RET ADDRESS AND SET STACK
- LXI H,FCB1+1 ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP
- MOV A,M ;GET FIRST CHAR OF FILENAME.TYP
- CPI ' ' ;IF <SP>, ALL WILD
- CZ FILLQ
- LDA FCB2+1 ;GET FIRST CHAR OF 2ND FILE NAME
- MVI B,80H ;PREPARE FOR DIR-ONLY SELECTION
- CPI ' ' ;ANY FLAG?
- JRZ DIRPR ;THERE IS NO FLAG, SO DIR ONLY
- MVI B,1 ;SET FOR BOTH DIR AND SYS FILES
- CPI SYSFLG ;SYSTEM AND DIR FLAG SPECIFIER?
- JRZ DIRPR ;GOT SYSTEM SPECIFIER
- CPI SOFLG ;SYS ONLY?
- JRNZ DIRPR
- DCR B ;B=0 FOR SYS FILES ONLY
- ;
- ENDIF ;DIRON
- ;
- ; DIRECTORY PRINT ROUTINE; ON ENTRY, B REG IS SET AS FOLLOWS:
- ; 0 FOR ONLY SYSTEM FILES, 80H FOR ONLY DIR FILES, 1 FOR BOTH
- ;
- IF DIRON OR ERAON OR LTON OR PROTON OR CPON OR RENON
- DIRPR:
- MOV A,B ;GET SYSTST FLAG
- CALL GETDIR ;LOAD AND SORT DIRECTORY
- JZ PRFNF ;PRINT NO FILE MESSAGE
- MVI E,4 ;COUNT DOWN TO 0
- ;
- ; ENTRY PRINT LOOP; ON ENTRY, HL PTS TO FILES SELECTED (TERMINATED BY 0)
- ; AND E IS ENTRY COUNTER
- ;
- DIR3:
- MOV A,M ;CHECK FOR DONE
- ORA A
- JZ EXIT ;EXIT IF DONE
- MOV A,E ;GET ENTRY COUNTER
- ORA A ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
- CZ DIRCRLF ;NEW LINE
- MOV A,E ;GET ENTRY COUNT
- CPI 4 ;FIRST ENTRY?
- JRZ DIR4
- CALL PRINT
- ;
- IF WIDE
- ;
- DB ' ' ;2 SPACES
- DB FENCE ;THEN FENCE CHAR
- DB ' '+80H ;THEN 1 MORE SPACE
- ;
- ELSE
- ;
- DB ' ' ;SPACE
- DB FENCE+80H ;THEN FENCE CHAR
- ;
- ENDIF ;WIDE
- ;
- DIR4:
- CALL PRFN ;PRINT FILE NAME
- CALL BREAK ;CHECK FOR ABORT
- DCR E ;DECREMENT ENTRY COUNTER
- JR DIR3
- ;
- ; CRLF FOR DIR ROUTINE
- ;
- DIRCRLF:
- PUSH PSW ;DON'T AFFECT PSW
- CALL CRLF ;NEW LINE
- POP PSW
- MVI E,4 ;RESET ENTRY COUNTER
- RET
- ;
- ; AFTER A SEARCH, RETURN NZ SET IF DESIRED TYPE OF FILE FOUND, Z IF NOT
- ; THIS ALGORITHM LOOKS AT THE SYSTEM BIT OF THE LOCATED FILE; THIS
- ; BIT IS SET TO 1 IF THE FILE IS A SYSTEM FILE AND 0 IF NOT A SYSTEM
- ; FILE. THE FOLLOWING EXCLUSIVE OR MASKS ARE APPLIED TO RETURN Z OR NZ
- ; AS REQUIRED BY THE CALLING PROGRAM:
- ;
- ; SYSTEM BYTE: X 0 0 0 0 0 0 0 (AFTER 80H MASK, X=1 IF SYS, 0 IF DIR)
- ;
- ; SYS-ONLY : 0 0 0 0 0 0 0 0 (XOR 0 = 0 if X=0, = 80H if X=1)
- ; DIR-ONLY : 1 0 0 0 0 0 0 0 (XOR 80H = 80h if X=0, = 0 if X=1)
- ; BOTH : 0 0 0 0 0 0 0 1 (XOR 1 = 81H or 1H, NZ in both cases)
- ;
- GETSBIT:
- 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)
- LXI D,TBUFF ;PT TO BUFFER
- MOV A,E ;BASE ADDRESS IN A
- ADD C ;ADD IN ENTRY OFFSET
- MOV E,A ;RESULT IN E
- PUSH D ;SAVE PTR IN DE
- ADI 10 ;ADD OFFSET OF 10 TO PT TO SYSTEM BYTE
- MOV E,A ;SET ADDRESS
- LDAX D ;GET BYTE
- POP D ;GET PTR IN DE
- ANI 80H ;LOOK AT ONLY SYSTEM BIT
- SYSTST EQU $+1 ;IN-THE-CODE VARIABLE
- XRI 0 ; IF SYSTST=0, SYS ONLY; IF SYSTST=80H, DIR
- ; ONLY; IF SYSTST=1, BOTH SYS AND DIR
- RET ;NZ IF OK, Z IF NOT OK
- ;
- ; FILL FCB @HL WITH '?'
- ;
- FILLQ:
- MVI B,11 ;NUMBER OF CHARS IN FN & FT
- MVI A,'?' ;STORE '?'
- FILLP:
- MOV M,A ;STORE BYTE
- INX H ;PT TO NEXT
- DJNZ FILLP ;COUNT DOWN
- RET
- ;
- ; LOAD DIRECTORY AND SORT IT
- ; ON INPUT, A=SYSTST FLAG (0=SYS, 1=DIR, 80H=BOTH)
- ; DIRECTORY IS LOADED INTO DIRBUF
- ; RETURN WITH ZERO SET IF NO MATCH AND HL PTS TO 1ST ENTRY IF MATCH
- ;
- GETDIR:
- STA SYSTST ; SET SYSTEM TEST FLAG
- CALL LOGUSR ; LOG INTO USER AREA OF FCB1
- LXI H,DIRBUF ; PT TO DIR BUFFER
- MVI M,0 ; SET EMPTY
- LXI B,0 ; SET COUNTER
- CALL SEARF ; LOOK FOR MATCH
- RZ ; RETURN IF NOT FOUND
- ;
- ; STEP 1: LOAD DIRECTORY
- ;
- GD1:
- PUSH B ; SAVE COUNTER
- CALL GETSBIT ; CHECK FOR SYSTEM OK
- POP B
- JRZ GD2 ; NOT OK, SO SKIP
- PUSH B ; SAVE COUNTER
- INX D ; PT TO FILE NAME
- XCHG ; HL PTS TO FILE NAME, DE PTS TO BUFFER
- MVI B,11 ; COPY 11 BYTES
- CALL LDIR ; DO COPY
- XCHG ; HL PTS TO NEXT BUFFER LOCATION
- POP B ; GET COUNTER
- INX B ; INCREMENT COUNTER
- GD2:
- CALL SEARN ; LOOK FOR NEXT
- JRNZ GD1
- MVI M,0 ; STORE ENDING 0
- LXI H,DIRBUF ; PT TO DIR BUFFER
- MOV A,M ; CHECK FOR EMPTY
- ORA A
- RZ
- ;
- ; STEP 2: SORT DIRECTORY
- ;
- PUSH H ; SAVE PTR TO DIRBUF FOR RETURN
- CALL DIRALPHA ; SORT
- POP H
- XRA A ; SET NZ FLAG FOR OK
- DCR A
- RET
-
- ;*
- ;* DIRALPHA -- ALPHABETIZES DIRECTORY IN DIRBUF; BC CONTAINS
- ;* THE NUMBER OF FILES IN THE DIRECTORY
- ;*
- DIRALPHA:
- MOV A,B ; ANY FILES?
- ORA C
- RZ
- MOV H,B ; HL=BC=FILE COUNT
- MOV L,C
- SHLD N ; SET "N"
- ;*
- ;* SHELL SORT --
- ;* THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
- ;* BY KERNIGAN AND PLAUGHER, PAGE 106. COPYRIGHT, 1976, ADDISON-WESLEY.
- ;* ON ENTRY, BC=NUMBER OF ENTRIES
- ;*
- N EQU $+1 ; POINTER FOR IN-THE-CODE MODIFICATION
- LXI H,0 ; NUMBER OF ITEMS TO SORT
- SHLD GAP ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2
-
- ;* FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
- SRTL0:
- ORA A ; CLEAR CARRY
- GAP EQU $+1 ; POINTER FOR IN-THE-CODE MODIFICATION
- LXI H,0 ; GET PREVIOUS GAP
- MOV A,H ; ROTATE RIGHT TO DIVIDE BY 2
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
-
- ;* TEST FOR ZERO
- ORA H
- RZ ; DONE WITH SORT IF GAP = 0
-
- SHLD GAP ; SET VALUE OF GAP
- SHLD I ; SET I=GAP FOR FOLLOWING LOOP
-
- ;* FOR (I = GAP + 1; I <= N; I = I + 1)
- SRTL1:
- I EQU $+1 ; POINTER FOR IN-THE-CODE MODIFICATION
- LXI H,0 ; ADD 1 TO I
- INX H
- SHLD I
-
- ;* TEST FOR I <= N
- XCHG ; I IS IN DE
- LHLD N ; GET N
- MOV A,L ; COMPARE BY SUBTRACTION
- SUB E
- MOV A,H
- SBB D ; CARRY SET MEANS I > N
- JRC SRTL0 ; DON'T DO FOR LOOP IF I > N
-
- LHLD I ; SET J = I INITIALLY FOR FIRST SUBTRACTION OF GAP
- SHLD J
-
- ;* FOR (J = I - GAP; J > 0; J = J - GAP)
- SRTL2:
- LHLD GAP ; GET GAP
- XCHG ; ... IN DE
- J EQU $+1 ; POINTER FOR IN-THE-CODE MODIFICATION
- LXI H,0 ; GET J
- MOV A,L ; COMPUTE J - GAP
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- SHLD J ; J = J - GAP
- JRC SRTL1 ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT
- MOV A,H ; J=0?
- ORA L
- JRZ SRTL1 ; IF ZERO, J=0 AND ABORT
-
- ;* SET JG = J + GAP
- XCHG ; J IN DE
- LHLD GAP ; GET GAP
- DAD D ; J + GAP
- SHLD JG ; JG = J + GAP
-
- ;* IF (V(J) <= V(JG))
- CALL ICOMPARE ; J IN DE, JG IN HL
-
- ;* ... THEN BREAK
- JRC SRTL1
-
- ;* ... ELSE EXCHANGE
- LHLD J ; SWAP J, JG
- XCHG
- JG EQU $+1 ; POINTER FOR IN-THE-CODE MODIFICATION
- LXI H,0
- CALL ISWAP ; J IN DE, JG IN HL
-
- ;* END OF INNER-MOST FOR LOOP
- JR SRTL2
-
- ;*
- ;* SWAP (Exchange) the elements whose indexes are in HL and DE
- ;*
- ISWAP:
- CALL IPOS ; COMPUTE POSITION FROM INDEX
- XCHG
- CALL IPOS ; COMPUTE 2ND ELEMENT POSITION FROM INDEX
- MVI B,11 ; 11 BYTES TO FLIP
- ISWAP1:
- LDAX D ; GET BYTES
- MOV C,M
- MOV M,A ; PUT BYTES
- MOV A,C
- STAX D
- INX H ; PT TO NEXT
- INX D
- DJNZ ISWAP1
- RET
- ;*
- ;* ICOMPARE compares the entry pointed to by the pointer pointed to by HL
- ;* with that pointed to by DE (1st level indirect addressing); on entry,
- ;* HL and DE contain the numbers of the elements to compare (1, 2, ...);
- ;* on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
- ;* and Non-Zero and No-Carry means ((DE)) > ((HL))
- ;*
- ICOMPARE:
- CALL IPOS ; GET POSITION OF FIRST ELEMENT
- XCHG
- CALL IPOS ; GET POSITION OF 2ND ELEMENT
- XCHG
- ;*
- ;* COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
- ;* NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
- ;* RET W/ZERO SET MEANS DE=HL
- ;*
- IF NOT SORTNT ; TYPE AND NAME?
- ;*
- ;* COMPARE BY FILE TYPE AND FILE NAME
- ;*
- PUSH H
- PUSH D
- LXI B,8 ; PT TO FT (8 BYTES)
- DAD B
- XCHG
- DAD B
- XCHG ; DE, HL NOW PT TO THEIR FT'S
- MVI B,3 ; 3 BYTES
- CALL COMP ; COMPARE FT'S
- POP D
- POP H
- RNZ ; CONTINUE IF COMPLETE MATCH
- MVI B,8 ; 8 BYTES
- JR COMP ; COMPARE FN'S
- ;
- ELSE ; NAME AND TYPE
- ;*
- ;* COMPARE BY FILE NAME AND FILE TYPE
- ;*
- MVI B,11 ; COMPARE FN, FT AND FALL THRU TO COMP
- ;*
- ;* COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
- ;* MSB IS DISREGARDED
- ;*
- COMP:
- MOV A,M ; GET (HL)
- ANI 7FH ; MASK MSB
- MOV C,A ; ... IN C
- LDAX D ; COMPARE
- ANI 7FH ; MASK MSB
- CMP C
- RNZ
- INX H ; PT TO NEXT
- INX D
- DJNZ COMP ; COUNT DOWN
- RET
- ;
- ENDIF ; NOT SORTNT
- ;*
- ;* Compute physical position of element whose index is in HL; on exit, HL
- ;* is the physical address of this element; Indexes are 1..N
- ;*
- IPOS:
- DCX H ; HL=(HL-1)*11+DIRBUF
- MOV B,H ; BC=HL
- MOV C,L
- DAD H ; HL=HL*2
- DAD H ; HL=HL*4
- DAD B ; HL=HL*5
- DAD H ; HL=HL*10
- DAD B ; HL=HL*11
- LXI B,DIRBUF ; ADD IN DIRBUF
- DAD B
- RET
- ;
- ENDIF ;DIRON OR ERAON OR LTON OR PROTON OR CPON OR RENON
- ;
- ;Section 5B
- ;Command: ERA
- ;Function: Erase files
- ;Forms:
- ; ERA <afn> Erase Specified files and print their names
- ; ERA <afn> I Erase Specified files and print their names, but ask
- ; for verification before Erase is done
- ;
- IF ERAON
- ERA:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WERA
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- LDA FCB2+1 ;GET ERAFLG IF IT'S THERE
- STA ERAFLG ;SAVE IT AS A FLAG
- MVI A,1 ;DIR FILES ONLY
- CALL GETDIR ;LOAD DIRECTORY OF FILES
- JZ PRFNF ;ABORT IF NO FILES
- ;
- ; MAIN ERASE LOOP
- ;
- ERA1:
- PUSH H ;SAVE PTR TO FILE
- CALL PRFN ;PRINT ITS NAME
- SHLD NXTFILE ;SAVE PTR TO NEXT FILE
- POP H ;GET PTR TO THIS FILE
- CALL ROTEST ;TEST FILE PTED TO BY HL FOR R/O
- JRNZ ERA3
- ERAFLG EQU $+1 ;ADDRESS OF FLAG
- MVI A,0 ;2ND BYTE IS FLAG
- CPI 'I' ;IS IT AN INSPECT OPTION?
- JRNZ ERA2 ;SKIP PROMPT IF IT IS NOT
- CALL ERAQ ;ERASE?
- JRNZ ERA3 ;SKIP IF NOT
- ERA2:
- LXI D,FCB1+1 ;COPY INTO FCB1
- MVI B,11 ;11 BYTES
- CALL LDIR
- CALL INITFCB1 ;INIT FCB
- MVI C,19 ;DELETE FILE
- CALL BDOS
- ERA3:
- LHLD NXTFILE ;HL PTS TO NEXT FILE
- MOV A,M ;GET CHAR
- ORA A ;DONE?
- JZ EXIT
- CALL CRLF ;NEW LINE
- JR ERA1
- ;
- ENDIF ;ERAON
- ;
- ;Section 5C
- ;Command: LIST
- ;Function: Print out specified file on the LST: Device
- ;Forms:
- ; LIST <afn> Print file (NO Paging)
- ;Notes:
- ; The flags which apply to TYPE do not take effect with LIST
- ;
- IF LTON
- LIST:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WLIST
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- MVI A,0FFH ;TURN ON PRINTER FLAG
- JR TYPE0
- ;
- ;Section 5D
- ;Command: TYPE
- ;Function: Print out specified file on the CON: Device
- ;Forms:
- ; TYPE <afn> Print file
- ; TYPE <afn> P Print file with paging flag
- ;Notes:
- ; The flag PGDFLG defines the letter which toggles the paging
- ; facility (P in the forms section above)
- ; The flag PGDFLT determines if TYPE is to page by default
- ; (PGDFLT=TRUE if TYPE pages by default); combined with
- ; PGDFLG, the following events occur --
- ; If PGDFLT = TRUE, PGDFLG turns OFF paging
- ; If PGDFLT = FALSE, PGDFLG turns ON paging
- ;
- TYPE:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WTYPE
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- XRA A ;TURN OFF PRINTER FLAG
- ;
- ; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
- ;
- TYPE0:
- STA PRFLG ;SET FLAG
- LDA FCB2+1 ;GET PAGE FLAG
- STA PGFLG ;SAVE IT AS A FLAG
- MVI A,1 ;SELECT DIR FILES
- CALL GETDIR ;ALLOW AMBIGUOUS FILES
- JZ PRFNF ;NO FILES
- SHLD NXTFILE ;SET PTR TO NEXT FILE
- JR TYPEX2
- TYPEX:
- LHLD NXTFILE ;GET PTR TO NEXT FILE
- MOV A,M ;ANY FILES?
- ORA A
- JZ EXIT
- LDA PRFLG ;CHECK FOR LIST OUTPUT
- ORA A ;0=TYPE
- JRZ TYPEX1
- MVI A,CR ;BOL ON PRINTER
- CALL LCOUT
- MVI A,FF ;FORM FEED THE PRINTER
- CALL LCOUT
- JR TYPEX2
- TYPEX1:
- CALL PAGEBREAK ;PAGE BREAK MESSAGE
- TYPEX2:
- LXI D,FCB1+1 ;COPY INTO FCB1
- MVI B,11 ;11 BYTES
- CALL LDIR
- SHLD NXTFILE ;SET PTR TO NEXT FILE
- CALL INITFCB1 ;INIT FCB1
- MVI C,15 ;OPEN FILE
- CALL BDOS
- INR A ;SET ERROR FLAG
- JZ PRFNF ;ABORT IF ERROR
- MVI A,NLINES-2 ;SET LINE COUNT
- STA PAGCNT
- MVI A,CR ;NEW LINE
- CALL LCOUT
- MVI A,LF
- CALL LCOUT
- LXI B,080H ;SET CHAR POSITION AND TAB COUNT
- ; (B=0=TAB, C=080H=CHAR POSITION)
- ;
- ; MAIN LOOP FOR LOADING NEXT BLOCK
- ;
- TYPE2:
- MOV A,C ;GET CHAR COUNT
- CPI 80H
- JRC TYPE3
- PUSH H ;READ NEXT BLOCK
- PUSH B
- LXI D,FCB1 ;PT TO FCB
- MVI C,20 ;READ RECORD
- CALL BDOS
- ORA A ;SET FLAGS
- POP B
- POP H
- JRNZ TYPE7 ;END OF FILE?
- MVI C,0 ;SET CHAR COUNT
- LXI H,TBUFF ;PT TO FIRST CHAR
- ;
- ; MAIN LOOP FOR PRINTING CHARS IN TBUFF
- ;
- TYPE3:
- MOV A,M ;GET NEXT CHAR
- ANI 7FH ;MASK OUT MSB
- CPI 1AH ;END OF FILE (^Z)?
- JRZ TYPE7 ;NEXT FILE IF SO
- ;
- ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
- ;
- CPI CR ;RESET TAB COUNT?
- JRZ TYPE4
- CPI LF ;RESET TAB COUNT?
- JRZ TYPE4
- CPI TAB ;TAB?
- JRZ TYPE5
- ;
- ; OUTPUT CHAR AND INCREMENT CHAR COUNT
- ;
- CALL LCOUT ;OUTPUT CHAR
- JZ TYPEX ;SKIP
- INR B ;INCREMENT TAB COUNT
- JR TYPE6
- ;
- ; OUTPUT <CR> OR <LF> AND RESET TAB COUNT
- ;
- TYPE4:
- CALL LCOUT ;OUTPUT <CR> OR <LF>
- JZ TYPEX ;SKIP
- MVI B,0 ;RESET TAB COUNTER
- JR TYPE6
- ;
- ; TABULATE
- ;
- TYPE5:
- MVI A,' ' ;<SP>
- CALL LCOUT
- JZ TYPEX ;SKIP
- INR B ;INCR POS COUNT
- MOV A,B
- ANI 7
- JRNZ TYPE5
- ;
- ; CONTINUE PROCESSING
- ;
- TYPE6:
- INR C ;INCREMENT CHAR COUNT
- INX H ;PT TO NEXT CHAR
- CALL BREAK ;CHECK FOR ABORT
- JZ TYPEX ;SKIP
- JR TYPE2
- TYPE7:
- LXI D,FCB1 ;CLOSE FILE
- MVI C,16 ;BDOS FUNCTION
- CALL BDOS
- JMP TYPEX
- ;
- ; SEND OUTPUT TO LST: OR CON:, AS PER THE FLAG
- ; RETURN WITH Z IF ABORT
- ;
- LCOUT:
- PUSH H ;SAVE REGS
- PUSH D
- PUSH B
- MOV E,A ;CHAR IN E
- MVI C,2 ;OUTPUT TO CON:
- PRFLG EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;2ND BYTE IS THE PRINT FLAG
- ORA A ;0=TYPE
- JRZ LC1
- MVI C,5 ;OUTPUT TO LST:
- LC1:
- PUSH D ;SAVE CHAR
- CALL BDOS ;OUTPUT CHAR IN E
- POP D ;GET CHAR
- MOV A,E
- CPI LF
- JRNZ LC2
- LDA PRFLG ;OUTPUT TO LST:?
- ORA A ;NZ = YES
- JRNZ LC2
- ;
- ; CHECK FOR PAGING
- ;
- LXI H,PAGCNT ;COUNT DOWN
- DCR M
- JRNZ LC2 ;JUMP IF NOT END OF PAUSE
- MVI M,NLINES-2 ;REFILL COUNTER
- PGFLG EQU $+1 ;POINTER TO IN-THE-CODE BUFFER
- MVI A,0 ;2ND BYTE IS THE PAGING FLAG
- CPI PGDFLG ;PAGE DEFAULT OVERRIDE OPTION WANTED?
- ;
- IF PGDFLT ;IF PAGING IS DEFAULT
- ;
- JRZ LC2 ;PGDFLG MEANS NO PAGING
- ;
- ELSE
- ;
- JRNZ LC2 ;PGDFLG MEANS PAGE
- ;
- ENDIF ;PGDFLT
- ;
- CALL PAGEBREAK ;PRINT PAGE BREAK MESSAGE
- JR LC3 ;Z TO SKIP
- LC2:
- XRA A ;SET OK
- DCR A ;NZ=OK
- LC3:
- POP B ;RESTORE REGS
- POP D
- POP H
- RET
- ;
- ; PRINT PAGE BREAK MESSAGE AND GET USER INPUT
- ; ABORT IF ^C, RZ IF ^X
- ;
- PAGEBREAK:
- PUSH H ;SAVE HL
- CALL PRINT
- DB cr,lf,' Typing',' '+80H
- LXI H,FCB1+1 ;PRINT FILE NAME
- CALL PRFN
- CALL DASH ;PRINT DASH
- CALL CONIN ;GET INPUT
- POP H ;RESTORE HL
- PUSH PSW
- CALL CRLF ;NEW LINE
- POP PSW
- CPI CTRLC ;^C
- JZ EXIT
- CPI CTRLX ;SKIP?
- RET
- ;
- ENDIF ;LTON
- ;
- ;Section 5E
- ;Command: REN
- ;Function: To change the name of an existing file
- ;Forms:
- ; REN <New ufn>=<Old ufn> Perform function
- ;
- IF RENON
- REN:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WREN
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- ;
- ;
- ; STEP 1: CHECK FOR FILE 2 BEING AMBIGUOUS
- ;
- LXI H,FCB2+1 ;CAN'T BE AMBIGUOUS
- CALL AMBCHK1
- ;
- ; STEP 2: LOG INTO USER AREA
- ;
- CALL LOGUSR ;LOG INTO USER AREA OF FCB1
- ;
- ; STEP 3: SEE IF NEW FILE ALREADY EXISTS
- ; EXTEST PERFORMS A NUMBER OF CHECKS:
- ; 1) AMBIGUITY
- ; 2) R/O
- ; 3) IF FILE EXISTS AND NOT R/O, PERMISSION TO DELETE
- ;
- CALL EXTEST
- JZ EXIT ;R/O OR NO PERMISSION
- ;
- ; STEP 4: EXCHANGE FILE NAME FIELDS FOR RENAME
- ;
- LXI H,FCB1 ;EXCHANGE NAMES ONLY
- PUSH H ;SAVE PTR
- INX H
- LXI D,FCB2+1
- MVI B,11 ;11 BYTES
- REN1:
- LDAX D ;GET OLD
- MOV C,A
- MOV A,M
- STAX D ;PUT NEW
- MOV M,C
- INX H ;PT TO NEXT
- INX D
- DJNZ REN1
- ;
- ; STEP 5: SEE IF OLD FILE IS R/O
- ;
- CALL SEARF ;LOOK FOR FILE
- JZ PRFNF
- CALL GETSBIT ;GET PTR TO ENTRY IN TBUFF
- XCHG ;HL PTS TO ENTRY
- INX H ;PT TO FN
- CALL ROTEST ;SEE IF FILE IS R/O
- JNZ EXIT
- ;
- ; STEP 6: RENAME THE FILE
- ;
- POP D ;GET PTR TO FCB
- MVI C,23 ;RENAME
- CALL BDOS
- INR A ;SET ZERO FLAG IF ERROR
- JZ PRFNF ;PRINT NO SOURCE FILE MESSAGE
- JMP EXIT
- ;
- ENDIF ;RENON
- ;
- ;Section 5F
- ;Command: PROT
- ;Function: To set the attributes of a file (R/O and SYS)
- ;
- ;Form:
- ; PROT afn RSI
- ;If either R or S are omitted, the file is made R/W or DIR, resp;
- ;R and S may be in any order. If I is present, Inspection is enabled.
- ;
- IF PROTON
- ATT:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WPROT
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- XRA A ;SET NO INSPECT
- STA INSPECT
- LXI H,0 ;SET R/O AND SYS ATTRIBUTES OFF
- LXI D,FCB2+1 ;PT TO ATTRIBUTES
- MVI B,3 ;3 CHARS MAX
- ATT1:
- LDAX D ;GET CHAR
- INX D ;PT TO NEXT
- CPI 'I' ;INSPECT?
- JRZ ATTI
- CPI 'R' ;SET R/O?
- JRZ ATTR
- CPI 'S' ;SET SYS?
- JRZ ATTS
- ATT2:
- DJNZ ATT1
- JR ATT3
- ATTI:
- STA INSPECT ;SET FLAG
- JR ATT2
- ATTR:
- MVI H,80H ;SET R/O BIT
- JR ATT2
- ATTS:
- MVI L,80H ;SET SYS BIT
- JR ATT2
- ATT3:
- SHLD FATT ;SAVE FILE ATTRIBUTES
- MVI A,1 ;SELECT DIR AND SYS FILES
- CALL GETDIR ;LOAD DIRECTORY
- JZ PRFNF ;NO FILE ERROR
- SHLD NXTFILE ;PT TO NEXT FILE
- JR ATT5
- ATT4:
- LHLD NXTFILE ;PT TO NEXT FILE
- MOV A,M ;END OF LIST?
- ORA A
- JZ EXIT
- CALL CRLF ;NEW LINE
- ATT5:
- PUSH H ;SAVE PTR TO CURRENT FILE
- CALL PRFN ;PRINT ITS NAME
- SHLD NXTFILE ;SAVE PTR TO NEXT FILE
- CALL PRINT
- DB ' Set to R','/'+80H
- LHLD FATT ;GET ATTRIBUTES
- MVI C,'W' ;ASSUME R/W
- MOV A,H ;GET R/O BIT
- ORA A
- JRZ ATT6
- MVI C,'O' ;SET R/O
- ATT6:
- MOV A,C ;GET CHAR
- CALL CONOUT
- MOV A,L ;GET SYS FLAG
- ORA A ;SET FLAG
- JRZ ATT7
- CALL PRINT
- DB ' and SY','S'+80H
- ATT7:
- INSPECT EQU $+1 ;PTR FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;GET INSPECT FLAG
- ORA A ;Z=NO
- POP H ;GET PTR TO CURRENT FILE
- JRZ ATT8
- CALL ERAQ1 ;ASK FOR Y/N
- JRNZ ATT4 ;ADVANCE TO NEXT FILE IF NOT Y
- ATT8:
- LXI D,FCB1+1 ;COPY INTO FCB1
- MVI B,11 ;11 BYTES
- CALL LDIR
- FATT EQU $+1 ;PTR FOR IN-THE-CODE MODIFICATION
- LXI H,0 ;GET ATTRIBUTES
- DCX D ;PT TO SYS BYTE
- DCX D
- MOV A,L ;GET SYS FLAG
- CALL ATTSET ;SET ATTRIBUTE CORRECTLY
- DCX D ;PT TO R/O BYTE
- MOV A,H ;GET R/O FLAG
- CALL ATTSET
- LXI D,FCB1 ;PT TO FCB
- MVI C,30 ;SET ATTRIBUTES
- CALL BDOS
- JR ATT4
- ATTSET:
- ORA A ;0=CLEAR ATTRIBUTE
- JRZ ATTST1
- LDAX D ;GET BYTE
- ORI 80H ;SET ATTRIBUTE
- STAX D
- RET
- ATTST1:
- LDAX D ;GET BYTE
- ANI 7FH ;CLEAR ATTRIBUTE
- STAX D
- RET
- ;
- ENDIF ;PROTON
- ;
- ;Section 5G
- ;Command: CP
- ;Function: To copy a file from one place to another
- ;
- ;Form:
- ; CP new=old
- ;
- IF CPON
- COPY:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WCP
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- ;
- ; STEP 0: IF NEW IS BLANK, MAKE IT THE SAME NAME AND TYPE AS OLD
- ;
- LXI D,FCB1+1 ;PT TO NEW FILE NAME
- LDAX D ;GET FIRST CHAR
- CPI ' ' ;NO NAME?
- JRNZ COPY0
- LXI H,FCB2+1 ;MAKE SAME AS OLD
- MVI B,11 ;11 BYTES
- CALL LDIR
- ;
- ; STEP 1: SEE IF NEW=OLD AND ABORT IF SO
- ;
- COPY0:
- LXI H,FCB1 ;PT TO NEXT
- LXI D,FCB2 ;PT TO OLD
- PUSH H ;SAVE PTRS
- PUSH D
- INX H ;PT TO FILE NAME
- INX D
- MVI B,13 ;COMPARE 13 BYTES
- COPY1:
- LDAX D ;GET OLD
- CMP M ;COMPARE TO NEW
- JRNZ COPY2
- INX H ;PT TO NEXT
- INX D
- DJNZ COPY1
- MVI C,25 ;GET CURRENT DISK
- CALL BDOS
- INR A ;MAKE 1..P
- MOV B,A ;CURRENT DISK IN B
- POP D ;GET PTR TO DN
- POP H
- LDAX D ;GET DISK
- MOV C,A ;... IN C
- ORA A ;CURRENT?
- JRNZ COPY1A
- MOV C,B ;MAKE C CURRENT
- COPY1A:
- MOV A,M ;GET DISK
- ORA A ;CURRENT?
- JRNZ COPY1B
- MOV A,B ;MAKE A CURRENT
- COPY1B:
- CMP C ;SAME DISK ALSO?
- JRNZ COPY3 ;CONTINUE WITH OPERATION
- JR CPERR
- COPY2:
- POP D ;GET PTRS
- POP H
- ;
- ; STEP 2: SET USER NUMBERS
- ;
- COPY3:
- LDA FCB1+13 ;GET NEW USER
- STA USRNEW
- LDA FCB2+13 ;GET OLD USER
- STA USROLD
- ;
- ; STEP 3: SEE IF OLD FILE EXISTS
- ;
- LXI H,OLDFCB ;COPY OLD INTO 2ND FCB
- PUSH H ;SAVE PTR TO 2ND FCB
- XCHG
- MVI B,14 ;14 BYTES
- CALL LDIR
- CALL LOGOLD ;LOG IN USER NUMBER OF OLD FCB
- POP H ;GET PTR TO 2ND FCB
- CALL INITFCB2 ;INIT FCB
- MVI C,17 ;LOOK FOR FILE
- CALL BDOS
- INR A ;CHECK FOR ERROR
- JZ PRFNF ;FILE NOT FOUND
- ;
- ; STEP 4: SEE IF NEW EXISTS
- ;
- CALL LOGNEW ;LOG INTO NEW'S USER AREA
- CALL EXTEST ;TEST
- JZ EXIT ;ERROR EXIT
- ;
- ; STEP 5: CREATE NEW
- ;
- LXI D,FCB1 ;PT TO FCB
- MVI C,22 ;MAKE FILE
- CALL BDOS
- INR A ;ERROR?
- JRNZ COPY4
- ;
- ; COPY ERROR
- ;
- CPERR:
- CALL PRINT
- DB ' Copy','?'+80H
- JMP EXIT
- ;
- ; STEP 6: OPEN OLD
- ;
- COPY4:
- CALL LOGOLD ;GET USER
- LXI H,OLDFCB ;PT TO FCB
- CALL INITFCB2 ;INIT FCB
- MVI C,15 ;OPEN FILE
- CALL BDOS
- ;
- ; STEP 7: COPY OLD TO NEW WITH BUFFERING
- ;
- COPY5:
- CALL LOGOLD ;GET USER
- MVI B,0 ;SET COUNTER
- LXI H,TPA ;SET NEXT ADDRESS TO COPY INTO
- COPY5A:
- PUSH H ;SAVE ADDRESS AND COUNTER
- PUSH B
- LXI D,OLDFCB ;READ BLOCK FROM FILE
- MVI C,20
- CALL BDOS
- POP B ;GET COUNTER AND ADDRESS
- POP D
- ORA A ;OK?
- JRNZ COPY5B
- PUSH B ;SAVE COUNTER
- LXI H,TBUFF ;COPY FROM BUFFER
- MVI B,128 ;128 BYTES
- CALL LDIR
- XCHG ;HL PTS TO NEXT
- POP B ;GET COUNTER
- INR B ;INCREMENT IT
- MOV A,B ;DONE?
- CPI CPBLOCKS ;DONE IF CPBLOCKS LOADED
- JRNZ COPY5A
- COPY5B:
- MOV A,B ;GET COUNT
- ORA A
- JRZ COPY6 ;DONE IF NOTHING LOADED
- PUSH B ;SAVE COUNT
- CALL LOGNEW ;GET USER
- LXI H,TPA ;PT TO TPA
- COPY5C:
- LXI D,TBUFF ;COPY INTO TBUFF
- MVI B,128 ;128 BYTES
- CALL LDIR
- PUSH H ;SAVE PTR TO NEXT
- LXI D,FCB1 ;PT TO FCB
- MVI C,21 ;WRITE BLOCK
- CALL BDOS
- ORA A
- JRNZ CPERR ;COPY ERROR
- POP H ;GET PTR TO NEXT BLOCK
- POP B ;GET COUNT
- DCR B ;COUNT DOWN
- JRZ COPY5 ;GET NEXT
- PUSH B ;SAVE COUNT
- JR COPY5C
- ;
- ; STEP 8: CLOSE FILES
- ;
- COPY6:
- CALL LOGOLD ;GET USER
- LXI D,OLDFCB ;PT TO FCB
- MVI C,16 ;CLOSE FILE
- CALL BDOS
- CALL LOGNEW ;GET USER
- LXI D,FCB1 ;PT TO FCB
- MVI C,16 ;CLOSE FILE
- CALL BDOS
- CALL PRINT
- DB ' Don','e'+80H
- JMP EXIT
- ;
- ; LOG INTO USER NUMBER OF OLD FILE
- ;
- LOGOLD:
- USROLD EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;GET NUMBER
- JMP SETUSR
- ;
- ; LOG INTO USER NUMBER OF NEW FILE
- ;
- LOGNEW:
- USRNEW EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- MVI A,0 ;GET NUMBER
- JMP SETUSR
- ;
- ENDIF ;CPON
- ;
- ;Section 5H
- ;Command: PEEK
- ;Function: Display memory
- ;
- ;Form:
- ; PEEK startadr - 256 bytes displayed
- ; PEEK startadr endadr - range of bytes displayed
- ;
- IF PEEKON
- PEEK:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WPEEK
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- LXI H,TBUFF+1 ;FIND FIRST NUMBER
- NXTPEEK EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION
- LXI D,0 ;DEFAULT PEEK ADDRESS IF NONE
- CALL SKSP ;SKIP TO NON-BLANK
- CNZ HEXNUM ;GET START ADDRESS IF ANY (ELSE DEFAULT)
- CALL PRINT
- DB ' Pee','k'+80H
- CALL ADRAT ;PRINT ADDRESS MESSAGE
- PUSH D ;SAVE IT
- LXI B,256 ;COMPUTE END ADDRESS
- XCHG
- DAD B
- XCHG ;END ADDRESS IN DE
- CALL SKSP ;SKIP TO NON-BLANK
- JRZ PEEK1 ;PROCESS
- CALL HEXNUM ;GET 2ND NUMBER IN DE
- PEEK1:
- POP H ;HL IS START ADDRESS, DE IS END ADDRESS
- CALL PEEK2 ;DO PEEK
- SHLD NXTPEEK ;SET CONTINUED PEEK ADDRESS
- JMP EXIT
- ;
- ; DISPLAY LOOP
- ;
- PEEK2:
- MOV A,D ;SEE IF DE<=HL
- CMP H
- RC ;OUT OF BOUNDS
- JRNZ PEEK2A ;HL > DE
- MOV A,E
- CMP L
- RZ
- RC
- PEEK2A:
- CALL CRLF ;NEW LINE
- MOV A,H ;PRINT ADDRESS
- CALL PASHC
- MOV A,L
- CALL PAHC
- CALL DASH ;PRINT LEADER
- MVI B,16 ;16 BYTES TO DISPLAY
- PUSH H ;SAVE START ADDRESS
- PEEK3:
- MOV A,M ;GET NEXT BYTE
- CALL PASHC ;PRINT WITH LEADING SPACE
- INX H ;PT TO NEXT
- DJNZ PEEK3
- POP H ;PT TO FIRST
- MVI B,16 ;16 BYTES
- MVI A,' ' ;SPACE AND FENCE
- CALL CONOUT
- CALL PRINT
- DB FENCE+80H
- PEEK4:
- MOV A,M ;GET NEXT BYTE
- MVI C,'.' ;ASSUME DOT
- ANI 7FH ;MASK IT
- CPI ' ' ;DOT IF LESS THAN SPACE
- JRC PEEK5
- CPI 7FH ;DON'T PRINT DEL
- JRZ PEEK5
- MOV C,A ;CHAR IN C
- PEEK5:
- MOV A,C ;GET CHAR
- CALL CONOUT ;SEND IT
- INX H ;PT TO NEXT
- DJNZ PEEK4
- CALL PRINT ;CLOSING FENCE
- DB FENCE+80H
- CALL BREAK ;ALLOW ABORT
- JR PEEK2
- ;
- ENDIF ;PEEKON
- ;
- ; PRINT A AS 2 HEX CHARS
- ; PASHC - LEADING SPACE
- ;
- IF PEEKON OR POKEON
- PASHC:
- PUSH PSW ;SAVE A
- CALL PRINT
- DB ' '+80H
- POP PSW
- PAHC:
- PUSH B ;SAVE BC
- MOV C,A ;BYTE IN C
- RRC ;EXCHANGE NYBBLES
- RRC
- RRC
- RRC
- CALL PAH ;PRINT HEX CHAR
- MOV A,C ;GET LOW
- POP B ;RESTORE BC AND FALL THRU TO PAH
- PAH:
- ANI 0FH ;MASK
- ADI '0' ;CONVERT TO ASCII
- CPI '9'+1 ;LETTER?
- JRC PAH1
- ADI 7 ;ADJUST TO LETTER
- PAH1:
- JMP CONOUT
- ;
- ENDIF ;PEEKON OR POKEON
- ;
- ;Section 5I
- ;Command: POKE
- ;Function: Place Values into Memory
- ;
- ;Form:
- ; POKE startadr val1 val2 ...
- ;
- IF POKEON
- POKE:
- ;
- ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
- ;
- IF WPOKE
- CALL WHLTST
- ENDIF ;WHEEL APPROVAL
- ;
- CALL RETSAVE
- LXI H,TBUFF+1 ;PT TO FIRST CHAR
- CALL SKSP ;SKIP TO NON-BLANK
- JRZ NOARGS ;ARG ERROR
- CALL HEXNUM ;CONVERT TO NUMBER
- CALL PRINT
- DB ' Pok','e'+80H
- CALL ADRAT ;PRINT AT MESSAGE
- ;
- ; LOOP FOR STORING HEX VALUES SEQUENTIALLY VIA POKE
- ;
- POKE1:
- PUSH D ;SAVE ADDRESS
- CALL SKSP ;SKIP TO NON-BLANK
- JZ EXIT ;DONE
- CPI '"' ;QUOTED TEXT?
- JRZ POKE2
- CALL HEXNUM ;GET NUMBER
- MOV A,E ;GET LOW
- POP D ;GET ADDRESS
- STAX D ;STORE NUMBER
- INX D ;PT TO NEXT
- JR POKE1
- ;
- ; STORE ASCII CHARS
- ;
- POKE2:
- POP D ;GET NEXT ADDRESS
- INX H ;PT TO NEXT CHAR
- POKE3:
- MOV A,M ;GET NEXT CHAR
- ORA A ;DONE?
- JZ EXIT
- STAX D ;PUT CHAR
- INX H ;PT TO NEXT
- INX D
- JR POKE3
- ;
- ; No Argument Error
- ;
- NOARGS:
- CALL PRINT
- DB ' Arg','?'+80H
- JMP EXIT
- ;
- ENDIF ;POKEON
- ;
- ;Section 5J
- ;Command: REG
- ;Function: Manipulate Memory Registers
- ;
- ;Forms:
- ; REG D or REG <-- Display Register Value
- ; REG Mreg <-- Decrement Register Value
- ; REG Preg <-- Increment Register Value
- ; REG Sreg value <-- Set Register Value
- ;
- IF REGON
- REGCMD:
- LXI H,FCB1+1 ;PT TO FIRST ARG
- MOV A,M ;GET FIRST CHAR
- PUSH PSW ;SAVE CHAR
- CPI 'A' ;ASSUME DIGIT IF LESS THAN 'A'
- JRC REGC1
- INX H ;PT TO DIGIT
- REGC1:
- MOV A,M ;GET DIGIT
- CALL REGPTR ;PT TO REGISTER
- POP PSW ;GET CHAR
- CPI 'S' ;SET?
- JRZ RSET
- CPI 'P' ;PLUS?
- JRZ RINC
- CPI 'M' ;MINUS?
- JRZ RDEC
- ;
- ; SHOW REGISTER VALUES
- ;
- RSHOW:
- XRA A ;SELECT REGISTER 0
- MOV B,A ;COUNTER SET TO 0 IN B
- CALL REGP2 ;HL PTS TO REGISTER 0
- RSHOW1:
- MOV A,B ;GET COUNTER VALUE
- CPI 10
- JZ CRLF ;NEW LINE AND EXIT IF DONE
- CALL PRINT
- DB ' Reg',' '+80H
- MOV A,B ;PRINT REGISTER NUMBER
- ADI '0'
- CALL CONOUT
- CALL PRINT
- DB ' ','='+80H
- PUSH B ;SAVE COUNTER
- CALL REGOUT ;PRINT REGISTER VALUE
- POP B ;GET COUNTER
- INR B ;INCREMENT COUNTER
- MOV A,B ;CHECK FOR NEW LINE
- ANI 3
- CZ CRLF
- INX H ;PT TO NEXT REGISTER
- JR RSHOW1
- ;
- ; INCREMENT REGISTER VALUE
- ; HL PTS TO MEMORY REGISTER ON INPUT
- ;
- RINC:
- INR M ;INCREMENT IT
- JR REGOUT ;PRINT RESULT
- ;
- ; DECREMENT REGISTER VALUE
- ; HL PTS TO MEMORY REGISTER ON INPUT
- ;
- RDEC:
- DCR M ;DECREMENT VALUE
- JR REGOUT ;PRINT RESULT
- ;
- ; SET REGISTER VALUE
- ; HL PTS TO REGISTER ON INPUT
- ;
- RSET:
- LXI D,FCB2+1 ;PT TO VALUE
- MVI B,0 ;INIT VALUE TO ZERO
- RSET1:
- LDAX D ;GET NEXT DIGIT
- INX D ;PT TO NEXT
- SUI '0' ;CONVERT TO BINARY
- JRC RSET2
- CPI 10 ;RANGE?
- JRNC RSET2
- MOV C,A ;DIGIT IN C
- MOV A,B ;MULTIPLY OLD BY 10
- ADD A ;*2
- ADD A ;*4
- ADD B ;*5
- ADD A ;*10
- ADD C ;ADD IN NEW DIGIT
- MOV B,A ;RESULT IN B
- JR RSET1
- RSET2:
- MOV M,B ;SET VALUE
- REGOUT:
- CALL PRINT ;PRINT LEADING SPACE
- DB ' '+80H
- MOV A,M ;GET REGISTER VALUE
- MVI B,100 ;PRINT 100'S
- MVI C,0 ;SET LEADING SPACE FLAG
- CALL DECB ;PRINT 100'S
- MVI B,10 ;PRINT 10'S
- CALL DECB ;PRINT 10'S
- ADI '0' ;PRINT 1'S
- JMP CONOUT
- ;
- ; SUBTRACT B FROM A UNTIL CARRY, THEN PRINT DIGIT COUNT
- ;
- DECB:
- MVI D,'0' ;SET DIGIT
- DECB1:
- SUB B ;SUBTRACT
- JRC DECB2
- INR D ;ADD 1 TO DIGIT CHAR
- JR DECB1
- DECB2:
- ADD B ;ADD BACK IN
- MOV E,A ;SAVE A IN E
- MOV A,D ;GET DIGIT CHAR
- CPI '0' ;LEADING ZERO CHECK
- JRNZ DECB3
- MOV A,C ;ANY LEADING DIGIT YET?
- ORA A
- JRZ DECB4
- DECB3:
- MOV A,D ;GET DIGIT CHAR
- CALL CONOUT ;PRINT IT
- INR C ;SET C<>0 FOR LEADING DIGIT CHECK
- DECB4:
- MOV A,E ;RESTORE A FOR NEXT ROUND
- RET
-
- ;
- ; SET HL TO POINT TO MEMORY REGISTER WHOSE INDEX IS PTED TO BY HL
- ; ON INPUT, A CONTAINS REGISTER CHAR
- ; ON OUTPUT, HL = ADDRESS OF MEMORY REGISTER (REG 0 ASSUMED IF ERROR)
- ;
- REGPTR:
- MVI B,0 ;INIT TO ZERO
- SUI '0' ;CONVERT
- JRC REGP1
- CPI 10 ;RANGE
- JRNC REGP1
- MOV B,A ;VALUE IN B
- REGP1:
- MOV A,B ;VALUE IN A
- REGP2:
- LXI H,Z3MSG+30H ;PT TO MEMORY REGISTERS
- ADD L ;PT TO PROPER REGISTER
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A ;HL PTS TO REGISTER
- RET
- ;
- ENDIF ;REGON
-
- ;
- ;Section 5K
- ;Command: WHL/WHLQ
- ;Function: Set the Wheel Byte on or off
- ;
- ;Form:
- ; WHL -- turn Wheel Byte OFF
- ; WHL password -- turn Wheel Byte ON if password is correct
- ; WHLQ -- find out status of Wheel Byte
- ;
- IF WHLON
- WHL:
- LXI H,FCB1+1 ;PT TO FIRST CHAR
- MOV A,M ;GET IT
- CPI ' ' ;TURN BYTE OFF IF NO PASSWORD
- JRZ WHLOFF
- LXI D,WHLPASS
- MVI B,8 ;CHECK 8 CHARS
- WHL1:
- LDAX D ;GET CHAR
- CMP M ;COMPARE
- JRNZ WHLMSG
- INX H ;PT TO NEXT
- INX D
- DJNZ WHL1
- ;
- ; TURN ON WHEEL BYTE
- ;
- MVI A,0FFH ;TURN ON WHEEL BYTE
- JR WHLSET
- ;
- ; TURN OFF WHEEL BYTE
- ;
- WHLOFF:
- XRA A ;TURN OFF WHEEL BYTE
- WHLSET:
- STA Z3WHL ;SET WHEEL BYTE AND PRINT MESSAGE
- ;
- ; PRINT WHEEL BYTE MESSAGE
- ;
- WHLMSG:
- CALL PRINT
- DB ' Wheel Byte',' '+80H
- LDA Z3WHL ;GET WHEEL BYTE
- ORA A ;ZERO IS OFF
- JRZ OFFM
- CALL PRINT
- DB 'O','N'+80H
- RET
- OFFM:
- CALL PRINT
- DB 'OF','F'+80H
- RET
- ;
- ; WHEEL PASSWORD DEFINED FROM SYSRCP.LIB FILE
- ;
- DB 'Z'-'@' ;LEADING ^Z IN CASE OF TYPE
- WHLPASS:
- WPASS ;USE MACRO
- ;
- ENDIF ;WHLON
-
- ;
- ;Section 5L
- ;Command: ECHO
- ;Function: Echo Text without Interpretation to Console or Printer
- ;
- ;Form:
- ; ECHO text <-- echo text to console
- ; ECHO $text <-- echo text to printer
- ;
- ; Additionally, if a form feed character is encountered in the
- ; output string, no further output will be done, a new line will be
- ; issued, and this will be followed by a form feed character. That is:
- ;
- ; ECHO $text^L
- ;
- ; will cause "text" to be printed on the printer followed by CR, LF, FF.
- ;
- ECHO:
- LXI H,TBUFF+1 ;PT TO FIRST CHAR
- ECHO1:
- MOV A,M ;SKIP LEADING SPACES
- INX H ;PT TO NEXT
- CPI ' '
- JRZ ECHO1
- ;
- IF ECHOLST
- MOV B,A ;CHAR IN B
- CPI '$' ;PRINT FLAG?
- JRZ ECHO2
- ENDIF ;ECHOLST
- ;
- DCX H ;PT TO CHAR
- ;
- ; LOOP TO ECHO CHARS
- ;
- ECHO2:
- MOV A,M ;GET CHAR
- ORA A ;EOL?
- JRZ ECHO4
- ;
- IF ECHOLST
- CPI FF ;FORM FEED?
- JRZ ECHO3
- ENDIF ;ECHOLST
- ;
- ECHO2C:
- CALL ECHOUT ;SEND CHAR
- INX H ;PT TO NEXT
- JR ECHO2
- ;
- ; FORM FEED - SEND NEW LINE FOLLOWED BY FORM FEED IF PRINTER OUTPUT
- ;
- IF ECHOLST
- ECHO3:
- MOV A,B ;CHECK FOR PRINTER OUTPUT
- CPI '$'
- JRNZ ECHOFF ;SEND FORM FEED NORMALLY IF NOT PRINTER
- CALL ECHONL ;SEND NEW LINE
- MVI A,FF ;SEND FORM FEED
- JR ECHOUT
- ;
- ; SEND FORM FEED CHAR TO CONSOLE
- ;
- ECHOFF:
- MVI A,FF ;GET CHAR
- JR ECHO2C
- ENDIF ;ECHOLST
- ;
- ; END OF PRINT LOOP - CHECK FOR PRINTER TERMINATION
- ;
- ECHO4:
- IF NOT ECHOLST
- ;
- RET
- ;
- ELSE
- ;
- MOV A,B ;CHECK FOR PRINTER OUTPUT
- CPI '$'
- RNZ ;DONE IF NO PRINTER OUTPUT
- ;
- ; OUTPUT A NEW LINE
- ;
- ECHONL:
- MVI A,CR ;OUTPUT NEW LINE ON PRINTER
- CALL ECHOUT
- MVI A,LF ;FALL THRU TO ECHOUT
- ;
- ENDIF ;NOT ECHOLST
- ;
- ; OUTPUT CHAR TO PRINTER OR CONSOLE
- ;
- ECHOUT:
- MOV C,A ;CHAR IN C
- PUSH H ;SAVE HL
- PUSH B ;SAVE BC
- LXI D,0CH-3 ;OFFSET FOR CONSOLE OUTPUT
- ;
- IF ECHOLST
- MOV A,B ;CHECK FOR PRINTER
- CPI '$'
- JRNZ ECHOUT1
- INX D ;ADD 3 FOR PRINTER OFFSET
- INX D
- INX D
- ;
- ENDIF ;ECHOLST
- ;
- ; OUTPUT CHAR IN C WITH BIOS OFFSET IN DE
- ;
- ECHOUT1:
- CALL BIOUT ;BIOS OUTPUT
- POP B ;RESTORE BC,HL
- POP H
- RET
-
- ;
- ; OUTPUT CHAR IN C TO BIOS WITH OFFSET IN DE
- ;
- BIOUT:
- LHLD WBOOT+1 ;GET ADDRESS OF WARM BOOT
- DAD D ;PT TO ROUTINE
- PCHL ;JUMP TO IT
-
- ;
- ; ** SUPPORT UTILITIES **
- ;
-
- ;
- ; CHECK FOR USER INPUT; IF ^C, RETURN WITH Z
- ;
- BREAK:
- PUSH H ;SAVE REGS
- PUSH D
- PUSH B
- MVI E,0FFH ;GET CHAR IF ANY
- MVI C,6 ;CONSOLE STATUS CHECK
- CALL BDOS
- POP B ;RESTORE REGS
- POP D
- POP H
- CPI CTRLC ;CHECK FOR ABORT
- JZ EXIT ;EXIT
- CPI CTRLX ;SKIP?
- RET
-
- ;
- ; COPY HL TO DE FOR B BYTES
- ;
- LDIR:
- MOV A,M ;GET
- STAX D ;PUT
- INX H ;PT TO NEXT
- INX D
- DJNZ LDIR ;LOOP
- RET
-
- ;
- ; PRINT FILE NOT FOUND MESSAGE
- ;
- PRFNF:
- CALL PRINT
- DB ' No File','s'+80H
- JMP EXIT
-
- ;
- ; OUTPUT NEW LINE TO CON:
- ;
- CRLF:
- MVI A,CR
- CALL CONOUT
- MVI A,LF
- JMP CONOUT
-
- ;
- ; SEARCH FOR FIRST AND NEXT
- ;
- SEARF:
- PUSH B ; SAVE COUNTER
- PUSH H ; SAVE HL
- MVI C,17 ; SEARCH FOR FIRST FUNCTION
- SEARF1:
- LXI D,FCB1 ; PT TO FCB
- CALL BDOS
- INR A ; SET ZERO FLAG FOR ERROR RETURN
- POP H ; GET HL
- POP B ; GET COUNTER
- RET
- SEARN:
- PUSH B ; SAVE COUNTER
- PUSH H ; SAVE HL
- MVI C,18 ; SEARCH FOR NEXT FUNCTION
- JR SEARF1
-
- ;
- ; CONSOLE INPUT
- ;
- CONIN:
- PUSH H ; SAVE REGS
- PUSH D
- PUSH B
- MVI C,1 ; INPUT
- CALL BDOS
- POP B ; GET REGS
- POP D
- POP H
- ANI 7FH ; MASK MSB
- CPI 61H
- RC
- ANI 5FH ; TO UPPER CASE
- RET
-
- ;
- ; LOG INTO USER AREA CONTAINED IN FCB1
- ;
- LOGUSR:
- LDA FCB1+13 ;GET USER NUMBER
- SETUSR:
- MOV E,A
- MVI C,32 ;USE BDOS FCT
- JMP BDOS
-
- ;
- ; PRINT FILE NAME PTED TO BY HL
- ;
- PRFN:
- CALL PRINT ;LEADING SPACE
- DB ' '+80H
- MVI B,8 ;8 CHARS
- CALL PRFN1
- MVI A,'.' ;DOT
- CALL CONOUT
- MVI B,3 ;3 CHARS
- PRFN1:
- MOV A,M ; GET CHAR
- INX H ; PT TO NEXT
- CALL CONOUT ; PRINT CHAR
- DJNZ PRFN1 ; COUNT DOWN
- RET
-
- ;
- ; SAVE RETURN ADDRESS
- ;
- RETSAVE:
- POP D ; GET RETURN ADDRESS
- POP H ; GET RETURN ADDRESS TO ZCPR3
- SHLD Z3RET ; SAVE IT
- PUSH H ; PUT RETURN ADDRESS TO ZCPR3 BACK
- PUSH D ; PUT RETURN ADDRESS BACK
- RET
-
- ;
- ; EXIT TO ZCPR3
- ;
- EXIT:
- Z3RET EQU $+1 ; POINTER TO IN-THE-CODE MODIFICATION
- LXI H,0 ; RETURN ADDRESS
- PCHL ; GOTO ZCPR3
-
- ;
- ; TEST WHEEL BYTE FOR APPROVAL
- ; IF WHEEL BYTE IS 0 (OFF), ABORT WITH A MESSAGE (FLUSH RET ADR AND EXIT)
- ;
- IF WHEEL ;IF ANY WHEEL OPTION IS RUNNING
- WHLTST:
- LDA Z3WHL ;GET WHEEL BYTE
- ORA A ;ZERO?
- RNZ
- POP PSW ;CLEAR STACK
- CALL PRINT
- DB ' No Whee','l'+80H
- RET
- ENDIF ;WHEEL
-
- ;
- ; PRINT A DASH
- ;
- IF LTON OR PEEKON
- DASH:
- CALL PRINT
- DB ' -',' '+80H
- RET
- ;
- ENDIF ;LTON OR PEEKON
- ;
- ; PRINT ADDRESS MESSAGE
- ; PRINT ADDRESS IN DE
- ;
- IF PEEKON OR POKEON
- ADRAT:
- CALL PRINT
- DB ' at',' '+80H
- MOV A,D ;PRINT HIGH
- CALL PAHC
- MOV A,E ;PRINT LOW
- JMP PAHC
- ;
- ; EXTRACT HEXADECIMAL NUMBER FROM LINE PTED TO BY HL
- ; RETURN WITH VALUE IN DE AND HL PTING TO OFFENDING CHAR
- ;
- HEXNUM:
- LXI D,0 ;DE=ACCUMULATED VALUE
- MVI B,5 ;B=CHAR COUNT
- HNUM1:
- MOV A,M ;GET CHAR
- CPI ' '+1 ;DONE?
- RC ;RETURN IF SPACE OR LESS
- INX H ;PT TO NEXT
- 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:
- 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
- RET
- ;
- ; NUMBER ERROR
- ;
- NUMERR:
- CALL PRINT
- DB ' Num','?'+80H
- JMP EXIT
- ;
- ; SKIP TO NEXT NON-BLANK
- ;
- SKSP:
- MOV A,M ;GET CHAR
- INX H ;PT TO NEXT
- CPI ' ' ;SKIP SPACES
- JRZ SKSP
- DCX H ;PT TO GOOD CHAR
- ORA A ;SET EOL FLAG
- RET
- ;
- ENDIF ;PEEKON OR POKEON
- ;
- ; Test File in FCB for unambiguity and existence, ask user to delete if so
- ; Return with Z flag set if R/O or no permission to delete
- ;
- IF RENON OR CPON
- EXTEST:
- CALL AMBCHK ;AMBIGUOUS FILE NAMES NOT ALLOWED
- CALL SEARF ;LOOK FOR SPECIFIED FILE
- JRZ EXOK ;OK IF NOT FOUND
- CALL GETSBIT ;POSITION INTO DIR
- INX D ;PT TO FILE NAME
- XCHG ;HL PTS TO FILE NAME
- PUSH H ;SAVE PTR TO FILE NAME
- CALL PRFN ;PRINT FILE NAME
- POP H
- CALL ROTEST ;CHECK FOR R/O
- JRNZ EXER
- CALL ERAQ ;ERASE?
- JRNZ EXER ;RESTART AS ERROR IF NO
- LXI D,FCB1 ;PT TO FCB1
- MVI C,19 ;DELETE FILE
- CALL BDOS
- EXOK:
- XRA A
- DCR A ;NZ = OK
- RET
- EXER:
- XRA A ;ERROR FLAG - FILE IS R/O OR NO PERMISSION
- RET
-
- ;
- ; CHECK FOR AMBIGUOUS FILE NAME IN FCB1
- ; RETURN Z IF SO
- ;
- AMBCHK:
- LXI H,FCB1+1 ;PT TO FCB
- ;
- ; CHECK FOR AMBIGUOUS FILE NAME PTED TO BY HL
- ;
- AMBCHK1:
- PUSH H
- MVI B,11 ;11 BYTES
- AMB1:
- MOV A,M ;GET CHAR
- ANI 7FH ;MASK
- CPI '?'
- JRZ AMB2
- INX H ;PT TO NEXT
- DJNZ AMB1
- DCR B ;SET NZ FLAG
- POP D
- RET
- AMB2:
- POP H ;PT TO FILE NAME
- CALL PRFN
- CALL PRINT
- DB ' is AF','N'+80H
- JMP EXIT
- ;
- ENDIF ;RENON OR CPON
- ;
- ; CHECK USER TO SEE IF HE APPROVES ERASE OF FILE
- ; RETURN WITH Z IF YES
- ;
- IF RENON OR CPON OR ERAON OR PROTON
- ERAQ:
- CALL PRINT
- DB ' - Eras','e'+80H
- ERAQ1:
- CALL PRINT
- DB ' (Y/N)?',' '+80H
- CALL CONIN ;GET RESPONSE
- CPI 'Y' ;KEY ON YES
- RET
- ;
- ENDIF ;RENON OR CPON OR ERAON OR PROTON
- ;
- ; TEST FILE PTED TO BY HL FOR R/O
- ; NZ IF R/O
- ;
- IF RENON OR ERAON OR CPON
- ROTEST:
- PUSH H ;ADVANCE TO R/O BYTE
- LXI B,8 ;PT TO 9TH BYTE
- DAD B
- MOV A,M ;GET IT
- ANI 80H ;MASK BIT
- PUSH PSW
- LXI H,ROMSG
- CNZ PRINT1 ;PRINT IF NZ
- POP PSW ;GET FLAG
- POP H ;GET PTR
- RET
- ROMSG:
- DB ' is R/','O'+80H
- ;
- ENDIF ;RENON OR ERAON OR CPON
- ;
- ; INIT FCB1, RETURN WITH DE PTING TO FCB1
- ;
- IF ERAON OR LTON OR CPON
- INITFCB1:
- LXI H,FCB1 ;PT TO FCB
- INITFCB2:
- PUSH H ;SAVE PTR
- LXI B,12 ;PT TO FIRST BYTE
- DAD B
- MVI B,24 ;ZERO 24 BYTES
- XRA A ;ZERO FILL
- CALL FILLP ;FILL MEMORY
- POP D ;PT TO FCB
- RET
- ;
- ENDIF ;ERAON OR LTON OR CPON
- ;
- ; BUFFERS
- ;
- NXTFILE:
- DS 2 ;PTR TO NEXT FILE IN LIST
-
- ;
- ; SIZE ERROR TEST
- ;
- IF ($ GT (RCP + RCPS*128))
- SIZERR EQU NOVALUE ;RCP IS TOO LARGE FOR BUFFER
- ENDIF
-
- ;
- ; END OF SYS.RCP
- ;
-
- END