?login_element?

Subversion Repositories NedoOS

Rev

Rev 1485 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  ifndef included_strtox
  2.  define included_strtox
  3.  include "../common/mov.asm"
  4.  include "../common/pushpop.asm"
  5.  include "routines/sla64.asm"
  6.  ;include "routines/ascii_to_uint8.asm"
  7.  include "../common/ascii_to_uint8.asm"
  8.  include "tables.asm"
  9.  include "constantsx.asm"
  10.  include "xmul.asm"
  11.  
  12.  ifndef char_TI_TOK
  13. char_NEG='-';$1A
  14. char_ENG='e';$1B
  15. char_DEC='.'
  16.  else
  17. ;otherwise, char_TI_CHR
  18. char_NEG=$B0
  19. char_ENG=$3B
  20. char_DEC=$3A
  21.  endif
  22.  
  23. ;#ifndef strtox_ptr
  24. strtox_ptr=xOP1+25 ;FIXME
  25. ;#endif
  26. strtox:
  27. ;;#Routines/Extended Precision
  28. ;;Inputs:
  29. ;;  HL points to the string
  30. ;;  BC points to where the float is output
  31. ;;Output:
  32. ;;  xOP1+25 is the pointer to the end of the string
  33. ;;Destroys:
  34. ;;  25 bytes at xOP1 ?
  35.   call pushpop
  36.   push bc
  37.  
  38. ;Check if there is a negative sign.
  39. ;   Save for later
  40. ;   Advance ptr
  41.   ld a,(hl)
  42.   sub char_NEG
  43.   sub 1
  44.   push af
  45.   jr nc,$+3;+_
  46.   inc hl
  47. ;_:
  48.   call strtox_sub0
  49. TItox_stepin:
  50. ;bc=exp-1
  51. ;Gotta multiply the number at (xOP1) by 2^64
  52.  
  53. ;Save the location of the ending byte of the string
  54.   ld (strtox_ptr),hl
  55.   ld d,100
  56.   call xOP1_xtimes_256
  57.   ld (xOP1+17),a
  58.   call xOP1_xtimes_256
  59.   ld (xOP1+16),a
  60.   call xOP1_xtimes_256
  61.   ld (xOP1+15),a
  62.   call xOP1_xtimes_256
  63.   ld (xOP1+14),a
  64.   call xOP1_xtimes_256
  65.   ld (xOP1+13),a
  66.   call xOP1_xtimes_256
  67.   ld (xOP1+12),a
  68.   call xOP1_xtimes_256
  69.   ld (xOP1+11),a
  70.   call xOP1_xtimes_256
  71.   ld (xOP1+10),a
  72.   call xOP1_xtimes_256
  73.   ld (xOP1+9),a
  74.  
  75. ;Now xOP1+9 is a 9-byte mantissa that needs to be normalized
  76. ;
  77.   ld hl,(xOP1+10)
  78.   or h
  79.   or l
  80.   ld hl,(xOP1+12)
  81.   or l
  82.   or h
  83.   ld hl,(xOP1+14)
  84.   or h
  85.   or l
  86.   ld hl,(xOP1+16)
  87.   or l
  88.   or h
  89.   jp z,strtox_zero-1
  90.   pop af
  91.   push bc
  92.   ld bc,$7FFF
  93.   rr b
  94.   ld a,h
  95.   or a
  96.   jp m,strtox_normed
  97.   ;Will need to iterate at most three times
  98. strtox_norm0;_:
  99.   dec bc
  100.   ld hl,xOP1+9
  101.   call sla64
  102.   adc a,a
  103.   jp p,strtox_norm0;-_
  104. strtox_normed:
  105. ;Move the number to xOP1
  106.   ld hl,(xOP1+10)
  107.   ld (xOP1),hl
  108.   ld hl,(xOP1+12)
  109.   ld (xOP1+2),hl
  110.   ld hl,(xOP1+14)
  111.   ld (xOP1+4),hl
  112.   ld hl,(xOP1+16)
  113.   ld h,a
  114.   ld (xOP1+6),hl
  115.   ld (xOP1+8),bc
  116.   pop bc
  117. ;now (xOP1) is our number, need to multiply by power of 10!
  118. ;Power of 10 is stored in BC, need to put in A first
  119.   xor a
  120.   or b;sub b ;Alone Coder
  121.   ld de,pow10table+120
  122.   jp p,strtox_powp;+_
  123.   xor a : sub c : ld c,a
  124.   sbc a,a : sub b : ld b,a
  125.   ld de,pown10table+120
  126. strtox_powp;_:
  127.   ld hl,xOP1
  128. strtox_muls0;_:
  129.   srl b
  130.   rr c
  131.   call strtox_mul;+_
  132.   ld a,b
  133.   or c
  134.   jr nz,strtox_muls0;-_
  135.   pop de
  136.   jp mov10
  137. strtox_mul;_:
  138.   push bc
  139.   ld b,h
  140.   ld c,l
  141.   call c,xmul
  142.   pop bc
  143.   ld a,e
  144.   sub 10
  145.   ld e,a
  146.   ret nc
  147.   dec d
  148.   ret
  149.  
  150. strtox_sub00;_:
  151.   inc hl
  152. strtox_sub0:
  153. ;Skip all leading zeroes
  154.   ld a,(hl)
  155.   cp '0'
  156.   jr z,strtox_sub00;-_
  157.  
  158. ;Set exponent to 0
  159.   ld bc,0
  160. ;Check if the next char is char_DEC
  161.   sub char_DEC
  162.   or a
  163.   jr nz,strtox_skipzeroesq;+_
  164.   inc c
  165. ;Get rid of zeroes
  166.   ld a,'0'
  167.   cpi
  168.   jr z,$-2
  169.   scf
  170. strtox_skipzeroesq;_:
  171. ;Now we read in the next 20 digits
  172.   ld de,xOP1+9
  173.   push bc
  174.   call ascii_to_uint8
  175.   call ascii_to_uint8
  176.   call ascii_to_uint8
  177.   call ascii_to_uint8
  178.   call ascii_to_uint8
  179.   call ascii_to_uint8
  180.   call ascii_to_uint8
  181.   call ascii_to_uint8
  182.   call ascii_to_uint8
  183.   call ascii_to_uint8
  184.   ld a,b
  185.   pop bc
  186.   push af
  187.   add a,c
  188.   ld c,a
  189.   jr nc,$+3
  190.   inc b
  191.   pop af
  192. ;Now `xOP1` holds the 10-digit base-100 number.
  193. ;BC is the exponent
  194. ;if carry flag is set, just need to get rid of remaining digits
  195. ;Otherwise, need to get rid of remaining digits, while incrementing the exponent
  196.   call skipdigits
  197. ;Now check for engineering `E` to modify the exponent
  198.   cp char_ENG-'0'
  199.   ret nz
  200. str_xeng_exp:
  201.   ld de,0
  202.   inc hl
  203.   ld a,(hl)
  204.   cp char_NEG    ;negative exponent?
  205.   push af
  206.   jr nz,$+3
  207.   inc hl
  208. str_xeng_exp0;_:
  209.   ld a,(hl)
  210.   sub 3Ah
  211.   add a,10
  212.   jr nc,str_xeng_expq;+_
  213.   inc hl
  214.   push hl
  215.   ld h,d
  216.   ld l,e
  217.   add hl,hl
  218.   add hl,hl
  219.   add hl,de
  220.   add hl,hl
  221.   add a,l
  222.   ld l,a
  223.   ex de,hl
  224.   pop hl
  225.   jr str_xeng_exp0;-_
  226. str_xeng_expq;_:
  227.   ld a,d
  228.   cp 20
  229.   jp nc,xeng_overflow
  230.   pop af
  231.   ld a,c
  232.   jr nz,str_xeng_add;+_
  233.   sub e
  234.   ld c,a
  235.   ld a,b
  236.   sbc a,d
  237.   ld b,a
  238.   ret
  239. str_xeng_add;_:
  240.   add a,e
  241.   ld c,a
  242.   ld a,d
  243.   adc a,b
  244.   ld b,a
  245.   ret
  246.  
  247. xOP1_xtimes_256:
  248.   push bc
  249.   ld e,8
  250. xOP1_xtimes_2560;_:
  251.   or a
  252.   ld hl,xOP1
  253.   call xOP1_xtimes_256pp;+_
  254.   call xOP1_xtimes_256pp;+_ ;итого 10 раз xOP1_xtimes_sub
  255.   rl c
  256.   dec e
  257.   jr nz,xOP1_xtimes_2560;-_
  258.   ld a,c
  259.   pop bc
  260.   ret
  261. xOP1_xtimes_256pp;_:
  262.   call xOP1_xtimes_sub
  263.   call xOP1_xtimes_sub
  264.   call xOP1_xtimes_sub
  265.   call xOP1_xtimes_sub
  266. xOP1_xtimes_sub:
  267.   ld a,(hl)
  268.   rla
  269.   cp d
  270.   jr c,$+2+1;+_
  271.   sub d
  272. ;_:
  273.   ld (hl),a
  274.   inc hl
  275.   ccf
  276.   ret
  277. xeng_overflow:
  278.   pop af
  279.   jr nz,strtox_inf
  280.   pop af
  281. strtox_zero:
  282.   ld hl,xconst_0
  283.   pop de
  284.   jp mov10
  285. strtox_inf:
  286. ;return inf
  287.   pop af
  288.   ld hl,xconst_INF
  289.   jr nc,$+2+3;+_
  290.   ld hl,xconst_nINF
  291. ;_:
  292.   pop de
  293.   jp mov10
  294.  
  295.  
  296. skipdigits:
  297.   jr nc,skipdigits_nodec
  298.   db $FE     ; start of `cp *` to skip the `inc hl`
  299. skipdigits0;_:
  300.   inc hl
  301.   ld a,(hl)
  302.   sub '0'
  303.   cp 10
  304.   jr c,skipdigits0;-_
  305.   ret
  306.  
  307. skipdigits_nodec0;_:
  308.   inc hl
  309.   inc bc
  310. skipdigits_nodec:
  311.   ld a,(hl)
  312.   sub '0'
  313.   cp 10
  314.   jr c,skipdigits_nodec0;-_
  315.   ret
  316.  endif
  317.