|
|
@@ -127,7 +127,7 @@ VAR
|
|
|
dataAt : CARDINAL ;
|
|
|
rtBase : CARDINAL ;
|
|
|
built : BOOLEAN ;
|
|
|
- entNm : ARRAY [0..20] OF ARRAY [0..MaxNm] OF CHAR ;
|
|
|
+ entNm : ARRAY [0..21] OF ARRAY [0..MaxNm] OF CHAR ;
|
|
|
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
(* name helpers *)
|
|
|
@@ -553,6 +553,30 @@ PROCEDURE MovAlBl ; BEGIN B (8AH) ; B (0C3H) END MovAlBl ; (* 8A C3: AL:=BL *)
|
|
|
PROCEDURE MovClBx ; BEGIN B (8AH) ; B (0FH) END MovClBx ; (* 8A 0F: CL:=[BX] *)
|
|
|
PROCEDURE XorBxBx ; BEGIN B (31H) ; B (0DBH) END XorBxBx ; (* 31 DB: BX:=0 *)
|
|
|
PROCEDURE MovBlDl ; BEGIN B (8AH) ; B (0DAH) END MovBlDl ; (* 8A DA: BL:=DL *)
|
|
|
+PROCEDURE MovBhAh ; BEGIN B (88H) ; B (0E7H) END MovBhAh ; (* 88 E7: BH:=AH *)
|
|
|
+PROCEDURE MovDxAx ; BEGIN B (89H) ; B (0C2H) END MovDxAx ; (* 89 C2: DX:=AX *)
|
|
|
+PROCEDURE MovSiBp4 ; BEGIN B (8BH) ; B (76H) ; B (4) END MovSiBp4 ; (* SI:=[BP+4] *)
|
|
|
+PROCEDURE MovSiBp6 ; BEGIN B (8BH) ; B (76H) ; B (6) END MovSiBp6 ; (* SI:=[BP+6] *)
|
|
|
+PROCEDURE LdAxSi ; BEGIN B (8BH) ; B (04H) END LdAxSi ; (* 8B 04: AX:=[SI] *)
|
|
|
+PROCEDURE StDiOffBx (off : CARDINAL) ;
|
|
|
+BEGIN B (89H) ; B (5DH) ; B (off MOD 256) END StDiOffBx ; (* MOV [DI+o],BX *)
|
|
|
+PROCEDURE StDiOffDx (off : CARDINAL) ;
|
|
|
+BEGIN B (89H) ; B (55H) ; B (off MOD 256) END StDiOffDx ; (* MOV [DI+o],DX *)
|
|
|
+PROCEDURE Js8 (nm : ARRAY OF CHAR ) ; BEGIN Jcc (78H, nm) END Js8 ;
|
|
|
+PROCEDURE Jns8 (nm : ARRAY OF CHAR ) ; BEGIN Jcc (79H, nm) END Jns8 ;
|
|
|
+PROCEDURE Jmp8 (nm : ARRAY OF CHAR ) ;
|
|
|
+BEGIN B (0EBH) ; AddFix (0, rpos, nm, 0) ; B (0) END Jmp8 ;
|
|
|
+PROCEDURE MovAxImm (v : CARDINAL ) ; BEGIN B (0B8H) ; W (v) END MovAxImm ;
|
|
|
+PROCEDURE XchgDlDh ; BEGIN B (86H) ; B (0D6H) END XchgDlDh ; (* 86 D6: DL<->DH *)
|
|
|
+PROCEDURE DecAl ; BEGIN B (0FEH) ; B (0C8H) END DecAl ; (* FE C8 *)
|
|
|
+PROCEDURE ShlDx1 ; BEGIN B (0D1H) ; B (0E2H) END ShlDx1 ; (* D1 E2: SHL DX,1 *)
|
|
|
+PROCEDURE NegDx ; BEGIN B (0F7H) ; B (0DAH) END NegDx ; (* F7 DA: NEG DX *)
|
|
|
+PROCEDURE CmpDh0 ; BEGIN B (80H) ; B (0FEH) ; B (0) END CmpDh0 ; (* 80 FE 00 *)
|
|
|
+PROCEDURE CmpBh0 ; BEGIN B (80H) ; B (0FFH) ; B (0) END CmpBh0 ; (* 80 FF 00 *)
|
|
|
+PROCEDURE CmpDx0 ; BEGIN B (83H) ; B (0FAH) ; B (0) END CmpDx0 ; (* 83 FA 00 *)
|
|
|
+PROCEDURE CmpAl0 ; BEGIN B (3CH) ; B (0) END CmpAl0 ; (* 3C 00 *)
|
|
|
+PROCEDURE AndDhImm (v : CARDINAL) ;
|
|
|
+BEGIN B (80H) ; B (0E6H) ; B (v MOD 256) END AndDhImm ; (* 80 E6 imm *)
|
|
|
PROCEDURE StVxBx (delta : CARDINAL ) ;
|
|
|
(* 89 1E lo hi: MOV [Vx],BX - the mirror of LdBxVx above, and it must use the
|
|
|
same mod=00 / rm=110 and the same Dd fixup kind, or one of the two
|
|
|
@@ -1390,6 +1414,74 @@ BEGIN
|
|
|
END
|
|
|
END Str5 ;
|
|
|
|
|
|
+PROCEDURE EmitRealFromInt ;
|
|
|
+(* intreal (TPSRC3 130): an INTEGER -> the 6-byte MBF real.
|
|
|
+
|
|
|
+ ABI: the source word's ADDRESS is at [BP+6] and the destination's at
|
|
|
+ [BP+4]; the caller pushes the source first, so [BP+6] is the source. (The
|
|
|
+ reference keeps the real in AX/BX/DX, where AL is the exponent byte, AH
|
|
|
+ and BX the low 39 mantissa bits and DX the high 16 with the sign in DH's
|
|
|
+ bit 7. Packing is therefore just the two stores.)
|
|
|
+
|
|
|
+ The arithmetic is the reference's, instruction for instruction:
|
|
|
+
|
|
|
+ zero -> all six bytes zero
|
|
|
+ sign -> BH, DX := |value|
|
|
|
+ AX := 0090h (exponent 144, clear mantissa)
|
|
|
+ small value: exponent 88h and shift the mantissa 8
|
|
|
+ normalise: shift DX left and decrement AL until DX's sign bit is set
|
|
|
+ positive: clear DH bit 7; negative: leave it as the sign
|
|
|
+ clear the rest of the mantissa (BX)
|
|
|
+
|
|
|
+ The sign convention here is the packed one: bit 7 of the last byte is the
|
|
|
+ sign, and the implicit 1 is not stored. That is why intreal leaves DX's
|
|
|
+ top bit alone for negatives (it becomes the sign) and clears it for
|
|
|
+ positives. *)
|
|
|
+BEGIN
|
|
|
+ M ("real_from_int") ;
|
|
|
+ PushBp ; MovBpSp ;
|
|
|
+ PushBx ; PushDx ; PushSi ; PushDi ;
|
|
|
+ MovSiBp6 ; (* SI := source word *)
|
|
|
+ LdAxSi ; (* AX := the integer *)
|
|
|
+ CmpAx0 ;
|
|
|
+ Jne8 ("rf_nz") ;
|
|
|
+ XorBxBx ;
|
|
|
+ XorDxDx ;
|
|
|
+ Jmp8 ("rf_store") ;
|
|
|
+ M ("rf_nz") ;
|
|
|
+ MovBhAh ; (* BH := the integer's sign byte *)
|
|
|
+ MovDxAx ;
|
|
|
+ CmpDx0 ;
|
|
|
+ Jns8 ("rf_pos") ;
|
|
|
+ NegDx ;
|
|
|
+ M ("rf_pos") ;
|
|
|
+ MovAxImm (0090H) ; (* AL = exponent 144, AH = 0 *)
|
|
|
+ CmpDh0 ;
|
|
|
+ Jne8 ("rf_16") ;
|
|
|
+ MovAlD (088H) ; (* 16-bit value in the top byte: bias 88 *)
|
|
|
+ XchgDlDh ;
|
|
|
+ M ("rf_16") ;
|
|
|
+ CmpDx0 ;
|
|
|
+ Js8 ("rf_done") ;
|
|
|
+ M ("rf_nrm") ;
|
|
|
+ DecAl ;
|
|
|
+ ShlDx1 ;
|
|
|
+ Jns8 ("rf_nrm") ;
|
|
|
+ M ("rf_done") ;
|
|
|
+ CmpBh0 ;
|
|
|
+ Js8 ("rf_pos2") ;
|
|
|
+ AndDhImm (7FH) ; (* positive: bit 7 of DH is not a sign *)
|
|
|
+ M ("rf_pos2") ;
|
|
|
+ XorBxBx ; (* only DX's 16 bits carry the value now *)
|
|
|
+ M ("rf_store") ;
|
|
|
+ MovDiBp4 ; (* DI := the destination *)
|
|
|
+ StDiAx ; (* bytes 0..1 *)
|
|
|
+ StDiOffBx (2) ; (* bytes 2..3 *)
|
|
|
+ StDiOffDx (4) ; (* bytes 4..5, sign in DH bit 7 *)
|
|
|
+ PopDi ; PopSi ; PopDx ; PopBx ;
|
|
|
+ MovSpBp ; PopBp ; RetR
|
|
|
+END EmitRealFromInt ;
|
|
|
+
|
|
|
PROCEDURE EmitData ;
|
|
|
(* The runtime's data block. The D_ constants name the offsets in it and are
|
|
|
ASSERTED against what is emitted here, three ways: the starting offset of
|
|
|
@@ -1486,6 +1578,7 @@ BEGIN
|
|
|
EmitRdChar ; EmitRdBool ; EmitRdLn ;
|
|
|
EmitGetCh ; EmitUnGetCh ;
|
|
|
EmitRdStr ; EmitStrStore ; EmitCmpStr ; EmitStrCat ;
|
|
|
+ EmitRealFromInt ;
|
|
|
EmitData ;
|
|
|
FixUp ;
|
|
|
SetStr (entNm [0], "initmem") ;
|
|
|
@@ -1509,6 +1602,7 @@ BEGIN
|
|
|
SetStr (entNm [18], "cmpstr") ;
|
|
|
SetStr (entNm [19], "strcat") ;
|
|
|
SetStr (entNm [20], "wrintw") ;
|
|
|
+ SetStr (entNm [21], "real_from_int") ;
|
|
|
built := TRUE
|
|
|
END RT_Build ;
|
|
|
|
|
|
@@ -1536,7 +1630,7 @@ BEGIN
|
|
|
IF NOT built THEN
|
|
|
RT_Build (0)
|
|
|
END ;
|
|
|
- IF i > 20 THEN
|
|
|
+ IF i > 21 THEN
|
|
|
RETURN 0
|
|
|
END ;
|
|
|
RETURN rtBase + LblOff (entNm [i])
|