mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4466 lines
96 KiB
4466 lines
96 KiB
|
|
; TITLE 'VFILER'
|
|
|
|
; VERSION: 3.0
|
|
; DATE: 26 June 84
|
|
; AUTHOR: Richard Conn
|
|
|
|
; Changes to make Version 3.4 by Richard Conn:
|
|
; Symbol CCP changed to CCPLEN (when Z3BASE.LIB was added, the
|
|
; symbol CCP in Z3BASE.LIB conflicted with this symbol in VFILER;
|
|
; how did version 3.3 ever assemble in the first place, unless someone
|
|
; has modified Z3BASE.LIB from the original format?)
|
|
; Comments on version 3.3 changes added, prefixed by <RLC>
|
|
|
|
; THE FOLLOWING MAJOR CHANGES WERE MADE BY JAY SAGE AND BOB DEMROW TO
|
|
; MAKE VERSION 3.3. The changes were built from version 3.1.
|
|
|
|
; The following changes were contributed by Jay P. Sage and marked by
|
|
; <JPS> on the lines or at the blocks changed or added:
|
|
; 1. Code modified to eliminate double loading of program, once to
|
|
; establish shell and once to run shell. Program now checks after
|
|
; shell is established to see if any commands are pending in the
|
|
; command line. If there are none, the code is run immediately
|
|
; without reloading from disk. Otherwise, pending commands are run
|
|
; first as in previous versions.
|
|
; <RLC> Good idea
|
|
; 2. The disk logging command was extended to include setting of the
|
|
; file selection mask in system file name 4. This command was also
|
|
; renamed from 'N' to 'L' to be consistent with common usage in
|
|
; previous versions of VFILER and other programs. An equate is
|
|
; provided early in the code for those who want to change this.
|
|
; The response to the 'L' command is now a general ambiguous file
|
|
; specification. If it includes a directory specification, then
|
|
; that directory is logged into. Otherwise, one remains in the
|
|
; current directory. If it includes a file name specification,
|
|
; then that name is copied to system file name 4 and is used as a
|
|
; mask for file selection. Otherwise '*.*' is used automatically.
|
|
; Note that the colon must now be included to specify only a new
|
|
; directory. Since a carriage return alone cancels the command,
|
|
; '*.*' would have to be entered to stay in the currect directory
|
|
; but include all files. As a shortcut one can enter just a colon
|
|
; or semicolon.
|
|
; <RLC> Fine; note that the change of the command name to 'N' was
|
|
; <RLC> done in the first place to be consistent with FRIENDLY,
|
|
; <RLC> the "commercial VFILER" sold by Ampro Computers; but, then
|
|
; <RLC> again, if you use FRIENDLY, you probably don't use VFILER,
|
|
; <RLC> so the problem of consistency may not come up
|
|
; 3. Several changes were made in the command table to allow for
|
|
; synonyms. The 'X' abort operation was deleted from the 'L'
|
|
; command but was made equivalent to control-c in the main command
|
|
; table. The functions control-a and control-f, though included in
|
|
; the help screen, had not previously been implemented. They are
|
|
; here made synonyms for '-' and '+', respectively. (The built-in
|
|
; help screen was modified to make this clear.) For ease in
|
|
; entering commands, '<' and ',' were made the same as control-s,
|
|
; and '>' and '.' were made the same as control-d.
|
|
; <RLC> Fine; I debated for some time about adding synonyms, and
|
|
; <RLC> had originally decided against it; let's try this change
|
|
; <RLC> as-is and see how it works; however, re the addition of
|
|
; <RLC> ^A and ^F as synonyms for - and +, I'm sorry I forgot to
|
|
; <RLC> delete these from the Help screen -- they were intentionally
|
|
; <RLC> omitted because of potential conflict with arrow keys from
|
|
; <RLC> Z3TCAP -- if an arrow key generated ^A or ^F, then the ^A/^F
|
|
; <RLC> movement functions were overriddent by ^A/^F arrows, so I
|
|
; <RLC> decided to drop them completely and have only - and +; again,
|
|
; <RLC> let's try this change for a while and see how it works out
|
|
; 4. When files are deleted with the 'D' command, notice to that
|
|
; effect is displayed on the command line at the bottom of the
|
|
; screen.
|
|
; 5. Highlighting on the 'Z80 Code' and '8080 Code' messages was
|
|
; deleted.
|
|
; <RLC> Cosmetic
|
|
; 6. Rename function made to completely update file ring and display.
|
|
; This solves the problem of renamed files being out of place.
|
|
; <RLC> Good idea
|
|
|
|
; The following changes were contributed by R.I.Demrow and are marked by
|
|
; <RID> on all lines that were changed.
|
|
; 1. Replaced Z3ENV equate by MACLIB reference to Z3BASE.LIB. This
|
|
; library includes definitions for true and false, the value of
|
|
; Z3ENV, and the value of I8080 (indicates whether to use Z80
|
|
; opcodes)
|
|
; <RLC> Good idea; it is nice to have these equates carried in thru
|
|
; <RLC> Z3BASE.LIB, but don't expect to find matching CRCs from one
|
|
; <RLC> assembly to the next -- the COM files will differ depending
|
|
; <RLC> on values in Z3BASE; I feel, tho, that the convenience of
|
|
; <RLC> including Z3BASE outweighs the inconvenience of matching CRCs
|
|
; 2. Added highlighting to current file and current disk on top line
|
|
; of display.
|
|
; <RLC> See comment under next change
|
|
; 3. Tagged files are now highlighted on the screen.
|
|
; <RLC> There was a lot of debate during the design of FRIENDLY as
|
|
; <RLC> to whether to point to a file via a pointer or via highlighting;
|
|
; <RLC> the highlighting option was ruled against for the simple reason
|
|
; <RLC> that pointing is very important and fundamental to the VFILER
|
|
; <RLC> concept, and, on some terminals in certain kinds of lighting,
|
|
; <RLC> it is nearly impossible to distinguish a highlighted file from
|
|
; <RLC> one which is not highlighted; however, in this case, the file
|
|
; <RLC> is highlighted AND followed by a tag character, so the best of
|
|
; <RLC> both worlds is retained
|
|
; 4. Two new group functions were added: mass print and mass view.
|
|
; <RLC> Not a bad idea, but I prefer using the PRINT and PAGE
|
|
; <RLC> commands for these operations; note that a VFILER.CMD file
|
|
; <RLC> could provide PRINT and PAGE easily without any cost inside
|
|
; <RLC> of VFILER
|
|
; 5. The simulated clear-to-end-of-line function was corrected. It
|
|
; only cleared part of line before, and it had the wrong divisor in
|
|
; a modulus calculation.
|
|
; <RLC> Good
|
|
; 6. Changed code to make use of TCAP information about length of
|
|
; printer page. That information was obtained in the previous code
|
|
; but was not utilized.
|
|
; <RLC> Good
|
|
|
|
|
|
; PREVIOUS VERSIONS: 2.0 (18 Sep 83), 1.8 (17 Sep 83)
|
|
; PREVIOUS VERSIONS: 1.7 (9 Sep 83), 1.6 (18 Aug 83), 1.5 (20 July 83)
|
|
; PREVIOUS VERSIONS: 1.4 (19 July 83), 1.3 (18 July 83)
|
|
; PREVIOUS VERSIONS: 1.2 (18 July 83), 1.1 (17 July 83), 1.0 (16 July 83)
|
|
; DERIVATION: From FILER (Version 1.6) by Richard Conn
|
|
; FILER from DISK7, Version 7.6C, by Frank Gaude'
|
|
|
|
|
|
VERS EQU 34 ;<RLC> Version Number
|
|
;<JPS><RID> version number
|
|
|
|
MACLIB Z3BASE.LIB ;<RID> USE LIB TO GET Z3ENV, I8080, FALSE,
|
|
; and TRUE
|
|
|
|
; VFILER is copyright (c) 1983, 1984, 1985 by Richard Conn
|
|
; All Rights Reserved
|
|
; VFILER may be used freely by the ZCPR3 Community
|
|
|
|
; VFILER is a screen-oriented, ZCPR3-specific file utility. It can not be
|
|
; installed to run under conventional CP/M. VFILER
|
|
; extensively employs cursor addressing to position a pointer on the
|
|
; screen, allow the user to manipulate the pointer (up, down, right, left,
|
|
; next screen, previous screen, GOTO file). The pointer points to files
|
|
; in the current user directory and displays the user's position dynamically
|
|
; on the screen. Once pointing to a file, user commands can be used to
|
|
; manipulate the file (delete, copy, view on console, print on printer, tag
|
|
; for later copy or delete, and untag). In the way of being ZCPR3-specific,
|
|
; VFILER can chain to external programs via the MCL and then return (ala
|
|
; MENU), and it recognizes Named Directories (so the user can log into B:, B4:,
|
|
; and MYDIR:, for example).
|
|
|
|
; VFILER is installed by Z3INS.
|
|
|
|
; VFILER works with ZCPR3 only, with 32k or more of RAM. File copy
|
|
; functions are faster with large amounts of RAM.
|
|
|
|
; VFILER can be assembled for use with a Z80 or 8080 microprocessor.
|
|
|
|
|
|
; SYSLIB, Z3LIB, and VLIB References
|
|
;
|
|
ext z3vinit,cls,gotoxy,ereol,envptr,getcrt,getprt,vprint
|
|
ext z3log,retud
|
|
ext fi0$open,f0$get,dutdir,fi0$close
|
|
ext sksp,putcl,getmdisk
|
|
ext cin,cout,caps,lout,crlf,lcrlf,pafdc,phlfdc
|
|
ext pfind,dnscan
|
|
ext getsh,getcl1,qshell,shpush,getzrun,putzex,putcst
|
|
ext getefcb,shpop,getsh2,getfn2,getshm,putshm
|
|
ext codend
|
|
ext stndout,stndend,getcl2,zprsfn ;<JPS>
|
|
;
|
|
; Basic Definitions
|
|
;
|
|
|
|
DIM EQU 1 ;GOTO DIM
|
|
BRIGHT EQU 2 ;GOTO BRIGHT
|
|
|
|
;
|
|
; User-Customized Definition
|
|
;
|
|
VFNAME MACRO ;;Name of VFILER
|
|
DB 'VFILER'
|
|
ENDM
|
|
VFNFILL MACRO ;;Spaces to fill out name to 8 chars
|
|
DB ' '
|
|
ENDM
|
|
;
|
|
Z80 EQU NOT I8080 ;<JPS> from Z3BASE.LIB
|
|
BIHELP EQU TRUE ;TRUE to provide built-in help info
|
|
WARMBOOT EQU FALSE ;set TRUE to warmboot on exit
|
|
DEFALPHA EQU TRUE ;set TRUE to alpha by name and type, FALSE for
|
|
; ... type and name by default
|
|
EPS EQU 18*4 ;N lines x 4 cols per screen
|
|
; EPS = Entries Per Screen
|
|
TAGCH EQU '#' ;character used to mark tagged files
|
|
DIRCMD EQU 'L' ;command used to log new dir -- be sure it
|
|
;does not conflict with other commands -- used
|
|
;to be 'N' for new (I prefer 'L' for log) <JPS>
|
|
|
|
;
|
|
; Command Line Builder Constants
|
|
;
|
|
FPESC EQU '%' ;escape char
|
|
FPDISK EQU 'D' ;disk only (D)
|
|
FPUSER EQU 'U' ;user only (U)
|
|
FPFILE EQU 'F' ;file name only
|
|
MNOTE EQU '#' ;denotes comment area in macro file
|
|
UIN1 EQU 27H ;single quote for user input
|
|
UIN2 EQU 22H ;double quote for user input
|
|
|
|
;
|
|
; Cursor Positioning Addresses
|
|
;
|
|
EPSLINE EQU (EPS/4)+4 ;position of last line of EPS
|
|
BANADR EQU 1*256+24 ;banner address
|
|
CURHOME EQU 3*256+1 ;home address of cursor
|
|
BOTADR EQU 24*256+1 ;bottom of screen
|
|
CPMADR EQU EPSLINE*256+1 ;command prompt message
|
|
CPADR EQU EPSLINE*256+22 ;command prompt
|
|
ERADR EQU (EPSLINE+1)*256+15 ;error message
|
|
FSADR EQU ERADR ;file size message
|
|
FNADR EQU 1*256+62 ;address of current file name
|
|
DUADR EQU 1*256+4 ;address of current DU
|
|
|
|
;
|
|
; System Functions
|
|
;
|
|
RDCON EQU 1
|
|
WRCON EQU 2
|
|
PUNCH EQU 4
|
|
LIST EQU 5
|
|
DIRCON EQU 6
|
|
RDBUF EQU 10
|
|
CONST EQU 11
|
|
RESETDK EQU 13
|
|
LOGIN EQU 14
|
|
OPEN EQU 15
|
|
CLOSE EQU 16
|
|
SRCHF EQU 17
|
|
SRCHN EQU 18
|
|
ERASE EQU 19
|
|
READ EQU 20
|
|
WRITE EQU 21
|
|
MAKE EQU 22
|
|
REN EQU 23
|
|
INQDISK EQU 25
|
|
SETDMA EQU 26
|
|
INQALC EQU 27
|
|
ATTR EQU 30
|
|
GETPARM EQU 31
|
|
SGUSER EQU 32
|
|
COMPSZ EQU 35
|
|
|
|
;
|
|
; System Addresses
|
|
;
|
|
OS$BASE EQU 000H ;system base..
|
|
CCPLEN EQU 800H ;..and 'ccp' length in bytes.
|
|
;<RLC> Changed name from CCP to CCPLEN
|
|
GET EQU 0FFH ;get user area e-reg value
|
|
BDOS EQU OS$BASE+05H
|
|
FCB EQU OS$BASE+5CH
|
|
FCBEXT EQU FCB+12
|
|
FCBRNO EQU FCB+32
|
|
FCB2 EQU OS$BASE+6CH
|
|
TBUF EQU OS$BASE+80H
|
|
TPA EQU OS$BASE+100H
|
|
|
|
;
|
|
; ASCII Definitions
|
|
;
|
|
CTRLA EQU 'A'-'@' ;<JPS>
|
|
CTRLC EQU 'C'-'@' ;..control-C..
|
|
CTRLD EQU 'D'-'@'
|
|
CTRLE EQU 'E'-'@'
|
|
CTRLF EQU 'F'-'@' ;<JPS>
|
|
CTRLR EQU 'R'-'@'
|
|
CTRLS EQU 'S'-'@' ;..XOFF..
|
|
CTRLX EQU 'X'-'@'
|
|
BS EQU 08H ;..backspace..
|
|
TAB EQU 09H ;..tab..
|
|
LF EQU 0AH ;..linefeed..
|
|
FF EQU 0CH ;..formfeed..
|
|
CR EQU 0DH ;..carriage return..
|
|
CAN EQU 18H ;..cancel..
|
|
EOFCHAR EQU 1AH ;..end-of-file..
|
|
CTRLZ EQU 1AH ;..clear screen..
|
|
ESC EQU 1BH ;..and escape character.
|
|
|
|
;
|
|
; MACROS TO PROVIDE Z80 EXTENSIONS
|
|
; MACROS INCLUDE:
|
|
;
|
|
; BR - JUMP RELATIVE
|
|
; BRC - JUMP RELATIVE IF CARRY
|
|
; BRNC - JUMP RELATIVE IF NO CARRY
|
|
; BRZ - JUMP RELATIVE IF ZERO
|
|
; BRNZ - JUMP RELATIVE IF NO ZERO
|
|
; BJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO
|
|
;
|
|
BR MACRO ?N ;;JUMP RELATIVE
|
|
IF Z80
|
|
.z80
|
|
jr ?N
|
|
.8080
|
|
ELSE
|
|
jmp ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
BRC MACRO ?N ;;JUMP RELATIVE ON CARRY
|
|
IF Z80
|
|
.z80
|
|
jr c,?N
|
|
.8080
|
|
ELSE
|
|
jc ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
BRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY
|
|
IF Z80
|
|
.z80
|
|
jr nc,?N
|
|
.8080
|
|
ELSE
|
|
jnc ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
BRZ MACRO ?N ;;JUMP RELATIVE ON ZERO
|
|
IF Z80
|
|
.z80
|
|
jr z,?N
|
|
.8080
|
|
ELSE
|
|
jz ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
BRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO
|
|
IF Z80
|
|
.z80
|
|
jr nz,?N
|
|
.8080
|
|
ELSE
|
|
jnz ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
BJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
|
|
IF Z80
|
|
.z80
|
|
djnz ?N
|
|
.8080
|
|
ELSE
|
|
dcr b
|
|
jnz ?N
|
|
ENDIF
|
|
ENDM
|
|
;
|
|
; END OF Z80 MACRO EXTENSIONS
|
|
;
|
|
|
|
;
|
|
; Environment Definition
|
|
;
|
|
if z3env ne 0
|
|
;
|
|
; External ZCPR3 Environment Descriptor
|
|
;
|
|
jmp start
|
|
db 'Z3ENV' ;This is a ZCPR3 Utility
|
|
db 1 ;External Environment Descriptor
|
|
z3eadr:
|
|
dw z3env
|
|
start:
|
|
lhld z3eadr ;pt to ZCPR3 environment
|
|
;
|
|
else
|
|
;
|
|
; Internal ZCPR3 Environment Descriptor
|
|
;
|
|
; MACLIB Z3BASE ;<JPS> already included above
|
|
MACLIB SYSENV
|
|
z3eadr:
|
|
jmp start
|
|
SYSENV
|
|
start:
|
|
lxi h,z3eadr ;pt to ZCPR3 environment
|
|
endif
|
|
|
|
;
|
|
; Start of Program -- Initialize ZCPR3 Environment
|
|
; Once Environment is Initialized, One of Three Major Functions
|
|
; will be Performed:
|
|
; 1. VFILER will be installed as a Shell if invoked explicitly
|
|
; by user command
|
|
; 2. The VFILER Function will be performed if VFILER is invoked
|
|
; by ZCPR3 as a Shell and ZEX is not Running
|
|
; 3. A Command Line will be Input by VFILER from ZEX and Passed
|
|
; on to ZCPR3 without Processing
|
|
;
|
|
call z3vinit ;initialize the ZCPR3 Env and the VLIB Env
|
|
;
|
|
; Set Opsys Stack Pointer
|
|
;
|
|
if not WARMBOOT
|
|
lxi h,0 ;clear hl-pair then..
|
|
dad sp ;..add stack address.
|
|
shld stack
|
|
endif ;not warmboot
|
|
|
|
;
|
|
; Check to see if VFILER was executed as a shell
|
|
;
|
|
call qshell ;get and test message from ZCPR3
|
|
jz runsh ;execute shell procedures
|
|
;
|
|
; Initialize VFILER as a Shell
|
|
;
|
|
call shtest1 ;there must be a shell stack
|
|
call shtest2 ;there must be a command line buffer
|
|
;
|
|
; FUNCTION 1: Set Up VFILER as a Shell
|
|
; Run Shell Via Exit to Opsys
|
|
;
|
|
call getefcb ;determine name of program
|
|
brz shgo1 ;name not given, so use default
|
|
inx h ;pt to name
|
|
lxi d,filercmd ;define name of program
|
|
mvi b,8
|
|
call moveb ;copy name
|
|
shgo1:
|
|
call idu ;set initial disk/user
|
|
lxi h,filercmd ;establish shell
|
|
call shpush ;push onto shell stack
|
|
brnz shgo2 ;error?
|
|
|
|
call filsel ;select file mask <JPS>
|
|
;
|
|
; Print Done Message
|
|
;
|
|
call vprint
|
|
db ' Shell Installed',cr,lf,0
|
|
mvi b,0 ;shell message 0
|
|
mvi a,0 ;no wait
|
|
call putshm ;set shell message
|
|
|
|
;changes made by <JPS>
|
|
; jmp chain2 ;set IDU into command line and go
|
|
call chain2 ;set IDU into command line
|
|
call getcl2 ;see if any more commands on line
|
|
ora a
|
|
brz runsh ;if none, run shell immediately
|
|
jmp os$ccp1 ;else return to opsys
|
|
|
|
;
|
|
; Establish File Selection (made into subroutine <JPS>)
|
|
;
|
|
filsel:
|
|
call getfn2 ;setup file name
|
|
lxi d,11*3 ;use 4th system file
|
|
dad d
|
|
lxi d,fcb+1 ;pt to FCB
|
|
xchg
|
|
mvi b,11 ;copy 11 chars
|
|
call moveb
|
|
lxi h,joker ;make wild if FCB is empty
|
|
mvi b,11 ;11 chars
|
|
ldax d ;check first char
|
|
cpi ' '
|
|
cz moveb
|
|
ret
|
|
;
|
|
; Error in Shell Stack Installation
|
|
;
|
|
shgo2:
|
|
cpi 2 ;shell stack full
|
|
brnz shgo3
|
|
call vprint
|
|
db ' Shell Stack Full',0
|
|
ret
|
|
shgo3:
|
|
call vprint
|
|
db ' Shell Entry Size',0
|
|
ret
|
|
|
|
;
|
|
; VFILER was invoked as a Shell
|
|
; Check for ZEX Input in Progress
|
|
;
|
|
runsh:
|
|
call getzrun ;check ZEX message byte
|
|
jnz zexrun ;process ZEX command line if ZEX running
|
|
;
|
|
; FUNCTION 2: Run VFILER and Perform Main Function
|
|
;
|
|
mvi a,0 ;set no shell message
|
|
call putcst
|
|
call setup ;init buffers and pointers
|
|
call stackset ;setup stack
|
|
;
|
|
; Process Initial Help if Available and Requested
|
|
;
|
|
if BIHELP ;built-in help available?
|
|
lda fcb+1 ;check for initial help
|
|
cpi '/'
|
|
brnz runsh1
|
|
call helpmsg ;print help message
|
|
call sak ;strike any key to continue
|
|
br runsh2
|
|
runsh1:
|
|
endif ;BIHELP
|
|
;
|
|
; Check for Delay Before Resuming VFILER and Delay if Set
|
|
;
|
|
mvi b,0
|
|
call getshm ;get shell message 0
|
|
ani 80h ;check MSB
|
|
cnz sak ;pause for input
|
|
;
|
|
; Begin VFILER Processing
|
|
;
|
|
runsh2:
|
|
call stackset ;reset stack
|
|
call fload ;load files
|
|
push psw
|
|
call setscr ;set up screen display variables
|
|
pop psw
|
|
brnz runsh4 ;continue if OK
|
|
;
|
|
; Entry Point to Log Into New Dir and Resume
|
|
;
|
|
runsh3:
|
|
call logdir ;error - log into another dir
|
|
br runsh2
|
|
;
|
|
; Entry Point for Command Processing
|
|
; Display Screen and Input/Process Command
|
|
;
|
|
runsh4:
|
|
call stackset ;reset stack
|
|
call refresh ;refresh screen display
|
|
;
|
|
; Display Current File and Input/Process Command
|
|
;
|
|
loopfn:
|
|
call loopfn1 ;print current file name
|
|
;
|
|
; Input/Process Command
|
|
;
|
|
loop:
|
|
call stackset ;reset stack
|
|
call loopfn2 ;get command from user
|
|
call loopfn3 ;process command in A
|
|
br loop ;continue
|
|
;
|
|
; Set Stack Pointer
|
|
;
|
|
stackset:
|
|
pop d ;get return address
|
|
lhld crctbl ;top of stack
|
|
sphl ;start local stack
|
|
push d ;return address on new stack
|
|
ret
|
|
;
|
|
; Check for Presence of Shell Stack
|
|
;
|
|
shtest1:
|
|
call getsh ;get shell stack data
|
|
rnz
|
|
pop psw ;clear stack
|
|
call vprint
|
|
db 'No Shell Stack',0
|
|
ret
|
|
|
|
;
|
|
; Check for Command Line
|
|
;
|
|
shtest2:
|
|
call getcl1 ;get command line data
|
|
rnz
|
|
pop psw ;clear stack
|
|
call vprint
|
|
db 'No Cmd Line',0
|
|
ret
|
|
|
|
;
|
|
; FUNCTION 3: Run ZEX on Top of VFILER
|
|
; Accept Command Line and Pass it to ZCPR3
|
|
;
|
|
zexrun:
|
|
call vprint ;print prompt
|
|
db 'VFILER> ',0
|
|
mvi a,1 ;tell ZEX that it is prompted
|
|
call putzex
|
|
call getcl1 ;pt to command line buffer
|
|
mov a,l ;set ptr to first char
|
|
adi 4
|
|
mov c,a
|
|
mov a,h
|
|
aci 0
|
|
mov b,a ;BC pts to first char
|
|
mov m,c ;store low
|
|
inx h
|
|
mov m,b ;store high
|
|
inx h ;pt to char count
|
|
xchg ;... in DE
|
|
mvi c,rdbuf ;input line via BDOS
|
|
push d ;save ptr
|
|
call bdos
|
|
pop h ;pt to char count
|
|
inx h
|
|
mov e,m ;get char count
|
|
inx h ;pt to first char
|
|
push h ;save ptr
|
|
mvi d,0 ;DE=char count
|
|
dad d
|
|
xra a ;A=0
|
|
mov m,a ;store ending 0
|
|
pop h ;pt to first char
|
|
call putzex ;resume ZEX (A=0)
|
|
call putcst ;set command status to normal (A=0)
|
|
ret ;return to opsys
|
|
|
|
;
|
|
;**************************************************
|
|
;
|
|
; CRT Routine for VFILER
|
|
;
|
|
VCLS:
|
|
CALL CLS ;try to clear the screen
|
|
RNZ ;OK if done
|
|
PUSH H ;save regs
|
|
PUSH B
|
|
CALL GETCRT ;get CRT Data
|
|
INX H ;get number of lines on screen
|
|
MOV B,M ;B=number of lines
|
|
VCLS1:
|
|
CALL CRLF ;new line
|
|
BJNZ VCLS1
|
|
POP B ;restore regs
|
|
POP H
|
|
RET
|
|
;
|
|
; EREOL Routine for VFILER
|
|
;
|
|
VEREOL:
|
|
CALL EREOL ;try to erase to EOL
|
|
RNZ ;OK if done
|
|
PUSH B ;save count
|
|
MVI A,' ' ;space out
|
|
CALL VEREOL1 ;send B spaces
|
|
POP B ;get count
|
|
MVI A,BS ;backspace in
|
|
VEREOL1:
|
|
CALL COUT ;send char
|
|
BJNZ VEREOL1 ;count down
|
|
RET
|
|
;
|
|
; Setup Screen Display Variables
|
|
;
|
|
SETSCR:
|
|
LXI H,CURHOME ;set cursor home
|
|
SHLD CURAT
|
|
LHLD RING ;set ring position
|
|
;
|
|
; Entry to Reset Ring Position at HL
|
|
;
|
|
SETSCR1:
|
|
SHLD RINGPOS
|
|
;
|
|
; Entry to Reset Local Ring Position at HL
|
|
;
|
|
SETSCR2:
|
|
SHLD LOCBEG ;front of ring
|
|
LXI D,EPS*13 ;new end?
|
|
DAD D
|
|
XCHG
|
|
LHLD RINGEND ;end of ring
|
|
XCHG
|
|
CALL CMPDEHL
|
|
BRC SETSCR3
|
|
XCHG
|
|
SETSCR3:
|
|
XCHG
|
|
SHLD LOCEND
|
|
RET
|
|
|
|
;
|
|
; Display file name of current file
|
|
;
|
|
LOOPFN1:
|
|
LXI H,FNADR ;position cursor for file name print
|
|
CALL GOTOXY
|
|
LHLD RINGPOS ;pt to current file name
|
|
INX H ;pt to first char
|
|
;<RID> JMP PRFN ;print file name
|
|
CALL STNDOUT ;<RID> turn on highlighting
|
|
CALL PRFN ;<RID> print file name
|
|
CALL STNDEND ;<RID> turnoff highlighting;
|
|
RET ;<RID>
|
|
; Get command from user and clear error line if any
|
|
;
|
|
LOOPFN2:
|
|
CALL ATCMD ;position at command prompt
|
|
CALL DKEYIN ;wait for character from keyboard
|
|
PUSH PSW ;save command
|
|
LDA ERMFLG ;error message?
|
|
ORA A ;0=no
|
|
CNZ ERCLR ;erase old error message
|
|
POP PSW ;get command
|
|
RET
|
|
;
|
|
; Process Command
|
|
;
|
|
LOOPFN3:
|
|
CPI MNOTE ;command summary
|
|
BRZ CPROCM
|
|
CPI '0' ;macro?
|
|
BRC CPROC0
|
|
CPI '9'+1 ;macro?
|
|
BRNC CPROC0
|
|
CPROCM:
|
|
CALL CMACRO ;process macro command
|
|
MOV B,A ;save command
|
|
CALL ERMSG
|
|
DB 'No U Fct ',0
|
|
MOV A,B ;get macro digit
|
|
JMP COUT ;return for loop processing
|
|
CPROC0:
|
|
CALL CTPROC ;process command or return if not found
|
|
CALL ERMSG
|
|
DB 'Invld Cmd: ',0
|
|
MOV A,B ;get char
|
|
CPI ' ' ;expand if less than space
|
|
BRNC CPROC1
|
|
MVI A,'^' ;control
|
|
CALL COUT
|
|
MOV A,B ;get byte
|
|
ADI '@' ;convert to letter
|
|
CPROC1:
|
|
JMP COUT ;return for loop processing
|
|
|
|
;
|
|
; SET UP BUFFERS
|
|
;
|
|
SETUP:
|
|
CALL RETUD ;get home DU
|
|
MOV A,B
|
|
STA H$DR ;home drive
|
|
MOV A,C
|
|
STA H$U$A ;home user area
|
|
CALL CODEND ;start of free space
|
|
LXI D,100H ;256 bytes/unit
|
|
DAD D
|
|
SHLD CRCTBL ;table for CRC list et al
|
|
DAD D
|
|
DAD D ;allow 512 bytes
|
|
SHLD CMDBUF ;command line buffer
|
|
MVI M,64 ;64 bytes in line
|
|
LXI D,70 ;arbitrary beyond EOL
|
|
DAD D
|
|
SHLD DUM$FCB ;dummy FCB
|
|
INR H
|
|
MVI L,0 ;next page
|
|
SHLD BUFENTRY ;free space to end of TPA
|
|
|
|
;
|
|
; Set CRT/Printer Data
|
|
;
|
|
CALL GETCRT ;CRT DATA
|
|
MOV A,M
|
|
STA CWIDTH ;WIDTH
|
|
INX H
|
|
MOV B,M
|
|
INX H
|
|
MOV A,M
|
|
STA CTPP ;TEXT
|
|
MOV C,A
|
|
MOV A,B ;TOTAL NUMBER OF LINES
|
|
SUB C
|
|
DCR A ;1 LESS
|
|
STA CSPP ;LINES TO SKIP
|
|
CALL GETPRT ;PRINTER DATA
|
|
MOV A,M
|
|
STA LWIDTH ;WIDTH
|
|
INX H
|
|
MOV B,M
|
|
INX H
|
|
MOV A,M
|
|
STA LTPP ;TEXT
|
|
MOV C,A
|
|
MOV A,B ;TOTAL NUMBER OF LINES
|
|
SUB C
|
|
STA LSPP ;LINES TO SKIP
|
|
INX H
|
|
MOV A,M
|
|
STA LFFEED ;CAN FORM FEED?
|
|
|
|
;
|
|
; Begin Further Inits
|
|
;
|
|
XRA A
|
|
STA HELPDISP ;no help display yet
|
|
;
|
|
MVI A,DEFALPHA ;alpha by name and type
|
|
STA ALPHA
|
|
;
|
|
LHLD ENVPTR ;pt to ZCPR3 Env Desc
|
|
LXI D,80H+10H ;pt to cursor commands
|
|
DAD D
|
|
LXI D,CTABLE ;pt to area
|
|
MVI B,4 ;4 commands
|
|
CURINIT:
|
|
MOV A,M ;get command
|
|
STAX D ;put it
|
|
INX H ;pt to next
|
|
INX D
|
|
INX D
|
|
INX D
|
|
BJNZ CURINIT
|
|
;
|
|
CALL IDU ;set initial disk/user
|
|
CALL LOGRDU ;log into it
|
|
;
|
|
LHLD BUFENTRY ;base address
|
|
SHLD RING ;beginning of ring
|
|
;
|
|
LXI H,CURHOME ;home address for cursor
|
|
SHLD CURAT
|
|
;
|
|
CALL GETMDISK ;get max disk number (1-N)
|
|
ADI '@' ;convert to ASCII (A-P)
|
|
STA MAXDR ;set letter
|
|
;
|
|
RET
|
|
|
|
; set initial disk/user
|
|
IDU:
|
|
LXI D,FCB ;log into DU specification
|
|
CALL Z3LOG ;perform login
|
|
IDU1:
|
|
CALL RETUD ;get current DU in BC
|
|
MOV A,C ;get current user
|
|
CALL IDU$USET ;set it
|
|
MOV A,B ;get current disk
|
|
CALL IDU$DSET ;set it
|
|
RET
|
|
IDU$USET:
|
|
STA C$U$A ;..store as current and..
|
|
STA O$USR ;..as original for exit.
|
|
STA R$U$A ;..requested user area
|
|
RET
|
|
IDU$DSET:
|
|
STA C$DR
|
|
STA R$DR ;requested disk
|
|
RET
|
|
|
|
; check for existance of file whose first 12 FCB bytes are pted to by DE
|
|
; return with A=0 if not found, A=0FFH if found
|
|
|
|
FILECHK:
|
|
LXI H,S$FCB ;copy into FCB
|
|
XCHG
|
|
MVI B,12 ;12 bytes
|
|
CALL MOVE ;copied into S$FCB
|
|
XCHG ;HL pts to FCB
|
|
CALL INITFCB ;init FCB
|
|
LXI D,S$FCB ;pt to FCB
|
|
JMP FFIND
|
|
|
|
;
|
|
; Select drive and user area (system reset for disk change on-the-fly)
|
|
; <JPS>
|
|
;
|
|
LOGDIR:
|
|
CALL CPRMPT ;prompt to get drive/user selection
|
|
DB 'Login DIR (and file mask): ',0
|
|
CALL DEFSPEC ;define full file specification
|
|
LOG1:
|
|
CALL LOGRDU ;set current and log in
|
|
JMP CRLF ;new line and exit
|
|
|
|
;
|
|
; Actually log into DU requested
|
|
;
|
|
LOGRDU:
|
|
LDA R$DR ;make requested disk current
|
|
STA C$DR
|
|
CALL RESET ;reset disk system
|
|
LDA R$U$A ;establish requested area..
|
|
STA C$U$A ;..as current area.
|
|
CALL SET$USR
|
|
LXI H,0 ;initialize tagged..
|
|
SHLD TAG$TOT ;..file size accumulator.
|
|
RET
|
|
|
|
;
|
|
; Define file specification <JPS>
|
|
; (comes before DEF$D$U and includes preparing to change system file 4 for new
|
|
; mask)
|
|
;
|
|
DEFSPEC:
|
|
CALL RDSPEC ;get user input
|
|
CALL TOKEN1 ;position HL to first token and test for end
|
|
JZ LOOP ;if no entry, loop back for another command
|
|
LXI D,FCB ;use default FCB
|
|
CALL ZPRSFN ;parse the filespec into FCB
|
|
CALL FILSEL ;copy filespec into system file 4
|
|
CALL TOKEN1 ;back to first token
|
|
XRA A ;scan for DIR before DU
|
|
CALL DNSCAN ;scan again to get drive and user values
|
|
BRNZ DEFDU2 ;if found, enter new values
|
|
RET ;otherwise, just return
|
|
|
|
;
|
|
; Define current drive and user area
|
|
; many modifications <JPS>
|
|
;
|
|
DEF$D$U:
|
|
CALL RDSPEC ;read DU and filespec <JPS>
|
|
CALL TOKEN1 ;position HL to first token
|
|
JZ LOOP
|
|
|
|
;delete this redundant test <JPS>
|
|
;
|
|
; MOV A,M ;check for exit
|
|
; CALL CAPS
|
|
; CPI 'X'
|
|
; BRNZ DEFDU1
|
|
; INX H ;check for space or EOL
|
|
; MOV A,M
|
|
; DCX H
|
|
; ANI 7FH ;mask MSB
|
|
; CPI ' '+1
|
|
; JC OS$CCP ;abort
|
|
;DEFDU1:
|
|
|
|
XRA A ;A=0 to scan for DIR before DU
|
|
CALL DNSCAN ;look for DU or DIR form and return DU
|
|
BRZ ERRET ;error
|
|
DEFDU2:
|
|
MOV A,B ;return disk and user
|
|
STA R$DR
|
|
INR A ;set FCB
|
|
STA FCB
|
|
MOV A,C
|
|
STA R$U$A
|
|
RET
|
|
;
|
|
; position to first token and set flag to show end of buffer
|
|
;
|
|
TOKEN1:
|
|
LHLD CMDBUF ;pt to possible drive
|
|
INX H
|
|
INX H
|
|
CALL SKSP ;skip over leading spaces and return
|
|
MOV A,M ;check for no input
|
|
ORA A
|
|
RET
|
|
;
|
|
; reads line of input from user -- pulled out as subroutine <JPS>
|
|
;
|
|
RDSPEC:
|
|
LHLD CMDBUF ;pt to command line buffer
|
|
INX H
|
|
INX H
|
|
MVI B,20 ; # of blanks to..
|
|
CALL FILL ;..clear 'cmdbuf'.
|
|
LHLD CMDBUF ;get DU selection from..
|
|
XCHG
|
|
MVI C,RDBUF ;..console buffer read.
|
|
CALL BDOS
|
|
JMP CONVERT ;make sure alpha is upper case and return
|
|
;
|
|
; Error return and recovery from command cancellation
|
|
;
|
|
ERRET:
|
|
CALL ERMSG
|
|
DB 'DIR Entry Error',0
|
|
JMP LOOP
|
|
COMCAN:
|
|
LDA CANFLG ;check for nature of abort
|
|
ORA A ;..from..
|
|
JZ RUNSH2 ;no file found, so run the shell again
|
|
JMP RUNSH4 ;..error/command abort.
|
|
;
|
|
; find file along path (file FCB pted to by DE)
|
|
; on return, A=0FFH if found, A=0 if not found, and flags set
|
|
;
|
|
FFIND:
|
|
MVI A,0FFH ;look in current dir also
|
|
JMP PFIND ;path search from Z3LIB
|
|
; log in default directory
|
|
DLOGIN:
|
|
LDA C$DR ;disk in B
|
|
MOV B,A
|
|
LDA C$U$A ;user in C
|
|
MOV C,A ;fall thru to SLOGIN
|
|
; log in DU in BC
|
|
SLOGIN:
|
|
PUSH H ;save regs
|
|
PUSH D
|
|
PUSH B
|
|
MOV A,C ;set user
|
|
CALL SET$USR
|
|
POP B
|
|
MOV A,B ;set disk
|
|
CALL SET$DR
|
|
POP D ;restore regs
|
|
POP H
|
|
RET
|
|
|
|
; e x i t
|
|
|
|
; return to ccp
|
|
|
|
;
|
|
; Entry point for VFILER exit
|
|
;
|
|
OS$CCP:
|
|
CALL SHPOP ;clear shell stack
|
|
;
|
|
; Entry point for command line exec
|
|
;
|
|
OS$CCP1:
|
|
LDA O$USR ;get and set original..
|
|
CALL SET$USR ;..user area and..
|
|
LXI D,TBUF ;..tidy up..
|
|
MVI C,SETDMA ;..before going home.
|
|
CALL BDOS
|
|
|
|
IF WARMBOOT
|
|
JMP OS$BASE
|
|
ENDIF ;warmboot
|
|
|
|
IF NOT WARMBOOT
|
|
LHLD STACK ;put pointer..
|
|
SPHL ;..back to 'sp'.
|
|
RET ;return to ccp
|
|
NOP ; to try jump to start
|
|
NOP
|
|
|
|
ENDIF ;not warmboot
|
|
|
|
;
|
|
; FLOAD loads the files into the buffer, setting up the ring
|
|
; Return with NZ if load OK, Z if no files loaded
|
|
;
|
|
FLOAD:
|
|
CALL FRESTOR ;get bytes remaining on drive (decode default)
|
|
;
|
|
; Set up file name from System File 4
|
|
; Select all files if no entry in System File 4
|
|
;
|
|
CALL GETFN2 ;pt to first system file name
|
|
LXI D,11*3 ;pt to 4th file name
|
|
DAD D
|
|
LXI D,FCB+1 ;pt to FCB
|
|
MVI B,11 ;11 bytes
|
|
CALL MOVEB
|
|
LXI H,JOKER ;..treat as '*.*' with 'joker'..
|
|
MVI B,11 ; # of characters to move
|
|
LDAX D ;get first char of file name
|
|
CPI ' ' ;if space, fill with *.*
|
|
CZ MOVEB ;set field to *.*
|
|
LDAX D ;get first char of file name
|
|
CPI '/' ;if opt, fill with *.*
|
|
CZ MOVEB
|
|
;
|
|
; Build ring with filename positioned in default FCB area
|
|
;
|
|
MVI C,SETDMA ;initialize dma address..
|
|
LXI D,TBUF ;..to default buffer.
|
|
CALL BDOS
|
|
XRA A ;clear search 'fcb'..
|
|
STA FCBEXT ;extent byte..
|
|
STA FCBRNO ;..and record number.
|
|
LXI D,FCB ;default FCB for search
|
|
CMA
|
|
STA CANFLG ;make cancel flag true
|
|
MVI C,SRCHF ;..of first occurrence.
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if no file found
|
|
BRNZ SETRING ;if found, branch and build ring.
|
|
STA CANFLG ;make log-cancel toggle false (0)
|
|
CALL ERMSG ;else say none found, fall thru to log.
|
|
DB 'No File Found',0
|
|
XRA A ;Set Error Code
|
|
RET
|
|
|
|
; establish ring (circular list) of filenames
|
|
|
|
SETRING:
|
|
LHLD RING ;initialize ring pointer
|
|
SHLD RINGPOS ;start --> current position of ring
|
|
|
|
; put each found name in ring. a-reg --> offset into 'tbuf' name storage
|
|
|
|
TO$RING:
|
|
DCR A ;un-do 'inr' from above and below
|
|
ADD A ;times 32 --> position index
|
|
ADD A
|
|
ADD A
|
|
ADD A
|
|
ADD A
|
|
ADI TBUF ;add page offset and..
|
|
MOV L,A ;..put address into..
|
|
MVI H,0 ;..hl-pair.
|
|
LDA FCB ;get drive/user designator and..
|
|
MOV M,A ;..put into 'fcb' buffer.
|
|
XCHG
|
|
LHLD RINGPOS ;pointer to current load point in ring
|
|
XCHG
|
|
MVI B,12 ;move drive designator and name to ring
|
|
CALL MOVE
|
|
XCHG ;de-pair contains next load point address
|
|
MVI M,' ' ;space for potential..
|
|
INX H ;..tagging of files for mass copy.
|
|
SHLD RINGPOS ;store and search..
|
|
MVI C,SRCHN ;..for next occurrence.
|
|
LXI D,FCB ;filename address field
|
|
CALL BDOS
|
|
INR A ;if all done, 0ffh --> 00h.
|
|
BRNZ TO$RING ;if not, put next name into ring.
|
|
;
|
|
; All filenames in ring -- setup ring size and copy-buffer start point
|
|
;
|
|
LHLD RINGPOS ;next load point of ring is start of buffer
|
|
SHLD RINGEND ;set ring end..
|
|
SHLD BUFSTART ;..and copy-buffer start.
|
|
PUSH H
|
|
LHLD RING
|
|
LXI D,13 ;compare 'ringend' (tab base+13)
|
|
DAD D
|
|
XCHG
|
|
POP H
|
|
CALL CMPDEHL
|
|
BRNZ SORT ;sort if more than one file in ring
|
|
XRA A ;set NZ for Return
|
|
DCR A
|
|
RET
|
|
;
|
|
; Sort ring of filenames
|
|
;
|
|
SORT:
|
|
LHLD RING ;initialize 'i' sort variable and..
|
|
SHLD RINGI
|
|
LXI D,13 ;..also 'j' variable.
|
|
DAD D
|
|
SHLD RINGJ
|
|
SORTLP:
|
|
LHLD RINGJ ;compare names 'i & j'
|
|
XCHG
|
|
LHLD RINGI
|
|
PUSH H ;save position pointers..
|
|
PUSH D ;..for potential swap.
|
|
LDA ALPHA ;check for type of alphabetization
|
|
ORA A ;if Zero, alpha by type and name
|
|
JZ SORTTN
|
|
|
|
; sort by file name and type
|
|
MVI B,12 ; # of characters to compare
|
|
CALL CMPSTR ;do comparison
|
|
BR NOCMP ;final test
|
|
|
|
; sort by file type and name
|
|
SORTTN:
|
|
PUSH H ;save ptrs
|
|
PUSH D
|
|
LXI B,9 ;pt to type
|
|
DAD B
|
|
XCHG
|
|
DAD B
|
|
XCHG
|
|
MVI B,3 ;3 chars in file type
|
|
CALL CMPSTR ;compare type
|
|
POP D ;get ptrs
|
|
POP H
|
|
BRNZ NOCMP ;final test
|
|
PUSH H
|
|
PUSH D
|
|
MVI B,8 ;8 chars in file name
|
|
INX H ;pt to first
|
|
INX D
|
|
CALL CMPSTR ;compare name
|
|
POP D ;get ptrs
|
|
POP H
|
|
BRNZ NOCMP ;final test
|
|
LDAX D ;final compare and fall thru
|
|
CMP M
|
|
|
|
; final test for swapping purposes
|
|
NOCMP:
|
|
POP D
|
|
POP H
|
|
MVI B,13
|
|
BRNC NOSWAP
|
|
;
|
|
; Swap if 'j' string larger than 'i'
|
|
;
|
|
SWAP:
|
|
MOV C,M ;get character from one string..
|
|
LDAX D ;..and one from other string.
|
|
MOV M,A ;second into first
|
|
MOV A,C ;first into second
|
|
STAX D
|
|
INX H ;bump swap pointers
|
|
INX D
|
|
BJNZ SWAP
|
|
NOSWAP:
|
|
LHLD RINGJ ;increment 'j' pointer
|
|
LXI D,13
|
|
DAD D
|
|
SHLD RINGJ
|
|
XCHG ;see if end of 'j' loop
|
|
LHLD RINGEND
|
|
CALL CMPDEHL
|
|
JNZ SORTLP ;no, so more 'j' looping.
|
|
LHLD RINGI ;bump 'i' pointer
|
|
LXI D,13
|
|
DAD D
|
|
SHLD RINGI
|
|
DAD D ;set start over 'j' pointer
|
|
SHLD RINGJ
|
|
XCHG ;see if end of 'i' loop
|
|
LHLD RINGEND
|
|
CALL CMPDEHL
|
|
JNZ SORTLP ;must be more 'i' loop to do
|
|
;
|
|
; Sort done -- initialize tables for fast crc calculations
|
|
;
|
|
CALL INITCRC
|
|
;
|
|
; Calculate buffer maximum available record capacity
|
|
;
|
|
B$SIZE:
|
|
LXI B,0 ;count records
|
|
LHLD BDOS+1 ;get 'bdos' entry (fbase)
|
|
|
|
IF NOT WARMBOOT
|
|
LXI D,-(CCPLEN)
|
|
DAD D
|
|
ENDIF ;not warmboot
|
|
|
|
DCX H
|
|
XCHG ;de-pair --> highest address of buffer
|
|
LHLD BUFSTART ;start address of buffer (end of ring list)
|
|
B$SIZE2:
|
|
INX B ;increase record count by one
|
|
PUSH D
|
|
LXI D,128 ; 128-byte record
|
|
DAD D ;buffer address + record size
|
|
POP D
|
|
CALL CMPDEHL ;compare for all done
|
|
BRNC B$SIZE2 ;more will fit?
|
|
DCX B ;set maximum record count less one
|
|
MOV A,B ;memory available for copy?
|
|
ORA C
|
|
BRNZ B$SIZE3 ;yes, buffer memory space available.
|
|
CALL ERMSG
|
|
DB 'No Room',0
|
|
XRA A ;Error code
|
|
RET
|
|
B$SIZE3:
|
|
MOV L,C ;store..
|
|
MOV H,B ;..maximum..
|
|
SHLD REC$MAX ;..record count.
|
|
XRA A ;return NZ for OK
|
|
DCR A
|
|
RET
|
|
;
|
|
; left to right compare of two strings (de-pair points to 'a' string;
|
|
; hl-pair, to 'b'; b-reg contains string length.)
|
|
;
|
|
CMPSTR:
|
|
LDAX D ;get an 'a' string character and..
|
|
CMP M ;..check against 'b' string character.
|
|
RNZ ;if not equal, set flag.
|
|
INX H ;bump compare..
|
|
INX D ;..pointers and..
|
|
DCR B ; (if compare, set as equal.)
|
|
BRNZ CMPSTR ;..do next character.
|
|
RET
|
|
;
|
|
; COMMAND: MACRO (0-9)
|
|
; Process macro command
|
|
;
|
|
CMACRO:
|
|
PUSH PSW ;save digit
|
|
LXI H,MACFCB ;set up name of macro file
|
|
LXI D,S$FCB
|
|
PUSH D
|
|
MVI B,12 ;12 chars
|
|
CALL MOVE
|
|
XCHG
|
|
CALL INITFCB ;init FCB
|
|
POP D ;pt to FCB
|
|
CALL FFIND ;search along path for file
|
|
BRNZ CMFOUND ;file found
|
|
POP PSW ;clear stack
|
|
POP D ;clear ret address
|
|
CALL ERMSG
|
|
DB 'File ',0
|
|
LXI H,MACFCB+1
|
|
CALL PRFN ;print file name
|
|
CALL VPRINT
|
|
DB ' NOT Found',0
|
|
JMP LOOP
|
|
; found macro file
|
|
CMFOUND:
|
|
CALL SLOGIN ;log in
|
|
CALL FI0$CLOSE ; CLOSE FILE IF ALREADY OPEN
|
|
LXI D,S$FCB ;pt to FCB
|
|
CALL FI0$OPEN ;open for byte-oriented input
|
|
POP PSW ;get command
|
|
MOV C,A ;... in C
|
|
; new line
|
|
CMFL1:
|
|
CALL F0$GET ;get first char of line
|
|
JNZ CMFLERR ;EOF encountered
|
|
CMP C ;match?
|
|
BRZ CMFL3
|
|
; skip out line
|
|
CMFL2:
|
|
CALL F0$GET ;skip out line
|
|
JNZ CMFLERR
|
|
CPI LF ;EOL?
|
|
BRNZ CMFL2
|
|
BR CMFL1
|
|
; found command
|
|
CMFL3:
|
|
MVI A,MNOTE ;macro note?
|
|
CMP C
|
|
JZ CMFLNOTE
|
|
PUSH D
|
|
LHLD CRCTBL ;buffer for command line
|
|
LXI D,256 ;+256
|
|
DAD D
|
|
POP D
|
|
; skip leading blanks in command line
|
|
CMFL4:
|
|
CALL F0$GET ;get next char
|
|
BRNZ CMFL6 ;mark end of buffer and go
|
|
CPI ' ' ;skip leading blanks
|
|
BRZ CMFL4
|
|
; load command line into buffer
|
|
CMFL5:
|
|
ANI 7FH ;mask char
|
|
CPI CR ;EOL?
|
|
BRZ CMFL6
|
|
CPI CTRLZ ;EOF?
|
|
BRZ CMFL6
|
|
CPI FPESC ;file pted to?
|
|
JZ CMFLIF
|
|
CPI UIN1 ;user input?
|
|
BRZ CMFL5A
|
|
CPI UIN2
|
|
BRZ CMFL5A
|
|
CMFL50:
|
|
MOV M,A ;store char
|
|
INX H ;pt to next
|
|
CMFL51:
|
|
CALL F0$GET ;get next char
|
|
BRZ CMFL5
|
|
BR CMFL6
|
|
|
|
; print prompt to user and get input
|
|
CMFL5A:
|
|
PUSH H ;save buffer ptr
|
|
CALL CPRMPT ;at command prompt line
|
|
DB 0
|
|
CMFL5B:
|
|
CALL F0$GET ;get next char
|
|
BRNZ CMFL5B1
|
|
ANI 7FH ;mask
|
|
CPI UIN1 ;end of prompt?
|
|
BRZ CMFL5C
|
|
CPI UIN2
|
|
BRZ CMFL5C
|
|
CPI CR ;end of prompt?
|
|
BRZ CMFL5C
|
|
CPI CTRLZ ;eof?
|
|
BRZ CMFL5C
|
|
CALL COUT ;send char
|
|
BR CMFL5B
|
|
CMFL5B1:
|
|
MVI A,CTRLZ ;eof
|
|
CMFL5C:
|
|
PUSH PSW ;save offending char
|
|
LHLD BUFSTART ;pt to buffer
|
|
MVI M,128 ;128 char in line
|
|
INX H ;set no chars
|
|
MVI M,0
|
|
DCX H ;pt to count
|
|
XCHG
|
|
MVI C,RDBUF ;get line from user
|
|
CALL BDOS
|
|
LHLD BUFSTART
|
|
INX H ;pt to count
|
|
MOV A,M ;get count
|
|
INX H ;pt to first char
|
|
PUSH H ;save ptr
|
|
ADD L
|
|
MOV L,A
|
|
MOV A,H
|
|
ACI 0
|
|
MOV H,A ;HL pts to after last char
|
|
MVI M,0 ;store ending zero
|
|
POP H ;HL pts to first char of line
|
|
POP PSW ;get char
|
|
POP D ;DE pts to next char in buffer
|
|
MOV B,A ;char in B
|
|
CMFL5D:
|
|
MOV A,M ;copy chars
|
|
ORA A ;zero=done
|
|
BRZ CMFL5E
|
|
STAX D ;put char
|
|
INX H ;pt to next
|
|
INX D
|
|
BR CMFL5D
|
|
CMFL5E:
|
|
XCHG ;HL pts to next char in buffer
|
|
MOV A,B ;check offending char
|
|
CPI UIN1 ;user input?
|
|
BRZ CMFL51
|
|
CPI UIN2
|
|
BRNZ CMFL5
|
|
BR CMFL51
|
|
; complete buffer and test for content
|
|
CMFL6:
|
|
MVI M,0 ;store ending 0
|
|
PUSH D
|
|
LHLD CRCTBL ;pt to first char in line
|
|
LXI D,256
|
|
DAD D
|
|
POP D
|
|
MOV A,M ;get first char
|
|
ORA A ;empty?
|
|
BRNZ CMFL7
|
|
; error return
|
|
CMFLERR:
|
|
PUSH B
|
|
CALL DLOGIN ;return home
|
|
POP B
|
|
MOV A,C ;invalid command
|
|
RET
|
|
; try to chain
|
|
CMFL7:
|
|
PUSH H ;save ptr
|
|
CALL DLOGIN ;return home
|
|
POP H
|
|
CALL CHAIN ;chain to command line pted to by HL
|
|
JMP LOOP
|
|
|
|
; print documentation built into the macro file
|
|
CMFLNOTE:
|
|
CALL VCLS ;new screen
|
|
MVI C,0 ;set tab counter
|
|
CMFLN1:
|
|
CALL F0$GET ;get next char
|
|
BRNZ CMFLN4 ;done
|
|
ANI 7FH ;mask
|
|
CPI CTRLZ ;eof=done
|
|
BRZ CMFLN4
|
|
CPI TAB ;tab process
|
|
BRZ CMFLN2
|
|
CALL COUT ;print char
|
|
CPI CR ;new line?
|
|
BRZ CMFLN3
|
|
INR C ;new pos
|
|
CPI LF
|
|
BRNZ CMFLN1
|
|
DCR C ;back up position count
|
|
BR CMFLN1
|
|
CMFLN2:
|
|
MVI A,' ' ;space over for tab
|
|
CALL COUT
|
|
INR C ;incr position
|
|
MOV A,C ;done?
|
|
ANI 7 ;every 8
|
|
BRNZ CMFLN2
|
|
BR CMFLN1
|
|
CMFLN3:
|
|
MVI C,0 ;bol for CR
|
|
BR CMFLN1
|
|
CMFLN4:
|
|
CALL DLOGIN ; RETURN HOME
|
|
LHLD RINGPOS ;print current file
|
|
INX H
|
|
CALL PRFN
|
|
CALL VPRINT
|
|
DB ' Enter Digit or RETURN - ',0
|
|
CALL DKEYIN
|
|
POP D ;get ret address
|
|
CPI '0' ;in range?
|
|
JC RUNSH4
|
|
CPI '9'+1 ;in range?
|
|
JNC RUNSH4
|
|
PUSH D ;replace ret address
|
|
JMP CMACRO
|
|
|
|
; insert file pted to (% prefix command)
|
|
CMFLIF:
|
|
CALL F0$GET ;get next char
|
|
JNZ CMFL6
|
|
CPI FPESC ;doubled?
|
|
JZ CMFL50
|
|
LXI D,CMFL51 ;return address
|
|
PUSH D ;... on stack
|
|
ANI 5FH ;capitalize
|
|
CPI FPFILE ;file only?
|
|
BRZ CMFLIF1
|
|
CPI FPDISK ;disk only?
|
|
BRZ CMFLIF2
|
|
CPI FPUSER ;user only?
|
|
BRZ CMFLIF3
|
|
CALL CMFLIF2 ;Disk
|
|
CALL CMFLIF3 ;User
|
|
MVI M,':' ;separator
|
|
INX H ;fall thru to file name
|
|
CMFLIF1:
|
|
XCHG ;save ptr to next
|
|
LHLD RINGPOS ;pt to current file
|
|
INX H
|
|
MVI B,8 ;8 chars in filename
|
|
CALL CMFL5X
|
|
MVI A,'.' ;put dot
|
|
STAX D
|
|
INX D
|
|
MVI B,3 ;3 chars max
|
|
CALL CMFL5X
|
|
XCHG ;HL pts to next
|
|
RET
|
|
CMFLIF2:
|
|
LDA C$DR ;store disk
|
|
ADI 'A'
|
|
MOV M,A
|
|
INX H ;pt to next
|
|
RET
|
|
CMFLIF3:
|
|
LDA C$U$A ;user
|
|
CPI 10 ;less than 10?
|
|
BRC CMFLIF32
|
|
MVI B,'0' ;compute 10's
|
|
CMFLIF30:
|
|
SUI 10 ;subtract 10's
|
|
BRC CMFLIF31
|
|
INR B
|
|
BR CMFLIF30
|
|
CMFLIF31:
|
|
ADI 10
|
|
MOV M,B ;store 10's
|
|
INX H
|
|
CMFLIF32:
|
|
ADI '0' ;store 1's
|
|
MOV M,A
|
|
INX H
|
|
RET
|
|
CMFL5X:
|
|
MOV A,M ;get char
|
|
CPI ' '
|
|
BRZ CMFL5X1
|
|
STAX D ;put char
|
|
INX H ;pt to next
|
|
INX D
|
|
BJNZ CMFL5X
|
|
RET
|
|
CMFL5X1:
|
|
INX H ;advance
|
|
BJNZ CMFL5X1
|
|
RET
|
|
;
|
|
; Process command from table
|
|
;
|
|
CTPROC:
|
|
MOV B,A ;command in B
|
|
LXI H,CTABLE ;pt to table
|
|
MOV A,M ;any cursor commands?
|
|
ORA A
|
|
JNZ CTPR1
|
|
LXI H,CTAB1
|
|
;
|
|
; Command table scanner
|
|
; HL = Table
|
|
; B = Command Letter
|
|
;
|
|
CTPR1:
|
|
MOV A,M ;get table command char
|
|
ORA A ;end of table?
|
|
RZ ;done if so
|
|
CMP B ;match?
|
|
BRZ CTPR2
|
|
INX H ;skip to next entry
|
|
INX H
|
|
INX H
|
|
BR CTPR1
|
|
CTPR2:
|
|
INX H ;pt to address
|
|
MOV A,M ;get low
|
|
INX H
|
|
MOV H,M ;get high
|
|
MOV L,A
|
|
XTHL ;address on stack
|
|
RET ;"jump" to routine
|
|
|
|
; Command Table
|
|
CTABLE:
|
|
DB 0 ;user cursor positioning
|
|
DW UP
|
|
DB 0
|
|
DW DOWN
|
|
DB 0
|
|
DW FORWARD
|
|
DB 0
|
|
DW REVERSE
|
|
CTAB1:
|
|
DB CTRLC ;if exit, then to opsys
|
|
DW OS$CCP
|
|
DB 'X' ;alternate exit <JPS>
|
|
DW OS$CCP
|
|
DB CTRLR ;screen refresh?
|
|
DW RUNSH4
|
|
DB CTRLE ;system cursor positioning
|
|
DW UP
|
|
DB CTRLX
|
|
DW DOWN
|
|
DB CTRLD
|
|
DW FORWARD
|
|
DB CTRLS
|
|
DW REVERSE
|
|
|
|
DB '.' ;alternate commands <JPS>
|
|
DW FORWARD
|
|
DB '>'
|
|
DW FORWARD
|
|
DB ','
|
|
DW REVERSE
|
|
DB '<'
|
|
DW REVERSE
|
|
|
|
DB CR ;nop
|
|
DW LOOP
|
|
DB '+' ;jump forward
|
|
DW JUMPF
|
|
DB CTRLF ;jump forward <JPS>
|
|
DW JUMPF
|
|
DB '-' ;jump backward
|
|
DW JUMPB
|
|
DB CTRLA ;jump backward <JPS>
|
|
DW JUMPB
|
|
DB ' ' ;go forward
|
|
DW FORWARD
|
|
DB BS ;back up?
|
|
DW REVERSE
|
|
DB 'A' ;alphabetize?
|
|
DW ALPHASW
|
|
DB 'C' ;copy a file?
|
|
DW FCOPY
|
|
DB 'D' ;delete a file?
|
|
DW FDEL
|
|
DB 'F' ;show file size?
|
|
DW FSIZE
|
|
DB 'G' ;group operation?
|
|
DW GROUP$OP
|
|
DB 'H' ;external help?
|
|
DW EXTHELP
|
|
DB 'J' ;jump to a file?
|
|
DW GOTO
|
|
DB DIRCMD ;log-in another drive?
|
|
DW RUNSH3
|
|
DB 'P' ;output file to 'list' device?
|
|
; DW LSTFILE ;<RID>
|
|
DW SPRINT ;<RID>
|
|
DB 'Q' ;screen refresh?
|
|
DW RUNSH4
|
|
DB 'R' ;rename?
|
|
DW RENAME
|
|
DB 'S' ;free bytes on..
|
|
DW DSTAT ;..requested drive?
|
|
DB 'T' ;if tag, put TAGCH in..
|
|
DW TAG ;..front of cursor.
|
|
DB 'U' ;remove TAGCH from..
|
|
DW UNTAG ;..in front of cursor?
|
|
DB 'V' ; 'view' file at console?
|
|
DW VIEW
|
|
DB 'Z' ;run ZCPR3 command
|
|
DW RUNZCPR3
|
|
;
|
|
IF BIHELP ;built-in help?
|
|
DB '?' ;help
|
|
DW HELP
|
|
DB '/' ;help also
|
|
DW HELP
|
|
ELSE
|
|
DB '?' ;help
|
|
DW EXTHELP
|
|
DB '/' ;help also
|
|
DW EXTHELP
|
|
ENDIF ;BIHELP
|
|
;
|
|
DB 0 ;end of table
|
|
|
|
; h e l p (menu)
|
|
|
|
IF BIHELP ;built-in Help?
|
|
HELPMSG:
|
|
CALL VPRINT
|
|
DB CR,LF,CR,LF
|
|
DB ' '
|
|
DB '-- Tagging Commands -- --------- File Operat'
|
|
DB 'ions ----------',CR,LF
|
|
DB ' '
|
|
DB ' T - ',DIM,'Tag File',BRIGHT
|
|
DB ' C - ',DIM,'Copy File',BRIGHT,' '
|
|
DB 'D - ',DIM,'Delete File',BRIGHT,CR,LF
|
|
DB ' '
|
|
DB ' U - ',DIM,'Untag File',BRIGHT
|
|
DB ' F - ',DIM,'File Size',BRIGHT,' '
|
|
DB 'R - ',DIM,'Rename File',BRIGHT,CR,LF
|
|
DB ' '
|
|
DB ' G - ',DIM,'Group '
|
|
DB 'Copy/Delete/FSize/Tag/Untag',BRIGHT,CR,LF ;<RID>
|
|
DB ' '
|
|
DB ' ',DIM,'Group ' ;<RID>
|
|
DB 'Print/View',BRIGHT,CR,LF,CR,LF ;<RID>
|
|
DB ' '
|
|
DB '-- File Print & View -- --- User Functions ---',CR,LF
|
|
DB ' -- Cursor -- '
|
|
DB 'P - ',DIM,'Print',BRIGHT
|
|
DB ' V - ',DIM,'View',BRIGHT
|
|
DB ' 0-9 - ',DIM,'Execute',BRIGHT,' ',MNOTE,' - ',DIM,'Help'
|
|
DB BRIGHT,CR,LF
|
|
DB ' ^E '
|
|
DB CR,LF
|
|
DB ' ^ '
|
|
DB '-- Movement Commands -- ---- Miscellaneous ----',CR,LF
|
|
DB ' ^S <-+-> ^D '
|
|
DB ' <SP> - ',DIM,'File Forward'
|
|
DB BRIGHT,' A - ',DIM,'Toggle Alpha Sort',BRIGHT,CR,LF
|
|
DB ' v '
|
|
DB ' <BS> - ',DIM,'File Backward'
|
|
DB BRIGHT,' H - ',DIM,'Help File',BRIGHT,CR,LF
|
|
DB ' ^X '
|
|
DB ' + - ',DIM,'Screen Forward',BRIGHT
|
|
DB ' '
|
|
|
|
DB DIRCMD ;changes to reflect command choice <JPS>
|
|
|
|
DB ' - ',DIM,'Log DIR and/or Mask',BRIGHT,CR,LF
|
|
DB ' '
|
|
DB ' - - ',DIM,'Screen Backward',BRIGHT
|
|
DB ' S - ',DIM,'Disk Status',BRIGHT,CR,LF
|
|
DB ' -- Screen -- '
|
|
DB ' J - ',DIM,'Jump to a File',BRIGHT
|
|
DB ' Z - ',DIM,'ZCPR3 Command',BRIGHT,CR,LF
|
|
DB ' ^A ',DIM,'Backward',BRIGHT,' ' ;<JPS>
|
|
DB ' Q - ',DIM,'Refresh Screen',BRIGHT
|
|
DB ' ^C - ',DIM,'Exit',BRIGHT,CR,LF
|
|
DB ' ^F ',DIM,'Forward',BRIGHT,' ' ;<JPS>
|
|
|
|
IF BIHELP ;<JPS>
|
|
DB ' ' ;<JPS>
|
|
DB '? or / - ',DIM,'Toggle Help Screen',BRIGHT ;<JPS>
|
|
ENDIF ;<JPS>
|
|
|
|
DB 0
|
|
RET
|
|
HELP:
|
|
LDA HELPDISP ;toggle flag
|
|
CMA
|
|
STA HELPDISP
|
|
JMP RUNSH4 ;refresh screen and restart
|
|
ENDIF ;BIHELP
|
|
;
|
|
; COMMAND: H
|
|
;
|
|
EXTHELP:
|
|
CALL CPRMPT
|
|
DB 'Read Help File (Y/N)? ',0
|
|
CALL CIN
|
|
CALL CAPS
|
|
CPI 'Y'
|
|
JNZ LOOPFN
|
|
CALL ERMSG
|
|
DB DIM,'Chaining to Help File ...',BRIGHT,0
|
|
LXI H,MOREHELP ;run HELP Command
|
|
CALL CHAIN ;chain to it
|
|
JMP LOOPFN
|
|
|
|
;
|
|
; COMMAND: A
|
|
;
|
|
; Toggle alphabetize switch and reload files
|
|
;
|
|
ALPHASW:
|
|
LDA ALPHA ;toggle flag
|
|
CMA
|
|
STA ALPHA
|
|
CALL CPRMPT ;tell user what is happening
|
|
DB 'Sorting by File ',0
|
|
LDA ALPHA ;get flag
|
|
ORA A ;check it
|
|
BRZ ASWTN
|
|
CALL VPRINT
|
|
DB 'Name and Type',0
|
|
JMP RUNSH2
|
|
ASWTN:
|
|
CALL VPRINT
|
|
DB 'Type and Name',0
|
|
JMP RUNSH2 ;reload files
|
|
|
|
;
|
|
; COMMAND: Z
|
|
;
|
|
; Execute ZCPR3 command line
|
|
;
|
|
RUNZCPR3:
|
|
CALL ERMSG ;position at error message line
|
|
DB 0
|
|
LXI H,H$DR ;pt to Home Drive (followed by Home User)
|
|
CALL PRDU ;print DU
|
|
CALL VPRINT ;print prompt
|
|
DB '> ',0
|
|
PUSH D
|
|
LHLD CRCTBL ;use last half of CRC Table
|
|
LXI D,256
|
|
DAD D
|
|
POP D
|
|
MVI M,126 ;store length of line
|
|
INX H
|
|
MVI M,0 ;store count
|
|
DCX H ;pt to beginning
|
|
XCHG ;DE pts to buffer
|
|
PUSH D
|
|
MVI C,RDBUF ;Read Line from User
|
|
CALL BDOS
|
|
POP H
|
|
INX H ;pt to char count
|
|
MOV E,M
|
|
INX H ;pt to first char
|
|
MVI D,0 ;set no high-order offset
|
|
PUSH H ;save current ptr for later
|
|
DAD D
|
|
MVI M,0 ;store ending zero
|
|
POP H ;pt to first char of command line
|
|
MOV A,M ;abort if no first char
|
|
ORA A
|
|
JZ LOOP
|
|
CALL CHAIN ;chain to it
|
|
JMP LOOPFN ;continue
|
|
|
|
; chain to command pted to by HL ending in zero
|
|
|
|
CHAIN:
|
|
CALL PUTCL ;store command line
|
|
BRNZ CHAIN1
|
|
CALL ERMSG
|
|
DB 'CL Err',0
|
|
RET
|
|
CHAIN1:
|
|
MVI B,0 ;set shell message 0
|
|
MVI A,80H ;enable wait
|
|
CALL PUTSHM
|
|
CALL CHAIN2 ;<JPS>
|
|
JMP OS$CCP1 ;run command line - moved <JPS>
|
|
|
|
|
|
;made a subroutine <JPS>
|
|
CHAIN2:
|
|
LDA C$DR ;get current disk
|
|
ADI 'A' ;convert to ASCII
|
|
STA FILE$D ;store in proper place
|
|
LDA C$U$A ;get current user
|
|
LXI H,FILE$U ;store user number
|
|
MVI C,'0' ;set char
|
|
CHAIN3:
|
|
SUI 10 ;convert to ASCII
|
|
BRC CHAIN4
|
|
INR C ;increment 10's char
|
|
BR CHAIN3
|
|
CHAIN4:
|
|
MOV M,C ;store 10's digit char
|
|
INX H ;pt to 1's digit
|
|
ADI 10+'0' ;add back for 1's digit
|
|
MOV M,A ;store 1's digit char
|
|
CALL GETSH2 ;pt to shell buffer
|
|
LXI D,8 ;skip 8 chars (VFILER Name)
|
|
DAD D
|
|
LXI D,FILE$D ;place DU
|
|
XCHG
|
|
MVI B,5 ;store 5 chars (duu:0)
|
|
CALL MOVEB
|
|
RET ;<JPS>
|
|
|
|
;
|
|
; COMMAND: G
|
|
;
|
|
; Group operation
|
|
;
|
|
GROUP$OP:
|
|
CALL CPRMPT
|
|
DB 'Group Cmd (Copy/View/Print/Delete/File Sizes/' ;<RID>
|
|
DB 'Tag/Untag)? ',0 ;<RID>
|
|
CALL KEYIN ;get response
|
|
MOV B,A ;command in B
|
|
LXI H,GTABLE ;pt to table
|
|
CALL CTPR1 ;process command
|
|
JMP LOOP ;resume if not found
|
|
;
|
|
; Group Command Table
|
|
;
|
|
GTABLE:
|
|
DB 'C'
|
|
DW MASS$COPY
|
|
DB 'D'
|
|
DW MASS$DEL
|
|
DB 'P' ;<RID>
|
|
DW MASS$PRINT ;<RID>
|
|
DB 'V' ;<RID>
|
|
DW MASS$VIEW ;<RID>
|
|
DB 'F'
|
|
DW MASS$FSIZE
|
|
DB 'T'
|
|
DW MASS$TAG
|
|
DB 'U'
|
|
DW MASS$UNTAG
|
|
DB 0 ;end of table
|
|
|
|
;
|
|
; COMMAND: GU
|
|
;
|
|
MASS$UNTAG:
|
|
MVI B,' ' ;untag char
|
|
;
|
|
; Common Entry Point for Mass Untag/Tag - B = Untag/Tag Char
|
|
;
|
|
MUTLOOP:
|
|
LHLD RINGPOS ;move to tag
|
|
LXI D,12
|
|
DAD D
|
|
MOV M,B ;set tag byte
|
|
INX H ;pt to next
|
|
SHLD RINGPOS
|
|
XCHG ;done?
|
|
LHLD LOCEND
|
|
CALL CMPDEHL
|
|
BRNZ MUTLOOP
|
|
LXI H,CURHOME ;reset cursor
|
|
SHLD CURAT
|
|
LHLD LOCBEG ;set ring position
|
|
JMP JFW0 ;reset screen from LOCBEG
|
|
|
|
;
|
|
; COMMAND: GT
|
|
;
|
|
MASS$TAG:
|
|
MVI B,TAGCH ;tag char
|
|
BR MUTLOOP ;do work
|
|
|
|
;
|
|
; COMMAND: U
|
|
;
|
|
UNTAG:
|
|
MVI B,' ' ;set tag byte
|
|
;
|
|
; Common Entry Point for Untag/Tag - B = Untag/Tag Char
|
|
;
|
|
UT:
|
|
LHLD RINGPOS ;move back one..
|
|
LXI D,12 ;..character position..
|
|
DAD D ;..and check tagging status.
|
|
MOV M,B ;if file previously tagged, remove..
|
|
CALL REFFN ;refresh file name
|
|
JMP FORWARD
|
|
|
|
;
|
|
; COMMAND: T
|
|
;
|
|
TAG:
|
|
MVI B,TAGCH ;tag char
|
|
BR UT ;do tag
|
|
|
|
;
|
|
; Refresh file name with new tag
|
|
;
|
|
REFFN:
|
|
CALL CLRCUR ;clear cursor
|
|
MVI A,' ' ;one more space
|
|
CALL COUT
|
|
LHLD RINGPOS ;reprint file name
|
|
;<RID> INX H
|
|
;<RID> CALL PRFN
|
|
;<RID> MOV A,M ;print tag
|
|
;<RID> JMP COUT
|
|
CALL HILITFN ;<RID> brighten
|
|
RET ;<RID>
|
|
|
|
;
|
|
; COMMAND: GF
|
|
;
|
|
MASS$FSIZE:
|
|
CALL WORKMSG ;print 'Working' msg
|
|
LXI H,0 ;zero total
|
|
SHLD TAG$TOT
|
|
LHLD RINGPOS ;save ring position
|
|
SHLD SRINGPOS
|
|
LHLD RING ;set new ring position
|
|
SHLD RINGPOS
|
|
;
|
|
; Main Loop to Compute File Sizes
|
|
;
|
|
MASS$FS:
|
|
LHLD RINGEND ;at end of ring?
|
|
XCHG
|
|
LHLD RINGPOS
|
|
CALL CMPDEHL ;same if so
|
|
BRZ MASS$FS2
|
|
LXI D,12 ;pt to tag
|
|
DAD D
|
|
MOV A,M ;get tag
|
|
INX H ;pt to next file
|
|
CPI TAGCH ;tagged?
|
|
BRNZ MASS$FS1 ;skip if not tagged
|
|
;
|
|
; Compute Size of Tagged File
|
|
;
|
|
PUSH H ;save ptr to next file
|
|
CALL SIZER ;compute file size
|
|
XCHG ;size in DE
|
|
LHLD TAG$TOT ;get total
|
|
DAD D
|
|
SHLD TAG$TOT ;new total
|
|
POP H ;get ptr to next file
|
|
MASS$FS1:
|
|
SHLD RINGPOS ;set ptr to next file
|
|
BR MASS$FS
|
|
;
|
|
; File Size Accumulation Done - Print Result
|
|
;
|
|
MASS$FS2:
|
|
LHLD SRINGPOS ;restore ring position
|
|
SHLD RINGPOS
|
|
CALL FSNOTE ;print file size message
|
|
CALL VPRINT ;print specific
|
|
DB 'Tagged Files is ',0
|
|
LHLD TAG$TOT ;get total
|
|
BR FSIZE1 ;print size in HL and return
|
|
|
|
;
|
|
; COMMAND: F
|
|
;
|
|
; determine and display file size in kilobytes -- round up to next disk
|
|
; allocation block -- accumulate tagged file summation
|
|
;
|
|
FSIZE:
|
|
CALL SIZER ;compute file size of current file
|
|
PUSH H ;save value
|
|
CALL FSNOTE ;print file size message
|
|
LHLD RINGPOS ;print file name
|
|
INX H
|
|
CALL PRFN
|
|
CALL VPRINT ;print trailer
|
|
DB ' is ',0
|
|
POP H ;get size
|
|
;
|
|
; Print file size in HL and exit to screen
|
|
;
|
|
FSIZE1:
|
|
CALL PHLFDC ;print value in HL as floating
|
|
MVI A,'K' ;print suffix
|
|
CALL COUT
|
|
JMP LOOPFN ;resume
|
|
|
|
;
|
|
; Compute File Size at RINGPOS
|
|
; Return Size in HL
|
|
;
|
|
SIZER:
|
|
CALL RINGFCB ;move name to 's$fcb'
|
|
;
|
|
; Determine file record count and save in RCNT
|
|
;
|
|
MVI C,COMPSZ
|
|
LXI D,S$FCB
|
|
CALL BDOS
|
|
LHLD S$FCB+33
|
|
SHLD RCNT ;save record count and..
|
|
LXI H,0
|
|
SHLD S$FCB+33 ;..reset opsys
|
|
;
|
|
; Round up to next disk allocation block
|
|
;
|
|
LDA B$MASK ;sectors/block - 1
|
|
PUSH PSW ;save 'blm'
|
|
MOV L,A
|
|
XCHG
|
|
LHLD RCNT ;..use here.
|
|
DAD D ;round up to next block
|
|
MVI B,3+1 ;convert from..
|
|
CALL SHIFTLP ;..records to kilobytes.
|
|
POP PSW ;retrieve 'blm'
|
|
RRC ;convert..
|
|
RRC ;..to..
|
|
RRC ;..kilobytes/block.
|
|
ANI 1FH
|
|
CMA ;finish rounding
|
|
ANA L
|
|
MOV L,A ;hl-pair contains # of kilobytes
|
|
RET
|
|
|
|
;
|
|
; COMMAND: - (Previous Screen)
|
|
;
|
|
JUMPB:
|
|
LXI H,CURHOME ;set cursor home
|
|
SHLD CURAT
|
|
LHLD RING ;at front?
|
|
XCHG
|
|
LHLD LOCBEG
|
|
CALL CMPDEHL
|
|
BRZ JUMPBW ;back up and wrap around
|
|
SHLD LOCEND ;set new end
|
|
LXI D,-EPS*13 ;back up
|
|
DAD D
|
|
SHLD LOCBEG ;new beginning
|
|
SHLD RINGPOS ;new position
|
|
JMP RUNSH4
|
|
JUMPBW:
|
|
LHLD LOCBEG ;at first screen?
|
|
XCHG
|
|
LHLD RING ;pt to first element of ring
|
|
CALL CMPDEHL
|
|
BRZ JBW0 ;advance to end
|
|
LXI H,-EPS*13 ;back up
|
|
DAD D ;first element of new local ring
|
|
BR JFW0
|
|
JBW0:
|
|
LXI D,EPS*13 ;pt to next screen
|
|
DAD D
|
|
XCHG
|
|
LHLD RINGEND
|
|
CALL CMPDEHL
|
|
XCHG
|
|
BRZ JBW1
|
|
BRC JBW0
|
|
JBW1:
|
|
LXI D,-EPS*13
|
|
DAD D ;pt to first element of new local ring
|
|
BR JFW0
|
|
;
|
|
; COMMAND: + (Next Screen)
|
|
;
|
|
JUMPF:
|
|
LXI H,CURHOME ;set cursor to home
|
|
SHLD CURAT
|
|
LHLD LOCEND ;see if Local End <= Ring End
|
|
XCHG
|
|
LHLD RINGEND
|
|
CALL CMPDEHL
|
|
BRZ CMDLOOP
|
|
LHLD LOCEND ;new screen starting at LOCEND
|
|
BR JFW0
|
|
|
|
;
|
|
; Reset to Beginning of RING and Resume Command Looping
|
|
;
|
|
CMDLOOP:
|
|
CALL SETSCR ;reset all screen pointers
|
|
CMDLRET:
|
|
JMP RUNSH4
|
|
;
|
|
; Reset RING Position to HL
|
|
;
|
|
JFW0:
|
|
CALL SETSCR1 ;reset RINGPOS on ...
|
|
BR CMDLRET
|
|
;
|
|
; Reset Local Ring to HL
|
|
;
|
|
JFW0A:
|
|
CALL SETSCR2 ;reset LOCBEG on ...
|
|
BR CMDLRET
|
|
|
|
;
|
|
; COMMAND: ' ', Left-Arrow
|
|
;
|
|
FORWARD:
|
|
CALL CLRCUR ;clear cursor
|
|
CALL FOR0 ;position on screen and in ring
|
|
CALL SETCUR ;set cursor
|
|
JMP LOOPFN
|
|
; advance routine
|
|
FOR0:
|
|
LHLD RINGPOS ;at end of loop yet?
|
|
LXI D,13 ;i.e., will we be at end of loop?
|
|
DAD D
|
|
XCHG
|
|
LHLD LOCEND
|
|
CALL CMPDEHL ;compare 'present' to 'end'
|
|
BRNZ FORW ;to next print position
|
|
CALL CUR$FIRST ;position cursor
|
|
LHLD LOCBEG ;set position pointer to beginning and..
|
|
SHLD RINGPOS
|
|
RET
|
|
FORW:
|
|
LHLD RINGPOS ;advance in ring
|
|
LXI D,13
|
|
DAD D
|
|
SHLD RINGPOS ;new position
|
|
CALL CUR$NEXT ;position cursor
|
|
RET
|
|
|
|
;
|
|
; COMMAND: BS, Right-Arrow
|
|
;
|
|
REVERSE:
|
|
CALL CLRCUR ;clear cursor
|
|
CALL REV0 ;position on screen and in ring
|
|
CALL SETCUR ;set cursor
|
|
JMP LOOPFN
|
|
; Back Up Routine
|
|
REV0:
|
|
LHLD LOCBEG
|
|
XCHG
|
|
LHLD RINGPOS ;see if at beginning of ring
|
|
CALL CMPDEHL
|
|
BRNZ REV1 ;skip position pointer reset if not..
|
|
CALL CUR$LAST ;end of local ring
|
|
LHLD LOCEND ;set to end +1 to backup to end
|
|
LXI D,-13
|
|
DAD D
|
|
SHLD RINGPOS
|
|
RET
|
|
REV1:
|
|
CALL CUR$BACK ;back up 1
|
|
REV2:
|
|
LHLD RINGPOS
|
|
LXI D,-13 ;one ring position..
|
|
DAD D ;..backwards.
|
|
SHLD RINGPOS
|
|
RET
|
|
|
|
;
|
|
; COMMAND: Up-Arrow
|
|
;
|
|
UP:
|
|
CALL CLRCUR ;clear cursor
|
|
LHLD RINGPOS ;see if wrap around
|
|
LXI D,-13*4 ;4 entries
|
|
DAD D
|
|
XCHG
|
|
LHLD LOCBEG ;beginning of local screen
|
|
CALL CMPDEHL
|
|
BRC UP2 ;wrap around
|
|
MVI B,4 ;back up 4 entries
|
|
UP1:
|
|
PUSH B ;save count
|
|
CALL REV0 ;back up in ring and on screen (no print)
|
|
POP B ;get count
|
|
BJNZ UP1
|
|
BR DOWN1A
|
|
UP2:
|
|
LHLD RINGPOS ;advance to beyond end
|
|
LXI D,13*4
|
|
DAD D
|
|
XCHG
|
|
LHLD LOCEND ;compare to local end
|
|
XCHG
|
|
CALL CMPDEHL
|
|
BRZ DOWN1A ;at end, so too far
|
|
BRC DOWN1A ;beyond end, so back up
|
|
SHLD RINGPOS ;new ring position
|
|
LHLD CURAT ;advance cursor
|
|
INR H ;next line
|
|
SHLD CURAT
|
|
BR UP2
|
|
|
|
;
|
|
; COMMAND: Down-Arrow
|
|
;
|
|
DOWN:
|
|
CALL CLRCUR ;clear cursor
|
|
LHLD RINGPOS ;see if wrap around
|
|
LXI D,13*4 ;4 entries
|
|
DAD D
|
|
XCHG
|
|
LHLD LOCEND ;end of local screen
|
|
XCHG
|
|
CALL CMPDEHL
|
|
BRZ DOWN2 ;wrap around
|
|
BRC DOWN2 ;wrap around
|
|
MVI B,4 ;forward 4 entries
|
|
DOWN1:
|
|
PUSH B ;save count
|
|
CALL FOR0 ;advance in ring and on screen (no print)
|
|
POP B ;get count
|
|
BJNZ DOWN1
|
|
DOWN1A:
|
|
CALL SETCUR ;set cursor
|
|
JMP LOOPFN
|
|
DOWN2:
|
|
LHLD CURAT ;preserve column
|
|
MOV B,L ;column number in B
|
|
LXI H,CURHOME ;home position
|
|
SHLD CURAT ;set new position
|
|
LHLD LOCBEG ;beginning of local ring
|
|
SHLD RINGPOS ;new ring position
|
|
DOWN3:
|
|
LHLD CURAT ;check for at top of column
|
|
MOV A,L ;get col
|
|
CMP B ;there?
|
|
BRZ DOWN1A
|
|
LHLD RINGPOS ;advance in ring
|
|
LXI D,13 ;13 bytes/entry
|
|
DAD D
|
|
SHLD RINGPOS
|
|
LHLD CURAT ;get cursor position
|
|
LXI D,19 ;advance 19 bytes/screen entry
|
|
DAD D
|
|
SHLD CURAT
|
|
BR DOWN3
|
|
|
|
;
|
|
; COMMAND: S
|
|
;
|
|
; Determine remaining storage on requested disk
|
|
;
|
|
DSTAT:
|
|
CALL CPRMPT
|
|
DB 'Status of Disk (Letter): ',0
|
|
CALL KEYIN ;get char
|
|
PUSH PSW
|
|
CALL CRLF
|
|
POP PSW
|
|
SUI 'A' ;convert to number
|
|
JC LOOP
|
|
MOV B,A ;... in B
|
|
LDA MAXDR ;compare to max
|
|
SUI 'A'
|
|
CMP B
|
|
JC LOOPFN
|
|
MOV A,B ;get disk
|
|
STA R$DR ;requested drive
|
|
CALL RESET ;..login as current.
|
|
CALL FRESTOR ;determine free space remaining
|
|
CALL PRINT$FRE ;print value
|
|
LDA C$DR ;login original as..
|
|
CALL SET$DR ;..current drive.
|
|
JMP LOOPFN
|
|
|
|
;
|
|
; COMMAND: GD
|
|
;
|
|
MASS$DEL:
|
|
MOV A,B ;<RID> recover the opcode
|
|
STA MASSOP ;<RID> need it later
|
|
CALL CPRMPT
|
|
DB 'Mass Delete (Y/N/V=Verify)? ',0
|
|
CALL KEYIN ;get response
|
|
CPI 'Y'
|
|
BRZ MD1
|
|
CPI 'V'
|
|
JNZ LOOP ;return to position
|
|
MD1:
|
|
STA MDFLG ;set flag
|
|
;<RID> STA MASSOP
|
|
JMP MASS$RUN
|
|
|
|
;
|
|
; COMMAND: D
|
|
;
|
|
FDEL:
|
|
XRA A ;set no mass operation
|
|
STA MFLAG
|
|
CALL DELETE ;delete file
|
|
;
|
|
; Was Deletion Done? Abort if Not
|
|
;
|
|
LDA DELCODE ;0=not done
|
|
ORA A
|
|
JZ LOOPFN ;abort if not
|
|
;
|
|
; Reset Local Display
|
|
;
|
|
LHLD LOCEND ;move in end
|
|
LXI D,-13
|
|
DAD D
|
|
SHLD LOCEND
|
|
XCHG
|
|
LHLD RINGPOS ;position beyond end of ring?
|
|
CALL CMPDEHL
|
|
BRNZ FDEL1
|
|
;
|
|
; Cursor Beyond End of Display
|
|
;
|
|
CALL CUR$BACK ;back up cursor
|
|
LHLD LOCEND ;reset position
|
|
LXI D,-13
|
|
DAD D
|
|
SHLD RINGPOS
|
|
FDEL1:
|
|
LHLD LOCEND ;get local end
|
|
XCHG ;... in DE
|
|
LHLD LOCBEG ;erased all local files?
|
|
CALL CMPDEHL
|
|
JZ CMDLOOP ;reset
|
|
JMP JFW0A ;rescreen from LOCBEG
|
|
|
|
;
|
|
; Delete filename at RINGPOS
|
|
;
|
|
DELETE:
|
|
XRA A
|
|
STA DELCODE ;set deletion not done
|
|
CALL RINGFCB ;get file name
|
|
LDA MFLAG ;mass operation?
|
|
ORA A ;0=no
|
|
BRZ DEL1A ;do delete with message <JPS>
|
|
;
|
|
; Test for Verify on Mass Delete
|
|
;
|
|
LDA MDFLG ;verify?
|
|
CPI 'V'
|
|
BRNZ DEL1 ;delete without verify
|
|
;
|
|
; Verify and Delete only if Approved
|
|
;
|
|
CALL CPRMPT
|
|
DB 'Delete ',0
|
|
CALL PRFNS ;print file name in S$FCB
|
|
CALL VPRINT
|
|
DB ' (Y/N)? ',0
|
|
CALL KEYIN
|
|
CPI 'Y'
|
|
RNZ ;abort if not approved
|
|
;
|
|
; Delete File (Mass Operation)
|
|
;
|
|
DEL1:
|
|
LDA MDFLG ;mass operation - verify on?
|
|
CPI 'V'
|
|
BRZ DEL2
|
|
DEL1A: CALL ERMSG ;print information for mass del w/o verify
|
|
DB 'Deleting File ',0
|
|
CALL PRFNS
|
|
;
|
|
; Delete File in S$FCB
|
|
;
|
|
DEL2:
|
|
LXI H,S$FCB ;set file to R/W
|
|
CALL ATTRIB
|
|
RZ ;abort
|
|
LXI D,S$FCB ;point at delete 'fcb'
|
|
MVI C,ERASE ;erase function
|
|
CALL BDOS
|
|
INR A
|
|
BRNZ DELCL ;close up erased position
|
|
FNF$MSG:
|
|
CALL FNF1 ;show error message
|
|
JMP LOOPFN
|
|
|
|
;
|
|
; Close up erased position
|
|
;
|
|
DELCL:
|
|
MVI A,0FFH
|
|
STA DELCODE ;set deletion done
|
|
LHLD RINGPOS ;prepare move up pointers
|
|
PUSH H
|
|
LXI D,13 ;13 bytes/entry
|
|
DAD D ;de-pair = 'to' location
|
|
POP D ;hl-pair = 'from' location
|
|
;
|
|
; Move 13-byte ring entries from HL to DE
|
|
;
|
|
MOVUP:
|
|
XCHG ;HL=dest
|
|
PUSH H ;check if at end
|
|
LHLD RINGEND ;get old end pointer
|
|
CALL CMPDEHL ;check against current end location
|
|
POP H
|
|
XCHG ;DE=dest
|
|
BRZ MOVDONE ;must be at end of ring
|
|
MVI B,13 ;one name size
|
|
CALL MOVE ;move one name up
|
|
BR MOVUP ;go check end parameters
|
|
;
|
|
; Move Complete
|
|
;
|
|
MOVDONE:
|
|
LHLD RING ;see if ring is empty
|
|
XCHG
|
|
SHLD RINGEND ;set new ring end if all moved
|
|
CALL CMPDEHL ;..(listend --> listpos --> ring)
|
|
RNZ
|
|
CALL ERMSG
|
|
DB 'List Empty',0
|
|
JMP RUNSH3 ;go to drive/user area with files
|
|
|
|
;
|
|
; COMMAND: R
|
|
;
|
|
; Set-up to rename file at cursor position -- scan keyboard buffer and
|
|
; move filename to destination FCB (DFCB)
|
|
;
|
|
RENAME:
|
|
LHLD RINGPOS ;move name from ring to rename 'fcb'
|
|
LXI D,D$FCB ;place to move name
|
|
MVI B,12 ;amount to move
|
|
CALL MOVE
|
|
CALL CPRMPT ;new name prompt
|
|
DB 'Rename File to: ',0
|
|
LXI D,D$FCB+16 ;pt to FCB to fill
|
|
CALL FILENAME ;get file name
|
|
LXI H,D$FCB+1 ;check for any wild cards -- none permitted
|
|
MVI B,11 ;11 bytes
|
|
WILDCHK:
|
|
MOV A,M ;get char
|
|
INX H ;pt to next
|
|
CPI '?' ;wild?
|
|
BRZ WILDFND
|
|
BJNZ WILDCHK
|
|
|
|
; copy old file status bit ($r/o or $sys) to new filename
|
|
|
|
CPYBITS:
|
|
LXI D,D$FCB+1 ;first character of old name..
|
|
LXI H,D$FCB+17 ;..and of new name.
|
|
MVI B,11 ; # of bytes with tag bits
|
|
CBITS1:
|
|
LDAX D ;fetch bit of old name character
|
|
ANI 80H ;strip upper bit and..
|
|
MOV C,A ;..save in c-reg.
|
|
MVI A,7FH ;mask for character only
|
|
ANA M ;put masked character into a-reg
|
|
ORA C ;add old bit
|
|
MOV M,A ;copy new byte back
|
|
INX H ;bump copy pointers
|
|
INX D
|
|
BJNZ CBITS1 ;DJNZ
|
|
|
|
; check if new filename already exists. if so, say so. then go
|
|
; to command loop without moving ring position
|
|
|
|
LDA D$FCB ;copy new name to source 'fcb'
|
|
STA S$FCB
|
|
MVI B,11
|
|
LXI H,D$FCB+17 ;copy new name to..
|
|
LXI D,S$FCB+1 ;..source 'fcb' for existence check.
|
|
CALL MOVE
|
|
LXI H,S$FCB+12 ;clear 'fcb' system..
|
|
CALL INITFCB ;..fields.
|
|
LXI D,S$FCB ;search to see if this file exists
|
|
MVI C,SRCHF ;search first function
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if file not found
|
|
BRZ RENFILE ;to rename, if duplicate doesn't exists.
|
|
CALL ERMSG ;announce the situation
|
|
DB 'File Already Exists',0
|
|
JMP COMCAN ;try again?
|
|
|
|
; wild char found in file name -- error
|
|
|
|
WILDFND:
|
|
CALL ERMSG
|
|
DB 'AFN NOT Allowed',0
|
|
JMP COMCAN
|
|
|
|
; copy new name into ring position
|
|
|
|
RENFILE:
|
|
;following not needed with full screen refresh
|
|
;<JPS> LHLD RINGPOS ;get ring position pointer
|
|
;<JPS> INX H ;pt to name
|
|
;<JPS> PUSH H ;save ptr
|
|
;<JPS> XCHG
|
|
;<JPS> LXI H,D$FCB+17 ;point at new name and..
|
|
;<JPS> MVI B,11
|
|
;<JPS> CALL MOVE ;..move.
|
|
;<JPS> LHLD CURAT ;get current position on screen
|
|
;<JPS> LXI D,4 ;advance 4 chars
|
|
;<JPS> DAD D
|
|
;<JPS> CALL GOTOXY
|
|
;<JPS> POP H ;get ptr
|
|
;<JPS> CALL PRFN ;print file name
|
|
;<JPS> MOV A,M ;print tag
|
|
;<JPS> CALL COUT
|
|
LXI D,D$FCB ;rename 'fcb' location
|
|
MVI C,REN ;rename function
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if rename error
|
|
;<JPS> JNZ LOOP ;if okay, proceed, else..
|
|
;<JPS> JMP FNF$MSG ;..show no-file msg.
|
|
JZ FNF$MSG ;if error, report it <JPS>
|
|
JMP RUNSH2 ;start over <JPS>
|
|
|
|
; get file name from user and process into FCB pted to by DE
|
|
FILENAME:
|
|
PUSH D ;save ptr
|
|
LHLD CMDBUF ;command line location
|
|
XCHG
|
|
MVI C,RDBUF ;console read-buffer function
|
|
CALL BDOS
|
|
CALL CONVERT ;capitalize alpha
|
|
POP H ;set to null drive
|
|
MVI M,0 ;..required by 'bdos'.
|
|
INX H
|
|
|
|
; initialize new filename field with spaces
|
|
|
|
PUSH H ;save start pointer
|
|
MVI B,11 ; # of spaces to 'blank'
|
|
CALL FILL
|
|
POP H
|
|
XCHG
|
|
LHLD CMDBUF ;put length..
|
|
INX H
|
|
MOV C,M ;..in c-reg.
|
|
INX H
|
|
XCHG ;de-pair --> buffer pointer and hl-pair..
|
|
CALL UNSPACE ;..--> 'fcb' pointer. remove leading spaces.
|
|
|
|
; extend buffer to spaces beyond command length
|
|
|
|
EXTEND:
|
|
PUSH H
|
|
MOV L,C ;double-byte remaining length
|
|
MVI H,0
|
|
DAD D ;to buffer end +1
|
|
MVI M,' ' ;force illegal character end
|
|
POP H
|
|
|
|
; start filename scan
|
|
|
|
SCAN:
|
|
MVI B,8 ; 8 characters in filename
|
|
SCAN1:
|
|
CALL CKLEGAL ;get and see if legal character
|
|
JC COMCAN ;all of command line?
|
|
CPI ' ' ;see if end of parameter field
|
|
RZ ;rename file
|
|
CPI '.' ;at end of filename
|
|
BRZ SCAN2 ;process filetype field
|
|
CPI '*' ;rest wild?
|
|
BRZ SCAN1B
|
|
MOV M,A ;put character into destination 'fcb'
|
|
INX H
|
|
BJNZ SCAN1
|
|
|
|
; entry if eight characters without a 'period'
|
|
|
|
SCAN1A:
|
|
CALL CKLEGAL ;scan buffer up to period or end
|
|
RC ;no extent if not legal
|
|
CPI ' ' ;end of parameter field?
|
|
RZ
|
|
CPI '.'
|
|
BRNZ SCAN1A ;do till end or period
|
|
BR SCAN2A ;continue at correct place
|
|
|
|
; make rest of entry wild
|
|
|
|
SCAN1B:
|
|
MVI M,'?' ;fill with ?'s
|
|
INX H
|
|
BJNZ SCAN1B
|
|
LDAX D ;get next char
|
|
INX D ;pt to after dot
|
|
CPI '.' ;must be dot
|
|
JNZ COMCAN ;cancel if not
|
|
BR SCAN2A
|
|
|
|
; build filetype field
|
|
|
|
SCAN2:
|
|
INX H ;advance ptr to file type field
|
|
BJNZ SCAN2
|
|
SCAN2A:
|
|
MVI B,3 ;length of filetype field
|
|
SCAN3:
|
|
CALL CKLEGAL ;get and check character
|
|
BRC SCAN4 ;name done if illegal
|
|
CPI ' ' ;end of parameter field?
|
|
BRZ SCAN4
|
|
CPI '.' ;check if another period
|
|
BRZ SCAN4
|
|
CPI '*' ;rest wild?
|
|
BRZ SCAN4B
|
|
MOV M,A
|
|
INX H
|
|
BJNZ SCAN3 ;get next character
|
|
BR SCAN4A
|
|
SCAN4:
|
|
INX H ;advance to end of type field
|
|
BJNZ SCAN4
|
|
SCAN4A:
|
|
CALL INITFCB ;..and zero counter fields.
|
|
RET
|
|
SCAN4B:
|
|
MVI M,'?' ;make wild
|
|
INX H
|
|
BJNZ SCAN4B
|
|
BR SCAN4A ;complete rest
|
|
|
|
;
|
|
; COMMAND: J
|
|
;
|
|
GOTO:
|
|
CALL CPRMPT
|
|
DB 'Jump to Filename: ',0
|
|
LXI D,D$FCB ;pt to FCB
|
|
CALL FILENAME ;get file name
|
|
LHLD RING ;pt to first element of ring
|
|
SHLD RINGPOS ;set position
|
|
SHLD LOCBEG ;set local beginning
|
|
PUSH H
|
|
LHLD CRCTBL ;pt to CRC Table
|
|
MVI M,0 ;set local counter
|
|
POP H
|
|
GOTOL:
|
|
CALL GOTOCOMP ;compare
|
|
BRZ GOTOF ;we are there
|
|
PUSH H
|
|
LHLD CRCTBL ;pt to table
|
|
INR M
|
|
MOV A,M
|
|
POP H
|
|
CPI EPS
|
|
BRNZ GOTOL1
|
|
LHLD CRCTBL ;zero first entry
|
|
MVI M,0
|
|
LHLD LOCBEG ;reset local beginning
|
|
LXI D,EPS*13
|
|
DAD D
|
|
SHLD LOCBEG
|
|
GOTOL1:
|
|
LHLD RINGPOS ;advance to next entry
|
|
LXI D,13
|
|
DAD D
|
|
SHLD RINGPOS ;new position
|
|
XCHG ;position in DE
|
|
LHLD RINGEND ;check for completion
|
|
CALL CMPDEHL ;compare current position with end of ring
|
|
BRNZ GOTOL
|
|
LHLD RING ;pt to first element
|
|
SHLD RINGPOS ;set position
|
|
CALL FNF1 ;print message
|
|
JMP CMDLOOP
|
|
GOTOF:
|
|
LHLD LOCBEG ;we have local beginning
|
|
PUSH H
|
|
XCHG ;ring location in DE
|
|
LXI H,CURHOME ;set cursor ptr
|
|
SHLD CURAT
|
|
GOTOF0:
|
|
LHLD RINGPOS ;at position?
|
|
CALL CMPDEHL
|
|
BRZ GOTOF1
|
|
LXI H,13 ;advance location
|
|
DAD D
|
|
PUSH H
|
|
CALL CUR$NEXT ;advance cursor
|
|
POP D ;pt to next ring position
|
|
BR GOTOF0
|
|
GOTOF1:
|
|
POP H ;pt to local ring
|
|
JMP JFW0A ;process
|
|
GOTOCOMP:
|
|
LHLD RINGPOS ;pt to current entry
|
|
INX H ;pt to first char of file name
|
|
LXI D,D$FCB+1 ;pt to first char of new file
|
|
MVI B,11 ;11 bytes
|
|
GOTOC1:
|
|
LDAX D ;get char
|
|
CPI '?' ;match?
|
|
BRZ GOTOC2
|
|
CMP M ;match?
|
|
RNZ ;no match
|
|
GOTOC2:
|
|
INX D ;pt to next
|
|
INX H
|
|
BJNZ GOTOC1
|
|
RET
|
|
|
|
;
|
|
; COMMAND: V
|
|
;
|
|
; Type file to console with pagination set to 'lps' -- single-line scroll
|
|
; using <space> bar , <ctrl-x> to cancel, any other key to page screen.
|
|
;
|
|
VIEW:
|
|
CALL VIEWFL ;<RID>
|
|
JMP RUNSH4 ;<RID>
|
|
|
|
VIEWFL: ;<RID>
|
|
CALL VCLS
|
|
CALL VPRINT
|
|
DB CR,LF,DIM,'<CTRL-C> Cancels, <SP> Turns Up One Line, '
|
|
DB 'Other Keys Page Screen',BRIGHT,CR,LF,LF,0
|
|
MVI A,1 ;initialize..
|
|
STA LPSCNT ;..lines-per-screen counter.
|
|
STA VIEWFLG ; 'view' paginate if not zero
|
|
MVI A,WRCON ;write console out function
|
|
BR CURRENT ;to common i/o processing
|
|
;
|
|
; COMMAND: P
|
|
;
|
|
; Send file to logical list device -- any keypress cancels
|
|
;
|
|
SPRINT: ;<RID>
|
|
;
|
|
;<RID> Set Flags for First Time Thru and No Mass Print
|
|
;
|
|
XRA A ;<RID> A=0
|
|
STA FIRST$M ;<RID> set for prompt for destination
|
|
;
|
|
;<RID> Do Print
|
|
;
|
|
CALL LSTFILE ;<RID> print file at RINGPOS
|
|
;
|
|
;<RID> Advance to Next File
|
|
;
|
|
JMP RUNSH4 ;<RID> refresh screen and reset stack
|
|
;
|
|
;
|
|
LSTFILE:
|
|
LDA FIRST$M ;<RID> by-pass prompt.
|
|
ORA A ;<RID>
|
|
BRNZ SKPPRMT ;<RID>..1st time thru in mass-print mode.
|
|
DCR A ;<RID> A=0FFH
|
|
STA FIRST$M ;<RID> set not first time any more
|
|
CALL CPRMPT
|
|
DB 'Print on LST Device (Y/N)? ',0
|
|
CALL KEYIN ;get response
|
|
CPI 'Y'
|
|
JNZ LOOP
|
|
SKPPRMT: ;<RID>
|
|
CALL ERMSG
|
|
DB 'Printing ',0
|
|
LHLD RINGPOS ;pt to file name
|
|
INX H
|
|
CALL PRFN ;print it
|
|
MVI A,1 ;one for..
|
|
STA VIEWFLG ;..output to printer.
|
|
DCR A ;zero for..
|
|
STA LPSCNT ;..lines-per-page counter
|
|
STA EOFLAG ;<RID> used to provide formfeed at end of file
|
|
MVI A,LIST ;out to 'list' device function and fall thru
|
|
|
|
; output character for console/list/punch processing
|
|
|
|
CURRENT:
|
|
STA CON$LST ;save bdos function
|
|
|
|
; output file to console/printer/punch
|
|
|
|
CALL RINGFCB ;position name to 'fcb'
|
|
XCHG ;HL pts to S$FCB
|
|
CALL INITFCB ;set 'fcb' for use
|
|
LXI D,TBUF ;set to use default dma buffer
|
|
MVI C,SETDMA ;address set function
|
|
CALL BDOS
|
|
LXI D,S$FCB ;open file for reading
|
|
MVI C,OPEN ;file open function code
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if open not okay
|
|
BRNZ ZEROCR ;if not okay, show error message.
|
|
;
|
|
; File Not Found Error
|
|
;
|
|
FNF:
|
|
CALL FNF1 ;print file not found message
|
|
JMP LOOP
|
|
;
|
|
; Print File Not Found Message
|
|
;
|
|
FNF1:
|
|
CALL ERMSG
|
|
DB 'File NOT Found',0
|
|
RET
|
|
;
|
|
; Continue
|
|
;
|
|
ZEROCR:
|
|
XRA A
|
|
STA S$FCB+32 ;zero file 'current record' field
|
|
STA CHARCNT ;zero char count for tabbing
|
|
CALL PHEAD ;print heading if output to LST device
|
|
READMR:
|
|
LXI D,S$FCB ;point at file 'fcb' for reading
|
|
MVI C,READ ;record read function
|
|
CALL BDOS
|
|
ORA A ;check if read okay
|
|
BRNZ CURDONE ;eof?
|
|
LXI H,TBUF ;point at record just read
|
|
MVI B,128 ;set record character counter to output
|
|
READLP:
|
|
MOV A,M ;get a character
|
|
ANI 7FH ;force to 'ascii'
|
|
CPI EOFCHAR ;see if end-of-file
|
|
BRZ CURDONE ;back to ring loop if 'eof'
|
|
MOV E,A ;put character for 'bdos' call
|
|
PUSH B
|
|
PUSH H
|
|
PUSH D ; (character in e-reg)
|
|
LDA CON$LST ;get function for punch/list/console output
|
|
MOV C,A
|
|
MOV A,E ;check char
|
|
CPI TAB ;tabulate?
|
|
BRNZ NOTAB
|
|
MVI E,' ' ;space over
|
|
TABL:
|
|
PUSH B ;save key regs
|
|
PUSH D
|
|
CALL BDOS
|
|
POP D ;get key regs
|
|
POP B
|
|
CALL INCCCNT ;increment char count
|
|
ANI 7 ;check for done at every 8
|
|
BRNZ TABL
|
|
BR TABDN
|
|
NOTAB:
|
|
CALL BDOS ;send character
|
|
CALL INCCCNT ;increment char count
|
|
TABDN:
|
|
LDA VIEWFLG ;if 'view'..
|
|
ORA A
|
|
POP D ;get char in E in case PAGER is called
|
|
CNZ PAGER ;..check for 'lf'.
|
|
MVI E,GET ;get status or char
|
|
MVI C,DIRCON ;console status function
|
|
CALL BDOS ;status?
|
|
POP H
|
|
POP B
|
|
ANI 7FH ;if character there, then abort..
|
|
CNZ CANVIEW ;already got char
|
|
INX H ;if not, bump buffer pointer.
|
|
BJNZ READLP ;no, more in present record.
|
|
BR READMR ;yes, get next record.
|
|
CURDONE:
|
|
MVI A,TRUE ;<RID> set eoflag for formfeed at end of file
|
|
STA EOFLAG ;<RID>
|
|
LDA CON$LST ;console?
|
|
CPI WRCON
|
|
JZ BOTTOM ;<RID> prompt for user
|
|
JMP FORMFD ;<RID>
|
|
;<RID> JMP RUNSH4 ;refresh screen and continue user input
|
|
|
|
PAGER:
|
|
MOV A,E ; (character in e-reg)
|
|
CPI LF
|
|
RNZ
|
|
XRA A ;zero char count
|
|
STA CHARCNT
|
|
LDA CON$LST ;printer or console?
|
|
CPI LIST ;check for printer
|
|
BRZ PAGEP
|
|
LDA CTPP ;get number of lines of text per screen
|
|
MOV B,A ;... in B
|
|
LDA LPSCNT ;is counter..
|
|
INR A ;..at..
|
|
STA LPSCNT ;..limit..
|
|
CMP B ;..of lines-per-screen?
|
|
RC ;no, return.
|
|
XRA A ;yes, initialize..
|
|
STA LPSCNT ;..for next screen full.
|
|
CALL VPRINT
|
|
DB ' ',DIM,'[View More...]',BRIGHT,CR,0 ;show msg line
|
|
CALL DKEYIN ;wait for keyboard input
|
|
CPI ' ' ;see if <space> bar..
|
|
PUSH PSW
|
|
CALL VPRINT
|
|
DB ' ',CR,0 ;clear above msg line
|
|
POP PSW
|
|
BRNZ CANVIEW ;..if not, see if cancel.
|
|
LDA CTPP ;set for single line
|
|
DCR A
|
|
STA LPSCNT ;..scroll and..
|
|
RET ;..return for one more line.
|
|
|
|
PAGEP:
|
|
LDA LTPP ;get number of lines of text per page
|
|
MOV B,A ;... in B
|
|
LDA LPSCNT ;is counter..
|
|
INR A ;..at..
|
|
STA LPSCNT ;..limit..
|
|
CMP B ;..of lines-per-screen?
|
|
RC ;no, return.
|
|
FORMFD: XRA A ;<RID> zero for..
|
|
STA LPSCNT ;..lines-per-page counter
|
|
LDA LFFEED ;form feed available?
|
|
ORA A ;0=no
|
|
JZ PRFEED
|
|
CALL LCRLF ;new line
|
|
MVI A,FF ;send form feed char
|
|
CALL LOUT
|
|
LDA EOFLAG ;<RID> if true then output final formfeed
|
|
ORA A ;<RID>
|
|
RNZ ;<RID> don't do heading if final formfeed
|
|
JMP PHEAD ;print header and done
|
|
PRFEED:
|
|
LDA LSPP ;number of lines to skip
|
|
MOV B,A ;number of lines to skip
|
|
MVI C,LIST ;LST output
|
|
PAGELST:
|
|
CALL LCRLF ;new line on LST
|
|
BJNZ PAGELST
|
|
JMP PHEAD ;print heading and done
|
|
|
|
CANVIEW:
|
|
CPI CTRLC ;^C?
|
|
JZ COMCAN
|
|
RET ;return for another page
|
|
|
|
INCCCNT:
|
|
LDA CHARCNT ;increment char count
|
|
INR A
|
|
STA CHARCNT
|
|
RET
|
|
|
|
PHEAD:
|
|
LDA CON$LST ;printing to printer?
|
|
CPI LIST
|
|
RNZ
|
|
LXI H,HEADMSG ;print heading
|
|
PHEAD1:
|
|
MOV A,M ;get char
|
|
ORA A ;done?
|
|
BRZ PHEAD2
|
|
CALL LOUT ;send to printer
|
|
INX H ;pt to next
|
|
BR PHEAD1
|
|
PHEAD2:
|
|
LXI H,S$FCB+1 ;pt to file name
|
|
MVI B,8 ;8 chars
|
|
CALL PHEAD3
|
|
MVI A,'.' ;dot
|
|
CALL LOUT
|
|
MVI B,3 ;3 more chars
|
|
CALL PHEAD3
|
|
CALL LCRLF ;new line
|
|
CALL LCRLF ;blank line
|
|
RET
|
|
PHEAD3:
|
|
MOV A,M ;get char
|
|
CALL LOUT ;LST it
|
|
INX H ;pt to next
|
|
BJNZ PHEAD3
|
|
RET
|
|
|
|
;
|
|
; COMMAND: GC
|
|
;
|
|
; Copy files tagged using the 't' command. auto-erase if file exists
|
|
; on requested destination drive or in user area.
|
|
;
|
|
MASS$COPY:
|
|
MOV A,B ;<RID> recover opcode
|
|
STA MASSOP ;<RID>
|
|
CALL ERMSG
|
|
DB 'Mass Copy',0
|
|
;<RID> XRA A ;A=0
|
|
;<RID> STA MASSOP ;set operation to mass copy
|
|
;
|
|
; Main Entry Point for Mass Operation of Copy or Delete
|
|
; On entry, MASSOP = 0 if copy, 0FFH if delete
|
|
;
|
|
MASS$RUN:
|
|
LHLD RINGPOS ;save position
|
|
SHLD SRINGPOS
|
|
LHLD RING
|
|
LXI D,-13 ;back up to before first ring element
|
|
DAD D
|
|
SHLD RINGPOS ;set position
|
|
;
|
|
; Set Flags for First Time Thru and Mass Operation
|
|
;
|
|
XRA A ;A=0
|
|
STA FIRST$M ;set for prompt for dest with first file
|
|
DCR A ;A=0FFH
|
|
STA MFLAG ;this is a mass operation
|
|
;
|
|
; Main Mass Operation Loop
|
|
;
|
|
MASS$OLP:
|
|
LHLD RINGPOS ;re-entry point for next file
|
|
LXI D,13 ;advance to next
|
|
DAD D
|
|
SHLD RINGPOS
|
|
XCHG ;at ring..
|
|
;
|
|
; Check for Loop Completion -- DE = Current RINGPOS
|
|
;
|
|
MASS$OLP1:
|
|
LHLD RINGEND ;..end yet?
|
|
CALL CMPDEHL ;compare present position with end
|
|
; BRZ MASS$OLX ;done
|
|
JZ MASS$OLX ;<JPS>
|
|
;
|
|
; Check for Tagged File at RINGPOS
|
|
;
|
|
LHLD RINGPOS ;get position
|
|
LXI D,12 ;get 1st possible tag location
|
|
DAD D
|
|
MOV A,M ;get tag
|
|
CPI TAGCH
|
|
BRNZ MASS$OLP ;not tagged, so skip
|
|
;
|
|
; Select Mass Operation
|
|
;
|
|
LDA MASSOP ;get type of mass operation
|
|
;<RID> ORA A ;0=COPY
|
|
;<RID> BRZ MASS$OC ;do copy
|
|
CPI 'C' ;<RID> check if copy
|
|
BRZ MASS$OC ;<RID> yes its copy
|
|
CPI 'P' ;<RID> check if print
|
|
BRZ MASS$LST ;<RID> yes its print
|
|
CPI 'D' ;<RID> check if delete
|
|
BRZ MDELETE ;<RID> its delete
|
|
CPI 'V' ;<RID> check if view
|
|
BRZ MASS$FVIEW ;<RID> its view
|
|
CALL ERMSG ;<RID> should be one of above
|
|
DB 'Illegal character',0 ;<RID>
|
|
JMP LOOP ;<RID> get new comand
|
|
|
|
;<RID> COMMAND: GP
|
|
;
|
|
;<RID> Print tagged files using the 't' command
|
|
;
|
|
|
|
MASS$PRINT: ;<RID>
|
|
MOV A,B ;<RID> recover opcode
|
|
STA MASSOP ;<RID>
|
|
CALL ERMSG ;<RID>
|
|
DB 'Mass Print',0 ;<RID>
|
|
BR MASS$RUN ;<RID>
|
|
|
|
MASS$LST: ;<RID>
|
|
CALL LSTFILE ;<RID>
|
|
BR MASS$OLP ;<RID> skip to next
|
|
|
|
;<RID> COMMAND: GV
|
|
;
|
|
;<RID> View tagged files using the 't' command
|
|
;
|
|
|
|
MASS$VIEW: ;<RID>
|
|
MOV A,B ;<RID> recover opcode
|
|
STA MASSOP ;<RID>
|
|
CALL ERMSG ;<RID>
|
|
DB 'Mass View',0 ;<RID>
|
|
; BR MASS$RUN ;<RID>
|
|
JMP MASS$RUN ;<JPS>
|
|
|
|
MASS$FVIEW:
|
|
CALL VIEWFL ;<RID>
|
|
BR MASS$OLP ;<RID>
|
|
|
|
|
|
; Do Mass Delete - Current File Delete
|
|
;
|
|
MDELETE: ;<RID>
|
|
CALL DELETE ;delete filename at RINGPOS
|
|
;
|
|
; Advance to Next File if Delete Aborted
|
|
;
|
|
LDA DELCODE ;deletion done?
|
|
ORA A ;0=no
|
|
; BRZ MASS$OLP ;skip to next if not
|
|
JZ MASS$OLP ;<JPS>
|
|
;
|
|
; Stay at Current File if Delete Done - Ring was Compressed by Delete
|
|
;
|
|
LHLD RINGPOS ;get current ring position
|
|
XCHG ;... in DE (don't advance)
|
|
; BR MASS$OLP1 ;loop until thru ring list
|
|
JMP MASS$OLP1 ;<JPS>
|
|
;
|
|
; Do Mass Copy - Current File Copy
|
|
;
|
|
MASS$OC:
|
|
CALL COPY ;do copy
|
|
; BR MASS$OLP ;loop until thru ring list
|
|
JMP MASS$OLP ;<JPS>
|
|
;
|
|
; Exit Mass Operation Loop
|
|
;
|
|
MASS$OLX:
|
|
LHLD SRINGPOS ;reset ring position
|
|
SHLD RINGPOS
|
|
LDA MASSOP ;<RID> (if delete, restart)
|
|
;<RID> ORA A ;NZ=delete
|
|
;<RID> JNZ RUNSH2
|
|
CPI 'D' ;<RID> check if delete
|
|
JZ RUNSH2 ;<RID> else either print or copy
|
|
LHLD LOCBEG ;copy, so reset local ring
|
|
JMP JFW0A ;rescreen
|
|
|
|
;
|
|
; COMMAND: C
|
|
;
|
|
; Copy source file at current 'ring' position to another drive. set-up
|
|
; fcb's and buffer area and check for correct keyboard inputs. contains
|
|
; auto-crc file copy verification.
|
|
;
|
|
FCOPY:
|
|
;
|
|
; Set Flags for First Time Thru and No Mass Copy
|
|
;
|
|
XRA A ;A=0
|
|
STA FIRST$M ;set for prompt for destination
|
|
STA MFLAG ;not a mass copy
|
|
;
|
|
; Do Copy
|
|
;
|
|
CALL COPY ;do copy of file at RINGPOS
|
|
;
|
|
; Advance to Next File
|
|
;
|
|
JMP FORWARD ;advance to next file
|
|
;
|
|
; Copy File at RINGPOS
|
|
;
|
|
COPY:
|
|
LXI H,0 ;initialize storage for..
|
|
SHLD CRCVAL ;..'crc' working value.
|
|
CALL RINGFCB ;move from 'ring' to 'sfcb'
|
|
LXI H,S$FCB+12 ;set pointer to source extent field
|
|
CALL INITFCB
|
|
MVI B,32 ;copy source 'fcb' to destination 'fcb'
|
|
LXI H,S$FCB+1 ;from point..
|
|
LXI D,D$FCB+1 ;..to point..
|
|
CALL MOVE ;..move across.
|
|
LXI D,S$FCB ;open file for reading
|
|
MVI C,OPEN ;open function
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if bad open
|
|
JZ FNF ;file not found
|
|
;
|
|
; Source File is Open -- If first time thru, get dest dir
|
|
;
|
|
COPY2:
|
|
LDA FIRST$M ;by-pass prompt, drive/user compatibility..
|
|
ORA A ;..test, and disk reset after..
|
|
BRNZ COPY3M ;..1st time thru in mass-copy mode.
|
|
DCR A ;A=0FFH
|
|
STA FIRST$M ;set not first time any more
|
|
CALL CPRMPT ;prompt for drive selection
|
|
DB 'Copy to DIR: ',0
|
|
CALL DEF$D$U
|
|
;
|
|
; Check to ensure that either drives or user areas are different
|
|
;
|
|
LDA FCB ;get requested drive from 'fcb' and..
|
|
MOV B,A ;..put into b-reg for..
|
|
LDA S$FCB ;..comparison
|
|
CMP B
|
|
BRNZ COPY3 ;branch if different
|
|
LDA R$U$A ;requested user area --> rua
|
|
MOV B,A
|
|
LDA C$U$A ;current user area --> cua
|
|
CMP B
|
|
BRNZ COPY3
|
|
CALL ERMSG ;if not, show error condition:
|
|
DB 'Src DIR = Dest DIR',0
|
|
JMP LOOP ;try again?
|
|
;
|
|
; First File Copy - Reset System
|
|
;
|
|
COPY3:
|
|
CALL RESET ;make sure disk is read/write
|
|
CALL DLOGIN ;return home
|
|
;
|
|
; Nth File Copy - Copy without Resetting System
|
|
;
|
|
COPY3M:
|
|
LDA FCB ;put requested drive into..
|
|
STA D$FCB ;..place in destination fcb (used to log in)
|
|
LDA R$U$A ;toggle to..
|
|
CALL SET$USR ;..requested user area.
|
|
LXI D,D$FCB ;search for duplicate
|
|
MVI C,SRCHF ; 'search first' function
|
|
CALL BDOS
|
|
INR A ;if not found, 0ffh --> 00h. then..
|
|
BRZ COPY5 ;go to 'make' function for new file.
|
|
LDA MFLAG ;auto-erase..
|
|
ORA A ;..if..
|
|
BRZ COPY4M ;..in mass-copy mode.
|
|
CALL ERMSG ;If found, ask to replace:
|
|
DB 0
|
|
LXI H,D$FCB+1
|
|
CALL PRFN
|
|
CALL VPRINT
|
|
DB ' Exists on Dest -- Erase (Y/N)? ',0
|
|
CALL KEYIN ;get answer
|
|
CPI 'Y' ;if yes, then delete and copy ...
|
|
BRZ COPY4M ;... else fall thru to CUA$LOG and exit
|
|
;
|
|
; Log into Current User Area
|
|
;
|
|
CUA$LOG:
|
|
LDA C$U$A ;reset to current user area
|
|
JMP SET$USR ;set user and return to caller
|
|
|
|
;
|
|
; Erase destination file and proceed
|
|
;
|
|
COPY4M:
|
|
;
|
|
; Set File Attributes
|
|
;
|
|
LXI H,D$FCB ;pt to FCB
|
|
CALL ATTRIB ;clear bytes in FCB and set attr of file
|
|
BRZ CUA$LOG ;return to caller if R/W not permitted
|
|
;
|
|
; Delete old file at dest
|
|
;
|
|
LXI D,D$FCB ;delete file already existing
|
|
MVI C,ERASE ;erase function
|
|
CALL BDOS
|
|
;
|
|
; Create new file at dest
|
|
;
|
|
COPY5:
|
|
LXI D,D$FCB ;create new file and open for writing
|
|
MVI C,MAKE ;make function
|
|
CALL BDOS
|
|
INR A ;if directory full, 0ffh --> 00h.
|
|
BRNZ COPY6 ;if not, branch.
|
|
CALL ERMSG
|
|
DB 'Dest Dir Full',0
|
|
JMP LOOPFN ;if error, back to ring processor.
|
|
;
|
|
; Perform Copy
|
|
;
|
|
COPY6:
|
|
CALL CPRMPT
|
|
DB 'Copying File ',0
|
|
LXI H,D$FCB+1 ;print file name
|
|
CALL PRFNSX
|
|
CALL VPRINT
|
|
DB ' to ',0
|
|
LDA D$FCB ;print dest DU
|
|
ADI '@'
|
|
CALL COUT ;print disk
|
|
LDA R$U$A ;get user
|
|
CALL PAFDC ;print user
|
|
MVI A,':'
|
|
CALL COUT
|
|
XRA A ;clear 'eof'..
|
|
STA EOFLAG ;..flag.
|
|
COPY6A:
|
|
CALL CUA$LOG ;current user area
|
|
LXI H,0 ;clear current-record..
|
|
SHLD REC$CNT ;..counter.
|
|
LHLD BUFSTART ;set buffer start pointer..
|
|
SHLD BUF$PT ;..to begin pointer.
|
|
;
|
|
; read source file -- fill buffer memory or stop on 'eof' -- update 'crc'
|
|
; on-the-fly
|
|
;
|
|
COPY7:
|
|
LHLD BUF$PT ;set dma address to buffer pointer
|
|
XCHG ; de-pair --> dma address
|
|
MVI C,SETDMA
|
|
CALL BDOS
|
|
LXI D,S$FCB ;source 'fcb' for reading
|
|
MVI C,READ ;record read function
|
|
CALL BDOS
|
|
ORA A ; 00h --> read okay
|
|
BRZ S$RD$OK
|
|
DCR A ;eof?
|
|
BRZ COPY8 ;yes, end-of-file, set 'eof' flag.
|
|
CALL ERMSG
|
|
DB 'Read Error',0
|
|
JMP LOOPFN
|
|
;
|
|
; Read OK - Update CRC
|
|
;
|
|
S$RD$OK:
|
|
LHLD BUF$PT
|
|
MVI B,128
|
|
COPY7A:
|
|
MOV A,M ;get character and..
|
|
CALL UPDCRC ;..add to 'crc' value.
|
|
INX H
|
|
DCR B
|
|
BRNZ COPY7A ;loop 'till record read finished
|
|
;
|
|
; Update Buffer Ptr and Record Count
|
|
;
|
|
LHLD BUF$PT ;bump buffer pointer..
|
|
LXI D,128 ;..by..
|
|
DAD D ;..one..
|
|
SHLD BUF$PT ;..record.
|
|
LHLD REC$CNT ;bump buffer..
|
|
INX H ;..record count and..
|
|
SHLD REC$CNT ;..store.
|
|
XCHG ;ready to compare to..
|
|
;
|
|
; Check for Full Buffer
|
|
;
|
|
LHLD REC$MAX ;..maximum record count (full-buffer).
|
|
CALL CMPDEHL ;compare
|
|
BRNZ COPY7 ;if not full, get next record.
|
|
BR COPY9 ;full, start first write session.
|
|
;
|
|
; Indicate end-of-file read
|
|
;
|
|
COPY8:
|
|
MVI A,TRUE ;set 'eof' flag
|
|
STA EOFLAG
|
|
;
|
|
; Write source file from memory buffer to destination
|
|
;
|
|
COPY9:
|
|
LDA R$U$A ;set user to requested..
|
|
CALL SET$USR ;..area.
|
|
LHLD BUFSTART ;adjust buffer pointer..
|
|
SHLD BUF$PT ;..to start address.
|
|
COPY10:
|
|
LHLD REC$CNT ;buffer empty?
|
|
MOV A,H
|
|
ORA L
|
|
BRZ COPY11 ;buffer empty, check 'eof' flag.
|
|
DCX H ;dec buffer record count for each write
|
|
SHLD REC$CNT
|
|
LHLD BUF$PT ;set up dma address
|
|
PUSH H ;save for size bump
|
|
XCHG ;pointer in de-pair
|
|
MVI C,SETDMA
|
|
CALL BDOS
|
|
POP H
|
|
LXI D,128 ;bump pointer one record length
|
|
DAD D
|
|
SHLD BUF$PT
|
|
LXI D,D$FCB ;destination file 'fcb'
|
|
MVI C,WRITE ;write record function
|
|
CALL BDOS
|
|
ORA A ; 00h --> write okay
|
|
BRZ COPY10 ;okay, do next record. else..
|
|
CALL ERMSG ;..say disk write error.
|
|
DB 'Copy Disk Full',0
|
|
;
|
|
; Error in Write -- Delete Destination File and Abort
|
|
;
|
|
C$ERA:
|
|
LXI D,D$FCB ;delete..
|
|
MVI C,ERASE ;..partial..
|
|
CALL BDOS ;..from directory.
|
|
JMP LOOPFN ;back to ring
|
|
;
|
|
; Destination Buffer Written - Check for End
|
|
;
|
|
COPY11:
|
|
LDA EOFLAG ;buffer all written, check for 'eof'.
|
|
ORA A
|
|
JZ COPY6A ;branch to read next buffer full
|
|
LXI D,D$FCB ;point at 'fcb' for file closure
|
|
MVI C,CLOSE
|
|
CALL BDOS
|
|
INR A ;if no-close-error then..
|
|
BRNZ CRC$CMP ;..compare file crc's.
|
|
CALL ERMSG
|
|
DB 'Copy Close Error',0
|
|
JMP C$ERA
|
|
;
|
|
; Read Destination File and Compare CRCs
|
|
;
|
|
CRC$CMP:
|
|
LHLD CRCVAL ;transfer 'crc' value to..
|
|
SHLD CRCVAL2 ;..new storage area.
|
|
LXI H,0 ;clear working storage..
|
|
SHLD CRCVAL ;..to continue.
|
|
LXI D,TBUF
|
|
MVI C,SETDMA
|
|
CALL BDOS
|
|
LXI H,D$FCB+12
|
|
CALL INITFCB
|
|
LXI D,D$FCB
|
|
MVI C,OPEN
|
|
CALL BDOS
|
|
INR A ; 0ffh --> 00h if bad open
|
|
JZ BADCRC ;if bad open, just say 'bad-crc'.
|
|
XRA A ;zero 'fcb'..
|
|
STA D$FCB+32 ;..'cr' field.
|
|
CRCWF1:
|
|
LXI D,D$FCB
|
|
MVI C,READ
|
|
CALL BDOS
|
|
ORA A ;read okay?
|
|
BRZ D$RD$OK ;yes, read more.
|
|
DCR A ;eof?
|
|
BRZ FINCRC ;yes, finish up and make 'crc' comparison.
|
|
CALL ERMSG
|
|
DB 'Copy Read Error',0
|
|
JMP LOOP
|
|
;
|
|
; Block Read OK - Update CRC
|
|
;
|
|
D$RD$OK:
|
|
LXI H,TBUF
|
|
MVI B,128
|
|
CRCWF2:
|
|
MOV A,M ;get character to..
|
|
CALL UPDCRC ;..add to 'crc' value.
|
|
INX H
|
|
BJNZ CRCWF2
|
|
BR CRCWF1
|
|
;
|
|
; Read Complete - Check CRCs
|
|
;
|
|
FINCRC:
|
|
LHLD CRCVAL ;put written-file 'crc' into..
|
|
XCHG ;..de-pair.
|
|
LHLD CRCVAL2 ;put read-file 'crc' and..
|
|
CALL CMPDEHL ;..compare 'de/hl' for equality.
|
|
BRNZ BADCRC ;if not zero, show copy-error message.
|
|
CALL VPRINT ;if zero, show 'verified' message.
|
|
DB ' -- Verified',0
|
|
JMP CUA$LOG ;return to current user and return to caller
|
|
;
|
|
; Error on Copy
|
|
;
|
|
BADCRC:
|
|
CALL CUA$LOG ;return to current user
|
|
CALL ERMSG
|
|
DB ' -- CRC Error',0
|
|
JMP LOOP ;abort
|
|
|
|
;
|
|
; clear attributes of file (HL) and set attributes on disk
|
|
; return code of 0FFH (NZ) indicates OK to proceed, 0 (Z) indicates abort
|
|
;
|
|
ATTRIB:
|
|
PUSH H ;save regs
|
|
PUSH H
|
|
PUSH D
|
|
LHLD DUM$FCB ;init FCB
|
|
LXI D,12 ;12 bytes in
|
|
DAD D
|
|
POP D
|
|
CALL INITFCB
|
|
LHLD DUM$FCB ;pt to dummy FCB
|
|
XCHG ;... in DE
|
|
POP H
|
|
MVI B,12 ;copy
|
|
PUSH D
|
|
CALL MOVE
|
|
POP D ;pt to FCB
|
|
MVI C,SRCHF ;look for file
|
|
CALL BDOS
|
|
INR A ;file not found = 0
|
|
POP H
|
|
RZ ;abort if no file
|
|
PUSH H ;save ptr
|
|
DCR A ;adjust
|
|
RRC ;right 3 bits to indicate offset into BUFF
|
|
RRC
|
|
RRC
|
|
LXI H,TBUF ;pt to buffer
|
|
ADD L ;pt to FCB of file
|
|
ADI 9 ;pt to R/O Byte
|
|
MOV L,A
|
|
MOV A,M ;get byte
|
|
ANI 80H ;extract R/O Bit
|
|
BRZ ATTRIB0
|
|
CALL ERMSG
|
|
DB 0
|
|
POP H
|
|
PUSH H
|
|
INX H ;pt to file name
|
|
CALL PRFN ;print file name
|
|
CALL VPRINT
|
|
DB ' is R/O -- Erase (Y/N)? ',0
|
|
CALL KEYIN
|
|
CPI 'Y'
|
|
JZ ATTRIB0
|
|
POP H
|
|
XRA A ;error return
|
|
RET
|
|
ATTRIB0:
|
|
POP H ;get ptr
|
|
PUSH H ;save ptr
|
|
INX H ;pt to first char
|
|
MVI B,11 ;11 Bytes
|
|
ATTRIB1:
|
|
MOV A,M ;get byte
|
|
ANI 7FH ;mask it
|
|
MOV M,A ;put byte
|
|
INX H ;pt to next
|
|
DCR B ;count down
|
|
JNZ ATTRIB1
|
|
POP D ;pt to FCB
|
|
MVI C,ATTR
|
|
CALL BDOS
|
|
XRA A
|
|
DCR A ;no error return
|
|
RET
|
|
|
|
;
|
|
;**************************************************
|
|
;
|
|
; CRC subroutines
|
|
;
|
|
; initialize tables for fast crc calculations
|
|
|
|
INITCRC:
|
|
LHLD CRCTBL
|
|
MVI C,0 ;table index
|
|
GLOOP:
|
|
XCHG
|
|
LXI H,0 ;initialize crc register pair
|
|
MOV A,C
|
|
PUSH B ;save index in c-reg
|
|
MVI B,8
|
|
XRA H
|
|
MOV H,A
|
|
LLOOP:
|
|
DAD H
|
|
BRNC LSKIP
|
|
MVI A,10H ;generator is x^16 + x^12 + x^5 + x^0 as..
|
|
XRA H ;..recommended by ccitt for asynchronous..
|
|
MOV H,A ;..communications. produces the same..
|
|
MVI A,21H ;..results as public domain programs..
|
|
XRA L ;..chek, comm7, mdm7, and modem7.
|
|
MOV L,A
|
|
LSKIP:
|
|
BJNZ LLOOP
|
|
POP B
|
|
XCHG ;de-pair now has crc, hl pointing into table.
|
|
MOV M,D ;store high byte of crc..
|
|
INR H
|
|
MOV M,E ;..and store low byte.
|
|
DCR H
|
|
INX H ;move to next table entry
|
|
INR C ;next index
|
|
BRNZ GLOOP
|
|
RET
|
|
|
|
UPDCRC:
|
|
PUSH B ;update 'crc'..
|
|
PUSH H ;..accumulator..
|
|
LHLD CRCVAL ;pick up partial remainder
|
|
XCHG ;de-pair now has partial
|
|
MVI B,0
|
|
XRA D
|
|
MOV C,A
|
|
LHLD CRCTBL
|
|
DAD B
|
|
MOV A,M
|
|
XRA E
|
|
MOV D,A
|
|
INR H
|
|
MOV E,M
|
|
XCHG
|
|
SHLD CRCVAL
|
|
POP H
|
|
POP B
|
|
RET
|
|
|
|
;
|
|
;**************************************************
|
|
;
|
|
; WORKHORSE Routines
|
|
;
|
|
; conin routine (waits for response)
|
|
;
|
|
KEYIN:
|
|
CALL CIN ;get input
|
|
CALL CAPS ;capitalize
|
|
JMP COUT ;echo
|
|
|
|
; direct console input w/o echo (waits for input)
|
|
|
|
DKEYIN:
|
|
CALL CIN ;get char from BIOS
|
|
JMP CAPS ;capitalize
|
|
|
|
; convert keyboard input to upper case
|
|
|
|
CONVERT:
|
|
LHLD CMDBUF ; 'current keyboard buffer length'..
|
|
INX H
|
|
MOV B,M ;..to b-reg.
|
|
MOV A,B
|
|
ORA A ;if zero length, skip conversion.
|
|
JZ COMCAN
|
|
CONVLP:
|
|
INX H ;point at character to capitalize
|
|
MOV A,M
|
|
CALL CAPS
|
|
MOV M,A ;put back into buffer
|
|
BJNZ CONVLP
|
|
RET
|
|
;
|
|
; Fill buffer with 'spaces' with count in b-reg
|
|
;
|
|
FILL:
|
|
MVI M,' ' ;put in space character
|
|
INX H
|
|
BJNZ FILL ;no, branch.
|
|
RET
|
|
;
|
|
; Ignore leading spaces (ls) in buffer, length in c-reg.
|
|
;
|
|
UNSPACE:
|
|
LDAX D ;get character
|
|
CPI ' '
|
|
RNZ ;not blank, a file is entered.
|
|
INX D ;to next character
|
|
DCR C
|
|
JZ COMCAN ;all spaces --> command recovery error
|
|
BR UNSPACE
|
|
;
|
|
; Check for legal filename character -- return with carry set if illegal
|
|
;
|
|
CKLEGAL:
|
|
LDAX D ;get character from de-pair
|
|
INX D ;point at next character
|
|
CPI ' ' ;less than space?
|
|
RC ;return carry if unpermitted character
|
|
PUSH H
|
|
PUSH B
|
|
CPI '[' ;if greater than 'z', exit with..
|
|
BRNC CKERR ;..carry set.
|
|
MVI B,CHR$TEND-CHR$TBL
|
|
LXI H,CHR$TBL
|
|
CHR$LP:
|
|
CMP M
|
|
BRZ CKERR
|
|
INX H
|
|
BJNZ CHR$LP
|
|
ORA A ;clear carry for good character
|
|
POP B
|
|
POP H
|
|
RET
|
|
|
|
CKERR:
|
|
POP B
|
|
POP H
|
|
STC ;error exit with carry set
|
|
RET
|
|
|
|
CHR$TBL:
|
|
DB ',',':',';','<','=','>' ;invalid character table
|
|
CHR$TEND:
|
|
DS 0
|
|
;
|
|
; Print file name in S$FCB
|
|
;
|
|
PRFNSX:
|
|
PUSH H ;save regs
|
|
PUSH B
|
|
BR PRFNS0
|
|
PRFNS:
|
|
PUSH H ;affect only PSW
|
|
PUSH B
|
|
LXI H,S$FCB+1
|
|
PRFNS0:
|
|
CALL PRFN ;print file name
|
|
POP B ;restore
|
|
POP H
|
|
RET
|
|
;
|
|
; Print file name pted to by HL
|
|
;
|
|
PRFN:
|
|
MVI B,8 ;8 chars
|
|
CALL PRFNS1
|
|
MVI A,'.'
|
|
CALL COUT
|
|
MVI B,3 ;file type and fall thru
|
|
PRFNS1:
|
|
MOV A,M ;get char
|
|
CALL COUT
|
|
INX H ;pt to next
|
|
BJNZ PRFNS1
|
|
RET
|
|
;
|
|
; Copy filename from RINGPOS to SFCB
|
|
;
|
|
RINGFCB:
|
|
LHLD RINGPOS ;move name from ring to source 'fcb'
|
|
LXI D,S$FCB ;place to move filename and..
|
|
MVI B,12 ;..amount to move (fall thru to MOVE)
|
|
;
|
|
; move subroutine -- move b-reg # of bytes from hl-pair to de-pair
|
|
;
|
|
MOVE:
|
|
MOV A,M ;get hl-pair referenced source byte
|
|
ANI 7FH ;strip attributes
|
|
STAX D ;put to de-pair referenced destination
|
|
INX H ;fix pointers for next search
|
|
INX D
|
|
BJNZ MOVE
|
|
RET
|
|
|
|
MOVEB:
|
|
PUSH H ;SAVE HL, DE
|
|
PUSH D
|
|
CALL MOVE
|
|
POP D ;RESTORE DE, HL
|
|
POP H
|
|
RET
|
|
;
|
|
; Initialize FCB system fields (entry with hl-pair pointing to FCB)
|
|
;
|
|
INITFCB:
|
|
MVI B,21 ;fill ex, s1, s2, rc, cr counters with zeros.
|
|
INITLP:
|
|
MVI M,0 ;put zero (null) in memory
|
|
INX H
|
|
BJNZ INITLP
|
|
RET
|
|
;
|
|
; Disk system reset -- login requested drive
|
|
;
|
|
RESET:
|
|
MVI C,RESETDK ;reset system
|
|
CALL BDOS
|
|
LDA R$DR ;make requested drive..
|
|
SET$DR:
|
|
MOV E,A ;..current
|
|
MVI C,LOGIN
|
|
JMP BDOS ;return to caller
|
|
;
|
|
; Set/reset (or get) user area (call with binary user area in a-reg)
|
|
;
|
|
SET$USR:
|
|
MOV E,A ;user number in E
|
|
GET$USR:
|
|
MVI C,SGUSER
|
|
JMP BDOS ;return to caller
|
|
;
|
|
; Compare de-pair to hl-pair and set flags accordingly
|
|
;
|
|
CMPDEHL:
|
|
MOV A,D ;see if high bytes set flags
|
|
CMP H
|
|
RNZ ;return if not equal
|
|
MOV A,E
|
|
CMP L ;low bytes set flags instead
|
|
RET
|
|
;
|
|
; Shift hl-pair b-reg bits (-1) to right (divider routine)
|
|
;
|
|
SHIFTLP:
|
|
DCR B
|
|
RZ
|
|
MOV A,H
|
|
ORA A
|
|
RAR
|
|
MOV H,A
|
|
MOV A,L
|
|
RAR
|
|
MOV L,A
|
|
BR SHIFTLP
|
|
|
|
;
|
|
; Determine free storage remaining on selected drive
|
|
;
|
|
FRESTOR:
|
|
MVI C,INQDISK ;determine current drive
|
|
CALL BDOS ;returns 0 as a:, 1 as b:, etc.
|
|
INR A ;make 1 --> a:, 2 --> b:, etc.
|
|
STA FCB
|
|
MVI C,GETPARM ;current disk parameter block
|
|
CALL BDOS
|
|
INX H ;bump to..
|
|
INX H
|
|
MOV A,M ;..block shift factor.
|
|
STA BSHIFTF ; 'bsh'
|
|
INX H ;bump to..
|
|
MOV A,M ;..block mask.
|
|
STA B$MASK ; 'blm'
|
|
INX H ;bump to..
|
|
INX H ;..get..
|
|
MOV E,M ;..maximum block number..
|
|
INX H ;..double..
|
|
MOV D,M ;..byte.
|
|
XCHG
|
|
SHLD B$MAX ; 'dsm'
|
|
MVI C,INQALC ;address of allocation vector
|
|
CALL BDOS
|
|
XCHG ;get its length
|
|
LHLD B$MAX
|
|
INX H
|
|
LXI B,0 ;initialize block count to zero
|
|
GSPBYT:
|
|
PUSH D ;save allocation address
|
|
LDAX D
|
|
MVI E,8 ;set to process 8 bits (blocks)
|
|
GSPLUP:
|
|
RAL ;test bit
|
|
BRC NOT$FRE
|
|
INX B
|
|
NOT$FRE:
|
|
MOV D,A ;save bits
|
|
DCX H
|
|
MOV A,L
|
|
ORA H
|
|
BRZ END$ALC ;quit if out of blocks
|
|
MOV A,D ;restore bits
|
|
DCR E ;count down 8 bits
|
|
BRNZ GSPLUP ;branch to do another bit
|
|
POP D ;bump to next count..
|
|
INX D ;..of allocation vector.
|
|
BR GSPBYT ;process it
|
|
|
|
END$ALC:
|
|
POP D ;clear alloc vector pointer from stack
|
|
MOV L,C ;copy # blocks to hl-pair
|
|
MOV H,B
|
|
LDA BSHIFTF ;get block shift factor
|
|
SUI 3 ;convert from sectors to thousands (k)
|
|
BRZ PRT$FRE ;skip shifts if 1k blocks
|
|
FREK$LP:
|
|
DAD H ;multiply blocks by k-bytes per block
|
|
DCR A ;multiply by 2, 4, 8, or 16.
|
|
BRNZ FREK$LP
|
|
PRT$FRE:
|
|
SHLD DISKSP ;save disk space
|
|
RET
|
|
;
|
|
; Print free space on disk
|
|
;
|
|
PRINT$FRE:
|
|
CALL ERMSG ;position and set flags
|
|
DB 0
|
|
LHLD DISKSP
|
|
CALL PHLFDC ; # of free k-bytes in hl-pair
|
|
CALL VPRINT
|
|
DB 'K Bytes on Disk',0
|
|
RET
|
|
|
|
;
|
|
;**************************************************
|
|
;
|
|
; MESSAGE Routines
|
|
;
|
|
; Print VFILER Banner
|
|
;
|
|
BANNER:
|
|
CALL VCLS ;clear screen
|
|
LXI H,BANADR
|
|
CALL GOTOXY
|
|
CALL VPRINT ;print banner
|
|
DB 'VFILER, Version '
|
|
DB VERS/10+'0','.',(VERS MOD 10)+'0'
|
|
IF Z80
|
|
DB ' '
|
|
; DB DIM ;<JPS>
|
|
DB '[Z80 Code]'
|
|
; DB BRIGHT ;<JPS>
|
|
ELSE
|
|
DB ' '
|
|
; DB DIM ;<JPS>
|
|
DB '[8080 Code]'
|
|
; DB BRIGHT ;<JPS>
|
|
ENDIF
|
|
DB 0
|
|
RET
|
|
;
|
|
; Home the Cursor
|
|
;
|
|
CUR$FIRST:
|
|
LXI H,CURHOME ; HOME ADDRESS
|
|
SHLD CURAT ; SET CURSOR POSITION
|
|
JMP GOTOXY
|
|
;
|
|
; Last File Position
|
|
;
|
|
CUR$LAST:
|
|
LHLD RINGPOS ; ADVANCE
|
|
SHLD LOCPOS ; SET LOCAL POSITION
|
|
CL0:
|
|
LXI D,13
|
|
DAD D
|
|
XCHG
|
|
LHLD LOCEND ; END OF LOCAL RING?
|
|
CALL CMPDEHL
|
|
RZ
|
|
XCHG ; NEW POSITION
|
|
SHLD LOCPOS
|
|
PUSH H ; SAVE POSITION
|
|
CALL CUR$NEXT ; ADVANCE CURSOR
|
|
POP H ; GET POSITION
|
|
BR CL0
|
|
;
|
|
; Advance the Cursor
|
|
;
|
|
CUR$NEXT:
|
|
LHLD CURAT ; COMPUTE NEW POSITION
|
|
MOV A,L ; CHECK FOR NEW LINE
|
|
ADI 19 ; SIZE OF EACH ENTRY
|
|
CPI 70
|
|
BRNC CN1 ; ADVANCE TO NEXT LINE
|
|
MOV L,A ; NEW POSITION
|
|
SHLD CURAT
|
|
JMP GOTOXY
|
|
CN1:
|
|
MOV A,H ; GET LINE
|
|
LXI H,CURHOME ; GET COL
|
|
MOV H,A ; SET LINE AND FALL GO TO CUR$DOWN
|
|
SHLD CURAT
|
|
BR CUR$DOWN
|
|
;
|
|
; Back Up the Cursor
|
|
;
|
|
CUR$BACK:
|
|
LXI H,CURHOME ; GET HOME
|
|
XCHG ; ... IN DE
|
|
LHLD CURAT
|
|
CALL CMPDEHL ; COMPARE
|
|
BRZ CUR$LAST ; GOTO END IF LAST
|
|
MOV A,L ; CHECK FOR FIRST COL
|
|
CMP E
|
|
BRZ CB1
|
|
SUI 19 ; BACK UP ONE COL
|
|
MOV L,A
|
|
SHLD CURAT ; NEW POS
|
|
JMP GOTOXY
|
|
CB1:
|
|
MOV A,E ; GET HOME COL
|
|
ADI 19*3 ; GET LAST COL
|
|
MOV L,A
|
|
DCR H ; PREV LINE
|
|
SHLD CURAT
|
|
JMP GOTOXY
|
|
;
|
|
; Move Cursor Down One Line
|
|
;
|
|
CUR$DOWN:
|
|
LXI H,CURHOME ; GET HOME ADDRESS
|
|
MOV B,H ; LINE IN B
|
|
LHLD CURAT ; GET CURRENT ADDRESS
|
|
INR H ; MOVE DOWN
|
|
MOV A,H ; CHECK FOR TOO FAR
|
|
SUB B
|
|
CPI EPS/4
|
|
BRNC CD1
|
|
SHLD CURAT ; OK, SO SET POSITION
|
|
JMP GOTOXY
|
|
CD1:
|
|
MOV A,L ; GET COL
|
|
LXI H,CURHOME
|
|
MOV L,A
|
|
SHLD CURAT
|
|
JMP GOTOXY
|
|
;
|
|
; Refresh Screen
|
|
;
|
|
REFRESH:
|
|
LHLD CURAT ; SAVE CURSOR AND RING POSITIONS
|
|
SHLD SCURAT
|
|
LHLD RINGPOS
|
|
SHLD SRINGPOS
|
|
CALL BANNER ; PRINT BANNER
|
|
;
|
|
IF BIHELP ;built-in help?
|
|
LDA HELPDISP ;DISPLAY HELP?
|
|
ORA A ;0=NO
|
|
BRZ REF1
|
|
CALL HELPMSG ;PRINT HELP MESSAGE
|
|
BR REF2
|
|
REF1:
|
|
ENDIF ;BIHELP
|
|
;
|
|
CALL DISPFILES ; DISPLAY FILES
|
|
REF2:
|
|
LXI H,DUADR ; DU ADDRESS
|
|
CALL GOTOXY
|
|
LXI H,C$DR ; PT TO CURRENT DRIVE (FOLLOWED BY CUR USER)
|
|
CALL STNDOUT ;<RID> TURNON HIGHLIGHTING
|
|
CALL PRDU ; PRINT DU:DIR>
|
|
CALL STNDEND ;<RID> TURN OFF HIGHLIGHTING
|
|
LXI H,CPMADR ; COMMAND PROMPT MESSAGE
|
|
CALL GOTOXY
|
|
CALL VPRINT ; PROMPT WITH DRIVE PREFIX
|
|
DB DIM
|
|
DB 'Command (? = ',0
|
|
LDA HELPDISP ; IN HELP NOW?
|
|
ORA A ; 0=NO
|
|
BRZ REF3
|
|
CALL VPRINT
|
|
DB 'Files',0
|
|
BR REF4
|
|
REF3:
|
|
CALL VPRINT
|
|
DB 'Help',0
|
|
REF4:
|
|
CALL VPRINT
|
|
DB ')?',BRIGHT,0
|
|
LHLD SCURAT ; RESTORE CURSOR AND RING POSITIONS
|
|
SHLD CURAT
|
|
LHLD SRINGPOS
|
|
SHLD RINGPOS
|
|
CALL SETCUR ; RESTORE CURSOR ON SCREEN
|
|
RET
|
|
;
|
|
; Print DU pted to by HL
|
|
;
|
|
PRDU:
|
|
PUSH H ; SAVE REGS
|
|
PUSH B
|
|
MOV A,M ; GET DRIVE
|
|
MOV B,A
|
|
ADI 'A' ; CONVERT TO LETTER
|
|
CALL COUT
|
|
INX H ; PT TO USER
|
|
MOV A,M ; GET USER
|
|
MOV C,A
|
|
CALL PAFDC ; PRINT USER AS FLOATING
|
|
MVI A,':' ; PRINT COLON
|
|
CALL COUT
|
|
CALL DUTDIR ; SCAN NAMED DIRECTORY TABLE
|
|
BRZ PRDU2 ; NO NAME?
|
|
MVI B,8 ; PRINT NAME
|
|
PRDU1:
|
|
MOV A,M ; GET CHAR
|
|
CPI ' ' ; DONE IF SPACE ENCOUNTERED
|
|
BRZ PRDU3
|
|
CALL COUT
|
|
INX H
|
|
BJNZ PRDU1
|
|
BR PRDU3
|
|
PRDU2:
|
|
CALL VPRINT
|
|
DB 'Noname',0
|
|
PRDU3:
|
|
POP B ; RESTORE REGS
|
|
POP H
|
|
RET
|
|
|
|
;
|
|
; Refresh File Display
|
|
;
|
|
DISPFILES:
|
|
CALL CUR$FIRST ; POSITION CURSOR AT FIRST POSITION
|
|
LHLD LOCBEG ; PT TO FIRST FILE NAME
|
|
SHLD LOCPOS ; SAVE LOCAL POSITION
|
|
DSPF1:
|
|
LHLD LOCEND ; AT END?
|
|
XCHG
|
|
LHLD LOCPOS
|
|
CALL CMPDEHL
|
|
JZ CUR$FIRST ; POSITION AT FIRST ENTRY AND RETURN
|
|
MVI B,4 ; 4 SPACES
|
|
MVI A,' '
|
|
DSPF2:
|
|
CALL COUT
|
|
BJNZ DSPF2
|
|
PUSH H ; SAVE CURRENT LOCAL POSITION IN RING
|
|
;<RID> INX H ; PT TO FILE NAME
|
|
;<RID> CALL PRFN ; PRINT FILE NAME
|
|
;<RID> MOV A,M ; PRINT TAG
|
|
;<RID> CALL COUT
|
|
CALL HILITFN ;<RID> brigten filename
|
|
POP H ; GET CURRENT LOCAL POSITION
|
|
LXI D,13
|
|
DAD D
|
|
SHLD LOCPOS
|
|
CALL CUR$NEXT ; ADVANCE CURSOR
|
|
BR DSPF1
|
|
|
|
HILITFN: ;<RID>
|
|
PUSH H ;<RID> save for later
|
|
LXI D,12 ;<RID> locate the tag byte
|
|
DAD D ;<RID>
|
|
MOV A,M ;<RID> put tag byte in a for store
|
|
STA TAGFLG ;<RID>
|
|
POP H ;<RID> back to beginning of filename
|
|
INX H ;<RID> point to filename
|
|
LDA TAGFLG ;<RID>
|
|
CPI ' ' ;<RID> if space don't highlight
|
|
CNZ STNDOUT ;<RID> set highlight on
|
|
CALL PRFN ;<RID> put out filename
|
|
MOV A,M ;<RID> get tag byte
|
|
CALL COUT ;<RID> and output it
|
|
LDA TAGFLG ;<RID>
|
|
CPI ' ' ;<RID>
|
|
CNZ STNDEND ;<RID> turn off highlighting
|
|
RET ;<RID>
|
|
; Position Cursor at CURAT
|
|
;
|
|
SETCUR:
|
|
LDA HELPDISP ; NOGO IF IN HELP DISPLAY
|
|
ORA A
|
|
RNZ
|
|
LHLD CURAT
|
|
CALL GOTOXY
|
|
CALL VPRINT
|
|
DB DIM,'-->',BRIGHT,0
|
|
RET
|
|
;
|
|
; Clear Cursor
|
|
;
|
|
CLRCUR:
|
|
LDA HELPDISP ; NOGO IF IN HELP DISPLAY
|
|
ORA A
|
|
RNZ
|
|
LHLD CURAT
|
|
CALL GOTOXY
|
|
CALL VPRINT
|
|
DB ' ',0
|
|
RET
|
|
;
|
|
; Command Prompt
|
|
;
|
|
CPRMPT:
|
|
LXI H,CPADR ; GET ADDRESS
|
|
MPRINT:
|
|
PUSH H ; SAVE ADDRESS
|
|
CALL GOTOXY
|
|
PUSH B
|
|
;<RID> MVI B,76-(CPADR MOD 255)
|
|
LDA CWIDTH ;<RID> find screen length in chars
|
|
SUI (CPADR MOD 256)-1 ;<RID> determine number of char. to blank
|
|
MOV B,A ;<RID> put number in b
|
|
CALL VEREOL ; ERASE TO EOL
|
|
POP B
|
|
POP H ; GET ADDRESS
|
|
CALL GOTOXY ; POSITION CURSOR
|
|
JMP VPRINT ; PRINT MESSAGE AND RETURN
|
|
;
|
|
; Working Message
|
|
;
|
|
WORKMSG:
|
|
CALL ERMSG
|
|
DB DIM,'Working ...',BRIGHT,0
|
|
RET
|
|
;
|
|
; Error Message
|
|
;
|
|
ERMSG:
|
|
MVI A,0FFH ; SET ERROR MESSAGE FLAG
|
|
STA ERMFLG
|
|
LXI H,ERADR ; GET ADDRESS
|
|
BR MPRINT
|
|
;
|
|
; Print File Size Info
|
|
;
|
|
FSNOTE:
|
|
CALL ERMSG ; USE THIS ROUTINE
|
|
DB 'Size of ',0
|
|
RET
|
|
;
|
|
; Position for File Size Print
|
|
;
|
|
ATFS:
|
|
LXI H,FSADR+13 ; POSITION FOR PRINT OF FILE SIZE
|
|
JMP GOTOXY
|
|
;
|
|
; Clear Error Message
|
|
;
|
|
ERCLR:
|
|
XRA A ; CLEAR FLAG
|
|
STA ERMFLG
|
|
LXI H,ERADR ; POSITION
|
|
CALL GOTOXY
|
|
PUSH B
|
|
;<RID> MVI B,76-(ERADR MOD 255)
|
|
LDA CWIDTH ;<RID> find screen length in chars
|
|
SUI (ERADR MOD 256)-1 ;<RID> determine number of char. to blank
|
|
MOV B,A ;<RID> put number in b
|
|
CALL VEREOL ; ERASE TO EOL
|
|
POP B
|
|
RET
|
|
;
|
|
; Position at Command Prompt and Clear It
|
|
;
|
|
ATCMD:
|
|
LXI H,CPADR ; POSITION
|
|
CALL GOTOXY
|
|
PUSH B
|
|
;<RID> MVI B,76-(CPADR MOD 255)
|
|
LDA CWIDTH ;<RID> find screen length in chars
|
|
SUI (CPADR MOD 256)-1 ;<RID> determine number of char. to blank
|
|
MOV B,A ;<RID> put number in b
|
|
CALL VEREOL ; CLEAR MESSAGE
|
|
POP B
|
|
LXI H,CPADR ; REPOSITION
|
|
JMP GOTOXY
|
|
;
|
|
; Position at Bottom of Screen and Prompt for Continuation
|
|
;
|
|
BOTTOM:
|
|
LXI H,BOTADR ; POSITION
|
|
CALL GOTOXY
|
|
;
|
|
; Prompt for Continuation
|
|
;
|
|
SAK:
|
|
CALL VPRINT
|
|
DB DIM,'Strike Any Key -- ',BRIGHT,0
|
|
JMP KEYIN
|
|
|
|
|
|
;
|
|
; S T O R A G E
|
|
;
|
|
; Initialized
|
|
;
|
|
HEADMSG:
|
|
DB 'File: ',0
|
|
MOREHELP:
|
|
DB 'HELP ' ;HELP Command for further info
|
|
VFNAME ;VFILER Name
|
|
DB 0
|
|
MACFCB:
|
|
DB 0
|
|
VFNAME ;VFILER Name
|
|
VFNFILL ;Filler
|
|
DB 'CMD'
|
|
FILERCMD:
|
|
VFNAME ;VFILER Name
|
|
VFNFILL ;Filler
|
|
DB ' ' ;one space
|
|
FILE$D:
|
|
DB 'x'
|
|
FILE$U:
|
|
DB 'xx'
|
|
DB ':' ;colon
|
|
DB 0
|
|
JOKER:
|
|
DB '???????????' ;*.* equivalent
|
|
FIRST$M:
|
|
DB FALSE ;1st time thru in mass-copy mode
|
|
MFLAG:
|
|
DB TRUE ;multiple file copy flag-->0 for mass copy
|
|
TAG$TOT:
|
|
DW 0 ;summation of tagged file sizes
|
|
CMDBUF:
|
|
DS 2 ;command buffer maximum length, usage, and..
|
|
;
|
|
; Uninitialized
|
|
;
|
|
STACK:
|
|
DS 2
|
|
LWIDTH:
|
|
DS 1 ;WIDTH OF LINE
|
|
LTPP:
|
|
DS 1 ;LINES OF TEXT PER PAGE
|
|
LSPP:
|
|
DS 1 ;LINES TO SKIP PER PAGE
|
|
LFFEED:
|
|
DS 1 ;PRINTER CAN FORMFEED? (0=NO)
|
|
CWIDTH:
|
|
DS 1 ;WIDTH OF SCREEN
|
|
CTPP:
|
|
DS 1 ;LINES OF TEXT PER SCREEN
|
|
CSPP:
|
|
DS 1 ;LINES TO SKIP PER SCREEN
|
|
ALPHA:
|
|
DS 1 ;alphabetization flag (0=type and name, 0FFH=
|
|
;...name and type)
|
|
B$MAX:
|
|
DS 2 ;highest block number on drive
|
|
B$MASK:
|
|
DS 1 ;sec/blk-1
|
|
BSHIFTF:
|
|
DS 1 ;# of shifts to multiply by sec/blk
|
|
BUFENTRY:
|
|
DS 2 ;buffer start
|
|
BUF$PT:
|
|
DS 2 ;copy buffer current pointer..
|
|
BUFSTART:
|
|
DS 2 ;..and begin pointer.
|
|
CANFLG:
|
|
DS 1 ;no-file-found cancel flag
|
|
C$DR:
|
|
DS 1 ;'current drive'
|
|
C$U$A:
|
|
DS 1 ;'current user area' (must follow C$DR)
|
|
CHARCNT:
|
|
DS 1 ;character count for tab expansion
|
|
CON$LST:
|
|
DS 1 ;bdos function storage
|
|
CRCTBL:
|
|
DS 2 ;tables for 'crc' calculations
|
|
CRCVAL:
|
|
DS 2 ;2-byte 'crc' value of working file and..
|
|
CRCVAL2:
|
|
DS 2 ;..of finished source read-file.
|
|
CURAT:
|
|
DS 2 ;current cursor position
|
|
DELCODE:
|
|
DS 1 ;deletion code (0=delete not done)
|
|
D$FCB:
|
|
DS 33 ;fcb for destination file/new name if rename
|
|
DISKSP:
|
|
DS 2 ;space remaining on disk
|
|
DUM$FCB:
|
|
DS 2 ;dummy FCB for file attributes
|
|
DRLET:
|
|
DS 1 ;scratch for drive letter
|
|
EOFLAG:
|
|
DS 1 ;file copy loop 'eof' flag
|
|
ERMFLG:
|
|
DS 1 ;error message present flag
|
|
H$DR:
|
|
DS 1 ;home drive
|
|
H$U$A:
|
|
DS 1 ;home user area (must follow H$DR)
|
|
HELPDISP:
|
|
DS 1 ;display help screen (0=no)
|
|
LPSCNT:
|
|
DS 1 ;lines-per-screen for 'view'
|
|
LOCBEG:
|
|
DS 2 ;local beginning of ring
|
|
LOCEND:
|
|
DS 2 ;local end of ring
|
|
LOCPOS:
|
|
DS 2 ;local ring position (temp)
|
|
MASSOP:
|
|
DS 1 ;mass file operation code (0=no)
|
|
MAXDR:
|
|
DS 1 ;max driver letter
|
|
MDFLG:
|
|
DS 1 ;mass delete verify flag
|
|
O$USR:
|
|
DS 1 ;store initial user area for exit
|
|
R$DR:
|
|
DS 1 ;'requested drive'
|
|
RCNT:
|
|
DS 2 ;# of records in file and..
|
|
REC$CNT:
|
|
DS 2 ;..currently in ram buffer.
|
|
REC$MAX:
|
|
DS 2 ;maximum 128-byte record capacity of buffer
|
|
RING:
|
|
DS 2 ;ptr to beginning of ring
|
|
RINGI:
|
|
DS 2 ;ring sort pointer
|
|
RINGJ:
|
|
DS 2 ;another ring sort pointer
|
|
RINGEND:
|
|
DS 2 ;current ring end pointer
|
|
RINGPOS:
|
|
DS 2 ;current ring position in scan
|
|
R$U$A:
|
|
DS 1 ;'requested user area'
|
|
SCURAT:
|
|
DS 2 ;save cursor position
|
|
S$FCB:
|
|
DS 36 ;fcb for source (random record) file
|
|
SRINGPOS:
|
|
DS 2 ;save ring position
|
|
TAGFLG: ;<RID> temp for tag
|
|
DS 1 ;<RID>
|
|
T$DR:
|
|
DS 1 ;temp disk
|
|
TEST$RT:
|
|
DS 1 ;intermediate right-justify data
|
|
T$U$A:
|
|
DS 1 ;temp user
|
|
T$UN$FG:
|
|
DS 1 ;tag/untag file summation switch
|
|
USER:
|
|
DS 1 ;temp user buffer
|
|
VIEWFLG:
|
|
DS 1 ;<RID> (00h) 1-->to list/punch else to crt 'view'
|
|
|
|
END
|
|
|
|
|