[Fuse-for-macosx-commits] SF.net SVN: fuse-for-macosx:[639] trunk
Brought to you by:
fredm
From: <fr...@us...> - 2010-05-24 14:23:46
|
Revision: 639 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=639&view=rev Author: fredm Date: 2010-05-24 14:23:37 +0000 (Mon, 24 May 2010) Log Message: ----------- Merge up to vendor revision 4135. Revision Links: -------------- http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=4135&view=rev Modified Paths: -------------- trunk/FuseGenerator/generate.pl trunk/FuseImporter/generate.pl trunk/fuse/ChangeLog trunk/fuse/Makefile.am trunk/fuse/README trunk/fuse/compat/unix/file.c trunk/fuse/compat/wii/paths.c trunk/fuse/compat.h trunk/fuse/configure.in trunk/fuse/debugger/command.c trunk/fuse/debugger/commandl.l trunk/fuse/debugger/debugger_internals.h trunk/fuse/debugger/disassemble.c trunk/fuse/disk/beta.c trunk/fuse/disk/beta.h trunk/fuse/disk/disk.c trunk/fuse/disk/disk.h trunk/fuse/disk/fdd.c trunk/fuse/disk/fdd.h trunk/fuse/disk/opus.c trunk/fuse/disk/plusd.c trunk/fuse/disk/upd_fdc.c trunk/fuse/disk/upd_fdc.h trunk/fuse/display.c trunk/fuse/fuse.c trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj trunk/fuse/fusepb/generate.pl trunk/fuse/fusepb/libspectrum.h trunk/fuse/hacking/ChangeLog trunk/fuse/ide/divide.c trunk/fuse/ide/zxatasp.c trunk/fuse/ide/zxcf.c trunk/fuse/if1.c trunk/fuse/if2.c trunk/fuse/input.c trunk/fuse/input.h trunk/fuse/keyboard.c trunk/fuse/keysyms.dat trunk/fuse/keysyms.pl trunk/fuse/machines/pentagon.c trunk/fuse/machines/pentagon1024.c trunk/fuse/machines/pentagon512.c trunk/fuse/machines/scorpion.c trunk/fuse/machines/specplus3.c trunk/fuse/machines/specplus3.h trunk/fuse/man/fuse.1 trunk/fuse/memory.c trunk/fuse/memory.h trunk/fuse/menu.c trunk/fuse/menu.h trunk/fuse/menu_data.dat trunk/fuse/periph.c trunk/fuse/printer.c trunk/fuse/rzx.c trunk/fuse/settings-header.pl trunk/fuse/settings.dat trunk/fuse/settings.pl trunk/fuse/sound/Makefile.am trunk/fuse/sound/coreaudiosound.c trunk/fuse/tape.c trunk/fuse/ui/fb/fbkeyboard.c trunk/fuse/ui/fb/fbui.c trunk/fuse/ui/gtk/gtkkeyboard.c trunk/fuse/ui/gtk/gtkui.c trunk/fuse/ui/gtk/picture.c trunk/fuse/ui/options.dat trunk/fuse/ui/sdl/sdldisplay.c trunk/fuse/ui/sdl/sdlkeyboard.c trunk/fuse/ui/sdl/sdlui.c trunk/fuse/ui/svga/svgadisplay.c trunk/fuse/ui/svga/svgakeyboard.c trunk/fuse/ui/svga/svgaui.c trunk/fuse/ui/ui.h trunk/fuse/ui/uijoystick.c trunk/fuse/ui/widget/browse.c trunk/fuse/ui/widget/debugger.c trunk/fuse/ui/widget/error.c trunk/fuse/ui/widget/filesel.c trunk/fuse/ui/widget/memory.c trunk/fuse/ui/widget/menu.c trunk/fuse/ui/widget/options.pl trunk/fuse/ui/widget/picture.c trunk/fuse/ui/widget/pokefinder.c trunk/fuse/ui/widget/query.c trunk/fuse/ui/widget/roms.c trunk/fuse/ui/widget/select.c trunk/fuse/ui/widget/text.c trunk/fuse/ui/widget/widget.c trunk/fuse/ui/widget/widget.h trunk/fuse/ui/wii/wiidisplay.c trunk/fuse/ui/wii/wiikeyboard.c trunk/fuse/ui/wii/wiiui.c trunk/fuse/ui/win32/confirm.c trunk/fuse/ui/win32/options-header.pl trunk/fuse/ui/win32/options-resource.pl trunk/fuse/ui/win32/options.pl trunk/fuse/ui/win32/picture.c trunk/fuse/ui/xlib/xdisplay.c trunk/fuse/ui/xlib/xerror.c trunk/fuse/ui/xlib/xkeyboard.c trunk/fuse/ui/xlib/xui.c trunk/fuse/ui.c trunk/fuse/ula.c trunk/fuse/utils.c trunk/fuse/windres.rc trunk/fuse/z80/z80.c trunk/libspectrum/generate.pl trunk/libspectrum/libspectrum/dck.c trunk/libspectrum/libspectrum/dll.c trunk/libspectrum/libspectrum/generate.pl.in trunk/libspectrum/libspectrum/hacking/ChangeLog trunk/libspectrum/libspectrum/internals.h trunk/libspectrum/libspectrum/libspectrum.h.in trunk/libspectrum/libspectrum/make-perl.c trunk/libspectrum/libspectrum/myglib/ghash.c trunk/libspectrum/libspectrum/plusd.c trunk/libspectrum/libspectrum/rzx.c trunk/libspectrum/libspectrum/snapshot.c trunk/libspectrum/libspectrum/szx.c trunk/libspectrum/libspectrum/tape.c trunk/libspectrum/libspectrum/warajevo_read.c trunk/libspectrum/libspectrum/wav.c trunk/libspectrum/libspectrum.h trunk/libspectrum/libspectrum.xcodeproj/project.pbxproj trunk/libspectrum/libspectrumpb/libspectrum.xcodeproj/project.pbxproj Added Paths: ----------- trunk/fuse/rectangle.c trunk/fuse/rectangle.h trunk/fuse/sound/blipbuffer.c trunk/fuse/sound/blipbuffer.h trunk/fuse/sound.c Removed Paths: ------------- trunk/fuse/sound/Blip_Buffer.cpp trunk/fuse/sound/Blip_Buffer.h trunk/fuse/sound.cpp Property Changed: ---------------- trunk/fuse/ trunk/libspectrum/libspectrum/ Modified: trunk/FuseGenerator/generate.pl =================================================================== --- trunk/FuseGenerator/generate.pl 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/FuseGenerator/generate.pl 2010-05-24 14:23:37 UTC (rev 639) @@ -172,6 +172,17 @@ /* we support snapshots etc. requiring zlib (e.g. compressed szx) */ #define LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION (1) + +/* zlib (de)compression routines */ + +WIN32_DLL libspectrum_error +libspectrum_zlib_inflate( const libspectrum_byte *gzptr, size_t gzlength, + libspectrum_byte **outptr, size_t *outlength ); + +WIN32_DLL libspectrum_error +libspectrum_zlib_compress( const libspectrum_byte *data, size_t length, + libspectrum_byte **gzptr, size_t *gzlength ); + CODE } Modified: trunk/FuseImporter/generate.pl =================================================================== --- trunk/FuseImporter/generate.pl 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/FuseImporter/generate.pl 2010-05-24 14:23:37 UTC (rev 639) @@ -172,6 +172,17 @@ /* we support snapshots etc. requiring zlib (e.g. compressed szx) */ #define LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION (1) + +/* zlib (de)compression routines */ + +WIN32_DLL libspectrum_error +libspectrum_zlib_inflate( const libspectrum_byte *gzptr, size_t gzlength, + libspectrum_byte **outptr, size_t *outlength ); + +WIN32_DLL libspectrum_error +libspectrum_zlib_compress( const libspectrum_byte *data, size_t length, + libspectrum_byte **gzptr, size_t *gzlength ); + CODE } Property changes on: trunk/fuse ___________________________________________________________________ Modified: svn:mergeinfo - /vendor/fuse-emulator/0.10.0/fuse:556-557 /vendor/fuse-emulator/0.10.0-pre1/fuse:545-546 /vendor/fuse-emulator/current/fuse:530-609 + /vendor/fuse-emulator/0.10.0/fuse:556-557 /vendor/fuse-emulator/0.10.0-pre1/fuse:545-546 /vendor/fuse-emulator/current/fuse:530-638 Modified: trunk/fuse/ChangeLog =================================================================== --- trunk/fuse/ChangeLog 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/ChangeLog 2010-05-24 14:23:37 UTC (rev 639) @@ -1,13 +1,13 @@ -2009-xx-xx Philip Kendall <phi...@sh...> +2010-xx-xx Philip Kendall <phi...@sh...> - * Fuse ?.??.? released + * Fuse 0.11.0 released - FIXME: Just a start, mostly changes visible on Fuse for OS X at the - moment * Add Opus Discovery disk interface support (Gergely Szasz and Fredrick Meunier). - * Wii support. - * Many improvements to Win32 UI (Marek Januszewski). + * Wii support (Bjoern Giesler, Philip Kendall, Marek Januszewski). + * Many improvements to Win32 UI, including an installer (Marek + Januszewski). + * Support weak data in +3 disk images (Gergely Szasz). * Add support for flipping disk images in single sided drives (Gergely Szasz). * Add support for automatically merging both both disk images where @@ -25,6 +25,16 @@ that use the 128K sound ports (Fredrick Meunier). * Add support for Pentagon 1024SL v2.2 16 colour mode (Fredrick Meunier). + * Implement GTK+ drag and drop support (Dmitry Semyonov). + * Better support for international keyboards (Michal Jurica). + * Allow svgalib UI to use full range of bit depths and scalers (Gergely + Szasz). + * Allow GTK+ scalers to set window size in GTK+ UI (rkd77, Fredrick + Meunier). + * Allow selection of "TV speaker" or "beeper"-style sound output + (Fredrick Meunier) + * Allow hot-key switching between full-screen and windowed mode in + SDL UI (György Szombathelyi). * Miscellaneous improvements: * Preformat new disks on +3 to allow the format command on +3 to work @@ -37,7 +47,51 @@ notebooks (thanks, Andrew Owen) (Fredrick Meunier). * Fixes for speed estimation (Gergely Szasz). * Fix border colour in Timex HiRes screenshots (Fredrick Meunier). + * Fix accelerated loaders when compiling with gcc 3.x (Carlos + Almeida, Alberto Garcia and Philip Kendall). + * Allow "combo" boxes in widget UI (Gergely Szasz). + * Allow Home and End keys to work in widget UI (Gergely Szasz). + * Fix poke finder passing the wrong page to the debugger (Marek + Januszewski). + * Ensure joystick code always activates fire buttons correctly + (thanks, anonymous user) + * Don't fire joystick fire button events unless they've actually + changed (Fredrick Meunier; thanks, Phil Reynolds). + * Make svgalib UI use event interface rather than polling (thanks, + anonymous user). + * Ensure empty XML elements can't cause a segfault (thanks, + anonymous user). + * Tweak sector padding to fix Opus ATC+Technician Ted.dsk (Gergely + Szasz; thanks, Simon Owen). + * Z80 NMI should take some time (Fredrick Meunier). + * Ensure netbooks always recognise the enter key (Fredrick Meunier; + thanks, Marce). + * Add a --without-png option to configure for Gentoo (José Manuel + Ferrer Ortiz) + * Many other things I forgot. If you contributed something and would + like to be mentioned here, please mail me. + +2009-01-14 Philip Kendall <phi...@sh...> + + * Fuse 0.10.0.2 released + + * Make loader acceleration work on all compilers (Philip Kendall; + thanks, Carlos Almeida, Alberto Garcia and Alexander Yurchenko). + + * Make the "Don't Save" option in the widget UI do the right thing + (Frederick Meunier). + + * Allow both +3 disk drives to be used at once (Gergely Szasz). + + * Allow both +D disk drives to be used at once (Gergely Szasz). + + * Make .dsk code handle missing newline on "Track-Info" header + (Gergely Szasz; thanks, Simon Owen). + + * Remove unnecessary 'use' directive when building widget options + header file; fixes some build issues (Frederick Meunier) + 2008-12-10 Philip Kendall <phi...@sh...> * Fuse 0.10.0.1 released @@ -981,4 +1035,4 @@ * Version 0.1.0 released. -$Id: ChangeLog 4060 2009-07-30 13:21:38Z fredm $ +$Id: ChangeLog 4134 2010-05-21 13:16:19Z fredm $ Modified: trunk/fuse/Makefile.am =================================================================== --- trunk/fuse/Makefile.am 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/Makefile.am 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ # Process this file with automake to produce Makefile.in ## Copyright (c) 1999-2009 Philip Kendall -## $Id: Makefile.am 4032 2009-06-10 11:09:44Z fredm $ +## $Id: Makefile.am 4112 2010-01-08 11:03:43Z fredm $ ## 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 @@ -81,13 +81,14 @@ printer.c \ profile.c \ psg.c \ + rectangle.c \ rzx.c \ scld.c \ screenshot.c \ settings.c \ slt.c \ snapshot.c \ - sound.cpp \ + sound.c \ spectrum.c \ tape.c \ ui.c \ @@ -149,8 +150,8 @@ BUILT_SOURCES = options.h settings.c settings.h -windres.o: windres.rc winfuse.ico - @WINDRES@ -I$(srcdir) -I. $(srcdir)/windres.rc windres.o +windres.o: windres.rc winfuse.ico ui/win32/*.rc + @WINDRES@ -I$(srcdir) -I. $(srcdir)/windres.rc @LIBSPEC_CFLAGS@ @CPPFLAGS@ windres.o settings.c: settings.pl settings.dat @PERL@ -I$(srcdir)/perl $(srcdir)/settings.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@ @@ -191,6 +192,7 @@ module.h \ periph.h \ psg.h \ + rectangle.h \ rzx.h \ screenshot.h \ settings.h \ Modified: trunk/fuse/README =================================================================== --- trunk/fuse/README 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/README 2010-05-24 14:23:37 UTC (rev 639) @@ -1,4 +1,4 @@ -The Free Unix Spectrum Emulator (Fuse) 0.10.0.1 +The Free Unix Spectrum Emulator (Fuse) 0.10.0.2 =============================================== Fuse (the Free Unix Spectrum Emulator) was originally, and somewhat @@ -111,9 +111,9 @@ Once you've got Fuse configured and built, read the man page :-) -Note that if you're using version of Fuse from CVS rather than one of -the released tarballs, you'll need to run `autogen.sh' before running -'configure' for the first time. +Note that if you're using version of Fuse from Subversion rather than +one of the released tarballs, you'll need to run `autogen.sh' before +running 'configure' for the first time. Building the OS X version of Fuse --------------------------------- @@ -138,7 +138,7 @@ --with-wii \ --without-libxml2 --without-libiconv --without-gpm \ --without-x --without-glib \ - CFLAGS="-g -I$DEVKITPPC/include -I$DEVKITPRO/libogc/include" \ + CFLAGS="-g -I$DEVKITPPC/include -I$DEVKITPRO/libogc/include -DGEKKO" \ LDFLAGS="-g -mrvl -mcpu=750 -meabi -mhard-float \ -Wl,-Map,fuse.elf.map -L$DEVKITPPC/lib \ -L$DEVKITPRO/libogc/lib/wii" \ @@ -151,6 +151,42 @@ This should build fuse.elf, which you can run on your Wii via the usual methods. +Building the Win32 version of Fuse on Linux +-------------------------------- + +You'll need to have the standard MinGW programming tool set. e.g. on Debian +`apt-get install mingw32 mingw-binutils mingw32-runtime' + <http://www.mingw.org/> + +First, have to compile libspectrum: + +./configure --host=i586-mingw32msvc --without-libaudiofile --without-zlib \ + --without-libgcrypt --without-bzip2 --without-glib --prefix=`pwd` +make install + +This should compile libspectrum without any external lib, and `install' into the +source directory. All of the external libs needed by libspectrum and fuse +compile with successfully with MingGW environment - in case of problems +with compiling any of the libs please refer to the lib's homepage for help. + +Then, compile fuse: + +./configure --host=i586-mingw32msvc --without-glib --prefix=`pwd` \ + --with-libspectrum-prefix=`pwd`/../libspectrum --with-win32 \ + --without-libxml2 --without-x +make + +You have to use the real path of libspectrum with `--with-libspectrum-prefix='. +This should build `fuse.exe' without any external lib, but you can run it on +Windows or Linux (with Wine). + +Note: you need `libspectrum-7.dll' and the `roms' directory and the `lib' + directory to `fuse' run perfectly. You may copy this file and directories + into that directory where `fuse.exe' exists. On windows you may need to + copy all files from `lib/uncompressed' into `lib'. + With wine you need `fltmgr.sys' in Windows `system32' directory. (e.g.: + ~/.wine/c_drive/windows/system32). + Closing comments ---------------- @@ -178,6 +214,6 @@ ( http://www.worldofspectrum.org/faq/index.html ) first! Philip Kendall <phi...@sh...> -10 December 2008 +14 January 2009 -$Id: README 4060 2009-07-30 13:21:38Z fredm $ +$Id: README 4132 2010-05-20 12:06:53Z fredm $ Modified: trunk/fuse/compat/unix/file.c =================================================================== --- trunk/fuse/compat/unix/file.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/compat/unix/file.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* file.c: File-related compatibility routines Copyright (c) 2008 Philip Kendall - $Id: file.c 4040 2009-06-27 09:32:42Z fredm $ + $Id: file.c 4072 2009-08-31 15:42:26Z specu $ 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 @@ -41,7 +41,7 @@ compat_fd compat_file_open( const char *path, int write ) { - return fopen( path, write ? "w" : "r" ); + return fopen( path, write ? "wb" : "rb" ); } off_t Modified: trunk/fuse/compat/wii/paths.c =================================================================== --- trunk/fuse/compat/wii/paths.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/compat/wii/paths.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* paths.c: Path-related compatibility routines Copyright (c) 1999-2009 Philip Kendall, Bjoern Giesler - $Id: paths.c 3970 2009-01-19 03:47:02Z specu $ + $Id: paths.c 4065 2009-08-13 18:33:21Z specu $ 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 @@ -50,5 +50,8 @@ if(strlen(path) >= strlen("fat:/") && strncmp(path, "fat:/", strlen("fat:/")) == 0) return 1; + if(strlen(path) >= strlen("sd:/") && + strncmp(path, "sd:/", strlen("sd:/")) == 0) + return 1; return 0; } Modified: trunk/fuse/compat.h =================================================================== --- trunk/fuse/compat.h 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/compat.h 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* compat.h: various compatibility bits Copyright (c) 2003-2008 Philip Kendall - $Id: compat.h 4040 2009-06-27 09:32:42Z fredm $ + $Id: compat.h 4068 2009-08-30 19:30:19Z specu $ 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 @@ -78,11 +78,11 @@ typedef FILE* compat_fd; -#ifndef UI_WII +#ifndef GEKKO typedef DIR* compat_dir; -#else /* #ifndef UI_WII */ +#else /* #ifndef GEKKO */ typedef DIR_ITER* compat_dir; -#endif /* #ifndef UI_WII */ +#endif /* #ifndef GEKKO */ extern const compat_fd COMPAT_FILE_OPEN_FAILED; Modified: trunk/fuse/configure.in =================================================================== --- trunk/fuse/configure.in 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/configure.in 2010-05-24 14:23:37 UTC (rev 639) @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Id: configure.in 4028 2009-05-31 13:15:52Z fredm $ +dnl $Id: configure.in 4132 2010-05-20 12:06:53Z fredm $ dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by @@ -24,11 +24,10 @@ AC_CANONICAL_SYSTEM dnl Use automake to produce `Makefile.in' -AM_INIT_AUTOMAKE(fuse, 0.10.0.1) +AM_INIT_AUTOMAKE(fuse, 0.10.0.2) dnl Checks for programs. AC_PROG_CC -AC_PROG_CXX AC_PROG_RANLIB AC_PATH_PROG(PERL, perl) AC_SUBST(PERL) @@ -308,10 +307,7 @@ ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBSPEC_CFLAGS" AC_TRY_COMPILE([#include <libspectrum.h>],[ -void test() -{ int test = LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION; -} ], AUTOLOAD_SNAPS=compressed; AC_MSG_RESULT(yes), AUTOLOAD_SNAPS=uncompressed; AC_MSG_RESULT(no)) @@ -348,33 +344,41 @@ lib/tape_ts2068.szx]) dnl Check if a version of libpng which supplies png_write_png is available -AC_PATH_PROG([LIBPNG_CONFIG], [libpng-config]) -if test -n "$LIBPNG_CONFIG"; then - PNG_CFLAGS=`libpng-config --cflags` - PNG_LIBS=`libpng-config --ldflags` - PNG_LIBS=`echo " $PNG_LIBS" | sed 's/ -l[[^ ]][[^ ]]*//g'` -fi +AC_MSG_CHECKING(whether PNG support requested) +AC_ARG_WITH(png, +[ --without-png don't use libpng], +if test "$withval" = no; then libpng=no; else libpng=yes; fi, +libpng=yes) +AC_MSG_RESULT($libpng) +if test "$libpng" = yes; then + AC_PATH_PROG([LIBPNG_CONFIG], [libpng-config]) + if test -n "$LIBPNG_CONFIG"; then + PNG_CFLAGS=`libpng-config --cflags` + PNG_LIBS=`libpng-config --ldflags` + PNG_LIBS=`echo " $PNG_LIBS" | sed 's/ -l[[^ ]][[^ ]]*//g'` + fi -ac_save_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $PNG_CFLAGS" -ac_save_LDFLAGS="$LDFLAGS" -LDFLAGS="$PNG_LIBS $LDFLAGS" + ac_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $PNG_CFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$PNG_LIBS $LDFLAGS" -AC_CHECK_LIB( png, png_write_png, - [AC_CHECK_HEADER( - png.h, - [AC_DEFINE([USE_LIBPNG], 1, [Defined if we're going to be using the installed libpng]) PNG_LIBS='-lpng -lm -lz'], - [AC_CHECK_HEADERS(libpng/png.h, - [CPPFLAGS="$ac_save_CPPFLAGS $PNG_CFLAGS/libpng" - AC_DEFINE([USE_LIBPNG], 1, [Defined if we're going to be using the installed libpng]) PNG_LIBS='-lpng -lm -lz'], - [AC_MSG_WARN(png.h not found - saving screenshots disabled) - PNG_LIBS=''] + AC_CHECK_LIB( png, png_write_png, + [AC_CHECK_HEADER( + png.h, + [AC_DEFINE([USE_LIBPNG], 1, [Defined if we're going to be using the installed libpng]) PNG_LIBS='-lpng -lm -lz'], + [AC_CHECK_HEADERS(libpng/png.h, + [CPPFLAGS="$ac_save_CPPFLAGS $PNG_CFLAGS/libpng" + AC_DEFINE([USE_LIBPNG], 1, [Defined if we're going to be using the installed libpng]) PNG_LIBS='-lpng -lm -lz'], + [AC_MSG_WARN(png.h not found - saving screenshots disabled) + PNG_LIBS=''] + )], )], - )], - [AC_MSG_WARN(png_write_png not found - saving screenshots disabled) - PNG_LIBS=''] -) -AC_SUBST(PNG_LIBS) + [AC_MSG_WARN(png_write_png not found - saving screenshots disabled) + PNG_LIBS=''] + ) + AC_SUBST(PNG_LIBS) +fi LDFLAGS="$ac_save_LDFLAGS" @@ -554,7 +558,7 @@ if test "$libxml2" = yes; then AM_PATH_XML2(2.0.0,AC_DEFINE([HAVE_LIB_XML2], 1, [Defined if we've got libxml2]), - AC_WARN(libxml2 not found - config file use disabled)) + AC_WARN(libxml2 not found - config file will use ini format)) fi dnl Work out which timer routines to use Modified: trunk/fuse/debugger/command.c =================================================================== --- trunk/fuse/debugger/command.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/debugger/command.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* command.c: Parse a debugger command Copyright (c) 2002-2008 Philip Kendall - $Id: command.c 3631 2008-05-26 12:22:29Z pak21 $ + $Id: command.c 4125 2010-05-06 22:18:50Z pak21 $ 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 Modified: trunk/fuse/debugger/commandl.l =================================================================== --- trunk/fuse/debugger/commandl.l 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/debugger/commandl.l 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* commandl.l: Debugger command lexical scanner Copyright (c) 2002-2008 Philip Kendall - $Id: commandl.l 3712 2008-07-06 11:45:24Z pak21 $ + $Id: commandl.l 4130 2010-05-18 12:06:19Z fredm $ 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 @@ -37,7 +37,9 @@ #define YY_INPUT(buf,result,max_size) \ { \ - if( !debugger_command_input( buf, &result, max_size ) ) result = YY_NULL; \ + int retval; \ + if( !debugger_command_input( buf, &retval, max_size ) ) retval = YY_NULL; \ + result = (yy_size_t)retval; \ } #define YY_NO_INPUT Modified: trunk/fuse/debugger/debugger_internals.h =================================================================== --- trunk/fuse/debugger/debugger_internals.h 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/debugger/debugger_internals.h 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* debugger_internals.h: The internals of Fuse's monitor/debugger Copyright (c) 2002-2008 Philip Kendall - $Id: debugger_internals.h 3681 2008-06-16 09:40:29Z pak21 $ + $Id: debugger_internals.h 4125 2010-05-06 22:18:50Z pak21 $ 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 Modified: trunk/fuse/debugger/disassemble.c =================================================================== --- trunk/fuse/debugger/disassemble.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/debugger/disassemble.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* disassemble.c: Fuse's disassembler Copyright (c) 2002-2003 Darren Salt, Philip Kendall - $Id: disassemble.c 3115 2007-08-19 02:49:14Z fredm $ + $Id: disassemble.c 4087 2009-09-02 13:42:00Z fredm $ 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 @@ -161,7 +161,7 @@ case 0x00: case 0x08: if( b <= 0x08 ) { - snprintf( buffer, buflen, opcode_00xxx000[ b >> 3 ] ); *length = 1; + snprintf( buffer, buflen, "%s", opcode_00xxx000[ b >> 3 ] ); *length = 1; } else { get_offset( buffer2, 40, address + 2, readbyte_internal( address + 1 ) ); snprintf( buffer, buflen, "%s%s", opcode_00xxx000[ b >> 3 ], buffer2 ); @@ -540,7 +540,7 @@ break; case 0x07: case 0x0f: - snprintf( buffer, buflen, opcode_01xxx111[ ( b >> 3 ) & 0x07 ] ); + snprintf( buffer, buflen, "%s", opcode_01xxx111[ ( b >> 3 ) & 0x07 ] ); *length = 1; break; @@ -560,7 +560,7 @@ snprintf( buffer, buflen, "NOPD" ); *length = 1; *length = 1; } else { /* Note: 0xbc to 0xbf already removed */ - snprintf( buffer, buflen, opcode_101xxxxx[ b & 0x1f ] ); *length = 1; + snprintf( buffer, buflen, "%s", opcode_101xxxxx[ b & 0x1f ] ); *length = 1; } } @@ -713,7 +713,7 @@ return 1; } else { const char *regs[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" }; - snprintf( buffer, buflen, regs[i] ); + snprintf( buffer, buflen, "%s", regs[i] ); return 0; } } Modified: trunk/fuse/disk/beta.c =================================================================== --- trunk/fuse/disk/beta.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/disk/beta.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* beta.c: Routines for handling the Beta disk interface Copyright (c) 2004-2008 Stuart Brady - $Id: beta.c 4060 2009-07-30 13:21:38Z fredm $ + $Id: beta.c 4131 2010-05-19 10:52:37Z fredm $ 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 @@ -58,6 +58,9 @@ #define DISK_TRY_MERGE(heads) ( option_enumerate_diskoptions_disk_try_merge() == 2 || \ ( option_enumerate_diskoptions_disk_try_merge() == 1 && heads == 1 ) ) +/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ +memory_page beta_memory_map_romcs[2]; + int beta_available = 0; int beta_active = 0; int beta_builtin = 0; @@ -124,8 +127,8 @@ { if( !beta_active ) return; - memory_map_read[0] = memory_map_write[0] = memory_map_romcs[ 0 ]; - memory_map_read[1] = memory_map_write[1] = memory_map_romcs[ 1 ]; + memory_map_read[0] = memory_map_write[0] = beta_memory_map_romcs[0]; + memory_map_read[1] = memory_map_write[1] = beta_memory_map_romcs[1]; } static void @@ -150,7 +153,7 @@ for( i = 0; i < BETA_NUM_DRIVES; i++ ) { d = &beta_drives[ i ]; - fdd_init( &d->fdd, FDD_SHUGART, 0, 0, 0 ); /* drive geometry 'autodetect' */ + fdd_init( &d->fdd, FDD_SHUGART, NULL, 0 ); /* drive geometry 'autodetect' */ d->disk.flag = DISK_FLAG_NONE; } beta_select_drive( 0 ); @@ -165,6 +168,7 @@ if( index_event == -1 ) return 1; module_register( &beta_module_info ); + for( i = 0; i < 2; i++ ) beta_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; return 0; } @@ -199,15 +203,15 @@ } if( !beta_builtin ) { - machine_load_rom_bank( memory_map_romcs, 0, 0, + machine_load_rom_bank( beta_memory_map_romcs, 0, 0, settings_current.rom_beta128, settings_default.rom_beta128, 0x4000 ); - memory_map_romcs[ 0 ].writable = 0; - memory_map_romcs[ 1 ].writable = 0; + beta_memory_map_romcs[ 0 ].writable = 0; + beta_memory_map_romcs[ 1 ].writable = 0; - memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; - memory_map_romcs[1].source = MEMORY_SOURCE_PERIPHERAL; + beta_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; + beta_memory_map_romcs[1].source = MEMORY_SOURCE_PERIPHERAL; beta_active = 0; @@ -225,8 +229,7 @@ /* We can eject disks only if they are currently present */ dt = &fdd_params[ option_enumerate_diskoptions_drive_beta128a_type() + 1 ]; /* +1 => there is no `Disabled' */ - fdd_init( &beta_drives[ BETA_DRIVE_A ].fdd, FDD_SHUGART, - dt->heads, dt->cylinders, 1 ); + fdd_init( &beta_drives[ BETA_DRIVE_A ].fdd, FDD_SHUGART, dt, 1 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_A, dt->enabled ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_A_EJECT, beta_drives[ BETA_DRIVE_A ].fdd.loaded ); @@ -237,8 +240,7 @@ dt = &fdd_params[ option_enumerate_diskoptions_drive_beta128b_type() ]; - fdd_init( &beta_drives[ BETA_DRIVE_B ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, - dt->heads, dt->cylinders, 1 ); + fdd_init( &beta_drives[ BETA_DRIVE_B ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_B, dt->enabled ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_B_FLIP_SET, !beta_drives[ BETA_DRIVE_B ].fdd.upsidedown ); @@ -249,8 +251,7 @@ dt = &fdd_params[ option_enumerate_diskoptions_drive_beta128c_type() ]; - fdd_init( &beta_drives[ BETA_DRIVE_C ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, - dt->heads, dt->cylinders, 1 ); + fdd_init( &beta_drives[ BETA_DRIVE_C ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_C, dt->enabled ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_C_FLIP_SET, !beta_drives[ BETA_DRIVE_C ].fdd.upsidedown ); @@ -261,8 +262,7 @@ dt = &fdd_params[ option_enumerate_diskoptions_drive_beta128d_type() ]; - fdd_init( &beta_drives[ BETA_DRIVE_D ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, - dt->heads, dt->cylinders, 1 ); + fdd_init( &beta_drives[ BETA_DRIVE_D ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_D, dt->enabled ); ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_BETA_D_FLIP_SET, !beta_drives[ BETA_DRIVE_D ].fdd.upsidedown ); @@ -702,7 +702,7 @@ if( libspectrum_snap_beta_custom_rom( snap ) && libspectrum_snap_beta_rom( snap, 0 ) && machine_load_rom_bank_from_buffer( - memory_map_romcs, 0, 0, + beta_memory_map_romcs, 0, 0, libspectrum_snap_beta_rom( snap, 0 ), MEMORY_PAGE_SIZE * 2, 1 ) ) @@ -734,7 +734,7 @@ libspectrum_snap_set_beta_active( snap, 1 ); - if( memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { + if( beta_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { size_t rom_length = MEMORY_PAGE_SIZE * 2; buffer = malloc( rom_length ); @@ -743,8 +743,8 @@ return; } - memcpy( buffer, memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); - memcpy( buffer + MEMORY_PAGE_SIZE, memory_map_romcs[1].page, + memcpy( buffer, beta_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); + memcpy( buffer + MEMORY_PAGE_SIZE, beta_memory_map_romcs[1].page, MEMORY_PAGE_SIZE ); libspectrum_snap_set_beta_rom( snap, 0, buffer ); Modified: trunk/fuse/disk/beta.h =================================================================== --- trunk/fuse/disk/beta.h 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/disk/beta.h 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* beta.h: Routines for handling the Beta disk interface Copyright (c) 2003-2004 Fredrick Meunier, Philip Kendall - $Id: beta.h 4029 2009-06-05 13:50:55Z fredm $ + $Id: beta.h 4099 2009-10-22 10:59:02Z fredm $ 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 @@ -30,6 +30,7 @@ #include <libspectrum.h> +#include "memory.h" #include "periph.h" #include "disk/fdd.h" @@ -37,6 +38,9 @@ extern int beta_active; /* Is the Beta disk interface enabled? */ extern int beta_builtin; /* Is the Beta disk interface built-in? */ +/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ +extern memory_page beta_memory_map_romcs[2]; + extern libspectrum_word beta_pc_mask; /* Bits to mask in PC for enable check */ extern libspectrum_word beta_pc_value; /* Value to compare masked PC against */ Modified: trunk/fuse/disk/disk.c =================================================================== --- trunk/fuse/disk/disk.c 2010-05-24 12:05:28 UTC (rev 638) +++ trunk/fuse/disk/disk.c 2010-05-24 14:23:37 UTC (rev 639) @@ -1,7 +1,7 @@ /* disk.c: Routines for handling disk images - Copyright (c) 2007 Gergely Szasz + Copyright (c) 2007-2010 Gergely Szasz - $Id: disk.c 4061 2009-07-30 23:37:29Z fredm $ + $Id: disk.c 4114 2010-01-15 13:45:51Z fredm $ 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 @@ -53,7 +53,7 @@ "Cannot close file", /* DISK_CLOSE */ "Cannot write disk image", /* DISK_WRFILE */ "Partially written file", /* DISK_WRPART */ - + "Unknown error code" /* DISK_LAST_ERROR */ }; @@ -135,7 +135,7 @@ id_read( disk_t *d, int *head, int *track, int *sector, int *length ) { int a1mark = 0; - + while( d->i < d->bpt ) { if( d->track[ d->i ] == 0xa1 && bitmap_test( d->clocks, d->i ) ) { /* 0xa1 with clock */ @@ -210,9 +210,8 @@ { int s; int del; - - d->track = d->data + ( ( d->sides * track + head ) * d->tlen ); - d->clocks = d->track + d->bpt; + + DISK_SET_TRACK( d, head, track ); d->i = 0; for( s = sector_base; s < sector_base + sectors; s++ ) { if( id_seek( d, s ) ) { @@ -232,9 +231,8 @@ { int h, t, s, seclen; int del; - - d->track = d->data + ( ( d->sides * track + head ) * d->tlen ); - d->clocks = d->track + d->bpt; + + DISK_SET_TRACK( d, head, track ); d->i = 0; while( id_read( d, &h, &t, &s, &seclen ) ) { if( datamark_read( d, &del ) ) { /* write data if we have data */ @@ -253,6 +251,8 @@ #define DISK_DDAM 32 #define DISK_CORRUPT_SECTOR 64 #define DISK_UNFORMATTED_TRACK 128 +#define DISK_FM_DATA 256 +#define DISK_WEAK_DATA 512 static int guess_track_geom( disk_t *d, int head, int track, int *sector_base, @@ -266,8 +266,7 @@ *seclen = -1; *mfm = -1; - d->track = d->data + ( d->sides * track + head ) * d->tlen; - d->clocks = d->track + d->bpt; + DISK_SET_TRACK( d, head, track ); d->i = 0; while( id_read( d, &h, &t, &s, &sl ) ) { if( *sector_base == -1 ) @@ -294,6 +293,31 @@ return r; } +static void +update_tracks_mode( disk_t *d ) +{ + int i, j, bpt; + int mfm, fm, weak; + + for( i = 0; i < d->cylinders * d->sides; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + mfm = 0, fm = 0, weak = 0; + bpt = d->track[-3] + 256 * d->track[-2]; + for( j = DISK_CLEN( bpt ) - 1; j >= 0; j-- ) { + mfm |= ~d->fm[j]; + fm |= d->fm[j]; + weak |= d->weak[j]; + } + if( mfm && !fm ) d->track[-1] = 0x00; + if( !mfm && fm ) d->track[-1] = 0x01; + if( mfm && fm ) d->track[-1] = 0x02; + if( weak ) { + d->track[-1] |= 0x80; + d->have_weak = 1; + } + } +} + static int check_disk_geom( disk_t *d, int *sector_base, int *sectors, int *seclen, int *mfm, int *unf ) @@ -301,7 +325,7 @@ int h, t, s, slen, sbase, m; int r = 0; - d->track = d->data; d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, 0 ); d->i = 0; *sector_base = -1; *sectors = -1; @@ -310,6 +334,9 @@ *unf = -1; for( t = 0; t < d->cylinders; t++ ) { for( h = 0; h < d->sides; h++ ) { + r |= ( d->track[-1] & 0x80 ) ? DISK_WEAK_DATA : 0; + r |= ( d->track[-1] & 0x03 ) == 0x02 ? DISK_MFM_VARI : 0; + r |= ( d->track[-1] & 0x03 ) == 0x01 ? DISK_FM_DATA : 0; r |= guess_track_geom( d, h, t, &sbase, &s, &slen, &m ); if( *sector_base == -1 ) *sector_base = sbase; @@ -512,7 +539,7 @@ /* if 'buffer' == NULL, then copy data bytes from 'data' */ static int data_add( disk_t *d, buffer_t *buffer, unsigned char *data, int len, int ddam, - int gaptype, int crc_error, int autofill ) + int gaptype, int crc_error, int autofill, int *start_data ) { int length; libspectrum_word crc = 0xffff; @@ -532,6 +559,7 @@ if( d->i + len + 2 >= d->bpt ) /* too many data bytes */ return 1; /*------------------------------ data ------------------------------*/ + if( start_data != NULL ) *start_data = d->i; /* record data start position */ if( buffer == NULL ) { memcpy( d->track + d->i, data, len ); length = len; @@ -580,6 +608,19 @@ return len; } +static int +calc_lenid( int sector_length ) +{ + int id = 0; + + while( sector_length > 0x80 ) { + id++; + sector_length >>= 1; + } + + return id; +} + #define NO_INTERLEAVE 1 #define INTERLEAVE_2 2 #define INTERLEAVE_OPUS 13 @@ -597,8 +638,7 @@ int idx; d->i = 0; - d->track = d->data + ( ( d->sides * track + head ) * d->tlen ); - d->clocks = d->track + d->bpt; + DISK_SET_TRACK( d, head, track ); if( preindex && preindex_add( d, gap ) ) return 1; if( postindex_add( d, gap ) ) @@ -608,9 +648,9 @@ pos = i = 0; for( s = sector_base; s < sector_base + sectors; s++ ) { d->i = idx + pos * slen; - if( id_add( d, head, track, s, sector_length >> 8, gap, CRC_OK ) ) + if( id_add( d, head, track, s, calc_lenid( sector_length ), gap, CRC_OK ) ) return 1; - if( data_add( d, buffer, NULL, sector_length, NO_DDAM, gap, CRC_OK, autofill ) ) + if( data_add( d, buffer, NULL, sector_length, NO_DDAM, gap, CRC_OK, autofill, NULL ) ) return 1; pos += interleave; if( pos >= sectors ) { /* wrap around */ @@ -672,8 +712,8 @@ } if( d->bpt > 0 ) - d->tlen = d->bpt + d->bpt / 8 + ( d->bpt % 8 ? 1 : 0 ); - dlen = d->sides * d->cylinders * d->tlen; /* track len with clock marks */ + d->tlen = 4 + d->bpt + 3 * DISK_CLEN( d->bpt ); + dlen = d->sides * d->cylinders * d->tlen; /* track len with clock and other marks */ if( ( d->data = calloc( 1, dlen ) ) == NULL ) return d->status = DISK_MEM; @@ -739,11 +779,221 @@ if( d->sides < 1 || d->sides > 2 || \ d->cylinders < 1 || d->cylinders > 85 ) return d->status = DISK_GEOM +#ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION static int +udi_read_compressed( const libspectrum_byte *buffer, + size_t compr_size, size_t uncompr_size, + libspectrum_byte **data, size_t *data_size ) +{ + libspectrum_error error; + libspectrum_byte *tmp; + size_t olength = uncompr_size; + + tmp = NULL; + + error = libspectrum_zlib_inflate( buffer, compr_size, &tmp, &olength ); + if( error ) { + if( *data ) free( *data ); + *data_size = 0; + return error; + } + if( *data_size < uncompr_size ) { + *data = libspectrum_realloc( *data, uncompr_size ); + *data_size = uncompr_size; + } + memcpy( *data, tmp, uncompr_size ); + libspectrum_free( tmp ); + + return 0; +} + +static int +udi_write_compressed( const libspectrum_byte *buffer, + size_t uncompr_size, size_t *compr_size, + libspectrum_byte **data, size_t *data_size ) +{ + libspectrum_error error; + libspectrum_byte *tmp; + + tmp = NULL; + error = libspectrum_zlib_compress( buffer, uncompr_size, + &tmp, compr_size ); + if( error ) return error; + + if( *data_size < *compr_size ) { + *data = libspectrum_realloc( *data, *compr_size ); + *data_size = *compr_size; + } + memcpy( *data, tmp, *compr_size ); + libspectrum_free( tmp ); + + return LIBSPECTRUM_ERROR_NONE; +} +#endif /* #ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + +static void +udi_pack_tracks( disk_t *d ) +{ + int i, tlen, clen, ttyp; + libspectrum_byte *tmp; + + for( i = 0; i < d->sides * d->cylinders; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + tmp = d->track; + ttyp = tmp[-1]; + tlen = tmp[-3] + 256 * tmp[-2]; + clen = DISK_CLEN( tlen ); + tmp += tlen; + /* copy clock if needed */ + if( tmp != d->clocks ) + memcpy( tmp, d->clocks, clen ); + if( ttyp == 0x00 || ttyp == 0x01 ) continue; + tmp += clen; + if( ttyp & 0x02 ) { /* copy FM marks */ + if( tmp != d->fm ) + memcpy( tmp, d->fm, clen ); + tmp += clen; + } + if( ! ( ttyp & 0x80 ) ) continue; + if( tmp != d->weak ) /* copy WEAK marks*/ + memcpy( tmp, d->weak, clen ); + } +} + +static void +udi_unpack_tracks( disk_t *d ) +{ + int i, tlen, clen, ttyp; + libspectrum_byte *tmp; + libspectrum_byte mask[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + + for( i = 0; i < d->sides * d->cylinders; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + tmp = d->track; + ttyp = tmp[-1]; + tlen = tmp[-3] + 256 * tmp[-2]; + clen = DISK_CLEN( tlen ); + tmp += tlen; + if( ttyp & 0x80 ) tmp += clen; + if( ttyp & 0x02 ) tmp += clen; + if( ( ttyp & 0x80 ) ) { /* copy WEAK marks*/ + if( tmp != d->weak ) + memcpy( d->weak, tmp, clen ); + tmp -= clen; + } else { /* clear WEAK marks*/ + memset( d->weak, 0, clen ); + } + if( ttyp & 0x02 ) { /* copy FM marks */ + if( tmp != d->fm ) + memcpy( d->fm, tmp, clen ); + tmp -= clen; + } else { /* set/clear FM marks*/ + memset( d->fm, ttyp & 0x01 ? 0xff : 0, clen ); + if( tlen % 8 ) { /* adjust last byte */ + d->fm[clen - 1] &= mask[ tlen % 8 ]; + } + } + /* copy clock if needed */ + if( tmp != d->clocks ) + memcpy( d->clocks, tmp, clen ); + } +} + +/* calculate track len from type, if type eq. 0x00/0x01/0x02/0x80/0x81/0x82 + !!! not for 0x83 nor 0xf0 !!! +*/ +#define UDI_TLEN( type, bpt ) ( ( bpt ) + DISK_CLEN( bpt ) * ( 1 + \ + ( type & 0x02 ? 1 : 0 ) + \ + ( type & 0x80 ? 1 : 0 ) ) ) + +static int +udi_uncompress_tracks( disk_t *d ) +{ + int i; + libspectrum_byte *data = NULL; +#ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION + size_t data_size = 0; + int bpt, tlen, clen, ttyp; +#endif /* #ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + + for( i = 0; i < d->sides * d->cylinders; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + if( d->track[-1] != 0xf0 ) continue; /* if not compressed */ + +#ifndef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION + /* if libspectrum cannot support */ + return d->status = DISK_UNSUP; +#else /* #ifndef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + clen = d->track[-3] + 256 * d->track[-2] + 1; + ttyp = d->track[0]; /* compressed track type */ + bpt = d->track[1] + 256 * d->track[2]; /* compressed track len... */ + tlen = UDI_TLEN( ttyp, bpt ); + d->track[-1] = ttyp; + d->track[-3] = d->track[1]; + d->track[-2] = d->track[2]; + if( udi_read_compressed( d->track + 3, clen, tlen, &data, &data_size ) ) { + if( data ) libspectrum_free( data ); + return d->status = DISK_UNSUP; + } + memcpy( d->track, data, tlen ); /* read track */ +#endif /* #ifndef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + } + if( data ) libspectrum_free( data ); + return DISK_OK; +} + +#ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION +static int +udi_compress_tracks( disk_t *d ) +{ + int i, tlen; + libspectrum_byte *data = NULL; + size_t clen, data_size = 0; + + for( i = 0; i < d->sides * d->cylinders; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + if( d->track[-1] == 0xf0 ) continue; /* already compressed??? */ + + tlen = UDI_TLEN( d->track[-1], d->track[-3] + 256 * d->track[-2] ); + /* if fail to compress, skip ... */ + if( udi_write_compressed( d->track, tlen, &clen, &data, &data_size ) || + clen < 1 ) continue; + /* if compression too large, skip... */ + if( clen > 65535 || clen >= tlen ) continue; + d->track[0] = d->track[-1]; /* track type... */ + d->track[1] = d->track[-3]; /* compressed track len... */ + d->track[2] = d->track[-2]; /* compressed track len... */ + memcpy( d->track + 3, data, clen ); /* read track */ + clen--; + d->track[-1] = 0xf0; + d->track[-3] = clen & 0xff; + d->track[-2] = ( clen >> 8 ) & 0xff; + } + if( data ) libspectrum_free( data ); + return DISK_OK; +} +#endif /* #ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + +static int open_udi( buffer_t *buffer, disk_t *d ) { - int i, j, bpt; + int i, bpt, ttyp, tlen, error; + size_t clen, eof; + libspectrum_dword crc; + crc = ~(libspectrum_dword) 0; + + /* check file length */ + eof = buff[4] + 256 * buff[5] + 65536 * buff[6] + 16777216 * buff[7]; + if( eof != buffer->file.length - 4 ) + return d->status = DISK_OPEN; + /* check CRC32 */ + for( i = 0; i < eof; i++ ) + crc = crc_udi( crc, buff[i] ); + if( crc != buff[eof] + 256 * buff[eof + 1] + 65536 * buff[eof + 2] + + 16777216 * buff[eof + 3] ) + return d->status = DISK_OPEN; + d->sides = buff[10] + 1; d->cylinders = buff[9] + 1; GEOM_CHECK; @@ -752,15 +1002,35 @@ d->bpt = 0; /* scan file for the longest track */ - for( i = 0; i < d->sides * d->cylinders; i++ ) { + for( i = 0; buffer->index < eof; i++ ) { if( buffavail( buffer ) < 3 ) return d->status = DISK_OPEN; - if( buff[0] != 0x00 ) + ttyp = buff[0]; + if( ttyp != 0x00 && ttyp != 0x01 && ttyp != 0x02 && ttyp != 0x80 && + ttyp != 0x81 && ttyp != 0x82 && ttyp != 0x83 && ttyp != 0xf0 ) return d->status = DISK_UNSUP; - bpt = buff[1] + 256 * buff[2]; /* current track len... */ + + /* if libspectrum cannot suppot*/ +#ifndef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION + if( ttyp == 0xf0 ) d->status = DISK_UNSUP; +#endif /* #ifndef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION */ + if( ttyp == 0x83 ) { /* multiple read */ + if( i == 0 ) return d->status = DISK_GEOM; /* cannot be first track */ + i--; bpt = 0; /* not a real track */ + tlen = buff[1] + 256 * buff[2]; /* current track len... */ + tlen = ( tlen & 0xfff8 ) * ( tlen & 0x07 ); + } else if( ttyp == 0xf0 ) { /* compressed track */ + if( buffavail( buffer ) < 7 ) + return d->status = DISK_OPEN; + bpt = buff[4] + 256 * buff[5]; + tlen = 7 + buff[1] + 256 * buff[2]; + } else { + bpt = buff[1] + 256 * buff[2]; /* current track len... */ + tlen = 3 + UDI_TLEN( ttyp, bpt ); + } if( bpt > d->bpt ) d->bpt = bpt; - if( buffseek( buffer, 3 + bpt + bpt / 8 + ( bpt % 8 ? 1 : 0 ), SEEK_CUR ) == -1 ) + if( buffseek( buffer, tlen, SEEK_CUR ) == -1 ) return d->status = DISK_OPEN; } @@ -768,33 +1038,46 @@ return d->status = DISK_GEOM; bpt = d->bpt; /* save the maximal value */ - d->tlen = bpt + bpt / 8 + ( bpt % 8 ? 1 : 0 ); + d->tlen = 3 + bpt + 3 * DISK_CLEN( bpt ); d->bpt = 0; /* we know exactly the track len... */ if( disk_alloc( d ) != DISK_OK ) return d->status; d->bpt = bpt; /* restore the maximal byte per track */ buffer->index = 16; - d->track = d->data; - for( i = 0; i < d->sides * d->cylinders; i++ ) { + for( i = 0; buffer->index < eof; i++ ) { + DISK_SET_TRACK_IDX( d, i ); + ttyp = buff[0]; bpt = buff[1] + 256 * buff[2]; /* current track len... */ - buffer->index += 3; + clen = DISK_CLEN( bpt ); + + memset( d->track, d->bpt, 0x4e ); /* fillup */ /* read track + clocks */ - if( d->bpt == bpt ) { /* if udi track length equal with the maximal track length */ - buffread( d->track, bpt + bpt / 8 + ( bpt % 8 ? 1 : 0 ), buffer ); + if( ttyp == 0x83 ) { /* multiple read */ + i--; /* not a real track */ + DISK_SET_TRACK_IDX( d, i ); /* back to previouse track */ + d->weak += buff[3] + 256 * buff[4]; /* add offset to weak */ + tlen = ( buff[1] + 256 * buff[2] ) >> 3; /* weak len in bytes */ + for( tlen--; tlen >= 0; tlen-- ) + d->weak[tlen] = 0xff; + tlen = buff[1] + 256 * buff[2]; /* current track len... */ + tlen = ( tlen & 0xfff8 ) * ( tlen & 0x07 ); + buffseek( buffer, tlen, SEEK_CUR ); } else { - buffread( d->track, bpt, buffer ); /* first the data */ - d->track += bpt; - for( j = d->bpt - bpt; j > 0; j--, d->track++ ) - *d->track = 0x4e; /* fill track data with 0x4e */ - buffread( d->track, bpt / 8 + ( bpt % 8 ? 1 : 0 ), buffer ); - d->track += bpt / 8 + ( bpt % 8 ? 1 : 0 ); - for( j = ( d->bpt / 8 + ( d->bpt % 8 ? 1 : 0 ) ) - - ( bpt / 8 + ( bpt % 8 ? 1 : 0 ) ); j > 0; j--, d->track++ ) - *d->track = 0x00; /* fill the clocks with 0x00 */ + if( ttyp == 0xf0 ) /* compressed */ + tlen = bpt + 4; + else + tlen = UDI_TLEN( ttyp, bpt ); + d->track[-1] = ttyp; + d->track[-3] = buff[1]; + d->track[-2] = buff[2]; + buffer->index += 3; + buffread( d->track, tlen, buffer ); /* first read data */ } - d->track += d->tlen; } + error = udi_uncompress_tracks( d ); + if( error ) return error; + udi_unpack_tracks( d ); return d->status = DISK_OK; } @@ -990,12 +1273,11 @@ buffread( head, 7, buffer ); /* 7 = track head */ track_offset = head[0x00] + 256 * head[0x01] + 65536 * head[0x02] + 16777216 * head[0x03]; - d->track = d->data + i * d->tlen; d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, i ); d->i = 0; if( preindex ) preindex_add( d, gap ); postindex_add( d, gap ); - bpt = 0; for( j = 0; j < head[0x06]; j++ ) { if( j % 35 == 0 ) { /* if we have more than 35 sector in a track, we have to seek back to the next sector @@ -1012,7 +1294,7 @@ data_add( d, buffer, NULL, ( head[ 0x0b + 7 * ( j % 35 ) ] & 0x3f ) == 0 ? -1 : 0x80 << head[ 0x0a + 7 * ( j % 35 ) ], head[ 0x0b + 7 * ( j % 35 ) ] & 0x80 ? DDAM : NO_DDAM, - gap, CRC_OK, NO_AUTOFILL ); + gap, CRC_OK, NO_AUTOFILL, NULL ); } head_offset += 7 + 7 * head[0x06]; gap4_add( d, gap ); @@ -1020,6 +1302,28 @@ return d->status = DISK_OK; } +static void +cpc_set_weak_range( disk_t *d, int idx, buffer_t *buffer, int n, int len ) +{ + int i, j, first = -1, last = -1; + libspectrum_byte *t, *w; + + t = d->track + idx; + w = buffer->file.buffer + buffer->index; + + for( i = 0; i < len; i++, t++, w++ ) { + for( j = 0; j < n - 1; j ++ ) { + if( *t != w[j * len] ) { + if( first == -1 ) first = idx + i; + last = idx + i; + } + } + } + for( ; first <= last; first++ ) { + bitmap_set( d->weak, first ); + } +} + #define CPC_ISSUE_NONE 0 #define CPC_ISSUE_1 1 #define CPC_ISSUE_2 2 @@ -1030,7 +1334,7 @@ static int open_cpc( buffer_t *buffer, disk_t *d, int preindex ) { - int i, j, seclen, idlen, gap, sector_pad; + int i, j, seclen, idlen, gap, sector_pad, idx; int bpt, max_bpt = 0, trlen; int fix[84], plus3_fix; unsigned char *hdrb; @@ -1122,7 +1426,7 @@ if( disk_alloc( d ) != DISK_OK ) return d->status; - d->track = d->data; d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, 0 ); buffer->index = 256; /* rewind to first track */ for( i = 0; i < d->sides*d->cylinders; i++ ) { hdrb = buff; @@ -1130,7 +1434,7 @@ gap = (unsigned char)hdrb[0x16] == 0xff ? GAP_MINIMAL_FM : GAP_MINIMAL_MFM; i = hdrb[0x10] * d->sides + hdrb[0x11]; /* adjust track No. */ - d->track = d->data + i * d->tlen; d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, i ); d->i = 0; if( preindex) preindex_add( d, gap ); @@ -1158,7 +1462,7 @@ data_add( d, buffer, NULL, seclen, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, NULL ); } else if( i < 84 && fix[i] == CPC_ISSUE_2 && j == 0 ) { /* 6144, 10x512 */ datamark_add( d, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap ); gap_add( d, 2, gap ); @@ -1167,13 +1471,13 @@ data_add( d, buffer, NULL, 128, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, NULL ); buffer->index += seclen - 128; } else if( i < 84 && fix[i] == CPC_ISSUE_4 ) { /* Nx8192 (max 6384 byte ) */ data_add( d, buffer, NULL, 6384, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, NULL ); buffer->index += seclen - 6384; } else if( i < 84 && fix[i] == CPC_ISSUE_5 ) { /* 9x512 */ /* 512 256 512 256 512 256 512 256 512 */ @@ -1181,22 +1485,22 @@ data_add( d, NULL, buff, 512, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, NULL ); buffer->index += idlen; } else { data_add( d, buffer, NULL, idlen, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, NULL ); } } else { data_add( d, buffer, NULL, seclen > idlen ? idlen : seclen, hdrb[ 0x1d + 8 * j ] & 0x40 ? DDAM : NO_DDAM, gap, hdrb[ 0x1c + 8 * j ] & 0x20 && hdrb[ 0x1d + 8 * j ] & 0x20 ? - CRC_ERROR : CRC_OK, 0x00 ); + CRC_ERROR : CRC_OK, 0x00, &idx ); if( seclen > idlen ) { /* weak sector with multiple copy */ - buffer->index +=( seclen / ( 0x80 << hdrb[ 0x1b + 8 * j ] ) - 1 ) * - ( 0x80 << hdrb[ 0x1b + 8 * j ] ); + cpc_set_weak_range( d, idx, buffer, seclen / idlen, idlen ); + buffer->index += ( seclen / idlen - 1 ) * idlen; /* ( ( N * len ) / len - 1 ) * len */ } } @@ -1236,8 +1540,7 @@ return d->status = DISK_GEOM; /* too many file */ buffer->index = 9; /* read SCL entries */ - d->track = d->data; /* track 0 */ - d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, 0 ); d->i = 0; postindex_add( d, GAP_TRDOS ); scl_i = d->i; /* the position of first sector */ @@ -1266,7 +1569,7 @@ if( j == 256 ) { /* one sector ready */ d->i = scl_i + ( ( s - 1 ) % 8 * 2 + ( s - 1 ) / 8 ) * seclen; /* 1 9 2 10 3 ... */ id_add( d, 0, 0, s, SECLEN_256, GAP_TRDOS, CRC_OK ); - data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL ); + data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL, NULL ); memset( head, 0, 256 ); s++; j = 0; @@ -1276,7 +1579,7 @@ if( j != 0 ) { /* we have to add this sector */ d->i = scl_i + ( ( s - 1 ) % 8 * 2 + ( s - 1 ) / 8 ) * seclen; /* 1 9 2 10 3 ... */ id_add( d, 0, 0, s, SECLEN_256, GAP_TRDOS, CRC_OK ); - data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL ); + data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL, NULL ); s++; } /* and add empty sectors up to No. 16 */ @@ -1296,7 +1599,7 @@ head[244] = scl_deleted; /* number of deleted files */ memcpy( head + 245, "FUSE-SCL", 8 ); } - data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL ); + data_add( d, NULL, head, 256, NO_DDAM, GAP_TRDOS, CRC_OK, NO_AUTOFILL, NULL ); if( s == 9 ) memset( head, 0, 256 ); /* clear sector data... */ } @@ -1346,7 +1649,6 @@ return d->status = DISK_OPEN; if( buff[1] + 1 > d->cylinders ) /* find the biggest cylinder number */ d->cylinders = buff[1] + 1; - bpt = 0; sector_offset = track_offset + 4; mfm = buff[2] & 0x80 ? 0 : 1; /* 0x80 == 1 => SD track */ bpt = postindex_len( d, mfm_old || mfm ? GAP_MINIMAL_FM : GAP_MINIMAL_MFM ) + @@ -1382,15 +1684,14 @@ if( disk_alloc( d ) != DISK_OK ) return d->status; - d->track = d->data; d->clocks = d->track + d->bpt; + DISK_SET_TRACK_IDX( d, 0 ); buffer->index = data_offset; /* first track header */ while( 1 ) { if( ( sectors = buff[0] ) == 255 ) /* sector number 255 => end of tracks */ break; - d->track = d->data + ( d->sides * buff[1] + ( buff[2] & 0x01 ) ) * d->tlen; - d->clocks = d->track + d->bpt; + DISK_SET_TRACK( d, ( buff[2] & 0x01 ), buff[1] ); d->i = 0; /* later teledisk -> if buff[2] & 0x80 -> FM track */ gap = mfm_old || buff[2] & 0x80 ? GAP_MINIMAL_FM : GAP_MINIMAL_MFM; @@ -1418,7 +1719,7 @@ return d->status = DISK_OPEN; } if( data_add( d, buffer, NULL, hdrb[6] + 256 * hdrb[7] - 1, - hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL ) ) { + hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL, NULL ) ) { if( uncomp_buff ) free( uncomp_buff ); return d->status = DISK_OPEN; @@ -1443,7 +1744,7 @@ i += 2 * ( hdrb[9] + 256 * hdrb[10] ); } if( data_add( d, NULL, uncomp_buff, hdrb[6] + 256 * hdrb[7] - 1, - hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL ) ) { + hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL, NULL ) ) { free( uncomp_buff ); return d->status = DISK_OPEN; } @@ -1482,7 +1783,7 @@ } } if( data_add( d, NULL, uncomp_buff, hdrb[6] + 256 * hdrb[7] - 1, - hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL ) ) { + hdrb[4] & 0x04 ? DDAM : NO_DDAM, gap, CRC_OK, NO_AUTOFILL, NULL ) ) { free( uncomp_buff ); return d->status = DISK_OPEN; } @@ -1503,6 +1804,21 @@ return d->status = DISK_OK; } +/* update tracks TLEN */ +void +disk_update_tlens( disk_t *d ) +{ + int i; + + for( i = 0; i < d->sides * d->cylinders; i++ ) { /* check tracks */ + DISK_SET_TRACK_IDX( d, i ); + if( d->track[-3] + 256 * d->track[-2] == 0 ) { + d->track[-3] = d->bpt & 0xff; + d->track[-2] = ( d->bpt >> 8 ) & 0xff; + } + } +} + /* open a disk image file, read and convert to our format * if preindex != 0 we generate preindex gap if needed */ @@ -1513,14 +1829,14 @@ libspectrum_id_t type; int error; -#ifdef UI_WII /* Wii doesn't have access() */ +#ifdef GEKKO /* Wii doesn't have access() */ d->wrprot = 0; -#else /* #ifdef UI_WII */ +#else /* #ifdef GEKKO */ if( access( filename, W_OK ) == -1 ) /* file read only */ d->wrprot = 1; else d->wrprot = 0; -#endif /* #ifdef UI_WII */ +#endif /* #ifdef GEKKO */ if( utils_read_file( filename, &buffer.file ) ) return d->status = DISK_OPEN; @@ -1582,6 +1898,8 @@ } utils_close_file( &buffer.file ); d->dirty = 0; + disk_update_tlens( d ); + update_tracks_mode( d ); return d->status = DISK_OK; } @@ -1610,7 +1928,7 @@ if( disk_alloc( d ) != DISK_OK ) return d->status; - clen = d->bpt / 8 + ( d->bpt % 8 ? 1 : 0 ); + clen = DISK_CLEN( d->bpt ); d->track = d->data; d1->track = d1->data; d2->track = d2->data; @@ -1618,19 +1936,25 @@ if( i < d1->cylinders ) memcpy( d->track, d1->track, d->tlen ); else { - memset( d->track, d->bpt, autofill & 0xff ); /* fill data */ - memset( d->track + d->bpt, clen, 0x00 ); /* no clock marks */ + d->track[0] = d->bpt & 0xff; + d->track[1] = ( d->bpt >> 8 ) & 0xff; + d->track[2] = 0x00; + memset( d->track + 3, d->bpt, autofill & 0xff ); /* fill data */ + memset( d->track + 3 + d->bpt, ... [truncated message content] |