OpenCores
URL https://opencores.org/ocsvn/m16c5x/m16c5x/trunk

Subversion Repositories m16c5x

[/] [m16c5x/] [trunk/] [Utils/] [IH2MEM.C] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 MichaelA
/*******************************************************************************
2
********************************************************************************
3
////////////////////////////////////////////////////////////////////////////////
4
//
5
//  Copyright 2013 by Michael A. Morris, dba M. A. Morris & Associates
6
//
7
//  All rights reserved. The source code contained herein is publicly released
8
//  under the terms and conditions of the GNU Lesser Public License. No part of
9
//  this source code may be reproduced or transmitted in any form or by any
10
//  means, electronic or mechanical, including photocopying, recording, or any
11
//  information storage and retrieval system in violation of the license under
12
//  which the source code is released.
13
//
14
//  The source code contained herein is free; it may be redistributed and/or
15
//  modified in accordance with the terms of the GNU Lesser General Public
16
//  License as published by the Free Software Foundation; either version 2.1 of
17
//  the GNU Lesser General Public License, or any later version.
18
//
19
//  The source code contained herein is freely released WITHOUT ANY WARRANTY;
20
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21
//  PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
22
//  more details.)
23
//
24
//  A copy of the GNU Lesser General Public License should have been received
25
//  along with the source code contained herein; if not, a copy can be obtained
26
//  by writing to:
27
//
28
//  Free Software Foundation, Inc.
29
//  51 Franklin Street, Fifth Floor
30
//  Boston, MA  02110-1301 USA
31
//
32
//  Further, no use of this source code is permitted in any form or means
33
//  without inclusion of this banner prominently in any derived works.
34
//
35
//  Michael A. Morris
36
//  Huntsville, AL
37
//
38
////////////////////////////////////////////////////////////////////////////////
39
********************************************************************************
40
*******************************************************************************/
41
 
42
/*******************************************************************************
43
********************************************************************************
44
 
45
This utility is designed to function as a filter program to translate an Intel
46
Hex programming file into a MEM file compatible with Xilinx's Data2MEM utility
47
program.
48
 
49
It expects an Intel Hex file generated by the Microchip MPLAB toolsuite to be
50
piped in on stdin, and it outputs its MEM-compatible output on stdout.
51
 
52
The M16C5x soft-core microcomputer for which this utility is designed has a
53
12-bit instruction width. The MPLAB Intel Hex output is byte-oriented, so it
54
outputs two 8-bit ASCII Hex characters for each 12-bit instruction word. The
55
least significant 8 bits are output first, and then that is followed by a
56
second 8 bit byte. The second byte holds the most significant 4 bits of the
57
instruction word in bits 3:0. The upper 4 bits of this second byte are set to
58
 
59
word nibbles, each 12-bit M16C5x instruction can be represented as a Verilog
60
vector in the following manner:
61
 
62
    {I[7:4], I[3:0], 4'b0000, I[11:8]}
63
 
64
For the Xilinx Data2MEM utility, in the block RAM configuration of the M16C5x
65
program memory, the output order of these nibbles to stdout is least
66
significant nibble to most significant nibble. Thus, the output order of the
67
ASCII Hex characters representing the instruction word nibbles is: 1, 0, 3.
68
 
69
This utility program is not intended to be general purpose. For every four
70
characters read from a data record of the Intel Hex programming file, the
71
utility only emits three characters. Each instruction word (3 characters) is
72
output on a separate line, although it's possible to emit the record address
73
and the instruction word data on a single line separated by spaces.
74
 
75
Furthermore, MPLAB's Intel Hex file format adheres to the 32-bit segmented
76
address format. The upper 16 bits of a data records address is provided by a
77
record having a type of "04". Because the M16C5x only supports a 4096 x 12
78
instruction memory address space, these records are ignored by this utility
79
program. Similarly, the utility ignores records of type "01". Thus, the
80
utility only outputs emits a MEM-compatible address for records of type "00".
81
 
82
********************************************************************************
83
Revision History
84
 
85
    1.00    13G18   MAM     Initial File Creation
86
 
87
    1.01    13G19   MAM     Added description and license header to file.
88
 
89
    1.10    13G19   MAM     Made several corrections: (1) record length changed
90
                            to instructions instead of bytes; (2) address output
91
                            is 1.5 bytes per instruction. Also, added check to
92
                            ensure address falls on byte boundary. Thus, if
93
                            address after multiplying by 3 is even, then it is
94
                            divided by 2 and emitted on a line by itself. If it
95
                            is odd, then 2 is subtracted before dividing the
96
                            resultant by 2. After emitting this modified address
97
                            a three character (1.5 bytes) pad is emitted before
98
                            the data in the record. (This situation generally
99
                            occurs when emitting the reset vectors, but may
100
                            occur in other situations.)
101
 
102
********************************************************************************
103
*******************************************************************************/
104
 
