Retro - 40 best procedure: Find the string.

ZX Review #7-8-9-10
      8.8. Substring search


  Length: 168

  Number of variables: 0

  Checksum: 19875

  Purpose: This program returns the position of the substring 
(B $) in the main line (A $), or 0 on failure.


  Calling the program:

     LET P = USR address

  Error checking: If Line
does not exist, or if the length
substring is zero, or if
length of the substring is greater than the length of the main 
line program returns 0. If no error, but the substring was not 
found in the main line, the program also gives 0.


  Comment: after leaving the
program in the native variable P (can use any other variable) 
will hold the desired value. Line, which made treatment can not 
be arrays data. To change the number of used lines marked with 
"*" 

should be changed. 66 * - this is
substring, 65 * - the main line.
To change these numbers need to replace code required
characters. For example, if you want to find a position in the 
H $ G $, then respectively, will need to enter 71 (code G) and 
72 (code H). 


   LISTING machine code
Assembly label number to VVODA147.


       SUB A 151

       LD B, A 71

       LD C, A 79

       LD D, A 87

       LD E, A 95

       LD HL, (23627) 42 75 92
NEXT_V LD A, (HL) 126

       CP 128 254 128

       JR Z, NOT_FD 40 95

       BIT 7, A 203 127

       JR NZ, FOR_NX 32 41

       CP 96254 1996

       JR NC, NUMBER 48 29

       CP 65 254 65 *

       JR NZ, SUBSTR 32 2

       LD D, H 84

       LD E, L 93
SUBSTR CP 66254 66 *

       JR NZ, CHECK 32 2

       LD B, H 68

       LD C, L 77
CHECK LD A, D 122

       OR E 179

       JR Z, STRING 40 4

       LD A, B 120

       OR C 177

       JR NZ, FOUND 32 38
STRING PUSH DE 213

       INC HL 35

       LD E, (HL) 94

       INC HL 35

       LD D, (HL) 86
ADD ADD HL, DE 25

       POP DE 209

       JR INCRS May 24
NUMBER INC HL 35

       INC HL 35

       INC HL 35

       INC HL 35

       INC HL 35
INCRS INC HL 35

       JR NEXT_V 24206
FOR_NX CP 224 254 224

       JR C, N_BIT 56 6

       PUSH DE 213

       LD DE, 18 17 18 0

       JR ADD 24234
N_BIT BIT 5, A 203 111

       JR Z, STRING 40225
NEXT_B INC HL 35

       BIT 7, (HL) 203 126

       JR Z, NEXT_B 40251

       JR NUMBER 24227
FOUND EX DE, HL 235

       INC HL 35

       INC HL 35

       PUSH HL 229

       PUSH HL 229

       INC BC 3

       PUSH BC 197

       LD A, (BC) 10

       LD E, A 95

       INC BC 3

       LD A, (BC) 10

       LD D, A 87

       OR E 179

       JR Z, ZERO 40 11

       PUSH DE 213

       LD A, (HL) 126

       DEC HL 1943

       LD L, (HL) 110

       LD H, A 103

       AND A 167

       SBC HL, DE 237 82

       JR NC, CONTIN 48 8

       POP BC 193
ZERO POP BC 193

       POP BC 193
ERROR POP BC 193
NOT_FD LD BC, 0 1 0 0

       RET 201
CONTIN POP IX 221225

       POP BC 193

       EX DE, HL 235

       POP HL 225

       INC BC 3

       INC BC 3
SAVE INC HL 35

       PUSH HL 229

       PUSH BC 197

       PUSH IX 221229

       PUSH DE 213
COMPAR LD A, (BC) 10

       CP (HL) 190

       JR Z, MATCH 40 12

       POP DE 209

       POP IX 221225

       POP BC 193

       POP HL 225

       LD A, D 122

       OR E 179

       JR Z, ERROR 40225

       DEC DE 1927

       JR SAVE 24,234
MATCH INC HL 35

       INC BC 3

       PUSH HL 229

       DEC IX 221 1943

       PUSH IX 221229

       POP HL 225

       LD A, H 124

       OR L 181

       POP HL 225

       JR NZ, COMPAR 32227

       POP DE 209

       POP DE 209

       AND A 167

       SBC HL, DE 237 82

       POP DE 209

       POP DE 209

       POP DE 209

       AND A 167

       SBC HL, DE 237 82

       LD B, H 68

       LD C, L 77

       RET 201
2

  How it works:

  In the battery, a pair of registers
BC and DE register pair is loaded 0. Later in the program
BC will be set to address B $, and
in DE will be set address A $.
In HL load address of the beginning
of program variables.

  As the battery is loaded bytes
from the address in HL.
If the battery contains the number 128, the program jumps to
NOT_FD, because reached the end of the program variables.
If bit 7 of the accumulator is set to 1, a transition is made to
FOR_NX, because found variable - not a string and not a number,
whose name consists only of
one letters. If the battery
contains a number greater than 95,
made the transition to a NUMBER.

  To achieve this phase
line must be found. If
in the accumulator contains the number
65, is determined by the location of the string A $, and the 
contents of HL copied to the DE. If the battery contains the 
number 66, is determined by the string B $, and HL is copied to 
the BC. If DE is not equal to 0 and BC is not equal to 0, 
determined the location of both lines, and the program jumps to 
FOUND. 

  If the program reaches a procedure STRING, DE stored in the
the stack and loads the long lines found. This amount is added 
to the address pointer high byte string and stored in the HL. 
DE recovered from the stack and made the transition to INCRS.


  The procedure NUMBER HL increases 5 times, pointing to the 
last byte of the number found. HL then increases, indicating

