Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: cf67b9f86d
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 452 lines (395 sloc) 12.154 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
/*
* bdump -- Dump info from a brother knitting machine file
*

Copyright 2009 Steve Conklin
steve at conklinhouse dot com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

This file is for experimentation, and reflects whatever I was working on.
It may be helpful as a starting point, but probably isn't of general use.

Book says max save of "approximately 13,600 stitches"
This is about 1700 bytes
2048 - 1700 = 348


---

#
# Pattern Number
# Position of the selector
# Pattern position for the selector setting
# Pattern position and number of repeats for each motif for selector (2) settings
# Variation key settings
# Memo display information
# Row numbers and memo key information

# 200 needles
# Max of 998 rows when entering your own patterns (depends on number of stitches in a row??)
# 998 rows would take 0x1F3 bytes for memo info, and there's not room where I think it should be
# pattern position is Yellow or Green (left or right)
# up to 6 motifs -


*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

// defines that are probably correct and will stay

// Sizes
#define NEEDLELEN 13 // 13 bytes for 200 bits

// Pattern variations
#define VAR_REV 0x01 // reverse
#define VAR_MH 0x02 // mirror horizontal
#define VAR_SH 0x08 // stretch horizontal
#define VAR_SV 0x10 // stretch vertical
#define VAR_IV 0x04 // invert horizontal
#define VAR_KHC 0x20 // KHC
#define VAR_KRC 0x40 // KRC
#define VAR_MB 0x80 // M button
/*
if (bd.variations & VAR_REV)
printf("REVERSE ");
if (bd.variations & VAR_MH)
printf("MIRROR_H ");
if (bd.variations & VAR_SH)
printf("STRETCH H ");
if (bd.variations & VAR_SV)
printf("STRETCH V ");
if (bd.variations & VAR_IV)
printf("INVERT V ");
if (bd.variations & VAR_KHC)
printf("KHC ");
if (bd.variations & VAR_KRC)
printf("KRC ");
if (bd.variations & VAR_UNK)
printf("UNKNOWN ");
*/
// Selector switch
#define SEL_ONE 0x10
#define SEL_TWO 0x20

static void hex_dump(void *data, int size)
{
    /* dumps size bytes of *data to stdout. Looks like:
* [0000] 75 6E 6B 6E 6F 77 6E 20
* 30 FF 00 00 00 00 39 00 unknown 0.....9.
* (in a single line of course)
*/

    unsigned char *p = data;
    unsigned char c;
    int n;
    int marked = 0;
    char bytestr[4] = {0};
    char addrstr[10] = {0};
    char hexstr[ 16*3 + 5] = {0};
    char charstr[16*1 + 5] = {0};
    for(n=1;n<=size;n++) {
        if (n%16 == 1) {
            /* store address for this line */
            snprintf(addrstr, sizeof(addrstr), "%.4x",
               ((unsigned int)p-(unsigned int)data) );
        }
            
        c = *p;
        if (isalnum(c) == 0) {
            c = '.';
        }


        /* store hex str (for left side) */
        snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
        strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);

        /* store char str (for right side) */
        snprintf(bytestr, sizeof(bytestr), "%c", c);
        strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);

        if(n%16 == 0) {
            /* line completed */
printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
hexstr[0] = 0;
charstr[0] = 0;
        } else if(n%8 == 0) {
            /* half line: add whitespaces */
            strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
            strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
        }
        p++; /* next byte */
    }

    if (strlen(hexstr) > 0) {
        /* print rest of buffer if not empty */
        printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
    }
}

/*
* TODO This needs to be reworked. These represent the
* values for all 200 needles. There are two copies in the file,
* probably for 'this row' and 'next row'.
*
* For both the needle values, patterns, and memo information,
* the data is always stored from higher to lower addresses
* in the file.
*/
void olddumpNeedles(unsigned short *pp) {
    unsigned short *pp1 = pp;
    unsigned short pb;
    int i, j;
    for (i=0; i<NEEDLELEN; i++) {
pb = htons(*pp1);
//printf("0x%04X\n", pb);
for (j=15; j>=0; j--) {
if (pb & (1<<j))
printf("*");
else
printf(" ");
}
pp1++;
    }
    printf("\n");
}