105
#include 
106
#include 
107
#include 
108
 
109
int ahtoi(char ch)
110
{
111
    int tmp;
112
 
113
    tmp = toupper(ch);
114
 
115
    tmp = (ch - '0');
116
    if(tmp > 9) tmp = (tmp - 7);
117
 
118
    return tmp;
119
}
120
 
121
void main(void)
122
{
123
    char ch;
124
    int  i = 0;
125
    int  j = 0;
126
    char state = 0;
127
 
128
    int  rlen = 0;
129
    int  radd = 0;
130
    int  rtyp = 0;
131
    char rdat[4];
132
 
133
    while(!feof(stdin)) {
134
 
135
        ch = fgetc(stdin);
136
 
137
        switch(state) {
138
           case 0 :                     // Find start of record
139
 
140
                if(ch == ':') {         // Read record length - 2 chars
141
                     i = 2;
142
                     j = 0;
143
                     rlen  = 0;
144
                     state = 1;
145
                }
146
 
147
                break;
148
 
149
           case 1 :                     // Read and convert record length field
150
 
151
                rlen = (rlen << 4) + ahtoi(ch);
152
 
153
                i -= 1;
154
 
155
                if(i == 0) {            // Capture record address field
156
                     i = 4;
157
                     j = 0;
158
                     rlen  = rlen / 2;
159
                     radd  = 0;
160
                     state = 2;
161
                }
162
 
163
                break;
164
 
165
           case 2 :                     // Read and convert record address field
166
 
167
                radd = (radd << 4) + ahtoi(ch);
168
 
169
                i -= 1;
170
                j += 1;
171
 
172
                if(i == 0) {            // Read record type
173
                     i = 2;             // read two (2) chars
174
                     j = 0;
175
 
176
                     radd = radd / 2;
177
 
178
                     rtyp  = 0;
179
                     state = 3;
180
                }
181
 
182
                break;
183
 
184
           case 3 :                     // Read and convert record type
185
 
186
                rtyp = (rtyp << 4) + ahtoi(ch); // Convert to integer
187
 
188
                i -= 1;
189
 
190
                if(i == 0) {            // ((rtype) ? 0 : 4)
191
                     i = 4;
192
                     j = 0;
193
 
194
                     if(rtyp == 0) {    // Read and print data records
195
                         radd = (radd * 3);
196
                         if(radd & 1) {
197
                            radd = (radd - 2) / 2; // emit address with padding
198
                            fprintf(stdout, "@%04X\n000\n", radd);
199
                         } else {
200
                            radd = radd / 2;     // 1.5 bytes per instruction
201
                            fprintf(stdout, "@%04X\n", radd);    // emit address
202
                         }
203
                         state = 4;
204
                     } else {           // Skip to next record or EOF
205
                         state = 0;
206
                     }
207
                }
208
 
209
                break;
210
 
211
           case 4 :                     // Read and output sorted data - 4 chars
212
 
213
                rdat[j] = ch;
214
 
215
                i -= 1;
216
                j += 1;
217
 
218
                if(i == 0) {
219
                     i = 4;
220
                     j = 0;
221
 
222 3 MichaelA
                     //fprintf(stdout, "%c%c%c\n", rdat[1], rdat[0], rdat[3]);
223
                     fprintf(stdout, "%c%c%c\n", rdat[3], rdat[0], rdat[1]);
224 2 MichaelA
 
225
                     rlen -= 1;      // Decrement record length
226
 
227
                     if(rlen == 0) {
228
                         state = 0;  // End of data, skip to next record/EOF
229
                     } else {
230
                         state = 4;  // Data available, read next data word
231
                     }
232
                }
233
 
234
                break;
235
 
236
           default : break;
237
        }
238
    }
239
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.