NAME Div_32_Module
;
;Eine Berechnung (LOAD_32 + DIV_16 + XX=LOW_16) dauert z.B. 1866 Zyklen
;
PUBLIC Load_32, ?Load_32?byte
PUBLIC Div_16,  ?Div_16?byte
PUBLIC Low_16
PUBLIC OP_0,OP_1,OP_2,OP_3
;
Div_32_Data  SEGMENT DATA
Div_32_Code  SEGMENT CODE
;
RSEG  Div_32_Data
?Load_32?byte:    DS 4
?Div_16?byte:     DS 2
OP_0:             DS 1
OP_1:             DS 1
OP_2:             DS 1
OP_3:             DS 1
TMP_0:            DS 1
TMP_1:            DS 1
TMP_2:            DS 1
TMP_3:            DS 1
;
RSEG  Div_32_Code


Load_32:
    ;Load all the OP registers with the value supplied
    mov    OP_3,?Load_32?byte
    mov    OP_2,?Load_32?byte + 1
    mov    OP_1,?Load_32?byte + 2
    mov    OP_0,?Load_32?byte + 3
    ret

Low_16:
    ;Return the lower 16 Bits of the OP registers
    mov    R6,OP_1
    mov    R7,OP_0
    ret

Div_16:
    ;Devides the 32 bit OP register by the value supplied
    mov    R7,#0
    mov    R6,#0               ;zero out partial remainder
    mov    TMP_0,#0
    mov    TMP_1,#0
    mov    TMP_2,#0
    mov    TMP_3,#0
    mov    R1,?Div_16?byte     ;load divisor
    mov    R0,?Div_16?byte + 1
    mov    R5,#32
    ;This begins the loop
Div_loop:
    call   Shift_D             ;Shift the dividend and return MSB in C
    mov    a,R6                ;shift carry into LSB of partial remainder
    rlc    a
    mov    R6,a
    mov    a,R7
    rlc    a
    mov    R7,a
    ; now test to see if R7:R6 >= R1:R0
    clr    c
    mov    a,R7                ;Subtract R1 from R7 to see if R1 < R7
    subb   a,R1                ; A=R7-R1, carry set if R7<R1
    jc     Cant_sub
    ; at this point R7>R1 or R7=R1
    jnz    Can_Sub             ;jump if R7>R1
    ; if R7=R1, test for R6>=R0
    clr    c
    mov    a,R6
    subb   a,R0                ; A=R6-R0, carry set if R6<R0
    jc     Cant_Sub
Can_Sub:
    ;Subtract the divisor from the partial remainder
    clr    c
    mov    a,R6
    subb   a,R0                ; A=R6-R0
    mov    R6,a
    mov    a,R7
    subb   a,R1                ; A=R7-R1-Borrow
    mov    R7,a
    setb   c                   ; shift a 1 into the quotient
    jmp    Quot
Cant_Sub:
    ;shift a 0 into the quotient
    clr    c
Quot:
    ;shift the carry bit into the quotient
    call   Shift_Q
    ; test for completion
    djnz   R5,Div_loop
    ; Now we are all done, move the TMP values back into OP
    mov    OP_0,TMP_0
    mov    OP_1,TMP_1
    mov    OP_2,TMP_2
    mov    OP_3,TMP_3
    ret

Shift_D:
    ; Shift the dividend one bit to the left and return the MSB in C
    clr    c
    mov    a,OP_0
    rlc    a
    mov    OP_0,a
    mov    a,OP_1
    rlc    a
    mov    OP_1,a
    mov    a,OP_2
    rlc    a
    mov    OP_2,a
    mov    a,OP_3
    rlc    a
    mov    OP_3,a
    ret

Shift_Q:
    ; Shift the quotient one bit to the left and shift the C into LSB
    mov    a,TMP_0
    rlc    a
    mov    TMP_0,a
    mov    a,TMP_1
    rlc    a
    mov    TMP_1,a
    mov    a,TMP_2
    rlc    a
    mov    TMP_2,a
    mov    a,TMP_3
    rlc    a
    mov    TMP_3,a
    ret

end
