Programming - procedures: screen scrolling, multiplication, stringing to a binary number, preparing a sprite for printing with pixel accuracy, calculating the screen address, calculating the address of the next line in the screen area.



                        Assembler.


  If you don't know what it is, but want to find out, then very
I recommend reading articles on this topic in ZF #7 & #8.
 In this issue the material is already for those who understand, our main
3M coder will share his skills.


  Hello people!
  I (3M) decided to share some coding secrets on
SPECCY. I've been on the 'disk' SPECTRUM for only 2 years, before that
there was a home-made cassette LENINGRAD 48, which worked for 5 years and
died from my 'brilliant' modifications, + the GENS assembler package and
ZEUS with 'instant' delivery to cassette accompanied by mournful sounds
pilot signal. It was on him that I earned my professional bo-
The pain of all 48kb is minimalism. Now let's get down to business.

 To begin with, I will give some procedures that I use for
writing your own programs. The first 2 of them are the most common and
the most necessary ones, calculate the address of the next line in
screen areas:


Input: HL - line address.
Output: HL - address of the next line.

   Search for next Search for next
    bottom line top line

 NEXTHL INC H BACKHL DEC H
         LD A,H LD A,H
         AND 7 CPL
         RET NZ AND 7
         LD A,L RET NZ
         ADD A,32 LD A,L
         LD L,ASUB 32
         RET C LD L,A
         LD A,H RET C
         SUB 8 LD A,H
         LD H,A ADD A,8
         RET LD H,A
                              RET


  I hope there are no questions here? Let's move on. Next
The following procedure, also common, calculates the screen address
at known coordinates:


Input: H - Y (0-191), L - X (0-255).
Output: HL - address, B - bit number (0-7).

   CORHL LD A,L
           AND 7
           LD B,A
           XOR L
           LD L,A
           LD A,H
           AND 7
           LD C,A
           XOR H
           RRA
           SCF
           RRA
           RRA
           LD H,A
           AND 7
           OR L
           RRCA
           RRCA
           RRCA
           LD L,A
           LD A,H
           AND 248
           OR C
           LD H,A
           RET


  If you add to this procedure (before RET) the following lines:


         INC B
         LD A,1
 ROLLER RRCA
         DJNZ ROLLER
         OR(HL) or XOR(HL); mask
         LD(HL),A


  then we get a procedure for printing a point - PLOT by coordinates in HL.
Although this procedure is very fast, its speed may not be
enough for temporary effects(DEMO, 3D graphics, etc.), for
They have a method for even faster point output in 69 clock cycles.
 The following procedure was developed by me, oia prepares
sprite for printing with pixel accuracy (if anyone has the data)
This procedure works faster, please call).


 Input: B - sprite height in pixels
        C - sprite width in bytes
        DE - sprite address
        HL - buffer address
        A - bit number or number of cyclic
             sprite shifts (0-7)
 Output: ready-made sprite with width+1 in the buffer

  RUNSPR PUSH HL
           EXX
           LD (L13+1),A
           INC A
           LD B,A
           LD A,1
  L10 RRCA
           DJNZ L10
           LD E,A
           DEC A
           OR E
           LD E,A
           POP HL
           EXX
  L11 LD A,C
           EXX
           LD B,A
           LD D,0
  L12 EXX
           LD A,(DE)
           INC DE
  L13 JR L13
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           EXX
           LD C,A
           AND E
           ORD
           LD(HL),A
           INC HL
           XOR D
           XOR C
           LD D,A
           DJNZ L12
           LD(HL),D
           INC HL
           EXX
           DJNZ L11
           RET


  The uniqueness of this procedure is that it is 'free'
ret' sprites of any size.
  Many novice coders are faced with the problem of printing
village. Her first clumsy solution is to use ROM routines,
who, as a result of close communication with the 'calculator', eat a lot
time. The following procedure will quickly prepare a number in the buffer in
in the form of a 5 byte string for its subsequent printing:


 Input: HL - number (0-65535)
        DE - 5 byte buffer address
 Output: string of numbers in buffer

 NUMSTR LD BC,10000
           CALL L10
           LD BC,1000
           CALL L10
           LD BC,100
           CALL L10
           LD BC,10
           CALL L10
           LD BC,1
 L10 LD A,47
 L11 INC A
           SBC HL,BC
           JR NC,L11
           ADD HL,BC
           LD(DE),A
           INC DE
           RET


  The following procedure performs the reverse task of the previous one -
converts a string to a binary number:


 Input: DE - 5 byte buffer address
 Output: HL - number

 STRNUM LD HL,0
           LD BC,10000
           CALL L10
           LD BC,1000
           CALL L10
           LD BC,100
           CALL L10
           LD BC,10
           CALL L10
           LD BC,1
 L10 LD A,(DE)
           INC DE
 L11 DEC A
           C.P.47
           RET Z
           ADD HL,BC
           JR L11


  And now the procedure for multiplying a 2 byte number by 1 byte
(the idea is also mine):


 Input: HL - number (0-65535)
        A - number (0-255)
 Output: HL=HL*A

 HLA LD DE,0
 HLA1 AND A
           RET Z
           RRA
           JR NC,L10
           EX DE,HL
           ADD HL,DE
           EX DE,HL
 L10 ADD HL,HL
           JR HLA1


  If we run it with HLA1, it will be equivalent to calculating
HL=HL*A+DE.
  And now 2 very short procedures for scrolling the screen by
familiar with the attributes:


      SCROLL UP SCROLL DOWN

SCRUP LD DE,16384 SCRDW LD DE,23295
       LD A,24 LD A,24
SU10 LD HL,32 SD10 LD HL,0-32
       ADD HL,DE ADD HL,DE
       LD BC,224 LD BC,224
       LDIR LDDR
       LD HL,1824 LD HL,0-1824
       ADD HL,DE ADD HL,DE
       LD BC,32 LD BC,32
       LDIR LDDR
       DEC A DEC A
       JR NZ,SU10 JR NZ,SD10
       RET RET


   The issue of screen scrolling is very important for creating
niya full-fledged text VIEWERS. Since the non-turbocharged Z80
notmanages to refresh the screen in one interruption, then when scrolling
In many cases there is unreadable flickering of the text. For
In order to avoid this, it is necessary to synchronize scrolling with
interruptions and rapid screen restructuring. This can be achieved
using 2 128 SPECCY screens, or a method that has recently been used
came to my mind and which should show good results.
  Its essence is that the finished screen begins to be thrown
not with the beginning of the interruption, but somewhere in the middle, as a result
which time for transfer will be about 1.5 INT, which on SCORPI-
ON'e (as on the brake one) will be >100,000 cycles, which is quite
not enough for scrolling without flickering. But all this is work -
Only when transferring (changing lanes) from top to bottom.
Sob may well provide scrolling speed without flickering
25 lines per second. And finally, I’ll give you the timing characteristics
some types of screen transfer (rearrangement):


            TACT METHOD
         1 according to LDIR 129024
         2 procedures SCRUP,SCRDW 99696
         3 stack throws 78336


   This concludes this story.

I will be glad to listen to all responses, wishes, questions and suggestions
by phone 28-70-91 (Marat) from 20-22 h.

Share your thoughts about the article