; 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' ; 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?