;=======================================================================
;   Беззнаковое умножение: DEHL = HL * BC
;-----------------------------------------------------------------------
umul:  
    lxi  d,0
    mvi  a,16
umx1: 
    dad  h
    xchg
    jnc  umx3
    dad  h
    jnc  umx2
    inx  d
umx2: 
    dad  b
    jnc  umx4
    inx  d
    jmp  umx4
umx3: 
    dad  h
    jnc  umx4
    inx  d
umx4: 
    xchg
    dcr  a
    jnz  umx1
    xchg
    ret
;=======================================================================
;
;=======================================================================
;   Беззнаковое деление: DEHL = DEHL / BC ; BC = DEHL MOD BC
;-----------------------------------------------------------------------
udiv:  
    xchg
    push h
    lxi  h,0
    mvi  a,33
umd1: 
    dcr  a
    jz   umd6
    xchg
    dad  h
    xchg
    ral
    xthl
    dad  h
    rar
    jnc  umd2
    inx  h
umd2: 
    xthl
    dad  h
    ral
    jnc  umd3
    inx  h
umd3: 
    ora  a
    rar
    push h
    push psw
    mov  a,l
    sub  c
    mov  l,a
    mov  a,h
    sbb  b
    mov  h,a
    jnc  umd4
    pop  psw
    jc   umd5
    pop  h
    jmp  umd1
umd4: 
    pop  psw
umd5: 
    inx  sp
    inx  sp
    inx  d
    jmp  umd1
umd6: 
    xchg
    mov b,d
    mov c,e
    pop d
    ret
;=======================================================================
;
;=======================================================================
; HL = BC/cos(HL) HL - градусы
;-----------------------------------------------------------------------
divcos:
    push b
    call quadrant
    mov a,e
    ani 1
    jz  @F
    mov a,e
    xri 2
    mov e,a
@@:    
    mvi a,90
    sub l
    mov l,a
    jmp divsin.cos
;=======================================================================
;
;=======================================================================
; HL = BC/sin(HL) HL - градусы
;-----------------------------------------------------------------------
divsin:
    push b
    call quadrant
    mov a,l
.cos:
    ora a
    jz  .zero
    cpi 90
    jz  .one
    push d
    lxi b,sintab2
    dad h
    dad b
    mov a,m
    inx h
    mov h,m
    mov l,a
    pop d
    pop b
    push d
    call umul
    mov l,h
    mov h,e
    pop d
    mov a,e
    sui 2
    jc @F
    inr d
@@:
    mov a,d
    ora a
    rpe    
    mov a,h
    cma
    mov h,a
    mov a,l
    cma
    mov l,a
    inx h
    ret
;-----------------------------------------------------------------------
.one:
    pop h
    ret
;-----------------------------------------------------------------------
.zero:
    lxi h,-1
    lxi d,-1
    pop b
    stc
    ret    
;-----------------------------------------------------------------------
sintab2:    ; 256/sin(a)
    dw    -1,14668, 7335, 4891, 3670, 2937, 2449, 2101, 1839, 1636
    dw  1474, 1342, 1231, 1138, 1058,  989,  929,  876,  828,  786
    dw   748,  714,  683,  655,  629,  606,  584,  564,  545,  528
    dw   512,  497,  483,  470,  458,  446,  436,  425,  416,  407
    dw   398,  390,  383,  375,  369,  362,  356,  350,  344,  339
    dw   334,  329,  325,  321,  316,  313,  309,  305,  302,  299
    dw   296,  293,  290,  287,  285,  282,  280,  278,  276,  274
    dw   272,  271,  269,  268,  266,  265,  264,  263,  262,  261
    dw   260,  259,  259,  258,  257,  257,  257,  256,  256,  256
;=======================================================================
;
;=======================================================================
; HL = cos(HL)*BC HL - градусы
;-----------------------------------------------------------------------
mulcos:
    push b
    call quadrant
    mov a,e
    ani 1
    jz  @F
    mov a,e
    xri 2
    mov e,a
@@:    
    mvi a,90
    sub l
    mov l,a
    jmp mulsin.cos
;=======================================================================
;
;=======================================================================
; HL = sin(HL)*BC HL - градусы
;-----------------------------------------------------------------------
mulsin:
    push b
    call quadrant
    mov a,l
