Coding - About smooth leafing.

 About smooth scrolling                       
                                                                
Smooth leaflets, which are in one frame, have been in our magazine since the 2nd 
numbers. In ZX-Guide #1 there was a small article, but, according to reviews, it
was too short and incomprehensible, despite the presence         
source in the application. "Assembler Lesson" in ZX-Guide #4         
contained a more detailed explanation, but this publication did not provide
result. People asked for more. So this time I'll write out EVERYTHING
algorithm, how it works in the leaflet Info Guide. I save and     
such Info Guide-specific subtlety as auto-selection of modes
(blink/hemoprahue, page/half page of attributes). Of course 
The program is not written perfectly. She could be more flexible if
memory for expanded text, sprites and attributes was not allocated
fixed addresses, but in any free space.        
The found non-optimalities are marked with asterisks.                 
                                                                
The source itself is posted on                                        
http://alonecoder.narod.ru/zx/books/IG1OSRC.rar                 
                                                                
;sprites blink if there are lines #FF, #XX, #YY (#YY >= #80)   
;if lines > #100, no blinking sprites allowed, 16k sprites in total
;otherwise blinking or 32k sprites                               
;64:MAX #1FF LINES                                              
;42:MAX #2ED LINES                                              
                                                                
COLLIST:                                                        
;text loaded approximately to the end of the PGTXT memory                   
;HL == start of text (after title)                          
                                                                
put the interrupt table in #7В00                               
                                                                
if code 13 is found in [HL+0..43],                                
 then: [TXtADR]=4, [TXaMSK]=#BB, [TXtWID]=42                   
 otherwise: [TXtADR]=0, [TXaMSK]=#55, [TXtWID]=64                   
                                                                
PUSH HL[cursprpg]=[curatrpg]=pgspr2                                    
*include the PGCOLTX page (???)                                
CALL TEXTatr ;decoding text attributes, determining number 
  ;lines of sprites and the presence of 2-screen sprites      
;HL == NOBYTE adr                                               
;НХ == number of lines of sprites, bit7 - sign of 2-screen sprites 
;DE,LX == current address and attribute page                    
LD A,LX                                                         
PUSH DE,AF                                                      
CALL TEXTspr ;generation of sprite outputs                      
POP AF,DE                                                       
                                                                
