home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-12 | 33.1 KB | 1,255 lines |
- ; ZPATCH vers 1.3
- ; April 5, 1988
- ; author: Steven M. Cohen
- ;
- ; Version 1.3 fixes various bugs in version 1.1.
- ; -- Searches now work correctly after the search function's help
- ; screen is printed. (Thanks, Ron Bardarson)
- ; -- The infamous "8-character" NDR bug (which, incredibly enough
- ; caused the display to go haywire) has been fixed. (Thanks, Bruce Morgen)
- ; -- An error in the DEC24 routine of M24 has been fixed. DEC24 was
- ; not used until version 1.3, so the error went unnoticed.
- ;
- ; The following enhancements are also provided:
- ; -- Some needless screen-repainting has been eliminated. (More work
- ; is still to be done in this area.)
- ; -- Arrow keys now work in the non-edit mode for advancing the address
- ; pointer byte by byte.
- ; -- Several command keys have been changed for more consistency with other
- ; Z-system tools:
- ; X (execute) changed to R (run)
- ; R (record #) changed to #
- ; Q and (quit) changed to X and (exit)
- ; -- This version is a ZCPR33 type-3 utility that can be linked to origin at
- ; addresses other than 100H.
- ; -- It automatically set the offset when working on Z33 type-3 .COM files
- ; to their correct load address.
- ; -- The ZEXRUN code has been eliminated in accordance with Jay Sage's
- ; Z33 programming notes
- ;
- ; This is an INTERIM version that fixes all known bugs.
- ; On the drawing board is an entirely revamped version that will implement
- ; a much more logical command interface and several other new features.
- ; Since I am rather busy these days, I decided to relase this version now
- ; because I have no idea when the revamped version will be released.
- ;
- ; ZPATCH and all files contained within ZPATCH13.LBR are copyright
- ; 1988 by Steven M. Cohen. They are released Apr 5, 1988 through the
- ; good offices of ZSIG, the Z-system users group. They may be freely
- ; copied by all but must not be sold either by themselves or as part
- ; of another package of software without the expressed written consent
- ; of the author.
- ;
- ; The author may be contacted by electronic mail on the Lillipute Z-Node
- ; in Chicago, 312-649-1730, which is also the official remote access system
- ; of ZSIG.
- ;
- ; This program was very much a learning experience for the programmer.
- ; It uses a MODULAR approach to assembly language programming, wherein
- ; the whole was built up from building blocks which might also find use
- ; in different future applications. One advantage of this approach for me
- ; was that once debugged these routines only needed to be LINKED to the rest
- ; of the program, not reassembled over and over. The disadvantage for the
- ; reader of this source code is that it might just be more difficult to follow.
- ; That is why source code has been so long in being released for this program.
- ; Finally after some prodding by Bruce Morgen I am releasing this source,
- ; even as I understand that some may find it difficult to follow. Better
- ; something than nothing, however.
- ;
- ; the files BEDITOR.REL, M24.REL, and SYSEXT.REL are relocatable files
- ; included in ZPATCH11.LBR.
- ;
- ; BEDITOR.REL is a library of routines for the byte editor used in
- ; ZPATCH.
- ;
- ; M24.REL is a library of routines to handle conversion of numeric strings
- ; to 24-bit numbers. It also includes some utility routines for handling
- ; these quantities.
- ;
- ; SYSEXT.REL is a library of routines either built upon or replacing
- ; routines from SYSLIB,Z3LIB,and VLIB, which may be regarded as useful
- ; extensions to these.
- ;
- ; Source for all these libraries has been released.
- ;
- ; EXTERNAL ROUTINES used by ZPATCH
- ;
- ; routines found in the standard Z-system libraries of Richard Conn
- ;
- ; syslib
- EXT IALLOC,ALLOC,BLINE,CAPS,CIN,COUT,PA2HC,GETFS1
- EXT MHL4HC,PHL4HC,F$OPEN,R$READ,R$WRITE,F$CLOSE,COMPHD
- EXT RETUD,LOGUD,CRLF,SKSP,SKNSP,F$READ
- ; z3lib
- EXT ZFNAME,PUTCST,GETEFCB,GETSH2,QSHELL,SHPOP,SHPUSH,GETWHL
- EXT PUTZEX,GETZRUN,GETCL1,GETCL2,PUTCL,DUTDIR,GETDUOK,GETEFCB
- EXT ROOT
- ; vlib
- EXT Z3VINIT,VPRINT,AT,STNDEND,GXYMSG,EREOL,CLS,TINIT,DINIT,GOTOXY
- ; z33lib
- EXT GETSRUN
- ;
- ;ROUTINES from libraries that were developed by the author for use in
- ;this program and possibly others.
- ;
- ; beditor
- EXT SHOWBYTE,SEARCH,CONTINU,INFOMSG,DISPLAY,SAK,MESSAGE
- EXT EDITOR,HEXDMP,DSPSEC,UNSHOWB
- ;
- ; m24
- EXT DOUBLE24,HALVE24,RADIX,NUMINP,RADIXDSP
- ;
- ; sysext
- EXT VLPSTR,VPSTR,LDFIL,MUD,DUDIRPFX,COPY8
- ;
- ;Assembly instructions for ZPATCH:
- ;
- ;Z80ASM/SLRNK:
- ;
- ;SET SLR EQUATE TO TRUE
- ;then
- ;Z80ASM ZPATCH.%D%D%Z/6;IF ~ER;SLRNK /P:nnnn,ZPATCH,ZPATCH/N/E;FI
- ; where nnnn is the desired hex load address
- ;
- ;
- ;M80/L80:
- ;SET SLR EQUATE TO FALSE
- ;then
- ;m80=zpatch
- ;l80 zpatch,beditor/s,m24/s,sysext/s,z33lib/s,vlib/s,z3lib/s,syslib/s,zpatch/n/e
- ;
- ;
- ;ZAS/ZLINK:
- ;SET SLR EQUATE TO FALSE
- ;then
- ;ZAS ZPATCH
- ;ZLINK ZPATCH,BEDITOR/,M24/,SYSEXT/,z33lib/,VLIB/,Z3LIB/,SYSLIB/
- ;
- ; If using SLR tools to assemble and link the linking libraries can be
- ; specified within the source program and need not be specified on the
- ; linker command line. If not using the SLR tools the libraries must be
- ; linked in the same order as given under the .request statement below.
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- SLR EQU TRUE ;set false if not using SLR tools
-
- IF SLR
-
- .request BEDITOR,M24,SYSEXT,VLIB,z33lib,Z3LIB,SYSLIB
-
- ENDIF
- ;
- ; VARIABLES USED TO TRANSMIT DATA BETWEEN THIS PROGRAM AND THE
- ; MODULES WITHIN BEDITOR.REL
- ;
- GLOBAL Z3EADR,FCB,OFFS,ABSADR,OUTBUF,FILESIZE,RECNUM
- GLOBAL BUFBEG,STRADR,DEFDU,SECADR,VERSION
- ;
- ; VARIOUS CONSTANTS included in a library file.
- ;
- INCLUDE ZPATCH.LIB
- ;
- ; MACROS needed to accomplish the 24-bit math needed to implement
- ; addressing within files longer than 64K
- ;
- INCLUDE MATH24.LIB
- ;
- .z80 ;for m80 compatiblity
- Z3ENV ASET 0FE00H
- VERS EQU 13
- ; ORG 100H ; SRLNK barfs on this and it's really
- ; unnecessary with any linker if you
- ; give it the proper commands.
- ;
- ; environment definition
- ;
- IF Z3ENV NE 0
- ;
- ; external ZCPR3 environment descriptor
- ;
- ORIGIN:
- JP START
- DB 'Z3ENV' ; this is a ZCPR33 utility
- DB 3 ; type-3 utility
- Z3EADR:
- DW Z3ENV
- DW ORIGIN
- ROOTONLY: ; true if zpatch.com will be located in
- DB TRUE ; root dir:
- USEPATH: ; if rootonly is false, should system search
- DB FALSE ; the path for zpatch.com?
- DUSER: ; if usepath and rootonly are both false
- DB 15 ; make this the user area for ZPATCH.COM
- DDRIVE: DB 0 ; and this the drive
- HELPCH: DB FALSE ; TRUE TO ALLOW CHAINING TO HELP FILE
- ;
- START:
- LD HL,(Z3EADR) ; pt to ZCPR3 environment
- ;
- ELSE ; is this just ritual? Does anyone know of
- ; anyone who uses the internal environmental
- ; descriptor??????
- ;
- ; internal ZCPR3 environment descriptor
- ;
- MACLIB Z3BASE.LIB
- MACLIB SYSENV.LIB
- Z3EADR:
- JP START
- SYSENV
- START:
- LD HL,Z3EADR ; pt to ZCPR3 environment
- ENDIF
- ;
- ; start of program -- initialize ZCPR3 environment
- ;
- CALL Z3VINIT
- CALL TINIT
- ;
- ; Scan the default FCB Area for a help request ('/')
- ;
- LD A,(FCB1+1)
- CP '/' ; Help requested?
- JR NZ,GSH ; no, on with it.
- LD HL,HLPMSG ; yes, give it and
- JP STRING ; abort
- ;
- ; get shell data
- ;
- GSH: CALL GETSH2 ; is there a shell stack?
- LD (SHSTK),HL
- JR Z,SHBAD ; no, abort
- LD A,E
- CP 32 ; Is shell stack entry >= 32 bytes?
- JR NC,SHFINE ; yes, continue
- SHBAD: LD HL,SHERR ; no, so error and abort
- JP STRING
- ;
- ; ZPATCH uses a scheme of shell stack management first hinted at by the author
- ; in his W.Z80, then developed and carried to its logical conclusion by
- ; Jay Sage. The author's idea in W was to use the shell stack to hold
- ; not, strictly speaking, the command line to be reloaded, but also other
- ; information for "taking up where we left off". This was done, in retrospect,
- ; quite clumsily in W -- since we hogged two whole shell stack entries to
- ; accomplish the task. Jay's refinement of this idea was to realize
- ; that the shell stack should not contain the whole command line
- ; but just enough to get the shell reloaded. The shell can be written to
- ; take care of getting the rest of its information, and what is left
- ; of the shell stack entry can be used to store what information is
- ; necessary in an optimal fashion i.e., an FCB fragment
- ; rather than DIR:FILENAME.TYP.
- ;
- ; In the case of ZPATCH we are storing, besides the initial command line,
- ; the name of the file we are working on in the form of an 11-byte
- ; FCB segment (FILENAMETYP), the DU: spec for this file as a word in the
- ; typical SYSLIB format, and finally our address within that file
- ; as three bytes. To make absolutely certain that there will never be
- ; any overlap we are forced to restrict possible
- ; renames of this shell to 6 characters or fewer. We thus allow for an
- ; 8 char named directory entry, a colon, a 6-char command name followed by
- ; a null. That is 16 bytes, leaving 16 in the standard configuration for
- ; our other purposes.
- ;
- ;
-
- SHFINE: ;establish a pointer to the aforementioned
- LD DE,16 ;FCB segment in the shell stack area
- ADD HL,DE ;which is always located at SHSTK+16
- LD (SHFCB),HL ;
- ;must have the extended file control block
- ;feature implemented so ZPATCH knows the
- ;name under which it is to be invoked.
- CALL GETEFCB
- JR NZ,SHF2 ;EFCB IS OK
- LD DE,EFCBERR ;no EFCB, so error msg and abort
- ABORTION:
- JP STRING
- SHF2:
- LD DE,7 ;IF THERE IS an EFCB
- ADD HL,DE ;IT MUST HOLD A <7 CHAR NAME
- LD A,(HL) ;as mentioned above
- CP ' ' ;SO EFCB+7 MUST HOLD A SPACE
- JR Z,WHEELT
- LD HL,NAMERR ;if >6 chars in the name, error msg
- JR ABORTION ;and abort.
- ;
- ;
- ; is user wheel-privileged?
- ;
- WHEELT:
- CALL GETWHL
- JR NZ,ALO ; WHEEL BYTE OKAY, LET USER GO
- LD HL,PEONMSG ; KICK THE SLOB OUT.
- JR ABORTION
- ; now that we have established that we are running on
- ; a Z-system that has the features we need and that we have not
- ; illegally renamed the program we can go on to do the real work
- ; which starts by allocating some variable storage
- ;
- ALO:
- XOR A ; ALLOCATE FREE MEM FROM CODEND
- CALL IALLOC ; TO CCP-1
-
- LD DE,1024
- CALL ALLOC
- LD (OUTBUF),HL ;1024 byte buffer for hex-dump output
-
- LD DE,2
- CALL ALLOC
- LD (BUFBEG),HL ;pointer to BLINE input buffer
- ; initialize this buffer
- LD (HL),255 ; indicate a 255 byte buffer there
- INC HL ;
- LD (HL),0 ; initialize counter byte to 0
- LD DE,512
- CALL ALLOC ; 512 bytes for actual buffer
- ; 256 for input buffer and an
- ; additional 256 for parsing by the search
- ; module
- LD (STRADR),HL ; has its own pointer
-
- LD DE,18 ; another scratch buffer
- CALL ALLOC
- LD (SHELBUF),HL ; 18 bytes long.
- ;
- ;
- CALL RETUD ;get the current du:
- LD (DEFDU),BC ;store it away
- ;
- ; determine whether to install shell or not
- ;
- CALL QSHELL ; is this a call to install shell?
- JR NZ,CKTCAP ; yes, go install
- ; no so prepare to reinvoke.
-
- HIERCHEK: ; check the command level hierarchy
- ; if anything above shell in priority
- ; drop out to the CCP and run that first
- CALL GETCL2 ; command line pending?
- RET NZ ; return to CCP
- CALL GETZRUN ; zex running?
- RET NZ ; return to CCP
- CALL GETSRUN ; submit running
- RET NZ ; return to CCP
- CALL SAK ; our "strike any key" prompt on reinvocation
- LD HL,(SHFCB) ; we first move our info off the shell stack
- LD DE,(FCB) ; to the locations where ZPATCH normally
- LD BC,11 ; expects
- INC DE
- LDIR ; to find it
- LD DE,FILDU ; storage for DU: of file
- LDI ; move two bytes off shell stack
- LDI
- LD DE,ABSADR ; storage for address within file
- LDI ; move three bytes off shell stack.
- LDI
- LDI
- ;
- JP RUNSH ; skip installation of shell
- ;
- ; install shell
- ;
- CKTCAP: ; make sure TCAP is adequate before we get
- ; into things too deeply.
- CALL CLS ; try to clear screen
- JR Z,BADTCAP ; Abort if function missing
- LD HL,0101
- CALL GOTOXY ; try to use direct cursor motion
- JR NZ,INSTSH ; OK to continue
- BADTCAP:
- LD HL,TCAPERR
- JP STRING
-
- INSTSH:
-
- CALL GETDU
- CALL SHASM ; put together the shell stack entry
- ; and load it on the shell stack
- JP Z,runsh ; everything all right
- LD HL,SHERR ; No so error msg
- JP STRING ; and abort
-
- ;
- ; dump the shell and exit
- ; Message in DE.
- ;
- QUIT:
- CALL SHPOP ; take our name off
- JP EXIT ; reset z3 command status and ret to ccp
- ;
- ; write string (address given in DE)
- ;
- STRING:
- CALL CRLF ; new line
- CALL VPSTR ; print string
- RET
- EXIT: XOR A ; common exit point.
- CALL DINIT ; reset the terminal
- JP PUTCST ; reset z3 command status msg and ret to ccp
- ;
- ; assemble our shell stack entry as described above
- SHASM:
- XOR A ; initialize the shell buffer with
- LD HL,(SHELBUF) ; nulls
- PUSH HL ; save its beginning
- LD BC,16
- CALL LDFIL
- ;
- EX DE,HL ; put the buffer address in DE.
- CALL ROOT ; root directory in BC
- LD A,(ROOTONLY) ; is that what we want?
- OR A
- JR NZ,PUTIT ; nz = yes, no need to search further
- LD A,(USEPATH) ; not root only, shall we search
- ; the path (i.e.) put NO DIR reference
- ; in front of "ZPATCH"?
- CPL ; reverse sense
- OR A
- JR Z,PUTFN ; Z says yes
- ; no, get user and drive
- LD BC,(DUSER) ; from the patch area
- ; now that all params are set we can
- PUTIT: CALL DUDIRPFX ; MOVE DIR: or DU: to buffer
- PUTFN: CALL GETEFCB ; EFCB address in HL
- INC HL ; we want its FN field
- CALL COPY8 ; copy just the file name to buffer
- POP HL ; hl holds shstk
- CALL SHPUSH ; put it in shellstack
- LD HL,(FCB) ; now move our copy of the file's FCB
- INC HL
- LD BC,11 ;
- LD DE,(SHFCB) ; to the shell stack
- LDIR
- LD HL,FILDU ; move the file's DU which we've been storing
- LDI ; to the shell stack
- LDI
- LD HL,ABSADR ; and now move our address within the
- LDI ; file (thats 3 bytes)
- LDI ; to shell stack
- LDI
- RET
-
- ;
- RUNSH:
- CALL DRADIX ; Install default radix
- CALL CLS ; clear the screen
- CALL ARROWS
- ;
- ; now evaluate the param in FCB1
- ;
- LD A,(FCB1+1) ; was a parameter left?
- CP ' ' ; space means no
- JP Z,GETFN ; prompt for a file name
- FTOP: ; entry pt for new file load
- LD BC,(FILDU)
- CALL LOGUD ; log into file's DU
- LD DE,(FCB)
- CALL F$OPEN ; open it
- JR Z,FILEOK ; OK?
- FNF:
- LD (FILEFLAG),A ; NO, store that result
- CALL CLS
- CALL BMENU ; present limited menu
- CALL MESSAGE ; tell 'em not found
- DB 'File not Found'
- DB BUZZER,0
- LLOOP:
- CALL MNURD ; read user's response
- LSEARCH:
- LD HL,LCTABLE ; search the limited commands
- JR CMSLOOP ; act on it
- ;
- FILEOK: ; file opened OK
- LD (FILEFLAG),A ;store that result in memory
- CALL F$READ ; read the first record
- PUSH DE ; save pointer to FCB
- CALL OFSFIG ; calculate beginning offset based on file type
- LD (OFFS),HL
- SUB1624 OFFS,TBUFF ; store as a 24-bit quantity
- CALL CLS ; clear the screen
- POP DE ; restore pointer to FCB
- CALL GETFS1 ; file size in records
- DEC HL ; less 1
- LD (FILESIZE),HL ; store file's size to memory
- ;
- ; re entry point for many commands
- ;
- RDLOOP:
- CALL ADRREC ; convert address to record number
- RDLOOP1:
- mov24 OldRecNum,RecNum
- ld hl,(recnum) ; put it in HL
- LD DE,FCB1
- CALL R$READ ; read that record from the file randomly
- EDLOOP:
- LD HL,TBUFF ; 80H in HL
- CALL HEXDMP ; dump the sector into memory
- CALL DISPLAY ; put it on the screen
- EDLOOP1:
- CALL SHOWBYTE ; highlight current byte
- CALL MENU ; show the menu
-
- FLOOP:
- CALL MNURD ; read user choice
- CMSEARCH:
- LD HL,CMTABLE ; full command list
- CMSLOOP:
- LD B,A ; store user choice away
- LD A,(HL) ; get table choice
- OR A ; is it null? (end of table)
- LD A,B ; first restore user choice to A
- JR Z,CMDRET ; not null so do it again
- CP (HL) ; compare user input to table entry
- INC HL ; move to routine address
- JR z,MATCH ; if equal, process command
- INC HL ; unequal, bump the pointer
- INC HL
- JR CMSLOOP ; and check next table entry
- ;
- CMDRET: ; user choice not in table
- LD A,(FILEFLAG) ; working with an open file?
- OR A
- JR Z,FLOOP ; yes, process full menu
- JP LLOOP ; no, process limited menu
- ;
- MATCH: ; user input matches table entry
- LD E,(HL) ; low byte in E
- INC HL
- LD D,(HL) ; high byte in D
- EX DE,HL ; move it to HL
- JP (HL) ; go to it
- ;
- ; table of commands in format:
- ; db command letter
- ; dw command address
- ;
- CMTABLE:
- db '>'
- dw FORWARD
- db '.'
- dw FORWARD
- db '<'
- dw BACK
- db ','
- dw BACK
- db 'A'
- dw ADDRESS
- db 'B'
- dw BOTTOM
- db 'C'
- dw CALLCONT
- db 'E'
- dw ENTRED
- db 'O'
- dw CHOFFSET
- db 'P'
- dw PRINTSEC
- db '#'
- dw RECFIND
- db 'S'
- dw CALLSCH
- db 'T'
- dw TOP
- db 'W'
- dw WRITE
- UpArrow:
- db 'E'-'@'
- DW UP16
- DownArrow:
- db 'X'-'@'
- DW DOWN16
- LeftArrow:
- db 'S'-'@'
- DW UP1
- RightArrow:
- db 'D'-'@'
- DW DOWN1
- LCTABLE: ; limited command table entry point
- db 'X'-'@' ; quit with either ^Q
- dw QUITZP
- db 'X' ; or Q
- dw QUITZP
- db 'F'
- dw GETFN
- db 'H'
- dw HELP
- db 'R'
- dw XECUTE
- db 'Z'
- dw ZCPR3
- db 0 ; indicated end of command table
- ;
- ENTRED: ; entry and exit from editor
- CALL EDITOR
- PUSH AF ; save carry flag which indicates write or no
- CALL CLS
- CALL GXYMSG
- DB 23,5
- DB "Written",0 ; in either case this goes to screen
- POP AF ; now get carry flag
- JP C,WRITE ; if carry, write to disk
- CALL GXYMSG ; we didn't want a write
- DB 23,1
- DB "Not",0 ; so preface "Written" with "Not"
- JP EDLOOP ; go back to command menus
- ;
- QUITZP: ; close the file and quit the shell
- CALL CLOSEF
- CALL CLS ; leave a cleam slate
- JP QUIT
- ;
- FORWARD: ; move forward one sector
- LD HL,(RECNUM)
- INC HL ; add 1 to current record number
- LD DE,(FILESIZE)
- CALL COMPHD ; past EOF?
- JR Z,EXITBF ; no, so go there
- JR C,EXITBF ; no, so go there
- ; yes fall through to next routine
- ;
- TOP: ; move to the beginning of file
- LD HL,0 ; record # 0
- JR EXITBF ; go there
- ;
- BACK: ; move back one sector
- LD HL,(RECNUM)
- LD A,H ; are we BOF?
- OR L
- JR Z,BOTTOM ; yes, go to EOF.
- DEC HL ; no, just subtract 1 from recnum
- JR EXITBF ; and go there
- BOTTOM: LD HL,(FILESIZE) ; get last record of file
-
- EXITBF: ; common exit point for all movement routines
- ; desired record number is in HL
- LD (RECNUM),HL ; store it in HL
- CALL RECADR ; readjust address within file
- JP RDLOOP ; show new record and get next user input
- ;
- WRITE: ; write sector to disk
- LD DE,FCB1
- LD HL,(RECNUM)
- CALL R$WRITE
- JP EDLOOP ; get next user input
- ;
- PRINTSEC: ; write sector to LST: device
- LD HL,INFOMSG ; banner line
- CALL VLPSTR ; to printer
- LD HL,(OUTBUF) ; hex dump
- CALL VLPSTR ; to printer
- JP FLOOP ; get next response
- ;
- CHOFFSET: ; get new offset value from user
- CALL MESSAGE
- DB 'Enter new offset: ',0
- LD DE,OFFS
- CALL NUMINP ; input a number and store in OFFS
- SUB1624 OFFS,TBUFF ; subtract 80H for actual DMA address
- JP EDLOOP ; display screen anew and get response
-
- UP1:
- DEC24 numbuf
- JR ADDR0
- DOWN1:
- INC24 numbuf
- JR ADDR0
- UP16: SUB1624 numbuf,16
- JR ADDR0
- DOWN16: ADD1624 numbuf,16
- JR ADDR0
- ADDRESS: ; get address to show from user
- CALL MESSAGE
- DB 'Enter address: ',0
-
- ld de,numbuf
- CALL NUMINP ; input a number
- sub1624 numbuf,tbuff ; adjust for actual DMA address
- sub24 numbuf,offs ; adjust for offset
- ADDR0: CALL UNSHOWB
- ld de,numbuf
- ex de,hl
- ld a,(hl)
- push af ;save lowest byte of numbuf
- ld b,7 ;convert to a record number value
- ALP: call halve24 ;by halving 7 times
- djnz alp
- push hl ;save this value
- ld de,(numbuf)
- ld hl,(filesize)
- call comphd
- pop hl
- pop bc ;lowest byte of numbuf in b
- ld a,b ;in a
- JR C,ADDR1X ; filesize<numbuf=out of range
- ADDR1: ; NO carry = address OK
- ld b,7 ;convert back to a file address
- a1lp: call double24 ; by doubling seven times
- djnz a1lp
- or (hl) ; or low byte with original low byte now
- ; in a
- ld (hl),a ; put it back in numbuf
- mov24 absadr,numbuf ; this is the new address within file
- ADDR1A:
- call ADRREC
- PUSH HL
- LD HL,OldRecNum
- LD DE,RecNum
- LD B,3
- COMP: LD A,(DE)
- CP (HL)
- JR NZ,NUREC ; yes, they're different, must read
- INC DE
- INC HL
- DJNZ COMP
- POP HL ; no,they're the same, don't read
- JP EDLOOP1
- NUREC:
- POP HL
- JP RDLOOP1 ; address OK, get it and dump it
- ;
- ADDR1X: CALL MESSAGE ; address out of range
- DB 'Address ',0 ; tell em so
- PUSH HL
- LD HL,OOR
- CALL VPSTR
- POP HL
- CALL EREOL ; clear rest of line
- JP FLOOP ; get next input from user
- ;
- RECFIND: ; go to record
- CALL RADIX
- DB 10 ; get this one in decimal
- CALL MESSAGE
- DB 'Enter Record # ',0
- LD DE,NUMBUF
- CALL NUMINP
- CALL DRADIX ; put back default hex radix
- LD HL,(NUMBUF)
- DEC HL ; computers like 0..n-1, humans 1..n
- LD DE,(filesize)
- INC DE
- CALL COMPHD ; beyond EOF?
- JR NC,TOOBIG ;
- LD (RECNUM),HL ; yes, so give error message
- CALL RECADR ; no, convert to address
- JR ADDR1A ; get it and dump it
- TOOBIG: CALL MESSAGE ; tell em bad news
- DB 'Record # ',0
- CALL VPRINT
- OOR: DB 'out of range',buzzer,0
- CALL EREOL
- ADDR2: JP FLOOP ; get next command
- ;
- ; Search routine dispatch and evaluation
- ;
- CALLCONT: ; entry pt for continue command
- CALL CONTINU ; do it
- JR EVALSCH ; evaluate results
- CALLSCH: ; entry point for search command
- CALL MESSAGE ; get search string
- SMSG:
- DB 'Enter Search String: ',0
- CALL VPRINT
- DB '(or ? for Help) ',0
- LD HL,(BUFBEG)
- XOR A
- CALL BLINE ; read search string from user
- OR A ; if no input, don't search
- JR Z,NULLEXIT
- LD A,'?' ; '?' in first char = help request
- CP (HL) ; help request?
- JR NZ,DOSCH ; NO, process as search string
- CALL CLS ; YES, clear screen
- LD HL,SRCHMSG ; print help
- CALL VPSTR
- CALL AT
- DB 23,1 ; re-prompt (without or ? for help)
- LD HL,SMSG
- CALL VPSTR
- LD HL,(BUFBEG) ; try again
- xor a ; don't capitalize input
- CALL BLINE ; get input
- OR A ; if no input, don't search
- JR NZ,DOSCH
- CALL CLS
- JR NX2
- DOSCH:
- CALL SEARCH ; look for it
- EVALSCH:
- PUSH AF ; save flags
- CALL DRADIX ; put default radix back
- CALL CLS ; clear screen after possible help request
- POP AF ; return flags
- CALL REACTION ; react to em
- JP RDLOOP
- NULLEXIT:
- CALL MESSAGE
- DB 0
- NX2: JP EDLOOP ; and return for more
- ;
- REACTION: ; respond to flags returned by search routine
- JR Z,MATCHED ; Z = matched or aborted
- NOMATCH: ; NZ = bad search string or not found
- JR C,BADSTMSG ; carry = bad string
- CALL MESSAGE ; not carry = not found
- DB 'String not found',0 ;tell'em
- RET
- BADSTMSG:
- CALL MESSAGE ; bad search string
- DB 'Search String Error',buzzer,0
- RET
- MATCHED: ; matched or aborted
- JR C,ABORTED ; carry = aborted
- ; NC = must be a match
- mov24 numbuf,absadr ; convert address for display purposes
- add24 numbuf,offs ; adjust for offset
- add1624 numbuf,tbuff ; adjust for DMA address
- CALL MESSAGE
- DB 'Found at ',0 ; tell 'em good news
- ld a,(numbuf+2) ; highest byte
- ld hl,(numbuf) ; lowest 2 bytes
- CALL pa2hc ; print high
- CALL phl4hc ; print lowest 2
- RET
- ;
- ABORTED:
- ; EX DE,HL ; old address within file to HL
- CALL MESSAGE
- DB 'Search aborted ',0
- RET
- ;
- GETFN: ; get new file name from user
- CALL MESSAGE
- DB 'Enter File Name: ',0
- LD HL,(BUFBEG)
- CALL BLINE ; get user input
- OR A
- JP Z,NULLEXIT ; don't perform function if no input
- LD A,(FILEFLAG) ; see if a file is open before we
- OR A ; try to close it
- JR NZ,GFN1 ; none open, none to close
- CALL CLOSEF ; gotta close open file
- GFN1: LD DE,(FCB)
- CALL ZFNAME ; parse it as Z would
- CALL GETDU ;
- XOR A
- LD HL,OFFS ;zero the 6 bytes of OFFS and ABSADR
- LD BC,6
- CALL LDFIL
- JP FTOP ; see if we can open it.
- ;
- ZCPR3: ; prepare to go to CCP w/ shell return
- CALL RESHELL ; reload the shell stack with new info
- ; now form our command prompt
- LD HL,(SHELBUF) ;
- XOR A ; a=0
- LD BC,16 ;
- CALL LDFIL ; zero 16 bytes
- EX DE,HL ; shelbuf in DE
- LD BC,(DEFDU) ; put DU: in BC
- CALL GETDUOK ; OK TO USE DU: FORM?
- JR Z,DONDR ; NO, JUST NDR
- CALL MUD ; put a DU: string in memory at (SHELBUF)
- LD A,':' ;
- LD (DE),A ; FOLLOW IT WITH A COLON
- INC DE ;
- DONDR: CALL DUTDIR ; name on this directory?
- JR NZ,GNDR ; get it
- LD HL,NONAME ; none available, say noname
- GNDR: CALL COPY8 ; move either to buffer
- LD A,'>' ; follow with a '>'
- LD (DE),A
- CALL MESSAGE
- DB 0 ; clear message line
- LD HL,(SHELBUF)
- CALL VPSTR ; print our prompt
- ; now we read cmdline
- LD HL,(BUFBEG)
- CALL BLINE ; get input
- OR A
- JP Z,NULLEXIT
- CMDINP2:
- LD A,(HL) ;look at first char of our command line
- CP '$' ; a '$'?
- JR NZ,PUTMCL1 ;no, just move it to mcl
- PUSH HL ;yes, save this loc
- ;
- ; compare 7-bits in type field of FCB to see if it's a .COM file
- ;
- LD HL,COM ; is it a .COM file?
- LD DE,FCB1+9
- CALL SEVENB
- POP HL ; get beginning of buffer
- JR NZ,NONCOM ; no, tell em they can't do that
- LD DE,256 ; make a new buffer (space already allocated)
- ADD HL,DE
- PUSH HL
- EX DE,HL ; new buffer address in DE
- CALL RETUD ; DU in BC
- CALL DUDIRPFX ; prefix it with DU: or DIR: as proper
- LD HL,FCB1+1
- CALL COPY8 ; move file name from FCB until ' ' or 8 chars
- LD HL,(STRADR)
- INC HL ; go one byte past the '$'
- NLOOP:
- LD A,(HL) ; keep moving byte until null found
- OR A
- LDI
- JR NZ,NLOOP
- ;
- PUTMCL: POP HL ; buffer address
- PUTMCL1:
- CALL CLOSEF ; close the file
- PMCL2: CALL PUTCL ; put it in z3 command buffer
-
- ZEXIT: JP EXIT ; and leave shell (temporarily)
- ;
- XECUTE: ; Execute the file if it is a .COM file
- ; handle as if user chose Z and responded
- ; with '$' alone. saves code to do this way.
- CALL RESHELL ; reload the shell stack with new info
- LD BC,(DOLLAR) ; move '$',0 to input buffer
- LD HL,(STRADR)
- LD (HL),C
- INC HL
- LD (HL),B
- DEC HL
- JR CMDINP2 ; and process as user input
- DOLLAR:
- DB '$',0
- ;
- NONCOM: ; not a com file
- CALL MESSAGE
- DB 'not a .COM file',0
- LD A,(FILEFLAG) ; have we an open file?
- OR A
- JP NZ,LLOOP ; no, only have limited menu
- JP FLOOP ; yes, do full menu
- ;
- HELP: ; help command
- LD A,(HELPCH) ; don't do it if help not enabled
- OR A
- JP Z,CMDRET
- CALL RESHELL ; okay to do it
- LD HL,HELPCMD
- PUSH HL
- JR PUTMCL ; put help into multi-command buffer
- HELPCMD:
- DB "HELP ZPATCH",0
-
- ;
- ; full menu if file opened successfully
- ;
- MENU:
- CALL GXYMSG
- DB 14,10
- DB HV,'E',LV,'dit',0
- CALL GXYMSG
- DB 14,50
- DB HV,'W',LV,'rite to disk',0
- CALL GXYMSG
- DB 15,5
- DB HV,'<',LV,' or ',HV,',',LV,' - back one sector',0
- CALL GXYMSG
- DB 15,45
- DB HV,'>',LV,' or ',HV,'.',LV,' - forward one sector',0
- CALL GXYMSG
- DB 16,10
- DB HV,'T',LV,'op of file',0
- CALL GXYMSG
- DB 16,50
- DB HV,'B',LV,'ottom of file',0
- CALL GXYMSG
- DB 17,5
- DB LV,'Goto ',HV,'A',LV,'ddress',0
- CALL GXYMSG
- DB 17,45
- DB 'Goto ',HV,'#',LV,'of record',0
- CALL GXYMSG
- DB 18,10
- DB HV,,'P',LV,'rint sector',0
- CALL GXYMSG
- DB 18,43
- DB LV,'Change ',HV,'O',LV,'ffset',0
- CALL GXYMSG
- DB 19,10
- DB HV,'S',LV,'earch',0
- CALL GXYMSG
- DB 19,50
- DB HV,'C',LV,'ontinue search',0
- ;
- ; limited menu if file not open
- ;
- BMENU:
- CALL GXYMSG
- DB 20,9
- DB LV,'e',HV,'X',LV,'it',0
- CALL GXYMSG
- DB 20,45
- DB LV,'Give ',HV,'F',LV,'ile Name',0
- CALL GXYMSG
- DB 21,10
- DB HV,'R',LV,'un .COM file',0
- CALL GXYMSG
- DB 21,50
- DB HV,'Z',LV,'CPR3 command',2,0
- LD A,(HELPCH)
- OR A
- RET Z
- CALL GXYMSG
- DB 21,30
- DB HV,'H',LV,'elp',2,0
- RET
- ;
- MNURD: CALL GXYMSG
- DB 22,30 ; clear any previous input
- DB ' ',8,0
- CALL CIN ; get new input from user
- CALL CAPS ; capitalize it
- PUSH AF ; save input
- CALL MESSAGE ; after input is read...
- DB 0 ; clear MESSAGE LINE
- MOV24 numbuf,absadr
- POP AF ; restore input
- RET
- ;
- ; CONVERT AN ABSOLUTE FILE BYTE ADDRESS INTO A RANDOM RECORD NUMBER
- ;
- ADRREC:
- MOV24 NUMBUF,ABSADR
- LD HL,NUMBUF
- LD B,7
- ADRRCLP:
- CALL HALVE24
- DJNZ ADRRCLP
- MOV24 RECNUM,NUMBUF
- RET
- ;
- ; CONVERT A RANDOM RECORD NUMBER INTO AN ABSOLUTE FILE BYTE ADDRESS
- ;
- RECADR:
- MOV24 NUMBUF,RECNUM
- LD HL,NUMBUF
- LD B,7
- RCADRLP:
- CALL DOUBLE24
- DJNZ RCADRLP
- MOV24 ABSADR,NUMBUF
- RET
- ;
- GETDU: ; routine for getting a DU: spec from
- ; an FCB.
- LD BC,(DEFDU) ; start with the DEFAULT DU:
- LD HL,(FCB) ; FCB addr in HL
- LD A,(HL) ; 1st byte into A
- OR A ; is it 0?
- JR Z,DEFA ; yes, use default
- DEC A ; no decrease by one
- LD B,A ; and put in B.
- DEFA:
- LD DE,13 ; go to Z3 user # area of FCB
- ADD HL,DE
- LD A,(HL) ; into A
- LD C,A ; and C
- LD (FILDU),BC ; store it in FILDU
- RET
-
- ;
- ; Figure the offset to use for .COM files, and all ZCPR3
- ; system segments
- ;
- OFSFIG:
- LD IX,(Z3EADR) ; ENV ptr
- LD DE,FCB1+9
- TSTCOM: LD HL,COM ; .COM file
- CALL SEVENB
- JR NZ,TSTENV ; no, move on to next
- LD A,(88H) ; first record has been read into 80H
- CP 3 ; check type-byte for Z33 type-3 .COM file
- LD HL,100H ; offset is 100H
- RET NZ ; not z33 type 3, use default
- LD HL,(8BH) ; offset read from the file
- RET
- ;
- TSTENV: ; A Z3 environmental descriptor?
- LD HL,Z3EADR-4
- CALL SEVENB
- JR NZ,TSTZ3T ; no, move on to next
- LD HL,(Z3EADR) ; yes, offset IS (z3eadr)
- RET
- ;
- TSTZ3T: LD HL,Z3T ; A z3 terminal descriptor?
- CALL SEVENB
- JR NZ,TSTRCP ; no, move on to next
- LD HL,(Z3EADR)
- LD DE,80H
- ADD HL,DE ; ENV PTR + 80H= terminal descriptor ptr
- RET
- ;
- TSTRCP: LD HL,RCP ; A z3 Resident command package?
- CALL SEVENB
- JR NZ,TSTIOP ; no, move on to next
- LD L,(IX+0CH) ; get offset from ENVIRONMENT DESCRIPTOR
- LD H,(IX+0DH)
- RET
- ;
- TSTIOP: LD HL,IOP ; A z3 input-output package?
- CALL SEVENB
- JR NZ,TSTFCP ; no, move on to next
- LD L,(IX+0FH) ; get offset from ENVIRONMENT DESCRIPTOR
- LD H,(IX+10H)
- RET
- ;
- TSTFCP: LD HL,FCP ; A z3 flow-command package?
- CALL SEVENB
- JR NZ,TSTNDR ; no, move on to next
- LD L,(IX+12H) ; get offset from ENVIRONMENT DESCRIPTOR
- LD H,(IX+13H)
- RET
- ;
- TSTNDR: LD HL,NDR ; A z3 named directory file?
- CALL SEVENB
- JR NZ,DEFTO0 ; no, use default
- LD L,(IX+15H) ; get offset from ENVIRONMENT DESCRIPTOR
- LD H,(IX+16H)
- RET
- DEFTO0: LD HL,0
- RET
- ;
- ; 7 bit comparison of three-byte buffers
- ;
- SEVENB: PUSH DE
- LD BC,0303H ; b=3 controls loop, c=3 to adjust for cpi's
- SEVENLP:
- LD A,(DE) ; get byte in A
- INC DE ; point to next
- AND 07FH ; strip high bit
- CPI ; compare and increment HL
- JR NZ,SLPXT ; not same, exit with nz flag
- DJNZ SEVENLP ; else exit is with z flag
- SLPXT: POP DE
- RET
- ;
- ; CLOSE FILE AND RESET USER AREA BEFORE EXITING
- ;
- CLOSEF: LD DE,(FCB)
- CALL F$CLOSE
- LD BC,(DEFDU)
- CALL LOGUD
- RET
- ;
- ; reset the default (HEX) radix
- ;
- DRADIX: CALL RADIX
- DEFB 16 ; 16=hex,10=dec,2=bin others default to decimal
- RET
- ;
- ; initialize arrow key values in command table from TCAP
- ; if unsupported leave with WS keys as default
- ;
- ARROWS:
- LD HL,(Z3EADR)
- LD DE,90H
- ADD HL,DE
- LD A,(HL)
- OR A
- RET Z
- LD (UpArrow),A
- INC HL
- LD A,(HL)
- LD (DownArrow),A
- INC HL
- LD A,(HL)
- LD (RightArrow),A
- INC HL
- LD A,(HL)
- LD (LeftArrow),A
- RET
- ;
- ; CLEAR OFF THE OLD SHELL STACK ENTRY, REASSEMBLE A NEW ONE
- ; PUT ON SHELL STACK
- ;
- RESHELL:
- CALL SHPOP
- CALL SHASM ; shell stack reassembly and loading
- RET
- ;
- HLPMSG: DB 'ZPATCH [du:]FILENAME.TYP',0
- SHERR: DB 'Shell Stack Error',0
- EFCBERR:DB 'Ext. FCB Error',0
- NAMERR: DB "Why did you rename ZPATCH?",0
- TCAPERR:
- DB 'Inadequate TCAP',0
- PEONMSG:
- DB "Can't run ZPATCH w/o wheel privileges",0
- SHSTK: DW 0
- SHFCB: DW 0
- SHELBUF:DW 0
- ;
- COM: DB 'COM' ;command file extent
- ENV: DB 'ENV' ;Z3 system segments
- RCP: DB 'RCP' ;" " "
- IOP: DB 'IOP' ;" " "
- FCP: DB 'FCP' ;" " "
- NDR: DB 'NDR' ;" " "
- Z3T: DB 'Z3T' ;" " "
- NONAME: DB 'Noname '
- FILEFLAG: ; flag so program knows if it has
- DB 0FFH ; open file or not. DEFAULT NO.
- ;
- ; Search help screen
- ;
- SRCHMSG:
- DB 2,"SEARCH SYNTAX:",CR,LF,CR,LF,1
- DB '"ASCII strings"',CR,LF
- DB 'HEX bytes and ASCII string units delimited by commas',CR,LF
- DB '"Steven" = "S",74,"ev",65,6e',CR,LF,CR,LF
- DB 'Options at end after semicolon',CR,LF,2
- DB ' A',1,' - start at beginning (else from present pos)',2,CR,LF
- DB ' B',1,' - backward search',2,CR,LF
- DB ' M',1,' - AND mask byte *',2,CR,LF
- DB ' S',1,' - skip * occurrences',2,CR,LF
- DB ' U',1,' - upper=lower',2,CR,LF
- DB ' 7',1,' - 7-bit search',1,CR,LF,CR,LF
- DB ' * = input after prompt',CR,LF,CR,LF
- DB 'e.g. "Steven";b7u -> 7-bit backward search '
- DB 'w/o regard to caps',CR,LF,CR,LF
- DB '^C to abort search',2,0
- ;
- NUMBUF: M24BQ ; numeric scratch buffer
- FILDU: DW 0
- ;
- ; the byte LINE and the following pointers are all externals
- ;
- LINE:: ; line on which screen display of sector starts
- DB 5
- FCB::
- DW FCB1 ; address of FCB of edited file
- OFFS:: ; offset of apparent vs absolute address
- M24BQ ; a 24-bit quantity
- ABSADR:: ; address within file
- M24BQ ; a 24-bit quantity
- OUTBUF:: ; address of screen dump output
- DW 0
- FILESIZE:: ; size of file in sectors
- DW 0
- RECNUM:: ; current record number
- M24BQ ; a 24-bit quantity
- OldRecNum:
- DB 0FFH,0FFH,0FFH
- BUFBEG::
- DW 0 ; pointer to BLINE buffer
- STRADR::
- DW 0 ; pointer to actual input of bline buffer
- DEFDU::
- DW 0 ; storage for defualt DU:
- SECADR::
- DW TBUFF ; memory address of edited sector
- VERSION::
- DB (VERS mod 10)+30H
- DB (VERS/10)+30H
- ;
- END
- ; have we changed record numbers?
-