the following variable, and a transition to NEXT_V.

  The procedure FOR_NX, if the battery contains a number of 
smaller than 224, a transition is made to

N_BIT, because encountered variable is not controllable
loop variable FOR-NEXT. If
accumulator value is greater
than 223, then the number 18 is added to the HL, pointing to 
the last bytes of the loop variable, and the program returns to 
INCRS. 

  If the program reaches N_BIT
and bit 5 of the battery is installed
to 0, a transition is made to STRING,
to get the HL address of the next variable, because found
array.

  If the program reaches NEXT_
B, found the number with a name that
more than one character in length.
Thus, HL is increased
until then, until the point to the
the last character of variable name, and then made the 
transition to NUMBER.


  The procedure FOUND in HL is loaded row address A $, and this
value increases twice
to get the address of the senior
byte pointers. This value
then stored on the stack twice. BC increases, indicating
at low byte pointers substring B $. Address to BC then stored 
in the stack. In DE loaded length of the string B $ and if this 
value is 0, is go to ZERO. DE then pushed onto the stack. In HL 
load length of the string A $, and if this value is not smaller 
than DE, the program jumps to CONTIN. The stack pointer is then 
reduced in BC is loaded 0 the program returns to BASIC.


  The procedure CONTIN in IX established the length of the 
string B $, and BC put the address young

Byte pointer to the substring
B $. In DE load difference
lengths of strings A $ and B $, but loaded HL address high byte
Pointers to A $. BC then increased twice to get the address of 
first character in substring B $. HL increases

pointing to the next character
string A $. HL, BC, IX and DE is then stored on the stack. As 
the battery is loaded byte at the BC, and if this value is 
equal to the byte at the address in HL, a transition is made to 
MATCH. DE, IX, BC and then HL recovered from the stack. If

DE contains a 0, a transition is made
for ERROR, because substring B $ is not in
string A $. Counter DE decreases, and the program returns to
SAVE.

  If the program reaches a procedure MATCH, HL and BC are 
increasing, pointing to the next symbol A $ and B $, 
respectively. HL is then stored in the stack.

IX, the counter decreases, and after recovery from HL Stack
If IX does not contain 0, the program returns to COMPAR.

  To achieve this phase
locate substrings B $ in
string A $ is to be determined. The length of the substring B $ 
is subtracted from the HL, and then address strarshego byte 
pointers for string A $ is subtracted from the HL. The result - 
a position of the substring B $ in the string A $. This value 
is copied into the register pair BC, and the program returns to 
BASIC. 


           *


  Ending print books Dzh.Hardmana and E. Hyuzona "40 best
procedures, we would like to give
small comment, which
On the format of the program variables in the Spectrum. The 
point that the procedures outlined in this last final block, 
commonly operate with them. Those who do not have firm 
instructions on the Spectrum (Book Vickers), may be a

this format and unfamiliar, and we
in his works still get by this issue is not addressed. Those 
who are interested in this question, can read your comment. 


   Data format in the Spectrum


  Data is stored in a Spectrum
as variables and arrays
specially designated for this
memory area. This area begins directly behind the area in which 
located text of the BASIC program.


  At the beginning of the program
variable indicates the double-byte system variable VARS.
It is located at 23267
(5AE3H).

  End of program variables is given a special marker - a byte 
whose value is 80H (128). 

  Spectrum distinguishes several
different types of variables. They are:

  - The usual numeric variable
whose name consists of one
letters, eg x;

  - A numerical variable whose name consists of more than one 
letter, for example, row; 

  - A numeric array, for example,
a (5) or b (3,3,40);

  - Variables that control the cycles FOR ... NEXT, for 
example, 1; 

  - String variables, eg, a $;

  - String arrays, for example,
b $ (10,40).


      Numeric variable

    with the name of one letter


  Occupies 6 bytes. In the first
byte kept her name in the next five - its value in the integral 
form. On the integral representation of real numbers, see 
"Programming native. "The first byte

has the following layout:



    0 1 1 b to have in a



  That this is a simple variable, indicates a specific
location of the first three bits.


  A numeric variable named

    more than one letter


  Her first byte has the following format:



    1 0 1 b to have in a



  Other bytes of the name (except the last) have the following 
format: 



    0 in y to a well. .



  The last byte of name:



    1 b to have a well. .



  For the name followed by 5 bytes
expressions of the numbers in the integral form.


        Numeric array


  First byte:



    1 0 0 b y k in a



  Bytes 2 and 3 contain a complete
length of all elements (5 bytes for each array element)
plus 2 bytes for each dimension of the array, plus one byte
to specify the number of dimensions, ie it contains
indication of the end of the array.

  Byte 4 contains the dimension
array.

  Bytes 5 and 6 contain a number of elements in the first 
dimension. If the dimension of the array more than 1, then:


  Bytes 7 and 8 contain a number of elements in the second 
dimension, etc. Then go themselves array elements: five bytes 
for each element. For multidimensional arrays, the order

the data rate is as follows:
b (1,1), b (1,2), b (1,3), b (2,1) ...
b (3,3).


        Loop variables


  First byte:



    1 1 1 b to have in a



  Next:

  5 bytes - the current value;

  5 bytes - the final value;

  5 bytes - step;

  2 bytes - number of rows returned
            TA;

  1 byte - number of operators in
line to which you are
return.


     Character variable


  First byte:



    0 1 0 b y k in a



  Next:

  2 bytes - length of string;

  x bytes - text string.


       Character array


  First byte:



    1 1 0 b y k in a



  Next:

  2 bytes - an indication of the end
array;

  1 byte - the dimension;

  2 bytes - length in the first dimension;

  ..............................

  2 bytes - length of the latter
dimension.

  Next: one byte for each element.