Finding LSB in a register

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Finding LSB in a register

Post by arkannoyed » Thu Jan 17, 2019 12:14 pm

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.
0 x

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: Finding LSB in a register

Post by arkannoyed » Thu Jan 17, 2019 12:21 pm

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.
0 x

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1195
Joined: Mon Nov 13, 2017 3:16 pm

Re: Finding LSB in a register

Post by Ast A. Moore » Thu Jan 17, 2019 1:17 pm

Not sure if this is fast enough for you, but I came up with this:

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
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).
0 x
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
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: Finding LSB in a register

Post by arkannoyed » Thu Jan 17, 2019 1:26 pm

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!
0 x

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1195
Joined: Mon Nov 13, 2017 3:16 pm

Re: Finding LSB in a register

Post by Ast A. Moore » Thu Jan 17, 2019 1:40 pm

arkannoyed wrote:
Thu Jan 17, 2019 1:26 pm
It does need to be small, and speed isn't massively important, more the smallness!
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.
0 x
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
Metalbrain
Dizzy
Posts: 81
Joined: Thu Feb 15, 2018 2:14 pm

Re: Finding LSB in a register

Post by Metalbrain » Thu Jan 17, 2019 2:19 pm

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
0 x

User avatar
arkannoyed
Manic Miner
Posts: 365
Joined: Mon Feb 05, 2018 9:56 am

Re: Finding LSB in a register

Post by arkannoyed » 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!
0 x

User avatar
Metalbrain
Dizzy
Posts: 81
Joined: Thu Feb 15, 2018 2:14 pm

Re: Finding LSB in a register

Post by Metalbrain » Thu Jan 17, 2019 3:05 pm

arkannoyed 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!
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 0
0 x

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1195
Joined: Mon Nov 13, 2017 3:16 pm

Re: Finding LSB in a register

Post by Ast A. Moore » Thu Jan 17, 2019 3:10 pm

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.
0 x
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.

Kweepa
Manic Miner
Posts: 215
Joined: Sat Feb 03, 2018 6:14 pm
Location: Austin, Texas

Re: Finding LSB in a register

Post by Kweepa » Thu Jan 17, 2019 3:49 pm

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
0 x

Post Reply