fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/utils/psi/merge.c *
7 * Created: 2013-06-09 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2013 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 "main.h"
24#include "merge.h"
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29
30#include <drivers/psi/psi.h>
31#include <drivers/psi/psi-img.h>
32
33
34static
35int psi_merge_sectors_equal (const psi_sct_t *s1, const psi_sct_t *s2)
36{
37 if ((s1->c != s2->c) || (s1->h != s2->h) || (s1->s != s2->s)) {
38 return (0);
39 }
40
41 if (s1->n != s2->n) {
42 return (0);
43 }
44
45 if (memcmp (s1->data, s2->data, s1->n) != 0) {
46 return (0);
47 }
48
49 return (1);
50}
51
52static
53int psi_merge_sectors_cb (psi_img_t *img, psi_sct_t *sct,
54 unsigned c, unsigned h, unsigned s, unsigned a, void *opaque)
55{
56 psi_img_t *dimg;
57 psi_sct_t *dsct, *dtmp;
58
59 dimg = opaque;
60
61 dsct = psi_img_get_sector (dimg, c, h, sct->s, 0);
62
63 if (dsct == NULL) {
64 dsct = psi_sct_clone (sct, 1);
65
66 if (dsct == NULL) {
67 return (1);
68 }
69
70 if (psi_img_add_sector (dimg, dsct, c, h)) {
71 psi_sct_del (dsct);
72 return (1);
73 }
74
75 while (dsct != NULL) {
76 par_cnt += 1;
77 dsct = dsct->next;
78 }
79
80 return (0);
81 }
82
83 dtmp = dsct;
84
85 while (dtmp != NULL) {
86 if (psi_merge_sectors_equal (dtmp, sct)) {
87 break;
88 }
89
90 dtmp = dtmp->next;
91 }
92
93 if (dtmp == NULL) {
94 dtmp = psi_sct_clone (sct, 0);
95
96 if (dtmp == NULL) {
97 return (1);
98 }
99
100 psi_sct_add_alternate (dsct, dtmp);
101
102 par_cnt += 1;
103 }
104
105 return (0);
106}
107
108int psi_merge_image (psi_img_t *img, const char *fname)
109{
110 int r;
111 psi_img_t *src;
112
113 src = psi_load (fname, PSI_FORMAT_NONE);
114
115 if (src == NULL) {
116 fprintf (stderr, "%s: loading image failed (%s)\n",
117 arg0, fname
118 );
119 return (1);
120 }
121
122 par_cnt = 0;
123
124 r = psi_for_all_sectors (src, psi_merge_sectors_cb, img);
125
126 psi_img_del (src);
127
128 if (par_verbose) {
129 fprintf (stderr, "%s: merge %lu sectors from %s\n",
130 arg0, par_cnt, fname
131 );
132 }
133
134 if (r) {
135 fprintf (stderr, "%s: merging failed\n", arg0);
136 }
137
138 return (r);
139}