.cos:    
    ora a
    jz  .zero
    cpi 90
    jz  .one
    push d
    lxi b,sintab
    dad h
    dad b
    mov a,m
    inx h
    mov h,m
    mov l,a
    pop d
    pop b
    push d
    call umul
    xchg
    pop d
    mov a,e
    sui 2
    jc @F
    inr d
@@:
    mov a,d
    ora a
    rpe    
    mov a,h
    cma
    mov h,a
    mov a,l
    cma
    mov l,a
    inx h
    ret
;-----------------------------------------------------------------------
.one:
    pop h
    ret
;-----------------------------------------------------------------------
.zero:
    mov h,a
    pop b
    ret    
;-----------------------------------------------------------------------
sintab:     ; 65536*sin(a)
    dw     0, 1144, 2287, 3430, 4572, 5712, 6850, 7987, 9121,10252
    dw 11380,12505,13626,14742,15855,16962,18064,19161,20252,21336
    dw 22415,23486,24550,25607,26656,27697,28729,29753,30767,31772
    dw 32768,33754,34729,35693,36647,37590,38521,39441,40348,41243
    dw 42126,42995,43852,44695,45525,46341,47143,47930,48703,49461
    dw 50203,50931,51643,52339,53020,53684,54332,54963,55578,56175
    dw 56756,57319,57865,58393,58903,59396,59870,60326,60764,61183
    dw 61584,61966,62328,62672,62997,63303,63589,63856,64104,64332
    dw 64540,64729,64898,65048,65177,65287,65376,65446,65496,65526
;=======================================================================
;
;=======================================================================
quadrant:
    lxi d,0
    mov a,h
    ora a
    jp  @F
    inr d       ; отрицательный угол
    cma  
    mov h,a
    mov a,l
    cma
    mov l,a
    inx h
@@:    
    mov a,l
    sui 67h
    mov a,h
    sbi 1
    jc  @F
    push d
    lxi b,360   ; угол больше или равен 360 градусам
    lxi d,0
    call udiv
    mov l,c
    mov h,b
    pop d
@@:
    dcr h
    mov a,l
    jnz .m255   ; угол меньше 256 градусов
    cpi 14
    jc  .m3     ; угол 256-270 градусов
    mvi a,68h   ; угол 270-360 градусов
    sub l
    mov l,a
    mvi e,3
    ret            
.m255:
    inr h
    cpi 180
    jnc .m3
    cpi 90
    rc
    mvi a,180
    sub l
    mov l,a
    mvi e,1
    ret
.m3:
    sui 180
    mov l,a
    mvi e,2
    ret    
;=======================================================================
;
;=======================================================================
;   DEHL - беззнаковое число, возврат: BC -> строка
;-----------------------------------------------------------------------
ui2a: 
    lxi b,.buffer-1
@@:    
    push b
    lxi b,10
    call udiv
    mov a,c
    ori 30h
    pop b
    stax b
    mov a,l
    ora h
    ora e
    ora d
    rz
    dcx b
    jmp @B  
;-----------------------------------------------------------------------
    rb 11
.buffer:
    db 0    
;=======================================================================
;
;=======================================================================
;   DEHL - знаковое число, возврат: BC -> строка
;-----------------------------------------------------------------------
i2a: 
    mov a,d
    ora a
    jp  ui2a
    call neg_dehl
    call ui2a
    dcx b
    mvi a,"-"
    stax b
    ret
;=======================================================================
;
;=======================================================================
;   L -> HL (знаковое)
;-----------------------------------------------------------------------
b2w:          
    mvi h,0
    mov a,l
    ora a
    rp
    dcr h
    ret
;=======================================================================
;
;=======================================================================
;   HL -> DEHL (знаковое)
;-----------------------------------------------------------------------
w2d:  
    lxi d,0
    mov a,h
    ora a
    rp
    dcx d
    ret
;=======================================================================
;
;=======================================================================
;   L -> DEHL (знаковое)
;-----------------------------------------------------------------------
b2d:  
    lxi d,0
    mov h,e
    mov a,l
    ora a
    rp
    dcr h
    dcx d
    ret
;=======================================================================
;
;=======================================================================
;   DEHL = DEHL*10
;-----------------------------------------------------------------------
mul10:
    push b
    call shl_dehl
    push h
    push d
    call shl_dehl
    call shl_dehl
    xchg
    pop b
    dad b
    xchg
    pop b
    dad b
    pop b
    rnc
    inx d
    ret
;=======================================================================
;
;=======================================================================
;   DEHL << 1
;-----------------------------------------------------------------------
shl_dehl:
    xchg
    dad h
    xchg
    dad h
    rnc
    inx d
    ret
;=======================================================================
;
;=======================================================================
;   DEHL = -DEHL
;-----------------------------------------------------------------------
neg_dehl:
    mov a,d
    cma
    mov d,a
    mov a,e
    cma
    mov e,a
    mov a,l
    cma
    mov l,a
    mov a,h
    cma
    mov h,a
    inx h
    rnc
    inx d
    ret
;=======================================================================
;
;=======================================================================
;   BC -> строка; выход: DEHL - число, BC -> последний символ 
;-----------------------------------------------------------------------
a2i: 
    lxi d,0
    lxi h,0
    xra a
    sta .sign
.lead:
    ldax b
    cpi "+"
    jz  .next
    cpi "-"
    jnz .start
    sta .sign
.next:
    inx b
    ldax b
.start:    
    sui "0" 
    jm  .done   
    cpi 10
    jnc .done
    push psw
    call mul10
    pop psw
    add l
    mov l,a
    mov a,h
    aci 0
    mov h,a
    jnc .next
    inx d
    jmp .next
.done:
    lda .sign
    ora a
    rz
    call neg_dehl
    ret
;-----------------------------------------------------------------------
.sign: db 0
;=======================================================================
;
;=======================================================================
;   A - байт, BC - байт hex
;-----------------------------------------------------------------------
i2h: 
    mov b,a
    ani 15
    cpi 10
    jc  @F
    adi 7
@@:    
    adi 30h
    mov c,a
    mov a,b
    rrc
    rrc
    rrc
    rrc
    ani 15
    cpi 10
    jc  @F
    adi 7
@@:    
    adi 30h
    mov b,a
    ret
;=======================================================================
;
;=======================================================================
;   BC -> строка; выход: DEHL - число, BC -> последний символ 
;-----------------------------------------------------------------------
h2i:
    lxi h,0
    lxi d,0
.next:
    ldax b
    sui 30h
    rc
    cpi 10
    jc  @F
    sui 7
    rc
    cpi 7
    rc
@@:
    call shl_dehl
    call shl_dehl
    call shl_dehl
    call shl_dehl
    ora l
    mov l,a
    inx b                
    jmp .next
;=======================================================================
;
;=======================================================================
;   RND -> DEHL
;-----------------------------------------------------------------------
get_rnd:
    lda .cnt
    dcr a
    jnz .lfsr
    lhld rnd
    lxi b,64525
    call umul
    push h
    push d
    lhld rnd+2
    call umul
    pop b
    dad h
    xchg
    pop h
    lxi b,1013904223 shr 16
    xchg
    dad b
    xchg
    lxi b,1013904223 and 0FFFFh
    dad b
    jnc @F
    inx d
@@:
    shld rnd
    xchg
    shld rnd+2
    mvi a,31
;-----------------------------------------------------------------------
.lfsr:
    sta .cnt
    lhld rnd+2
    xchg
    lhld rnd
    mov a,l
    xri 57h
    mov l,a
    mov a,d
    xri 80h
    mov d,a
    xchg
    dad h
    xchg
    dad h
    jnc @F
    inx d
@@:
    ral
    jnc @F
    inx h
@@:
    shld rnd
    xchg
    shld rnd+2
    xchg
    ret
;-----------------------------------------------------------------------
.cnt:   db 31
;=======================================================================
;
;=======================================================================
rnd:    dd 1
;=======================================================================
;
;=======================================================================
set_rnd:
    shld rnd
    xchg
    shld rnd+2
    xchg
    ret
;=======================================================================
;
;=======================================================================
;   HL = sqrt(HL)
;-----------------------------------------------------------------------
sqrt:
    lxi d,4000h


    ret
;=======================================================================
    
           