⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 st.asm

📁 ucos porting source for Am188
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	XOR	SI, SI	; the move always starts on a paragraph boundary
	XOR	DI, DI	; zero both SI and DI
	REP	MOVSB	; move DS:SI to ES:DI

	; update counters and segments
	SUB	DX, BX	; BX contains paragraphs that were moved
	MOV	AX, ES
	ADD	AX, BX	; increment ES by the same amount
	MOV	ES, AX
	MOV	AX, DS
	ADD	AX, BX	; increment DS by the same amount
	MOV	DS, AX
	JMP	SHORT move_again
done_move:

ENDIF

	; Zero BSS, STACK and FAR_BSS
	MOV	AX, SEG	BEG_BSS
	MOV	ES, AX
	MOV	DX, SEG _HEAP
	SUB	DX, AX
zero_again:
	CMP	DX, 0		; DX contains paragraphs to move...
	JZ	done_zero
	CMP	DX, 0F00H	; we can only zero 64K at a time
	JA	big_zero
	MOV	CX, DX
	JMP	SHORT small_zero
big_zero:
	MOV	CX, 0F00H	; F00H paragraphs = F000H bytes = 60K
small_zero:
	MOV	BX, CX	; save paragraphs in BX
	SHL	CX, 1	; paragraphs * 16 = bytes
	SHL	CX, 1
	SHL	CX, 1
	SHL	CX, 1	; zero CX bytes
	XOR	AX, AX
	MOV	DI, AX
	REP	STOSB

	; update counters and segments
	SUB	DX, BX	; BX contains paragraphs that were moved
	MOV	AX, ES
	ADD	AX, BX	; increment ES by the same amount
	MOV	ES, AX
	JMP	SHORT zero_again
done_zero:

	; Set up DGROUP (DS = SS = DGROUP)
	PUSH	SS
	POP	DS

	; Record where the stack resides
	; Microsoft C needs to know SP in 2 places
IF COMPILER LT TC2
	MOV	word ptr [_abrktb], SP
ENDIF
	MOV	[_atopsp], SP



; Initialize Floating Point Packages (if required)


IF FLOAT ; {
        ; Display to screen the intended FP package
 IF COMPILER GE TC2
    IF FLOAT EQ INLINE
        out1    <* Floating Point (Inline -f87)>
    ENDIF
    IF FLOAT EQ EMULATED
        out1    <* Floating Point (Emulator -f)>
    ENDIF
 ELSE
    IF FLOAT EQ INLINE
        out1    <* Floating Point (Inline /FPi87)>
    ENDIF
    IF FLOAT EQ EMULATED
        out1    <* Floating Point (Emulator /FPi)>
    ENDIF
    IF FLOAT EQ ALTERNATE
        out1    <* Floating Point (Alternate /FPa)>
    ENDIF
 ENDIF

        ; Set INT 21H vector to our pseudo-handler
        XOR     BX,BX
        MOV     ES,BX
        MOV     BX,21H * 4
        CLI
        MOV     AX,WORD PTR ES:[BX]     ; save the old INT 21H
        MOV     WORD PTR old21, AX      ; for later restore
        MOV     AX,WORD PTR ES:[BX+2]
        MOV     WORD PTR old21+2,AX
        MOV     WORD PTR ES:[BX],OFFSET CS:__mini_21
        MOV     WORD PTR ES:[BX+2],CS
        STI

        ; Point INT 11H to our handler (we can use INT 21H from above)
        MOV     AX,3511H                        ; get int11 interrupt vector
        INT     21H
        MOV     WORD PTR old11,BX       ; save the old INT 11H
        MOV     WORD PTR old11+2,ES     ; for later restore
        PUSH    DS
        MOV     AX,2511H
        MOV     DX,OFFSET CS:__mini_11
        PUSH    CS
        POP     DS              ; DS:DX points to INT 11H handler
        INT     21H
        POP     DS

       ; set INT 07H to point to our special INT (for V25s and 188s)
IF CPUTYPE
        PUSH    DS
        MOV     AX,2507H
        MOV     DX,OFFSET CS:__mini_07
       PUSH    CS
        POP     DS              ; DS:DX points to INT 11H handler
        INT     21H
        POP     DS
ENDIF ; CPUTYPE

        ; set INT 19H to point to V25/V35 IBRK Interrupt handler
IF CPUTYPE EQ V25
        MOV     AX,2513H
        MOV     DX,OFFSET _DATA:V25_IO_Interrupt
        INT     21H             ; DS:DX points to V25_IO_Interrupt handler
ENDIF ; CPUTYPE

        ; Initialize Floating Point for Microsoft C 5.0, 5.1 and 6.0
IF COMPILER LT TC2
        c_callm _cinit
        push    SS
        pop     DS

        ; Initialize Floating Point for Borland/Turbo C++
ELSE
        ; Borland Turbo C++ compilers only
  IF COMPILER GE TCPP
        public  StartExit

        mov     si,offset DGROUP:InitStart      ;si = start of table
        mov     di,offset DGROUP:InitEnd        ;di = end of table
        call    StartExit

        PUSH    SS
        POP     DS

        ; Initialize Turbo C 2.0
  ELSE
        push    cs
        call    ds:[__emu1st]
  ENDIF
ENDIF
        ; We are done w/ INT 21H and INT 11H, reset vectors
        PUSH    DS
        LDS     DX, old11
        MOV     AX, 2511H
        INT     21H
        POP     DS

        PUSH    DS
        LDS     DX, old21
        MOV     AX, 2521H
        INT     21H
        POP     DS
ELSE
        out1    <* No floating point>

  ; Initialize C++ for MSC 7.0
  IF COMPILER EQ MSC7
        c_callm _cinit
  ENDIF

  ; Initialize constructors for Borland C++
  IF COMPILER GE TCPP ; {
        public  StartExit

        mov     si,offset DGROUP:InitStart      ;si = start of table
        mov     di,offset DGROUP:InitEnd        ;di = end of table
        call    StartExit

        PUSH    SS
        POP     DS
  ENDIF ; } // Borland C++ compilers

ENDIF ; } // FLOAT

        ; trap INT 21H to cause an exit() if INT 21H is called
