;THIS IS A REWRITE OF BDPATCH.ASM TO ELIMINATE SOME
;SERIOUS DRAWBACKS. THESE ARE:

;IF YOU TYPED ERA *.* YOU WOULD ERASE ALL PUBLIC FILES AND
;ALL PUBLIC FILES THAT ARE NOT SYSTEM FILES WOULD BE SHOWN
;EACH TIME YOU TYPED DIR OR IN WORDSTAR. EVEN AFTER YOU
;ERASED A FILE DIR WOULD STILL FIND IT AS A PUBLIC FILE.

;THIS PROGRAM CONTAINS A PATCH FOR CP/M 2.2 THAT ADDS
;A NEW FILE ATTRIBUTE: THE PUBLIC ATTRIBUTE.
;WHEN A FILE'S PUBLIC ATTRIBUTE IS SET, IT IS AVAILABLE
;TO ALL USERS. THE PUBLIC ATTRIBUTE IS F1' (THE HIGH BIT
;OF THE FIRST CHARACTER OF THE FILENAME).

;I DON'T KNOW WHO WROTE THE ORIGINAL VERSION BUT I ADDED
;SOME ADDITIONAL CODE AND NOW THIS WORKS CORRECTLY. I AM
;AFRAID IT IS LONGER THAN THE ORIGINAL PATCH AND YOU WILL
;HAVE TO PUT SOME OF THIS ELSEWHERE. IF ANYONE CAN MAKE
;THIS CODE SMALLER, PLEASE DO SO. THIS WILL ALSO LET YOU SEE
;THE PUBLIC FILES IF YOU ARE ON THE CORRECT USER.   A.S.A.

MSIZE  EQU     63      ;PUT YOUR CP/M SIZE IN K-BYTES

BIAS   EQU     (MSIZE - 20) * 1024
HI$MEMORY      EQU     0F662H  ;WHEREVER YOU WANT THE REST OF CODE


;Z80 MACROS

@GENDD MACRO   ?DD
       IF (?DD GT 7FH) AND (?DD LT 0FF80H)
       DB      100H    ;RANGE ERROR ON JUMP RELATIVE
       ELSE
       DB      ?DD
       ENDIF
       ENDM
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, JMP NZ
       DB      10H
       @GENDD  ?N-$-1
       ENDM

;BDOS ENTRY POINTS
FIND   EQU     432DH + BIAS
NXTDIR EQU     4205H + BIAS
CHKLST EQU     41F5H + BIAS
EXITFF EQU     4394H + BIAS
FCBPTR EQU     49D9H + BIAS
CKNDIR EQU     417FH + BIAS
DIRADD EQU     415EH + BIAS
CMPCNT EQU     49D8H + BIAS
CMPEXT EQU     4307H + BIAS
DIRNUM EQU     49EAH + BIAS
RESULT EQU     3F45H + BIAS
FNDFLG EQU     49D4H + BIAS

       ORG     FIND

FIND:
       LXI     H,0FFFFH        ;SET UP CONTROL
       SHLD    SER$EXIT+1

       MVI     C,0
       CALL    NXTDIR  ;SET UP NEXT DIR ENTRY
       CALL    CHKLST  ;SET Z IF READ PAST END OF DIR
       JRZ     EXITFF  ;RET NOT FOUND IF SO
       LHLD    FCBPTR
       XCHG
       LDAX    D
       CPI     0E5H    ;LOOKING FOR FREE DIR SLOT?
       JRZ     FIND1
       PUSH    D       ;QUIT IF PASSED ALL ACTIVE
       CALL    CKNDIR  ;CALL IF NOT LOOKING FOR FREE SLOT
       POP     D

FIND1:
       CALL    DIRADD  ;GET ADDR OF NEXT ENTRY
       LDA     CMPCNT  ;NR. OF FCB BYTES TO COMPARE
       INR     A
       MOV     C,A
       MVI     B,-1    ;C IS COUNT, B IS INDEX

FIND2:
       DCR     C       ;ALL MATCHED?
       JZ      FIND5   ;JMP IF SO
       INR     B       ;BUMP INDEX
       JRNZ    FIND2A  ;JMP IF NOT CHECKING USER BYTE

