1 /* 2 * This file has been modified for the cdrkit suite. 3 * 4 * The behaviour and appearence of the program code below can differ to a major 5 * extent from the version distributed by the original author(s). 6 * 7 * For details, see Changelog file distributed with the cdrkit package. If you 8 * received this file from another source then ask the distributing person for 9 * a log of modifications. 10 * 11 */ 12 13 /* @(#)sector.c 1.13 04/03/01 Copyright 2001-2004 J. Schilling */ 14 /* 15 * Functions needed to use libedc_ecc from cdrecord 16 * 17 * Copyright (c) 2001-2004 J. Schilling 18 */ 19 /* 20 * This program is free software; you can redistribute it and/or modify 21 * it under the terms of the GNU General Public License version 2 22 * as published by the Free Software Foundation. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License along with 30 * this program; see the file COPYING. If not, write to the Free Software 31 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 32 */ 33 34 #include <mconfig.h> 35 #include <stdio.h> 36 #include <standard.h> 37 #include <utypes.h> 38 #include <timedefs.h> 39 #include <schily.h> 40 41 #include "wodim.h" 42 #include "movesect.h" 43 44 #ifdef HAVE_LIB_EDC_ECC 45 46 47 #define LAYER2 48 #define EDC_LAYER2 49 #define ENCODER 50 #define EDC_ENCODER 51 #include <ecc.h> 52 53 #ifdef DO8 54 #define HAVE_NEW_LIB_EDC 55 #endif 56 57 int encspeed(BOOL be_verbose); 58 void encsectors(track_t *trackp, Uchar *bp, int address, int nsecs); 59 void scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs); 60 void encodesector(Uchar *sp, int sectype, int address); 61 void fillsector(Uchar *sp, int sectype, int address); 62 63 /* 64 * Sector types known by lib libedc_ecc: 65 */ 66 #ifdef __comment__ 67 /* MMC */ 68 #define MODE_0 0 /* -> XX 12+4+2336 (12+4uuu von libedc) */ 69 #define MODE_1 1 /* -> 8 12+4+2048+288 (124+4uuu+288 von libedc)*/ 70 #define MODE_2 2 /* -> 9 12+4+2336 (12+4uuu von libedc) */ 71 #define MODE_2_FORM_1 3 /* -> 10/11 12+4+8+2048+280 (12+4hhhuuu+280 von libedc)*/ 72 #define MODE_2_FORM_2 4 /* -> 12 (eher 13!) 12+4+8+2324+4 (12+4hhhuuu+4 von libedc)*/ 73 #define AUDIO 5 74 #define UNKNOWN 6 75 #endif 76 77 /* 78 * known sector types 79 */ 80 #ifndef EDC_MODE_0 81 #define EDC_MODE_0 MODE_0 82 #endif 83 #ifndef EDC_MODE_1 84 #define EDC_MODE_1 MODE_1 85 #endif 86 #ifndef EDC_MODE_2 87 #define EDC_MODE_2 MODE_2 88 #endif 89 #ifndef EDC_MODE_2_FORM_1 90 #define EDC_MODE_2_FORM_1 MODE_2_FORM_1 91 #endif 92 #ifndef EDC_MODE_2_FORM_2 93 #define EDC_MODE_2_FORM_2 MODE_2_FORM_2 94 #endif 95 #ifndef EDC_AUDIO 96 #define EDC_AUDIO AUDIO 97 #endif 98 #ifndef EDC_UNKNOWN 99 #define EDC_UNKNOWN UNKNOWN 100 #endif 101 102 /* 103 * Compute max sector encoding speed 104 */ 105 int 106 encspeed(BOOL be_verbose) 107 { 108 track_t t[1]; 109 Uchar sect[2352]; 110 int i; 111 struct timeval tv; 112 struct timeval tv2; 113 114 t[0].sectype = ST_MODE_1; 115 116 /* 117 * Encoding speed is content dependant. 118 * Set up a known non-null pattern in the sector before; to make 119 * the result of this test independant of the current stack content. 120 */ 121 for (i = 0; i < 2352; ) { 122 sect[i++] = 'J'; 123 sect[i++] = 'S'; 124 } 125 gettimeofday(&tv, (struct timezone *)0); 126 for (i = 0; i < 75000; i++) { /* Goes up to 1000x */ 127 encsectors(t, sect, 12345, 1); 128 gettimeofday(&tv2, (struct timezone *)0); 129 if (tv2.tv_sec >= (tv.tv_sec+1) && 130 tv2.tv_usec >= tv.tv_usec) 131 break; 132 } 133 if (be_verbose) { 134 printf("Encoding speed : %dx (%d sectors/s) for libedc from Heiko Ei�feldt\n", 135 (i+74)/75, i); 136 } 137 return ((i+74)/75); 138 } 139 140 /* 141 * Encode sectors according to trackp->sectype 142 */ 143 void 144 encsectors(track_t *trackp, Uchar *bp, int address, int nsecs) 145 { 146 int sectype = trackp->sectype; 147 148 if ((sectype & ST_MODE_MASK) == ST_MODE_AUDIO) 149 return; 150 151 while (--nsecs >= 0) { 152 encodesector(bp, sectype, address); 153 address++; 154 bp += trackp->secsize; 155 } 156 } 157 158 159 #ifdef CLONE_WRITE 160 161 #define IS_SECHDR(p) ((p)[0] == 0 && \ 162 (p)[1] == 0xFF && (p)[2] == 0xFF && \ 163 (p)[3] == 0xFF && (p)[4] == 0xFF && \ 164 (p)[5] == 0xFF && (p)[6] == 0xFF && \ 165 (p)[7] == 0xFF && (p)[8] == 0xFF && \ 166 (p)[9] == 0xFF && (p)[10] == 0xFF && \ 167 (p)[11] == 0) 168 /* 169 * Scramble data sectors without coding (needed for clone writing) 170 */ 171 void 172 scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs) 173 { 174 /* 175 * In Clone write mode, we cannot expect that the sector type 176 * of a "track" which really is a file holding the whole disk 177 * is flagged with something that makes sense. 178 * 179 * For this reason, we check each sector if it's a data sector 180 * and needs scrambling. 181 */ 182 while (--nsecs >= 0) { 183 if (IS_SECHDR(bp)) 184 scramble_L2(bp); 185 bp += trackp->secsize; 186 } 187 } 188 #else 189 void 190 scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs) 191 { 192 comerrno(EX_BAD, "Cannot write in clone RAW mode.\n"); 193 } 194 #endif 195 196 /* 197 * Encode one sector according to trackp->sectype 198 */ 199 void 200 encodesector(Uchar *sp, int sectype, int address) 201 { 202 if (address < -150) 203 address += 450150; 204 else 205 address += 150; 206 #define _address address 207 208 209 switch (sectype & ST_MODE_MASK) { 210 211 case ST_MODE_0: 212 do_encode_L2(sp, EDC_MODE_0, _address); 213 break; 214 215 case ST_MODE_1: 216 do_encode_L2(sp, EDC_MODE_1, _address); 217 break; 218 219 case ST_MODE_2: 220 do_encode_L2(sp, EDC_MODE_2, _address); 221 break; 222 223 case ST_MODE_2_FORM_1: 224 sp[16+2] &= ~0x20; /* Form 1 sector */ 225 sp[16+4+2] &= ~0x20; /* Form 1 sector 2nd copy */ 226 /* FALLTHROUGH */ 227 228 case ST_MODE_2_MIXED: 229 do_encode_L2(sp, EDC_MODE_2_FORM_1, _address); 230 break; 231 232 case ST_MODE_2_FORM_2: 233 sp[16+2] |= 0x20; /* Form 2 sector */ 234 sp[16+4+2] |= 0x20; /* Form 2 sector 2nd copy */ 235 236 do_encode_L2(sp, EDC_MODE_2_FORM_2, _address); 237 break; 238 239 case ST_MODE_AUDIO: 240 return; 241 default: 242 fill2352(sp, '\0'); 243 return; 244 } 245 if ((sectype & ST_NOSCRAMBLE) == 0) { 246 scramble_L2(sp); 247 #ifndef EDC_SCRAMBLE_NOSWAP 248 swabbytes(sp, 2352); 249 #endif 250 } 251 } 252 253 /* 254 * Create one zero filles encoded sector (according to trackp->sectype) 255 */ 256 void 257 fillsector(Uchar *sp, int sectype, int address) 258 { 259 fill2352(sp, '\0'); 260 encodesector(sp, sectype, address); 261 } 262 263 #endif /* HAVE_LIB_EDC_ECC */ 264