IF INT_21_CHK ; {
         out1    <* Trapping INT 21H>
         XOR     BX,BX
         MOV     ES,BX
         MOV     BX,21H * 4
         MOV     WORD PTR ES:[BX],OFFSET CS:_int_21_fail
         MOV     WORD PTR ES:[BX+2],CS
ENDIF ; } // INT_21_CHK

        ; Set up heap (for use by malloc)
        MOV     _heap_seg, SEG _HEAP    ; after FAR_BSS
        MOV     _heap_eseg, HEAPEND     ; HEAPEND defined in ST.INC


        ; Call main() -- the real user program
        PUSH    SS
        POP     ES
        STI

        c_callm main

        ; main() has returned, call exit()
        MOV     AX,ERR_MAINRET
	PUSH	AX
	c_callm	exit



;	[]---------------------------------------------[]
;	 |						|
;	 |		EXIT CODE	 		|
;	 |						|
;	[]---------------------------------------------[]

IFE	USEREXIT

;	exit has alternate labels

_abort:
__exit:
	PUBLIC	_abort, __exit
c_func	exit
	PUSH	BP
	MOV	BP, SP
	MOV	AX, P[BP]	; error code
	MOV	exit_status,AX
exit1:	STI
	JMP	exit1		; infinite loop with interrupts enabled so
c_endp	exit			; that RDEB can break out of it

ELSE

;	exit has alternate labels

c_func	exit
	PUBLIC	_abort, __exit
_abort:
__exit:
	PUSH	BP
	MOV	BP,SP
	MOV	AX,P[BP]	; error code
	MOV	exit_status,AX
exit1:	STI
	c_callm	my_exit
c_endp	exit			; that RDEB can break out of it

ENDIF




;	[]---------------------------------------------[]
;	 |						|
;	 |	STACK AND OVERFLOW CHECKING		|
;	 |						|
;	[]---------------------------------------------[]

;
;	Borland Turbo C, C++ only
;
;	TC checks the stack in each function with inline
;	code.  It calls this overflow if there is an overflow.
;	Compare this with MSC where it calls a "check stack"
;	routine from every function.
;
IF COMPILER GE TC2

	PUBLIC	OVERFLOW@, F_OVERFLOW@
