;
;       DIRFIX.ASM as of 6/4/80
;       by Keith Petersen, W8SDZ
;
;This program is for use on CP/M 1.4, CDOS or IMDOS.
;Its purpose is to fix directory entries made under
;CP/M 2.x or other operating systems which use bit
;7 of the file name for attributes, thus making the
;file unreadable.
;
;The program prints  out the disk directory
;on the signed on drive. If an illegal ASCII
;character is found in the filename or filetype
;it will be stored in a table of names to be renamed
;when the printing is finished.
;
BDOS    EQU     05H
FCB     EQU     5CH
FCBEXT  EQU     FCB+12
FCB2    EQU     FCB+16
FCBEXT2 EQU     FCB2+12
TBUFF   EQU     80H
;
       ORG     100H
;
;       PROGRAM BEGINS HERE
;
BEGIN:  LXI     SP,STACK
       LXI     H,RENFIL
       SHLD    RENPTR  ;INITIALIZE RENAME POINTER
       CALL    SEARCH  ;SEARCH FOR FIRST FILE
;
MAIN02: LDA     RESULT
       CPI     0FFH    ;NO FILE?
       JZ      MAIN04  ;NO FILE, EXIT LOOP
       CALL    WORKLOOP
       CALL    NEXTFILE ;SEARCH FOR NEXT FILE
       JMP     MAIN02
;
MAIN04: LHLD    RENPTR  ;GET TABLE POINTER
       LXI     D,RENFIL ;POINT TO TABLE START
       MOV     A,L     ;CHECK TO SEE IF THEY ARE SAME
       CMP     E
       JNZ     MAIN06  ;NOT SAME, CONTINUE
       MOV     A,H
       CMP     D
       JZ      QUIT    ;YES, SAME - EXIT TO CP/M
;
MAIN06: LXI     D,-11   ;SUBTRACT 11
       DAD     D
       SHLD    RENPTR
       XCHG            ;DE POINTS TO NAME
       LXI     H,FCB+1 ;WHERE TO PUT OLD NAME
       MVI     B,11    ;NUMBER OF CHARACTERS
       CALL    MOVE
       XRA     A
       STA     FCB     ;ZERO DRIVE NAME
       STA     FCBEXT  ;ZERO EXTENT BYTE
       STA     FCB2    ;ZERO DRIVE NAME
       STA     FCBEXT2 ;ZERO FCB2 EXTENT BYTE
       LHLD    RENPTR
       XCHG            ;DE NOW HAS NAME POINTER
       LXI     H,FCB2+1 ;WHERE TO PUT NEW NAME
       MVI     B,11    ;NUMBER OF CHARACTERS
;
MAIN08: LDAX    D       ;GET CHARACTER
       ANI     7FH     ;STRIP OFF ATTRIBUTE
       MOV     M,A
       INX     H
       INX     D
       DCR     B
       JNZ     MAIN08
       LXI     D,FCB
       CALL    RENAME
       JMP     MAIN04
;
QUIT:   JMP     0       ;EXIT TO CP/M WARM BOOT
;
;       SYSTEM SUBROUTINES
;
;MAIN WORK LOOP
;
;THIS ROUTINE FINDS THE POSITION OF THE FILE
;INFORMATION IN THE DIRECTORY DMA, PRINTS THE
;NAME IF IT IS A CURRENT FILE, AND PRINTS A
;MESSAGE IF THE FILE WILL BE RENAMED.
;
WORKLOOP:
       LDA     RESULT  ;RESULT HOLDS POSITION OF-
       MOV     B,A     ; -THE DIRECTORY ENTRY IN THE DIR. DMA
       ANI     3
       RAL
       RAL
       RAL
       RAL
       RAL
       ANI     0E0H
       MOV     E,A
       MVI     D,0
       LXI     H,TBUFF
       DAD     D       ;HL NOW POINTS TO THE FILE INFO
       MOV     A,M
       ORA     A       ;USER 0 FILE?
       RNZ             ;NO, IGNORE IT
       STA     ENTBYT  ;A = 0
       INX     H       ;POINT TO NAME
       SHLD    DIRPTR  ;SAVE DIRECTORY POSITION POINTER
       MVI     B,11    ;NUMBER OF CHARACTERS
;
;PRINT AS ASCII THE FIRST 11 CHARS IN THE ENTRY
;
WORK02: MOV     A,M
       CALL    ILLCHK
       CALL    TYPE
       DCR     B       ;ONE LESS CHARACTER
       INX     H
       JNZ     WORK02
       CALL    CRLF    ;TURN UP NEW LINE
       LDA     ENTBYT
       ORA     A
       RZ
       LXI     D,RENMSG ;RENAMING MESSAGE
       MVI     C,9     ;WRITE CONSOLE FUNCTION
       CALL    BDOS
       CALL    CRLF    ;TURN UP NEW LINE
       LHLD    DIRPTR  ;GET DIRECTORY POSITION POINTER
       XCHG            ;DE NOW = DIRECTORY POSITION
       LHLD    RENPTR
       MVI     B,11    ;NUMBER OF CHARACTERS
       CALL    MOVE
       SHLD    RENPTR
       RET
;
;       TYPE A CHAR FROM (A)
;
TYPE:   PUSH    B
       PUSH    D
       PUSH    H
       MVI     C,2     ;WRITE CONSOLE FUNCTION
       MOV     E,A     ;CHARACTER TO E FOR CP/M
       CALL    BDOS
       POP     H
       POP     D
       POP     B
       RET
;
;       SEARCH FOR A FILE
;
SEARCH: PUSH    B
       PUSH    D
       PUSH    H
       MVI     C,17    ;SEARCH FIRST FUNCTION
       LXI     D,AFN
       CALL    BDOS
       STA     RESULT
       POP     H
       POP     D
       POP     B
       RET
;
;FIND NEXT OCCURRENCE OF FILE
;
NEXTFILE:
       PUSH    B
       PUSH    D
       PUSH    H
       MVI     C,18    ;SEARCH NEXT FUNCTION
       LXI     D,AFN
       CALL    BDOS
       STA     RESULT
       POP     H
       POP     D
       POP     B
       RET
;
;RENAME A FILE
;
RENAME: PUSH    B
       PUSH    D
       PUSH    H
       MVI     C,23    ;RENAME FUNCTION
       CALL    BDOS
       POP     H
       POP     D
       POP     B
       RET
;
;NEWLINE
;
CRLF:   MVI     A,0DH
       CALL    TYPE
       MVI     A,0AH
       CALL    TYPE
       RET
;
;MOVE (B) CHARACTERS FROM (DE) TO (HL)
;
MOVE:   LDAX    D
       MOV     M,A
       INX     H
       INX     D
       DCR     B
       JNZ     MOVE
       RET
;
;CHECK FOR NONASCII CHARACTER  <20H  OR  >60H
;
ILLCHK: CPI     20H
       JC      ILLEGL
       CPI     61H
       JNC     ILLEGL
       RET
;
ILLEGL: MVI     A,0FFH
       STA     ENTBYT
       MVI     A,'-'
       RET
;
RENMSG: DB      ' ++RENAMING$'
;
;AMBIGUOUS FILENAME.TYP
;
AFN:    DB      0,'???????????',0
;
RESULT: DB      0       ;STORAGE FOR RESULT OF BDOS CALL
;
;STACK SPACE
;
       DS      60
STACK:  EQU     $
;
;SOME STORAGE LOCATIONS
;
ENTBYT: DS      1
DIRPTR: DS      2
RENPTR: DS      2
RENFIL  EQU     $       ;FILE OF RENAMEABLE FILES BUILDS HERE
;
       END