📄 card_cpuv21.inc
字号:
;***********************************************************
;程序名称: CPU卡操作子程序
;程序开发: 前锋集团技术中心
;编写时间: 2004年7月13日
;软件环境: 供税控器QF561型的上层C语言使用
;硬件环境: QF561税控器硬件版本V1.0
;MCU: TOSHIBA TMP93CS41@max 16M/1
;程序版本: V1.00
;最后修订时间: 2004年12月28日
;修订部分说明:
;----------------------------------------------------------
;汇编词典:
;----------------------------------------------------------
;需要的变量定义:
TEMP_BUFFER equ 0x182
TEMP_BUFFER1 equ 0x183
TEMP_BUFFER2 equ 0x187
count_del equ 0x226
T_RETT equ 0x228 ;16位定时器用的寄存器
TEMP_BUFFER3 equ 0x229
tc_modify equ 0x22A
TC2 equ 0x22D
TC1 equ 0x22E
ETU_COUTER equ 0x22F
SAM_RACK equ 0x230 ;复位应答所用到的标志寄存器
SAM_ASPE equ 0x231 ;复位应答所用到的方向寄存器
TS equ 0x232 ;复位应答开始存放地
T0 equ 0x233
TA1 equ 0x24C
TB1 equ 0x24D
TD1 equ 0x24E
TA2 equ 0x24F
TB2 equ 0x250
TD2 equ 0x251
;发送或接收数据存放起始地
data_cmd equ 0x252 ;0x00-LE存在,0X01-LC存在
CLA equ 0x253
INS equ 0x254
COMMAND_p1 equ 0x255
COMMAND_p2 equ 0x256
COMMAND_p3 equ 0x257
trans_recive_adr equ 0x258
filename0 equ 0x258
filename1 equ 0x259
FILENAME equ 0x120 ;文件名
;**********************************************************
;---全局函数声明---
PUBLIC __card_release ;***卡片释放,用户卡和税控卡同时释放
PUBLIC __SAM_RESET ;***税控卡复位
PUBLIC __USER_RESET ;***用户卡复位
PUBLIC __COM_S_D ;***发送命令函数
PUBLIC __UPDATE_CONTROLS ;***更新税控卡内监控管理数据
PUBLIC __FISCAL_REGISTER ;***初始化注册流程(user&sam)
PUBLIC __DATA_COLLECT ;***申报数据汇总采集(user)
PUBLIC __DECLARE_DUTY ;***生成申报数据(sam)
PUBLIC __ISSUE_INVOICE ;***开票流程(sam)
PUBLIC __VERIFY_FISCAL_PIN ;***校验税控机使用口令(sam)
PUBLIC __VERIFY ;***校验pin的正确性(user)
PUBLIC __INPUT_INVOICE_NB ;***税控卡录入发票号(打印)(sam)
PUBLIC __DISTRIBUTE_INVOICE_NB ;***分发用户卡中的发票号(打印)(user)
PUBLIC __GET_CHALLENGE ;***请求一个用于相关过程的随机数(sam&user)
PUBLIC __EXTERNAL_AUTHENTICATION ;***外部认证(user),认证级别外部放入(COMMAND_p2)
PUBLIC __INTERNAL_ATUHNTICATION ;***内部认证(sam),认证级别外部放入(COMMAND_p2)
PUBLIC __READ_RECORD ;***读记录(sam&user)
PUBLIC __UPDATE_RECORD ;***更新记录(sam&user)
PUBLIC __READ_BINARY ;***读2进制文件(sam&user)
PUBLIC __DAILY_COLLECT_SIGN ;***日交易累计或其他数据签名(sam)
PUBLIC __SELECTMF ;***选择MF文件(sam&user)
PUBLIC __SELECTDF ;***选择DF文件(sam&user)
PUBLIC __SELECT_EF01 ;***选择EF01文件(sam&user)
PUBLIC __SELECT_EF02 ;***选择EF02文件(sam&user)
PUBLIC __SELECT_EF03 ;***选择EF03文件(sam&user)
PUBLIC __SELECT_EF04 ;***选择EF04文件(sam&user)
PUBLIC __SELECT_EF05 ;***选择EF05文件(sam&user)
PUBLIC __SELECT_EF06 ;***选择EF06文件(sam&user)
PUBLIC __SELECT_EF07 ;***选择EF07文件(sam&user)
PUBLIC __SELECT_EF08 ;***选择EF08文件(sam&user)
PUBLIC __SELECT_EFCOM ;***选择EF文件(sam&user)
PUBLIC __SELECT_FILE01 ;***选择EF01文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE02 ;***选择EF02文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE03 ;***选择EF03文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE04 ;***选择EF04文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE05 ;***选择EF05文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE06 ;***选择EF06文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE07 ;***选择EF07文件(sam&user),在没有选择MF、DF情况下
PUBLIC __SELECT_FILE08 ;***选择EF08文件(sam&user),在没有选择MF、DF情况下
PUBLIC __TIM5_INTER
;**********************************************************
;定义伪指令,当硬件结构改变时修改本位置上的指令即可完成程序修改
;----------------------------------------------------------
;P8.7 ICINT user卡座到位中断,上升沿中断
;P9.7 ICPOW user卡电源控制,0=开
;P9.6 SAMPOW sam卡电源控制,0=开
;P9.2 SAMRST sam卡复位
;P9.5 ICRST user卡复位
;PA.0 ICSI 1101卡MISO
;PA.1 ICSO 1101卡MOSI、user卡I/O口
;PA.2 SAMIO sam卡I/O口
;PA.3 ICRST 1101卡时钟
;PA.4 ICCLK 1101卡片选CS
;----------------------------------------------------------
;SAM卡和USER卡的复位被安排在端口cs_ret_port的cs_rst_bit位和cu_rst_bit位上
cs_rst_port equ P9 ;---Cpu card SAM ReSeT PORT
cs_rst_bit equ 2 ;---Cpu card SAM ReSeT BIT
cu_rst_bit equ 5 ;---Cpu card User ReSeT BIT
;----------------------------------------------------------
;USER卡座电源控制被安排在端口ic_pow_port的cu_pow_bit位上
ic_pow_port equ P9 ;---IC POWer control PORT
cu_pow_bit equ 7 ;---Cpu card User POWer control BIT
;----------------------------------------------------------
;SAM卡座电源控制被安排在端口cc_pow_port的cs_pow_bit位上
cc_pow_port equ P9 ;---Cpu Card sam POWer control PORT
cs_pow_bit equ 6 ;---Cpu card Sam POWer control BIT
;----------------------------------------------------------
;SAM卡和USER卡的I/O口被安排在端口cc_port的cs_io_bit位和cu_io_bit位上
cc_port equ PA ;---Cpu Card i/o PORT
cs_io_bit equ 2 ;---Cpu card Sam I/O BIT
cu_io_bit equ 1 ;---Cpu card User I/O BIT
;**********************************************************
;RES_ONEBYTE1:
RES_ONEBYTE_ACK: ;复位应答使用的接收
ld w,4 ;出错后的循环计数器
ld (TEMP_BUFFER3),0x32 ;50*240=12000etu
jr RES_ONEBYTE0
RES_ONEBYTE: ;普通命令使用的接收
ld w,4 ;出错后的循环计数器
ld (TEMP_BUFFER3),0x78 ;120*240=28800etu
;*******两种接收只是定时使用的等待时间长短不同*************
RES_ONEBYTE0: ;接收应答一个字节
ld (T_RETT),(TEMP_BUFFER3)
ld (SAM_RACK),0x00
call IO_IN
call ON_TIME39800C ;重开定时器40etu
RES_ONEBONE:
ldcf 1,(SAM_RACK) ;超时?
jp c,EXIT_RET ;若定时9800ETU或19200etu到,退出
ldcf a,(cc_port)
jr c,RES_ONEBONE ;为高没接收到起始位,继续接收
and (TRUN),0x9F ;关定时器
call DELAY0_5ETU ;延时1.5个etu 在5MHz时,etu=74.4us
call DELAY1_0ETU
;************* START RECEIVE ONE BYTE**********************
REC_ONEBYTE:
ld B,8 ;为低接收到起始位,接收8个数据2s
and (SAM_ASPE),0xDF ;将奇偶位清0 7s
ldcf 0,(SAM_ASPE) ;8s
jr C,FANXIANG ;判断方向后去接收 8/4s
RECE_EIGHT: ;正向接收流程
ldcf A,(cc_port)
rr 1,D ;将收到的数据存放在D寄存器中6s
ldcf A,(cc_port)
xorcf 5,(SAM_ASPE) ;8s
stcf 5,(SAM_ASPE) ;8s
call DELAY0_9ETU ;延时0.9个etu dog
djnz B,RECE_EIGHT ;11/7s
ldcf A,(cc_port) ;接收奇偶校验位位
jr SET_BIT_VER
FANXIANG: ;反向接收流程
ldcf A,(cc_port)
ccf ;将c寄存器取反
rl 1,D ;将收到的数据存放在D寄存器中
ldcf A,(cc_port)
ccf ;将c寄存器取反
xorcf 5,(SAM_ASPE)
stcf 5,(SAM_ASPE)
call DELAY0_9ETU ;延时0.9个etu dog
djnz B,FANXIANG
ldcf A,(cc_port)
ccf
SET_BIT_VER:
xorcf 5,(SAM_ASPE)
stcf 2,(SAM_RACK) ;将奇偶送入奇偶标志标志位
jr C,ONERERE ;出错后重试
call DELAY1_0ETU
ret
ONERERECON:
call DELAY1_0ETU
rcf
stcf A,(cc_port)
call IO_OUT
call DELAY1_0ETU
jp RES_ONEBYTE0
ONERERE:
djnz W,ONERERECON
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
REC_RESET_FIRSTBYTE: ;接收应答一个字节;((b-1)*11+7+4+76)*0.125uS=100us = 400clk
ld W,4 ;4s 重试接收的循环次数
REC_RESET_INI:
ld (SAM_RACK),0x00 ;5s 初始化复位应答寄存器
call IO_IN ;50s
call ON_TIME40000C ;14+75s 重开定时器40000clk
REC_RESET_START: ;timer programer 325s
ldcf 1,(SAM_RACK)
jp C,EXIT_RET ;若定时到,退出
ldcf A,(cc_port)
jr C,REC_RESET_START ;8/4s ;为高没接收到起始位,继续接收
and (TRUN),0x9F ;关定时器
RESET_START_OK:
call DELAY0_5ETU ;延时1.5个etu 在5MHz时,etu=74.4us
call DELAY1_0ETU
;**************START RECEIVE ONE BYTE**********************
ld B,8 ;为低接收到起始位,接收8个数据2s
res 5,(SAM_ASPE) ;将奇偶位清0,7s and 0xDF
RECE_RESET_BIT:
ldcf A,(cc_port)
rr 1,D ;将收到的数据存放在接收用的D寄存器中6s
ldcf A,(cc_port)
xorcf 5,(SAM_ASPE) ;8s
stcf 5,(SAM_ASPE) ;8s 将奇偶送入奇偶标志标志位
call DELAY0_9ETU ;延时0.9个etu dog
djnz B,RECE_RESET_BIT ;11/7s
ldcf A,(cc_port) ;接收奇偶校验位位
xorcf 5,(SAM_ASPE)
stcf 2,(SAM_RACK) ;将奇偶送入奇偶标志标志位
;**************RECEIVE ONE BYTE OVER***********************
jr C,OD_ERR
cp D,0x3B ;正向约定
jr Z,EXIT_RET1
cp D,0x03 ;反向约定
jr Z,NEGATIVE
set 3,(SAM_RACK) ;收到的TS与规定的不符合
ret
NEGATIVE:
set 0,(SAM_ASPE) ;反向约定
ld D,0x3F
EXIT_RET1:
ld (TS),D ;保存TS
EXIT_RET:
call DELAY1_0ETU
ret ;接收TS完成
OD_ERR: ;重试
djnz W,RE_RESET_SEND0
ret
RE_RESET_SEND0:
CALL DELAY1_0ETU
RCF
;STCF A,(P6)
STCF A,(cc_port)
CALL IO_OUT
CALL DELAY1_0ETU
jp REC_RESET_INI
;*************复位应答处理***********
ANSWER_TO_RESET:
ld E,3 ;E为错误后的重试计数器
ldcf 7,(SAM_ASPE) ;判断是否是用户卡
jr C,USER_ACTIVATION
PSAM_ACTIVATION: ;SAM卡的复位流程
ld a,2 ;a是用于接收过程中针对SAM卡和用户卡不同的设置I/O的
res cs_pow_bit,(cc_pow_port);SAM卡上电,P9.6=0
PSAM_ACTIVATION1:
res cs_rst_bit,(cs_rst_port);RESET设低,p9.2=0,7s
ld (CKOCR),0x03 ;启动时钟,5s
call IO_IN ;I\0口设为输入,50s
call REC_RESET_FIRSTBYTE ;接收第一个应答字节TS,14s
cp (SAM_RACK),0x02 ;判断超时否
jr NZ,REC_OTHER_BYTE ;接收下一个应答字节
;重新做一次热复位
set cs_rst_bit,(cs_rst_port);RESET设高,,p9.2=1
call REC_RESET_FIRSTBYTE
cp (SAM_RACK),0x02 ;判断超时否
jr NZ,REC_OTHER_BYTE
djnz E,PSAM_ACTIVATION1 ;重试复位
jp __card_release
USER_ACTIVATION: ;用户卡的复位流程
ld a,3 ;a是用于接收过程中针对SAM卡和用户卡不同的设置I/O的
res cu_pow_bit,(ic_pow_port);上电,P3.2=0
USER_ACTIVATION1:
res cu_rst_bit,(cs_rst_port);RESET设低,p9.5=0
ld (CKOCR),0x03 ;启动时钟
call IO_IN ;I\0口设为输入
call REC_RESET_FIRSTBYTE
cp (SAM_RACK),0X02
jr nz,REC_OTHER_BYTE
set cu_rst_bit,(cs_rst_port);RESET口设为高,p9.5=0
call REC_RESET_FIRSTBYTE
cp (SAM_RACK),0X02
jr nz,REC_OTHER_BYTE
djnz e,USER_ACTIVATION1
jp __card_release ;如果错误重试后,释放卡片
;**********************************************************
REC_OTHER_BYTE: ;TS后的应答接收
ld XHL,T0 ;初始化接收区指针
call RES_ONEBYTE_ACK ;接收数据
cp (SAM_RACK),0x00 ;判断接收是否有错
jp NZ,EXIT_RET
ld (XHL+),D ;接收到的数据存入存储区
REC_TA1:
ldcf 4,(T0)
jr NC,REC_TB1 ;判断是否接收TA1
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TA1),D
ld (XHL+),D ;接收到的数据存入存储区
;CALL TA1_analysis ;TA1的分析流程
REC_TB1:
ldcf 5,(T0)
jr NC,REC_TC1 ;判断是否接收TB1
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02 ;判断超时
jp Z,EXIT_RET
ld (TB1),D
ld (XHL+),D ;接收到的数据存入存储区
REC_TC1:
ldcf 6,(T0)
jr NC,REC_TD1 ;判断是否接收TC1
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TC1),D
ld (XHL+),D ;接收到的数据存入存储区
REC_TD1:
ldcf 7,(T0)
jp NC,REC_HISTORY_CHAR ;判断是否接收TD1
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TD1),D
ld (XHL+),D ;接收到的数据存入存储区
ld C,D
and C,0x0F
jp Z,REC_TA2
set 4,(SAM_RACK) ;不是T=0协议,错误卡或无效卡
REC_TA2:
ldcf 4,(TD1)
jr NC,REC_TB2 ;判断是否接收TA2
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TA2),D
ld (XHL+),D ;接收到的数据存入存储区
REC_TB2:
ldcf 5,(TD1)
jr NC,REC_TC2 ;判断是否接收TB2
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TB2),D
ld (XHL+),D ;接收到的数据存入存储区
REC_TC2:
ldcf 6,(TD1)
jr NC,REC_TD2 ;判断是否接收TC2
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (XHL+),D ;接收到的数据存入存储区
ld E,D
ld D,0x00
mul DE,0x18 ;D*12
ld (TC2),E
REC_TD2:
ldcf 7,(TD1)
jr NC,REC_HISTORY_CHAR ;判断是否接收TD2
call RES_ONEBYTE_ACK
cp (SAM_RACK),0x02
jp Z,EXIT_RET ;判断超时
ld (TD2),D
ld (XHL+),D ;接收到的数据存入存储区
ld C,D
and C,0x0F
jp Z,VOID_CARD ;不是T=0协议,错误卡或无效卡
set 4,(SAM_RACK)
;jr C,VOID_CARD ;ADD leo1
REC_HISTORY_CHAR:
ld e,(T0)
and e,0x0F ;leo1
REC_HISTORY_CHAR_CON:
call RES_ONEBYTE_ACK
ld (XHL+),D ;接收到的数据存入存储区
cp (SAM_RACK),0x02 ;
jp Z,EXIT_RET ;判断超时leo1
;jp NZ,REC_HISTORY_CHAR ;循环接收历史字节,靠超时跳出流程
djnz e,REC_HISTORY_CHAR_CON ;循环接收历史字节leo1
;res 1,(SAM_RACK)
;dec 1,xhl
sub XHL,TS
ld (COMMAND_p3),L
ret
VOID_CARD:
call RES_ONEBYTE_ACK
ld (XHL+),D ;接收到的数据存入存储区
cp (SAM_RACK),0x00
jr Z,VOID_CARD
res 1,(SAM_RACK)
dec 1,XHL
sub XHL,TS
ld (COMMAND_p3),L
dec 1,xhl
ld D,(xhl)
verfi_tck:
xor D,(xhl+)
cp xhl,T0
jr NZ,verfi_tck
cp D,0x00
jr NZ,CARD_ERR
set 5,(SAM_RACK) ;表示不是T=0的协议卡片
ret
CARD_ERR:
set 4,(SAM_RACK) ;设置出错
ret
F_TAB:
DB 0x01,0x74,0x01,0x74,0x02,0x2E,0x02,0xE8,0x04,0x5C,0x05,0xD0,0x08,0xB8,0x01,0x74
DB 0x01,0x74,0x02,0x00,0x03,0x00,0x04,0x00,0x06,0x00,0x08,0x00,0x01,0x74,0x01,0x74
D_TAB:
DB 0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x01,0x0C,0x14,0x01,0x01,0x01,0x01,0x01,0x01
TA1_analysis: ;对TA1的分析
LD C,(TA1)
RR 4,C
AND C,0X0F
LD xhl,F_TAB
RCF
RL 1,C
LD B,0X00
ADD xhl,XBC
LD D,(xhl+)
LD E,(xhl)
MUL XDE,0X0019 ;*25
DIV XDE,0X0174 ;/372
LD C,(TA1)
AND C,0X0F
LD xhl,D_TAB
LD B,0X00
ADD xhl,XBC
LD C,(xhl)
LD B,0X00
DIV XDE,BC
LD (ETU_COUTER),E
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
__card_release: ;卡片的释放
res 7,(SAM_ASPE)
__RELEASE: ;SAM卡的释放
res cs_rst_bit,(cs_rst_port) ;RESET设低,p9.2=0
ld (CKOCR),0x02 ;关闭时钟
res cs_io_bit,(cc_port) ;设低,pa.2=0
call IO_IN ;I\0 口设为输入
set cs_pow_bit,(cc_pow_port) ;下电,P9.6=1
RELEASEUSER: ;用户卡的释放
set 7,(SAM_ASPE)
res cu_rst_bit,(cs_rst_port) ;RESET设低,p9.5=0
res cu_io_bit,(cc_port) ;设低,pa.3=0
call IO_IN ;I\0 口设为输入
set cu_pow_bit,(ic_pow_port) ;下电,P9.7=1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
__USER_RESET:
ld (SAM_ASPE),0x80
jr SAM_RESTORE
__SAM_RESET:
ld (SAM_ASPE),0x00
SAM_RESTORE:
ld (ETU_COUTER),25 ;means 372
ld (TC2),0xF0 ;9600etu
ld (TC1),0x00
;ld (P6CR_RAM),0xA9 ;0xEF
;ld (P6CR),(P6CR_RAM) ;初始化P6方向寄存器
ld (PACR_RAM),0x60 ;0xEF
ld (PACR),(PACR_RAM) ;初始化PA方向寄存器
call ANSWER_TO_RESET
RET
ON_TIME39800C: ;(定时器5,定时80etu)
and (TRUN),0x9F ;7s
ld (INTET76),0xD0 ;5s
ld (T5FFCR),0xC3 ;5s
ld (T5MOD),0x21 ;0X23 ;5s
ld (T45CR),0x00 ;5s
ldw (TREG6),0x00 ;8s
ldw (TREG7),0xAE60 ;8s ;240etu
or (TRUN),0xA0 ;7s
ret ;11s
ON_TIME40000C:
ld (T_RETT),0x01 ;6s
and (TRUN),0x9F ;7s
ld (INTET76),0xD0 ;5s
ld (T5FFCR),0xC3 ;5s
ld (T5MOD),0x21 ;0X23 ;5s
ld (T45CR),0x00 ;5s
ldw (TREG6),0x00 ;8s
ldw (TREG7),0x4F00 ;8s
or (TRUN),0xA0 ;7s
ret ;11s
__TIM5_INTER:
DEC 1,(T_RETT) ;6s
JR Z,TIME_OUT ;8s/4s
CALL ON_TIME39800C ;14s+75s
RET ;11s
TIME_OUT:
;OR (SAM_RACK),0X02 ;7s
SET 1,(SAM_RACK)
AND (TRUN),0X9F ;7s ;关定时器
RET ;11s
SET_W:
LDCF 7,(SAM_ASPE)
JR C,NEXT_W ;Sam卡
LD a,2
RET
NEXT_W:
LD a,3 ;用户卡
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SEND_ONEBYTE:
LD w,4
LD (TEMP_BUFFER2),B
REPSEND:
LD (SAM_RACK),0
SCF
;STCF a,(P6)
STCF a,(cc_port)
CALL IO_OUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -