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

📄 st.asm

📁 ucos porting source for Am188
💻 ASM
📖 第 1 页 / 共 3 页
字号:
COMMENT ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

              C_thru_ROM Startup Code
                  Version 2.00
       Copyright (C) 1988-1992 Datalight, Inc.
                All Rights Reserved

   This file is the Startup Code for the C_thru_ROM package.
   While it is provided in source form, this file should NOT
   be changed.  All startup code options should be set in
   the file ST.INC.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

        .186

; ALPHA TEST FEATURE - NOT FOR GENERAL USE!!
; Copy all of program CODE and DATA to RAM.  Typically RAMs are
; faster than ROMs so the program will run faster.
COPYCODE = 0

; define COMPILER types, this MUST be before ST.INC is included
USEASM	=	0
MSC5	=	1
MSC6	=	2
MSC7	=	3
TC2		=	10
TCPP	=	11
BC2		=	12
BC3		=	13

; define FLOATing point types, this MUST be before ST.INC is included
NONE		=	0
INLINE		=	1
EMULATED  	=	2
ALTERNATE 	=	3

; define CPU types, this MUST be before ST.INC is included
I8086	= 0
I186	= 1
I286	= 2
I386	= 3
I486	= 4
V25		= 5
V40		= 6
V53		= 7

; define BOOT METHODs, this MUST be before ST.INC is included
POWERUP	= 1
BIOSEXT	= 2

include .\inc\st.inc

; handle the USEASM compiler switch
IF COMPILER EQ USEASM
  IFDEF ??version
    IF ??version LT 0200H
      COMPILER = TC2
    ENDIF
    IF ??version EQ 0200H
      COMPILER = TCPP
    ENDIF
    IF ??version EQ 0205H
      COMPILER = BC2
    ENDIF
    IF ??version EQ 0300H
      COMPILER = BC3
    ENDIF
  ELSE
	; NOTE: we should figure out MASM versions
    COMPILER = MSC6
  ENDIF
ENDIF


; this cannot be included until AFTER st.inc
include .\inc\macros.inc
include .\inc\am186msr.inc


;	[]--------------------------------------[]
;	 |					|
;	 |	DEFINE THE exit() CODES		|
;	 |					|
;	[]--------------------------------------[]
;
;	80H	Return from main
;	81H	NULL ptr assignment
;	82H	Stack overflow
;	83H	MS-DOS call
;	90H	Floating Point not loaded
;	91H	Divide by zero
;	92H	Divide overflow
;	93H	Floating Point Exception

ERR_MAINRET	equ	80H	; main() has returned
ERR_NULLPTR	equ	81H	; the data at DS:0 has been modified
ERR_OVERFLOW	equ	82H	; the stack has overflowed
ERR_NO21	equ	83H	; INT 21H has occurred when it shouldn't
ERR_NOFLOAT	equ	90H	; floating point not loaded
ERR_DIVZERO	equ	91H	; divide by zero
ERR_DIVOVER	equ	92H	; overflow (INTO)
ERR_FP		equ	93H	; floating point exception


;	[]----------------------------------------------[]
;	 |						|
;	 |	DEFINE THE SEGMENT ORDERING		|
;	 |						|
;	[]----------------------------------------------[]
;
;
;		CODE		All program code (runs in ROM)
;		PLHOLDER	Placeholder in ROM to find FAR_DATA
;		FAR_DATA	Floating point and large arrays
;	    +--	DATA		Initialized data
;	    |	INITDATA	(BC++ only) Global Constructors
;	    |	EXITDATA	(BC++ only) Global Destructors
;DGROUP	----|	CONST		(MSC only) Constant data
;	    |	MSG		(MSC only) Message data
;	    |	BSS		Unintialized data
;	    +--	STACK		The stack
;		FAR_BSS		Large uninitialized arrays
;		HEAP		Beginning of the heap

; segment defined when booting via BIOS extension
IF BOOTMETHOD EQ BIOSEXT ; {

; ALPHA TEST CONCEPT - TRIAL BASIS
IF COPYCODE ; {

; a BIOS extension must be 1st.  If copying CODE, then
; the segment BIOS_EXT must be in its own class.
BIOS_EXT SEGMENT PARA PUBLIC 'BIOS_EXT'
BIOS_EXT ENDS

RELOC_CODE SEGMENT PARA PUBLIC 'PLHOLDER'
	DB "RELOC_CODE XXXX",0
RELOC_CODE ENDS

; to simplify location, the BIOS extension is in class CODE
ELSE

BIOS_EXT SEGMENT PARA PUBLIC 'CODE'
BIOS_EXT ENDS

ENDIF ; }

; segment defined when cold booting the processor
; note:	program CANNOT contain BOTH a BIOS extension and
;	a cold boot segment
ELSE
 IF BOOTMETHOD EQ POWERUP ; {

; This segment will contain cold boot code
POWER_UP SEGMENT PARA PUBLIC 'POWER_UP'
POWER_UP ENDS

; ALPHA TEST IDEA - NOT NORMALLY USED
IF COPYCODE ; {

RELOC_CODE SEGMENT PARA PUBLIC 'PLHOLDER'
	DB "RELOC_CODE DATA",0
RELOC_CODE ENDS

ENDIF ; }

; paragraph align the CODE so segment is different than POWER_UP
BEG_CODE SEGMENT PARA PUBLIC 'CODE'
BEG_CODE ENDS

 ENDIF ; }  powerup
ENDIF ; }  biosext

; this segment is the startup code
cBegCode
; Borland C needs DGROUP to be the first fixup
IF COMPILER GE TC2
	dw	DGROUP
ENDIF
cEndCode

; if Microsoft C and Floating Point
IF COMPILER LT TC2
IF FLOAT
EMULATOR_TEXT SEGMENT PARA PUBLIC 'CODE'
IF COMPILER GE MSC6
    public __EmDataSeg
IF FLOAT EQ ALTERNATE
    __EmDataSeg dw  0
ELSE
    __EmDataSeg dw  EMULATOR_DATA
ENDIF
ENDIF ; MSC6
EMULATOR_TEXT ENDS
ENDIF ; Floating Point
ENDIF ; MSC

; placeholder to find initialized data in ROM
IFE COPYCODE
RELOC_DATA SEGMENT PARA PUBLIC 'PLHOLDER'
	PUBLIC	__alicia
__alicia DB "Alicia Gislason",0		; to my lovely wife...
RELOC_DATA ENDS
ENDIF

; far data 
_FARDATA SEGMENT PARA PUBLIC 'FAR_DATA'
	db	?	; just so far_data always has something in it
_FARDATA ENDS

; Microsoft C and Floating Point (not alternate)
IF (COMPILER LT TC2) AND FLOAT AND (FLOAT NE ALTERNATE)
EMULATOR_DATA SEGMENT PARA PUBLIC 'FAR_DATA'
EMULATOR_DATA ENDS
ENDIF ; MSC FLOAT, NOT ALTERNATE

; DATA begins 1 para (16 bytes) after RDATA
cBegData
cEndData

IF FLOAT
; define a "fake" PSP so FP init can look at "environment"
	DGROUP GROUP PSP
PSP	SEGMENT PARA PUBLIC 'DATA'
db	2CH DUP (?)
	public	envseg
envseg	dw	seg PSP		; point to a NULL environment
PSP	ENDS
ENDIF

;
;   Borland Turbo C and C++
;
IF COMPILER GE TC2 ; {

  IF FLOAT ; {

  ; add all these segments to the DATA GROUP
  DGROUP	GROUP	_EMUSEG

  ; the emulator data
  _EMUSEG SEGMENT WORD COMMON 'DATA'
  _EMUSEG ENDS

  ENDIF ; } // Floating Point

  DGROUP GROUP _CVTSEG, _SCNSEG
  _CVTSEG SEGMENT WORD PUBLIC 'DATA'
  _CVTSEG ENDS
  _SCNSEG SEGMENT WORD PUBLIC 'DATA'
  _SCNSEG ENDS

ENDIF ; } // Borland/Turbo C/C++


; Used ONLY by Borland C++, these segments are defined so a
; common LOCation file can be used for both MSC and BC programs.
DGROUP	GROUP	_INIT_,_INITEND_,_EXIT_,_EXITEND_
_INIT_	SEGMENT WORD PUBLIC 'INITDATA'
InitStart       label byte
_INIT_	ENDS
_INITEND_ SEGMENT BYTE PUBLIC 'INITDATA'
InitEnd         label byte
_INITEND_ ENDS
_EXIT_	SEGMENT WORD PUBLIC 'EXITDATA'
ExitStart       label byte
_EXIT_	ENDS
_EXITEND_ SEGMENT BYTE PUBLIC 'EXITDATA'
ExitEnd         label byte
_EXITEND_ ENDS


; Used ONLY by Microsoft C, these segments are defined so a
; common LOCation file can be used by both MSC and BC programs.
DGROUP	GROUP	_CONST,MSG
_CONST	SEGMENT WORD PUBLIC 'CONST'
_CONST	ENDS
MSG	SEGMENT WORD PUBLIC 'MSG'
MSG	ENDS


	DGROUP GROUP BEG_BSS
