Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- xdef _calc
- xdef readFloat
- xdef writeFloat
- xdef ___loop
- xdef add
- xdef _pack
- xdef _unpack
- xref __main
- xref _readFt
- xref _writeFt
- include c:\devpac\incdir\gemdos.i ; needed for makefile
- ; struct number
- SIGN equ 0 ; bool sign
- EXP equ 2 ; byte biased_exponent
- MANT equ 4 ; long mantissa
- FLOAT_STRUCT_SZ equ 8
- SZ_LONG equ 4
- EXCESS equ $7F
- MASK_EXP equ $FF
- MASK_MANT equ $7FFFFF
- MASK_SIGN equ $80000000
- MASK_EOR equ $8000
- OFFSET_SGN equ 256
- OFFSET_MANT equ 23
- OFFSET_SIGN equ 31
- OFFSET_EXP equ 7
- OFFSET_NC_NORM equ $C0000000
- OFFSET_PC_NORM equ $C00000
- OFFSET_P4_NORM equ $400000
- OFFSET_P8_NORM equ $800000
- NULL equ 0
- GEMDOS equ 1
- CR equ 13
- LF equ 10
- _calc:
- movem.l d0-d2/a0-a2,-(sp)
- ___loop:
- clr.l d0
- pea __prompt1
- jsr s_printf ; s_printf("%s", __prompt1);
- addq #4,sp
- subq.l #4,sp
- jsr readFloat
- move.l (sp)+,d1
- move #CR,d0
- jsr write_char
- pea __prompt2
- jsr s_printf ; s_printf("%s", __prompt2);
- addq #4,sp
- subq.l #4,sp
- jsr readFloat
- move.l (sp)+,d2
- cmp d2,d1
- bhi no_swap
- exg.l d1,d2
- no_swap:
- subq #4,sp
- move.l d2,-(sp)
- move.l d1,-(sp)
- jsr add
- add #8,sp
- move.l (sp)+,d1
- pea __prompt3
- jsr s_printf ; s_printf("%s", __prompt3);
- addq #4,sp
- move.l d1,d0
- move.l d0,-(sp)
- jsr writeFloat
- adda.l #4,sp
- jsr new_line
- pea __prompt4
- jsr s_printf ; s_printf("%s", __prompt4);
- addq #4,sp
- jsr read_char
- and.w #$FF,d0
- move.l d0,d1
- jsr new_line
- jsr new_line
- cmp #'y',d1
- beq ___loop
- jsr new_line
- movem.l (sp)+,d0-d2/a0-a2
- rts
- __prompt1: dc.b "first operand ",NULL
- even
- __prompt2: dc.b "second operand ",NULL
- even
- __prompt3: dc.b "The answer = ",NULL
- even
- __prompt4: dc.b "Do another addition (y/n): ",NULL
- even
- ; long readFloat ()
- RF_RESULT equ 8
- readFloat:
- link a6,#0
- movem.l a0-a2/d0-d2,-(sp)
- jsr _readFt
- move.l d0,RF_RESULT(a6)
- movem.l (sp)+,a0-a2/d0-d2
- unlk a6
- rts
- ; void writeFloat (long value)
- WF_VALUE equ 8
- writeFloat:
- link a6,#0
- movem.l a0-a2/d0-d2,-(sp)
- move.l WF_VALUE(a6),-(sp)
- jsr _writeFt
- adda.l #4,sp
- movem.l (sp)+,a0-a2/d0-d2
- unlk a6
- rts
- ;----- SUBROUTINE: write_char -----
- xdef write_char
- write_char: movem.l d0-d2/a0-a2,-(sp)
- and.l #$0000FF,d0
- move.w d0,-(sp)
- move.w #2,-(sp)
- trap #1
- addq.l #4,sp
- movem.l (sp)+,d0-d2/a0-a2
- rts
- ;----- SUBROUTINE: s_printf -----
- ; void s_printf(const char *array);
- ;
- ; 'Prints a null terminated string'
- ;
- ; PARAMETERS: NULL terminated, character array.
- ;
- ; RETURN: N/A
- ;
- ; USAGE:
- ; pea buf
- ; bsr s_printf
- ; addq.l #4,a7
- ;
- xdef s_printf
- S_STR equ 8
- s_printf: link a6,#0
- movem.l d0-d2/a0-a2,-(sp)
- move.l S_STR(a6),-(sp)
- move.w #c_conws,-(sp)
- gem: trap #GEMDOS
- nop
- addq.l #6,sp
- movem.l (sp)+,d0-d2/a0-a2
- unlk a6
- rts
- nop
- ;----- SUBROUTINE: read_char -----
- ;
- ; PURPOSE: waits for and reads a single keystroke from the keyboard.
- ;
- ; CALLER OUTPUT: returns the ASCII value of the key in the low byte
- ; of D0.
- ;
- ; IMPORTANT: NOTE THAT THE HIGHER_ORDER BYTES OF D0 ARE UNDEFINED.
- ; DON'T ASSUME THEY ARE ZEROED OUT!
- ;
- ; E.G. CALL: bsr read_char
- ; ... now use D0.b ...
- read_char: movem.l d1-d2/a0-a2,-(sp)
- move.w #1,-(sp)
- trap #1
- addq.l #2,sp
- movem.l (sp)+,d1-d2/a0-a2
- rts
- ; new_line();
- new_line:
- movem.l a0-a2/d0-d2,-(sp)
- move.w #CR,-(sp)
- move.w #c_conout,-(sp)
- trap #GEMDOS
- addq.l #4,sp
- move.w #LF,-(sp)
- move.w #c_conout,-(sp)
- trap #GEMDOS
- addq.l #4,sp
- movem.l (sp)+,a0-a2/d0-d2
- rts
- ; ----- SUBROUTINE: add -----
- ; float add(float, float);
- ;
- ; 'Adds 2 32-bit IEEE Floating-point numbers'
- ;
- ; PARAMETERS: 2 32 bit floats to be added.
- ;
- ; RETURN: The packed 32 bit IEEE number. Stored in a long.
- ;
- ; ; struct float_struct
- ; {
- ; bool sign;
- ; byte biased_exponent;
- ; long mantissa;
- ; };
- ;
- ; Layout of _STRUCT_SZ In memory.
- ; |-2 BYTES----|2 BYTES------|4 BYTES-------|----------|
- ; |-16 sign -14|exponent -12|mantissa -8 | ... 0|
- ; |-index1----------------------------------|#-index2--|
- ;
- _FLOAT_STRUCT_ equ -FLOAT_STRUCT_SZ*2
- ADD_FLOAT equ 8
- ADD_FLOAT2 equ 12
- ADD_RESULT equ 16
- add:
- link a6,#_FLOAT_STRUCT_
- movem.l d0-d3/a0-a2,-(sp)
- clr.l d0
- clr.l d1
- move.l ADD_FLOAT(a6),d0 ; Check for zero.
- beq f1_zero ; result is other operand.
- move.l ADD_FLOAT2(a6),d1 ; check next float for zero.
- beq f2_zero ; result is other operand.
- clr.l d0
- clr.l d1
- clr.l d2
- move.l #1,d1 ; initialize counter.
- next_float: ; do{....} while(count != -1)
- move.l ADD_FLOAT(a6,d2.l),-(sp); Push the value of float_number(n) onto the stack.
- pea _FLOAT_STRUCT_(a6,d0.l) ; Push the address of the structure onto the stack.
- jsr _unpack ; unpack(float,&float_struct);
- addq #8,sp ; pop (restore stack).
- move.l #SZ_LONG,d2 ; the (parameter) address of the second float in memory.
- add.l #FLOAT_STRUCT_SZ,d0 ; Index of struct2. _STRUCT_SZ1/2.
- dbra d1,next_float ; (count == -1) ? break : loop again
- addition:
- lea _FLOAT_STRUCT_(a6),a0 ; initialize.
- lea _FLOAT_STRUCT_/2(a6),a1
- clr.l d0
- clr.l d1
- move.w EXP(a0),d0
- move.w EXP(a1),d1
- exponents:
- cmp.w d0,d1
- bge check_align ; align mantissas.
- exg a1,a0 ; swap structs, for 'right shift'.
- check_align:
- sub d1,d0 ; get new EXP.
- beq check_signs ; if exponents are equal, mantissas are aligned.
- bpl exp_pos
- neg.w d0
- exp_pos:
- move.w d0,d2 ; temp = exponent.
- subq.w #1,d0 ; offset for dbra.
- move.l MANT(a0),d1 ; mantissa to align.
- shift_right:
- asr.l #1,d1 ; shift to the right, so no bits are lost.
- dbra d0,shift_right
- add.w d2,EXP(a0) ; adjust new EXP.
- move.l d1,MANT(a0) ; store aligned mantissa.
- check_signs:
- clr.l d6 ; offset.
- addq #2,d6
- move.w SIGN(a0),d0 ; copy value of sign1.
- beq s1_pos ; s1+ve.
- sub.w #1,d6 ; offset--
- move.l MANT(a0),d0 ; s1-ve.
- neg.l d0
- move.l d0,MANT(a0) ; value is negative, fix for signed addition.
- s1_pos: move.w SIGN(a1),d1 ; check if sign2 is +ve.
- beq add_mantissas
- move.l MANT(a1),d1 ; s2-ve
- neg.l d1
- sub.w #1,d6 ; offset--
- move.l d1,MANT(a1)
- add_mantissas:
- move.l MANT(a0),d0
- move.l MANT(a1),d1 ; addition.
- add.l d0,d1 ; mantissa1+mantissa2
- bpl positive ; result is +ve
- negative:
- neg.l d1 ; result is -ve
- sub.w d6,d1
- move.w #1,SIGN(a0) ; make sign -ve
- move.l d1,d0
- rol.l #8,d0
- and.l #OFFSET_NC_NORM,d0 ; check MSBs 01.
- bmi pack_result ; check if CCR N bit is set.
- cmp #0,d6
- beq double_neg
- add.w d6,d1 ; offset
- lsl.l #1,d1 ; normalize mantissa
- sub.w #1,EXP(a0) ; adjust exponent.
- bra pack_result
- double_neg:
- add.w d6,d1 ; offset
- lsl.l #1,d1 ; normalize mantissa
- add.w #1,EXP(a0) ; adjust exponent.
- bra pack_result
- positive:
- move.l d1,d0
- move.w #0,SIGN(a0) ; make sign +ve
- and.l #OFFSET_PC_NORM,d0 ; check MSBs 10.
- cmp.l #OFFSET_P4_NORM,d0
- bne pack_result ; check if CCR Z bit is clear.
- addq.w #1,EXP(a0) ; adjust exponent. +ve, +ve = 1.
- lsr.l #1,d1 ; mantissa << 1
- pack_result:
- clr.l d2 ; offset of SIGN
- move.w SIGN(a0),_FLOAT_STRUCT_(a6,d2.w) ; result sign.
- addq #2,d2 ; offset of EXP
- move.w EXP(a0),_FLOAT_STRUCT_(a6,d2.w) ; result exponent.
- addq.w #2,d2 ; offset of MANT
- move.l d1,_FLOAT_STRUCT_(a6,d2.l) ; result mantissa.
- subq #4,sp ; put room on stack for return value.
- pea _FLOAT_STRUCT_(a6) ; pass float struct to stack.
- jsr _pack ; packed_float = pack(&float_struct);
- add #4,sp ; clen stack.
- move.l (sp)+,ADD_RESULT(a6) ; pop return value.
- bra return_sum ; return.
- f1_zero:
- move.l ADD_FLOAT2(a6),ADD_RESULT(a6) ; float 1 was zero.
- bra return_sum
- f2_zero:
- move.l ADD_FLOAT(a6),ADD_RESULT(a6) ; float 2 was zero
- return_sum:
- movem.l (sp)+,d0-d3/a0-a2
- unlk a6
- rts
- ; ----- SUBROUTINE: _pack -----
- ; float unpack(const float_struct *);
- ;
- ; 'Packs a 32-bit IEEE Floating-point number'
- ;
- ; PARAMETERS: a reference to a structure.
- ;
- ; RETURN: The packed 32 bit IEEE number. Stored in a long.
- ;
- ; ; struct float_struct
- ; {
- ; bool sign;
- ; byte biased_exponent;
- ; long mantissa;
- ; };
- ;
- PCK_STRUCT equ 8
- PCK_FLOAT equ 12
- _pack:
- link a6,#0
- movem.l d0-d3/a0,-(sp)
- movea.l PCK_STRUCT(a6),a0
- clr.l d0
- clr.l d1
- clr.l d2
- clr.l d3
- tst.w EXP(a0) ; check if addition resulted in zero.
- bne pack_exp
- tst.l MANT(a0)
- beq return_float
- pack_exp:
- move.l #EXP,d3 ; copy exponent from struct.
- move.w (a0,d3.w),d0
- add.w #EXCESS,d0 ; add biassed to exponent.
- pack_sign:
- move.l #SIGN,d3
- tst.w (a0,d3.w) ; check for negative.
- beq pack_mant
- ori.w #OFFSET_SGN,d0
- pack_mant:
- swap d0
- lsl.l #7,d0
- move.l #MANT,d3 ; offset for location of mantissa in memory.
- move.l (a0,d3.l),d1 ; copy mantissa from struct.
- and.l #MASK_MANT,d1 ; mask = ((1 << 23) -1) clear hidden.
- or.l d1,d0 ; return value |= mantissa.
- return_float:
- move.l d0,PCK_FLOAT(a6) ; return the packed float
- movem.l (sp)+,d0-d3/a0
- unlk a6
- rts
- nop
- ;
- ; ----- SUBROUTINE: _unpack -----
- ; void unpack(float, float_struct *);
- ;
- ; 'Unpacks a 32-bit IEEE Floating-point number'
- ;
- ; PARAMETERS: Packed float, a structure for storage.
- ;
- ; RETURN: A structure containing the components
- ; of the floating point number.
- ;
- ; struct float_struct
- ; {
- ; bool sign;
- ; byte biased_exponent;
- ; long mantissa;
- ; };
- ;
- ;
- ; USAGE:
- ; move.l d2,-(sp) ; pass the value of float_number1.
- ; pea (a0,d0) ; pass the address of the structure.
- ; jsr _unpack ; unpack(float, &struct);
- ; addq #8,sp ; restore stack.
- ;
- UNP_STRUCT equ 8
- UNP_FLOAT equ 12
- _unpack:
- link a6,#0
- movem.l d0-d3/a0-a1,-(sp)
- movea.l UNP_STRUCT(a6),a0
- movea.l UNP_FLOAT(a6),a1
- clr.l d0
- tst.w EXP(a0)
- clr.l d1 ; bitmask
- clr.l d2 ; offset for location in struct.
- move.l #MANT,d2 ; offset for mantissa in struct.
- move.l a1,d0 ; mantissa = *(const int *) &float
- and.l #MASK_MANT,d0 ; mantissa &= ((1 << 23) -1
- or.l #MASK_MANT+1,d0 ; hiddenbit |= MASK_MANT+1
- move.l d0,(a0,d2) ; copy mantissa to the struct.
- move.w #SIGN,d2 ; offset for signbit in struct.
- move.l a1,d0 ; sign = *(const int *) &float.
- and.l #MASK_SIGN,d0 ; signbit &= ((1 << 31) -1)
- rol.l d0
- move.w d0,(a0,d2) ; copy the signbit to the struct.
- move.w #EXP,d2 ; offset for exponent in struct.
- move.l a1,d0 ; exp = *(const int *) &float
- swap d0 ; exp = (exp >> 23) - 127;
- lsr.w #OFFSET_EXP,d0
- and.w #MASK_EXP,d0
- subi.w #EXCESS,d0 ; get true exponent.
- move.w d0,(a0,d2) ; copy the exponent to the struct.
- movem.l (sp)+,d0-d3/a0-a1
- unlk a6
- rts
- nop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement