Finding LSB in a register
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Finding LSB in a register
Hey folks, I'm back!
I'm currently shaving more bytes off the Chess display engine (it got down to 589 bytes last year!). A few fresh ideas to explore after a break from it. I've speeded it up a little so far, which is nice, but I've an idea that requires to find the LSB within HL. Is there a quick method anyone knows of?
Ta.
I'm currently shaving more bytes off the Chess display engine (it got down to 589 bytes last year!). A few fresh ideas to explore after a break from it. I've speeded it up a little so far, which is nice, but I've an idea that requires to find the LSB within HL. Is there a quick method anyone knows of?
Ta.
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
I should've also added that I want to isolate that BIT and set all the bits to the Right of it ideally.
I know that you could just DEC HL which will set all to the right, but clearing the rest, is there an easy way? 8 bit maths is easy, 16 bit less so.
I know that you could just DEC HL which will set all to the right, but clearing the rest, is there an easy way? 8 bit maths is easy, 16 bit less so.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Finding LSB in a register
Not sure if this is fast enough for you, but I came up with this:
The DJNZ loop can be replaced with a simple jump, if you’re positive that at least one bit in HL is set. As a bonus, though, B will hold the position of the first set bit counting from the left (if you need it).
Code: Select all
;HL holds the value for testing
ld de,0
push hl
ld b,16
l1 rrc h ;mind the C in RRC here.
rr l
jr c,p1
ccf
rl e
rl d
djnz l1
p1
pop hl
add hl,de
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.
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.
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
Interesting. Whichever way I've tried so far, its coming out a lot more complicated than I'd originally imagined.
Basically this is an auto masking excercise, where I want to create a mask by using the LSB as the marker for where to create the mask, so for instance;
if HL were;
00000101 11000000 then bit 6 of L is the marker and would make a mask say in BC of 00000000 00111111
does that make sense?
It does need to be small, and speed isn't massively important, more the smallness!
Basically this is an auto masking excercise, where I want to create a mask by using the LSB as the marker for where to create the mask, so for instance;
if HL were;
00000101 11000000 then bit 6 of L is the marker and would make a mask say in BC of 00000000 00111111
does that make sense?
It does need to be small, and speed isn't massively important, more the smallness!
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Finding LSB in a register
In that case, my routine can be modified to save one byte: replace LD B,16 with LD B,D or LD B,E. You’ll end up with having to LD A,B/NEG/INC A to get the first set bit position (now counting from the right) in A.arkannoyed wrote: ↑Thu Jan 17, 2019 1:26 pm It does need to be small, and speed isn't massively important, more the smallness!
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.
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.
- Metalbrain
- Microbot
- Posts: 107
- Joined: Thu Feb 15, 2018 2:14 pm
Re: Finding LSB in a register
What about this?
Code: Select all
;Input: DE = original value
;Output: HL = mask
ld hl,0
and a
nextbit: adc hl,hl
ret c
rr d
rr e
ccf
jr c,nextbit
ret
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
Oooh, yes. Now the RET C won't be needed, as theres no need for error protection (I think thats what its there for?), though I will need to push and pop DE, but that just might work. Off to test thanks!
- Metalbrain
- Microbot
- Posts: 107
- Joined: Thu Feb 15, 2018 2:14 pm
Re: Finding LSB in a register
I was about to post that the RET C could be removed, but it's not for error protection, just to exit earlier in the case of initial value being 0arkannoyed wrote: ↑Thu Jan 17, 2019 3:02 pm Oooh, yes. Now the RET C won't be needed, as theres no need for error protection (I think thats what its there for?), though I will need to push and pop DE, but that just might work. Off to test thanks!
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Finding LSB in a register
Oh, I see. You only want the mask, not the already masked value. Sorry, I didn’t get that from your initial posts. Disregard my code then.
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.
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.
Re: Finding LSB in a register
No loops:
ld bc,hl
dec bc
ld a,h
xor 255
and b
ld b,a
ld a,l
xor 255
and c
ld c,a
Just uses HL & BC
ld bc,hl
dec bc
ld a,h
xor 255
and b
ld b,a
ld a,l
xor 255
and c
ld c,a
Just uses HL & BC
Re: Finding LSB in a register
Mine is 13 bytes (checked with www.asm80.com, which is awesome!).
Metalbrain's is 12 bytes, if you remove the ret c and replace ld hl,0 with xor h/xor l.
Metalbrain's is 12 bytes, if you remove the ret c and replace ld hl,0 with xor h/xor l.
Re: Finding LSB in a register
Could you replace XOR 255 with CPL and get it down to 11 bytes?
Re: Finding LSB in a register
Yep, that works
Didn't know about that instruction!
Didn't know about that instruction!
Re: Finding LSB in a register
If you're doing regular AND-then-OR masking, you can just use OR B instead of CPL: AND B (and the same for C) as it doesn't matter what the mask is when the pixel value is set. That would get it down to 9 bytes.
(EDIT: Actually in that case all you need to create the mask is a single DEC instruction. So this method only requires one byte.)
Maybe other types of masking would work, for instance OR for the mask and then XOR for the sprite. Are you doing the same thing to create a mask on the left using the MSB?
(EDIT: Actually in that case all you need to create the mask is a single DEC instruction. So this method only requires one byte.)
Maybe other types of masking would work, for instance OR for the mask and then XOR for the sprite. Are you doing the same thing to create a mask on the left using the MSB?
- Metalbrain
- Microbot
- Posts: 107
- Joined: Thu Feb 15, 2018 2:14 pm
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
Wow, some great ideas, and it certainly looks as if the 8 bit logic methods will win. I'll have a go with some ideas later and see what works best.
Lots of re-designing to do to make the printing byte-wise work as opposed to bit-wise, which is how the Chess pieces are done currently. The speed improvement will be huge though, and hopefully might lose a few bytes as well as a bonus!
Lots of re-designing to do to make the printing byte-wise work as opposed to bit-wise, which is how the Chess pieces are done currently. The speed improvement will be huge though, and hopefully might lose a few bytes as well as a bonus!
- lister_of_smeg
- Microbot
- Posts: 145
- Joined: Thu Nov 16, 2017 1:44 pm
Re: Finding LSB in a register
ld bc,hl isn't a valid z80 instruction
Last edited by lister_of_smeg on Fri Jan 18, 2019 9:48 am, edited 2 times in total.
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
yes, but ld B,H and ld C,L are, which does the same thing.
- arkannoyed
- Manic Miner
- Posts: 436
- Joined: Mon Feb 05, 2018 9:56 am
- Location: Northamptonshire
Re: Finding LSB in a register
Seems to almost do what it needs to. The only thing left that I should've mentioned before is that it needs to RESet the LSB in HL (the data register).
So whereas maybe HL=05c0h, after creating the mask, bit 6 of L needs to be cleared, giving the result HL=0580h.
Does that make sense?
So whereas maybe HL=05c0h, after creating the mask, bit 6 of L needs to be cleared, giving the result HL=0580h.
Does that make sense?
Re: Finding LSB in a register
Wow, apparently asm80.com is too clever for its own good - it automatically converted ld bc,hl to ld b,h/ld c,l!arkannoyed wrote: ↑Fri Jan 18, 2019 9:46 am yes, but ld B,H and ld C,L are, which does the same thing.
- lister_of_smeg
- Microbot
- Posts: 145
- Joined: Thu Nov 16, 2017 1:44 pm
Re: Finding LSB in a register
This any good?arkannoyed wrote: ↑Fri Jan 18, 2019 2:01 pm Seems to almost do what it needs to. The only thing left that I should've mentioned before is that it needs to RESet the LSB in HL (the data register).
So whereas maybe HL=05c0h, after creating the mask, bit 6 of L needs to be cleared, giving the result HL=0580h.
Does that make sense?
Code: Select all
ld d, h
ld e, l
dec de
ld a, d
xor h
ld d, a
cpl
and h
ld h, a
ld a, e
xor l
ld e, a
cpl
and l
ld l, a
rr d
rr e