void dumpNeedles(unsigned short *pp) {
    void *pat = pp;
    pat += NEEDLELEN;
/*
unsigned short *pp1 = pp;
unsigned short pb;
int i, j;
for (i=0; i<NEEDLELEN; i++) {
pb = htons(*pp1);
//printf("0x%04X\n", pb);
for (j=15; j>=0; j--) {
if (pb & (1<<j))
printf("*");
else
printf(" ");
}
pp1++;
}
*/
    printf("\n");
}
/*
void dumpPattern(void *pat, int stitches, int rows) {
// TODO finish this - how are things padded for odd numbers of stitches?
return;
}
*/

int main (int argc, char *argv[]) {

    FILE *fin;
    char *infile;

    // our struct - doesn't reflect file structure
    typedef struct {
unsigned char pos;
unsigned char right;
unsigned char copies;
    } motifstr, *motifptr;

    // This 7 byte structure is the file format
    // for the information about each custom
    // pattern 901-999
    typedef struct {
unsigned char status;
unsigned char unk1;
unsigned char rows_t:4;
unsigned char rows_h:4;
unsigned char stitches_h:4;
unsigned char rows_o:4;
unsigned char stitches_o:4;
unsigned char stitches_t:4;
unsigned char num_h:4;
unsigned char unk:4;
unsigned char num_o:4;
unsigned char num_t:4;
    } pgminfo, *ppgminfo;

    struct {
pgminfo pgms[99];
unsigned char head[1073];
unsigned short needles1[NEEDLELEN];
unsigned char afterfirst1[13];
unsigned char variations;
unsigned char afterfirst2[8];
unsigned short needles2[NEEDLELEN];
unsigned char tail1[186];
unsigned char selector[1];
unsigned char selfiller;
unsigned char motifdata[20];
    } bd;

    unsigned char selector;
    motifstr motif[6];
    int nummotifs;
    unsigned char selone_pos;
    unsigned char selone_right;

    // misc variables
    int readlen;
    int i;
    unsigned char cval, *cptr;
    unsigned long foolong;

 
    if (argc != 2) {
printf("usage: %s filename\n", argv[0]);
exit(-1);
    }

    infile = argv[1];
    
    if (!(fin=fopen(infile, "r"))) {
printf("Unable to open file %s\n", argv[1]);
exit(-1);
    }

    printf("length of struct is %d\n", sizeof(bd));

    readlen = fread(&bd, 1, sizeof(bd), fin);
    if (readlen != sizeof(bd)) {
printf("Failed read, %d\n", readlen);
exit(-1);
    }

    fclose(fin);

    printf("===== programs =====\n");
    //for(i=0;i<100;i++) {
    for(i=0;i<5;i++) {
ppgminfo pptr = &bd.pgms[i];
unsigned int ival;
//if (pptr->status == 1) {
if (1) {
printf("Position %d:\n", i);
ival = (pptr->num_h * 100) + (pptr->num_t * 10) + (pptr->num_o);
printf("Status 0x%02X (%d)\n", pptr->status, pptr->status);
printf(" Pgm Number: % 3d\n", ival);
printf(" Unk nibble: % 3d\n", pptr->unk);
printf(" unk1 0x%02X (%d)\n", pptr->unk1, pptr->unk1);
ival = (pptr->rows_h * 100) + (pptr->rows_t * 10) + (pptr->rows_o);
printf(" Rows: % 3d\n", ival);
ival = (pptr->stitches_h * 100) + (pptr->stitches_t * 10) + (pptr->stitches_o);
printf(" Stitches: % 3d\n", ival);

printf("--------\n");
}
    }

    printf("===== head =====\n");
    hex_dump(bd.head, sizeof(bd.head));

    printf("===== Needles1 =====\n");
    dumpNeedles(bd.needles1);

    printf("===== afterfirst1 =====\n");
    hex_dump(bd.afterfirst1, sizeof(bd.afterfirst1));

    printf("===== Variations =====\n");
    printf("variations = 0x%02X - ", bd.variations);
    if (bd.variations & VAR_REV)
printf("REVERSE ");
    if (bd.variations & VAR_MH)
printf("MIRROR_H ");
    if (bd.variations & VAR_SH)
printf("STRETCH H ");
    if (bd.variations & VAR_SV)
printf("STRETCH V ");
    if (bd.variations & VAR_IV)
printf("INVERT V ");
    if (bd.variations & VAR_KHC)
printf("KHC ");
    if (bd.variations & VAR_KRC)
printf("KRC ");
    //if (bd.variations & VAR_UNK)
    //printf("UNKNOWN ");
    printf("\n");

    printf("===== afterfirst2 =====\n");
    hex_dump(bd.afterfirst2, sizeof(bd.afterfirst2));

    printf("===== Needles2 =====\n");
    dumpNeedles(bd.needles2);

    printf("===== tail1 =====\n");
    hex_dump(bd.tail1, sizeof(bd.tail1));

    printf("===== selector =====\n"); // 0x7EA
    //printf("Selector = 0x%02X | %d\n", *bd.selector, *bd.selector);
    cval = *bd.selector & 0xF0;
    selector = cval;
    if (cval == SEL_ONE) {
printf("Selector One (all over pattern):\n");
    } else if (cval == SEL_TWO) {
printf("Selector Two (motifs):\n");
    } else {
printf("Unknown selector value of 0x%X found\n", cval);
    }

    printf("===== selector low nibble =====\n"); // 0x7EA
    printf("Selector low nibble = 0x%02X\n", *bd.selector & 0x0F);

    printf("===== selfiller = 0x%02X =====\n", bd.selfiller);

    // read the motifs
    // Motif data is three bytes for each motif, but it is not
    // byte aligned - it is off alignment by 4 bits.
    cptr = &bd.motifdata[0];
    cval = *cptr & 0xF0;
    printf("MSB at beggining of motif info = 0x%02X\n", cval);
    for(i=5; i>=0; i--) {
// First byte, skip MSB
cval = *cptr & 0x0F; // LSB
//printf("cval (LSB) = 0x%02X\n", cval);
if (cval & 8) {
motif[i].right = 1;
cval &= 0x07;
} else {
motif[i].right = 0;
}
if (cval > 1)
printf("Unexpected value of %d for position hundreds, motif %d\n", cval, i);
motif[i].pos = cval * 100;
// Second byte
cptr++;
//cval = *cptr;
//printf("cval = 0x%02X\n", cval);
cval = (*cptr>>4) & 0x0F; // MSB
motif[i].pos += cval * 10;
cval = *cptr & 0x0F; // LSB
motif[i].pos += cval;
// Third byte
cptr++;
//cval = *cptr;
//printf("cval = 0x%02X\n", cval);
cval = (*cptr>>4) & 0x0F; // MSB
motif[i].copies = cval * 100;
cval = *cptr & 0x0F; // LSB
motif[i].copies += cval * 10;
// Fourth byte
cptr++;
cval = (*cptr>>4) & 0x0F; // MSB
//printf("cval (MSB) = 0x%02X\n", cval);
motif[i].copies += cval;
// Leave pointer so we grab LSB next round
//printf("--\n");
    }
    // now in the last three nibbles is the starting
    // location for the pattern for Selector One
    // First byte, skip MSB
    cval = *cptr & 0x0F; // LSB
    if (cval & 8) {
selone_right = 1;
cval &= 0x07;
    } else {
selone_right = 0;
    }
    if (cval > 1)
printf("Unexpected value of %d for selector One position hundreds\n", cval);
    selone_pos = cval * 100;
    // Second byte
    cptr++;
    cval = (*cptr>>4) & 0x0F; // MSB
    selone_pos += cval * 10;
    cval = *cptr & 0x0F; // LSB
    selone_pos += cval;

    // see how many are in use - the first zero for
    // number of copies is the end
    nummotifs = 6;
    for (i=0; i<=5; i++) {
if (motif[i].copies == 0) {
nummotifs = i;
break;
}
    }

    printf("========== Selector Two (motifs) ==========\n");
    printf("%d motifs are used\n", nummotifs);
    for (i=0; i<=5; i++) {
printf("Motif %d: ", i+1);
printf(" %3d Copies ", motif[i].copies);
if (motif[i].right)
printf("starting at %3d Right ", motif[i].pos);
else
printf("starting at %3d Left ", motif[i].pos);
if (i+1 > nummotifs)
printf(" (UNUSED)\n");
else
printf("\n");

    }
    printf("========== Selector One (all over pattern) ==========\n");
    if (selone_right)
printf("Selector One pattern start is position %3d Right\n", selone_pos);
    else
printf("Selector One pattern start is position %3d Left\n", selone_pos);
}
Something went wrong with that request. Please try again.