Scrolling the attribute memory sideways

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
dfzx
Manic Miner
Posts: 673
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Scrolling the attribute memory sideways

Post by dfzx »

What's the most efficient way of scrolling the attribute memory sideways, right to left, introducing a column of, say, black ink/white paper attributes down the right hand side?

In C, which is where I'd start, it's a fairly simple loop of 31 byte copies from an attribute address into the byte one address lower, within a loop of 24 rows. But that doesn't sound too efficient. What's the best approach in assembler?
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
User avatar
RMartins
Manic Miner
Posts: 776
Joined: Thu Nov 16, 2017 3:26 pm

Re: Scrolling the attribute memory sideways

Post by RMartins »

dfzx wrote: Thu Jan 04, 2018 8:55 pm What's the most efficient way of scrolling the attribute memory sideways, right to left, introducing a column of, say, black ink/white paper attributes down the right hand side?

In C, which is where I'd start, it's a fairly simple loop of 31 byte copies from an attribute address into the byte one address lower, within a loop of 24 rows. But that doesn't sound too efficient. What's the best approach in assembler?
Actually, you can do exactly the same in ASM.
NOTE: C is very close to assembly, although many people do not realize it.

But to speed it up, you can use LDIR/LDDR or better 31 LDI/LDD, to make the copy.
You just need to set the source origin (HL) and destination (DE), correct depending on the direction you want to go.

If the column that is disappearing is on the right (scrolling/moving colors from left to right), you want to use LDD, and start on the right most column
If the column that is disappearing is on the left (scrolling/moving colors from right to left), you want to use LDI, and start on the left most column.

For the top character line, something like this

Code: Select all

LD HL, ATTR_ADDR+1
LD DE, ATTR_ADDR
LD BC, 31
LDIR
LD (HL), A		; A = new color appearing on right
Similar stuff for LDI, but then you can use BC, to control the end of your outer loop, by adding the total count for all columns, since LDI still decrements BC
Last edited by RMartins on Thu Jan 04, 2018 9:50 pm, edited 1 time in total.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Scrolling the attribute memory sideways

Post by Ast A. Moore »

Well, you could read data byte by byte and place it on the screen incrementing the address until you reach the right edge. Then repeat, but start placing it on the screen one byte to the left; increment the address, read next data byte, check for the edge; etc. Yes, you’ll have to do it line by line (well, row by row), and yes, the entire screen will take a bit of time to update.

On the upside, though, moving one cell left or right inside the attributes area only requires that you increment/decrement the low byte of the address, which is 2 T states quicker than incrementing/decrementing a register pair. This may not seem like much, but it adds up quickly over the span of the entire screen.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
RMartins
Manic Miner
Posts: 776
Joined: Thu Nov 16, 2017 3:26 pm

Re: Scrolling the attribute memory sideways

Post by RMartins »

Ast A. Moore wrote: Thu Jan 04, 2018 9:46 pm ...
On the upside, though, moving one cell left or right inside the attributes area only requires that you increment/decrement the low byte of the address, which is 2 T states quicker than incrementing/decrementing a register pair. This may not seem like much, but it adds up quickly over the span of the entire screen.
I was just re-reading this, and that sentence is not entirely true.
Attributes are 32x24 = 768

And increment/decrement only the lower part, is only valid if we process each line individually, and if we are not in the frontier (at the edge) of one of the 1/3 of the screen, since 768/256 = 3.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Scrolling the attribute memory sideways

Post by Ast A. Moore »

RMartins wrote: Mon Jul 29, 2019 2:51 pm only valid if we process each line individually
Yup. I explicitly say that in my post. ;)
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Einar Saukas
Bugaboo
Posts: 3070
Joined: Wed Nov 15, 2017 2:48 pm

Re: Scrolling the attribute memory sideways

Post by Einar Saukas »

Not tested:

Code: Select all

    LD A, attribute-value
    LD HL, $5801
    LD DE, $5800
    LD BC, 24*(31+256)
loop:
    REPT 31
      LDI
    ENDR
    LD (DE), A
    INC L
    INC DE
    DJNZ loop
    RET
Post Reply