Code optimization, an example
Posted: Tue May 14, 2019 9:16 pm
Suppose you want to read the keyboard key by key and know what key is pressed
You can use this code to get that result.
Now these 17 bytes looks as the shortest code, which we need in 1K, but is it?
Indirectly we do a double read from the A-register from (lastk).
The first is clear, the second is the LD A,C where C was loaded with (lastk).
Can we somehow get rid of this double read and so shorten the code?
First we alter the code without deleting any commands. This will give as a method how we can eliminate the double
read in the end.
As you see we moved line 3 a bit down. The code is still working although BC is now loaded in the first loop too.
The second read is inside the first loop too. This makes the first read redundant. We can alter the code now in
We know that when (last) holds 255 no key is pressed. Only 255 signals a nokeypressed. What we do
with the XOR A is we simulate a keypress. The first INC A will signal a keypressed, then we read the actual keyboard in BC
We copy the result in A. The code evaluates the previous keypress (a key pressed).
The code will wait for a key up. Now at some moment we read nokeypressed, this will be found and the program comes in the second
loop. This time the test on keydown is done. While nokey is pressed the program will no wait for a keypress
and evaluate the key when pressed. We saved 2 bytes
We set A to 0 to enter the routine. When you know that A will never hold 255 on entry of this routine you can even win another byte.
The XOR A is not needed. The first INC A will never go from 255 to 0. We know that A doesn't hold 255.
We have optimized the inputroutine.
You can use this code to get that result.
Code: Select all
wup ld a,(lastk) ; 03
inc a ; 04 test keyup
jr nz,wup ; 06
wdown ld bc,(lastk) ; 10 bc needs IN and IN-result from lastk to translate
ld a,c ; 11
inc a ; 12 test keydown, no key when A holds 255
jr z,down ; 14
call #7bd ; 17 translate IN and result to ASCII in A (0..39)
Indirectly we do a double read from the A-register from (lastk).
The first is clear, the second is the LD A,C where C was loaded with (lastk).
Can we somehow get rid of this double read and so shorten the code?
First we alter the code without deleting any commands. This will give as a method how we can eliminate the double
read in the end.
Code: Select all
wup ld a,(lastk) ; 03
inc a ; 04 test keyup
wdown ld bc,(lastk) ; 08 bc needs IN and IN-result from lastk to translate
ld a,c ; 09
jr nz,wup ; 11
inc a ; 12 test keydown, no key when A holds 255
jr z,down ; 14
call #7bd ; 17 translate IN and result to ASCII in A (0..39)
The second read is inside the first loop too. This makes the first read redundant. We can alter the code now in
Code: Select all
xor a ; 01 extra command needed to stay in first loop
wup inc a ; 02 test keyup
wdown ld bc,(lastk) ; 06 bc needs IN and IN-result from lastk to translate
ld a,c ; 07
jr nz,wup ; 09
inc a ; 10 test keydown, no key when A holds 255
jr z,down ; 12
call #7bd ; 15 translate IN and result to ASCII in A (0..39)
with the XOR A is we simulate a keypress. The first INC A will signal a keypressed, then we read the actual keyboard in BC
We copy the result in A. The code evaluates the previous keypress (a key pressed).
The code will wait for a key up. Now at some moment we read nokeypressed, this will be found and the program comes in the second
loop. This time the test on keydown is done. While nokey is pressed the program will no wait for a keypress
and evaluate the key when pressed. We saved 2 bytes
We set A to 0 to enter the routine. When you know that A will never hold 255 on entry of this routine you can even win another byte.
Code: Select all
wup inc a ; 01 test keyup
wdown ld bc,(lastk) ; 05 bc needs IN and IN-result from lastk to translate
ld a,c ; 06
jr nz,wup ; 08
inc a ; 09 test keydown, no key when A holds 255
jr z,down ; 11
call #7bd ; 14 translate IN and result to ASCII in A (0..39)
We have optimized the inputroutine.