;       TAG Version 1.2 - Original by Bruce Ratoff
;       Latest Revision: 2/17/81 Tim Nicholas
;
;       title   'TAG - set or reset and display the "no copy" flag on a file'
;       by Bruce R. Ratoff - first version 5/18/80
;       modified 5/19/80 by BRR to display 4 across
;
;
;02/17/81 Added conditional assy to tag either "f1" or
;         "f2" bit for MP/M v1.1 compatibility.
;         XMODEM v4.1 now tests both "f1" and "f2" for
;         tagged files.
;
;
;
; The purpose of this program is to set or reset the f1' bit on a file.
; This is used by the XMODEM program to indicate that a file may not
; be transmitted.  The anticipated purpose is to allow remote use of
; licensed programs without the danger of their being copied by the
; remote users.  This should protect the licensee from liabilities
; associated with dissemination of licensed software.
;
; To Set the "no copy" flag on a file, type:
;    A>TAG d:filename.typ S
; To Reset the flag (allows copying via XMODEM), type:
;    A>TAG d:filename.typ R
;
; The filename.typ may contain the wildcards "*" and "?".
;
;
;
; Please forward all comments, suggestions and improvements to:
;       Bruce R. Ratoff
;       80 Gill Lane, Apt 1B
;       Iselin, New Jersey 08830
;
;
false   equ     0               ;define false.
true    equ     not false       ;define true
;
f2tag   equ     true            ;False = f1 tag.
                               ;True  = f2 tag.
;
;
bdos    equ     5               ;cp/m entry point
exit    equ     0               ;cp/m exit point
dfcb    equ     5ch             ;cp/m default fcb
dbuff   equ     80h             ;default disk buffer
;
pchar   equ     2               ;print character function
pmessg  equ     9               ;print message function
seldsk  equ     14              ;select drive function
srchfst equ     17              ;search for first file match
srchnxt equ     18              ;search for next file match
attrib  equ     30              ;set file attributes function
;
;
       org     100h
begin:
       lhld    bdos+1          ;set up a stack
       sphl                    ;at top of tpa
;
; Signon message - reports version and attribute used
;                  for tagging "f1" or "f2".
;
       lxi     d,signon        ;get signon address.
       mvi     c,pmessg        ;print string fuction.
       call    bdos            ;print it.
;
signon: db      13,10
       db      'TAG - V1.2  2/17/81'
       db      13,10
;
       IF      NOT F2TAG
       db      'Uses "f1" for Tag'
       ENDIF
;
       IF      F2TAG
       db      'Uses "f2" for Tag'
       ENDIF
;
       db      13,10,13,10,'$'
       lda     dfcb            ;check for specific drive
       dcr     a
       mov     e,a             ;set up for select disk call
       mvi     c,seldsk
       inr     a               ;if no specified drive, skip call
       cnz     bdos
       sub     a               ;now zap out drive spec
       sta     dfcb
       mvi     a,'?'           ;force extent number wild
       sta     dfcb+12
       lda     dfcb+17         ;get "S" or "R" option
       sta     sropt
       cpi     'S'
       jz      okopt
       cpi     'R'
       jz      okopt
       cpi     ' '
       jz      okopt
badopt:
       lxi     d,ilgopt
       mvi     c,pmessg        ;bitch about illegal option
       call    bdos
       jmp     exit
ilgopt:
       db      'Invalid option letter$'
okopt:
       sub     a               ;zero out file count
       sta     filcnt
       lxi     d,dfcb          ;find the first file and get its block map
       mvi     c,srchfst
       call    bdos
       inr     a               ;search successful?
       jnz     gotfile         ;yes, go process rest
       lxi     d,nofile
       mvi     c,pmessg        ;say "no file"
       call    bdos
       jmp     exit
nofile:
       db      'File not found$'
