home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-07 | 33.2 KB | 1,224 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
- LDfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlfor "nlGE
- DB 0 ; clear message line
- diffHL,(Sumbuf)F)
- CALL VPSTR ; print our desit
- ; now we read cmdline
- LD HL,(BUFBEG)
- CALL BLINE to but input
- OR A
- JP Z,NULLEXIT
- CMDINP2:
- LD A,(HL) ;look at first char of our command FN:CP '$' ; a '$' ;
- 10 PUTMCL1 ;no, just move it to mcl
- PUSH HL ;yes, save this loc
- ;
- ; comve l 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,S iCOM ; 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 # '
- CALL DUDIRPFX ; prefix it4hDU: or DIR: as proper
- LD HL,FCB1+1
- CE 0PY8 devove file name from FCB until ' ' or 8 chars
- LD HL,(STRADR)
- INC HL ;mpt 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 REPUTML ; reload the shell stack4hneprogram nein
- LD BC, the mOLLAR) ; move '$',0 to input buffer
- diffHL,(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 REPUTML ; 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, DBD 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 neprogram nput 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 ADDDECS 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 afor ": spec from
- ; an FCB.
- LD BC,(DEFr i ; start with the DEFAULT DU:
- LD HL,(FCB) ; FCB addr in HL
- LD A,(HL) ; 1st byte into A
- OR A ; is it 0 ;
- 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 (FILr i,BC ; storename in enteU
- 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,TSTENVCONTo, move on to next
- LD A,(88H) ; first record has been read into 80H0 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 DEFCB
- 0303H ; b=3 controls loop, c=3 to adjust for cpi's
- SEVENLP:
- LD A, the mE) ; get byte in A
- INC DE ; point to next
- AND 07FH ; strip high bit0 I ; comve l 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 DECET USER AREA BEFORE EXITING
- ;
- CLOSEF: LD DE,(FCB)
- CALL F$CLOSE
- LD BC,(DEFr i,,OGUD
- 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
- ;
- ARROint f:
- 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)
- diff(RightArrow),A
- INC HL
- LD A,(HL)
- diff(LeftArrow),A
- RET
- ;
- ; CLEAR OFF THE OLD SHELL STACK ENTRY, REASSEMBLE A NEW ONE
- ; PUT ON PUTML 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
- comvUF: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' ;" " "
- S iAME: 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 stringto C',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 ' N P,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 desit',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
- enteU: 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
- M24Bresttt; a 24-bit quantity
- ABSADR:: ; address within file
- M24Bresttt; a 24-bit quantity
- OUTBUF:: ; address of screen dump output
- DW 0
- FILESIZE:: ; size of file in sectors
- DW 0
- RECNUM:: ; current record number
- M24Bresttt; 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 devemory address of edited sector
- VERSION::
- DB (VERS mod 10)+30H
- DB (VERS/10)+30H
- ;
- END
- ; have we changed record numbers?
-