;recoding of attributes according to the principle                          
;ВС=AtrTab+[DE]*2, [DE++]=[ВС], [HL++]=[ВС+1]:                  
if (A != pgspr2) and (C` != pgspr2):                            
 [SET5H+1],236 ;turns on flickering                               
 if DE>= #E000:                                              
  recode attributes from PGATR to PGATR and pgspr2               
  [atrswpF]=24 ;"jr" (page switch flicker enabled)  
 otherwise:                                                         
  recode attributes from [PGATR:#C000]                        
   in [PGATR:#C000] and [PGATR:#E000] to the end of the page            
  [atrswpF]=40 ;"jz" (page switch flicker disabled) 
otherwise:                                                          
 [SET5H+1],252 ;disables flickering                              
 recode attributes from [pgspr2:ATR2BEG]                      
  in [pgspr2:ATR2BEG] and [pgspr2:ATR2BEG] to the end of the page       
 recode attributes from [PGATR:#C000]                         
  in [PGATR:#C000] and [PGATR:#C000] to the end of the page             
 [atrswpF]=40 ;"jz" (page switch flicker disabled)  
                                                                
POP HL                                                          
                                                                
CALL TEXTtxt ;decoding text intoconstant width lines   
  ;and duplication of sprite attributes                 
[NOBYTE]=IX*2                                                   
[NEWPGHL]=HL=-([NEWPGIX]+HGT)*2                                 
              ;-2*(+HGT)
turn on the PGCOLTX page and copy there from #8000 #4000 bytes   
                                                                
generate a table in TABNL:                                     
 HGT pieces of 2-byte addresses of the ends of familiar strings           
  (#4040,#4060,..)                                              
                                                                
;font generator                                               
if (TXtWID) != 64:                                            
 clear FS (#2400 bytes) ;FS=#9C00                               
 expand 6 fonts (in screen format)                   
  from WASFb7 (characters 21 to 254) as follows:           
 ;HL=FS, B=8                                                    
 ;HL=FS+#600, V=12;HL=FS+#C00, V=4                                               
 ;HL=FS+#1200, V=10                                             
 ;HL=FS+#1800, V=14                                             
 ;HL=FS+#1E00, V=6                                              
 for each of the 6 lines of the character: take a byte in A from the font,       
  mask & #FC, shift from A to (HL) by B bits to the right         
if (TXtWID) == 64:                                            
 clear FS (#600 bytes)                                          
 expand the font in FS (in screen format)                  
  from FONT48 (there are graphics starting from character 21,                  
  2 bytes in one %22221111, i.e. 3 bytes per character)      
 copy from FS to FS+#600, and in FS we make byte&#F0,         
  and in FS+#600 byte�F                                          
                                                                
put the interrupt table in FS-#100                             
                                                                
DE=clln, CALL DECRNET ;generate an empty string                 
 ;(clln == PROG-151)                       
                                                                
;generator PROG                                                 
HL=PROG                                                         
repeat HGT times:                                              
 HL=HL+7 ;here will be "exx:ld sp,hl:inc l,l:exx:pop hl:inc h"     
 generate 6 lines of this type in [HL++]:                       
  "ld sp,hl:16*(ld bc,:push bc):inc h"                          
 HL=HL-1 ;the last "inc h" is not needed                            
generate in [HL++]: jp PROG                                    
                                                                
;generator of procedure for filling line (IX,IY) with text (HL)     
[COLPLJP+1]=HL ;her address                                        
generate in [HL++]: "ld (..),sp:ld sp,hl"                      
if [TXtWID] != 64:                                            
 generate in [HL++]: "pop hl:ld c,l:ld l,h"                    
 DE=62+128                                                      
 repeat 5 times:                                               
  generate in [HL++]: "ld a,(ьс):inc b"                        
  A=66, CALL LDIX;generates "ld (ix/iy+),a"                
 ;and shifts DE to the next line              
 generated in [HL++]: "ld a,(с):inc b"                         
 A=-329, CALL LDIX, D=0 ;generates "ld (ix/iy+),a"          
  ;and shifts DE 5 lines up and 1 byte to the right
 repeat for C=10..1:                                         
  generate in [HL++]: "ld h,`FS:pop de:ld с,e"                 
  CALL LINEBC ;column from "ld a,(с):hog (hl):inc b:inc h"      
 ;and step to the right                                     
 generated in [HL++]: "inc h:inc b:ld l,d"                     
  INC C:CALL LINEBC:DEC C ;column from                           
 ;"ld a,(с):hog (hl):inc b:inc h"             
 ;and step to the right                                 
 generated in [HL++]: "inc h:inc b:pop de:ld c,e:ld b,`FS+18"  
 CALL LINEBC;column from "ld a,(с):hog (hl):inc b:inc h"      
 ;and step to the right                                     
 generated in [HL++]: "ld l,d:inc b"                           
  HL=HL-1 ;the last "inc b" is not needed                           
 generated in [HL++]: "ld h,`FS"                               
 repeat 6 times:                                               
  generate in [HL++]: "ld a,(hl):inc h"                        
  A=66, CALL LDIX ;generates "ld (ix/iy+),a"                
 ;and shifts DE to the next line              
if [TXtWID] == 64:                                            
 generate in [HL++]: "ld de,"                     
 DE=62+128                                                      
 repeat for C=31..0:                                         
  generate in [HL++]: "pop hl:ld c,h:ld h,e:ld b,d"            
  CALL LINEBC ;column from "ld a,(с):hog (hl):inc b:inc h"      
 ;and step to the right                                     
generate in [HL++]: "ld sp,0:ret",                             
 the address of zero is entered into the command "ld (..),sp" above                 
                                                                
[LDIRKA+1]=HL                                                   
generate in [HL++]: "ld (..),sp:ld sp,hl"                      
for HGT lines of 16 2-byte words, starting with DE=#5820:         
 generate in [HL++]: "pop hl:ld (),hl"                     
generate in [HL++] "ld sp,0:ret",                              
 the address of zero is entered into the command "ld (..),sp" above                 
HALT                                                            
[BOTTOM]=HGT*2                                                  
                                                                
COLBEG:                                                         
;fill the contents of PROG with graphics of HGT lines:                  
HL=[BOTTOM]                                                     
[COLPROGTOP]=DE=PROG                                            
Repeat HALT:5*CALL COLPGPP 4 times,                           
 then another HALT:CALL COLPGPP                                    
clear line spacing on the screen:                         
from address #4020 #E0 bytes and from address #4720 #E0 bytes               
from address #4800 #100bytes and from address #4F00 #100 bytes             
from address #5000 #C0 bytes and from address #5700 #C0 bytes               
                                                                
COLST:                                                          
;display the contents of PROG:                              
;PROG contains HGT lines of the following form:                       
;for text:                                                    
;       EXX                                                     
;       LDSP,HL                                                
;       INC L,L                                                 
;       EXX ;+4                                      
;       POP HL ;+5                                      
;      DUP 6                                                    
;       INC N                                                   
;       (16*LD Sun,..:PUSH Sun)                                   
;      EDUP                                                     
;for a sprite string or an empty string:                          
;       LD IY,
; JP