예제 #1
0
파일: pp.c 프로젝트: Flaviowebit/openCBM
static int pp_read(CBM_FILE fd, unsigned char *c1, unsigned char *c2)
{
                                                                        SETSTATEDEBUG((void)0);
    cbm_iec_release(fd, IEC_CLOCK);
                                                                        SETSTATEDEBUG((void)0);
#ifndef USE_CBM_IEC_WAIT
    while(cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 0);
#endif
                                                                        SETSTATEDEBUG((void)0);
    *c1 = cbm_pp_read(fd);

                                                                        SETSTATEDEBUG((void)0);
    cbm_iec_set(fd, IEC_CLOCK);
                                                                        SETSTATEDEBUG((void)0);
#ifndef USE_CBM_IEC_WAIT
    while(!cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 1);
#endif
                                                                        SETSTATEDEBUG((void)0);
    *c2 = cbm_pp_read(fd);

                                                                        SETSTATEDEBUG((void)0);
    return 0;
}
예제 #2
0
파일: pp.c 프로젝트: Flaviowebit/openCBM
static int pp_write(CBM_FILE fd, char c1, char c2)
{
                                                                        SETSTATEDEBUG((void)0);
    pp_check_direction(PP_WRITE);
                                                                        SETSTATEDEBUG((void)0);
#ifndef USE_CBM_IEC_WAIT
    while(!cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 1);
#endif
                                                                        SETSTATEDEBUG((void)0);
    cbm_pp_write(fd, c1);
                                                                        SETSTATEDEBUG((void)0);
    cbm_iec_release(fd, IEC_CLOCK);

                                                                        SETSTATEDEBUG((void)0);
#ifndef USE_CBM_IEC_WAIT
    while(cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 0);
#endif
                                                                        SETSTATEDEBUG((void)0);
    cbm_pp_write(fd, c2);
                                                                        SETSTATEDEBUG((void)0);
    cbm_iec_set(fd, IEC_CLOCK);

                                                                        SETSTATEDEBUG((void)0);
    return 0;
}
예제 #3
0
void
changelines(CBM_FILE f)
{
    cbm_iec_release(f,IEC_DATA);
    cbm_iec_release(f,IEC_ATN);
    cbm_iec_release(f,IEC_CLOCK);

    sleep(2);

    for (int atn=0; atn<2; atn++)
    {
        if (atn)
            cbm_iec_set(f, IEC_ATN);
        else
            cbm_iec_release(f, IEC_ATN);

        for (int clk=0; clk<2; clk++)
        {
            if (clk)
                cbm_iec_set(f, IEC_CLOCK);
            else
                cbm_iec_release(f, IEC_CLOCK);

            for (int data=0; data<2; data++)
            {
                if (data)
                    cbm_iec_set(f, IEC_DATA);
                else
                    cbm_iec_release(f, IEC_DATA);

                sleep(1);
            }
        }
    }
}
예제 #4
0
파일: pp.c 프로젝트: jkaessens/opencbm
static int pp_read(CBM_FILE fd, unsigned char *c1, unsigned char *c2)
{
    pp_check_direction(PP_READ);
#ifndef USE_CBM_IEC_WAIT
    while(!cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 1);
#endif
    *c1 = cbm_pp_read(fd);
    cbm_iec_release(fd, IEC_CLOCK);

#ifndef USE_CBM_IEC_WAIT
    while(cbm_iec_get(fd, IEC_DATA));
#else
    cbm_iec_wait(fd, IEC_DATA, 0);
#endif
    *c2 = cbm_pp_read(fd);
    cbm_iec_set(fd, IEC_CLOCK);

    return 0;
}
예제 #5
0
int ARCH_MAINDECL main(int argc, char *argv[])
{
    int status = 0, id_ofs = 0, name_len, i;
    CBM_FILE fd;
//    unsigned char drive, tracks = 35, bump = 1, orig = 0, show_progress = 0;
    unsigned char drive, tracks = 35, bump = 1, orig = 0x4b, show_progress = 0;
    char cmd[40], name[20], *arg;
    int erroroccured = 0;
    char *adapter = NULL;
    int option;

    struct option longopts[] =
    {
        { "help"       , no_argument      , NULL, 'h' },
        { "version"    , no_argument      , NULL, 'V' },
        { "adapter"    , required_argument, NULL, '@' },
        { "no-bump"    , no_argument      , NULL, 'n' },
        { "extended"   , no_argument      , NULL, 'x' },
//        { "original"   , no_argument      , NULL, 'o' },
{ "fill"  , required_argument, NULL, 'f' },

        { "status"     , no_argument      , NULL, 's' },
        { "progress"   , no_argument      , NULL, 'p' },

        /* undocumented */
        { "end-track"  , required_argument, NULL, 't' },
        { NULL         , 0                , NULL, 0   }
    };

//    const char shortopts[] ="hVnxospt:";
    const char shortopts[] ="hVnxf:spt:";


    while((option = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1)
    {
        switch(option)
        {
            case 'n': bump = 0;
                      break;
            case 'f': //orig = 0x4b;
orig=arch_atoc(optarg);
                      break;
            case 's': status = 1;
                      break;
            case 'x': tracks = 40;
                      break;
            case 'h': help();
                      return 0;
            case 'V': printf("frm_analyzer %s\n", OPENCBM_VERSION);
                      return 0;
            case 'p': show_progress = 1;
                      break;
            case 't': tracks = arch_atoc(optarg);
                      break;
            case '@': if (adapter == NULL)
                          adapter = cbmlibmisc_strdup(optarg);
                      else
                      {
                          fprintf(stderr, "--adapter/-@ given more than once.");
                          hint(argv[0]);
                          return 1;
                      }
                      break;
            default : hint(argv[0]);
                      return 1;
        }
    }

    if(optind + 2 != argc)
    {
        fprintf(stderr, "Usage: %s [OPTION]... DRIVE NAME,ID\n", argv[0]);
        hint(argv[0]);
        return 1;
    }

    arg = argv[optind++];
    drive = arch_atoc(arg);
    if(drive < 8 || drive > 11)
    {
        fprintf(stderr, "Invalid drive number (%s)\n", arg);
        return 1;
    }
    
    arg      = argv[optind++];
    name_len = 0;
    while(*arg)
    {
        unsigned char c;
        c = (unsigned char) toupper(*arg);
        if(c == ',')
        {
            if(id_ofs)
            {
                fprintf(stderr, "More than one `,' in disk name\n");
                return 1;
            }
            id_ofs = name_len;
        }
        name[name_len++] = c;
        if(name_len > 19)
        {
            fprintf(stderr, "Disk name too long\n");
            return 1;
        }
        arg++;
    }
    name[name_len] = 0;

    if(cbm_driver_open_ex(&fd, adapter) == 0)
    {
        cbm_upload(fd, drive, 0x0300, dskfrmt, sizeof(dskfrmt));
        sprintf(cmd, "M-E%c%c%c%c%c%c0:%s", 3, 3, tracks + 1, 
                orig, bump, show_progress, name);
        cbm_exec_command(fd, drive, cmd, 11+strlen(name));
#if 0
        if(show_progress)
        {
            /* do some handshake */
            cbm_iec_release(fd, IEC_CLOCK);
            for(i = 1; i <= tracks; i++)
            {
                cbm_iec_wait(fd, IEC_DATA, 1);
                cbm_iec_set(fd, IEC_CLOCK);
                cbm_iec_wait(fd, IEC_DATA, 0);
                cbm_iec_release(fd, IEC_CLOCK);

                printf("#");
                fflush(stdout);
            }
            printf("\n");
        }
#endif
        erroroccured = cbm_device_status(fd, drive, cmd, sizeof(cmd));

        if(erroroccured && status)
        {
            printf("%s\n", cmd);
        }

        if(!erroroccured && (tracks > 35))
        {
            cbm_open(fd, drive, 2, "#", 1);
            cbm_exec_command(fd, drive, "U1:2 0 18 0", 11);
            cbm_exec_command(fd, drive, "B-P2 192", 8);
            cbm_listen(fd, drive, 2);
            while(tracks > 35)
            {
                cbm_raw_write(fd, "\021\377\377\001", 4);
                tracks--;
            }
            cbm_unlisten(fd);
            cbm_exec_command(fd, drive, "U2:2 0 18 0", 11);
            cbm_close(fd, drive, 2);
        }

        if(!erroroccured && status)
        {
            cbm_device_status(fd, drive, cmd, sizeof(cmd));
            printf("%s\n", cmd);
        }
#if 1   // verbose output
        {
#if 0 // @TODO unused variables
            float RPMval;
            int sectors, virtGAPsze, remainder, trackTailGAP, flags, retry, lastTr;
            const char *vrfy;
#endif
            unsigned char data[0x100];
            if (cbm_download(fd, drive, 0x0500, data, sizeof(data)) == sizeof(data))
            {


#if 1
                // TODO, Pattern analyzer, get the lenght of the PLL synchronization period
                //
                    // search the last byte triple consisting of: 0x49, 0x24, 0x92
                    // 
                int k;
                const unsigned char pattern[]={0x49, 0x24, 0x92};
                // const unsigned char pattern[]={0xdb, 0x6d, 0xb6};

                for(k=sizeof(data)-3; k>=0; --k)
                {
                    if(data[k]==pattern[0] && data[k+1]==pattern[1] && data[k+2]==pattern[2]) break;
                }
                if(k<0)
                {
                    // no part of the written sequence was found
                    k=sizeof(data);
                }
                else
                {    
                        // now search the beginning of that "010010010010010010010010..." bit stream
                    while(k>=0 && data[k]==pattern[0] && data[k+1]==pattern[1] && data[k+2]==pattern[2])
                    {
                        k-=3;
                    }
                    k+=3;
    
                        // do single byte decreases
                    if(k>=1 && data[k-1]==pattern[2]) --k;
                    if(k>=1 && data[k-1]==pattern[1]) --k;
                    if(k>=1 && data[k-1]==pattern[0]) --k;
                }

                printf("Result with Pattern: 0x%02X / %3d, formatted on track %2d, PLL synchronization length: %3d\n", orig, orig, tracks, k);


                for (i=0; i < sizeof(data); i++)
                {
                    /*
                    if(data[i] == 0)
                    {
                        printf("\n");
                        break;
                    }
                    */
                    printf(" %02X", data[i]);
                    if((i&0x0f) == 0x0f) printf("\n");
                }
#else
                int i;
                printf("Track|Retry|sctrs|slctd|| GAP |modulo |modulo|tail| Verify  | RPM  |\n"
                       "     |     |     | GAP ||adjst|complmt| dvsr |GAP |         |      |\n"
                       "-----+-----+-----+-----++-----+-------+------+----+---------+------+\n");

                lastTr=-1;
                for (i=0; i < sizeof(data); i+=4)
                {
                    if(data[i]==0) break;    // no more data is available


                    if(data[i+3]>=0x40 && data[i]>42){
                            // logging continuation line
                        printf("     |     | debug log || $%02X | $%02X $%02X $%02X\n",
                               data[i], data[i+1], data[i+2], data[i+3]);
                        continue;    // proceed with next loop run
                        }


                    if(data[i]==lastTr) retry++;
                    else                retry=0;
                    lastTr=data[i];

                    if(data[i]>=25)            // preselect track dependent constants
                    {
                        if(data[i]>=31) sectors=17, RPMval=60000000.0f/16;
                        else            sectors=18, RPMval=60000000.0f/15;
                    }
                    else
                    {
                        if(data[i]>=18) sectors=19, RPMval=60000000.0f/14;
                        else            sectors=21, RPMval=60000000.0f/13;
                    }

                        // separate some flags
                    flags=(data[i+3]>>6)&0x03;
                    data[i+3]&=0x3f;

                    switch(flags)
                    {
                        case 0x01: vrfy="SYNC fail"; break;
                        case 0x02: vrfy="verify OK"; break;
                        case 0x03: vrfy="vrfy fail"; break;
                        default:   vrfy="   ./.   ";
                    }

                        // recalculation of the track tail GAP out of the
                        // choosen GAP for this track, the new GAP size
                        // adjustment and the complement of the remainder
                        // of the adjustment division

                    virtGAPsze=data[i+1]         -3;    // virtual GAP increase to
                        // prevent reformatting, when only one byte is missing


                    remainder=((data[i+2]==0xff) ? virtGAPsze : sectors)
                                 - data[i+3];


                    trackTailGAP=((data[i+2]==0xff) ? 0 : data[i+2]*sectors + virtGAPsze)
                                    + remainder;

                        // the following constants are nybble based (double the
                        // size of the well known constants for SYNC lengths,
                        // block header size, data block GAP and data block)
                        //
                        // (0x01&data[i+1]&sectors) is a correction term, if "half
                        // GAPs" are written and the number of sectors is odd
                        //
                    // RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]&sectors) + trackTailGAP - data[i+1])

                    RPMval = (flags != 0x01) ?
                        RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]&sectors) + trackTailGAP - data[i+1])
                        : 0;

                    printf(" %3u | ", data[i]);
                    if(retry>0) printf("%3u", retry);
                    else        printf("   ");
                   /*      " |sctrs |slctd  || GAP   |modulo   |modulo  |tail | Verify  | RPM  |\n"
                    *      " |      | GAP   ||adjst  |complmt  |        |GAP  |         |      |\n"
                    *      "-+----- +-----  ++-----  +-------  +------  +---- +---------+------+\n"
                    */
                    printf(" |  %2u | $%02X || $%02X |   $%02X |  $%02X |$%03X|%9s|%6.2f|\n",
                           sectors, data[i+1], data[i+2], data[i+3],
                           remainder, trackTailGAP, vrfy, RPMval);
                }
                printf("\n  *) Note: All GAP based numbers shown here (sedecimal values) are\n"
                         "           nybble based (4 GCR Bits) instead of GCR byte based.\n");
#endif
            }
            else
            {
예제 #6
0
파일: main.c 프로젝트: bogde/OpenCBM
static int
main_testlines(int argc, char **argv)
{
    /* CBM_FILE fd; */
    int rv;

    FUNC_ENTER();

    do
    {
        rv = cbm_driver_open(&fd, 0);

        if (rv != 0)
            break;

        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing all lines"));
        cbm_iec_release(fd, IEC_CLOCK | IEC_DATA | IEC_ATN | IEC_RESET);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting CLOCK"));
        cbm_iec_set(fd, IEC_CLOCK);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting DATA"));
        cbm_iec_set(fd, IEC_DATA);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting ATN"));
        cbm_iec_set(fd, IEC_ATN);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting RESET"));
        cbm_iec_set(fd, IEC_RESET);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing CLOCK"));
        cbm_iec_release(fd, IEC_CLOCK);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing DATA"));
        cbm_iec_release(fd, IEC_DATA);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing ATN"));
        cbm_iec_release(fd, IEC_ATN);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing RESET"));
        cbm_iec_release(fd, IEC_RESET);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting DATA and ATN"));
        cbm_iec_set(fd, IEC_DATA | IEC_ATN);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Setting CLOCK, releasing ATN"));
        cbm_iec_setrelease(fd, IEC_ATN | IEC_CLOCK, IEC_CLOCK);
        read_line_status(fd);

        DBG_PRINT((DBG_PREFIX ""));
        DBG_PRINT((DBG_PREFIX "Releasing all lines"));
        cbm_iec_release(fd, IEC_CLOCK | IEC_DATA | IEC_ATN | IEC_RESET);
        read_line_status(fd);

    } while (0);

    if (rv == 0)
        cbm_driver_close(fd);

    FUNC_LEAVE_INT(0);
}