?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  ifndef included_xtostr
  2.  define included_xtostr
  3.  include "../common/pushpop.asm"
  4.  include "../common/mov.asm"
  5.  include "routines/sla64.asm"
  6.  include "routines/add64.asm"
  7.  include "mul/xOP1mul10.asm"
  8.  include "../common/mul16.asm"
  9.  include "xmul.asm"
  10.  include "tables.asm"
  11.  include "../common/common_str.asm"
  12. ;fmtDigits = 97B0h
  13. ;#define EXTERNAL_FORMAT_LEN    ;Uses an external reference to get the format length
  14. ;#define EXTERNAL_FORMAT_LEN_LOC fmtDigits    ;Use for TI-OS
  15. ;#ifndef MAX_FORMAT_LEN
  16. MAX_FORMAT_LEN=19
  17. ;#endif
  18. ;#ifndef DEFAULT_FORMAT_LEN
  19. DEFAULT_FORMAT_LEN=18
  20. ;#endif
  21. ;#ifndef TOK_ENG
  22. TOK_ENG='e'
  23. ;#endif
  24. ;#ifndef TOK_NEG
  25. TOK_NEG='-';$1A
  26. ;#endif
  27.  
  28. pow10exp=xOP3+42
  29. strout=pow10exp+3
  30. xtostr:
  31.   call pushpop
  32.   push bc
  33.   call xtostrpp;+_
  34.   pop de
  35.   xor a
  36.   cp (hl)
  37.   ldi
  38.   jr nz,$-3
  39.   ret
  40. xtostrpp;_:
  41.   ld de,xOP1
  42.   call mov10
  43.   ld de,(xOP1+8)   ;this is the exponent and sign
  44.   ld hl,strout
  45.   bit 7,d
  46.   jr z,xtostr_p;+_
  47.   res 7,d
  48.   ld (xOP1+8),de   ;just making it positive
  49.   ld (hl),TOK_NEG    ;negative sign
  50.   inc hl
  51. xtostr_p;_:
  52.   ld a,d
  53.   or e
  54.   jp z,strcase
  55.  
  56. ;We should write '0' next. When rounding 9.999999... for example, not padding with a 0 will return '.' instead of '1.'
  57.   ld (hl),'0'
  58.   inc hl
  59.  
  60. ;Now we need to perform (DE-0x4000)*19728 (approximation of exponent*log10(2))
  61.   ld bc,19728
  62.   push hl       ;points to where the string is being written
  63.   call mul16    ;when analyzing timing, note that the first iteration is guaranteed to skip
  64.   ld hl,-4932
  65.   add hl,de
  66.   ld (pow10exp),hl
  67.   ld de,pown10table
  68.   jr c,xtostr_expp;+_
  69. ;the exponent is negative, need to be multiplying by 10^-exponent
  70.   xor a
  71.   sub l
  72.   ld l,a
  73.   sbc a,a
  74.   sub h
  75.   ld h,a
  76.   ld de,pow10table   ;get the table of 10^-(2^k)
  77. xtostr_expp;_:
  78.   ld bc,xOP1
  79.   add hl,hl
  80.   add hl,hl
  81.   add hl,hl
  82.   call xtostr_mul
  83.   call xtostr_mul
  84.   call xtostr_mul
  85.   call xtostr_mul
  86.   call xtostr_mul
  87.   call xtostr_mul
  88.   call xtostr_mul
  89.   call xtostr_mul
  90.   call xtostr_mul
  91.   call xtostr_mul
  92.   call xtostr_mul
  93.   call xtostr_mul
  94.   call xtostr_mul
  95. ;now the number is pretty close to a nice value
  96.   jr xtostr_inloop
  97. xtostr_inloop0;_:
  98.   call xOP1mul10
  99.   ld hl,(pow10exp)
  100.   dec hl
  101.   ld (pow10exp),hl
  102. xtostr_inloop:
  103.   ld a,(xOP1+8)
  104.   add a,a
  105.   jr c,xtostr_inloop0;-_
  106.  
  107. ;quick, convert to a fixed-point number !
  108.   rra
  109.   inc a
  110. ;  jr z,noadjustxtostr
  111.   ;number of bits to shift
  112.   ld b,a
  113.   xor a
  114.   ld (xOP1+8),a
  115. xtostr_rl0;_:
  116.   call sla64_xOP1
  117.   inc hl
  118.   rl (hl)
  119.   djnz xtostr_rl0;-_
  120. noadjustxtostr:
  121.  ifdef EXTERNAL_FORMAT_LEN
  122.   ld a,(EXTERNAL_FORMAT_LEN_LOC)
  123. ; If it is 0 or 1, reset it to the default
  124.   inc a
  125.   jr z,$+5 ;DEFAULT_FORMAT_LEN
  126.   dec a
  127.   jr nz,$+2+2;+_
  128.   ld a,DEFAULT_FORMAT_LEN
  129. ;_:
  130. ;If it is greater than the maximum length, need to set it to the max
  131.   cp MAX_FORMAT_LEN
  132.   jr c,$+2+2;+_
  133.   ld a,MAX_FORMAT_LEN
  134. ;_:
  135.   ld b,a
  136.   inc b
  137.  else
  138.   ld b,DEFAULT_FORMAT_LEN+1
  139.  endif
  140.  
  141.   ld a,(hl) ;the first digit, might be as large as twenty
  142.   pop hl
  143.   ld c,10
  144.   cp c
  145.   jr c,xtostr_tochar;+_
  146.   ld de,(pow10exp)
  147.   ld (hl),'0'-1
  148.   db $FE   ;start of `cp **` (to avoid the very first "inc de")
  149.   inc de : inc (hl) : sub c : jr nc,$-3
  150.   ld (pow10exp),de
  151.   add a,c
  152.   inc hl
  153.   dec b
  154.  ifdef EXTERNAL_FORMAT_LEN
  155.   jr z,xtostr_round
  156.  endif
  157. xtostr_tochar;_:
  158.   add a,'0'
  159.   ld (hl),a
  160.   dec b
  161.  ifdef EXTERNAL_FORMAT_LEN
  162.   jr z,xtostr_round
  163.  endif
  164. xtostr_tochar0;_:
  165.   inc hl
  166.   push hl
  167.   push bc
  168.   call xtostrmul10
  169.   pop bc
  170.   pop hl
  171.   add a,'0'
  172.   ld (hl),a
  173.   djnz xtostr_tochar0;-_
  174.  
  175. xtostr_round:
  176. ;Now let's round!
  177.   cp '5'
  178.   jr c,xtostr_round0;+_
  179.   ld a,$3A
  180.   ld (hl),'0'
  181.   dec hl
  182.   inc (hl)
  183.   cp (hl)
  184.   jr z,$-5
  185.  
  186. ;Strip trailing zeros
  187.   db $FE   ;start of `cp **` (to avoid the very first "dec hl")
  188. xtostr_round0;_:
  189.   dec hl
  190.   ld a,(hl)
  191.   cp '0'
  192.   jr z,xtostr_round0;-_
  193. ;_:
  194.   inc hl
  195.  
  196. ;Strip the leading zero if it exists (rounding may have bumped this to `1`)
  197.   ex de,hl
  198.   ld hl,strout
  199.   ld a,(hl)
  200.   cp TOK_NEG
  201.   jr nz,$+2+1+1;+_
  202.   inc hl
  203.   ld a,(hl)
  204. ;_:
  205.   cp '0'
  206.   jr nz,xtostr_no_leading_0
  207.   dec de
  208.   push de
  209.   ex de,hl
  210.   ;Now lets shift the string back 1 byte from DE+1 to DE
  211.  
  212.  ifdef EXTERNAL_FORMAT_LEN
  213.   ld a,(EXTERNAL_FORMAT_LEN_LOC)
  214. ; If it is 0 or 1, reset it to the default
  215.   inc a
  216.   jr z,$+5 ;DEFAULT_FORMAT_LEN
  217.   dec a
  218.   jr nz,$+2+2;+_
  219.   ld a,DEFAULT_FORMAT_LEN
  220. ;_:
  221. ;If it is greater than the maximum length, need to set it to the max
  222.   cp MAX_FORMAT_LEN
  223.   jr c,$+2+2;+_
  224.   ld a,MAX_FORMAT_LEN
  225. ;_:
  226.   ld c,a
  227.   inc c
  228.   ld b,0
  229.  else
  230.   ld bc,DEFAULT_FORMAT_LEN+1
  231.  endif
  232.  
  233.  
  234.   ld h,d
  235.   ld l,e
  236.   inc hl
  237.   ldir
  238.   cp a
  239.   db $3E
  240. xtostr_no_leading_0:
  241.   push de
  242.  
  243. ;If z flag is reset, this means that the exponent should be bumped up 1
  244.   ld hl,(pow10exp)
  245.   jr z,$+2+1+3;+_
  246.   inc hl
  247.   ld (pow10exp),hl
  248. ;_:
  249.  
  250.   ;if -4<=HL<=10, then need to insert the decimal place somewhere.
  251.   ld bc,4
  252.   add hl,bc
  253.   ld a,h
  254.   or a
  255.   jr nz,xtostr_decimalafter1st;+_
  256.   ld a,l
  257.   cp 15
  258.   jp c,movdec
  259. xtostr_decimalafter1st;_:
  260.   ;for this, we need to insert the decimal after the first digit
  261.   ;Then, we need to append the exponent string
  262.   ld hl,strout
  263.   ld de,strout-1
  264.   ld a,(hl)
  265.   cp TOK_NEG    ;negative sign
  266.   jr nz,$+2+2;+_
  267.   ldi
  268. ;_:
  269.   ldi
  270.   ld a,'.'
  271.   ld (de),a
  272. ;now we need to append the exponent to the end of the string
  273.   pop hl
  274.   ld (hl),TOK_ENG
  275.   inc hl
  276.   ld de,(pow10exp)
  277.   bit 7,d
  278.   jr z,xtostr_expok;+_
  279.   ld (hl),TOK_NEG    ;negative sign
  280.   inc hl
  281.   xor a
  282.   sub e
  283.   ld e,a
  284.   sbc a,a
  285.   sub d
  286.   ld d,a
  287. xtostr_expok;_:
  288.   push hl
  289.   ex de,hl
  290.   ld bc,-1000
  291.   ld a,'0'-1
  292.   or a
  293. ;_:
  294.   inc a
  295.   add hl,bc
  296.   jr c,$-2;-_
  297.   sbc hl,bc
  298.   cp $30
  299.   jr z,$+2+1+1;+_
  300.   ld (de),a
  301.   inc de
  302. ;_:
  303.  
  304.   ld bc,-100
  305.   ld a,'0'-1
  306. ;_:
  307.   inc a
  308.   add hl,bc
  309.   jr c,$-2;-_
  310.   sbc hl,bc
  311.   ld (de),a
  312.   inc de
  313.  
  314.   ld bc,$2F0A
  315.   ld a,l
  316. ;_:
  317.   inc b
  318.   sub c
  319.   jr nc,$-2;-_
  320.   ex de,hl
  321.   ld (hl),b
  322.   inc hl
  323.   add a,$3A
  324.   ld (hl),a
  325.   inc hl
  326.   xor a
  327.   ld (hl),a
  328.   pop de
  329.   ld h,d
  330.   ld l,e
  331.   ld a,'0'
  332. ;_:
  333.   cpi
  334.   jr z,$-2;-_
  335.   dec hl
  336.   call mov4
  337.   ld hl,strout-1
  338.   ret
  339. movdec:
  340.   ld hl,(pow10exp)
  341.   bit 7,h
  342.   jr z,posdec
  343. ;need to put zeroes before everything
  344.   ld de,strout
  345.   ld a,(de)
  346.   cp TOK_NEG    ;negative sign
  347.   push af
  348.   ld a,'0'
  349.   jr z,$+3
  350. movdec0;_:
  351.   dec de
  352.   ld (de),a
  353.   inc l
  354.   jr nz,movdec0;-_
  355.   inc h
  356.   jr nz,movdec0;-_
  357. ;_:
  358.   ld a,'.'
  359.   ld (de),a
  360.   pop af
  361.   ex de,hl
  362.   jr nz,$+2+1+1;+_
  363.   dec hl
  364.   ld (hl),a
  365. ;_:
  366.   pop de
  367.   xor a
  368.   ld (de),a
  369.   ret
  370. posdec:
  371.   ld hl,strout
  372.   ld de,strout-1
  373.   ld bc,(pow10exp)
  374.   ld a,b
  375.   or c
  376.   ld a,(hl)
  377.   jr z,$+2+2;+_
  378.   ldir
  379. ;_:
  380.   ldi
  381.   cp TOK_NEG    ;negative sign
  382.   jr nz,$+2+2;+_
  383.   ldi
  384. ;_:
  385.   pop hl
  386. ;HL points to the end of the string
  387. ;DE points to where the decimal is printed
  388. ;If HL+1 <= DE, then don't write a decimal, and set HL=DE
  389.   ex de,hl
  390.   or a
  391.   dec de
  392.   sbc hl,de
  393.   add hl,de
  394.   inc de
  395.   jr nc,$+2+1+2+1;+_
  396.   ex de,hl
  397.   ld a,'.'
  398.   ld (de),a
  399. ;_:
  400.   ld (hl),0
  401.   ld hl,strout-1
  402.   ret
  403. strcase:
  404.   ld de,str_Zero
  405.   ld a,(xOP1+7)
  406.   and $C0
  407.   jr z,xtostr_specstr;+_
  408.   ld de,str_INF
  409.   jp pe,xtostr_specstr;+_
  410.   ld de,str_NaN
  411. xtostr_specstr;_:
  412.   ex de,hl
  413.   call mov4
  414.   ld hl,strout
  415.   ret
  416. xtostr_mul:
  417.   add hl,hl
  418.   push hl
  419.   call c,xtostr_mulpp;+_
  420.   ld hl,10
  421.   add hl,de
  422.   ex de,hl
  423.   pop hl
  424.   ret
  425. xtostr_mulpp;_:
  426.   ld h,b
  427.   ld l,c
  428.   jp xmul
  429. xtostrmul10:
  430. ;multiply the 0.64 fixed point number at xOP1 by 10
  431. ;overflow in A register
  432.   ld hl,xOP1
  433.   ld de,xOP2
  434.   call mov9
  435.   xor a
  436.   inc hl
  437.   call sla64
  438.   rla
  439.   ld hl,xOP2
  440.   call sla64
  441.   rla
  442.   push af
  443.   ld de,xOP1
  444.   ld hl,xOP2
  445.   call add64
  446.   pop hl
  447.   ld a,h
  448.   adc a,0
  449.   call sla64_xOP1
  450.   rla
  451.   ret
  452.  endif
  453.