home *** CD-ROM | disk | FTP | other *** search
/ ticalc.org / ticalc_org_rev_b.iso / archives / 85 / asm / source / routines / fixpoint.asm < prev    next >
Encoding:
Assembly Source File  |  2001-07-01  |  16.0 KB  |  485 lines

  1. ;------------------------------------------------------------------
  2. ;                  16 bit fixpoint math rutines ver 1.0           ;
  3. ;                                                                 ;
  4. ; 16 bit fixpoint and 2's complement 16 bit fixpoint              ;
  5. ; math rutines by Dines Justesen Corp. 1996                       ;
  6. ;                                                                 ;
  7. ; Some rutines is based on work by or written by the following    ;
  8. ; people:                                                         ;
  9. ;   Magnus Hagander (e95_mha@e.kth.se)                            ;
  10. ;   Darryl Nester (nesterd@bluffton.edu)                          ;
  11. ;                                                                 ;
  12. ; You are allow to include the following rutines in your programs ;
  13. ; as long as you follow the rules stated below.                   ;
  14. ;                                                                 ;
  15. ; If you use any of the functions in one of your programs give me ;
  16. ; credit for my work. Some of the functions included was made by  ;
  17. ; others or based on some one elses work, they too should get the ;
  18. ; credit for their work. One way of doing this is by including    ;
  19. ; lines like the ones below in the documentation.                 ;
  20. ;                                                                 ;
  21. ; Fixpoint math by Dines Justesen (c958362@student.dtu.dk)        ;
  22. ; Some rutines by/based on work by Magnus Hagander                ;
  23. ;                                                                 ;
  24. ; You are NOT ALLOWED to distribute any modified versions of these;
  25. ; rutines, or only parts of the document.                         ;
  26. ;                                                                 ;
  27. ; The reason i decieded to release the source code for these      ;
  28. ; rutines was to help other people getting stared with more math  ;
  29. ; intensive programs. So  please don't just rip things off, either; 
  30. ; give methe credit or make your own rutines.                     ; 
  31. ;                                                                 ;
  32. ; This is the first version and some of the rutines are completly ;
  33. ; new,so there might by bugs in some rutines. The rutines to show ;
  34. ; numbers was written really fast so they a probably a bit slow.  ;
  35. ; If you find any bugs please report them to me. Any suggestion of;
  36. ; new rutines or improvements of the in the document are very     ;
  37. ; welcome, and i will include them in a future relase.            ;
  38. ;                                                                 ;
  39. ; Send comments and ideas to:                                     ;
  40. ;   Dines Justesen : c958362@student.dtu.dk or                    ;
  41. ;                    dines@MAILHOST.NET                           ;
  42. ;                    http://www.gbar.dtu.dk/~c958362/             ;
  43. ; Dines justesen april, 1996                                      ;
  44. ;------------------------------------------------------------------
  45.  
  46. #INCLUDE "TI-85.H"
  47.  
  48. RES = $80DF ; Used for temporary storage
  49.  
  50. .org 0
  51. ;------------------------------------------------------------------
  52. ;
  53. ; Program to test some of the fixpoint rutines
  54. ;
  55. ;------------------------------------------------------------------
  56.  
  57. .db "Fix Test",0
  58.         ld a,4                  ; Clear LCD
  59.         out (5),a
  60.         ROM_CALL(CLEARLCD)      
  61.         ld l,11111111b          ;Show a negative 2's complement number
  62.         ld h,11111111b
  63.         CALL_(ShowFix2)
  64.         CALL_(Loop)
  65.         ld bc,$0280             ;Multiply 2.5 and 16.125
  66.         ld de,$1020
  67.         CALL_(Mul16)
  68.         ld h,c
  69.         ld l,d
  70.         CALL_(ShowFix2)
  71.         CALL_(Loop)
  72.         ld hl,1111110110000000b             ;add -2.5 and -3.25
  73.         ld bc,1111110011000000b
  74.         CALL_(Add162)
  75.         CALL_(ShowFix2)
  76. KeyLoop1:
  77.     call GET_KEY
  78.     cp $37
  79.         ret z                   ; return if [EXIT] is pressed
  80.         jr KeyLoop1
  81.  
  82. Loop:                             ; Label
  83.         call GET_KEY              ; Call getkey
  84.         cp 9                      ; Enter ?
  85.         jr nz,Loop                ; No, loop
  86.         ret
  87.  
  88. ;------------------------------------------------------------------
  89. ;
  90. ; Below is the math rutines tested above
  91. ;
  92. ;------------------------------------------------------------------
  93.  
  94. ;------------------------------------------------------------------
  95. ;
  96. ; Addition + Subtraction
  97. ;
  98. ; Both of these operations are buldt in the z80. Use sbc, add, and
  99. ; add.
  100. ;
  101. ;------------------------------------------------------------------
  102.  
  103. ;------------------------------------------------------------------
  104. ;
  105. ; Add162
  106. ;
  107. ; Addition of 2  16 bit fixpoint 2's complement number
  108. ;
  109. ; Entry :  Hl = Op1 BC = Op2
  110. ; Exit  :  HL = Op1+Op2
  111. ;
  112. ;------------------------------------------------------------------
  113.  
  114. Add162:                 ;H bit 7 = x = B bit 7 check at res bit 7 = x
  115.   bit 7,H               ;Check bit 7
  116.   jr nz,First1          ;Jump if 1
  117.   bit 7,B               ;Check bit 7
  118.   jr nz,Zeroes          ;Jump if 0
  119. AddIt:
  120.   Add Hl,BC             ;Add  
  121.   AND A                 ;Clear carry
  122.   Ret                   ;Return
  123. First1:
  124.   bit 7,b               ;Check bit 7
  125.   jr z,AddIt            ;If 0 then add
  126.   Add HL,BC             ;Add
  127.   Bit 7,H               ;Check bit 7
  128.   Jr z,AddOv            ;If 0 then overflow !!
  129.   AND A                 ;Clear carry
  130.   Ret                   ;Return
  131. Zeroes:
  132.   Add Hl,BC             ;Add
  133.   Bit 7,H               ;Check bit 7
  134.   jr nz,AddOv           ;If 1 then overflow !!
  135.   AND A                 ;Clear carry
  136.   Ret                   ;Return
  137. AddOv:
  138.   Scf                   ;Set carry flag
  139.   Ret                   ;Return
  140.  
  141. ;------------------------------------------------------------------
  142. ;
  143. ; Sub162
  144. ;
  145. ; Subtraction of 2  16 bit fixpoint 2's complement number
  146. ;
  147. ; Entry :  Hl = Op1 DE = Op2
  148. ; Exit  :  Hl = Op1-Op2
  149. ;
  150. ;------------------------------------------------------------------
  151.  
  152.                         ; bit 7 = X = not bit 7 res=X
  153. Sub16:                  ; (-x)-(y) = -z  (x)-(-y) = +z
  154.   bit 7,h
  155.   jr nz,SFirst1
  156.   bit 7,d
  157.   jr nz,PosRes
  158. JustSub:
  159.   And A                 ;Clear carry
  160.   Sbc Hl,DE             ;Subtract
  161.   And A                 ;Clear carry
  162.   Ret                   ;Return
  163. SFirst1:                
  164.   bit 7,d
  165.   jr nz,JustSub
  166.   And A                 ;Clear carry
  167.   Sbc Hl,De             ;Subtract
  168.   bit 7,h               
  169.   jr z,SOver
  170.   And A                 ;Clear carry
  171.   Ret                   ;Return
  172. PosRes:                 
  173.   And A
  174.   Sbc Hl,De
  175.   bit 7,h
  176.   jr nz,SOver
  177.   And A
  178.   Ret
  179. SOver:
  180.   Scf                   ;Set carry
  181.   Ret                   ;Return
  182.  
  183. ;------------------------------------------------------------------
  184. ;
  185. ; Mul16
  186. ;
  187. ; Multiplication of two 16 bit numbers giving a 32 bit result.
  188. ; If fixpoint numbers are used then discard 8 LSB's if the 8 MSB's
  189. ; <>0 then the number is too big to stor as normal 16 bit fixpoint.
  190. ;
  191. ; Entry : BC = Mult1 DE= Mult2
  192. ; Exit  : BCDE = Mult1*Mult2 (B=MSB, E=LSB)
  193. ;         Destroys hl 
  194. ;
  195. ;------------------------------------------------------------------
  196.  
  197. Mul16:
  198.   push af               ;Save regs
  199.   push hl          
  200.   ld hl,0               ;reset hl
  201.   ld a,10h              ;counter = 16 bits
  202. mulloop:
  203.   add hl,hl             ;shift left temp result
  204.   rl e                  ;move next bit to carry
  205.   rl d
  206.   jr nc,mulover         ;if bit=0 then next
  207.   add hl,bc             ;else add multplcant to temp. result
  208.   jr nc,mulover         ;if no overflow then continue
  209.   inc de                ;else inc high 16 bits
  210. mulover:
  211.   dec a                 ;dec counter
  212.   jr nz,mulloop         ;if all bits done
  213.   ex de,hl              ;move low 16 bits of result to DE
  214.   ex (sp),hl            ;put high 16 bits on stack
  215.   pop bc                ;Bc = high 16 bits of result
  216.   pop af                ;Restore AF
  217.   ret 
  218.  
  219. ;------------------------------------------------------------------
  220. ; Cmp16
  221. ;
  222. ; 16 bit Compare works for both normal fixpoint numbers and 2's comp.
  223. ; This rutine is from the book Z80 assembly language subrutines by
  224. ; Lance A. Leventhal.
  225. ;
  226. ; Entry : HL=Value1 De=Value2
  227. ; Exit  : if 2'scomplement is used then
  228. ;               zero=1 and sign=0 then Value1=Value2
  229. ;               zero=0 and sign=0 then Value1>Value2
  230. ;               zero=0 and sign=1 then Value1<Value2
  231. ;         if not 2's complement then use carry instead of sign.
  232. ;         hl and a are destroyed.         
  233. ;
  234. ;------------------------------------------------------------------
  235.  
  236. Cmp16:
  237.   or a                  ;Clear carry
  238.   sbc hl,de             ;Value1-Value2
  239.   ret po                ;If no overflow occured
  240.                         ;If overflow occured then signed is
  241.                         ;changed on 2's complement
  242.   ld a,h                ;Get 8 MSB
  243.   rra                   ;Save carry from subtraction
  244.   xor 01000000b         ;Complement sign bit
  245.   scf                   ;ensure a non-zero result
  246.   adc a,a               ;restore carry, complemented sign
  247.                         ;zero flag=0
  248.   ret
  249.   
  250.  
  251. ;------------------------------------------------------------------
  252. ;
  253. ; ShowFix2
  254. ;
  255. ; Shows the 16 bit 2's complement fixpoint number stored in hl on
  256. ; the display
  257. ;
  258. ; Uses ShowFix
  259. ;
  260. ;------------------------------------------------------------------
  261.  
  262. ShowFix2:
  263.         bit 7,h         ;Check sign
  264.         jr z,notneg     ;Jump if positive
  265.         ld de,$FFFF     ;16 bit not
  266.         ex de,hl
  267.         sbc hl,de
  268.         inc hl          ;add 1
  269.         ld a,'-'        ;Display sign
  270.         ROM_CALL(TX_CHARPUT)
  271. notneg:
  272.         CALL_(ShowFix)  ;Show number
  273.         ret
  274. ;------------------------------------------------------------------
  275. ;
  276. ; ShowFix
  277. ;
  278. ; Shows the 16 bit fixpoint number stored in hl on the display
  279. ;
  280. ; Uses  : ShowInt and ShowFrac
  281. ;
  282. ;------------------------------------------------------------------
  283.  
  284. ShowFix:                
  285.         push hl         ;Save number for later use
  286.         ld a,h          ;Get integer part
  287.         CALL_(ShowInt)  ;Show it
  288.         ld a,'.'        ;Show decimal point
  289.         ROM_CALL(TX_CHARPUT)
  290.         pop hl          ;Restore number
  291.         ld a,l          ;Get fraction
  292.         CALL_(ShowFrac) ;Show it
  293.         ret
  294.  
  295. ;------------------------------------------------------------------
  296. ;
  297. ; ShowInt
  298. ;
  299. ; Displays integer part of a fixpoint number (8 MSB)
  300. ; This rutines is based on the rutine used in TEXAN by
  301. ; Magnus Hagander (e95_mha@e.kth.se), but has been
  302. ; changed a bit by me :-)
  303. ;
  304. ; Entry : A holds value to be printed
  305. ; Exit  : A HL and DE destroyed
  306. ;
  307. ;------------------------------------------------------------------
  308.  
  309. ShowInt:
  310.         ld l,a          ;Store value in hl
  311.         ld a,0
  312.         ld h,a
  313.         ld de,RES+3     ;Location of the end of the string
  314.         ld (de),a       ;Make string 0 terminated
  315.         dec de          ;point to last digit
  316.         ld b,3          ;Number of digits
  317. ConvLoop:
  318.         call UNPACK_HL  ;Unpack on digit from hl
  319.         cp 0
  320.         add a,'0'       ;make it ascii
  321.         ld (de),a       ;store it
  322.         dec de          ;point to next digit
  323.         djnz ConvLoop
  324.         ld hl,RES       ;point to string
  325.         ROM_CALL(D_ZT_STR) ;Display it
  326.         ret
  327.  
  328. ;------------------------------------------------------------------
  329. ;
  330. ; ShowFrac
  331. ;
  332. ; Displays the fraction part of a fixpoint number on screen.
  333. ;
  334. ; Entry : A holds value (lower 8 bits of a number)
  335. ; Exit  : All regs destroyed
  336. ; Uses  : RES and the most of the rutines below
  337. ;------------------------------------------------------------------
  338.  
  339. ShowFrac:
  340.         CALL_(Frac2bcd)         ;Convert number to BCD array
  341.         ld hl,RES               ;Point to array
  342.         CALL_(PrintArray)       ;Print number
  343.         ret
  344.  
  345. ;------------------------------------------------------------------
  346. ; Frac2bcd
  347. ;
  348. ; This procedure converts the fraction part of a fixpoint number to
  349. ; a 4 byte array containing the BCD values. Result is stored at adr.
  350. ; RES
  351. ;
  352. ; Entry : a hold the value to be converted
  353. ; Exit  : all regs destroyed
  354. ; Uses  : Addarray
  355. ;------------------------------------------------------------------
  356.  
  357. Frac2bcd:
  358.         ld b,8                  ;Number of bits in number
  359.         ld hl,RES               ;point to string
  360.         ld d,0                  ;Set result to 0
  361. reset:
  362.         ld (hl),d
  363.         inc hl
  364.         djnz reset
  365.         ld hl,RES               ;point to string
  366.         ld b,8                  ;number of bits
  367.         push hl                 ;Store pointer to result
  368.         ld hl,Cstart            ;Get adr. of first string
  369.         ld de,(PROGRAM_ADDR)    ;Add program offset
  370.         add hl,de
  371.         ex de,hl                ;store in de
  372.         pop hl                  ;Restore pointer to result
  373. loop:
  374.         rr a                    ;Shift left
  375.         jr nc,next              ;skip if bit=0
  376.         push hl                 ;Save pointer to result
  377.         CALL_(Addarray)         ;Add number
  378.         pop hl                  ;Restore pointer to result
  379.         jr next2                ;
  380. next:
  381.         dec de                  ;Point to next number
  382.         dec de
  383.         dec de
  384.         dec de
  385. next2:
  386.         djnz loop               ;Repeat for all bits
  387.                                 ;Now RES cointains a 8 byte bcd array with the 
  388. result.
  389.         ret
  390.  
  391. ;------------------------------------------------------------------
  392. ;
  393. ; PrintBCD
  394. ;
  395. ; Prints the BCD number in A on the display. This function was
  396. ; originally called PrintHex and was made by Darryl Nester
  397. ; (email : nesterd@bluffton.edu)
  398. ;
  399. ; Entry : A holds value to be printed
  400. ; Exit  : No regs destroyed
  401. ;------------------------------------------------------------------
  402.  
  403. PrintBCD:
  404.   push  af                      ;Save number
  405.   rrca                          ;Make the 4 MSB's the 4 LSB's
  406.   rrca
  407.   rrca
  408.   rrca
  409.   CALL_(Digit)                  ;Display first digit
  410.   pop   af                      ;Restore number
  411. Digit:
  412.   and $0F                       ;Use only lower 4 bits
  413.   add a,'0'                     ;Make ascii
  414.   ROM_CALL(TX_CHARPUT)          ;Show digit
  415.   ret
  416.  
  417. ;------------------------------------------------------------------
  418. ;
  419. ; PrintArray
  420. ;
  421. ; Prints a 4 byte array of BCD numbers on the display.
  422. ;
  423. ; Entry : HL points to array
  424. ; Exit  : Destroys A and HL
  425. ; Uses  : uses PrintBCD to print each digit
  426. ;
  427. ;------------------------------------------------------------------
  428.  
  429. PrintArray:
  430.         ld b,4                  ;Number of bytes in array
  431. PALoop:
  432.         ld a,(hl)               ;Get byte
  433.         CALL_(PrintBCD);        ;Print it
  434.         inc hl                  ;point to next byte
  435.         djnz PALoop
  436.         ret
  437.  
  438. ;------------------------------------------------------------------
  439. ; Addarray
  440. ;
  441. ; Addition of two 8 byte long bcd/numbers.
  442. ;
  443. ; Entry : hl points to start of array
  444. ;         de points to last byte in second array  
  445. ; Exit  : destroys bc,de,hl and flags
  446. ;------------------------------------------------------------------
  447.  
  448. Addarray:
  449.         ld bc,$0003             ;Lenght of string-1
  450.         add hl,bc               ;Point to end of string
  451.         ld b,4                  ;Number of bytes
  452.         ld c,a                  ;Save a reg
  453.         and a                   ;clear carry
  454. Addloop:
  455.         ld a,(de)               ;Get first byte
  456.         adc a,(hl)              ;Add second byte
  457.         daa                     ;Make BCD
  458.         ld (hl),a               ;Store result
  459.         dec hl                  ;Point to next bytes
  460.         dec de
  461.         djnz Addloop            ;Do it for all bytes in array
  462.         ld a,c                  ;Restore A reg
  463.         ret                     ;Done
  464.  
  465. C7:
  466. .db $50,$00,$00,$00             ;Arrays used for bin->ascii convertion of fracs.
  467. C6:
  468. .db $25,$00,$00,$00
  469. C5:
  470. .db $12,$50,$00,$00
  471. C4:
  472. .db $06,$25,$00,$00
  473. C3:
  474. .db $03,$12,$50,$00
  475. C2:
  476. .db $01,$56,$25,$00
  477. C1:
  478. .db $00,$78,$12,$50
  479. C0:
  480. .db $00,$39,$06
  481. Cstart:                         ;Make it easy to point last byte
  482. .db $25
  483. .END
  484.  
  485.