OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [SDGenerator.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
package ao486;
28
 
29
import java.io.File;
30
import java.io.FileInputStream;
31
import java.io.RandomAccessFile;
32
import java.nio.ByteBuffer;
33
import java.nio.ByteOrder;
34
import java.nio.file.Files;
35
import java.util.Arrays;
36
import java.util.HashMap;
37
import java.util.LinkedList;
38
import java.util.Properties;
39
 
40
public class SDGenerator {
41
 
42
    static byte[] crc32(byte bytes[]) {
43
        int crc[] = new int[32];
44
 
45
        for(int i=0; i<32; i++) crc[i] = 1;
46
 
47
        for(byte b : bytes) {
48
            int in[] = new int[8];
49
            for(int j=0; j<8; j++) in[j] = (b >> j) & 1;
50
 
51
            int new_crc[] = new int[32];
52
 
53
            new_crc[31] = in[2] ^ crc[23] ^ crc[29];
54
            new_crc[30] = in[0] ^ in[3] ^ crc[22] ^ crc[28] ^ crc[31];
55
            new_crc[29] = in[0] ^ in[1] ^ in[4] ^ crc[21] ^ crc[27] ^ crc[30] ^ crc[31];
56
            new_crc[28] = in[1] ^ in[2] ^ in[5] ^ crc[20] ^ crc[26] ^ crc[29] ^ crc[30];
57
            new_crc[27] = in[0] ^ in[2] ^ in[3] ^ in[6] ^ crc[19] ^ crc[25] ^ crc[28] ^ crc[29] ^ crc[31];
58
            new_crc[26] = in[1] ^ in[3] ^ in[4] ^ in[7] ^ crc[18] ^ crc[24] ^ crc[27] ^ crc[28] ^ crc[30];
59
            new_crc[25] = in[4] ^ in[5] ^ crc[17] ^ crc[26] ^ crc[27];
60
            new_crc[24] = in[0] ^ in[5] ^ in[6] ^ crc[16] ^ crc[25] ^ crc[26] ^ crc[31];
61
            new_crc[23] = in[1] ^ in[6] ^ in[7] ^ crc[15] ^ crc[24] ^ crc[25] ^ crc[30];
62
            new_crc[22] = in[7] ^ crc[14] ^ crc[24];
63
            new_crc[21] = in[2] ^ crc[13] ^ crc[29];
64
            new_crc[20] = in[3] ^ crc[12] ^ crc[28];
65
            new_crc[19] = in[0] ^ in[4] ^ crc[11] ^ crc[27] ^ crc[31];
66
            new_crc[18] = in[0] ^ in[1] ^ in[5] ^ crc[10] ^ crc[26] ^ crc[30] ^ crc[31];
67
            new_crc[17] = in[1] ^ in[2] ^ in[6] ^ crc[9] ^ crc[25] ^ crc[29] ^ crc[30];
68
            new_crc[16] = in[2] ^ in[3] ^ in[7] ^ crc[8] ^ crc[24] ^ crc[28] ^ crc[29];
69
            new_crc[15] = in[0] ^ in[2] ^ in[3] ^ in[4] ^ crc[7] ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[31];
70
            new_crc[14] = in[0] ^ in[1] ^ in[3] ^ in[4] ^ in[5] ^ crc[6] ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30] ^ crc[31];
71
            new_crc[13] = in[0] ^ in[1] ^ in[2] ^ in[4] ^ in[5] ^ in[6] ^ crc[5] ^ crc[25] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[30] ^ crc[31];
72
            new_crc[12] = in[1] ^ in[2] ^ in[3] ^ in[5] ^ in[6] ^ in[7] ^ crc[4] ^ crc[24] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30];
73
            new_crc[11] = in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[3] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28];
74
            new_crc[10] = in[2] ^ in[4] ^ in[5] ^ in[7] ^ crc[2] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[29];
75
            new_crc[9] = in[2] ^ in[3] ^ in[5] ^ in[6] ^ crc[1] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29];
76
            new_crc[8] = in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[0] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28];
77
            new_crc[7] = in[0] ^ in[2] ^ in[4] ^ in[5] ^ in[7] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[31];
78
            new_crc[6] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[5] ^ in[6] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31];
79
            new_crc[5] = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31];
80
            new_crc[4] = in[1] ^ in[3] ^ in[4] ^ in[5] ^ in[7] ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30];
81
            new_crc[3] = in[0] ^ in[4] ^ in[5] ^ in[6] ^ crc[25] ^ crc[26] ^ crc[27] ^ crc[31];
82
            new_crc[2] = in[0] ^ in[1] ^ in[5] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[26] ^ crc[30] ^ crc[31];
83
            new_crc[1] = in[0] ^ in[1] ^ in[6] ^ in[7] ^ crc[24] ^ crc[25] ^ crc[30] ^ crc[31];
84
            new_crc[0] = in[1] ^ in[7] ^ crc[24] ^ crc[30];
85
 
86
            System.arraycopy(new_crc, 0, crc, 0, 32);
87
        }
88
 
89
        long output = 0;
90
        for(int i=0; i<32; i++) {
91
            output |= crc[i] << (31-i);
92
        }
93
        output = ~output;
94
 
95
        byte out[] = new byte[4];
96
        for(int i=0; i<4; i++) out[i] = (byte)((output >> (i*8)) & 0xFF);
97
        return out;
98
    }
99
 
100
    final static byte TYPE_BIOS     = 1;
101
    final static byte TYPE_VGABIOS  = 2;
102
    final static byte TYPE_HDD      = 3;
103
    final static byte TYPE_FD_1_44M = 16;
104
    final static byte TYPE_CRC32    = 127;
105
 
106
    final static int HEADER_MAX_ENTRIES = 128;
107
 
108
    static void append_name(String name, ByteBuffer buf) throws Exception {
109
        byte name_bytes[] = name.getBytes();
110
        buf.put(name_bytes, 0, (name_bytes.length > 14)? 14 : name_bytes.length);
111
        for(int i=name_bytes.length; i<14; i++) buf.put((byte)0);
112
        buf.put((byte)0);
113
    }
114
 
