123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646 |
- /*
- dc.c - Dreamcast support for uCON64
- Copyright (c) 2004 NoisyB <noisyb@gmx.net>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include "misc/file.h"
- #include "misc/misc.h"
- #include "misc/property.h"
- #include "misc/string.h"
- #ifdef USE_ZLIB
- #include "misc/archive.h"
- #endif
- #include "misc/getopt2.h" // st_getopt2_t
- #include "ucon64.h"
- #include "ucon64_misc.h"
- #include "dc.h"
- const st_getopt2_t dc_usage[] =
- {
- {
- NULL, 0, 0, 0,
- NULL, "Dreamcast" /* "1998 SEGA http://www.sega.com" */,
- NULL
- },
- {
- "dc", 0, 0, UCON64_DC,
- NULL, "force recognition",
- &ucon64_wf[WF_OBJ_DC_SWITCH]
- },
- #if 0
- {
- "vms", 1, 0, UCON64_VMS,
- "SAV", "convert NES SAV file to a VMS file for use with NesterDC",
- NULL
- },
- #endif
- {
- "scr", 0, 0, UCON64_SCR,
- NULL, "scramble 1ST_READ.BIN for selfboot CDs",
- &ucon64_wf[WF_OBJ_DC_DEFAULT]
- },
- {
- "unscr", 0, 0, UCON64_UNSCR,
- NULL, "unscramble 1ST_READ.BIN for non-selfboot CDs",
- &ucon64_wf[WF_OBJ_DC_DEFAULT]
- },
- #if 0
- {
- "ip", 1, 0, UCON64_IP,
- "FILE", "extract ip.bin FILE from IMAGE; " OPTION_LONG_S "rom=IMAGE",
- NULL
- },
- #endif
- {
- "mkip", 0, 0, UCON64_MKIP,
- NULL, "generate IP.BIN file with default values",
- &ucon64_wf[WF_OBJ_DC_NO_ROM]
- },
- {
- "parse", 1, 0, UCON64_PARSE,
- "TEMPLATE", "parse TEMPLATE file into a IP.BIN;\n"
- "creates an empty template when TEMPLATE does not exist",
- &ucon64_wf[WF_OBJ_DC_NO_ROM]
- },
- {NULL, 0, 0, 0, NULL, NULL, NULL}
- };
- static int
- calc_crc (const unsigned char *buf, int size)
- {
- int i, c, n = 0xffff;
- for (i = 0; i < size; i++)
- {
- n ^= (buf[i] << 8);
- for (c = 0; c < 8; c++)
- if (n & 0x8000)
- n = (n << 1) ^ 4129;
- else
- n = (n << 1);
- }
- return n & 0xffff;
- }
- static void
- update_crc (char *ip)
- {
- int n = calc_crc ((unsigned char *) (ip + 0x40), 16);
- char buf[5];
- sprintf (buf, "%04X", n);
- if (memcmp (buf, ip + 0x20, 4))
- {
- printf ("Setting CRC to %s (was %.4s)\n", buf, ip + 0x20);
- memcpy (ip + 0x20, buf, 4);
- }
- }
- static unsigned int seed;
- static void
- dc_srand (unsigned int n)
- {
- seed = n & 0xffff;
- }
- static unsigned int
- dc_rand ()
- {
- seed = (seed * 2109 + 9273) & 0x7fff;
- return (seed + 0xc000) & 0xffff;
- }
- #if 0
- // header for SAV -> VMS conversion
- static const uint8_t nstrsave_bin[1024] = {
- 0x4e, 0x45, 0x53, 0x52, 0x4f, 0x4d, 0x2e, 0x4e, // 0x8 (8)
- 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 (16)
- 0x4e, 0x65, 0x73, 0x74, 0x65, 0x72, 0x44, 0x43, // 0x18 (24)
- 0x20, 0x53, 0x61, 0x76, 0x65, 0x52, 0x61, 0x6d, // 0x20 (32)
- 0x20, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, // 0x28 (40)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 (48)
- 0x2a, 0x2a, 0x2a, 0x4e, 0x65, 0x73, 0x74, 0x65, // 0x38 (56)
- 0x72, 0x44, 0x43, 0x2a, 0x2a, 0x2a, 0x00, 0x00, // 0x40 (64)
- 0x01, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, // 0x48 (72)
- 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 (80)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 (88)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 (96)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 (104)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 (112)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 (120)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 (128)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 (136)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 (144)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 (152)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 (160)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa8 (168)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 (176)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb8 (184)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 (192)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc8 (200)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 (208)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd8 (216)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 (224)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe8 (232)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0 (240)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf8 (248)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x100 (256)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x108 (264)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x110 (272)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x118 (280)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x120 (288)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x128 (296)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x130 (304)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x138 (312)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x140 (320)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x148 (328)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x150 (336)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x158 (344)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x160 (352)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x168 (360)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x170 (368)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x178 (376)
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x180 (384)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x188 (392)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x190 (400)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x198 (408)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a0 (416)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a8 (424)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b0 (432)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b8 (440)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c0 (448)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c8 (456)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d0 (464)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d8 (472)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e0 (480)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e8 (488)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f0 (496)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f8 (504)
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x200 (512)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x208 (520)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x210 (528)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x218 (536)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x220 (544)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x228 (552)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x230 (560)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x238 (568)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x240 (576)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x248 (584)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x250 (592)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x258 (600)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x260 (608)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x268 (616)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x270 (624)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x278 (632)
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x280 (640)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x288 (648)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x290 (656)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x298 (664)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a0 (672)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a8 (680)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b0 (688)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b8 (696)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c0 (704)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c8 (712)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d0 (720)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d8 (728)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e0 (736)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e8 (744)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f0 (752)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f8 (760)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x300 (768)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x308 (776)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x310 (784)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x318 (792)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x320 (800)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x328 (808)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x330 (816)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x338 (824)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x340 (832)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x348 (840)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x350 (848)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x358 (856)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x360 (864)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x368 (872)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x370 (880)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x378 (888)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x380 (896)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x388 (904)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x390 (912)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x398 (920)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a0 (928)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a8 (936)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b0 (944)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b8 (952)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c0 (960)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c8 (968)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d0 (976)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d8 (984)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e0 (992)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e8 (1000)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f0 (1008)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f8 (1016)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x400 (1024)
- };
- #endif
- int
- dc_init (st_rominfo_t *rominfo)
- {
- int result = -1;
- rominfo->console_usage = dc_usage[0].help;
- return result;
- }
- static int
- check_areasym (char *ptr, int len)
- {
- int i, a = 0;
- for (i = 0; i < len; i++)
- switch (ptr[i])
- {
- case 'J':
- a |= (1<<0);
- break;
- case 'U':
- a |= (1<<1);
- break;
- case 'E':
- a |= (1<<2);
- break;
- case ' ':
- break;
- default:
- fprintf (stderr, "ERROR: Unknown area symbol '%c'\n", ptr[i]);
- return -1;
- }
- for (i = 0; i < len; i++)
- if ((a & (1<<i)) == 0)
- ptr[i] = ' ';
- else
- ptr[i] = "JUE"[i];
- return 0;
- }
- typedef struct
- {
- char *name;
- int pos;
- int len;
- int (*extra_check) (char *, int);
- char *def;
- char *comment;
- } st_templ_t;
- st_templ_t templ[] =
- {
- {"hardware_id", 0x0, 0x10, NULL, "SEGA SEGAKATANA", "Hardware ID (always \"SEGA SEGAKATANA\")"},
- {"maker_id", 0x10, 0x10, NULL, "SEGA ENTERPRISES", "Maker ID (always \"SEGA ENTERPRISES\")"},
- {"device_info", 0x20, 0x10, NULL, "0000 CD-ROM1/1", "Device Information"},
- {"area_symbols", 0x30, 0x8, check_areasym, "JUE", "Area Symbols"},
- {"peripherals", 0x38, 0x8, NULL, "E000F10", "Peripherals"},
- {"product_no", 0x40, 0xa, NULL, "T0000", "Product number (\"HDR-nnnn\" etc.)"},
- {"version", 0x4a, 0x6, NULL, "V1.000", "Product version"},
- {"release_date", 0x50, 0x10, NULL, "20000627", "Release date (YYYYMMDD)"},
- {"boot_filename", 0x60, 0x10, NULL, "1ST_READ.BIN", "Boot filename (usually \"1ST_READ.BIN\")"},
- {"sw_maker_name", 0x70, 0x10, NULL, "YOUR NAME HERE", "Name of the company that produced the disc"},
- {"game_title", 0x80, 0x80, NULL, "TITLE OF THE SOFTWARE", "Name of the software"},
- {NULL, 0, 0, NULL, NULL, NULL}
- };
- static int
- parse_templ (const char *templ_file, char *ip)
- {
- int filled_in[MAXBUFSIZE];
- static char buf[MAXBUFSIZE];
- int i;
- memset (filled_in, 0, sizeof (filled_in));
- for (i = 0; templ[i].name; i++)
- {
- char *p = buf;
- get_property (templ_file, templ[i].name, p, templ[i].def);
- strtriml (strtrimr (p));
- if (!(*p))
- continue;
- memset (ip + templ[i].pos, ' ', templ[i].len);
- if ((int) strlen (p) > templ[i].len)
- {
- fprintf (stderr, "ERROR: Data for field \"%s\" is too long... stripping to %d chars\n",
- templ[i].name, templ[i].len);
- p[templ[i].len] = 0;
- }
- memcpy (ip + templ[i].pos, p, strlen (p));
- if (templ[i].extra_check)
- if (templ[i].extra_check (ip + templ[i].pos, templ[i].len) == -1)
- return -1;
- filled_in[i] = 1;
- }
- for (i = 0; templ[i].name; i++)
- if (!filled_in[i])
- {
- fprintf (stderr, "ERROR: Missing value for \"%s\"\n", templ[i].name);
- return -1;
- }
- return 0;
- }
- int
- dc_parse (const char *templ_file)
- {
- char ip[0x8000], dest_name[FILENAME_MAX];
- if (access (templ_file, F_OK) == -1)
- {
- int i = 0;
- printf ("Creating empty template file: \"%s\"\n", templ_file);
- for (i = 0; templ[i].name; i++)
- set_property (templ_file, templ[i].name, templ[i].def, templ[i].comment);
- printf (ucon64_msg[WROTE], templ_file);
- }
- if (parse_templ (templ_file, ip) == -1)
- return -1;
- update_crc (ip);
- strcpy (dest_name, "ip.bin");
- ucon64_file_handler (dest_name, NULL, 0);
- ucon64_fwrite (ip, 0, 0x8000, dest_name, "wb");
- printf (ucon64_msg[WROTE], dest_name);
- return 0;
- }
- int
- dc_mkip (void)
- {
- dc_parse ("default");
- return 0;
- }
- static int
- load_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
- {
- #define MAXCHUNK (2048*1024)
- static int idx[MAXCHUNK / 32];
- int32_t i;
- /* Convert chunk size to number of slices */
- sz /= 32;
- /* Initialize index table with unity,
- so that each slice gets loaded exactly once */
- for (i = 0; i < sz; i++)
- idx[i] = i;
- for (i = sz - 1; i >= 0; --i)
- {
- /* Select a replacement index */
- int x = (dc_rand () * i) >> 16;
- /* Swap */
- int tmp = idx[i];
- idx[i] = idx[x];
- idx[x] = tmp;
- /* Load resulting slice */
- if (fread (ptr + 32 * idx[i], 1, 32, fh) != 32)
- return -1;
- }
- return 0;
- }
- static int
- load_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
- {
- uint32_t chunksz;
- dc_srand (filesz);
- /* Descramble 2 meg blocks for as long as possible, then
- gradually reduce the window down to 32 bytes (1 slice) */
- for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
- while (filesz >= chunksz)
- {
- load_chunk (fh, ptr, chunksz);
- filesz -= chunksz;
- ptr += chunksz;
- }
- /* Load final incomplete slice */
- if (filesz)
- if (fread (ptr, 1, filesz, fh) != filesz)
- return -1;
- return 0;
- }
- static int
- save_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
- {
- static int idx[MAXCHUNK / 32];
- int32_t i;
- /* Convert chunk size to number of slices */
- sz /= 32;
- /* Initialize index table with unity,
- so that each slice gets saved exactly once */
- for (i = 0; i < sz; i++)
- idx[i] = i;
- for (i = sz - 1; i >= 0; --i)
- {
- /* Select a replacement index */
- int x = (dc_rand () * i) >> 16;
- /* Swap */
- int tmp = idx[i];
- idx[i] = idx[x];
- idx[x] = tmp;
- /* Save resulting slice */
- if (fwrite (ptr + 32 * idx[i], 1, 32, fh) != 32)
- return -1;
- }
- return 0;
- }
- static int
- save_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
- {
- uint32_t chunksz;
- dc_srand (filesz);
- /* Descramble 2 meg blocks for as long as possible, then
- gradually reduce the window down to 32 bytes (1 slice) */
- for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
- while (filesz >= chunksz)
- {
- save_chunk (fh, ptr, chunksz);
- filesz -= chunksz;
- ptr += chunksz;
- }
- /* Save final incomplete slice */
- if (filesz)
- if (fwrite (ptr, 1, filesz, fh) != filesz)
- return -1;
- return 0;
- }
- static int
- descramble (const char *src, char *dst)
- {
- unsigned char *ptr = NULL;
- uint32_t sz = 0;
- FILE *fh;
- if (!(fh = fopen (src, "rb")))
- return -1;
- sz = fsizeof (src);
- if (!(ptr = (unsigned char *) malloc (sz)))
- return -1;
- load_file (fh, ptr, sz);
- fclose (fh);
- if (!(fh = fopen (dst, "wb")))
- return -1;
- if (fwrite (ptr, 1, sz, fh) != sz)
- return -1;
- fclose (fh);
- free (ptr);
- return 0;
- }
- static int
- scramble (const char *src, char *dst)
- {
- unsigned char *ptr = NULL;
- uint32_t sz = 0;
- FILE *fh;
- if (!(fh = fopen (src, "rb")))
- return -1;
- sz = fsizeof (src);
- if (!(ptr = (unsigned char *) malloc (sz)))
- return -1;
- if (fread (ptr, 1, sz, fh) != sz)
- return -1;
- fclose (fh);
- if (!(fh == fopen (dst, "wb")))
- return -1;
- save_file (fh, ptr, sz);
- fclose (fh);
- free (ptr);
- return 0;
- }
- int
- dc_scramble (void)
- {
- char dest_name[FILENAME_MAX];
- strcpy (dest_name, ucon64.rom);
- ucon64_file_handler (dest_name, NULL, 0);
- if (!scramble (ucon64.rom, dest_name))
- printf (ucon64_msg[WROTE], dest_name);
- else
- fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
- return 0;
- }
- int
- dc_unscramble (void)
- {
- char dest_name[FILENAME_MAX];
- strcpy (dest_name, ucon64.rom);
- ucon64_file_handler (dest_name, NULL, 0);
- if (!descramble (ucon64.rom, dest_name))
- printf (ucon64_msg[WROTE], dest_name);
- else
- fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
- return 0;
- }
|