;************************************************************************* ; Mathematik-Bibliothek ;************************************************************************* .hide ; Inhalt: ; ; SplitA: R0 := Exponent, R2..R5 := Mantisse b234 ; SplitB: R1 := Exponent, $09..$0b := Mantisse b250 ; Ins_Exp: Einfgen von Exponent und Vorzeichen b274 ; Hid_Bit: Hiddenbit-Mantisse formen b286 ; Add_Help:Rechtsversch. der Mantisse mit kleinerem Exponenten b2c8 ; Add_GK: R2..R5 := R2..R5 + $08..$0b b317 ; Sub_GK: R2..R5 := R2..R5 - $08..$0b b385 ; Comp_Min:Vergleich: ACC.7 := 1 wenn R2..R5 < $08..$0b b38a ; Mult_GK: R2..R5 := R2..R5 * $08..$0b b3b8 ; Div_GK: R2..R5 := R2..R5 / $08..$0b b470 ; ; GK_Int32: R2..R5 := dword-integer(R2..R5) b500 ; Int8S_GK: R2..R5 := GK(R5) *** vorzeichenbeh.*** b566 ; Int16S_GK: R2..R5 := GK(R4,R5) *** vorzeichenbeh.*** b56f ; Int32S_GK: R2..R5 := GK(R2..R5) *** vorzeichenbeh.*** b575 ; Int8_GK: R2..R5 := GK(R5) *** vorzeichenlos *** b5a2 ; Int16_GK: R2..R5 := GK(R4,R5) *** vorzeichenlos *** b5a4 ; Int32_GK: R2..R5 := GK(R2..R5) *** vorzeichenlos *** b5a7 ; ; Div_Mod_16: R2,R3/R4,R5 := R2,R3 div/mod R4,R5 b5b3 ; Div_16: R2,R3 := (R2,R3) div (R4,R5) *** vorzeichenlos *** b608 ; Mod_16: R2,R3 := (R2,R3) mod (R4,R5) *** vorzeichenlos *** b614 ; Betrag: R2,R3 := |R2,R3| und R4,R5 := |R4,R5| b624 ; Mod_16S: R2,R3 := (R2,R3) mod (R4,R5) *** vorzeichenbeh.*** b63b ; Div_16S: R2,R3 := (R2,R3) div (R4,R5) *** vorzeichenbeh.*** b64f ; Comp_Equ:Vergleich: ACC := 0 wenn (R2..R5) = ($08..$0b) b66e ; Div_Mod_32: R2..R5/$08..$0b := R2..R5 div/mod $08..$0b b695 ; ; Mult_16: R2,R3 := (R2,R3) * (R4,R5) bb55 ; Mult_32: R2..R5 := (R2..R5) * ($08..$0b) bb73 ;************************************************************************* ; Export: .global Add_GK, Sub_GK, Mult_GK, Div_GK, Comp_Min, Comp_Equ .global Div_16, Mod_16, Div_16S, Mod_16S, Mult_16, Div_Mod_32, Mult_32 .global GK_Int32 .global Int8S_GK, Int16S_GK, Int32S_GK, Int8_GK, Int16_GK, Int32_GK ;************************************************************************* ; Konstanten: ZeroA = $01 ZeroB = $02 ExpOV = $04 ExpUF = $08 SignA = $80 SignB = $40 ;************************************************************************* .text_rel .show ; **** Aufspaltung GK($08..$0b) -> R1 := Exponent, $09..$0b := Mantisse ** ; R7.6 = Vorzeichen ; Register: A, R1, R7, $08..$0b SplitB: mov a,$08 rrc a anl a,#SignB ; ACC.6 := Vorzeichen anl $07,#SignA|ZeroA ; R7 l”schen, R7.[7,0] bleiben -> 1.Zahl orl $07,a ; R7.6 := Vorzeichen mov a,$09 rlc a mov a,$08 rlc a mov r1,a ; R1 := Exponent jz ?SplB1 ; Sprung wenn R1 = 0 -> alle 0 orl $09,#$80 ; $09.7 setzen -> Hiddenbit ! mov $08,#$00 ; $08 l”schen RET ?SplB1: mov $08,A ; -> R1 = 0, $08 l”schen mov a,$09 orl a,$0a orl a,$0b jz ?SplB0 ; Sprung bei 0 mov a,$0b ; sonst: Linksverschiebung add a,$0b mov $0b,a mov a,$0a rlc a mov $0a,a mov a,$09 rlc a mov $09,a ; $09..$0b := 2 * $09..$0b := rl $09..$0b RET ?SplB0: ; -> alle 0 orl $07,#ZeroB RET ; **** Aufspaltung GK(R2..R5) -> R0 := Exponent, R2..R5 := Mantisse ****** ; R7.7 := Vorzeichen ; Register: A, R0, R2..R5, R7 SplitA: mov a,r2 anl a,#SignA ; ACC.7 := Vorzeichen anl $07,#SignB|ZeroB ; R7 l”schen, R7.[6,1] bleiben -> 2.Zahl orl $07,a ; R7.7 := Vorzeichen mov a,r3 rlc a mov a,r2 rlc a mov r0,a ; R0 := Exponent jz ?SplA1 ; Sprung wenn R0 = 0 -> alle 0 / kein Hiddenbit orl $03,#$80 ; R3.7 setzen -> Hiddenbit ! mov r2,#$00 ; R2 l”schen RET ?SplA1: mov r2,A ; -> R0 = 0, R2 l”schen ! mov a,R3 orl a,R4 orl a,R5 jz ?SplA0 ; Sprung bei 0 mov a,r5 ; sonst: Linksverschiebung add a,r5 mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a ; R3..R5 := 2 * R3..R5 = rl R3..R5 RET ?SplA0: clr a ; -> alle 0 mov r0,a orl $07,#ZeroA RET ; **** Einfgen von Exponent und Vorzeichen: R2,R3 := (R7.7, rr R0) ****** ; Register: A, R0, R2, R3, R7 Ins_Exp: mov a,r0 clr c rrc a ; C := LSB-Exponent, ACC := 7-Bit-Exponent anl $07,#SignA ; R7 := Vorzeichen orl a,r7 ; ACC.7 := Vorzeichen mov r2,a ; R2 := Vorzeichen + 7-Bit-Exponent/MS-Byte mov a,r0 rr a anl a,#$80 anl $03,#$7f orl $03,a ; R3.7 := LSB-Exponent RET ; **** Hiddenbit-Mantisse formen ***************************************** ; Register: A, R0, R2..R5 Hid_Bit: mov a,r7 anl a,#ExpUF jnz ?Hid2 ; Sprung wenn Unterlauf: Rechtsverschiebung mov a,r2 jz ?Hid3 ; Sprung wenn keine Rechtsverschiebung n”tig ?Hid0: ;mov a,r2 ; -> Rechtsverschiebung bis R2 = 0 cjne a,#$01,?Hid1 ; Sprung wenn nich MSB in R2.0 : kein Aufrunden mov a,r5 add a,#$01 mov r5,a clr a addc a,r4 mov r4,a clr a addc a,r3 mov r3,a clr a addc a,r2 mov r2,a ; R2..R5 := R2..R5 + 1 -> Aufrunden ?Hid1: ; -> kein Aufrunden, jetzt Rechtverschiebung : inc r0 ; Exponent erh”hen mov a,r0 jnz ?Hid2 ; Sprung wenn kein šberlauf orl $07,#ExpOV ; šberlauf anzeigen anl $07,#$ff^ExpUF ?Hid2: mov a,r2 ; -> Rechtverschiebung : clr c rrc a mov r2,a mov a,r3 rrc a mov r3,a mov a,r4 rrc a mov r4,a mov a,r5 rrc a mov r5,a ; R2..R5 := rr R2..R5 mov a,r2 jnz ?Hid0 ; Wiederholen bis R2 = 0 mov a,r7 anl a,#ExpUF jnz ?Hid1 RET ?Hid3: orl a,r3 ; -> R2 = 0: keine Rechtsverschiebung n”tig orl a,r4 orl a,r5 jz ?SplA0 ; alle 0 ? -> R2..R5 := 0, R0 := 0 mov a,r0 jz ?Hid2 ; Sprung wenn R0 = 0: einmalige Rechtsverschiebung ; sonst: Linksverschiebung ?Hid4: mov a,r3 ; -> Rcksprung: Schleife Linksverschiebung jb $e7,?Hid5 ; MSB gesetzt ? -> hidden-bit -> fertig mov a,r5 add a,r5 mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a mov a,r2 rlc a mov r2,a ; R2..R5 := 2 * R2..R5 = rl R2..R5 dec r0 ; Exponent nach Linksverschiebung verkleinern mov a,r0 ; Exponenten-Unterlauf prfen jnz ?Hid4 ; Rcksprung wenn kein Unterlauf sjmp ?Hid2 ; sonst: einmalige Rechtsverschiebung ?Hid5: RET ; **** UP fr GK-Addition ************************************************ ; Rechtsverschiebung der Mantisse mit kleinerem Exponenten ; Register: A, R0, R1, R2..R5, $08..$0b Add_Help: mov a,r0 clr c subb a,r1 ; Test: R0 - R1 jnc ?AddH1 ; Sprung wenn R0 >= R1, d.h. 2.Summand kleiner add a,#$20 ; Test: (R0 - R1) + 32 jc ?AddH0 ; Sprung wenn R0 - R1 < 32 mov a,r1 ; sonst: kein Beitrag durch 1.Summand mov r0,a ; Exponent1 := Exponent2 clr a mov r2,a mov r3,a mov r4,a mov r5,a ; R2..R5 := 0 = Mantisse 1 RET ?AddH0: inc r0 ; -> Rechtsverschiebung von R2..R5 mov a,r2 ; bis Exponenten gleich clr c rrc a mov r2,a mov a,r3 rrc a mov r3,a mov a,r4 rrc a mov r4,a mov a,r5 rrc a mov r5,a ; R2..R5 := rr R2..R5 mov a,r0 cjne a,$01,?AddH0 ; Wiederholen bis Exponenten gleich RET ?AddH1: add a,#$e0 ; -> R0 >= R1, Test: (R0 - R1) - 32 jnc ?AddH3 ; Sprung wenn R0 - R1 < 32 mov a,r0 ; sonst: kein Beitrag durch 2.Summand mov r1,a ; Exponent2 := Exponent1 clr a mov $08,a mov $09,a mov $0a,a mov $0b,a ; $08..$0b := 0 = Mantisse 2 RET ?AddH2: inc r1 ; -> Rechtsverschiebung von $08..$0b clr c ; bis Exponenten gleich mov a,$08 rrc a mov $08,a mov a,$09 rrc a mov $09,a mov a,$0a rrc a mov $0a,a mov a,$0b rrc a mov $0b,a ; $08..$0b := rr $08..$0b ?AddH3: mov a,r0 cjne a,$01,?AddH2 ; Wiederholen bis Exponenten gleich RET ; **** 4-Byte-Real-Subtraktion: R2..R5 := R2..R5 - $08..$0b ************** ; Register: A, R2..R5, $08..$0b, MathFlags Sub_GK: xrl $08,#$80 ; Vorzeichenumkehr ; sjmp Add_GK ; R2..R5 := R2..R5 + $08..$0b ; **** 4-Byte-Real-Addition: R2..R5 := R2..R5 + $08..$0b ***************** ; Register: A, R2..R5, $08..$0b, MathFlags Add_GK: push $07 push $06 push $01 push $00 LCALL SplitA ; R0 := Exponent, R2..R5 := Mantisse LCALL SplitB ; R1 := Exponent, $09..$0b := Mantisse mov a,r7 anl a,#ZeroB jnz ?Add3 ; Sprung wenn $08..$0b = 0 mov a,r7 anl a,#ZeroA jz ?Add0 ; Sprung wenn R2..R5 <> 0 mov a,r1 ; sonst: kein Beitrag durch 1.Summand mov r0,a ; Exponent1 := Exponent2 sjmp ?Add1 ?Add0: LCALL Add_Help ; Rechtsverschiebung der Mantisse (kleinerer Exp.) mov a,r7 jnb $e7,?Add1 ; Sprung wenn R2..R5 positiv clr c ; sonst: Komplementbildung clr a subb a,r5 mov r5,a clr a subb a,r4 mov r4,a clr a subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2..R5 := - R2..R5 ?Add1: mov a,r7 ; -> R2..R5 positiv jnb $e6,?Add2 ; Sprung wenn $08..$0b positiv clr c ; sonst: Komplementbildung clr a subb a,$0b mov $0b,a clr a subb a,$0a mov $0a,a clr a subb a,$09 mov $09,a clr a subb a,$08 mov $08,a ; $08..$0b := - $08..$0b ?Add2: mov a,r5 ; -> $08..$0b positiv, jetzt Addieren : add a,$0b mov r5,a mov a,$0a addc a,r4 mov r4,a mov a,$09 addc a,r3 mov r3,a mov a,$08 addc a,r2 mov r2,a ; R2..R5 := R2..R5 + $08..$0b = Ergebnis clr a mov r7,a mov a,r2 jnb $e7,?Add3 ; Sprung wenn R2..R5 positiv mov r7,a ; sonst: Komplementbildung clr c clr a subb a,r5 mov r5,a clr a subb a,r4 mov r4,a clr a subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2..R5 := - R2..R5 ?Add3: LCALL Hid_Bit ; Hiddenbit-Mantisse formen LCALL Ins_Exp ; R2,R3 := (R7.7, rr R0) -> Exp. und Vorzeichen pop $00 pop $01 pop $06 pop $07 RET ; **** Bin„rer-Vergleich: ACC.7 := 1 wenn R2..R5 < $08..$0b ************** ; Register: A, B Comp_Min: mov a,r2 xrl a,$08 jnb $e7,?CMin0 ; Sprung wenn gleiches Vorzeichen mov a,r2 ; sonst verschiedenes Vorzeichen RET ?CMin0: clr c ; -> gleiches Vorzeichen mov a,r2 subb a,$08 ; Test: R2 - $08 jnz ?CMin2 mov a,r3 subb a,$09 ; Test: R3 - ($09 + C) jnz ?CMin2 mov a,r4 subb a,$0a ; Test: R4 - ($0a + C) jnz ?CMin2 mov a,r5 subb a,$0b ; Test: R5 - ($09 + C) jnz ?CMin2 ?CMin1: RET ; ACC = 0, d.h. gleich ! ?CMin2: jnc ?CMin3 ; -> Sprung wenn kein Unterlauf, d.h. R2..R5 gr”áer mov a,#$ff ; ACC := -1 sjmp ?CMin4 ?CMin3: mov a,#$01 ; -> kein Unterlauf: ACC := 1 ?CMin4: mov $f0,r2 ; -> Unterlauf, B := R2 jnb $f7,?CMin1 ; Sprung wenn positive Zahlen cpl $e7 ; sonst -> ja RET ; **** 4-Byte-Real-Multiplikation : R2..R5 := R2..R5 * $08..$0b ********** ; Register: A, R2..R5, $08..$0b, $0c..$0f Mult_GK: push $07 push $06 push $01 push $00 LCALL SplitA ; R0 := Exponent, R2..R5 := Mantisse LCALL SplitB ; R1 := Exponent, $09..$0b := Mantisse clr a mov $0c,a mov $0d,a mov $0e,a mov $0f,a ; $0c..$0f := 0 = Rechenregister mov r6,#$07 ; 7 Durchl„ufe Schleife 1 mov a,r7 anl a,#ZeroA|ZeroB jz ?Mul0 ; Sprung wenn $08..$0b <> 0 und R2..R5 <> 0 ljmp ?Mul6 ; sonst: Ergebnis = 0 ?Mul0: clr c ; -> Beginn Schleife 1: 7 Durchl„ufe mov a,$08 ; Funktion: $0c..$0f := R2..R5 * $0b.[6..0] rrc a ; Rechtsverschiebung $08..$0b: mov $08,a mov a,$09 rrc a mov $09,a mov a,$0a rrc a mov $0a,a mov a,$0b rrc a mov $0b,a ; $08..$0b := rr $08..$0b jnc ?Mul1 ; Sprung wenn LSB = 0 mov a,r5 add a,$0f mov $0f,a mov a,$0e addc a,r4 mov $0e,a mov a,$0d addc a,r3 mov $0d,a mov a,$0c addc a,r2 mov $0c,a ; $0c..$0f := $0c..$0f + R2..R5 ?Mul1: mov a,r5 ; -> Addition bersprungen add a,r5 ; jetzt Linksverschiebung R2..R5: mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a mov a,r2 rlc a mov r2,a ; R2..R5 := rl R2..R5 djnz r6,?Mul0 ; Ende Schleife 1 mov r6,#$11 sjmp ?Mul3 ?Mul2: clr c ; -> Beginn Schleife 2: 17 Durchl„ufe mov a,$0c ; Funktion: $0c..$0f := R2..R5 * $08..$0b.7 rrc a ; Rechtsverschiebung $0c..$0f : mov $0c,a mov a,$0d rrc a mov $0d,a mov a,$0e rrc a mov $0e,a mov a,$0f rrc a mov $0f,a ; $0c..$0f := rr $0c..$0f ?Mul3: clr c ; -> Einsprung Schleife 2 mov a,$08 ; Rechtsverschiebung $08..$0b : rrc a mov $08,a mov a,$09 rrc a mov $09,a mov a,$0a rrc a mov $0a,a mov a,$0b rrc a mov $0b,a ; $08..$0b := rr $08..$0b jnc ?Mul4 ; Sprung wenn LSB = 0 mov a,r5 ; sonst: Addition add a,$0f mov $0f,a mov a,$0e addc a,r4 mov $0e,a mov a,$0d addc a,r3 mov $0d,a mov a,$0c addc a,r2 mov $0c,a ; $0c..$0f := $0c..$0f + R2..R5 ?Mul4: djnz r6,?Mul2 ; -> Addition bersprungen, Ende Schleife 2 mov r2,a mov r3,$0d mov r4,$0e mov r5,$0f ; R2..R5 := $0c..$0f = Mantisse ; SJMP ?Mul8 ; šberlauf/Unterlauf-Prfung berspringen clr c jnb $e7,?Mul5 ; Sprung wenn kein šbertrag setb c ; sonst: bei šbertrag wird Exponent gr”áer ?Mul5: mov a,r0 ; Exponenten-šberlauf/Unterlauf prfen: addc a,r1 jnc ?Mul7 ; Sprung wenn Unterlauf m”glich add a,#$82 ; sonst: šberlauf prfen, d.h. Summe <= 7d jnc ?Mul8 ; Sprung wenn nicht zu groá ?Mul6: clr a ; -> sonst: alles 0 mov r2,a mov r3,a mov r4,a mov r5,a sjmp ?Mul9 ; und fertig ?Mul7: add a,#$80 ; -> Unterlauf prfen, d.h. Summe >= 80 jc ?Mul8 ; Sprung wenn nicht zu klein orl $07,#ExpUF ; Unterlauf anzeigen ?Mul8: mov a,r0 ; -> kein Unterlauf/šberlauf add a,r1 add a,#$7a ; 7-fache Linksversch. - Offset 7f = -86H = 7aH mov r0,a ; R0 := R0 + R1 + #$7a = Exponent mov a,r7 anl a,#SignB ; ACC.6 := Vorzeichen 2 rl a xrl $07,a ; R7.7 := R7.6 xrl R7.7 = Vorzeichen LCALL Hid_Bit ; Hiddenbit-Mantisse formen LCALL Ins_Exp ; R2,R3 := (R7.7, rr R0) -> Exp. und Vorzeichen ?Mul9: pop $00 pop $01 pop $06 pop $07 RET ; **** 4-Byte-Real-Division: R2..R5 := R2..R5 / $08..$0b ***************** ; Register: A, R2..R5, $08..$0b, $0c..$0f Div_GK: push $07 push $06 push $01 push $00 LCALL SplitA ; R0 := Exponent, R2..R5 := Mantisse LCALL SplitB ; R1 := Exponent, $09..$0b := Mantisse clr a mov $0c,a mov $0d,a mov $0e,a mov $0f,a ; $0c..$0f := 0 = Rechenregister mov r6,#$1a ; 26 (31) Durchl„ufe mov a,r7 anl a,#ZeroA|ZeroB jz ?Div_0 ; Sprung wenn $08..$0b <> 0 und R2..R5 <> 0 ljmp ?Div6 ; sonst: Ergebnis = 0 ?Div_0: mov a,r1 jnz ?Div_2 ; Sprung wenn r1 <> 0 ; sonst Linksverschiebung $09..$0b mov a,$09 jb $e7,?Div_2 ; Sprung wenn $09.7 = 1 ?Div_1: inc r0 clr c mov a,$0b rlc a mov $0b,a mov a,$0a rlc a mov $0a,a mov a,$09 rlc a mov $09,a jnb $e7,?Div_1 ; Sprung wenn $09.7 = 0 ?Div_2: mov a,r3 jb $e7,?Div0 ; Sprung wenn R3.7 = 1 ?Div_3: inc r1 clr c mov a,r5 rlc a mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a jnb $e7,?Div_3 ; Sprung wenn R3.7 = 0 ?Div0: mov a,$0f ; -> Beginn Schleife: 26 (31) Durchl„ufe add a,$0f ; Division durch stellenweise Subtraktion mov $0f,a ; Linksverschiebung $0c..$0f : mov a,$0e ; Einschieben von 0/1 bei $0f.0 rlc a ; je nach Ergebnis des Gr”áenvergleichs mov $0e,a mov a,$0d rlc a mov $0d,a mov a,$0c rlc a mov $0c,a ; $0c..$0f := rl $0c..$0f clr c mov a,r2 subb a,$08 ; Test: R2 - $08 jc ?Div2 ; Sprung wenn $08..$0b gr”áer: keine Subtraktion jnz ?Div1 ; Sprung wenn nicht gleich: Subtraktion mov a,r3 subb a,$09 ; Test: R2 - $08 jc ?Div2 ; Sprung wenn $08..$0b gr”áer: keine Subtraktion jnz ?Div1 ; Sprung wenn nicht gleich: Subtraktion mov a,r4 subb a,$0a ; Test: R2 - $08 jc ?Div2 ; Sprung wenn $08..$0b gr”áer: keine Subtraktion jnz ?Div1 ; Sprung wenn nicht gleich: Subtraktion mov a,r5 subb a,$0b ; Test: R2 - $08 jc ?Div2 ; Sprung wenn $08..$0b gr”áer: keine Subtraktion ?Div1: mov a,r5 ; -> R2..R5 > $08..$0b, jetzt Subtraktion: subb a,$0b mov r5,a mov a,r4 subb a,$0a mov r4,a mov a,r3 subb a,$09 mov r3,a mov a,r2 subb a,$08 mov r2,a ; R2..R5 := R2..R5 - $08..$0b orl $0f,#$01 ; $0f.0 := 1 ?Div2: mov a,r5 ; -> Subtraktion bersprungen add a,r5 mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a mov a,r2 rlc a mov r2,a ; R2..R5 := rl R2..R5 djnz r6,?Div0 mov r2,$0c mov r3,$0d mov r4,$0e mov r5,$0f ; Exponenten-Unterlauf/šberlauf prfen: ; sjmp ?Div8 ; šberlauf/Unterlauf-Prfung berspringen mov a,r2 clr c jb $e1,?Div5 ; Sprung wenn kein Unterlauf setb c ; sonst: bei Unterlauf wird Exponent kleiner ?Div5: mov a,r0 ; Exponenten-šberlauf/Unterlauf prfen: subb a,r1 jc ?Div7 ; Sprung wenn Unterlauf m”glich add a,#$80 ; sonst šberlauf prfen, d.h. r0 - r1 - c <= 7f jnc ?Div8 ; Sprung wenn nicht zu groá ?Div6: clr a ; -> sonst: alles 0 mov r2,a mov r3,a mov r4,a mov r5,a sjmp ?Div9 ; und fertig ?Div7: add a,#$7e ; -> Unterlauf prfen, d.h. r0 - r1 >= 82 = -7e jc ?Div8 ; Sprung wenn nicht zu klein orl $07,#ExpUF ; Unterlauf anzeigen ?Div8: clr c ; -> kein Unterlauf/šberlauf mov a,r0 subb a,r1 add a,#$7d ; 2(7)-fache Linksversch. + Offset 7f = 7d (78H) mov r0,a ; R0 := R0 - R1 + #$7d (78) mov a,r7 anl a,#SignB ; ACC.6 := Vorzeichen 2 rl a xrl $07,a ; R7.7 := R7.6 xrl R7.7 = Vorzeichen LCALL Hid_Bit ; Hiddenbit-Mantisse formen LCALL Ins_Exp ; R2,R3 := (R7.7, rr R0) -> Exp. und Vorzeichen ?Div9: pop $00 pop $01 pop $06 pop $07 RET ; **** Konvertierung: R2..R5 := dword-integer(R2..R5) ******************** ; Register: A, R2..R5 GK_Int32: push $07 push $06 push $01 push $00 LCALL SplitA ; R0 := Exponent, R2..R5 := Mantisse, R7 := Sign mov a,r0 add a,#$82 jb $e7,?GKI0 ; Sprung wenn negativer Exponent mov a,r0 add a,#$6a jb $e7,?GKI5 ; Sprung wenn Mantisse zu groá -> R0 < 7f + 23 mov r0,a ; -> Mantisse zu klein add a,#$f8 jnc ?GKI3 ; Sprung wenn Exponent < 7f + 23 + 8 ; sonst: Bereichsberschreitung ?GKI0: clr a ; -> negativer Exponent: < 1 -> 0 mov r2,a mov r3,a mov r4,a mov r5,a ?GKI1: mov a,r7 ; -> fertig jnb $e7,?GKI2 ; Sprung wenn positive Zahl clr c ; sonst: Komplementbildung clr a subb a,r5 mov r5,a clr a subb a,r4 mov r4,a clr a subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2..R5 := - R2..R5 ?GKI2: pop $00 pop $01 pop $06 pop $07 RET ?GKI3: mov a,r0 ; -> Linksverschiebung mov r6,a jz ?GKI1 ?GKI4: mov a,r5 ; -> Schleifen-Beginn add a,r5 mov r5,a mov a,r4 rlc a mov r4,a mov a,r3 rlc a mov r3,a mov a,r2 rlc a mov r2,a djnz r6,?GKI4 ; R2..R5 := rlc R2..R5 (r6-fach) sjmp ?GKI1 ; Sprung ! -> fertig ?GKI5: cpl a ; -> Rechtsverschiebung add a,#$01 mov r6,a jz ?GKI1 ?GKI6: mov a,r2 ; -> Schleifen-Beginn clr c rrc a mov r2,a mov a,r3 rrc a mov r3,a mov a,r4 rrc a mov r4,a mov a,r5 rrc a mov r5,a djnz r6,?GKI6 ; R2..R5 := rrc R2..R5 (r6-fach) sjmp ?GKI1 ; Sprung ! -> fertig ; ************************************************************************ ; **** Konvertierung: R2..R5 := GK(R5) *** vorzeichenbeh.***************** ; Register: A, R2..R5 Int8S_GK: mov a,r5 rlc a mov r4,a subb a,r4 mov r4,a ; R2..R4 := 0 wenn positive Zahl mov r3,a ; R2..R4 := #$ffffff wenn negative Zahl mov r2,a sjmp Int32S_GK ; Konvertierung: R2..R5 := GK(R2..R5) ; **** Konvertierung: R2..R5 := GK(R4,R5) *** vorzeichenbeh.************** ; Register: A, R2..R5 Int16S_GK: mov a,r4 ; R2,R3 := 0 wenn positive Zahl rlc a ; R2,R3 := #$ffff wenn negative Zahl mov r3,a subb a,r3 mov r3,a ; R3 := 0 - R4.7 mov r2,a ; **** Einsprung/Fortsetzung Konv.: R2..R5 := GK(R2..R5) *** vorzbeh.***** ; Register: A, R2..R5 Int32S_GK: push $07 push $06 push $01 push $00 mov a,r2 anl a,#$80 mov r7,a ; R7.7 := Vorzeichen jnb $e7,?Posi ; Sprung wenn positive Zahl clr c ; sonst Komplement bilden clr a subb a,r5 mov r5,a clr a subb a,r4 mov r4,a clr a subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2..R5 := - R2..R5 ?Posi: mov r0,#$96 ; Exponentenverschiebung #$7f + 23 Stellen = #$96 LCALL Hid_Bit ; Hiddenbit-Mantisse formen LCALL Ins_Exp ; R2,R3 := (R7.7, rr R0) -> Exp. und Vorzeichen pop $00 pop $01 pop $06 pop $07 RET ; **** Konvertierung: 1/2/4-Byte(vorzeichenlos) -> IEEE-4-Byte-Gleitkomma ; Register: A, R2..R5 Int8_GK: mov r4,#$00 ;Einsprung UP: R2..R5 := 4-Byte-GK (R5) Int16_GK: clr a ;Einsprung UP: R2..R5 := 4-Byte-GK (R4,R5) mov r3,a mov r2,a Int32_GK: push $07 ;Einsprung UP: R2..R5 := 4-Byte-GK (R2..R5) push $06 push $01 push $00 mov r7,#$00 sjmp ?Posi ; **** R2,R3 := R2,R3 div R4,R5 ****************************************** ; R4,R5 := R2,R3 mod R4,R5 ; Register: A, B, R0, R1, R2..R5 Div_Mod_16: clr a mov $f0,a ; B := 0 mov r0,a mov r1,a ; R0,R1 := 0 mov a,r2 orl a,r3 jz ?DM16_8 ; Sprung wenn R2,R3 = 0 mov a,r4 orl a,r5 jnz ?DM16_3 ; Sprung wenn R4,R5 <> 0 RET ; sonst: R4,R5 = 0 -> Division durch 0 ; ***** Verschiebe R4,R5 solange nach links, bis R4,R5 > R2,R3 *********** ?DM16_1:mov a,r2 ; Beginn Schleife1: R4,R5 := 2 * R4,R5, B := B + 1 clr c subb a,r4 jc ?DM16_4 ; Sprung wenn R4 > R2 -> Schleife verlassen jnz ?DM16_2 ; Sprung wenn R2 > R4 -> R3,R5 nicht prfen mov a,r3 ; sonst: R4 = R2 -> R3,R5 prfen subb a,r5 jc ?DM16_4 ; Sprung wenn R4,R5 > R2,R3 -> Schleife verlassen ?DM16_2:mov a,r5 ; -> R2 > R4 clr c rlc a mov r5,a mov a,r4 rlc a mov r4,a ; R4,R5 := 2 * R4,R5 ?DM16_3:inc $f0 ; -> Einsprung in Schleife1: in B mitz„hlen mov a,r4 jnb $e7,?DM16_1 ; Ende Schleife1: Rcksprung solange R4.7 = 0 ; ***** stellenweise Subtraktion: **************************************** ?DM16_4:mov a,r2 ; Beginn Schleife2: -> R4,R5 > R2,R3 clr c ; probeweise Subtraktion: R2,R3 - R4,R5 subb a,r4 ; ACC := R2 - R4 jc ?DM16_5 ; Sprung wenn R4 > R2 jnz ?DM16_6 ; Sprung wenn R2 > R4 mov a,r3 ; R2 = R4 subb a,r5 ; ACC := R3 - R5 jnc ?DM16_6 ; Sprung wenn R3 >= R5 ?DM16_5:clr c ; in R0,R1 eine Null einschieben sjmp ?DM16_7 ; und Subtraktion berspringen ?DM16_6:clr c ; -> stellenweise Subtraktion, wenn R2,R3 >= R4,R5 mov a,r3 subb a,r5 mov r3,a mov a,r2 subb a,r4 mov r2,a ; R2,R3 := R2,R3 - R4,R5 -> Rest setb c ; in R0,R1 eine Eins einschieben ?DM16_7: ; -> R2,R3 < R4,R5 , C = 0 mov a,r1 rlc a mov r1,a mov a,r0 rlc a mov r0,a ; R0,R1 := rlc R0,R1 -> Quotient mov a,r4 clr c rrc a mov r4,a mov a,r5 rrc a mov r5,a ; R4,R5 := rrc R4,R5 mit C = 0 djnz $f0,?DM16_4 ; Ende Schleife2: Rcksprung wenn B > 1 ?DM16_8:mov $05,r3 ; -> R2,R3 = 0 mov $04,r2 ; R4,R5 := R2,R3 -> Rest mov $02,r0 mov $03,r1 ; R2,R3 := R0,R1 -> Quotient RET ; **** R2,R3 := (R2,R3) div (R4,R5) *** vorzeichenlos ******************** ; Register: A, B, R2..R5 Div_16: push $00 push $01 LCALL Div_Mod_16 ; R2,R3/R4,R5 := R2,R3 div/mod R4,R5 pop $01 pop $00 RET ; **** R2,R3 := (R2,R3) mod (R4,R5) *** vorzeichenlos ******************** ; Register: A, B, R2..R5 Mod_16: push $00 push $01 LCALL Div_Mod_16 ; R2,R3/R4,R5 := R2,R3 div/mod R4,R5 pop $01 pop $00 mov $02,r4 mov $03,r5 RET ; **** Betrag: R2,R3 := |R2,R3| und R4,R5 := |R4,R5| ********************* ; Register: A, B, R2..R5 Betrag: mov a,r2 jnb $e7,?Betr0 ; Sprung wenn R2,R3 positiv clr a clr c subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2,R3 := - R2,R3 ?Betr0: mov a,r4 jnb $e7,?Betr1 ; Sprung wenn R4,R5 positiv -> fertig clr a clr c subb a,r5 mov r5,a clr a subb a,r4 mov r4,a ; R4,R5 := - R4,R5 ?Betr1: RET ; **** R2,R3 := (R2,R3) mod (R4,R5) *** vorzeichenbehaftet *************** ; Register: A, B, R2..R5 Mod_16S: push $00 push $01 mov a,r4 xrl a,r2 ; ACC.7 := 0 bei gleichem Vorzeichen push $e0 ; Vorzeichen-Info retten LCALL Betrag ; R2,R3 := |R2,R3| und R4,R5 := |R4,R5| LCALL Div_Mod_16 ; R2,R3/R4,R5 := R2,R3 div/mod R4,R5 mov $02,r4 mov $03,r5 sjmp ?Sign0 ; Vorzeichenkorrektur ; **** R2,R3 := (R2,R3) div (R4,R5) *** vorzeichenbehaftet *************** ; Register: A, B, R2..R5 Div_16S: push $00 push $01 mov a,r4 xrl a,r2 ; ACC.7 := 0 bei gleichem Vorzeichen push $e0 ; Vorzeichen-Info retten LCALL Betrag ; R2,R3 := |R2,R3| und R4,R5 := |R4,R5| LCALL Div_Mod_16 ; R2,R3/R4,R5 := R2,R3 div/mod R4,R5 ?Sign0: pop $e0 ; Vorzeichen-Info holen jnb $e7,?Sign1 ; Sprung wenn gleiches Vorzeichen clr a ; sonst: Ergebnis invertieren clr c subb a,r3 mov r3,a clr a subb a,r2 mov r2,a ; R2,R3 := - R2,R3 ?Sign1: pop $01 pop $00 RET ; **** Vergleich: ACC := 0 wenn (R2..R5) = ($08..$0b) ******************** ; Register: A Comp_Equ: clr c mov a,r2 subb a,$08 jz ?CEqu0 jnb $d2,?CEqu2 ; fertig wenn kein Wertebereichs-šberlauf cpl $e7 ; ACC.7 invertieren sjmp ?CEqu2 ; fertig ?CEqu0: mov a,r3 subb a,$09 jnz ?CEqu1 mov a,r4 subb a,$0a jnz ?CEqu1 mov a,r5 subb a,$0b jz ?CEqu2 ?CEqu1: setb $e0 mov $e7,c ; negativ bei Carry ?CEqu2: RET ; ***** R2..R5 := R2..R5 div $08..$0b ************************************ ; $08..$0b := R2..R5 mod $08..$0b ; Register: A, R2..R5, $08..$0b, $0c..$0f Div_Mod_32: push $00 clr a mov r0,a ; R0 := 0 mov $0c,a mov $0d,a mov $0e,a mov $0f,a ; $0c..$0f := 0 mov a,r5 orl a,r4 orl a,r3 orl a,r2 jnz ?DM32_0 ; Sprung wenn R2..R5 <> 0 LJMP ?DM32_8 ; $08..$0b := R2..R5 = 0 und fertig ?DM32_0:mov a,$08 orl a,$09 orl a,$0a orl a,$0b jnz ?DM32_3 ; Sprung wenn $08..$0b <> 0 pop $00 RET ; R2..R5 = 0 und $08..$0b = 0, fertig ; ***** Verschiebe R2..R5 solange nach links, bis R2..R5 > $08..$0b ****** ?DM32_1:mov a,r2 ; -> Begin Schleife1 clr c subb a,$08 jc ?DM32_4 ; Schleife verlassen wenn $08..$0b > R2..R5 jnz ?DM32_2 ; Sprung wenn noch zu klein mov a,r3 subb a,$09 jc ?DM32_4 ; Schleife verlassen wenn $08..$0b > R2..R5 jnz ?DM32_2 ; Sprung wenn noch zu klein mov a,r4 subb a,$0a jc ?DM32_4 ; Schleife verlassen wenn $08..$0b > R2..R5 jnz ?DM32_2 ; Sprung wenn noch zu klein mov a,r5 subb a,$0b jc ?DM32_4 ; Schleife verlassen wenn $08..$0b > R2..R5 ?DM32_2:mov a,$0b ; -> Linksverschiebung von $08..$0b add a,$0b mov $0b,a mov a,$0a addc a,$0a mov $0a,a mov a,$09 addc a,$09 mov $09,a mov a,$08 addc a,$08 mov $08,a ; $08..$0b := 2 * ($08..$0b) ?DM32_3:inc r0 ; -> Einsprung Schleife1, in R0 mitz„hlen mov a,$08 jnb $e7,?DM32_1 ; Ende Schleife1: Rcksprung wenn $08.7 = 0 ; ***** stellenweise Subtraktion: **************************************** ?DM32_4:mov a,$08 ; Beginn Schleife 2 clr c subb a,r2 ; Test ob $08..$0b > R2..R5 jc ?DM32_6 jnz ?DM32_5 mov a,$09 subb a,r3 jc ?DM32_6 jnz ?DM32_5 mov a,$0a subb a,r4 jc ?DM32_6 jnz ?DM32_5 mov a,$0b subb a,r5 jc ?DM32_6 jz ?DM32_6 ?DM32_5:clr c ; in $0c..$0f eine Null einschieben sjmp ?DM32_7 ; und Subtraktion berspringen ?DM32_6:clr c ; -> stellenweise Subtraktion, wenn R2..R5 >= $08..$0b mov a,r5 subb a,$0b mov r5,a mov a,r4 subb a,$0a mov r4,a mov a,r3 subb a,$09 mov r3,a mov a,r2 subb a,$08 mov r2,a ; R2..R5 := R2..R5 - $08..$0b -> Rest setb c ; in $0c..$0f eine Eins einschieben ?DM32_7:mov a,$0f ; -> $08..$0b > R2..R5, C = 0 rlc a ; C in in $0c..$0f schieben mov $0f,a mov a,$0e rlc a mov $0e,a mov a,$0d rlc a mov $0d,a mov a,$0c rlc a mov $0c,a ; $0c..$0f := rlc $0c..$0f -> Quotient mov a,$08 clr c rrc a mov $08,a mov a,$09 rrc a mov $09,a mov a,$0a rrc a mov $0a,a mov a,$0b rrc a ; $08..$0b := rrc $08..$0b mov $0b,a djnz r0,?DM32_4 ; Ende Schleife 2: Rcksprung wenn R0 > 1 ?DM32_8:mov $0b,r5 ; -> wenn R2..R5 = 0 mov $0a,r4 mov $09,r3 mov $08,r2 ; $08..$0b := R2..R5 -> Rest mov r5,$0f mov r4,$0e mov r3,$0d mov r2,$0c ; R2..R5 := $0c..$0f -> Quotient pop $00 RET ; **** R2,R3 := (R2,R3) * (R4,R5) **************************************** ; Register: A, B, R2..R5 Mult_16: push $00 push $01 mov a,r5 mov $f0,r3 mul ab mov r0,a mov r1,$f0 ; R1,R0 := R3 * R5 mov a,r5 mov $f0,r2 mul ab add a,r1 mov r1,a ; R1 := R1 + R2 * R5 mov a,r4 mov $f0,r3 mul ab add a,r1 mov r2,a ; R2 := R1 + R3 * R4 mov a,r0 mov r3,a ; R3 := R0 pop $01 pop $00 RET ; **** R2..R5 := (R2..R5) * ($08..$0b) *********************************** ; Register: A, B, R2..R5, $08..$0b, $0c..$0f Mult_32: mov a,r5 mov $f0,$0b mul ab ; r5 * $0a mov $0f,a ; $0f := Low(r5*$0b) mov $0e,$f0 ; $0e := High(r5*$0b) mov a,r5 mov $f0,$0a mul ab ; r5 * $0a * #$100 add a,$0e mov $0e,a ; $0e := $0e + Low(r5*$0a) mov a,$f0 addc a,#$00 mov $0d,a ; $0d := High(r5*$0a)+C mov a,r5 mov $f0,$09 mul ab ; r5 * $09 * #$10000 add a,$0d mov $0d,a ; $0d := $0d + Low(r5*$09) mov a,$f0 addc a,#$00 mov $0c,a ; $0c := High(r5*$09)+C mov a,r5 mov $f0,$08 mul ab ; r5 * $08 * #$1000000 add a,$0c mov $0c,a ; $0c := $0c + Low(r5*$08) mov a,r4 mov $f0,$0b mul ab ; r4 * $0b * #$100 add a,$0e mov $0e,a ; $0e := $0e + Low(r4*$0b) mov a,$f0 addc a,$0d mov $0d,a ; $0d := $0d + High(r4*$0b)+C mov a,$0c addc a,#$00 mov $0c,a ; $0c := $0c + C mov a,r4 mov $f0,$0a mul ab ; r4 * $0a * #$10000 add a,$0d mov $0d,a ; $0d := $0d + Low(r4*$0a) mov a,$f0 addc a,$0c mov $0c,a ; $0c := $0c + High(r4*$0a)+C mov a,r4 mov $f0,$09 mul ab ; r4 * $09 * #$1000000 add a,$0c mov $0c,a ; $0c := $0c + Low(r4*$09) mov a,r3 mov $f0,$0b mul ab ; r3 * $0b * #$10000 add a,$0d mov $0d,a ; $0d := $0d + Low(r3*$0b) mov a,$f0 addc a,$0c mov $0c,a ; $0c := $0c + High(r3*$0b)+C mov a,r3 mov $f0,$0a mul ab ; r3 * $0a * #$1000000 add a,$0c mov $0c,a ; $0c := $0c + Low(r3*$0a) mov a,r2 mov $f0,$0b mul ab ; r2 * $0b * #$1000000 add a,$0c mov r2,a ;r2 := $0c + Low(r2*$0b) mov r3,$0d ;r3 := $0d mov r4,$0e ;r4 := $0e mov r5,$0f ;r5 := $0f RET ;