📄 memory.asm
字号:
*********************************************************************************
* MEMORY.ASM v1.00 *
* 版权(c) 2003- 北京合众达电子技术有限责任公司 *
* 设计者: 段立锋 *
*********************************************************************************
.file "memory.asm"
.c_mode
.mmregs
.copy "vc54x.inc" ; VC5402 Memory-Mapped Register Declaration
.copy "dec5416.inc" ; SEED DEC5416 Memory-Mapped Register Declaration
.def _flash_erase
.def _flash_writes
.def _flash_writem
.def _flash_reads
.def _flash_readm
.def _progm_readm
.def _progm_writem
.text
*********************************************************************************
* 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 *
* *
*********************************************************************************
_flash_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
erase_poll: READA *(BL)
BITF *(BL),#Polling_Bit
NOP
NOP
BC erase_poll,NTC ; 查询擦除是否完成?
;STM #00H,AH
.if __far_mode
CMPM 3H,#Flash_SE
BC verify_SE,TC ; 扇区擦除时,转verify_SE
CMPM 3H,#Flash_BE
BC verify_BE,TC ; 块擦除时,转verify_BE
CMPM 3H,#Flash_CE
BC verify_CE,TC ; 整片擦除时,转verify_CE
POPM SWWSR
LD #0,A ; 不是上述3种擦除操作,则置未擦除干净标志,返回
FRET
.else
CMPM 2H,#Flash_SE
BC verify_SE,TC ; 扇区擦除时,转verify_SE
CMPM 2H,#Flash_BE
BC verify_BE,TC ; 块擦除时,转verify_BE
CMPM 2H,#Flash_CE
BC verify_CE,TC ; 整片擦除时,转verify_CE
POPM SWWSR
LD #0,A ; 不是上述3种擦除操作,则置未擦除干净标志,返回
RET
.endif
verify_SE: ;SFTL A,Flash_SBIT
;OR #Flash_base,16,A ; A = 被擦除扇区的起始地址
BD verify_erase
LD #Flash_SSIZE,B ; B = 扇区大小
verify_BE: ;SFTL A,Flash_BBIT
;OR #Flash_base,16,A ; A = 被擦除块的起始地址
BD verify_erase
LD #Flash_BSIZE,B ; B = 块大小
verify_CE: LD #Flash_base,16,A ; A = Flash起始地址
LD #Flash_CSIZE,4,B ; B = Flash大小
verify_erase: READA *(AR0)
CMPM *(AR0),#Flash_BLANK
BCD erase_end,NTC
XC 1,NTC
LD #0,A ; 置未擦除干净标志
ADD #ONE,A
SUB #ONE,B
BC verify_erase,BNEQ
LD #1,A ; 置擦除干净标志,返回
erase_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 *
* *
*********************************************************************************
_flash_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
write_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 write_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 *
* *
*********************************************************************************
_flash_writem: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
.if __far_mode
LDU 2H,B
.else
LDU 1H,B
.endif
STLM B,AR0 ; AR0 ← 数据起始地址
writem_loop: PSHM AL ; 保存地址
PSHM AH
.if __far_mode
FRAME -2
LDU *AR0+,B ; 取数据
STL B,0H ; 传递数据
FCALL _flash_writes
RC AEQ ; 未写入,则A = 0,返回
FRAME 2
POPM AH
POPM AL
ADD #ONE,A ; Flash地址+1
ADDM #-1,3H
CMPM 3H,#ZERO
.else
FRAME -1
LDU *AR0+,B ; 取数据
STL B,0H ; 传递数据
CALL _flash_writes
RC AEQ ; 未写入,则A = 0,返回
FRAME 1
POPM AH
POPM AL
ADD #ONE,A ; Flash地址+1
ADDM #-1,2H
CMPM 2H,#ZERO
.endif
BC writem_loop,NTC
LD #1,A ; 已写入,则A = 1,返回
POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
*********************************************************************************
* *
* 函数定义:uint _flash_reads(ulong addr) *
* 功 能:从addr指定的Flash单元中读出一个数据 *
* *
* 入口参数:A ---- 地址addr,Amsb~A0 *
* Amsb: A16,Flash用SST39VF200时 *
* A17,Flash用SST39VF400时(缺省) *
* A18,Flash用SST39VF800时 *
* Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH *
* 地址addr为从0开始的偏移地址,而非Flash的绝对地址 *
* 出口参数:A ---- 读出数据 *
* 资源使用:A *
* *
*********************************************************************************
_flash_reads: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
OR #Flash_base,16,A
READA *(AL)
POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
*********************************************************************************
* *
* 函数定义:void _flash_readm(ulong addr, uint * ptr, uint length) *
* 功 能:从addr指定的Flash单元中读出length数据到ptr所指向的数据缓冲区中 *
* *
* 入口参数: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) ---- 数据长度length,如果是.far_mode模式则m为3,否则m为2 *
* 出口参数:A ---- 读出数据 *
* 资源使用:B,AR0 *
* *
*********************************************************************************
_flash_readm: PSHM SWWSR ;保存当前的系统等待时间
LDM SWWSR,B
OR #03FH,B ;设置系统为14个等待
STLM B,SWWSR
OR #Flash_base,16,A
.if __far_mode
LDU 2H,B
.else
LDU 1H,B
.endif
STLM B,AR0 ; AR0 ← 数据起始地址
readm_loop: READA *AR0+
ADD #ONE,A ; Flash地址+1
.if __far_mode
ADDM #-1,3H
CMPM 3H,#ZERO
.else
ADDM #-1,2H
CMPM 2H,#ZERO
.endif
BC readm_loop,NTC
POPM SWWSR
.if __far_mode
FRET
.else
RET
.endif
*************************************************************************************
* *
* 函数定义:void _progm_readm(ulong addr, uint * ptr, uint length) *
* 功 能:从addr指定的程序空间中读出length数据到ptr所指向的数据缓冲区中 *
* *
* 入口参数:A ---- 地址addr,程序空间的地址 *
* (SP+n) ---- 数据缓冲区起始地址ptr,如果是.far_mode模式则n为2,否则n为1 *
* (SP+m) ---- 数据长度length,如果是.far_mode模式则m为3,否则m为2 *
* 出口参数:A ---- 读出数据 *
* 资源使用:B,AR0 *
* *
*************************************************************************************
_progm_readm: .if __far_mode ;获取数据缓冲区的首址
LDU 2H,B
.else
LDU 1H,B
.endif
STLM B,AR0 ; AR0 ← 数据起始地址
preadm_loop: READA *AR0+
ADD #ONE,A ; 程序空间地址+1
.if __far_mode
ADDM #-1,3H ; 数据区长度-1
CMPM 3H,#ZERO
.else
ADDM #-1,2H
CMPM 2H,#ZERO
.endif
BC preadm_loop,NTC ; 操作是否完成
.if __far_mode
FRET
.else
RET
.endif
*************************************************************************************
* *
* 函数定义:void _progm_writem(ulong addr, uint * ptr, uint length) *
* 功 能:从ptr所指向的数据缓冲区中将length长的数据写入addr指定的程序空间中 *
* *
* 入口参数:A ---- 地址addr,程序空间的地址 *
* (SP+n) ---- 数据缓冲区起始地址ptr,如果是.far_mode模式则n为2,否则n为1 *
* (SP+m) ---- 数据长度length,如果是.far_mode模式则m为3,否则m为2 *
* 出口参数:A ---- 读出数据 *
* 资源使用:B,AR0 *
* *
*************************************************************************************
_progm_writem: .if __far_mode ;获取数据缓冲区的首址
LDU 2H,B
.else
LDU 1H,B
.endif
STLM B,AR0 ; AR0 ← 数据起始地址
pwritem_loop: WRITA *AR0+
ADD #ONE,A ; 程序空间地址+1
.if __far_mode
ADDM #-1,3H ; 数据区长度-1
CMPM 3H,#ZERO
.else
ADDM #-1,2H
CMPM 2H,#ZERO
.endif
BC pwritem_loop,NTC ; 操作是否完成
.if __far_mode
FRET
.else
RET
.endif
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -