C_RESULT update_gamepad(void) { static bool_t refresh_values = FALSE; ssize_t res; static struct js_event js_e_buffer[64]; //If algorithms are enabled, update them before checking joystick: //*****ALGORITHM CONTROL***** if(planner->enabled) { y = planner->dpitch_final; x = planner->droll_final; yaw = planner->dyaw_final; z = planner->dgaz_final; ardrone_at_set_radiogp_inputC(y, x, z, yaw); //range checking done in C wrapper // PRINT("Pitch:%3d Roll:%3d Gaz:%3d Yaw:%3d\n", y, x, z, yaw); } //Handled in keyboard.cpp res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64); if( !res || (res < 0 && errno == EAGAIN) ) return C_OK; if( res < 0 ) return C_OK; if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored return C_OK; // Buffer décomposition in blocs (if the last is incomplete, it's ignored) uint32_t idx = 0; refresh_values = FALSE; for (idx = 0; idx < res / sizeof(struct js_event); idx++) { if(js_e_buffer[idx].type & JS_EVENT_INIT )// If Init, the first values are ignored { break; } else if(js_e_buffer[idx].type & JS_EVENT_BUTTON )// Event Button detected { //*****JOYSTICK COMMANDS***** switch( js_e_buffer[idx].number ) { case 5 : //5th button (360 RB) to toggle image stream capture if(js_e_buffer[idx].value == 1) { CAPTUREIMAGESTREAM = CAPTUREIMAGESTREAM ? false : true; if(CAPTUREIMAGESTREAM) { printf("*******************************************\n"); printf("** Starting Image Stream Capture... **\n"); printf("*******************************************\n"); } else { printf("*******************************************\n"); printf("** Stopping Image Stream Capture... **\n"); printf("*******************************************\n"); } } break; case 3 : //3rd button (360 Y-Button) to dump image if(js_e_buffer[idx].value == 1) { char filename[256]; timeval t; gettimeofday(&t, NULL); sprintf(filename, "%d.%06d.bmp", (int)t.tv_sec, (int)t.tv_usec); if(frontImgStream != NULL && cvSaveImage(filename, cvCloneImage(frontImgStream))) printf("Front Image dumped to %s\n", filename); else printf("Error dumping image.\n"); sprintf(filename, "%d.%06dbot.bmp", (int)t.tv_sec, (int)t.tv_usec); if(bottomImgStream != NULL && cvSaveImage(filename, cvCloneImage(bottomImgStream))) printf("Bottom Image dumped to %s\n", filename); else printf("Error dumping image.\n"); } break; case 2 : //2nd button (360 X-Button) for camera toggle saveColourNow = 1; //if(js_e_buffer[idx].value == 1) ardrone_at_zapC(ZAP_CHANNEL_NEXT); break; case 1 : //thumb button/360 B-Button for start/stop if(js_e_buffer[idx].value == 1) { PRINT("******************************************************Starting/Landing...\n"); start_stop(); } break; case 0 : //Joystick trigger/360 A-button enables/disables algorithms if(js_e_buffer[idx].value == 1 && planner != NULL) { planner->enabled = planner->enabled ? FALSE : TRUE; if(planner->enabled) PRINT("Algorithms Enabled.\n"); else PRINT("Algorithms Disabled.\n"); ardrone_at_set_radiogp_inputC(0, 0, 0, 0); //reset } break; default: break; } } else if(js_e_buffer[idx].type & JS_EVENT_AXIS )// Event Axis detected { double DeadzoneFix = 1/(1-(JSDEADZONE/25000.0)); refresh_values = TRUE; //******JOYSTICK CONTROL****** switch( js_e_buffer[idx].number ) { case PAD_X: x = (int32_t)((double)( js_e_buffer[idx].value + 1 ) / xfactor); if(js_e_buffer[idx].value < JSDEADZONE && js_e_buffer[idx].value > -JSDEADZONE) x = 0; else if(js_e_buffer[idx].value > 0) x -= JSDEADZONE / xfactor; else x += JSDEADZONE / xfactor; x = (double)x * DeadzoneFix; break; case PAD_Y: y = (int32_t)((double)( js_e_buffer[idx].value + 1 ) / yfactor); if(js_e_buffer[idx].value < JSDEADZONE && js_e_buffer[idx].value > -JSDEADZONE) y = 0; else if(js_e_buffer[idx].value > 0) y -= JSDEADZONE / yfactor; else y += JSDEADZONE / yfactor; y = (double)y * DeadzoneFix; break; case PAD_YAW: yaw = (int32_t)((double)( js_e_buffer[idx].value + 1 ) / yawfactor); if(js_e_buffer[idx].value < JSDEADZONE && js_e_buffer[idx].value > -JSDEADZONE) yaw = 0; else if(js_e_buffer[idx].value > 0) yaw -= JSDEADZONE / yawfactor; else yaw += JSDEADZONE / yawfactor; yaw = (double)yaw * DeadzoneFix; break; case PAD_Z: z = (int32_t)((double)( js_e_buffer[idx].value + 1 ) / zfactor); if(js_e_buffer[idx].value < JSDEADZONE && js_e_buffer[idx].value > -JSDEADZONE) z = 0; else if(js_e_buffer[idx].value > 0) z -= JSDEADZONE / zfactor; else z += JSDEADZONE / zfactor; z = (double)z * DeadzoneFix; break; default: break; } } else {// TODO: default: ERROR (non-supported) } } /************* at_set_radiogp_input **************** * Description : Fill struct radiogp_cmd, * used with at_cmds_loop function. * pitch : y-axis (rad) (-25000, +25000) * roll : x-axis (rad) (-25000, +25000) * gaz : altitude (mm/s) (-25000, +25000) * yaw : z-axis (rad/s) (-25000, +25000) */ if(refresh_values && (planner == NULL || !planner->enabled))// Axis values to refresh { ardrone_at_set_radiogp_inputC(y, x, z, yaw); //range checking done in C wrapper //PRINT("Pitch:%3d Roll:%3d Gaz:%3d Yaw:%3d\n", y, x, z, yaw); } return C_OK; }
int main(int argc, char **argv) { iso_primary_descriptor_type ipd; char *dev = default_dev; char vendor[9],model[17],rev[5]; unsigned char reply[1024]; char tmpstr[255]; int replylen=sizeof(reply); int trackno = 0; int info_only = 0; unsigned char *buffer; int buffersize = READBLOCKS*BLOCKSIZE; int start,stop,imagesize=0,tracksize=0; int counter = 0; long readsize = 0; long imagesize_bytes = 0; int drive_block_size, init_bsize; int force_mode = 0; int scanbus_mode = 0; int dump_start, dump_count; MD5_CTX *MD5; char digest[16],digest_text[33]; int md5_mode = 0; int opt_index = 0; int audio_track = 0; int readblocksize = BLOCKSIZE; int file_format = AF_FILE_AIFFC; #ifdef IRIX CDPARSER *cdp = CDcreateparser(); CDFRAME cdframe; #endif int dev_type; int i,c,o; int len; int start_time,cur_time,kbps; if (rcsid); MD5 = malloc(sizeof(MD5_CTX)); buffer=(unsigned char*)malloc(READBLOCKS*AUDIOBLOCKSIZE); if (!buffer || !MD5) die("No memory"); if (argc<2) die("parameter(s) missing\n" "Try '%s --help' for more information.\n",PRGNAME); /* parse command line parameters */ while(1) { if ((c=getopt_long(argc,argv,"SMmvhid:",long_options,&opt_index)) == -1) break; switch (c) { case 'a': file_format=AF_FILE_AIFF; break; case 'A': file_format=AF_FILE_AIFFC; break; case 'v': verbose_mode=1; break; case 'h': p_usage(); break; case 'd': dev=strdup(optarg); break; case 't': if (sscanf(optarg,"%d",&trackno)!=1) trackno=0; break; case 'i': info_only=1; break; case 'c': if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2) die("invalid parameters"); dump_mode=1; break; #ifdef IRIX case 'C': if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2) die("invalid parameters"); dump_mode=2; break; #endif case 'f': if (sscanf(optarg,"%d",&force_mode)!=1) die("invalid parameters"); if (force_mode<1 || force_mode >2) { die("invalid parameters"); } break; case 'm': md5_mode=1; break; case 'M': md5_mode=2; break; case 's': audio_mode=1; break; case 'S': scanbus_mode=1; break; case 'V': printf(PRGNAME " " VERSION " " HOST_TYPE "\nCopyright (c) Timo Kokkonen, 1997-1998.\n\n"); exit(0); break; case '?': break; default: die("error parsing parameters"); } } if (!info_only) { if (md5_mode==2) outfile=fopen("/dev/null","w"); else outfile=fopen(argv[optind],"w"); if (!outfile) { if (argv[optind]) die("cannot open output file '%s'",argv[optind]); info_only=1; } } printf("readiso(9660) " VERSION "\n"); /* open the scsi device */ if (scsi_open(dev)) die("error opening scsi device '%s'",dev); if (scanbus_mode) { printf("\n"); scan_bus(); exit(0); } memset(reply,0,sizeof(reply)); if ((dev_type=inquiry(vendor,model,rev))<0) die("error accessing scsi device"); if (verbose_mode) { printf("device: %s\n",dev); printf("Vendor: %s\nModel: %s\nRevision: %s\n",vendor,model,rev); } if ( (dev_type&0x1f) != 0x5 ) { die("Device doesn't seem to be a CD-ROM!"); } #ifdef IRIX if (strcmp(vendor,"TOSHIBA")) { warn("NOTE! Audio track reading probably not supported on this device.\n"); } #endif test_ready(); if (test_ready()!=0) { sleep(2); if (test_ready()!=0) die("device not ready"); } fprintf(stderr,"Initializing...\n"); if (audio_mode) { #ifdef IRIX audioport=ALopenport("readiso","w",0); if (!audioport) { warn("Cannot initialize audio."); audio_mode=0; } #else audio_mode=0; #endif } #ifdef IRIX /* Make sure we get sane underflow exception handling */ sigfpe_[_UNDERFL].repls = _ZERO; handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL); #endif /* set_removable(1); */ #if 0 replylen=255; if (mode_sense10(reply,&replylen)==0) { printf("replylen=%d blocks=%d blocklen=%d\n",replylen, V3(&reply[8+1]),V3(&reply[8+5])); PRINT_BUF(reply,replylen); } replylen=255; /* sizeof(reply); */ if (mode_sense(reply,&replylen)==0) { printf("replylen=%d blocks=%d blocklen=%d\n",replylen, V3(&reply[4+1]),V3(&reply[4+5])); PRINT_BUF(reply,replylen); } #endif if (dump_mode==2) init_bsize=AUDIOBLOCKSIZE; else init_bsize=BLOCKSIZE; start_stop(0); if ( (drive_block_size=get_block_size()) < 0 ) { warn("cannot get current block size"); drive_block_size=init_bsize; } if (drive_block_size != init_bsize) { mode_select(init_bsize,(dump_mode==2?0x82:0x00)); drive_block_size=get_block_size(); if (drive_block_size!=init_bsize) warn("cannot set drive block size."); } start_stop(1); if (dump_mode && !info_only) { #ifdef IRIX CDFRAME buf; if (dump_mode==2) { if (cdp) { CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0); } else die("No audioparser"); } #endif fprintf(stderr,"Dumping %d sector(s) starting from LBA=%d\n", dump_count,dump_start); for (i=dump_start;i<dump_start+dump_count;i++) { len=buffersize; read_10(i,1,buffer,&len); if (len<init_bsize) break; #ifdef IRIX if (dump_mode==2) { memcpy(&buf,buffer,CDDA_BLOCKSIZE); CDparseframe(cdp,&buf); } #endif fwrite(buffer,len,1,outfile); fprintf(stderr,"."); } fprintf(stderr,"\ndone.\n"); goto quit; } fprintf(stderr,"Reading disc TOC..."); replylen=sizeof(reply); read_toc(reply,&replylen,verbose_mode); printf("\n"); if (trackno==0) { /* try to find first data track */ for (i=0;i<(reply[3]-reply[2]+1);i++) { o=4+i*8; if (reply[o+1]&DATA_TRACK) { trackno=i+1; break; } } if (trackno==0) die("No data track(s) found."); } fprintf(stderr,"Reading track %d...\n",trackno); if ( (trackno < reply[2]) || (trackno > reply[3]) ) die("Invalid track specified."); if ( ((reply[(trackno-1)*8+4+1]&DATA_TRACK)==0) ) { fprintf(stderr,"Not a data track.\n"); mode_select(AUDIOBLOCKSIZE,0x82); if (mode_sense(reply,&replylen)!=0) die("cannot get sense data"); drive_block_size=V3(&reply[9]); fprintf(stderr,"Selecting CD-DA mode, output file format: %s\n", file_format==AF_FILE_AIFFC?"AIFFC":"AIFF"); audio_track=1; } else { audio_track=0; } start=V4(&reply[(trackno-1)*8+4+4]); stop=V4(&reply[(trackno)*8+4+4]); tracksize=abs(stop-start); /* if (verbose_mode) printf("Start LBA=%d\nStop LBA=%d\n",start,stop); */ len=buffersize; read_10(start-0,1,buffer,&len); /* PRINT_BUF(buffer,32); */ if (!audio_track) { /* read the iso9660 primary descriptor */ fprintf(stderr,"Reading ISO9660 primary descriptor...\n"); len=buffersize; read_10(start+16,1,buffer,&len); if (len<sizeof(ipd)) die("cannot read iso9660 primary descriptor."); memcpy(&ipd,buffer,sizeof(ipd)); imagesize=ISONUM(ipd.volume_space_size); /* we should really check here if we really got a valid primary descriptor or not... */ if ( (imagesize>(stop-start)) || (imagesize<1) ) { fprintf(stderr,"\aInvalid ISO primary descriptor!!!\n"); if (!info_only) fprintf(stderr,"Copying entire track to image file.\n"); force_mode=2; } if (force_mode==1) {} /* use size from ISO primary descriptor */ else if (force_mode==2) imagesize=tracksize; /* use size from TOC */ else { if ( ( (tracksize-imagesize) > MAX_DIFF_ALLOWED ) || ( imagesize > tracksize ) ) { fprintf(stderr,"ISO primary descriptor has suspicious volume size" " (%d blocks)\n",imagesize); imagesize=tracksize; fprintf(stderr, "Using track size from TOC record (%d blocks) instead.\n", imagesize); fprintf(stderr, "(option -f can be used to override this behaviour.)\n"); } } imagesize_bytes=imagesize*BLOCKSIZE; if (verbose_mode||info_only) { printf("ISO9660 image info:\n"); printf("Type: %02xh\n",ipd.type[0]); ISOGETSTR(tmpstr,ipd.id,5); printf("ID: %s\n",tmpstr); printf("Version: %u\n",ipd.version[0]); ISOGETSTR(tmpstr,ipd.system_id,32); printf("System id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.volume_id,32); printf("Volume id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.volume_set_id,128); if (strlen(tmpstr)>0) printf("Volume set id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.publisher_id,128); if (strlen(tmpstr)>0) printf("Publisher id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.preparer_id,128); if (strlen(tmpstr)>0) printf("Preparer id: %s\n",tmpstr); ISOGETSTR(tmpstr,ipd.application_id,128); if (strlen(tmpstr)>0) printf("Application id: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.creation_date); printf("Creation date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.modification_date); if (!NULLISODATE(ipd.modification_date)) printf("Modification date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.expiration_date); if (!NULLISODATE(ipd.expiration_date)) printf("Expiration date: %s\n",tmpstr); ISOGETDATE(tmpstr,ipd.effective_date); if (!NULLISODATE(ipd.effective_date)) printf("Effective date: %s\n",tmpstr); printf("Image size: %02d:%02d:%02d, %d blocks (%ld bytes)\n", LBA_MIN(ISONUM(ipd.volume_space_size)), LBA_SEC(ISONUM(ipd.volume_space_size)), LBA_FRM(ISONUM(ipd.volume_space_size)), ISONUM(ipd.volume_space_size), (long)ISONUM(ipd.volume_space_size)*BLOCKSIZE ); printf("Track size: %02d:%02d:%02d, %d blocks (%ld bytes)\n", LBA_MIN(tracksize), LBA_SEC(tracksize), LBA_FRM(tracksize), tracksize, (long)tracksize*BLOCKSIZE ); } } else { #ifdef IRIX /* if reading audio track */ imagesize=tracksize; imagesize_bytes=imagesize*CDDA_DATASIZE; buffersize = READBLOCKS*AUDIOBLOCKSIZE; readblocksize = AUDIOBLOCKSIZE; if (cdp) { CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0); } else die("No audioparser"); fclose(outfile); aiffsetup=AFnewfilesetup(); AFinitrate(aiffsetup,AF_DEFAULT_TRACK,44100.0); /* 44.1 kHz */ AFinitfilefmt(aiffsetup,file_format); /* set file format */ AFinitchannels(aiffsetup,AF_DEFAULT_TRACK,2); /* stereo */ AFinitsampfmt(aiffsetup,AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP,16); /* 16bit */ aiffoutfile=AFopenfile(argv[optind],"w",aiffsetup); if (!aiffoutfile) die("Cannot open target file (%s).",argv[optind]); #endif } /* read the image */ if (md5_mode) MD5Init(MD5); if (!info_only) { start_time=(int)time(NULL); fprintf(stderr,"Reading %s (%ldMb)...\n", audio_track?"audio track":"ISO9660 image", imagesize_bytes/(1024*1024)); do { len=buffersize; if(readsize/readblocksize+READBLOCKS>imagesize) { read_10(start+counter,imagesize-readsize/readblocksize,buffer,&len); } else read_10(start+counter,READBLOCKS,buffer,&len); if ((counter%(1024*1024/readblocksize))<READBLOCKS) { cur_time=(int)time(NULL); if ((cur_time-start_time)>0) { kbps=(readsize/1024)/(cur_time-start_time); } else { kbps=0; } fprintf(stderr,"%3dM of %dM read. (%d kb/s) \r", counter/512,imagesize/512,kbps); } counter+=READBLOCKS; readsize+=len; if (!audio_track) { fwrite(buffer,len,1,outfile); } else { #ifdef IRIX /* audio track */ for(i=0;i<(len/CDDA_BLOCKSIZE);i++) { CDparseframe(cdp,(CDFRAME*)&buffer[i*CDDA_BLOCKSIZE]); } #endif } if (md5_mode) MD5Update(MD5,buffer,(readsize>imagesize_bytes? len-(readsize-imagesize_bytes):len) ); } while (len==readblocksize*READBLOCKS&&readsize<imagesize*readblocksize); fprintf(stderr,"\n"); if (!audio_track) { if (readsize > imagesize_bytes) ftruncate(fileno(outfile),imagesize_bytes); if (readsize < imagesize_bytes) fprintf(stderr,"Image not complete!\n"); else fprintf(stderr,"Image complete.\n"); fclose(outfile); } else { #ifdef IRIX AFclosefile(aiffoutfile); #endif } } if (md5_mode && !info_only) { MD5Final((unsigned char*)digest,MD5); md2str((unsigned char*)digest,digest_text); fprintf(stderr,"MD5 (%s) = %s\n",(md5_mode==2?"'image'":argv[optind]), digest_text); } quit: start_stop(0); /* set_removable(1); */ /* close the scsi device */ scsi_close(); return 0; }
void MainWindow::step() { if(isRunning()) start_stop(); petri_dish.step(); changed = true; }
MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags), petri_dish(), histogramDialog(0), changed(true), auto_save(false), update_thread(this, this) { setupUi(this); connect(&timer, SIGNAL(timeout()), &petri_dish, SLOT(step())); connect(&petri_dish, SIGNAL(changed()), worldView, SLOT(queueUpdate())); //connect(&petri_dish, SIGNAL(changed()), worldView, SLOT(repaint())); connect(&petri_dish, SIGNAL(changed()), this, SLOT(set_stats())); connect(runButton, SIGNAL(clicked()), this, SLOT(start_stop())); //connect(checkIntegrity, SIGNAL(clicked()), this, SLOT(check_integrity())); connect(stepBtn, SIGNAL(clicked()), this, SLOT(step())); connect(radViewDefault, SIGNAL(clicked()), &petri_dish, SLOT(set_default_view_mode())); connect(radViewBugs, SIGNAL(clicked()), &petri_dish, SLOT(set_bugs_view_mode())); connect(radViewEnergy, SIGNAL(clicked()), &petri_dish, SLOT(set_energy_view_mode())); connect(radViewAge, SIGNAL(clicked()), &petri_dish, SLOT(set_age_view_mode())); connect(radViewSize, SIGNAL(clicked()), &petri_dish, SLOT(set_dna_size_view_mode())); connect(radViewDNA, SIGNAL(clicked()), &petri_dish, SLOT(set_dna_view_mode())); connect(radViewTerrain, SIGNAL(clicked()), &petri_dish, SLOT(set_terrain_view_mode())); connect(actionNew, SIGNAL(triggered()), this, SLOT(new_world())); connect(actionSave, SIGNAL(triggered()), this, SLOT(save_world())); connect(actionOpen, SIGNAL(triggered()), this, SLOT(load_world())); connect(actionSave_As, SIGNAL(triggered()), this, SLOT(save_as_world())); connect(settings, SIGNAL(settingsChanged()), this, SLOT(change_world())); connect(actionAutoSave, SIGNAL(triggered()), this, SLOT(autosave_world())); connect(actionCheck_Integrity, SIGNAL(triggered()), this, SLOT(check_integrity())); connect(worldView, SIGNAL(clicked(int, int)), this, SLOT(edit_bug(int, int))); connect(idleChk, SIGNAL(clicked(bool)), this, SLOT(enableIdleDetect(bool))); connect(&idleTimer, SIGNAL(timeout()), this, SLOT(checkIdle())); autosave_timer.setInterval(1000 * 60 * 2); // every two mins connect(&autosave_timer, SIGNAL(timeout()), this, SLOT(save_world())); petri_dish.set_widget(worldView); petri_dish.init(settings->getParams()); totalEnergy->setText(QString().setNum(petri_dish.get_total_energy())); spinDNAVal->setMaximum(settings->getParams().max_data); set_stats(); last_time = 0; update_time.start(); updates_per_sec = 0; //update_thread.start(); horizontalSlider->setValue(1000); timer.start(0); setAttribute(Qt::WA_QuitOnClose, true); repaint(); if(!qApp->arguments().size() > 1) { bool running; load_from_file(qApp->arguments().at(1), running); if(running) start(); } }
/* * Set page code 5 for TAO mode. */ int prepare_for_write(cd_device *dev, int track_mode, int test_write, int keep_disc_open) { uchar_t *buf; int no_err; int reset_device; if ((write_mode == DAO_MODE) && keep_disc_open) { (void) printf(gettext( "Multi-session is not supported on DVD media\n")); exit(1); } if ((write_mode == DAO_MODE) && debug) { (void) printf("Preparing to write in DAO\n"); } (void) start_stop(dev->d_fd, 1); /* Some drives do not support this command but still do it */ (void) rezero_unit(dev->d_fd); buf = (uchar_t *)my_zalloc(64); no_err = get_mode_page(dev->d_fd, 5, 0, 64, buf); if (no_err) no_err = ((buf[1] + 2) > 64) ? 0 : 1; /* * If the device is already in simulation mode and again a * simulation is requested, then set the device in non-simulation * 1st and then take it to simulation mode. This will flush any * previous fake state in the drive. */ if (no_err && test_write && (buf[2] & 0x10)) { reset_device = 1; } else { reset_device = 0; } if (no_err != 0) { buf[0] &= 0x3f; /* set TAO or DAO writing mode */ buf[2] = (write_mode == TAO_MODE)?1:2; /* set simulation flag */ if (test_write && (!reset_device)) { buf[2] |= 0x10; } else { buf[2] &= ~0x10; } /* Turn on HW buffer underrun protection (BUFE) */ if (!test_write) { buf[2] |= 0x40; } /* set track mode type */ if (device_type == CD_RW) { buf[3] = track_mode & 0x0f; /* ctrl nibble */ } if (keep_disc_open) { buf[3] |= 0xc0; /* Allow more sessions */ } /* Select track type (audio or data) */ if (track_mode == TRACK_MODE_DATA) { buf[4] = 8; /* 2048 byte sector */ } else { buf[4] = 0; /* 2352 byte sector */ } buf[7] = buf[8] = 0; /* Need to clear these fields for setting into DAO */ if (write_mode == DAO_MODE) buf[5] = buf[15] = 0; /* print out mode for detailed log */ if (debug && verbose) { int i; (void) printf("setting = [ "); for (i = 0; i < 15; i++) (void) printf("0x%x ", buf[i]); (void) printf("]\n"); } no_err = set_mode_page(dev->d_fd, buf); if (no_err && reset_device) { /* Turn the test write bit back on */ buf[2] |= 0x10; no_err = set_mode_page(dev->d_fd, buf); } /* * Since BUFE is the only optional flag we are * setting we will try to turn it off if the command * fails. */ if (!no_err) { /* * Some old drives may not support HW * buffer underrun protection, try again * after turning it off. */ if (debug) (void) printf("Turning off BUFE\n"); buf[2] &= ~0x40; no_err = set_mode_page(dev->d_fd, buf); } } free(buf); return (no_err); }