OVERFLOW@	PROC	FAR
F_OVERFLOW@:
	MOV	AX,ERR_OVERFLOW
	PUSH	AX
	c_callm	exit
OVERFLOW@	ENDP


;
;	Microsoft C only
;
;	This "check stack" routine makes sure we haven't
;	overflowed and optionally checks for null ptr
;	assignment.
;
ELSE

c_labelP	_chkstk		; stack checking
c_labelP	_aNchkstk	; another chkstk label for MSC 6.0
c_labelP	_aFchkstk	; another chkstk label for MSC 6.0

  IF	NULL_PTR_CHK
  out1	<* Null Ptr Chk>
	XOR	BX,BX		; checksum the copyright message
	MOV	CX,29H
	MOV	DL,0
  chksum:
	ADD	DL,[BX]
	INC	BX
	LOOP	chksum
	CMP	DL,8BH		; value of all bytes added together
	JZ	_chkstk2

	; someone has modified the data at DS:0
	MOV	AX,ERR_NULLPTR
	PUSH	AX
	c_callm	exit
  _chkstk2:
  ENDIF

	; remove return address from stack
  IF	largeCODE
	POP	CX		; get return offset
	POP	DX		; get return segment
  ELSE
	POP	CX		; get return offset
  ENDIF

	MOV	BX,SP
	SUB	BX,AX		; new position (make room for locals)

	CMP	BX,[STKHQQ]	; SP - AX : STKHQQ (for heap/stack)
	JB	stk_ovfl	; Check for over flow

	MOV	SP,BX		; set new stack pointer

	; go back into function which called us
  IF	largeCODE
  chkproc	PROC	FAR
	PUSH	DX		; push segment
	PUSH	CX		; push offset
	RET			; far return to dx:cx
  chkproc	ENDP
  ELSE
	JMP	CX		; return to cx
  ENDIF

stk_ovfl:
	MOV	AX,82H		; stack overflow error
	PUSH	AX
	c_callm	exit
ENDIF


;
;  Microsoft C only
;
IF COMPILER LT TC2

c_label	_cintDIV,NEAR
	MOV	AX,91H		; Divide by Zero
	PUSH	AX
	CALL	exit

c_label	_amsg_exit,NEAR
	MOV	AX,92H		; amsg_exit
	PUSH	AX
	CALL	exit
ENDIF




;	[]----------------------------------------------[]
;	 |						|
;	 |		INTERRUPT TRAPPING		|
;	 |						|
;	[]----------------------------------------------[]
;

;	we have gotten an unsupport DOS call, fail immediately

IF INT_21_CHK OR FLOAT
	PUBLIC	_int_21_fail
_int_21_fail:
	STI			; re-enable interrupts
	MOV	BX,DGROUP
	MOV	DS,BX		; make sure we have a valid ds
	MOV	_exit_21func,AX			; save the function #
	POP	AX
	MOV	WORD PTR _exit_21addr,AX	; and CS:IP (address) of
	POP	AX
	MOV	WORD PTR _exit_21addr+2,AX	; the offending DOS call
	MOV	BX,ERR_NO21	; exit status for unsupported DOS call
	PUSH	BX
	c_callm	exit
ENDIF


;
;	Floating point initialization requires a miniature
;	INT 21H handler.  It supports 3 functions:
;
;	25H (set vector), 30H (get version), 35H (get vector).
;
IF FLOAT
	public __mini_21
__mini_21	PROC FAR

	; reenable interrupts
	STI

	; INT21H, function 30H - Get DOS Version
	CMP	AH,30H
	JNZ	m21_25
	MOV	AX, DOS_VERSION
	IRET

	; INT21H, function 25H - Get Interrupt Vector
m21_25: CMP	AH,25H
	JNZ	m21_35
	CMP	AL,5H
	JB	m21_25i

	PUSH	ES
	PUSH	BX

	; get pointer to vector
	XOR	BX,BX
	MOV	ES,BX
	MOV	BL,AL
	SHL	BX,1
	SHL	BX,1

	; set the vector
	CLI
	MOV	ES:[BX],DX
	MOV	ES:[BX+2],DS
	STI

	POP	BX
	POP	ES
m21_25i:
	IRET

	; INT21H, function 35H - Set Interrupt Vector
