home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR2 / VFILER.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  94KB  |  4,348 lines

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