📄 bootmain.asm
字号:
STM #Flash_base,AH
STM #0,BL
PSHM BL
FCALL _bflash_writes
POPM BL
BC boot_end,ANEQ ;if A!=0 ,write next data
b $
boot_end: b $
*********************************************************************************
* FLASH的操作 *
*********************************************************************************
*********************************************************************************
* *
* 函数定义:uint _flash_erase(uint addr, uint type) *
* 功 能:Flash扇区/块/整片擦除操作 *
* *
* 入口参数:A ---- 地址addr *
* 扇区擦除:Amsb~A11,每个扇区2K *
* 块擦除 :Amsb~A15,每个块32K *
* 整片擦除:5555H *
* Amsb: A16,Flash用SST39VF200时 *
* A17,Flash用SST39VF400时(缺省) *
* A18,Flash用SST39VF800时 *
* Flash定位在程序储存空间0x4000000~401FFFFH *
* ~403FFFFH(缺省) *
* ~407FFFFH *
* 地址addr为从A11开始的偏移地址,而非Flash的绝对地址 *
* (SP+n) ---- 操作类型type,如果是.far_mode模式则n为2,否则n为1 *
* 扇区擦除:30H *
* 块擦除: 50H *
* 整片擦除:10H *
* 出口参数:A ---- 擦除标志 *
* 未擦干净:00H *
* 已擦干净:01H *
* 资源使用:B,AR0 *
* *
*********************************************************************************
_bflash_erase: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
PSHM AH
PSHM AL ; 保存地址
STM #Flash_base,AH
STM #Flash_5555,AL
STM #Flash_UL1,BL
WRITA *(BL) ; AAH -> (405555H)
STM #Flash_2AAA,AL
STM #Flash_UL2,BL
WRITA *(BL) ; 55H -> (402AAAH)
STM #Flash_5555,AL
STM #Flash_ERASE,BL
WRITA *(BL) ; 80H -> (405555H)
STM #Flash_5555,AL
STM #Flash_UL1,BL
WRITA *(BL) ; AAH -> (405555H)
STM #Flash_2AAA,AL
STM #Flash_UL2,BL
WRITA *(BL) ; 55H -> (82AAAH)
POPM AL ; 恢复地址
POPM AH
NOP
NOP
NOP
.if __far_mode
WRITA 3H ; type -> (addr)
.else
WRITA 2H
.endif
berase_poll: READA *(BL)
BITF *(BL),#Polling_Bit
NOP
NOP
BC berase_poll,NTC ; 查询擦除是否完成?
;STM #00H,AH
.if __far_mode
LD 3H,A
CMPM 3H,#Flash_SE
BC bverify_SE,TC ; 扇区擦除时,转verify_SE
CMPM 3H,#Flash_BE
BC bverify_BE,TC ; 块擦除时,转verify_BE
CMPM 3H,#Flash_CE
BC bverify_CE,TC ; 整片擦除时,转verify_CE
NOP
POPM SWWSR
LD #0,A ; 不是上述3种擦除操作,则置未擦除干净标志,返回
FRET
.else
CMPM 2H,#Flash_SE
BC bverify_SE,TC ; 扇区擦除时,转verify_SE
CMPM 2H,#Flash_BE
BC bverify_BE,TC ; 块擦除时,转verify_BE
CMPM 2H,#Flash_CE
BC bverify_CE,TC ; 整片擦除时,转verify_CE
POPM SWWSR
LD #0,A ; 不是上述3种擦除操作,则置未擦除干净标志,返回
RET
.endif
bverify_SE: ;SFTL A,Flash_SBIT
;OR #Flash_base,16,A ; A = 被擦除扇区的起始地址
BD bverify_erase
LD #Flash_SSIZE,B ; B = 扇区大小
bverify_BE: ;SFTL A,Flash_BBIT
;OR #Flash_base,16,A ; A = 被擦除块的起始地址
BD bverify_erase
LD #Flash_BSIZE,B ; B = 块大小
bverify_CE: LD #Flash_base,16,A ; A = Flash起始地址
LD #Flash_CSIZE,4,B ; B = Flash大小
bverify_erase: READA *(AR0)
CMPM *(AR0),#Flash_BLANK
BCD berase_end,NTC
XC 1,NTC
LD #0,A ; 置未擦除干净标志
ADD #ONE,A
SUB #ONE,B
BC bverify_erase,BNEQ
LD #1,A ; 置擦除干净标志,返回
berase_end: POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
*********************************************************************************
* *
* 函数定义:uint _flash_writes(ulong addr, uint data) *
* 功 能:将数据data写入addr所指定的Flash单元 *
* *
* 入口参数:A ---- 地址addr,Amsb~A0 *
* Amsb: A16,Flash用SST39VF200时 *
* A17,Flash用SST39VF400时(缺省) *
* A18,Flash用SST39VF800时 *
* Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH *
* 地址addr为从0开始的偏移地址,而非Flash的绝对地址 *
* (SP+n) ---- 数据data,如果是.far_mode模式则n为2,否则n为1 *
* 出口参数:A ---- 写入标志 *
* 未写入:00H *
* 已写入:01H *
* 资源使用:B *
* *
*********************************************************************************
_bflash_writes: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
PSHM AL
PSHM AH ; 保存地址
STM #Flash_base,AH
STM #Flash_5555,AL
STM #Flash_UL1,BL
WRITA *(BL) ; AAH -> (85555H)
STM #Flash_2AAA,AL
STM #Flash_UL2,BL
WRITA *(BL) ; 55H -> (82AAAH)
STM #Flash_5555,AL
STM #Flash_PRG,BL
WRITA *(BL) ; A0H -> (85555H)
POPM AH ; 恢复地址
POPM AL
OR #Flash_base,16,A
.if __far_mode
WRITA 3H ; data -> (addr)
.else
WRITA 2H
.endif
bwrite_poll: READA *(BL)
NOP
NOP
.if __far_mode
XOR 3H,B ; data ^ B
.else
XOR 2H,B
.endif
NOP
NOP
NOP
BITF *(BL),#Polling_Bit
BC bwrite_poll,TC ; 查询写操作是否完成?
READA *(BL)
.if __far_mode
XOR 3H,B ; data ^ B
.else
XOR 2H,B
.endif
NOP
NOP
NOP
STM #ZERO,BH ; 验证写操作
LD #1,A ; 正确,A = 1
XC 1,BNEQ
LD #0,A ; 错误,A = 0
NOP
NOP
NOP
POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
*********************************************************************************
* *
* 函数定义:uint _flash_writem(ulong addr, uint * ptr, uint length) *
* 功 能:将ptr所指向的数据缓冲区中的length个数据写入addr所指定的Flash单元 *
* *
* 入口参数:A ---- 地址addr,Amsb~A0 *
* Amsb: A16,Flash用SST39VF200时 *
* A17,Flash用SST39VF400时(缺省) *
* A18,Flash用SST39VF800时 *
* Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH *
* 地址addr为从0开始的偏移地址,而非Flash的绝对地址 *
* (SP+n) ---- 数据缓冲区起始地址ptr,如果是.far_mode模式则n为2,否则n为1 *
* (SP+m) ---- 数据长度lrngth,如果是.far_mode模式则m为3,否则m为2 *
* 出口参数:A ---- 写入标志 *
* 未写入:00H *
* 已写入:01H *
* 资源使用:B,AR0 *
* *
*********************************************************************************
_bflash_writem: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
STM #60H,AR0
.if __far_mode
DLD 4H,B
.else
DLD 3H,B
.endif
DST B,*AR0 ; AR0 ← 数据起始地址
bwritem_loop: PSHM AL ; 保存地址
PSHM AH
DLD *AR0,B ; 取数据的地址
LD B,A
ADD #1,B
DST B,*AR0
READA *(BL)
NOP
NOP
NOP
POPM AH
POPM AL
PSHM AL
PSHM AH
PSHM BL
FCALL _bflash_writes
POPM BL
RC AEQ ; 未写入,则A = 0,返回
POPM AH
POPM AL
ADD #ONE,A ; Flash地址+1
.if __far_mode
ADDM #-1,3H
CMPM 3H,#ZERO
.else
ADDM #-1,2H
CMPM 2H,#ZERO
.endif
BC bwritem_loop,NTC
LD #1,A ; 已写入,则A = 1,返回
POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -