;these are some search and compare routines i've developed.i just thought ;that since many people use algorithms similar to this, you could save a bit of time. ;each one specifies the necessaryinputs and outputs. the first one is probably ;useful in final programs, while the others are more likely to be useful in development. ;if you use any of them, please give proper credit. ; ;not that a few addresses are used for scratch space in these routines, and it is not ;necessary to include them as .db's and .dw's. you can simply give them equ's ;for _textshadow or any other scratch space you'd like. i just included them as ;the way they are in case you're using the other scratch space for something ;else. ; ;-Jonah Cohen ;this one is from On86. mostly, i just changed the comments. ;what it does is compare to data lists of the same size and ;goes to one address if they're equal, and another if they ;aren't equal. compare_data: ;should be jumped to, not called! ;input: ; hl points to one datalist ; de points to another datalist ; b is length of lists ; top 2 bytes on stack=where to go if not equal ; ix=where to go if equal ;output: ; if data is equal, jump to (ix) ; if data is not equal, jump to address on stack compare_loop: ld a,(de) ;get first data cp (hl) ;compare to other data ret nz ;if they're different, go to different local inc de ;move to next byte inc hl djnz compare_loop ;run loop until b=0 ;data equal pop hl ;get rid of other location jp (ix) ;jump to (ix) ;this one will search the entire contents of loaded memory for a specific ;list of data. it does not handle paging, however. note that it ;uses the above routine, slightly modified. search_for_data: ;search for the data pointed to by de in the ti-86 memory ;input: ; de=pointer to datalist ; a=size of list ;output: ; hl=pointer to beginning of datalist in memory ; if datalist not found, carry flag set ld hl,$0000 ;start at beggining of memory push hl ;save address ld (data),de ;save data ld (size),a ;save size jr first_try ;skip initial step next_search: or a ;reset the carry flag pop hl ;retrieve address inc hl ;increment ret c ;if overflow, return. all memory has been searched. push hl ;save changed address first_try: ld a,(size) ;retrieve size ld b,a ;store in b ld de,(data) ;retrieve data compare_loop: ld a,(de) ;get first data cp (hl) ;compare to other data jr nz,next_search ;if they're different, ;increment address and try again inc de ;move to next byte inc hl djnz compare_loop ;repeat until every byte has been compared ;data equal pop hl ;retrieve address (before increments) ret ;return. hl=pointer to data. data: .dw 0 size: .db 0 ;this one searches the entire contents of memory, including all pages, ;for a specified datalist. this is a modification of the above program. ;much more complicated, though. ;the routines at the end, search_page and cphlde can be used on their own, ;but they're necessary for this routine ;note that de must either be in the range $0000-$3fff or $c000-$ffff search_memory: ;search for the data pointed to by de in memory. ;input: ; de=pointer to datalist ; a=size of list (0-255) ;output: ; a=ram/rom page ; hl=pointer to beginning of datalist in memory when page swapped ; (port 5 for rom, port 6 for ram) ; if datalist not found, carry flag set ld (save_size),a ;save size ld (save_pointer),de ;save data xor a ;start with rom page 0 ld (page),a ;store page rom_search: out (5),a ;load rom page ld de,(save_pointer) ;retrieve data ld a,(save_size) ;retrieve size ld hl,$4000 ;start of rom page call search_page ;search page jr nc,data_found_rom ;if carry flag not set, then data was found. ld hl,page ;point to rom page inc (hl) ;move to next page ld a,(hl) ;a=rom page cp 16 ;if rom page=16, then stop. ;0-15 are valid pages jr nz,rom_search ;otherwise, repeat search with next page ld a,$40 ;start with ram page 0 (bit 6 set to define ;ram page, reset to define rom page) ld (page),a ;store page ram_search: out (6),a ;load ram page ld de,(save_pointer) ;retrieve data ld a,(save_size) ;retrieve size ld hl,$8000 ;start of ram page call search_page ;search page jr nc,data_found_ram ;check if data found ld hl,page ;point to ram page inc (hl) ;move to next page ld a,(hl) ;a=ram page cp $48 ;if ram page=$48, then stop. $40-$47 are valid pages jr nz,ram_search ;otherwise, repeat search with next page call restore_pages ;restore original pages scf ;data not found. set carry flag. ret ;return restore_pages: push af ;save register ld a,13 ;default rom page out (5),a ;restore ld a,$41 ;default ram page out (6),a ;restore pop af ;retrieve register or a ;reset carry flag ret ;return data_found_rom: in a,(5) ;retrieve rom page jr restore_pages ;restore original pages, then return data_found_ram: in a,(6) ;retrieve ram page jr restore_pages ;restore original pages, then return save_size: .db 0 save_pointer: .dw 0 page: .db 0 ;searches an entire page beginning at hl ;looks for the list of data pointed to by de, with length a search_page: ;input: ; hl=beginning of page ; de=pointer to data (0-255) ; a=size of data ;output: ; hl=pointer to beginning of datalist in memory ; if datalist not found, carry flag set ld (size),a ;save size ld (data),de ;save data push hl ;save start of page ld de,$3fff ;size of page-1 add hl,de ;hl=end of page ld c,a ;get size of data ld b,0 ;clear b or a ;reset carry flag sbc hl,bc ;subtract ld (stop_value),hl ;store pop hl ;retrieve starting address push hl ;save again jr first_try ;skip initial steps next_search: pop hl ;retrieve address inc hl ;increment push hl ;save changed address ld de,(stop_value) ;retrieve stop value call cphlde ;check if it has found it jr z,failed ;if reached end of page, quit first_try: ld a,(size) ;retrieve size ld b,a ;store in b ld de,(data) ;retrieve data compare_loop: ld a,(de) ;get first data cp (hl) ;compare to other data jr nz,next_search ;if they're different, ;increment address and try again inc de ;move to next byte inc hl djnz compare_loop ;repeat until every byte has been compared ;data equal pop hl ;retrieve address (before increments) or a ;reset carry flag ret ;return. hl=pointer to data. failed: ;failed to find data pop hl ;remove address from stack scf ;set carry flag ret ;return cphlde: ;compares hl to de ;already in rom, but since we're swapping pages, can't ;rely on it being there. this is identical routine push hl ;save hl or a ;reset carry flag sbc hl,de ;subtract de from hl and store in hl pop hl ;restore hl (all that was affected by subtraction was flags) ret ;return data: .dw 0 size: .db 0 stop_value: .dw 0