News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Using Index registers

Started by IndyUK, 21:43, 15 May 21

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

IndyUK

Hi folks,

Wanted to get peoples opinion on the use of the Index registers. Whenever I read any tutorial on Z80 assembly, I always find that somewhere in the index register section there is always a suggestion of not using them because they are slow. It is true to say they are slow (based on the t-states tests I've done) but, I think they are very convient. I have been experimenting with creating array types of objects (probably their primary use) and really tried to void using them but, just couldn't avoid them altogether. My code got messy and lengthy and to be honest I lost interest in continuing with the project.

So my question really is - when should we use them and when not?

Looking forward to your feedback.

roudoudou

use them when you want, this is not school, neither an exam. Optimisations may come later if needed...
My pronouns are RASM and ACE

Axelay


I don't think you can really put in place 'rules' about when you should or shouldn't use them.  They are slow, so when speed is important, it is worth thinking about whether an alternative approach might be faster, but you also need to bear in mind that sometimes the alternatives might end up even slower if too much work is involved in avoiding the index registers and that will be different in each circumstance.


If speed is not important then use them as much as you like, just as roudoudou suggests.  But if speed is important, I think it's worth thinking about how not to use the index registers from the outset, I wouldn't leave it until later myself, at least for the circumstances I might use them.


Some examples of when I do use them:
- manipulating high score or other tables outside of a game loop when size, structure and speed is of no real concern
- returning from routines jumped to during stack manipulation using jp (iy) or jp (ix) because call is not available
- occasionally as a register when no alternative would be an option, or slower in that specific case.  For example, using alternate registers if the firmware is not active


For data structures in game loops, I avoid using the index registers by page aligning the data structures, thinking about what would be accessed most often together and sometimes 'interleave' parts of the data structures together so data can be processed using hl as a pointer with a minimum of 8 bit inc/dec and the occasional set/res.  This does mean the tables I use are a power of 2 in size, with occasional unused bytes, though rarely.  So when it comes to data structures, I don't think leaving optimisation until later is a good idea, as trying to not use the index registers will most likely require re-organising the data structure, and an awful lot of re-coding.

IndyUK

Hi Guys

Thanks for your valued input.

I have to say that I'm kind of in agreement with both of you, although I do favour Axeley's suggestion of not leaving all optimisation stuff till later. Sometimes it makes sense to deal with it while you're there otherwise can become a significant undertaking to do it later.
Axelay - In my test project I did use the approach of using the 16bit registers to read/write updates to my arrays (don't know why I keep calling them that as that's not really an official thing) in my main loop but, as I mentioned in my orginal post, this really got out of hand and became difficult to juggle things around. Thinking back I'd say this was probably due to me using the firmware to perform screen manipulation and of course most of the calls require passing values into the HL, DE registers, which meant having to devise ways of backing up their current values/mem location elsewhere. I think this is what prompted me to ask the question.

Incidentally, I am aware that screen manipulation can be done without resorting to the firmware but, I am currently conducting an experiment.


Anyway, thanks again guys.

BSC

#4
One use case which sprung to my mind was the Soundtrakker player. There, I had 3 instances of a struct, one for each track in the tune, corresponding to a voice of the AY, and it was very straightforward to write the player such that most of the code was not aware of *which* voice it was actually dealing with - in a way that felt very object-oriented. In theory, it would also have been very easy to extend this to 4, 5 or more voices. The objects attributes were at IX (plus some offset for each of the distinct attributes) and the parts of the player code acting on a track / voice were like the objects methods. This made it easy to think about the player and to solve specific tasks. I am pretty sure that I am not the only one thinking of and taking advantage of this relation to object-oriented programming. Yes, they are comparably slow, but that's mostly a concern when you are working on a demo or a game. For applications and such the pros outweigh the cons most of the time, I think. On top of this: it depends.
** My SID player/tracker AYAY Kaeppttn! on github **  Some CPC music and experiments ** Other music ** More music on scenestream (former nectarine) ** Some shaders ** Some Soundtrakker tunes ** Some tunes in Javascript

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

Targhan

Use Index registers as much as you can! Just be aware they are slower, which may be a problem only in a code that is called many times. But then again, this is not always true. Many, many, many codes get speed from the IX and IY power. My fastest sample replay routine use IX and IY. You can do wonderful things with them, including:
add ix,de
add ix,bc
jp (ix)

IXL and IXH are also handy as alternate counters...
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

redbox

Quote from: BSC on 14:48, 16 May 21
it was very straightforward to write the player such that most of the code was not aware of *which* voice it was actually dealing with - in a way that felt very object-oriented ... I am pretty sure that I am not the only one thinking of and taking advantage of this relation to object-oriented programming.

This.  I have also used index registers to construct pseudo "classes".

For example you can have an enemy class, i.e. baddies which have different characteristics but are all still enemies, and write one routine to deal with them all.

Powered by SMFPacks Menu Editor Mod