summaryrefslogtreecommitdiff
path: root/firmware/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/debug.c')
-rw-r--r--firmware/debug.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/firmware/debug.c b/firmware/debug.c
new file mode 100644
index 0000000000..d78fa17528
--- /dev/null
+++ b/firmware/debug.c
@@ -0,0 +1,181 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "sh7034.h"
20#include <string.h>
21#include <stdio.h>
22#include <stdarg.h>
23
24char debugmembuf[100];
25char debugbuf[200];
26
27static int debug_tx_ready(void)
28{
29 return (SSR1 & SCI_TDRE);
30}
31
32static void debug_tx_char(char ch)
33{
34 while (!debug_tx_ready())
35 {
36 ;
37 }
38
39 /*
40 * Write data into TDR and clear TDRE
41 */
42 TDR1 = ch;
43 SSR1 &= ~SCI_TDRE;
44}
45
46static void debug_handle_error(char ssr)
47{
48 SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
49}
50
51static int debug_rx_ready(void)
52{
53 char ssr;
54
55 ssr = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
56 if ( ssr )
57 debug_handle_error ( ssr );
58 return SSR1 & SCI_RDRF;
59}
60
61static char debug_rx_char(void)
62{
63 char ch;
64 char ssr;
65
66 /* Special debug hack. Shut off the IRQ while polling, to prevent the debug
67 stub from catching the IRQ */
68 SCR1 &= ~0x40;
69
70 while (!debug_rx_ready())
71 {
72 ;
73 }
74
75 ch = RDR1;
76 SSR1 &= ~SCI_RDRF;
77
78 ssr = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
79
80 if (ssr)
81 debug_handle_error (ssr);
82
83 /* Special debug hack. Enable the IRQ again */
84 SCR1 |= 0x40;
85 return ch;
86}
87
88static const char hexchars[] = "0123456789abcdef";
89
90static char highhex(int x)
91{
92 return hexchars[(x >> 4) & 0xf];
93}
94
95static char lowhex(int x)
96{
97 return hexchars[x & 0xf];
98}
99
100static void putpacket (char *buffer)
101{
102 register int checksum;
103
104 char *src = buffer;
105 debug_tx_char ('$');
106 checksum = 0;
107
108 while (*src)
109 {
110 int runlen;
111
112 /* Do run length encoding */
113 for (runlen = 0; runlen < 100; runlen ++)
114 {
115 if (src[0] != src[runlen])
116 {
117 if (runlen > 3)
118 {
119 int encode;
120 /* Got a useful amount */
121 debug_tx_char (*src);
122 checksum += *src;
123 debug_tx_char ('*');
124 checksum += '*';
125 checksum += (encode = runlen + ' ' - 4);
126 debug_tx_char (encode);
127 src += runlen;
128 }
129 else
130 {
131 debug_tx_char (*src);
132 checksum += *src;
133 src++;
134 }
135 break;
136 }
137 }
138 }
139
140
141 debug_tx_char ('#');
142 debug_tx_char (highhex(checksum));
143 debug_tx_char (lowhex(checksum));
144
145 /* Wait for the '+' */
146 debug_rx_char();
147}
148
149/* convert the memory, pointed to by mem into hex, placing result in buf */
150/* return a pointer to the last char put in buf (null) */
151static char *mem2hex (char *mem, char *buf, int count)
152{
153 int i;
154 int ch;
155 for (i = 0; i < count; i++)
156 {
157 ch = *mem++;
158 *buf++ = highhex (ch);
159 *buf++ = lowhex (ch);
160 }
161 *buf = 0;
162 return (buf);
163}
164
165void debug(char *msg)
166{
167 debugbuf[0] = 'O';
168
169 mem2hex(msg, &debugbuf[1], strlen(msg));
170 putpacket(debugbuf);
171}
172
173void debugf(char *fmt, ...)
174{
175 va_list ap;
176
177 va_start(ap, fmt);
178 vsprintf(debugmembuf, fmt, ap);
179 va_end(ap);
180 debug(debugmembuf);
181}