fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/drivers/psi/psi.c *
7 * Created: 2010-08-13 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2010-2025 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26
27#include "psi.h"
28
29
30psi_sct_t *psi_sct_new (unsigned c, unsigned h, unsigned s, unsigned n)
31{
32 psi_sct_t *sct;
33
34 sct = malloc (sizeof (psi_sct_t));
35
36 if (sct == NULL) {
37 return (NULL);
38 }
39
40 sct->next = NULL;
41
42 sct->c = c;
43 sct->h = h;
44 sct->s = s;
45 sct->n = n;
46
47 sct->flags = 0;
48
49 sct->encoding = PSI_ENC_MFM;
50
51 sct->cur_alt = 0;
52
53 if (n > 0) {
54 sct->data = malloc (n);
55
56 if (sct->data == NULL) {
57 free (sct);
58 return (NULL);
59 }
60 }
61 else {
62 sct->data = NULL;
63 }
64
65 sct->weak = NULL;
66
67 sct->tag_cnt = 0;
68
69 sct->position = -1;
70 sct->read_time = 0;
71
72 sct->have_mfm_size = 0;
73 sct->have_gcr_format = 0;
74
75 return (sct);
76}
77
78void psi_sct_del (psi_sct_t *sct)
79{
80 psi_sct_t *tmp;
81
82 while (sct != NULL) {
83 tmp = sct;
84 sct = sct->next;
85
86 free (tmp->weak);
87 free (tmp->data);
88 free (tmp);
89 }
90}
91
92psi_sct_t *psi_sct_clone (const psi_sct_t *sct, int deep)
93{
94 psi_sct_t *dst, *tmp;
95
96 dst = psi_sct_new (sct->c, sct->h, sct->s, sct->n);
97
98 if (dst == NULL) {
99 return (NULL);
100 }
101
102 dst->flags = sct->flags;
103 dst->encoding = sct->encoding;
104
105 memcpy (dst->data, sct->data, dst->n);
106
107 if (sct->weak != NULL) {
108 if ((dst->weak = malloc (dst->n)) == NULL) {
109 psi_sct_del (dst);
110 return (NULL);
111 }
112
113 memcpy (dst->weak, sct->weak, dst->n);
114 }
115
116 dst->tag_cnt = sct->tag_cnt;
117
118 if (sct->tag_cnt > 0) {
119 memcpy (dst->tag, sct->tag, sct->tag_cnt);
120 }
121
122 dst->position = sct->position;
123 dst->read_time = sct->read_time;
124
125 if (sct->have_mfm_size) {
126 dst->have_mfm_size = 1;
127 dst->mfm_size = sct->mfm_size;
128 }
129
130 if (sct->have_gcr_format) {
131 dst->have_gcr_format = 1;
132 dst->gcr_format = sct->gcr_format;
133 }
134
135 if (deep == 0) {
136 dst->cur_alt = 0;
137 }
138 else {
139 dst->cur_alt = sct->cur_alt;
140
141 tmp = dst;
142 sct = sct->next;
143
144 while (sct != NULL) {
145 tmp->next = psi_sct_clone (sct, 0);
146
147 if (tmp->next == NULL) {
148 psi_sct_del (dst);
149 return (NULL);
150 }
151
152 sct = sct->next;
153 }
154 }
155
156 return (dst);
157}
158
159/* allocate the weak bit mask */
160int psi_weak_alloc (psi_sct_t *sct)
161{
162 if (sct->weak != NULL) {
163 return (0);
164 }
165
166 if ((sct->weak = malloc (sct->n)) == NULL) {
167 return (1);
168 }
169
170 memset (sct->weak, 0, sct->n);
171
172 return (0);
173}
174
175/* free the weak bit mask */
176void psi_weak_free (psi_sct_t *sct)
177{
178 if (sct->weak != NULL) {
179 free (sct->weak);
180 sct->weak = NULL;
181 }
182}
183
184/* check if there are any non-zero bits in the weak bit mask */
185int psi_weak_check (const psi_sct_t *sct)
186{
187 unsigned i;
188
189 if (sct->weak == NULL) {
190 return (0);
191 }
192
193 for (i = 0; i < sct->n; i++) {
194 if (sct->weak[i] != 0) {
195 return (1);
196 }
197 }
198
199 return (0);
200}
201
202/* clean up the weak bit mask */
203void psi_weak_clean (psi_sct_t *sct)
204{
205 if (sct->weak == NULL) {
206 return;
207 }
208
209 if (psi_weak_check (sct)) {
210 return;
211 }
212
213 free (sct->weak);
214 sct->weak = NULL;
215}
216
217void psi_sct_add_alternate (psi_sct_t *sct, psi_sct_t *alt)
218{
219 while (sct->next != NULL) {
220 sct = sct->next;
221 }
222
223 sct->next = alt;
224}
225
226psi_sct_t *psi_sct_get_alternate (psi_sct_t *sct, unsigned idx)
227{
228 while (idx > 0) {
229 if (sct == NULL) {
230 return (NULL);
231 }
232
233 sct = sct->next;
234 idx -= 1;
235 }
236
237 return (sct);
238}
239
240int psi_sct_set_size (psi_sct_t *sct, unsigned size, unsigned filler)
241{
242 unsigned char *data, *weak;
243
244 if (size <= sct->n) {
245 sct->n = size;
246 return (0);
247 }
248
249 if ((data = realloc (sct->data, size)) == NULL) {
250 return (1);
251 }
252
253 sct->data = data;
254
255 if (sct->weak != NULL) {
256 if ((weak = realloc (sct->weak, size)) == NULL) {
257 return (1);
258 }
259
260 sct->weak = weak;
261 }
262
263 if (size > sct->n) {
264 memset (sct->data + sct->n, filler, size - sct->n);
265
266 if (sct->weak != NULL) {
267 memset (sct->weak + sct->n, 0, size - sct->n);
268 }
269 }
270
271 sct->n = size;
272
273 return (0);
274}
275
276unsigned psi_sct_get_size (const psi_sct_t *sct)
277{
278 return (sct->n);
279}
280
281void psi_sct_fill (psi_sct_t *sct, unsigned val)
282{
283 unsigned i;
284
285 for (i = 0; i < sct->n; i++) {
286 sct->data[i] = val;
287 }
288}
289
290int psi_sct_uniform (const psi_sct_t *sct)
291{
292 unsigned i;
293
294 for (i = 1; i < sct->n; i++) {
295 if (sct->data[0] != sct->data[i]) {
296 return (0);
297 }
298 }
299
300 return (1);
301}
302
303void psi_sct_set_flags (psi_sct_t *sct, unsigned long flags, int set)
304{
305 if (set) {
306 sct->flags |= flags;
307 }
308 else {
309 sct->flags &= ~flags;
310 }
311}
312
313void psi_sct_set_encoding (psi_sct_t *sct, unsigned enc)
314{
315 while (sct != NULL) {
316 sct->encoding = enc;
317 sct = sct->next;
318 }
319}
320
321int psi_sct_have_position (const psi_sct_t *sct)
322{
323 return (sct->position != (unsigned long) -1);
324}
325
326void psi_sct_clear_position (psi_sct_t *sct)
327{
328 sct->position = (unsigned long) -1;
329}
330
331void psi_sct_set_position (psi_sct_t *sct, unsigned long val)
332{
333 sct->position = val;
334}
335
336unsigned long psi_sct_get_position (const psi_sct_t *sct)
337{
338 return (sct->position);
339}
340
341void psi_sct_set_read_time (psi_sct_t *sct, unsigned long val)
342{
343 sct->read_time = val;
344}
345
346unsigned long psi_sct_get_read_time (const psi_sct_t *sct)
347{
348 return (sct->read_time);
349}
350
351void psi_sct_set_mfm_size (psi_sct_t *sct, unsigned char val)
352{
353 sct->have_mfm_size = 1;
354 sct->mfm_size = val;
355}
356
357unsigned psi_sct_get_mfm_size (const psi_sct_t *sct)
358{
359 unsigned n;
360
361 if (sct->have_mfm_size) {
362 return (sct->mfm_size);
363 }
364
365 n = 0;
366
367 while ((128 << n) < sct->n) {
368 n += 1;
369 }
370
371 return (n);
372}
373
374void psi_sct_set_gcr_format (psi_sct_t *sct, unsigned char val)
375{
376 sct->have_gcr_format = (val < 64);
377 sct->gcr_format = val;
378}
379
380unsigned psi_sct_get_gcr_format (const psi_sct_t *sct)
381{
382 if (sct->have_gcr_format) {
383 return (sct->gcr_format);
384 }
385
386 return (0xff);
387}
388
389unsigned psi_sct_set_tags (psi_sct_t *sct, const void *buf, unsigned cnt)
390{
391 unsigned i;
392 const unsigned char *src;
393
394 if ((src = buf) == NULL) {
395 cnt = 0;
396 }
397
398 if (cnt > PSI_TAGS_MAX) {
399 cnt = PSI_TAGS_MAX;
400 }
401
402 sct->tag_cnt = cnt;
403
404 for (i = 0; i < cnt; i++) {
405 sct->tag[i] = src[i];
406 }
407
408 return (cnt);
409}
410
411unsigned psi_sct_get_tags (const psi_sct_t *sct, void *buf, unsigned cnt)
412{
413 unsigned i, n;
414 unsigned char *dst;
415
416 dst = buf;
417
418 n = (cnt < sct->tag_cnt) ? cnt : sct->tag_cnt;
419
420 for (i = 0; i < n; i++) {
421 dst[i] = sct->tag[i];
422 }
423
424 for (i = n; i < cnt; i++) {
425 dst[i] = 0;
426 }
427
428 return (n);
429}
430
431
432psi_trk_t *psi_trk_new (unsigned h)
433{
434 psi_trk_t *trk;
435
436 trk = malloc (sizeof (psi_trk_t));
437
438 if (trk == NULL) {
439 return (NULL);
440 }
441
442 trk->h = h;
443 trk->sct_cnt = 0;
444 trk->sct = NULL;
445
446 return (trk);
447}
448
449void psi_trk_free (psi_trk_t *trk)
450{
451 unsigned i;
452
453 for (i = 0; i < trk->sct_cnt; i++) {
454 psi_sct_del (trk->sct[i]);
455 }
456
457 free (trk->sct);
458
459 trk->sct_cnt = 0;
460 trk->sct = NULL;
461}
462
463void psi_trk_del (psi_trk_t *trk)
464{
465 if (trk != NULL) {
466 psi_trk_free (trk);
467 free (trk);
468 }
469}
470
471int psi_trk_add_sector (psi_trk_t *trk, psi_sct_t *sct)
472{
473 psi_sct_t **tmp;
474
475 tmp = realloc (trk->sct, (trk->sct_cnt + 1) * sizeof (psi_sct_t *));
476
477 if (tmp == NULL) {
478 return (1);
479 }
480
481 trk->sct = tmp;
482
483 trk->sct[trk->sct_cnt] = sct;
484 trk->sct_cnt += 1;
485
486 return (0);
487}
488
489psi_sct_t *psi_trk_get_indexed_sector (psi_trk_t *trk, unsigned idx, int phy)
490{
491 unsigned i;
492 unsigned min_sct, min_idx, min_cnt;
493
494 if (trk->sct_cnt == 0) {
495 return (NULL);
496 }
497
498 if (phy) {
499 if (idx < trk->sct_cnt) {
500 return (trk->sct[idx]);
501 }
502
503 return (NULL);
504 }
505
506 min_sct = 0;
507
508 while (1) {
509 min_idx = 0;
510 min_cnt = 0;
511
512 for (i = 0; i < trk->sct_cnt; i++) {
513 if (trk->sct[i]->s < min_sct) {
514 ;
515 }
516 else if (min_cnt == 0) {
517 min_idx = i;
518 min_cnt = 1;
519 }
520 else if (trk->sct[i]->s < trk->sct[min_idx]->s) {
521 min_idx = i;
522 min_cnt = 1;
523 }
524 else if (trk->sct[i]->s == trk->sct[min_idx]->s) {
525 min_cnt += 1;
526 }
527 }
528
529 if (min_cnt == 0) {
530 return (NULL);
531 }
532
533 if (idx < min_cnt) {
534 for (i = 0; i < trk->sct_cnt; i++) {
535 if (trk->sct[i]->s == trk->sct[min_idx]->s) {
536 if (idx == 0) {
537 return (trk->sct[i]);
538 }
539
540 idx -= 1;
541 }
542 }
543 }
544 else {
545 idx -= min_cnt;
546 }
547
548 min_sct = trk->sct[min_idx]->s + 1;
549 }
550
551 return (NULL);
552}
553
554void psi_trk_clear_position (psi_trk_t *trk)
555{
556 unsigned i;
557
558 for (i = 0; i < trk->sct_cnt; i++) {
559 if (trk->sct[i] != NULL) {
560 psi_sct_clear_position (trk->sct[i]);
561 }
562 }
563}
564
565int psi_trk_interleave (psi_trk_t *trk, unsigned il)
566{
567 unsigned i, j, n;
568 psi_sct_t **sct, *tmp;
569
570 n = trk->sct_cnt;
571
572 if (n < 2) {
573 return (0);
574 }
575
576 sct = malloc (n * sizeof (psi_sct_t *));
577
578 if (sct == NULL) {
579 return (1);
580 }
581
582 for (i = 0; i < n; i++) {
583 tmp = trk->sct[i];
584 trk->sct[i] = NULL;
585
586 j = i;
587 while ((j > 0) && (tmp->s < sct[j - 1]->s)) {
588 sct[j] = sct[j - 1];
589 j -= 1;
590 }
591
592 sct[j] = tmp;
593 }
594
595 j = 0;
596
597 for (i = 0; i < n; i++) {
598 while (trk->sct[j] != NULL) {
599 j = (j + 1) % n;
600 }
601
602 trk->sct[j] = sct[i];
603
604 j = (j + il) % n;
605 }
606
607 free (sct);
608
609 return (0);
610}
611
612
613psi_cyl_t *psi_cyl_new (unsigned c)
614{
615 psi_cyl_t *cyl;
616
617 cyl = malloc (sizeof (psi_cyl_t));
618
619 if (cyl == NULL) {
620 return (NULL);
621 }
622
623 cyl->c = c;
624 cyl->trk_cnt = 0;
625 cyl->trk = NULL;
626
627 return (cyl);
628}
629
630void psi_cyl_free (psi_cyl_t *cyl)
631{
632 unsigned i;
633
634 for (i = 0; i < cyl->trk_cnt; i++) {
635 psi_trk_del (cyl->trk[i]);
636 }
637
638 free (cyl->trk);
639
640 cyl->trk_cnt = 0;
641 cyl->trk = 0;
642}
643
644void psi_cyl_del (psi_cyl_t *cyl)
645{
646 if (cyl != NULL) {
647 psi_cyl_free (cyl);
648 free (cyl);
649 }
650}
651
652int psi_cyl_add_track (psi_cyl_t *cyl, psi_trk_t *trk)
653{
654 psi_trk_t **tmp;
655
656 tmp = realloc (cyl->trk, (cyl->trk_cnt + 1) * sizeof (psi_trk_t *));
657
658 if (tmp == NULL) {
659 return (1);
660 }
661
662 cyl->trk = tmp;
663
664 if (trk == NULL) {
665 trk = psi_trk_new (cyl->trk_cnt);
666
667 if (trk == NULL) {
668 return (1);
669 }
670 }
671
672 cyl->trk[cyl->trk_cnt] = trk;
673 cyl->trk_cnt += 1;
674
675 return (0);
676}
677
678psi_trk_t *psi_cyl_get_track (psi_cyl_t *cyl, unsigned h, int alloc)
679{
680 if (h < cyl->trk_cnt) {
681 return (cyl->trk[h]);
682 }
683
684 if (alloc == 0) {
685 return (NULL);
686 }
687
688 while (cyl->trk_cnt <= h) {
689 if (psi_cyl_add_track (cyl, NULL)) {
690 return (NULL);
691 }
692 }
693
694 return (cyl->trk[h]);
695}
696
697void psi_cyl_clear_position (psi_cyl_t *cyl)
698{
699 unsigned i;
700
701 for (i = 0; i < cyl->trk_cnt; i++) {
702 if (cyl->trk[i] != NULL) {
703 psi_trk_clear_position (cyl->trk[i]);
704 }
705 }
706}
707
708
709psi_img_t *psi_img_new (void)
710{
711 psi_img_t *img;
712
713 img = malloc (sizeof (psi_img_t));
714
715 if (img == NULL) {
716 return (NULL);
717 }
718
719 img->cyl_cnt = 0;
720 img->cyl = NULL;
721
722 img->comment_size = 0;
723 img->comment = NULL;
724
725 return (img);
726}
727
728void psi_img_free (psi_img_t *img)
729{
730 unsigned i;
731
732 for (i = 0; i < img->cyl_cnt; i++) {
733 psi_cyl_del (img->cyl[i]);
734 }
735
736 free (img->cyl);
737
738 img->cyl_cnt = 0;
739 img->cyl = NULL;
740
741 free (img->comment);
742}
743
744void psi_img_del (psi_img_t *img)
745{
746 if (img != NULL) {
747 psi_img_free (img);
748 free (img);
749 }
750}
751
752void psi_img_erase (psi_img_t *img)
753{
754 unsigned i;
755
756 for (i = 0; i < img->cyl_cnt; i++) {
757 psi_cyl_del (img->cyl[i]);
758 }
759
760 free (img->cyl);
761
762 img->cyl_cnt = 0;
763 img->cyl = NULL;
764
765 free (img->comment);
766
767 img->comment_size = 0;
768 img->comment = NULL;
769}
770
771int psi_img_add_cylinder (psi_img_t *img, psi_cyl_t *cyl)
772{
773 psi_cyl_t **tmp;
774
775 tmp = realloc (img->cyl, (img->cyl_cnt + 1) * sizeof (psi_cyl_t *));
776
777 if (tmp == NULL) {
778 return (1);
779 }
780
781 img->cyl = tmp;
782
783 if (cyl == NULL) {
784 cyl = psi_cyl_new (img->cyl_cnt);
785
786 if (cyl == NULL) {
787 return (1);
788 }
789 }
790
791 img->cyl[img->cyl_cnt] = cyl;
792 img->cyl_cnt += 1;
793
794 return (0);
795}
796
797int psi_img_add_track (psi_img_t *img, psi_trk_t *trk, unsigned c)
798{
799 psi_cyl_t *cyl;
800
801 cyl = psi_img_get_cylinder (img, c, 1);
802
803 if (cyl == NULL) {
804 return (1);
805 }
806
807 if (psi_cyl_add_track (cyl, trk)) {
808 return (1);
809 }
810
811 return (0);
812}
813
814int psi_img_add_sector (psi_img_t *img, psi_sct_t *sct, unsigned c, unsigned h)
815{
816 psi_trk_t *trk;
817
818 trk = psi_img_get_track (img, c, h, 1);
819
820 if (trk == NULL) {
821 return (1);
822 }
823
824 if (psi_trk_add_sector (trk, sct)) {
825 return (1);
826 }
827
828 return (0);
829}
830
831void psi_img_remove_sector (psi_img_t *img, const psi_sct_t *sct)
832{
833 unsigned c, h, s, d;
834 psi_cyl_t *cyl;
835 psi_trk_t *trk;
836
837 for (c = 0; c < img->cyl_cnt; c++) {
838 cyl = img->cyl[c];
839
840 for (h = 0; h < cyl->trk_cnt; h++) {
841 trk = cyl->trk[h];
842
843 d = 0;
844
845 for (s = 0; s < trk->sct_cnt; s++) {
846 if (trk->sct[s] != sct) {
847 trk->sct[d++] = trk->sct[s];
848 }
849 }
850
851 trk->sct_cnt = d;
852 }
853 }
854}
855
856int psi_img_set_track (psi_img_t *img, psi_trk_t *trk, unsigned c, unsigned h)
857{
858 psi_cyl_t *cyl;
859
860 if ((cyl = psi_img_get_cylinder (img, c, 1)) == NULL) {
861 return (1);
862 }
863
864 while (cyl->trk_cnt <= h) {
865 if (psi_cyl_add_track (cyl, NULL)) {
866 return (1);
867 }
868 }
869
870 if (cyl->trk[h] != NULL) {
871 psi_trk_del (cyl->trk[h]);
872 }
873
874 cyl->trk[h] = trk;
875
876 return (0);
877}
878
879psi_cyl_t *psi_img_get_cylinder (psi_img_t *img, unsigned c, int alloc)
880{
881 if (c < img->cyl_cnt) {
882 return (img->cyl[c]);
883 }
884
885 if (alloc == 0) {
886 return (NULL);
887 }
888
889 while (img->cyl_cnt <= c) {
890 if (psi_img_add_cylinder (img, NULL)) {
891 return (NULL);
892 }
893 }
894
895 return (img->cyl[c]);
896}
897
898psi_trk_t *psi_img_get_track (psi_img_t *img, unsigned c, unsigned h, int alloc)
899{
900 psi_cyl_t *cyl;
901 psi_trk_t *trk;
902
903 cyl = psi_img_get_cylinder (img, c, alloc);
904
905 if (cyl == NULL) {
906 return (NULL);
907 }
908
909 trk = psi_cyl_get_track (cyl, h, alloc);
910
911 if (trk == NULL) {
912 return (NULL);
913 }
914
915 return (trk);
916}
917
918psi_sct_t *psi_img_get_sector (psi_img_t *img, unsigned c, unsigned h, unsigned s, int phy)
919{
920 unsigned i;
921 psi_trk_t *trk;
922
923 trk = psi_img_get_track (img, c, h, 0);
924
925 if (trk == NULL) {
926 return (NULL);
927 }
928
929 if (phy) {
930 if (s < trk->sct_cnt) {
931 return (trk->sct[s]);
932 }
933
934 return (NULL);
935 }
936
937 for (i = 0; i < trk->sct_cnt; i++) {
938 if (trk->sct[i]->s == s) {
939 return (trk->sct[i]);
940 }
941 }
942
943 return (NULL);
944}
945
946int psi_img_map_sector (psi_img_t *img, unsigned long idx, unsigned *pc, unsigned *ph, unsigned *ps)
947{
948 unsigned i, j, k;
949 psi_cyl_t *cyl;
950 psi_trk_t *trk;
951 psi_sct_t *sct;
952
953 for (i = 0; i < img->cyl_cnt; i++) {
954 cyl = img->cyl[i];
955
956 for (j = 0; j < cyl->trk_cnt; j++) {
957 trk = cyl->trk[j];
958
959 if (idx < trk->sct_cnt) {
960 sct = psi_trk_get_indexed_sector (trk, idx, 0);
961
962 if (sct == NULL) {
963 return (1);
964 }
965
966 *pc = i;
967 *ph = j;
968 *ps = 0;
969
970 for (k = 0; k < trk->sct_cnt; k++) {
971 if (trk->sct[k] == sct) {
972 return (0);
973 }
974
975 *ps += 1;
976 }
977
978 return (1);
979 }
980
981 idx -= trk->sct_cnt;
982 }
983 }
984
985 return (1);
986}
987
988int psi_img_add_comment (psi_img_t *img, const unsigned char *buf, unsigned cnt)
989{
990 unsigned char *tmp;
991
992 tmp = realloc (img->comment, img->comment_size + cnt);
993
994 if (tmp == NULL) {
995 return (1);
996 }
997
998 memcpy (tmp + img->comment_size, buf, cnt);
999
1000 img->comment_size += cnt;
1001 img->comment = tmp;
1002
1003 return (0);
1004}
1005
1006int psi_img_set_comment (psi_img_t *img, const unsigned char *buf, unsigned cnt)
1007{
1008 free (img->comment);
1009
1010 img->comment_size = 0;
1011 img->comment = NULL;
1012
1013 if ((buf == NULL) || (cnt == 0)) {
1014 return (0);
1015 }
1016
1017 if (psi_img_add_comment (img, buf, cnt)) {
1018 return (1);
1019 }
1020
1021 return (0);
1022}
1023
1024void psi_img_clean_comment (psi_img_t *img)
1025{
1026 unsigned i, j, n;
1027 unsigned char *p;
1028
1029 i = 0;
1030 j = 0;
1031 n = img->comment_size;
1032 p = img->comment;
1033
1034 while ((i < n) && (p[i] == 0x0a)) {
1035 i += 1;
1036 }
1037
1038 while (i < n) {
1039 if (p[i] == 0x0d) {
1040 p[j++] = 0x0a;
1041
1042 if (((i + 1) < n) && (p[i + 1] == 0x0a)) {
1043 i += 1;
1044 }
1045 }
1046 else if (p[i] == 0) {
1047 p[j++] = 0x0a;
1048 }
1049 else {
1050 p[j++] = p[i];
1051 }
1052
1053 i += 1;
1054 }
1055
1056 while ((j > 0) && (p[j - 1] == 0x0a)) {
1057 j -= 1;
1058 }
1059
1060 img->comment_size = j;
1061
1062 if (j == 0) {
1063 free (img->comment);
1064 img->comment = NULL;
1065 }
1066}
1067
1068void psi_img_clear_position (psi_img_t *img)
1069{
1070 unsigned i;
1071
1072 for (i = 0; i < img->cyl_cnt; i++) {
1073 if (img->cyl[i] != NULL) {
1074 psi_cyl_clear_position (img->cyl[i]);
1075 }
1076 }
1077}
1078
1079
1080unsigned long psi_img_get_sector_count (const psi_img_t *img)
1081{
1082 unsigned long cnt;
1083 unsigned c, h, s;
1084 psi_cyl_t *cyl;
1085 psi_trk_t *trk;
1086 psi_sct_t *sct;
1087
1088 cnt = 0;
1089
1090 for (c = 0; c < img->cyl_cnt; c++) {
1091 cyl = img->cyl[c];
1092
1093 for (h = 0; h < cyl->trk_cnt; h++) {
1094 trk = cyl->trk[h];
1095
1096 for (s = 0; s < trk->sct_cnt; s++) {
1097 sct = trk->sct[s];
1098
1099 while (sct != NULL) {
1100 sct = sct->next;
1101 cnt += 1;
1102 }
1103 }
1104 }
1105 }
1106
1107 return (cnt);
1108}