|
@@ -47,7 +47,7 @@ CONST
|
|
|
that case; the fill checks below make any future overflow a HALT instead
|
|
that case; the fill checks below make any future overflow a HALT instead
|
|
|
of wrong code. tests/check_runtime.py's branch-boundary check is what
|
|
of wrong code. tests/check_runtime.py's branch-boundary check is what
|
|
|
caught this one. *)
|
|
caught this one. *)
|
|
|
- MaxLbl = 160 ; (* the MBF core's labels took the count past 96 *)
|
|
|
|
|
|
|
+ MaxLbl = 320 ; (* fmtreal/ascreal added ~70 labels to the MBF core's 160 *)
|
|
|
MaxFix = 768 ;
|
|
MaxFix = 768 ;
|
|
|
MaxNm = 15 ;
|
|
MaxNm = 15 ;
|
|
|
|
|
|
|
@@ -82,7 +82,17 @@ CONST
|
|
|
D_RMUL21 = 41 ; (* b's saved CX (low byte is the exponent, skipped) *)
|
|
D_RMUL21 = 41 ; (* b's saved CX (low byte is the exponent, skipped) *)
|
|
|
D_RMUL22 = 43 ; (* b's saved SI *)
|
|
D_RMUL22 = 43 ; (* b's saved SI *)
|
|
|
D_RMUL23 = 45 ; (* b's saved DI *)
|
|
D_RMUL23 = 45 ; (* b's saved DI *)
|
|
|
- D_END = 47 ; (* the block is padded to here *)
|
|
|
|
|
|
|
+ D_CVOUT = 47 ; (* 12 bytes: realdec's decimal digits *)
|
|
|
|
|
+ D_CVDECEXP = 59 ; (* realrang's decimal exponent, sign in bit 7 *)
|
|
|
|
|
+ D_CVEXPCNT = 60 ; (* ascreal's decimal-point counter *)
|
|
|
|
|
+ D_FLTDEC = 61 ; (* 10 x 6 bytes: 1e0, 1e4, ... 1e36 (TPSRC3) *)
|
|
|
|
|
+ D_FMTBUF = 121 ; (* 64 bytes: fmtreal's unpadded output *)
|
|
|
|
|
+ D_FMTLEN = 185 ; (* 2 bytes: its length *)
|
|
|
|
|
+ D_FMTW = 187 ; (* 2 bytes: the requested field width *)
|
|
|
|
|
+ D_FMTPAD = 189 ; (* 2 bytes: left padding *)
|
|
|
|
|
+ D_FMTTOT = 191 ; (* 2 bytes: pad + length *)
|
|
|
|
|
+ D_ASCSRC = 193 ; (* 2 bytes: ascreal's source pointer *)
|
|
|
|
|
+ D_END = 195 ; (* the block is padded to here *)
|
|
|
|
|
|
|
|
(* THE LOAD BIAS. Everything above is an offset into the image as this
|
|
(* THE LOAD BIAS. Everything above is an offset into the image as this
|
|
|
compiler numbers it: the entry JMP is at image 0. But a DOS .COM is
|
|
compiler numbers it: the entry JMP is at image 0. But a DOS .COM is
|
|
@@ -139,7 +149,7 @@ VAR
|
|
|
dataAt : CARDINAL ;
|
|
dataAt : CARDINAL ;
|
|
|
rtBase : CARDINAL ;
|
|
rtBase : CARDINAL ;
|
|
|
built : BOOLEAN ;
|
|
built : BOOLEAN ;
|
|
|
- entNm : ARRAY [0..27] OF ARRAY [0..MaxNm] OF CHAR ;
|
|
|
|
|
|
|
+ entNm : ARRAY [0..29] OF ARRAY [0..MaxNm] OF CHAR ;
|
|
|
|
|
|
|
|
(* ---------------------------------------------------------------- *)
|
|
(* ---------------------------------------------------------------- *)
|
|
|
(* name helpers *)
|
|
(* name helpers *)
|
|
@@ -697,6 +707,104 @@ PROCEDURE CmpAhData (delta : CARDINAL) ;
|
|
|
BEGIN B (3AH) ; B (26H) ; Dd (delta) END CmpAhData ;
|
|
BEGIN B (3AH) ; B (26H) ; Dd (delta) END CmpAhData ;
|
|
|
PROCEDURE SubAhData (delta : CARDINAL) ;
|
|
PROCEDURE SubAhData (delta : CARDINAL) ;
|
|
|
BEGIN B (2AH) ; B (26H) ; Dd (delta) END SubAhData ; (* SUB.B AH,remul21a: ignores the carry *)
|
|
BEGIN B (2AH) ; B (26H) ; Dd (delta) END SubAhData ; (* SUB.B AH,remul21a: ignores the carry *)
|
|
|
|
|
+
|
|
|
|
|
+(* --- the real formatter/parser's instruction set (fmtreal/ascreal) ------ *)
|
|
|
|
|
+PROCEDURE Jl8 (nm : ARRAY OF CHAR ) ; BEGIN Jcc (7CH, nm) END Jl8 ;
|
|
|
|
|
+PROCEDURE Jg8 (nm : ARRAY OF CHAR ) ; BEGIN Jcc (7FH, nm) END Jg8 ;
|
|
|
|
|
+PROCEDURE MovAxBx ; BEGIN B (89H) ; B (0D8H) END MovAxBx ; (* AX:=BX *)
|
|
|
|
|
+PROCEDURE MovAxSi ; BEGIN B (89H) ; B (0F0H) END MovAxSi ; (* AX:=SI *)
|
|
|
|
|
+PROCEDURE MovSiDi ; BEGIN B (89H) ; B (0FEH) END MovSiDi ; (* SI:=DI *)
|
|
|
|
|
+PROCEDURE MovBlCl ; BEGIN B (88H) ; B (0CBH) END MovBlCl ; (* BL:=CL *)
|
|
|
|
|
+PROCEDURE MovChDh ; BEGIN B (88H) ; B (0F5H) END MovChDh ; (* CH:=DH *)
|
|
|
|
|
+PROCEDURE MovChCl ; BEGIN B (88H) ; B (0CDH) END MovChCl ; (* CH:=CL *)
|
|
|
|
|
+PROCEDURE MovDlCh ; BEGIN B (88H) ; B (0EAH) END MovDlCh ; (* DL:=CH *)
|
|
|
|
|
+PROCEDURE MovDhAl ; BEGIN B (88H) ; B (0C6H) END MovDhAl ; (* DH:=AL *)
|
|
|
|
|
+PROCEDURE MovClAh ; BEGIN B (88H) ; B (0E1H) END MovClAh ; (* CL:=AH *)
|
|
|
|
|
+PROCEDURE MovClAl ; BEGIN B (88H) ; B (0C1H) END MovClAl ; (* CL:=AL *)
|
|
|
|
|
+PROCEDURE MovAhAl ; BEGIN B (88H) ; B (0C4H) END MovAhAl ; (* AH:=AL *)
|
|
|
|
|
+PROCEDURE MovAlCl ; BEGIN B (88H) ; B (0C8H) END MovAlCl ; (* AL:=CL *)
|
|
|
|
|
+PROCEDURE MovChImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0B5H) ; B (v MOD 256) END MovChImm ; (* MOV CH,imm8 *)
|
|
|
|
|
+PROCEDURE CmpDxImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (81H) ; B (0FAH) ; W (v) END CmpDxImm ; (* CMP DX,imm16 *)
|
|
|
|
|
+PROCEDURE CmpAxImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (3DH) ; W (v) END CmpAxImm ; (* CMP AX,imm16 *)
|
|
|
|
|
+PROCEDURE CmpDl0 ; BEGIN B (80H) ; B (0FAH) ; B (0) END CmpDl0 ;
|
|
|
|
|
+PROCEDURE TestChImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0F6H) ; B (0C5H) ; B (v MOD 256) END TestChImm ; (* TEST CH,imm8 *)
|
|
|
|
|
+PROCEDURE TestDiOffImm (off, v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0F6H) ; B (45H) ; B (off MOD 256) ; B (v MOD 256) END TestDiOffImm ;
|
|
|
|
|
+PROCEDURE AndClImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (0E1H) ; B (v MOD 256) END AndClImm ; (* AND CL,imm8 *)
|
|
|
|
|
+PROCEDURE AndBlImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (0E3H) ; B (v MOD 256) END AndBlImm ; (* AND BL,imm8 *)
|
|
|
|
|
+PROCEDURE OrChImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (0CDH) ; B (v MOD 256) END OrChImm ; (* OR CH,imm8 *)
|
|
|
|
|
+PROCEDURE AddChImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (0C5H) ; B (v MOD 256) END AddChImm ; (* ADD CH,imm8 *)
|
|
|
|
|
+PROCEDURE AddClImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (0C1H) ; B (v MOD 256) END AddClImm ; (* ADD CL,imm8 *)
|
|
|
|
|
+PROCEDURE ShrChCl ; BEGIN B (0D2H) ; B (0EDH) END ShrChCl ; (* SHR CH,CL *)
|
|
|
|
|
+PROCEDURE ShrBl1 ; BEGIN B (0D0H) ; B (0EBH) END ShrBl1 ; (* SHR BL,1 *)
|
|
|
|
|
+PROCEDURE ShlAx1 ; BEGIN B (0D1H) ; B (0E0H) END ShlAx1 ; (* SHL AX,1 *)
|
|
|
|
|
+PROCEDURE ShlAl1 ; BEGIN B (0D0H) ; B (0E0H) END ShlAl1 ; (* SHL AL,1 *)
|
|
|
|
|
+PROCEDURE AddBlBh ; BEGIN B (00H) ; B (0FBH) END AddBlBh ; (* BL:=BL+BH *)
|
|
|
|
|
+PROCEDURE XorBhBh ; BEGIN B (30H) ; B (0FFH) END XorBhBh ; (* BH:=0 *)
|
|
|
|
|
+PROCEDURE AddAlAh ; BEGIN B (00H) ; B (0E0H) END AddAlAh ; (* AL:=AL+AH *)
|
|
|
|
|
+PROCEDURE AddAxCx ; BEGIN B (03H) ; B (0C1H) END AddAxCx ; (* AX:=AX+CX *)
|
|
|
|
|
+PROCEDURE AdcBxCx ; BEGIN B (13H) ; B (0D9H) END AdcBxCx ; (* BX:=BX+CX+CF *)
|
|
|
|
|
+PROCEDURE AdcDxCx ; BEGIN B (13H) ; B (0D1H) END AdcDxCx ; (* DX:=DX+CX+CF *)
|
|
|
|
|
+PROCEDURE AddAxDx ; BEGIN B (03H) ; B (0C2H) END AddAxDx ; (* AX:=AX+DX *)
|
|
|
|
|
+PROCEDURE AddBxAx ; BEGIN B (03H) ; B (0D8H) END AddBxAx ; (* BX:=BX+AX *)
|
|
|
|
|
+PROCEDURE SubAxDx ; BEGIN B (2BH) ; B (0C2H) END SubAxDx ; (* AX:=AX-DX *)
|
|
|
|
|
+PROCEDURE AddAxImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (05H) ; W (v) END AddAxImm ; (* ADD AX,imm16 *)
|
|
|
|
|
+PROCEDURE DecBx ; BEGIN B (4BH) END DecBx ; (* DEC BX *)
|
|
|
|
|
+PROCEDURE DecCh ; BEGIN B (0FEH) ; B (0CDH) END DecCh ; (* DEC CH *)
|
|
|
|
|
+PROCEDURE DecDl ; BEGIN B (0FEH) ; B (0CAH) END DecDl ; (* DEC DL *)
|
|
|
|
|
+PROCEDURE NegCl ; BEGIN B (0F6H) ; B (0D9H) END NegCl ; (* NEG CL *)
|
|
|
|
|
+PROCEDURE Cbw ; BEGIN B (98H) END Cbw ; (* AL -> AX *)
|
|
|
|
|
+PROCEDURE ImulDx ; BEGIN B (0F7H) ; B (0EAH) END ImulDx ; (* IMUL DX *)
|
|
|
|
|
+PROCEDURE StSiImm (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0C7H) ; B (04H) ; W (v) END StSiImm ; (* [SI]:=imm16 *)
|
|
|
|
|
+PROCEDURE StSiAl ; BEGIN B (88H) ; B (04H) END StSiAl ; (* [SI]:=AL *)
|
|
|
|
|
+PROCEDURE StSiCh ; BEGIN B (88H) ; B (2CH) END StSiCh ; (* [SI]:=CH *)
|
|
|
|
|
+PROCEDURE StBxAl ; BEGIN B (88H) ; B (07H) END StBxAl ; (* [BX]:=AL *)
|
|
|
|
|
+PROCEDURE LdAlSi ; BEGIN B (8AH) ; B (04H) END LdAlSi ; (* AL:=[SI] *)
|
|
|
|
|
+PROCEDURE LdClBx ; BEGIN B (8AH) ; B (0FH) END LdClBx ; (* CL:=[BX] *)
|
|
|
|
|
+PROCEDURE LdAlDi ; BEGIN B (8AH) ; B (05H) END LdAlDi ; (* AL:=[DI] *)
|
|
|
|
|
+PROCEDURE XorDiOffImm (off, v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (75H) ; B (off MOD 256) ; B (v MOD 256) END XorDiOffImm ;
|
|
|
|
|
+PROCEDURE LdClSi ; BEGIN B (8AH) ; B (0CH) END LdClSi ; (* CL:=[SI] *)
|
|
|
|
|
+PROCEDURE LdAxDi ; BEGIN B (8BH) ; B (05H) END LdAxDi ; (* AX:=[DI] *)
|
|
|
|
|
+PROCEDURE LdBxDiOff (off : CARDINAL) ;
|
|
|
|
|
+BEGIN B (8BH) ; B (5DH) ; B (off MOD 256) END LdBxDiOff ; (* [DI+off] *)
|
|
|
|
|
+PROCEDURE LdDxDiOff (off : CARDINAL) ;
|
|
|
|
|
+BEGIN B (8BH) ; B (55H) ; B (off MOD 256) END LdDxDiOff ; (* [DI+off] *)
|
|
|
|
|
+PROCEDURE LeaDiBxData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (8DH) ; B (0BFH) ; Dd (delta) END LeaDiBxData ; (* LEA DI,[BX+data] *)
|
|
|
|
|
+PROCEDURE MovSiData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0BEH) ; Dd (delta) END MovSiData ;
|
|
|
|
|
+PROCEDURE MovBxDataAddr (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0BBH) ; Dd (delta) END MovBxDataAddr ;
|
|
|
|
|
+PROCEDURE CmpSiData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (81H) ; B (0FEH) ; Dd (delta) END CmpSiData ;
|
|
|
|
|
+PROCEDURE MovAxData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (8BH) ; B (06H) ; Dd (delta) END MovAxData ;
|
|
|
|
|
+PROCEDURE LdClData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (8AH) ; B (0EH) ; Dd (delta) END LdClData ;
|
|
|
|
|
+PROCEDURE DecData (delta : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0FEH) ; B (0EH) ; Dd (delta) END DecData ;
|
|
|
|
|
+PROCEDURE CmpBxByte (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (80H) ; B (3FH) ; B (v MOD 256) END CmpBxByte ; (* CMP [BX],imm8 *)
|
|
|
|
|
+PROCEDURE MovBxByte (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0C6H) ; B (07H) ; B (v MOD 256) END MovBxByte ; (* [BX]:=imm8 *)
|
|
|
|
|
+PROCEDURE MovBxOff1Byte (v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0C6H) ; B (47H) ; B (1) ; B (v MOD 256) END MovBxOff1Byte ;
|
|
|
|
|
+PROCEDURE IncBxByte ; BEGIN B (0FEH) ; B (07H) END IncBxByte ; (* INC [BX] *)
|
|
|
|
|
+PROCEDURE MovDiBp6 ; BEGIN B (8BH) ; B (7EH) ; B (6) END MovDiBp6 ;
|
|
|
|
|
+PROCEDURE MovDxBp6 ; BEGIN B (8BH) ; B (56H) ; B (6) END MovDxBp6 ;
|
|
|
|
|
+PROCEDURE PushBp6 ; BEGIN B (0FFH) ; B (76H) ; B (6) END PushBp6 ;
|
|
|
PROCEDURE SbbBxData (delta : CARDINAL) ;
|
|
PROCEDURE SbbBxData (delta : CARDINAL) ;
|
|
|
BEGIN B (1BH) ; B (1EH) ; Dd (delta) END SbbBxData ;
|
|
BEGIN B (1BH) ; B (1EH) ; Dd (delta) END SbbBxData ;
|
|
|
PROCEDURE SbbDxData (delta : CARDINAL) ;
|
|
PROCEDURE SbbDxData (delta : CARDINAL) ;
|
|
@@ -707,6 +815,9 @@ PROCEDURE Clc ; BEGIN B (0F8H) END Clc ;
|
|
|
PROCEDURE IncCl ; BEGIN B (0FEH) ; B (0C1H) END IncCl ;
|
|
PROCEDURE IncCl ; BEGIN B (0FEH) ; B (0C1H) END IncCl ;
|
|
|
PROCEDURE DecDi ; BEGIN B (4FH) END DecDi ;
|
|
PROCEDURE DecDi ; BEGIN B (4FH) END DecDi ;
|
|
|
PROCEDURE SubAhCh ; BEGIN B (28H) ; B (0ECH) END SubAhCh ; (* AH:=AH-CH *)
|
|
PROCEDURE SubAhCh ; BEGIN B (28H) ; B (0ECH) END SubAhCh ; (* AH:=AH-CH *)
|
|
|
|
|
+PROCEDURE SubAlDl ; BEGIN B (2AH) ; B (0C2H) END SubAlDl ; (* AL:=AL-DL *)
|
|
|
|
|
+PROCEDURE IncCh ; BEGIN B (0FEH) ; B (0C5H) END IncCh ; (* INC CH *)
|
|
|
|
|
+PROCEDURE IncDl ; BEGIN B (0FEH) ; B (0C2H) END IncDl ; (* INC DL *)
|
|
|
PROCEDURE MovClImm (v : CARDINAL) ;
|
|
PROCEDURE MovClImm (v : CARDINAL) ;
|
|
|
BEGIN B (0B1H) ; B (v MOD 256) END MovClImm ;
|
|
BEGIN B (0B1H) ; B (v MOD 256) END MovClImm ;
|
|
|
PROCEDURE CmpClImm (v : CARDINAL) ;
|
|
PROCEDURE CmpClImm (v : CARDINAL) ;
|
|
@@ -734,14 +845,14 @@ PROCEDURE TestDhImm (v : CARDINAL) ;
|
|
|
BEGIN B (0F6H) ; B (0C6H) ; B (v MOD 256) END TestDhImm ;
|
|
BEGIN B (0F6H) ; B (0C6H) ; B (v MOD 256) END TestDhImm ;
|
|
|
PROCEDURE StDataImm (delta, v : CARDINAL) ;
|
|
PROCEDURE StDataImm (delta, v : CARDINAL) ;
|
|
|
BEGIN B (0C7H) ; B (06H) ; Dd (delta) ; W (v) END StDataImm ;
|
|
BEGIN B (0C7H) ; B (06H) ; Dd (delta) ; W (v) END StDataImm ;
|
|
|
|
|
+PROCEDURE StDataByte (delta, v : CARDINAL) ;
|
|
|
|
|
+BEGIN B (0C6H) ; B (06H) ; Dd (delta) ; B (v MOD 256) END StDataByte ;
|
|
|
PROCEDURE StDataCl (delta : CARDINAL) ;
|
|
PROCEDURE StDataCl (delta : CARDINAL) ;
|
|
|
BEGIN B (88H) ; B (0EH) ; Dd (delta) END StDataCl ;
|
|
BEGIN B (88H) ; B (0EH) ; Dd (delta) END StDataCl ;
|
|
|
PROCEDURE StDataDi (delta : CARDINAL) ;
|
|
PROCEDURE StDataDi (delta : CARDINAL) ;
|
|
|
BEGIN B (89H) ; B (3EH) ; Dd (delta) END StDataDi ;
|
|
BEGIN B (89H) ; B (3EH) ; Dd (delta) END StDataDi ;
|
|
|
PROCEDURE LdAlData (delta : CARDINAL) ;
|
|
PROCEDURE LdAlData (delta : CARDINAL) ;
|
|
|
BEGIN B (0A0H) ; Dd (delta) END LdAlData ;
|
|
BEGIN B (0A0H) ; Dd (delta) END LdAlData ;
|
|
|
-PROCEDURE LdClData (delta : CARDINAL) ;
|
|
|
|
|
-BEGIN B (8AH) ; B (0EH) ; Dd (delta) END LdClData ;
|
|
|
|
|
PROCEDURE XorDiData (delta : CARDINAL) ;
|
|
PROCEDURE XorDiData (delta : CARDINAL) ;
|
|
|
BEGIN B (33H) ; B (3EH) ; Dd (delta) END XorDiData ; (* XOR DI,[Vx] *)
|
|
BEGIN B (33H) ; B (3EH) ; Dd (delta) END XorDiData ; (* XOR DI,[Vx] *)
|
|
|
PROCEDURE XorDataDh (delta : CARDINAL) ;
|
|
PROCEDURE XorDataDh (delta : CARDINAL) ;
|
|
@@ -1650,11 +1761,21 @@ BEGIN
|
|
|
PushBx ; PushDx ; PushSi ; PushDi ;
|
|
PushBx ; PushDx ; PushSi ; PushDi ;
|
|
|
MovSiBp6 ; (* SI := source word *)
|
|
MovSiBp6 ; (* SI := source word *)
|
|
|
LdAxSi ; (* AX := the integer *)
|
|
LdAxSi ; (* AX := the integer *)
|
|
|
|
|
+ Call ("rf_core") ;
|
|
|
|
|
+ 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 ;
|
|
|
|
|
+ (* ---- the callable integer -> real core: AX in, AX/BX/DX out ---- *)
|
|
|
|
|
+ M ("rf_core") ;
|
|
|
CmpAx0 ;
|
|
CmpAx0 ;
|
|
|
Jne8 ("rf_nz") ;
|
|
Jne8 ("rf_nz") ;
|
|
|
XorBxBx ;
|
|
XorBxBx ;
|
|
|
XorDxDx ;
|
|
XorDxDx ;
|
|
|
- Jmp8 ("rf_store") ;
|
|
|
|
|
|
|
+ Jmp8 ("rf_core_ret") ;
|
|
|
M ("rf_nz") ;
|
|
M ("rf_nz") ;
|
|
|
MovBhAh ; (* BH := the integer's sign byte *)
|
|
MovBhAh ; (* BH := the integer's sign byte *)
|
|
|
MovDxAx ;
|
|
MovDxAx ;
|
|
@@ -1680,13 +1801,8 @@ BEGIN
|
|
|
AndDhImm (7FH) ; (* positive: bit 7 of DH is not a sign *)
|
|
AndDhImm (7FH) ; (* positive: bit 7 of DH is not a sign *)
|
|
|
M ("rf_pos2") ;
|
|
M ("rf_pos2") ;
|
|
|
XorBxBx ; (* only DX's 16 bits carry the value now *)
|
|
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
|
|
|
|
|
|
|
+ M ("rf_core_ret") ;
|
|
|
|
|
+ RetR
|
|
|
END EmitRealFromInt ;
|
|
END EmitRealFromInt ;
|
|
|
|
|
|
|
|
PROCEDURE EmitRealAddSub ;
|
|
PROCEDURE EmitRealAddSub ;
|
|
@@ -2112,6 +2228,515 @@ BEGIN
|
|
|
Jmp8 ("ri_store")
|
|
Jmp8 ("ri_store")
|
|
|
END EmitRealInt ;
|
|
END EmitRealInt ;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE EmitRealConv ;
|
|
|
|
|
+(* fmtreal / ascreal: the decimal<->binary conversions, TPSRC3 880-1250.
|
|
|
|
|
+
|
|
|
|
|
+ The cores are transcribed with their reference register conventions:
|
|
|
|
|
+ m10 multiplies AX/BX/DX by ten in place; rrange multiplies by 10**CL
|
|
|
|
|
+ through the fltdec table and the remult/rediv cores; rdec turns a packed
|
|
|
|
|
+ real into twelve decimal digits in D_CVOUT and returns the sign in CH and
|
|
|
|
|
+ the decimal exponent in CL; round and fdig* are the reference's helpers.
|
|
|
|
|
+ They all use CALL/RET internally, so a caller's flags survive where the
|
|
|
|
|
+ reference relies on that (the digit loop's CH flags are pushed explicitly
|
|
|
|
|
+ because rd_core uses CX for its second operand).
|
|
|
|
|
+
|
|
|
|
|
+ Two entries:
|
|
|
|
|
+ real_fmt (28): [BP+4] real ptr, [BP+6] destination; CX = width in CL
|
|
|
|
|
+ and decimals in CH. Writes a length-prefixed string
|
|
|
|
|
+ (dest[0] = length) padded on the LEFT to width, and
|
|
|
|
|
+ returns the length in AX. DEC >= 25 selects the
|
|
|
|
|
+ reference's scientific mode and derives the number of
|
|
|
|
|
+ fraction digits from the width.
|
|
|
|
|
+ real_val (29): [BP+4] ASCIIZ source, [BP+6] destination real. Returns
|
|
|
|
|
+ AX = the offset of the first character not consumed, or
|
|
|
|
|
+ FFFFh on a hard error (in which case the destination is
|
|
|
|
|
+ untouched). A trailing non-digit is NOT an error; the
|
|
|
|
|
+ offset tells Val where to report it, as TPSRC's ascreal
|
|
|
|
|
+ returns BX = end. *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ (* ---------------------------------------------------------- real_fmt *)
|
|
|
|
|
+ M ("real_fmt") ;
|
|
|
|
|
+ PushBp ; MovBpSp ;
|
|
|
|
|
+ PushBx ; PushDx ; PushSi ; PushDi ;
|
|
|
|
|
+ MovDiBp4 ; (* DI := the real *)
|
|
|
|
|
+ MovDlCh ; (* DL := decimals *)
|
|
|
|
|
+ MovChImm (0) ; (* CX := width *)
|
|
|
|
|
+ MovDhImm (0) ;
|
|
|
|
|
+ PushCx ; (* keep the width across rdec *)
|
|
|
|
|
+ MovBxDataAddr (D_FMTBUF) ;
|
|
|
|
|
+ Call ("rc_fmt") ;
|
|
|
|
|
+ PopCx ;
|
|
|
|
|
+ MovAxBx ; (* AX := end of the formatted text *)
|
|
|
|
|
+ MovBxDataAddr (D_FMTBUF) ;
|
|
|
|
|
+ SubAxBx ; (* AX := its length *)
|
|
|
|
|
+ StDataAx (D_FMTLEN) ;
|
|
|
|
|
+ StDataCx (D_FMTW) ;
|
|
|
|
|
+ (* pad := max (width - length, 0) *)
|
|
|
|
|
+ MovAxData (D_FMTW) ;
|
|
|
|
|
+ MovDxData (D_FMTLEN) ;
|
|
|
|
|
+ SubAxDx ;
|
|
|
|
|
+ CmpAx0 ;
|
|
|
|
|
+ Jge8 ("rc_fpadok") ;
|
|
|
|
|
+ XorAxAx ;
|
|
|
|
|
+ M ("rc_fpadok") ;
|
|
|
|
|
+ StDataAx (D_FMTPAD) ;
|
|
|
|
|
+ MovDxData (D_FMTLEN) ;
|
|
|
|
|
+ AddAxDx ; (* AX := pad + length *)
|
|
|
|
|
+ CmpAxImm (0FFH) ; (* a Pascal string's length is one byte *)
|
|
|
|
|
+ JccNear (76H, "rc_ftotok") ;
|
|
|
|
|
+ MovAxImm (0FFH) ;
|
|
|
|
|
+ M ("rc_ftotok") ;
|
|
|
|
|
+ StDataAx (D_FMTTOT) ;
|
|
|
|
|
+ (* dest[0] := length; then pad spaces, then the number *)
|
|
|
|
|
+ MovDxBp6 ; MovDiDx ;
|
|
|
|
|
+ StDiAl ;
|
|
|
|
|
+ IncDi ;
|
|
|
|
|
+ MovCxData (D_FMTPAD) ;
|
|
|
|
|
+ Jcxz8 ("rc_fpad_done") ;
|
|
|
|
|
+ M ("rc_fpad_loop") ;
|
|
|
|
|
+ MovAlD (20H) ; StDiAl ; IncDi ; Loop8 ("rc_fpad_loop") ;
|
|
|
|
|
+ M ("rc_fpad_done") ;
|
|
|
|
|
+ MovSiData (D_FMTBUF) ;
|
|
|
|
|
+ MovCxData (D_FMTLEN) ;
|
|
|
|
|
+ Jcxz8 ("rc_fcopy_done") ;
|
|
|
|
|
+ M ("rc_fcopy_loop") ;
|
|
|
|
|
+ LdAlSi ; StDiAl ; IncSi ; IncDi ; Loop8 ("rc_fcopy_loop") ;
|
|
|
|
|
+ M ("rc_fcopy_done") ;
|
|
|
|
|
+ MovAxData (D_FMTTOT) ;
|
|
|
|
|
+ PopDi ; PopSi ; PopDx ; PopBx ;
|
|
|
|
|
+ MovSpBp ; PopBp ; RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ---------------------------------------------------------- real_val *)
|
|
|
|
|
+ M ("real_val") ;
|
|
|
|
|
+ PushBp ; MovBpSp ;
|
|
|
|
|
+ PushBx ; PushDx ; PushSi ; PushDi ;
|
|
|
|
|
+ MovBxBp4 ;
|
|
|
|
|
+ MovDiBp6 ;
|
|
|
|
|
+ StDataBx (D_ASCSRC) ;
|
|
|
|
|
+ Call ("rc_asc") ;
|
|
|
|
|
+ JccNear (72H, "rc_averr") ;
|
|
|
|
|
+ MovAxBx ; (* AX := end pointer *)
|
|
|
|
|
+ MovDxData (D_ASCSRC) ;
|
|
|
|
|
+ SubAxDx ; (* AX := consumed length *)
|
|
|
|
|
+ JmpNear ("rc_avdone") ;
|
|
|
|
|
+ M ("rc_averr") ;
|
|
|
|
|
+ MovAxImm (0FFFFH) ;
|
|
|
|
|
+ M ("rc_avdone") ;
|
|
|
|
|
+ PopDi ; PopSi ; PopDx ; PopBx ;
|
|
|
|
|
+ MovSpBp ; PopBp ; RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ---------------------------------------------------------- m10 *)
|
|
|
|
|
+ (* AX/BX/DX := value * 10; CF = overflow; CX is preserved. The reference
|
|
|
|
|
+ multiplies by 1.25 (add the /4 value) and then by 8 via the exponent. *)
|
|
|
|
|
+ M ("rc_m10") ;
|
|
|
|
|
+ CmpAl0 ;
|
|
|
|
|
+ JccNear (75H, "rc_m10nz") ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_m10nz") ;
|
|
|
|
|
+ OrDhImm (80H) ;
|
|
|
|
|
+ PushCx ; PushDx ; PushBx ; PushAx ;
|
|
|
|
|
+ ShrDx1 ; RcrBx1 ; RcrAh1 ;
|
|
|
|
|
+ ShrDx1 ; RcrBx1 ; RcrAh1 ;
|
|
|
|
|
+ PopCx ; AddAhCh ;
|
|
|
|
|
+ PopCx ; AdcBxCx ;
|
|
|
|
|
+ PopCx ; AdcDxCx ;
|
|
|
|
|
+ PopCx ;
|
|
|
|
|
+ JccNear (73H, "rc_m10nrm") ;
|
|
|
|
|
+ RcrDx1 ; RcrBx1 ; RcrAh1 ;
|
|
|
|
|
+ IncAl ;
|
|
|
|
|
+ JccNear (75H, "rc_m10nrm") ;
|
|
|
|
|
+ Stc ; RetR ;
|
|
|
|
|
+ M ("rc_m10nrm") ;
|
|
|
|
|
+ AndDhImm (7FH) ;
|
|
|
|
|
+ AddAlImm (3) ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* -------------------------------------------------------- rrange *)
|
|
|
|
|
+ (* AX/BX/DX := value * 10**CL, signed CL, via the fltdec table. *)
|
|
|
|
|
+ M ("rc_range") ;
|
|
|
|
|
+ PushDx ; PushBx ; PushAx ;
|
|
|
|
|
+ StDataCl (D_CVDECEXP) ;
|
|
|
|
|
+ CmpCl0 ;
|
|
|
|
|
+ JccNear (79H, "rc_rpos") ;
|
|
|
|
|
+ NegCl ;
|
|
|
|
|
+ M ("rc_rpos") ;
|
|
|
|
|
+ MovBlCl ;
|
|
|
|
|
+ AndBlImm (0FCH) ;
|
|
|
|
|
+ MovBhBl ;
|
|
|
|
|
+ ShrBl1 ;
|
|
|
|
|
+ AddBlBh ;
|
|
|
|
|
+ XorBhBh ;
|
|
|
|
|
+ LeaDiBxData (D_FLTDEC) ;
|
|
|
|
|
+ LdAxDi ; LdBxDiOff (2) ; LdDxDiOff (4) ;
|
|
|
|
|
+ AndClImm (3) ;
|
|
|
|
|
+ JccNear (74H, "rc_rdone") ;
|
|
|
|
|
+ M ("rc_rmul") ;
|
|
|
|
|
+ Call ("rc_m10") ;
|
|
|
|
|
+ DecCl ;
|
|
|
|
|
+ JccNear (75H, "rc_rmul") ;
|
|
|
|
|
+ M ("rc_rdone") ;
|
|
|
|
|
+ MovCxAx ; MovSiBx ; MovDiDx ;
|
|
|
|
|
+ PopAx ; PopBx ; PopDx ;
|
|
|
|
|
+ TestDataImm (D_CVDECEXP, 80H) ;
|
|
|
|
|
+ JccNear (75H, "rc_rdiv") ;
|
|
|
|
|
+ JmpNear ("rm_core") ;
|
|
|
|
|
+ M ("rc_rdiv") ;
|
|
|
|
|
+ JmpNear ("rv_core") ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ------------------------------------------------------- rangem *)
|
|
|
|
|
+ (* the signed range check around rrange: |CL| <= 38 *)
|
|
|
|
|
+ M ("rc_rangem") ;
|
|
|
|
|
+ CmpClImm (0DAH) ; JccNear (7CH, "rc_rerr") ;
|
|
|
|
|
+ CmpClImm (26H) ; JccNear (7FH, "rc_rerr") ;
|
|
|
|
|
+ PushCx ; PushSi ; PushDi ;
|
|
|
|
|
+ Call ("rc_range") ;
|
|
|
|
|
+ PopDi ; PopSi ; PopCx ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_rerr") ;
|
|
|
|
|
+ Stc ; RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ---------------------------------------------------------- rdec *)
|
|
|
|
|
+ (* DI -> real. D_CVOUT gets twelve digits; CH = sign, CL = decimal
|
|
|
|
|
+ exponent. The estimate is 77/256 * (exponent - 128), TPSRC's
|
|
|
|
|
+ log10(2) approximation. *)
|
|
|
|
|
+ M ("rc_rdec") ;
|
|
|
|
|
+ LdAxDi ; LdBxDiOff (2) ; LdDxDiOff (4) ;
|
|
|
|
|
+ CmpAl0 ;
|
|
|
|
|
+ JccNear (75H, "rc_rdno0") ;
|
|
|
|
|
+ MovSiData (D_CVOUT) ;
|
|
|
|
|
+ M ("rc_rdfill") ;
|
|
|
|
|
+ StSiImm (3030H) ;
|
|
|
|
|
+ IncSi ; IncSi ;
|
|
|
|
|
+ CmpSiData (D_CVOUT + 12) ;
|
|
|
|
|
+ JccNear (75H, "rc_rdfill") ;
|
|
|
|
|
+ MovCxImm (0) ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_rdno0") ;
|
|
|
|
|
+ MovChDh ;
|
|
|
|
|
+ AndDhImm (7FH) ;
|
|
|
|
|
+ PushAx ; PushDx ;
|
|
|
|
|
+ SubAl (80H) ; Cbw ; MovDxImm (004DH) ; ImulDx ; AddAxImm (5) ;
|
|
|
|
|
+ MovClAh ;
|
|
|
|
|
+ PopDx ; PopAx ;
|
|
|
|
|
+ CmpClImm (0D9H) ;
|
|
|
|
|
+ JccNear (75H, "rc_rdnocomp") ;
|
|
|
|
|
+ IncCl ;
|
|
|
|
|
+ M ("rc_rdnocomp") ;
|
|
|
|
|
+ PushCx ;
|
|
|
|
|
+ NegCl ;
|
|
|
|
|
+ Call ("rc_range") ;
|
|
|
|
|
+ PopCx ;
|
|
|
|
|
+ CmpAl (81H) ;
|
|
|
|
|
+ JccNear (73H, "rc_rdnoadj") ;
|
|
|
|
|
+ Call ("rc_m10") ;
|
|
|
|
|
+ DecCl ;
|
|
|
|
|
+ M ("rc_rdnoadj") ;
|
|
|
|
|
+ PushCx ;
|
|
|
|
|
+ OrDhImm (80H) ;
|
|
|
|
|
+ MovClImm (84H) ;
|
|
|
|
|
+ SubClAl ;
|
|
|
|
|
+ MovAlD (0) ;
|
|
|
|
|
+ CmpCl0 ;
|
|
|
|
|
+ JccNear (74H, "rc_rdnosh") ;
|
|
|
|
|
+ M ("rc_rdshift") ;
|
|
|
|
|
+ ShrDx1 ; RcrBx1 ; RcrAh1 ;
|
|
|
|
|
+ DecCl ;
|
|
|
|
|
+ JccNear (75H, "rc_rdshift") ;
|
|
|
|
|
+ M ("rc_rdnosh") ;
|
|
|
|
|
+ MovSiData (D_CVOUT) ;
|
|
|
|
|
+ M ("rc_rdconv") ;
|
|
|
|
|
+ MovChDh ; MovClImm (4) ; ShrChCl ; AddChImm (30H) ;
|
|
|
|
|
+ StSiCh ;
|
|
|
|
|
+ AndDhImm (0FH) ;
|
|
|
|
|
+ PushDx ; PushBx ; PushAx ;
|
|
|
|
|
+ ShlAx1 ; RclBx1 ; RclDx1 ;
|
|
|
|
|
+ ShlAx1 ; RclBx1 ; RclDx1 ;
|
|
|
|
|
+ PopCx ; AddAxCx ;
|
|
|
|
|
+ PopCx ; AdcBxCx ;
|
|
|
|
|
+ PopCx ; AdcDxCx ;
|
|
|
|
|
+ ShlAx1 ; RclBx1 ; RclDx1 ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ CmpSiData (D_CVOUT + 12) ;
|
|
|
|
|
+ JccNear (75H, "rc_rdconv") ;
|
|
|
|
|
+ PopCx ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* --------------------------------------------------------- round *)
|
|
|
|
|
+ (* round the digits at index AL: look at the next digit, and carry if it is
|
|
|
|
|
+ 5 or more. CL is the decimal exponent and is incremented on carry-out. *)
|
|
|
|
|
+ M ("rc_round") ;
|
|
|
|
|
+ XorAhAh ;
|
|
|
|
|
+ MovBxDataAddr (D_CVOUT) ;
|
|
|
|
|
+ AddBxAx ;
|
|
|
|
|
+ CmpBxByte (35H) ;
|
|
|
|
|
+ MovBxByte (0) ;
|
|
|
|
|
+ JccNear (72H, "rc_rounddone") ;
|
|
|
|
|
+ M ("rc_roundloop") ;
|
|
|
|
|
+ DecAl ;
|
|
|
|
|
+ JccNear (78H, "rc_roundexp") ;
|
|
|
|
|
+ DecBx ;
|
|
|
|
|
+ IncBxByte ;
|
|
|
|
|
+ CmpBxByte (3AH) ;
|
|
|
|
|
+ JccNear (72H, "rc_rounddone") ;
|
|
|
|
|
+ MovBxByte (0) ;
|
|
|
|
|
+ JmpNear ("rc_roundloop") ;
|
|
|
|
|
+ M ("rc_roundexp") ;
|
|
|
|
|
+ MovBxByte (31H) ;
|
|
|
|
|
+ MovBxOff1Byte (0) ;
|
|
|
|
|
+ IncCl ;
|
|
|
|
|
+ M ("rc_rounddone") ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ------------------------------------------------------------ fdig *)
|
|
|
|
|
+ M ("rc_fdig") ;
|
|
|
|
|
+ LdAlSi ;
|
|
|
|
|
+ CmpAl0 ;
|
|
|
|
|
+ JccNear (74H, "rc_fdig0") ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ JmpNear ("rc_fdigsto") ;
|
|
|
|
|
+ M ("rc_fdig0") ;
|
|
|
|
|
+ MovAlD (30H) ;
|
|
|
|
|
+ M ("rc_fdigsto") ;
|
|
|
|
|
+ StBxAl ;
|
|
|
|
|
+ IncBx ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ---------------------------------------------------------- fcore *)
|
|
|
|
|
+ (* DI = real, BX = destination, CX = width, DX = decimals. Writes raw
|
|
|
|
|
+ characters (no padding) and leaves BX one past the end. *)
|
|
|
|
|
+ M ("rc_fmt") ;
|
|
|
|
|
+ PushBx ;
|
|
|
|
|
+ CmpDxImm (19H) ;
|
|
|
|
|
+ JccNear (72H, "rc_fnlim2") ;
|
|
|
|
|
+ MovAxCx ;
|
|
|
|
|
+ CmpCh0 ;
|
|
|
|
|
+ JccNear (74H, "rc_flimok") ;
|
|
|
|
|
+ TestChImm (80H) ;
|
|
|
|
|
+ JccNear (74H, "rc_flimpos") ;
|
|
|
|
|
+ XorAxAx ;
|
|
|
|
|
+ JmpNear ("rc_flimok") ;
|
|
|
|
|
+ M ("rc_flimpos") ;
|
|
|
|
|
+ MovAxImm (0FFH) ;
|
|
|
|
|
+ M ("rc_flimok") ;
|
|
|
|
|
+ MovDl (7) ;
|
|
|
|
|
+ TestDiOffImm (5, 80H) ;
|
|
|
|
|
+ JccNear (74H, "rc_frpos") ;
|
|
|
|
|
+ IncDl ;
|
|
|
|
|
+ M ("rc_frpos") ;
|
|
|
|
|
+ SubAlDl ;
|
|
|
|
|
+ JccNear (73H, "rc_frnound") ;
|
|
|
|
|
+ MovAlD (0) ;
|
|
|
|
|
+ M ("rc_frnound") ;
|
|
|
|
|
+ CmpAl (9) ;
|
|
|
|
|
+ JccNear (72H, "rc_frnolim") ;
|
|
|
|
|
+ MovAlD (9) ;
|
|
|
|
|
+ M ("rc_frnolim") ;
|
|
|
|
|
+ IncAl ;
|
|
|
|
|
+ MovDlAl ;
|
|
|
|
|
+ MovDhAl ;
|
|
|
|
|
+ M ("rc_fnlim2") ;
|
|
|
|
|
+ PushDx ;
|
|
|
|
|
+ Call ("rc_rdec") ;
|
|
|
|
|
+ PopDx ;
|
|
|
|
|
+ MovAlDl ;
|
|
|
|
|
+ IncAl ;
|
|
|
|
|
+ CmpDh0 ;
|
|
|
|
|
+ JccNear (75H, "rc_frround") ;
|
|
|
|
|
+ AddAlCl ;
|
|
|
|
|
+ JccNear (79H, "rc_frlimprc") ;
|
|
|
|
|
+ StDataByte (D_CVOUT, 0) ;
|
|
|
|
|
+ JmpNear ("rc_frfmtit") ;
|
|
|
|
|
+ M ("rc_frlimprc") ;
|
|
|
|
|
+ CmpAl (0CH) ;
|
|
|
|
|
+ JccNear (72H, "rc_frround") ;
|
|
|
|
|
+ MovAlD (0BH) ;
|
|
|
|
|
+ M ("rc_frround") ;
|
|
|
|
|
+ Call ("rc_round") ;
|
|
|
|
|
+ M ("rc_frfmtit") ;
|
|
|
|
|
+ PopBx ;
|
|
|
|
|
+ MovSiData (D_CVOUT) ;
|
|
|
|
|
+ TestChImm (80H) ;
|
|
|
|
|
+ JccNear (74H, "rc_frpos2") ;
|
|
|
|
|
+ MovAlD (2DH) ;
|
|
|
|
|
+ Call ("rc_fdigsto") ;
|
|
|
|
|
+ M ("rc_frpos2") ;
|
|
|
|
|
+ MovChCl ;
|
|
|
|
|
+ CmpDh0 ;
|
|
|
|
|
+ JccNear (74H, "rc_frzer") ;
|
|
|
|
|
+ MovChImm (0) ;
|
|
|
|
|
+ M ("rc_frzer") ;
|
|
|
|
|
+ CmpCh0 ;
|
|
|
|
|
+ JccNear (79H, "rc_frint") ;
|
|
|
|
|
+ Call ("rc_fdig0") ;
|
|
|
|
|
+ JmpNear ("rc_frfrac0") ;
|
|
|
|
|
+ M ("rc_frint") ;
|
|
|
|
|
+ Call ("rc_fdig") ;
|
|
|
|
|
+ DecCh ;
|
|
|
|
|
+ JccNear (79H, "rc_frint") ;
|
|
|
|
|
+ M ("rc_frfrac0") ;
|
|
|
|
|
+ CmpDl0 ;
|
|
|
|
|
+ JccNear (74H, "rc_frexp") ;
|
|
|
|
|
+ MovAlD (2EH) ;
|
|
|
|
|
+ Call ("rc_fdigsto") ;
|
|
|
|
|
+ M ("rc_frfill0") ;
|
|
|
|
|
+ IncCh ;
|
|
|
|
|
+ JccNear (74H, "rc_frfrac") ;
|
|
|
|
|
+ Call ("rc_fdig0") ;
|
|
|
|
|
+ DecDl ;
|
|
|
|
|
+ JccNear (75H, "rc_frfill0") ;
|
|
|
|
|
+ M ("rc_frfrac") ;
|
|
|
|
|
+ DecDl ;
|
|
|
|
|
+ JccNear (78H, "rc_frexp") ;
|
|
|
|
|
+ Call ("rc_fdig") ;
|
|
|
|
|
+ JmpNear ("rc_frfrac") ;
|
|
|
|
|
+ M ("rc_frexp") ;
|
|
|
|
|
+ CmpDh0 ;
|
|
|
|
|
+ JccNear (75H, "rc_frputexp") ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_frputexp") ;
|
|
|
|
|
+ MovAlD (45H) ;
|
|
|
|
|
+ Call ("rc_fdigsto") ;
|
|
|
|
|
+ MovAlD (2BH) ;
|
|
|
|
|
+ CmpCl0 ;
|
|
|
|
|
+ JccNear (79H, "rc_frposexp") ;
|
|
|
|
|
+ NegCl ;
|
|
|
|
|
+ MovAlD (2DH) ;
|
|
|
|
|
+ M ("rc_frposexp") ;
|
|
|
|
|
+ Call ("rc_fdigsto") ;
|
|
|
|
|
+ MovAlD (2FH) ;
|
|
|
|
|
+ M ("rc_frexpsub") ;
|
|
|
|
|
+ IncAl ;
|
|
|
|
|
+ SubClImm (0AH) ;
|
|
|
|
|
+ JccNear (73H, "rc_frexpsub") ;
|
|
|
|
|
+ Call ("rc_fdigsto") ;
|
|
|
|
|
+ AddClImm (3AH) ;
|
|
|
|
|
+ MovAlCl ;
|
|
|
|
|
+ JmpNear ("rc_fdigsto") ;
|
|
|
|
|
+
|
|
|
|
|
+ (* ------------------------------------------------------------ asc *)
|
|
|
|
|
+ (* BX = ASCIIZ source, DI = destination real. Returns BX = end, CF = 1 on
|
|
|
|
|
+ a hard error. The digit add keeps the reference's stack dance: the
|
|
|
|
|
+ digit's real goes in a and the accumulated value in b (addition is
|
|
|
|
|
+ commutative), while the pointers and the CH flags are saved around the
|
|
|
|
|
+ call because rd_core uses CX/SI/DI. *)
|
|
|
|
|
+ M ("rc_asc") ;
|
|
|
|
|
+ LdClBx ;
|
|
|
|
|
+ CmpClImm (2DH) ;
|
|
|
|
|
+ JccNear (75H, "rc_asign") ;
|
|
|
|
|
+ IncBx ;
|
|
|
|
|
+ M ("rc_asign") ;
|
|
|
|
|
+ PushCx ;
|
|
|
|
|
+ Call ("rc_asc2") ;
|
|
|
|
|
+ PopCx ;
|
|
|
|
|
+ JccNear (72H, "rc_aouterr") ;
|
|
|
|
|
+ CmpClImm (2DH) ;
|
|
|
|
|
+ JccNear (75H, "rc_aok") ;
|
|
|
|
|
+ LdAlDi ;
|
|
|
|
|
+ CmpAl0 ;
|
|
|
|
|
+ JccNear (74H, "rc_aok") ;
|
|
|
|
|
+ XorDiOffImm (5, 80H) ;
|
|
|
|
|
+ M ("rc_aok") ;
|
|
|
|
|
+ Clc ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_aouterr") ;
|
|
|
|
|
+ Stc ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+ M ("rc_asc2") ;
|
|
|
|
|
+ MovSiBx ;
|
|
|
|
|
+ XorAxAx ; XorBxBx ; XorDxDx ; XorCxCx ;
|
|
|
|
|
+ StDataByte (D_CVEXPCNT, 0) ;
|
|
|
|
|
+ M ("rc_aloop") ;
|
|
|
|
|
+ LdClSi ;
|
|
|
|
|
+ CmpClImm (61H) ; JccNear (72H, "rc_aup") ;
|
|
|
|
|
+ CmpClImm (7AH) ; Ja8 ("rc_aup") ;
|
|
|
|
|
+ SubClImm (20H) ;
|
|
|
|
|
+ M ("rc_aup") ;
|
|
|
|
|
+ Call ("rc_adigit2") ;
|
|
|
|
|
+ JccNear (72H, "rc_anodig") ;
|
|
|
|
|
+ Call ("rc_m10") ;
|
|
|
|
|
+ JccNear (72H, "rc_aerr") ;
|
|
|
|
|
+ PushDi ; PushSi ; PushCx ;
|
|
|
|
|
+ PushDx ; PushBx ; PushAx ;
|
|
|
|
|
+ MovAlCl ;
|
|
|
|
|
+ XorAhAh ;
|
|
|
|
|
+ Call ("rf_core") ;
|
|
|
|
|
+ MovCxAx ; MovSiBx ; MovDiDx ;
|
|
|
|
|
+ PopAx ; PopBx ; PopDx ;
|
|
|
|
|
+ StDataImm (D_RSIGN, 0) ; (* readd, not resub: resign := 0 *)
|
|
|
|
|
+ Call ("rd_core") ;
|
|
|
|
|
+ PopCx ; PopSi ; PopDi ;
|
|
|
|
|
+ TestChImm (40H) ;
|
|
|
|
|
+ JccNear (74H, "rc_anext") ;
|
|
|
|
|
+ DecData (D_CVEXPCNT) ;
|
|
|
|
|
+ M ("rc_anext") ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ JmpNear ("rc_aloop") ;
|
|
|
|
|
+ M ("rc_anodig") ;
|
|
|
|
|
+ CmpClImm (2EH) ;
|
|
|
|
|
+ JccNear (75H, "rc_aexp") ;
|
|
|
|
|
+ TestChImm (40H) ;
|
|
|
|
|
+ JccNear (75H, "rc_aerr") ;
|
|
|
|
|
+ OrChImm (40H) ;
|
|
|
|
|
+ JmpNear ("rc_anext") ;
|
|
|
|
|
+ M ("rc_aexp") ;
|
|
|
|
|
+ CmpClImm (45H) ;
|
|
|
|
|
+ LdClData (D_CVEXPCNT) ;
|
|
|
|
|
+ JccNear (75H, "rc_aexp3") ;
|
|
|
|
|
+ Call ("rc_rangem") ;
|
|
|
|
|
+ JccNear (72H, "rc_aerr") ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ LdClSi ;
|
|
|
|
|
+ CmpClImm (2BH) ;
|
|
|
|
|
+ JccNear (74H, "rc_aposexp") ;
|
|
|
|
|
+ CmpClImm (2DH) ;
|
|
|
|
|
+ JccNear (75H, "rc_aexp2") ;
|
|
|
|
|
+ OrChImm (20H) ;
|
|
|
|
|
+ M ("rc_aposexp") ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ M ("rc_aexp2") ;
|
|
|
|
|
+ Call ("rc_adigit") ;
|
|
|
|
|
+ JccNear (72H, "rc_aerr") ;
|
|
|
|
|
+ PushAx ;
|
|
|
|
|
+ MovAlCl ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ Call ("rc_adigit") ;
|
|
|
|
|
+ JccNear (72H, "rc_aonedig") ;
|
|
|
|
|
+ MovAhAl ;
|
|
|
|
|
+ ShlAl1 ; ShlAl1 ; AddAlAh ; ShlAl1 ; AddAlCl ;
|
|
|
|
|
+ IncSi ;
|
|
|
|
|
+ M ("rc_aonedig") ;
|
|
|
|
|
+ MovClAl ;
|
|
|
|
|
+ PopAx ;
|
|
|
|
|
+ TestChImm (20H) ;
|
|
|
|
|
+ JccNear (74H, "rc_aexp3") ;
|
|
|
|
|
+ NegCl ;
|
|
|
|
|
+ M ("rc_aexp3") ;
|
|
|
|
|
+ Call ("rc_rangem") ;
|
|
|
|
|
+ JccNear (72H, "rc_aerr") ;
|
|
|
|
|
+ StDiAx ; StDiOffBx (2) ; StDiOffDx (4) ;
|
|
|
|
|
+ Clc ;
|
|
|
|
|
+ JmpNear ("rc_aret") ;
|
|
|
|
|
+ M ("rc_aerr") ;
|
|
|
|
|
+ Stc ;
|
|
|
|
|
+ M ("rc_aret") ;
|
|
|
|
|
+ MovBxSi ;
|
|
|
|
|
+ RetR ;
|
|
|
|
|
+
|
|
|
|
|
+ (* -------------------------------------------------------- adigit *)
|
|
|
|
|
+ M ("rc_adigit") ;
|
|
|
|
|
+ LdClSi ;
|
|
|
|
|
+ M ("rc_adigit2") ;
|
|
|
|
|
+ CmpClImm (30H) ;
|
|
|
|
|
+ JccNear (72H, "rc_adret") ;
|
|
|
|
|
+ CmpClImm (3AH) ;
|
|
|
|
|
+ Cmc ;
|
|
|
|
|
+ JccNear (72H, "rc_adret") ;
|
|
|
|
|
+ SubClImm (30H) ;
|
|
|
|
|
+ M ("rc_adret") ;
|
|
|
|
|
+ RetR
|
|
|
|
|
+END EmitRealConv ;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
PROCEDURE EmitData ;
|
|
PROCEDURE EmitData ;
|
|
|
(* The runtime's data block. The D_ constants name the offsets in it and are
|
|
(* 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
|
|
ASSERTED against what is emitted here, three ways: the starting offset of
|
|
@@ -2184,6 +2809,67 @@ BEGIN
|
|
|
HALT
|
|
HALT
|
|
|
END ;
|
|
END ;
|
|
|
B (0) ; B (0) ;
|
|
B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_CVOUT # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ (* twelve decimal digit slots; rdconv fills all of them *)
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_CVDECEXP # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ;
|
|
|
|
|
+ IF dataAt + D_CVEXPCNT # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ;
|
|
|
|
|
+ IF dataAt + D_FLTDEC # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ (* 1e0, 1e4, ... 1e36 as the reference's AX:BX:DX triples, low byte first *)
|
|
|
|
|
+ B (081H) ; B (000H) ; B (000H) ; B (000H) ; B (000H) ; B (000H) ;
|
|
|
|
|
+ B (08EH) ; B (000H) ; B (000H) ; B (000H) ; B (040H) ; B (01CH) ;
|
|
|
|
|
+ B (09BH) ; B (000H) ; B (000H) ; B (020H) ; B (0BCH) ; B (03EH) ;
|
|
|
|
|
+ B (0A8H) ; B (000H) ; B (010H) ; B (0A5H) ; B (0D4H) ; B (068H) ;
|
|
|
|
|
+ B (0B6H) ; B (004H) ; B (0BFH) ; B (0C9H) ; B (01BH) ; B (00EH) ;
|
|
|
|
|
+ B (0C3H) ; B (0ACH) ; B (0C5H) ; B (0EBH) ; B (078H) ; B (02DH) ;
|
|
|
|
|
+ B (0D0H) ; B (0CDH) ; B (0CEH) ; B (01BH) ; B (0C2H) ; B (053H) ;
|
|
|
|
|
+ B (0DEH) ; B (0F9H) ; B (078H) ; B (039H) ; B (03FH) ; B (001H) ;
|
|
|
|
|
+ B (0EBH) ; B (02BH) ; B (0A8H) ; B (0ADH) ; B (0C5H) ; B (01DH) ;
|
|
|
|
|
+ B (0F8H) ; B (0C9H) ; B (07BH) ; B (0CEH) ; B (097H) ; B (040H) ;
|
|
|
|
|
+ IF dataAt + D_FMTBUF # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ (* 64 bytes of formatted output; a fixed-format 1e38 with 10 decimals is
|
|
|
|
|
+ about 50 characters, so this has room *)
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_FMTLEN # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_FMTW # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_FMTPAD # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_FMTTOT # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ; B (0) ;
|
|
|
|
|
+ IF dataAt + D_ASCSRC # rpos THEN
|
|
|
|
|
+ HALT
|
|
|
|
|
+ END ;
|
|
|
|
|
+ B (0) ; B (0) ;
|
|
|
WHILE rpos < dataAt + D_END DO
|
|
WHILE rpos < dataAt + D_END DO
|
|
|
B (0)
|
|
B (0)
|
|
|
END ;
|
|
END ;
|
|
@@ -2253,7 +2939,7 @@ BEGIN
|
|
|
EmitGetCh ; EmitUnGetCh ;
|
|
EmitGetCh ; EmitUnGetCh ;
|
|
|
EmitRdStr ; EmitStrStore ; EmitCmpStr ; EmitStrCat ;
|
|
EmitRdStr ; EmitStrStore ; EmitCmpStr ; EmitStrCat ;
|
|
|
EmitRealFromInt ; EmitRealAddSub ; EmitRealMul ;
|
|
EmitRealFromInt ; EmitRealAddSub ; EmitRealMul ;
|
|
|
- EmitRealCmp ; EmitRealInt ;
|
|
|
|
|
|
|
+ EmitRealCmp ; EmitRealInt ; EmitRealConv ;
|
|
|
EmitData ;
|
|
EmitData ;
|
|
|
FixUp ;
|
|
FixUp ;
|
|
|
SetStr (entNm [0], "initmem") ;
|
|
SetStr (entNm [0], "initmem") ;
|
|
@@ -2284,6 +2970,8 @@ BEGIN
|
|
|
SetStr (entNm [25], "real_div") ;
|
|
SetStr (entNm [25], "real_div") ;
|
|
|
SetStr (entNm [26], "real_cmp") ;
|
|
SetStr (entNm [26], "real_cmp") ;
|
|
|
SetStr (entNm [27], "real_int") ;
|
|
SetStr (entNm [27], "real_int") ;
|
|
|
|
|
+ SetStr (entNm [28], "real_fmt") ;
|
|
|
|
|
+ SetStr (entNm [29], "real_val") ;
|
|
|
built := TRUE
|
|
built := TRUE
|
|
|
END RT_Build ;
|
|
END RT_Build ;
|
|
|
|
|
|
|
@@ -2311,7 +2999,7 @@ BEGIN
|
|
|
IF NOT built THEN
|
|
IF NOT built THEN
|
|
|
RT_Build (0)
|
|
RT_Build (0)
|
|
|
END ;
|
|
END ;
|
|
|
- IF i > 27 THEN
|
|
|
|
|
|
|
+ IF i > 29 THEN
|
|
|
RETURN 0
|
|
RETURN 0
|
|
|
END ;
|
|
END ;
|
|
|
RETURN rtBase + LblOff (entNm [i])
|
|
RETURN rtBase + LblOff (entNm [i])
|