You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
660 lines
19 KiB
Plaintext
660 lines
19 KiB
Plaintext
16 years ago
|
;
|
||
|
; This file should only be included in the 78K0R_Kx3L demo. The 78K0R_Kx3 demo
|
||
|
; uses the standard startup file. This is work around a bug in the startup
|
||
|
; file provided with the IAR tools.
|
||
|
;
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; CSTARTUP source for 78K
|
||
|
;
|
||
|
; This module contains the code executed before the C/C++ "main"
|
||
|
; function is called.
|
||
|
;
|
||
|
; The code usually must be tailored to suit a specific hardware
|
||
|
; configuration.
|
||
|
;
|
||
|
; Assembler options:
|
||
|
;
|
||
|
; -D__STANDARD_MODEL__ To assemble for use with compiler standard
|
||
|
; code model.
|
||
|
;
|
||
|
; -D__BANKED_MODEL__ To assemble for use with compiler banked
|
||
|
; code model.
|
||
|
;
|
||
|
; -D__NEAR_MODEL__ To assemble for use with compiler near
|
||
|
; code model.
|
||
|
;
|
||
|
; -D__FAR_MODEL__ To assemble for use with compiler far
|
||
|
; code model.
|
||
|
;
|
||
|
; Linker options:
|
||
|
;
|
||
|
; -D_CODEBANK_REG=0 To link for use with "standard" code model,
|
||
|
; no banked functions.
|
||
|
;
|
||
|
; -D_CODEBANK_REG='addr' To link for use with "banked" code model or
|
||
|
; "standard" code model with banked functions.
|
||
|
; 'addr' = bank switch register address.
|
||
|
;
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Copyright (c) 2003-2008 IAR Systems AB.
|
||
|
; $Revision: 3577 $
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
#if !defined(__STANDARD_MODEL__) && !defined(__BANKED_MODEL__) && !defined(__NEAR_MODEL__) && !defined(__FAR_MODEL__)
|
||
|
#error One of the macros __STANDARD_MODEL__, __BANKED_MODEL__, __NEAR_MODEL__ or __FAR_MODEL__ must be defined !
|
||
|
#endif
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; The stack segment.
|
||
|
; The stack size is defined in the linker command file
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?CSTARTUP
|
||
|
|
||
|
RSEG CSTACK:DATA:ROOT(1)
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; The interrupt vector segment.
|
||
|
; Interrupt functions with defined vectors will reserve
|
||
|
; space in this area as well as conformingly written assembly
|
||
|
; language interrupt handlers
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
COMMON INTVEC:CODE:ROOT(1)
|
||
|
|
||
|
DC16 __program_start_fr ; Reset vector
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; The actual startup code
|
||
|
;
|
||
|
; Entry: __program_start
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
RSEG RCODE:CODE:ROOT(0)
|
||
|
|
||
|
PUBLIC ?C_STARTUP
|
||
|
PUBLIC `@cstart` ; NEC debugger specific
|
||
|
PUBLIC __program_start_fr
|
||
|
|
||
|
EXTERN __low_level_init
|
||
|
EXTERN __MAIN_CALL
|
||
|
|
||
|
#if defined(__STANDARD_MODEL__) || defined(__BANKED_MODEL__)
|
||
|
EXTERN _CODEBANK_REG
|
||
|
#else
|
||
|
EXTERN _NEAR_CONST_LOCATION
|
||
|
PMC DEFINE 0xFFFFE
|
||
|
#endif
|
||
|
#if defined(__BANKED_MODEL__)
|
||
|
EXTERN ?FAR_CALL_L07
|
||
|
|
||
|
SFRTYPE BANK_REG BYTE, READ, WRITE = _CODEBANK_REG
|
||
|
#endif
|
||
|
|
||
|
REQUIRE __MAIN_CALL
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Perform the run-time initialization.
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
?C_STARTUP:
|
||
|
`@cstart`:
|
||
|
__program_start_fr:
|
||
|
DI
|
||
|
|
||
|
#if defined(__BANKED_MODEL__)
|
||
|
MOV BANK_REG, #0 ; Banked, clear bank register
|
||
|
#elif defined(__STANDARD_MODEL__)
|
||
|
MOVW AX, #_CODEBANK_REG
|
||
|
OR A, X
|
||
|
BZ nobank ; Standard, no banked functions, no bank register (=0)
|
||
|
MOVW HL, #_CODEBANK_REG
|
||
|
XOR A, A
|
||
|
MOV [HL], A ; Standard with banked functions, clear bank register
|
||
|
nobank:
|
||
|
#else
|
||
|
MOV A, #(_NEAR_CONST_LOCATION & 1) ; Near/Far, set mirror area
|
||
|
MOV1 CY, A.0
|
||
|
MOV1 PMC.0, CY
|
||
|
#endif
|
||
|
|
||
|
#if __CORE__ != __78K0S__
|
||
|
MOVW SP, #sfe(CSTACK)
|
||
|
#else
|
||
|
MOVW AX, #sfe(CSTACK)
|
||
|
MOVW SP, AX
|
||
|
#endif
|
||
|
|
||
|
|
||
|
; Init stack segment for 78K0R, as the generated code may sometimes
|
||
|
; access the 4th byte of a return address before it is initialized
|
||
|
#if __CORE__ == __78K0R__
|
||
|
MOVW HL, #sfb(CSTACK)
|
||
|
MOVW BC, #LWRD(sizeof(CSTACK))
|
||
|
CMP0 C
|
||
|
SKZ
|
||
|
INC B
|
||
|
MOV A, #0xCD
|
||
|
loop_s:
|
||
|
MOV [HL], A
|
||
|
INCW HL
|
||
|
DEC C
|
||
|
BNZ loop_s
|
||
|
DEC B
|
||
|
BNZ loop_s
|
||
|
#endif
|
||
|
|
||
|
#if __CORE__ == __78K0R__
|
||
|
MOV CS, #0
|
||
|
#endif
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Here is the place to put user initializations.
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
; User initialization code
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Call __low_level_init to perform initialization before initializing
|
||
|
; segments and calling main.
|
||
|
; If the function returns 0, no segment initialization should take place.
|
||
|
;
|
||
|
; Link with your own version of __low_level_init to override the
|
||
|
; default action: to do nothing but return 1.
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
#if defined(__FAR_MODEL__)
|
||
|
CALL F:__low_level_init
|
||
|
#elif defined(__BANKED_MODEL__)
|
||
|
MOV E, #byte3(__low_level_init)
|
||
|
MOVW HL, #lwrd(__low_level_init)
|
||
|
CALL ?FAR_CALL_L07
|
||
|
#else
|
||
|
CALL __low_level_init
|
||
|
#endif
|
||
|
OR A, X
|
||
|
#if __CORE__ == __78K0R__
|
||
|
SKNZ
|
||
|
BR N:__MAIN_CALL
|
||
|
#else
|
||
|
BZ __MAIN_CALL
|
||
|
#endif
|
||
|
ENDMOD
|
||
|
|
||
|
#if defined(__NEAR_MODEL__) || defined(__FAR_MODEL__)
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; FAR_Z "uninitialized far data" are filled with zero
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_FAR_Z
|
||
|
|
||
|
RSEG FAR_Z:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_FAR_Z
|
||
|
|
||
|
__INIT_FAR_Z:
|
||
|
MOV ES, #BYTE3(sfb(FAR_Z))
|
||
|
MOVW HL, #LWRD(sfb(FAR_Z))
|
||
|
MOV D, #BYTE3(sizeof(FAR_Z))
|
||
|
MOVW BC, #LWRD(sizeof(FAR_Z))
|
||
|
CMP0 C
|
||
|
SKZ
|
||
|
INC B
|
||
|
CMP0 B
|
||
|
SKZ
|
||
|
INC D
|
||
|
CLRB A
|
||
|
loop:
|
||
|
MOV ES:[HL], A
|
||
|
INCW HL
|
||
|
MOV A, H
|
||
|
OR A, L
|
||
|
CLRB A
|
||
|
SKNZ
|
||
|
INC ES
|
||
|
DEC C
|
||
|
BNZ loop
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
DEC D
|
||
|
BNZ loop
|
||
|
|
||
|
ENDMOD
|
||
|
#endif
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; NEAR_Z "uninitialized near data" are filled with zero
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_NEAR_Z
|
||
|
|
||
|
RSEG NEAR_Z:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_NEAR_Z
|
||
|
|
||
|
__INIT_NEAR_Z:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
LIMIT sfb(NEAR_Z)>=0xF0000,1,1,"NEAR_I not placed in near memory"
|
||
|
#endif
|
||
|
MOVW HL, #sfb(NEAR_Z)
|
||
|
MOVW BC, #sizeof(NEAR_Z)
|
||
|
#if __CORE__ == __78K0R__
|
||
|
CMP0 C
|
||
|
SKZ
|
||
|
INC B
|
||
|
CLRB A
|
||
|
#else
|
||
|
MOV A, C
|
||
|
OR A, A
|
||
|
BZ cont
|
||
|
INC B
|
||
|
XOR A, A
|
||
|
cont:
|
||
|
#endif
|
||
|
loop:
|
||
|
MOV [HL], A
|
||
|
INCW HL
|
||
|
#if __CORE__ == __78K0R__
|
||
|
DEC C
|
||
|
BNZ loop
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
#else
|
||
|
DBNZ C, loop
|
||
|
DBNZ B, loop
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; SADDR_Z "uninitialized saddr data" are filled with zero
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_SADDR_Z
|
||
|
|
||
|
RSEG SADDR_Z:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_SADDR_Z
|
||
|
|
||
|
__INIT_SADDR_Z:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
LIMIT sfb(SADDR_Z),0xFFE20,0xFFF1F,"SADDR_Z not within saddr memory range"
|
||
|
LIMIT sfe(SADDR_Z),0xFFE20,0xFFF1F,"SADDR_Z not within saddr memory range"
|
||
|
#else
|
||
|
LIMIT sfb(SADDR_Z),0xFE20,0xFF1F,"SADDR_Z not within saddr memory range"
|
||
|
LIMIT sfe(SADDR_Z),0xFE20,0xFF1F,"SADDR_Z not within saddr memory range"
|
||
|
#endif
|
||
|
MOVW HL, #sfb(SADDR_Z)
|
||
|
MOV B, #sizeof(SADDR_Z)
|
||
|
#if __CORE__ == __78K0R__
|
||
|
CLRB A
|
||
|
#else
|
||
|
XOR A, A
|
||
|
#endif
|
||
|
loop:
|
||
|
MOV [HL], A
|
||
|
INCW HL
|
||
|
#if __CORE__ == __78K0R__
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
#else
|
||
|
DBNZ B, loop
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; WRKSEG short address work area is filled with zero
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_WRKSEG
|
||
|
|
||
|
RSEG WRKSEG:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_WRKSEG
|
||
|
|
||
|
__INIT_WRKSEG:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
LIMIT sfb(WRKSEG),0xFFE20,0xFFF1F,"WRKSEG not within saddr memory range"
|
||
|
LIMIT sfe(WRKSEG),0xFFE20,0xFFF1F,"WRKSEG not within saddr memory range"
|
||
|
#else
|
||
|
LIMIT sfb(WRKSEG),0xFE20,0xFF1F,"WRKSEG not within saddr memory range"
|
||
|
LIMIT sfe(WRKSEG),0xFE20,0xFF1F,"WRKSEG not within saddr memory range"
|
||
|
#endif
|
||
|
MOVW HL, #sfb(WRKSEG)
|
||
|
MOV B, #sizeof(WRKSEG)
|
||
|
#if __CORE__ == __78K0R__
|
||
|
CLRB A
|
||
|
#else
|
||
|
XOR A, A
|
||
|
#endif
|
||
|
loop:
|
||
|
MOV [HL], A
|
||
|
INCW HL
|
||
|
#if __CORE__ == __78K0R__
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
#else
|
||
|
DBNZ B, loop
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
#if defined(__NEAR_MODEL__) || defined(__FAR_MODEL__)
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; FAR_ID is copied to FAR_I "initialized far data"
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_FAR_I
|
||
|
|
||
|
RSEG FAR_I:DATA(0)
|
||
|
RSEG FAR_ID:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_FAR_I
|
||
|
|
||
|
__INIT_FAR_I:
|
||
|
; First make sure FAR_I and FAR_ID have the same size
|
||
|
LIMIT sizeof(FAR_I)-sizeof(FAR_ID),0,0,"FAR_I and FAR_ID not same size"
|
||
|
|
||
|
; Sanity check
|
||
|
LIMIT (sfb(FAR_I)-sfb(FAR_ID))==0,0,0,"FAR_I and FAR_ID have same start address"
|
||
|
|
||
|
; FAR_I and FAR_ID must start at the same offset in a 64k page, unless sizeof
|
||
|
; FAR_I is less than 64k, then it's enugh if both segments reside within a 64k
|
||
|
; boundary
|
||
|
LIMIT (((sfb(FAR_I)^sfb(FAR_ID)) & 0xFFFF) == 0) || ( (sizeof(FAR_I)< 0x10000) && (((sfb(FAR_I)^sfe(FAR_I)) & 0xF0000) == 0) && (((sfb(FAR_I)^sfe(FAR_I)) & 0xF0000) == 0) ),1,1,"FAR_I and FAR_ID have same start address"
|
||
|
|
||
|
|
||
|
|
||
|
; LIMIT (sfb(FAR_I)^sfb(FAR_ID)) & 0xFFFF,0,0,"FAR_I and FAR_ID must start at the same offset into a 64k page"
|
||
|
MOV ES, #BYTE3(sfb(FAR_ID))
|
||
|
MOVW HL, #LWRD(sfb(FAR_ID))
|
||
|
MOV CS, #BYTE3(sizeof(FAR_ID)) ; CS is used as counter
|
||
|
MOVW AX, #LWRD(sizeof(FAR_ID))
|
||
|
MOVW BC, AX
|
||
|
CMP0 C
|
||
|
SKZ
|
||
|
INC B
|
||
|
CMP0 B
|
||
|
SKZ
|
||
|
INC CS ; counter
|
||
|
MOV A, #BYTE3(sfb(FAR_I))
|
||
|
MOVW DE, #LWRD(sfb(FAR_I))
|
||
|
MOV X, A
|
||
|
loop:
|
||
|
MOV A, ES:[HL]
|
||
|
XCH A, X
|
||
|
XCH A, ES
|
||
|
XCH A, X
|
||
|
MOV ES:[DE], A
|
||
|
XCH A, X
|
||
|
XCH A, ES
|
||
|
XCH A, X
|
||
|
INCW HL
|
||
|
MOV A, H
|
||
|
OR A, L
|
||
|
SKNZ
|
||
|
INC ES
|
||
|
INCW DE
|
||
|
MOV A, D
|
||
|
OR A, E
|
||
|
SKNZ
|
||
|
INC X
|
||
|
DEC C
|
||
|
BNZ loop
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
DEC CS ; counter
|
||
|
BNZ loop
|
||
|
|
||
|
ENDMOD
|
||
|
#endif
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; NEAR_ID is copied to NEAR_I "initialized near data"
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_NEAR_I
|
||
|
|
||
|
RSEG NEAR_I:DATA(0)
|
||
|
RSEG NEAR_ID:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_NEAR_I
|
||
|
|
||
|
__INIT_NEAR_I:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
LIMIT sfb(NEAR_I)>=0xF0000,1,1,"NEAR_I not placed in near memory"
|
||
|
#endif
|
||
|
LIMIT sizeof(NEAR_I)-sizeof(NEAR_ID),0,0,"NEAR_I and NEAR_ID not same size"
|
||
|
#if __CORE__ == __78K0R__
|
||
|
MOV ES, #BYTE3(sfb(NEAR_ID))
|
||
|
#endif
|
||
|
MOVW HL, #sfb(NEAR_ID)
|
||
|
MOVW BC, #sizeof(NEAR_ID)
|
||
|
#if __CORE__ == __78K0R__
|
||
|
CMP0 C
|
||
|
SKZ
|
||
|
INC B
|
||
|
#else
|
||
|
MOV A, C
|
||
|
OR A, A
|
||
|
BZ cont
|
||
|
INC B
|
||
|
cont:
|
||
|
#endif
|
||
|
MOVW DE, #sfb(NEAR_I)
|
||
|
loop:
|
||
|
#if __CORE__ != __78K0R__
|
||
|
MOV A, [HL]
|
||
|
#else
|
||
|
MOV A, ES:[HL]
|
||
|
#endif
|
||
|
MOV [DE], A
|
||
|
INCW HL
|
||
|
INCW DE
|
||
|
#if __CORE__ == __78K0R__
|
||
|
DEC C
|
||
|
BNZ loop
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
#else
|
||
|
DBNZ C, loop
|
||
|
DBNZ B, loop
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Segment initialization
|
||
|
;
|
||
|
; SADDR_ID is copied to SADDR_I "initialized saddr data"
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_SADDR_I
|
||
|
|
||
|
RSEG SADDR_I:DATA(0)
|
||
|
RSEG SADDR_ID:DATA(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_SADDR_I
|
||
|
|
||
|
__INIT_SADDR_I:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
LIMIT sfb(SADDR_I),0xFFE20,0xFFF1F,"SADDR_I not within saddr memory range"
|
||
|
LIMIT sfe(SADDR_I),0xFFE20,0xFFF1F,"SADDR_I not within saddr memory range"
|
||
|
#else
|
||
|
LIMIT sfb(SADDR_I),0xFE20,0xFF1F,"SADDR_I not within saddr memory range"
|
||
|
LIMIT sfe(SADDR_I),0xFE20,0xFF1F,"SADDR_I not within saddr memory range"
|
||
|
#endif
|
||
|
LIMIT sizeof(SADDR_I)-sizeof(SADDR_ID),0,0,"SADDR_I and SADDR_ID not same size"
|
||
|
#if __CORE__ == __78K0R__
|
||
|
MOV ES, #BYTE3(sfb(SADDR_ID))
|
||
|
#endif
|
||
|
MOVW HL, #sfb(SADDR_ID)
|
||
|
MOV B, #sizeof(SADDR_ID)
|
||
|
MOVW DE, #sfb(SADDR_I)
|
||
|
loop:
|
||
|
#if __CORE__ != __78K0R__
|
||
|
MOV A, [HL]
|
||
|
#else
|
||
|
MOV A, ES:[HL]
|
||
|
#endif
|
||
|
MOV [DE], A
|
||
|
INCW HL
|
||
|
INCW DE
|
||
|
#if __CORE__ == __78K0R__
|
||
|
DEC B
|
||
|
BNZ loop
|
||
|
#else
|
||
|
DBNZ B, loop
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Initialize constructors
|
||
|
;
|
||
|
; This segment part is required by the compiler when it is
|
||
|
; necessary to call constructors of global objects.
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__INIT_CTORS
|
||
|
|
||
|
RSEG DIFUNCT(0)
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __INIT_CTORS
|
||
|
|
||
|
EXTERN __call_ctors
|
||
|
#if defined(__BANKED_MODEL__)
|
||
|
EXTERN ?FAR_CALL_L07
|
||
|
#endif
|
||
|
|
||
|
__INIT_CTORS:
|
||
|
#if __CORE__ == __78K0R__
|
||
|
MOV X, #byte3(sfe(DIFUNCT))
|
||
|
PUSH AX
|
||
|
MOVW AX, #lwrd(sfe(DIFUNCT))
|
||
|
PUSH AX
|
||
|
MOV X, #byte3(sfb(DIFUNCT))
|
||
|
PUSH AX
|
||
|
MOVW AX, #lwrd(sfb(DIFUNCT))
|
||
|
PUSH AX
|
||
|
CALL F:__call_ctors
|
||
|
#elif defined(__BANKED_MODEL__)
|
||
|
MOVW AX, #sfb(DIFUNCT)
|
||
|
MOVW BC, #sfe(DIFUNCT)
|
||
|
MOV E, #byte3(__call_ctors)
|
||
|
MOVW HL, #lwrd(__call_ctors)
|
||
|
CALL ?FAR_CALL_L07
|
||
|
#else
|
||
|
MOVW AX, #sfb(DIFUNCT)
|
||
|
MOVW BC, #sfe(DIFUNCT)
|
||
|
CALL __call_ctors
|
||
|
#endif
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Enter main
|
||
|
;
|
||
|
; Call the actual "main" function
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__MAIN_CALL
|
||
|
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __MAIN_CALL
|
||
|
PUBLIC `@cend` ; NEC debugger specific
|
||
|
|
||
|
EXTERN main
|
||
|
EXTERN exit
|
||
|
#if defined(__BANKED_MODEL__)
|
||
|
EXTERN ?FAR_CALL_L07
|
||
|
#endif
|
||
|
|
||
|
__MAIN_CALL:
|
||
|
#if defined(__FAR_MODEL__)
|
||
|
CALL F:main
|
||
|
CALL F:exit
|
||
|
#elif defined(__BANKED_MODEL__)
|
||
|
MOV E, #byte3(main)
|
||
|
MOVW HL, #lwrd(main)
|
||
|
CALL ?FAR_CALL_L07
|
||
|
|
||
|
MOV E, #byte3(exit)
|
||
|
MOVW HL, #lwrd(exit)
|
||
|
CALL ?FAR_CALL_L07
|
||
|
#else
|
||
|
CALL main
|
||
|
CALL exit
|
||
|
#endif
|
||
|
|
||
|
`@cend`:
|
||
|
|
||
|
; STOP ; Should not return
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
|
||
|
;------------------------------------------------------------------------------
|
||
|
; Low level initialization function
|
||
|
;
|
||
|
; Entry: __low_level_init
|
||
|
;
|
||
|
; The only action of this default version of '__low_level_init' is to
|
||
|
; return 1. By doing so it signals that normal initialization of data
|
||
|
; segments should be done.
|
||
|
;
|
||
|
; A customized version of '__low_level_init' may be created in order to
|
||
|
; perform initialization before initializing segments and calling main
|
||
|
; and/or to skip initialization of data segments under certain
|
||
|
; circumstances.
|
||
|
;------------------------------------------------------------------------------
|
||
|
|
||
|
MODULE ?__low_level_init_stub
|
||
|
|
||
|
RSEG RCODE:CODE:NOROOT(0)
|
||
|
|
||
|
PUBLIC __low_level_init
|
||
|
|
||
|
__low_level_init: ; By returning 1 this function
|
||
|
MOVW AX, #1 ; indicates that the normal
|
||
|
RET ; initialization should take place
|
||
|
|
||
|
ENDMOD
|
||
|
|
||
|
END
|