Page 4 of 5
Posted: Sat 11 Jun, 2005 4:28 am
by Dwedit
I've already made my multi-line text displayer used in bubble bobble...
Code: Select all
call DrawText
.dw Textlines
ret
DrawText:
ex (sp),hl
ld e,(hl)
inc hl
ld d,(hl)
inc hl
ex (sp),hl
ex de,hl
;now loop...
DrawTextLoop:
ld e,(hl)
inc hl
ld d,(hl)
inc hl
ld (pencol),de
vputs
ld a,(hl)
inc a
jr nz,DrawTextLoop
ret
Textlines:
.db 4,8,"Hello world!",0
.db 4,14,"Line 2!",0,255
Posted: Sat 01 Oct, 2005 6:30 pm
by eightythreeplus
Here is an optimization I've used many times. Suppose you have a variable that contains a letter representing the current player (like 'O' or 'X' for Tic-Tac-Toe). After each move, the variable will alternate between each of two states - $4F or $58. Here is the simplest way to make this work (assuming the current state is in register a):
Code: Select all
cp $4F
jp Z, state2
ld a, $4F
jp done
state2:
ld a, $58
done:
At the end of the code, register a contains the other value ($58 if it was $4F, or $4F if it was $58). But this code can be made shorter and faster. If you add $4F and $58, you get $A7. You can get the same results by evaluating $A7 - a. Here's how:
The code is much shorter and faster, but harder to understand what is going on (which is why you would document it :).
Posted: Sat 01 Oct, 2005 7:02 pm
by DarkerLine
Even shorter and even harder to understand:
Explanation: $4F xor $58 = $17.
Therefore $4F xor $17 = $58 and $58 xor $17 = $4F.
I don't think you can get any smaller.
Posted: Sat 01 Oct, 2005 7:36 pm
by CoBB
By the way, when you want to calculate N-A generally, never do this:
You can cut off a byte and some clocks by doing it this way:
This is because neg is practically equivalent to cpl \ inc a.
Posted: Sun 02 Oct, 2005 7:15 pm
by eightythreeplus
Ahh, so if I have two states [x] and [y] that I want to alternate between:
Code: Select all
ld a, [x]
xor [y]
ld (xor_val), a
Now if I save the value in register a, the following code will cause an alternation between the states [x] and [y] (assuming register b contains the current state):
Is this correct, DarkerLine?
Posted: Sun 02 Oct, 2005 8:02 pm
by CoBB
Yes, that's correct.
Posted: Wed 05 Oct, 2005 2:24 am
by eightythreeplus
In the expression N - a, it would actually be more efficient to use the "neg a/ add a, N" combination if N refers to a register rather than a constant. Or would there be a more efficient method in that situation?
Posted: Wed 05 Oct, 2005 2:35 am
by eightythreeplus
If you are displaying multiple strings at different locations and the strings are located sequentially in memory, you can optimize by using the de register to set curRow and curCol rather than the hl register; it does add 1 byte for each "ld (xxxx), de" instruction, but you save 3 because you don't have to repoint hl to the next string after it is "messed up" with a screen-coordinate value.
Change
Code: Select all
ld hl, $0303
ld (curRow), hl
ld hl, strPtr1
b_call(_PutS)
ld hl, $0505
ld (curRow), hl
ld hl, strPtr2
b_call(_PutS)
to
Code: Select all
ld de, $0303
ld (curRow), de
ld hl, strPtr1
b_call(_PutS)
ld de, $0505
ld (curRow), de
b_call(_PutS)
when strPtr2 follows strPtr1 in memory to save 1 byte. Another alternative would be to save and retrieve hl from the stack; this would save de from being destroyed, but it would also keep you from using stack-related operations between the two blocks of code.
Posted: Fri 24 Nov, 2006 4:16 pm
by King Harold
Flags instead of bit, whenever possible, can save around 8 T-states.
instead of:
works for sign bit since its a copy of bit 7
Posted: Fri 24 Nov, 2006 5:00 pm
by CoBB
That’s wrong. The dummy input does not use the flag register as the destination! It just sets the flags as in all other inputs and throws away the value that was read.
Posted: Fri 24 Nov, 2006 5:13 pm
by King Harold
It works though, for bit 7 anyway, its a pitty bits 5 and 3 don't have a conditional thing, they're also copies of the real value - or so the manual says.
@coBB: sorry wasn't paying much attention - corrected now
Posted: Sat 10 Mar, 2007 1:58 pm
by King Harold
You could use the flag trick for an LCD waiter:
Code: Select all
WaitLCD:
ld c,$10
-: in (c)
ret p
jr {-}
will wait until the LCD driver is ready for the next command, CPU speed etc. doesn't matter.
Posted: Sun 11 Mar, 2007 8:35 pm
by snowman_hater
instead of putting 2 nop's between setting the key group and reading from the key pad, use a 1-byte instruction that takes like 7 t-states.
Code: Select all
ld a,$fe
out (1),a
ld a,(de)
in a,(1)
Posted: Fri 23 Mar, 2007 8:50 pm
by Halifax
Gambit wrote:Normally, you would use the following to increment a variable:
But if hl is not tied up and all you do is check flags, use indirection:
Code: Select all
ld hl,var
inc (hl)
ld a,(hl) ;Optional
Does this not waste 10 tstates.I looked up the tstates for the instructions and their parameters and it shows that indirection wastes 10 tstates.
Posted: Fri 23 Mar, 2007 10:10 pm
by Liazon
Halifax wrote:Gambit wrote:Normally, you would use the following to increment a variable:
But if hl is not tied up and all you do is check flags, use indirection:
Code: Select all
ld hl,var
inc (hl)
ld a,(hl) ;Optional
Does this not waste 10 tstates.I looked up the tstates for the instructions and their parameters and it shows that indirection wastes 10 tstates.
IIRC
ld a,(var)
13 tstates
inc a
4 tstates
ld (var),a
13 tstates
total
30 tstates
ld hl,var
10 tstates
inc (hl)
11 tstates
ld a,(hl) <optional>
7 tstates
total
28 tstates
and LESS space iirc taken up. (2 bytes less)
only downside probably is the fact you've swamped 2 registers.