📄 parsera.asm
字号:
BEGN_OPER LTE2 ; LTE, test ST, clear
; return !(Arg2->d.x <= Arg1->d.x) in AX
fcom st(2) ; comp Arg1 to Arg2
fstsw ax
fninit ; clear stack
and ah,1 ; mask cf
shr ax,8 ; ax=1 when arg1 < arg1
END_OPER LTE2 ; return (Arg1 < Arg2),
; --------------------------------------------------------------------------
BEGN_OPER LodLTE ; load, LTE
; return (1,0) on stack if arg2 <= arg1
FIXUP LodLTE, fcomp, X ; compare arg2 to arg1, pop st
fstsw ax ; y ...
POP_STK 1 ; ...
sahf
fldz ; 0 ...
ja short LodLTEfalse ; jump when arg2 > arg1
fld1 ; 1 0 ...
EXIT_OPER LodLTE
LodLTEfalse:
fldz ; 0 0 ...
END_OPER LodLTE
; --------------------------------------------------------------------------
BEGN_OPER LodLTE2 ; Load, LTE, test ST, clear
; return !(Arg2->d.x <= Arg1->d.x) in AX
FIXUP LodLTE2, fcom, X ; comp Arg2 to Arg1
fstsw ax
fninit
sahf
seta al
xor ah,ah ; ax=1 for expr. false
END_OPER LodLTE2 ; return (Arg2 > Arg1)
; --------------------------------------------------------------------------
BEGN_OPER LodLTEMul ; Lod, LTE, Multiply (needs 4 on stack)
; for '<expr> * ( <expr> <= <var> )'
; return number on stack if arg2 <= arg1
FIXUP LodLTEMul, fcomp, X ; comp Arg2 to Arg1, pop st
fstsw ax ; save status
POP_STK 1 ; clear 1 from stack
sahf
ja short LodLTEMulfalse ; jump if arg2 > arg1
EXIT_OPER LodLTEMul ; return value on st
PARSALIGN
LodLTEMulfalse:
POP_STK 2 ; return (0,0)
fldz
fldz
END_OPER LodLTEMul
; --------------------------------------------------------------------------
BEGN_OPER LodLTEAnd2 ; Load, LTE, AND, test ST, clear
; this is for 'expression && (expression <= value)'
; stack has {arg2.x arg2.y logical.x junk} on entry (arg1 in memory)
; Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x);
FIXUP LodLTEAnd2, fcom, X ; comp Arg2 to Arg1
fstsw ax
sahf
fxch st(2) ; logical.x arg2.y arg2.x junk ...
ja LTEA2RFalse ; right side is false, Arg2 > Arg1
ftst ; now see if left side of expr is true
fstsw ax
sahf
fninit ; clear fpu
jz LTEA2LFalse ; jump if left side of && is false
xor ax,ax ; return zero in ax for expr true
EXIT_OPER LodLTEAnd2
LTEA2RFalse:
fninit
LTEA2LFalse:
mov ax,1 ; return ax=1 for condition false
END_OPER LodLTEAnd2
; --------------------------------------------------------------------------
BEGN_OPER GTE ; >=
; Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x);
fcomp st(2) ; y x y (compare arg1,arg2)
fstsw ax
POP_STK 3 ; clear 3 from stk
sahf
fldz ; 0 (Arg2->d.y = 0.0;)
ja short GTEfalse ; jmp if arg1 > arg2
fld1 ; 1 0 (return arg2 >= arg1 on stack)
EXIT_OPER GTE
GTEfalse:
fldz ; 0 0
END_OPER GTE
; --------------------------------------------------------------------------
BEGN_OPER LodGTE ; load, GTE
; return (1,0) on stack if arg2 >= arg1
FIXUP LodGTE, fcomp, X ; compare arg2 to arg1, pop st
fstsw ax ; y ...
POP_STK 1 ; ...
fldz ; 0 ...
sahf
jb short LodGTEfalse ; jump when arg2 < arg1
fld1 ; 1 0 ...
EXIT_OPER LodGTE
LodGTEfalse:
fldz ; 0 0 ...
END_OPER LodGTE
; --------------------------------------------------------------------------
BEGN_OPER LodGTE2 ; Lod, GTE, set AX, clear FPU
; return !(Arg2->d.x >= Arg1->d.x) in AX
FIXUP LodGTE2, fcom, X ; compare arg2, arg1
fstsw ax
fninit ; clear fpu
and ah,1 ; mask cf
shr ax,8 ; shift it (AX = 1 when arg2 < arg1)
END_OPER LodGTE2 ; ret 0 in ax for true, 1 for false
; --------------------------------------------------------------------------
BEGN_OPER EQ ; ==
; Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x);
fcomp st(2) ; compare arg1, arg2
fstsw ax
POP_STK 3
sahf
fldz ; 0 (Arg2->d.y = 0.0;)
jne short EQfalse ; jmp if arg1 != arg2
fld1 ; 1 0 (ret arg2 == arg1)
EXIT_OPER EQ
EQfalse:
fldz
END_OPER EQ
; --------------------------------------------------------------------------
BEGN_OPER LodEQ ; load, EQ
; return (1,0) on stack if arg2 == arg1
FIXUP LodEQ, fcomp, X ; compare arg2 to arg1, pop st
fstsw ax ; y ...
POP_STK 1 ; ...
fldz ; 0 ...
sahf
jne short LodEQfalse ; jump when arg2 != arg1
fld1 ; 1 0 ... (return arg2 == arg1)
EXIT_OPER LodEQ
LodEQfalse:
fldz ; 0 0 ...
END_OPER LodEQ
; --------------------------------------------------------------------------
BEGN_OPER NE ; !=
; Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x);
fcomp st(2) ; compare arg1,arg2
fstsw ax
POP_STK 3
sahf
fldz
je short NEfalse ; jmp if arg1 == arg2
fld1 ; ret arg2 != arg1
EXIT_OPER NE
NEfalse:
fldz
END_OPER NE
; --------------------------------------------------------------------------
BEGN_OPER LodNE ; load, NE
; return (1,0) on stack if arg2 != arg1
FIXUP LodNE, fcomp, X ; compare arg2 to arg1, pop st
fstsw ax ; y ...
POP_STK 1 ; ...
fldz ; 0 ...
sahf
je short LodNEfalse ; jump when arg2 == arg1
; CAE changed above 'jne' to 'je' 9 MAR 1993
fld1 ; 1 0 ...
EXIT_OPER LodNE
LodNEfalse:
fldz ; 0 0 ...
END_OPER LodNE
; --------------------------------------------------------------------------
BEGN_OPER OR ; Or
; Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x);
ftst ; a1.x a1.y a2.x a2.y ...
fstsw ax
sahf
POP_STK 2 ; a2.x a2.y ...
jnz short Arg1True
ftst
fstsw ax
sahf
POP_STK 2 ; ...
fldz ; 0 ...
jz short NoneTrue
fld1 ; 1 0 ...
EXIT_OPER OR
PARSALIGN
Arg1True:
POP_STK 2 ; ...
fldz ; 0 ...
fld1 ; 1 0 ...
EXIT_OPER OR
NoneTrue: ; 0 ...
fldz ; 0 0 ...
END_OPER OR
; --------------------------------------------------------------------------
BEGN_OPER AND ; And
; Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x);
ftst ; a1.x a1.y a2.x a2.y ...
fstsw ax
sahf
POP_STK 2 ; a2.x a2.y ...
jz short Arg1False
ftst
fstsw ax
sahf
POP_STK 2 ; ...
fldz ; 0 ...
jz short Arg2False
fld1 ; 1 0 ...
EXIT_OPER AND
Arg1False:
POP_STK 2 ; ...
fldz ; 0 ...
Arg2False:
fldz ; 0 0 ...
END_OPER AND
; --------------------------------------------------------------------------
BEGN_OPER ANDClr2 ; And, test ST, clear FPU
; for bailouts using <condition> && <condition>
; Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x);
; Returns !(Arg1 && Arg2) in ax
ftst ; y.x y.y x.x x.y
fstsw ax
sahf
jz short Arg1False2
fxch st(2) ; x.x y.y y.x x.y
ftst
fstsw ax
sahf
fninit
jz short Arg2False2
BothTrue2:
xor ax,ax
EXIT_OPER ANDClr2
Arg1False2:
fninit
Arg2False2:
mov ax, 1
END_OPER ANDClr2
; --------------------------------------------------------------------------
assume ds:DGROUP, es:nothing
; called once per image
public _Img_Setup
align 4
_Img_Setup proc near
les si,_pfls ; es:si = &pfls[0]
mov di,_LastOp ; load index of lastop
shl di,2 ; convert to offset
mov bx,offset DGROUP:_fLastOp ; set bx for store
add di,si ; di = offset lastop
mov WORD PTR [bx],di ; save value of flastop
mov ax,es ; es has segment value
mov WORD PTR [bx+2],ax ; save seg for easy reload
mov ax,word ptr _v ; build a ptr to Z
add ax,3*CARG+CPFX
mov _PtrToZ,ax ; and save it
ret
_Img_Setup endp
; --------------------------------------------------------------------------
; orbitcalc function follows
; --------------------------------------------------------------------------
public _fFormula
align 16
_fFormula proc far
push di ; don't build a frame here
mov di,offset DGROUP:_s ; reset this for stk overflow area
mov bx,_InitOpPtr ; bx -> one before first token
mov ax,ds ; save ds in ax
lds cx,_fLastOp ; ds:cx -> one past last token
mov es,ax
assume es:DGROUP, ds:nothing ; swap es, ds before any fn. calls
push si
inner_loop:
add bx,4 ; point to next pointer pair
cmp bx,cx ; time to quit yet?
jae short past_loop
mov si,WORD PTR [bx+2] ; set si to operand pointer
push offset PARSERFP_TEXT:inner_loop
jmp WORD PTR [bx] ; jmp to operator fn
past_loop:
; NOTE: AX is set by the last operator fn that was called.
mov si,_PtrToZ ; ds:si -> z
mov di,offset DGROUP:_new ; es:di -> new
mov cx,4
rep movsd ; new = z
mov bx,es
pop si
pop di ; restore si, di
mov ds,b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -