📄 startup400.a51
字号:
; ---------------------------------------------------------------------------
; Copyright (C) 2003-2004 Dallas Semiconductor Corporation, All Rights Reserved.
;
; Permission is hereby granted, free of charge, to any person obtaining a
; copy of this software and associated documentation files (the "Software"),
; to deal in the Software without restriction, including without limitation
; the rights to use, copy, modify, merge, publish, distribute, sublicense,
; and/or sell copies of the Software, and to permit persons to whom the
; Software is furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included
; in all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
; IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
; OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
; OTHER DEALINGS IN THE SOFTWARE.
;
; Except as contained in this notice, the name of Dallas Semiconductor
; shall not be used except as stated in the Dallas Semiconductor
; Branding Policy.
; ---------------------------------------------------------------------------
;;;;
;; Startup Code Version 6
;;;;
$NOMOD51
#include <REG390.H>
EXTERN ECODE(init_romexport)
;****************************************************************************
;
; BEGIN CONFIGURABLE OPTIONS
;
; Set INITIALIZE_SERIAL0 to 0 to disable initialization of serial port 0.
; Disabling serial port 0 initialization will also disable the printing of
; the copyright message in init_rom(). When disabled, you must initialize
; serial port 0 yourself and/or override the C putchar() function if you
; want putchar(), puts(), or printf() to work.
;
$set (INITIALIZE_SERIAL0 = 1)
;
; Set USE_MONITOR to 0 to configure this program to load into bank 40 (flash on TINIm400)
; Set USE_MONITOR to 1 to configure this program to load into bank 20 (RAM on TINIm400)
; where it is suitable for use by the Keil monitor.
;
$set (USE_MONITOR = 0)
;
; Set XTALMULT to 2 or 4 to use the crystal doubler or quadrupler.
; Set XTALMULT to 1 to use the default. Do not use other
; values for XTALMULT.
;
$set (XTALMULT = 1)
;
; Set the OSCILLATOR_FREQ value to the value of the oscillator you are using.
; The TINIm400 uses a 14745600 Hz oscillator. DO NOT CHANGE THIS VALUE TO
; REFLECT THE USE OF THE CRYSTAL MULTIPLIER.
;
OSCILLATOR_FREQ equ 14745600
;
; Set SERIAL0_BAUDRATE to the baud rate you want to get standard output at.
; Default is 115200.
;
SERIAL0_BAUDRATE equ 115200
;
; Set USE_REENTRANT_STACK to 1 to use Keil's reentrant stack (allows
; recursive function calls). Set REENTRANT_STACK_TOP to the top of the
; reentrant stack if USE_REENTRANT_STACK is 1.
;
$set (USE_REENTRANT_STACK = 0)
REENTRANT_STACK_TOP equ 0FFFFh
;
; Set SETMAC to 1 to give the TINI a specific MAC ID as defined by
; the equates MAC_MSB, MAC_5, ..., MAC_LSB. Set SETMAC to 2 to
; set registers r5:r4:r3:r2:r1:r0 to your own MAC ID (see 'User MAC Code'
; below). Use a SETMAC of 0 to find the MAC in a 2502-E48.
; (Note: You also have to call init_setclock() if there is no 2502-E48.)
;
$set (SETMAC = 0)
MAC_MSB equ 00h
MAC_5 equ 60h
MAC_4 equ 62h
MAC_3 equ 63h
MAC_2 equ 64h
MAC_1 equ 65h
MAC_LSB equ 67h
;
; Change ERASE_IDATA to erase the internal data memory before the program begins.
; Do not use a value of 1 for ERASE_IDATA.
;
ERASE_IDATA equ 0h ; the amount of IDATA memory to erase
;
; Change length from 0 to erase starting at address ERASE_XDATA_ADDR for
; ERASE_XDATA_LEN bytes.
;
ERASE_XDATA_ADDR equ 0h ; the absolute start-address of XDATA memory
ERASE_XDATA_LEN equ 0h ; the length of XDATA memory in bytes.
;
; END OF CONFIGURABLE OPTIONS
;
;****************************************************************************
TIMER_RELOAD equ (65536 - ((OSCILLATOR_FREQ) / (32 * SERIAL0_BAUDRATE)))
$if (USE_REENTRANT_STACK <> 0)
C_XBP_SEG SEGMENT DATA AT 070H
RSEG C_XBP_SEG
?C_XBP: DSB 2
XBPSTACKTOP equ REENTRANT_STACK_TOP + 1
Public ?C_XBP
$endif
name ?C_STARTUP
;
; Make sure the compiler does not use the OS flags & bits
;
DSEG at 08h
regbank123: ds 24
DSEG AT 20h
wos_flags: ds 1
DSEG AT 27h
rom_flags: ds 1
DSEG AT 68h
wos_crit_count: ds 1
DSEG AT 6Bh
sched_reload: ds 2
curr_pc: ds 3
DSEG AT 72h
sched: ds 3
ms_count: ds 5
DSEG AT 7Bh
hb_chandle: ds 5
extrn code (?C_START)
public ?C_STARTUP
$if (USE_MONITOR = 0)
?C_CPURESET?0 segment code at 400000H
$endif
$if (USE_MONITOR = 1)
?C_CPURESET?0 segment code at 200000H
$endif
rseg ?C_CPURESET?0
?C_STARTUP: sjmp past_loader_tag
db 'TINI' ; Tag for TINI Environment 1.02c
; or later (ignored in 1.02b)
db byte2(?C_STARTUP) ; Target bank
past_loader_tag:
clr ea ; No interrupts, please
;
; Make sure we are in contiguous mode
;
mov ta, #0xAA ; Enable access to ACON
mov ta, #0x55
orl acon, #2 ; 24 bit mode
ljmp far sanity_check ; Sanity check: Make sure 24 bit mode is on
sanity_check:
mov ta, #0xAA ; Enable access to MCON
mov ta, #0x55
mov mcon, #0xAF ; Relocate RAM, data memory
mov ta, #0xAA ; Enable access to ACON
mov ta, #0x55
orl acon, #0x04 ; Extended stack
;
; Use the minimum number of stretch cycles on MOVX memory
;
anl ckcon, #0f8h
;
; Make sure we are in a known state with respect to
; our fancy data pointers and register banks
;
mov dps, #0
mov psw, #0
;
; Set stack to 0 (we lose one byte, but don't
; have to know the size)
;
mov sp,#0
mov esp,#0
;
; Do the Crystal Multiplier
;
$if XTALMULT = 2
startup_setxtal_mult_2:
;
; Multiply crystal frequency by 2
;
mov pmr, #10000010b ; Set for crystal * 2
mov pmr, #10010010b ; Enable multiplier
WaitCrystal:
mov a, exif ; Wait for multiplier to be ready
jnb acc.3, WaitCrystal ; Jump if CKRY is low
mov pmr, #00010010b ; Go to crystal * 2
$elseif XTALMULT = 4
startup_setxtal_mult_4:
;
; Multiply crystal frequency by 4
;
mov pmr, #10000010b ; Set to power up value
mov pmr, #10001010b ; Set for crystal * 4
mov pmr, #10011010b ; Enable multiplier
WaitCrystal4:
mov a, exif ; Wait for multiplier to be ready
jnb acc.3, WaitCrystal4 ; Jump if CKRY is low
mov pmr, #00011010b ; Go to crystal * 4
$endif
$if (INITIALIZE_SERIAL0 <> 0)
; Enable the serial0, using timer 2 at 115200
; Use this equation for the reloads:
; reload H:L = 65536 - (oscillator / (32 * baud))
; We now use User Configurable Equates for the serial
; port settings. The default is for 115200, which
; yeilds the following:
; 65536 - (14745600 / (32 * 115200)) = 65536 - (14745600 / 3686400)
; = 65536 - 4
; = 65532
; = 0xFFFC
mov scon0, #5Ah ; 10 bit serial 0, use timer baud rate, enable recieving
mov rcap2h, #High(TIMER_RELOAD) ; Set timer reload high byte
mov rcap2l, #Low(TIMER_RELOAD) ; Set timer reload low bye
mov t2con, #30h ; Enable timer 2 for serial port
setb tr2 ; Set timer 2 to run
; Make sure that we can output to the serial port
setb ti
$else
clr tr2 ; Disable serial 0 output if configured by ROM loader
$endif
$if (USE_REENTRANT_STACK <> 0)
mov ?C_XBP,#HIGH XBPSTACKTOP
mov ?C_XBP+1,#LOW XBPSTACKTOP
$endif
$if SETMAC = 1
mov r0, #MAC_LSB
mov r1, #MAC_2
mov r2, #MAC_3
mov r3, #MAC_4
mov r4, #MAC_5
mov r5, #MAC_MSB
$endif
$if SETMAC = 2
;
; User MAC Code
;
; Insert code here that will get a MAC address in registers
; r5:r4:r3:r2:r1:r0, with r5 the MSB.
;
$endif
$if SETMAC > 0
; Push registers r0 to r5
push 0
push 1
push 2
push 3
push 4
push 5
mov a, #'C'
push acc
mov a, #'A'
push acc
mov a, #'M'
push acc
$endif
IF ERASE_XDATA_LEN <> 0
mov dptr, #ERASE_XDATA_ADDR
mov r7, #BYTE0 (ERASE_XDATA_LEN)
IF (BYTE0 (ERASE_XDATA_LEN)) <> 0
mov r6, #(BYTE1 ERASE_XDATA_LEN) +1
ELSE
mov r6, #BYTE1 (ERASE_XDATA_LEN)
ENDIF
IF (BYTE1 (ERASE_XDATA_LEN)) <> 0
mov r5, #(BYTE2 ERASE_XDATA_LEN) +1
ELSE
mov r5, #BYTE2 (ERASE_XDATA_LEN)
ENDIF
clr a
erase_xdata_loop:
movx @dptr, a
inc dptr
djnz r7, erase_xdata_loop
djnz r6, erase_xdata_loop
djnz r5, erase_xdata_loop
endif
lcall init_romexport
if ERASE_IDATA <> 0
mov r0, #ERASE_IDATA - 1
clr a
erase_idata_loop:
mov @r0, a
djnz r0, erase_idata_loop
endif
ljmp ?C_START
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -