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 byteF0,
and in FS+#600 byteF
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