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

Subversion Repositories m16c5x

[/] [m16c5x/] [trunk/] [Utils/] [IH2MEM.C] - Diff between revs 2 and 3

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
/*******************************************************************************
/*******************************************************************************
********************************************************************************
********************************************************************************
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//  Copyright 2013 by Michael A. Morris, dba M. A. Morris & Associates
//  Copyright 2013 by Michael A. Morris, dba M. A. Morris & Associates
//
//
//  All rights reserved. The source code contained herein is publicly released
//  All rights reserved. The source code contained herein is publicly released
//  under the terms and conditions of the GNU Lesser Public License. No part of
//  under the terms and conditions of the GNU Lesser Public License. No part of
//  this source code may be reproduced or transmitted in any form or by any
//  this source code may be reproduced or transmitted in any form or by any
//  means, electronic or mechanical, including photocopying, recording, or any
//  means, electronic or mechanical, including photocopying, recording, or any
//  information storage and retrieval system in violation of the license under
//  information storage and retrieval system in violation of the license under
//  which the source code is released.
//  which the source code is released.
//
//
//  The source code contained herein is free; it may be redistributed and/or
//  The source code contained herein is free; it may be redistributed and/or
//  modified in accordance with the terms of the GNU Lesser General Public
//  modified in accordance with the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either version 2.1 of
//  License as published by the Free Software Foundation; either version 2.1 of
//  the GNU Lesser General Public License, or any later version.
//  the GNU Lesser General Public License, or any later version.
//
//
//  The source code contained herein is freely released WITHOUT ANY WARRANTY;
//  The source code contained herein is freely released WITHOUT ANY WARRANTY;
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
//  PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
//  PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
//  more details.)
//  more details.)
//
//
//  A copy of the GNU Lesser General Public License should have been received
//  A copy of the GNU Lesser General Public License should have been received
//  along with the source code contained herein; if not, a copy can be obtained
//  along with the source code contained herein; if not, a copy can be obtained
//  by writing to:
//  by writing to:
//
//
//  Free Software Foundation, Inc.
//  Free Software Foundation, Inc.
//  51 Franklin Street, Fifth Floor
//  51 Franklin Street, Fifth Floor
//  Boston, MA  02110-1301 USA
//  Boston, MA  02110-1301 USA
//
//
//  Further, no use of this source code is permitted in any form or means
//  Further, no use of this source code is permitted in any form or means
//  without inclusion of this banner prominently in any derived works.
//  without inclusion of this banner prominently in any derived works.
//
//
//  Michael A. Morris
//  Michael A. Morris
//  Huntsville, AL
//  Huntsville, AL
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
********************************************************************************
********************************************************************************
*******************************************************************************/
*******************************************************************************/
/*******************************************************************************
/*******************************************************************************
********************************************************************************
********************************************************************************
This utility is designed to function as a filter program to translate an Intel
This utility is designed to function as a filter program to translate an Intel
Hex programming file into a MEM file compatible with Xilinx's Data2MEM utility
Hex programming file into a MEM file compatible with Xilinx's Data2MEM utility
program.
program.
It expects an Intel Hex file generated by the Microchip MPLAB toolsuite to be
It expects an Intel Hex file generated by the Microchip MPLAB toolsuite to be
piped in on stdin, and it outputs its MEM-compatible output on stdout.
piped in on stdin, and it outputs its MEM-compatible output on stdout.
The M16C5x soft-core microcomputer for which this utility is designed has a
The M16C5x soft-core microcomputer for which this utility is designed has a
12-bit instruction width. The MPLAB Intel Hex output is byte-oriented, so it
12-bit instruction width. The MPLAB Intel Hex output is byte-oriented, so it
outputs two 8-bit ASCII Hex characters for each 12-bit instruction word. The
outputs two 8-bit ASCII Hex characters for each 12-bit instruction word. The
least significant 8 bits are output first, and then that is followed by a
least significant 8 bits are output first, and then that is followed by a
second 8 bit byte. The second byte holds the most significant 4 bits of the
second 8 bit byte. The second byte holds the most significant 4 bits of the
instruction word in bits 3:0. The upper 4 bits of this second byte are set to
instruction word in bits 3:0. The upper 4 bits of this second byte are set to
0 by MPLAB. Considering the MPLAB Intel Hex output as a stream of instruction
0 by MPLAB. Considering the MPLAB Intel Hex output as a stream of instruction
word nibbles, each 12-bit M16C5x instruction can be represented as a Verilog
word nibbles, each 12-bit M16C5x instruction can be represented as a Verilog
vector in the following manner:
vector in the following manner:
    {I[7:4], I[3:0], 4'b0000, I[11:8]}
    {I[7:4], I[3:0], 4'b0000, I[11:8]}
For the Xilinx Data2MEM utility, in the block RAM configuration of the M16C5x
For the Xilinx Data2MEM utility, in the block RAM configuration of the M16C5x
program memory, the output order of these nibbles to stdout is least
program memory, the output order of these nibbles to stdout is least
significant nibble to most significant nibble. Thus, the output order of the
significant nibble to most significant nibble. Thus, the output order of the
ASCII Hex characters representing the instruction word nibbles is: 1, 0, 3.
ASCII Hex characters representing the instruction word nibbles is: 1, 0, 3.
This utility program is not intended to be general purpose. For every four
This utility program is not intended to be general purpose. For every four
characters read from a data record of the Intel Hex programming file, the
characters read from a data record of the Intel Hex programming file, the
utility only emits three characters. Each instruction word (3 characters) is
utility only emits three characters. Each instruction word (3 characters) is
output on a separate line, although it's possible to emit the record address
output on a separate line, although it's possible to emit the record address
and the instruction word data on a single line separated by spaces.
and the instruction word data on a single line separated by spaces.
Furthermore, MPLAB's Intel Hex file format adheres to the 32-bit segmented
Furthermore, MPLAB's Intel Hex file format adheres to the 32-bit segmented
address format. The upper 16 bits of a data records address is provided by a
address format. The upper 16 bits of a data records address is provided by a
record having a type of "04". Because the M16C5x only supports a 4096 x 12
record having a type of "04". Because the M16C5x only supports a 4096 x 12
instruction memory address space, these records are ignored by this utility
instruction memory address space, these records are ignored by this utility
program. Similarly, the utility ignores records of type "01". Thus, the
program. Similarly, the utility ignores records of type "01". Thus, the
utility only outputs emits a MEM-compatible address for records of type "00".
utility only outputs emits a MEM-compatible address for records of type "00".
********************************************************************************
********************************************************************************
Revision History
Revision History
    1.00    13G18   MAM     Initial File Creation
    1.00    13G18   MAM     Initial File Creation
    1.01    13G19   MAM     Added description and license header to file.
    1.01    13G19   MAM     Added description and license header to file.
    1.10    13G19   MAM     Made several corrections: (1) record length changed
    1.10    13G19   MAM     Made several corrections: (1) record length changed
                            to instructions instead of bytes; (2) address output
                            to instructions instead of bytes; (2) address output
                            is 1.5 bytes per instruction. Also, added check to
                            is 1.5 bytes per instruction. Also, added check to
                            ensure address falls on byte boundary. Thus, if
                            ensure address falls on byte boundary. Thus, if
                            address after multiplying by 3 is even, then it is
                            address after multiplying by 3 is even, then it is
                            divided by 2 and emitted on a line by itself. If it
                            divided by 2 and emitted on a line by itself. If it
                            is odd, then 2 is subtracted before dividing the
                            is odd, then 2 is subtracted before dividing the
                            resultant by 2. After emitting this modified address
                            resultant by 2. After emitting this modified address
                            a three character (1.5 bytes) pad is emitted before
                            a three character (1.5 bytes) pad is emitted before
                            the data in the record. (This situation generally
                            the data in the record. (This situation generally
                            occurs when emitting the reset vectors, but may
                            occurs when emitting the reset vectors, but may
                            occur in other situations.)
                            occur in other situations.)
********************************************************************************
********************************************************************************
*******************************************************************************/
*******************************************************************************/
#include 
#include 
#include 
#include 
#include 
#include 
int ahtoi(char ch)
int ahtoi(char ch)
{
{
    int tmp;
    int tmp;
    tmp = toupper(ch);
    tmp = toupper(ch);
    tmp = (ch - '0');
    tmp = (ch - '0');
    if(tmp > 9) tmp = (tmp - 7);
    if(tmp > 9) tmp = (tmp - 7);
    return tmp;
    return tmp;
}
}
void main(void)
void main(void)
{
{
    char ch;
    char ch;
    int  i = 0;
    int  i = 0;
    int  j = 0;
    int  j = 0;
    char state = 0;
    char state = 0;
    int  rlen = 0;
    int  rlen = 0;
    int  radd = 0;
    int  radd = 0;
    int  rtyp = 0;
    int  rtyp = 0;
    char rdat[4];
    char rdat[4];
    while(!feof(stdin)) {
    while(!feof(stdin)) {
        ch = fgetc(stdin);
        ch = fgetc(stdin);
        switch(state) {
        switch(state) {
           case 0 :                     // Find start of record
           case 0 :                     // Find start of record
                if(ch == ':') {         // Read record length - 2 chars
                if(ch == ':') {         // Read record length - 2 chars
                     i = 2;
                     i = 2;
                     j = 0;
                     j = 0;
                     rlen  = 0;
                     rlen  = 0;
                     state = 1;
                     state = 1;
                }
                }
                break;
                break;
           case 1 :                     // Read and convert record length field
           case 1 :                     // Read and convert record length field
                rlen = (rlen << 4) + ahtoi(ch);
                rlen = (rlen << 4) + ahtoi(ch);
                i -= 1;
                i -= 1;
                if(i == 0) {            // Capture record address field
                if(i == 0) {            // Capture record address field
                     i = 4;
                     i = 4;
                     j = 0;
                     j = 0;
                     rlen  = rlen / 2;
                     rlen  = rlen / 2;
                     radd  = 0;
                     radd  = 0;
                     state = 2;
                     state = 2;
                }
                }
                break;
                break;
           case 2 :                     // Read and convert record address field
           case 2 :                     // Read and convert record address field
                radd = (radd << 4) + ahtoi(ch);
                radd = (radd << 4) + ahtoi(ch);
                i -= 1;
                i -= 1;
                j += 1;
                j += 1;
                if(i == 0) {            // Read record type
                if(i == 0) {            // Read record type
                     i = 2;             // read two (2) chars
                     i = 2;             // read two (2) chars
                     j = 0;
                     j = 0;
                     radd = radd / 2;
                     radd = radd / 2;
                     rtyp  = 0;
                     rtyp  = 0;
                     state = 3;
                     state = 3;
                }
                }
                break;
                break;
           case 3 :                     // Read and convert record type
           case 3 :                     // Read and convert record type
                rtyp = (rtyp << 4) + ahtoi(ch); // Convert to integer
                rtyp = (rtyp << 4) + ahtoi(ch); // Convert to integer
                i -= 1;
                i -= 1;
                if(i == 0) {            // ((rtype) ? 0 : 4)
                if(i == 0) {            // ((rtype) ? 0 : 4)
                     i = 4;
                     i = 4;
                     j = 0;
                     j = 0;
                     if(rtyp == 0) {    // Read and print data records
                     if(rtyp == 0) {    // Read and print data records
                         radd = (radd * 3);
                         radd = (radd * 3);
                         if(radd & 1) {
                         if(radd & 1) {
                            radd = (radd - 2) / 2; // emit address with padding
                            radd = (radd - 2) / 2; // emit address with padding
                            fprintf(stdout, "@%04X\n000\n", radd);
                            fprintf(stdout, "@%04X\n000\n", radd);
                         } else {
                         } else {
                            radd = radd / 2;     // 1.5 bytes per instruction
                            radd = radd / 2;     // 1.5 bytes per instruction
                            fprintf(stdout, "@%04X\n", radd);    // emit address
                            fprintf(stdout, "@%04X\n", radd);    // emit address
                         }
                         }
                         state = 4;
                         state = 4;
                     } else {           // Skip to next record or EOF
                     } else {           // Skip to next record or EOF
                         state = 0;
                         state = 0;
                     }
                     }
                }
                }
                break;
                break;
           case 4 :                     // Read and output sorted data - 4 chars
           case 4 :                     // Read and output sorted data - 4 chars
                rdat[j] = ch;
                rdat[j] = ch;
                i -= 1;
                i -= 1;
                j += 1;
                j += 1;
                if(i == 0) {
                if(i == 0) {
                     i = 4;
                     i = 4;
                     j = 0;
                     j = 0;
 
 
                     fprintf(stdout, "%c%c%c\n", rdat[1], rdat[0], rdat[3]);
                     //fprintf(stdout, "%c%c%c\n", rdat[1], rdat[0], rdat[3]);
 
                     fprintf(stdout, "%c%c%c\n", rdat[3], rdat[0], rdat[1]);
 
 
                     rlen -= 1;      // Decrement record length
                     rlen -= 1;      // Decrement record length
                     if(rlen == 0) {
                     if(rlen == 0) {
                         state = 0;  // End of data, skip to next record/EOF
                         state = 0;  // End of data, skip to next record/EOF
                     } else {
                     } else {
                         state = 4;  // Data available, read next data word
                         state = 4;  // Data available, read next data word
                     }
                     }
                }
                }
                break;
                break;
           default : break;
           default : break;
        }
        }
    }
    }
 
 

powered by: WebSVN 2.1.0

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