BEG_BSS	SEGMENT PARA PUBLIC 'BSS'
BEG_BSS ENDS

	DGROUP	GROUP	_STACK
_STACK	SEGMENT STACK PARA 'STACK'
c_label	_bss_end,word
	DB	STACKSIZE dup (?)	; default stack size
c_label	_stack_end,word
_STACK	ENDS

; FAR_BSS allows for large amounts of uninitialized data
_FARBSS	SEGMENT	PARA PUBLIC 'FAR_BSS'
c_label	_beg_farbss,word
_FARBSS	ENDS

; start of heap for malloc()
_HEAP	SEGMENT PARA PUBLIC 'HEAP'
	DB	16 DUP (?)
_HEAP	ENDS


	;[]---------------------------------------------[]
	; |												|
	; |		INTITIALIZED DATA						|
	; |												|
	;[]---------------------------------------------[]

; used only for miniature INT 21H handler
DOS_VERSION	equ	0B02H

cBegData
	; copyright must be at DS:0 for NULL PTR CHECK to work.
	DB	"Copyright (C) Datalight, 1988, 1989, 1990",0

	; Display the startup code version
	out1	<>
	out1	<Startup Version 2.00>

	; Display the chosen compiler
	IF COMPILER EQ MSC5
		out1	<For Microsoft C 5.0, 5.1>
	ENDIF
	IF COMPILER EQ MSC6
		out1	<For Microsoft C 6.0>
	ENDIF
	IF COMPILER EQ MSC7
		out1	<For Microsoft C/C++ 7.0>
	ENDIF
	IF COMPILER EQ TC2
		out1	<For Turbo C 2.0>
	ENDIF
	IF COMPILER EQ TCPP
		out1	<For Turbo C++ 1.0>
	ENDIF
	IF COMPILER EQ BC2
		out1	<For Borland C/C++ 2.0>
	ENDIF
	IF COMPILER EQ BC3
		out1	<For Borland C/C++ 3.0>
	ENDIF

	; Display the memory model to screen
	outif memS,<Small Model>
	outif memM,<Medium Model>
	outif memC,<Compact Model>
	outif memL,<Large Model>
	outif memH,<Huge Model>

;
;	C_thru_ROM Specific Data
;
;
	c_public st_ver
	c_public exit_status,exit_21func,exit_21addr

_st_ver		DW	200H	; version 2.00 of C_thru_ROM startup code
_exit_status	DW	?	; exit status error code
_exit_21func	DW	?	; the INT 21H function that caused abort
_exit_21addr	DD	?	; the address of the offending INT 21H


;
;	Turbo C/Borland C++ Specific Data
;
;
IF COMPILER GE TC2
	PUBLIC	__version,_errno

IF FLOAT
  IF FLOAT EQ INLINE
	PUBLIC	__8087
__8087	DW	0FFFFH
  ELSE
	PUBLIC	__8087
__8087	DW	0H
  ENDIF
ENDIF

__version	DW	DOS_VERSION	; this label is used even though
_errno		DW	0		; no DOS is present

	; used by memory management
	c_public _asizds, _atopsp, __brklvl
__asizds	DW	8000H		; DS size (in bytes)
__atopsp	DW	0 		; top of stack (heap bottom)
___brklvl	DW	GOFFSET _bss_end+6,DGROUP	; bottom of stack


;
;	Microsoft C Specific Data
;
;
ELSE

segrec	struc			; note: from MSC 5.0
	sz	dw      ?
	sg	dw      ?
segrec	ends


	; this "variable" is defined in every MSC module to force
	; the linker to pull in MSC startup code.  We must define
	; it here so CTR startup is used instead.
PUBLIC	__acrtused
	__acrtused = 9876h	; can be anything

	PUBLIC	STKHQQ
	PUBLIC	__aintdiv,__fac,_errno,__doserrno,__umaskval
	PUBLIC	__osmajor,__osminor
	PUBLIC	_pspadr,_psp

	c_public _atopsp
	c_public _abrktb
	c_public _abrktbe,_abrkp


;	memory management variables

STKHQQ	DW	GOFFSET _bss_end+6	; bottom of stack
__atopsp	DW	0 		; top of stack (heap bottom)
__abrktb	DW	?		; segment table for brkctl
	DW	DGROUP
	DB	(20-1) * (size segrec) dup (?)	; MAX segments for


__abrktbe LABEL	WORD
__abrkp	DW	OFFSET _abrktb


__aintdiv	DD	0 	; divide error interrupt vector save
__fac		DQ	0	; floating accumulator
_errno		DW	0	; initial error code
__doserrno	DW	0	; dos error #, not used (needed for ext defs)
__umaskval	DW	0 	; initial umask value


;	do not change the order of the following

