📄 st.asm
字号:
mov dx,di ; set sentinel to end of table
mov bx,si ; bx = start of table
@@TopOfTable: cmp bx,di ; and the end of the table?
je @@EndOfTable ; yes, exit the loop
cmp [bx.calltype],NOTUSED ; check the call type
je @@Next
cmp [bx.priority],ah ; check the priority
JA_JB: ja @@Next ; too high? skip
mov ah,[bx.priority] ; keep priority
mov dx,bx ; keep index in dx
@@Next: add bx,SIZE SE ; bx = next item in table
jmp @@TopOfTable
@@EndOfTable: cmp dx,di ; did we exhaust the table?
je @@Done ; yes, quit
mov bx,dx ; bx = highest priority item
push ds ; save ds
pop es
push es ; es = ds
cmp [bx.calltype],PNEAR ; is it near or far?
mov [bx.calltype],NOTUSED ; wipe the call type
push ss
pop ds ; get DGROUP back
je @@NearCall
@@FarCall: call DWORD PTR es:[bx.addrlow]
pop ds ; restore ds
jmp @@Start
@@NearCall: call WORD PTR es:[bx.addrlow]
pop ds ; restore ds
jmp @@Start
@@Done: ret
StartExit ENDP
cEndCode
ENDIF ; } // Borland C++ compilers (not Turbo C 2.0)
_CVTSEG SEGMENT
PUBLIC __RealCvtVector
__RealCvtVector label word
_CVTSEG ENDS
_SCNSEG SEGMENT
PUBLIC __ScanTodVector
__ScanTodVector label word
_SCNSEG ENDS
; Floating Point Initialization for all Borland Compilers
IF FLOAT ; {
; Borland, For Inline Floating Point Only
IF FLOAT EQ INLINE
public FIARQQ,FICRQQ,FIDRQQ,FIERQQ,FISRQQ
public FJARQQ,FJCRQQ,FJSRQQ
FIARQQ = 0
FICRQQ = 0
FIDRQQ = 0
FIERQQ = 0
FISRQQ = 0
FJARQQ = 0
FJCRQQ = 0
FJSRQQ = 0
ENDIF
cBegData
PUBLIC emws_limitSP, emws_initialSP
PUBLIC emws_saveVector,emws_nmiVector
PUBLIC emws_status, emws_control, emws_TOS, emws_adjust
PUBLIC emws_fixSeg, emws_BPsafe
PUBLIC emws_stamp, emws_version
PUBLIC emws_instrnPtr, emws_dataPtr, emws_instruction
; Allocate a set of 8 iNDP registers, plus extras for workspace
emws_limitSP label word
db (16 * 12) DUP (?)
; Append a spare for underflow situations.
emws_initialSP label word
dw 6 dup (?)
emws_saveVector dd ? ; prior contents of NMI vector
emws_nmiVector dd ? ; PC/AT error vector for 80287 exceptions
emws_status dw ? ; result of comparisons
emws_control dw ? ; processing options and exceptions.
emws_TOS dw ? ; current level of e87 register stack
emws_adjust dw ? ; adjusts TOS at exit
emws_fixSeg dw ? ; selector implied by segFix
emws_BPsafe dw ? ; keep BP --> userRegs here for safety.
emws_stamp dd ? ; after initialization, 'emu', 87h
emws_version dw ? ; 1 for TC2, TP5; 2 for TB2
emws_instrnPtr dd ? ; used with error recovery
emws_dataPtr dd ? ; --------- " ------------
emws_instruction dw ? ; bytes swapped, used for error recovery
PUBLIC __psp
; Borland C/C++ only
IF COMPILER GE TCPP
__psp dw seg PSP
ELSE
__psp dw ?
ENDIF
;
; V25_IO_Interrupt is invoked when an interrupt occurs in an NEC V25/V35 CPU
; when an I/O (inp, out) instruction is executed with the XX bit set in
; the flags register. The XX flag is set by Borland floating Point
; emulation. This bit has no effect on most CPU's, but on the V25/V35
; it is used to specify interrupts when an I/O instructions is executed.
;
; This routine assumes that at the time this interrupt occured CS:IP is
; one instruction past an IN or OUT instruction. The IN and OUT instructions
; can be 1 byte in size
; IN AL,DX - IN AX,DX - OUT DX,AL - OUT DX,AX
; or 2 bytes in size
; IN AL,123 - IN AX,123 - OUT 123,AL - OUT 123,AX
;
Assume CS:_Data
V25_IO_Interrupt:
push DS
push AX
push BX
mov BX, 9090H ; Set V25_1 to NOP, NOP
mov word ptr CS:[V25_1], BX
pushf
pop AX
or AX, 2 ; Set bit in flags that says Interrupt IOts
push AX
popf
mov BX, SP
push SS:[BX + 8] ; CS of program
pop DS
mov BX, SS:[BX + 6] ; IP of program
cmp byte ptr [BX], 0ECH
jNC V25_one_byte_IO
jmp V25_two_byte_IO
V25_one_byte_IO: ; Get one byte instruction
mov AL, [BX]
mov byte ptr CS:[V25_1], AL
mov BX, SP
inc word ptr SS:[BX + 6] ; IP of program
jmp V25_IO_done
V25_two_byte_IO: ; Get two bytes of instruction
mov AX, [BX]
mov word ptr CS:[V25_1], AX
mov BX, SP
inc word ptr SS:[BX + 6] ; IP of program
inc word ptr SS:[BX + 6] ; IP of program
public V25_IO_done, V25_1
V25_IO_done: ; Pop Regs and get ready to do IO
pop BX
pop AX
pop DS
V25_1 label byte
nop ; IO Instruction is placed here
nop ; Port Byte (if any is placed here)
iret
Assume CS:_Text
cEndData
;
; Special TC Floating Point Segments
;
;
_EMUSEG SEGMENT
__emu1st dw NoEmulator
__emuLast dw NoEmulator
_EMUSEG ENDS
cBegCode
NoEmulator PROC FAR
mov __8087,0
ret
NoEmulator ENDP
c_func _fperr
RET
c_endp _fperr
cEndCode
ENDIF ; } // FLOAT
ENDIF ; } // Borland/Turbo C/C++
; []----------------------------------------------[]
; | |
; | FLOATING POINT FOR MICROSOFT C |
; | |
; []----------------------------------------------[]
IF COMPILER LT TC2 ; {
;
; Define the segments needed for initializing C++
;
IF COMPILER EQ MSC7 ; {
DGROUP GROUP XIFCB, XIFU, XIFL, XIFM, XIFCE
XIFCB SEGMENT word public 'DATA'
xifcbegin label byte
XIFCB ENDS
XIFU SEGMENT word public 'DATA'
XIFU ENDS
XIFL SEGMENT word public 'DATA'
XIFL ENDS
XIFM SEGMENT word public 'DATA'
XIFM ENDS
XIFCE SEGMENT word public 'DATA'
xifcend label byte
XIFCE ENDS
ENDIF ; } MSC7
IF FLOAT ; {
;
; Add all the segments to DGROUP
;
DGROUP GROUP CDATA
DGROUP GROUP XIFB,XIF,XIFE,XIB,XI,XIE,XOB,XO,XOE
DGROUP GROUP XPB,XP,XPE,XCB,XC,XCE,XCFB,XCF,XCFE
CDATA SEGMENT word common 'DATA' ; Common data segment
CDATA ENDS
XIFB SEGMENT word public 'DATA'
xifbegin label byte
XIFB ENDS
XIF SEGMENT word public 'DATA' ; far inits
XIF ENDS
XIFE SEGMENT word public 'DATA'
xifend label byte
XIFE ENDS
XIB SEGMENT word public 'DATA'
xibegin label byte
XIB ENDS
XI SEGMENT word public 'DATA' ; near inits
XI ENDS
XIE SEGMENT word public 'DATA'
xiend label byte
XIE ENDS
XOB SEGMENT word public 'BSS'
xontab label byte
XOB ENDS
XO SEGMENT word public 'BSS' ; onexit table
XO ENDS
XOE SEGMENT word public 'BSS'
xonend label byte
XOE ENDS
XPB SEGMENT word public 'DATA'
xpbegin label byte ; end of onexit table
XPB ENDS
XP SEGMENT word public 'DATA' ; preterm's
XP ENDS
XPE SEGMENT word public 'DATA'
xpend label byte
XPE ENDS
XCB SEGMENT word public 'DATA'
xcbegin label byte
XCB ENDS
XC SEGMENT word public 'DATA' ; term's
XC ENDS
XCE SEGMENT word public 'DATA'
xcend label byte
XCE ENDS
XCFB SEGMENT word public 'DATA'
xcfbegin label byte
XCFB ENDS
XCF SEGMENT word public 'DATA' ; far term's
XCF ENDS
XCFE SEGMENT word public 'DATA'
xcfend label byte
XCFE ENDS
ENDIF ; }
cBegCode
c_func _cinit
ASSUME SS:DGROUP
IF FLOAT ; {
; 1. Initialize Floating Point
; make sure
IF COMPILER GE MSC6
mov word ptr [fpmath], offset __fpmath
mov word ptr [fpmath+2], seg __fpmath
IF FLOAT NE ALTERNATE
mov word ptr [fpdata], offset __fptaskdata
mov word ptr [fpdata+2], seg __fptaskdata
ENDIF ; NOT ALTERNATE
ENDIF ; MSC6
; re-route _fpsignal to our FP error handler
mov word ptr [fpsignal], offset _fpsig_out
mov word ptr [fpsignal+2], cs
mov si, word ptr envseg ; environment segment
lds ax, [fpdata] ; get task data area
ASSUME DS:NOTHING
mov dx,ds ; into dx:ax
xor bx,bx ; (si) = environment segment
call dword ptr ss:[fpmath] ; initialize floating point
push ss ; restore ds from ss
pop ds
jnc fpok
ASSUME DS:DGROUP
jmp _fptrap ; issue "Floating point not loaded"
; error and abort
fpok:
; initialize _cfltcvt_tab (a floating pt table)
mov bx, GOFFSET _cfltcvt_tab
IF largeCODE
mov word ptr [bx], COFFSET _cfltcvt
mov word ptr [bx+2], seg _cfltcvt
mov word ptr [bx+4], COFFSET _cropzeros
mov word ptr [bx+6], seg _cropzeros
mov word ptr [bx+8], COFFSET _fassign
mov word ptr [bx+10], seg _fassign
mov word ptr [bx+12], COFFSET _forcdecpt
mov word ptr [bx+14], seg _forcdecpt
mov word ptr [bx+16], COFFSET _positive
mov word ptr [bx+18], seg _positive
ELSE
mov word ptr [bx], COFFSET _cfltcvt
mov word ptr [bx+2],COFFSET _cropzeros
mov word ptr [bx+4],COFFSET _fassign
mov word ptr [bx+6],COFFSET _forcdecpt
mov word ptr [bx+8],COFFSET _positive
ENDIF ; largCODE
IF FLOAT NE ALTERNATE
; point the exception routine to matherr
push DS
mov AX, SEG EMULATOR_DATA
mov DS, AX
mov AX, offset _matherr
mov DS:[0], AX
mov AX, seg _matherr
mov DS:[2], AX
pop DS
ENDIF
ENDIF ; } FLOAT
IF COMPILER EQ MSC7 ; {
; 2. Initialize C++ (global constructors, etc)
IF FLOAT
mov si,GOFFSET xifbegin
mov di,GOFFSET xifend
call farinitterm ; call the far initializers
mov si,GOFFSET xibegin
mov di,GOFFSET xiend
call initterm ; call the initializers
ENDIF
mov si,GOFFSET xifcbegin
mov di,GOFFSET xifcend
call farinitterm ; call far C++ constructors.
ENDIF ; } MSC7
ret
c_endp _cinit
IF COMPILER EQ MSC7 ; {
public initterm, farinitterm
; under large code models, initterm and farinitterm are the same
IF largeCODE
farinitterm:
ENDIF
initterm:
cmp SI, DI ; are we done?
jae itdone ; yes - no more
IF largeCODE ; {
sub DI, 4
mov AX, [DI]
or AX, [DI+2]
jz initterm ; skip null procedures
call dword ptr [DI]
ELSE
dec DI
dec DI
mov CX, [DI]
jcxz initterm ; skip null procedures
call CX
ENDIF ; }
jmp initterm ; keep looping
itdone: ret
IFE largeCODE ; {
farinitterm:
cmp SI, DI ; are we done?
jae faritdone ; yes - no more
sub DI, 4
mov AX, [DI]
or AX, [DI+2]
jz farinitterm ; skip null procedures
call dword ptr [DI]
jmp farinitterm ; keep looping
faritdone:
ret
ENDIF ; } !largeCODE
ENDIF ; } MSC7
cEndCode
IF FLOAT ; {
IF COMPILER GE MSC6
extrn __fpmath:far
IF FLOAT NE ALTERNATE
extrn __fptaskdata:far
ENDIF
ENDIF
; CDATA is a COMMON segment
CDATA SEGMENT
ASSUME DS:DGROUP
c_extrn _cfltcvt_tab,WORD ; a jmp table for floating pt
DW 0 ; force segment to be at least 0's
c_label _fpinit,DWORD ; public for signal
fpmath DD 1 dup (?) ; linking trick for fp
fpdata DD 1 dup (?)
fpsignal DD 1 dup (?) ; fp signal message
CDATA ENDS
cBegCode
c_extrnP _cfltcvt
c_extrnP _cropzeros
c_extrnP _fassign
c_extrnP _forcdecpt
c_extrnP _positive
IF COMPILER GE MSC6
PUBLIC __dataseg
__dataseg label word
DW DGROUP
ENDIF ; MSC6
c_func _fpsig_out
mov ah, ERR_FP
push ax ; floating point signal call
call exit ; and die
c_endp _fpsig_out
c_func _fptrap
mov ax, ERR_NOFLOAT
push ax ; issue floating point not loaded
call exit ; and die...
c_endp _fptrap
c_func _NMSG_WRITE
mov ax,95H
push ax
call exit
c_endp _NMSG_WRITE
__wrt2err:
PUBLIC __wrt2err
c_func wrt2err
mov ax,96H
push ax
call exit
c_endp wrt2err
cEndCode
; Microsoft C only
IF FLOAT EQ INLINE
public FIARQQ,FICRQQ,FIDRQQ,FIERQQ,FISRQQ,FIWRQQ
public FJARQQ,FJCRQQ,FJSRQQ
FIARQQ equ 0
FICRQQ equ 0
FIDRQQ equ 0
FIERQQ equ 0
FISRQQ equ 0
FIWRQQ equ 0
FJARQQ equ 0
FJCRQQ equ 0
FJSRQQ equ 0
ELSE
IF COMPILER GE MSC6
public FIARQQ,FICRQQ,FIDRQQ,FIERQQ,FISRQQ,FIWRQQ
public FJARQQ,FJCRQQ,FJSRQQ
FIARQQ EQU 0FE32H
FICRQQ EQU 00E32H
FIDRQQ EQU 05C32H
FIERQQ EQU 01632H
FISRQQ EQU 00632H
FIWRQQ EQU 024FBH ; change WAIT,NOP to MOV AX,AX
FJARQQ EQU 04000H
FJCRQQ EQU 0C000H
FJSRQQ EQU 08000H
ENDIF ; MSC6
ENDIF
ENDIF ; } FLOAT
ENDIF ; } Microsoft C
; []----------------------------------------------[]
; | |
; | ALTERNATE STARTUP METHODS |
; | |
; []----------------------------------------------[]
; Start via cold boot of 80x86 processor
IF BOOTMETHOD EQ POWERUP ; {
out1 <* Including Powerup Segment>
include .\inc\POWERUP.INC
START_LABEL equ reset
ELSE
; Start via BIOS extension (address range C0000-F0000)
IF BOOTMETHOD EQ BIOSEXT ; {
out1 <* Including Bios Extension>
include .\inc\BIOSEXT.INC
START_LABEL equ extend
ELSE
; Start via JMP instruction (another program's responsibility)
START_LABEL equ __astart
ENDIF ; }
ENDIF ; } /* powerup */
IF HARDINIT
out1 <* Including Hardware Initialization>
ENDIF
IF HEAPEND
out1 <* Heap (malloc) Enabled>
ELSE
out1 <* No Heap>
ENDIF
; Let user know we are copying code to RAM
IF COPYCODE
out1 <* Copy CODE to RAM enabled>
ENDIF
out1 <>
end START_LABEL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -