This is a multi-part message in MIME format. --------------090309060607000509030701 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi all. Been messing around with a lot of LCD Character display messages recently. C18 seems to be pretty good at dealing with things, but the combination of my poor C knowledge, and C18 produces HEX files that are too large for my PIC. In order to rationalize, I put together a system where I declared just one string constant (const rom char[]) that contains all the messages seperated by a null character. Then all my LCD code references this array at a given "defined" offset, and outputs the message till the next null characer. This reduced the HEX file size by 40% (and gave me some more room). Keeping track of the "pointers" manually in the code is a real pain though, so I wrote this Java program to do the grunt work. For those who want it, feel free. (It is Java 1.5). The code will "optimize" the string usage by "overlaying" strings where it can. Thus, the input can declare the same string many times (with different names), and it will only use one copy from rom memory. Additionally, it will identify where ne string is the "tail" of another, and it will offset the pointer to be only the tail part of another string... i.e. it takes no more memory to store "ACE" if "SPACE" is also declared. C18 then uses table reads to get the data out, so the data is packed 2bytes per program word, and is most (space) efficient. The first part of the output is the concatenated strings. The second part are defines that give "pointers" in to the concatenated string. The third part is a double-check to make sure that the data comes out right at the end (and so that in the code you can see (easily) what the strings are.. There is a disclaimer..... I just finished the Java code and I don't have C18 with me right now. Although I am confident that it all works, there may be some formatting problems or something... but, you should be able to just paste the output at the top of you code. A little playing with the Java and I am sure it could produce a useful c and h file to #include if easier. By way of example: The "input" file looks like: ==========Start============= M_NULL= M_MAIN=Main Menu M_A=AAAA M_B=BBBB M_C=CCCC M_SPACE= SPACE M_CRAZY=!@#$% M_LONG=AbcdEfgHijkLmnopQrstUvwZyz M_SUBSET=ACE M_SUPERSET=CCAAAA ==========End============= The Output from the program looks like: ==========Start============= const rom char strings[] = "\ CCAAAA\000AbcdEfgHijkLmnopQrstUvwZyz\000CCCC\000!@#$%\000BBBB\000\ SPACE\000Main Menu\000\ "; #define M_NULL 67 #define M_MAIN 58 #define M_A 2 #define M_B 45 #define M_C 34 #define M_SPACE 50 #define M_CRAZY 39 #define M_LONG 7 #define M_SUBSET 54 #define M_SUPERSET 0 // M_NULL-> // M_MAIN->Main Menu // M_A->AAAA // M_B->BBBB // M_C->CCCC // M_SPACE-> SPACE // M_CRAZY->!@#$% // M_LONG->AbcdEfgHijkLmnopQrstUvwZyz // M_SUBSET->ACE // M_SUPERSET->CCAAAA ==========End============ You will notice that it "optimizes" the strings so that if any string appears at the end of another string it will "double up" that string value (AAAA is a subset of CCAAAA). To use this code it becomes a "simple" case of: void LCDPrintString(int pos) { while (strings[pos]) LCDWriteChar(strings[pos++]); } ..... LCDPrintString(M_MENU); LCDPrintString(M_SUPERSET); .... Perhaps this will buy me some lee-way when asking dumb questions later... Rolf --------------090309060607000509030701 Content-Type: text/plain; name="StringFormat.java" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="StringFormat.java" import java.io.*; import java.util.*; public class StringFormat { public static class StringReference { private final int i_offset; private final String i_string; public StringReference(int offset, String string) { super(); // TODO Auto-generated constructor stub i_offset = offset; i_string = string; } public int getOffset() { return i_offset; } public String getString() { return i_string; } } /** * @param args */ public static void main(String[] args) throws IOException { InputStream is = System.in; HashMap stringrefs = new HashMap(); LinkedList keyorder = new LinkedList(); if (args.length > 0) { is = new FileInputStream(args[0]); } BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { String[] parts = line.split("=", 2); if (parts.length == 2) { String key = parts[0]; String value = parts[1]; keyorder.add(key); if (stringrefs.containsKey(key)) { throw new IllegalStateException("Already declared key '" + key + "' in file."); } StringReference toadd = null; for (Map.Entry entry : stringrefs.entrySet()) { String ref = entry.getValue().getString(); if (ref.endsWith(value)) { int offset = ref.length() - value.length(); toadd = new StringReference(offset, ref); break; } else if (value.endsWith(ref)) { toadd = new StringReference(0, value); StringReference replacement = new StringReference(value.length() - ref.length(), value); entry.setValue(replacement); } } if (toadd == null) { toadd = new StringReference(0, value); } stringrefs.put(key, toadd); } } // right, all named pairs accounted for. HashMap done = new HashMap(); TreeMap references = new TreeMap(); StringBuilder sb = new StringBuilder(); StringBuilder test = new StringBuilder(); sb.append("const rom char strings[] = \"\\\n"); int last = 0; int len = 0; for (Map.Entry entry : stringrefs.entrySet()) { int cursor = last; if (!done.containsKey(entry.getValue().getString())) { if (len > 60) { len = 0; sb.append("\\\n"); } sb.append(entry.getValue().getString()); sb.append("\\000"); test.append(entry.getValue().getString()); test.append('\0'); int elen = entry.getValue().getString().length() + 1; len += elen + 3; done.put(entry.getValue().getString(), last); last += elen; } cursor = done.get(entry.getValue().getString()); cursor += entry.getValue().getOffset(); references.put(entry.getKey(), cursor); } sb.append("\\\n\";\n"); System.out.print(sb.toString()); System.out.print('\n'); for (String key : keyorder) { System.out.print("#define " + key + " " + references.get(key) + "\n"); } System.out.print('\n'); char[] chars = test.toString().toCharArray(); for (String key : keyorder) { int pos = references.get(key); System.out.print("// " + key + "->"); while (chars[pos] != 0) { System.out.print(chars[pos++]); } System.out.println(); } } } --------------090309060607000509030701 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist --------------090309060607000509030701--