Hi all, I was writing a binary search algorithm and since I cannot test it just yet, I was hoping people might be able to spot any problems or optimizations. My intent was to optimize this for the eZ80. Feel free to offer suggestions that include instructions from the eZ80 instruction set.
First, the input is a "key" to search for. It is zero terminated, so it may be something like .db "Hello",0
The table to look for it in is comprised of indices to the actual data. So the table might look like:
table_start:
.dw (table_end-table_start)/2-1
.dw expr0
.dw expr1
.dw expr2
...
.dw exprlast
.table_end:
expr0: .db "AAAaaa",0
;other data
expr1: .db "BBBbbb",0
;other data
...
The actual strings do not need to be in order, just the order in which they are indexed. The strings must be zero-terminated, too.
So, passing a pointer to the keyword in DE and the table start in HL:
BinarySearch:
;expected in Z80 mode
ld (key_ptr),de
ld e,(hl) \ inc hl
ld d,(hl) \ inc hl
ld b,h \ ld c,l
ld (max),de
or a \ sbc hl,hl \ ld (min),hl
.loop0:
;average max (de) and min (hl) with truncation
add hl,de \ rr h \ rr l
push hl
;2 bytes per index, and BC points to the base of the table
add hl,hl \ add hl,bc
;load the pointer to the expression to compare to in HL
ld hl,(hl) \ ld de,(key_ptr)
.loop1:
ld a,(de) \ cp (hl) \ jr c,less
;if they are the same, make sure to test if the bytes are zero (termination)
jr z,$+4
jr nc,more
;if a != 0 then the string is not terminated, but we don't know which string is "bigger" so keep looping
inc de \ inc hl \ or a \ jr nz,loop1
.match:
pop bc \ ret
.less:
; "or a" is just to reset the c flag for future code
;if [index]<key, add 1 to the average of min and max and set that as the new min
or a \ pop hl \ inc hl \ ld (min),hl \ ld de,(max) \ jr loop0_end
.more:
;[index]>key set max to the average of max and min.
pop de \ ld (max),de \ ld hl,(min)
.loop0_end:
sbc hl,de \ add hl,de \ jr nz,loop0
or 1
ret
The output should have z flag if a match was found, else nz. In the case of a match being found, BC is the index number, DE points to the byte after the key, HL points to the byte after the match. If no match was found, HL and DE point to the index in front of where the match should have been and BC points to the table data start. In any case, the c flag is reset.