m21_35: CMP	AH,35H
	JNZ	m21_do_nothing

	; get pointer to vector
	XOR	BX,BX
	MOV	ES,BX
	MOV	BL,AL
	SHL	BX,1
	SHL	BX,1

	; set the vector
	LES	BX,dword ptr ES:[BX]
	IRET

m21_do_nothing:
	IRET
__mini_21	ENDP

ENDIF


;	[]----------------------------------------------[]
;	 |						|
;	 |	    FLOATING POINT SUPPORT		|
;	 |						|
;	[]----------------------------------------------[]

IF FLOAT

;	fake BIOS call to get equipment list
	PUBLIC	__mini_11
__mini_11	proc	far
	push	BX
	push	BX
	push	BX
	push	DS
	push	BP
	mov	BP,SP
	mov	BX, SS:[BP+10]		; DS:BX = CS:IP at time of Interrupt
	mov	DS, SS:[BP+12]
	sub	bx, 2
	cmp	word ptr DS:[BX], 011CDH
	jnz	goto_next11		; if did a "int 11H" to get here 
	pop	BP
	pop	DS
	pop	BX
	pop	BX
	pop	BX
  IF FLOAT EQ INLINE
	MOV	AX, 10b	; xxxx xx1x = 80x87 coprocessor present
  ELSE
	MOV	AX, 0	; xxxx xx0x = 80x87 coprocessor absent
  ENDIF
	iret

	; This INT 11H was not software generated - do the
	; hardware interrupt instead.  This code only comes
	; into play 
goto_next11:
	mov	BX, DGROUP
	mov	DS, BX
	mov	BX, word ptr old11	; Get old11 vector
	mov	[BP+8], BX		; Put old11 Vector on stack
	mov	BX, word ptr old11+2
	mov	[BP+10], BX
	pop	BP
	pop	DS
	pop	BX
	retf				; Chain to old11 Vector
__mini_11	endp


; handle an INT 07H (generated by the 188 on an ESC instruction)
IF CPUTYPE
	PUBLIC	__mini_07
__mini_07	proc far
	PUSH	BX
	PUSH	BP
	PUSH	DS
	MOV	BP,SP

	; get pointer to instruction
	LDS	BX,[BP+6]
	CMP	BYTE PTR DS:[BX],0DBH	; FINIT   2 byte instruction
	JNZ	fourbyte
	MOV	BX,2
	JMP	SHORT done07

fourbyte:
	MOV	BX,4					; FSTCW   4 byte instruction

done07: ADD	WORD PTR [BP+6], BX

	; we're done - return out
	POP	DS
	POP	BP
	POP	BX
	IRET
__mini_07	endp
ENDIF ; CPUTYPE


; user can (and should) supply the FP exception routines
IF USERMATHERR
  IF largeCODE
	extrn	_matherr:far
  ELSE
	extrn	_matherr:near
  ENDIF
ELSE
c_func	matherr
	MOV	AX,1
	RET
c_endp	matherr
ENDIF ; USERMATHERR

ENDIF ; FLOAT

cEndCode


;	[]----------------------------------------------[]
;	 |						|
;	 |	FLOATING POINT FOR BORLAND C/C++	|
;	 |						|
;	[]----------------------------------------------[]

; Borland and Turbo C/C++ only (no Microsoft)
IF COMPILER GE TC2 ; {

; For Borland Turbo C++ only...
IF COMPILER GE TCPP ; {

cBegCode

;------------------------------------------------------------------
;  Loop through a startup/exit (SE) table, 
;  calling functions in order of priority.
;  DS:SI is assumed to point to the beginning of the SE table
;  DS:DI is assumed to point to the end of the SE table
;  First 64 priorities are reserved by Borland
;------------------------------------------------------------------
PNEAR           EQU     0
PFAR            EQU     1
NOTUSED         EQU     0ffh

SE              STRUC
calltype        db      ?                       ; 0=near,1=far,ff=not used
priority        db      ?                       ; 0=highest,ff=lowest
addrlow         dw      ?
addrhigh        dw      ?
SE              ENDS

StartExit       PROC    NEAR
@@Start:        mov     ah,0ffh                 ; start with lowest priority

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -