; JCCHR.MAC -- CHARACTER COMPARE ; AUTHOR: S. F. HEFFNER ; DATE WRITTEN: 12/2/76 ; DATE REVISED: 12/3/76 ; 07/14/77 LEN, FOR ASCII CHARACTERS ; 11/08/77 LEN, MODE 4 UPDATED FOR ASCII ; .NLIST TOC ;TBL OF CONTENTS NOT WANTED ; .TITLE JCCHR .SBTTL CHARACTER COMPARE ; ***DEBUG< .ENABL AMA ;NO PC-REL ADDRS ; ***DEBUG> ; .MCALL SUBR,FRTN .MCALL MINIT,PUSH,POP .MCALL CPARGS,INIWS,RESWS,NMWS,PTWS ; MINIT ; ;* FUNCTION JCCHR - STRING CHARACTER COMPARE ; ; I = JCCHR(STR1,STCH1,ECH1,STR2,STCH2,ECH2,MODE) ; ; WHERE: ; I = SET BY JCCHR ACCORDING TO MODE (SEE BELOW) ; STR1,2 = CHAR STRING ADDRS ; STCH1,2 = STARTING CHAR POSITIONS ; ECH1,2 = ENDING CHAR POSITIONS (BUT NULL BYTE W/IN ; THIS TERMINATES COMPARE) ; MODE = MODE OF COMPARE: ; MODE 1: FOR LGTH OF SHORTER STRING, ; IF STR1 = STR2, ; IF LGTHS SAME, RETURN 2; ; IF STR1 SHORTER, RETURN 1; ; IF STR1 LONGER, RETURN 4. ; IF STR1 < STR2, RETURN 1. ; IF STR1 > STR2, RETURN 4. ; MODE 2: FOR LGTH OF SHORTER STRING, ; IF STR1 = STR2, RETURN 8. ; IF STR1 <> STR2, RETURN 0. ; MODE 3: ; IF STR2 A SUBSTR OF STR1, RETURN THE STARTING ; POSITION IN STR1 WHERE STR2 APPEARS. ; IF NOT, RETURN 0. ; MODE 4: DEFINING A DELIMITER AS ANY ; ASCII CHAR .NE. (0-9) OR (A-Z) ; IF STR2 IS A DELIMITED SUBSTR OF STR1 (DELIMITERS ; NOT REQUIRED AT START OR END OF STR1), ; RETURN THE STARTING POSITION IN STR1 WHERE ; STR2 APPEARS. ; IF NOT, RETURN 0. ; E.G., ; SEARCH FOR 'BUF' IN 'A = BUFF*BUF-1' ; 'BUFF' WILL BE IGNORED AND 'BUF' SELECTED AS ; IT IS DELIMITED BY '*' AND '-' ; THE STARTING POSITION IS 10 ; ; ; ;- ; NMWS ; NOTE: NMWS SEQUENCE S1A,...,S2L IS REQUIRED BY SETUP ; CODE BELOW. ; ; FLAGS IN CFLGS: ; S1H = 1 ;STR1 > STR2 ; SUBR JCCHR,7 MOV R5,R0 ;SAVE ARG PTR RESWS TOTWS/2 ;RESERVE WS ON STK PTWS ;SET R5 AS WS PTR CLR CFLGS(R5) ;INIT FLAGS MOV #-1,R3 ;SET UP 2 STRS ;EBC MOV #1,R4 ;PREP TO FLIP BYTES CCHSET: MOV (R0)+,S1A(R5) ;GET STR ADDR MOV S1A(R5),A1S(R5) ;SAVE STR1 ADDR FOR MODE 3/4 MOV @(R0)+,R1 ;GET ST POS DEC R1 ;FROM 0, NOT 1 ADD R1,S1A(R5) ;NOW ST CHAR ADDR MOV @(R0)+,R2 ;GET END POS SUB R1,R2 ;NOW STR LGTH MOV R2,S1L(R5) ;SAVE IT MOV S1A(R5),R1 ;GET STR ADDR CCHSLP: ;EBC XOR R4,R1 ;FLIP BYTE ADDR TSTB (R1) ;NULL BYTE? BEQ CCH1 ;IF SO, ENDS STR ;EBC XOR R4,R1 ;NO, FLIP BACK INC R1 ;BUMP TO NEXT CHAR SOB R2,CCHSLP ;END OF GIVEN LGTH? CCH1: SUB R2,S1L(R5) ;CORRECT LGTH SUB #4,R5 ;PT TO NEXT STR WS INC R3 ;DONE BOTH STRS? BEQ CCHSET ;IF NOT, DO STR2 ADD #8.,R5 ;YES, RESET WS PTR MOV @(R0)+,MODE(R5) ;GET CMP MODE CMP MODE(R5),#2 ;SUBSTR SRCH? BGT CCHM34 ;IF SO MOV S1A(R5),R1 ;NO, GET STR ADDRS MOV S2A(R5),R2 MOV S1L(R5),R3 ;USE SHORTER LGTH CMP R3,S2L(R5) ;STR2 SHORTER? BLE CCH2 ;IF NOT MOV S2L(R5),R3 ;YES, USE STR2 LGTH PUSH #1 ;PREP TO FLIP BYTES MOV (SP),R4 CCH2: ;EBC XOR R4,R1 ;FLIP BYTE ADDRS ;EBC XOR R4,R2 MOVB (R1),R0 ;GET STR1 CHAR BIC #177400,R0 ;CLN IT UP MOVB (R2),R4 ;GET STR2 CHAR BIC #177400,R4 ;CLN IT UP CMP R0,R4 ;STR1 : STR2 BEQ CCHEQ1 ;IF SAME SO FAR BLT CCHNE1 ;IF S1 < S2 BIS #S1H,CFLGS(R5) ;S1 > S2, REMEM CCHNE1: POP ;CLN UP STK CMP MODE(R5),#1 ;MODE 2? BGT CCHRT0 ;IF SO RTN 0 BIT CFLGS(R5),#S1H ;MODE 1, S1>S2? BNE CCHRT4 ;IF SO, RTN 4 CCHRT1: MOV #1,R0 ;S1S2, RTN 4 BR CCHRTN CCHRT8: MOV #8.,R0 ;MATCH FND, RTN 8 BR CCHRTN CHRT34: SUB A1S(R5),S1A(R5) ;GET POS WHERE FOUND FOR 3, 4 MOV S1A(5),R0 ;FUNCTION RETURN ADD #1,R0 ;NOT FROM 0 BR CCHRTN CCHEQ1: MOV (SP),R4 ;FLIP BYTE ADDRS BACK ;EBC XOR R4,R1 ;EBC XOR R4,R2 INC R1 ;BUMP CHAR PTRS INC R2 SOB R3,CCH2 ;END OF CMP? POP ;YES, CLN UP STK CMP MODE(R5),#2 ;MODE 2? BEQ CCHRT8 ;IF SO, RTN 8 CMP S1L(R5),S2L(R5) ;MODE 1, CMP LGTHS BLT CCHRT1 ;IF S1 SHORTER BEQ CCHRT2 ;IF SAME LGTH BR CCHRT4 ;S1 LONGER CCHM34: MOV #1,R4 ;PREP TO FLIP ADDRS CCH5: CMP S1L(R5),S2L(R5) ;ROOM IN S1 FOR MATCH? BLT CCHRT0 ;IF NOT, NO MATCH MOV S1A(R5),R1 ;YES, GET STR ADDRS MOV S2A(R5),R2 MOV S2L(R5),R3 ;LGTH TO CMP CCH6: ;EBC XOR R4,R1 ;FLIP BYTE ADDRS ;EBC XOR R4,R2 CMPB (R1),(R2) ;BYTES SAME? BNE CCHNE2 ;IF DIFFERENT ;EBC XOR R4,R1 ;FLIP BYTE ADDRS BACK ;EBC XOR R4,R2 INC R1 ;BUMP TO NEXT CHAR INC R2 SOB R3,CCH6 ;END OF THIS CMP? CMP MODE(R5),#3 ;YES, MODE 3? BEQ CHRT34 ;IF SO, RTN 8 MOV R1,R2 ;END OF S1? SUB S1A(R5),R2 CMP R2,S1L(R5) BEQ CHRT34 ;IF SO, RTN 8 ;EBC XOR R4,R1 ;NO, GET NEXT CHAR JSR PC,TSTAS ;CHECK FOR SPECIAL CHARS CMP R2,#0 ;0 IF SPECIAL BEQ CHRT34 ;IF PUNCT, GD MATCH BR CCH7 ;NOT PUNCT, NO MATCH CCHNE2: CMP MODE(R5),#3 ;MODE 3? BGT CCH7 ;IF NOT, MODE 4 INC S1A(R5) ;UPDT S1 ADDR DEC S1L(R5) ;UPDT S1 LGTH BR CCH5 ;GO TRY AGN CCH7: MOV S1A(R5),R1 ;GET S1 ADDR ;EBC XOR R4,R1 ;FLIP BYTE ORDER JSR PC,TSTAS ;CHECK FOR SPECIAL CHARS CMP R2,#0 ;IS IT PUNCT? BEQ CCH8 ;IF SO INC S1A(R5) ;NO, UPDT S1 ADDR DEC S1L(R5) ;UPDT S1 LGTH BGT CCH7 ;IF NOT S1 END BR CCHRT0 ;S1 END, NO MATCH CCH8: INC S1A(R5) ;BUMP PAST PUNCT DEC S1L(R5) ;UPDT S1 LGTH BR CCH5 ;GO TRY AGN ; ;TSTAS - CHECK FOR SPECIAL CHARACTERS ; TSTAS: MOVB (R1),R2 ;GET CHARACTER BIC #177400,R2 ;CLEAN IT UP CMP R2,#60 ;LESS THAN '0' ? BLT PUNCT CMP R2,#71 ;GREATER THAN '9' ? BLE RET ;CHAR IS (0-9), RETURN BIC #40,R2 ;MAKE IT UPPER CASE FOR TESTING PURPOSES CMP R2,#101 ;LESS THAN 'A' ? BLT PUNCT ;YES, THEN PUNCTUATION CMP R2,#132 ;GREATER THAN 'Z' ? BLE RET ;CHAR IS (A-Z), RETURN PUNCT: CLR R2 ;CLEAR R2 TO INDIC. SPECIAL CHAR RET: RTS PC ;RETURN TO CALLER ; .END