;***************************************************************************
;
;                                GLOBAL.M68
;
;
;                      Written By: James A. Jarboe IV
;                             1401 19th Street
;                           Huntsville, TX 77340
;                               409-295-5767
;
;                                 04/14/86
;                                 GR/AM
;                       copyright @ 1986 James A. Jarboe IV
;****************************************************************************
; Description: Replace 1 string with another within a given string
;              Similiar to VUE's global command
; Type:        XCALL GLOBAL,STRING,WHAT,WITH
;              The WHAT variable will be replaced by the WITH variable
;              within the STRING variable as long as the length of the
;              STRING variable is long enough to handle the LEN(WITH)+
;              the LEN(STRING).
;              If the WHAT string is longer than the WITH string then
;              the entire STRING will be truncated.
;              If the WHAT string is shorter than the WITH string then
;              the entire STRING will be expanded if the LEN(STRING) is
;              long enough.
;              If WITH string is empty then WHAT string will be replaced
;              with nothing and the entire STRING will be truncated.
;              WARNING: it will replace strings just as the vue global
;                       does. If  WHAT=is and WITH=as it will change
;                       "this" to "thas"
; Example:
;       STRING = a string variable any length
;       WHAT   = string to change, any length
;       WITH   = string to change WHAT to any length
;                as long as the length + length of the rest of STRING
;                is not greater than the mapped length of STRING
;
; 10 MAP1 STRING,S,20,"ABCDEFG"  ! size of string longer than Len(string)
; 20 MAP1 WHAT  ,S,5 ,"ABC"      ! variable to change
; 30 MAP1 WITH  ,S,5 ,"Z"        ! variable to change to
; 40 ? STRING
; 50 XCALL GLOBAL,STRING,WHAT,WITH
; 60 ? STRING
; 70 END
;      Would look like;
;      ABCDEFG
;      ZDEFG
;
; WHAT="B"
; WITH="XYZ"
;
;      Would look like;
;      ABCDEFG
;      AXYZCDEFG
;
; WHAT="ABC"
; WITH=""
;
;      Would look like:
;       ABCDEFG
;       DEFG


       SEARCH  SYS
       SEARCH  SYSSYM
       OBJNAM  .SBR
ASECT
=0
P.TOP:  BLKW    1                       ; number of variables
A.TYP:  BLKW    1                       ; type
A.ADR:  BLKL    1                       ; address
A.SIZ:  BLKL    1                       ; size
B.TYP:  BLKW    1                       ; type
B.ADR:  BLKL    1                       ; address
B.SIZ:  BLKL    1                       ; size
C.TYP:  BLKW    1                       ; type
C.ADR:  BLKL    1                       ; address
C.SIZ:  BLKL    1                       ; size


       PSECT

       PHDR    -1,0,PH$REE!PH$REU
;
; Check for variable & set up registers
;

       CMMW    P.TOP(A3),#3            ; must be 3 variables
       JNE     NOTHRE                  ; no ... then quit
       MOV     A.SIZ(A3),D3            ; D3 is size of main STRING
       MOV     A.ADR(A3),A0            ; A0 points to start of STRING
       MOV     B.ADR(A3),A1            ; A1 points to WHAT string

; to set up we make A0 point to the begining of STRING and
; A4 points past the end of the string as mapped in BASIC
; then we find the LEN(STRING) by looking for null
; then move end'char to end of string
; before:
; STRING |ABCDEFG             |       ! mapped as in BASIC
; after:
; STRING |             ABCDEFG|
; Later we move it back adding the WITH for WHAT
; later:
; STRING |ZDEFG               |
;
SETUP:
       MOV     A0,A4                   ; A4 points to start of STRING
       ADD     D3,A4                   ; A4 points past end of STRING
       CLR     D2                      ; D2 now 0
10$:
       TSTB    @A0                     ; end of STRING ?
       BEQ     20$                     ; yes... go forward
       INC     A0                      ; lets find the end of STRIN
       INC     D2                      ; add 1 to counter
       BR      10$                     ; do it again
20$:
       CMP     D2,#0                   ; counter=0 ?
       BEQ     LOOP                    ; yes...go forward
       MOVB    -(A0),-(A4)             ; mov STRING char to end of STRING
       DEC     D2                      ; counter=-1
       DEC     D3  ;ADDED
       BR      20$                     ; do it again
LOOP:
       CTRLC   OUTOF                   ; control c then quit
       CLR     D2
       TSTB    @A4                     ; TEST FOR NULL
       BEQ     NOMORE                  ; QUIT IF THROUGH VARIABLE WITH null
       CMP     D3,A.SIZ(A3)            ; test for size of string
       BEQ     NOMORE                  ; quit if through variable by size
       CMMB    @A4,@A1                 ; compare STRING to WHAT
       BNE     A.DIT                   ; branch if no match
       SAVE    A4,A1,D3                ; save pointer in case a match
10$:
       TSTB    @A1                     ; at end of LEN(WHAT) string ?
       BEQ     REPLC                   ; yes then lets process
       CMP     D2,B.SIZ(A3)            ; at end of size WHAT string ?
       BEQ     REPLC                   ; yes then lets process
       INC     D2                      ; add 1 to counter
       INC     D3
       CMMB    (A4)+,(A1)+             ; compare STRING char to WHAT char
       BEQ     10$                     ; If equal then goto next char
       REST    A4,A1,D3                ; no match restore pointers
A.DIT:
       MOVB    (A4)+,(A0)+             ; increment variable place
       INC     D3
       JMP     LOOP                    ; do it again
REPLC:
       MOV     A4,D1                   ; make D1 hold pointer
       MOV     D3,D2
       REST    A4,A1,D3                ; restore because we saved
       MOV     D2,D3
       MOV     D1,A4                   ; now make A4 what it was
       CLR     D2                      ; clear counter
       MOV     C.ADR(A3),A2            ; point to WITH string
10$:
       TSTB    @A2
       BEQ     NOWITH
       CMP     D2,C.SIZ(A3)
       BEQ     NOWITH
       MOVB    (A2)+,(A0)+
       INC     D2
       BR      10$
NOWITH:
       JMP     LOOP

NOMORE:
       CLRB    @A0                     ; clear end of string
       RTN                             ; return to basic

NOTHRE:
       TYPECR  Not enough variables passed in GLOBAL.SBR
       RTN
OUTOF:
       EXIT
       END