;DDTF5.ASM A "find-string" function for ddt, sid, zsid, etc. ;5/22/86 (Needs CP/M 2.2) ; ;Copyright 1981, 1985, 1986, 1988 by Roy Lipscomb, Logic Associates, Chicago ; Permission is granted for non-profit copying and distribution. ; ; ; >>>>> Essential: Read the directions given in DDTF5.DOC ; before attempting to assemble this source code. ; ;----------------------------------------------------------------------- ;INTRODUCTION ; ; (The term "dbg" is used here as the generic of ddt, sid, etc.) ; ; This module prints a signon message, relocates itself under the ; ccp, then invokes dbg. To have dbg automatically ; load filename.com, type "ddtf filename.com". ; ; dbg must be either on same drive as ddtf, on drive A, or on ; the default drive. ; ; DDFT4 invokes DDT by poking a command into the CCP command line. ; ; Instructions on use of DDTF5 are provided in DDTF5.DOC. ; ; ******************************************************************** ; ;Version 5, 2/20/88 ; ; 1) Should now execute properly regardless of what other utilities ; are already present below the CCP. (The BIOS vector table ; is temporarily patched to insure that DDTF is not removed by ; other sub-CCP utilities before it has a change to execute.) ; ; 2) Changes to version 4 are marked in this file by the string "v.5". ; ;Version 4, 4/10/85 ; ; 1) Made compatible with Apple CP/Ms. Still not compatible with ; ZCPR3, though should work with earlier versions of ZCPR. ; ; ;Version 3, 11/20/85 ; ; 1) allows wild-card compares. ; 2) allows quicker interrupt from keyboard. ; ; ;Version 2, 9/12/82 ; ; 1) shortened test for presence of ccp. ; 2) eliminated use of restarts, for greater compatibility. ; 3) corrected code that searches for dbg on disk. ; 4) changed search starter to control-F (vs. "GB"). ; 5) added control-A as command to display ddtf instructions. ; 6) simplified code. ; ; ********************************************************* ; loader routines * ********************************************************* if copy1 ;service routines org 100h entry: jmp begin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; customizing variables ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bdos7 db 11h ;Contents of bdos page at offset 7 in your ; system. This is 11H in standard CP/M 2.2. ; ;(Contents of CP/M bdos page at offset 6 is ; always C3H.) ; ;If DDTF5 will not boot in your system, ; changing bdos7 value may help. Otherwise, ; changing this value has no effect. ; ;To save the time and trouble of reassembling, ; you can poke a new value for "bdos7" into ; DDTF5.COM at entry + 3 by using a debugger ; (ddt, etc.) or a disk utility (e.g. DUU). dbg db 'DDT ' ;Change this name to match your debugger. ; ^^^^^^^^ ; (MUST BE EXACTLY 8 CHARS LONG). ; ;You can poke a new value for "dbg" into ; DDTF5.COM at entry + 4 using a disk utility ; (e.g. DUU) or your debugger (ddt, sid, etc.) srchstr equ 0 ;start address of area to be searched srchlen equ 0ffffh ;length of area to be searched boot equ 0 ;warmstart vector linelen equ 16 ;number of chars dumpable on a line. (an 80- ; col crt can handle 16 hex-expanded chars.) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; universal variables ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; there is normally no need to change these bdos equ boot+5 conin equ 1 conout equ 2 dconin equ 6 pstr equ 9 cbuffin equ 10 constat equ 11 searchf equ 17 deffcb equ boot+5ch templat equ deffcb+1 ;location to hold search string tbuff equ boot+80h bufflen equ 60 ;expected maximum length of command ;line (for inserting " DDT ") ;(short length protects debug stack ;while testing under dbg) ctla equ 'A' and 0fh ctlf equ 'F' and 0fh ctls equ 'S' and 0fh cr equ 13 lf equ 10 blank equ ' ' wboff equ 3 ;offset to warmboot vector in bios jtable. v.5 ssoff equ 21h ;offset to set-sect vector in bios jtable. v.5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;values used in manipulating the ccp bdosent dw 0 ;bdos starting address ccp dw 0 ;ccp starting address ccpbmax equ 6 ;offset to ccp buff maxlength value ccpcoml equ ccpbmax+1 ;offset to ccp command-length byte ccpbuff equ ccpcoml+1 ;offset to start of ccp command line curdrv equ 4 ;current drive in pg zero ccpcmd dw 0 ;pointer to first char in ccp buff dbgfcb db 0,' COM',0,0,0,0 ;fcb used to locate dbg dw 0,0,0,0,0,0,0,0 dw 0,0 ;-------------------------------------------------------- ;variables used in tests, moves, and message printing loadpnt dw 0 ;address to which DDTF5 relocates itself. eom equ '$' helpmes db cr,lf db ' DDTF5 Copyright 1988 Logic Associates, Chicago',cr,lf db cr,lf db cr,lf db ' A "find string" command, user-customized for-- ........' hlp1 equ $-8 db cr,lf db ' which should be present on one of following drives:' db cr,lf db ' 1) Explicit drive, 2) Drive A, 3) Default drive.' db cr,lf db cr,lf db ' For brief instructions, type control-A at any time.' db cr,lf db cr,lf db eom mnoccp db 'Abort: unable to locate CCP',cr,lf db eom mismess db 'Abort: ........' nodbg equ $-8 ;space for actual dbg name db ' not found',cr,lf db eom ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; mainline ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;initialize module and print message begin lxi sp,stack call hskp ;initialize and print signon message call getload ;compute load address: just below CCP jz ccperr ;ccp not found ;insure good environment call testdbg ;insure dbg present jz dbgmiss ;do it call chgaddr ;convert to true addresses call patbios ;patch bios to double-protect DDTF5. v.5 call movemod ;move module to load address jmp getdbug ;link to dbg ("jmp" to ccp) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; housekeeping: initialize variables ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;move dbg name to messages and to fcb, then print message. hskp: lxi d,hlp1 lxi h,dbg call move8 call signon ;print signon message lxi d,dbgfcb+1 lxi h,dbg call move8 lxi d,nodbg lxi h,dbg call move8 ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; find load point for ddtf ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;find bdos, then ccp, then adjust down for length of module. ;on exit, if error, then z = yes. getload: call locbdos ;find bdos. jnz getlod7 ; not found? abort. call locccp ;find ccp. jnz getlod7 ; not found? abort. lhld ccp ;point again to start of ccp. lda bdos+2 sub h ;ccp page < = address-5 page? jnc getlod4 ; yes, use ccp start as tpatop lhld bdos+1 ; no, use location 5 as tpatop. getlod4: ;compute loadpoint: TPA minus length of DDTF5. lxi d,-length dad d getlod5: shld loadpnt ;save new loadpnt. ori 1 ;say "no error" jmp getlod9 getlod7: call ccperr xra a ;say "error" getlod9: ret ;on exit, if error, then z = yes. ;------------------------------------------------------- ;locate beginning instruction of bdos. ;on exit, if found, z = yes ; hl = bdos start (offset 6) locbdos: lhld boot+1 ;get bios address lxi d,-100h mvi b,31h ;check for max of 3000h below bios locbd2: dcr b jz locbd6 ;exhausted search, no success: abort. mvi l,6 ;set for offset to bdos start. dad d ;compute bdos start shld bdosent ;save in case found mov a,m cpi jmp ;at page plus 6, is there a "jmp"... jnz locbd2 inx h mov a,m cpi 11h jz locbd4 ; ...followed by an 11h (if CP/M)... lda bdos7 ; ...or the user-defined value for bdos+7? cmp m jnz locbd2 ; no, try next page. locbd4: mvi b,1 ; yes, bdos page "found" jmp locbd9 locbd6: lhld boot+6 ;location boot+6 points to an offset of 6? cpi 6 shld bdosent ; yes, have to assume it points to bdos page; jz locbd4 ; it's our last resort. locbd9: dcr b ;set z flag to "yes" (found) or "no" (missing) ret ;------------------------------------------------ ;check for ccp ;on exit, if ccp found, z = yes ; hl = ccpstart locccp: lhld bdosent mvi b,31h ;check no more than 3000h below bdos. lxi d,-100h loccp2: dcr b jz loccp9 mvi l,0 ;correct to bdos start. dad d ;advance to next lower page call isitjmp ;check for two jmp instructions. jnz loccp2 call isitjmp ;found? jnz loccp2 ; no, abort. mov a,m cpi 80h ;max bufflen byte greater than 7f? jnc loccp2 ; yes, abort. ;test for bufflen <= max bufflen inx h ;max bufflen < actual bufflen? cmp m jc loccp2 ; yes, abort. inx h inx h add l ;check for the two pointers to the ccp buffer. mov l,a mov a,h ;get ccp page. inx h ;1st pointer in same page as ccp? cmp m jnz loccp2 ; no, abort. inx h inx h ;2nd pointer in same page as ccp? cmp m jnz loccp2 ; no, abort. mvi l,0 ;correct to ccp start. shld ccp mvi b,1 ;set for "found" loccp9: dcr b ;set z flag. ret ;--------------------------------------------------- ;check for jump instruction isitjmp: mov a,m cpi jmp inx h inx h inx h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; test if debugger present, update messages with drive ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;move dbg name to messages and to fcb testdbg lxi d,dbgfcb+1 lxi h,dbg call move8 lxi d,nodbg lxi h,dbg call move8 lxi d,hlp1 lxi h,dbg call move8 ;find first character of lastest ccp command lhld ccp lxi d,ccpbuff dad d mvi a,blank ;skip blanks skipbl cmp m inx h jz skipbl ;test for drive prefix on latest ccp command (viz, "B:DDTF5") mov a,m cpi ':' dcx h ;readdress first non-blank char jnz nodriv ;if not ":", no drive name mov a,m sui 40h ;set explicit drive into fcb sta dbgfcb inx h inx h ;keep explicit drive prefix in ccp buff jmp buildbg ;prefix new ccp command with two blanks (in place of "A:", "B:", etc) nodriv call twoblnk ;create complete command, move it to ccp buffer buildbg shld ccpcmd ;save pointer to ccp buff start call build ;insure dbg is present (do only after command moved from tbuff) call dbgpres ret ;zero set if dbg not found ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; find debugger on explicit drive, default drive, or A: ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;if not found any place, set zero flag = error ;try to find dbg on selected drive dbgpres call srchdbg rnz ;if not zero, debugger found ;search for debugger on drive A. lhld ccpcmd dcx h mvi m,':' dcx h mvi m,'A' mvi a,1 sta dbgfcb call srchdbg rnz ;if not zero, found ;set up to search for dbg on default drive lhld ccpcmd ;clear "x:DDT" back to " DDT" in ccp dcx h dcx h call twoblnk ;blank out explicit drive, if present xra a sta dbgfcb ;set dbg fcb to default drive call srchdbg ret ;return non-zero if found ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; convert module1 to true addresses ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; change pseudo addresses to true addresses chgaddr lxi b,length lxi d,module1 lxi h,module2 truloop ldax d cmp m cnz convert inx h inx d dcx b mov a,b ora c jnz truloop ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; convert displacement into address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; convert push b ;length of module not yet processed push h ;module2 character position ; get displacement from instruction, put into bc. ldax d mov b,a dcx d ldax d mov c,a lxi h,-module1 ;normalize displacement to zero dad b push h pop b lhld loadpnt ;add load point for true addr dad b ; move true address to instruction mov a,l stax d inx d mov a,h stax d pop h pop b ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; move module into place ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movemod lhld loadpnt xchg ;de=destination lxi h,module1 ;hl=source lxi b,length call move ; protect the module (removed by wboot) protect lhld boot+6 xchg lhld loadpnt lxi b,tobdos+1 dad b mov m,e inx h mov m,d lhld loadpnt shld boot+6 ;install dbg name in help message within relocated module lxi d,hlp2 dad d xchg lxi h,dbg call move8 ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; patch bios jump table ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;patch "set sector" trap inline with bios routine. ;entire routine added in v.5. patbios: lhld boot+1 ;patch warmboot bios vector. mvi l,wboff inx h mov e,m inx h mov d,m xchg shld trwbx+module1+1 xchg push h lhld loadpnt lxi d,trwb dad d xchg pop h mov m,d dcx h mov m,e lhld boot+1 ;patch set-sector bios vector. mvi l,ssoff inx h mov e,m inx h mov d,m xchg shld trssx+module1+1 xchg push h lhld loadpnt lxi d,trss dad d xchg pop h mov m,d dcx h mov m,e ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; utility routines ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;install two blanks at location pointed to by hl twoblnk mvi m,blank inx h mvi m,blank inx h ret ;test if debugger is on drive srchdbg lxi d,dbgfcb mvi c,searchf call bdos inr a ret ;if not zero, debugger found. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; print error messages ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dbgmiss lxi d,mismess jmp domess ccperr lxi d,mnoccp domess call putstr jmp boot ;return to cpm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; print signon mess ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; signon lxi d,helpmes putstr mvi c,pstr call bdos ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; invoke dbg ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;set ccp command-buffer pointer getdbug lhld ccp lxi d,ccpbmax ;offset of ccp char ptr dad d mvi a,ccpbuff+1 add m mov l,a mvi m,ccpbuff ;store char pointer ;select drive lda curdrv mov c,a ;select current drive ; execute lhld ccp pchl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; build new command in CCP buffer ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;set default ccp command length (= max buff). ;no problem, since ccp will stop scanning command when ;it finds a null. build lhld ccp lxi d,ccpbmax dad d mov a,m inx h mov m,a ;move debugger name into ccp command buffer lhld ccpcmd ;destination (ccp) to de xchg lxi h,dbg call move8 ;move command-line parameters (if any) to ccp buffer (use current de) lxi h,tbuff ;source-1 to hl (tbuff) mov c,m mvi b,0 ;length to bc inx h ;source to hl call move ;install end-of-command marker xra a stax d ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; move block of data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;source in hl, destination in de, length in bc. move8 lxi b,8 movex mov a,m stax d inx d inx h dcx b move mov a,b ora c jnz movex ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; end of loader routines ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ds 64 stack equ $ endif ********************************************************* ********************************************************* ; beginning of relocatable module * ********************************************************* ********************************************************* ;must org on page boundary, though final copy ;is loadable anywhere. org ($/100h+1)*100h cbase set $ if copy1 module1 equ $ endif if not copy1 module2 equ $ endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; jump to start (this is where location 5 points) jmp start+cbase ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; instructions ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instr equ $-cbase db cr,lf db cr,lf,'Using the A, I, or S command of ........' hlp2 equ $-cbase-8 db cr,lf,'place string XSTRINGX at 5dh, where' db cr,lf,'STRING is the string to be found, and' db cr,lf,'X is any char not used in STRING.' db cr,lf db cr,lf,'The wild-card character is "?". Each' db cr,lf,'"?" present in STRING means "don''t' db cr,lf,'check this byte, assume it matches."' db cr,lf db cr,lf,'Type control-F to perform search. Type' db cr,lf,'control-F again to repeat the search.' db cr,lf db cr,lf,'To interrupt the search, press any key.' crlf equ $-cbase db cr,lf,eom ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; vestibule processing ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start equ $-cbase mov a,c cpi cbuffin jz trapin+cbase cpi conin jz trapin+cbase cpi dconin jnz tobdos+cbase mov a,e ;if direct console i/o, trap only input inr a mov a,c jz trapin+cbase tobdos equ $-cbase jmp $-$ ;place true bdos entry point here **************************************************************** ; get and test console input for control-F ; **************************************************************** trapin equ $-cbase push b ;save function code push d ;save buffer addr (in case cbuffin) call tobdos+cbase ;do the call pop d ;restore buffer addr pop b ;restore function call ;conin and cbuffin require different tests mov b,a mov a,c cpi cbuffin jz srchbuf+cbase ;conin or dconin: test this single char mov a,b cpi ctlf jz dosrch+cbase cpi ctla jz dohelp+cbase ret ;cbuffin: test entire buffer srchbuf equ $-cbase inx d ;address bufflen byte mov h,d ;save buffer pointer in hl mov l,e mov b,m ;put length into b inr b tstbf equ $-cbase dcr b rz ;not found inx d ldax d cpi ctla jz dohelp1+cbase cpi ctlf jnz tstbf+cbase ;perform search mvi m,0 ;clear buffer length to 0 dosrch equ $-cbase call srch+cbase jmp exitf+cbase ;display help instructions dohelp1 equ $-cbase mvi m,0 ;clear buffer length to 0 dohelp equ $-cbase lxi d,instr+cbase mvi c,pstr call tobdos+cbase ;print instructions ;exit from search module exitf equ $-cbase xra a ;say "no char" (in case conin, dconin) ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; mainline: find substring ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;initialize srch equ $-cbase call newline+cbase lxi b,srchstr ;load start-of-search address lxi d,srchlen ;load length of search search equ $-cbase ;begin comparison anew mov a,d ora e ;at end of search block? rz ; yes, return mov a,c ;at start of new page? 11/20/85 ora a ; jnz oksof0+cbase ; no, continue push b ; 11/20/85 push d ; 11/20/85 mvi c,constat ; 11/20/85 call tobdos+cbase ; yes, test for console status.11/20/85 pop d ; 11/20/85 pop b ; 11/20/85 ora a ;key pressed? 11/20/85 jz oksof0+cbase ; no, continue. 11/20/85 mvi c,conin ;flush keyboard. 11/20/85 call tobdos+cbase ; 11/20/85 ret ;quit. 11/20/85 oksof0 equ $-cbase ; 11/20/85 push d ;save count of chars left push b ;save current lead-off char ptr lxi h,templat+1 ;address the template oksofar equ $-cbase lda templat ;address initial terminator cmp m ;is this the end terminator? jz dumplin+cbase ; yes, full match: do dump, and ; jump to reset ldax b ;not template end, so get block char cmp m ;does it match template char? mov a,m ;(get template char) 11/20/85 inx b ;(address next char in block) inx h ;(address next char in template) jz oksof2+cbase ; yes, a match. 11/20/85 cpi '?' ;template char = wild-card? 11/20/85 jnz reset+cbase ; no, no match; reinitialize the compare. oksof2 equ $-cbase ; 11/20/85 dcx d mov a,d ora e ;a match, but is it end of block? jnz oksofar+cbase ; no, looks good; keep going... reset equ $-cbase ;reinitialize at next block char pop b ;get old lead-off position for block pop d ;get char count at lead-off position dcx d ;count down chars left in block inx b ;bump to next lead-off position jmp search+cbase ;restart the comparison ********************************************************* ; dump routines * ********************************************************* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;dump line dumplin equ $-cbase pop b ;restore lead-off character push b ;...and resave ;begin dump half-a-line back from target string lxi h,-linelen/2 dad b ;output sections of the line call dispadr+cbase call dumphex+cbase call dumpasc+cbase call newline+cbase ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;check for interrupt ;key pressed? mvi c,constat ;key pressed? call tobdos+cbase ora a ;if zero, no key pressed, jz reset+cbase ; continue processing ;get char (if ctl-s, resume listing) mvi c,conin ;get character call tobdos+cbase ani 7fh cpi ctls jz reset+cbase ; continue processing ;interrupt requested: stop dump, and return to dbg pop b pop d ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;display address in hl dispadr equ $-cbase push h ;display high byte mov a,h call disphex+cbase pop h push h ;display low byte mov a,l call disphex+cbase mvi b,1 ;output a blank call blanks+cbase pop h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;dump line in hex dumphex equ $-cbase push h ;save start dump-address mvi b,linelen ;set line length dhloop equ $-cbase push h ;save current dump-address push b ;save current char position mov a,m ;get character call disphex+cbase ;output mvi b,1 ;output blank call blanks+cbase pop b ;restore char count pop h ;restore curr dump-address inx h dcr b ;done? jnz dhloop+cbase ; no, do next char pop h ;restore start dump-address ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;dump line in ascii dumpasc equ $-cbase push h ;save start dump-address mvi b,linelen ;set line length daloop equ $-cbase push h ;save current-char address push b ;save char count mov a,m ;get current char inr a ;wrap around for "del" (127h) jm period+cbase ;if > 127, change to "." cpi ' '+1 ;if < " ", change to "." mov a,m ;(reget original char) jp charok+cbase ;display char as is period equ $-cbase mvi a,'.' charok equ $-cbase call charout+cbase pop b pop h inx h dcr b jnz daloop+cbase ;do again if more chars left pop h ;restore start dump-address ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;display hex character in ascii format disphex equ $-cbase push psw rar rar rar rar call dhex2+cbase pop psw dhex2 equ $-cbase ani 0fh cpi 10 jm under10+cbase adi 7 under10 equ $-cbase adi '0' jmp charout+cbase ********************************************************* ; display routines * ********************************************************* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;output blanks (number from b) blanks equ $-cbase mvi a,blank blanks2 equ $-cbase push b call charout+cbase pop b dcr b jnz blanks2+cbase ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;skip to new line newline equ $-cbase mvi a,cr call charout+cbase mvi a,lf ; display char on console charout equ $-cbase push psw mvi c,conout mov e,a call tobdos+cbase pop psw ret ********************************************************* ; set sector * ********************************************************* ;added in v.5. trss equ $-cbase trssx equ $-cbase call $-$ lxi h,start+cbase ;bdos vector points below lda bdos+2 ; or to this module? dcr a cmp h jc trssx2+cbase ; yes, skip shld bdos+1 ; no, point it to this module. trssx2 equ $-cbase ret ********************************************************* ; unpatch routine (warmboot) * ********************************************************* ;added in v.5. trwb equ $-cbase lhld boot+1 mvi l,ssoff xchg lhld trssx+cbase+1 xchg call unpatch+cbase mvi l,wboff xchg lhld trwbx+cbase+1 xchg call unpatch+cbase trwbx equ $-cbase jmp $-$ ;do the warmboot. ;-------------------------------------------------------- ;unpatch a bios jump vector. ;added in v.5. unpatch equ $-cbase inx h mov m,e inx h mov m,d ret ********************************************************* ; end of relocatable routines * ********************************************************* ;get length of relocatable routines length equ $-cbase ;flip the copy1/copy2 toggle copy1 set not copy1 ;link a second copy, if this was the first copy if not copy1 link ddtf5 endif ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ;end of source code for DDTF5.ASM.