115
    public static void main(String args[]) throws Exception {
116
 
117
        File sd_root = new File("../sd");
118
 
119
        //scan for bios
120
        String bios_files[] = new File(sd_root, "bios").list();
121
        Arrays.sort(bios_files);
122
 
123
        //scan for vgabios files
124
        String vgabios_files[] = new File(sd_root, "vgabios").list();
125
        Arrays.sort(vgabios_files);
126
 
127
        //1_44m floppies
128
        String fd_1_44m_files[] = new File(sd_root, "fd_1_44m").list();
129
        Arrays.sort(fd_1_44m_files);
130
 
131
        //hdd
132
        String hdd_files[] = new File(sd_root, "hdd").list();
133
        Arrays.sort(hdd_files);
134
 
135
        //header
136
        ByteBuffer buf = ByteBuffer.allocate(32 * (HEADER_MAX_ENTRIES - 1));
137
        buf.order(ByteOrder.LITTLE_ENDIAN);
138
 
139
        int first_free_sector = 32 * HEADER_MAX_ENTRIES;
140
        if((first_free_sector % 512) != 0) throw new Exception("Header not % 512 !");
141
        first_free_sector /= 512;
142
 
143
        HashMap<Integer, Object> files = new HashMap<>();
144
        LinkedList<Integer> used_sectors = new LinkedList<>();
145
 
146
        //process bios files
147
        for(String name : bios_files) {
148
            File file = new File(sd_root, "bios/" + name);
149
            byte file_bytes[] = Files.readAllBytes(file.toPath());
150
 
151
            buf.put(TYPE_BIOS);
152
            append_name(name, buf);
153
            buf.putInt(first_free_sector);
154
            buf.putInt((int)file.length());
155
            buf.putInt(0xF0000);
156
            buf.put(crc32(file_bytes));
157
 
158
            files.put(first_free_sector, file_bytes);
159
            first_free_sector += (file_bytes.length + 511)/512;
160
        }
161
 
162
        //process vgabios files
163
        for(String name : vgabios_files) {
164
            File file = new File(sd_root, "vgabios/" + name);
165
            byte file_bytes[] = Files.readAllBytes(file.toPath());
166
 
167
            buf.put(TYPE_VGABIOS);
168
            append_name(name, buf);
169
            buf.putInt(first_free_sector);
170
            buf.putInt((int)file.length());
171
            buf.putInt(0xC0000);
172
            buf.put(crc32(file_bytes));
173
 
174
            files.put(first_free_sector, file_bytes);
175
            first_free_sector += (file_bytes.length + 511)/512;
176
        }
177
 
178
        //process hdd files
179
        for(String name : hdd_files) {
180
            File file = new File(sd_root, "hdd/" + name);
181
            Properties props = new Properties();
182
            props.load(new FileInputStream(file));
183
 
184
            int start     = Integer.parseInt(props.getProperty("start"));
185
            if((start % 512) != 0) throw new Exception("Invalid start property in file: " + file.getCanonicalPath());
186
 
187
            int cylinders = Integer.parseInt(props.getProperty("cylinders"));
188
            int heads     = Integer.parseInt(props.getProperty("heads"));
189
            int spt       = Integer.parseInt(props.getProperty("spt"));
190
 
191
            int size      = Integer.parseInt(props.getProperty("size"));
192
 
193
            if(cylinders * heads * spt * 512 != size) throw new Exception("Invalid parameters in hdd file: " + file.getCanonicalPath());
194
 
195
            buf.put(TYPE_HDD);
196
            append_name(name.substring(0, name.indexOf(".")), buf);
197
            buf.putInt(start/512);
198
            buf.putInt(cylinders);
199
            buf.putInt(heads);
200
            buf.putInt(spt);
201
 
202
            used_sectors.add(start/512);
203
            used_sectors.add(start/512 + size/512 - 1);
204
        }
205
 
206
        //process fd_1_44m files
207
        for(String name : fd_1_44m_files) {
208
            File file = new File(sd_root, "fd_1_44m/" + name);
209
            byte file_bytes[] = Files.readAllBytes(file.toPath());
210
 
211
            buf.put(TYPE_FD_1_44M);
212
            append_name(name, buf);
213
            buf.putInt(first_free_sector);
214
            buf.putInt(0);
215
            buf.putInt(0);
216
            buf.putInt(0);
217
 
218
            files.put(first_free_sector, file_bytes);
219
            first_free_sector += (file_bytes.length + 511)/512;
220
        }
221
 
222
        //verify that sectors do not overlap
223
        for(int i=0; i<used_sectors.size(); i+=2) {
224
            int start = used_sectors.get(i+0);
225
            int end   = used_sectors.get(i+1);
226
 
227
            if(first_free_sector >= start) throw new Exception("first_free_sector overlaps used_sectors: " + i);
228
 
229
            for(int j=i+2; j<used_sectors.size(); j+=2) {
230
                int cmp_start = used_sectors.get(j+0);
231
                int cmp_end   = used_sectors.get(j+1);
232
 
233
                if(cmp_end >= start && cmp_end <= end)      throw new Exception("cmp_end overlaps: " + i + ", " + j);
234
                if(cmp_start >= start && cmp_start <= end)  throw new Exception("cmp_start overlaps: " + i + ", " + j);
235
                if(cmp_start < start && cmp_end > end)      throw new Exception("cmp overlaps: " + i + ", " + j);
236
            }
237
        }
238
 
239
        //prepare header for output file
240
        byte header_start[] = new byte[buf.position()];
241
        if((header_start.length % 32) != 0) throw new Exception("Invalid header_start - not %32");
242
        buf.flip();
243
        buf.get(header_start);
244
 
245
        //crc32 entry
246
        buf = ByteBuffer.allocate(32);
247
        buf.put(TYPE_CRC32);
248
        for(int i=0; i<15; i++) buf.put((byte)0);
249
        buf.put(crc32(header_start));
250
 
251
        byte header_end[] = new byte[buf.position()];
252
        buf.flip();
253
        buf.get(header_end);
254
 
255
        //output
256
        File sd_dat = new File("sd.dat");
257
        if(sd_dat.exists()) {
258
            if(sd_dat.delete() == false) throw new Exception("Can not delete file: " + sd_dat.getCanonicalPath());
259
        }
260
 
261
        RandomAccessFile raf = new RandomAccessFile(sd_dat, "rws");
262
        raf.seek(0);
263
        raf.write(header_start);
264
        raf.write(header_end);
265
 
266
        for(int pos : files.keySet()) {
267
            byte bytes[] = (byte [])files.get(pos);
268
 
269
            raf.seek(pos*512);
270
            raf.write(bytes);
271
        }
272
        raf.close();
273
    }
274
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.