gotfile:
       dcr     a               ;compensate for inr above
       rrc                     ;file offset to bits 5 and 6
       rrc
       rrc
       ani     60h
       lxi     h,dbuff         ;point to base of buffer
       mov     c,a
       mvi     b,0
       dad     b               ;index by file offset
       push    h               ;save for the moment
       lxi     b,filetable
       call    filepoint       ;get table pointer to hl
       xchg                    ;de now points to place in table
       lda     filcnt
       inr     a
       sta     filcnt          ;bump file count
       pop     h               ;hl points to directory entry
       mvi     b,32
       call    blkmov          ;copy entry into table
       mvi     c,srchnxt       ;search for another entry
       lxi     d,dfcb
       call    bdos
       inr     a               ;returns 0ffh at end of search
       jnz     gotfile         ;got another one...go save it
;
; end of directory encountered, now process them
;
tagfile:
       lxi     b,filetable-32  ;allow for filcnt one greater than desired
       call    filepoint
       push    h
       lxi     d,dfcb          ;copy next name to default fcb
       mvi     b,32
       call    blkmov
       sub     a
       sta     dfcb            ;clear drive number
       lxi     d,-20           ;point back to extent field
       dad     d
       mvi     m,'$'           ;tag end of print here
       pop     d               ;get back pointer to start of entry
       inx     d               ;bump fwd to name
       mvi     c,pmessg
       call    bdos            ;say what we're working on
       lda     dfcb+12         ;get extent #
       push    psw             ;save it
       adi     '0'             ;convert to ascii
       mov     e,a
       mvi     c,pchar
       pop     psw
       ora     a               ;print extent if nonzero
       jnz     pext
       mvi     e,' '
pext:
       call    bdos
       lda     sropt           ;get S or R
       cpi     ' '             ;display only?
       jz      nextfile
       rrc                     ;bit 7=0 for R, 1 for S
       ani     80h
       mov     b,a             ;save mask
;
       IF      NOT F2TAG
       lxi     d,dfcb+1        ;Point to f1.
       ENDIF
;
       IF      F2TAG
       lxi     d,dfcb+2        ;point to f2
       ENDIF
;
       ldax    d               ;get it
       ani     7fh             ;strip fx'
       ora     b               ;set bit if option was S
       stax    d               ;put it back
       dcx     d               ;point to start of fcb
;
       IF      F2TAG
       dcx     d
       ENDIF
;
       sub     a               ;zap out drive field
       stax    d
       mvi     c,attrib        ;do set attributes call
       call    bdos
nextfile:
       IF      NOT F2TAG
       lda     dfcb+1          ;get f1
       ENDIF
;
       IF      F2TAG
       lda     dfcb+2          ;get f2
       ENDIF
;
       rlc                     ;isolate fx'
       ani     1
       adi     'R'             ;make an R or S
       sta     donmsg+1
       lxi     d,donmsg
       mvi     c,pmessg        ;print completion message for this file
       call    bdos
       lda     filcnt          ;get file counter
       ani     3               ;multiple of 4?
       lxi     d,crlf
       mvi     c,9             ;if so, time for new line
       cz      bdos
       lxi     h,filcnt        ;point to file counter
       dcr     m               ;count it down
       jz      exit            ;exit if done
       jmp     tagfile         ;and go work on next one
donmsg:
       db      '  ',9,'$'
crlf:
       db      13,10,'$'
;
;
; subroutine to do block moves
blkmov:
       mov     a,m             ;copy byte from m(hl) to m(de)
       stax    d
       inx     h               ;bump pointers
       inx     d
       dcr     b               ;loop for count in b
       jnz     blkmov
       ret
;
;
; subroutine to index bc by file counter
filepoint:
       lhld    filcnt          ;get file counter
       mvi     h,0             ;force hi ord to 0
       dad     h               ;multiply by 32
       dad     h
       dad     h
       dad     h
       dad     h
       dad     b               ;use as index to file table
       ret
;
;
;
;
filcnt: ds      1               ;count of files in filetable
sropt:  ds      1               ;storage for S or R option letter
;
filetable       equ     $       ;start table here, take all avail memory
;
       end