Advertisement
Guest User

Untitled

a guest
Dec 12th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     xdef    _calc
  2.     xdef    readFloat
  3.     xdef    writeFloat
  4.     xdef    ___loop
  5.     xdef    add
  6.     xdef    _pack
  7.     xdef    _unpack
  8.  
  9.     xref    __main
  10.     xref    _readFt
  11.     xref    _writeFt
  12.  
  13.     include c:\devpac\incdir\gemdos.i   ; needed for makefile
  14.  
  15. ; struct number
  16. SIGN        equ 0           ; bool sign
  17. EXP         equ 2           ; byte biased_exponent
  18. MANT        equ 4           ; long mantissa
  19.  
  20. FLOAT_STRUCT_SZ     equ 8
  21.  
  22. SZ_LONG     equ 4
  23.  
  24. EXCESS      equ $7F
  25. MASK_EXP    equ $FF
  26. MASK_MANT   equ $7FFFFF
  27. MASK_SIGN   equ $80000000
  28. MASK_EOR    equ $8000
  29.  
  30. OFFSET_SGN  equ 256
  31. OFFSET_MANT equ 23
  32. OFFSET_SIGN equ 31
  33. OFFSET_EXP  equ 7
  34.  
  35. OFFSET_NC_NORM  equ $C0000000
  36. OFFSET_PC_NORM  equ $C00000
  37. OFFSET_P4_NORM  equ $400000
  38. OFFSET_P8_NORM  equ $800000
  39.  
  40. NULL    equ 0
  41. GEMDOS  equ 1
  42. CR  equ 13
  43. LF  equ     10
  44.  
  45. _calc:
  46.     movem.l d0-d2/a0-a2,-(sp)
  47. ___loop:
  48.     clr.l   d0
  49.     pea     __prompt1
  50.     jsr     s_printf    ; s_printf("%s", __prompt1);
  51.     addq    #4,sp
  52.  
  53.     subq.l  #4,sp
  54.     jsr     readFloat
  55.     move.(sp)+,d1
  56.  
  57.     move    #CR,d0
  58.     jsr     write_char
  59.  
  60.     pea     __prompt2
  61.     jsr     s_printf    ; s_printf("%s", __prompt2);
  62.     addq    #4,sp
  63.  
  64.     subq.l  #4,sp
  65.     jsr     readFloat
  66.     move.(sp)+,d2
  67.  
  68.     cmp     d2,d1
  69.     bhi     no_swap
  70.     exg.l   d1,d2
  71. no_swap:
  72.     subq    #4,sp
  73.     move.l  d2,-(sp)
  74.     move.l  d1,-(sp)
  75.     jsr     add
  76.    
  77.     add     #8,sp
  78.     move.(sp)+,d1
  79.    
  80.     pea     __prompt3
  81.     jsr     s_printf    ; s_printf("%s", __prompt3);
  82.     addq    #4,sp
  83.  
  84.     move.l  d1,d0
  85.  
  86.     move.l  d0,-(sp)
  87.     jsr     writeFloat
  88.     adda.l  #4,sp
  89.  
  90.     jsr new_line
  91.  
  92.     pea     __prompt4
  93.     jsr     s_printf    ; s_printf("%s", __prompt4);
  94.     addq    #4,sp
  95.  
  96.     jsr     read_char
  97.     and.w   #$FF,d0
  98.     move.l  d0,d1
  99.    
  100.     jsr     new_line
  101.     jsr     new_line
  102.  
  103.     cmp     #'y',d1
  104.     beq     ___loop
  105.  
  106.     jsr new_line
  107.    
  108.     movem.l (sp)+,d0-d2/a0-a2
  109.     rts
  110.  
  111. __prompt1:  dc.b    "first operand ",NULL
  112.         even
  113. __prompt2:  dc.b    "second operand ",NULL
  114.         even
  115. __prompt3:  dc.b    "The answer = ",NULL
  116.         even
  117. __prompt4:  dc.b    "Do another addition (y/n): ",NULL
  118.         even
  119.  
  120. ; long readFloat ()
  121. RF_RESULT   equ 8
  122.  
  123. readFloat:
  124.     link    a6,#0
  125.     movem.l a0-a2/d0-d2,-(sp)
  126.  
  127.     jsr     _readFt
  128.     move.l  d0,RF_RESULT(a6)
  129.  
  130.     movem.l (sp)+,a0-a2/d0-d2
  131.     unlk    a6
  132.     rts
  133.  
  134. ; void writeFloat (long value)
  135. WF_VALUE    equ 8
  136.  
  137. writeFloat:
  138.     link    a6,#0
  139.     movem.l a0-a2/d0-d2,-(sp)
  140.  
  141.     move.l  WF_VALUE(a6),-(sp)
  142.     jsr     _writeFt
  143.     adda.l  #4,sp
  144.    
  145.     movem.l (sp)+,a0-a2/d0-d2
  146.     unlk    a6
  147.     rts
  148.  
  149.  
  150. ;----- SUBROUTINE: write_char -----
  151.         xdef    write_char
  152.        
  153. write_char: movem.l d0-d2/a0-a2,-(sp)
  154.         and.l   #$0000FF,d0
  155.         move.w  d0,-(sp)
  156.         move.w  #2,-(sp)
  157.         trap    #1
  158.         addq.l  #4,sp
  159.         movem.l (sp)+,d0-d2/a0-a2
  160.         rts
  161.  
  162. ;----- SUBROUTINE: s_printf -----
  163. ; void s_printf(const char *array);
  164. ;
  165. ; 'Prints a null terminated string'
  166. ;
  167. ; PARAMETERS: NULL terminated, character array.
  168. ;
  169. ; RETURN: N/A
  170. ;
  171. ; USAGE:
  172. ;   pea buf
  173. ;   bsr s_printf
  174. ;   addq.l  #4,a7
  175. ;  
  176.         xdef    s_printf
  177.  
  178. S_STR       equ 8
  179.  
  180. s_printf:   link    a6,#0
  181.         movem.l d0-d2/a0-a2,-(sp)
  182.  
  183.         move.l  S_STR(a6),-(sp)
  184.         move.w  #c_conws,-(sp)
  185. gem:        trap    #GEMDOS
  186.         nop
  187.  
  188.         addq.l  #6,sp
  189.  
  190.         movem.l (sp)+,d0-d2/a0-a2
  191.         unlk    a6
  192.  
  193.         rts
  194.         nop
  195.  
  196. ;----- SUBROUTINE: read_char -----
  197. ;
  198. ; PURPOSE: waits for and reads a single keystroke from the keyboard.
  199. ;
  200. ; CALLER OUTPUT: returns the ASCII value of the key in the low byte
  201. ;                of D0.
  202. ;
  203. ; IMPORTANT: NOTE THAT THE HIGHER_ORDER BYTES OF D0 ARE UNDEFINED.
  204. ;            DON'T ASSUME THEY ARE ZEROED OUT!
  205. ;
  206. ; E.G. CALL:    bsr read_char
  207. ;       ... now use D0.b ...
  208.  
  209. read_char:  movem.l d1-d2/a0-a2,-(sp)
  210.     move.w  #1,-(sp)
  211.     trap    #1
  212.     addq.l  #2,sp  
  213.     movem.l (sp)+,d1-d2/a0-a2
  214.     rts
  215.  
  216. ; new_line();
  217. new_line:
  218.     movem.l a0-a2/d0-d2,-(sp)
  219.     move.w  #CR,-(sp)
  220.     move.w  #c_conout,-(sp)
  221.     trap    #GEMDOS
  222.     addq.l  #4,sp
  223.    
  224.     move.w  #LF,-(sp)
  225.     move.w  #c_conout,-(sp)
  226.     trap    #GEMDOS
  227.     addq.l  #4,sp
  228.     movem.l (sp)+,a0-a2/d0-d2
  229.     rts
  230.  
  231. ; ----- SUBROUTINE: add -----
  232. ; float add(float, float);
  233. ;
  234. ; 'Adds 2 32-bit IEEE Floating-point numbers'
  235. ;
  236. ; PARAMETERS: 2 32 bit floats to be added.
  237. ;
  238. ; RETURN: The packed 32 bit IEEE number. Stored in a long.
  239. ;
  240. ; ; struct float_struct
  241. ; {
  242. ;   bool sign;
  243. ;   byte biased_exponent;
  244. ;   long mantissa;
  245. ; };
  246. ;
  247. ;          Layout of _STRUCT_SZ In memory.
  248. ;  |-2 BYTES----|2 BYTES------|4 BYTES-------|----------|
  249. ;  |-16 sign -14|exponent  -12|mantissa   -8 |    ...  0|  
  250. ;  |-index1----------------------------------|#-index2--|
  251. ;
  252.  
  253. _FLOAT_STRUCT_      equ -FLOAT_STRUCT_SZ*2
  254.  
  255. ADD_FLOAT   equ 8
  256. ADD_FLOAT2  equ 12
  257. ADD_RESULT  equ 16
  258.  
  259. add:   
  260.     link    a6,#_FLOAT_STRUCT_
  261.     movem.l d0-d3/a0-a2,-(sp)
  262.  
  263.     clr.l   d0
  264.     clr.l   d1
  265.    
  266.     move.l  ADD_FLOAT(a6),d0    ; Check for zero.
  267.     beq     f1_zero         ; result is other operand.
  268.     move.l  ADD_FLOAT2(a6),d1   ; check next float for zero.
  269.     beq     f2_zero         ; result is other operand.
  270.    
  271.     clr.l   d0
  272.     clr.l   d1
  273.     clr.l   d2
  274.     move.l  #1,d1           ; initialize counter.
  275.  
  276. next_float: ; do{....} while(count != -1)  
  277.     move.l  ADD_FLOAT(a6,d2.l),-(sp); Push the value of float_number(n) onto the stack.
  278.     pea     _FLOAT_STRUCT_(a6,d0.l) ; Push the address of the structure onto the stack.
  279.     jsr     _unpack         ; unpack(float,&float_struct);
  280.     addq    #8,sp           ; pop (restore stack).
  281.     move.l  #SZ_LONG,d2     ; the (parameter) address of the second float in memory.
  282.     add.l   #FLOAT_STRUCT_SZ,d0 ; Index of struct2. _STRUCT_SZ1/2.
  283.     dbra    d1,next_float       ; (count == -1) ? break : loop again
  284.  
  285. addition:
  286.     lea     _FLOAT_STRUCT_(a6),a0   ; initialize.
  287.     lea     _FLOAT_STRUCT_/2(a6),a1
  288.     clr.l   d0
  289.     clr.l   d1
  290.  
  291.     move.w  EXP(a0),d0
  292.     move.w  EXP(a1),d1
  293.  
  294. exponents:
  295.     cmp.w   d0,d1
  296.     bge     check_align ; align mantissas.
  297.     exg     a1,a0       ; swap structs, for 'right shift'.
  298.  
  299. check_align:
  300.     sub     d1,d0       ; get new EXP.
  301.     beq     check_signs ; if exponents are equal, mantissas are aligned.
  302.     bpl     exp_pos
  303.  
  304.     neg.w   d0
  305. exp_pos:
  306.     move.w  d0,d2       ; temp = exponent.
  307.  
  308.     subq.w  #1,d0       ; offset for dbra.
  309.     move.l  MANT(a0),d1 ; mantissa to align.
  310.  
  311. shift_right:
  312.     asr.l   #1,d1       ; shift to the right, so no bits are lost.
  313.     dbra    d0,shift_right
  314.     add.w   d2,EXP(a0)  ; adjust new EXP.
  315.     move.l  d1,MANT(a0) ; store aligned mantissa.
  316.  
  317. check_signs:
  318.     clr.l   d6      ; offset.
  319.     addq    #2,d6
  320.  
  321.     move.w  SIGN(a0),d0 ; copy value of sign1.
  322.     beq     s1_pos      ; s1+ve.
  323.  
  324.     sub.w   #1,d6       ; offset--
  325.  
  326.     move.l  MANT(a0),d0 ; s1-ve.
  327.     neg.l   d0
  328.     move.l  d0,MANT(a0) ; value is negative, fix for signed addition.
  329.  
  330. s1_pos:     move.w  SIGN(a1),d1 ; check if sign2 is +ve.
  331.     beq     add_mantissas
  332.     move.l  MANT(a1),d1 ; s2-ve
  333.     neg.l   d1
  334.     sub.w   #1,d6       ; offset--
  335.  
  336.     move.l  d1,MANT(a1)
  337. add_mantissas:
  338.     move.l  MANT(a0),d0
  339.     move.l  MANT(a1),d1 ; addition.
  340.  
  341.     add.l   d0,d1       ; mantissa1+mantissa2
  342.     bpl     positive    ; result is +ve
  343.  
  344. negative:
  345.     neg.l   d1      ; result is -ve
  346.     sub.w   d6,d1
  347.  
  348.     move.w  #1,SIGN(a0) ; make sign -ve
  349.  
  350.     move.l  d1,d0
  351.     rol.l   #8,d0
  352.     and.l   #OFFSET_NC_NORM,d0  ; check MSBs 01.
  353.     bmi     pack_result     ; check if CCR N bit is set.
  354.  
  355.     cmp     #0,d6
  356.     beq     double_neg
  357.  
  358.     add.w   d6,d1           ; offset
  359.     lsl.l   #1,d1           ; normalize mantissa
  360.     sub.w   #1,EXP(a0)      ; adjust exponent.
  361.     bra     pack_result
  362.  
  363. double_neg:
  364.     add.w   d6,d1           ; offset
  365.     lsl.l   #1,d1           ; normalize mantissa
  366.     add.w   #1,EXP(a0)      ; adjust exponent.
  367.     bra     pack_result
  368.  
  369. positive:
  370.     move.l  d1,d0
  371.     move.w  #0,SIGN(a0)     ; make sign +ve
  372.  
  373.     and.l   #OFFSET_PC_NORM,d0  ; check MSBs 10.
  374.     cmp.l   #OFFSET_P4_NORM,d0
  375.     bne     pack_result     ; check if CCR Z bit is clear.
  376.  
  377.     addq.w  #1,EXP(a0)      ; adjust exponent. +ve, +ve = 1.
  378.     lsr.l   #1,d1           ; mantissa << 1
  379.  
  380. pack_result:   
  381.     clr.l   d2                  ; offset of SIGN
  382.     move.w  SIGN(a0),_FLOAT_STRUCT_(a6,d2.w)    ; result sign.
  383.     addq    #2,d2                   ; offset of EXP
  384.     move.w  EXP(a0),_FLOAT_STRUCT_(a6,d2.w)     ; result exponent.
  385.     addq.w  #2,d2                   ; offset of MANT
  386.     move.l  d1,_FLOAT_STRUCT_(a6,d2.l)      ; result mantissa.
  387.  
  388.     subq    #4,sp           ; put room on stack for return value.
  389.     pea     _FLOAT_STRUCT_(a6)  ; pass float struct to stack.
  390.     jsr     _pack           ; packed_float = pack(&float_struct);
  391.     add     #4,sp           ; clen stack.
  392.     move.(sp)+,ADD_RESULT(a6)    ; pop return value.
  393.  
  394.     bra     return_sum              ; return.
  395.  
  396. f1_zero:   
  397.     move.l  ADD_FLOAT2(a6),ADD_RESULT(a6)   ; float 1  was zero.
  398.     bra return_sum
  399. f2_zero:   
  400.     move.l  ADD_FLOAT(a6),ADD_RESULT(a6)    ; float 2 was zero
  401.  
  402. return_sum:
  403.     movem.l (sp)+,d0-d3/a0-a2
  404.     unlk    a6
  405.     rts
  406.  
  407. ; ----- SUBROUTINE: _pack -----
  408. ; float unpack(const float_struct *);
  409. ;
  410. ; 'Packs a 32-bit IEEE Floating-point number'
  411. ;
  412. ; PARAMETERS: a reference to a structure.
  413. ;
  414. ; RETURN: The packed 32 bit IEEE number. Stored in a long.
  415. ;
  416. ; ; struct float_struct
  417. ; {
  418. ;   bool sign;
  419. ;   byte biased_exponent;
  420. ;   long mantissa;
  421. ; };
  422. ;
  423.  
  424. PCK_STRUCT  equ 8
  425. PCK_FLOAT   equ 12
  426.  
  427. _pack:
  428.     link    a6,#0
  429.     movem.l d0-d3/a0,-(sp)
  430.     movea.l PCK_STRUCT(a6),a0
  431.  
  432.     clr.l   d0
  433.     clr.l   d1
  434.     clr.l   d2
  435.     clr.l   d3
  436.  
  437.     tst.w   EXP(a0)         ; check if addition resulted in zero.
  438.     bne     pack_exp
  439.     tst.l   MANT(a0)
  440.     beq     return_float
  441.  
  442. pack_exp:
  443.     move.l  #EXP,d3         ; copy exponent from struct.
  444.     move.(a0,d3.w),d0       
  445.     add.w   #EXCESS,d0      ; add biassed to exponent.
  446.  
  447. pack_sign: 
  448.     move.l  #SIGN,d3
  449.     tst.w   (a0,d3.w)       ; check for negative.
  450.     beq     pack_mant
  451.     ori.w   #OFFSET_SGN,d0
  452.  
  453. pack_mant:
  454.     swap    d0
  455.     lsl.l   #7,d0
  456.  
  457.     move.l  #MANT,d3            ; offset for location of mantissa in memory.
  458.     move.(a0,d3.l),d1        ; copy mantissa from struct.
  459.     and.l   #MASK_MANT,d1       ; mask = ((1 << 23) -1) clear hidden.
  460.     or.l    d1,d0               ; return value |= mantissa.
  461.  
  462. return_float:
  463.     move.l  d0,PCK_FLOAT(a6)    ; return the packed float
  464.     movem.l (sp)+,d0-d3/a0
  465.     unlk    a6
  466.     rts
  467.     nop
  468. ;
  469. ; ----- SUBROUTINE: _unpack -----
  470. ; void unpack(float, float_struct *);
  471. ;
  472. ; 'Unpacks a 32-bit IEEE Floating-point number'
  473. ;
  474. ; PARAMETERS: Packed float, a structure for storage.  
  475. ;
  476. ; RETURN: A structure containing the components
  477. ; of the floating point number.
  478. ;
  479. ; struct float_struct
  480. ; {
  481. ;   bool sign;
  482. ;   byte biased_exponent;
  483. ;   long mantissa;
  484. ; };
  485. ;
  486. ;
  487. ; USAGE:
  488. ;   move.l  d2,-(sp)    ; pass the value of float_number1.
  489. ;   pea     (a0,d0)         ; pass the address of the structure.
  490. ;   jsr     _unpack         ; unpack(float, &struct);
  491. ;   addq    #8,sp           ; restore stack.
  492. ;
  493.  
  494. UNP_STRUCT  equ 8
  495. UNP_FLOAT   equ 12
  496.    
  497. _unpack:
  498.     link    a6,#0
  499.     movem.l d0-d3/a0-a1,-(sp)
  500.  
  501.     movea.l UNP_STRUCT(a6),a0
  502.     movea.l UNP_FLOAT(a6),a1
  503.  
  504.     clr.l   d0
  505.     tst.w   EXP(a0)
  506.  
  507.     clr.l   d1      ; bitmask
  508.     clr.l   d2      ; offset for location in struct.
  509.  
  510.     move.l  #MANT,d2        ; offset for mantissa in struct.
  511.     move.l  a1,d0           ; mantissa = *(const int *) &float
  512.     and.l   #MASK_MANT,d0   ; mantissa &= ((1 << 23) -1
  513.     or.l    #MASK_MANT+1,d0 ; hiddenbit |= MASK_MANT+1
  514.     move.l  d0,(a0,d2)      ; copy mantissa to the struct.
  515.  
  516.     move.w  #SIGN,d2        ; offset for signbit in struct.
  517.     move.l  a1,d0           ; sign = *(const int *) &float.
  518.     and.l   #MASK_SIGN,d0   ; signbit &= ((1 << 31) -1)
  519.     rol.l   d0
  520.     move.w  d0,(a0,d2)      ; copy the signbit to the struct.
  521.  
  522.     move.w  #EXP,d2         ; offset for exponent in struct.
  523.     move.l  a1,d0           ; exp = *(const int *) &float
  524.     swap    d0              ; exp = (exp >> 23) - 127;
  525.     lsr.w   #OFFSET_EXP,d0 
  526.     and.w   #MASK_EXP,d0
  527.     subi.w  #EXCESS,d0      ; get true exponent.
  528.  
  529.     move.w  d0,(a0,d2)      ; copy the exponent to the struct.
  530.     movem.l (sp)+,d0-d3/a0-a1
  531.     unlk    a6
  532.     rts
  533.     nop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement