home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol146 / vfiler11.a86 < prev    next >
Encoding:
Text File  |  1984-04-29  |  87.8 KB  |  3,914 lines

  1. ; DATE 10/10/83  11:21  last revision
  2. ;
  3. ; SIG/M release copy
  4. ;
  5. ; ENH@VID,HIDDEN,ON@OFF,CLOCK set to FALSE MDRIVE set to 0FF (no Mdrive)
  6. ;
  7.         TITLE    'VFILER CP/M-86 VER 1.1'
  8.  
  9. ; DATE  10/06/83  17:13
  10. ; by:H.M. Van Tassell 120 Hill Hollow Rd, Watchung NJ 07060 (201)755-5372
  11. ;
  12. ; This is a direct knock-off of Rich Conn's ZCPR2 utility VFILER ver 1.7
  13. ; Please see SIG/M vol 145 for the original release and author credits.
  14. ;
  15. ; The original program was translated to 8086 code using XLT86.
  16. ; The unique ZCPR2 features have been mostly removed. More than 1000
  17. ; lines of code were removed and/or changed to enable the translation.
  18. ; Some of the ZCPR2 code and all of the data storage area are intact.
  19. ;
  20. ; REVIEW! the equates, parameters, and routines at the start of the program.
  21. ;
  22. ; Additions to VFILER ver 1.7 in this CP/M-86 version include:
  23. ;     1. Enhanced video mode if your terminal has reverse, underline, and
  24. ;       dim modes,either hidden or non-hidden video attributes.
  25. ;          Terminal cursor on/off is also supported - stops screen flashing.
  26. ;    2. MDRIVE code was added to allow a gap in drive numbers.
  27. ;    3. Status request now only shows free space on disk
  28. ;    4. Command structure and names changed to suit my preferences.
  29. ;    5. New X command added to eXecute current CMD file.
  30. ;    6. CP/M-86 ver 1.1 supports chaining but not mult. commands so
  31. ;       you can run a CMD file but will not return to VFILER. The new
  32. ;         CP/M-86 Plus will support mult. commands-I'll do new version.
  33. ;    7. External HELP if you modify the HELP.HLP file to support VFILER
  34. ;       and set HLP@FIL equate true. Note VILERr will search along
  35. ;          the specified internal search path for HELP.CMD.
  36. ;    8. Printer output features:
  37. ;         a.  Quit allowed on ESC, Q ,or ^C key press
  38. ;         b.  Ask for paging and header options 
  39. ;         c.  Date in header, you must supply your clock read routine
  40. ;         d.  Dont allow Printing (Viewing) of CMD files.
  41. ;    9. Verify Destination Copy Erase option added to mass copy
  42. ;
  43. ;
  44. ; TO GENERATE PROGRAM
  45. ; ASM86 VFILER $SZPZ
  46. ; GENCMD VFILER 8080 CODE[M3FF,XF00]
  47. ;
  48. ; Memory allowed in GENCMD is in paragraphs. The XF00 allows program to use
  49. ; memory up to 0F000h if available at program startup.
  50. ;
  51. ; If you must limit memory, then dont use ',XF00' in GENCMD tail, the 3FF
  52. ; allows room for most any number of directory entrys and a smaller size
  53. ; copy buffer. Increase if not large enough for big hard disk directorys.
  54. ;
  55.  
  56. VERS    EQU    11            ;version number
  57.  
  58. ; starting definitions
  59.  
  60. M    EQU    Byte Ptr 0[BX]
  61.  
  62. TRUE    EQU    0FFFFH            ;define true and..
  63. FALSE    EQU    0            ;..false.
  64.  
  65. ENH@VID    EQU    FALSE            ;true for enhanced video
  66. HIDDEN    EQU    FALSE            ;true for hidden video attribites
  67. ON@OFF    EQU    FALSE            ;true for cursor on/off control
  68. HLP@FIL EQU    FALSE            ;true for external help file
  69. CLOCK    EQU    FALSE            ;true only if special rdtime routine
  70.  
  71. CPM@BASE EQU    000H            ;cp/m system base..
  72. TPA    EQU    100H            ;..'transient program area' start..
  73.  
  74. GET    EQU    0FFH            ;get user area e-reg value
  75. EPS    EQU    16*4            ;16 lines x 4 cols per screen
  76. ;  EPS = Entries Per Screen
  77.  
  78. ; cursor positioning as per the user's particular terminal
  79. ;   this is set for the ADM 31 arrow keys
  80. USER@UP    EQU    0BH            ;^K
  81. USER@DOWN EQU    0AH            ;^J
  82. USER@RIGHT EQU    0CH            ;^L
  83. USER@LEFT EQU    08H            ;^H
  84.  
  85. SCR@FOR    EQU    1AH            ;^Z to scroll forward
  86. SCR@BACK EQU    17H            ;^W
  87.  
  88. ; cursor positioning addresses
  89. EPSLINE    EQU    (EPS/4)+5        ;position of last line of EPS
  90. BANADR    EQU    1*256+24        ;banner address
  91. SDMADR    EQU    3*256+30        ;screen directory message
  92. CURHOME    EQU    4*256+1            ;home address of cursor
  93. BOTADR    EQU    23*256+1        ;bottom of screen
  94. CPMADR    EQU    EPSLINE*256+1        ;command prompt message
  95. CPADR    EQU    EPSLINE*256+30        ;command prompt
  96. ERADR    EQU    (EPSLINE+1)*256+30    ;error message
  97. FSADR    EQU    ERADR            ;file size message
  98. FNADR    EQU    (EPSLINE+1)*256+15    ;address of file name
  99.  
  100. ; ASCII definitions
  101. CTRLC    EQU    'C'-'@'            ;..control-C..
  102. CTRLD    EQU    'D'-'@'
  103. CTRLE    EQU    'E'-'@'
  104. CTRLR    EQU    'R'-'@'
  105. CTRLS    EQU    'S'-'@'            ;..XOFF..
  106. CTRLX    EQU    'X'-'@'
  107. BS    EQU    08H            ;..backspace..
  108. TAB    EQU    09H            ;..tab..
  109. LF    EQU    0AH            ;..linefeed..
  110. CR    EQU    0DH            ;..carriage return..
  111. CAN    EQU    18H            ;..cancel..
  112. EOFCHAR    EQU    1AH            ;..end-of-file..
  113. CTRLZ    EQU    1AH            ;..clear screen..
  114. ESC    EQU    1BH            ;..and escape character.
  115.  
  116. ; cp/m system functions
  117. RDCON    EQU    1            ;console input function
  118. WRCON    EQU    2            ;write character to console..
  119. PUNCH    EQU    4            ;..punch and..
  120. LLIST    EQU    5            ;..to list logical devices.
  121. DIRCON    EQU    6            ;direct console i/o
  122. RDBUF    EQU    10            ;read input string
  123. CONST    EQU    11            ;get console status
  124. RESETDK    EQU    13            ;reset disk system
  125. LOGIN    EQU    14            ;log-in new drive
  126. OPEN    EQU    15            ;open file
  127. CLOSE    EQU    16            ;close file
  128. SRCHF    EQU    17            ;search directory for first..
  129. SRCHN    EQU    18            ;..and next occurrence.
  130. ERASE    EQU    19            ;erase file
  131. READ    EQU    20            ;read and..
  132. WRITE    EQU    21            ;..write 128-record.
  133. MAKE    EQU    22            ;make file
  134. REN    EQU    23            ;rename file
  135. INQDISK    EQU    25            ;get current (default) drive
  136. SETDMA    EQU    26            ;set dma address
  137. INQALC    EQU    27            ;allocation vector
  138. ATTR    EQU    30            ;set file attributes
  139. GETPARM    EQU    31            ;current drive parameters address
  140. SGUSER    EQU    32            ;set or get user area
  141. COMPSZ    EQU    35            ; # of records in file
  142.  
  143. ; system addresses
  144. BDOS    EQU    CPM@BASE+05H        ;bdos function entry address
  145. FCB    EQU    CPM@BASE+5CH        ;default file control block
  146. FCBEXT    EQU    FCB+12            ;extent byte in 'fcb'
  147. FCBRNO    EQU    FCB+32            ;record number in 'fcb'
  148. FCB2    EQU    CPM@BASE+6CH        ;2nd FCB
  149. TBUF    EQU    CPM@BASE+80H        ;default cp/m buffer
  150.  
  151. ;
  152. ; assembly origin (load address) and program beginning
  153.     ORG    CPM@BASE+TPA
  154. SOURCE:
  155.     JMP    FILER
  156. L_A1    EQU    $
  157.     DSEG
  158.     ORG    Offset L_A1
  159. ;
  160. ;
  161. ;  INTERNAL PATH DATA            ;Used to find HELP.CMD
  162. ;
  163. ; DISK = 1 FOR A, '*' FOR CURRENT
  164. ; USER = NUMBER, '*' FOR CURRENT
  165. ;
  166. INTPATH    DB    1,0            ; DISK, USER FOR FIRST PATH ELEMENT
  167.     DB    1,'*'            ; DISK, USER FOR 2OD PATH ELEMENT
  168.     DB    2,'*'            ; ETC.
  169.     DB    0,0
  170.     DB    0,0            
  171.     DB    0            ; END OF PATH
  172. ;
  173. ;  DISK/USER LIMITS
  174. ;
  175. MDISK    RS    0
  176.     DB    2             ; MAXIMUM NUMBER OF DISKS
  177. MDRIVE    RS    0
  178.     DB    0FFH            ; MEM DRIVE, = 0FFH IF NONE
  179. MUSER    RS    0
  180.     DB    15            ; MAXIMUM USER NUMBER
  181. ;
  182. ;  CURRENT USER/DISK INDICATOR
  183. ;
  184. CINDIC    RS    0
  185.     DB    '*'            ; CP/M Plus notation for SEARCH PATH
  186. ;
  187. ;  DMA ADDRESS FOR DISK TRANSFERS
  188. ;
  189. DMADR    RS    0
  190.     DW    80H            ; TBUFF AREA
  191. ;
  192. ;
  193. LWIDTH    RS    0
  194.     DB    80            ; WIDTH OF LINE
  195. LTPP    RS    0
  196.     DB    59            ; LINES OF TEXT PER PAGE
  197. LSPP    RS    0
  198.     DB    5            ; LINES TO SKIP PER PAGE
  199. CWIDTH    RS    0
  200.     DB    80            ; WIDTH OF SCREEN
  201. CTPP    RS    0
  202.     DB    22            ; LINES OF TEXT PER SCREEN
  203. CSPP    RS    0
  204.     DB    1            ; LINES TO SKIP PER SCREEN
  205.  
  206. ;  END OF PARAMETER DATA
  207. ;
  208. ;******************************************************************
  209.  
  210.  
  211. L_A2    EQU    $
  212.     CSEG
  213.     ORG    Offset L_A2
  214. ;
  215. ;  Screen Routines
  216. ;
  217. ; screen routines (set for ADM-31 type terminals)
  218. ;  clear screen - must have routine
  219. CLS:
  220.     MOV    AL,ESC            ;clear screen
  221.     CALL    TTYPE
  222.     MOV    AL,'*'
  223.     JMP    TTYPE
  224.  
  225. ;  position cursor (H=row, L=col) where 0,0=upper left
  226. ;  must have routine
  227. GOTOXY:
  228.     MOV    AL,ESC            ;ESCape
  229.     CALL    TTYPE
  230.     MOV    AL,'='
  231.     CALL    TTYPE
  232.     MOV    AL,BH            ;row
  233.     ADD    AL,' '
  234.     CALL    TTYPE
  235.     MOV    AL,BL            ;column
  236.     ADD    AL,' '
  237.     JMP    TTYPE
  238.  
  239. ;  erase to end of line
  240. ;  must have routine
  241. EREOL:
  242.     MOV    AL,ESC            ;ESCape
  243.     CALL    TTYPE
  244.     MOV    AL,'T'
  245.     JMP    TTYPE
  246.  
  247. ;
  248. ; Next four routine are for terminals with enhanced video mode.
  249. ; The video attributes can be either hidden of take a space.
  250. ; Set ENH@VID and HIDDEN equates to suit.
  251. ;
  252.     IF    ENH@VID
  253. STD@VID:                ;Standard Video Mode
  254.     MOV    AL,ESC
  255.     CALL    TTYPE
  256.     MOV    AL,'G'
  257.     CALL    TTYPE
  258.     MOV    AL,'0'
  259.     JMP    TTYPE
  260. CUR@VID:                ;cursor Video mode
  261.     MOV    AL,ESC                  ;set mode for cursor display
  262.     CALL    TTYPE
  263.     MOV    AL,'G'
  264.     CALL    TTYPE
  265.     MOV    AL,'4'
  266.     JMP    TTYPE
  267. TAG@VID: RET    ;<<------ NOTE RET    ;tag Video mode -display tagged files
  268.     MOV    AL,ESC            ;    >>>> NOTE <<<<<
  269.     CALL    TTYPE            ;my terminal (WYSE) has a dim video 
  270.     MOV    AL,'G'            ;seq. ESC,G,p but that seems to be
  271.     CALL    TTYPE            ;special. So I put a RET for this
  272.     MOV    AL,'p'            ;routine, you need to fix if you want
  273.     JMP    TTYPE            ;tagged files to be in dim video
  274. STAT@VID:                ;Status line Video Mode
  275.     MOV    AL,ESC
  276.     CALL    TTYPE
  277.     MOV    AL,'G'
  278.     CALL    TTYPE
  279.     MOV    AL,'8'
  280.     JMP    TTYPE
  281.     ENDIF
  282.  
  283.     IF  NOT ENH@VID
  284.     STD@VID:
  285.     CUR@VID:
  286.     TAG@VID:
  287.     STAT@VID:
  288.     RET
  289.     ENDIF
  290.  
  291.     IF    ON@OFF            ;set true if terminal has on/off
  292. CUR@OFF:                ;WYSE-200 turn off cursor
  293.     MOV    AL,ESC
  294.     CALL    TTYPE
  295.     MOV    AL,'`'
  296.     CALL    TTYPE
  297.     MOV    AL,'0'
  298.     JMP    TTYPE
  299. CUR@ON:                    ;turn on cursor
  300.     MOV    AL,ESC
  301.     CALL    TTYPE
  302.     MOV    AL,'`'
  303.     CALL    TTYPE
  304.     MOV    AL,'1'
  305.     JMP    TTYPE
  306.     ENDIF    ;ON@OFF
  307.  
  308.     IF  NOT ON@OFF
  309.     CUR@OFF:
  310.     CUR@ON:    RET
  311.     ENDIF    ;NOT ON@OFF
  312.  
  313.  
  314. RDTIME:    ;PUT YOUR CLOCK ROUTINE HERE AND SET CLOCK EQUATE TRUE
  315.     IF    CLOCK            ;COMPUPRO CLOCK ROUTINE
  316. CLKCP    EQU    50H+10            ;CLOCK COMMAND PORT
  317.     MOV    BX,OFFSET DATESTR     ;POINT TO DATE STRING
  318.     MOV    SI,OFFSET DIGTAB     ;POINT TO DIGIT TABLE
  319.     MOV    CL,6            ;READ TWO COUNTER
  320. RTWO:    MOV    CH,2            ;READ ONE COUNTER
  321. ;
  322. ; READ A DIGIT FROM CLOCK CHIP
  323. ; ENTRY: SI => DIGIT TABLE DATA ENTRY
  324. ;        BX => STRING POSITION
  325. ; EXIT:  ASCII DIGIT LOADED IN STRING
  326. ;        SI & BX INCREMENTED
  327. ;
  328. RONE:    MOV    AL,[SI]        ;GET DIGIT TABLE DATA
  329.     INC    SI        ;BUMP TO NEXT ENTRY
  330.     ADD    AL,10H        ;SET READ BIT
  331.     OUT    CLKCP,AL    ;OUTPUT DIGIT DATA
  332.     CMP    AL,15H        ;CHECK FOR HOURS 10 DIGIT
  333.     IN    AL,CLKCP+1    ;READ BCD DIGIT FROM CLOCK
  334.     JNE    NOHOUR
  335.     SUB    AL,8
  336. NOHOUR:    ADD    AL,'0'        ;MAKE ASCII
  337.     MOV    [BX],AL
  338.     INC    BX        ;POINT TO NEXT STR POSITION
  339.     DEC    CH
  340.     JNZ    RONE        ;GET SECOND DIGIT
  341.     INC    BX        ;BUMP OVER SEPERATOR
  342.     CMP    CL,4
  343.     JNE    NOBUMP
  344.     INC    BX        ;BIG BUMP OVER WHITE SPACE
  345. NOBUMP:    DEC    CL
  346.     JNZ    RTWO        ;READ TWO MORE DIGITS
  347.     RET            ;RETURN TO CALLER
  348.  
  349. DIGTAB    DB    10,9,8,7,12,11,5,4,3,2,1,0 ;CLOCK DIGIT TABLE
  350.     ENDIF    ;CLOCK
  351.     RET
  352. ;
  353. ;  END OF TERMINAL DEPENDENT ROUTINES
  354. ;
  355. ;******************************************************************
  356.  
  357. ; start of program
  358. FILER:
  359.     MOV    AX,DS
  360.     MOV    SS,AX
  361.     MOV    SP,(Offset STACK)    ;start local stack
  362.     MOV    Word Ptr DATA_SEG,AX    ;save data segment
  363.     CALL    IDU            ;set initial disk/user
  364.     MOV    BX,(Offset BUFENTRY)    ;base address
  365.     MOV    Word Ptr RING,BX    ;beginning of ring
  366.     MOV    AL,Byte Ptr MDISK    ;get max disk number
  367.     ADD    AL,'A'-1
  368.     MOV    Byte Ptr MAXDR,AL    ;set letter
  369.     MOV    AL,Byte Ptr .FCB+1    ;check for initial help
  370.     CMP    AL,'/'
  371.     JE    FILERH
  372.     MOV    AL,Byte Ptr .FCB2+1    ;check for wait
  373.     CMP    AL,'W'
  374.     JNE    FILER0
  375.  
  376. FILERSAK:
  377.     CALL    ILPRT
  378.     DB    CR,LF,'Strike Any Key to Enter VFILER -- ',0
  379.     CALL    DKEYIN
  380.     JMPS    FILER0
  381. FILERH:
  382.     CALL    HELPMSG            ;print help message
  383. FILER0:
  384.     IF    HLP@FIL
  385.     CALL    HELPCHK            ;check for availability of HELP Files
  386.     ENDIF
  387.     JMPS    EMBARK
  388. ;  set initial disk/user
  389. IDU:
  390.     MOV    BX,FCB+1        ;check for DU specification
  391.     MOV    AL,M
  392.     CMP    AL,'/'            ;is there a help request?
  393.     JZ    IDU1
  394.     CMP    AL,' '            ;<SP>=none
  395.     JZ    IDU1
  396.     CALL    DEF@DU0            ;extrace drive/user
  397.     MOV    AL,CL            ;get current user
  398.     CALL    IDU@USET        ;set it
  399.     MOV    AL,CH            ;get current disk
  400.     CALL    IDU@DSET        ;set it
  401.     JMP    LOG1Z            ;log it in
  402. IDU1:
  403.     MOV    DL,GET            ;determine..
  404.     CALL    GET@USR            ;..user area then..
  405.     CALL    IDU@USET        ;set current user
  406.     MOV    CL,INQDISK        ;determine current disk
  407.     INT    224
  408.     CALL    IDU@DSET        ;set current disk
  409.     JMP    LOG1Z            ;set current user and disk
  410. IDU@USET:
  411.     MOV    Byte Ptr C@U@A,AL    ;..store as current and..
  412.     MOV    Byte Ptr O@USR,AL    ;..as original for exit.
  413.     MOV    Byte Ptr R@U@A,AL    ;..requested user area
  414.     RET
  415. IDU@DSET:
  416.     MOV    Byte Ptr C@DR,AL
  417.     MOV    Byte Ptr R@DR,AL    ;requested disk
  418.     RET
  419. ; check for availability of HELP Files (HELP.CMD)
  420. HELPCHK:
  421.     XOR    AL,AL            ;assume NO
  422.     MOV    Byte Ptr HELPFLG,AL    ;set flag
  423.     MOV    DX,(Offset HELPFCB)
  424.     CALL    FILECHK            ;check for file
  425.     OR    AL,AL            ;0=no
  426.     JNZ    L_A3
  427.     RET
  428. L_A3:
  429.     MOV    AL,0FFH            ;set flag
  430.     MOV    Byte Ptr HELPFLG,AL
  431.     MOV    AL,Byte Ptr Z@DR    ;Get disk from FFIND
  432.     ADD    AL,'A'            ;convert to ASCII
  433.     MOV    Byte Ptr MOREHELP,AL    ;put it in filename
  434.     RET
  435.  
  436. ; check for existance of file whose first 12 FCB bytes are pted to by DE
  437. ;   return with A=0 if not found, A=0FFH if found
  438. FILECHK:
  439.     MOV    BX,(Offset S@FCB)    ;copy into FCB
  440.     XCHG    BX,DX
  441.     MOV    CH,12            ;12 bytes
  442.     CALL    MOVE            ;copied into S$FCB
  443.     XCHG    BX,DX            ;HL pts to FCB
  444.     CALL    INITFCB            ;init FCB
  445.     MOV    DX,(Offset S@FCB)    ;pt to FCB
  446.     JMP    FFIND
  447. ; determine if specific file(s) requested -- show remaining storage
  448. EMBARK:
  449.     CALL    FRESTOR            ;get bytes remaining on drive (decode default)
  450.     MOV    BX,(Offset JOKER)    ;..treat as '*.*' with 'joker'..
  451.     MOV    DX,FCB+1        ;..loaded here.
  452.     MOV    CH,11            ; # of characters to move
  453.     CALL    MOVE            ;set field to *.*
  454. ; build 'ring' with filename positioned in default 'fcb' area
  455. PLUNGE:
  456.     MOV    CL,SETDMA        ;initialize dma address..
  457.     MOV    DX,TBUF            ;..to default buffer.
  458.     INT    224
  459.     XOR    AL,AL            ;clear search 'fcb'..
  460.     MOV    Byte Ptr .FCBEXT,AL    ;extent byte..
  461.     MOV    Byte Ptr .FCBRNO,AL    ;..and record number.
  462.     NOT    AL
  463.     MOV    Byte Ptr CANFLG,AL    ;make cancel flag true
  464.     MOV    DX,FCB            ;default 'fcb' for search..
  465.     MOV    CL,SRCHF        ;..of first occurrence.
  466.     INT    224
  467.     INC    AL            ; 0ffh --> 00h if no file found
  468.     JZ    L_A4    
  469.     JMP    SETRING            ;if found, branch and build ring.
  470. L_A4:
  471.     MOV    Byte Ptr CANFLG,AL    ;make log-cancel toggle false
  472.     CALL    ERMSG            ;else say none found, fall thru to log.
  473.     DB    'No File Found',0
  474. ; l o g
  475. ; select drive and user area (system reset for disk change on-the-fly)
  476. LOG:
  477.     CALL    CPRMPT            ;prompt to get drive/user selection
  478.     DB    'Login DIR: ',0
  479.     CALL    DEF@D@U
  480. LOG1:
  481.     CALL    LOG1Z            ;set current and log in
  482.     CALL    CRLF            ;new line
  483.     JMPS    EMBARK            ;..restart
  484. ;  set current user and disk
  485. LOG1X:
  486.     MOV    BX,(Offset LOG@DU@MSG)
  487.     MOV    AL,Byte Ptr R@DR    ;set prompt message
  488.     ADD    AL,'A'            ;adjust to letter
  489.     MOV    M,AL
  490.     INC    BX
  491.     MOV    M,' '            ;prep for user < 10
  492.     MOV    AL,Byte Ptr R@U@A    ;get user
  493.     CMP    AL,10            ;less than 10?
  494.     JB    LOG2
  495.     MOV    CH,'1'            ;set digits
  496. LOG1A:
  497.     SUB    AL,10            ;adjust user
  498.     CMP    AL,10            ;less?
  499.     JB    LOG1B
  500.     INC    CH            ;incr 10's
  501.     JMPS    LOG1A
  502. LOG1B:
  503.     MOV    M,CH            ;set 10's
  504. LOG2:
  505.     INC    BX            ;pt to 1's
  506.     ADD    AL,'0'            ;to ASCII
  507.     MOV    M,AL
  508.     RET
  509. ;  actually log into DU requested
  510. LOG1Y:
  511.     MOV    AL,Byte Ptr R@U@A    ;establish requested area..
  512.     MOV    Byte Ptr C@U@A,AL    ;..as current area.
  513.     CALL    SET@USR
  514.     CALL    RESET            ;reset disk system, make requested current.
  515.     MOV    BX,0            ;initialize tagged..
  516.     MOV    Word Ptr TAG@TOT,BX    ;..file size accumulator.
  517.     RET
  518. ;  set current DU and log into it
  519. LOG1Z:
  520.     CALL    LOG1X            ;set current
  521.     CALL    LOG1Y            ;actually log in
  522.     RET
  523. ; routine to define current drive and user area with full error trapping.
  524. ; (check validity of user area entry first, then drive validity, then proceed
  525. ; with implementation.)
  526. DEF@D@U:
  527.     MOV    BX,(Offset CMDBUF)+2
  528.     MOV    CH,20            ; # of blanks to..
  529.     CALL    FILL            ;..clear 'cmdbuf'.
  530.     MOV    DX,(Offset CMDBUF)    ;get DU selection from..
  531.     MOV    CL,RDBUF        ;..console buffer read.
  532.     INT    224
  533.     CALL    CONVERT            ;make sure alpha is upper case
  534.     MOV    BX,(Offset CMDBUF)+2    ;pt to possible drive
  535. DEF@DU0:
  536.     CALL    ZDNFIND        ;look for DU form and return DU
  537.     JZ    ERRET            ;error
  538.     MOV    AL,CH            ;return disk and user
  539.     MOV    Byte Ptr R@DR,AL
  540.     INC    AL            ;set FCB
  541.     MOV    Byte Ptr .FCB,AL
  542.     MOV    AL,CL
  543.     MOV    Byte Ptr R@U@A,AL
  544.     RET
  545. ; error return and recovery from command cancellation
  546. ERRET:
  547.     CALL    ERMSG
  548.     DB    'DIR Entry Error',0
  549.     JMP    NEUTRAL
  550. COMCAN:
  551.     MOV    SP,(Offset STACK)    ;reset stack..
  552.     MOV    AL,Byte Ptr CANFLG
  553.     OR    AL,AL            ;..from..
  554.     JNZ    L_A5    
  555.     JMP    PLUNGE
  556. L_A5:
  557.     CALL    REFRESH            ;refresh screen
  558.     JMP    LOOPFN            ;..error/command abort.
  559. ; find file along path (file FCB pted to by DE)
  560. ;   on return, A=0FFH if found, A=0 if not found, and flags set
  561. FFIND:
  562.     PUSH    DX            ;save ptr to FCB
  563.     MOV    DL,GET            ;get and save current DU
  564.     CALL    GET@USR
  565.     MOV    Byte Ptr C@U@A,AL
  566.     MOV    Byte Ptr Z@U@A,AL
  567.     MOV    CL,INQDISK
  568.     INT    224
  569.     MOV    Byte Ptr C@DR,AL
  570.     MOV    Byte Ptr Z@DR,AL
  571.     POP    DX            ;get ptr to FCB
  572.     MOV    BX,(Offset INTPATH)    ;internal path
  573. FFINDL:
  574.     CALL    SEARF            ;look for file
  575.     JNZ    FFOUND            ;found file
  576.     MOV    AL,Byte Ptr CINDIC    ;get current indictor
  577.     MOV    CL,AL            ;... in C
  578.     MOV    AL,M            ;get drive
  579.     OR    AL,AL            ;0=done=not found
  580.     JZ    FNFOUND
  581.     CMP    AL,CL            ;current disk?
  582.     JNZ    FF1
  583.     MOV    AL,Byte Ptr C@DR    ;get current disk
  584.     INC    AL            ;increment for following DCR
  585. FF1:
  586.     DEC    AL            ;adjust to 0 for A
  587.     MOV    CH,AL            ;disk in B
  588.     MOV    Byte Ptr Z@DR,AL    ;note disk
  589.     INC    BX            ;pt to user
  590.     MOV    AL,M            ;user in A
  591.     CMP    AL,CL            ;current?
  592.     JNZ    FF2
  593.     MOV    AL,Byte Ptr C@U@A    ;get current user
  594. FF2:
  595.     MOV    CL,AL            ;user in C
  596.     MOV    Byte Ptr Z@U@A,AL    ;note user
  597.     LAHF                ;pt to next entry
  598.     INC    BX
  599.     SAHF
  600.     CALL    SLOGIN            ;log in DU
  601.     JMPS    FFINDL
  602. FFOUND:
  603.     CALL    DLOGIN            ;log in default
  604.     MOV    AL,0FFH            ;set flag
  605.     OR    AL,AL
  606.     RET
  607. FNFOUND:
  608.     CALL    DLOGIN            ;log in default
  609.     XOR    AL,AL            ;set flag
  610.     RET
  611. ; search for file pted to by DE; don't affect DE or HL; ret code in A
  612. SEARF:
  613.     PUSH    BX            ;save regs
  614.     PUSH    DX
  615.     MOV    CL,SRCHF        ;search for file
  616.     INT    224
  617.     INC    AL            ;set flags
  618.     POP    DX            ;get regs
  619.     POP    BX
  620.     RET
  621. ; log in default directory
  622. DLOGIN:
  623.     MOV    AL,Byte Ptr C@DR    ;disk in B
  624.     MOV    CH,AL
  625.     MOV    AL,Byte Ptr C@U@A    ;user in C
  626.     MOV    CL,AL            ;fall thru to SLOGIN
  627. ; log in DU in BC
  628. SLOGIN:
  629.     PUSH    BX            ;save regs
  630.     PUSH    DX
  631.     PUSH    CX
  632.     MOV    AL,CL            ;set user
  633.     CALL    SET@USR
  634.     POP    CX
  635.     MOV    AL,CH            ;set disk
  636.     CALL    SET@DR
  637.     POP    DX            ;restore regs
  638.     POP    BX
  639.     RET
  640.  
  641. QUIT:
  642.     CALL    CPRMPT
  643.     DB    'Confirm Quitting (Y/N)? ',0
  644.     CALL    KEYIN
  645.     CMP    AL,'Y'
  646.     JE    CPM@CCP
  647.     JMP    NEUTRAL
  648.  
  649. ; e x i t
  650. ; return to cp/m ccp
  651. CPM@CCP:
  652.     MOV    AL,Byte Ptr O@USR    ;get and set original..
  653.     CALL    SET@USR            ;..user area and..
  654.     MOV    DX,TBUF            ;..tidy up..
  655.     MOV    CL,SETDMA        ;..before going home.
  656.     INT    224
  657.     CALL    CLS
  658.     MOV    CL,0
  659.     MOV    DL,0
  660.     INT    224
  661. ;warmboot
  662. ; establish ring (circular list) of filenames
  663. SETRING:
  664.     MOV    BX,Word Ptr RING    ;initialize ring pointer
  665.     MOV    Word Ptr RINGPOS,BX    ;start --> current position of ring
  666. ; put each found name in ring.  a-reg --> offset into 'tbuf' name storage
  667. TO@RING:
  668.     DEC    AL            ;un-do 'inr' from above and below
  669.     ADD    AL,AL            ;times 32 --> position index
  670.     ADD    AL,AL
  671.     ADD    AL,AL
  672.     ADD    AL,AL
  673.     ADD    AL,AL
  674.     ADD    AL,TBUF            ;add page offset and..
  675.     MOV    BL,AL            ;..put address into..
  676.     MOV    BH,0            ;..hl-pair.
  677.     MOV    AL,Byte Ptr .FCB    ;get drive/user designator and..
  678.     MOV    M,AL            ;..put into 'fcb' buffer.
  679.     XCHG    BX,DX
  680.     MOV    BX,Word Ptr RINGPOS    ;pointer to current load point in ring
  681.     XCHG    BX,DX
  682.     MOV    CH,12            ;move drive designator and name to ring
  683.     CALL    MOVE
  684.     XCHG    BX,DX            ;de-pair contains next load point address
  685.     MOV    M,' '            ;space for potential..
  686.     LAHF                ;..tagging of files for mass copy.
  687.     INC    BX
  688.     SAHF
  689.     MOV    Word Ptr RINGPOS,BX    ;store and search..
  690.     MOV    CL,SRCHN        ;..for next occurrence.
  691.     MOV    DX,FCB            ;filename address field
  692.     INT    224
  693.     INC    AL            ;if all done, 0ffh --> 00h.
  694.     JNZ    TO@RING            ;if not, put next name into ring.
  695. ; all filenames in ring -- setup ring size and copy-buffer start point
  696.     MOV    BX,Word Ptr RINGPOS    ;next load point of ring is start of buffer
  697.     MOV    Word Ptr RINGEND,BX    ;set ring end..
  698.     MOV    Word Ptr BUFSTART,BX    ;..and copy-buffer start.
  699.     PUSH    BX
  700.     MOV    BX,Word Ptr RING
  701.     MOV    DX,13            ;compare 'ringend' (tab base+13)
  702.     LAHF
  703.     ADD    BX,DX
  704.     RCR    SI,1
  705.     SAHF
  706.     RCL    SI,1
  707.     XCHG    BX,DX
  708.     POP    BX
  709.     CALL    CMPDEHL
  710.     JNZ    L_A6    
  711.     JMP    CMDLOOP            ;go to command loop, if no sort.
  712. L_A6:
  713. ; sort ring of filenames
  714. SORT:
  715.     MOV    BX,Word Ptr RING    ;initialize 'i' sort variable and..
  716.     MOV    Word Ptr RINGI,BX
  717.     MOV    DX,13            ;..also 'j' variable.
  718.     ADD    BX,DX
  719.     MOV    Word Ptr RINGJ,BX
  720. SORTLP:
  721.     MOV    BX,Word Ptr RINGJ    ;compare names 'i & j'
  722.     XCHG    BX,DX
  723.     MOV    BX,Word Ptr RINGI
  724.     PUSH    BX            ;save position pointers..
  725.     PUSH    DX            ;..for potential swap.
  726.     MOV    CH,13            ; # of characters to compare
  727. ; left to right compare of two strings (de-pair points to 'a' string;
  728. ; hl-pair, to 'b'; b-reg contains string length.)
  729. CMPSTR:
  730.     MOV    SI,DX            ;get an 'a' string character and..
  731.     MOV    AL,[SI]
  732.     CMP    AL,M            ;..check against 'b' string character.
  733.     JNZ    NOCMP            ;if not equal, set flag.
  734.     INC    BX            ;bump compare..
  735.     INC    DX            ;..pointers and..
  736.     DEC    CH            ; (if compare, set as equal.)
  737.     JNZ    CMPSTR            ;..do next character.
  738. NOCMP:
  739.     POP    DX
  740.     POP    BX
  741.     MOV    CH,13
  742.     JNB    NOSWAP
  743. ; swap if 'j' string larger than 'i'
  744. SWAP:
  745.     MOV    CL,M            ;get character from one string..
  746.     MOV    SI,DX            ;..and one from other string.
  747.     MOV    AL,[SI]
  748.     MOV    M,AL            ;second into first
  749.     MOV    AL,CL            ;first into second
  750.     MOV    SI,DX
  751.     MOV    [SI],AL
  752.     INC    BX            ;bump swap pointers
  753.     INC    DX
  754.     DEC    CH
  755.     JNZ    SWAP
  756. NOSWAP:
  757.     MOV    BX,Word Ptr RINGJ    ;increment 'j' pointer
  758.     MOV    DX,13
  759.     LAHF
  760.     ADD    BX,DX
  761.     SAHF
  762.     MOV    Word Ptr RINGJ,BX
  763.     XCHG    BX,DX            ;see if end of 'j' loop
  764.     MOV    BX,Word Ptr RINGEND
  765.     CALL    CMPDEHL
  766.     JNZ    SORTLP            ;no, so more 'j' looping.
  767.     MOV    BX,Word Ptr RINGI    ;bump 'i' pointer
  768.     MOV    DX,13
  769.     LAHF
  770.     ADD    BX,DX
  771.     SAHF
  772.     MOV    Word Ptr RINGI,BX
  773.     LAHF                ;set start over 'j' pointer
  774.     ADD    BX,DX
  775.     SAHF
  776.     MOV    Word Ptr RINGJ,BX
  777.     XCHG    BX,DX            ;see if end of 'i' loop
  778.     MOV    BX,Word Ptr RINGEND
  779.     CALL    CMPDEHL
  780.     JZ    L_A7    
  781.     JMP    SORTLP            ;must be more 'i' loop to do
  782. L_A7:
  783. ; sort done -- initialize tables for fast crc calculations
  784.     CALL    INITCRC
  785. ; calculate buffer maximum available record capacity
  786. B@SIZE:
  787.     MOV    CX,0            ;count records
  788.     MOV    BX,Word Ptr .BDOS+1    ;get mem. allow from page one
  789.     DEC    BX
  790.     XCHG    BX,DX            ;de-pair --> highest address of buffer
  791.     MOV    BX,Word Ptr BUFSTART    ;start address of buffer (end of ring list)
  792. B@SIZE2:
  793.     INC    CX            ;increase record count by one
  794.     PUSH    DX
  795.     MOV    DX,128            ; 128-byte record
  796.     ADD    BX,DX            ;buffer address + record size
  797.     POP    DX
  798.     CALL    CMPDEHL            ;compare for all done
  799.     JNB    B@SIZE2            ;more will fit?
  800.     DEC    CX            ;set maximum record count less one
  801.     MOV    AL,CH            ;memory available for copy?
  802.     OR    AL,CL
  803.     JNZ    B@SIZE3            ;yes, buffer memory space available.
  804.     CALL    ERMSG
  805.     DB    'No Memory for Copy Buffer',0
  806.     JMP    NEUTRAL
  807. B@SIZE3:
  808.     MOV    BL,CL            ;store..
  809.     MOV    BH,CH            ;..maximum..
  810.     MOV    Word Ptr REC@MAX,BX    ;..record count.
  811.     JMP    CMDLOOP
  812.  
  813. ; buffer size suitable -- process file/display loop
  814. LOOPFN:
  815.     MOV    BX,FNADR        ;position cursor for file name print
  816.     IF    (ENH@VID AND (NOT HIDDEN))
  817.     DEC    BX            ;allow video attribute space
  818.     ENDIF
  819.     CALL    GOTOXY
  820.     MOV    BX,Word Ptr RINGPOS    ;pt to current file name
  821.     LAHF                ;pt to first char
  822.     INC    BX
  823.     SAHF
  824.     CALL    STAT@VID
  825.     CALL    PRFN            ;print file name
  826.     CALL    STD@VID
  827. LOOP:
  828.     CALL    ATCMD            ;position at command prompt
  829.     CALL    DKEYIN            ;wait for character from keyboard
  830.     LAHF                ;save command
  831.     XCHG    AL,AH
  832.     PUSH    AX
  833.     MOV    AL,Byte Ptr ERMFLG    ;error message?
  834.     OR    AL,AL            ;0=no
  835.     JZ    CPROC
  836.     CALL    ERCLR            ;erase old error message
  837. CPROC:
  838.     POP    AX            ;get command
  839.     XCHG    AL,AH
  840.     SAHF
  841.     CALL    CTPROC            ;process command or return if not found
  842.     CALL    ERMSG
  843.     DB    'Invalid Command: ',0
  844.     MOV    AL,CH            ;get char
  845.     CMP    AL,' '            ;expand if less than space
  846.     JNB    CPROC1
  847.     MOV    AL,'^'            ;control
  848.     CALL    TTYPE
  849.     MOV    AL,CH            ;get byte
  850.     ADD    AL,'@'            ;convert to letter
  851. CPROC1:
  852.     CALL    TTYPE
  853. NEUTRAL:
  854.     JMPS    LOOP            ;..position.
  855. ; process command from table
  856. CTPROC:
  857.     MOV    BX,(Offset CTABLE)    ;pt to table
  858.     MOV    CH,AL            ;command in B
  859. CTPR1:
  860.     MOV    AL,M            ;get table command char
  861.     OR    AL,AL            ;end of table?
  862.     JNZ    L_A8    
  863.     RET                ;done if so
  864. L_A8:
  865.     CMP    AL,CH            ;match?
  866.     JZ    CTPR2
  867.     INC    BX            ;skip to next entry
  868.     INC    BX
  869.     INC    BX
  870.     JMPS    CTPR1
  871. CTPR2:
  872.     LAHF                ;pt to address
  873.     INC    BX
  874.     SAHF
  875.     MOV    AL,M            ;get low
  876.     LAHF
  877.     INC    BX
  878.     SAHF
  879.     MOV    BH,M            ;get high
  880.     MOV    BL,AL
  881.     MOV    BP,SP            ;address on stack
  882.     XCHG    BX,[BP]
  883.     RET                ;"jump" to routine
  884. L_A9    EQU    $
  885.     DSEG
  886.     ORG    Offset L_A9
  887. ; Command Table
  888. CTABLE    DB    USER@UP            ;user cursor positioning
  889.     DW    (Offset UP)
  890.     DB    USER@DOWN
  891.     DW    (Offset DOWN)
  892.     DB    USER@RIGHT
  893.     DW    (Offset FORWARD)
  894.     DB    USER@LEFT
  895.     DW    (Offset REVERSE)
  896.     DB    SCR@FOR
  897.     DW    (Offset JUMPF)
  898.     DB    SCR@BACK
  899.     DW    (Offset JUMPB)
  900.     DB    CTRLE            ;system cursor positioning
  901.     DW    (Offset UP)
  902.     DB    CTRLX
  903.     DW    (Offset DOWN)
  904.     DB    CTRLD
  905.     DW    (Offset FORWARD)
  906.     DB    CTRLS
  907.     DW    (Offset REVERSE)
  908.     DB    '+'            ;jump forward
  909.     DW    (Offset JUMPF)
  910.     DB    '-'            ;jump backward
  911.     DW    (Offset JUMPB)
  912.     DB    ' '            ;go forward
  913.     DW    (Offset FORWARD)
  914.     DB    '.'            ;go forward
  915.     DW    (Offset FORWARD)
  916.     DB    '>'            ;go forward
  917.     DW    (Offset FORWARD)
  918.     DB    ','            ;back up?
  919.     DW    (Offset REVERSE)
  920.     DB    '<'            ;back up?
  921.     DW    (Offset REVERSE)
  922.     DB    'C'            ;copy a file?
  923.     DW    (Offset COPY)
  924.     DB    'D'            ;delete a file?
  925.     DW    (Offset DELETE)
  926.     DB    'E'            ;enter a command?
  927.     DW    (Offset RUN@CMD)
  928.     DB    'F'            ;show file size?
  929.     DW    (Offset FIL@SIZ)
  930.     DB    'G'            ;goto a file?
  931.     DW    (Offset GOTO)
  932.     DB    'H'            ;external help?
  933.     DW    (Offset EXTHELP)
  934.     DB    'L'            ;log-in another drive?
  935.     DW    (Offset LOG)
  936.     DB    'M'            ;tagged multiple file copy?
  937.     DW    (Offset MASS@COPY)
  938.     DB    'N'            ;new screen
  939.     DW    (Offset SCREFRESH)
  940.     DB    'P'            ;output file to 'list' device?
  941.     DW    (Offset LSTFILE)
  942.     DB    'Q'            ;quit
  943.     DW    (Offset QUIT)
  944.     DB    'R'            ;if rename, get to work.
  945.     DW    (Offset RENAME)
  946.     DB    'S'            ;free bytes on..
  947.     DW    (Offset R@DR@ST)    ;..requested drive?
  948.     DB    'T'            ;if tag, put '*' in..
  949.     DW    (Offset TAG@EM)        ;..front of cursor.
  950.     DB    'U'            ;remove '*' from..
  951.     DW    (Offset UNTAG)        ;..in front of cursor?
  952.     DB    'W'            ;mass tag/untag?
  953.     DW    (Offset MASS@TU)
  954.     DB    'V'            ; 'view' file at console?
  955.     DW    (Offset VIEW)
  956.     DB    'X'            ;execute command file
  957.     DW    (Offset XQT@CMD)
  958.     DB    'Y'            ;mass delete?
  959.     DW    (Offset MASS@DEL)
  960.     DB    ESC            ; 'esc' quits to cp/m ccp also.
  961.     DW    (Offset QUIT)
  962.     DB    '?'            ;help
  963.     DW    (Offset HELP)
  964.     DB    '/'            ;help also
  965.     DW    (Offset HELP)
  966.     DB    0            ;end of table
  967. L_A10    EQU    $
  968.     CSEG
  969.     ORG    Offset L_A10
  970. ; h e l p  (menu)
  971. HELP:
  972.     CALL    HELPMSG            ;print message
  973.     CALL    REFRESH            ;refresh screen
  974.     JMP    LOOPFN
  975. HELPMSG:
  976.     CALL    CLS
  977.     CALL    ILPRT
  978.     DB    '-- VFILER '
  979.     DB    VERS/10+'0','.',VERS MOD 10+'0'
  980.     DB    ': CPM-86 File Manipulation Program -- '
  981.     DB    CR,LF,CR,LF
  982.     DB    '-- Tagging Commands --      -- File Operations --',CR,LF
  983.     DB    '    T - Tag File              C - Copy File',CR,LF
  984.     DB    '    U - Untag File            D - Delete File',CR,LF
  985.     DB    '    W - Mass Tag/Untag        F - File Size',CR,LF
  986.     DB    '                              M - Mass Copy',CR,LF
  987.     DB    '-- File Print & View --       R - Rename File',CR,LF
  988.     DB    'P - Print      V - View       Y - Mass Delete',CR,LF
  989.     DB    CR,LF
  990.     DB    '-- Movement Commands --     -- Miscellaneous --',CR,LF
  991.     IF    HLP@FIL
  992.     DB    '    <SP> - File Forward       H - Detailed HELP',CR,LF
  993.     ENDIF
  994.     IF  NOT HLP@FIL
  995.     DB    '    <SP> - File Forward       / - This Summary',CR,LF
  996.     ENDIF
  997.  
  998.     DB    '     >   - File Forward       E - Enter Command',CR,LF
  999.     DB    '    <BS> - File Backward      L - Login DIR',CR,LF
  1000.     DB    '     <   - File Backward      N - reNew Screen',CR,LF
  1001.     DB    '     G   - Go To a File       S - Status of Disk',CR,LF
  1002.     DB    '     +   - Screen Forward     Q - Quit VFILER',CR,LF
  1003.     DB    '     -   - Screen Backward    X - eXecute CMD file',CR,LF
  1004.     DB    CR,LF
  1005.     DB    '                -- Screen Movement --',CR,LF
  1006.     DB    'File:    ^S - LEFT   ^D - RIGHT   ^E - UP   ^X - DOWN',CR,LF
  1007.     DB    'Screen:  ^W - LEFT   ^Z - RIGHT',CR,LF
  1008.     DB    0
  1009.     CALL    BOTTOM
  1010.     RET
  1011.  
  1012. EXTHELP:
  1013.     TEST    HELPFLG,TRUE
  1014.     JZ    EHLP1            ;jmp if further help not avail
  1015.     CALL    CLS
  1016.     CALL    ILPRT
  1017.     DB    'Running External HELP ....',0
  1018.     MOV    SI,OFFSET MOREHELP    ;run HELP command
  1019.     MOV    DI,TBUF
  1020.     MOV    CX,13
  1021.     CALL    CHAIN
  1022.     JMP    LOOPFN
  1023.  
  1024. EHLP1:
  1025.     CALL    ERMSG
  1026.     DB    'External HELP Facility Not Available',0
  1027.     JMP    LOOPFN
  1028.  
  1029. ; refresh screen
  1030. SCREFRESH:
  1031.     CALL    REFRESH            ;do it
  1032.     JMP    LOOPFN            ;reprint name
  1033.  
  1034. CHK@CMD:                ;check if CMD file
  1035. ;    ENTRY:     file in RINGPOS
  1036. ;    EXIT:    zero set if CMD type
  1037. ;
  1038.     PUSH    BX
  1039.     MOV    BX,Word Ptr RINGPOS    ;get addr file location
  1040.     ADD    BX,9            ;point to file type
  1041.     CMP    Byte Ptr[BX],'C'    ;test for CMD
  1042.     JNE    CC_RET
  1043.     INC    BX
  1044.     CMP    Byte Ptr[BX],'M'
  1045.     JNE    CC_RET
  1046.     INC    BX
  1047.     CMP    Byte Ptr[BX],'D'
  1048. CC_RET:    POP    BX
  1049.     RET                ;zero set if CMD type
  1050.  
  1051. XQT@CMD:
  1052.     CALL    CPRMPT
  1053.     DB    'Execute Current CMD File (Y/N)? ',0
  1054.     CALL    KEYIN
  1055.     CMP    AL,'Y'
  1056.     JE    XQT1
  1057.     JMP    NEUTRAL
  1058. XQT1:
  1059.     CALL    CHK@CMD            ;check if CMD filetype
  1060.     JZ    XQT2            ;give error if not
  1061.     CALL    ERMSG
  1062.     DB    'Only CMD type files can be executed',0
  1063.     JMP    LOOPFN
  1064.  
  1065. XQT2:    CALL    CLS
  1066.     MOV    DI,TBUF            ;put CMD in default DMA buffer
  1067.     MOV    SI,Word Ptr RINGPOS    ;get position in ring
  1068.     MOV    AL,[SI]            ;get drive number
  1069.     ADD    AL,'A'-1        ;make into letter
  1070.     MOV    Byte Ptr[DI],AL        ;move it
  1071.     INC    SI ! INC DI        ;SI -> filename
  1072.     MOV    Byte Ptr[DI],':'    
  1073.     INC    DI            ;DI -> TBUF+2
  1074.     MOV    CX,8            ;bytes in filename
  1075.     JMP    CHAIN
  1076.  
  1077. RUN@CMD:
  1078.     CALL    ERMSG
  1079.     DB    'Enter Command? ',0
  1080.     MOV    BX,OFFSET CRCTBL+256    ;use last half of CRC table
  1081.     MOV    M,102            ;allow 100 length of line
  1082.     INC    BX
  1083.     MOV    M,0            ;store count
  1084.     MOV    DX,OFFSET CRCTBL+256
  1085.     PUSH    DX
  1086.     MOV    CL,RDBUF
  1087.     INT    224
  1088.     POP    BX            ;BX -> beginning of buffer
  1089.     INC    BX            ;point to char count
  1090.     MOV    CL,M            ;put in CL
  1091.     INC    BX            ;point to first char
  1092.     MOV    CH,0            ;CX = char count
  1093.     PUSH    BX            ;save current ptr for later
  1094.     ADD    BX,CX
  1095.     MOV    M,0            ;store ending zero
  1096.     POP    BX            ;point to first char
  1097.     CMP    Byte Ptr[BX],0        ;abort if no first char
  1098.     JZ    NO_CMD
  1099.     MOV    SI,BX            ;SI -> Command
  1100.     MOV    DI,TBUF            
  1101.     CALL    UC_CMD            ;make sure its upper CASE
  1102.     CALL    CLS
  1103.     JMP    RUN_CMD1
  1104. NO_CMD:    JMP    NEUTRAL            
  1105. RUN_CMD1:
  1106.     CALL    CHAIN
  1107.     JMP    LOOPFN
  1108.  
  1109. CHAIN:
  1110. ;    ENTRY:    SI -> buffer containing command
  1111. ;        DI -> dest of command
  1112. ;        CX =  length of command
  1113.  
  1114.     MOV    AX,Word Ptr DATA_SEG
  1115.     MOV    ES,AX
  1116.  
  1117.     CLD                ;set forward direction
  1118.     REP    MOVSB            ;move it
  1119.     MOV    ES:Byte Ptr [DI],0    ;end with a zero
  1120.  
  1121.     MOV    CL,47            ;Chain function
  1122.     MOV    DX,0FFFFH        ;chain flag
  1123.     INT    224
  1124.  
  1125.     CALL    SCREFRESH
  1126.     RET
  1127.  
  1128. UC_CMD:    ;make string ending in 0h upper case
  1129. ;    ENTRY:    BX -> string
  1130. ;
  1131.  
  1132. UC_LOOP:
  1133.     CMP    Byte Ptr[BX],0
  1134.     JZ    UC_RET            ;quit if zero
  1135.     CMP     Byte Ptr[BX],61h
  1136.     JB    UC_OK            ;skip unless lower case
  1137.     AND    Byte Ptr[BX],5FH    ;make uppercase
  1138. UC_OK:    INC    BX            ;point to next char
  1139.     JMP    UC_LOOP            ;and process it
  1140. UC_RET:
  1141.     RET
  1142.  
  1143. ; mass tag or untag
  1144. MASS@TU:
  1145.     MOV    AL,TRUE            ;update file totals
  1146.     MOV    Byte Ptr FS@FLG,AL    ;of tagged/untagged files
  1147.     CALL    CPRMPT
  1148.     DB    'Mass Tag or Untag (T/U)? ',0
  1149.     CALL    KEYIN            ;get response
  1150.     CMP    AL,'T'
  1151.     JZ    MASS@TAG
  1152.     CMP    AL,'U'
  1153.     JZ    L_A11    
  1154.     JMP    NEUTRAL            ;fall thru to MASS$UNTAG
  1155. L_A11:
  1156. ; mass   u n t a g
  1157. MASS@UNTAG:
  1158.     XOR    AL,AL            ;set tag/untag..
  1159.     MOV    Byte Ptr T@UN@FG,AL    ;..flag to untag
  1160.     MOV    Byte Ptr FSDFLG,AL    ;no file size display
  1161.     CALL    WORKMSG
  1162. MUTLOOP:
  1163.     MOV    BX,Word Ptr RINGPOS    ;move to tag
  1164.     MOV    DX,12
  1165.     ADD    BX,DX
  1166.     MOV    AL,M            ;get tag
  1167.     CMP    AL,'*'            ;check for tag
  1168.     MOV    M,' '            ;clear tag
  1169.     JNZ    L_A12    
  1170.     CALL    FSIZ            ;adjust sizes
  1171. L_A12:
  1172.     MOV    BX,Word Ptr RINGPOS    ;advance to next
  1173.     MOV    DX,13
  1174.     LAHF
  1175.     ADD    BX,DX
  1176.     SAHF
  1177.     MOV    Word Ptr RINGPOS,BX
  1178.     XCHG    BX,DX            ;done?
  1179.     MOV    BX,Word Ptr LOCEND
  1180.     CALL    CMPDEHL
  1181.     JNZ    MUTLOOP
  1182.     MOV    BX,CURHOME        ;reset cursor
  1183.     MOV    Word Ptr CURAT,BX
  1184.     MOV    BX,Word Ptr LOCBEG    ;set ring position
  1185.     JMP    JFW0
  1186. ; mass   t a g
  1187. MASS@TAG:
  1188.     XOR    AL,AL
  1189.     MOV    Byte Ptr FSDFLG,AL    ;no file size display
  1190.     MOV    AL,TRUE            ;set tag/untag..
  1191.     MOV    Byte Ptr T@UN@FG,AL    ;..flag to untag
  1192.     CALL    WORKMSG
  1193. MTLOOP:
  1194.     MOV    BX,Word Ptr RINGPOS    ;move to tag
  1195.     MOV    DX,12
  1196.     ADD    BX,DX
  1197.     MOV    AL,M            ;get tag
  1198.     CMP    AL,'*'            ;check for tag
  1199.     MOV    M,'*'            ;clear tag
  1200.     JZ    L_A13    
  1201.     CALL    FSIZ            ;adjust sizes
  1202. L_A13:
  1203.     MOV    BX,Word Ptr RINGPOS    ;advance to next
  1204.     MOV    DX,13
  1205.     LAHF
  1206.     ADD    BX,DX
  1207.     SAHF
  1208.     MOV    Word Ptr RINGPOS,BX
  1209.     XCHG    BX,DX            ;done?
  1210.     MOV    BX,Word Ptr LOCEND
  1211.     CALL    CMPDEHL
  1212.     JNZ    MTLOOP
  1213.     MOV    BX,CURHOME        ;reset cursor
  1214.     MOV    Word Ptr CURAT,BX
  1215.     MOV    BX,Word Ptr LOCBEG    ;set ring position
  1216.     JMP    JFW0
  1217. ; u n t a g
  1218. UNTAG:
  1219.     XOR    AL,AL            ;set tag/untag..
  1220.     MOV    Byte Ptr T@UN@FG,AL    ;..flag to untag.
  1221.     NOT    AL
  1222.     MOV    Byte Ptr FS@FLG,AL    ;set flag to compute file size
  1223.     MOV    BX,Word Ptr RINGPOS    ;move back one..
  1224.     MOV    DX,12            ;..character position..
  1225.     ADD    BX,DX            ;..and check tagging status.
  1226.     MOV    AL,M            ;if file previously tagged, remove..
  1227.     CMP    AL,'*'            ;..size from..
  1228.     LAHF                ;save flag
  1229.     XCHG    AL,AH
  1230.     PUSH    AX
  1231.     MOV    M,' '            ; (untag character, to next ring position.)
  1232.     CALL    REFFN            ;refresh file name
  1233.     POP    AX            ;get flag
  1234.     XCHG    AL,AH
  1235.     SAHF
  1236.     JZ    FS2            ;..summation.
  1237.     JMP    FORWARD
  1238. ; t a g
  1239. TAG@EM:
  1240.     MOV    AL,TRUE            ;set..
  1241.     MOV    Byte Ptr T@UN@FG,AL    ;..tag/untag and..
  1242.     MOV    Byte Ptr FS@FLG,AL    ;..file size flags to tag.
  1243.     MOV    BX,Word Ptr RINGPOS
  1244.     MOV    DX,12            ;move back one..
  1245.     ADD    BX,DX            ;..position..
  1246.     MOV    AL,M            ; (if file
  1247.     CMP    AL,'*'            ; already tagged, skip
  1248.     JNZ    L_A14    
  1249.     JMP    FORWARD            ; to next file.)
  1250. L_A14:
  1251.     MOV    M,'*'            ;..and store a '*' tag character.
  1252.     CALL    REFFN            ;refresh file name
  1253.     JMPS    FS2            ;get file size
  1254. ; refresh file name with new tag
  1255. REFFN:
  1256.  
  1257.     MOV    BX,Word Ptr CURAT    ;clear cursor
  1258.     IF    ENH@VID
  1259.     ADD    BX,4            ;advance 4 spaces
  1260.     CALL    GOTOXY
  1261.     ENDIF
  1262.     IF  NOT  ENH@VID
  1263.     CALL    GOTOXY
  1264.     CALL    ILPRT
  1265.     DB    '    ',0        ;clear cursor
  1266.     ENDIF
  1267.     
  1268.     MOV    BX,Word Ptr RINGPOS    ;reprint file name
  1269.     INC    BX
  1270.     CALL    NC@PRFN            ;print file name
  1271.     RET
  1272.  
  1273. ; f i l e   s i z e
  1274. ; determine and display file size in kilobytes -- round up to next disk
  1275. ; allocation block -- accumulate tagged file summation
  1276. FIL@SIZ:
  1277.     XOR    AL,AL            ;set file size/tagged..
  1278.     MOV    Byte Ptr FS@FLG,AL    ;..file flag to file size.
  1279.     NOT    AL
  1280.     MOV    Byte Ptr FSDFLG,AL    ;display file size
  1281.     CALL    FSIZ            ;compute and print file size
  1282.     JMP    LOOPFN
  1283. FS2:
  1284.     MOV    AL,TRUE
  1285.     MOV    Byte Ptr FSDFLG,AL    ;display file size
  1286.     CALL    FSIZ            ;compute and print file size
  1287.     JMP    FORWARD
  1288. ;  print file size
  1289. FSIZ:
  1290.     MOV    AL,Byte Ptr FSDFLG    ;display file size?
  1291.     OR    AL,AL            ;0=no
  1292.     JZ    L_A15    
  1293.     CALL    FSNOTE
  1294. L_A15:
  1295.     CALL    RINGFCB            ;move name to 's$fcb'
  1296. ; determine file record count and save in 'rcnt'
  1297.     MOV    CL,COMPSZ
  1298.     MOV    DX,(Offset S@FCB)
  1299.     INT    224
  1300.     MOV    BX,Word Ptr S@FCB+33
  1301.     MOV    Word Ptr RCNT,BX    ;save record count and..
  1302.     MOV    BX,0
  1303.     MOV    Word Ptr S@FCB+33,BX    ;..reset cp/m.
  1304. ; round up to next disk allocation block
  1305.     MOV    AL,Byte Ptr B@MASK    ;sectors/block - 1
  1306.     LAHF                ;save 'blm'
  1307.     XCHG    AL,AH
  1308.     PUSH    AX
  1309.     XCHG    AL,AH
  1310.     MOV    BL,AL
  1311.     XCHG    BX,DX
  1312.     MOV    BX,Word Ptr RCNT    ;..use here.
  1313.     LAHF                ;round up to next block
  1314.     ADD    BX,DX
  1315.     RCR    SI,1
  1316.     SAHF
  1317.     RCL    SI,1
  1318.     MOV    CH,3+1            ;convert from..
  1319.     CALL    SHIFTLP            ;..records to kilobytes.
  1320.     POP    AX            ;retrieve 'blm'
  1321.     XCHG    AL,AH
  1322.     ROR    AL,1            ;convert..
  1323.     ROR    AL,1            ;..to..
  1324.     ROR    AL,1            ;..kilobytes/block.
  1325.     AND    AL,1FH
  1326.     NOT    AL            ;finish rounding
  1327.     AND    AL,BL
  1328.     MOV    BL,AL            ;hl-pair contains # of kilobytes
  1329.     MOV    AL,Byte Ptr FS@FLG
  1330.     OR    AL,AL
  1331.     JZ    D@F@SIZ            ;branch if 'f' function
  1332. ; tagged file size summation
  1333.     XCHG    BX,DX            ;file size to de-pair
  1334.     MOV    AL,Byte Ptr T@UN@FG
  1335.     OR    AL,AL
  1336.     JZ    TAKE            ;if untag, take size from total.
  1337.     MOV    BX,Word Ptr TAG@TOT    ;accumulate..
  1338.     ADD    BX,DX            ;..sum of..
  1339.     MOV    Word Ptr TAG@TOT,BX    ;..tagged file sizes.
  1340.     XCHG    BX,DX            ;file size to hl-pair
  1341.     JMPS    D@F@SIZ            ;branch to display sizes
  1342. TAKE:
  1343.     MOV    BX,Word Ptr TAG@TOT    ;subtract..
  1344.     MOV    AL,BL            ;..file..
  1345.     SUB    AL,DL            ;..size..
  1346.     MOV    BL,AL            ;..from..
  1347.     MOV    AL,BH            ;..summation..
  1348.     SBB    AL,DH            ;..total.
  1349.     MOV    BH,AL            ;then put..
  1350.     MOV    Word Ptr TAG@TOT,BX    ; (save total)
  1351.     XCHG    BX,DX            ;..file size in hl-pair.
  1352. ; display file size in kilobytes -- right justify tagged file total
  1353. D@F@SIZ:
  1354.     MOV    AL,Byte Ptr FSDFLG    ;display file size?
  1355.     OR    AL,AL            ;0=no
  1356.     JNZ    L_A16
  1357.     RET
  1358. L_A16:
  1359.     PUSH    BX            ;save value
  1360.     CALL    ATFS            ;position for file size print
  1361.     MOV    BX,Word Ptr RINGPOS    ;print file name of current file
  1362.     LAHF
  1363.     INC    BX
  1364.     SAHF
  1365.     CALL    PRFN
  1366.     MOV    AL,':'
  1367.     CALL    TTYPE
  1368.     POP    BX            ;get value
  1369.     CALL    DECOUT            ;print individual file size
  1370.     MOV    AL,'K'
  1371.     CALL    TTYPE
  1372. ; determine # of digits in tagged summation
  1373.     MOV    BX,Word Ptr TAG@TOT    ;get present summation
  1374.     CALL    ILPRT
  1375.     DB    ' Tagged:',0
  1376.     CALL    DECOUT            ;print tagged file summation
  1377.     MOV    AL,'K'
  1378.     JMP    TTYPE
  1379. ; j u m p
  1380. ; backward
  1381. JUMPB:
  1382.     CALL    CUR@OFF            ;turn off term. cursor
  1383.     MOV    BX,CURHOME        ;set cursor home
  1384.     MOV    Word Ptr CURAT,BX
  1385.     MOV    BX,Word Ptr RING    ;at front?
  1386.     XCHG    BX,DX
  1387.     MOV    BX,Word Ptr LOCBEG
  1388.     CALL    CMPDEHL
  1389.     JZ    JUMPBW            ;back up and wrap around
  1390.     MOV    Word Ptr LOCEND,BX    ;set new end
  1391.     MOV    DX,-EPS*13        ;back up
  1392.     LAHF
  1393.     ADD    BX,DX
  1394.     RCR    SI,1
  1395.     SAHF
  1396.     RCL    SI,1
  1397.     MOV    Word Ptr LOCBEG,BX    ;new beginning
  1398.     MOV    Word Ptr RINGPOS,BX    ;new position
  1399.     CALL    REFRESH            ;refresh screen
  1400.     CALL    CUR@ON            ;turn on term. cursor
  1401.     JMP    LOOPFN
  1402. JUMPBW:
  1403.     MOV    BX,Word Ptr LOCBEG    ;at first screen?
  1404.     XCHG    BX,DX
  1405.     MOV    BX,Word Ptr RING    ;pt to first element of ring
  1406.     CALL    CMPDEHL
  1407.     JZ    JBW0            ;advance to end
  1408.     MOV    BX,-EPS*13        ;back up
  1409.     LAHF
  1410.     ADD    BX,DX
  1411.     SAHF
  1412.     JMPS    JFW0
  1413. JBW0:
  1414.     MOV    DX,EPS*13        ;pt to next screen
  1415.     LAHF
  1416.     ADD    BX,DX
  1417.     RCR    SI,1
  1418.     SAHF
  1419.     RCL    SI,1
  1420.     XCHG    BX,DX
  1421.     MOV    BX,Word Ptr RINGEND
  1422.     CALL    CMPDEHL
  1423.     XCHG    BX,DX
  1424.     JZ    JBW1
  1425.     JB    JBW0
  1426. JBW1:
  1427.     MOV    DX,-EPS*13
  1428.     LAHF                ;pt to first element of local ring
  1429.     ADD    BX,DX
  1430.     SAHF
  1431.     JMPS    JFW0
  1432. JUMPF:
  1433.     CALL    CUR@OFF            ;tuen off term. cursor
  1434.     MOV    BX,CURHOME        ;set cursor to home
  1435.     MOV    Word Ptr CURAT,BX
  1436.     MOV    BX,Word Ptr LOCEND    ;see if Local End <= Ring End
  1437.     XCHG    BX,DX
  1438.     MOV    BX,Word Ptr RINGEND
  1439.     CALL    CMPDEHL
  1440.     JZ    CMDLOOP
  1441.     MOV    BX,Word Ptr LOCEND    ;new screen
  1442.     JMPS    JFW0
  1443. CMDLOOP:
  1444.     CALL    CUR@OFF            ;turn off cursor
  1445.     MOV    BX,CURHOME        ;set cursor home
  1446.     MOV    Word Ptr CURAT,BX
  1447.     MOV    BX,Word Ptr RING    ;set ring position
  1448. JFW0:
  1449.     MOV    Word Ptr RINGPOS,BX
  1450. JFW0A:
  1451.     MOV    Word Ptr LOCBEG,BX    ;front of ring
  1452.     MOV    DX,EPS*13        ;new end?
  1453.     LAHF
  1454.     ADD    BX,DX
  1455.     RCR    SI,1
  1456.     SAHF
  1457.     RCL    SI,1
  1458.     XCHG    BX,DX
  1459.     MOV    BX,Word Ptr RINGEND    ;end of ring
  1460.     XCHG    BX,DX
  1461.     CALL    CMPDEHL
  1462.     JB    JFW1
  1463.     XCHG    BX,DX
  1464. JFW1:
  1465.     XCHG    BX,DX
  1466.     MOV    Word Ptr LOCEND,BX
  1467.     CALL    REFRESH
  1468.     CALL    CUR@ON            ;turn on term. cursor
  1469.     JMP    LOOPFN
  1470.  
  1471. ; f o r w a r d
  1472. FORWARD:
  1473.     CALL    CUR@OFF            ;turn off term. cursor
  1474.     CALL    CLRCUR            ;clear cursor
  1475.     CALL    FOR0            ;position on screen and in ring
  1476.     CALL    SETCUR            ;set cursor
  1477.     CALL    CUR@ON            ;turn on term. cursor
  1478.     JMP    LOOPFN
  1479. ;  advance routine
  1480. FOR0:
  1481.     MOV    BX,Word Ptr RINGPOS    ;at end of loop yet?
  1482.     MOV    DX,13            ;i.e., will we be at end of loop?
  1483.     LAHF
  1484.     ADD    BX,DX
  1485.     RCR    SI,1
  1486.     SAHF
  1487.     RCL    SI,1
  1488.     XCHG    BX,DX
  1489.     MOV    BX,Word Ptr LOCEND
  1490.     CALL    CMPDEHL            ;compare 'present' to 'end'
  1491.     JNZ    FORW            ;to next print position
  1492.     CALL    CUR@FIRST        ;position cursor
  1493.     MOV    BX,Word Ptr LOCBEG    ;set position pointer to beginning and..
  1494.     MOV    Word Ptr RINGPOS,BX
  1495.     RET
  1496. FORW:
  1497.     MOV    BX,Word Ptr RINGPOS    ;advance in ring
  1498.     MOV    DX,13
  1499.     LAHF
  1500.     ADD    BX,DX
  1501.     RCR    SI,1
  1502.     SAHF
  1503.     RCL    SI,1
  1504.     MOV    Word Ptr RINGPOS,BX    ;new position
  1505.     CALL    CUR@NEXT        ;position cursor
  1506.     RET
  1507. ; r e v e r s e
  1508. REVERSE:
  1509.     CALL    CUR@OFF            ;turn off term. cursor
  1510.     CALL    CLRCUR            ;clear cursor
  1511.     CALL    REV0            ;position on screen and in ring
  1512.     CALL    SETCUR            ;set cursor
  1513.     CALL    CUR@ON            ;turn on term. cursor
  1514.     JMP    LOOPFN
  1515. ;  Back Up Routine
  1516. REV0:
  1517.     MOV    BX,Word Ptr LOCBEG
  1518.     XCHG    BX,DX
  1519.     MOV    BX,Word Ptr RINGPOS    ;see if at beginning of ring
  1520.     CALL    CMPDEHL
  1521.     JNZ    REV1            ;skip position pointer reset if not..
  1522.     CALL    CUR@LAST        ;end of local ring
  1523.     MOV    BX,Word Ptr LOCEND    ;set to end +1 to backup to end
  1524.     MOV    DX,-13
  1525.     LAHF
  1526.     ADD    BX,DX
  1527.     RCR    SI,1
  1528.     SAHF
  1529.     RCL    SI,1
  1530.     MOV    Word Ptr RINGPOS,BX
  1531.     RET
  1532. REV1:
  1533.     CALL    CUR@BACK        ;back up 1
  1534. REV2:
  1535.     MOV    BX,Word Ptr RINGPOS
  1536.     MOV    DX,-13            ;one ring position..
  1537.     LAHF                ;..backwards.
  1538.     ADD    BX,DX
  1539.     RCR    SI,1
  1540.     SAHF
  1541.     RCL    SI,1
  1542.     MOV    Word Ptr RINGPOS,BX
  1543.     RET
  1544. ; u p
  1545. UP:
  1546.     CALL    CUR@OFF            ;turn off term. cursor
  1547.     CALL    CLRCUR            ;clear cursor
  1548.     MOV    BX,Word Ptr RINGPOS    ;see if wrap around
  1549.     MOV    DX,-13*4        ;4 entries
  1550.     LAHF
  1551.     ADD    BX,DX
  1552.     RCR    SI,1
  1553.     SAHF
  1554.     RCL    SI,1
  1555.     XCHG    BX,DX
  1556.     MOV    BX,Word Ptr LOCBEG    ;beginning of local screen
  1557.     CALL    CMPDEHL
  1558.     JB    UP2            ;wrap around
  1559.     MOV    CH,4            ;back up 4 entries
  1560. UP1:
  1561.     PUSH    CX            ;save count
  1562.     CALL    REV0            ;back up in ring and on screen (no print)
  1563.     POP    CX            ;get count
  1564.     DEC    CH
  1565.     JNZ    UP1
  1566.     JMPS    DOWN1A
  1567. UP2:
  1568.     MOV    BX,Word Ptr RINGPOS    ;advance to beyond end
  1569.     MOV    DX,13*4
  1570.     LAHF
  1571.     ADD    BX,DX
  1572.     RCR    SI,1
  1573.     SAHF
  1574.     RCL    SI,1
  1575.     XCHG    BX,DX
  1576.     MOV    BX,Word Ptr LOCEND    ;compare to local end
  1577.     XCHG    BX,DX
  1578.     CALL    CMPDEHL
  1579.     JZ    DOWN1A            ;at end, so too far
  1580.     JB    DOWN1A            ;beyond end, so back up
  1581.     MOV    Word Ptr RINGPOS,BX    ;new ring position
  1582.     MOV    BX,Word Ptr CURAT    ;advance cursor
  1583.     INC    BH            ;next line
  1584.     MOV    Word Ptr CURAT,BX
  1585.     JMPS    UP2
  1586. ; d o w n
  1587. DOWN:
  1588.     CALL    CUR@OFF            ;turn off term. cursor
  1589.     CALL    CLRCUR            ;clear cursor
  1590.     MOV    BX,Word Ptr RINGPOS    ;see if wrap around
  1591.     MOV    DX,13*4            ;4 entries
  1592.     LAHF
  1593.     ADD    BX,DX
  1594.     RCR    SI,1
  1595.     SAHF
  1596.     RCL    SI,1
  1597.     XCHG    BX,DX
  1598.     MOV    BX,Word Ptr LOCEND    ;end of local screen
  1599.     XCHG    BX,DX
  1600.     CALL    CMPDEHL
  1601.     JZ    DOWN2            ;wrap around
  1602.     JB    DOWN2            ;wrap around
  1603.     MOV    CH,4            ;forward 4 entries
  1604. DOWN1:
  1605.     PUSH    CX            ;save count
  1606.     CALL    FOR0            ;advance in ring and on screen (no print)
  1607.     POP    CX            ;get count
  1608.     DEC    CH
  1609.     JNZ    DOWN1
  1610. DOWN1A:
  1611.     CALL    SETCUR            ;set cursor
  1612.     CALL    CUR@ON            ;turn on term. cursor
  1613.     JMP    LOOPFN
  1614. DOWN2:
  1615.     MOV    BX,Word Ptr CURAT    ;preserve column
  1616.     MOV    CH,BL            ;column number in B
  1617.     MOV    BX,CURHOME        ;home position
  1618.     MOV    Word Ptr CURAT,BX    ;set new position
  1619.     MOV    BX,Word Ptr LOCBEG    ;beginning of local ring
  1620.     MOV    Word Ptr RINGPOS,BX    ;new ring position
  1621. DOWN3:
  1622.     MOV    BX,Word Ptr CURAT    ;check for at top of column
  1623.     MOV    AL,BL            ;get col
  1624.     CMP    AL,CH            ;there?
  1625.     JZ    DOWN1A
  1626.     MOV    BX,Word Ptr RINGPOS    ;advance in ring
  1627.     MOV    DX,13            ;13 bytes/entry
  1628.     ADD    BX,DX
  1629.     MOV    Word Ptr RINGPOS,BX
  1630.     MOV    BX,Word Ptr CURAT    ;get cursor position
  1631.     MOV    DX,19            ;advance 19 bytes/screen entry
  1632.     ADD    BX,DX
  1633.     MOV    Word Ptr CURAT,BX
  1634.     JMPS    DOWN3
  1635. ; s t a t
  1636. ; determine remaining storage on requested disk
  1637. R@DR@ST:
  1638.     CALL    CPRMPT
  1639.     DB    'Status of Disk: ',0
  1640.     CALL    KEYIN            ;get char
  1641.     LAHF
  1642.     XCHG    AL,AH
  1643.     PUSH    AX
  1644.     CALL    CRLF
  1645.     POP    AX
  1646.     XCHG    AL,AH
  1647.     SUB    AL,'A'            ;convert to number
  1648.     JNB    L_A17    
  1649.     JMP    NEUTRAL
  1650. L_A17:
  1651.     MOV    CH,AL            ;... in B
  1652.     MOV    AL,Byte Ptr MAXDR    ;compare to max
  1653.     SUB    AL,'A'
  1654.     CMP    AL,CH
  1655.     JNB       L_A18    
  1656.     MOV    AL,Byte Ptr MDRIVE
  1657.     DEC    AL
  1658.     CMP    AL,CH
  1659.     JE    L_A18
  1660.     JMP    LOOPFN
  1661. L_A18:
  1662.     MOV    AL,CH            ;get disk
  1663.     MOV    Byte Ptr R@DR,AL    ;requested drive
  1664.     CALL    RESET            ;..login as current.
  1665.     CALL    FRESTOR            ;determine free space remaining
  1666.     CALL    PRINT@FRE        ;print value
  1667.     MOV    AL,Byte Ptr C@DR    ;login original as..
  1668.     CALL    SET@DR            ;..current drive.
  1669.     JMP    LOOPFN            ;done
  1670.  
  1671.  
  1672. ; d e l e t e
  1673.  
  1674. ; mass delete
  1675. MASS@DEL:
  1676.     CALL    CPRMPT
  1677.     DB    'Mass Delete (Y/N/V=Verify Each)? ',0
  1678.     CALL    KEYIN            ;get response
  1679.     CMP    AL,'Y'
  1680.     JZ    MD1
  1681.     CMP    AL,'V'
  1682.  
  1683.     JNZ    NEUT_J            ;return to position
  1684.     JMPS    MD1
  1685. NEUT_J:    JMP    NEUTRAL            ;too far for a jmps
  1686.  
  1687. MD1:
  1688.     MOV    Byte Ptr MDFLG,AL    ;set flag
  1689.     XOR    AL,AL            ;set for mass delete
  1690.     MOV    Byte Ptr MFLAG,AL
  1691.     MOV    BX,Word Ptr RING
  1692.     MOV    Word Ptr RINGPOS,BX    ;set ring position
  1693. MD@LP:
  1694.     MOV    BX,Word Ptr RINGPOS    ;get current position
  1695.     MOV    DX,12            ;pt to tag
  1696.     ADD    BX,DX
  1697.     MOV    AL,M            ;get tag
  1698.     CMP    AL,'*'
  1699.     JNZ    MD@LOOP
  1700.     CALL    RINGFCB            ;set up file name
  1701.     MOV    AL,Byte Ptr MDFLG    ;verify?
  1702.     CMP    AL,'V'
  1703.     JZ    MDEL1            ;delete with verify
  1704.     JMP    DEL1            ;delete without verify
  1705. MD@LOOP:
  1706.     MOV    BX,Word Ptr RINGPOS    ;re-entry point for next file mass-copy
  1707.     MOV    DX,13            ;advance to next
  1708.     LAHF
  1709.     ADD    BX,DX
  1710.     RCR    SI,1
  1711.     SAHF
  1712.     RCL    SI,1
  1713.     MOV    Word Ptr RINGPOS,BX
  1714. MD1@LOOP:
  1715.     XCHG    BX,DX            ;at ring..
  1716.     MOV    BX,Word Ptr RINGEND    ;..end yet?
  1717.     CALL    CMPDEHL            ; (compare present position with end)
  1718.     JNZ    MD@LP            ;no, loop 'till thru ring list.
  1719. MD@EXIT:
  1720.     MOV    AL,TRUE            ;set no
  1721.     MOV    Byte Ptr MFLAG,AL    ;..mass-delete request.
  1722.     JMP    CMDLOOP            ;jump to 'ring' beginning
  1723. ; set up to delete filename at cursor position
  1724. DELETE:
  1725.     MOV    AL,TRUE            ;set for no mass delete
  1726.     MOV    Byte Ptr MFLAG,AL
  1727.     MOV    Byte Ptr MDFLG,AL
  1728. MDELETE:
  1729.     CALL    RINGFCB            ;move file name
  1730. MDEL1:
  1731.     CALL    CPRMPT
  1732.     DB    'Delete ',0
  1733.     CALL    PRFNS            ;print file name in S$FCB
  1734.     CALL    ILPRT
  1735.     DB    ' (Y/N)? ',0
  1736.     CALL    KEYIN
  1737.     CMP    AL,'Y'
  1738.     JZ    DEL1
  1739.     MOV    AL,Byte Ptr MFLAG    ;mass delete?
  1740.     OR    AL,AL
  1741.     JZ    MD@LOOP
  1742. MDEL2:
  1743.     MOV    BX,Word Ptr LOCEND    ;move in end
  1744.     MOV    DX,-13
  1745.     LAHF
  1746.     ADD    BX,DX
  1747.     RCR    SI,1
  1748.     SAHF
  1749.     RCL    SI,1
  1750.     MOV    Word Ptr LOCEND,BX
  1751.     XCHG    BX,DX
  1752.     MOV    BX,Word Ptr RINGPOS    ;position beyond end of ring?
  1753.     CALL    CMPDEHL
  1754.     JNZ    MDEL3
  1755.     CALL    CUR@BACK        ;back up cursor
  1756.     MOV    BX,Word Ptr LOCEND    ;reset position
  1757.     MOV    DX,-13
  1758.     LAHF
  1759.     ADD    BX,DX
  1760.     RCR    SI,1
  1761.     SAHF
  1762.     RCL    SI,1
  1763.     MOV    Word Ptr RINGPOS,BX
  1764.     MOV    BX,Word Ptr LOCEND    ;get end
  1765.     XCHG    BX,DX
  1766. MDEL3:
  1767.     MOV    BX,Word Ptr LOCBEG    ;erased all local files?
  1768.     CALL    CMPDEHL
  1769.     JNZ    L_B3    
  1770.     JMP    CMDLOOP            ;reset
  1771. L_B3:
  1772.     JMP    JFW0A            ;rescreen
  1773. ; delete file
  1774. DEL1:
  1775.     MOV    AL,Byte Ptr MDFLG    ;Y option on Mass Delete?
  1776.     CMP    AL,'Y'
  1777.     JNZ    DEL1A
  1778.     CALL    ERMSG
  1779.     DB    'Deleting File ',0
  1780.     CALL    PRFNS
  1781. DEL1A:
  1782.     MOV    BX,(Offset S@FCB)    ;set file to R/W
  1783.     CALL    ATTRIB
  1784.     MOV    DX,(Offset S@FCB)    ;point at delete 'fcb'
  1785.     MOV    CL,ERASE        ;erase function
  1786.     INT    224
  1787.     INC    AL
  1788.     JZ    FNF@MSG            ;print error message
  1789.     CALL    DEL2            ;close up erased position
  1790.     MOV    AL,Byte Ptr MFLAG    ;check for mass delete
  1791.     OR    AL,AL
  1792.     JZ    L_B4    
  1793.     JMP    MDEL2
  1794. L_B4:
  1795.     MOV    BX,Word Ptr RINGPOS    ;no advance because of close up
  1796.     JMP    MD1@LOOP
  1797. FNF@MSG:
  1798.     CALL    ERMSG            ;show error message
  1799.     DB    'No File Found',0
  1800.     JMP    LOOPFN
  1801. ; reverse ring to close up erased position
  1802. DEL2:
  1803.     MOV    BX,Word Ptr RINGPOS    ;prepare move up pointers
  1804.     PUSH    BX
  1805.     MOV    DX,13            ;13 bytes/entry
  1806.     LAHF                ;de-pair = 'to' location
  1807.     ADD    BX,DX
  1808.     RCR    SI,1
  1809.     SAHF
  1810.     RCL    SI,1
  1811.     POP    DX            ;hl-pair = 'from' location
  1812. MOVUP:
  1813.     XCHG    BX,DX
  1814.     PUSH    BX            ;check if at end
  1815.     MOV    BX,Word Ptr RINGEND    ;get old end pointer
  1816.     CALL    CMPDEHL            ;check against current end location
  1817.     POP    BX
  1818.     XCHG    BX,DX
  1819.     JZ    MOVDONE            ;must be at end of ring
  1820.     MOV    CH,13            ;one name size
  1821.     CALL    MOVE            ;move one name up
  1822.     JMPS    MOVUP            ;go check end parameters
  1823. MOVDONE:
  1824.     MOV    BX,Word Ptr RING    ;see if ring is empty
  1825.     XCHG    BX,DX
  1826.     MOV    Word Ptr RINGEND,BX    ;set new ring end if all moved
  1827.     CALL    CMPDEHL            ;..(listend --> listpos --> ring)
  1828.     JZ    L_B5
  1829.     RET
  1830. L_B5:
  1831.     MOV    BX,Word Ptr RINGPOS
  1832.     CALL    CMPDEHL
  1833.     JZ    L_B6    
  1834.     RET                ;neither equal so not empty
  1835. L_B6:
  1836.     MOV    SP,(Offset STACK)    ;reset stack
  1837.     CALL    ERMSG
  1838.     DB    'List Empty',0
  1839.     JMP    LOG            ;go to drive/user area with files
  1840. ; r e n a m e
  1841. ; set-up to rename file at cursor position -- scan keyboard buffer and
  1842. ; move filename to 'rename' destination 'fcb' (dfcb)
  1843. RENAME:
  1844.     MOV    BX,Word Ptr RINGPOS    ;move name from ring to rename 'fcb'
  1845.     MOV    DX,(Offset D@FCB)    ;place to move name
  1846.     MOV    CH,12            ;amount to move
  1847.     CALL    MOVE
  1848.     CALL    CPRMPT            ;new name prompt
  1849.     DB    'Rename File to: ',0
  1850.     MOV    DX,(Offset D@FCB)+16    ;pt to FCB to fill
  1851.     CALL    FILENAME        ;get file name
  1852.     MOV    BX,(Offset D@FCB)+1    ;check for any wild cards -- none permitted
  1853.     MOV    CH,11            ;11 bytes
  1854. WILDCHK:
  1855.     MOV    AL,M            ;get char
  1856.     INC    BX            ;pt to next
  1857.     CMP    AL,'?'            ;wild?
  1858.     JZ    WILDFND
  1859.     DEC    CH
  1860.     JNZ    WILDCHK
  1861. ; copy old file status bit ($r/o or $sys) to new filename
  1862. CPYBITS:
  1863.     MOV    DX,(Offset D@FCB)+1    ;first character of old name..
  1864.     MOV    BX,(Offset D@FCB)+17    ;..and of new name.
  1865.     MOV    CH,11            ; # of bytes with tag bits
  1866. CBITS1:
  1867.     MOV    SI,DX            ;fetch bit of old name character
  1868.     MOV    AL,[SI]
  1869.     AND    AL,128            ;strip upper bit and..
  1870.     MOV    CL,AL            ;..save in b-reg.
  1871.     MOV    AL,7FH            ;mask for character only
  1872.     AND    AL,M            ;put masked character into a-reg
  1873.     OR    AL,CL            ;add old bit
  1874.     MOV    M,AL            ;copy new byte back
  1875.     LAHF                ;bump copy pointers
  1876.     INC    BX
  1877.     SAHF
  1878.     LAHF
  1879.     INC    DX
  1880.     SAHF
  1881.     DEC    CH
  1882.     JNZ    CBITS1
  1883. ; check if new filename already exists.  if so, say so.  then go
  1884. ; to command loop without moving ring position
  1885.     MOV    AL,Byte Ptr D@FCB    ;copy new name to source 'fcb'
  1886.     MOV    Byte Ptr S@FCB,AL
  1887.     MOV    CH,11
  1888.     MOV    BX,(Offset D@FCB)+17    ;copy new name to..
  1889.     MOV    DX,(Offset S@FCB)+1    ;..source 'fcb' for existence check.
  1890.     CALL    MOVE
  1891.     MOV    BX,(Offset S@FCB)+12    ;clear cp/m 'fcb' system..
  1892.     CALL    INITFCB            ;..fields.
  1893.     MOV    DX,(Offset S@FCB)    ;search to see if this file exists
  1894.     MOV    CL,SRCHF        ;search first function
  1895.     INT    224
  1896.     INC    AL            ; 0ffh --> 00h if file not found
  1897.     JZ    RENFILE            ;to rename, if duplicate doesn't exists.
  1898.     CALL    ERMSG            ;announce the situation
  1899.     DB    'File Already Exists',0
  1900.     JMP    COMCAN            ;try again?
  1901. ; wild char found in file name -- error
  1902. WILDFND:
  1903.     CALL    ERMSG
  1904.     DB    'Ambiguous File Name NOT Allowed',0
  1905.     JMP    COMCAN
  1906. ; copy new name into ring position
  1907. RENFILE:
  1908.     MOV    BX,Word Ptr RINGPOS    ;get ring position pointer
  1909.     LAHF                ;pt to name
  1910.     INC    BX
  1911.     SAHF
  1912.     PUSH    BX            ;save ptr
  1913.     XCHG    BX,DX
  1914.     MOV    BX,(Offset D@FCB)+17    ;point at new name and..
  1915.     MOV    CH,11
  1916.     CALL    MOVE            ;..move.
  1917.     MOV    BX,Word Ptr CURAT    ;get current position on screen
  1918.     MOV    DX,4            ;advance 4 chars
  1919.     LAHF
  1920.     ADD    BX,DX
  1921.     RCR    SI,1
  1922.     SAHF
  1923.     RCL    SI,1
  1924.     CALL    GOTOXY
  1925.     POP    BX            ;get ptr
  1926.     CALL    AC@PRFN            ;print file name
  1927.     MOV    DX,(Offset D@FCB)    ;rename 'fcb' location
  1928.     MOV    CL,REN            ;rename function
  1929.     INT    224
  1930.     INC    AL            ; 0ffh --> 00h if rename error
  1931.     JZ    L_B7    
  1932.     JMP    NEUTRAL            ;if okay, proceed, else..
  1933. L_B7:
  1934.     JMP    FNF@MSG            ;..show no-file msg.
  1935. ; get file name from user and process into FCB pted to by DE
  1936. FILENAME:
  1937.     PUSH    DX            ;save ptr
  1938.     MOV    DX,(Offset CMDBUF)    ;command line location
  1939.     MOV    CL,RDBUF        ;console read-buffer function
  1940.     INT    224
  1941.     CALL    CONVERT            ;capitalize alpha
  1942.     POP    BX            ;set to null drive
  1943.     MOV    M,0            ;..required by 'bdos'.
  1944.     LAHF
  1945.     INC    BX
  1946.     SAHF
  1947. ; initialize new filename field with spaces
  1948.     PUSH    BX            ;save start pointer
  1949.     MOV    CH,11            ; # of spaces to 'blank'
  1950.     CALL    FILL
  1951.     POP    BX
  1952.     XCHG    BX,DX
  1953.     MOV    BX,(Offset CMDBUF)+1    ;put length..
  1954.     MOV    CL,M            ;..in c-reg.
  1955.     LAHF
  1956.     INC    BX
  1957.     SAHF
  1958.     XCHG    BX,DX            ;de-pair --> buffer pointer and hl-pair..
  1959.     CALL    UNSPACE            ;..--> 'fcb' pointer.  remove leading spaces.
  1960. ; extend buffer to spaces beyond command length
  1961. EXTEND:
  1962.     PUSH    BX
  1963.     MOV    BL,CL            ;double-byte remaining length
  1964.     MOV    BH,0
  1965.     LAHF                ;to buffer end +1
  1966.     ADD    BX,DX
  1967.     RCR    SI,1
  1968.     SAHF
  1969.     RCL    SI,1
  1970.     MOV    M,' '            ;force illegal character end
  1971.     POP    BX
  1972. ; start filename scan
  1973. SCAN:
  1974.     MOV    CH,8            ; 8 characters in filename
  1975. SCAN1:
  1976.     CALL    CKLEGAL            ;get and see if legal character
  1977.     JNB    L_B8    
  1978.     JMP    COMCAN            ;all of command line?
  1979. L_B8:
  1980.     CMP    AL,' '            ;see if end of parameter field
  1981.     JNZ    L_B9    
  1982.     RET                ;rename file
  1983. L_B9:
  1984.     CMP    AL,'.'            ;at end of filename
  1985.     JZ    SCAN2            ;process filetype field
  1986.     CMP    AL,'*'            ;rest wild?
  1987.     JZ    SCAN1B
  1988.     MOV    M,AL            ;put character into destination 'fcb'
  1989.     LAHF
  1990.     INC    BX
  1991.     SAHF
  1992.     DEC    CH
  1993.     JNZ    SCAN1
  1994. ; entry if eight characters without a 'period'
  1995. SCAN1A:
  1996.     CALL    CKLEGAL            ;scan buffer up to period or end
  1997.     JNB    L_B10    
  1998.     RET                ;no extent if not legal
  1999. L_B10:
  2000.     CMP    AL,' '            ;end of parameter field?
  2001.     JNZ    L_B11
  2002.     RET
  2003. L_B11:
  2004.     CMP    AL,'.'
  2005.     JNZ    SCAN1A            ;do till end or period
  2006.     JMPS    SCAN2A            ;continue at correct place
  2007. ; make rest of entry wild
  2008. SCAN1B:
  2009.     MOV    M,'?'            ;fill with ?'s
  2010.     INC    BX
  2011.     DEC    CH
  2012.     JNZ    SCAN1B
  2013.     MOV    SI,DX            ;get next char
  2014.     MOV    AL,[SI]
  2015.     INC    DX            ;pt to after dot
  2016.     CMP    AL,'.'            ;must be dot
  2017.     JZ    L_B12    
  2018.     JMP    COMCAN            ;cancel if not
  2019. L_B12:
  2020.     JMPS    SCAN2A
  2021. ; build filetype field
  2022. SCAN2:
  2023.     LAHF                ;advance ptr to file type field
  2024.     INC    BX
  2025.     SAHF
  2026.     DEC    CH
  2027.     JNZ    SCAN2
  2028. SCAN2A:
  2029.     MOV    CH,3            ;length of filetype field
  2030. SCAN3:
  2031.     CALL    CKLEGAL            ;get and check character
  2032.     JB    SCAN4            ;name done if illegal
  2033.     CMP    AL,' '            ;end of parameter field?
  2034.     JZ    SCAN4
  2035.     CMP    AL,'.'            ;check if another period
  2036.     JZ    SCAN4
  2037.     CMP    AL,'*'            ;rest wild?
  2038.     JZ    SCAN4B
  2039.     MOV    M,AL
  2040.     LAHF
  2041.     INC    BX
  2042.     SAHF
  2043.     DEC    CH
  2044.     JNZ    SCAN3            ;get next character
  2045.     JMPS    SCAN4A
  2046. SCAN4:
  2047.     LAHF                ;advance to end of type field
  2048.     INC    BX
  2049.     SAHF
  2050.     DEC    CH
  2051.     JNZ    SCAN4
  2052. SCAN4A:
  2053.     CALL    INITFCB            ;..and zero counter fields.
  2054.     RET
  2055. SCAN4B:
  2056.     MOV    M,'?'            ;make wild
  2057.     LAHF
  2058.     INC    BX
  2059.     SAHF
  2060.     DEC    CH
  2061.     JNZ    SCAN4B
  2062.     JMPS    SCAN4A            ;complete rest
  2063. ; goto file
  2064. GOTO:
  2065.     CALL    CPRMPT
  2066.     DB    'Goto Filename: ',0
  2067.     MOV    DX,(Offset D@FCB)    ;pt to FCB
  2068.     CALL    FILENAME        ;get file name
  2069.     MOV    BX,Word Ptr RING    ;pt to first element of ring
  2070.     MOV    Word Ptr RINGPOS,BX    ;set position
  2071.     MOV    Word Ptr LOCBEG,BX    ;set local beginning
  2072.     XOR    AL,AL            ;set local counter
  2073.     MOV    Byte Ptr CRCTBL,AL    ;use this buffer
  2074. GOTOL:
  2075.     CALL    GOTOCOMP        ;compare
  2076.     JZ    GOTOF            ;we are there
  2077.     MOV    AL,Byte Ptr CRCTBL    ;increment count
  2078.     INC    AL
  2079.     MOV    Byte Ptr CRCTBL,AL
  2080.     CMP    AL,EPS
  2081.     JNZ    GOTOL1
  2082.     XOR    AL,AL            ;reset count
  2083.     MOV    Byte Ptr CRCTBL,AL
  2084.     MOV    BX,Word Ptr LOCBEG    ;reset local beginning
  2085.     MOV    DX,EPS*13
  2086.     LAHF
  2087.     ADD    BX,DX
  2088.     SAHF
  2089.     MOV    Word Ptr LOCBEG,BX
  2090. GOTOL1:
  2091.     MOV    BX,Word Ptr RINGPOS    ;advance to next entry
  2092.     MOV    DX,13
  2093.     LAHF
  2094.     ADD    BX,DX
  2095.     RCR    SI,1
  2096.     SAHF
  2097.     RCL    SI,1
  2098.     MOV    Word Ptr RINGPOS,BX    ;new position
  2099.     XCHG    BX,DX            ;position in DE
  2100.     MOV    BX,Word Ptr RINGEND    ;check for completion
  2101.     CALL    CMPDEHL            ;compare current position with end of ring
  2102.     JNZ    GOTOL
  2103.     MOV    BX,Word Ptr RING    ;pt to first element
  2104.     MOV    Word Ptr RINGPOS,BX    ;set position
  2105.     CALL    ERMSG
  2106.     DB    'File NOT Found',0
  2107.     JMP    CMDLOOP
  2108. GOTOF:
  2109.     MOV    BX,Word Ptr LOCBEG    ;we have local beginning
  2110.     PUSH    BX
  2111.     XCHG    BX,DX            ;ring location in DE
  2112.     MOV    BX,CURHOME        ;set cursor ptr
  2113.     MOV    Word Ptr CURAT,BX
  2114. GOTOF0:
  2115.     CALL    CUR@OFF            ;turn off term. cursor
  2116. GOTOF0A:
  2117.     MOV    BX,Word Ptr RINGPOS    ;at position?
  2118.     CALL    CMPDEHL
  2119.     JZ    GOTOF1
  2120.     MOV    BX,13            ;advance location
  2121.     LAHF
  2122.     ADD    BX,DX
  2123.     RCR    SI,1
  2124.     SAHF
  2125.     RCL    SI,1
  2126.     PUSH    BX
  2127.     CALL    CUR@NEXT        ;advance cursor
  2128.     POP    DX            ;pt to next ring position
  2129.     JMPS    GOTOF0A
  2130. GOTOF1:
  2131.     CALL     CUR@ON            ;turn on term. cursor
  2132.     POP    BX            ;pt to local ring
  2133.     JMP    JFW0A            ;process
  2134. GOTOCOMP:
  2135.     MOV    BX,Word Ptr RINGPOS    ;pt to current entry
  2136.     INC    BX            ;pt to first char of file name
  2137.     MOV    DX,(Offset D@FCB)+1    ;pt to first char of new file
  2138.     MOV    CH,11            ;11 bytes
  2139. GOTOC1:
  2140.     MOV    SI,DX            ;get char
  2141.     MOV    AL,[SI]
  2142.     CMP    AL,'?'            ;match?
  2143.     JZ    GOTOC2
  2144.     CMP    AL,M            ;match?
  2145.     JZ    L_B13    
  2146.     RET                ;no match
  2147. L_B13:
  2148. GOTOC2:
  2149.     LAHF                ;pt to next
  2150.     INC    DX
  2151.     SAHF
  2152.     LAHF
  2153.     INC    BX
  2154.     SAHF
  2155.     DEC    CH
  2156.     JNZ    GOTOC1
  2157.     RET
  2158.  
  2159. ; v i e w
  2160. ; type file to console with pagination set to 'lps' -- single-line scroll
  2161. ; using <space> bar , <ctrl-x> to cancel, any other key to page screen.
  2162. VIEW:
  2163.     CALL    CHK@CMD            ;check if CMD filetype
  2164.     JNZ    OK_VIEW            ;give error if CMD type
  2165.     CALL    ERMSG
  2166.     DB    'Can not View CMD type files',0
  2167.     JMP    LOOPFN
  2168. OK_VIEW:
  2169.     CALL    CLS
  2170.     CALL    ILPRT
  2171.     DB    CR,LF,'<Q or ESC> Quits, <SP> Turns Up One Line, '
  2172.     DB    'Other Keys Page Screen',CR,LF,LF,0
  2173.     MOV    AL,1            ;initialize..
  2174.     MOV    Byte Ptr LPSCNT,AL    ;..lines-per-screen counter.
  2175.     MOV    Byte Ptr VIEWFLG,AL    ; 'view' paginate if not zero
  2176.     MOV    AL,WRCON        ;write console out function
  2177.     JMP    CURRENT            ;to common i/o processing
  2178. ; p r i n t e r
  2179. ; send file to logical list device -- any keypress cancels
  2180. LSTFILE:
  2181.     CALL    CPRMPT
  2182.     DB    'Print current file (Y/N)? ',0
  2183.     CALL    KEYIN            ;get response
  2184.     CMP    AL,'Y'
  2185.     JE    L_B14    
  2186.     JMP    NEUTRAL
  2187. L_B14:
  2188.     CALL    CHK@CMD            ;check if CMD filetype
  2189.     JNZ    OK_LST            ;give error if CMD type
  2190.     CALL    ERMSG
  2191.     DB    'Can not Print CMD type files',0
  2192.     JMP    LOOPFN
  2193. OK_LST:
  2194.     CALL    RDTIME            ;read clock
  2195.     MOV    AL,Byte Ptr LTPP    ;get lines to print per page
  2196.     MOV    Byte Ptr LTPP1,AL    ;stash
  2197.     MOV    Byte Ptr HEADFLG,TRUE    ;set flag defaults
  2198.     MOV    Byte Ptr PAGEFLG,TRUE
  2199.     CALL    ERMSG
  2200.     DB    '*** Make Printer Ready ***',0
  2201.     CALL    CPRMPT
  2202.     DB    'Page the printer output (Y/N)? ',0
  2203.     CALL    KEYIN
  2204.     CMP    AL,'Y'
  2205.     JE    L_B14A
  2206.     MOV    Byte Ptr PAGEFLG,FALSE
  2207.     JMPS    L_B14B
  2208. L_B14A:
  2209.     CALL    CPRMPT
  2210.     DB    'Print Header on every page (Y/N)? ',0
  2211.     CALL    KEYIN
  2212.     CMP    AL,'Y'
  2213.     JE    L_B14B
  2214.     MOV    HEADFLG,FALSE        ;set flag false
  2215. L_B14B:
  2216.     CALL    ERMSG
  2217.     DB    'Printing ',0
  2218.     MOV    BX,Word Ptr RINGPOS    ;pt to file name
  2219.     LAHF
  2220.     INC    BX
  2221.     SAHF
  2222.     CALL    PRFN            ;print it
  2223.     CALL    CPRMPT
  2224.     DB    'Press ESC, or Q key to quit printing ',0
  2225.  
  2226.     MOV    AL,1            ;one for..
  2227.     MOV    Byte Ptr VIEWFLG,AL    ;..output to printer.
  2228.     DEC    AL            ;zero for..
  2229.     MOV    Byte Ptr LPSCNT,AL    ;..lines-per-page counter
  2230.     MOV    AL,LLIST        ;out to 'list' device function and fall thru
  2231. ; output character for console/list/punch processing
  2232. CURRENT:
  2233.     MOV    Byte Ptr CON@LST,AL    ;save bdos function
  2234. ; output file to console/printer/punch
  2235.     CALL    RINGFCB            ;position name to 'fcb'
  2236.     XCHG    BX,DX            ;HL pts to S$FCB
  2237.     CALL    INITFCB            ;set 'fcb' for use
  2238.     MOV    DX,TBUF            ;set to use default cp/m dma buffer
  2239.     MOV    CL,SETDMA        ;address set function
  2240.     INT    224
  2241.     MOV    DX,(Offset S@FCB)    ;open file for reading
  2242.     MOV    CL,OPEN            ;file open function code
  2243.     INT    224
  2244.     INC    AL            ; 0ffh --> 00h if open not okay
  2245.     JNZ    ZEROCR            ;if not okay, show error message.
  2246.     CALL    ERMSG
  2247.     DB    'Unable to Open File',0
  2248.     JMP    NEUTRAL
  2249. ZEROCR:
  2250.     XOR    AL,AL
  2251.     MOV    Byte Ptr S@FCB+32,AL    ;zero file 'current record' field
  2252.     MOV    Byte Ptr CHARCNT,AL    ;zero char count for tabbing
  2253.     CALL    PHEAD            ;print heading if output to LST device
  2254. READMR:
  2255.     MOV    DX,(Offset S@FCB)    ;point at file 'fcb' for reading
  2256.     MOV    CL,READ            ;record read function
  2257.     INT    224
  2258.     OR    AL,AL            ;check if read okay
  2259.     JZ    L_B15    
  2260.     JMP    CURDONE            ;eof?
  2261. L_B15:
  2262.     MOV    BX,TBUF            ;point at record just read
  2263.     MOV    CH,128            ;set record character counter to output
  2264. READLP:
  2265.     MOV    AL,M            ;get a character
  2266.     AND    AL,7FH            ;force to 'ascii'
  2267.     CMP    AL,EOFCHAR        ;see if end-of-file
  2268.     JNZ    L_B16    
  2269.     JMP    CURDONE            ;back to ring loop if 'eof'
  2270. L_B16:
  2271.     MOV    DL,AL            ;put character for 'bdos' call
  2272.     PUSH    CX
  2273.     PUSH    BX
  2274.     PUSH    DX            ; (character in e-reg)
  2275.     MOV    AL,Byte Ptr CON@LST    ;get function for punch/list/console output
  2276.     MOV    CL,AL
  2277.     MOV    AL,DL            ;check char
  2278.     CMP    AL,TAB            ;tabulate?
  2279.     JNZ    NOTAB
  2280.     MOV    DL,' '            ;space over
  2281. TABL:
  2282.     PUSH    CX            ;save key regs
  2283.     PUSH    DX
  2284.     INT    224
  2285.     POP    DX            ;get key regs
  2286.     POP    CX
  2287.     CALL    INCCCNT            ;increment char count
  2288.     AND    AL,7            ;check for done at every 8
  2289.     JNZ    TABL
  2290.     JMPS    TABDN
  2291. NOTAB:
  2292.     INT    224            ;send character
  2293.     CALL    INCCCNT            ;increment char count
  2294. TABDN:
  2295.     MOV    AL,Byte Ptr VIEWFLG    ;if 'view'..
  2296.     OR    AL,AL
  2297.     POP    DX            ;get char in E in case PAGER is called
  2298.     JZ    L_B17    
  2299.     CALL    PAGER            ;..check for 'lf'.
  2300. L_B17:
  2301.     MOV    DL,GET            ;get status or char
  2302.     MOV    CL,DIRCON        ;console status function
  2303.     INT    224            ;status?
  2304.     POP    BX
  2305.     POP    CX
  2306.     AND    AL,7FH            ;if character there, then abort..
  2307.     JZ    L_B18    
  2308.     CALL    CHK@CAN            ;already got char
  2309. L_B18:
  2310.     INC    BX            ;if not, bump buffer pointer.
  2311.     DEC    CH
  2312.     JZ    L_B19    
  2313.     JMP    READLP            ;no, more in present record.
  2314. L_B19:
  2315.     JMP    READMR            ;yes, get next record.
  2316. CURDONE:
  2317.     MOV    AL,Byte Ptr CON@LST    ;console?
  2318.     CMP    AL,WRCON
  2319.     JNZ    L_B20    
  2320.     CALL    BOTTOM            ;prompt for user
  2321. L_B20:
  2322.     CALL    REFRESH            ;refresh screen
  2323.     JMP    LOOPFN
  2324. PAGER:
  2325.     MOV    AL,DL            ; (character in e-reg)
  2326.     CMP    AL,LF
  2327.     JZ    L_B21
  2328.     RET
  2329. L_B21:
  2330.     XOR    AL,AL            ;zero char count
  2331.     MOV    Byte Ptr CHARCNT,AL
  2332.     MOV    AL,Byte Ptr CON@LST    ;printer or console?
  2333.     CMP    AL,LLIST        ;check for printer
  2334.     JZ    PAGEP
  2335.     MOV    AL,Byte Ptr CTPP    ;get number of lines of text per screen
  2336.     MOV    CH,AL            ;... in B
  2337.     MOV    AL,Byte Ptr LPSCNT    ;is counter..
  2338.     INC    AL            ;..at..
  2339.     MOV    Byte Ptr LPSCNT,AL    ;..limit..
  2340.     CMP    AL,CH            ;..of lines-per-screen?
  2341.     JNB    L_B22    
  2342.     RET                ;no, return.
  2343. L_B22:
  2344.     XOR    AL,AL            ;yes, initialize..
  2345.     MOV    Byte Ptr LPSCNT,AL    ;..for next screen full.
  2346.     CALL    ILPRT
  2347.     DB    '  [View More...]',CR,0    ;show msg line
  2348.     CALL    DKEYIN            ;wait for keyboard input
  2349.     CMP    AL,' '            ;see if <space> bar..
  2350.     LAHF
  2351.     XCHG    AL,AH
  2352.     PUSH    AX
  2353.     CALL    ILPRT
  2354.     DB    '                ',CR,0    ;clear above msg line
  2355.     POP    AX
  2356.     XCHG    AL,AH
  2357.     SAHF
  2358.     JNZ    CHK@CAN            ;..if not, see if cancel.
  2359.     MOV    AL,Byte Ptr CTPP    ;set for single line
  2360.     DEC    AL
  2361.     MOV    Byte Ptr LPSCNT,AL    ;..scroll and..
  2362.     RET                ;..return for one more line.
  2363.  
  2364. PAGEP:
  2365.     CALL    PRN@CAN            ;check if cancel
  2366.     TEST    Byte Ptr PAGEFLG,TRUE    ;test paging flag
  2367.     JZ    PAGE_RET        ;if true then...
  2368.     MOV    AL,Byte Ptr LTPP1    ;get number of lines of text per page
  2369.     MOV    CH,AL            ;... in B
  2370.     MOV    AL,Byte Ptr LPSCNT    ;is counter..
  2371.     INC    AL            ;..at..
  2372.     MOV    Byte Ptr LPSCNT,AL    ;..limit..
  2373.     CMP    AL,CH            ;..of lines-per-screen?
  2374.     JNB    L_B23    
  2375.     RET                ;no, return.
  2376. L_B23:
  2377.     XOR    AL,AL            ;zero for..
  2378.     MOV    Byte Ptr LPSCNT,AL    ;..lines-per-page counter
  2379.     MOV    AL,Byte Ptr LSPP    ;number of lines to skip
  2380.     MOV    CH,AL            ;number of lines to skip
  2381.     MOV    CL,LLIST        ;LST output
  2382. PAGELST:
  2383.     CALL    LCRLF            ;new line on LST
  2384.     DEC    CH
  2385.     JNZ    PAGELST
  2386.  
  2387.     TEST    Byte Ptr HEADFLG,TRUE    ;test if print header true
  2388.     JNZ    PRN_HEAD        ;if not true then...
  2389.  
  2390.     MOV    AL,Byte Ptr LTPP    ;get lines to print per page
  2391.     INC AL ! INC AL            ;add 2 lines 
  2392.     MOV    Byte Ptr LTPP1,AL
  2393.     RET                ;and return
  2394. PRN_HEAD:
  2395.     CALL    PHEAD            ;...else print heading
  2396. PAGE_RET:
  2397.     RET                ;done
  2398.  
  2399. PRN@CAN:                ;check for list cancel
  2400.     CALL    CST            ;has key been hit
  2401.     CMP    AL,0
  2402.     JNZ    KEY_HIT
  2403.     RET                ;if not, return
  2404. KEY_HIT:
  2405.     CALL    CIN            ;else get char
  2406.                     ;and ... 
  2407. CHK@CAN:                ;check for cancel
  2408.     CALL    UCASE
  2409.     CMP    AL,'Q'            ;Q = quit
  2410.     JE    L_B24    
  2411.     CMP    AL,ESC            ;so does ESC
  2412.     JE    L_B24
  2413.     CMP    AL,CTRLC        ;and ^C
  2414.     JE    L_B24
  2415.     RET                ;return for another page
  2416. L_B24:
  2417.     MOV    CL,Byte Ptr CON@LST    ;get function
  2418.     MOV    DL,CR            ;and send it a <CR>
  2419.     INT    224            ;to flush printer buffer
  2420.     JMP    COMCAN            ;cancel
  2421.  
  2422. INCCCNT:
  2423.     MOV    AL,Byte Ptr CHARCNT    ;increment char count
  2424.     INC    AL
  2425.     MOV    Byte Ptr CHARCNT,AL
  2426.     RET
  2427.  
  2428. PHEAD:
  2429.     MOV    AL,Byte Ptr CON@LST    ;printing to printer?
  2430.     CMP    AL,LLIST
  2431.     JZ    L_B25
  2432.     RET
  2433. L_B25:
  2434.     MOV    BX,(Offset HEADMSG)    ;print heading
  2435.     CALL    PHEAD1
  2436. PHEAD2:
  2437.     MOV    BX,(Offset S@FCB)+1    ;pt to file name
  2438.     MOV    CH,8            ;8 chars
  2439.     CALL    PHEAD3
  2440.     MOV    AL,'.'            ;dot
  2441.     CALL    LOUT
  2442.     MOV    CH,3            ;3 more chars
  2443.     CALL    PHEAD3
  2444.  
  2445.     MOV    BX,OFFSET DATE
  2446.     CALL    PHEAD1
  2447.  
  2448.     CALL    LCRLF            ;new line
  2449.     CALL    LCRLF            ;blank line
  2450.     RET
  2451.  
  2452. PHEAD1:
  2453.     MOV    AL,M            ;get char
  2454.     OR    AL,AL            ;done?
  2455.     JZ    PH1_RET
  2456.     CALL    LOUT            ;send to printer
  2457.     INC    BX            ;pt to next
  2458.     JMPS    PHEAD1
  2459. PH1_RET:
  2460.     RET
  2461.  
  2462. PHEAD3:
  2463.     MOV    AL,M            ;get char
  2464.     CALL    LOUT            ;LST it
  2465.     LAHF                ;pt to next
  2466.     INC    BX
  2467.     SAHF
  2468.     DEC    CH
  2469.     JNZ    PHEAD3
  2470.     RET
  2471.  
  2472. ; m a s s   c o p y
  2473. ; copy files tagged using the 't' command.  auto-erase if file exists
  2474. ; on requested destination drive or in user area.
  2475. MASS@COPY:
  2476.     CALL    CPRMPT
  2477.     DB    'Mass Copy (Y/N/V=Verify Overwrite)? ',0
  2478.     CALL    KEYIN
  2479.     CMP    AL,'Y' ! JE MASC1
  2480.     CMP    AL,'V' ! JE MASC1
  2481.     JMP    NEUTRAL
  2482. MASC1:
  2483.     MOV    Byte Ptr MCFLG,AL    ;save answer
  2484.     MOV    BX,Word Ptr RINGPOS    ;save position
  2485.     MOV    Word Ptr SRINGPOS,BX
  2486.     MOV    BX,Word Ptr RING
  2487.     MOV    Word Ptr RINGPOS,BX    ;set position
  2488. MASS@LP:
  2489.     MOV    BX,Word Ptr RINGPOS    ;get position
  2490.     MOV    DX,12            ;get 1st possible tag location
  2491.     ADD    BX,DX
  2492.     MOV    AL,M            ;get tag
  2493.     CMP    AL,'*'
  2494.     JZ    MCOPY            ;copy filename with tag character (*)
  2495. M@LP:
  2496.     MOV    BX,Word Ptr RINGPOS    ;re-entry point for next file mass-copy
  2497.     MOV    DX,13            ;advance to next
  2498.     LAHF
  2499.     ADD    BX,DX
  2500.     SAHF
  2501.     MOV    Word Ptr RINGPOS,BX
  2502.     XCHG    BX,DX            ;at ring..
  2503.     MOV    BX,Word Ptr RINGEND    ;..end yet?
  2504.     CALL    CMPDEHL            ; (compare present position with end)
  2505.     JNZ    MASS@LP            ;loop 'till thru ring list.
  2506. MF@EXIT:
  2507.     XOR    AL,AL            ;reset flags..
  2508.     MOV    Byte Ptr FIRST@M,AL    ;..for..
  2509.     NOT    AL            ;..next..
  2510.     MOV    Byte Ptr MFLAG,AL    ;..mass-copy request.
  2511.     MOV    BX,Word Ptr SRINGPOS    ;reset ring position
  2512.     MOV    Word Ptr RINGPOS,BX
  2513.     MOV    BX,Word Ptr LOCBEG    ;local ring
  2514.     JMP    JFW0A            ;rescreen
  2515. ; c o p y
  2516. ; copy source file at current 'ring' position to another drive.  set-up
  2517. ; fcb's and buffer area and check for correct keyboard inputs.  contains
  2518. ; auto-crc file copy verification.
  2519. MCOPY:
  2520.     XOR    AL,AL            ;zero flag to..
  2521.     MOV    Byte Ptr MFLAG,AL    ;..mass copy.
  2522.     JMPS    COPY0M
  2523. COPY:
  2524.     MOV    Byte Ptr MCFLG,'V'    ;initialize verify flag
  2525. COPY0M:
  2526.     MOV    BX,0            ;initialize storage for..
  2527.     MOV    Word Ptr CRCVAL,BX    ;..'crc' working value.
  2528.     CALL    RINGFCB            ;move from 'ring' to 'sfcb'
  2529.     MOV    BX,(Offset S@FCB)+12    ;set pointer to source extent field
  2530.     CALL    INITFCB
  2531.     XOR    AL,AL            ;zero fcb 'cr' field
  2532.     MOV    Byte Ptr S@FCB+32,AL
  2533.     MOV    CH,32            ;copy source 'fcb' to destination 'fcb'
  2534.     MOV    BX,(Offset S@FCB)+1    ;from point..
  2535.     MOV    DX,(Offset D@FCB)+1    ;..to point..
  2536.     CALL    MOVE            ;..move across.
  2537.     MOV    DX,(Offset S@FCB)    ;open file for reading
  2538.     MOV    CL,OPEN            ;open function
  2539.     INT    224
  2540.     INC    AL            ; 0ffh --> 00h if bad open
  2541.     JNZ    COPY2            ;if okay, skip error message.
  2542.     CALL    ERMSG
  2543.     DB    'Unable to Open Source',0
  2544.     JMP    NEUTRAL
  2545.  
  2546. COPY2:
  2547.     MOV    AL,Byte Ptr FIRST@M    ;by-pass prompt, drive/user compatibility..
  2548.     OR    AL,AL            ;..test, and disk reset after..
  2549.     JNZ    COPY3M            ;..1st time thru in mass-copy mode.
  2550.     CALL    CPRMPT            ;prompt for drive selection
  2551.     DB    'Copy to DIR: ',0
  2552.     CALL    DEF@D@U
  2553. ; either drives or user areas must be different
  2554.     MOV    AL,Byte Ptr .FCB    ;get requested drive from 'fcb' and..
  2555.     MOV    CH,AL            ;..put into b-reg for..
  2556.     MOV    AL,Byte Ptr S@FCB    ;..comparison.
  2557.     CMP    AL,CH
  2558.     JNZ    COPY3            ;branch if different
  2559.     MOV    AL,Byte Ptr R@U@A    ;requested user area --> rua
  2560.     MOV    CH,AL
  2561.     MOV    AL,Byte Ptr C@U@A    ;current user area --> cua
  2562.     CMP    AL,CH
  2563.     JNZ    COPY3
  2564.     CALL    ERMSG            ;if not, show error condition:
  2565.     DB    'Drives or User Areas must be different',0
  2566.     JMP    NEUTRAL            ;try again?
  2567. COPY3:
  2568.     CALL    RESET            ;make sure disk is read/write
  2569. COPY3M:
  2570.     CALL    ATCMD            ;clear command line
  2571.     CALL    ERMSG 
  2572.     DB    'Copying File ',0
  2573.     MOV    BX,(Offset D@FCB)+1    ;print file name
  2574.     CALL    PRFNSX
  2575.  
  2576.     MOV    AL,Byte Ptr .FCB    ;put requested drive into..
  2577.     MOV    Byte Ptr D@FCB,AL    ;..place in destination fcb.
  2578.     MOV    AL,Byte Ptr R@U@A    ;toggle to..
  2579.     CALL    SET@USR            ;..requested user area.
  2580.     MOV    DX,(Offset D@FCB)    ;search for duplicate
  2581.     MOV    CL,SRCHF        ; 'search first' function
  2582.     INT    224
  2583.     INC    AL            ;if not found, 0ffh --> 00h.  then..
  2584.     JZ    COPY5            ;go to 'make' function for new file.
  2585.  
  2586.     CMP    Byte Ptr MCFLG,'V'    ;verify or auto erase
  2587.     JNE    COPY4M            ;..in mass-copy mode.
  2588.     CALL    CPRMPT            ;CPR2 - if found, ask to replace:
  2589.     DB    'Overwrite Existing File (Y/N)? ',0
  2590.     CALL    KEYIN            ;get answer
  2591.     CMP    AL,'Y'            ;if yes, then..
  2592.     JZ    COPY4M            ;..delete and overlay.
  2593.     CMP    Byte Ptr MFLAG,0    ;zero is mass copy
  2594.     JNZ    NOT_MASS
  2595.     MOV    Byte Ptr FIRST@M,0FFH    ;set first pass flag
  2596.     JMP    M@LP            ;...and re-enter mass copy loop
  2597. NOT_MASS:
  2598.     MOV    AL,Byte Ptr C@U@A    ;reset to..
  2599.     CALL    SET@USR            ;..current user area.
  2600.     JMP    FORWARD            ;if re-copy not wanted, to next position.
  2601. COPY4M:
  2602.     MOV    BX,(Offset D@FCB)    ;pt to FCB
  2603.     CALL    ATTRIB            ;clear bytes in FCB and set attr of file
  2604.     MOV    DX,(Offset D@FCB)    ;delete file already existing
  2605.     MOV    CL,ERASE        ;erase function
  2606.     INT    224
  2607. COPY5:
  2608.     MOV    DX,(Offset D@FCB)    ;create new file and open for writing
  2609.     MOV    CL,MAKE            ;make function
  2610.     INT    224
  2611.     INC    AL            ;if directory full, 0ffh --> 00h.
  2612.     JNZ    COPY6            ;if not, branch.
  2613.     CALL    ERMSG
  2614.     DB    'Destination Directory Full',0
  2615.     JMP    LOOPFN            ;if error, back to ring processor.
  2616. COPY6:
  2617. ;    CALL    ERMSG
  2618. ;    DB    'Copying File ',0
  2619. ;    MOV    BX,(Offset D@FCB)+1    ;print file name
  2620. ;    CALL    PRFNSX
  2621.     MOV    BX,ERADR
  2622.     ADD    BX,26            ;position cursor after file name
  2623.     CALL    GOTOXY
  2624.     XOR    AL,AL            ;clear 'eof'..
  2625.     MOV    Byte Ptr EOFLAG,AL    ;..flag.
  2626. COPY6A:
  2627.     MOV    AL,Byte Ptr C@U@A    ;reset user area..
  2628.     CALL    SET@USR            ;..to current.
  2629.     MOV    BX,0            ;clear current-record..
  2630.     MOV    Word Ptr REC@CNT,BX    ;..counter.
  2631.     MOV    BX,Word Ptr BUFSTART    ;set buffer start pointer..
  2632.     MOV    Word Ptr BUF@PT,BX    ;..to begin pointer.
  2633. ; read source file -- fill buffer memory or stop on 'eof' -- update 'crc'
  2634. ; on-the-fly
  2635. COPY7:
  2636.     MOV    BX,Word Ptr BUF@PT    ;set dma address to buffer pointer
  2637.     XCHG    BX,DX            ; de-pair --> dma address
  2638.     MOV    CL,SETDMA
  2639.     INT    224
  2640.     MOV    DX,(Offset S@FCB)    ;source 'fcb' for reading
  2641.     MOV    CL,READ            ;record read function
  2642.     INT    224
  2643.     OR    AL,AL            ; 00h --> read okay
  2644.     JZ    S@RD@OK
  2645.     DEC    AL            ;eof?
  2646.     JZ    COPY8            ;yes, end-of-file, set 'eof' flag.
  2647.     CALL    ERMSG
  2648.     DB    'Source Read Error',0
  2649.     JMP    LOOPFN
  2650. S@RD@OK:
  2651.     MOV    BX,Word Ptr BUF@PT
  2652.     MOV    CH,128
  2653. COPY7A:
  2654.     MOV    AL,M            ;get character and..
  2655.     CALL    UPDCRC            ;..add to 'crc' value.
  2656.     INC    BX
  2657.     DEC    CH
  2658.     JNZ    COPY7A            ;loop 'till record read finished
  2659.     MOV    BX,Word Ptr BUF@PT    ;bump buffer pointer..
  2660.     MOV    DX,128            ;..by..
  2661.     LAHF                ;..one..
  2662.     ADD    BX,DX
  2663.     SAHF
  2664.     MOV    Word Ptr BUF@PT,BX    ;..record.
  2665.     MOV    BX,Word Ptr REC@CNT    ;bump buffer..
  2666.     LAHF                ;..record count and..
  2667.     INC    BX
  2668.     SAHF
  2669.     MOV    Word Ptr REC@CNT,BX    ;..store.
  2670.     XCHG    BX,DX            ;ready to compare to..
  2671.     MOV    BX,Word Ptr REC@MAX    ;..maximum record count (full-buffer).
  2672.     CALL    CMPDEHL            ;compare
  2673.     JNZ    COPY7            ;if not full, get next record.
  2674.     JMPS    COPY9            ;full, start first write session.
  2675. ; indicate end-of-file read
  2676. COPY8:
  2677.     MOV    AL,TRUE            ;set 'eof' flag
  2678.     MOV    Byte Ptr EOFLAG,AL
  2679. ; write 'read-file' from memory buffer to destination 'written-file'
  2680. COPY9:
  2681.     MOV    AL,Byte Ptr R@U@A    ;set user to requested..
  2682.     CALL    SET@USR            ;..area.
  2683.     MOV    BX,Word Ptr BUFSTART    ;adjust buffer pointer..
  2684.     MOV    Word Ptr BUF@PT,BX    ;..to start address.
  2685. COPY10:
  2686.     MOV    BX,Word Ptr REC@CNT    ;buffer empty?
  2687.     MOV    AL,BH
  2688.     OR    AL,BL
  2689.     JZ    COPY11            ;buffer empty, check 'eof' flag.
  2690.     DEC    BX            ;dec buffer record count for each write
  2691.     MOV    Word Ptr REC@CNT,BX
  2692.     MOV    BX,Word Ptr BUF@PT    ;set up dma address
  2693.     PUSH    BX            ;save for size bump
  2694.     XCHG    BX,DX            ;pointer in de-pair
  2695.     MOV    CL,SETDMA
  2696.     INT    224
  2697.     POP    BX
  2698.     MOV    DX,128            ;bump pointer one record length
  2699.     ADD    BX,DX
  2700.     MOV    Word Ptr BUF@PT,BX
  2701.     MOV    DX,(Offset D@FCB)    ;destination file 'fcb'
  2702.     MOV    CL,WRITE        ;write record function
  2703.     INT    224
  2704.     OR    AL,AL            ; 00h --> write okay
  2705.     JZ    COPY10            ;okay, do next record.  else..
  2706.     CALL    ERMSG            ;..say disk write error.
  2707.     DB    'Copy Disk Full',0
  2708. C@ERA:
  2709.     MOV    DX,(Offset D@FCB)    ;delete..
  2710.     MOV    CL,ERASE        ;..partial..
  2711.     INT    224            ;..from directory.
  2712.     XOR    AL,AL            ;reset 1st-time-thru tag flag..
  2713.     MOV    Byte Ptr FIRST@M,AL    ;..for continuation of mass copying.
  2714.     JMP    LOOPFN            ;back to ring
  2715. COPY11:
  2716.     MOV    AL,Byte Ptr EOFLAG    ;buffer all written, check for 'eof'.
  2717.     OR    AL,AL
  2718.     JNZ    L_C19    
  2719.     JMP    COPY6A            ;branch to read next buffer full
  2720. L_C19:
  2721.     MOV    DX,(Offset D@FCB)    ;point at 'fcb' for file closure
  2722.     MOV    CL,CLOSE
  2723.     INT    224
  2724.     INC    AL            ;if no-close-error then..
  2725.     JNZ    CRC@CMP            ;..compare file crc's.
  2726.     CALL    ERMSG
  2727.     DB    'Copy Close Error',0
  2728.     JMPS    C@ERA
  2729. ; read destination 'written-file' and compare crc's
  2730. CRC@CMP:
  2731.     MOV    BX,Word Ptr CRCVAL    ;transfer 'crc' value to..
  2732.     MOV    Word Ptr CRCVAL2,BX    ;..new storage area.
  2733.     MOV    BX,0            ;clear working storage..
  2734.     MOV    Word Ptr CRCVAL,BX    ;..to continue.
  2735.     MOV    DX,TBUF
  2736.     MOV    CL,SETDMA
  2737.     INT    224
  2738.     MOV    BX,(Offset D@FCB)+12
  2739.     CALL    INITFCB
  2740.     MOV    DX,(Offset D@FCB)
  2741.     MOV    CL,OPEN
  2742.     INT    224
  2743.     INC    AL            ; 0ffh --> 00h if bad open
  2744.     JNZ    L_C20    
  2745.     JMP    BADCRC            ;if bad open, just say 'bad-crc'.
  2746. L_C20:
  2747.     XOR    AL,AL            ;zero 'fcb'..
  2748.     MOV    Byte Ptr D@FCB+32,AL    ;..'cr' field.
  2749. CRCWF1:
  2750.     MOV    DX,(Offset D@FCB)
  2751.     MOV    CL,READ
  2752.     INT    224
  2753.     OR    AL,AL            ;read okay?
  2754.     JZ    D@RD@OK            ;yes, read more.
  2755.     DEC    AL            ;eof?
  2756.     JNZ    L_C21    
  2757.     JMP    FINCRC            ;yes, finish up and make 'crc' comparison.
  2758. L_C21:
  2759.     CALL    ERMSG
  2760.     DB    'Copy Read Error',0
  2761.     JMP    NEUTRAL
  2762. D@RD@OK:
  2763.     MOV    BX,TBUF
  2764.     MOV    CH,128
  2765. CRCWF2:
  2766.     MOV    AL,M            ;get character to..
  2767.     CALL    UPDCRC            ;..add to 'crc' value. 
  2768.     INC    BX
  2769.     DEC    CH
  2770.     JNZ    CRCWF2
  2771.     JMPS    CRCWF1
  2772. ; clear attributes of file (HL) and set attributes on disk
  2773. ATTRIB:
  2774.     PUSH    BX            ;save ptr
  2775.     INC    BX            ;pt to first char
  2776.     MOV    CH,11            ;11 Bytes
  2777. ATTRIB1:
  2778.     MOV    AL,M            ;get byte
  2779.     AND    AL,7FH            ;mask it
  2780.     MOV    M,AL            ;put byte
  2781.     INC    BX            ;pt to next
  2782.     DEC    CH            ;count down
  2783.     JNZ    ATTRIB1
  2784.     POP    DX            ;pt to FCB
  2785.     MOV    CL,ATTR
  2786.     INT    224
  2787.     RET
  2788. ; crc subroutines
  2789. ; initialize tables for fast crc calculations
  2790. INITCRC:
  2791.     MOV    BX,(Offset CRCTBL)
  2792.     MOV    CL,0            ;table index
  2793. GLOOP:
  2794.     XCHG    BX,DX
  2795.     MOV    BX,0            ;initialize crc register pair
  2796.     MOV    AL,CL
  2797.     PUSH    CX            ;save index in c-reg
  2798.     MOV    CH,8
  2799.     XOR    AL,BH
  2800.     MOV    BH,AL
  2801. LLOOP:
  2802.     SHL    BX,1
  2803.     JNB    LSKIP
  2804.     MOV    AL,10H            ;generator is x^16 + x^12 + x^5 + x^0 as..
  2805.     XOR    AL,BH            ;..recommended by ccitt for asynchronous..
  2806.     MOV    BH,AL            ;..communications.  produces the same..
  2807.     MOV    AL,21H            ;..results as public domain programs..
  2808.     XOR    AL,BL            ;..chek, comm7, mdm7, and modem7.
  2809.     MOV    BL,AL
  2810. LSKIP:
  2811.     DEC    CH
  2812.     JNZ    LLOOP
  2813.     POP    CX
  2814.     XCHG    BX,DX            ;de-pair now has crc, hl pointing into table.
  2815.     MOV    M,DH            ;store high byte of crc..
  2816.     INC    BH
  2817.     MOV    M,DL            ;..and store low byte.
  2818.     DEC    BH
  2819.     LAHF                ;move to next table entry
  2820.     INC    BX
  2821.     SAHF
  2822.     INC    CL            ;next index
  2823.     JNZ    GLOOP
  2824.     RET
  2825. UPDCRC:
  2826.     PUSH    CX            ;update 'crc'..
  2827.     PUSH    BX            ;..accumulator..
  2828.     MOV    BX,Word Ptr CRCVAL    ;pick up partial remainder
  2829.     XCHG    BX,DX            ;de-pair now has partial
  2830.     MOV    CH,0
  2831.     XOR    AL,DH
  2832.     MOV    CL,AL
  2833.     MOV    BX,(Offset CRCTBL)
  2834.     ADD    BX,CX
  2835.     MOV    AL,M
  2836.     XOR    AL,DL
  2837.     MOV    DH,AL
  2838.     INC    BH
  2839.     MOV    DL,M
  2840.     XCHG    BX,DX
  2841.     MOV    Word Ptr CRCVAL,BX
  2842.     POP    BX
  2843.     POP    CX
  2844.     RET
  2845. FINCRC:
  2846.     MOV    AL,Byte Ptr C@U@A    ;reset user from 'requested'..
  2847.     CALL    SET@USR            ;..to 'current' area.
  2848.     MOV    BX,Word Ptr CRCVAL    ;put written-file 'crc' into..
  2849.     XCHG    BX,DX            ;..de-pair.
  2850.     MOV    BX,Word Ptr CRCVAL2    ;put read-file 'crc' and..
  2851.     CALL    CMPDEHL            ;..compare 'de/hl' for equality.
  2852.     JNZ    BADCRC            ;if not zero, show copy-error message.
  2853.     CALL    ILPRT            ;if zero, show 'verified' message.
  2854.     DB    ' -- CRC Verified',0
  2855.     MOV    AL,Byte Ptr MFLAG    ;if not mass-copy mode, return..
  2856.     OR    AL,AL            ;..to next 'ring' position.
  2857.     JZ    L_C22    
  2858.     JMP    FORWARD            ;else..
  2859. L_C22:
  2860.     NOT    AL            ;..set 1st-time-thru flag..
  2861.     MOV    Byte Ptr FIRST@M,AL    ;..and..
  2862.     JMP    M@LP            ;..get next file to copy, if one.
  2863. BADCRC:
  2864.     CALL    ERMSG
  2865.     DB    'Error on CRC compare',0
  2866.     JMP    FORWARD            ;move to next 'ring' position
  2867. ; w o r k h o r s e   r o u t i n e s
  2868. ; inline print of message
  2869. ILPRT:
  2870.     MOV    BP,SP            ;save hl, get msg pointer.
  2871.     XCHG    BX,[BP]
  2872. ILPLP:
  2873.     MOV    AL,M            ;get character
  2874.     INC    BX            ;pt to next
  2875.     AND    AL,7FH            ;strip type bits
  2876.     JZ    ILPLP1
  2877.     CALL    TTYPE            ;show on console
  2878.     JMPS    ILPLP
  2879. ILPLP1:
  2880.     MOV    BP,SP            ;set hl-pair and..
  2881.     XCHG    BX,[BP]
  2882.     RET                ;..return past message.
  2883. ; output 'crlf' to console
  2884. CRLF:
  2885.     MOV    AL,CR
  2886.     CALL    TTYPE
  2887.     MOV    AL,LF
  2888. ; conout routine
  2889. TTYPE:
  2890.     LAHF
  2891.     XCHG    AL,AH
  2892.     PUSH    AX
  2893.     XCHG    AL,AH
  2894.     PUSH    CX
  2895.     PUSH    DX
  2896.     PUSH    BX
  2897.     LAHF                ; check for flow control
  2898.     XCHG    AL,AH
  2899.     PUSH    AX
  2900.     XCHG    AL,AH
  2901.     CALL    CST            ; BIOS console status
  2902.     OR    AL,AL            ; 0 means nothing
  2903.     JZ    TYPE1
  2904.     CALL    CIN            ; BIOS console input
  2905.     CMP    AL,CTRLS        ; pause?
  2906.     JNZ    TYPE1
  2907.     CALL    CIN            ; BIOS console input
  2908. TYPE1:
  2909.     POP    AX            ; get char
  2910.     XCHG    AL,AH
  2911.     MOV    DL,AL
  2912.     MOV    CL,WRCON
  2913.     INT    224
  2914.     POP    BX
  2915.     POP    DX
  2916.     POP    CX
  2917.     POP    AX
  2918.     XCHG    AL,AH
  2919.     SAHF
  2920.     RET
  2921.  
  2922. ; direct I/O
  2923. CST:    ;Console status
  2924.     PUSH    DX
  2925.     PUSH    BX
  2926.     MOV    DL,0FFH
  2927.     MOV    CL,DIRCON
  2928.     INT    224
  2929.     POP    BX
  2930.     POP    DX
  2931.     RET
  2932.  
  2933. CIN:    ;Input from console - no echo
  2934.     PUSH    DX
  2935.     PUSH    BX
  2936. CIN0:    MOV    DL,0FFH
  2937.     MOV    CL,DIRCON
  2938.     INT    224
  2939.     OR    AL,AL
  2940.     JZ    CIN0
  2941.     POP    BX
  2942.     POP    DX
  2943.     RET
  2944. ; output 'crlf' to printer
  2945. LCRLF:
  2946.     MOV    AL,CR
  2947.     CALL    LOUT
  2948.     MOV    AL,LF
  2949. ; printer routine
  2950. LOUT:
  2951.     LAHF
  2952.     XCHG    AL,AH
  2953.     PUSH    AX
  2954.     XCHG    AL,AH
  2955.     PUSH    CX
  2956.     PUSH    DX
  2957.     PUSH    BX
  2958.     MOV    DL,AL
  2959.     MOV    CL,LLIST
  2960.     INT    224
  2961.     POP    BX
  2962.     POP    DX
  2963.     POP    CX
  2964.     POP    AX
  2965.     XCHG    AL,AH
  2966.     SAHF
  2967.     RET
  2968. ; crt clear-line function
  2969. CLR@L:
  2970.     MOV    AL,CR
  2971.     CALL    TTYPE
  2972.     MOV    CH,30            ;blank # of characters on line
  2973.     MOV    AL,' '
  2974. CL@LP:
  2975.     CALL    TTYPE
  2976.     DEC    CH
  2977.     JNZ    CL@LP
  2978.     RET
  2979. ; conin routine (waits for response)
  2980. KEYIN:
  2981.     MOV    CL,RDCON
  2982.     INT    224
  2983. ; convert character in a-reg to upper case
  2984. UCASE:
  2985.     CMP    AL,61H            ;less than small 'a'?
  2986.     JNB    L_C23    
  2987.     RET                ;if so, no convert needed.
  2988. L_C23:
  2989.     CMP    AL,7AH+1        ; >small 'z'?
  2990.     JNAE    L_C24    
  2991.     RET                ;if so, ignore.
  2992. L_C24:
  2993.     AND    AL,5FH            ;otherwise convert
  2994.     RET
  2995. ; direct console input w/o echo (waits for input)
  2996. DKEYIN:
  2997.     CALL    CIN            ;get char from BIOS
  2998.     AND    AL,7FH            ;mask MSB
  2999.     JMPS    UCASE            ;capitalize
  3000. ; convert keyboard input to upper case
  3001. CONVERT:
  3002.     MOV    BX,(Offset CMDBUF)+1    ; 'current keyboard buffer length'..
  3003.     MOV    CH,M            ;..to b-reg.
  3004.     MOV    AL,CH
  3005.     OR    AL,AL            ;if zero length, skip conversion.
  3006.     JNZ    L_C25    
  3007.     JMP    COMCAN
  3008. L_C25:
  3009. CONVLP:
  3010.     LAHF                ;point at character to capitalize
  3011.     INC    BX
  3012.     SAHF
  3013.     MOV    AL,M
  3014.     CALL    UCASE
  3015.     MOV    M,AL            ;put back into buffer
  3016.     DEC    CH
  3017.     JNZ    CONVLP
  3018.     RET
  3019. ; fill buffer with 'spaces' with count in b-reg
  3020. FILL:
  3021.     MOV    M,' '            ;put in space character
  3022.     LAHF
  3023.     INC    BX
  3024.     SAHF
  3025.     DEC    CH
  3026.     JNZ    FILL            ;no, branch.
  3027.     RET
  3028. ; ignore leading spaces (ls) in buffer, length in c-reg.
  3029. UNSPACE:
  3030.     MOV    SI,DX            ;get character
  3031.     MOV    AL,[SI]
  3032.     CMP    AL,' '
  3033.     JZ    L_C26    
  3034.     RET                ;not blank, a file is entered.
  3035. L_C26:
  3036.     INC    DX            ;to next character
  3037.     DEC    CL
  3038.     JNZ    L_C27    
  3039.     JMP    COMCAN            ;all spaces --> command recovery error
  3040. L_C27:
  3041.     JMPS    UNSPACE
  3042. ; check for legal cp/m filename character -- return with carry set if illegal
  3043. CKLEGAL:
  3044.     MOV    SI,DX            ;get character from de-pair
  3045.     MOV    AL,[SI]
  3046.     INC    DX            ;point at next character
  3047.     CMP    AL,' '            ;less than space?
  3048.     JNB    L_C28    
  3049.     RET                ;return carry if unpermitted character
  3050. L_C28:
  3051.     PUSH    BX
  3052.     PUSH    CX
  3053.     CMP    AL,'['            ;if greater than 'z', exit with..
  3054.     JNB    CKERR            ;..carry set.
  3055.     MOV    CH,(Offset CHR@TEND)-(Offset CHR@TBL)
  3056.     MOV    BX,(Offset CHR@TBL)
  3057. CHR@LP:
  3058.     CMP    AL,M
  3059.     JZ    CKERR
  3060.     INC    BX
  3061.     DEC    CH
  3062.     JNZ    CHR@LP
  3063.     OR    AL,AL            ;clear carry for good character
  3064.     POP    CX
  3065.     POP    BX
  3066.     RET
  3067. CKERR:
  3068.     POP    CX
  3069.     POP    BX
  3070.     STC                ;error exit with carry set
  3071.     RET
  3072. L_C29    EQU    $
  3073.     DSEG
  3074.     ORG    Offset L_C29
  3075. CHR@TBL    RS    0
  3076.     DB    ',',':',';','<','=','>'    ;invalid character table
  3077. L_C30    EQU    $
  3078.     CSEG
  3079.     ORG    Offset L_C30
  3080. CHR@TEND:
  3081.     RS    0
  3082. ; print file name in S$FCB
  3083. PRFNSX:
  3084.     PUSH    BX            ;save regs
  3085.     PUSH    CX
  3086.     JMPS    PRFNS0
  3087. PRFNS:
  3088.     PUSH    BX            ;affect only PSW
  3089.     PUSH    CX
  3090.     MOV    BX,(Offset S@FCB)+1
  3091. PRFNS0:
  3092.     CALL    PRFN            ;print file name
  3093.     POP    CX            ;restore
  3094.     POP    BX
  3095.     RET
  3096. ; print file name pted to by HL
  3097. PRFN:
  3098.     MOV    CH,8            ;8 chars
  3099.     CALL    PRFNS1
  3100.     MOV    AL,'.'
  3101.     CALL    TTYPE
  3102.     MOV    CH,3            ;file type and fall thru
  3103. PRFNS1:
  3104.     MOV    AL,M            ;get char
  3105.     CALL    TTYPE
  3106.     LAHF                ;pt to next
  3107.     INC    BX
  3108.     SAHF
  3109.     DEC    CH
  3110.     JNZ    PRFNS1
  3111.     RET
  3112.  
  3113. ; print filename  & tag in reverse video if at cursor
  3114. AC@PRFN:
  3115.     IF    ENH@VID
  3116.     CALL    CUR@VID
  3117.     CALL    PRFN            ;print file name
  3118.     CMP    M,'*'            ;is it tagged?
  3119.     JNE    AC@RET
  3120.     MOV    AL,M            ;print tag
  3121.     CALL    TTYPE
  3122. AC@RET:
  3123.     CALL     STD@VID
  3124.     RET
  3125.     ENDIF    ;ENH@VID
  3126.  
  3127.     IF  NOT ENH@VID
  3128.     CALL    PRFN
  3129.     MOV    AL,M            ;print tag
  3130.     JMP    TTYPE
  3131.     ENDIF    ;NOT ENH@VID
  3132.  
  3133. ; print filename if not at  cursor
  3134. NC@PRFN:
  3135.     CMP    Byte Ptr .11[BX],'*'    ;is it tagged?
  3136.     JNZ    STD            ;use std video if not tagged
  3137.     CALL    TAG@VID
  3138.     JMPS    NO@STD
  3139. STD:    CALL    STD@VID
  3140. NO@STD:    CALL    PRFN            ;print file name
  3141.     MOV    AL,M
  3142.     CALL    TTYPE
  3143.     JMP     STD@VID
  3144.  
  3145. ; filename from 'ring' to 'sfcb'
  3146. RINGFCB:
  3147.     MOV    BX,Word Ptr RINGPOS    ;move name from ring to source 'fcb'
  3148.     MOV    DX,(Offset S@FCB)    ;place to move filename and..
  3149.     MOV    CH,12            ;..amount to move.
  3150. ; move subroutine -- move b-reg # of bytes from hl-pair to de-pair
  3151. MOVE:
  3152.     MOV    AL,M            ;get hl-pair referenced source byte
  3153.     AND    AL,7FH            ;strip cp/m 2.x attributes
  3154.     MOV    SI,DX            ;put to de-pair referenced destination
  3155.     MOV    [SI],AL
  3156.     LAHF                ;fix pointers for next search
  3157.     INC    BX
  3158.     SAHF
  3159.     LAHF
  3160.     INC    DX
  3161.     SAHF
  3162.     DEC    CH
  3163.     JNZ    MOVE
  3164.     RET
  3165. ; initialize 'fcb' cp/m system fields (entry with hl-pair pointing to 'fcb')
  3166. INITFCB:
  3167.     MOV    CH,4            ;fill ex, s1, s2, rc counters with zeros.
  3168. INITLP:
  3169.     MOV    M,0            ;put zero (null) in memory
  3170.     LAHF
  3171.     INC    BX
  3172.     SAHF
  3173.     DEC    CH
  3174.     JNZ    INITLP
  3175.     RET
  3176. ; disk system reset -- login requested drive
  3177. RESET:
  3178.     MOV    CL,INQDISK        ;determine and..
  3179.     INT    224            ;..save..
  3180.     MOV    Byte Ptr C@DR,AL    ;..current drive.
  3181.     MOV    CL,RESETDK        ;reset system
  3182.     INT    224
  3183.     MOV    AL,Byte Ptr R@DR    ;make requested drive..
  3184. SET@DR:
  3185.     MOV    DL,AL            ;..current.
  3186.     MOV    CL,LOGIN
  3187.     INT    224            ;return to caller
  3188.     RET
  3189. ; set/reset (or get) user area (call with binary user area in a-reg)
  3190. SET@USR:
  3191.     MOV    DL,AL            ; 0 --> 0, 1 --> 1, etc.
  3192. GET@USR:
  3193.     MOV    CL,SGUSER
  3194.     INT    224            ;return to caller
  3195.     RET
  3196. ; compare de-pair to hl-pair and set flags accordingly
  3197. CMPDEHL:
  3198.     MOV    AL,DH            ;see if high bytes set flags
  3199.     CMP    AL,BH
  3200.     JZ    L_C31    
  3201.     RET                ;return if not equal
  3202. L_C31:
  3203.     MOV    AL,DL
  3204.     CMP    AL,BL            ;low bytes set flags instead
  3205.     RET
  3206. ; shift hl-pair b-reg bits (-1) to right (divider routine)
  3207. SHIFTLP:
  3208.     DEC    CH
  3209.     JNZ    L_C32
  3210.     RET
  3211. L_C32:
  3212.     MOV    AL,BH
  3213.     OR    AL,AL
  3214.     RCR    AL,1
  3215.     MOV    BH,AL
  3216.     MOV    AL,BL
  3217.     RCR    AL,1
  3218.     MOV    BL,AL
  3219.     JMPS    SHIFTLP
  3220. ; decimal pretty print (h-reg contains msb; l-reg, the lsb.)
  3221. DECOUT:
  3222.     MOV    AL,5            ;set leading space count
  3223.     MOV    Byte Ptr LDSP,AL
  3224. DECOU1:
  3225.     LAHF
  3226.     XCHG    AL,AH
  3227.     PUSH    AX
  3228.     PUSH    CX
  3229.     PUSH    DX
  3230.     PUSH    BX
  3231.     MOV    AL,Byte Ptr LDSP    ;count down
  3232.     DEC    AL
  3233.     MOV    Byte Ptr LDSP,AL
  3234.     MOV    CX,-10            ;radix
  3235.     MOV    DX,-1
  3236. DECOU2:
  3237.     ADD    BX,CX            ;sets..
  3238.     INC    DX
  3239.     JB    DECOU2            ;..carry.    
  3240.     MOV    CX,10
  3241.     ADD    BX,CX
  3242.     XCHG    BX,DX
  3243.     MOV    AL,BH
  3244.     OR    AL,BL
  3245.     JZ    L_C33    
  3246.     CALL    DECOU1            ; (recursive)
  3247. L_C33:
  3248.     MOV    AL,Byte Ptr LDSP    ; any spaces?
  3249.     OR    AL,AL            ; 0=none
  3250.     JZ    DECOU4
  3251.     MOV    CH,AL            ; count in B
  3252.     MOV    AL,' '
  3253. DECOU3:
  3254.     CALL    TTYPE
  3255.     DEC    CH
  3256.     JNZ    DECOU3
  3257.     XOR    AL,AL            ;A=0
  3258.     MOV    Byte Ptr LDSP,AL    ;set flag
  3259. DECOU4:
  3260.     MOV    AL,DL
  3261.     ADD    AL,'0'            ;make ascii
  3262.     CALL    TTYPE
  3263.     POP    BX
  3264.     POP    DX
  3265.     POP    CX
  3266.     POP    AX
  3267.     XCHG    AL,AH
  3268.     SAHF
  3269.     RET
  3270. ; determine free storage remaining on selected drive
  3271. FRESTOR:
  3272.     MOV    CL,INQDISK        ;determine current drive
  3273.     INT    224            ;returns 0 as a:, 1 as b:, etc.
  3274.     INC    AL            ;make 1 --> a:, 2 --> b:, etc.
  3275.     MOV    Byte Ptr .FCB,AL
  3276.     MOV    CL,GETPARM        ;current disk parameter block
  3277.     INT    224
  3278.     INC    BX            ;bump to..
  3279.     INC    BX
  3280.     MOV    AL,ES:M            ;..block shift factor.
  3281.     MOV    Byte Ptr BSHIFTF,AL    ; 'bsh'
  3282.     INC    BX            ;bump to..
  3283.     MOV    AL,ES:M            ;..block mask.
  3284.     MOV    Byte Ptr B@MASK,AL    ; 'blm'
  3285.     INC    BX            ;bump to..
  3286.     INC    BX            ;..get..
  3287.     MOV    DL,ES:M            ;..maximum block number..
  3288.     INC    BX            ;..double..
  3289.     MOV    DH,ES:M            ;..byte.
  3290.     XCHG    BX,DX
  3291.     MOV    Word Ptr B@MAX,BX    ; 'dsm'
  3292.     MOV    CL,INQALC        ;address of cp/m allocation vector
  3293.     INT    224
  3294.     XCHG    BX,DX            ;get its length
  3295.     MOV    BX,Word Ptr B@MAX
  3296.     INC    BX
  3297.     MOV    CX,0            ;initialize block count to zero
  3298. GSPBYT:
  3299.     PUSH    DX            ;save allocation address
  3300.     MOV    SI,DX
  3301.     MOV    AL,ES:[SI]
  3302.     MOV    DL,8            ;set to process 8 bits (blocks)
  3303. GSPLUP:
  3304.     RCL    AL,1            ;test bit
  3305.     JB    NOT@FRE
  3306.     INC    CX
  3307. NOT@FRE:
  3308.     MOV    DH,AL            ;save bits
  3309.     DEC    BX
  3310.     MOV    AL,BL
  3311.     OR    AL,BH
  3312.     JZ    END@ALC            ;quit if out of blocks
  3313.     MOV    AL,DH            ;restore bits
  3314.     DEC    DL            ;count down 8 bits
  3315.     JNZ    GSPLUP            ;branch to do another bit
  3316.     POP    DX            ;bump to next count..
  3317.     INC    DX            ;..of allocation vector.
  3318.     JMPS    GSPBYT            ;process it
  3319. END@ALC:
  3320.     POP    DX            ;clear alloc vector pointer from stack
  3321.     MOV    BL,CL            ;copy # blocks to hl-pair
  3322.     MOV    BH,CH
  3323.     MOV    AL,Byte Ptr BSHIFTF    ;get block shift factor
  3324.     SUB    AL,3            ;convert from sectors to thousands (k)
  3325.     JZ    PRT@FRE            ;skip shifts if 1k blocks
  3326. FREK@LP:
  3327.     SHL    BX,1            ;multiply blocks by k-bytes per block
  3328.     DEC    AL            ;multiply by 2, 4, 8, or 16.
  3329.     JNZ    FREK@LP
  3330. PRT@FRE:
  3331.     MOV    Word Ptr DISKSP,BX    ;save disk space
  3332.     RET
  3333. ;
  3334. ;  Print free space on disk
  3335. ;
  3336. PRINT@FRE:
  3337.     CALL    ERMSG            ;position and set flags
  3338.     DB    0
  3339.     MOV    BX,Word Ptr DISKSP
  3340.     CALL    DECOUT            ; # of free k-bytes in hl-pair
  3341.     CALL    ILPRT
  3342.     DB    'K Bytes on Disk',0
  3343.     RET
  3344. ;
  3345. ;
  3346. ;
  3347. ;
  3348. ;
  3349. ZDNFIND:
  3350.     PUSH    DX            ; SAVE DE
  3351.     MOV    Word Ptr DIRNAME,BX    ; SAVE DIRECTORY NAME AWAY
  3352.     MOV    CL,INQDISK        ; SAVE CURRENT POSITION
  3353.     INT    224
  3354.     MOV    Byte Ptr DISK,AL
  3355.     MOV    Byte Ptr T@DR,AL
  3356.     MOV    DL,GET
  3357.     CALL    GET@USR
  3358.     MOV    Byte Ptr USER,AL
  3359.     MOV    BX,Word Ptr DIRNAME    ; PT TO NAME
  3360.     JMPS    SVDISK            ; CHECK DU FORM FIRST
  3361. ;
  3362. ;  LOOK AT START OF DU: FORM
  3363. ;    ON ENTRY, HL PTS TO FIRST CHAR OF DIRECTORY NAME
  3364. ;
  3365. SVDISK:
  3366.     MOV    CL,Byte Ptr MDISK    ; GET MAX DISK
  3367. ;    INC    CL            ; +1 FOR LATER COMPARE
  3368.     MOV    AL,M            ; GET DISK LETTER
  3369.     CMP    AL,'A'            ; DIGIT?
  3370.     JB     USERCK            ; IF NO DIGIT, MUST BE USER OR COLON
  3371.     SUB    AL,'A'            ; CONVERT TO NUMBER
  3372.     CMP    AL,CL            ; LIMIT?
  3373.     JNAE     L_D3    
  3374.     MOV    CL,MDRIVE
  3375.     DEC    CL
  3376.     CMP    CL,AL
  3377.     JE    L_D3
  3378.     JMP    DIRNXX            ; NAME IF OUT OF LIMIT
  3379. L_D3:
  3380.     MOV    Byte Ptr DISK,AL    ; SAVE DISK
  3381.     INC    BX            ; PT TO NEXT CHAR
  3382. ;
  3383. ;  CHECK FOR USER
  3384. ;
  3385. USERCK:
  3386.     MOV    AL,M            ; GET POSSIBLE USER NUMBER
  3387.     CMP    AL,':'            ; NO USER NUMBER
  3388.     JZ    DIRNX            ; EXIT IF SO
  3389.     CMP    AL,' '            ; NO USER NUMBER
  3390.     JZ    DIRNX
  3391.     OR    AL,AL
  3392.     JZ    DIRNX
  3393.     XOR    AL,AL            ; ZERO USER NUMBER
  3394.     MOV    CH,AL            ; B=ACCUMULATOR FOR USER NUMBER
  3395. USRLOOP:
  3396.     MOV    AL,M            ; GET DIGIT
  3397.     INC    BX            ; PT TO NEXT
  3398.     CMP    AL,':'            ; DONE?
  3399.     JZ    USRDN
  3400.     CMP    AL,' '            ; DONE?
  3401.     JZ    USRDN
  3402.     SUB    AL,'0'            ; CONVERT TO BINARY
  3403.     JB    DIRNXX            ; NAME IF USER NUMBER ERROR
  3404.     CMP    AL,10
  3405.     JNB    DIRNXX
  3406.     MOV    CL,AL            ; NEXT DIGIT IN C
  3407.     MOV    AL,CH            ; OLD NUMBER IN A
  3408.     ADD    AL,AL            ; *2
  3409.     ADD    AL,AL            ; *4
  3410.     ADD    AL,CH            ; *5
  3411.     ADD    AL,AL            ; *10
  3412.     ADD    AL,CL            ; *10+NEW DIGIT
  3413.     MOV    CH,AL            ; RESULT IN B
  3414.     JMPS    USRLOOP
  3415. USRDN:
  3416.     MOV    AL,CH            ; GET NEW USER NUMBER
  3417.     CMP    AL,32            ; WITHIN RANGE?
  3418.     JNB    DIRNXX            ; NAME IF OUT OF RANGE
  3419.     MOV    Byte Ptr USER,AL    ; SAVE IN FLAG
  3420. ;
  3421. ;  VALID EXIT -- FOUND IT, SO LOAD BC AND EXIT FLAG; ON ENTRY, HL PTS TO :
  3422. ;
  3423. DIRNX:
  3424.     MOV    AL,Byte Ptr USER    ; RETURN USER IN C, DISK IN B
  3425.     MOV    CL,AL
  3426.     MOV    AL,Byte Ptr DISK
  3427.     MOV    CH,AL
  3428.     MOV    AL,0FFH            ; SET NO ERROR
  3429.     OR    AL,AL            ; SET FLAGS
  3430.     POP    DX            ; RESTORE DE
  3431.     RET
  3432. ;
  3433. ;  INVALID EXIT -- NOT FOUND OR ERROR
  3434. ;    NO VALID RETURN PARAMETERS (BC, HL)
  3435. ;
  3436. DIRNERR:
  3437.     XOR    AL,AL            ; ERROR CODE
  3438.     MOV    Byte Ptr DNLOAD,AL    ; SET LOAD FLAG TO NO LOAD
  3439.     POP    DX            ; RESTORE DE
  3440.     RET
  3441. DIRNXX:
  3442.     POP    DX
  3443.     XOR    AL,AL
  3444.     RET
  3445.  
  3446. ;
  3447. ;  OPEN FILE FOR GET
  3448. ;
  3449. FIOPEN:
  3450.     PUSH    DX
  3451.     MOV    CL,OPEN            ; OPEN FILE
  3452.     INT    224
  3453.     POP    DX
  3454. FIO1:
  3455.     MOV    CL,READ            ; READ FIRST BLOCK
  3456.     INT    224
  3457.     MOV    BX,TBUF            ; SET PTR
  3458.     MOV    Word Ptr FIPTR,BX
  3459.     RET
  3460. ;
  3461. ;  GET NEXT BYTE FROM FILE
  3462. ;
  3463. FGET:
  3464.     PUSH    BX            ; SAVE REGS
  3465.     PUSH    DX
  3466.     PUSH    CX
  3467.     MOV    BX,Word Ptr FIPTR    ; PT TO NEXT CHAR
  3468.     MOV    AL,M            ; GET IT
  3469.     MOV    Byte Ptr FICHAR,AL    ; SAVE IT
  3470.     LAHF                ; PT TO NEXT
  3471.     INC    BX
  3472.     SAHF
  3473.     MOV    Word Ptr FIPTR,BX    ; SET PTR
  3474.     MOV    DX,TBUF+80H        ; END OF BUFFER?
  3475.     CALL    CMPDEHL            ; COMPARE
  3476.     JNZ    FGETD            ; DONE IF NOT
  3477.     MOV    DX,(Offset S@FCB)    ; PT TO FCB
  3478.     CALL    FIO1            ; READ BLOCK AND SET PTR
  3479.     OR    AL,AL            ; SET FLAG (NZ = ERROR)
  3480.     JMPS    FGETD1
  3481. FGETD:
  3482.     XOR    AL,AL            ; NO ERROR (Z)
  3483. FGETD1:
  3484.     POP    CX            ; GET REGS
  3485.     POP    DX
  3486.     POP    BX
  3487.     MOV    AL,Byte Ptr FICHAR    ; GET CHAR
  3488.     RET
  3489. ; message routines
  3490. ; print VFILER banner
  3491. BANNER:
  3492.     CALL    CLS            ;clear screen
  3493.     MOV    BX,BANADR
  3494.     CALL    GOTOXY
  3495.     CALL    ILPRT            ;print banner
  3496.     DB    '      VFILER  CP/M-86 Ver '
  3497.     DB    VERS/10+'0','.',(VERS MOD 10)+'0'
  3498.     DB    0
  3499.     RET
  3500. ; home the cursor
  3501. CUR@FIRST:
  3502.     MOV    BX,CURHOME        ; HOME ADDRESS
  3503.     MOV    Word Ptr CURAT,BX    ; SET CURSOR POSITION
  3504.     JMP    GOTOXY
  3505. ; last file position
  3506. CUR@LAST:
  3507.     MOV    BX,Word Ptr RINGPOS    ; ADVANCE
  3508.     MOV    Word Ptr LOCPOS,BX    ; SET LOCAL POSITION
  3509. CL0:
  3510.     MOV    DX,13
  3511.     LAHF
  3512.     ADD    BX,DX
  3513.     RCR    SI,1
  3514.     SAHF
  3515.     RCL    SI,1
  3516.     XCHG    BX,DX
  3517.     MOV    BX,Word Ptr LOCEND    ; END OF LOCAL RING?
  3518.     CALL    CMPDEHL
  3519.     JNZ    L_C34
  3520.     RET
  3521. L_C34:
  3522.     XCHG    BX,DX            ; NEW POSITION
  3523.     MOV    Word Ptr LOCPOS,BX
  3524.     PUSH    BX            ; SAVE POSITION
  3525.     CALL    CUR@NEXT        ; ADVANCE CURSOR
  3526.     POP    BX            ; GET POSITION
  3527.     JMPS    CL0
  3528. ; advance the cursor
  3529. CUR@NEXT:
  3530.     MOV    BX,Word Ptr CURAT    ; COMPUTE NEW POSITION
  3531.     MOV    AL,BL            ; CHECK FOR NEW LINE
  3532.     ADD    AL,19            ; SIZE OF EACH ENTRY
  3533.     CMP    AL,70
  3534.     JNB    CN1            ; ADVANCE TO NEXT LINE
  3535.     MOV    BL,AL            ; NEW POSITION
  3536.     MOV    Word Ptr CURAT,BX
  3537.     JMP    GOTOXY
  3538. CN1:
  3539.     MOV    AL,BH            ; GET LINE
  3540.     MOV    BX,CURHOME        ; GET COL
  3541.     MOV    BH,AL            ; SET LINE AND FALL GO TO CUR$DOWN
  3542.     MOV    Word Ptr CURAT,BX
  3543.     JMPS    CUR@DOWN
  3544. ; back up the cursor
  3545. CUR@BACK:
  3546.     MOV    BX,CURHOME        ; GET HOME
  3547.     XCHG    BX,DX            ; ... IN DE
  3548.     MOV    BX,Word Ptr CURAT
  3549.     CALL    CMPDEHL            ; COMPARE
  3550.     JZ    CUR@LAST        ; GOTO END IF LAST
  3551.     MOV    AL,BL            ; CHECK FOR FIRST COL
  3552.     CMP    AL,DL
  3553.     JZ    CB1
  3554.     SUB    AL,19            ; BACK UP ONE COL
  3555.     MOV    BL,AL
  3556.     MOV    Word Ptr CURAT,BX    ; NEW POS
  3557.     JMP    GOTOXY
  3558. CB1:
  3559.     MOV    AL,DL            ; GET HOME COL
  3560.     ADD    AL,19*3            ; GET LAST COL
  3561.     MOV    BL,AL
  3562.     DEC    BH            ; PREV LINE
  3563.     MOV    Word Ptr CURAT,BX
  3564.     JMP    GOTOXY
  3565. ; move cursor down one line
  3566. CUR@DOWN:
  3567.     MOV    BX,CURHOME        ; GET HOME ADDRESS
  3568.     MOV    CH,BH            ; LINE IN B
  3569.     MOV    BX,Word Ptr CURAT    ; GET CURRENT ADDRESS
  3570.     INC    BH            ; MOVE DOWN
  3571.     MOV    AL,BH            ; CHECK FOR TOO FAR
  3572.     SUB    AL,CH
  3573.     CMP    AL,EPS/4
  3574.     JNB    CD1
  3575.     MOV    Word Ptr CURAT,BX    ; OK, SO SET POSITION
  3576.     JMP    GOTOXY
  3577. CD1:
  3578.     MOV    AL,BL            ; GET COL
  3579.     MOV    BX,CURHOME
  3580.     MOV    BL,AL
  3581.     MOV    Word Ptr CURAT,BX
  3582.     JMP    GOTOXY
  3583. ; refresh screen
  3584. REFRESH:
  3585.     MOV    BX,Word Ptr CURAT    ; SAVE CURSOR AND RING POSITIONS
  3586.     MOV    Word Ptr SCURAT,BX
  3587.     MOV    BX,Word Ptr RINGPOS
  3588.     MOV    Word Ptr SRINGPOS,BX
  3589.     CALL    CLS            ; CLEAR SCREEN
  3590.     CALL    CUR@OFF            ; TURN OFF TERM. CURSOR
  3591.     CALL    BANNER            ; PRINT BANNER
  3592.     CALL    NEWPOS            ; DISPLAY FILES
  3593.     MOV    BX,CPMADR        ; COMMAND PROMPT MESSAGE
  3594.     CALL    GOTOXY
  3595.     CALL    ILPRT            ; PROMPT WITH DRIVE PREFIX
  3596. LOG@DU@MSG:
  3597.     DB    '   :  '
  3598.     DB    'Command (? for Help)?',0
  3599.     MOV    BX,SDMADR        ; SCREEN DIRECTORY MESSAGE
  3600.     CALL    GOTOXY
  3601.     CALL    ILPRT
  3602.     DB    '-- Screen Directory --',0
  3603.     MOV    BX,FNADR        ; PT TO WHERE FILE NAME IS PRINTED
  3604.     MOV    BL,1            ; COL 1 FOR THIS MESSAGE
  3605.     CALL    GOTOXY            ; GO THERE
  3606.     CALL    ILPRT
  3607.     DB    'Current File:',0
  3608.     MOV    BX,Word Ptr SCURAT    ; RESTORE CURSOR AND RING POSITIONS
  3609.     MOV    Word Ptr CURAT,BX
  3610.     MOV    BX,Word Ptr SRINGPOS
  3611.     MOV    Word Ptr RINGPOS,BX
  3612.     CALL    SETCUR            ; RESTORE CURSOR ON SCREEN
  3613.     CALL    CUR@ON            ; TURN ON TERM. CURSOR
  3614.     RET
  3615.  
  3616. ; refresh file display
  3617. NEWPOS:
  3618.     CALL    CUR@FIRST        ; POSITION CURSOR AT FIRST POSITION
  3619.     MOV    BX,Word Ptr LOCBEG    ; PT TO FIRST FILE NAME
  3620.     MOV    Word Ptr LOCPOS,BX    ; SAVE LOCAL POSITION
  3621. NEWP1:
  3622.     MOV    BX,Word Ptr LOCEND    ; AT END?
  3623.     XCHG    BX,DX
  3624.     MOV    BX,Word Ptr LOCPOS
  3625.     CALL    CMPDEHL
  3626.     JNZ    L_C35    
  3627.     JMP    CUR@FIRST        ; POSITION AT FIRST ENTRY AND RETURN
  3628. L_C35:
  3629.     MOV    CH,4            ; 4 SPACE
  3630.     MOV    AL,' '
  3631. T4:
  3632.     CALL    TTYPE
  3633.     DEC    CH
  3634.     JNZ    T4
  3635.     PUSH    BX            ; SAVE CURRENT LOCAL POSITION IN RING
  3636.     LAHF                ; PT TO FILE NAME
  3637.     INC    BX
  3638.     SAHF
  3639.     CALL    NC@PRFN            ; PRINT FILE NAME
  3640.     POP    BX            ; GET CURRENT LOCAL POSITION
  3641.     MOV    DX,13
  3642.     LAHF
  3643.     ADD    BX,DX
  3644.     RCR    SI,1
  3645.     SAHF
  3646.     RCL    SI,1
  3647.     MOV    Word Ptr LOCPOS,BX
  3648.     CALL    CUR@NEXT        ; ADVANCE CURSOR
  3649.     JMPS    NEWP1
  3650.  
  3651. ; position cursor at CURAT
  3652. SETCUR:
  3653.     MOV    BX,Word Ptr CURAT
  3654.  
  3655.     IF    ENH@VID
  3656.     ADD    BX,4            ;advance 4 spaces
  3657.     CALL    GOTOXY
  3658.     ENDIF
  3659.     IF  NOT ENH@VID
  3660.     CALL    GOTOXY
  3661.     CALL    ILPRT
  3662.     DB    '--> ',0
  3663.     ENDIF
  3664.  
  3665.     MOV    BX,Word Ptr RINGPOS    ;pt to current file name
  3666.     INC     BX            ;pt to first char
  3667.     CALL    AC@PRFN
  3668.     RET
  3669.  
  3670. ; clear cursor
  3671. CLRCUR:
  3672.     MOV    BX,Word Ptr CURAT
  3673.  
  3674.     IF    ENH@VID
  3675.     ADD    BX,4            ;advance 4 spaces
  3676.     CALL    GOTOXY
  3677.     ENDIF
  3678.     IF  NOT ENH@VID
  3679.     CALL    GOTOXY
  3680.     CALL    ILPRT
  3681.     DB    '    ',0
  3682.     ENDIF
  3683.  
  3684.     MOV    BX,Word Ptr RINGPOS    ;pt to current file name
  3685.     INC    BX            ;pt to first char
  3686.     CALL    NC@PRFN            ;print file name
  3687.     RET
  3688.  
  3689. ; command prompt
  3690. CPRMPT:
  3691.     MOV    BX,CPADR        ; GET ADDRESS
  3692. MPRINT:
  3693.     PUSH    BX            ; SAVE ADDRESS
  3694.     CALL    GOTOXY
  3695.     CALL    EREOL            ; ERASE TO EOL
  3696.     POP    BX            ; GET ADDRESS
  3697.     CALL    GOTOXY            ; POSITION CURSOR
  3698.     JMP    ILPRT            ; PRINT MESSAGE AND RETURN
  3699.  
  3700. ; working message
  3701. WORKMSG:
  3702.     CALL    ERMSG
  3703.     DB    'Working ...',0
  3704.     RET
  3705. ; error message
  3706. ERMSG:
  3707.     MOV    AL,0FFH            ; SET ERROR MESSAGE FLAG
  3708.     MOV    Byte Ptr ERMFLG,AL
  3709.     MOV    BX,ERADR        ; GET ADDRESS
  3710.     JMPS    MPRINT
  3711. ; print file size info
  3712. FSNOTE:
  3713.     CALL    ERMSG            ; USE THIS ROUTINE
  3714.     DB    'File Size of ',0
  3715.     RET
  3716. ; position for file size print
  3717. ATFS:
  3718.     MOV    BX,FSADR+13        ; POSITION FOR PRINT OF FILE SIZE
  3719.     JMP    GOTOXY
  3720. ; clear error message
  3721. ERCLR:
  3722.     XOR    AL,AL            ; CLEAR FLAG
  3723.     MOV    Byte Ptr ERMFLG,AL
  3724.     MOV    BX,ERADR        ; POSITION
  3725.     CALL    GOTOXY
  3726.     JMP    EREOL            ; ERASE TO EOL
  3727. ; position at command prompt and clear it
  3728. ATCMD:
  3729.     MOV    BX,CPADR        ; POSITION
  3730.     CALL    GOTOXY
  3731.     CALL    EREOL            ; CLEAR MESSAGE
  3732.     MOV    BX,CPADR        ; REPOSITION
  3733.     JMP    GOTOXY
  3734. ; position at bottom of screen and prompt for continuation
  3735. BOTTOM:
  3736.     MOV    BX,BOTADR        ; POSITION
  3737.     CALL    GOTOXY
  3738.     CALL    ILPRT
  3739.     DB    'Strike Any Key to Continue -- ',0
  3740.     JMP    KEYIN
  3741. L_C36    EQU    $
  3742.     DSEG
  3743.     ORG    Offset L_C36
  3744. ; s t o r a g e
  3745. ; initialized
  3746.  
  3747. HELPFLG    DB    0            ;is HELP available externally?  0=No
  3748.  
  3749. HEADMSG    DB    'File: ',0
  3750.  
  3751. DATE    DB    '      '
  3752.     IF    CLOCK
  3753. DATESTR    DB    'MM/DD/YY  MM:MM:SS'     ;date & time go here
  3754.     ENDIF
  3755.     DB    0
  3756.  
  3757. MOREHELP    RS    0
  3758.     DB    'A'            ;SET BY HELPCHK ROUTINE
  3759.     DB    ':HELP VFILER',0    ;HELP Command for further info
  3760. HELPFCB    RS    0
  3761.     DB    0,'HELP    CMD'
  3762. FILERCMD    RS    0
  3763.     DB    '!VFILER '
  3764. FILE@D    RS    0
  3765.     DB    'x'
  3766. FILE@U    RS    0
  3767.     DB    'xx'
  3768.     DB    ' W'            ;WAIT option
  3769.     DB    0
  3770. JOKER    RS    0
  3771.     DB    '???????????'        ; *.* equivalent
  3772. FIRST@M    RS    0
  3773.     DB    FALSE            ; 1st time thru in mass-copy mode
  3774. MFLAG    RS    0
  3775.     DB    TRUE            ;multiple file copy flag --> 0 for mass copy
  3776. TAG@TOT    RS    0
  3777.     DW    0            ;summation of tagged file sizes
  3778. CMDBUF    RS    0
  3779.     DB    32,0            ;command buffer maximum length, usage, and..
  3780. ; uninitialized
  3781.     RS    100            ;..storage for buffer and local stack.
  3782. STACK    RS    0
  3783.     RS    2            ;cp/m's stack pointer stored here
  3784. B@MAX    RS    0
  3785.     RS    2            ;highest block number on drive
  3786. B@MASK    RS    0
  3787.     RS    1            ;sec/blk - 1
  3788. BSHIFTF    RS    0
  3789.     RS    1            ; # of shifts to multiply by sec/blk
  3790. BUF@PT    RS    0
  3791.     RS    2            ;copy buffer current pointer..
  3792. BUFSTART    RS    0
  3793.     RS    2            ;..and begin pointer.
  3794. CANFLG    RS    0
  3795.     RS    1            ;no-file-found cancel flag
  3796. C@DR    RS    0
  3797.     RS    1            ; 'current drive'
  3798. CHARCNT    RS    0
  3799.     RS    1            ;character count for tab expansion
  3800. CON@LST    RS    0
  3801.     RS    1            ;bdos function storage
  3802. CRCTBL    RS    0
  3803.     RS    512            ;tables for 'crc' calculations
  3804. CRCVAL    RS    0
  3805.     RS    2            ; 2-byte 'crc' value of working file and..
  3806. CRCVAL2    RS    0
  3807.     RS    2            ;..of finished source read-file.
  3808. C@U@A    RS    0
  3809.     RS    1            ; 'current user area'
  3810. CURAT    RS    0
  3811.     RS    2            ;current cursor position
  3812. D@FCB    RS    0
  3813.     RS    33            ;fcb for destination file/new name if rename
  3814. DIRNAME    RS    0
  3815.     RS    2            ;ptr to DIR prefix
  3816. DISK    RS    0
  3817.     RS    1            ;selected disk for ZDNAME
  3818. DISKSP    RS    0
  3819.     RS    2            ;space remaining on disk
  3820. DNLOAD    RS    0
  3821.     RS    1            ;NAMES.DIR loaded flag
  3822. DRLET    RS    0
  3823.     RS    1            ;scratch for drive letter
  3824. ENTRY    RS    0
  3825.     RS    11            ;scratch for ZDNAME/ZDNFIND
  3826. EOFLAG    RS    0
  3827.     RS    1            ;file copy loop 'eof' flag
  3828. ERMFLG    RS    0
  3829.     RS    1            ;error message present flag
  3830. FICHAR    RS    0
  3831.     RS    1            ;byte-oriented input char
  3832. FIPTR    RS    0
  3833.     RS    2            ;byte-oriented input ptr
  3834. FSDFLG    RS    0
  3835.     RS    1            ;display file size flag (yes/no)
  3836. FS@FLG    RS    0
  3837.     RS    1            ;tag total versus file size flag
  3838. LDSP    RS    0
  3839.     RS    1            ;leading space count for DECOUT
  3840. LPSCNT    RS    0
  3841.     RS    1            ;lines-per-screen for 'view'
  3842. LOCBEG    RS    0
  3843.     RS    2            ;local beginning of ring
  3844. LOCEND    RS    0
  3845.     RS    2            ;local end of ring
  3846. LOCPOS    RS    0
  3847.     RS    2            ;local ring position (temp)
  3848. MAXDR    RS    0
  3849.     RS    1            ;max driver letter
  3850. MDFLG    RS    0
  3851.     RS    1            ;mass delete verify flag
  3852. O@USR    RS    0
  3853.     RS    1            ;store initial user area for exit
  3854. R@DR    RS    0
  3855.     RS    1            ; 'requested drive'
  3856. RCNT    RS    0
  3857.     RS    2            ; # of records in file and..
  3858. REC@CNT    RS    0
  3859.     RS    2            ;..currently in ram buffer.
  3860. REC@MAX    RS    0
  3861.     RS    2            ;maximum 128-byte record capacity of buffer
  3862. RING    RS    0
  3863.     RS    2            ;ptr to beginning of ring
  3864. RINGI    RS    0
  3865.     RS    2            ;ring sort pointer
  3866. RINGJ    RS    0
  3867.     RS    2            ;another ring sort pointer
  3868. RINGEND    RS    0
  3869.     RS    2            ;current ring end pointer
  3870. RINGPOS    RS    0
  3871.     RS    2            ;current ring position in scan
  3872. R@U@A    RS    0
  3873.     RS    1            ; 'requested user area'
  3874. SCURAT    RS    0
  3875.     RS    2            ;save cursor position
  3876. S@FCB    RS    0
  3877.     RS    36            ;fcb for source (random record) file
  3878. SRINGPOS    RS    0
  3879.     RS    2            ;save ring position
  3880. T@DR    RS    0
  3881.     RS    1            ;temp disk
  3882. TEST@RT    RS    0
  3883.     RS    1            ;intermediate right-justify data
  3884. T@U@A    RS    0
  3885.     RS    1            ;temp user
  3886. T@UN@FG    RS    0
  3887.     RS    1            ;tag/untag file summation switch
  3888. USER    RS    0
  3889.     RS    1            ;temp user buffer
  3890. VIEWFLG    RS    0
  3891.     RS    1            ; 00h --> to list/punch else to crt 'view'
  3892. Z@DR    RS    0
  3893.     RS    1            ;disk for ZDNAME
  3894. Z@U@A    RS    0
  3895.     RS    1            ;user area for ZDNAME
  3896. DATA_SEG RS    2            ;program data segment
  3897.  
  3898. PAGEFLG    RS    1            ;true for printing pages
  3899.  
  3900. HEADFLG    RS    1            ;true for printing header
  3901.  
  3902. LTPP1    RS    1            ;modified lines per page
  3903.  
  3904. MCFLG    RS    1            ;mass copy verify flag
  3905.  
  3906.  
  3907.  
  3908. ; assembled 'com' and 'ram-loaded' file size (0c00h = 3k)
  3909. COMFILE    EQU    ((Offset CMDBUF)+2)-256    ; 'prn' listing shows 'com'..
  3910. ALAST    RS    1            ; 1 for byte before BUFENTRY
  3911. ; even-page base of filename ring storage
  3912. BUFENTRY EQU    (((Offset $)/100H)*100H)+100H
  3913.     END                ;..and loaded file size.
  3914.