[Fuse-for-macosx-commits] SF.net SVN: fuse-for-macosx:[598] vendor/fuse-emulator/current/fuse
Brought to you by:
fredm
From: <fr...@us...> - 2009-06-27 15:31:35
|
Revision: 598 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=598&view=rev Author: fredm Date: 2009-06-27 12:33:22 +0000 (Sat, 27 Jun 2009) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 13 renames. * vendor/fuse-emulator/current/fuse/ide/ide.c: Renamed from vendor/fuse-emulator/current/fuse/ide.c. * vendor/fuse-emulator/current/fuse/ide/ide.h: Renamed from vendor/fuse-emulator/current/fuse/ide.h. * vendor/fuse-emulator/current/fuse/ide/divide.c: Renamed from vendor/fuse-emulator/current/fuse/divide.c. * vendor/fuse-emulator/current/fuse/ide/divide.h: Renamed from vendor/fuse-emulator/current/fuse/divide.h. * vendor/fuse-emulator/current/fuse/sound.cpp: Renamed from vendor/fuse-emulator/current/fuse/sound.c. * vendor/fuse-emulator/current/fuse/ide/zxatasp.c: Renamed from vendor/fuse-emulator/current/fuse/zxatasp.c. * vendor/fuse-emulator/current/fuse/ide/zxatasp.h: Renamed from vendor/fuse-emulator/current/fuse/zxatasp.h. * vendor/fuse-emulator/current/fuse/ide/zxcf.c: Renamed from vendor/fuse-emulator/current/fuse/zxcf.c. * vendor/fuse-emulator/current/fuse/ide/zxcf.h: Renamed from vendor/fuse-emulator/current/fuse/zxcf.h. * vendor/fuse-emulator/current/fuse/ide/simpleide.c: Renamed from vendor/fuse-emulator/current/fuse/simpleide.c. * vendor/fuse-emulator/current/fuse/ide/simpleide.h: Renamed from vendor/fuse-emulator/current/fuse/simpleide.h. * vendor/fuse-emulator/current/fuse/compat/unix/timer.c: Renamed from vendor/fuse-emulator/current/fuse/timer/unix.c. * vendor/fuse-emulator/current/fuse/compat/win32/timer.c: Renamed from vendor/fuse-emulator/current/fuse/timer/win32.c. Added Paths: ----------- vendor/fuse-emulator/current/fuse/compat/unix/timer.c vendor/fuse-emulator/current/fuse/compat/win32/timer.c vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/ide/divide.c vendor/fuse-emulator/current/fuse/ide/divide.h vendor/fuse-emulator/current/fuse/ide/ide.c vendor/fuse-emulator/current/fuse/ide/ide.h vendor/fuse-emulator/current/fuse/ide/simpleide.c vendor/fuse-emulator/current/fuse/ide/simpleide.h vendor/fuse-emulator/current/fuse/ide/zxatasp.c vendor/fuse-emulator/current/fuse/ide/zxatasp.h vendor/fuse-emulator/current/fuse/ide/zxcf.c vendor/fuse-emulator/current/fuse/ide/zxcf.h vendor/fuse-emulator/current/fuse/sound.cpp Removed Paths: ------------- vendor/fuse-emulator/current/fuse/divide.c vendor/fuse-emulator/current/fuse/divide.h vendor/fuse-emulator/current/fuse/ide.c vendor/fuse-emulator/current/fuse/ide.h vendor/fuse-emulator/current/fuse/simpleide.c vendor/fuse-emulator/current/fuse/simpleide.h vendor/fuse-emulator/current/fuse/sound.c vendor/fuse-emulator/current/fuse/timer/unix.c vendor/fuse-emulator/current/fuse/timer/win32.c vendor/fuse-emulator/current/fuse/zxatasp.c vendor/fuse-emulator/current/fuse/zxatasp.h vendor/fuse-emulator/current/fuse/zxcf.c vendor/fuse-emulator/current/fuse/zxcf.h Copied: vendor/fuse-emulator/current/fuse/compat/unix/timer.c (from rev 597, vendor/fuse-emulator/current/fuse/timer/unix.c) =================================================================== --- vendor/fuse-emulator/current/fuse/compat/unix/timer.c (rev 0) +++ vendor/fuse-emulator/current/fuse/compat/unix/timer.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,72 @@ +/* unix.c: UNIX speed routines for Fuse + Copyright (c) 1999-2007 Philip Kendall, Marek Januszewski, Fredrick Meunier + + $Id: unix.c 3115 2007-08-19 02:49:14Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: phi...@sh... + +*/ + +#include <config.h> + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include "timer.h" +#include "ui/ui.h" + +int +timer_get_real_time( timer_type *real_time ) +{ + int error; + + error = gettimeofday( real_time, NULL ); + if( error ) { + ui_error( UI_ERROR_ERROR, "error getting time: %s", strerror( errno ) ); + return 1; + } + + return 0; +} + +float +timer_get_time_difference( timer_type *a, timer_type *b ) +{ + return ( a->tv_sec - b->tv_sec ) + ( a->tv_usec - b->tv_usec ) / 1000000.0; +} + +void +timer_add_time_difference( timer_type *a, long msec ) +{ + a->tv_usec += msec * 1000; + if( a->tv_usec >= 1000000 ) { + a->tv_usec -= 1000000; + a->tv_sec += 1; + } else if( a->tv_usec < 0 ) { + a->tv_usec += 1000000; + a->tv_sec -= 1; + } +} + +void +timer_sleep_ms( int ms ) +{ + usleep( ms * 1000 ); +} Copied: vendor/fuse-emulator/current/fuse/compat/win32/timer.c (from rev 597, vendor/fuse-emulator/current/fuse/timer/win32.c) =================================================================== --- vendor/fuse-emulator/current/fuse/compat/win32/timer.c (rev 0) +++ vendor/fuse-emulator/current/fuse/compat/win32/timer.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,54 @@ +/* win32.c: Win32 speed routines for Fuse + Copyright (c) 1999-2007 Philip Kendall, Marek Januszewski, Fredrick Meunier + + $Id: win32.c 3087 2007-07-31 19:08:50Z zubzero $ + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: phi...@sh... + +*/ + +#include <config.h> + +#include "timer.h" + +int +timer_get_real_time( timer_type *real_time ) +{ + *real_time = GetTickCount(); + + return 0; +} + +float +timer_get_time_difference( timer_type *a, timer_type *b ) +{ + return ( (long)*a - (long)*b ) / 1000.0; +} + +void +timer_add_time_difference( timer_type *a, long msec ) +{ + *a += msec; +} + +void +timer_sleep_ms( int ms ) +{ + Sleep( ms ); +} Deleted: vendor/fuse-emulator/current/fuse/divide.c =================================================================== --- vendor/fuse-emulator/current/fuse/divide.c 2009-06-24 09:52:27 UTC (rev 597) +++ vendor/fuse-emulator/current/fuse/divide.c 2009-06-27 12:33:22 UTC (rev 598) @@ -1,445 +0,0 @@ -/* divide.c: DivIDE interface routines - Copyright (c) 2005-2008 Matthew Westcott, Philip Kendall - - $Id: divide.c 3703 2008-06-30 20:36:11Z 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 - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Author contact information: - - E-mail: Philip Kendall <phi...@sh...> - -*/ - -#include <config.h> - -#include <libspectrum.h> - -#include <string.h> - -#include "debugger/debugger.h" -#include "ide.h" -#include "machine.h" -#include "module.h" -#include "periph.h" -#include "settings.h" -#include "ui/ui.h" -#include "divide.h" - -/* Private function prototypes */ - -static libspectrum_byte divide_ide_read( libspectrum_word port, int *attached ); -static void divide_ide_write( libspectrum_word port, libspectrum_byte data ); -static void divide_control_write( libspectrum_word port, libspectrum_byte data ); -static void divide_control_write_internal( libspectrum_byte data ); -static void divide_page( void ); -static void divide_unpage( void ); -static libspectrum_ide_register port_to_ide_register( libspectrum_byte port ); - -/* Data */ - -const periph_t divide_peripherals[] = { - { 0x00e3, 0x00a3, divide_ide_read, divide_ide_write }, - { 0x00ff, 0x00e3, NULL, divide_control_write }, -}; - -const size_t divide_peripherals_count = - sizeof( divide_peripherals ) / sizeof( periph_t ); - -static const libspectrum_byte DIVIDE_CONTROL_CONMEM = 0x80; -static const libspectrum_byte DIVIDE_CONTROL_MAPRAM = 0x40; - -int divide_automapping_enabled = 0; -int divide_active = 0; -static libspectrum_byte divide_control; - -/* divide_automap tracks opcode fetches to entry and exit points to determine - whether DivIDE memory *would* be paged in at this moment if mapram / wp - flags allowed it */ -static int divide_automap = 0; - -static libspectrum_ide_channel *divide_idechn0; -static libspectrum_ide_channel *divide_idechn1; - -#define DIVIDE_PAGES 4 -#define DIVIDE_PAGE_LENGTH 0x2000 -static libspectrum_byte divide_ram[ DIVIDE_PAGES ][ DIVIDE_PAGE_LENGTH ]; -static libspectrum_byte divide_eprom[ DIVIDE_PAGE_LENGTH ]; - -static void divide_reset( int hard_reset ); -static void divide_memory_map( void ); -static void divide_enabled_snapshot( libspectrum_snap *snap ); -static void divide_from_snapshot( libspectrum_snap *snap ); -static void divide_to_snapshot( libspectrum_snap *snap ); - -static module_info_t divide_module_info = { - - divide_reset, - divide_memory_map, - divide_enabled_snapshot, - divide_from_snapshot, - divide_to_snapshot, - -}; - -/* Debugger events */ -static const char *event_type_string = "divide"; -static int page_event, unpage_event; - -/* Housekeeping functions */ - -int -divide_init( void ) -{ - int error; - - divide_idechn0 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); - divide_idechn1 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); - - ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 0 ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 0 ); - - if( settings_current.divide_master_file ) { - error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_MASTER, - settings_current.divide_master_file ); - if( error ) return error; - ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 1 ); - } - - if( settings_current.divide_slave_file ) { - error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_SLAVE, - settings_current.divide_slave_file ); - if( error ) return error; - ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 1 ); - } - - module_register( ÷_module_info ); - - if( periph_register_paging_events( event_type_string, &page_event, - &unpage_event ) ) - return 1; - - return 0; -} - -int -divide_end( void ) -{ - int error; - - error = libspectrum_ide_free( divide_idechn0 ); - error = libspectrum_ide_free( divide_idechn1 ) || error; - - return error; -} - -/* DivIDE does not page in immediately on a reset condition (we do that by - trapping PC instead); however, it needs to perform housekeeping tasks upon - reset */ -static void -divide_reset( int hard_reset ) -{ - divide_active = 0; - - if( !settings_current.divide_enabled ) return; - - if( hard_reset ) { - divide_control = 0; - } else { - divide_control &= DIVIDE_CONTROL_MAPRAM; - } - divide_automap = 0; - divide_refresh_page_state(); - - libspectrum_ide_reset( divide_idechn0 ); - libspectrum_ide_reset( divide_idechn1 ); -} - -int -divide_insert( const char *filename, libspectrum_ide_unit unit ) -{ - char **setting; - ui_menu_item item; - - switch( unit ) { - case LIBSPECTRUM_IDE_MASTER: - setting = &settings_current.divide_master_file; - item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT; - break; - - case LIBSPECTRUM_IDE_SLAVE: - setting = &settings_current.divide_slave_file; - item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT; - break; - - default: return 1; - } - - return ide_insert( filename, divide_idechn0, unit, divide_commit, setting, - item ); -} - -int -divide_commit( libspectrum_ide_unit unit ) -{ - int error; - - error = libspectrum_ide_commit( divide_idechn0, unit ); - - return error; -} - -int -divide_eject( libspectrum_ide_unit unit ) -{ - char **setting; - ui_menu_item item; - - switch( unit ) { - case LIBSPECTRUM_IDE_MASTER: - setting = &settings_current.divide_master_file; - item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT; - break; - - case LIBSPECTRUM_IDE_SLAVE: - setting = &settings_current.divide_slave_file; - item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT; - break; - - default: return 1; - } - - return ide_eject( divide_idechn0, unit, divide_commit, setting, item ); -} - -/* Port read/writes */ - -static libspectrum_ide_register -port_to_ide_register( libspectrum_byte port ) -{ - switch( port & 0xff ) { - case 0xa3: - return LIBSPECTRUM_IDE_REGISTER_DATA; - case 0xa7: - return LIBSPECTRUM_IDE_REGISTER_ERROR_FEATURE; - case 0xab: - return LIBSPECTRUM_IDE_REGISTER_SECTOR_COUNT; - case 0xaf: - return LIBSPECTRUM_IDE_REGISTER_SECTOR; - case 0xb3: - return LIBSPECTRUM_IDE_REGISTER_CYLINDER_LOW; - case 0xb7: - return LIBSPECTRUM_IDE_REGISTER_CYLINDER_HIGH; - case 0xbb: - return LIBSPECTRUM_IDE_REGISTER_HEAD_DRIVE; - default: /* 0xbf */ - return LIBSPECTRUM_IDE_REGISTER_COMMAND_STATUS; - } -} - -libspectrum_byte -divide_ide_read( libspectrum_word port, int *attached ) -{ - int ide_register; - if( !settings_current.divide_enabled ) return 0xff; - - *attached = 1; - ide_register = port_to_ide_register( port ); - - return libspectrum_ide_read( divide_idechn0, ide_register ); -} - -static void -divide_ide_write( libspectrum_word port, libspectrum_byte data ) -{ - int ide_register; - if( !settings_current.divide_enabled ) return; - - ide_register = port_to_ide_register( port ); - - libspectrum_ide_write( divide_idechn0, ide_register, data ); -} - -static void -divide_control_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data ) -{ - int old_mapram; - - if( !settings_current.divide_enabled ) return; - - /* MAPRAM bit cannot be reset, only set */ - old_mapram = divide_control & DIVIDE_CONTROL_MAPRAM; - divide_control_write_internal( data | old_mapram ); -} - -static void -divide_control_write_internal( libspectrum_byte data ) -{ - divide_control = data; - divide_refresh_page_state(); -} - -void -divide_set_automap( int state ) -{ - divide_automap = state; - divide_refresh_page_state(); -} - -void -divide_refresh_page_state( void ) -{ - if( divide_control & DIVIDE_CONTROL_CONMEM ) { - /* always paged in if conmem enabled */ - divide_page(); - } else if( settings_current.divide_wp - || ( divide_control & DIVIDE_CONTROL_MAPRAM ) ) { - /* automap in effect */ - if( divide_automap ) { - divide_page(); - } else { - divide_unpage(); - } - } else { - divide_unpage(); - } -} - -static void -divide_page( void ) -{ - divide_active = 1; - machine_current->ram.romcs = 1; - machine_current->memory_map(); - - debugger_event( page_event ); -} - -static void -divide_unpage( void ) -{ - divide_active = 0; - machine_current->ram.romcs = 0; - machine_current->memory_map(); - - debugger_event( unpage_event ); -} - -void -divide_memory_map( void ) -{ - int upper_ram_page; - - if( !divide_active ) return; - - /* low bits of divide_control register give page number to use in upper - bank; only lowest two bits on original 32K model */ - upper_ram_page = divide_control & (DIVIDE_PAGES - 1); - - if( divide_control & DIVIDE_CONTROL_CONMEM ) { - memory_map_romcs[0].page = divide_eprom; - memory_map_romcs[0].writable = !settings_current.divide_wp; - memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; - memory_map_romcs[1].writable = 1; - } else { - if( divide_control & DIVIDE_CONTROL_MAPRAM ) { - memory_map_romcs[0].page = divide_ram[3]; - memory_map_romcs[0].writable = 0; - memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; - memory_map_romcs[1].writable = ( upper_ram_page != 3 ); - } else { - memory_map_romcs[0].page = divide_eprom; - memory_map_romcs[0].writable = 0; - memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; - memory_map_romcs[1].writable = 1; - } - } - - memory_map_read[0] = memory_map_write[0] = memory_map_romcs[0]; - memory_map_read[1] = memory_map_write[1] = memory_map_romcs[1]; -} - -static void -divide_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_divide_active( snap ) ) - settings_current.divide_enabled = 1; -} - -static void -divide_from_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - if( !libspectrum_snap_divide_active( snap ) ) return; - - settings_current.divide_wp = - libspectrum_snap_divide_eprom_writeprotect( snap ); - divide_control_write_internal( libspectrum_snap_divide_control( snap ) ); - - if( libspectrum_snap_divide_eprom( snap, 0 ) ) { - memcpy( divide_eprom, - libspectrum_snap_divide_eprom( snap, 0 ), DIVIDE_PAGE_LENGTH ); - } - - for( i = 0; i < libspectrum_snap_divide_pages( snap ); i++ ) - if( libspectrum_snap_divide_ram( snap, i ) ) - memcpy( divide_ram[ i ], libspectrum_snap_divide_ram( snap, i ), - DIVIDE_PAGE_LENGTH ); - - if( libspectrum_snap_divide_paged( snap ) ) { - divide_page(); - } else { - divide_unpage(); - } -} - -static void -divide_to_snapshot( libspectrum_snap *snap ) -{ - size_t i; - libspectrum_byte *buffer; - - if( !settings_current.divide_enabled ) return; - - libspectrum_snap_set_divide_active( snap, 1 ); - libspectrum_snap_set_divide_eprom_writeprotect( snap, - settings_current.divide_wp ); - libspectrum_snap_set_divide_paged( snap, divide_active ); - libspectrum_snap_set_divide_control( snap, divide_control ); - - buffer = malloc( DIVIDE_PAGE_LENGTH * sizeof( libspectrum_byte ) ); - if( !buffer ) { - ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); - return; - } - - memcpy( buffer, divide_eprom, DIVIDE_PAGE_LENGTH ); - libspectrum_snap_set_divide_eprom( snap, 0, buffer ); - - libspectrum_snap_set_divide_pages( snap, DIVIDE_PAGES ); - - for( i = 0; i < DIVIDE_PAGES; i++ ) { - - buffer = malloc( DIVIDE_PAGE_LENGTH * sizeof( libspectrum_byte ) ); - if( !buffer ) { - ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); - return; - } - - memcpy( buffer, divide_ram[ i ], DIVIDE_PAGE_LENGTH ); - libspectrum_snap_set_divide_ram( snap, i, buffer ); - } -} Deleted: vendor/fuse-emulator/current/fuse/divide.h =================================================================== --- vendor/fuse-emulator/current/fuse/divide.h 2009-06-24 09:52:27 UTC (rev 597) +++ vendor/fuse-emulator/current/fuse/divide.h 2009-06-27 12:33:22 UTC (rev 598) @@ -1,54 +0,0 @@ -/* divide.h: DivIDE interface routines - Copyright (c) 2005 Matthew Westcott - - $Id: divide.h 2993 2007-06-17 13:54:49Z 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 - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Author contact information: - - E-mail: Philip Kendall <phi...@sh...> - -*/ - -#ifndef FUSE_DIVIDE_H -#define FUSE_DIVIDE_H - -#include <libspectrum.h> -#include "periph.h" - -extern const periph_t divide_peripherals[]; -extern const size_t divide_peripherals_count; - -/* Whether DivIDE is currently paged in */ -extern int divide_active; - -/* Notify DivIDE hardware of an opcode fetch to one of the designated - entry / exit points. Depending on configuration, it may or may not - result in the DivIDE memory being paged in */ -void divide_set_automap( int state ); - -/* Call this after some state change other than an opcode fetch which could - trigger DivIDE paging (such as updating the write-protect flag), to - re-evaluate whether paging will actually happen */ -void divide_refresh_page_state( void ); - -int divide_init( void ); -int divide_end( void ); -int divide_insert( const char *filename, libspectrum_ide_unit unit ); -int divide_commit( libspectrum_ide_unit unit ); -int divide_eject( libspectrum_ide_unit unit ); - -#endif /* #ifndef FUSE_DIVIDE_H */ Copied: vendor/fuse-emulator/current/fuse/ide/divide.c (from rev 597, vendor/fuse-emulator/current/fuse/divide.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/divide.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/divide.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,445 @@ +/* divide.c: DivIDE interface routines + Copyright (c) 2005-2008 Matthew Westcott, Philip Kendall + + $Id: divide.c 3703 2008-06-30 20:36:11Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#include <config.h> + +#include <libspectrum.h> + +#include <string.h> + +#include "debugger/debugger.h" +#include "ide.h" +#include "machine.h" +#include "module.h" +#include "periph.h" +#include "settings.h" +#include "ui/ui.h" +#include "divide.h" + +/* Private function prototypes */ + +static libspectrum_byte divide_ide_read( libspectrum_word port, int *attached ); +static void divide_ide_write( libspectrum_word port, libspectrum_byte data ); +static void divide_control_write( libspectrum_word port, libspectrum_byte data ); +static void divide_control_write_internal( libspectrum_byte data ); +static void divide_page( void ); +static void divide_unpage( void ); +static libspectrum_ide_register port_to_ide_register( libspectrum_byte port ); + +/* Data */ + +const periph_t divide_peripherals[] = { + { 0x00e3, 0x00a3, divide_ide_read, divide_ide_write }, + { 0x00ff, 0x00e3, NULL, divide_control_write }, +}; + +const size_t divide_peripherals_count = + sizeof( divide_peripherals ) / sizeof( periph_t ); + +static const libspectrum_byte DIVIDE_CONTROL_CONMEM = 0x80; +static const libspectrum_byte DIVIDE_CONTROL_MAPRAM = 0x40; + +int divide_automapping_enabled = 0; +int divide_active = 0; +static libspectrum_byte divide_control; + +/* divide_automap tracks opcode fetches to entry and exit points to determine + whether DivIDE memory *would* be paged in at this moment if mapram / wp + flags allowed it */ +static int divide_automap = 0; + +static libspectrum_ide_channel *divide_idechn0; +static libspectrum_ide_channel *divide_idechn1; + +#define DIVIDE_PAGES 4 +#define DIVIDE_PAGE_LENGTH 0x2000 +static libspectrum_byte divide_ram[ DIVIDE_PAGES ][ DIVIDE_PAGE_LENGTH ]; +static libspectrum_byte divide_eprom[ DIVIDE_PAGE_LENGTH ]; + +static void divide_reset( int hard_reset ); +static void divide_memory_map( void ); +static void divide_enabled_snapshot( libspectrum_snap *snap ); +static void divide_from_snapshot( libspectrum_snap *snap ); +static void divide_to_snapshot( libspectrum_snap *snap ); + +static module_info_t divide_module_info = { + + divide_reset, + divide_memory_map, + divide_enabled_snapshot, + divide_from_snapshot, + divide_to_snapshot, + +}; + +/* Debugger events */ +static const char *event_type_string = "divide"; +static int page_event, unpage_event; + +/* Housekeeping functions */ + +int +divide_init( void ) +{ + int error; + + divide_idechn0 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); + divide_idechn1 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); + + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 0 ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 0 ); + + if( settings_current.divide_master_file ) { + error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_MASTER, + settings_current.divide_master_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT, 1 ); + } + + if( settings_current.divide_slave_file ) { + error = libspectrum_ide_insert( divide_idechn0, LIBSPECTRUM_IDE_SLAVE, + settings_current.divide_slave_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 1 ); + } + + module_register( ÷_module_info ); + + if( periph_register_paging_events( event_type_string, &page_event, + &unpage_event ) ) + return 1; + + return 0; +} + +int +divide_end( void ) +{ + int error; + + error = libspectrum_ide_free( divide_idechn0 ); + error = libspectrum_ide_free( divide_idechn1 ) || error; + + return error; +} + +/* DivIDE does not page in immediately on a reset condition (we do that by + trapping PC instead); however, it needs to perform housekeeping tasks upon + reset */ +static void +divide_reset( int hard_reset ) +{ + divide_active = 0; + + if( !settings_current.divide_enabled ) return; + + if( hard_reset ) { + divide_control = 0; + } else { + divide_control &= DIVIDE_CONTROL_MAPRAM; + } + divide_automap = 0; + divide_refresh_page_state(); + + libspectrum_ide_reset( divide_idechn0 ); + libspectrum_ide_reset( divide_idechn1 ); +} + +int +divide_insert( const char *filename, libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.divide_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.divide_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_insert( filename, divide_idechn0, unit, divide_commit, setting, + item ); +} + +int +divide_commit( libspectrum_ide_unit unit ) +{ + int error; + + error = libspectrum_ide_commit( divide_idechn0, unit ); + + return error; +} + +int +divide_eject( libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.divide_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.divide_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_eject( divide_idechn0, unit, divide_commit, setting, item ); +} + +/* Port read/writes */ + +static libspectrum_ide_register +port_to_ide_register( libspectrum_byte port ) +{ + switch( port & 0xff ) { + case 0xa3: + return LIBSPECTRUM_IDE_REGISTER_DATA; + case 0xa7: + return LIBSPECTRUM_IDE_REGISTER_ERROR_FEATURE; + case 0xab: + return LIBSPECTRUM_IDE_REGISTER_SECTOR_COUNT; + case 0xaf: + return LIBSPECTRUM_IDE_REGISTER_SECTOR; + case 0xb3: + return LIBSPECTRUM_IDE_REGISTER_CYLINDER_LOW; + case 0xb7: + return LIBSPECTRUM_IDE_REGISTER_CYLINDER_HIGH; + case 0xbb: + return LIBSPECTRUM_IDE_REGISTER_HEAD_DRIVE; + default: /* 0xbf */ + return LIBSPECTRUM_IDE_REGISTER_COMMAND_STATUS; + } +} + +libspectrum_byte +divide_ide_read( libspectrum_word port, int *attached ) +{ + int ide_register; + if( !settings_current.divide_enabled ) return 0xff; + + *attached = 1; + ide_register = port_to_ide_register( port ); + + return libspectrum_ide_read( divide_idechn0, ide_register ); +} + +static void +divide_ide_write( libspectrum_word port, libspectrum_byte data ) +{ + int ide_register; + if( !settings_current.divide_enabled ) return; + + ide_register = port_to_ide_register( port ); + + libspectrum_ide_write( divide_idechn0, ide_register, data ); +} + +static void +divide_control_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data ) +{ + int old_mapram; + + if( !settings_current.divide_enabled ) return; + + /* MAPRAM bit cannot be reset, only set */ + old_mapram = divide_control & DIVIDE_CONTROL_MAPRAM; + divide_control_write_internal( data | old_mapram ); +} + +static void +divide_control_write_internal( libspectrum_byte data ) +{ + divide_control = data; + divide_refresh_page_state(); +} + +void +divide_set_automap( int state ) +{ + divide_automap = state; + divide_refresh_page_state(); +} + +void +divide_refresh_page_state( void ) +{ + if( divide_control & DIVIDE_CONTROL_CONMEM ) { + /* always paged in if conmem enabled */ + divide_page(); + } else if( settings_current.divide_wp + || ( divide_control & DIVIDE_CONTROL_MAPRAM ) ) { + /* automap in effect */ + if( divide_automap ) { + divide_page(); + } else { + divide_unpage(); + } + } else { + divide_unpage(); + } +} + +static void +divide_page( void ) +{ + divide_active = 1; + machine_current->ram.romcs = 1; + machine_current->memory_map(); + + debugger_event( page_event ); +} + +static void +divide_unpage( void ) +{ + divide_active = 0; + machine_current->ram.romcs = 0; + machine_current->memory_map(); + + debugger_event( unpage_event ); +} + +void +divide_memory_map( void ) +{ + int upper_ram_page; + + if( !divide_active ) return; + + /* low bits of divide_control register give page number to use in upper + bank; only lowest two bits on original 32K model */ + upper_ram_page = divide_control & (DIVIDE_PAGES - 1); + + if( divide_control & DIVIDE_CONTROL_CONMEM ) { + memory_map_romcs[0].page = divide_eprom; + memory_map_romcs[0].writable = !settings_current.divide_wp; + memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; + memory_map_romcs[1].writable = 1; + } else { + if( divide_control & DIVIDE_CONTROL_MAPRAM ) { + memory_map_romcs[0].page = divide_ram[3]; + memory_map_romcs[0].writable = 0; + memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; + memory_map_romcs[1].writable = ( upper_ram_page != 3 ); + } else { + memory_map_romcs[0].page = divide_eprom; + memory_map_romcs[0].writable = 0; + memory_map_romcs[1].page = divide_ram[ upper_ram_page ]; + memory_map_romcs[1].writable = 1; + } + } + + memory_map_read[0] = memory_map_write[0] = memory_map_romcs[0]; + memory_map_read[1] = memory_map_write[1] = memory_map_romcs[1]; +} + +static void +divide_enabled_snapshot( libspectrum_snap *snap ) +{ + if( libspectrum_snap_divide_active( snap ) ) + settings_current.divide_enabled = 1; +} + +static void +divide_from_snapshot( libspectrum_snap *snap ) +{ + size_t i; + + if( !libspectrum_snap_divide_active( snap ) ) return; + + settings_current.divide_wp = + libspectrum_snap_divide_eprom_writeprotect( snap ); + divide_control_write_internal( libspectrum_snap_divide_control( snap ) ); + + if( libspectrum_snap_divide_eprom( snap, 0 ) ) { + memcpy( divide_eprom, + libspectrum_snap_divide_eprom( snap, 0 ), DIVIDE_PAGE_LENGTH ); + } + + for( i = 0; i < libspectrum_snap_divide_pages( snap ); i++ ) + if( libspectrum_snap_divide_ram( snap, i ) ) + memcpy( divide_ram[ i ], libspectrum_snap_divide_ram( snap, i ), + DIVIDE_PAGE_LENGTH ); + + if( libspectrum_snap_divide_paged( snap ) ) { + divide_page(); + } else { + divide_unpage(); + } +} + +static void +divide_to_snapshot( libspectrum_snap *snap ) +{ + size_t i; + libspectrum_byte *buffer; + + if( !settings_current.divide_enabled ) return; + + libspectrum_snap_set_divide_active( snap, 1 ); + libspectrum_snap_set_divide_eprom_writeprotect( snap, + settings_current.divide_wp ); + libspectrum_snap_set_divide_paged( snap, divide_active ); + libspectrum_snap_set_divide_control( snap, divide_control ); + + buffer = malloc( DIVIDE_PAGE_LENGTH * sizeof( libspectrum_byte ) ); + if( !buffer ) { + ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); + return; + } + + memcpy( buffer, divide_eprom, DIVIDE_PAGE_LENGTH ); + libspectrum_snap_set_divide_eprom( snap, 0, buffer ); + + libspectrum_snap_set_divide_pages( snap, DIVIDE_PAGES ); + + for( i = 0; i < DIVIDE_PAGES; i++ ) { + + buffer = malloc( DIVIDE_PAGE_LENGTH * sizeof( libspectrum_byte ) ); + if( !buffer ) { + ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); + return; + } + + memcpy( buffer, divide_ram[ i ], DIVIDE_PAGE_LENGTH ); + libspectrum_snap_set_divide_ram( snap, i, buffer ); + } +} Copied: vendor/fuse-emulator/current/fuse/ide/divide.h (from rev 597, vendor/fuse-emulator/current/fuse/divide.h) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/divide.h (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/divide.h 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,54 @@ +/* divide.h: DivIDE interface routines + Copyright (c) 2005 Matthew Westcott + + $Id: divide.h 2993 2007-06-17 13:54:49Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#ifndef FUSE_DIVIDE_H +#define FUSE_DIVIDE_H + +#include <libspectrum.h> +#include "periph.h" + +extern const periph_t divide_peripherals[]; +extern const size_t divide_peripherals_count; + +/* Whether DivIDE is currently paged in */ +extern int divide_active; + +/* Notify DivIDE hardware of an opcode fetch to one of the designated + entry / exit points. Depending on configuration, it may or may not + result in the DivIDE memory being paged in */ +void divide_set_automap( int state ); + +/* Call this after some state change other than an opcode fetch which could + trigger DivIDE paging (such as updating the write-protect flag), to + re-evaluate whether paging will actually happen */ +void divide_refresh_page_state( void ); + +int divide_init( void ); +int divide_end( void ); +int divide_insert( const char *filename, libspectrum_ide_unit unit ); +int divide_commit( libspectrum_ide_unit unit ); +int divide_eject( libspectrum_ide_unit unit ); + +#endif /* #ifndef FUSE_DIVIDE_H */ Copied: vendor/fuse-emulator/current/fuse/ide/ide.c (from rev 597, vendor/fuse-emulator/current/fuse/ide.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/ide.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/ide.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,92 @@ +/* ide.c: Generic routines shared between the various IDE devices + Copyright (c) 2005 Philip Kendall + + $Id: ide.c 2889 2007-05-26 17:45:08Z zubzero $ + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#include <config.h> + +#include <libspectrum.h> + +#include "ide.h" +#include "ui/ui.h" +#include "settings.h" + +int +ide_insert( const char *filename, libspectrum_ide_channel *chn, + libspectrum_ide_unit unit, + int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, + ui_menu_item item ) +{ + int error; + + /* Remove any currently inserted disk; abort if we want to keep the current + disk */ + if( *setting ) + if( ide_eject( chn, unit, commit_fn, setting, item ) ) + return 0; + + error = settings_set_string( setting, filename ); if( error ) return error; + + error = libspectrum_ide_insert( chn, unit, filename ); + if( error ) return error; + + error = ui_menu_activate( item, 1 ); if( error ) return error; + + return 0; +} + +int +ide_eject( libspectrum_ide_channel *chn, libspectrum_ide_unit unit, + int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, + ui_menu_item item ) +{ + int error; + + if( libspectrum_ide_dirty( chn, unit ) ) { + + ui_confirm_save_t confirm = ui_confirm_save( + "Hard disk has been modified.\nDo you want to save it?" + ); + + switch( confirm ) { + + case UI_CONFIRM_SAVE_SAVE: + error = commit_fn( unit ); if( error ) return error; + break; + + case UI_CONFIRM_SAVE_DONTSAVE: break; + case UI_CONFIRM_SAVE_CANCEL: return 1; + + } + } + + free( *setting ); *setting = NULL; + + error = libspectrum_ide_eject( chn, unit ); + if( error ) return error; + + error = ui_menu_activate( item, 0 ); + if( error ) return error; + + return 0; +} Copied: vendor/fuse-emulator/current/fuse/ide/ide.h (from rev 597, vendor/fuse-emulator/current/fuse/ide.h) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/ide.h (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/ide.h 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,42 @@ +/* ide.h: Generic routines shared between the various IDE devices + Copyright (c) 2005 Philip Kendall + + $Id: ide.h 2889 2007-05-26 17:45:08Z zubzero $ + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#ifndef FUSE_IDE_H +#define FUSE_IDE_H + +#include "ui/ui.h" + +int +ide_insert( const char *filename, libspectrum_ide_channel *chn, + libspectrum_ide_unit unit, + int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, + ui_menu_item item ); + +int +ide_eject( libspectrum_ide_channel *chn, libspectrum_ide_unit unit, + int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, + ui_menu_item item ); + +#endif /* #ifndef FUSE_IDE_H */ Copied: vendor/fuse-emulator/current/fuse/ide/simpleide.c (from rev 597, vendor/fuse-emulator/current/fuse/simpleide.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/simpleide.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/simpleide.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,210 @@ +/* simpleide.c: Simple 8-bit IDE interface routines + Copyright (c) 2003-2004 Garry Lancaster, + 2004 Philip Kendall, + 2008 Fredrick Meunier + + $Id: simpleide.c 3703 2008-06-30 20:36:11Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#include <config.h> + +#include <libspectrum.h> + +#include "ide.h" +#include "module.h" +#include "periph.h" +#include "settings.h" +#include "simpleide.h" +#include "ui/ui.h" + +/* Private function prototypes */ + +static libspectrum_byte simpleide_read( libspectrum_word port, int *attached ); +static void simpleide_write( libspectrum_word port, libspectrum_byte data ); + +/* Data */ + +const periph_t simpleide_peripherals[] = { + { 0x0010, 0x0000, simpleide_read, simpleide_write }, +}; + +const size_t simpleide_peripherals_count = + sizeof( simpleide_peripherals ) / sizeof( periph_t ); + +static libspectrum_ide_channel *simpleide_idechn; + +static void simpleide_from_snapshot( libspectrum_snap *snap ); +static void simpleide_to_snapshot( libspectrum_snap *snap ); + +static module_info_t simpleide_module_info = { + + simpleide_reset, + NULL, + NULL, + simpleide_from_snapshot, + simpleide_to_snapshot, + +}; + +/* Housekeeping functions */ + +int +simpleide_init( void ) +{ + int error; + + simpleide_idechn = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA8 ); + + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_MASTER_EJECT, 0 ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_SLAVE_EJECT, 0 ); + + if( settings_current.simpleide_master_file ) { + error = libspectrum_ide_insert( simpleide_idechn, LIBSPECTRUM_IDE_MASTER, + settings_current.simpleide_master_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_MASTER_EJECT, 1 ); + } + + if( settings_current.simpleide_slave_file ) { + error = libspectrum_ide_insert( simpleide_idechn, LIBSPECTRUM_IDE_SLAVE, + settings_current.simpleide_slave_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_SLAVE_EJECT, 1 ); + } + + module_register( &simpleide_module_info ); + + return 0; +} + +int +simpleide_end( void ) +{ + return libspectrum_ide_free( simpleide_idechn ); +} + +void +simpleide_reset( int hard_reset GCC_UNUSED ) +{ + libspectrum_ide_reset( simpleide_idechn ); +} + +int +simpleide_insert( const char *filename, libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.simpleide_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.simpleide_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_insert( filename, simpleide_idechn, unit, simpleide_commit, + setting, item ); +} + +int +simpleide_commit( libspectrum_ide_unit unit ) +{ + int error; + + error = libspectrum_ide_commit( simpleide_idechn, unit ); + + return error; +} + +int +simpleide_eject( libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.simpleide_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.simpleide_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_eject( simpleide_idechn, unit, simpleide_commit, setting, item ); +} + +/* Port read/writes */ + +static libspectrum_byte +simpleide_read( libspectrum_word port, int *attached ) +{ + libspectrum_ide_register idereg; + + if( !settings_current.simpleide_active ) return 0xff; + + *attached = 1; + + idereg = ( ( port >> 8 ) & 0x01 ) | ( ( port >> 11 ) & 0x06 ); + + return libspectrum_ide_read( simpleide_idechn, idereg ); +} + +static void +simpleide_write( libspectrum_word port, libspectrum_byte data ) +{ + libspectrum_ide_register idereg; + + if( !settings_current.simpleide_active ) return; + + idereg = ( ( port >> 8 ) & 0x01 ) | ( ( port >> 11 ) & 0x06 ); + + libspectrum_ide_write( simpleide_idechn, idereg, data ); +} + +static void +simpleide_from_snapshot( libspectrum_snap *snap ) +{ + settings_current.simpleide_active = + libspectrum_snap_simpleide_active( snap ); +} + +static void +simpleide_to_snapshot( libspectrum_snap *snap ) +{ + if( !settings_current.simpleide_active ) return; + + libspectrum_snap_set_simpleide_active( snap, 1 ); +} Copied: vendor/fuse-emulator/current/fuse/ide/simpleide.h (from rev 597, vendor/fuse-emulator/current/fuse/simpleide.h) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/simpleide.h (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/simpleide.h 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,40 @@ +/* simpleide.h: Simple 8-bit IDE interface routines + Copyright (c) 2003-2004 Garry Lancaster + + $Id: simpleide.h 2995 2007-06-17 14:31:36Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + +*/ + +#ifndef FUSE_SIMPLEIDE_H +#define FUSE_SIMPLEIDE_H + +#include <libspectrum.h> +#include "periph.h" + +extern const periph_t simpleide_peripherals[]; +extern const size_t simpleide_peripherals_count; + +int simpleide_init( void ); +int simpleide_end( void ); +void simpleide_reset( int hard_reset ); +int simpleide_insert( const char *filename, libspectrum_ide_unit unit ); +int simpleide_commit( libspectrum_ide_unit unit ); +int simpleide_eject( libspectrum_ide_unit unit ); + +#endif /* #ifndef FUSE_SIMPLEIDE_H */ Copied: vendor/fuse-emulator/current/fuse/ide/zxatasp.c (from rev 597, vendor/fuse-emulator/current/fuse/zxatasp.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ide/zxatasp.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ide/zxatasp.c 2009-06-27 12:33:22 UTC (rev 598) @@ -0,0 +1,581 @@ +/* zxatasp.c: ZXATASP interface routines + Copyright (c) 2003-2008 Garry Lancaster and Philip Kendall + + $Id: zxatasp.c 3707 2008-06-30 21:33:49Z 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: Philip Kendall <phi...@sh...> + +*/ + +#include <config.h> + +#include <string.h> + +#include <libspectrum.h> + +#include "debugger/debugger.h" +#include "ide.h" +#include "machine.h" +#include "memory.h" +#include "module.h" +#include "periph.h" +#include "settings.h" +#include "ui/ui.h" +#include "zxatasp.h" + +/* + TBD: Allow memory size selection (128K/512K) + TBD: Should support for secondary channel be removed? + No software ever supported it, and v2.0+ boards don't have it. +*/ + + +/* Debugger events */ +static const char *event_type_string = "zxatasp"; +static int page_event, unpage_event; + +/* Private function prototypes */ + +static libspectrum_byte zxatasp_portA_read( libspectrum_word port, + int *attached ); +static void zxatasp_portA_write( libspectrum_word port, + libspectrum_byte data ); +static libspectrum_byte zxatasp_portB_read( libspectrum_word port, + int *attached ); +static void zxatasp_portB_write( libspectrum_word port, + libspectrum_byte data ); +static libspectrum_byte zxatasp_portC_read( libspectrum_word port, + int *attached ); +static void zxatasp_portC_write( libspectrum_word port, + libspectrum_byte data ); +static libspectrum_byte zxatasp_control_read( libspectrum_word port, + int *attached ); +static void zxatasp_control_write( libspectrum_word port, + libspectrum_byte data ); +static void zxatasp_resetports( void ); +static void set_zxatasp_bank( int bank ); + +static void zxatasp_readide( libspectrum_ide_channel *chn, + libspectrum_ide_register idereg ); +static void zxatasp_writeide( libspectrum_ide_channel *chn, + libspectrum_ide_register idereg ); + +/* Data */ + +const periph_t zxatasp_peripherals[] = { + { 0x039f, 0x009f, zxatasp_portA_read, zxatasp_portA_write }, + { 0x039f, 0x019f, zxatasp_portB_read, zxatasp_portB_write }, + { 0x039f, 0x029f, zxatasp_portC_read, zxatasp_portC_write }, + { 0x039f, 0x039f, zxatasp_control_read, zxatasp_control_write }, +}; + +const size_t zxatasp_peripherals_count = + sizeof( zxatasp_peripherals ) / sizeof( periph_t ); + +static libspectrum_byte zxatasp_control; +static libspectrum_byte zxatasp_portA; +static libspectrum_byte zxatasp_portB; +static libspectrum_byte zxatasp_portC; +static size_t current_page; + +static libspectrum_ide_channel *zxatasp_idechn0; +static libspectrum_ide_channel *zxatasp_idechn1; + +#define ZXATASP_PAGES 32 +#define ZXATASP_PAGE_LENGTH 0x4000 +static libspectrum_byte ZXATASPMEM[ ZXATASP_PAGES ][ ZXATASP_PAGE_LENGTH ]; + +static const size_t ZXATASP_NOT_PAGED = 0xff; + +/* We're ignoring all mode bits and only emulating mode 0, basic I/O */ +static const libspectrum_byte MC8255_PORT_C_LOW_IO = 0x01; +static const libspectrum_byte MC8255_PORT_B_IO = 0x02; +static const libspectrum_byte MC8255_PORT_C_HI_IO = 0x08; +static const libspectrum_byte MC8255_PORT_A_IO = 0x10; +static const libspectrum_byte MC8255_SETMODE = 0x80; + +static const libspectrum_byte ZXATASP_IDE_REG = 0x07; +static const libspectrum_byte ZXATASP_RAM_BANK = 0x1f; +static const libspectrum_byte ZXATASP_IDE_WR = 0x08; +static const libspectrum_byte ZXATASP_IDE_RD = 0x10; +static const libspectrum_byte ZXATASP_IDE_PRIMARY = 0x20; +static const libspectrum_byte ZXATASP_RAM_LATCH = 0x40; +static const libspectrum_byte ZXATASP_RAM_DISABLE = 0x80; +static const libspectrum_byte ZXATASP_IDE_SECONDARY = 0x80; + +#define ZXATASP_READ_PRIMARY( x ) \ + ( ( x & ( ZXATASP_IDE_PRIMARY | ZXATASP_RAM_LATCH | \ + ZXATASP_IDE_RD | ZXATASP_IDE_WR ) ) == \ + ( ZXATASP_IDE_PRIMARY | ZXATASP_IDE_RD ) ) +#define ZXATASP_WRITE_PRIMARY( x ) \ + ( ( x & ( ZXATASP_IDE_PRIMARY | ZXATASP_RAM_LATCH | \ + ZXATASP_IDE_RD | ZXATASP_IDE_WR ) ) == \ + ( ZXATASP_IDE_PRIMARY | ZXATASP_IDE_WR ) ) +#define ZXATASP_READ_SECONDARY( x ) \ + ( ( x & ( ZXATASP_IDE_SECONDARY | ZXATASP_RAM_LATCH | \ + ZXATASP_IDE_RD | ZXATASP_IDE_WR ) ) == \ + ( ZXATASP_IDE_SECONDARY | ZXATASP_IDE_RD ) ) +#define ZXATASP_WRITE_SECONDARY( x ) \ + ( ( x & ( ZXATASP_IDE_SECONDARY | ZXATASP_RAM_LATCH | \ + ZXATASP_IDE_RD | ZXATASP_IDE_WR ) ) == \ + ( ZXATASP_IDE_SECONDARY | ZXATASP_IDE_WR ) ) + +static void zxatasp_reset( int hard_reset ); +static void zxatasp_memory_map( void ); +static void zxatasp_from_snapshot( libspectrum_snap *snap ); +static void zxatasp_to_snapshot( libspectrum_snap *snap ); + +static module_info_t zxatasp_module_info = { + + zxatasp_reset, + zxatasp_memory_map, + NULL, + zxatasp_from_snapshot, + zxatasp_to_snapshot, + +}; + +/* Housekeeping functions */ + +int +zxatasp_init( void ) +{ + int error = 0; + + zxatasp_idechn0 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); + zxatasp_idechn1 = libspectrum_ide_alloc( LIBSPECTRUM_IDE_DATA16 ); + + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXATASP_MASTER_EJECT, 0 ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXATASP_SLAVE_EJECT, 0 ); + + if( settings_current.zxatasp_master_file ) { + error = libspectrum_ide_insert( zxatasp_idechn0, LIBSPECTRUM_IDE_MASTER, + settings_current.zxatasp_master_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXATASP_MASTER_EJECT, 1 ); + } + + if( settings_current.zxatasp_slave_file ) { + error = libspectrum_ide_insert( zxatasp_idechn0, LIBSPECTRUM_IDE_SLAVE, + settings_current.zxatasp_slave_file ); + if( error ) return error; + ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_ZXATASP_SLAVE_EJECT, 1 ); + } + + module_register( &zxatasp_module_info ); + + if( periph_register_paging_events( event_type_string, &page_event, + &unpage_event ) ) + return 1; + + return error; +} + +int +zxatasp_end( void ) +{ + int error; + + error = libspectrum_ide_free( zxatasp_idechn0 ); + error = libspectrum_ide_free( zxatasp_idechn1 ) || error; + + return error; +} + +static void +zxatasp_reset( int hard_reset GCC_UNUSED ) +{ + if( !settings_current.zxatasp_active ) return; + + machine_current->ram.romcs = 1; + + set_zxatasp_bank( 0 ); current_page = 0; + machine_current->memory_map(); + + zxatasp_control = MC8255_SETMODE | MC8255_PORT_A_IO | MC8255_PORT_B_IO | + MC8255_PORT_C_HI_IO | MC8255_PORT_C_LOW_IO; + zxatasp_resetports(); + + libspectrum_ide_reset( zxatasp_idechn0 ); + libspectrum_ide_reset( zxatasp_idechn1 ); +} + +int +zxatasp_insert( const char *filename, libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.zxatasp_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_ZXATASP_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.zxatasp_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_ZXATASP_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_insert( filename, zxatasp_idechn0, unit, zxatasp_commit, setting, + item ); +} + +int +zxatasp_commit( libspectrum_ide_unit unit ) +{ + int error; + + error = libspectrum_ide_commit( zxatasp_idechn0, unit ); + + return error; +} + +int +zxatasp_eject( libspectrum_ide_unit unit ) +{ + char **setting; + ui_menu_item item; + + switch( unit ) { + case LIBSPECTRUM_IDE_MASTER: + setting = &settings_current.zxatasp_master_file; + item = UI_MENU_ITEM_MEDIA_IDE_ZXATASP_MASTER_EJECT; + break; + + case LIBSPECTRUM_IDE_SLAVE: + setting = &settings_current.zxatasp_slave_file; + item = UI_MENU_ITEM_MEDIA_IDE_ZXATASP_SLAVE_EJECT; + break; + + default: return 1; + } + + return ide_eject( zxatasp_idechn0, unit, zxatasp_commit, setting, item ); +} + +/* Port read/writes */ + +libspectrum_byte +zxatasp_portA_read( libspectrum_word port GCC_UNUSED, int *attached ) +{ + if( !settings_current.zxatasp_active ) return 0xff; + + *attached = 1; + + return zxatasp_portA; +} + +static void +zxatasp_portA_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data ) +{ + if( !settings_current.zxatasp_active ) return; + + if( !( zxatasp_control & MC8255_PORT_A_IO ) ) zxatasp_portA = data; +} + +libspectrum_byte +zxatasp_portB_read( libspectrum_word port GCC_UNUSED, int *attached ) +{ + if( !settings_current.zxatasp_active ) return 0xff; + + *attached = 1; + + return zxatasp_portB; +} + +static void +zxatasp_portB_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data ) +{ + if( !settings_current.zxatasp_active ) return; + + if( !( zxatasp_control & MC8255_PORT_B_IO ) ) zxatasp_portB = data; +} + +libspectrum_byte +zxatasp_portC_read( libspectrum_word port GCC_UNUSED, int *attached ) +{ + if( !settings_current.zxatasp_active ) return 0xff; + + *attached = 1; + + return zxatasp_portC; +} + +static void +zxatasp_portC_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data ) +{ + libspectrum_byte oldC = zxatasp_portC; + libspectrum_byte newC; + + if( !settings_current.zxatasp_active ) return; + + /* Determine new port C value, dependent on I/O modes */ + newC = ( zxatasp_control & MC8255_PORT_C_LOW_IO ) + ? ( oldC & 0x0f ) : ( data & 0x0f ); + + newC |= ( zxatasp_control & MC8255_PORT_C_HI_IO ) + ? ( oldC & 0xf0 ) : ( data & 0xf0 ); + + /* Set the new port value */ + zxatasp_portC = newC; + + /* No action can occur if high part of port C is in input mode */ + if( zxatasp_control & MC8255_PORT_C_HI_IO ) return; + + /* Check for any I/O action */ + if( ( ZXATASP_READ_PRIMARY( newC ) ) & + !( ZXATASP_READ_PRIMARY( oldC ) ) ) { + zxatasp_readide( zxatasp_idechn0, ( newC & ZXATASP... [truncated message content] |