📄 cstartxf.asm
字号:
JMP cc_UC, STBINIT ; start bit initialization
BPNZ: ; bit pointer not zero
MOV R7, #16 ; R7 = 16
SUB R7, BP_RAM ; R7 = 16 - bitpointer
CMP R5, R7 ; if (initbits < (16 - bitpointer))
JMP cc_ULT, LT16 ; then bitblocksize = initbits
MOV R9, R7 ; bitblocksize = 16 - bitpointer
SUB R5, R9 ; initbits -= bitblocksize
STBINIT: ; start bit initialization
MOV R8, #0FFFFH ; mask = 0XFFFF
MOV R6, #00000H ; bitbuffer = 0X0000
MOV R10, R9 ; i = bitblocksize
NBI: ; next bit init
SHR R8, #1 ; mask >> 1;
SHR R6, #1 ; bitbuffer >> 1;
MOVB RL7, [SOF_ROM+] ; move initialization data to RL7
; and initdata++;
JMP CC_Z, CLRB ; if ( initialization data == 0 )
; then clear bitbuffer.15
BSET R6.15 ; else set bitbuffer.15
CLRB: ; R6.15 already zero
CMPD1 R10, #1 ; if ( i != 1 )
JMP cc_NE, NBI ; then i--; next bit init;
; else save bit data block
MOV R7, #16 ; R7 = 16
SUB R7, R9 ; R7 = 16 - bitblocksize
ADD R7, BP_RAM ; R7 = 16 - bitblocksize + bitpointer
SHR R6, R7 ; bitbuffer >> ((16 - bitblocksize ) +
; bitpointer)
LOOPMASK: ; mask >> ((16 - bitblocksize ) +
; bitpointer)
CMPD1 R7, #0 ;
JMP cc_Z, ENDMASK ;
SHR R8, #1 ;
BSET R8.15 ;
JMP cc_UC, LOOPMASK ;
ENDMASK: ;
AND R8, [SOF_RAM] ; mask &= *bitdata;
OR R6, R8 ; bitbuffer |= mask;
MOV [SOF_RAM], R6 ; *bitdata == bitbuffer;
ADD SOF_RAM, #2 ; bitdata += 2;
MOV BP_RAM, #0 ; bitpointer = 0;
CMP R5, #0 ; if( initbits != 0)
JMP cc_NZ, NBBI ; then continue bit initialization
; else end of bit initialization
@IF( @EQS( @MODEL, "SMALL" ) )
MOV DPP1, #PAG ?BASE_DPP1 ; restore data page register DPP1 and
MOV DPP2, #PAG ?BASE_DPP2 ; DPP2 to their default values.
@ENDI
JMP CC_UC, INIT ; next initialization
;
@ELSE ; NO BIT INITIALIZATION
;
INIT_01:
ADD R4,#0CH ; skip DBPTR, DPTR and DW
JMP CC_UC, INIT ; continue with next initialization
@ENDI
INIT_END: ;
; C166_BSS
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") | @EQS(@MODEL,"SMALL") )
MOV R4, #POF ?C166_BSS_HEAD ; move intra-page offset address rom
; data section C166_BSS to R4
BSS_DPP0: ;
MOV DPP0,#PAG ?C166_BSS_HEAD ; load data page pointer register DPP0
; with data page of rom data C166_BSS
NOP ; delay for pipeline effect
@ENDI
@IF( @EQS( @MODEL, "TINY" ) )
MOV R4, #?C166_BSS_HEAD ; move intra-segment offset address rom
; data section C166_BSS to R4
@ENDI
BSS: ;
MOV R5, [R4+] ; BSS block header code -> R5
@IF( @EQS(@MODEL,"TINY") | @EQS(@MODEL,"SMALL") )
CMP R5, #05H ; check if header code 5 (near)
@IF( @EQS(@MODEL,"SMALL") )
JMP CC_EQ, BSS_05 ;
@ELSE
JMP CC_NE, BSS_END ; if(no header code) end initialization
@ENDI
@ENDI
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") | @EQS(@MODEL,"SMALL") )
CMP R5, #06H ; check if header code 6 (far)
JMP CC_EQ, BSS_06 ;
CMP R5, #07H ; check if header code 7 (huge)
JMP CC_NE, BSS_END ; if(no header code) end initialization
BSS_07: ; clear huge ram data (data > 64 K)
MOV SOF_RAM, [R4+] ; move intra-segment offset address ram
; data block to SOF_RAM=R1
MOV R3, [R4+] ; move segment address ram data block
; to R3
; process data page number ram data
MOV RH3, SOF_RAM_H ; R3.15:14=lower order bits of data page
ROL R3, #2 ; R3.3:2:1:0 = data page number
AND R3, #0FH ; clr bit R3.15 - R3.4
MOV DPP1, R3 ; load data page pointer register DPP1
; with data page of ram data block
BFLDH SOF_RAM, #0C0H, #040H ; DPP1:POF_RAM ->SOF_RAM=R1
;
MOV R5, [R4+] ; number of bytes (R6:R5) to clear in
MOV R6, [R4+] ; specified ram data block.
; MSW=R6, LSW=R5 (long word)
;
CB07_2: CMPD1 R5, #0 ; test if all bytes are cleared and
JMP CC_NE, CB07_1 ; decrement number of bytes to clear.
CMPD1 R6, #0 ;
@IF( @EQS( @MODEL, "SMALL" ) )
JMP CC_EQ, CB07_3 ;
@ELSE
JMP CC_EQ, BSS ; if( block end ) next initialization
@ENDI
CB07_1: MOVB [SOF_RAM], ZEROS ; clear byte
CMPI1 SOF_RAM, #07FFFH ; test end of data page and inc SOF_RAM
JMP CC_NE, CB07_2 ; if(no page end) next byte clear
MOV SOF_RAM, #04000H ; preset offset address ram data
ADD DPP1, #1 ; next page ram data; increment DPP1
JMP CC_UC, CB07_2 ; jump for next byte clear
@IF( @EQS( @MODEL, "SMALL" ) )
CB07_3: MOV DPP1, #PAG ?BASE_DPP1 ; restore data page register DPP1.
JMP CC_UC, BSS ; next initialization
@ENDI
BSS_06: ; clear far ram data. (CPU mode is
; segmented with DPP usage linear or
; paged.)
MOV POF_RAM, [R4+] ; move intra-page offset address ram
; data block to POF_RAM=R1
BFLDH SOF_RAM, #0C0H, #040H ; DPP1:POF_RAM ->SOF_RAM=R1
MOV DPP1, [R4] ; load data page pointer register DPP1
; with data page of ram data block
ADD R4, #2 ; inc offset address to ram data section
; C166_BSS and also insure a delay for
; pipeline effect. (DPP1 set)
;
MOV R5, [R4+] ; number of bytes to clear in specified
; ram data block
;
CB06_1: CMPD1 R5, #0 ; test on data block end
@IF( @EQS( @MODEL, "SMALL" ) )
JMP CC_EQ, CB06_2 ;
@ELSE
JMP CC_EQ, BSS ; if( block end ) next initialization
@ENDI
MOVB [SOF_RAM], ZEROS ; clear byte
ADD SOF_RAM, #1 ; inc SOF_RAM
JMP CC_UC, CB06_1 ; jump for next byte clear
@IF( @EQS( @MODEL, "SMALL" ) )
CB06_2: MOV DPP1, #PAG ?BASE_DPP1 ; restore data page register DPP1
JMP CC_UC, BSS ; next initialization
@ENDI
@ENDI
@IF( @EQS(@MODEL,"TINY") | @EQS(@MODEL,"SMALL") )
BSS_05: ; clear near ram data. (DPP usage
; is linear, CPU mode is segmented
; for SMALL memory model and not
; segmented for TINY memory model.)
MOV SOF_RAM, [R4+] ; move intra-segment offset address ram
; data block to SOF_RAM=R1
;
MOV R5, [R4+] ; number of bytes to clear in specified
; ram data block
@IF( @EQS( @MODEL, "SMALL" ) )
MOV DPP0, #PAG ?BASE_DPP0 ; restore DPP0 to its default value
@ENDI
CB05_1: CMPD1 R5, #0 ; test on data block end, and delay for
; pipeline effect if DPP0 is restored
; for SMALL memory model
@IF( @EQS( @MODEL, "TINY" ) )
JMP CC_EQ, BSS ; if( block end ) next initialization
@ELSE
JMP CC_EQ, BSS_DPP0 ; if( block end ) reload data page
; pointer register DPP0 with data page
; of rom data C166_BSS and start next
; initialization
@ENDI
MOVB [SOF_RAM], ZEROS ; clear byte
ADD SOF_RAM, #1 ; inc SOF_RAM
JMP CC_UC, CB05_1 ; jump for next byte clear
@ENDI
BSS_END:
@IF( @EQS(@MODEL,"SMALL") )
MOV DPP0, #PAG ?BASE_DPP0 ; restore DPP0 to its default value
@ENDI
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") )
MOV DPP0, #0 ; restore DPP0 to its default value
MOV DPP1, #PAG ?USRSTACK_TOP ; set DPP1 to page of user stack
MOV DPP2, #PAG C166_DGROUP ; set DPP2 to page of default data
; group
NOP ; delay for pipeline effect
@ENDI
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") )
MOV R0, #POF ?USRSTACK_TOP ; set user stack pointer
BSET R0.0EH ; User stack uses DPP1
@ELSE
MOV R0, #?USRSTACK_TOP ; set user stack pointer
@ENDI
@IF( @EVA )
BSET IEN ; allow monitor to break application
@ENDI
MOV R12, #0 ; set argc to 0
MOV R13, #0 ;
MOV R14, #0 ; set argv[] to 0
@IF( @PXROS )
@IF( @EQS( @MODEL, "SMALL" ) | @EQS( @MODEL, "LARGE" ) )
MOV R1, #SOF __MAIN_RET ; store inter-segment jump to label
MOV [-R0], R1 ; __MAIN_RET on the user stack
MOV R1, #SEG __MAIN_RET ;
MOV [-R0], R1 ;
JMPS SEG _main, SOF _main ; call reset task main()
__MAIN_RET: ;
ADD R0, #4 ;
@ELSE
MOV R1, #SOF __MAIN_RET ; store intra-segment address return
MOV [-R0], R1 ; label __MAIN_RET on the user stack
JMPA CC_UC, _main ; call reset task main()
__MAIN_RET: ;
@ENDI
@ELSE
CALL _main ; call reset task main()
@ENDI
@IF( @EX_AB )
MOV R12, #0 ; set exit status 0
JMP _exit ; jump to exit(0) function
@ENDI
; The exit() function causes normal program termination to occur. First, all
; functions registered by the atexit() function are called in the reverse
; order. Next, all open streams with unwritten buffered data are flushed, all
; open streams are closed and all files created by the tmpfile() function are
; removed. The status value passed to exit is returned in R4.
__EXIT: LABEL FAR ; the exit() or abort() function jumps
; to this entry.
@IF( @EX_AB )
; restore (host) environment.
MOV SP, #?SYSSTACK_TOP ; restore stack pointer.
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") )
MOV R0, #POF ?USRSTACK_TOP ; restore user stack pointer
BSET R0.0EH ; User stack uses DPP1
@ELSE
MOV R0, #?USRSTACK_TOP ; restore user stack pointer
@ENDI
@IF( @FLOAT )
MOV R1, #?FPSTKUN ; restore floating point stack pointer.
MOV ?FPSP, R1 ; ?FPSP normally initialized via
; C166_INIT.
@ENDI
@ENDI
__IDLE: IDLE ; Power down CPU until peripheral inter-
; rupt or external interrupt occurs.
JMPR CC_UC, __IDLE ; set idle mode again.
RETV ; Virtual return.
__CSTART ENDP
__CSTART_PR ENDS
@IF( @EQS(@MODEL,"TINY") | @EQS(@MODEL,"SMALL") )
C166_US SECTION LDAT WORD GLBUSRSTACK 'CUSTACK'
@ENDI
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") )
C166_US SECTION DATA WORD GLBUSRSTACK 'CUSTACK'
@ENDI
@IF( @PXROS & ( @EQS(@MODEL,"SMALL") | @EQS(@MODEL,"LARGE") ) )
@IF( @EQS( @MODEL, "SMALL" ) | @EQS( @MODEL, "LARGE" ) )
DS 2+4 ; Allocate a user stack of at least 2 bytes +
; return label main (__MAIN_RET).
@ELSE
DS 2+2 ; Allocate a user stack of at least 2 bytes +
; return label main (__MAIN_RET).
@ENDI
@ELSE
DS 2 ; Allocate a user stack of at least 2 bytes
@ENDI
C166_US ENDS
@IF( @EQS(@MODEL,"MEDIUM") | @EQS(@MODEL,"LARGE") )
C166_DGROUP DGROUP __DUMMY
__DUMMY SECTION DATA WORD PUBLIC 'CNEAR'
__DUMMY ENDS
@ENDI
; REGDEF R0-R15 COMMON=REGS ; register usage ####2####
; EXTERN osek_sys_rb:WORD ; ####2####
osek_sys_rb REGDEF R0-R15
SSKDEF __STKSZ ; System stack size
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -