; ***************************************** ; * Konvertiere LONG-INTEGER in ; * single-precision-Fliesskomma ; * Parameter: Operand ueber Stack ; * Ergebnis: in BC-DE: MSB in B, LSB in E ; * ; Aus KONV.MAC ; op1 equ 4 ; jetzt Offset-Definitionen fuer bias equ 127 ; Bias des Exponenten maxexpo equ 255 ; Maximal zulaessiger Exponent ext f_stack,f_hl,start f_ltof: push hl ; alten Basepointer retten ld (f_stack),sp ; aktuellen Stackpointer abspeichern ld hl,(f_stack) ; und in HL laden (= Basepointer) push af ; benoetigte Register retten ld bc,op1 add hl,bc ; Offset fuer Operand addieren ld b,(hl) ; Operand in Register laden inc hl ; Reihenfolge: CDEB ld e,(hl) ; (erspart spaeter Vertauschungen) inc hl ld d,(hl) inc hl ld c,(hl) ld h,c ; Vorzeichen in H, Bit 7 xor a ; A = 0 cp b ; Operand = 0? jr nz,lf_noz cp e jr nz,lf_noz cp d jr nz,lf_noz cp c jr z,lf_res ; Ergebnis = Null lf_noz: bit 7,h ; Zahl positiv? jr z,lf_pos ld a,b ; Zahl negieren cpl ; dazu zunaechst das ld b,a ; Einserkomplement bilden, ld a,e ; dann Eins aufaddieren cpl ld e,a ld a,d cpl ld d,a ld a,c cpl ld c,a inc b ; Eins addieren jr nz,lf_pos ; ggf. Uebertraege beruecksichtigen inc e jr nz,lf_pos inc d jr nz,lf_pos inc c lf_pos: ld l,bias+32 ; Exponent vorbesetzen lf_shft:dec l sla b ; Mantisse verschieben, bis rl e ; fuehrende Eins auftaucht rl d rl c jr nc,lf_shft ld b,l ; Exponent einsetzen sla h ; Vorzeichen in Carry rr b ; Ins Ergebnis einschleben rr c rr d rr e lf_res: pop af ; Register restaurieren pop hl ld (f_hl),hl ; Parameter vom Stack deallozieren ex (sp),hl ld sp,(f_stack) push hl ld hl,(f_hl) ret ; und return ; ****************************************** ; * Konvertiere single-precision-Fliesskomma ; * in LONG-INTEGER ; * Parameter: Operand ueber Stack ; * Ergebnis: in BC-DE: MSB in B, LSB in E ; * f_ftol: push hl ; alten Basepointer retten ld (f_stack),sp ; aktuellen Stackpointer abspeichern ld hl,(f_stack) ; und in HL laden (= Basepointer) push af ; benoetigte Register retten ld bc,op1 add hl,bc ; Offset fuer Operand addieren ld d,(hl) ; Operand in Register laden inc hl ; Reihenfolge: EBCD ld c,(hl) ; (erspart spaeter Vertauschungen) inc hl ld b,(hl) inc hl ld e,(hl) ld h,e ; Vorzeichen in H, Bit 7 ld a,e ; Exponent in A aufbauen sla a bit 7,b ; LSB des Exponenten gesetzt? jr z,fl_exz set 0,a ; ggf. Bit 0 setzen fl_exz: sub bias ld l,a ; Exponent nach L kopieren jp m,fl_zero ; falls kleiner Null, Ergebnie Null ld a,30 cp l ; groesser als 30? jr c,fl_over ; dann Ueberlauf set 7,b ; Implizite Eins real machen ld e,0 ; Zahl jetzt in BCDE in der Form inc a ; 1fff ... ffff 0000 0000 fl_shft:srl b ; jetzt Mantisse verschieben rr c rr d rr e inc l cp l ; bis Exponent stimmt jr nz,fl_shft ; (Exponent = 31) bit 7,h ; Zahl negativ? jr z,lf_res ; nein, fertig ld a,e ; Zahl negieren cpl ; dazu zunaechst das ld e,a ; Einserkomplement bilden, ld a,d ; dann Eins aufaddieren cpl ld d,a ld a,c cpl ld c,a ld a,b cpl ld b,a inc e ; Eins addieren jr nz,lf_res ; ggf. Uebertraege beruecksichtigen inc d jr nz,lf_res inc c jr nz,lf_res inc b jp lf_res fl_zero:xor a ; A = 0 ld b,a ld c,a ld d,a ld e,a ; Ergebnif = Null jp lf_res fl_over:bit 7,h ; Ergebnis positiv? jr z,fl_opos ld b,080h ; MININT laden xor a ; A = 0 ld c,a ld d,a ld e,a jp lf_res fl_opos:ld b,07fh ; MAXINT laden ld a,0ffh ld c,a ld d,a ld e,a jp lf_res ; **************************************** ; * Multipliziere eine single-precision ; * Fliesskommazahl mit einer Zweierpotenz ; * Parameter: Operand 1 ueber Stack ; * Operand 2 in Register A ; * Ergebnis: in BC-DE: MSB in B, LSB in E ; * f_mul2: push hl ; alten Basepointer retten ld (f_stack),sp ; aktuellen Stackpointer abspeichern ld hl,(f_stack) ; und in HL laden (= Basepointer) push af ; benoetigte Register retten ld bc,op1 add hl,bc ; Offset fuer Operand addieren ld e,(hl) ; Operand 1 in Register laden inc hl ld d,(hl) inc hl ld c,(hl) inc hl ld b,(hl) ld h,a ; Operand 2 nach H kopieren ld l,b ; Vorzeichen in L, Bit 7 xor a ; A = 0 cp b ; Operand 1 = Null? jr nz,m2_noz cp c jr nz,m2_noz cp d jr nz,m2_noz cp e jr z,m2_zero m2_noz: sla e ; Operand 1 verschieben rl d rl c rl b ; Form eeee eeee ffff ... fff0 jr z,m2_den ; Falls Exponent = Null: --> add a,h ; A = 0 + H jp m,m2_div ; Falls Op2 kleiner Null --> Divisior add a,b ; A = Summe der Exponenten ld b,a ; zurueck nach B jr c,m2_over ; bei Ueberlauf --> cp maxexpo ; oder genau MAXEXPO jr z,m2_over m2_res: sla l ; Vorzeichen in Carry schieben rr b rr c rr d rr e ; Ergebnis zusammensetzen m2_zero:pop af ; Register restaurieren pop hl ld (f_hl),hl ; Parameter vom Stack deallozieren ex (sp),hl ld sp,(f_stack) push hl ld hl,(f_hl) ret ; und return m2_over:ld b,maxexpo ; Ueberlauf: Exponent = Maxexpo xor a ; Mantisse = Null ld c,a ld d,a ld e,a jp m2_res m2_div: add a,b ; A = Summe der Exponenten ld b,a ; zurueck nach B jr z,m2_dv2 jp p,m2_res ; falls > Null, dann Ergebnis ablief. m2_dv2: scf ; implizite Eins real machen rr c rr d rr e ; Form: eeee eeee 1fff ... ffff m2_dnr: xor a ; A = 0 cp b ; Exponent = Null? jr z,m2_res ; ja, Ergebnis abliefern srl c rr d rr e ; Mantisse denormalisieren jr nz,m2_nz2 cp d jr nz,m2_nz2 cp c jr nz,m2_nz2 ld b,a ; totaler Unterlauf, Ergebnis = Null jp m2_zero m2_nz2: inc b ; Exponent erhoehen jp m2_dnr ; weiter denormalisieren m2_ddd: add a,b ; A = Summe der Exponenten ld b,a ; zurueck nach B jp m2_dnr m2_den: add a,h ; A = 0 + H jp m,m2_ddd ; bei Division verzweigen m2_nor: sla e ; Multiplikation: Eine rl d ; denormalisierte Mantisse rl c ; wird wieder normalisiert jr c,m2_stp ; bis fuehrende Eins rausfliegt dec h ; oder Operand 2 = Null jr nz,m2_nor jp m2_res m2_stp: ld a,h ; Summe der Exponenten bilden add a,b ld b,a ; zurueck nach b jp m2_res end start