; findbit.s
%pragma once
bits 16

%define trybyte(x,y) _trybyte x,y ;; try :: bool val -> int8 byte -> bool isfound
%macro _trybyte 2
    mov ax,0x00ff
    test %1,0x01
    jnz %%nzero
 %%zero:
    not %2
 %%nzero:
    test %2,al
    jz %%nfound
 %%found:
    clc
    jmp %%end
 %%nfound:
    stc
 %%end:
%endmacro

; Findbit :: bitmap *seg:addr -> int16 size -> bool val -> int16 bitno
Findbit:
    enter 0,0
    push bx
    push cx
    push dx
    push si
    push di
    chseg(es,[bp+4])

    mov si,[bp+6]       ; si=bitmap addr
    mov cx,[bp+8]       ; cx=size
    mov bx,[bp+10]      ; bl=val

    xor dx,dx
    xor di,di
 .loop:
    mov byte dl,es:[si] ; dl=byte
    ; cf =
        trybyte(bl,dl)
    jc .next
.found:
    xor dx,dx
    mov cx,0x0008
    mov ax,di
    mul cx          ; ax=startbit
    mov si,[bp+6]   ; si=orig bitmap addr
    push ax
    push bx
    push si
    call trybit     ; ax=bitno (subroutine cannot fail at this point)
    add sp,0x0006
    jmp .ok

 .next:
    inc si
    inc di
    loop .loop
 .err:
    xor ax,ax
    stc
    jmp .end
 .ok:
    clc
 .end:
    sret(es)
    pop di
    pop si
    pop dx
    pop cx
    pop bx

    leave
    ret

; trybit :: bitmap *addr -> bool val -> int16 startbit -> int16 bitno
trybit:
    enter 0,0
    push bx
    push cx
    push dx
    push si

    mov si,[bp+4]       ; si=bitmap addr
    mov dx,[bp+6]       ; dx=val
    mov bx,[bp+8]       ; bx=startbit

    xor ax,ax
    mov cx,0x0008
 .loop:
    ; al=
        getbit(es,si,bx)
    cmp byte al,dl
    je .done
 .next:
    inc bx
    loop .loop
 .done:
    mov ax,bx
    pop si
    pop dx
    pop cx
    pop bx

    clc
    leave
    ret
