Code optimization, an example

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Post Reply
dr beep
Posts: 1186
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Code optimization, an example

Post by dr beep » 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.

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)
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.

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)
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

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)
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.

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)
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.

Post Reply