;FIRST SEE IF FREE DIRECTORY SPACE
       LDAX    D       ;
       CPI     0E5H    ;LOOKING FOR FREE DIR SLOT?
       JRZ     FIND2A  ;SKIP PUBLIC CHECK IF SO


;SEE IF WE ARE ON THE SAME USER AREA SO WE CAN SEE
;PUBLIC FILES IF WE ARE ON THAT USER AREA
       SUB     M       ;CHECKS USER AREA WE ARE ON
       JZ      FIND4   ;IF SO WE HAVE A MATCH

;NEXT SEE IF THIS IS A DELETED FILE ELSE THESE WILL
;SHOW UP AGAIN IF DIR IS TYPED
       MOV     A,M
       RAL             ;SET CY FLAG IF E5
       JRC     FIND2A  ;SKIP PUBLIC CHECK

;SEE IF WE ARE LOOKING AT A PUBLIC FILE
       INX     H       ;->F1 BYTE
       MOV     A,M
       DCX     H
       RAL             ;SET CY FLAG ON PUBLIC ATTRIBUTE
       JRNC    FIND2A  ;IF NOT CORRECT USER OR PUBLIC CHECK
                       ;NEXT FILE
;NOW TELL WE HAVE FOUND A PUBLIC FILE
       XRA     A
       STA     PUB$FLAG
       JMP     FIND4

;WE ARE HERE IF WE HAVE A CORRECT USER OR IF PUBLIC FILE

FIND2A:
;NEXT CHECK IF ANY WILD CARDS USED IN FILE
       LDAX    D
       CPI     '?'     ;? MATCHES ANYTHING
       JRNZ    FIND2B  ;NO WILD CARDS SEARCH ON

;FOUND A WILD CARD TELL ABOUT IT
       XRA     A
       STA     WILD$FLAG
       JMP     FIND4

;WE ARE HERE ONLY IF NOT FINDING ANY WILD CARDS
FIND2B:
       MOV     A,B
       CPI     13      ;WE ON S1 BYTE?
       JZ      FIND4   ;S1 BYTE ALWAYS MATCHES
       CPI     12      ;EXTENT BYTE?
       LDAX    D       ;GET BYTE AGAIN
       JMP     FIND$HI


;THIS MUST BE PUT IN SOMEWHERE OTHER THAN IN BDOS BECAUSE THE
;WHOLE ROUTINE IS LONGER THAN AVAILABLE SPACE. I PUT THIS IN MY
;BIOS FOR NOW

       ORG     HI$MEMORY

FIND$HI:
       JZ      FIND3   ;JMP IF ON EXTENT BYTE
       SUB     M       ;COMPARE
       ANI     7FH     ;MASK OUT ATTRIB BIT
       JNZ     FIND    ;MISMATCH, TRY NEXT DIR ENTRY
       JMP     FIND4   ;IF MATCHED

FIND3:
       PUSH    B
       MOV     C,M
       CALL    CMPEXT  ;COMPARE EXTENT BYTES
       POP     B
       JNZ     FIND    ;JMP IF MISMATCH
FIND4:
       INX     D       ;BUMP TO NEXT BYTES
       INX     H
       JMP     FIND2

;WE ARRIVE HERE ONLY ON MATCHED BYTES

FIND5:

WILD$FLAG      EQU     $+1
PUB$FLAG       EQU     $+2

SER$EXIT:
       LXI     H,0000H ;THIS GETS PATCHED IF WE HAVE EITHER A PUBLIC
                       ;FILE OR A WILD CARD IS USED
       MOV     A,H
       ORA     L
       JZ      FIND    ;WE CAN NOT ALLOW SEARCHING FOR ANY PUBLIC
                       ;FILES IF WE USE WILD CARDS
       LDA     DIRNUM  ;MATCHED, FIX UP RESULT
       ANI     3
       STA     RESULT
       LXI     H,FNDFLG
       MOV     A,M
       RAL
       RNC
       XRA     A
       MOV     M,A
       RET


       END