📄 serialkd.lst
字号:
C196 Compiler SERIALKD 13-Dec-106 17:03:10 Page 1
80C196 C compiler v5.0 r3 SN000000-194 (C)1996 Tasking Software BV
Object module placed in SERIALKD.obj
Compiler invoked by: C:\XINGYAN\C196\BIN\C196.EXE SERIALKD.C md(kb) DB SB CO MS Ot(1) SP(0) DN(1) RG(220) SI(C:\XingYan\
-c196\Include)
Line Level Incl
cseg
1 /*
2 ** FILE : serialkd.c
3 ** This program was published in "Embedded Applications Journal" 3Q 1993.
4 ** The article: 'C' Interrupt Routine for the serial MCS-96 Asynchronous Port.
5 ** by Larry C. Ferra, Intel Corporation.
6 **
7 ** NOTE : compile with model(kd) control
8 ** or use: #pragma model(kd)
9 ** or even better use:
1 ** mk196 -f serialkd.mak
11 */
12 //#pragma model(196)
13 #include <stdio.h>
14 #include <kd_sfrs.h>
15 #include <kd_funcs.h>
16
17 /* declare interrupt routines */
18 #pragma interrupt(receive=25,transmit=24)
19
2
21 /* Initialize the chip configuration bytes */
22 const unsigned int ccr = {0x20CD};
23 #pragma locate(ccr=0x2018)
24
25
26 #define FREQUENCY 12000000L /* 16 MHz */
27 #define BAUD_RATE_VALUE 1200
28 #define BAUD_REG ((unsigned int)(FREQUENCY/((long)BAUD_RATE_VALUE*16)-1)+0x8000
-)
29
3 #define RI_BIT 0x40
31 #define TI_BIT 0x20
32
33 unsigned char status_temp; /* image of sp_stat to preserve the RI
34 and TI bits on a read. */
35
36 /* receive and transmit buffers and their indexes */
37
38 #define TRANSMIT_BUF_SIZE 2
39 unsigned char trans_buff[TRANSMIT_BUF_SIZE];
4 char begin_trans_buff;
41 char end_trans_buff;
42
43 #define RECEIVE_BUF_SIZE 2
44 unsigned char receive_buff[RECEIVE_BUF_SIZE];
45 char end_rec_buff;
46 char begin_rec_buff;
47
48
C196 Compiler SERIALKD 13-Dec-106 17:03:10 Page 2
Assembly Listing of Object Code
49 /* declares and locates the special function registers */
5
51 void transmit(void) /* serial interrupt routine */
52 {
0000 transmit:
0000 F2 pushf
0001 C81C push Tmp0
53 1 wsr = 0;
0003 1100 E clrb wsr
54 1
55 1 status_temp |= sp_stat; /* image sp_stat into status_temp */
0005 900000 E orb status_temp,sp_stat
56 1
57 1 /* transmitt a character if there is a character in the buffer */
58 1 if (begin_trans_buff != end_trans_buff)
0008 980201 R cmpb begin_trans_buff,end_trans_buff
000B DF14 be @0002
59 1 {
6 2 sbuf = trans_buff[begin_trans_buff]; /* transmit character */
000D BC011C R ldbse Tmp0,begin_trans_buff
0010 B31D000000 E ldb sbuf,trans_buff[Tmp0]
61 2
62 2 /* The next statement makes the buffer circular by starting over when the
63 2 index reaches the end of the buffer. */
64 2
65 2 if (++begin_trans_buff>TRANSMIT_BUF_SIZE - 1)
0015 1701 R incb begin_trans_buff
0017 990101 R cmpb begin_trans_buff,#1
001A DA02 ble @0003
66 2 begin_trans_buff=0;
001C 1101 R clrb begin_trans_buff
001E @0003:
67 2 status_temp &= (~TI_BIT); /* clear TI bit in status_temp. */
001E 71DF00 R andb status_temp,#0DFH
0021 @0002:
68 2 }
69 1 }
0021 CC1C pop Tmp0
0023 F3 popf
0024 F0 ret
; Function Statistics for: transmit
; Code Size : 37 Parameter Count:
; Stack Size: Parameter Size :
; OReg Size : Stack Depth : 6
7
71 void receive(void) /* serial interrupt routine */
72 {
0025 receive:
0025 F2 pushf
0026 C81C push Tmp0
0028 C81E push Tmp2
73 1 wsr = 0;
002A 1100 E clrb wsr
74 1
C196 Compiler SERIALKD 13-Dec-106 17:03:10 Page 3
Assembly Listing of Object Code
75 1 status_temp |= sp_stat; /* image sp_stat into status_temp */
002C 900000 E orb status_temp,sp_stat
76 1
77 1 /* If the input buffer is full, the last character will be ignored,
78 1 and the BEL character is output to the terminal. */
79 1
8 1 if (end_rec_buff+1==begin_rec_buff
81 1 ||
82 1 (end_rec_buff==RECEIVE_BUF_SIZE-1 && !begin_rec_buff))
002F BC031C R ldbse Tmp0,end_rec_buff
0032 071C inc Tmp0
0034 BC041E R ldbse Tmp2,begin_rec_buff
0037 881E1C cmp Tmp0,Tmp2
003A DF0A be @0006
003C 990103 R cmpb end_rec_buff,#1
003F D707 bne @0005
0041 980400 R cmpb R0,begin_rec_buff
0044 D702 bne @0005
0046 @0006:
83 1 {
84 2 ; /* input overrun code */
85 2 }
86 1 else
0046 2011 br @0007
0048 @0005:
87 1 {
88 2 /* The next statement makes the buffer circular by starting over when the
89 2 index reaches the end of the buffer. */
9 2
91 2 if (++end_rec_buff > RECEIVE_BUF_SIZE - 1)
0048 1703 R incb end_rec_buff
004A 990103 R cmpb end_rec_buff,#1
004D DA02 ble @0008
92 2 end_rec_buff=0;
004F 1103 R clrb end_rec_buff
0051 @0008:
93 2 receive_buff[end_rec_buff]=sbuf; /* place character in buffer */
0051 BC031C R ldbse Tmp0,end_rec_buff
0054 C71D020000 E stb sbuf,receive_buff[Tmp0]
0059 @0007:
94 2 }
95 1 status_temp &= (~RI_BIT); /* clear RI bit in status_temp. */
0059 71BF00 R andb status_temp,#0BFH
96 1 }
005C CC1E pop Tmp2
005E CC1C pop Tmp0
0060 F3 popf
0061 F0 ret
; Function Statistics for: receive
; Code Size : 61 Parameter Count:
; Stack Size: Parameter Size :
; OReg Size : Stack Depth : 8
97
98 /* See stdio.h for declaration of putch. */
C196 Compiler SERIALKD 13-Dec-106 17:03:10 Page 4
Assembly Listing of Object Code
99 int putch(int c)
1 {
0062 putch:
0062 C800 E push ?FRAME01
0064 A01800 E ld ?FRAME01,SP
0067 2000 br @000B
0069 @000A:
1 1 /* remain in loop while the buffer is full. This is done by checking
1 1 the end of buffer index to make sure it does not overrun the
1 1 beginning of buffer index. The while instruction checks the case
1 1 when the end index is one less then the beginning index and at the
1 1 end of the buffer when the beginning index may be equal to 0 and
1 1 the end buffer index may be at the buffer end. */
1 1
1 1 while ((end_trans_buff+1==begin_trans_buff)
1 1 ||
11 1 (end_trans_buff==TRANSMIT_BUF_SIZE -1 && !begin_trans_buff));
0069 @000B:
0069 BC021C R ldbse Tmp0,end_trans_buff
006C 071C inc Tmp0
006E BC011E R ldbse Tmp2,begin_trans_buff
0071 881E1C cmp Tmp0,Tmp2
0074 DFF3 be @000A
0076 990102 R cmpb end_trans_buff,#1
0079 D705 bne @000D
007B 980100 R cmpb R0,begin_trans_buff
007E DFE9 be @000A
0080 @000D:
111 1
112 1 trans_buff[end_trans_buff]=c; /* put character in buffer */
0080 B300041C E ldb Tmp0,c[?FRAME01]
0084 BC021E R ldbse Tmp2,end_trans_buff
0087 C71F00001C R stb Tmp0,trans_buff[Tmp2]
113 1 if (++end_trans_buff>TRANSMIT_BUF_SIZE - 1) /* make buffer appear */
008C 1702 R incb end_trans_buff
008E 990102 R cmpb end_trans_buff,#1
0091 DA02 ble @000E
114 1 end_trans_buff=0; /* circular. */
0093 1102 R clrb end_trans_buff
0095 @000E:
115 1 if (status_temp & TI_BIT)
0095 5120001C R andb Tmp0,status_temp,#2
0099 981C00 cmpb R0,Tmp0
009C DF03 be @000F
116 1 int_pend1 |= 0x01; /* If transmitt buffer
009E 910100 E orb int_pend1,#1
00A1 @000F:
117 1 * was empty, then cause
118 1 * an interrupt to start
119 1 * transmitting. */
12 1 }
00A1 CC00 E pop ?FRAME01
00A3 F0 ret
; Function Statistics for: putch
; Code Size : 66 Parameter Count: 1
C196 Compiler SERIALKD 13-Dec-106 17:03:10 Page 5
Assembly Listing of Object Code
; Stack Size: Parameter Size : 2
; OReg Size : Stack Depth : 2
121
122 /* See stdio.h for declaration of getch. */
123 int getch(void)
124 {
00A4 getch:
00A4 2000 br @0012
00A6 @0011:
125 1 while (begin_rec_buff==end_rec_buff); /* remain in loop while there is
00A6 @0012:
00A6 980304 R cmpb begin_rec_buff,end_rec_buff
00A9 DFFB be @0011
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -