📄 parsera.asm
字号:
PAGE ,132
; Name: PARSERA.ASM
; Author: Chuck Ebbert CompuServe [76306,1226]
; internet: 76306.1226@compuserve.com
; Date: 12 July 1993
; Fast floating-point routines for Fractint.
; Copyright (C) 1992, 1993 Chuck Ebbert. All rights reserved.
; This program is an assembler version of the C 'execution engine' part
; of Mark Peterson's FRACTINT Formula Parser. Many of the operator
; functions were copied from Mark's code in the files FPU087.ASM
; and FPU387.ASM. The basic operator functions are assembler versions
; of the code in PARSER.C. Many 'combined' operators functions were
; added to the program as well.
; This code may be freely distributed and used in non-commercial
; programs provided the author is credited either during program
; execution or in the documentation, and this copyright notice
; is left intact. Sale of this code, or its use in any commercial
; product requires permission from the author. Nominal distribution
; and handling fees may be charged by shareware and freeware
; distributors.
; Chuck Ebbert
; 1915 Blust Ln.
; Enola, PA 17025
.386 ; this only works on a 386
.387 ; with a 387
ifdef ??version
masm51
quirks
endif
ARGSZ equ 16 ; size of complex arg
;;;ARGSZ equ 32 ; size of hypercomplex arg
CPFX equ 4 ; size of constarg prefix
CARG equ CPFX+ARGSZ ; size of constarg
LASTSQR equ CARG*4+CPFX ; offset of lastsqr from start of v
; ---------------------------------------------------------------------------
FRAME MACRO regs ; build a stack frame
push bp
mov bp, sp
IRP reg, <regs>
push reg
ENDM
ENDM
UNFRAME MACRO regs ; unframe before return
IRP reg, <regs>
pop reg
ENDM
pop bp
ENDM
; ---------------------------------------------------------------------------
; Pop a number of scalars from the FPU stack.
; Generate as many 'fcompp' instr.'s as possible.
; Then a 'fstp st(0)' if needed.
POP_STK MACRO StkPop
NumToPop = StkPop SHR 1
REPT NumToPop
fcompp
ENDM
NumToPop = StkPop - ( NumToPop SHL 1 )
REPT NumToPop
fstp st(0)
ENDM
ENDM
; Uncomment the following line to enable compiler code generation.
;;;COMPILER EQU 1
; ---------------------------------------------------------------------------
; Generate beginning code for operator fn.
BEGN_OPER MACRO OperName
ifdef COMPILER
;; generate the fixups for compiler
;; size of fn.
db Size_&OperName
;; offset of x fixup
db XFixup_&OperName
;; offset of y fixup
db YFixup_&OperName
;; offset of included(called) fn
db Incl_&OperName
;; addr of fn to include
dw IAddr_&OperName
;; size of fn to include
db ILen_&OperName
else
;; only align when no compiler
align 4
endif
;; always generate public and begin of proc
public _fStk&OperName
_fStk&OperName proc near
ENDM
; ---------------------------------------------------------------------------
; Generate end of operator fn. code.
;
END_OPER MACRO OperName
ifndef COMPILER
;; gen a return instr.
ret
else
;; gen a jump label
End_&OperName:
;; generate zero for fixups not generated during fn.
ifndef Incl_&OperName
;; No included operator. Generate zero offset, address, and size.
Incl_&OperName EQU 0
IAddr_&OperName EQU 0
ILen_&OperName EQU 0
endif
ifndef XFixup_&OperName
;; No X fixup.
XFixup_&OperName EQU 0
endif
ifndef YFixup_&OperName
;; No Y fixup
YFixup_&OperName EQU 0
endif
endif
;; Always gen size of fn
Size_&OperName EQU $ - _fStk&OperName
;; and end of procedure.
_fStk&OperName endp
ENDM
; ---------------------------------------------------------------------------
; Generate beginning code for 'included' operator fn.
; No fixups here.
BEGN_INCL MACRO OperName
ifndef COMPILER
;; No align for 'compiler' mode.
align 4
endif
;; Generate public (incl fns. can be called directly) and begin of proc.
public _fStk&OperName
_fStk&OperName proc near
ENDM
; ---------------------------------------------------------------------------
; Generate end of 'included' operator fn. code.
END_INCL MACRO OperName
ifndef COMPILER
;; generate return
ret
else
;; generate label for jump to end of fn.
End_&OperName:
endif
;; always generate actual size of fn.
Size_&OperName EQU $ - _fStk&OperName
;; always generate end-of-proc
_fStk&OperName endp
ENDM
; ---------------------------------------------------------------------------
; 'Include' a function inside another one
INCL_OPER MACRO CallingOper,OperToIncl
ifdef COMPILER
;; Offset of include in outer fn.
Incl_&CallingOper EQU $ - _fStk&CallingOper
;; Address of included fn.
IAddr_&CallingOper EQU _fStk&OperToIncl
;; Length of included fn.
ILen_&CallingOper EQU Size_&OperToIncl
else
;; Generate a call to the included fn.
call _fStk&OperToIncl
endif
ENDM
; ---------------------------------------------------------------------------
; Exit early from an operator function.
EXIT_OPER MACRO FnToExit
ifdef COMPILER
;; jump to end of operator fn
jmp short End_&FnToExit
else
;; return to caller
ret
endif
ENDM
; ---------------------------------------------------------------------------
; Generate an FPU instruction and a fixup.
; AddrToFix is = X or Y
FIXUP MACRO OperName, InstrToFix, Addr
ifdef COMPILER
;; Generate a fixup as an offset from start of fn.
;; This is why no includes allowed before a fixup.
;; Fixup is two bytes into the instruction, thus the '+ 2'.
;; This may not be true for all instructions.
ifidni <Addr>, <X>
XFixup_&OperName EQU $ - _fStk&OperName + 2
else
;; assume fixup is for y
YFixup_&OperName EQU $ - _fStk&OperName + 2
endif
;; Generate a load, store or whatever of any convenient value using DS.
&InstrToFix QWORD PTR ds:_fLastOp
else
ifidni <Addr>, <X>
;; Gen load of X using SI.
&InstrToFix QWORD PTR [si]
else
;; Assume fixup is for y, use SI+8.
&InstrToFix QWORD PTR [si+8]
endif
endif
ENDM
; ---------------------------------------------------------------------------
; Align 4 if no compiler.
PARSALIGN macro AlignFn
ifndef COMPILER
align 4
endif
ENDM
; ---------------------------------------------------------------------------
; external functions
extrn _TranspPerPixel:far
; ---------------------------------------------------------------------------
_DATA segment word public use16 'DATA'
extrn _maxit:WORD
extrn _inside:WORD
extrn _outside:WORD
extrn _color:WORD
extrn _realcolor:WORD
extrn _kbdcount:WORD ; keyboard counter
extrn _dotmode:WORD
extrn __1_:QWORD, _PointFive:QWORD, __2_:QWORD, _infinity:QWORD
extrn _LastOp:WORD, _LastInitOp:WORD
extrn _InitOpPtr:WORD, _InitStoPtr:WORD, _InitLodPtr:WORD
extrn _s:WORD
extrn _OpPtr:WORD, _LodPtr:WORD, _StoPtr:WORD
extrn _Load:DWORD, _Store:DWORD
extrn _FormName:byte
extrn _dy1:DWORD, _dx1:DWORD, _dy0:DWORD, _dx0:DWORD
extrn _new:WORD, _old:WORD
extrn _overflow:WORD
extrn _col:WORD, _row:WORD
extrn _Transparent3D:WORD
extrn _Arg1:WORD, _Arg2:WORD
extrn _f:DWORD, _pfls:DWORD, _v:DWORD
_DATA ends
_BSS segment word public use16 'BSS'
_fLastOp label DWORD ; save seg, offset of lastop here
dd ?
_PtrToZ label WORD
dw ?
_BSS ends
DGROUP group _DATA,_BSS
; ---------------------------------------------------------------------------
; Operator Functions follow.
; ---------------------------------------------------------------------------
; NOTE: None of these operator functions may change any registers but
; ax and si. The exceptions are those functions that update
; the current values of the 'status' regs as needed.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -