From: MagerValp on 18 Oct 2006 04:51 >>>>> "M" == MagerValp <MagerValp(a)cling.gu.se> writes: M> 19+1 bytes per line gives 36 lines of data. The same method can be M> used with base-64 of course, giving 30 lines of data. What would M> people prefer though? My bad, base-64 requires quotes around the data, so you only get 30 characters per line. So, 33 vs 36 lines. Readability is more important than a measly 3-line advantage. -- ___ . . . . . + . . o _|___|_ + . + . + . Per Olofsson, arkadspelare o-o . . . o + MagerValp(a)cling.gu.se - + + . http://www.cling.gu.se/~cl3polof/
From: Wolfgang Moser on 18 Oct 2006 06:24 Hi Per, MagerValp schrieb: >>>>>> "WM" == Wolfgang Moser <wnhp(a)d81.de.invalid> writes: > > WM> Which bit depth comes with the C64's floating point format > WM> regarding the base (anything but exponent and sign)? > > IIRC, 8-bit exponent, 1-bit sign, and 31-bit mantissa. Plenty of > precision there. More than enough. > How about something like this: ? you saw my posting from midnight, didn't you? > readline: > read a$ > if a$="end" then end > v=0 : s=0 : c=0 > for i=1 to len(a$) > q=asc(mid$(a$,i,1)) : gosub conv32 > v=v*32+q : s=s+5 You may want to do the "if" first, so that the last n bits with n>8 automatically remain within v and no extra check for loop exiting is needed. > if s<7 goto nextchar You surely want to extract a byte, when 8 or more bits got collected, so if vote for: "s<8" > q=v and 255 : v=v/256 : s=s-8 Hmmmm.... at first, "v=int(v/256)" seems to be a good idea to get rid of the unneded fractional part. And it prevents a possible "?illegal quantity error" as a test case just showed to me. Maybe a "(v/256) and 15" does the same and further reduces to a non-float number. Left shifting and inserting at the right with "v=v*32+q" from above and then again extracting from the right side would require some weird bit permutations in the data line encoder. But in fact it reduces type-in size. > if i=len(a$) goto checksum This check could be omitted as said above. > poke a,q : a=a+1 : c=c+q > goto nextchar > > checksum: > if c<>q then print "checksum error" : end With the checksum there're surely some improvents possible I did not think about in depth. With 31 characters per data line and each car storing 5 bits, you get out 18 bytes and 11 additional bits usable for checksums. Or 19 bytes plus 3 checksum bits. Maybe that one is enough checksum info??? My loop reordering needs to be undone then. > nextchar: > next > goto readline > > (Hmm, I should write a simple basic preprocessor, so you can write > line number-less code like this) :-) Along with Tok64 integrated to produce true BASIC files for testing and cbmconvert for creating a D64... > 19+1 bytes per line gives 36 lines of data. The same method can be > used with base-64 of course, giving 30 lines of data. What would > people prefer though? As you said later, the 5-Bit scheme seems to be extraordinary type-in efficient. This must be no argument against Leif's observations as long as we don't start measuring groups of people trying to type-in programs after one or another scheme. Womo
From: MagerValp on 18 Oct 2006 07:52 >>>>> "WM" == Wolfgang Moser <wnhp(a)d81.de.invalid> writes: MV> How about something like this: WM> ? you saw my posting from midnight, didn't you? Yes, I just haven't had time to sit down at a C64 and play with it. MV> readline: MV> read a$ MV> if a$="end" then end MV> v=0 : s=0 : c=0 MV> for i=1 to len(a$) MV> q=asc(mid$(a$,i,1)) : gosub conv32 MV> v=v*32+q : s=s+5 WM> You may want to do the "if" first, so that the last n bits with WM> n>8 automatically remain within v and no extra check for loop WM> exiting is needed. Mmm, good point. MV> if s<7 goto nextchar WM> You surely want to extract a byte, when 8 or more bits got WM> collected, so if vote for: "s<8" Right, tpyo :) MV> q=v and 255 : v=v/256 : s=s-8 WM> Hmmmm.... at first, "v=int(v/256)" seems to WM> be a good idea to get rid of the unneded WM> fractional part. Yup, whups. WM> Left shifting and inserting at the right with "v=v*32+q" from WM> above and then again extracting from the right side would require WM> some weird bit permutations in the data line encoder. But in fact WM> it reduces type-in size. Yeah, it should be fairly simple to add. MV> poke a,q : a=a+1 : c=c+q MV> goto nextchar MV> checksum: MV> if c<>q then print "checksum error" : end WM> With the checksum there're surely some improvents possible I did WM> not think about in depth. With 31 characters per data line and WM> each car storing 5 bits, you get out 18 bytes and 11 additional WM> bits usable for checksums. You can fit 32 characters per line: 0123456789012345678901234567890123456789 99 data01234567890123456789012345678901 19+1 bytes seems like the best option. MV> (Hmm, I should write a simple basic preprocessor, so you can write MV> line number-less code like this) WM> :-) Along with Tok64 integrated to produce true BASIC files for WM> testing and cbmconvert for creating a D64... I've been using petcat -w2. How does that compare to Tok64? -- ___ . . . . . + . . o _|___|_ + . + . + . Per Olofsson, arkadspelare o-o . . . o + MagerValp(a)cling.gu.se - + + . http://www.cling.gu.se/~cl3polof/
From: Wolfgang Moser on 18 Oct 2006 15:04 Hello Per, I got some fun writing the encoder ;-) MagerValp schrieb: > WM> You may want to do the "if" first, so that the last n bits with > WM> n>8 automatically remain within v and no extra check for loop > WM> exiting is needed. > > Mmm, good point. Well, I know vote for using a 3-bit checksum only and then this exchange is not needed. > WM> Left shifting and inserting at the right with "v=v*32+q" from > WM> above and then again extracting from the right side would require > WM> some weird bit permutations in the data line encoder. But in fact > WM> it reduces type-in size. > > Yeah, it should be fairly simple to add. I know did it upside/down, back-to-front and it seems to work. > WM> With the checksum there're surely some improvents possible I did > WM> not think about in depth. With 31 characters per data line and > WM> each car storing 5 bits, you get out 18 bytes and 11 additional > WM> bits usable for checksums. > > You can fit 32 characters per line: > > 0123456789012345678901234567890123456789 > > 99 data01234567890123456789012345678901 > > 19+1 bytes seems like the best option. Hmmm, it smells like this decreases type-in efficiency again, since the letter after the data is somewhat difficult to read. Therefore I vote for only using 31 chars. But with using a 3-bit checksum only, we don't lose a single decoded raw byte. > I've been using petcat -w2. How does that compare to Tok64? Well, although I knew of it, I didn't recognized it yesterday when I "just" needed such a thing. petcat is a lot more mighty then Tok64. The latter one even does not know how to handle long filenames. Do you like Java-5 ? Then the following encoder routine is a little present (as well as the decoder done for validating reasons). I changed the character mapping a bit, because "2" was too similar to "Z". Therefore I reintegrated "V" into the mapping, which is different enough from "W". Womo ======snip/snap===== /* * (C) 2006, Wolfgang Moser, created on 18.10.2006 */ /** * <p> * base64 style encoding system, but with 5 Bits instead * of 6 Bits per encoded character. So only the chars * A..T, V..Z and 3..9 * are used effectively. There are three equivalencies * to eliminate misinterpretations: * 0 = O, 1 = I, 2 = Z * </p> * <p> * Each encoded line with 31 chars each furthermore * contains 3 bits for line checksumming. * </p> * * @author <a href="http://wmsr.de">Wolfgang Moser</a> * * @version $Id: typeincdc.java 1 2006-10-18 20:46:23Z wmsr $ * @version $HeadURL: https://svnrepo/Eclipse/C64typein/src/typeincdc.java $ */ public class typeincdc { final static String sccsid = "@(#)$Id: typeincdc.java 1 2006-10-18 20:46:23Z wmsr $\\\n"; private static byte inpb[] = new byte[19]; private static char encb[] = new char[31]; private static byte decb[] = new byte[19]; public static void main(String[] args) { System.out.print("Test array prefilled with: ["); for(int i=0; i<inpb.length; ++i) { inpb[i] = (byte)(Math.random()*256); System.out.print("" + inpb[i] + ','); } System.out.println("]"); encode(); System.out.println("Encoded array filled with: " + String.valueOf(encb)); decode(); System.out.print("Redecoded array filled with: ["); for(byte t : decb) { System.out.print("" + t + ','); } System.out.println("]"); // test the checksum on repeated encodings and decodings for(int i=0;i<65536;++i) { for(int j=0; j<inpb.length; ++j) { inpb[j] = (byte)(Math.random()*256); } encode(); if(! decode()) { System.err.println("Checksum error on run: " + i); } } } private static void encode() { short reg = 0; byte s; // calc checksum for(byte t : inpb) reg += t; // limit checksum to three bits reg &= 7; s = 3; // System.out.println("Checksum: reg="+reg); // encode with the last byte beginning for(int i=inpb.length-1, j=encb.length-1; i>=0; --i) { reg <<= 8; reg |= 255 & inpb[i]; s += 8; while(s>=5) { encb[j--] = enmap(reg); reg >>>= 5; s -= 5; } } } /* private static char enmap_old(short b) { String map = "ABCDEFGH1JKLMN0PQRSTWXYZ23456789"; // String map = "abcdefgh1jklmn0pqrstwxyz23456789"; // Z == 2 return map.charAt(b&31); } */ private static char enmap(short b) { // String map = "ABCDEFGH1JKLMN0PQRSTVWXY23456789"; String map = "ABCDEFGHIJKLMNOPQRSTVWXYZ3456789"; return map.charAt(b&31); } private static boolean decode() { short reg = 0; byte s = 0; byte ck = 0; int j=0; for(char t : encb) { reg <<= 5; reg |= demap(t); // no negatives expected here s += 5; if(s<8) continue; decb[j++] = (byte)reg; ck += reg; ck &= 7; reg >>>= 8; s -= 8; } // System.out.println("Checksum: ck="+ck+", reg="+reg); return ck == reg; } /* private static byte demap_old(char c) { if(c>'Z') c-=('a'-'A'); // map [a-z] to [A-Z] if(c=='0') c='O'; if(c=='1') c='I'; if(c=='V') c='U'; if(c>='W') c-=2; // map wxyz to uvwx if(c<'A') c+=('Y'-'2'); // map 23456789 to yz[\]^_' return (byte)((c-'A')&31); } */ private static byte demap(char c) { if(c>'Z') c-=('a'-'A'); // map [a-z] to [A-Z] if(c=='0') c='O'; if(c=='1') c='I'; if(c>='V') c-=1; // map vwxy to uvwx and z to y if(c<'A') c+=('Y'-'2'); // map 23456789 to yz[\]^_' return (byte)((c-'A')&31); } }
From: MagerValp on 18 Oct 2006 15:49
>>>>> "WM" == Wolfgang Moser <wnhp(a)d81.de.invalid> writes: WM> Hmmm, it smells like this decreases type-in efficiency again, WM> since the letter after the data is somewhat difficult to read. WM> Therefore I vote for only using 31 chars. But with using a 3-bit WM> checksum only, we don't lose a single decoded raw byte. 3-bit checksum just won't do though. Way too easy to get a typo that isn't caught, like an 8 instead of a 0. WM> Do you like Java-5 ? Actually, no :P WM> Then the following encoder routine is a little present (as well as WM> the decoder done for validating reasons). I changed the character WM> mapping a bit, because "2" was too similar to "Z". Therefore I WM> reintegrated "V" into the mapping, which is different enough from WM> "W". Ah, good point. -- ___ . . . . . + . . o _|___|_ + . + . + . Per Olofsson, arkadspelare o-o . . . o + MagerValp(a)cling.gu.se - + + . http://www.cling.gu.se/~cl3polof/ |