c_label		_osversion,WORD
c_label		_dosvermajor,BYTE
__osmajor	DB	0
c_label		_dosverminor,BYTE
__osminor	DB	0
_pspadr	DW	0 		; psp:0 (far * to PSP segment)

  IF FLOAT
_psp	DW	seg PSP		; psp:0 (paragraph #)
  ELSE
_psp	DW	0		; psp:0 (paragraph #)
  ENDIF

ENDIF ; MSC

cEndData

cBegUdata

	public	_heap_seg, _heap_eseg
_heap_seg	dw	?	; segment of start of heap
_heap_eseg	dw	?	; segment of end of heap

;	places to save the INT 21H and 11H vectors (for FP init)
IF FLOAT
old21	dd	?	; for saving the old interrupt vectors
old11	dd	?
ENDIF ; FLOAT

cEndUdata

;	[]---------------------------------------------[]
;	 |						|
;	 |		THE STARTUP CODE 		|
;	 |						|
;	[]---------------------------------------------[]

	c_extrnP	main		; C main function
IF USEREXIT
	c_extrnP	my_exit		; C or assembly exit() function
ENDIF

cBegCode

COMMENT ~
/*
	Here is the real start of code.  This program makes
	a stack, copies data from ROM to RAM and calls main().
*/
void	_astart()
~
	PUBLIC	__astart
__astart:

	; Set up a stack
	MOV	AX,DGROUP
	CLI
	MOV	SS,AX
	MOV	SP,GOFFSET _stack_end	; top of the stack
	MOV	DS,AX

	; Initialize hardware
IF HARDINIT
	include .\inc\HARDINIT.INC
	; Set up the stack again in case user changed it
	MOV	AX,DGROUP
	CLI
	MOV	SS,AX
	MOV	SP,GOFFSET _stack_end
ENDIF

; This section relocates initialized data (and CODE if requested)
; from ROM into RAM.  The mechanism requires cooperation between
; the startup code (here) and the location (.LOC) file for this
; program.  See the Startup Code and Locator chapters.
;
IF COPYCODE
	; Relocate CODE and DATA from ROM to RAM
	CLD

	; get start of move into DS and ES
	MOV	AX, SEG RELOC_CODE	; The RELOC_CODE segment begins
	INC	AX			; one paragraph before CODE in
	MOV	DS, AX			; ROM.  Any references directly
	MOV	AX, SEG _TEXT		; to CODE would yield a RAM address.
	MOV	ES, AX

	; determine length to move in paras
	MOV	DX, SEG	BEG_BSS		; move everything from CODE to
	SUB	DX, SEG _TEXT		; the end of initialized data

move_again:
	CMP	DX, 0		; DX contains paragraphs to move...
	JZ	done_move
	CMP	DX, 0F00H	; we can only move 64K at a time
	JA	big_move
	MOV	CX, DX			
	JMP	SHORT small_move
big_move:
	MOV	CX, 0F00H	; F00H paragraphs = F000H bytes = 60K
small_move:
	MOV	BX, CX	; save paragraphs in BX
	SHL	CX, 1	; paragraphs * 16 = bytes
	SHL	CX, 1
	SHL	CX, 1
	SHL	CX, 1	; move CX bytes
	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:

	; jump to the RAM address
	MOV	AX, SEG _TEXT
	PUSH	AX
	MOV	AX, OFFSET _TEXT:done_copy
	PUSH	AX
	RETF
done_copy:

ELSE
	; Relocate initialized far data from ROM to RAM
	CLD
	MOV	AX, SEG RELOC_DATA	; The RELOC_DATA segment begins
	INC	AX			; one paragraph before FAR_DATA
	MOV	DS, AX			; in ROM.  Any references directly
	MOV	AX, SEG _FARDATA	; to FAR_DATA would yield RAM address.
	MOV	ES, AX			; DS:0 now points to FAR_DATA
					; ES:0 now points to RAM address
					; for FAR_DATA
	; determine length of move in paras
	MOV	DX, SEG	BEG_BSS
	SUB	DX, SEG _FARDATA

move_again:
	CMP	DX, 0		; DX contains paragraphs to move...
	JZ	done_move
	CMP	DX, 0F00H	; we can only move 64K at a time
	JA	big_move
	MOV	CX, DX
	JMP	SHORT small_move
big_move:
	MOV	CX, 0F00H	; F00H paragraphs = F000H bytes = 60K
small_move:
	MOV	BX, CX	; save paragraphs in BX
	SHL	CX, 1	; paragraphs * 16 = bytes
	SHL	CX, 1
	SHL	CX, 1
	SHL	CX, 1	; move CX bytes

⌨️ 快捷键说明

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