; ; +++++++ LOOK +++++++ ; ;By Kenyon Swartwout ;Reprinted from INTERFACE AGE, May, 1978 ; ;This program will look for a byte or a sequence of 2 to 9 ;bytes in any program and when found, the address and byte ;will be printed. If no match is found "NO MATCH" will be ;printed. Type a "0" when asked for number of bytes to re- ;turn to CP/M. ; ; CP/Mified on 5/16/80 by: ; ; Kelly Smith ; Simi Valley, Calif. ; (805) 527-0518 Verbal ; (805) 527-9321 Modem ; ; ; CP/M VERSION 1.4 FUNCTION CALL EQUATES ; RDCON EQU 1 ;READ CONSOLE CHARACTER WRCON EQU 2 ;WRITE CONSOLE CHARACTER WRCBUF EQU 9 ;WRITE BUFFER CONTENTS TO CONSOLE ; ; CP/M VERSION 1.4 ADDRESS CONSTANTS ; BASE EQU 0 BDOS EQU 05H+BASE ;ENTRY TO FDOS ; ; DEFINE THE ASCII CONTROL CHARACTERS ; BEL EQU 007H ;(^G) BELL LF EQU 00AH ;(^J) LINE FEED CR EQU 00DH ;(^M) CARRIAGE RETURN ORG 0100H ; LXI H,0 ;CLEAR H&L REGS. DAD SP ;ADD STACK POINTER SHLD OLDSTK ;SAVE "OLD" STACK START: LXI SP,NEWSTK ;MAKE "NEW" STACK CALL ZBUF ;ZERO BUFFER LXI D,MSG1 CALL MSGOUT ;OUTPUT 1ST MESSAGE ST1: CALL CONIN CPI '0' JZ CPM ;EXIT TO CP/M IF "0" CPI '1' JC ST1 CPI '9'+1 JNC ST1 SUI 48 MOV C,A ;SAVE COUNT IN C STA NBR STA NM LXI D,MSG2 CALL MSGOUT ;OUTPUT 2ND MESSAGE LXI D,BYTE CALL GET1 JMP LK2 LK1: CALL CONIN STAX D ;PUT 1ST CHAR IN MEMORY INX D CALL CONIN ;INPUT 2ND CHAR STAX D ;PUT 2ND CHAR IN MEMORY DCX D ;BACK TO 1ST CHAR CALL AHEX ;HEX TO BINARY MOV A,L DCX D DCX D STAX D INX D DCR C MVI A,0 CMP C RZ ;RETURN WHEN ENTERED JMP LK1 ;TO ENTER NEXT BYTE LK2: LXI D,MSG3 CALL MSGOUT LXI D,SA MVI C,2 CALL LK1 ;TO ENTER START ADDR. CALL REV LXI D,MSG4 CALL MSGOUT ;OUT FIN. ADDR MESSAGE LXI D,FA MVI C,2 CALL LK1 ;TO ENTER FINISH ADDR CALL REV ; ;LOOK FOR CHARACTER SEQUENCE ; CALL CRLF LOOK: LXI H,FA ;FINISH ADDR IN H,L MOV C,M INX H MOV B,M LOOK1: LXI D,BYTE LHLD SA LDAX D PUSH PSW LDA NBR STA NUM CALL ENCK ;CHECK FOR FINISH POP PSW CMP M JZ LOOK2 INX H SHLD SA ;NEXT ADDR IN SA JMP LOOK1 LOOK2: INX H SHLD SA DCX H LOOK3: LDA NUM ;CHECK FOR COMPLETION OF BYTE MATCH DCR A STA NUM JZ PRT INX H INX D LDAX D CMP M JZ LOOK3 JMP LOOK1 ; ;THIS ROUTINE PRINTS ADDRESS AND MATCHED BYTES ; PRT: CALL CRLF MVI A,BEL ;RING THE BELL... CALL CONOUT LHLD SA DCX H ;ADDR OF OK BYTE SHLD SA MOV A,H ;CONVERT TO HEX & OUT PUSH H CALL HOUT POP H MOV A,L CALL HOUT MVI A,' ' CALL CONOUT LXI H,NBR MOV C,M LXI H,BYTE PRT1: MOV A,M PUSH H CALL HOUT POP H MVI A,' ' CALL CONOUT DCR C PUSH H LXI H,NM MOV A,C MOV M,C POP H MVI A,0 CMP C JZ PRT2 ;IF THRU INX H JMP PRT1 PRT2: LXI H,NBR ;GET BYTE COUNT MOV C,M LHLD SA ;GET CURRENT MEMORY POINTER PRT3: INX H DCR C JNZ PRT3 ;BUMP POINTER PER BYTE COUNT SHLD SA ;SAVE NEW POINTER JMP LOOK GET1: CALL CONIN STAX D ;PUT 1ST CHAR IN MEMORY INX D CALL CONIN ;INPUT 2ND CHAR STAX D ;PUT 2ND CHAR IN MEMORY MVI A,' ' CALL CONOUT DCX D ;BACK TO 1ST CHAR CALL AHEX ;HEX TO BINARY MOV A,L DCX D DCX D STAX D INX D DCR C MVI A,0 CMP C RZ ;RETURN WHEN ENTERED JMP GET1 ;TO ENTER NEXT BYTE MSG1: DB CR,LF,CR,LF,'How many bytes (0,1-9)? $' MSG2: DB CR,LF,'List bytes in hex ..... $' MSG3: DB CR,LF,'Start address ......... $' MSG4: DB CR,LF,'Finish address ........ $' MSG5: DB CR,LF,'NO MATCH$' MSG6: DB CR,LF,'$' ; ;THIS ROUTINE CHECKS FOR HL AT FINISH ADDRESS ; ENCK: MOV A,B CMP H RNZ ;RETURN IF NOT COMPLETE MOV A,C CMP L RNZ ;RETURN IF NOT COMPLETE LDA NM CPI 0 JZ START ;MATCHING COMPLETED LXI D,MSG5 CALL MSGOUT CALL CRLF JMP START ; ;THIS ROUTINE REVERSES 2 BYTES IN MEMORY ; REV: DCX D XCHG PUSH B MOV C,M DCX H MOV B,M MOV M,C INX H MOV M,B POP B XCHG INX D RET ; ; ; ; ; ;THIS ROUTINE CONVERTS A BINARY VALUE TO ASCII ;HEX AND OUTPUTS CHAR. MEMORY AT HCON. ; HOUT: CALL BINH LXI H,HCON ;CONVERSION AREA CHOT: MOV A,M CALL CONOUT INX H MOV A,M CALL CONOUT RET ; ;CONVERTS BINARY VALUE IN REG A TO ASCII HEX ;DIGITS AND STORES IN MEMORY. ; BINH: LXI H,HCON MOV B,A RAR RAR RAR RAR CALL BIN1 MOV M,A INX H MOV A,B CALL BIN1 MOV M,A RET ; ;THIS ROUTINE CONVERTS BINARY TO HEX ; BIN1: ANI 0FH ;LOW 4 BITS ADI 48 ;CONVERTS TO ASCII CPI 58 ;DIGIT 0-9 RC ADI 7 ;MODIFY FOR A-F RET ; ;THIS ROUTINE FETCHES DIGITS FROM THE ;BUFFER ADDRESSED BY B,C AND CONVERTS ;ASCII HEX DIGITS TO BINARY. UP TO ;16 BITS CAN BE CONVERTED. STOPS AT 0. ; AHEX: LXI H,0 AHE1: LDAX D ;FETCH ASCII DIGIT ORA A ;SET Z FLAG RZ DAD H DAD H DAD H DAD H CALL ASH1 ;CONVERT TO BINARY CPI 10H ;CHECK FOR LEGAL VALUE CMC RC ;RETURN IF ERROR ADD L MOV L,A INX D JMP AHE1 ; ;CONVERTS ASCII HEX TO BINARY ; ASH1: SUI 48 ;ASCII BIAS CPI 10 ;DIGIT 1-10 RC SUI 7 ;ALPHA BIAS RET ; ; ;THIS ROUTINE ZEROES OUT A BUFFER ; ZBUF: MVI B,ENDZ-STARTZ LXI H,STARTZ ZBU1: XRA A MOV M,A INX H DCR B JNZ ZBU1 ;LOOP 'TILL BUFFER ZERO'D RET ; ; ; CONSOLE CHARACTER INPUT SUBROUTINE ; ; ENTRY = NONE ; EXIT = ASCII CHARACTER RETURNS IN A REG. ; CONIN: PUSH H ;SAVE REGISTERS PUSH D PUSH B MVI C,RDCON ;READ CONSOLE CALL BDOS POP B POP D POP H ;RESTORE REGISTERS RET ; ; CONSOLE CHARACTER OUTPUT SUBROUTINE ; ; ENTRY = ENTER WITH ASCII CHARACTER IN A REG. ; EXIT = NONE ; CONOUT: PUSH H ;SAVE REGISTERS PUSH D PUSH B PUSH PSW MOV E,A ;CHARACTER TO E REG. MVI C,WRCON ;WRITE CONSOLE FUNCTION CALL BDOS POP PSW POP B POP D POP H ;RESTORE REGISTERS RET ; ; PRINT MESSAGE TO CONSOLE SUBROUTINE ; ; ENTER = MESSAGE STRING POINTED TO BY D&E REGS. ; EXIT = NONE ; MSGOUT: PUSH H ;SAVE ALL REGISTERS PUSH B PUSH PSW MVI C,WRCBUF;PRINT CONSOLE BUFFER FUNCTION CALL BDOS POP PSW POP B POP H ;RESTORE REGISTERS RET ; ; DISPLAY CARRIAGE RETURN/LINE FEED SUBROUTINE ; ; ENTRY = NONE ; EXIT =NONE ; CRLF: PUSH H ;SAVE ALL REGISTERS PUSH D PUSH B PUSH PSW LXI D,MSG6 ;POINT TO CR/LF MESSAGE CALL MSGOUT POP PSW POP B POP D POP H ;RESTORE ALL REGISTERS RET ;RETURN FROM "CRLF" CPM: LHLD OLDSTK ;GET "OLD" STACK POINTER SPHL ;RESTORE THE STACK POINTER RET ;RETURN FROM WHENCE WE CAME... STAT EQU 3 DATA EQU 2 STARTZ EQU $ ;START OF ZERO'D BUFFER NBR DS 1 NUM DS 1 BYTE DS 10 HCON DS 2 NM DS 1 SA DS 3 FA DS 3 ENDZ EQU $ ;END OF ZERO'D BUFFER OLDSTK DS 2 ;STORAGE FOR "OLD" STACK DS 64 ;32 LEVEL STACK NEWSTK EQU $ ;STORAGE FOR "NEW" STACK ; END