Thread: [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] |
From: <fr...@us...> - 2010-05-24 11:59:24
|
Revision: 636 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=636&view=rev Author: fredm Date: 2010-05-24 11:59:18 +0000 (Mon, 24 May 2010) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 1 rename. * vendor/fuse-emulator/current/fuse/sound.c: Renamed from vendor/fuse-emulator/current/fuse/sound.cpp. Added Paths: ----------- vendor/fuse-emulator/current/fuse/sound.c Removed Paths: ------------- vendor/fuse-emulator/current/fuse/sound.cpp Copied: vendor/fuse-emulator/current/fuse/sound.c (from rev 635, vendor/fuse-emulator/current/fuse/sound.cpp) =================================================================== --- vendor/fuse-emulator/current/fuse/sound.c (rev 0) +++ vendor/fuse-emulator/current/fuse/sound.c 2010-05-24 11:59:18 UTC (rev 636) @@ -0,0 +1,652 @@ +/* sound.cpp: Sound support + Copyright (c) 2000-2009 Russell Marks, Matan Ziv-Av, Philip Kendall, + Fredrick Meunier + + $Id: sound.cpp 4036 2009-06-13 09:57:55Z 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... + +*/ + +/* The AY white noise RNG algorithm is based on info from MAME's ay8910.c - + * MAME's licence explicitly permits free use of info (even encourages it). + */ + +extern "C" { +#include "fuse.h" +#include "machine.h" +#include "options.h" +#include "settings.h" +#include "sound.h" +#include "tape.h" +#include "ui/ui.h" +} + +#include "sound/Blip_Buffer.h" + +/* Do we have any of our sound devices available? */ + +/* configuration */ +int sound_enabled = 0; /* Are we currently using the sound card */ +int sound_enabled_ever = 0; /* if it's *ever* been in use; see + sound_ay_write() and sound_ay_reset() */ +int sound_stereo = 0; /* true for stereo *output sample* (only) */ +int sound_stereo_ay = 0; /* local copy of settings_current.stereo_ay */ + +/* assume all three tone channels together match the beeper volume (ish). + * Must be <=127 for all channels; 50+2+(24*3) = 124. + * (Now scaled up for 16-bit.) + */ +#define AMPL_BEEPER ( 50 * 256) +#define AMPL_TAPE ( 5 * 256 ) +#define AMPL_AY_TONE ( 24 * 256 ) /* three of these */ + +/* max. number of sub-frame AY port writes allowed; + * given the number of port writes theoretically possible in a + * 50th I think this should be plenty. + */ +#define AY_CHANGE_MAX 8000 + +int sound_freq; +int sound_framesiz; + +static int sound_channels; + +static unsigned int ay_tone_levels[16]; + +static unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick; +static unsigned int ay_tone_cycles, ay_env_cycles; +static unsigned int ay_env_internal_tick, ay_env_tick; +static unsigned int ay_tone_period[3], ay_noise_period, ay_env_period; + +/* Local copy of the AY registers */ +static libspectrum_byte sound_ay_registers[16]; + +struct ay_change_tag +{ + libspectrum_dword tstates; + unsigned char reg, val; +}; + +static struct ay_change_tag ay_change[ AY_CHANGE_MAX ]; +static int ay_change_count; + +Blip_Buffer *left_buf; +Blip_Buffer *right_buf; +blip_sample_t *samples; + +typedef Blip_Synth<blip_good_quality, blip_unscaled> fuse_synth; +fuse_synth *left_beeper_synth, *right_beeper_synth; + +fuse_synth *ay_a_synth, *ay_b_synth, *ay_c_synth; +fuse_synth *ay_a_synth_r, *ay_b_synth_r, *ay_c_synth_r; + +struct speaker_type_tag +{ + int bass; + double treble; +}; + +static struct speaker_type_tag speaker_type[] = + { { 200, -47.0 }, { 1000, -67.0 } }; + +static double +sound_get_volume( int volume ) +{ + if( volume < 0 ) volume = 0; + else if( volume > 100 ) volume = 100; + + return volume / 100.0; +} + +/* Returns the emulation speed adjusted processor speed */ +libspectrum_dword +sound_get_effective_processor_speed( void ) +{ + return machine_current->timings.processor_speed / 100 * + settings_current.emulation_speed; +} + +bool +sound_init_blip( Blip_Buffer **buf, fuse_synth **synth ) +{ + *buf = new Blip_Buffer(); + (*buf)->clock_rate( sound_get_effective_processor_speed() ); + /* Allow up to 1s of playback buffer - this allows us to cope with slowing + down to 2% of speed where a single Speccy frame generates just under 1s + of sound */ + if ( (*buf)->set_sample_rate( settings_current.sound_freq, 1000 ) ) { + sound_end(); + ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ ); + return false; + } + + *synth = new fuse_synth(); + + (*synth)->volume( sound_get_volume( settings_current.volume_beeper ) ); + (*synth)->output( *buf ); + + (*buf)->bass_freq( speaker_type[ option_enumerate_sound_speaker_type() ].bass ); + (*synth)->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + + return true; +} + +static void +sound_ay_init( void ) +{ + /* AY output doesn't match the claimed levels; these levels are based + * on the measurements posted to comp.sys.sinclair in Dec 2001 by + * Matthew Westcott, adjusted as I described in a followup to his post, + * then scaled to 0..0xffff. + */ + static const int levels[16] = { + 0x0000, 0x0385, 0x053D, 0x0770, + 0x0AD7, 0x0FD5, 0x15B0, 0x230C, + 0x2B4C, 0x43C1, 0x5A4B, 0x732F, + 0x9204, 0xAFF1, 0xD921, 0xFFFF + }; + int f; + + /* scale the values down to fit */ + for( f = 0; f < 16; f++ ) + ay_tone_levels[f] = ( levels[f] * AMPL_AY_TONE + 0x8000 ) / 0xffff; + + ay_noise_tick = ay_noise_period = 0; + ay_env_internal_tick = ay_env_tick = ay_env_period = 0; + ay_tone_cycles = ay_env_cycles = 0; + for( f = 0; f < 3; f++ ) + ay_tone_tick[f] = ay_tone_high[f] = 0, ay_tone_period[f] = 1; + + ay_change_count = 0; +} + +void +sound_init( const char *device ) +{ + int ret; + float hz; + + /* Allow sound as long as emulation speed is greater than 2% + (less than that and a single Speccy frame generates more + than a seconds worth of sound which is bigger than the + maximum Blip_Buffer of 1 second) */ + if( !( !sound_enabled && settings_current.sound && + settings_current.emulation_speed > 1 ) ) + return; + + sound_stereo_ay = settings_current.stereo_ay; + + /* only try for stereo if we need it */ + if( sound_stereo_ay ) + sound_stereo = 1; + + ret = + sound_lowlevel_init( device, &settings_current.sound_freq, &sound_stereo ); + + if( ret ) + return; + + if( !sound_init_blip(&left_buf, &left_beeper_synth) ) return; + if( sound_stereo && !sound_init_blip(&right_buf, &right_beeper_synth) ) return; + + ay_a_synth = new fuse_synth(); + ay_a_synth->volume( sound_get_volume( settings_current.volume_ay) ); + ay_a_synth->output( left_buf ); + ay_a_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + + ay_b_synth = new fuse_synth(); + ay_b_synth->volume( sound_get_volume( settings_current.volume_ay) ); + ay_b_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + + ay_c_synth = new fuse_synth(); + ay_c_synth->volume( sound_get_volume( settings_current.volume_ay) ); + ay_c_synth->output( left_buf ); + ay_c_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + + /* important to override these settings if not using stereo + * (it would probably be confusing to mess with the stereo + * settings in settings_current though, which is why we make copies + * rather than using the real ones). + */ + if( !sound_stereo ) { + sound_stereo_ay = 0; + } + + ay_a_synth_r = 0; + ay_b_synth_r = 0; + ay_c_synth_r = 0; + + if( sound_stereo ) { + ay_c_synth_r = new fuse_synth(); + ay_c_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); + ay_c_synth_r->output( right_buf ); + + if( sound_stereo_ay ) { + /* stereo with ACB stereo. */ + ay_b_synth->output( right_buf ); + } else { + ay_a_synth_r = new fuse_synth(); + ay_a_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); + ay_a_synth_r->output( right_buf ); + ay_a_synth_r->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + + ay_b_synth->output( left_buf ); + + ay_b_synth_r = new fuse_synth(); + ay_b_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); + ay_b_synth_r->output( right_buf ); + ay_b_synth_r->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); + } + } else { + ay_b_synth->output( left_buf ); + } + + sound_enabled = sound_enabled_ever = 1; + + sound_channels = ( sound_stereo ? 2 : 1 ); + + /* Adjust relative processor speed to deal with adjusting sound generation + frequency against emulation speed (more flexible than adjusting generated + sample rate) */ + hz = ( float )sound_get_effective_processor_speed() / + machine_current->timings.tstates_per_frame; + + /* Size of audio data we will get from running a single Spectrum frame */ + sound_framesiz = ( float )settings_current.sound_freq / hz; + sound_framesiz++; + + samples = (blip_sample_t *)calloc( sound_framesiz * sound_channels, + sizeof(blip_sample_t) ); +} + +void +sound_pause( void ) +{ + if( sound_enabled ) + sound_end(); +} + +void +sound_unpause( void ) +{ + /* No sound if fastloading in progress */ + if( settings_current.fastload && tape_is_playing() ) + return; + + sound_init( settings_current.sound_device ); +} + +void +sound_end( void ) +{ + if( sound_enabled ) { + delete left_beeper_synth; left_beeper_synth = 0; + delete left_buf; left_buf = 0; + delete right_beeper_synth; right_beeper_synth = 0; + delete right_buf; right_buf = 0; + + delete ay_a_synth; ay_a_synth = 0; + delete ay_b_synth; ay_b_synth = 0; + delete ay_c_synth; ay_c_synth = 0; + delete ay_a_synth_r; ay_a_synth_r = 0; + delete ay_b_synth_r; ay_b_synth_r = 0; + delete ay_c_synth_r; ay_c_synth_r = 0; + + sound_lowlevel_end(); + free( samples ); + sound_enabled = 0; + } +} + +static inline void +ay_do_tone( int level, unsigned int tone_count, int& var, int chan ) +{ + var = 0; + + ay_tone_tick[ chan ] += tone_count; + + if( ay_tone_tick[ chan ] >= ay_tone_period[ chan ] ) { + ay_tone_tick[ chan ] -= ay_tone_period[ chan ]; + ay_tone_high[ chan ] = !ay_tone_high[ chan ]; + } + + if( level ) { + if( ay_tone_high[ chan ] ) + var = level; + else { + var = -level; + } + } + + /* The AY output goes from 0 to the maximum volume, so there + * is a DC component that is half the maxmum volume. + * Robocop uses a high frequency square wave with a tone + * period of one to average out to being like a DC offset at + * around half the maximum volume. This is used as a base for + * the sample playback. + * This seems to intefere with our attempt to remove the + * returned DC offset, so for now we just ignore the high + * frequency wave and hope it's a sample + */ + if( ay_tone_period[ chan ] == 1 ) { + var = -level; + } +} + +/* bitmasks for envelope */ +#define AY_ENV_CONT 8 +#define AY_ENV_ATTACK 4 +#define AY_ENV_ALT 2 +#define AY_ENV_HOLD 1 + +/* the AY steps down the external clock by 16 for tone and noise + generators */ +#define AY_CLOCK_DIVISOR 16 +/* all Spectrum models and clones with an AY seem to count down the + master clock by 2 to drive the AY */ +#define AY_CLOCK_RATIO 2 + +static void +sound_ay_overlay( void ) +{ + static int rng = 1; + static int noise_toggle = 0; + static int env_first = 1, env_rev = 0, env_counter = 15; + int tone_level[3]; + int mixer, envshape; + int g, level; + libspectrum_dword f; + struct ay_change_tag *change_ptr = ay_change; + int changes_left = ay_change_count; + int reg, r; + int chan1, chan2, chan3; + int last_chan1 = 0, last_chan2 = 0, last_chan3 = 0; + unsigned int tone_count, noise_count; + + /* If no AY chip, don't produce any AY sound (!) */ + if( !( periph_fuller_active || periph_melodik_active || + machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) ) + return; + + for( f = 0; f < machine_current->timings.tstates_per_frame; + f+= AY_CLOCK_DIVISOR * AY_CLOCK_RATIO ) { + /* update ay registers. */ + while( changes_left && f >= change_ptr->tstates ) { + sound_ay_registers[ reg = change_ptr->reg ] = change_ptr->val; + change_ptr++; + changes_left--; + + /* fix things as needed for some register changes */ + switch ( reg ) { + case 0: case 1: case 2: case 3: case 4: case 5: + r = reg >> 1; + /* a zero-len period is the same as 1 */ + ay_tone_period[r] = ( sound_ay_registers[ reg & ~1 ] | + ( sound_ay_registers[ reg | 1 ] & 15 ) << 8 ); + if( !ay_tone_period[r] ) + ay_tone_period[r]++; + + /* important to get this right, otherwise e.g. Ghouls 'n' Ghosts + * has really scratchy, horrible-sounding vibrato. + */ + if( ay_tone_tick[r] >= ay_tone_period[r] * 2 ) + ay_tone_tick[r] %= ay_tone_period[r] * 2; + break; + case 6: + ay_noise_tick = 0; + ay_noise_period = ( sound_ay_registers[ reg ] & 31 ); + break; + case 11: case 12: + ay_env_period = + sound_ay_registers[11] | ( sound_ay_registers[12] << 8 ); + break; + case 13: + ay_env_internal_tick = ay_env_tick = ay_env_cycles = 0; + env_first = 1; + env_rev = 0; + env_counter = ( sound_ay_registers[13] & AY_ENV_ATTACK ) ? 0 : 15; + break; + } + } + + /* the tone level if no enveloping is being used */ + for( g = 0; g < 3; g++ ) + tone_level[g] = ay_tone_levels[ sound_ay_registers[ 8 + g ] & 15 ]; + + /* envelope */ + envshape = sound_ay_registers[13]; + level = ay_tone_levels[ env_counter ]; + + for( g = 0; g < 3; g++ ) + if( sound_ay_registers[ 8 + g ] & 16 ) + tone_level[g] = level; + + /* envelope output counter gets incr'd every 16 AY cycles. */ + ay_env_cycles += AY_CLOCK_DIVISOR; + noise_count = 0; + while( ay_env_cycles >= 16 ) { + ay_env_cycles -= 16; + noise_count++; + ay_env_tick++; + while( ay_env_tick >= ay_env_period ) { + ay_env_tick -= ay_env_period; + + /* do a 1/16th-of-period incr/decr if needed */ + if( env_first || + ( ( envshape & AY_ENV_CONT ) && !( envshape & AY_ENV_HOLD ) ) ) { + if( env_rev ) + env_counter -= ( envshape & AY_ENV_ATTACK ) ? 1 : -1; + else + env_counter += ( envshape & AY_ENV_ATTACK ) ? 1 : -1; + if( env_counter < 0 ) + env_counter = 0; + if( env_counter > 15 ) + env_counter = 15; + } + + ay_env_internal_tick++; + while( ay_env_internal_tick >= 16 ) { + ay_env_internal_tick -= 16; + + /* end of cycle */ + if( !( envshape & AY_ENV_CONT ) ) + env_counter = 0; + else { + if( envshape & AY_ENV_HOLD ) { + if( env_first && ( envshape & AY_ENV_ALT ) ) + env_counter = ( env_counter ? 0 : 15 ); + } else { + /* non-hold */ + if( envshape & AY_ENV_ALT ) + env_rev = !env_rev; + else + env_counter = ( envshape & AY_ENV_ATTACK ) ? 0 : 15; + } + } + + env_first = 0; + } + + /* don't keep trying if period is zero */ + if( !ay_env_period ) + break; + } + } + + /* generate tone+noise... or neither. + * (if no tone/noise is selected, the chip just shoves the + * level out unmodified. This is used by some sample-playing + * stuff.) + */ + chan1 = tone_level[0]; + chan2 = tone_level[1]; + chan3 = tone_level[2]; + mixer = sound_ay_registers[7]; + + ay_tone_cycles += AY_CLOCK_DIVISOR; + tone_count = ay_tone_cycles >> 3; + ay_tone_cycles &= 7; + + if( ( mixer & 1 ) == 0 ) { + level = chan1; + ay_do_tone( level, tone_count, chan1, 0 ); + } + if( ( mixer & 0x08 ) == 0 && noise_toggle ) + chan1 = 0; + + if( ( mixer & 2 ) == 0 ) { + level = chan2; + ay_do_tone( level, tone_count, chan2, 1 ); + } + if( ( mixer & 0x10 ) == 0 && noise_toggle ) + chan2 = 0; + + if( ( mixer & 4 ) == 0 ) { + level = chan3; + ay_do_tone( level, tone_count, chan3, 2 ); + } + if( ( mixer & 0x20 ) == 0 && noise_toggle ) + chan3 = 0; + + if( last_chan1 != chan1 ) { + ay_a_synth->update( f, chan1 ); + if( ay_a_synth_r ) ay_a_synth_r->update( f, chan1 ); + last_chan1 = chan1; + } + if( last_chan2 != chan2 ) { + ay_b_synth->update( f, chan2 ); + if( ay_b_synth_r ) ay_b_synth_r->update( f, chan2 ); + last_chan2 = chan2; + } + if( last_chan3 != chan3 ) { + ay_c_synth->update( f, chan3 ); + if( ay_c_synth_r ) ay_c_synth_r->update( f, chan3 ); + last_chan3 = chan3; + } + + /* update noise RNG/filter */ + ay_noise_tick += noise_count; + while( ay_noise_tick >= ay_noise_period ) { + ay_noise_tick -= ay_noise_period; + + if( ( rng & 1 ) ^ ( ( rng & 2 ) ? 1 : 0 ) ) + noise_toggle = !noise_toggle; + + /* rng is 17-bit shift reg, bit 0 is output. + * input is bit 0 xor bit 2. + */ + rng |= ( ( rng & 1 ) ^ ( ( rng & 4 ) ? 1 : 0 ) ) ? 0x20000 : 0; + rng >>= 1; + + /* don't keep trying if period is zero */ + if( !ay_noise_period ) + break; + } + } +} + +/* don't make the change immediately; record it for later, + * to be made by sound_frame() (via sound_ay_overlay()). + */ +void +sound_ay_write( int reg, int val, libspectrum_dword now ) +{ + if( ay_change_count < AY_CHANGE_MAX ) { + ay_change[ ay_change_count ].tstates = now; + ay_change[ ay_change_count ].reg = ( reg & 15 ); + ay_change[ ay_change_count ].val = val; + ay_change_count++; + } +} + +/* no need to call this initially, but should be called + * on reset otherwise. + */ +void +sound_ay_reset( void ) +{ + int f; + + /* recalculate timings based on new machines ay clock */ + sound_ay_init(); + + ay_change_count = 0; + for( f = 0; f < 16; f++ ) + sound_ay_write( f, 0, 0 ); + for( f = 0; f < 3; f++ ) + ay_tone_high[f] = 0; + ay_tone_cycles = ay_env_cycles = 0; +} + +void +sound_frame( void ) +{ + long count; + + if( !sound_enabled ) + return; + + /* overlay AY sound */ + sound_ay_overlay(); + + left_buf->end_frame( machine_current->timings.tstates_per_frame ); + + if( sound_stereo ) { + right_buf->end_frame( machine_current->timings.tstates_per_frame ); + + /* Read left channel into even samples, right channel into odd samples: + LRLRLRLRLR... */ + count = left_buf->read_samples( samples, sound_framesiz, 1 ); + right_buf->read_samples( samples + 1, count, 1 ); + count <<= 1; + } else { + count = left_buf->read_samples( samples, sound_framesiz ); + } + + sound_lowlevel_frame( samples, count ); + + ay_change_count = 0; +} + +void +sound_beeper( int on ) +{ + static int beeper_ampl[] = { 0, AMPL_TAPE, AMPL_BEEPER, AMPL_BEEPER+AMPL_TAPE }; + + int val; + int ampl; + + if( !sound_enabled ) + return; + + /* Timex machines have no loading noise */ + if( tape_is_playing() && + ( !settings_current.sound_load || machine_current->timex ) ) + on = on & 0x02; + + ampl = beeper_ampl[on]; + + val = -beeper_ampl[3] + ampl*2; + + left_beeper_synth->update( tstates, val ); + if( sound_stereo ) { + right_beeper_synth->update( tstates, val ); + } +} Deleted: vendor/fuse-emulator/current/fuse/sound.cpp =================================================================== --- vendor/fuse-emulator/current/fuse/sound.cpp 2010-04-06 11:24:38 UTC (rev 635) +++ vendor/fuse-emulator/current/fuse/sound.cpp 2010-05-24 11:59:18 UTC (rev 636) @@ -1,652 +0,0 @@ -/* sound.cpp: Sound support - Copyright (c) 2000-2009 Russell Marks, Matan Ziv-Av, Philip Kendall, - Fredrick Meunier - - $Id: sound.cpp 4036 2009-06-13 09:57:55Z 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... - -*/ - -/* The AY white noise RNG algorithm is based on info from MAME's ay8910.c - - * MAME's licence explicitly permits free use of info (even encourages it). - */ - -extern "C" { -#include "fuse.h" -#include "machine.h" -#include "options.h" -#include "settings.h" -#include "sound.h" -#include "tape.h" -#include "ui/ui.h" -} - -#include "sound/Blip_Buffer.h" - -/* Do we have any of our sound devices available? */ - -/* configuration */ -int sound_enabled = 0; /* Are we currently using the sound card */ -int sound_enabled_ever = 0; /* if it's *ever* been in use; see - sound_ay_write() and sound_ay_reset() */ -int sound_stereo = 0; /* true for stereo *output sample* (only) */ -int sound_stereo_ay = 0; /* local copy of settings_current.stereo_ay */ - -/* assume all three tone channels together match the beeper volume (ish). - * Must be <=127 for all channels; 50+2+(24*3) = 124. - * (Now scaled up for 16-bit.) - */ -#define AMPL_BEEPER ( 50 * 256) -#define AMPL_TAPE ( 5 * 256 ) -#define AMPL_AY_TONE ( 24 * 256 ) /* three of these */ - -/* max. number of sub-frame AY port writes allowed; - * given the number of port writes theoretically possible in a - * 50th I think this should be plenty. - */ -#define AY_CHANGE_MAX 8000 - -int sound_freq; -int sound_framesiz; - -static int sound_channels; - -static unsigned int ay_tone_levels[16]; - -static unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick; -static unsigned int ay_tone_cycles, ay_env_cycles; -static unsigned int ay_env_internal_tick, ay_env_tick; -static unsigned int ay_tone_period[3], ay_noise_period, ay_env_period; - -/* Local copy of the AY registers */ -static libspectrum_byte sound_ay_registers[16]; - -struct ay_change_tag -{ - libspectrum_dword tstates; - unsigned char reg, val; -}; - -static struct ay_change_tag ay_change[ AY_CHANGE_MAX ]; -static int ay_change_count; - -Blip_Buffer *left_buf; -Blip_Buffer *right_buf; -blip_sample_t *samples; - -typedef Blip_Synth<blip_good_quality, blip_unscaled> fuse_synth; -fuse_synth *left_beeper_synth, *right_beeper_synth; - -fuse_synth *ay_a_synth, *ay_b_synth, *ay_c_synth; -fuse_synth *ay_a_synth_r, *ay_b_synth_r, *ay_c_synth_r; - -struct speaker_type_tag -{ - int bass; - double treble; -}; - -static struct speaker_type_tag speaker_type[] = - { { 200, -47.0 }, { 1000, -67.0 } }; - -static double -sound_get_volume( int volume ) -{ - if( volume < 0 ) volume = 0; - else if( volume > 100 ) volume = 100; - - return volume / 100.0; -} - -/* Returns the emulation speed adjusted processor speed */ -libspectrum_dword -sound_get_effective_processor_speed( void ) -{ - return machine_current->timings.processor_speed / 100 * - settings_current.emulation_speed; -} - -bool -sound_init_blip( Blip_Buffer **buf, fuse_synth **synth ) -{ - *buf = new Blip_Buffer(); - (*buf)->clock_rate( sound_get_effective_processor_speed() ); - /* Allow up to 1s of playback buffer - this allows us to cope with slowing - down to 2% of speed where a single Speccy frame generates just under 1s - of sound */ - if ( (*buf)->set_sample_rate( settings_current.sound_freq, 1000 ) ) { - sound_end(); - ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ ); - return false; - } - - *synth = new fuse_synth(); - - (*synth)->volume( sound_get_volume( settings_current.volume_beeper ) ); - (*synth)->output( *buf ); - - (*buf)->bass_freq( speaker_type[ option_enumerate_sound_speaker_type() ].bass ); - (*synth)->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - - return true; -} - -static void -sound_ay_init( void ) -{ - /* AY output doesn't match the claimed levels; these levels are based - * on the measurements posted to comp.sys.sinclair in Dec 2001 by - * Matthew Westcott, adjusted as I described in a followup to his post, - * then scaled to 0..0xffff. - */ - static const int levels[16] = { - 0x0000, 0x0385, 0x053D, 0x0770, - 0x0AD7, 0x0FD5, 0x15B0, 0x230C, - 0x2B4C, 0x43C1, 0x5A4B, 0x732F, - 0x9204, 0xAFF1, 0xD921, 0xFFFF - }; - int f; - - /* scale the values down to fit */ - for( f = 0; f < 16; f++ ) - ay_tone_levels[f] = ( levels[f] * AMPL_AY_TONE + 0x8000 ) / 0xffff; - - ay_noise_tick = ay_noise_period = 0; - ay_env_internal_tick = ay_env_tick = ay_env_period = 0; - ay_tone_cycles = ay_env_cycles = 0; - for( f = 0; f < 3; f++ ) - ay_tone_tick[f] = ay_tone_high[f] = 0, ay_tone_period[f] = 1; - - ay_change_count = 0; -} - -void -sound_init( const char *device ) -{ - int ret; - float hz; - - /* Allow sound as long as emulation speed is greater than 2% - (less than that and a single Speccy frame generates more - than a seconds worth of sound which is bigger than the - maximum Blip_Buffer of 1 second) */ - if( !( !sound_enabled && settings_current.sound && - settings_current.emulation_speed > 1 ) ) - return; - - sound_stereo_ay = settings_current.stereo_ay; - - /* only try for stereo if we need it */ - if( sound_stereo_ay ) - sound_stereo = 1; - - ret = - sound_lowlevel_init( device, &settings_current.sound_freq, &sound_stereo ); - - if( ret ) - return; - - if( !sound_init_blip(&left_buf, &left_beeper_synth) ) return; - if( sound_stereo && !sound_init_blip(&right_buf, &right_beeper_synth) ) return; - - ay_a_synth = new fuse_synth(); - ay_a_synth->volume( sound_get_volume( settings_current.volume_ay) ); - ay_a_synth->output( left_buf ); - ay_a_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - - ay_b_synth = new fuse_synth(); - ay_b_synth->volume( sound_get_volume( settings_current.volume_ay) ); - ay_b_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - - ay_c_synth = new fuse_synth(); - ay_c_synth->volume( sound_get_volume( settings_current.volume_ay) ); - ay_c_synth->output( left_buf ); - ay_c_synth->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - - /* important to override these settings if not using stereo - * (it would probably be confusing to mess with the stereo - * settings in settings_current though, which is why we make copies - * rather than using the real ones). - */ - if( !sound_stereo ) { - sound_stereo_ay = 0; - } - - ay_a_synth_r = 0; - ay_b_synth_r = 0; - ay_c_synth_r = 0; - - if( sound_stereo ) { - ay_c_synth_r = new fuse_synth(); - ay_c_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); - ay_c_synth_r->output( right_buf ); - - if( sound_stereo_ay ) { - /* stereo with ACB stereo. */ - ay_b_synth->output( right_buf ); - } else { - ay_a_synth_r = new fuse_synth(); - ay_a_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); - ay_a_synth_r->output( right_buf ); - ay_a_synth_r->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - - ay_b_synth->output( left_buf ); - - ay_b_synth_r = new fuse_synth(); - ay_b_synth_r->volume( sound_get_volume( settings_current.volume_ay ) ); - ay_b_synth_r->output( right_buf ); - ay_b_synth_r->treble_eq( speaker_type[ option_enumerate_sound_speaker_type() ].treble ); - } - } else { - ay_b_synth->output( left_buf ); - } - - sound_enabled = sound_enabled_ever = 1; - - sound_channels = ( sound_stereo ? 2 : 1 ); - - /* Adjust relative processor speed to deal with adjusting sound generation - frequency against emulation speed (more flexible than adjusting generated - sample rate) */ - hz = ( float )sound_get_effective_processor_speed() / - machine_current->timings.tstates_per_frame; - - /* Size of audio data we will get from running a single Spectrum frame */ - sound_framesiz = ( float )settings_current.sound_freq / hz; - sound_framesiz++; - - samples = (blip_sample_t *)calloc( sound_framesiz * sound_channels, - sizeof(blip_sample_t) ); -} - -void -sound_pause( void ) -{ - if( sound_enabled ) - sound_end(); -} - -void -sound_unpause( void ) -{ - /* No sound if fastloading in progress */ - if( settings_current.fastload && tape_is_playing() ) - return; - - sound_init( settings_current.sound_device ); -} - -void -sound_end( void ) -{ - if( sound_enabled ) { - delete left_beeper_synth; left_beeper_synth = 0; - delete left_buf; left_buf = 0; - delete right_beeper_synth; right_beeper_synth = 0; - delete right_buf; right_buf = 0; - - delete ay_a_synth; ay_a_synth = 0; - delete ay_b_synth; ay_b_synth = 0; - delete ay_c_synth; ay_c_synth = 0; - delete ay_a_synth_r; ay_a_synth_r = 0; - delete ay_b_synth_r; ay_b_synth_r = 0; - delete ay_c_synth_r; ay_c_synth_r = 0; - - sound_lowlevel_end(); - free( samples ); - sound_enabled = 0; - } -} - -static inline void -ay_do_tone( int level, unsigned int tone_count, int& var, int chan ) -{ - var = 0; - - ay_tone_tick[ chan ] += tone_count; - - if( ay_tone_tick[ chan ] >= ay_tone_period[ chan ] ) { - ay_tone_tick[ chan ] -= ay_tone_period[ chan ]; - ay_tone_high[ chan ] = !ay_tone_high[ chan ]; - } - - if( level ) { - if( ay_tone_high[ chan ] ) - var = level; - else { - var = -level; - } - } - - /* The AY output goes from 0 to the maximum volume, so there - * is a DC component that is half the maxmum volume. - * Robocop uses a high frequency square wave with a tone - * period of one to average out to being like a DC offset at - * around half the maximum volume. This is used as a base for - * the sample playback. - * This seems to intefere with our attempt to remove the - * returned DC offset, so for now we just ignore the high - * frequency wave and hope it's a sample - */ - if( ay_tone_period[ chan ] == 1 ) { - var = -level; - } -} - -/* bitmasks for envelope */ -#define AY_ENV_CONT 8 -#define AY_ENV_ATTACK 4 -#define AY_ENV_ALT 2 -#define AY_ENV_HOLD 1 - -/* the AY steps down the external clock by 16 for tone and noise - generators */ -#define AY_CLOCK_DIVISOR 16 -/* all Spectrum models and clones with an AY seem to count down the - master clock by 2 to drive the AY */ -#define AY_CLOCK_RATIO 2 - -static void -sound_ay_overlay( void ) -{ - static int rng = 1; - static int noise_toggle = 0; - static int env_first = 1, env_rev = 0, env_counter = 15; - int tone_level[3]; - int mixer, envshape; - int g, level; - libspectrum_dword f; - struct ay_change_tag *change_ptr = ay_change; - int changes_left = ay_change_count; - int reg, r; - int chan1, chan2, chan3; - int last_chan1 = 0, last_chan2 = 0, last_chan3 = 0; - unsigned int tone_count, noise_count; - - /* If no AY chip, don't produce any AY sound (!) */ - if( !( periph_fuller_active || periph_melodik_active || - machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) ) - return; - - for( f = 0; f < machine_current->timings.tstates_per_frame; - f+= AY_CLOCK_DIVISOR * AY_CLOCK_RATIO ) { - /* update ay registers. */ - while( changes_left && f >= change_ptr->tstates ) { - sound_ay_registers[ reg = change_ptr->reg ] = change_ptr->val; - change_ptr++; - changes_left--; - - /* fix things as needed for some register changes */ - switch ( reg ) { - case 0: case 1: case 2: case 3: case 4: case 5: - r = reg >> 1; - /* a zero-len period is the same as 1 */ - ay_tone_period[r] = ( sound_ay_registers[ reg & ~1 ] | - ( sound_ay_registers[ reg | 1 ] & 15 ) << 8 ); - if( !ay_tone_period[r] ) - ay_tone_period[r]++; - - /* important to get this right, otherwise e.g. Ghouls 'n' Ghosts - * has really scratchy, horrible-sounding vibrato. - */ - if( ay_tone_tick[r] >= ay_tone_period[r] * 2 ) - ay_tone_tick[r] %= ay_tone_period[r] * 2; - break; - case 6: - ay_noise_tick = 0; - ay_noise_period = ( sound_ay_registers[ reg ] & 31 ); - break; - case 11: case 12: - ay_env_period = - sound_ay_registers[11] | ( sound_ay_registers[12] << 8 ); - break; - case 13: - ay_env_internal_tick = ay_env_tick = ay_env_cycles = 0; - env_first = 1; - env_rev = 0; - env_counter = ( sound_ay_registers[13] & AY_ENV_ATTACK ) ? 0 : 15; - break; - } - } - - /* the tone level if no enveloping is being used */ - for( g = 0; g < 3; g++ ) - tone_level[g] = ay_tone_levels[ sound_ay_registers[ 8 + g ] & 15 ]; - - /* envelope */ - envshape = sound_ay_registers[13]; - level = ay_tone_levels[ env_counter ]; - - for( g = 0; g < 3; g++ ) - if( sound_ay_registers[ 8 + g ] & 16 ) - tone_level[g] = level; - - /* envelope output counter gets incr'd every 16 AY cycles. */ - ay_env_cycles += AY_CLOCK_DIVISOR; - noise_count = 0; - while( ay_env_cycles >= 16 ) { - ay_env_cycles -= 16; - noise_count++; - ay_env_tick++; - while( ay_env_tick >= ay_env_period ) { - ay_env_tick -= ay_env_period; - - /* do a 1/16th-of-period incr/decr if needed */ - if( env_first || - ( ( envshape & AY_ENV_CONT ) && !( envshape & AY_ENV_HOLD ) ) ) { - if( env_rev ) - env_counter -= ( envshape & AY_ENV_ATTACK ) ? 1 : -1; - else - env_counter += ( envshape & AY_ENV_ATTACK ) ? 1 : -1; - if( env_counter < 0 ) - env_counter = 0; - if( env_counter > 15 ) - env_counter = 15; - } - - ay_env_internal_tick++; - while( ay_env_internal_tick >= 16 ) { - ay_env_internal_tick -= 16; - - /* end of cycle */ - if( !( envshape & AY_ENV_CONT ) ) - env_counter = 0; - else { - if( envshape & AY_ENV_HOLD ) { - if( env_first && ( envshape & AY_ENV_ALT ) ) - env_counter = ( env_counter ? 0 : 15 ); - } else { - /* non-hold */ - if( envshape & AY_ENV_ALT ) - env_rev = !env_rev; - else - env_counter = ( envshape & AY_ENV_ATTACK ) ? 0 : 15; - } - } - - env_first = 0; - } - - /* don't keep trying if period is zero */ - if( !ay_env_period ) - break; - } - } - - /* generate tone+noise... or neither. - * (if no tone/noise is selected, the chip just shoves the - * level out unmodified. This is used by some sample-playing - * stuff.) - */ - chan1 = tone_level[0]; - chan2 = tone_level[1]; - chan3 = tone_level[2]; - mixer = sound_ay_registers[7]; - - ay_tone_cycles += AY_CLOCK_DIVISOR; - tone_count = ay_tone_cycles >> 3; - ay_tone_cycles &= 7; - - if( ( mixer & 1 ) == 0 ) { - level = chan1; - ay_do_tone( level, tone_count, chan1, 0 ); - } - if( ( mixer & 0x08 ) == 0 && noise_toggle ) - chan1 = 0; - - if( ( mixer & 2 ) == 0 ) { - level = chan2; - ay_do_tone( level, tone_count, chan2, 1 ); - } - if( ( mixer & 0x10 ) == 0 && noise_toggle ) - chan2 = 0; - - if( ( mixer & 4 ) == 0 ) { - level = chan3; - ay_do_tone( level, tone_count, chan3, 2 ); - } - if( ( mixer & 0x20 ) == 0 && noise_toggle ) - chan3 = 0; - - if( last_chan1 != chan1 ) { - ay_a_synth->update( f, chan1 ); - if( ay_a_synth_r ) ay_a_synth_r->update( f, chan1 ); - last_chan1 = chan1; - } - if( last_chan2 != chan2 ) { - ay_b_synth->update( f, chan2 ); - if( ay_b_synth_r ) ay_b_synth_r->update( f, chan2 ); - last_chan2 = chan2; - } - if( last_chan3 != chan3 ) { - ay_c_synth->update( f, chan3 ); - if( ay_c_synth_r ) ay_c_synth_r->update( f, chan3 ); - last_chan3 = chan3; - } - - /* update noise RNG/filter */ - ay_noise_tick += noise_count; - while( ay_noise_tick >= ay_noise_period ) { - ay_noise_tick -= ay_noise_period; - - if( ( rng & 1 ) ^ ( ( rng & 2 ) ? 1 : 0 ) ) - noise_toggle = !noise_toggle; - - /* rng is 17-bit shift reg, bit 0 is output. - * input is bit 0 xor bit 2. - */ - rng |= ( ( rng & 1 ) ^ ( ( rng & 4 ) ? 1 : 0 ) ) ? 0x20000 : 0; - rng >>= 1; - - /* don't keep trying if period is zero */ - if( !ay_noise_period ) - break; - } - } -} - -/* don't make the change immediately; record it for later, - * to be made by sound_frame() (via sound_ay_overlay()). - */ -void -sound_ay_write( int reg, int val, libspectrum_dword now ) -{ - if( ay_change_count < AY_CHANGE_MAX ) { - ay_change[ ay_change_count ].tstates = now; - ay_change[ ay_change_count ].reg = ( reg & 15 ); - ay_change[ ay_change_count ].val = val; - ay_change_count++; - } -} - -/* no need to call this initially, but should be called - * on reset otherwise. - */ -void -sound_ay_reset( void ) -{ - int f; - - /* recalculate timings based on new machines ay clock */ - sound_ay_init(); - - ay_change_count = 0; - for( f = 0; f < 16; f++ ) - sound_ay_write( f, 0, 0 ); - for( f = 0; f < 3; f++ ) - ay_tone_high[f] = 0; - ay_tone_cycles = ay_env_cycles = 0; -} - -void -sound_frame( void ) -{ - long count; - - if( !sound_enabled ) - return; - - /* overlay AY sound */ - sound_ay_overlay(); - - left_buf->end_frame( machine_current->timings.tstates_per_frame ); - - if( sound_stereo ) { - right_buf->end_frame( machine_current->timings.tstates_per_frame ); - - /* Read left channel into even samples, right channel into odd samples: - LRLRLRLRLR... */ - count = left_buf->read_samples( samples, sound_framesiz, 1 ); - right_buf->read_samples( samples + 1, count, 1 ); - count <<= 1; - } else { - count = left_buf->read_samples( samples, sound_framesiz ); - } - - sound_lowlevel_frame( samples, count ); - - ay_change_count = 0; -} - -void -sound_beeper( int on ) -{ - static int beeper_ampl[] = { 0, AMPL_TAPE, AMPL_BEEPER, AMPL_BEEPER+AMPL_TAPE }; - - int val; - int ampl; - - if( !sound_enabled ) - return; - - /* Timex machines have no loading noise */ - if( tape_is_playing() && - ( !settings_current.sound_load || machine_current->timex ) ) - on = on & 0x02; - - ampl = beeper_ampl[on]; - - val = -beeper_ampl[3] + ampl*2; - - left_beeper_synth->update( tstates, val ); - if( sound_stereo ) { - right_beeper_synth->update( tstates, val ); - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fr...@us...> - 2012-01-14 05:18:20
|
Revision: 680 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=680&view=rev Author: fredm Date: 2012-01-14 05:18:11 +0000 (Sat, 14 Jan 2012) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 24 renames. * vendor/fuse-emulator/current/fuse/peripherals/disk: Renamed from vendor/fuse-emulator/current/fuse/disk. * vendor/fuse-emulator/current/fuse/peripherals/ide: Renamed from vendor/fuse-emulator/current/fuse/ide. * vendor/fuse-emulator/current/fuse/peripherals/ay.c: Renamed from vendor/fuse-emulator/current/fuse/ay.c. * vendor/fuse-emulator/current/fuse/peripherals/ay.h: Renamed from vendor/fuse-emulator/current/fuse/ay.h. * vendor/fuse-emulator/current/fuse/peripherals/dck.c: Renamed from vendor/fuse-emulator/current/fuse/dck.c. * vendor/fuse-emulator/current/fuse/peripherals/dck.h: Renamed from vendor/fuse-emulator/current/fuse/dck.h. * vendor/fuse-emulator/current/fuse/peripherals/fuller.c: Renamed from vendor/fuse-emulator/current/fuse/fuller.c. * vendor/fuse-emulator/current/fuse/peripherals/fuller.h: Renamed from vendor/fuse-emulator/current/fuse/fuller.h. * vendor/fuse-emulator/current/fuse/peripherals/if1.c: Renamed from vendor/fuse-emulator/current/fuse/if1.c. * vendor/fuse-emulator/current/fuse/peripherals/if1.h: Renamed from vendor/fuse-emulator/current/fuse/if1.h. * vendor/fuse-emulator/current/fuse/peripherals/if2.c: Renamed from vendor/fuse-emulator/current/fuse/if2.c. * vendor/fuse-emulator/current/fuse/peripherals/if2.h: Renamed from vendor/fuse-emulator/current/fuse/if2.h. * vendor/fuse-emulator/current/fuse/peripherals/joystick.c: Renamed from vendor/fuse-emulator/current/fuse/joystick.c. * vendor/fuse-emulator/current/fuse/peripherals/joystick.h: Renamed from vendor/fuse-emulator/current/fuse/joystick.h. * vendor/fuse-emulator/current/fuse/peripherals/kempmouse.c: Renamed from vendor/fuse-emulator/current/fuse/kempmouse.c. * vendor/fuse-emulator/current/fuse/peripherals/kempmouse.h: Renamed from vendor/fuse-emulator/current/fuse/kempmouse.h. * vendor/fuse-emulator/current/fuse/peripherals/melodik.c: Renamed from vendor/fuse-emulator/current/fuse/melodik.c. * vendor/fuse-emulator/current/fuse/peripherals/melodik.h: Renamed from vendor/fuse-emulator/current/fuse/melodik.h. * vendor/fuse-emulator/current/fuse/peripherals/printer.c: Renamed from vendor/fuse-emulator/current/fuse/printer.c. * vendor/fuse-emulator/current/fuse/peripherals/printer.h: Renamed from vendor/fuse-emulator/current/fuse/printer.h. * vendor/fuse-emulator/current/fuse/peripherals/scld.c: Renamed from vendor/fuse-emulator/current/fuse/scld.c. * vendor/fuse-emulator/current/fuse/peripherals/scld.h: Renamed from vendor/fuse-emulator/current/fuse/scld.h. * vendor/fuse-emulator/current/fuse/peripherals/ula.c: Renamed from vendor/fuse-emulator/current/fuse/ula.c. * vendor/fuse-emulator/current/fuse/peripherals/ula.h: Renamed from vendor/fuse-emulator/current/fuse/ula.h. Added Paths: ----------- vendor/fuse-emulator/current/fuse/peripherals/ vendor/fuse-emulator/current/fuse/peripherals/ay.c vendor/fuse-emulator/current/fuse/peripherals/ay.h vendor/fuse-emulator/current/fuse/peripherals/dck.c vendor/fuse-emulator/current/fuse/peripherals/dck.h vendor/fuse-emulator/current/fuse/peripherals/disk/ vendor/fuse-emulator/current/fuse/peripherals/fuller.c vendor/fuse-emulator/current/fuse/peripherals/fuller.h vendor/fuse-emulator/current/fuse/peripherals/ide/ vendor/fuse-emulator/current/fuse/peripherals/if1.c vendor/fuse-emulator/current/fuse/peripherals/if1.h vendor/fuse-emulator/current/fuse/peripherals/if2.c vendor/fuse-emulator/current/fuse/peripherals/if2.h vendor/fuse-emulator/current/fuse/peripherals/joystick.c vendor/fuse-emulator/current/fuse/peripherals/joystick.h vendor/fuse-emulator/current/fuse/peripherals/kempmouse.c vendor/fuse-emulator/current/fuse/peripherals/kempmouse.h vendor/fuse-emulator/current/fuse/peripherals/melodik.c vendor/fuse-emulator/current/fuse/peripherals/melodik.h vendor/fuse-emulator/current/fuse/peripherals/printer.c vendor/fuse-emulator/current/fuse/peripherals/printer.h vendor/fuse-emulator/current/fuse/peripherals/scld.c vendor/fuse-emulator/current/fuse/peripherals/scld.h vendor/fuse-emulator/current/fuse/peripherals/ula.c vendor/fuse-emulator/current/fuse/peripherals/ula.h Removed Paths: ------------- vendor/fuse-emulator/current/fuse/ay.c vendor/fuse-emulator/current/fuse/ay.h vendor/fuse-emulator/current/fuse/dck.c vendor/fuse-emulator/current/fuse/dck.h vendor/fuse-emulator/current/fuse/disk/ vendor/fuse-emulator/current/fuse/fuller.c vendor/fuse-emulator/current/fuse/fuller.h vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/if1.c vendor/fuse-emulator/current/fuse/if1.h vendor/fuse-emulator/current/fuse/if2.c vendor/fuse-emulator/current/fuse/if2.h vendor/fuse-emulator/current/fuse/joystick.c vendor/fuse-emulator/current/fuse/joystick.h vendor/fuse-emulator/current/fuse/kempmouse.c vendor/fuse-emulator/current/fuse/kempmouse.h vendor/fuse-emulator/current/fuse/melodik.c vendor/fuse-emulator/current/fuse/melodik.h vendor/fuse-emulator/current/fuse/printer.c vendor/fuse-emulator/current/fuse/printer.h vendor/fuse-emulator/current/fuse/scld.c vendor/fuse-emulator/current/fuse/scld.h vendor/fuse-emulator/current/fuse/ula.c vendor/fuse-emulator/current/fuse/ula.h Deleted: vendor/fuse-emulator/current/fuse/ay.c =================================================================== --- vendor/fuse-emulator/current/fuse/ay.c 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 05:18:11 UTC (rev 680) @@ -1,169 +0,0 @@ -/* ay.c: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.c 4030 2009-06-07 14:38:38Z 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 <string.h> - -#include "compat.h" -#include "machine.h" -#include "module.h" -#include "printer.h" -#include "psg.h" -#include "sound.h" - -/* Unused bits in the AY registers are silently zeroed out; these masks - accomplish this */ -static const libspectrum_byte mask[ AY_REGISTERS ] = { - - 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0xff, - 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x0f, 0xff, 0xff, - -}; - -static void ay_reset( int hard_reset ); -static void ay_from_snapshot( libspectrum_snap *snap ); -static void ay_to_snapshot( libspectrum_snap *snap ); - -static module_info_t ay_module_info = { - - ay_reset, - NULL, - NULL, - ay_from_snapshot, - ay_to_snapshot, - -}; - -int -ay_init( void ) -{ - module_register( &ay_module_info ); - - return 0; -} - -static void -ay_reset( int hard_reset GCC_UNUSED ) -{ - ayinfo *ay = &machine_current->ay; - - ay->current_register = 0; - memset( ay->registers, 0, sizeof( ay->registers ) ); -} - -/* What happens when the AY register port (traditionally 0xfffd on the 128K - machines) is read from */ -libspectrum_byte -ay_registerport_read( libspectrum_word port GCC_UNUSED, int *attached ) -{ - int current; - const libspectrum_byte port_input = 0xbf; /* always allow serial output */ - - *attached = 1; - - current = machine_current->ay.current_register; - - /* The AY I/O ports return input directly from the port when in - input mode; but in output mode, they return an AND between the - register value and the port input. So, allow for this when - reading R14... */ - - if( current == 14 ) { - if(machine_current->ay.registers[7] & 0x40) - return (port_input & machine_current->ay.registers[14]); - else - return port_input; - } - - /* R15 is simpler to do, as the 8912 lacks the second I/O port, and - the input-mode input is always 0xff */ - if( current == 15 && !( machine_current->ay.registers[7] & 0x80 ) ) - return 0xff; - - /* Otherwise return register value, appropriately masked */ - return machine_current->ay.registers[ current ] & mask[ current ]; -} - -/* And when it's written to */ -void -ay_registerport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - machine_current->ay.current_register = (b & 15); -} - -/* What happens when the AY data port (traditionally 0xbffd on the 128K - machines) is written to; no corresponding read function as this - always returns 0xff */ -void -ay_dataport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - int current; - - current = machine_current->ay.current_register; - - machine_current->ay.registers[ current ] = b & mask[ current ]; - sound_ay_write( current, b, tstates ); - if( psg_recording ) psg_write_register( current, b ); - - if( current == 14 ) printer_serial_write( b ); -} - -void -ay_state_from_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - ay_registerport_write( 0xfffd, - libspectrum_snap_out_ay_registerport( snap ) ); - - for( i = 0; i < AY_REGISTERS; i++ ) { - machine_current->ay.registers[i] = - libspectrum_snap_ay_registers( snap, i ); - sound_ay_write( i, machine_current->ay.registers[i], 0 ); - } -} - -static void -ay_from_snapshot( libspectrum_snap *snap ) -{ - if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) { - ay_state_from_snapshot( snap ); - } -} - -static void -ay_to_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - libspectrum_snap_set_out_ay_registerport( - snap, machine_current->ay.current_register - ); - - for( i = 0; i < AY_REGISTERS; i++ ) - libspectrum_snap_set_ay_registers( snap, i, - machine_current->ay.registers[i] ); -} Deleted: vendor/fuse-emulator/current/fuse/ay.h =================================================================== --- vendor/fuse-emulator/current/fuse/ay.h 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 05:18:11 UTC (rev 680) @@ -1,47 +0,0 @@ -/* ay.h: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.h 4030 2009-06-07 14:38:38Z 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... - -*/ - -#ifndef FUSE_AY_H -#define FUSE_AY_H - -#include <libspectrum.h> - -#define AY_REGISTERS 16 - -typedef struct ayinfo { - int current_register; - libspectrum_byte registers[ AY_REGISTERS ]; -} ayinfo; - -int ay_init( void ); - -libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached ); -void ay_registerport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_dataport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_state_from_snapshot( libspectrum_snap *snap ); - -#endif /* #ifndef FUSE_AY_H */ Deleted: vendor/fuse-emulator/current/fuse/dck.c =================================================================== --- vendor/fuse-emulator/current/fuse/dck.c 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 05:18:11 UTC (rev 680) @@ -1,184 +0,0 @@ -/* dck.c: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#include <config.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <libspectrum.h> - -#include "dck.h" -#include "machine.h" -#include "memory.h" -#include "settings.h" -#include "scld.h" -#include "ui/ui.h" -#include "utils.h" -#include "debugger/debugger.h" - -/* Dock cart inserted? */ -int dck_active = 0; - -int -dck_insert( const char *filename ) -{ - int error; - - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return 1; - } - - error = settings_set_string( &settings_current.dck_file, filename ); - if( error ) return error; - - machine_reset( 0 ); - - return 0; -} - -void -dck_eject( void ) -{ - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return; - } - - if( settings_current.dck_file ) free( settings_current.dck_file ); - settings_current.dck_file = NULL; - - dck_active = 0; - - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - - machine_reset( 0 ); -} - -int -dck_reset( void ) -{ - utils_file file; - size_t num_block = 0; - libspectrum_dck *dck; - int error; - - dck_active = 0; - - if( !settings_current.dck_file ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - return 0; - } - - dck = libspectrum_dck_alloc(); - - error = utils_read_file( settings_current.dck_file, &file ); - if( error ) { libspectrum_dck_free( dck, 0 ); return error; } - - error = libspectrum_dck_read2( dck, file.buffer, file.length, - settings_current.dck_file ); - if( error ) { - utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; - } - - if( utils_close_file( &file ) ) { - libspectrum_dck_free( dck, 0 ); - return 1; - } - - while( dck->dck[num_block] != NULL ) { - memory_page **mem; - int i; - - switch( dck->dck[num_block]->bank ) { - case LIBSPECTRUM_DCK_BANK_HOME: - mem = memory_map_home; - break; - case LIBSPECTRUM_DCK_BANK_DOCK: - mem = memory_map_dock; - break; - case LIBSPECTRUM_DCK_BANK_EXROM: - mem = memory_map_exrom; - break; - default: - ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", - dck->dck[num_block]->bank ); - libspectrum_dck_free( dck, 0 ); - return 1; - } - - for( i = 0; i < 8; i++ ) { - - switch( dck->dck[num_block]->access[i] ) { - - case LIBSPECTRUM_DCK_PAGE_NULL: - break; - - case LIBSPECTRUM_DCK_PAGE_ROM: - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - mem[i]->writable = 0; - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - break; - - case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: - case LIBSPECTRUM_DCK_PAGE_RAM: - /* Because the scr and snapshot code depends on the standard - memory map being in the RAM[] array, we just copy RAM - blocks from the HOME bank into the appropriate page; in - other cases, we allocate ourselves a new page to store the - contents in */ - if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - mem[i]->writable = 1; - } - - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - break; - - } - } - num_block++; - } - - dck_active = 1; - - /* Make the menu item to eject the cartridge active */ - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); - - return libspectrum_dck_free( dck, 0 ); -} Deleted: vendor/fuse-emulator/current/fuse/dck.h =================================================================== --- vendor/fuse-emulator/current/fuse/dck.h 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 05:18:11 UTC (rev 680) @@ -1,39 +0,0 @@ -/* dck.h: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003 Darren Salt, Fredrick Meunier - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#ifndef FUSE_DCK_H -#define FUSE_DCK_H - -/* Dock cart inserted? */ -extern int dck_active; - -int dck_insert( const char *filename ); -void dck_eject( void ); -int dck_reset( void ); - -#endif Deleted: vendor/fuse-emulator/current/fuse/fuller.c =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.c 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 05:18:11 UTC (rev 680) @@ -1,90 +0,0 @@ -/* fuller.c: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.c 4032 2009-06-10 11:09:44Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#include <config.h> - -#include <libspectrum.h> - -#include "ay.h" -#include "compat.h" -#include "fuller.h" -#include "joystick.h" -#include "module.h" -#include "periph.h" -#include "settings.h" - -static void fuller_enabled_snapshot( libspectrum_snap *snap ); -static void fuller_from_snapshot( libspectrum_snap *snap ); -static void fuller_to_snapshot( libspectrum_snap *snap ); - -static module_info_t fuller_module_info = { - - NULL, - NULL, - fuller_enabled_snapshot, - fuller_from_snapshot, - fuller_to_snapshot, - -}; - -const periph_t fuller_peripherals[] = { - { 0x00ff, 0x003f, ay_registerport_read, ay_registerport_write }, - { 0x00ff, 0x005f, NULL, ay_dataport_write }, - { 0x00ff, 0x007f, joystick_fuller_read, NULL }, -}; - -const size_t fuller_peripherals_count = - sizeof( fuller_peripherals ) / sizeof( periph_t ); - -static void -fuller_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_fuller_box_active( snap ) ) - settings_current.fuller = 1; -} - -static void -fuller_from_snapshot( libspectrum_snap *snap ) -{ - if( periph_fuller_active ) { - ay_state_from_snapshot( snap ); - } -} - -static void -fuller_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_snap_set_fuller_box_active( snap, periph_fuller_active ); -} - -int -fuller_init( void ) -{ - module_register( &fuller_module_info ); - - return 0; -} Deleted: vendor/fuse-emulator/current/fuse/fuller.h =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.h 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 05:18:11 UTC (rev 680) @@ -1,40 +0,0 @@ -/* fuller.h: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.h 4030 2009-06-07 14:38:38Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#ifndef FUSE_FULLER_H -#define FUSE_FULLER_H - -#include <libspectrum.h> - -#include "periph.h" - -extern const periph_t fuller_peripherals[]; -extern const size_t fuller_peripherals_count; - -int fuller_init( void ); - -#endif /* #ifndef FUSE_FULLER_H */ Deleted: vendor/fuse-emulator/current/fuse/if1.c =================================================================== --- vendor/fuse-emulator/current/fuse/if1.c 2011-11-19 11:19:30 UTC (rev 679) +++ vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 05:18:11 UTC (rev 680) @@ -1,1304 +0,0 @@ -/* if1.c: Interface I handling routines - Copyright (c) 2004-2008 Gergely Szasz, Philip Kendall - - $Id: if1.c 4180 2010-10-09 12:59: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 - 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: - - Gergely: sz...@hu... - -*/ - -#include <config.h> - -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <unistd.h> - -#include "compat.h" -#include "debugger/debugger.h" -#include "if1.h" -#include "machine.h" -#include "memory.h" -#include "module.h" -#include "periph.h" -#include "settings.h" -#include "utils.h" -#include "ui/ui.h" - -#undef IF1_DEBUG_MDR -#undef IF1_DEBUG_NET -#undef IF1_DEBUG_NET_1 - -#define BUFF_EMPTY 0x100 - -enum { - SYNC_NO = 0, - SYNC_OK = 0xff -}; - -/* - Microdrive cartridge - GAP PREAMBLE 15 byte GAP PREAMBLE 15 byte 512 1 - [-----][00 00 ... ff ff][BLOCK HEAD][-----][00 00 ... ff ff][REC HEAD][ DATA ][CHK] - Preamble = 10 * 0x00 + 2 * 0xff (12 byte) -*/ - -typedef struct microdrive_t { - utils_file file; - char *filename; /* old filename */ - int inserted; - int modified; - int motor_on; - int head_pos; - int transfered; - int max_bytes; - libspectrum_byte pream[512]; /* preamble/sync area written */ - libspectrum_byte last; - libspectrum_byte gap; - libspectrum_byte sync; - - libspectrum_microdrive *cartridge; /* write protect, len, blocks */ - -} microdrive_t; - -typedef struct if1_ula_t { - int fd_r; /* file descriptor for reading bytes or bits RS232 */ - int fd_t; /* file descriptor for writing bytes or bits RS232 */ - int fd_net; /* file descriptor for rw bytes or bits SinclairNET */ - int rs232_buffer; /* read buffer */ - int s_net_mode; - int status; /* if1_ula/SinclairNET */ - int comms_data; /* the previous data comms state */ - int comms_clk; /* the previous data comms state */ - int cts; /* CTS of peripheral */ - int dtr; /* DTR of peripheral */ - int tx; /* TxD the name is very kind, because this is the read end of - the TxD wire of DATA machine (really RxD the view of - spectrum */ - int rx; /* RxD the name is very kind, because this is the write end of - the RxD wire of DATA machine (really TxD the view of - spectrum */ - int data_in; /* interpreted incoming data */ - int count_in; - int data_out; /* interpreted outgoing data */ - int count_out; - int esc_in; /* if we compose an escape seq */ - - int net; /* Network in/out (really 1 wire bus :-) */ - int net_data; /* Interpreted network data */ - int net_state; /* Interpreted network data */ - int wait; /* Wait state */ - int busy; /* Indicate busy; if1 software never poll it ... */ -} if1_ula_t; - -/* - 7 6 5 4 3 2 1 0 - STATUS RO $EF(239) --- --- --- BSY DTR GAP SYN WPR - - CONTRO WO $EF(239) --- --- WAT CTS ERA R/w CLK DTA - - MDR DT RW $E7(231) D7 D6 D5 D4 D3 D2 D1 D0 - - COMM I RO $F7(247) TX --- --- --- --- --- --- NET - - COMM O WO $F7(247) --- --- --- --- --- --- --- NET/RX - -RS232: - DTR -> Data Terminal Ready (DTE -> DCE) - CTS -> Clear To Send (DCE -> DTE) - TX -> Transmitted Data (DTE -> DCE) - RX -> Received Data (DCE -> DTE) - - The IF1 serial behaves not as a DTE (Data Terminal Equipment, e.g. - a computer) but as a DCE (Data Communications Equipment, e.g. a modem) - - If we were to consider the ZX Spectrum a DTE, we would rename the lines: - DTR := DSR (Data Set Ready) - CTS := RTS (Request To Send) - TX := RX - RX := TX - - On the communication channels: - Bytes interpreted as is, except: - 0x00 0x00 --> DTR ~~\__ - 0x00 0x01 --> DTR __/~~ - 0x00 0x02 --> CTS ~~\__ - 0x00 0x03 --> CTS __/~~ - 0x00 ? --> lost - 0x00 * --> 0x00 - Additionally: - if fuse read 0x00 0x00 => DTR = 0 ~~\__ - if fuse read 0x00 0x01 => DTR = 1 __/~~ - if CTS = ~~\__ fuse send 0x00 0x02 - if CTS = __/~~ fuse send 0x00 0x03 - if fuse lost send 0x00 + 0x3f (?) - every other 0x00 + 0x## are discarded -*/ - -/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ -static memory_page if1_memory_map_romcs[2]; - -/* IF1 paged out ROM activated? */ -int if1_active = 0; -int if1_available = 0; -static int if1_mdr_status = 0; - -int rnd_factor = ( ( RAND_MAX >> 2 ) << 2 ) / 19 + 1; - -static microdrive_t microdrive[8]; /* We have 8 microdrive */ -static if1_ula_t if1_ula; - -static void microdrives_reset( void ); -static void microdrives_restart( void ); -static void increment_head( int m ); - -#define MDR_IN(m) microdrive[m - 1].inserted -#define MDR_WP(m) libspectrum_microdrive_write_protect( microdrive[m - 1].cartridge ) - -enum if1_menu_item { - - UMENU_ALL = 0, - UMENU_MDRV1, - UMENU_MDRV2, - UMENU_MDRV3, - UMENU_MDRV4, - UMENU_MDRV5, - UMENU_MDRV6, - UMENU_MDRV7, - UMENU_MDRV8, - UMENU_RS232, -}; - -enum if1_port { - PORT_MDR, - PORT_CTR, - PORT_NET, - PORT_UNKNOWN, -}; - -static void if1_reset( int hard_reset ); -static void if1_enabled_snapshot( libspectrum_snap *snap ); -static void if1_from_snapshot( libspectrum_snap *snap ); -static void if1_to_snapshot( libspectrum_snap *snap ); - -static module_info_t if1_module_info = { - - if1_reset, - if1_memory_map, - if1_enabled_snapshot, - if1_from_snapshot, - if1_to_snapshot, - -}; - -const periph_t if1_peripherals[] = { - { 0x0018, 0x0010, if1_port_in, if1_port_out }, - { 0x0018, 0x0008, if1_port_in, if1_port_out }, - { 0x0018, 0x0000, if1_port_in, if1_port_out }, -}; - -const size_t if1_peripherals_count = - sizeof( if1_peripherals ) / sizeof( periph_t ); - -/* Debugger events */ -static const char *event_type_string = "if1"; -static int page_event, unpage_event; - -static void -update_menu( enum if1_menu_item what ) -{ - if( what == UMENU_ALL || what == UMENU_MDRV1 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_EJECT, MDR_IN( 1 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_WP_SET, - !MDR_IN( 1 ) ? 0 : !MDR_WP( 1 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV2 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_EJECT, MDR_IN( 2 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_WP_SET, - !MDR_IN( 2 ) ? 0 : !MDR_WP( 2 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV3 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_EJECT, MDR_IN( 3 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_WP_SET, - !MDR_IN( 3 ) ? 0 : !MDR_WP( 3 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV4 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_EJECT, MDR_IN( 4 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_WP_SET, - !MDR_IN( 4 ) ? 0 : !MDR_WP( 4 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV5 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_EJECT, MDR_IN( 5 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_WP_SET, - !MDR_IN( 5 ) ? 0 : !MDR_WP( 5 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV6 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_EJECT, MDR_IN( 6 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_WP_SET, - !MDR_IN( 6 ) ? 0 : !MDR_WP( 6 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV7 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_EJECT, MDR_IN( 7 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_WP_SET, - !MDR_IN( 7 ) ? 0 : !MDR_WP( 7 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV8 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_EJECT, MDR_IN( 8 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_WP_SET, - !MDR_IN( 8 ) ? 0 : !MDR_WP( 8 ) ); - } - - if( what == UMENU_ALL || what == UMENU_RS232 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_R, - ( if1_ula.fd_r > -1 ) ? 1 : 0 ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_T, - ( if1_ula.fd_t > -1 ) ? 1 : 0 ); -#ifdef BUILD_WITH_SNET - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_SNET_UNPLUG, - ( if1_ula.fd_net > -1 ) ? 1 : 0 ); -#endif - } -} - -int -if1_init( void ) -{ - int m, i; - - if1_ula.fd_r = -1; - if1_ula.fd_t = -1; - if1_ula.dtr = 0; /* No data terminal yet */ - if1_ula.cts = 2; /* force to emit first cts status */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; /* really? */ - if1_ula.fd_net = -1; - if1_ula.s_net_mode = 1; - if1_ula.net = 0; - if1_ula.esc_in = 0; /* empty */ - - for( m = 0; m < 8; m++ ) { - microdrive[m].cartridge = libspectrum_microdrive_alloc(); - microdrive[m].inserted = 0; - microdrive[m].modified = 0; - } - - if( settings_current.rs232_rx ) { - if1_plug( settings_current.rs232_rx, 1 ); - free( settings_current.rs232_rx ); - settings_current.rs232_rx = NULL; - } - - if( settings_current.rs232_tx ) { - if1_plug( settings_current.rs232_tx, 2 ); - free( settings_current.rs232_tx ); - settings_current.rs232_tx = NULL; - } - - if( settings_current.snet ) { - if1_plug( settings_current.snet, 3 ); - free( settings_current.snet ); - settings_current.snet = NULL; - } - - module_register( &if1_module_info ); - for( i = 0; i < 2; i++ ) if1_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; - - if( periph_register_paging_events( event_type_string, &page_event, - &unpage_event ) ) - return 1; - - return 0; -} - -libspectrum_error -if1_end( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - libspectrum_error error = - libspectrum_microdrive_free( microdrive[m].cartridge ); - if( error ) return error; - } - - return LIBSPECTRUM_ERROR_NONE; -} - -void -if1_update_menu( void ) -{ - update_menu( UMENU_ALL ); -} - -static void -if1_reset( int hard_reset GCC_UNUSED ) -{ - if1_active = 0; - if1_available = 0; - - if( !periph_interface1_active ) return; - - machine_load_rom_bank( if1_memory_map_romcs, 0, 0, - settings_current.rom_interface_i, - settings_default.rom_interface_i, - MEMORY_PAGE_SIZE ); - - if1_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; - - machine_current->ram.romcs = 0; - - if1_ula.cts = 2; /* force to emit first out if raw */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; - if1_ula.net = 0; - if1_ula.esc_in = 0; - - microdrives_reset(); - - update_menu( UMENU_ALL ); - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - - if1_mdr_status = 0; - - if1_available = 1; -} - -void -if1_page( void ) -{ - if1_active = 1; - machine_current->ram.romcs = 1; - machine_current->memory_map(); - - debugger_event( page_event ); -} - -void -if1_unpage( void ) -{ - if1_active = 0; - machine_current->ram.romcs = 0; - machine_current->memory_map(); - - debugger_event( unpage_event ); -} - -void -if1_memory_map( void ) -{ - if( !if1_active ) return; - - memory_map_read[0] = memory_map_write[0] = if1_memory_map_romcs[0]; -} - -static void -if1_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_interface1_active( snap ) ) - settings_current.interface1 = 1; -} - -static void -if1_from_snapshot( libspectrum_snap *snap ) -{ - if( !libspectrum_snap_interface1_active( snap ) ) return; - - if( libspectrum_snap_interface1_custom_rom( snap ) && - libspectrum_snap_interface1_rom( snap, 0 ) && - machine_load_rom_bank_from_buffer( - if1_memory_map_romcs, 0, 0, - libspectrum_snap_interface1_rom( snap, 0 ), - libspectrum_snap_interface1_rom_length( snap, 0 ), - 1 ) ) - return; - - if( libspectrum_snap_interface1_paged( snap ) ) { - if1_page(); - } else { - if1_unpage(); - } -} - -static void -if1_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_byte *buffer; - - if( !periph_interface1_active ) return; - - libspectrum_snap_set_interface1_active( snap, 1 ); - libspectrum_snap_set_interface1_paged ( snap, if1_active ); - libspectrum_snap_set_interface1_drive_count( snap, 8 ); - - if( if1_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { - size_t rom_length = MEMORY_PAGE_SIZE; - - if( if1_memory_map_romcs[1].source == MEMORY_SOURCE_CUSTOMROM ) { - rom_length <<= 1; - } - - libspectrum_snap_set_interface1_custom_rom( snap, 1 ); - libspectrum_snap_set_interface1_rom_length( snap, 0, rom_length ); - - buffer = malloc( rom_length ); - if( !buffer ) { - ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); - return; - } - - memcpy( buffer, if1_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); - - if( rom_length == MEMORY_PAGE_SIZE*2 ) { - memcpy( buffer + MEMORY_PAGE_SIZE, if1_memory_map_romcs[1].page, - MEMORY_PAGE_SIZE ); - } - - libspectrum_snap_set_interface1_rom( snap, 0, buffer ); - } -} - -static void -microdrives_reset( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - microdrive[m].head_pos = 0; - microdrive[m].motor_on = 0; /* motor off */ - microdrive[m].gap = 15; - microdrive[m].sync = 15; - microdrive[m].transfered = 0; - } - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; -/* - if1_ula.comms_data = 0; - if1_ula.count_in = 0; - if1_ula.count_out = 0; - if1_ula.cts = 0; - if1_ula.dtr = 0; - if1_ula.wait = 0; - if1_ula.busy = 0; - if1_ula.net = 0; - if1_ula.net_state = 0; -*/ -} - -static enum if1_port -decode_port( libspectrum_word port ) -{ - switch( port & 0x0018 ) { - case 0x0000: return PORT_MDR; - case 0x0008: return PORT_CTR; - case 0x0010: return PORT_NET; - default: return PORT_UNKNOWN; - } -} - -static libspectrum_byte -port_mdr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - - if( mdr->transfered < mdr->max_bytes ) { - mdr->last = libspectrum_microdrive_data( mdr->cartridge, - mdr->head_pos ); - increment_head( m ); - } - - mdr->transfered++; - ret &= mdr->last; /* I assume negative logic, but how know? */ - } - - } - - return ret; -} - -static libspectrum_byte -port_ctr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m, block; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->pream[block] == SYNC_OK ) { /* if formatted */ - if( mdr->gap ) { - /* ret &= 0xff; GAP and SYNC high ? */ - mdr->gap--; - } else { - ret &= 0xf9; /* GAP and SYNC low */ - if( mdr->sync ) { - mdr->sync--; - } else { - mdr->gap = 15; - mdr->sync = 15; - } - } - } - /* if write protected */ - if( libspectrum_microdrive_write_protect( mdr->cartridge) ) - ret &= 0xfe; /* active bit */ - } - } - /* Here we have to poll, the if1_ula DTR 'line' */ - if( if1_ula.rs232_buffer > 0xff ) { /* buffer empty */ - unsigned char byte; - int yes = 1; - - while( yes && read( if1_ula.fd_r, &byte, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( byte == '*' ) { - if1_ula.rs232_buffer = 0x00; - yes = 0; - } else if( byte == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( byte == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( byte == 0x00 ) { - if1_ula.esc_in = 1; - } else { - if1_ula.rs232_buffer = byte; - yes = 0; - break; - } - } - } - - if( if1_ula.dtr == 0 ) - ret &= 0xf7; /* %11110111 */ - - /* Here we have to poll, the 'SinclairNet' busy flag but never used by - software in Interface 1 */ - if( if1_ula.busy == 0 ) - ret &= 0xef; /* %11101111 */ - /* fprintf( stderr, "Read CTR ( %%%d%d%d%d%d%d%d%d ).\n", - !!(ret & 128), !!(ret & 64), !!(ret & 32), !!(ret & 16), - !!(ret & 8), !!(ret & 4), !!(ret & 2), !!(ret & 1)); */ - microdrives_restart(); - - return ret; -} - -/* - return 1 if read a byte - 0 if nothing interesting... -*/ - -static int -read_rs232() -{ - if( if1_ula.rs232_buffer <= 0xff ) { /* we read from the buffer */ - if1_ula.data_in = if1_ula.rs232_buffer; - if1_ula.rs232_buffer = 0x0100; - return 1; - } - while( read( if1_ula.fd_r, &if1_ula.data_in, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( if1_ula.data_in == '*' ) { - if1_ula.data_in = 0x00; - return 1; - } else if( if1_ula.data_in == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( if1_ula.data_in == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( if1_ula.data_in == 0x00 ) { - if1_ula.esc_in = 1; - } else { - return 1; - } - } - return 0; -} - -static libspectrum_byte -port_net_in( void ) -{ - libspectrum_byte ret = 0xff; - - if( if1_ula.fd_r == -1 ) - goto no_rs232_in; - - /* Here is the RS232 input routine */ - if( if1_ula.cts ) { /* If CTS == 1 */ - if( if1_ula.count_in == 0 ) { - if( if1_ula.fd_r >= 0 && read_rs232() == 1 ) { - if1_ula.count_in++; /* Ok, if read a byte, we begin */ - } - if1_ula.tx = 0; /* now send __ to if1 - later we raise :-) */ - } else if( if1_ula.count_in >= 1 && if1_ula.count_in < 5 ) { - if1_ula.tx = 1; /* send ~~ (start bit :-) */ - if1_ula.count_in++; - } else if( if1_ula.count_in >= 5 && if1_ula.count_in < 13 ) { - if1_ula.tx = ( if1_ula.data_in & 0x01 ) ? 0 : 1; - /* send .. (data bits :-) */ - if1_ula.data_in >>= 1; /* prepare next bit :-) */ - if1_ula.count_in++; - } else - if1_ula.count_in = 0; - } else { /* if( if1_ula.cts ) */ - if1_ula.count_in = 0; /* reset serial in */ - if1_ula.tx = 0; /* send __ stop bits or s.e. :-) */ - } - -no_rs232_in: - if( if1_ula.fd_net == -1 ) - goto no_snet_in; - - if( if1_ula.s_net_mode == 0 ) { /* if we do raw */ - /* Here is the input routine */ - read( if1_ula.fd_net, &if1_ula.net, 1 ); /* Ok, if no byte, we send last*/ - } else {/* if( if1_ula.s_net_mode == 1 ) if we do interpreted */ -/* Here is the input routine. There are several stage in input - and output. So first for output. if1 first do SEND-SC - (http://www.wearmouth.demon.co.uk/if1_2.htm#L101E) to send - a Sync-Out signal and SEND-SC do first a NET-STATE - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FBC) to see - the line activity: - 11xxxxxx times (192-255) have to get a zero (bit for network) - plus 1 times more from SEND-SC. Next SEND-SC send a 0 which is - a 1 on the net wire (negated output, straight input!!!) - - OK. In input first if1 call WT-SC-E to check Network activity - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FD3). Now check - 128 times the net wire (we do two round, because to differentiate - net out routines...) -*/ - - if( if1_ula.net_state < 0x0100 ) { /* if1 may in NET-STATE */ - if1_ula.net_state++; - if1_ula.net = 0; -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? We send 0!\n", if1_ula.net_state ); -#endif - } else if( if1_ula.net_state == 0x0100 ) { /* probably waiting for input */ - if( read( if1_ula.fd_net, &if1_ula.net_data, 1 ) == 1 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* Start with __/~~ */ - } /* Ok, if have a byte, we send it! */ - } else if( if1_ula.net_state == 0x0101 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* one more ~~ */ - } else if( if1_ula.net_state > 0x0101 && - if1_ula.net_state < 0x010a ) { /* we send the data bits... */ - if1_ula.net_state++; - if1_ula.net = if1_ula.net_data & 1; - if1_ula.net_data >>= 1; - } else if( if1_ula.net_state == 0x010a ) { - if1_ula.net = 0; - if1_ula.net_state = 0; /* OK, we starting a new byte... */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? Get a byte!\n", if1_ula.net_state ); -#endif - } - } -no_snet_in: - if( !if1_ula.tx ) - ret &= 0x7f; - if( !if1_ula.net ) - ret &= 0xfe; - microdrives_restart(); - - return ret; -} - -libspectrum_byte -if1_port_in( libspectrum_word port GCC_UNUSED, int *attached ) -{ - libspectrum_byte ret = 0xff; - - if( !if1_active ) return ret; - - *attached = 1; - - switch( decode_port( port ) ) - { - case PORT_MDR: ret &= port_mdr_in(); break; - case PORT_CTR: ret &= port_ctr_in(); break; - case PORT_NET: ret &= port_net_in(); break; - case PORT_UNKNOWN: break; - } - - return ret; -} - -static void -port_mdr_out( libspectrum_byte val ) -{ - int m, block; - - /* allow access to the port only if motor 1 is ON and there's a file open */ - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { -#ifdef IF1_DEBUG_MDR - fprintf(stderr, "#%05d %03d(%03d): 0x%02x\n", - mdr->head_pos, mdr->transfered, mdr->max_bytes, val ); -#endif - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->transfered == 0 && val == 0x00 ) { /* start pream */ - mdr->pream[block] = 1; - } else if( mdr->transfered > 0 && mdr->transfered < 10 && val == 0x00 ) { - mdr->pream[block]++; - } else if( mdr->transfered > 9 && mdr->transfered < 12 && val == 0xff ) { - mdr->pream[block]++; - } else if( mdr->transfered == 12 && mdr->pream[block] == 12 ) { - mdr->pream[block] = SYNC_OK; - } - if( mdr->transfered > 11 && - mdr->transfered < mdr->max_bytes + 12 ) { - - libspectrum_microdrive_set_data( mdr->cartridge, mdr->head_pos, - val ); - increment_head( m ); - mdr->modified = 1; - } - mdr->transfered++; - } - } -} - -static void -port_ctr_out( libspectrum_byte val ) -{ - int m; - - if( !( val & 0x02 ) && ( if1_ula.comms_clk ) ) { /* ~~\__ */ - - for( m = 7; m > 0; m-- ) { - /* Rotate one drive */ - microdrive[m].motor_on = microdrive[m - 1].motor_on; - } - microdrive[0].motor_on = (val & 0x01) ? 0 : 1; - - if( microdrive[0].motor_on || microdrive[1].motor_on || - microdrive[2].motor_on || microdrive[3].motor_on || - microdrive[4].motor_on || microdrive[5].motor_on || - microdrive[6].motor_on || microdrive[7].motor_on ) { - if( !if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_ACTIVE ); - if1_mdr_status = 1; - } - } else if ( if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; - } - } - if( val & 0x01 ) { /* comms_data == 1 */ - /* Interface 1 service manual p.:1.4 par.: 1.5.1 - The same pin on IC1 (if1 ULA), pin 33, is used for the network - transmit data and for the RS232 transmit data. In order to select - the required function IC1 uses its COMMS_OUT (pin 30) signal, - borrowed from the microdrive control when the microdrive is not - being used (I do not know what it is exactly meaning. It is a - hardware not being used, or a software should not use..?) This signal - is routed from pin 30 to the emitter of transistor Q3 (RX DATA) and - via resistor R4, to the base of transistor Q1 (NET). When COMMS_OUT - is high Q3 is enabled this selecting RS232, and when it is low - Q1 is enabled selecting the network. - - OK, the schematics offer a different interpretation, because if - COMMS_OUT pin level high (>+3V) then Q3 is off (the basis cannot - be more higher potential then emitter (NPN transistor), so whatever - is on the IC1 RX DATA (pin 33) the basis of Q4 is always on +12V, - so the collector of Q4 (PNP transistor) always on -12V. - If COMMS_OUT pin level goes low (~0V), then Q3 basis (connected - to IC1 RX DATA pin) can be higher level (>+3V) than emitter, so - the basis potential of Q4 depend on IC1 RX DATA. - - OK, Summa summarum I assume that, the COMMS OUT pin is a - negated output of the if1 ULA CTR register's COMMS DATA bit. - */ - /* C_DATA = 1 */ - if( if1_ula.comms_data == 0 ) { - if1_ula.count_out = 0; - if1_ula.data_out = 0; - if1_ula.count_in = 0; - if1_ula.data_in = 0; - } - } - if1_ula.wait = ( val & 0x20 ) ? 1 : 0; - if1_ula.comms_data = ( val & 0x01 ) ? 1 : 0; - if1_ula.comms_clk = ( val & 0x02 ) ? 1 : 0; - val = ( val & 0x10 ) ? 1 : 0; - if( settings_current.rs232_handshake && - if1_ula.fd_t != -1 && if1_ula.cts != val ) { - char data = val ? 0x03 : 0x02; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - do ; while( write( if1_ula.fd_t, &data, 1 ) != 1 ); - } - if1_ula.cts = val; - -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Set CTS to %d, set WAIT to %d and COMMS_DATA to %d\n", - if1_ula.cts, if1_ula.wait, if1_ula.comms_data ); -#endif - - microdrives_restart(); -} - -static void -port_net_out( libspectrum_byte val ) -{ - if( if1_ula.fd_t == -1 ) - return; /* nothing to write */ - - if( if1_ula.comms_data == 1 ) { /* OK, RS232 */ - val &= 0x01; - if( if1_ula.count_out == 0 && !val ) { /* waiting for ~~\__ */ - if1_ula.count_out++; - } else if( if1_ula.count_out == 1 ) { - if( if1_ula.cts != 0 || !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; /* else get the start bit __/~~ */ - } else if( if1_ula.count_out >= 2 && if1_ula.count_out <= 9 ) { - if1_ula.data_out >>= 1; - if1_ula.data_out |= val & 0x01 ? 0 : 128; - if1_ula.count_out++; /* waiting for next data bit */ - } else if( if1_ula.count_out >= 10 && if1_ula.count_out <= 11 ) { - if( val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 12 ) { - if( !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 13 ) { - if( val ) - if1_ula.count_out = -1; - } - - if( if1_ula.count_out == -1 ) { - if1_ula.count_out = 13; - if1_ula.data_out = '?'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - if( if1_ula.count_out == 13 ) { - /* Here is the output routine */ - if( if1_ula.data_out == 0x00 ) { - if1_ula.data_out = '*'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - do ; while( write( if1_ula.fd_t, &if1_ula.data_out, 1 ) != 1 ); - if1_ula.count_out = 0; - } - if1_ula.rx = val & 0x01; /* set rx */ - } else { /* if( if1_ula.comms_data == 1 ) SinclairNET :-)*/ - if( if1_ula.s_net_mode == 0 ) { /* if we out bit by bit, do it */ - /* Here is the output routine */ - -/* OK, examining the schematics of if1 and the disassembly of if1 ROM, I - see that the Q1 and Q2 transistors negate the RX DATA signal, and the - floating state of the net wire is the ~0V level, the forced is the ~3V. - The if1 software send complemented data and read straight data. -*/ - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set rx */ - lseek( if1_ula.fd_net, 0, SEEK_SET ); /* we save only the state of the wire*/ - do ; while( write( if1_ula.fd_net, &if1_ula.net, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Send SinclairNET: %d\n", if1_ula.net ); -#endif - } else { /* if( if1_ula.s_net_mode == 0 ) if we out byte by byte, do it */ - if( if1_ula.net_state >= 0x0200 && if1_ula.net_state < 0x0208 ) { - if1_ula.net_state++; - if1_ula.net_data <<= 1; - if1_ula.net_data |= ( val & 0x01 ) ? 0 : 1; - } else if( if1_ula.net_state == 0x0208 ) { - if1_ula.net_data &= 0xff; - if1_ula.net_state++; /* OK, now we get data bytes... */ - -/* lseek( if1_ula.fd_net, 0, SEEK_SET ); start a packet */ - /* first we send the station number */ - do ; while( write( if1_ula.fd_net, &if1_ula.net_data, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "SC-OUT send network number: %d\n", - if1_ula.net_data ^ 0xff ); -#endif - } else if( if1_ula.net_state > 192 && if1_ula.net_state < 0x0200 && - ( ( val & 0x01 ) == 0 ) ) { - /* NET-STATE ask as many times.... and now send a 0 */ -/* if1_ula.net = 1; */ - if1_ula.net_state = 0x0200; /* Send the station number */ - } - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set net wire? */ - } - } - microdrives_restart(); -} - -void -if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val ) -{ - if( !if1_active ) return; - -#ifdef IF1_DEBUG_NET_1 - fprintf( stderr, "In if1_port_out( %%%d%d%d%d%d%d%d%d => 0x%04x ).\n", - !!(val & 128), !!(val & 64), !!(val & 32), !!(val & 16), - !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port); -#endif - - switch( decode_port( port ) ) { - case PORT_MDR: port_mdr_out( val ); break; - case PORT_CTR: port_ctr_out( val ); break; - case PORT_NET: port_net_out( val ); break; - case PORT_UNKNOWN: break; - } -} - -static void -increment_head( int m ) -{ - microdrive[m].head_pos++; - if( microdrive[m].head_pos >= - libspectrum_microdrive_cartridge_len( microdrive[m].cartridge ) * - LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) - microdrive[m].head_pos = 0; -} - -static void -microdrives_restart( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - while( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != 0 && - ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != LIBSPECTRUM_MICRODRIVE_HEAD_LEN ) - increment_head( m ); /* put head in the start of a block */ - - microdrive[m].transfered = 0; /* reset current number of bytes written */ - - if( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) == 0 ) { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN; /* up to 15 bytes for header blocks */ - } else { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN + LIBSPECTRUM_MICRODRIVE_DATA_LEN + 1; /* up to 528 bytes for data blocks */ - } - } -} - -void -if1_mdr_writeprotect( int drive, int wrprot ) -{ - libspectrum_microdrive_set_write_protect( microdrive[drive].cartridge, - wrprot ? 1 : 0 ); - microdrive[drive].modified = 1; - - update_menu( UMENU_MDRV1 + drive ); -} - -static void -if1_mdr_new( microdrive_t *mdr ) -{ - libspectrum_byte len; - long int i; - - mdr->filename = NULL; - if( settings_current.mdr_random_len ) { /* Random length */ - len = 171 + ( ( rand() >> 2 ) + ( rand() >> 2 ) + - ( rand() >> 2 ) + ( rand() >> 2 ) ) - / rnd_factor; - } else - len = settings_current.mdr_len = settings_current.mdr_len < 10 ? 10 : - settings_current.mdr_len > LIBSPECTRUM_MICRODRIVE_BLOCK_MAX ? LIBSPECTRUM_MICRODRIVE_BLOCK_MAX : settings_current.mdr_len; - - /* Erase the entire cartridge */ - libspectrum_microdrive_set_cartridge_len( mdr->cartridge, len ); - - for( i = 0; i < len * LIBSPECTRUM_MICRODRIVE_BLOCK_LEN; i++ ) - libspectrum_microdrive_set_data( mdr->cartridge, i, 0xff ); - - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_NO; - - /* but don't write-protect */ - libspectrum_microdrive_set_write_protect( mdr->cartridge, 0 ); - - mdr->inserted = 1; - mdr->modified = 1; - -} - -int -if1_mdr_insert( int which, const char *filename ) -{ - microdrive_t *mdr; - int m, i; - - if( which == -1 ) { /* find an empty one */ - for( m = 0; m < 8; m++ ) { - if( !microdrive[m].inserted ) { - which = m; - break; - } - } - } - - if( which == -1 ) { - ui_error( UI_ERROR_ERROR, - "Cannot insert cartridge '%s', all Microdrives in use", - filename ); - return 1; - } - - if( which >= 8 ) { - ui_error( UI_ERROR_ERROR, "if1_mdr_insert: unknown drive %d", which ); - return 1; - } - - mdr = µdrive[ which ]; - - /* Eject any cartridge already in the drive */ - if( mdr->inserted ) { - /* Abort the insert if we want to keep the current cartridge */ - if( if1_mdr_eject( which, 0 ) ) return 0; - } - - if( filename == NULL ) { /* insert new unformatted cartridge */ - if1_mdr_new( mdr ); - update_menu( UMENU_MDRV1 + which ); - return 0; - } - - if( utils_read_file( filename, &mdr->file ) ) { - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( libspectrum_microdrive_mdr_read( mdr->cartridge, mdr->file.buffer, - mdr->file.length ) ) { - utils_close_file( &mdr->file ); - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( utils_close_file( &mdr->file ) ) return 1; - - mdr->inserted = 1; - mdr->modified = 0; - mdr->filename = strdup( filename ); - /* we assume formatted cartridges */ - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_OK; - - update_menu( UMENU_MDRV1 + which ); - - return 0; -} - -int -if1_mdr_eject( int which, int saveas ) -{ - microdrive_t *mdr; - - if( which >= 8 ) - return 1; - - mdr = µdrive[ which ]; - - if( !mdr->inserted ) - return 0; - - if( saveas ) { /* 1 -> save as.., 2 -> save */ - - if( mdr->filename == NULL ) saveas = 1; - if( ui_mdr_write( which, 2 - saveas ) ) return 1; - mdr->modified = 0; - return 0; - - } else { - - if( mdr->modified ) { - - ui_confirm_save_t confirm = ui_confirm_save( - "Cartridge in Microdrive %i has been modified.\n" - "Do you want to save it?", - which + 1 - ); - - switch( confirm ) { - - case UI_CONFIRM_SAVE_SAVE: - if( if1_mdr_eject( which, 2 ) ) return 1; /* first save */ - break; - - case UI_CONFIRM_SAVE_DONTSAVE: break; - case UI_CONFIRM_SAVE_CANCEL: return 1; - - } - } - } - - mdr->inserted = 0; - if( mdr->filename != NULL ) { - free( mdr->filename ); - mdr->filename = NULL; - } - - update_menu( UMENU_MDRV1 + which ); - return 0; -} - -int -if1_mdr_write( int which, const char *filename ) -{ - microdrive_t *mdr = µdrive[which]; - - libspectrum_microdrive_mdr_write( mdr->cartridge, &mdr->file.buffer, - &mdr->file.length ); - - if( filename == NULL ) filename = mdr->filename; /* Write over the original file */ - - if( utils_write_file( filename, mdr->file.buffer, mdr->file.length ) ) - return 1; - - if( mdr->filename && strcmp( filename, mdr->filename ) ) { - free( mdr->filename ); - mdr->filename = strdup( filename ); - } - return 0; -} - -#ifndef O_NONBLOCK -#define O_NONBLOCK FNDELAY -#endif - -void -if1_plug( const char *filename, int what ) -{ -#ifdef WIN32 - ui_error( UI_ERROR_ERROR, "Not yet implemented on Win32" ); - return; -#else - int fd = -1; - - switch( what ) { - case 1: - if( if1_ula.fd_r >= 0 ) - close( if1_ula.fd_r ); - fd = if1_ula.fd_r = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_RDONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_RDONLY on '%s': %s", - filename, strerror( errno ) ); - if1_ula.rs232_buffer = 0x100; /* buffer is empty */ - break; - case 2: - if( if1_ula.fd_t >= 0 ) - close( if1_ula.fd_t ); - fd = if1_ula.fd_t = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_WRONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_WRONLY on '%s': %s", - filename, strerror( errno ) ); - break; - case 3: - if( if1_ula.fd_net >= 0 ) - close( if1_ula.fd_net ); - fd = if1_ula.fd_net = open( filename, O_RDWR | O_NONBLOCK ); - break; - } - - /* rs232_handshake == 0 -> we assume DTR(DSR) always... [truncated message content] |
From: <fr...@us...> - 2012-01-14 12:08:24
|
Revision: 681 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=681&view=rev Author: fredm Date: 2012-01-14 12:08:15 +0000 (Sat, 14 Jan 2012) Log Message: ----------- Reverse half imported code. Added Paths: ----------- vendor/fuse-emulator/current/fuse/ay.c vendor/fuse-emulator/current/fuse/ay.h vendor/fuse-emulator/current/fuse/dck.c vendor/fuse-emulator/current/fuse/dck.h vendor/fuse-emulator/current/fuse/disk/ vendor/fuse-emulator/current/fuse/fuller.c vendor/fuse-emulator/current/fuse/fuller.h vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/if1.c vendor/fuse-emulator/current/fuse/if1.h vendor/fuse-emulator/current/fuse/if2.c vendor/fuse-emulator/current/fuse/if2.h vendor/fuse-emulator/current/fuse/joystick.c vendor/fuse-emulator/current/fuse/joystick.h vendor/fuse-emulator/current/fuse/kempmouse.c vendor/fuse-emulator/current/fuse/kempmouse.h vendor/fuse-emulator/current/fuse/melodik.c vendor/fuse-emulator/current/fuse/melodik.h vendor/fuse-emulator/current/fuse/printer.c vendor/fuse-emulator/current/fuse/printer.h vendor/fuse-emulator/current/fuse/scld.c vendor/fuse-emulator/current/fuse/scld.h vendor/fuse-emulator/current/fuse/ula.c vendor/fuse-emulator/current/fuse/ula.h Removed Paths: ------------- vendor/fuse-emulator/current/fuse/peripherals/ Copied: vendor/fuse-emulator/current/fuse/ay.c (from rev 679, vendor/fuse-emulator/current/fuse/ay.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ay.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,169 @@ +/* ay.c: AY-8-3912 routines + Copyright (c) 1999-2009 Philip Kendall + + $Id: ay.c 4030 2009-06-07 14:38:38Z 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 <string.h> + +#include "compat.h" +#include "machine.h" +#include "module.h" +#include "printer.h" +#include "psg.h" +#include "sound.h" + +/* Unused bits in the AY registers are silently zeroed out; these masks + accomplish this */ +static const libspectrum_byte mask[ AY_REGISTERS ] = { + + 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0xff, + 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x0f, 0xff, 0xff, + +}; + +static void ay_reset( int hard_reset ); +static void ay_from_snapshot( libspectrum_snap *snap ); +static void ay_to_snapshot( libspectrum_snap *snap ); + +static module_info_t ay_module_info = { + + ay_reset, + NULL, + NULL, + ay_from_snapshot, + ay_to_snapshot, + +}; + +int +ay_init( void ) +{ + module_register( &ay_module_info ); + + return 0; +} + +static void +ay_reset( int hard_reset GCC_UNUSED ) +{ + ayinfo *ay = &machine_current->ay; + + ay->current_register = 0; + memset( ay->registers, 0, sizeof( ay->registers ) ); +} + +/* What happens when the AY register port (traditionally 0xfffd on the 128K + machines) is read from */ +libspectrum_byte +ay_registerport_read( libspectrum_word port GCC_UNUSED, int *attached ) +{ + int current; + const libspectrum_byte port_input = 0xbf; /* always allow serial output */ + + *attached = 1; + + current = machine_current->ay.current_register; + + /* The AY I/O ports return input directly from the port when in + input mode; but in output mode, they return an AND between the + register value and the port input. So, allow for this when + reading R14... */ + + if( current == 14 ) { + if(machine_current->ay.registers[7] & 0x40) + return (port_input & machine_current->ay.registers[14]); + else + return port_input; + } + + /* R15 is simpler to do, as the 8912 lacks the second I/O port, and + the input-mode input is always 0xff */ + if( current == 15 && !( machine_current->ay.registers[7] & 0x80 ) ) + return 0xff; + + /* Otherwise return register value, appropriately masked */ + return machine_current->ay.registers[ current ] & mask[ current ]; +} + +/* And when it's written to */ +void +ay_registerport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) +{ + machine_current->ay.current_register = (b & 15); +} + +/* What happens when the AY data port (traditionally 0xbffd on the 128K + machines) is written to; no corresponding read function as this + always returns 0xff */ +void +ay_dataport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) +{ + int current; + + current = machine_current->ay.current_register; + + machine_current->ay.registers[ current ] = b & mask[ current ]; + sound_ay_write( current, b, tstates ); + if( psg_recording ) psg_write_register( current, b ); + + if( current == 14 ) printer_serial_write( b ); +} + +void +ay_state_from_snapshot( libspectrum_snap *snap ) +{ + size_t i; + + ay_registerport_write( 0xfffd, + libspectrum_snap_out_ay_registerport( snap ) ); + + for( i = 0; i < AY_REGISTERS; i++ ) { + machine_current->ay.registers[i] = + libspectrum_snap_ay_registers( snap, i ); + sound_ay_write( i, machine_current->ay.registers[i], 0 ); + } +} + +static void +ay_from_snapshot( libspectrum_snap *snap ) +{ + if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) { + ay_state_from_snapshot( snap ); + } +} + +static void +ay_to_snapshot( libspectrum_snap *snap ) +{ + size_t i; + + libspectrum_snap_set_out_ay_registerport( + snap, machine_current->ay.current_register + ); + + for( i = 0; i < AY_REGISTERS; i++ ) + libspectrum_snap_set_ay_registers( snap, i, + machine_current->ay.registers[i] ); +} Copied: vendor/fuse-emulator/current/fuse/ay.h (from rev 679, vendor/fuse-emulator/current/fuse/ay.h) =================================================================== --- vendor/fuse-emulator/current/fuse/ay.h (rev 0) +++ vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,47 @@ +/* ay.h: AY-8-3912 routines + Copyright (c) 1999-2009 Philip Kendall + + $Id: ay.h 4030 2009-06-07 14:38:38Z 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... + +*/ + +#ifndef FUSE_AY_H +#define FUSE_AY_H + +#include <libspectrum.h> + +#define AY_REGISTERS 16 + +typedef struct ayinfo { + int current_register; + libspectrum_byte registers[ AY_REGISTERS ]; +} ayinfo; + +int ay_init( void ); + +libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached ); +void ay_registerport_write( libspectrum_word port, libspectrum_byte b ); + +void ay_dataport_write( libspectrum_word port, libspectrum_byte b ); + +void ay_state_from_snapshot( libspectrum_snap *snap ); + +#endif /* #ifndef FUSE_AY_H */ Copied: vendor/fuse-emulator/current/fuse/dck.c (from rev 679, vendor/fuse-emulator/current/fuse/dck.c) =================================================================== --- vendor/fuse-emulator/current/fuse/dck.c (rev 0) +++ vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,184 @@ +/* dck.c: dock snapshot (Warajevo .DCK) handling routines + Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall + + $Id: dck.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: + + Philip: phi...@sh... + + Darren: li...@yo... + Fred: fr...@sp... + +*/ + +#include <config.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <libspectrum.h> + +#include "dck.h" +#include "machine.h" +#include "memory.h" +#include "settings.h" +#include "scld.h" +#include "ui/ui.h" +#include "utils.h" +#include "debugger/debugger.h" + +/* Dock cart inserted? */ +int dck_active = 0; + +int +dck_insert( const char *filename ) +{ + int error; + + if ( !( libspectrum_machine_capabilities( machine_current->machine ) & + LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { + ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); + return 1; + } + + error = settings_set_string( &settings_current.dck_file, filename ); + if( error ) return error; + + machine_reset( 0 ); + + return 0; +} + +void +dck_eject( void ) +{ + if ( !( libspectrum_machine_capabilities( machine_current->machine ) & + LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { + ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); + return; + } + + if( settings_current.dck_file ) free( settings_current.dck_file ); + settings_current.dck_file = NULL; + + dck_active = 0; + + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); + + machine_reset( 0 ); +} + +int +dck_reset( void ) +{ + utils_file file; + size_t num_block = 0; + libspectrum_dck *dck; + int error; + + dck_active = 0; + + if( !settings_current.dck_file ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); + return 0; + } + + dck = libspectrum_dck_alloc(); + + error = utils_read_file( settings_current.dck_file, &file ); + if( error ) { libspectrum_dck_free( dck, 0 ); return error; } + + error = libspectrum_dck_read2( dck, file.buffer, file.length, + settings_current.dck_file ); + if( error ) { + utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; + } + + if( utils_close_file( &file ) ) { + libspectrum_dck_free( dck, 0 ); + return 1; + } + + while( dck->dck[num_block] != NULL ) { + memory_page **mem; + int i; + + switch( dck->dck[num_block]->bank ) { + case LIBSPECTRUM_DCK_BANK_HOME: + mem = memory_map_home; + break; + case LIBSPECTRUM_DCK_BANK_DOCK: + mem = memory_map_dock; + break; + case LIBSPECTRUM_DCK_BANK_EXROM: + mem = memory_map_exrom; + break; + default: + ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", + dck->dck[num_block]->bank ); + libspectrum_dck_free( dck, 0 ); + return 1; + } + + for( i = 0; i < 8; i++ ) { + + switch( dck->dck[num_block]->access[i] ) { + + case LIBSPECTRUM_DCK_PAGE_NULL: + break; + + case LIBSPECTRUM_DCK_PAGE_ROM: + mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); + if( !mem[i]->page ) return 1; + memcpy( mem[i]->page, dck->dck[num_block]->pages[i], + MEMORY_PAGE_SIZE ); + mem[i]->writable = 0; + mem[i]->source = MEMORY_SOURCE_CARTRIDGE; + break; + + case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: + case LIBSPECTRUM_DCK_PAGE_RAM: + /* Because the scr and snapshot code depends on the standard + memory map being in the RAM[] array, we just copy RAM + blocks from the HOME bank into the appropriate page; in + other cases, we allocate ourselves a new page to store the + contents in */ + if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { + mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); + if( !mem[i]->page ) return 1; + mem[i]->writable = 1; + } + + mem[i]->source = MEMORY_SOURCE_CARTRIDGE; + memcpy( mem[i]->page, dck->dck[num_block]->pages[i], + MEMORY_PAGE_SIZE ); + break; + + } + } + num_block++; + } + + dck_active = 1; + + /* Make the menu item to eject the cartridge active */ + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); + + return libspectrum_dck_free( dck, 0 ); +} Copied: vendor/fuse-emulator/current/fuse/dck.h (from rev 679, vendor/fuse-emulator/current/fuse/dck.h) =================================================================== --- vendor/fuse-emulator/current/fuse/dck.h (rev 0) +++ vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,39 @@ +/* dck.h: dock snapshot (Warajevo .DCK) handling routines + Copyright (c) 2003 Darren Salt, Fredrick Meunier + + $Id: dck.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: + + Philip: phi...@sh... + + Darren: li...@yo... + Fred: fr...@sp... + +*/ + +#ifndef FUSE_DCK_H +#define FUSE_DCK_H + +/* Dock cart inserted? */ +extern int dck_active; + +int dck_insert( const char *filename ); +void dck_eject( void ); +int dck_reset( void ); + +#endif Copied: vendor/fuse-emulator/current/fuse/fuller.c (from rev 679, vendor/fuse-emulator/current/fuse/fuller.c) =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.c (rev 0) +++ vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,90 @@ +/* fuller.c: Routines for handling the Fuller Box + Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier + + $Id: fuller.c 4032 2009-06-10 11:09:44Z 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: + + Philip: phi...@sh... + + Stuart: sd...@nt... + +*/ + +#include <config.h> + +#include <libspectrum.h> + +#include "ay.h" +#include "compat.h" +#include "fuller.h" +#include "joystick.h" +#include "module.h" +#include "periph.h" +#include "settings.h" + +static void fuller_enabled_snapshot( libspectrum_snap *snap ); +static void fuller_from_snapshot( libspectrum_snap *snap ); +static void fuller_to_snapshot( libspectrum_snap *snap ); + +static module_info_t fuller_module_info = { + + NULL, + NULL, + fuller_enabled_snapshot, + fuller_from_snapshot, + fuller_to_snapshot, + +}; + +const periph_t fuller_peripherals[] = { + { 0x00ff, 0x003f, ay_registerport_read, ay_registerport_write }, + { 0x00ff, 0x005f, NULL, ay_dataport_write }, + { 0x00ff, 0x007f, joystick_fuller_read, NULL }, +}; + +const size_t fuller_peripherals_count = + sizeof( fuller_peripherals ) / sizeof( periph_t ); + +static void +fuller_enabled_snapshot( libspectrum_snap *snap ) +{ + if( libspectrum_snap_fuller_box_active( snap ) ) + settings_current.fuller = 1; +} + +static void +fuller_from_snapshot( libspectrum_snap *snap ) +{ + if( periph_fuller_active ) { + ay_state_from_snapshot( snap ); + } +} + +static void +fuller_to_snapshot( libspectrum_snap *snap ) +{ + libspectrum_snap_set_fuller_box_active( snap, periph_fuller_active ); +} + +int +fuller_init( void ) +{ + module_register( &fuller_module_info ); + + return 0; +} Copied: vendor/fuse-emulator/current/fuse/fuller.h (from rev 679, vendor/fuse-emulator/current/fuse/fuller.h) =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.h (rev 0) +++ vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,40 @@ +/* fuller.h: Routines for handling the Fuller Box + Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier + + $Id: fuller.h 4030 2009-06-07 14:38:38Z 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: + + Philip: phi...@sh... + + Stuart: sd...@nt... + +*/ + +#ifndef FUSE_FULLER_H +#define FUSE_FULLER_H + +#include <libspectrum.h> + +#include "periph.h" + +extern const periph_t fuller_peripherals[]; +extern const size_t fuller_peripherals_count; + +int fuller_init( void ); + +#endif /* #ifndef FUSE_FULLER_H */ Copied: vendor/fuse-emulator/current/fuse/if1.c (from rev 679, vendor/fuse-emulator/current/fuse/if1.c) =================================================================== --- vendor/fuse-emulator/current/fuse/if1.c (rev 0) +++ vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,1304 @@ +/* if1.c: Interface I handling routines + Copyright (c) 2004-2008 Gergely Szasz, Philip Kendall + + $Id: if1.c 4180 2010-10-09 12:59: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 + 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: + + Gergely: sz...@hu... + +*/ + +#include <config.h> + +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <unistd.h> + +#include "compat.h" +#include "debugger/debugger.h" +#include "if1.h" +#include "machine.h" +#include "memory.h" +#include "module.h" +#include "periph.h" +#include "settings.h" +#include "utils.h" +#include "ui/ui.h" + +#undef IF1_DEBUG_MDR +#undef IF1_DEBUG_NET +#undef IF1_DEBUG_NET_1 + +#define BUFF_EMPTY 0x100 + +enum { + SYNC_NO = 0, + SYNC_OK = 0xff +}; + +/* + Microdrive cartridge + GAP PREAMBLE 15 byte GAP PREAMBLE 15 byte 512 1 + [-----][00 00 ... ff ff][BLOCK HEAD][-----][00 00 ... ff ff][REC HEAD][ DATA ][CHK] + Preamble = 10 * 0x00 + 2 * 0xff (12 byte) +*/ + +typedef struct microdrive_t { + utils_file file; + char *filename; /* old filename */ + int inserted; + int modified; + int motor_on; + int head_pos; + int transfered; + int max_bytes; + libspectrum_byte pream[512]; /* preamble/sync area written */ + libspectrum_byte last; + libspectrum_byte gap; + libspectrum_byte sync; + + libspectrum_microdrive *cartridge; /* write protect, len, blocks */ + +} microdrive_t; + +typedef struct if1_ula_t { + int fd_r; /* file descriptor for reading bytes or bits RS232 */ + int fd_t; /* file descriptor for writing bytes or bits RS232 */ + int fd_net; /* file descriptor for rw bytes or bits SinclairNET */ + int rs232_buffer; /* read buffer */ + int s_net_mode; + int status; /* if1_ula/SinclairNET */ + int comms_data; /* the previous data comms state */ + int comms_clk; /* the previous data comms state */ + int cts; /* CTS of peripheral */ + int dtr; /* DTR of peripheral */ + int tx; /* TxD the name is very kind, because this is the read end of + the TxD wire of DATA machine (really RxD the view of + spectrum */ + int rx; /* RxD the name is very kind, because this is the write end of + the RxD wire of DATA machine (really TxD the view of + spectrum */ + int data_in; /* interpreted incoming data */ + int count_in; + int data_out; /* interpreted outgoing data */ + int count_out; + int esc_in; /* if we compose an escape seq */ + + int net; /* Network in/out (really 1 wire bus :-) */ + int net_data; /* Interpreted network data */ + int net_state; /* Interpreted network data */ + int wait; /* Wait state */ + int busy; /* Indicate busy; if1 software never poll it ... */ +} if1_ula_t; + +/* + 7 6 5 4 3 2 1 0 + STATUS RO $EF(239) --- --- --- BSY DTR GAP SYN WPR + + CONTRO WO $EF(239) --- --- WAT CTS ERA R/w CLK DTA + + MDR DT RW $E7(231) D7 D6 D5 D4 D3 D2 D1 D0 + + COMM I RO $F7(247) TX --- --- --- --- --- --- NET + + COMM O WO $F7(247) --- --- --- --- --- --- --- NET/RX + +RS232: + DTR -> Data Terminal Ready (DTE -> DCE) + CTS -> Clear To Send (DCE -> DTE) + TX -> Transmitted Data (DTE -> DCE) + RX -> Received Data (DCE -> DTE) + + The IF1 serial behaves not as a DTE (Data Terminal Equipment, e.g. + a computer) but as a DCE (Data Communications Equipment, e.g. a modem) + + If we were to consider the ZX Spectrum a DTE, we would rename the lines: + DTR := DSR (Data Set Ready) + CTS := RTS (Request To Send) + TX := RX + RX := TX + + On the communication channels: + Bytes interpreted as is, except: + 0x00 0x00 --> DTR ~~\__ + 0x00 0x01 --> DTR __/~~ + 0x00 0x02 --> CTS ~~\__ + 0x00 0x03 --> CTS __/~~ + 0x00 ? --> lost + 0x00 * --> 0x00 + Additionally: + if fuse read 0x00 0x00 => DTR = 0 ~~\__ + if fuse read 0x00 0x01 => DTR = 1 __/~~ + if CTS = ~~\__ fuse send 0x00 0x02 + if CTS = __/~~ fuse send 0x00 0x03 + if fuse lost send 0x00 + 0x3f (?) + every other 0x00 + 0x## are discarded +*/ + +/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ +static memory_page if1_memory_map_romcs[2]; + +/* IF1 paged out ROM activated? */ +int if1_active = 0; +int if1_available = 0; +static int if1_mdr_status = 0; + +int rnd_factor = ( ( RAND_MAX >> 2 ) << 2 ) / 19 + 1; + +static microdrive_t microdrive[8]; /* We have 8 microdrive */ +static if1_ula_t if1_ula; + +static void microdrives_reset( void ); +static void microdrives_restart( void ); +static void increment_head( int m ); + +#define MDR_IN(m) microdrive[m - 1].inserted +#define MDR_WP(m) libspectrum_microdrive_write_protect( microdrive[m - 1].cartridge ) + +enum if1_menu_item { + + UMENU_ALL = 0, + UMENU_MDRV1, + UMENU_MDRV2, + UMENU_MDRV3, + UMENU_MDRV4, + UMENU_MDRV5, + UMENU_MDRV6, + UMENU_MDRV7, + UMENU_MDRV8, + UMENU_RS232, +}; + +enum if1_port { + PORT_MDR, + PORT_CTR, + PORT_NET, + PORT_UNKNOWN, +}; + +static void if1_reset( int hard_reset ); +static void if1_enabled_snapshot( libspectrum_snap *snap ); +static void if1_from_snapshot( libspectrum_snap *snap ); +static void if1_to_snapshot( libspectrum_snap *snap ); + +static module_info_t if1_module_info = { + + if1_reset, + if1_memory_map, + if1_enabled_snapshot, + if1_from_snapshot, + if1_to_snapshot, + +}; + +const periph_t if1_peripherals[] = { + { 0x0018, 0x0010, if1_port_in, if1_port_out }, + { 0x0018, 0x0008, if1_port_in, if1_port_out }, + { 0x0018, 0x0000, if1_port_in, if1_port_out }, +}; + +const size_t if1_peripherals_count = + sizeof( if1_peripherals ) / sizeof( periph_t ); + +/* Debugger events */ +static const char *event_type_string = "if1"; +static int page_event, unpage_event; + +static void +update_menu( enum if1_menu_item what ) +{ + if( what == UMENU_ALL || what == UMENU_MDRV1 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_EJECT, MDR_IN( 1 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_WP_SET, + !MDR_IN( 1 ) ? 0 : !MDR_WP( 1 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV2 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_EJECT, MDR_IN( 2 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_WP_SET, + !MDR_IN( 2 ) ? 0 : !MDR_WP( 2 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV3 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_EJECT, MDR_IN( 3 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_WP_SET, + !MDR_IN( 3 ) ? 0 : !MDR_WP( 3 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV4 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_EJECT, MDR_IN( 4 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_WP_SET, + !MDR_IN( 4 ) ? 0 : !MDR_WP( 4 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV5 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_EJECT, MDR_IN( 5 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_WP_SET, + !MDR_IN( 5 ) ? 0 : !MDR_WP( 5 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV6 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_EJECT, MDR_IN( 6 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_WP_SET, + !MDR_IN( 6 ) ? 0 : !MDR_WP( 6 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV7 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_EJECT, MDR_IN( 7 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_WP_SET, + !MDR_IN( 7 ) ? 0 : !MDR_WP( 7 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV8 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_EJECT, MDR_IN( 8 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_WP_SET, + !MDR_IN( 8 ) ? 0 : !MDR_WP( 8 ) ); + } + + if( what == UMENU_ALL || what == UMENU_RS232 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_R, + ( if1_ula.fd_r > -1 ) ? 1 : 0 ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_T, + ( if1_ula.fd_t > -1 ) ? 1 : 0 ); +#ifdef BUILD_WITH_SNET + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_SNET_UNPLUG, + ( if1_ula.fd_net > -1 ) ? 1 : 0 ); +#endif + } +} + +int +if1_init( void ) +{ + int m, i; + + if1_ula.fd_r = -1; + if1_ula.fd_t = -1; + if1_ula.dtr = 0; /* No data terminal yet */ + if1_ula.cts = 2; /* force to emit first cts status */ + if1_ula.comms_clk = 0; + if1_ula.comms_data = 0; /* really? */ + if1_ula.fd_net = -1; + if1_ula.s_net_mode = 1; + if1_ula.net = 0; + if1_ula.esc_in = 0; /* empty */ + + for( m = 0; m < 8; m++ ) { + microdrive[m].cartridge = libspectrum_microdrive_alloc(); + microdrive[m].inserted = 0; + microdrive[m].modified = 0; + } + + if( settings_current.rs232_rx ) { + if1_plug( settings_current.rs232_rx, 1 ); + free( settings_current.rs232_rx ); + settings_current.rs232_rx = NULL; + } + + if( settings_current.rs232_tx ) { + if1_plug( settings_current.rs232_tx, 2 ); + free( settings_current.rs232_tx ); + settings_current.rs232_tx = NULL; + } + + if( settings_current.snet ) { + if1_plug( settings_current.snet, 3 ); + free( settings_current.snet ); + settings_current.snet = NULL; + } + + module_register( &if1_module_info ); + for( i = 0; i < 2; i++ ) if1_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; + + if( periph_register_paging_events( event_type_string, &page_event, + &unpage_event ) ) + return 1; + + return 0; +} + +libspectrum_error +if1_end( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + libspectrum_error error = + libspectrum_microdrive_free( microdrive[m].cartridge ); + if( error ) return error; + } + + return LIBSPECTRUM_ERROR_NONE; +} + +void +if1_update_menu( void ) +{ + update_menu( UMENU_ALL ); +} + +static void +if1_reset( int hard_reset GCC_UNUSED ) +{ + if1_active = 0; + if1_available = 0; + + if( !periph_interface1_active ) return; + + machine_load_rom_bank( if1_memory_map_romcs, 0, 0, + settings_current.rom_interface_i, + settings_default.rom_interface_i, + MEMORY_PAGE_SIZE ); + + if1_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; + + machine_current->ram.romcs = 0; + + if1_ula.cts = 2; /* force to emit first out if raw */ + if1_ula.comms_clk = 0; + if1_ula.comms_data = 0; + if1_ula.net = 0; + if1_ula.esc_in = 0; + + microdrives_reset(); + + update_menu( UMENU_ALL ); + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + + if1_mdr_status = 0; + + if1_available = 1; +} + +void +if1_page( void ) +{ + if1_active = 1; + machine_current->ram.romcs = 1; + machine_current->memory_map(); + + debugger_event( page_event ); +} + +void +if1_unpage( void ) +{ + if1_active = 0; + machine_current->ram.romcs = 0; + machine_current->memory_map(); + + debugger_event( unpage_event ); +} + +void +if1_memory_map( void ) +{ + if( !if1_active ) return; + + memory_map_read[0] = memory_map_write[0] = if1_memory_map_romcs[0]; +} + +static void +if1_enabled_snapshot( libspectrum_snap *snap ) +{ + if( libspectrum_snap_interface1_active( snap ) ) + settings_current.interface1 = 1; +} + +static void +if1_from_snapshot( libspectrum_snap *snap ) +{ + if( !libspectrum_snap_interface1_active( snap ) ) return; + + if( libspectrum_snap_interface1_custom_rom( snap ) && + libspectrum_snap_interface1_rom( snap, 0 ) && + machine_load_rom_bank_from_buffer( + if1_memory_map_romcs, 0, 0, + libspectrum_snap_interface1_rom( snap, 0 ), + libspectrum_snap_interface1_rom_length( snap, 0 ), + 1 ) ) + return; + + if( libspectrum_snap_interface1_paged( snap ) ) { + if1_page(); + } else { + if1_unpage(); + } +} + +static void +if1_to_snapshot( libspectrum_snap *snap ) +{ + libspectrum_byte *buffer; + + if( !periph_interface1_active ) return; + + libspectrum_snap_set_interface1_active( snap, 1 ); + libspectrum_snap_set_interface1_paged ( snap, if1_active ); + libspectrum_snap_set_interface1_drive_count( snap, 8 ); + + if( if1_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { + size_t rom_length = MEMORY_PAGE_SIZE; + + if( if1_memory_map_romcs[1].source == MEMORY_SOURCE_CUSTOMROM ) { + rom_length <<= 1; + } + + libspectrum_snap_set_interface1_custom_rom( snap, 1 ); + libspectrum_snap_set_interface1_rom_length( snap, 0, rom_length ); + + buffer = malloc( rom_length ); + if( !buffer ) { + ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); + return; + } + + memcpy( buffer, if1_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); + + if( rom_length == MEMORY_PAGE_SIZE*2 ) { + memcpy( buffer + MEMORY_PAGE_SIZE, if1_memory_map_romcs[1].page, + MEMORY_PAGE_SIZE ); + } + + libspectrum_snap_set_interface1_rom( snap, 0, buffer ); + } +} + +static void +microdrives_reset( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + microdrive[m].head_pos = 0; + microdrive[m].motor_on = 0; /* motor off */ + microdrive[m].gap = 15; + microdrive[m].sync = 15; + microdrive[m].transfered = 0; + } + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + if1_mdr_status = 0; +/* + if1_ula.comms_data = 0; + if1_ula.count_in = 0; + if1_ula.count_out = 0; + if1_ula.cts = 0; + if1_ula.dtr = 0; + if1_ula.wait = 0; + if1_ula.busy = 0; + if1_ula.net = 0; + if1_ula.net_state = 0; +*/ +} + +static enum if1_port +decode_port( libspectrum_word port ) +{ + switch( port & 0x0018 ) { + case 0x0000: return PORT_MDR; + case 0x0008: return PORT_CTR; + case 0x0010: return PORT_NET; + default: return PORT_UNKNOWN; + } +} + +static libspectrum_byte +port_mdr_in( void ) +{ + libspectrum_byte ret = 0xff; + int m; + + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { + + if( mdr->transfered < mdr->max_bytes ) { + mdr->last = libspectrum_microdrive_data( mdr->cartridge, + mdr->head_pos ); + increment_head( m ); + } + + mdr->transfered++; + ret &= mdr->last; /* I assume negative logic, but how know? */ + } + + } + + return ret; +} + +static libspectrum_byte +port_ctr_in( void ) +{ + libspectrum_byte ret = 0xff; + int m, block; + + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { + block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); + if( mdr->pream[block] == SYNC_OK ) { /* if formatted */ + if( mdr->gap ) { + /* ret &= 0xff; GAP and SYNC high ? */ + mdr->gap--; + } else { + ret &= 0xf9; /* GAP and SYNC low */ + if( mdr->sync ) { + mdr->sync--; + } else { + mdr->gap = 15; + mdr->sync = 15; + } + } + } + /* if write protected */ + if( libspectrum_microdrive_write_protect( mdr->cartridge) ) + ret &= 0xfe; /* active bit */ + } + } + /* Here we have to poll, the if1_ula DTR 'line' */ + if( if1_ula.rs232_buffer > 0xff ) { /* buffer empty */ + unsigned char byte; + int yes = 1; + + while( yes && read( if1_ula.fd_r, &byte, 1 ) == 1 ) { + if( if1_ula.esc_in == 1 ) { + if1_ula.esc_in = 0; + if( byte == '*' ) { + if1_ula.rs232_buffer = 0x00; + yes = 0; + } else if( byte == 0x00 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 0; + } else if( byte == 0x01 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 1; + } + } else if( byte == 0x00 ) { + if1_ula.esc_in = 1; + } else { + if1_ula.rs232_buffer = byte; + yes = 0; + break; + } + } + } + + if( if1_ula.dtr == 0 ) + ret &= 0xf7; /* %11110111 */ + + /* Here we have to poll, the 'SinclairNet' busy flag but never used by + software in Interface 1 */ + if( if1_ula.busy == 0 ) + ret &= 0xef; /* %11101111 */ + /* fprintf( stderr, "Read CTR ( %%%d%d%d%d%d%d%d%d ).\n", + !!(ret & 128), !!(ret & 64), !!(ret & 32), !!(ret & 16), + !!(ret & 8), !!(ret & 4), !!(ret & 2), !!(ret & 1)); */ + microdrives_restart(); + + return ret; +} + +/* + return 1 if read a byte + 0 if nothing interesting... +*/ + +static int +read_rs232() +{ + if( if1_ula.rs232_buffer <= 0xff ) { /* we read from the buffer */ + if1_ula.data_in = if1_ula.rs232_buffer; + if1_ula.rs232_buffer = 0x0100; + return 1; + } + while( read( if1_ula.fd_r, &if1_ula.data_in, 1 ) == 1 ) { + if( if1_ula.esc_in == 1 ) { + if1_ula.esc_in = 0; + if( if1_ula.data_in == '*' ) { + if1_ula.data_in = 0x00; + return 1; + } else if( if1_ula.data_in == 0x00 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 0; + } else if( if1_ula.data_in == 0x01 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 1; + } + } else if( if1_ula.data_in == 0x00 ) { + if1_ula.esc_in = 1; + } else { + return 1; + } + } + return 0; +} + +static libspectrum_byte +port_net_in( void ) +{ + libspectrum_byte ret = 0xff; + + if( if1_ula.fd_r == -1 ) + goto no_rs232_in; + + /* Here is the RS232 input routine */ + if( if1_ula.cts ) { /* If CTS == 1 */ + if( if1_ula.count_in == 0 ) { + if( if1_ula.fd_r >= 0 && read_rs232() == 1 ) { + if1_ula.count_in++; /* Ok, if read a byte, we begin */ + } + if1_ula.tx = 0; /* now send __ to if1 + later we raise :-) */ + } else if( if1_ula.count_in >= 1 && if1_ula.count_in < 5 ) { + if1_ula.tx = 1; /* send ~~ (start bit :-) */ + if1_ula.count_in++; + } else if( if1_ula.count_in >= 5 && if1_ula.count_in < 13 ) { + if1_ula.tx = ( if1_ula.data_in & 0x01 ) ? 0 : 1; + /* send .. (data bits :-) */ + if1_ula.data_in >>= 1; /* prepare next bit :-) */ + if1_ula.count_in++; + } else + if1_ula.count_in = 0; + } else { /* if( if1_ula.cts ) */ + if1_ula.count_in = 0; /* reset serial in */ + if1_ula.tx = 0; /* send __ stop bits or s.e. :-) */ + } + +no_rs232_in: + if( if1_ula.fd_net == -1 ) + goto no_snet_in; + + if( if1_ula.s_net_mode == 0 ) { /* if we do raw */ + /* Here is the input routine */ + read( if1_ula.fd_net, &if1_ula.net, 1 ); /* Ok, if no byte, we send last*/ + } else {/* if( if1_ula.s_net_mode == 1 ) if we do interpreted */ +/* Here is the input routine. There are several stage in input + and output. So first for output. if1 first do SEND-SC + (http://www.wearmouth.demon.co.uk/if1_2.htm#L101E) to send + a Sync-Out signal and SEND-SC do first a NET-STATE + (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FBC) to see + the line activity: + 11xxxxxx times (192-255) have to get a zero (bit for network) + plus 1 times more from SEND-SC. Next SEND-SC send a 0 which is + a 1 on the net wire (negated output, straight input!!!) + + OK. In input first if1 call WT-SC-E to check Network activity + (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FD3). Now check + 128 times the net wire (we do two round, because to differentiate + net out routines...) +*/ + + if( if1_ula.net_state < 0x0100 ) { /* if1 may in NET-STATE */ + if1_ula.net_state++; + if1_ula.net = 0; +#ifdef IF1_DEBUG_NET + fprintf( stderr, "NET-STAT(%03d)? We send 0!\n", if1_ula.net_state ); +#endif + } else if( if1_ula.net_state == 0x0100 ) { /* probably waiting for input */ + if( read( if1_ula.fd_net, &if1_ula.net_data, 1 ) == 1 ) { + if1_ula.net_state++; + if1_ula.net = 1; /* Start with __/~~ */ + } /* Ok, if have a byte, we send it! */ + } else if( if1_ula.net_state == 0x0101 ) { + if1_ula.net_state++; + if1_ula.net = 1; /* one more ~~ */ + } else if( if1_ula.net_state > 0x0101 && + if1_ula.net_state < 0x010a ) { /* we send the data bits... */ + if1_ula.net_state++; + if1_ula.net = if1_ula.net_data & 1; + if1_ula.net_data >>= 1; + } else if( if1_ula.net_state == 0x010a ) { + if1_ula.net = 0; + if1_ula.net_state = 0; /* OK, we starting a new byte... */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "NET-STAT(%03d)? Get a byte!\n", if1_ula.net_state ); +#endif + } + } +no_snet_in: + if( !if1_ula.tx ) + ret &= 0x7f; + if( !if1_ula.net ) + ret &= 0xfe; + microdrives_restart(); + + return ret; +} + +libspectrum_byte +if1_port_in( libspectrum_word port GCC_UNUSED, int *attached ) +{ + libspectrum_byte ret = 0xff; + + if( !if1_active ) return ret; + + *attached = 1; + + switch( decode_port( port ) ) + { + case PORT_MDR: ret &= port_mdr_in(); break; + case PORT_CTR: ret &= port_ctr_in(); break; + case PORT_NET: ret &= port_net_in(); break; + case PORT_UNKNOWN: break; + } + + return ret; +} + +static void +port_mdr_out( libspectrum_byte val ) +{ + int m, block; + + /* allow access to the port only if motor 1 is ON and there's a file open */ + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { +#ifdef IF1_DEBUG_MDR + fprintf(stderr, "#%05d %03d(%03d): 0x%02x\n", + mdr->head_pos, mdr->transfered, mdr->max_bytes, val ); +#endif + block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); + if( mdr->transfered == 0 && val == 0x00 ) { /* start pream */ + mdr->pream[block] = 1; + } else if( mdr->transfered > 0 && mdr->transfered < 10 && val == 0x00 ) { + mdr->pream[block]++; + } else if( mdr->transfered > 9 && mdr->transfered < 12 && val == 0xff ) { + mdr->pream[block]++; + } else if( mdr->transfered == 12 && mdr->pream[block] == 12 ) { + mdr->pream[block] = SYNC_OK; + } + if( mdr->transfered > 11 && + mdr->transfered < mdr->max_bytes + 12 ) { + + libspectrum_microdrive_set_data( mdr->cartridge, mdr->head_pos, + val ); + increment_head( m ); + mdr->modified = 1; + } + mdr->transfered++; + } + } +} + +static void +port_ctr_out( libspectrum_byte val ) +{ + int m; + + if( !( val & 0x02 ) && ( if1_ula.comms_clk ) ) { /* ~~\__ */ + + for( m = 7; m > 0; m-- ) { + /* Rotate one drive */ + microdrive[m].motor_on = microdrive[m - 1].motor_on; + } + microdrive[0].motor_on = (val & 0x01) ? 0 : 1; + + if( microdrive[0].motor_on || microdrive[1].motor_on || + microdrive[2].motor_on || microdrive[3].motor_on || + microdrive[4].motor_on || microdrive[5].motor_on || + microdrive[6].motor_on || microdrive[7].motor_on ) { + if( !if1_mdr_status ) { + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_ACTIVE ); + if1_mdr_status = 1; + } + } else if ( if1_mdr_status ) { + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + if1_mdr_status = 0; + } + } + if( val & 0x01 ) { /* comms_data == 1 */ + /* Interface 1 service manual p.:1.4 par.: 1.5.1 + The same pin on IC1 (if1 ULA), pin 33, is used for the network + transmit data and for the RS232 transmit data. In order to select + the required function IC1 uses its COMMS_OUT (pin 30) signal, + borrowed from the microdrive control when the microdrive is not + being used (I do not know what it is exactly meaning. It is a + hardware not being used, or a software should not use..?) This signal + is routed from pin 30 to the emitter of transistor Q3 (RX DATA) and + via resistor R4, to the base of transistor Q1 (NET). When COMMS_OUT + is high Q3 is enabled this selecting RS232, and when it is low + Q1 is enabled selecting the network. + + OK, the schematics offer a different interpretation, because if + COMMS_OUT pin level high (>+3V) then Q3 is off (the basis cannot + be more higher potential then emitter (NPN transistor), so whatever + is on the IC1 RX DATA (pin 33) the basis of Q4 is always on +12V, + so the collector of Q4 (PNP transistor) always on -12V. + If COMMS_OUT pin level goes low (~0V), then Q3 basis (connected + to IC1 RX DATA pin) can be higher level (>+3V) than emitter, so + the basis potential of Q4 depend on IC1 RX DATA. + + OK, Summa summarum I assume that, the COMMS OUT pin is a + negated output of the if1 ULA CTR register's COMMS DATA bit. + */ + /* C_DATA = 1 */ + if( if1_ula.comms_data == 0 ) { + if1_ula.count_out = 0; + if1_ula.data_out = 0; + if1_ula.count_in = 0; + if1_ula.data_in = 0; + } + } + if1_ula.wait = ( val & 0x20 ) ? 1 : 0; + if1_ula.comms_data = ( val & 0x01 ) ? 1 : 0; + if1_ula.comms_clk = ( val & 0x02 ) ? 1 : 0; + val = ( val & 0x10 ) ? 1 : 0; + if( settings_current.rs232_handshake && + if1_ula.fd_t != -1 && if1_ula.cts != val ) { + char data = val ? 0x03 : 0x02; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + do ; while( write( if1_ula.fd_t, &data, 1 ) != 1 ); + } + if1_ula.cts = val; + +#ifdef IF1_DEBUG_NET + fprintf( stderr, "Set CTS to %d, set WAIT to %d and COMMS_DATA to %d\n", + if1_ula.cts, if1_ula.wait, if1_ula.comms_data ); +#endif + + microdrives_restart(); +} + +static void +port_net_out( libspectrum_byte val ) +{ + if( if1_ula.fd_t == -1 ) + return; /* nothing to write */ + + if( if1_ula.comms_data == 1 ) { /* OK, RS232 */ + val &= 0x01; + if( if1_ula.count_out == 0 && !val ) { /* waiting for ~~\__ */ + if1_ula.count_out++; + } else if( if1_ula.count_out == 1 ) { + if( if1_ula.cts != 0 || !val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; /* else get the start bit __/~~ */ + } else if( if1_ula.count_out >= 2 && if1_ula.count_out <= 9 ) { + if1_ula.data_out >>= 1; + if1_ula.data_out |= val & 0x01 ? 0 : 128; + if1_ula.count_out++; /* waiting for next data bit */ + } else if( if1_ula.count_out >= 10 && if1_ula.count_out <= 11 ) { + if( val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; + } else if( if1_ula.count_out == 12 ) { + if( !val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; + } else if( if1_ula.count_out == 13 ) { + if( val ) + if1_ula.count_out = -1; + } + + if( if1_ula.count_out == -1 ) { + if1_ula.count_out = 13; + if1_ula.data_out = '?'; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + } + if( if1_ula.count_out == 13 ) { + /* Here is the output routine */ + if( if1_ula.data_out == 0x00 ) { + if1_ula.data_out = '*'; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + } + do ; while( write( if1_ula.fd_t, &if1_ula.data_out, 1 ) != 1 ); + if1_ula.count_out = 0; + } + if1_ula.rx = val & 0x01; /* set rx */ + } else { /* if( if1_ula.comms_data == 1 ) SinclairNET :-)*/ + if( if1_ula.s_net_mode == 0 ) { /* if we out bit by bit, do it */ + /* Here is the output routine */ + +/* OK, examining the schematics of if1 and the disassembly of if1 ROM, I + see that the Q1 and Q2 transistors negate the RX DATA signal, and the + floating state of the net wire is the ~0V level, the forced is the ~3V. + The if1 software send complemented data and read straight data. +*/ + if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set rx */ + lseek( if1_ula.fd_net, 0, SEEK_SET ); /* we save only the state of the wire*/ + do ; while( write( if1_ula.fd_net, &if1_ula.net, 1 ) == -1 ); +#ifdef HAVE_FSYNC + fsync( if1_ula.fd_net ); +#endif /* #ifdef HAVE_FSYNC */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "Send SinclairNET: %d\n", if1_ula.net ); +#endif + } else { /* if( if1_ula.s_net_mode == 0 ) if we out byte by byte, do it */ + if( if1_ula.net_state >= 0x0200 && if1_ula.net_state < 0x0208 ) { + if1_ula.net_state++; + if1_ula.net_data <<= 1; + if1_ula.net_data |= ( val & 0x01 ) ? 0 : 1; + } else if( if1_ula.net_state == 0x0208 ) { + if1_ula.net_data &= 0xff; + if1_ula.net_state++; /* OK, now we get data bytes... */ + +/* lseek( if1_ula.fd_net, 0, SEEK_SET ); start a packet */ + /* first we send the station number */ + do ; while( write( if1_ula.fd_net, &if1_ula.net_data, 1 ) == -1 ); +#ifdef HAVE_FSYNC + fsync( if1_ula.fd_net ); +#endif /* #ifdef HAVE_FSYNC */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "SC-OUT send network number: %d\n", + if1_ula.net_data ^ 0xff ); +#endif + } else if( if1_ula.net_state > 192 && if1_ula.net_state < 0x0200 && + ( ( val & 0x01 ) == 0 ) ) { + /* NET-STATE ask as many times.... and now send a 0 */ +/* if1_ula.net = 1; */ + if1_ula.net_state = 0x0200; /* Send the station number */ + } + if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set net wire? */ + } + } + microdrives_restart(); +} + +void +if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val ) +{ + if( !if1_active ) return; + +#ifdef IF1_DEBUG_NET_1 + fprintf( stderr, "In if1_port_out( %%%d%d%d%d%d%d%d%d => 0x%04x ).\n", + !!(val & 128), !!(val & 64), !!(val & 32), !!(val & 16), + !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port); +#endif + + switch( decode_port( port ) ) { + case PORT_MDR: port_mdr_out( val ); break; + case PORT_CTR: port_ctr_out( val ); break; + case PORT_NET: port_net_out( val ); break; + case PORT_UNKNOWN: break; + } +} + +static void +increment_head( int m ) +{ + microdrive[m].head_pos++; + if( microdrive[m].head_pos >= + libspectrum_microdrive_cartridge_len( microdrive[m].cartridge ) * + LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) + microdrive[m].head_pos = 0; +} + +static void +microdrives_restart( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + while( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != 0 && + ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != LIBSPECTRUM_MICRODRIVE_HEAD_LEN ) + increment_head( m ); /* put head in the start of a block */ + + microdrive[m].transfered = 0; /* reset current number of bytes written */ + + if( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) == 0 ) { + microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN; /* up to 15 bytes for header blocks */ + } else { + microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN + LIBSPECTRUM_MICRODRIVE_DATA_LEN + 1; /* up to 528 bytes for data blocks */ + } + } +} + +void +if1_mdr_writeprotect( int drive, int wrprot ) +{ + libspectrum_microdrive_set_write_protect( microdrive[drive].cartridge, + wrprot ? 1 : 0 ); + microdrive[drive].modified = 1; + + update_menu( UMENU_MDRV1 + drive ); +} + +static void +if1_mdr_new( microdrive_t *mdr ) +{ + libspectrum_byte len; + long int i; + + mdr->filename = NULL; + if( settings_current.mdr_random_len ) { /* Random length */ + len = 171 + ( ( rand() >> 2 ) + ( rand() >> 2 ) + + ( rand() >> 2 ) + ( rand() >> 2 ) ) + / rnd_factor; + } else + len = settings_current.mdr_len = settings_current.mdr_len < 10 ? 10 : + settings_current.mdr_len > LIBSPECTRUM_MICRODRIVE_BLOCK_MAX ? LIBSPECTRUM_MICRODRIVE_BLOCK_MAX : settings_current.mdr_len; + + /* Erase the entire cartridge */ + libspectrum_microdrive_set_cartridge_len( mdr->cartridge, len ); + + for( i = 0; i < len * LIBSPECTRUM_MICRODRIVE_BLOCK_LEN; i++ ) + libspectrum_microdrive_set_data( mdr->cartridge, i, 0xff ); + + for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); + i > 0; i-- ) + mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_NO; + + /* but don't write-protect */ + libspectrum_microdrive_set_write_protect( mdr->cartridge, 0 ); + + mdr->inserted = 1; + mdr->modified = 1; + +} + +int +if1_mdr_insert( int which, const char *filename ) +{ + microdrive_t *mdr; + int m, i; + + if( which == -1 ) { /* find an empty one */ + for( m = 0; m < 8; m++ ) { + if( !microdrive[m].inserted ) { + which = m; + break; + } + } + } + + if( which == -1 ) { + ui_error( UI_ERROR_ERROR, + "Cannot insert cartridge '%s', all Microdrives in use", + filename ); + return 1; + } + + if( which >= 8 ) { + ui_error( UI_ERROR_ERROR, "if1_mdr_insert: unknown drive %d", which ); + return 1; + } + + mdr = µdrive[ which ]; + + /* Eject any cartridge already in the drive */ + if( mdr->inserted ) { + /* Abort the insert if we want to keep the current cartridge */ + if( if1_mdr_eject( which, 0 ) ) return 0; + } + + if( filename == NULL ) { /* insert new unformatted cartridge */ + if1_mdr_new( mdr ); + update_menu( UMENU_MDRV1 + which ); + return 0; + } + + if( utils_read_file( filename, &mdr->file ) ) { + ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); + return 1; + } + + if( libspectrum_microdrive_mdr_read( mdr->cartridge, mdr->file.buffer, + mdr->file.length ) ) { + utils_close_file( &mdr->file ); + ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); + return 1; + } + + if( utils_close_file( &mdr->file ) ) return 1; + + mdr->inserted = 1; + mdr->modified = 0; + mdr->filename = strdup( filename ); + /* we assume formatted cartridges */ + for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); + i > 0; i-- ) + mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_OK; + + update_menu( UMENU_MDRV1 + which ); + + return 0; +} + +int +if1_mdr_eject( int which, int saveas ) +{ + microdrive_t *mdr; + + if( which >= 8 ) + return 1; + + mdr = µdrive[ which ]; + + if( !mdr->inserted ) + return 0; + + if( saveas ) { /* 1 -> save as.., 2 -> save */ + + if( mdr->filename == NULL ) saveas = 1; + if( ui_mdr_write( which, 2 - saveas ) ) return 1; + mdr->modified = 0; + return 0; + + } else { + + if( mdr->modified ) { + + ui_confirm_save_t confirm = ui_confirm_save( + "Cartridge in Microdrive %i has been modified.\n" + "Do you want to save it?", + which + 1 + ); + + switch( confirm ) { + + case UI_CONFIRM_SAVE_SAVE: + if( if1_mdr_eject( which, 2 ) ) return 1; /* first save */ + break; + + case UI_CONFIRM_SAVE_DONTSAVE: break; + case UI_CONFIRM_SAVE_CANCEL: return 1; + + } + } + } + + mdr->inserted = 0; + if( mdr->filename != NULL ) { + free( mdr->filename ); + mdr->filename = NULL; + } + + update_menu( UMENU_MDRV1 + which ); + return 0; +} + +int +if1_mdr_write( int which, const char *filename ) +{ + microdrive_t *mdr = µdrive[which]; + + libspectrum_microdrive_mdr_write( mdr->cartridge, &mdr->file.buffer, + &mdr->file.length ); + + if( filename == NULL ) filename = mdr->filename; /* Write over the original file */ + + if( utils_write_file( filename, mdr->file.buffer, mdr->file.length ) ) + return 1; + + if( mdr->filename && strcmp( filename, mdr->filename ) ) { + free( mdr->filename ); + mdr->filename = strdup( filename ); + } + return 0; +} + +#ifndef O_NONBLOCK +#define O_NONBLOCK FNDELAY +#endif + +void +if1_plug( const char *filename, int what ) +{ +#ifdef WIN32 + ui_error( UI_ERROR_ERROR, "Not yet implemented on Win32" ); + return; +#else + int fd = -1; + + switch( what ) { + case 1: + if( if1_ula.fd_r >= 0 ) + close( if1_ula.fd_r ); + fd = if1_ula.fd_r = open( filename, O_RDWR | O_NONBLOCK ); + if( fcntl( fd, F_SETFL, O_RDONLY | O_NONBLOCK ) ) + ui_error( UI_ERROR_ERROR, "Cannot set O_RDONLY on '%s': %s", + filename, strerror( errno ) ); + if1_ula.rs232_buffer = 0x100; /* buffer is empty */ + break; + case 2: + if( if1_ula.fd_t >= 0 ) + close( if1_ula.fd_t ); + fd = if1_ula.fd_t = open( filename, O_RDWR | O_NONBLOCK ); + if( fcntl( fd, F_SETFL, O_WRONLY | O_NONBLOCK ) ) + ui_error( UI_ERROR_ERROR, "Cannot set O_WRONLY on '%s': %s", + filename, strerror( errno ) ); + break; + case 3: + if( if1_ula.fd_net >= 0 ) + close( if1_ula.fd_net ); + fd = if1_ula.fd_net = open( filename, O_RDWR | O_NONBLOCK ); + break; + } + + /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ + if( !settings_current.rs232_handshake && + if1_ula.fd_t != -1 && if1_ula.fd_r != -1 ) + if1_ula.dtr = 1; + + if( fd < 0 ) { + ui_error( UI_ERROR_ERROR, "Error opening '%s': %s", + filename, strerror( errno ) ); + return; + } + + if1_ula.s_net_mode = settings_current.raw_s_net ? 0 : 1; + update_menu( UMENU_RS232 ); +#endif +} + +void +if1_unplug( int what ) +{ + switch( what ) { + case 1: + if( if1_ula.fd_r >= 0 ) + close( if1_ula.fd_r ); + if1_ula.fd_r = -1; + break; + case 2: + if( if1_ula.fd_t >= 0 ) + close( if1_ula.fd_t ); + if1_ula.fd_t = -1; + if1_ula.dtr = 0; + break; + case 3: + if( if1_ula.fd_net >= 0 ) + close( if1_ula.fd_net ); + if1_ula.fd_net = -1; + break; + } + /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ + if( !settings_current.rs232_handshake && + ( if1_ula.fd_t == -1 || if1_ula.fd_r == -1 ) ) + if1_ula.dtr = 0; + update_menu( UMENU_RS232 ); +} Copied: vendor/fuse-emulator/current/fuse/if1.h (from rev 679, vendor/fuse-emulator/current/fuse/if1.h) =================================================================== --- vendor/fuse-emulator/current/fuse/if1.h (rev 0) +++ vendor/fuse-emulator/current/fuse/if1.h 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,59 @@ +/* if1.h: Interface I handling routines + Copyright (c) 2004-2005 Gergely Szasz, Philip Kendall + + $Id: if1.h 3327 2007-11-22 23:06:47Z 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: + + Gergely: sz...@hu... + +*/ + +#ifndef FUSE_IF1_H +#define FUSE_IF1_H + +#include <libspectrum.h> + +#include "periph.h" + +/* IF1 */ +extern int if1_active; +extern int if1_available; + +extern const periph_t if1_peripherals[]; +extern const size_t if1_peripherals_count; + +int if1_init( void ); +libspectrum_error if1_end( void ); + +void if1_page( void ); +void if1_unpage( void ); +void if1_memory_map( void ); + +void if1_port_out( libspectrum_word port, libspectrum_byte val ); +libspectrum_byte if1_port_in( libspectrum_word port, int *attached ); + +int if1_mdr_insert( int drive, const char *filename ); +int if1_mdr_write( int drive, const char *filename ); +int if1_mdr_eject( int drive, int write ); +void if1_mdr_writeprotect( int drive, int wrprot ); +void if1_plug( const char *filename, int what ); +void if1_unplug( int what ); + +void if1_update_menu( void ); + +#endif /* #ifndef FUSE_IF1_H */ Copied: vendor/fuse-emulator/current/fuse/if2.c (from rev 679, vendor/fuse-emulator/current/fuse/if2.c) =================================================================== --- vendor/fuse-emulator/current/fuse/if2.c (rev 0) +++ vendor/fuse-emulator/current/fuse/if2.c 2012-01-14 12:08:15 UTC (rev 681) @@ -0,0 +1,204 @@ +/* if2.c: Interface II cartridge handling routines + Copyright (c) 2003 Darren Salt, Fredrick Meunier, Philip Kendall + Copyright (c) 2004 Fredrick Meunier + + $Id: if2.c 4099 2009-10-22 10:59:02Z fredm $ + + This program is free software; you can redistr... [truncated message content] |
From: <fr...@us...> - 2012-01-14 12:26:58
|
Revision: 682 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=682&view=rev Author: fredm Date: 2012-01-14 12:26:49 +0000 (Sat, 14 Jan 2012) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 24 renames. * vendor/fuse-emulator/current/fuse/peripherals/disk: Renamed from vendor/fuse-emulator/current/fuse/disk. * vendor/fuse-emulator/current/fuse/peripherals/ide: Renamed from vendor/fuse-emulator/current/fuse/ide. * vendor/fuse-emulator/current/fuse/peripherals/ay.c: Renamed from vendor/fuse-emulator/current/fuse/ay.c. * vendor/fuse-emulator/current/fuse/peripherals/ay.h: Renamed from vendor/fuse-emulator/current/fuse/ay.h. * vendor/fuse-emulator/current/fuse/peripherals/dck.c: Renamed from vendor/fuse-emulator/current/fuse/dck.c. * vendor/fuse-emulator/current/fuse/peripherals/dck.h: Renamed from vendor/fuse-emulator/current/fuse/dck.h. * vendor/fuse-emulator/current/fuse/peripherals/fuller.c: Renamed from vendor/fuse-emulator/current/fuse/fuller.c. * vendor/fuse-emulator/current/fuse/peripherals/fuller.h: Renamed from vendor/fuse-emulator/current/fuse/fuller.h. * vendor/fuse-emulator/current/fuse/peripherals/if1.c: Renamed from vendor/fuse-emulator/current/fuse/if1.c. * vendor/fuse-emulator/current/fuse/peripherals/if1.h: Renamed from vendor/fuse-emulator/current/fuse/if1.h. * vendor/fuse-emulator/current/fuse/peripherals/if2.c: Renamed from vendor/fuse-emulator/current/fuse/if2.c. * vendor/fuse-emulator/current/fuse/peripherals/if2.h: Renamed from vendor/fuse-emulator/current/fuse/if2.h. * vendor/fuse-emulator/current/fuse/peripherals/joystick.c: Renamed from vendor/fuse-emulator/current/fuse/joystick.c. * vendor/fuse-emulator/current/fuse/peripherals/joystick.h: Renamed from vendor/fuse-emulator/current/fuse/joystick.h. * vendor/fuse-emulator/current/fuse/peripherals/kempmouse.c: Renamed from vendor/fuse-emulator/current/fuse/kempmouse.c. * vendor/fuse-emulator/current/fuse/peripherals/kempmouse.h: Renamed from vendor/fuse-emulator/current/fuse/kempmouse.h. * vendor/fuse-emulator/current/fuse/peripherals/melodik.c: Renamed from vendor/fuse-emulator/current/fuse/melodik.c. * vendor/fuse-emulator/current/fuse/peripherals/melodik.h: Renamed from vendor/fuse-emulator/current/fuse/melodik.h. * vendor/fuse-emulator/current/fuse/peripherals/printer.c: Renamed from vendor/fuse-emulator/current/fuse/printer.c. * vendor/fuse-emulator/current/fuse/peripherals/printer.h: Renamed from vendor/fuse-emulator/current/fuse/printer.h. * vendor/fuse-emulator/current/fuse/peripherals/scld.c: Renamed from vendor/fuse-emulator/current/fuse/scld.c. * vendor/fuse-emulator/current/fuse/peripherals/scld.h: Renamed from vendor/fuse-emulator/current/fuse/scld.h. * vendor/fuse-emulator/current/fuse/peripherals/ula.c: Renamed from vendor/fuse-emulator/current/fuse/ula.c. * vendor/fuse-emulator/current/fuse/peripherals/ula.h: Renamed from vendor/fuse-emulator/current/fuse/ula.h. Added Paths: ----------- vendor/fuse-emulator/current/fuse/peripherals/ vendor/fuse-emulator/current/fuse/peripherals/ay.c vendor/fuse-emulator/current/fuse/peripherals/ay.h vendor/fuse-emulator/current/fuse/peripherals/dck.c vendor/fuse-emulator/current/fuse/peripherals/dck.h vendor/fuse-emulator/current/fuse/peripherals/disk/ vendor/fuse-emulator/current/fuse/peripherals/fuller.c vendor/fuse-emulator/current/fuse/peripherals/fuller.h vendor/fuse-emulator/current/fuse/peripherals/ide/ vendor/fuse-emulator/current/fuse/peripherals/if1.c vendor/fuse-emulator/current/fuse/peripherals/if1.h vendor/fuse-emulator/current/fuse/peripherals/if2.c vendor/fuse-emulator/current/fuse/peripherals/if2.h vendor/fuse-emulator/current/fuse/peripherals/joystick.c vendor/fuse-emulator/current/fuse/peripherals/joystick.h vendor/fuse-emulator/current/fuse/peripherals/kempmouse.c vendor/fuse-emulator/current/fuse/peripherals/kempmouse.h vendor/fuse-emulator/current/fuse/peripherals/melodik.c vendor/fuse-emulator/current/fuse/peripherals/melodik.h vendor/fuse-emulator/current/fuse/peripherals/printer.c vendor/fuse-emulator/current/fuse/peripherals/printer.h vendor/fuse-emulator/current/fuse/peripherals/scld.c vendor/fuse-emulator/current/fuse/peripherals/scld.h vendor/fuse-emulator/current/fuse/peripherals/ula.c vendor/fuse-emulator/current/fuse/peripherals/ula.h Removed Paths: ------------- vendor/fuse-emulator/current/fuse/ay.c vendor/fuse-emulator/current/fuse/ay.h vendor/fuse-emulator/current/fuse/dck.c vendor/fuse-emulator/current/fuse/dck.h vendor/fuse-emulator/current/fuse/disk/ vendor/fuse-emulator/current/fuse/fuller.c vendor/fuse-emulator/current/fuse/fuller.h vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/if1.c vendor/fuse-emulator/current/fuse/if1.h vendor/fuse-emulator/current/fuse/if2.c vendor/fuse-emulator/current/fuse/if2.h vendor/fuse-emulator/current/fuse/joystick.c vendor/fuse-emulator/current/fuse/joystick.h vendor/fuse-emulator/current/fuse/kempmouse.c vendor/fuse-emulator/current/fuse/kempmouse.h vendor/fuse-emulator/current/fuse/melodik.c vendor/fuse-emulator/current/fuse/melodik.h vendor/fuse-emulator/current/fuse/printer.c vendor/fuse-emulator/current/fuse/printer.h vendor/fuse-emulator/current/fuse/scld.c vendor/fuse-emulator/current/fuse/scld.h vendor/fuse-emulator/current/fuse/ula.c vendor/fuse-emulator/current/fuse/ula.h Deleted: vendor/fuse-emulator/current/fuse/ay.c =================================================================== --- vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 12:26:49 UTC (rev 682) @@ -1,169 +0,0 @@ -/* ay.c: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.c 4030 2009-06-07 14:38:38Z 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 <string.h> - -#include "compat.h" -#include "machine.h" -#include "module.h" -#include "printer.h" -#include "psg.h" -#include "sound.h" - -/* Unused bits in the AY registers are silently zeroed out; these masks - accomplish this */ -static const libspectrum_byte mask[ AY_REGISTERS ] = { - - 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0xff, - 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x0f, 0xff, 0xff, - -}; - -static void ay_reset( int hard_reset ); -static void ay_from_snapshot( libspectrum_snap *snap ); -static void ay_to_snapshot( libspectrum_snap *snap ); - -static module_info_t ay_module_info = { - - ay_reset, - NULL, - NULL, - ay_from_snapshot, - ay_to_snapshot, - -}; - -int -ay_init( void ) -{ - module_register( &ay_module_info ); - - return 0; -} - -static void -ay_reset( int hard_reset GCC_UNUSED ) -{ - ayinfo *ay = &machine_current->ay; - - ay->current_register = 0; - memset( ay->registers, 0, sizeof( ay->registers ) ); -} - -/* What happens when the AY register port (traditionally 0xfffd on the 128K - machines) is read from */ -libspectrum_byte -ay_registerport_read( libspectrum_word port GCC_UNUSED, int *attached ) -{ - int current; - const libspectrum_byte port_input = 0xbf; /* always allow serial output */ - - *attached = 1; - - current = machine_current->ay.current_register; - - /* The AY I/O ports return input directly from the port when in - input mode; but in output mode, they return an AND between the - register value and the port input. So, allow for this when - reading R14... */ - - if( current == 14 ) { - if(machine_current->ay.registers[7] & 0x40) - return (port_input & machine_current->ay.registers[14]); - else - return port_input; - } - - /* R15 is simpler to do, as the 8912 lacks the second I/O port, and - the input-mode input is always 0xff */ - if( current == 15 && !( machine_current->ay.registers[7] & 0x80 ) ) - return 0xff; - - /* Otherwise return register value, appropriately masked */ - return machine_current->ay.registers[ current ] & mask[ current ]; -} - -/* And when it's written to */ -void -ay_registerport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - machine_current->ay.current_register = (b & 15); -} - -/* What happens when the AY data port (traditionally 0xbffd on the 128K - machines) is written to; no corresponding read function as this - always returns 0xff */ -void -ay_dataport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - int current; - - current = machine_current->ay.current_register; - - machine_current->ay.registers[ current ] = b & mask[ current ]; - sound_ay_write( current, b, tstates ); - if( psg_recording ) psg_write_register( current, b ); - - if( current == 14 ) printer_serial_write( b ); -} - -void -ay_state_from_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - ay_registerport_write( 0xfffd, - libspectrum_snap_out_ay_registerport( snap ) ); - - for( i = 0; i < AY_REGISTERS; i++ ) { - machine_current->ay.registers[i] = - libspectrum_snap_ay_registers( snap, i ); - sound_ay_write( i, machine_current->ay.registers[i], 0 ); - } -} - -static void -ay_from_snapshot( libspectrum_snap *snap ) -{ - if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) { - ay_state_from_snapshot( snap ); - } -} - -static void -ay_to_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - libspectrum_snap_set_out_ay_registerport( - snap, machine_current->ay.current_register - ); - - for( i = 0; i < AY_REGISTERS; i++ ) - libspectrum_snap_set_ay_registers( snap, i, - machine_current->ay.registers[i] ); -} Deleted: vendor/fuse-emulator/current/fuse/ay.h =================================================================== --- vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 12:26:49 UTC (rev 682) @@ -1,47 +0,0 @@ -/* ay.h: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.h 4030 2009-06-07 14:38:38Z 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... - -*/ - -#ifndef FUSE_AY_H -#define FUSE_AY_H - -#include <libspectrum.h> - -#define AY_REGISTERS 16 - -typedef struct ayinfo { - int current_register; - libspectrum_byte registers[ AY_REGISTERS ]; -} ayinfo; - -int ay_init( void ); - -libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached ); -void ay_registerport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_dataport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_state_from_snapshot( libspectrum_snap *snap ); - -#endif /* #ifndef FUSE_AY_H */ Deleted: vendor/fuse-emulator/current/fuse/dck.c =================================================================== --- vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 12:26:49 UTC (rev 682) @@ -1,184 +0,0 @@ -/* dck.c: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#include <config.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <libspectrum.h> - -#include "dck.h" -#include "machine.h" -#include "memory.h" -#include "settings.h" -#include "scld.h" -#include "ui/ui.h" -#include "utils.h" -#include "debugger/debugger.h" - -/* Dock cart inserted? */ -int dck_active = 0; - -int -dck_insert( const char *filename ) -{ - int error; - - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return 1; - } - - error = settings_set_string( &settings_current.dck_file, filename ); - if( error ) return error; - - machine_reset( 0 ); - - return 0; -} - -void -dck_eject( void ) -{ - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return; - } - - if( settings_current.dck_file ) free( settings_current.dck_file ); - settings_current.dck_file = NULL; - - dck_active = 0; - - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - - machine_reset( 0 ); -} - -int -dck_reset( void ) -{ - utils_file file; - size_t num_block = 0; - libspectrum_dck *dck; - int error; - - dck_active = 0; - - if( !settings_current.dck_file ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - return 0; - } - - dck = libspectrum_dck_alloc(); - - error = utils_read_file( settings_current.dck_file, &file ); - if( error ) { libspectrum_dck_free( dck, 0 ); return error; } - - error = libspectrum_dck_read2( dck, file.buffer, file.length, - settings_current.dck_file ); - if( error ) { - utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; - } - - if( utils_close_file( &file ) ) { - libspectrum_dck_free( dck, 0 ); - return 1; - } - - while( dck->dck[num_block] != NULL ) { - memory_page **mem; - int i; - - switch( dck->dck[num_block]->bank ) { - case LIBSPECTRUM_DCK_BANK_HOME: - mem = memory_map_home; - break; - case LIBSPECTRUM_DCK_BANK_DOCK: - mem = memory_map_dock; - break; - case LIBSPECTRUM_DCK_BANK_EXROM: - mem = memory_map_exrom; - break; - default: - ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", - dck->dck[num_block]->bank ); - libspectrum_dck_free( dck, 0 ); - return 1; - } - - for( i = 0; i < 8; i++ ) { - - switch( dck->dck[num_block]->access[i] ) { - - case LIBSPECTRUM_DCK_PAGE_NULL: - break; - - case LIBSPECTRUM_DCK_PAGE_ROM: - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - mem[i]->writable = 0; - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - break; - - case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: - case LIBSPECTRUM_DCK_PAGE_RAM: - /* Because the scr and snapshot code depends on the standard - memory map being in the RAM[] array, we just copy RAM - blocks from the HOME bank into the appropriate page; in - other cases, we allocate ourselves a new page to store the - contents in */ - if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - mem[i]->writable = 1; - } - - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - break; - - } - } - num_block++; - } - - dck_active = 1; - - /* Make the menu item to eject the cartridge active */ - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); - - return libspectrum_dck_free( dck, 0 ); -} Deleted: vendor/fuse-emulator/current/fuse/dck.h =================================================================== --- vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 12:26:49 UTC (rev 682) @@ -1,39 +0,0 @@ -/* dck.h: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003 Darren Salt, Fredrick Meunier - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#ifndef FUSE_DCK_H -#define FUSE_DCK_H - -/* Dock cart inserted? */ -extern int dck_active; - -int dck_insert( const char *filename ); -void dck_eject( void ); -int dck_reset( void ); - -#endif Deleted: vendor/fuse-emulator/current/fuse/fuller.c =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 12:26:49 UTC (rev 682) @@ -1,90 +0,0 @@ -/* fuller.c: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.c 4032 2009-06-10 11:09:44Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#include <config.h> - -#include <libspectrum.h> - -#include "ay.h" -#include "compat.h" -#include "fuller.h" -#include "joystick.h" -#include "module.h" -#include "periph.h" -#include "settings.h" - -static void fuller_enabled_snapshot( libspectrum_snap *snap ); -static void fuller_from_snapshot( libspectrum_snap *snap ); -static void fuller_to_snapshot( libspectrum_snap *snap ); - -static module_info_t fuller_module_info = { - - NULL, - NULL, - fuller_enabled_snapshot, - fuller_from_snapshot, - fuller_to_snapshot, - -}; - -const periph_t fuller_peripherals[] = { - { 0x00ff, 0x003f, ay_registerport_read, ay_registerport_write }, - { 0x00ff, 0x005f, NULL, ay_dataport_write }, - { 0x00ff, 0x007f, joystick_fuller_read, NULL }, -}; - -const size_t fuller_peripherals_count = - sizeof( fuller_peripherals ) / sizeof( periph_t ); - -static void -fuller_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_fuller_box_active( snap ) ) - settings_current.fuller = 1; -} - -static void -fuller_from_snapshot( libspectrum_snap *snap ) -{ - if( periph_fuller_active ) { - ay_state_from_snapshot( snap ); - } -} - -static void -fuller_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_snap_set_fuller_box_active( snap, periph_fuller_active ); -} - -int -fuller_init( void ) -{ - module_register( &fuller_module_info ); - - return 0; -} Deleted: vendor/fuse-emulator/current/fuse/fuller.h =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 12:26:49 UTC (rev 682) @@ -1,40 +0,0 @@ -/* fuller.h: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.h 4030 2009-06-07 14:38:38Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#ifndef FUSE_FULLER_H -#define FUSE_FULLER_H - -#include <libspectrum.h> - -#include "periph.h" - -extern const periph_t fuller_peripherals[]; -extern const size_t fuller_peripherals_count; - -int fuller_init( void ); - -#endif /* #ifndef FUSE_FULLER_H */ Deleted: vendor/fuse-emulator/current/fuse/if1.c =================================================================== --- vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 12:08:15 UTC (rev 681) +++ vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 12:26:49 UTC (rev 682) @@ -1,1304 +0,0 @@ -/* if1.c: Interface I handling routines - Copyright (c) 2004-2008 Gergely Szasz, Philip Kendall - - $Id: if1.c 4180 2010-10-09 12:59: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 - 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: - - Gergely: sz...@hu... - -*/ - -#include <config.h> - -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <unistd.h> - -#include "compat.h" -#include "debugger/debugger.h" -#include "if1.h" -#include "machine.h" -#include "memory.h" -#include "module.h" -#include "periph.h" -#include "settings.h" -#include "utils.h" -#include "ui/ui.h" - -#undef IF1_DEBUG_MDR -#undef IF1_DEBUG_NET -#undef IF1_DEBUG_NET_1 - -#define BUFF_EMPTY 0x100 - -enum { - SYNC_NO = 0, - SYNC_OK = 0xff -}; - -/* - Microdrive cartridge - GAP PREAMBLE 15 byte GAP PREAMBLE 15 byte 512 1 - [-----][00 00 ... ff ff][BLOCK HEAD][-----][00 00 ... ff ff][REC HEAD][ DATA ][CHK] - Preamble = 10 * 0x00 + 2 * 0xff (12 byte) -*/ - -typedef struct microdrive_t { - utils_file file; - char *filename; /* old filename */ - int inserted; - int modified; - int motor_on; - int head_pos; - int transfered; - int max_bytes; - libspectrum_byte pream[512]; /* preamble/sync area written */ - libspectrum_byte last; - libspectrum_byte gap; - libspectrum_byte sync; - - libspectrum_microdrive *cartridge; /* write protect, len, blocks */ - -} microdrive_t; - -typedef struct if1_ula_t { - int fd_r; /* file descriptor for reading bytes or bits RS232 */ - int fd_t; /* file descriptor for writing bytes or bits RS232 */ - int fd_net; /* file descriptor for rw bytes or bits SinclairNET */ - int rs232_buffer; /* read buffer */ - int s_net_mode; - int status; /* if1_ula/SinclairNET */ - int comms_data; /* the previous data comms state */ - int comms_clk; /* the previous data comms state */ - int cts; /* CTS of peripheral */ - int dtr; /* DTR of peripheral */ - int tx; /* TxD the name is very kind, because this is the read end of - the TxD wire of DATA machine (really RxD the view of - spectrum */ - int rx; /* RxD the name is very kind, because this is the write end of - the RxD wire of DATA machine (really TxD the view of - spectrum */ - int data_in; /* interpreted incoming data */ - int count_in; - int data_out; /* interpreted outgoing data */ - int count_out; - int esc_in; /* if we compose an escape seq */ - - int net; /* Network in/out (really 1 wire bus :-) */ - int net_data; /* Interpreted network data */ - int net_state; /* Interpreted network data */ - int wait; /* Wait state */ - int busy; /* Indicate busy; if1 software never poll it ... */ -} if1_ula_t; - -/* - 7 6 5 4 3 2 1 0 - STATUS RO $EF(239) --- --- --- BSY DTR GAP SYN WPR - - CONTRO WO $EF(239) --- --- WAT CTS ERA R/w CLK DTA - - MDR DT RW $E7(231) D7 D6 D5 D4 D3 D2 D1 D0 - - COMM I RO $F7(247) TX --- --- --- --- --- --- NET - - COMM O WO $F7(247) --- --- --- --- --- --- --- NET/RX - -RS232: - DTR -> Data Terminal Ready (DTE -> DCE) - CTS -> Clear To Send (DCE -> DTE) - TX -> Transmitted Data (DTE -> DCE) - RX -> Received Data (DCE -> DTE) - - The IF1 serial behaves not as a DTE (Data Terminal Equipment, e.g. - a computer) but as a DCE (Data Communications Equipment, e.g. a modem) - - If we were to consider the ZX Spectrum a DTE, we would rename the lines: - DTR := DSR (Data Set Ready) - CTS := RTS (Request To Send) - TX := RX - RX := TX - - On the communication channels: - Bytes interpreted as is, except: - 0x00 0x00 --> DTR ~~\__ - 0x00 0x01 --> DTR __/~~ - 0x00 0x02 --> CTS ~~\__ - 0x00 0x03 --> CTS __/~~ - 0x00 ? --> lost - 0x00 * --> 0x00 - Additionally: - if fuse read 0x00 0x00 => DTR = 0 ~~\__ - if fuse read 0x00 0x01 => DTR = 1 __/~~ - if CTS = ~~\__ fuse send 0x00 0x02 - if CTS = __/~~ fuse send 0x00 0x03 - if fuse lost send 0x00 + 0x3f (?) - every other 0x00 + 0x## are discarded -*/ - -/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ -static memory_page if1_memory_map_romcs[2]; - -/* IF1 paged out ROM activated? */ -int if1_active = 0; -int if1_available = 0; -static int if1_mdr_status = 0; - -int rnd_factor = ( ( RAND_MAX >> 2 ) << 2 ) / 19 + 1; - -static microdrive_t microdrive[8]; /* We have 8 microdrive */ -static if1_ula_t if1_ula; - -static void microdrives_reset( void ); -static void microdrives_restart( void ); -static void increment_head( int m ); - -#define MDR_IN(m) microdrive[m - 1].inserted -#define MDR_WP(m) libspectrum_microdrive_write_protect( microdrive[m - 1].cartridge ) - -enum if1_menu_item { - - UMENU_ALL = 0, - UMENU_MDRV1, - UMENU_MDRV2, - UMENU_MDRV3, - UMENU_MDRV4, - UMENU_MDRV5, - UMENU_MDRV6, - UMENU_MDRV7, - UMENU_MDRV8, - UMENU_RS232, -}; - -enum if1_port { - PORT_MDR, - PORT_CTR, - PORT_NET, - PORT_UNKNOWN, -}; - -static void if1_reset( int hard_reset ); -static void if1_enabled_snapshot( libspectrum_snap *snap ); -static void if1_from_snapshot( libspectrum_snap *snap ); -static void if1_to_snapshot( libspectrum_snap *snap ); - -static module_info_t if1_module_info = { - - if1_reset, - if1_memory_map, - if1_enabled_snapshot, - if1_from_snapshot, - if1_to_snapshot, - -}; - -const periph_t if1_peripherals[] = { - { 0x0018, 0x0010, if1_port_in, if1_port_out }, - { 0x0018, 0x0008, if1_port_in, if1_port_out }, - { 0x0018, 0x0000, if1_port_in, if1_port_out }, -}; - -const size_t if1_peripherals_count = - sizeof( if1_peripherals ) / sizeof( periph_t ); - -/* Debugger events */ -static const char *event_type_string = "if1"; -static int page_event, unpage_event; - -static void -update_menu( enum if1_menu_item what ) -{ - if( what == UMENU_ALL || what == UMENU_MDRV1 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_EJECT, MDR_IN( 1 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_WP_SET, - !MDR_IN( 1 ) ? 0 : !MDR_WP( 1 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV2 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_EJECT, MDR_IN( 2 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_WP_SET, - !MDR_IN( 2 ) ? 0 : !MDR_WP( 2 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV3 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_EJECT, MDR_IN( 3 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_WP_SET, - !MDR_IN( 3 ) ? 0 : !MDR_WP( 3 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV4 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_EJECT, MDR_IN( 4 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_WP_SET, - !MDR_IN( 4 ) ? 0 : !MDR_WP( 4 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV5 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_EJECT, MDR_IN( 5 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_WP_SET, - !MDR_IN( 5 ) ? 0 : !MDR_WP( 5 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV6 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_EJECT, MDR_IN( 6 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_WP_SET, - !MDR_IN( 6 ) ? 0 : !MDR_WP( 6 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV7 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_EJECT, MDR_IN( 7 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_WP_SET, - !MDR_IN( 7 ) ? 0 : !MDR_WP( 7 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV8 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_EJECT, MDR_IN( 8 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_WP_SET, - !MDR_IN( 8 ) ? 0 : !MDR_WP( 8 ) ); - } - - if( what == UMENU_ALL || what == UMENU_RS232 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_R, - ( if1_ula.fd_r > -1 ) ? 1 : 0 ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_T, - ( if1_ula.fd_t > -1 ) ? 1 : 0 ); -#ifdef BUILD_WITH_SNET - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_SNET_UNPLUG, - ( if1_ula.fd_net > -1 ) ? 1 : 0 ); -#endif - } -} - -int -if1_init( void ) -{ - int m, i; - - if1_ula.fd_r = -1; - if1_ula.fd_t = -1; - if1_ula.dtr = 0; /* No data terminal yet */ - if1_ula.cts = 2; /* force to emit first cts status */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; /* really? */ - if1_ula.fd_net = -1; - if1_ula.s_net_mode = 1; - if1_ula.net = 0; - if1_ula.esc_in = 0; /* empty */ - - for( m = 0; m < 8; m++ ) { - microdrive[m].cartridge = libspectrum_microdrive_alloc(); - microdrive[m].inserted = 0; - microdrive[m].modified = 0; - } - - if( settings_current.rs232_rx ) { - if1_plug( settings_current.rs232_rx, 1 ); - free( settings_current.rs232_rx ); - settings_current.rs232_rx = NULL; - } - - if( settings_current.rs232_tx ) { - if1_plug( settings_current.rs232_tx, 2 ); - free( settings_current.rs232_tx ); - settings_current.rs232_tx = NULL; - } - - if( settings_current.snet ) { - if1_plug( settings_current.snet, 3 ); - free( settings_current.snet ); - settings_current.snet = NULL; - } - - module_register( &if1_module_info ); - for( i = 0; i < 2; i++ ) if1_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; - - if( periph_register_paging_events( event_type_string, &page_event, - &unpage_event ) ) - return 1; - - return 0; -} - -libspectrum_error -if1_end( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - libspectrum_error error = - libspectrum_microdrive_free( microdrive[m].cartridge ); - if( error ) return error; - } - - return LIBSPECTRUM_ERROR_NONE; -} - -void -if1_update_menu( void ) -{ - update_menu( UMENU_ALL ); -} - -static void -if1_reset( int hard_reset GCC_UNUSED ) -{ - if1_active = 0; - if1_available = 0; - - if( !periph_interface1_active ) return; - - machine_load_rom_bank( if1_memory_map_romcs, 0, 0, - settings_current.rom_interface_i, - settings_default.rom_interface_i, - MEMORY_PAGE_SIZE ); - - if1_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; - - machine_current->ram.romcs = 0; - - if1_ula.cts = 2; /* force to emit first out if raw */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; - if1_ula.net = 0; - if1_ula.esc_in = 0; - - microdrives_reset(); - - update_menu( UMENU_ALL ); - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - - if1_mdr_status = 0; - - if1_available = 1; -} - -void -if1_page( void ) -{ - if1_active = 1; - machine_current->ram.romcs = 1; - machine_current->memory_map(); - - debugger_event( page_event ); -} - -void -if1_unpage( void ) -{ - if1_active = 0; - machine_current->ram.romcs = 0; - machine_current->memory_map(); - - debugger_event( unpage_event ); -} - -void -if1_memory_map( void ) -{ - if( !if1_active ) return; - - memory_map_read[0] = memory_map_write[0] = if1_memory_map_romcs[0]; -} - -static void -if1_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_interface1_active( snap ) ) - settings_current.interface1 = 1; -} - -static void -if1_from_snapshot( libspectrum_snap *snap ) -{ - if( !libspectrum_snap_interface1_active( snap ) ) return; - - if( libspectrum_snap_interface1_custom_rom( snap ) && - libspectrum_snap_interface1_rom( snap, 0 ) && - machine_load_rom_bank_from_buffer( - if1_memory_map_romcs, 0, 0, - libspectrum_snap_interface1_rom( snap, 0 ), - libspectrum_snap_interface1_rom_length( snap, 0 ), - 1 ) ) - return; - - if( libspectrum_snap_interface1_paged( snap ) ) { - if1_page(); - } else { - if1_unpage(); - } -} - -static void -if1_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_byte *buffer; - - if( !periph_interface1_active ) return; - - libspectrum_snap_set_interface1_active( snap, 1 ); - libspectrum_snap_set_interface1_paged ( snap, if1_active ); - libspectrum_snap_set_interface1_drive_count( snap, 8 ); - - if( if1_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { - size_t rom_length = MEMORY_PAGE_SIZE; - - if( if1_memory_map_romcs[1].source == MEMORY_SOURCE_CUSTOMROM ) { - rom_length <<= 1; - } - - libspectrum_snap_set_interface1_custom_rom( snap, 1 ); - libspectrum_snap_set_interface1_rom_length( snap, 0, rom_length ); - - buffer = malloc( rom_length ); - if( !buffer ) { - ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); - return; - } - - memcpy( buffer, if1_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); - - if( rom_length == MEMORY_PAGE_SIZE*2 ) { - memcpy( buffer + MEMORY_PAGE_SIZE, if1_memory_map_romcs[1].page, - MEMORY_PAGE_SIZE ); - } - - libspectrum_snap_set_interface1_rom( snap, 0, buffer ); - } -} - -static void -microdrives_reset( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - microdrive[m].head_pos = 0; - microdrive[m].motor_on = 0; /* motor off */ - microdrive[m].gap = 15; - microdrive[m].sync = 15; - microdrive[m].transfered = 0; - } - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; -/* - if1_ula.comms_data = 0; - if1_ula.count_in = 0; - if1_ula.count_out = 0; - if1_ula.cts = 0; - if1_ula.dtr = 0; - if1_ula.wait = 0; - if1_ula.busy = 0; - if1_ula.net = 0; - if1_ula.net_state = 0; -*/ -} - -static enum if1_port -decode_port( libspectrum_word port ) -{ - switch( port & 0x0018 ) { - case 0x0000: return PORT_MDR; - case 0x0008: return PORT_CTR; - case 0x0010: return PORT_NET; - default: return PORT_UNKNOWN; - } -} - -static libspectrum_byte -port_mdr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - - if( mdr->transfered < mdr->max_bytes ) { - mdr->last = libspectrum_microdrive_data( mdr->cartridge, - mdr->head_pos ); - increment_head( m ); - } - - mdr->transfered++; - ret &= mdr->last; /* I assume negative logic, but how know? */ - } - - } - - return ret; -} - -static libspectrum_byte -port_ctr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m, block; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->pream[block] == SYNC_OK ) { /* if formatted */ - if( mdr->gap ) { - /* ret &= 0xff; GAP and SYNC high ? */ - mdr->gap--; - } else { - ret &= 0xf9; /* GAP and SYNC low */ - if( mdr->sync ) { - mdr->sync--; - } else { - mdr->gap = 15; - mdr->sync = 15; - } - } - } - /* if write protected */ - if( libspectrum_microdrive_write_protect( mdr->cartridge) ) - ret &= 0xfe; /* active bit */ - } - } - /* Here we have to poll, the if1_ula DTR 'line' */ - if( if1_ula.rs232_buffer > 0xff ) { /* buffer empty */ - unsigned char byte; - int yes = 1; - - while( yes && read( if1_ula.fd_r, &byte, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( byte == '*' ) { - if1_ula.rs232_buffer = 0x00; - yes = 0; - } else if( byte == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( byte == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( byte == 0x00 ) { - if1_ula.esc_in = 1; - } else { - if1_ula.rs232_buffer = byte; - yes = 0; - break; - } - } - } - - if( if1_ula.dtr == 0 ) - ret &= 0xf7; /* %11110111 */ - - /* Here we have to poll, the 'SinclairNet' busy flag but never used by - software in Interface 1 */ - if( if1_ula.busy == 0 ) - ret &= 0xef; /* %11101111 */ - /* fprintf( stderr, "Read CTR ( %%%d%d%d%d%d%d%d%d ).\n", - !!(ret & 128), !!(ret & 64), !!(ret & 32), !!(ret & 16), - !!(ret & 8), !!(ret & 4), !!(ret & 2), !!(ret & 1)); */ - microdrives_restart(); - - return ret; -} - -/* - return 1 if read a byte - 0 if nothing interesting... -*/ - -static int -read_rs232() -{ - if( if1_ula.rs232_buffer <= 0xff ) { /* we read from the buffer */ - if1_ula.data_in = if1_ula.rs232_buffer; - if1_ula.rs232_buffer = 0x0100; - return 1; - } - while( read( if1_ula.fd_r, &if1_ula.data_in, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( if1_ula.data_in == '*' ) { - if1_ula.data_in = 0x00; - return 1; - } else if( if1_ula.data_in == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( if1_ula.data_in == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( if1_ula.data_in == 0x00 ) { - if1_ula.esc_in = 1; - } else { - return 1; - } - } - return 0; -} - -static libspectrum_byte -port_net_in( void ) -{ - libspectrum_byte ret = 0xff; - - if( if1_ula.fd_r == -1 ) - goto no_rs232_in; - - /* Here is the RS232 input routine */ - if( if1_ula.cts ) { /* If CTS == 1 */ - if( if1_ula.count_in == 0 ) { - if( if1_ula.fd_r >= 0 && read_rs232() == 1 ) { - if1_ula.count_in++; /* Ok, if read a byte, we begin */ - } - if1_ula.tx = 0; /* now send __ to if1 - later we raise :-) */ - } else if( if1_ula.count_in >= 1 && if1_ula.count_in < 5 ) { - if1_ula.tx = 1; /* send ~~ (start bit :-) */ - if1_ula.count_in++; - } else if( if1_ula.count_in >= 5 && if1_ula.count_in < 13 ) { - if1_ula.tx = ( if1_ula.data_in & 0x01 ) ? 0 : 1; - /* send .. (data bits :-) */ - if1_ula.data_in >>= 1; /* prepare next bit :-) */ - if1_ula.count_in++; - } else - if1_ula.count_in = 0; - } else { /* if( if1_ula.cts ) */ - if1_ula.count_in = 0; /* reset serial in */ - if1_ula.tx = 0; /* send __ stop bits or s.e. :-) */ - } - -no_rs232_in: - if( if1_ula.fd_net == -1 ) - goto no_snet_in; - - if( if1_ula.s_net_mode == 0 ) { /* if we do raw */ - /* Here is the input routine */ - read( if1_ula.fd_net, &if1_ula.net, 1 ); /* Ok, if no byte, we send last*/ - } else {/* if( if1_ula.s_net_mode == 1 ) if we do interpreted */ -/* Here is the input routine. There are several stage in input - and output. So first for output. if1 first do SEND-SC - (http://www.wearmouth.demon.co.uk/if1_2.htm#L101E) to send - a Sync-Out signal and SEND-SC do first a NET-STATE - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FBC) to see - the line activity: - 11xxxxxx times (192-255) have to get a zero (bit for network) - plus 1 times more from SEND-SC. Next SEND-SC send a 0 which is - a 1 on the net wire (negated output, straight input!!!) - - OK. In input first if1 call WT-SC-E to check Network activity - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FD3). Now check - 128 times the net wire (we do two round, because to differentiate - net out routines...) -*/ - - if( if1_ula.net_state < 0x0100 ) { /* if1 may in NET-STATE */ - if1_ula.net_state++; - if1_ula.net = 0; -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? We send 0!\n", if1_ula.net_state ); -#endif - } else if( if1_ula.net_state == 0x0100 ) { /* probably waiting for input */ - if( read( if1_ula.fd_net, &if1_ula.net_data, 1 ) == 1 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* Start with __/~~ */ - } /* Ok, if have a byte, we send it! */ - } else if( if1_ula.net_state == 0x0101 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* one more ~~ */ - } else if( if1_ula.net_state > 0x0101 && - if1_ula.net_state < 0x010a ) { /* we send the data bits... */ - if1_ula.net_state++; - if1_ula.net = if1_ula.net_data & 1; - if1_ula.net_data >>= 1; - } else if( if1_ula.net_state == 0x010a ) { - if1_ula.net = 0; - if1_ula.net_state = 0; /* OK, we starting a new byte... */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? Get a byte!\n", if1_ula.net_state ); -#endif - } - } -no_snet_in: - if( !if1_ula.tx ) - ret &= 0x7f; - if( !if1_ula.net ) - ret &= 0xfe; - microdrives_restart(); - - return ret; -} - -libspectrum_byte -if1_port_in( libspectrum_word port GCC_UNUSED, int *attached ) -{ - libspectrum_byte ret = 0xff; - - if( !if1_active ) return ret; - - *attached = 1; - - switch( decode_port( port ) ) - { - case PORT_MDR: ret &= port_mdr_in(); break; - case PORT_CTR: ret &= port_ctr_in(); break; - case PORT_NET: ret &= port_net_in(); break; - case PORT_UNKNOWN: break; - } - - return ret; -} - -static void -port_mdr_out( libspectrum_byte val ) -{ - int m, block; - - /* allow access to the port only if motor 1 is ON and there's a file open */ - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { -#ifdef IF1_DEBUG_MDR - fprintf(stderr, "#%05d %03d(%03d): 0x%02x\n", - mdr->head_pos, mdr->transfered, mdr->max_bytes, val ); -#endif - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->transfered == 0 && val == 0x00 ) { /* start pream */ - mdr->pream[block] = 1; - } else if( mdr->transfered > 0 && mdr->transfered < 10 && val == 0x00 ) { - mdr->pream[block]++; - } else if( mdr->transfered > 9 && mdr->transfered < 12 && val == 0xff ) { - mdr->pream[block]++; - } else if( mdr->transfered == 12 && mdr->pream[block] == 12 ) { - mdr->pream[block] = SYNC_OK; - } - if( mdr->transfered > 11 && - mdr->transfered < mdr->max_bytes + 12 ) { - - libspectrum_microdrive_set_data( mdr->cartridge, mdr->head_pos, - val ); - increment_head( m ); - mdr->modified = 1; - } - mdr->transfered++; - } - } -} - -static void -port_ctr_out( libspectrum_byte val ) -{ - int m; - - if( !( val & 0x02 ) && ( if1_ula.comms_clk ) ) { /* ~~\__ */ - - for( m = 7; m > 0; m-- ) { - /* Rotate one drive */ - microdrive[m].motor_on = microdrive[m - 1].motor_on; - } - microdrive[0].motor_on = (val & 0x01) ? 0 : 1; - - if( microdrive[0].motor_on || microdrive[1].motor_on || - microdrive[2].motor_on || microdrive[3].motor_on || - microdrive[4].motor_on || microdrive[5].motor_on || - microdrive[6].motor_on || microdrive[7].motor_on ) { - if( !if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_ACTIVE ); - if1_mdr_status = 1; - } - } else if ( if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; - } - } - if( val & 0x01 ) { /* comms_data == 1 */ - /* Interface 1 service manual p.:1.4 par.: 1.5.1 - The same pin on IC1 (if1 ULA), pin 33, is used for the network - transmit data and for the RS232 transmit data. In order to select - the required function IC1 uses its COMMS_OUT (pin 30) signal, - borrowed from the microdrive control when the microdrive is not - being used (I do not know what it is exactly meaning. It is a - hardware not being used, or a software should not use..?) This signal - is routed from pin 30 to the emitter of transistor Q3 (RX DATA) and - via resistor R4, to the base of transistor Q1 (NET). When COMMS_OUT - is high Q3 is enabled this selecting RS232, and when it is low - Q1 is enabled selecting the network. - - OK, the schematics offer a different interpretation, because if - COMMS_OUT pin level high (>+3V) then Q3 is off (the basis cannot - be more higher potential then emitter (NPN transistor), so whatever - is on the IC1 RX DATA (pin 33) the basis of Q4 is always on +12V, - so the collector of Q4 (PNP transistor) always on -12V. - If COMMS_OUT pin level goes low (~0V), then Q3 basis (connected - to IC1 RX DATA pin) can be higher level (>+3V) than emitter, so - the basis potential of Q4 depend on IC1 RX DATA. - - OK, Summa summarum I assume that, the COMMS OUT pin is a - negated output of the if1 ULA CTR register's COMMS DATA bit. - */ - /* C_DATA = 1 */ - if( if1_ula.comms_data == 0 ) { - if1_ula.count_out = 0; - if1_ula.data_out = 0; - if1_ula.count_in = 0; - if1_ula.data_in = 0; - } - } - if1_ula.wait = ( val & 0x20 ) ? 1 : 0; - if1_ula.comms_data = ( val & 0x01 ) ? 1 : 0; - if1_ula.comms_clk = ( val & 0x02 ) ? 1 : 0; - val = ( val & 0x10 ) ? 1 : 0; - if( settings_current.rs232_handshake && - if1_ula.fd_t != -1 && if1_ula.cts != val ) { - char data = val ? 0x03 : 0x02; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - do ; while( write( if1_ula.fd_t, &data, 1 ) != 1 ); - } - if1_ula.cts = val; - -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Set CTS to %d, set WAIT to %d and COMMS_DATA to %d\n", - if1_ula.cts, if1_ula.wait, if1_ula.comms_data ); -#endif - - microdrives_restart(); -} - -static void -port_net_out( libspectrum_byte val ) -{ - if( if1_ula.fd_t == -1 ) - return; /* nothing to write */ - - if( if1_ula.comms_data == 1 ) { /* OK, RS232 */ - val &= 0x01; - if( if1_ula.count_out == 0 && !val ) { /* waiting for ~~\__ */ - if1_ula.count_out++; - } else if( if1_ula.count_out == 1 ) { - if( if1_ula.cts != 0 || !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; /* else get the start bit __/~~ */ - } else if( if1_ula.count_out >= 2 && if1_ula.count_out <= 9 ) { - if1_ula.data_out >>= 1; - if1_ula.data_out |= val & 0x01 ? 0 : 128; - if1_ula.count_out++; /* waiting for next data bit */ - } else if( if1_ula.count_out >= 10 && if1_ula.count_out <= 11 ) { - if( val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 12 ) { - if( !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 13 ) { - if( val ) - if1_ula.count_out = -1; - } - - if( if1_ula.count_out == -1 ) { - if1_ula.count_out = 13; - if1_ula.data_out = '?'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - if( if1_ula.count_out == 13 ) { - /* Here is the output routine */ - if( if1_ula.data_out == 0x00 ) { - if1_ula.data_out = '*'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - do ; while( write( if1_ula.fd_t, &if1_ula.data_out, 1 ) != 1 ); - if1_ula.count_out = 0; - } - if1_ula.rx = val & 0x01; /* set rx */ - } else { /* if( if1_ula.comms_data == 1 ) SinclairNET :-)*/ - if( if1_ula.s_net_mode == 0 ) { /* if we out bit by bit, do it */ - /* Here is the output routine */ - -/* OK, examining the schematics of if1 and the disassembly of if1 ROM, I - see that the Q1 and Q2 transistors negate the RX DATA signal, and the - floating state of the net wire is the ~0V level, the forced is the ~3V. - The if1 software send complemented data and read straight data. -*/ - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set rx */ - lseek( if1_ula.fd_net, 0, SEEK_SET ); /* we save only the state of the wire*/ - do ; while( write( if1_ula.fd_net, &if1_ula.net, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Send SinclairNET: %d\n", if1_ula.net ); -#endif - } else { /* if( if1_ula.s_net_mode == 0 ) if we out byte by byte, do it */ - if( if1_ula.net_state >= 0x0200 && if1_ula.net_state < 0x0208 ) { - if1_ula.net_state++; - if1_ula.net_data <<= 1; - if1_ula.net_data |= ( val & 0x01 ) ? 0 : 1; - } else if( if1_ula.net_state == 0x0208 ) { - if1_ula.net_data &= 0xff; - if1_ula.net_state++; /* OK, now we get data bytes... */ - -/* lseek( if1_ula.fd_net, 0, SEEK_SET ); start a packet */ - /* first we send the station number */ - do ; while( write( if1_ula.fd_net, &if1_ula.net_data, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "SC-OUT send network number: %d\n", - if1_ula.net_data ^ 0xff ); -#endif - } else if( if1_ula.net_state > 192 && if1_ula.net_state < 0x0200 && - ( ( val & 0x01 ) == 0 ) ) { - /* NET-STATE ask as many times.... and now send a 0 */ -/* if1_ula.net = 1; */ - if1_ula.net_state = 0x0200; /* Send the station number */ - } - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set net wire? */ - } - } - microdrives_restart(); -} - -void -if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val ) -{ - if( !if1_active ) return; - -#ifdef IF1_DEBUG_NET_1 - fprintf( stderr, "In if1_port_out( %%%d%d%d%d%d%d%d%d => 0x%04x ).\n", - !!(val & 128), !!(val & 64), !!(val & 32), !!(val & 16), - !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port); -#endif - - switch( decode_port( port ) ) { - case PORT_MDR: port_mdr_out( val ); break; - case PORT_CTR: port_ctr_out( val ); break; - case PORT_NET: port_net_out( val ); break; - case PORT_UNKNOWN: break; - } -} - -static void -increment_head( int m ) -{ - microdrive[m].head_pos++; - if( microdrive[m].head_pos >= - libspectrum_microdrive_cartridge_len( microdrive[m].cartridge ) * - LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) - microdrive[m].head_pos = 0; -} - -static void -microdrives_restart( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - while( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != 0 && - ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != LIBSPECTRUM_MICRODRIVE_HEAD_LEN ) - increment_head( m ); /* put head in the start of a block */ - - microdrive[m].transfered = 0; /* reset current number of bytes written */ - - if( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) == 0 ) { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN; /* up to 15 bytes for header blocks */ - } else { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN + LIBSPECTRUM_MICRODRIVE_DATA_LEN + 1; /* up to 528 bytes for data blocks */ - } - } -} - -void -if1_mdr_writeprotect( int drive, int wrprot ) -{ - libspectrum_microdrive_set_write_protect( microdrive[drive].cartridge, - wrprot ? 1 : 0 ); - microdrive[drive].modified = 1; - - update_menu( UMENU_MDRV1 + drive ); -} - -static void -if1_mdr_new( microdrive_t *mdr ) -{ - libspectrum_byte len; - long int i; - - mdr->filename = NULL; - if( settings_current.mdr_random_len ) { /* Random length */ - len = 171 + ( ( rand() >> 2 ) + ( rand() >> 2 ) + - ( rand() >> 2 ) + ( rand() >> 2 ) ) - / rnd_factor; - } else - len = settings_current.mdr_len = settings_current.mdr_len < 10 ? 10 : - settings_current.mdr_len > LIBSPECTRUM_MICRODRIVE_BLOCK_MAX ? LIBSPECTRUM_MICRODRIVE_BLOCK_MAX : settings_current.mdr_len; - - /* Erase the entire cartridge */ - libspectrum_microdrive_set_cartridge_len( mdr->cartridge, len ); - - for( i = 0; i < len * LIBSPECTRUM_MICRODRIVE_BLOCK_LEN; i++ ) - libspectrum_microdrive_set_data( mdr->cartridge, i, 0xff ); - - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_NO; - - /* but don't write-protect */ - libspectrum_microdrive_set_write_protect( mdr->cartridge, 0 ); - - mdr->inserted = 1; - mdr->modified = 1; - -} - -int -if1_mdr_insert( int which, const char *filename ) -{ - microdrive_t *mdr; - int m, i; - - if( which == -1 ) { /* find an empty one */ - for( m = 0; m < 8; m++ ) { - if( !microdrive[m].inserted ) { - which = m; - break; - } - } - } - - if( which == -1 ) { - ui_error( UI_ERROR_ERROR, - "Cannot insert cartridge '%s', all Microdrives in use", - filename ); - return 1; - } - - if( which >= 8 ) { - ui_error( UI_ERROR_ERROR, "if1_mdr_insert: unknown drive %d", which ); - return 1; - } - - mdr = µdrive[ which ]; - - /* Eject any cartridge already in the drive */ - if( mdr->inserted ) { - /* Abort the insert if we want to keep the current cartridge */ - if( if1_mdr_eject( which, 0 ) ) return 0; - } - - if( filename == NULL ) { /* insert new unformatted cartridge */ - if1_mdr_new( mdr ); - update_menu( UMENU_MDRV1 + which ); - return 0; - } - - if( utils_read_file( filename, &mdr->file ) ) { - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( libspectrum_microdrive_mdr_read( mdr->cartridge, mdr->file.buffer, - mdr->file.length ) ) { - utils_close_file( &mdr->file ); - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( utils_close_file( &mdr->file ) ) return 1; - - mdr->inserted = 1; - mdr->modified = 0; - mdr->filename = strdup( filename ); - /* we assume formatted cartridges */ - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_OK; - - update_menu( UMENU_MDRV1 + which ); - - return 0; -} - -int -if1_mdr_eject( int which, int saveas ) -{ - microdrive_t *mdr; - - if( which >= 8 ) - return 1; - - mdr = µdrive[ which ]; - - if( !mdr->inserted ) - return 0; - - if( saveas ) { /* 1 -> save as.., 2 -> save */ - - if( mdr->filename == NULL ) saveas = 1; - if( ui_mdr_write( which, 2 - saveas ) ) return 1; - mdr->modified = 0; - return 0; - - } else { - - if( mdr->modified ) { - - ui_confirm_save_t confirm = ui_confirm_save( - "Cartridge in Microdrive %i has been modified.\n" - "Do you want to save it?", - which + 1 - ); - - switch( confirm ) { - - case UI_CONFIRM_SAVE_SAVE: - if( if1_mdr_eject( which, 2 ) ) return 1; /* first save */ - break; - - case UI_CONFIRM_SAVE_DONTSAVE: break; - case UI_CONFIRM_SAVE_CANCEL: return 1; - - } - } - } - - mdr->inserted = 0; - if( mdr->filename != NULL ) { - free( mdr->filename ); - mdr->filename = NULL; - } - - update_menu( UMENU_MDRV1 + which ); - return 0; -} - -int -if1_mdr_write( int which, const char *filename ) -{ - microdrive_t *mdr = µdrive[which]; - - libspectrum_microdrive_mdr_write( mdr->cartridge, &mdr->file.buffer, - &mdr->file.length ); - - if( filename == NULL ) filename = mdr->filename; /* Write over the original file */ - - if( utils_write_file( filename, mdr->file.buffer, mdr->file.length ) ) - return 1; - - if( mdr->filename && strcmp( filename, mdr->filename ) ) { - free( mdr->filename ); - mdr->filename = strdup( filename ); - } - return 0; -} - -#ifndef O_NONBLOCK -#define O_NONBLOCK FNDELAY -#endif - -void -if1_plug( const char *filename, int what ) -{ -#ifdef WIN32 - ui_error( UI_ERROR_ERROR, "Not yet implemented on Win32" ); - return; -#else - int fd = -1; - - switch( what ) { - case 1: - if( if1_ula.fd_r >= 0 ) - close( if1_ula.fd_r ); - fd = if1_ula.fd_r = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_RDONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_RDONLY on '%s': %s", - filename, strerror( errno ) ); - if1_ula.rs232_buffer = 0x100; /* buffer is empty */ - break; - case 2: - if( if1_ula.fd_t >= 0 ) - close( if1_ula.fd_t ); - fd = if1_ula.fd_t = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_WRONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_WRONLY on '%s': %s", - filename, strerror( errno ) ); - break; - case 3: - if( if1_ula.fd_net >= 0 ) - close( if1_ula.fd_net ); - fd = if1_ula.fd_net = open( filename, O_RDWR | O_NONBLOCK ); - break; - } - - /* rs232_handshake == 0 -> we assume DTR(DSR) always... [truncated message content] |
From: <fr...@us...> - 2012-01-14 13:01:19
|
Revision: 683 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=683&view=rev Author: fredm Date: 2012-01-14 13:01:10 +0000 (Sat, 14 Jan 2012) Log Message: ----------- Reverse another set of half imported code. Added Paths: ----------- vendor/fuse-emulator/current/fuse/ay.c vendor/fuse-emulator/current/fuse/ay.h vendor/fuse-emulator/current/fuse/dck.c vendor/fuse-emulator/current/fuse/dck.h vendor/fuse-emulator/current/fuse/disk/ vendor/fuse-emulator/current/fuse/fuller.c vendor/fuse-emulator/current/fuse/fuller.h vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/if1.c vendor/fuse-emulator/current/fuse/if1.h vendor/fuse-emulator/current/fuse/if2.c vendor/fuse-emulator/current/fuse/if2.h vendor/fuse-emulator/current/fuse/joystick.c vendor/fuse-emulator/current/fuse/joystick.h vendor/fuse-emulator/current/fuse/kempmouse.c vendor/fuse-emulator/current/fuse/kempmouse.h vendor/fuse-emulator/current/fuse/melodik.c vendor/fuse-emulator/current/fuse/melodik.h vendor/fuse-emulator/current/fuse/printer.c vendor/fuse-emulator/current/fuse/printer.h vendor/fuse-emulator/current/fuse/scld.c vendor/fuse-emulator/current/fuse/scld.h vendor/fuse-emulator/current/fuse/ula.c vendor/fuse-emulator/current/fuse/ula.h Removed Paths: ------------- vendor/fuse-emulator/current/fuse/peripherals/ Copied: vendor/fuse-emulator/current/fuse/ay.c (from rev 681, vendor/fuse-emulator/current/fuse/ay.c) =================================================================== --- vendor/fuse-emulator/current/fuse/ay.c (rev 0) +++ vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,169 @@ +/* ay.c: AY-8-3912 routines + Copyright (c) 1999-2009 Philip Kendall + + $Id: ay.c 4030 2009-06-07 14:38:38Z 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 <string.h> + +#include "compat.h" +#include "machine.h" +#include "module.h" +#include "printer.h" +#include "psg.h" +#include "sound.h" + +/* Unused bits in the AY registers are silently zeroed out; these masks + accomplish this */ +static const libspectrum_byte mask[ AY_REGISTERS ] = { + + 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0xff, + 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x0f, 0xff, 0xff, + +}; + +static void ay_reset( int hard_reset ); +static void ay_from_snapshot( libspectrum_snap *snap ); +static void ay_to_snapshot( libspectrum_snap *snap ); + +static module_info_t ay_module_info = { + + ay_reset, + NULL, + NULL, + ay_from_snapshot, + ay_to_snapshot, + +}; + +int +ay_init( void ) +{ + module_register( &ay_module_info ); + + return 0; +} + +static void +ay_reset( int hard_reset GCC_UNUSED ) +{ + ayinfo *ay = &machine_current->ay; + + ay->current_register = 0; + memset( ay->registers, 0, sizeof( ay->registers ) ); +} + +/* What happens when the AY register port (traditionally 0xfffd on the 128K + machines) is read from */ +libspectrum_byte +ay_registerport_read( libspectrum_word port GCC_UNUSED, int *attached ) +{ + int current; + const libspectrum_byte port_input = 0xbf; /* always allow serial output */ + + *attached = 1; + + current = machine_current->ay.current_register; + + /* The AY I/O ports return input directly from the port when in + input mode; but in output mode, they return an AND between the + register value and the port input. So, allow for this when + reading R14... */ + + if( current == 14 ) { + if(machine_current->ay.registers[7] & 0x40) + return (port_input & machine_current->ay.registers[14]); + else + return port_input; + } + + /* R15 is simpler to do, as the 8912 lacks the second I/O port, and + the input-mode input is always 0xff */ + if( current == 15 && !( machine_current->ay.registers[7] & 0x80 ) ) + return 0xff; + + /* Otherwise return register value, appropriately masked */ + return machine_current->ay.registers[ current ] & mask[ current ]; +} + +/* And when it's written to */ +void +ay_registerport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) +{ + machine_current->ay.current_register = (b & 15); +} + +/* What happens when the AY data port (traditionally 0xbffd on the 128K + machines) is written to; no corresponding read function as this + always returns 0xff */ +void +ay_dataport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) +{ + int current; + + current = machine_current->ay.current_register; + + machine_current->ay.registers[ current ] = b & mask[ current ]; + sound_ay_write( current, b, tstates ); + if( psg_recording ) psg_write_register( current, b ); + + if( current == 14 ) printer_serial_write( b ); +} + +void +ay_state_from_snapshot( libspectrum_snap *snap ) +{ + size_t i; + + ay_registerport_write( 0xfffd, + libspectrum_snap_out_ay_registerport( snap ) ); + + for( i = 0; i < AY_REGISTERS; i++ ) { + machine_current->ay.registers[i] = + libspectrum_snap_ay_registers( snap, i ); + sound_ay_write( i, machine_current->ay.registers[i], 0 ); + } +} + +static void +ay_from_snapshot( libspectrum_snap *snap ) +{ + if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) { + ay_state_from_snapshot( snap ); + } +} + +static void +ay_to_snapshot( libspectrum_snap *snap ) +{ + size_t i; + + libspectrum_snap_set_out_ay_registerport( + snap, machine_current->ay.current_register + ); + + for( i = 0; i < AY_REGISTERS; i++ ) + libspectrum_snap_set_ay_registers( snap, i, + machine_current->ay.registers[i] ); +} Copied: vendor/fuse-emulator/current/fuse/ay.h (from rev 681, vendor/fuse-emulator/current/fuse/ay.h) =================================================================== --- vendor/fuse-emulator/current/fuse/ay.h (rev 0) +++ vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,47 @@ +/* ay.h: AY-8-3912 routines + Copyright (c) 1999-2009 Philip Kendall + + $Id: ay.h 4030 2009-06-07 14:38:38Z 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... + +*/ + +#ifndef FUSE_AY_H +#define FUSE_AY_H + +#include <libspectrum.h> + +#define AY_REGISTERS 16 + +typedef struct ayinfo { + int current_register; + libspectrum_byte registers[ AY_REGISTERS ]; +} ayinfo; + +int ay_init( void ); + +libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached ); +void ay_registerport_write( libspectrum_word port, libspectrum_byte b ); + +void ay_dataport_write( libspectrum_word port, libspectrum_byte b ); + +void ay_state_from_snapshot( libspectrum_snap *snap ); + +#endif /* #ifndef FUSE_AY_H */ Copied: vendor/fuse-emulator/current/fuse/dck.c (from rev 681, vendor/fuse-emulator/current/fuse/dck.c) =================================================================== --- vendor/fuse-emulator/current/fuse/dck.c (rev 0) +++ vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,184 @@ +/* dck.c: dock snapshot (Warajevo .DCK) handling routines + Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall + + $Id: dck.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: + + Philip: phi...@sh... + + Darren: li...@yo... + Fred: fr...@sp... + +*/ + +#include <config.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <libspectrum.h> + +#include "dck.h" +#include "machine.h" +#include "memory.h" +#include "settings.h" +#include "scld.h" +#include "ui/ui.h" +#include "utils.h" +#include "debugger/debugger.h" + +/* Dock cart inserted? */ +int dck_active = 0; + +int +dck_insert( const char *filename ) +{ + int error; + + if ( !( libspectrum_machine_capabilities( machine_current->machine ) & + LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { + ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); + return 1; + } + + error = settings_set_string( &settings_current.dck_file, filename ); + if( error ) return error; + + machine_reset( 0 ); + + return 0; +} + +void +dck_eject( void ) +{ + if ( !( libspectrum_machine_capabilities( machine_current->machine ) & + LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { + ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); + return; + } + + if( settings_current.dck_file ) free( settings_current.dck_file ); + settings_current.dck_file = NULL; + + dck_active = 0; + + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); + + machine_reset( 0 ); +} + +int +dck_reset( void ) +{ + utils_file file; + size_t num_block = 0; + libspectrum_dck *dck; + int error; + + dck_active = 0; + + if( !settings_current.dck_file ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); + return 0; + } + + dck = libspectrum_dck_alloc(); + + error = utils_read_file( settings_current.dck_file, &file ); + if( error ) { libspectrum_dck_free( dck, 0 ); return error; } + + error = libspectrum_dck_read2( dck, file.buffer, file.length, + settings_current.dck_file ); + if( error ) { + utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; + } + + if( utils_close_file( &file ) ) { + libspectrum_dck_free( dck, 0 ); + return 1; + } + + while( dck->dck[num_block] != NULL ) { + memory_page **mem; + int i; + + switch( dck->dck[num_block]->bank ) { + case LIBSPECTRUM_DCK_BANK_HOME: + mem = memory_map_home; + break; + case LIBSPECTRUM_DCK_BANK_DOCK: + mem = memory_map_dock; + break; + case LIBSPECTRUM_DCK_BANK_EXROM: + mem = memory_map_exrom; + break; + default: + ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", + dck->dck[num_block]->bank ); + libspectrum_dck_free( dck, 0 ); + return 1; + } + + for( i = 0; i < 8; i++ ) { + + switch( dck->dck[num_block]->access[i] ) { + + case LIBSPECTRUM_DCK_PAGE_NULL: + break; + + case LIBSPECTRUM_DCK_PAGE_ROM: + mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); + if( !mem[i]->page ) return 1; + memcpy( mem[i]->page, dck->dck[num_block]->pages[i], + MEMORY_PAGE_SIZE ); + mem[i]->writable = 0; + mem[i]->source = MEMORY_SOURCE_CARTRIDGE; + break; + + case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: + case LIBSPECTRUM_DCK_PAGE_RAM: + /* Because the scr and snapshot code depends on the standard + memory map being in the RAM[] array, we just copy RAM + blocks from the HOME bank into the appropriate page; in + other cases, we allocate ourselves a new page to store the + contents in */ + if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { + mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); + if( !mem[i]->page ) return 1; + mem[i]->writable = 1; + } + + mem[i]->source = MEMORY_SOURCE_CARTRIDGE; + memcpy( mem[i]->page, dck->dck[num_block]->pages[i], + MEMORY_PAGE_SIZE ); + break; + + } + } + num_block++; + } + + dck_active = 1; + + /* Make the menu item to eject the cartridge active */ + ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); + + return libspectrum_dck_free( dck, 0 ); +} Copied: vendor/fuse-emulator/current/fuse/dck.h (from rev 681, vendor/fuse-emulator/current/fuse/dck.h) =================================================================== --- vendor/fuse-emulator/current/fuse/dck.h (rev 0) +++ vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,39 @@ +/* dck.h: dock snapshot (Warajevo .DCK) handling routines + Copyright (c) 2003 Darren Salt, Fredrick Meunier + + $Id: dck.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: + + Philip: phi...@sh... + + Darren: li...@yo... + Fred: fr...@sp... + +*/ + +#ifndef FUSE_DCK_H +#define FUSE_DCK_H + +/* Dock cart inserted? */ +extern int dck_active; + +int dck_insert( const char *filename ); +void dck_eject( void ); +int dck_reset( void ); + +#endif Copied: vendor/fuse-emulator/current/fuse/fuller.c (from rev 681, vendor/fuse-emulator/current/fuse/fuller.c) =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.c (rev 0) +++ vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,90 @@ +/* fuller.c: Routines for handling the Fuller Box + Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier + + $Id: fuller.c 4032 2009-06-10 11:09:44Z 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: + + Philip: phi...@sh... + + Stuart: sd...@nt... + +*/ + +#include <config.h> + +#include <libspectrum.h> + +#include "ay.h" +#include "compat.h" +#include "fuller.h" +#include "joystick.h" +#include "module.h" +#include "periph.h" +#include "settings.h" + +static void fuller_enabled_snapshot( libspectrum_snap *snap ); +static void fuller_from_snapshot( libspectrum_snap *snap ); +static void fuller_to_snapshot( libspectrum_snap *snap ); + +static module_info_t fuller_module_info = { + + NULL, + NULL, + fuller_enabled_snapshot, + fuller_from_snapshot, + fuller_to_snapshot, + +}; + +const periph_t fuller_peripherals[] = { + { 0x00ff, 0x003f, ay_registerport_read, ay_registerport_write }, + { 0x00ff, 0x005f, NULL, ay_dataport_write }, + { 0x00ff, 0x007f, joystick_fuller_read, NULL }, +}; + +const size_t fuller_peripherals_count = + sizeof( fuller_peripherals ) / sizeof( periph_t ); + +static void +fuller_enabled_snapshot( libspectrum_snap *snap ) +{ + if( libspectrum_snap_fuller_box_active( snap ) ) + settings_current.fuller = 1; +} + +static void +fuller_from_snapshot( libspectrum_snap *snap ) +{ + if( periph_fuller_active ) { + ay_state_from_snapshot( snap ); + } +} + +static void +fuller_to_snapshot( libspectrum_snap *snap ) +{ + libspectrum_snap_set_fuller_box_active( snap, periph_fuller_active ); +} + +int +fuller_init( void ) +{ + module_register( &fuller_module_info ); + + return 0; +} Copied: vendor/fuse-emulator/current/fuse/fuller.h (from rev 681, vendor/fuse-emulator/current/fuse/fuller.h) =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.h (rev 0) +++ vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,40 @@ +/* fuller.h: Routines for handling the Fuller Box + Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier + + $Id: fuller.h 4030 2009-06-07 14:38:38Z 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: + + Philip: phi...@sh... + + Stuart: sd...@nt... + +*/ + +#ifndef FUSE_FULLER_H +#define FUSE_FULLER_H + +#include <libspectrum.h> + +#include "periph.h" + +extern const periph_t fuller_peripherals[]; +extern const size_t fuller_peripherals_count; + +int fuller_init( void ); + +#endif /* #ifndef FUSE_FULLER_H */ Copied: vendor/fuse-emulator/current/fuse/if1.c (from rev 681, vendor/fuse-emulator/current/fuse/if1.c) =================================================================== --- vendor/fuse-emulator/current/fuse/if1.c (rev 0) +++ vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,1304 @@ +/* if1.c: Interface I handling routines + Copyright (c) 2004-2008 Gergely Szasz, Philip Kendall + + $Id: if1.c 4180 2010-10-09 12:59: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 + 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: + + Gergely: sz...@hu... + +*/ + +#include <config.h> + +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <unistd.h> + +#include "compat.h" +#include "debugger/debugger.h" +#include "if1.h" +#include "machine.h" +#include "memory.h" +#include "module.h" +#include "periph.h" +#include "settings.h" +#include "utils.h" +#include "ui/ui.h" + +#undef IF1_DEBUG_MDR +#undef IF1_DEBUG_NET +#undef IF1_DEBUG_NET_1 + +#define BUFF_EMPTY 0x100 + +enum { + SYNC_NO = 0, + SYNC_OK = 0xff +}; + +/* + Microdrive cartridge + GAP PREAMBLE 15 byte GAP PREAMBLE 15 byte 512 1 + [-----][00 00 ... ff ff][BLOCK HEAD][-----][00 00 ... ff ff][REC HEAD][ DATA ][CHK] + Preamble = 10 * 0x00 + 2 * 0xff (12 byte) +*/ + +typedef struct microdrive_t { + utils_file file; + char *filename; /* old filename */ + int inserted; + int modified; + int motor_on; + int head_pos; + int transfered; + int max_bytes; + libspectrum_byte pream[512]; /* preamble/sync area written */ + libspectrum_byte last; + libspectrum_byte gap; + libspectrum_byte sync; + + libspectrum_microdrive *cartridge; /* write protect, len, blocks */ + +} microdrive_t; + +typedef struct if1_ula_t { + int fd_r; /* file descriptor for reading bytes or bits RS232 */ + int fd_t; /* file descriptor for writing bytes or bits RS232 */ + int fd_net; /* file descriptor for rw bytes or bits SinclairNET */ + int rs232_buffer; /* read buffer */ + int s_net_mode; + int status; /* if1_ula/SinclairNET */ + int comms_data; /* the previous data comms state */ + int comms_clk; /* the previous data comms state */ + int cts; /* CTS of peripheral */ + int dtr; /* DTR of peripheral */ + int tx; /* TxD the name is very kind, because this is the read end of + the TxD wire of DATA machine (really RxD the view of + spectrum */ + int rx; /* RxD the name is very kind, because this is the write end of + the RxD wire of DATA machine (really TxD the view of + spectrum */ + int data_in; /* interpreted incoming data */ + int count_in; + int data_out; /* interpreted outgoing data */ + int count_out; + int esc_in; /* if we compose an escape seq */ + + int net; /* Network in/out (really 1 wire bus :-) */ + int net_data; /* Interpreted network data */ + int net_state; /* Interpreted network data */ + int wait; /* Wait state */ + int busy; /* Indicate busy; if1 software never poll it ... */ +} if1_ula_t; + +/* + 7 6 5 4 3 2 1 0 + STATUS RO $EF(239) --- --- --- BSY DTR GAP SYN WPR + + CONTRO WO $EF(239) --- --- WAT CTS ERA R/w CLK DTA + + MDR DT RW $E7(231) D7 D6 D5 D4 D3 D2 D1 D0 + + COMM I RO $F7(247) TX --- --- --- --- --- --- NET + + COMM O WO $F7(247) --- --- --- --- --- --- --- NET/RX + +RS232: + DTR -> Data Terminal Ready (DTE -> DCE) + CTS -> Clear To Send (DCE -> DTE) + TX -> Transmitted Data (DTE -> DCE) + RX -> Received Data (DCE -> DTE) + + The IF1 serial behaves not as a DTE (Data Terminal Equipment, e.g. + a computer) but as a DCE (Data Communications Equipment, e.g. a modem) + + If we were to consider the ZX Spectrum a DTE, we would rename the lines: + DTR := DSR (Data Set Ready) + CTS := RTS (Request To Send) + TX := RX + RX := TX + + On the communication channels: + Bytes interpreted as is, except: + 0x00 0x00 --> DTR ~~\__ + 0x00 0x01 --> DTR __/~~ + 0x00 0x02 --> CTS ~~\__ + 0x00 0x03 --> CTS __/~~ + 0x00 ? --> lost + 0x00 * --> 0x00 + Additionally: + if fuse read 0x00 0x00 => DTR = 0 ~~\__ + if fuse read 0x00 0x01 => DTR = 1 __/~~ + if CTS = ~~\__ fuse send 0x00 0x02 + if CTS = __/~~ fuse send 0x00 0x03 + if fuse lost send 0x00 + 0x3f (?) + every other 0x00 + 0x## are discarded +*/ + +/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ +static memory_page if1_memory_map_romcs[2]; + +/* IF1 paged out ROM activated? */ +int if1_active = 0; +int if1_available = 0; +static int if1_mdr_status = 0; + +int rnd_factor = ( ( RAND_MAX >> 2 ) << 2 ) / 19 + 1; + +static microdrive_t microdrive[8]; /* We have 8 microdrive */ +static if1_ula_t if1_ula; + +static void microdrives_reset( void ); +static void microdrives_restart( void ); +static void increment_head( int m ); + +#define MDR_IN(m) microdrive[m - 1].inserted +#define MDR_WP(m) libspectrum_microdrive_write_protect( microdrive[m - 1].cartridge ) + +enum if1_menu_item { + + UMENU_ALL = 0, + UMENU_MDRV1, + UMENU_MDRV2, + UMENU_MDRV3, + UMENU_MDRV4, + UMENU_MDRV5, + UMENU_MDRV6, + UMENU_MDRV7, + UMENU_MDRV8, + UMENU_RS232, +}; + +enum if1_port { + PORT_MDR, + PORT_CTR, + PORT_NET, + PORT_UNKNOWN, +}; + +static void if1_reset( int hard_reset ); +static void if1_enabled_snapshot( libspectrum_snap *snap ); +static void if1_from_snapshot( libspectrum_snap *snap ); +static void if1_to_snapshot( libspectrum_snap *snap ); + +static module_info_t if1_module_info = { + + if1_reset, + if1_memory_map, + if1_enabled_snapshot, + if1_from_snapshot, + if1_to_snapshot, + +}; + +const periph_t if1_peripherals[] = { + { 0x0018, 0x0010, if1_port_in, if1_port_out }, + { 0x0018, 0x0008, if1_port_in, if1_port_out }, + { 0x0018, 0x0000, if1_port_in, if1_port_out }, +}; + +const size_t if1_peripherals_count = + sizeof( if1_peripherals ) / sizeof( periph_t ); + +/* Debugger events */ +static const char *event_type_string = "if1"; +static int page_event, unpage_event; + +static void +update_menu( enum if1_menu_item what ) +{ + if( what == UMENU_ALL || what == UMENU_MDRV1 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_EJECT, MDR_IN( 1 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_WP_SET, + !MDR_IN( 1 ) ? 0 : !MDR_WP( 1 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV2 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_EJECT, MDR_IN( 2 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_WP_SET, + !MDR_IN( 2 ) ? 0 : !MDR_WP( 2 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV3 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_EJECT, MDR_IN( 3 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_WP_SET, + !MDR_IN( 3 ) ? 0 : !MDR_WP( 3 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV4 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_EJECT, MDR_IN( 4 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_WP_SET, + !MDR_IN( 4 ) ? 0 : !MDR_WP( 4 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV5 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_EJECT, MDR_IN( 5 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_WP_SET, + !MDR_IN( 5 ) ? 0 : !MDR_WP( 5 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV6 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_EJECT, MDR_IN( 6 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_WP_SET, + !MDR_IN( 6 ) ? 0 : !MDR_WP( 6 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV7 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_EJECT, MDR_IN( 7 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_WP_SET, + !MDR_IN( 7 ) ? 0 : !MDR_WP( 7 ) ); + } + + if( what == UMENU_ALL || what == UMENU_MDRV8 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_EJECT, MDR_IN( 8 ) ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_WP_SET, + !MDR_IN( 8 ) ? 0 : !MDR_WP( 8 ) ); + } + + if( what == UMENU_ALL || what == UMENU_RS232 ) { + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_R, + ( if1_ula.fd_r > -1 ) ? 1 : 0 ); + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_T, + ( if1_ula.fd_t > -1 ) ? 1 : 0 ); +#ifdef BUILD_WITH_SNET + ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_SNET_UNPLUG, + ( if1_ula.fd_net > -1 ) ? 1 : 0 ); +#endif + } +} + +int +if1_init( void ) +{ + int m, i; + + if1_ula.fd_r = -1; + if1_ula.fd_t = -1; + if1_ula.dtr = 0; /* No data terminal yet */ + if1_ula.cts = 2; /* force to emit first cts status */ + if1_ula.comms_clk = 0; + if1_ula.comms_data = 0; /* really? */ + if1_ula.fd_net = -1; + if1_ula.s_net_mode = 1; + if1_ula.net = 0; + if1_ula.esc_in = 0; /* empty */ + + for( m = 0; m < 8; m++ ) { + microdrive[m].cartridge = libspectrum_microdrive_alloc(); + microdrive[m].inserted = 0; + microdrive[m].modified = 0; + } + + if( settings_current.rs232_rx ) { + if1_plug( settings_current.rs232_rx, 1 ); + free( settings_current.rs232_rx ); + settings_current.rs232_rx = NULL; + } + + if( settings_current.rs232_tx ) { + if1_plug( settings_current.rs232_tx, 2 ); + free( settings_current.rs232_tx ); + settings_current.rs232_tx = NULL; + } + + if( settings_current.snet ) { + if1_plug( settings_current.snet, 3 ); + free( settings_current.snet ); + settings_current.snet = NULL; + } + + module_register( &if1_module_info ); + for( i = 0; i < 2; i++ ) if1_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; + + if( periph_register_paging_events( event_type_string, &page_event, + &unpage_event ) ) + return 1; + + return 0; +} + +libspectrum_error +if1_end( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + libspectrum_error error = + libspectrum_microdrive_free( microdrive[m].cartridge ); + if( error ) return error; + } + + return LIBSPECTRUM_ERROR_NONE; +} + +void +if1_update_menu( void ) +{ + update_menu( UMENU_ALL ); +} + +static void +if1_reset( int hard_reset GCC_UNUSED ) +{ + if1_active = 0; + if1_available = 0; + + if( !periph_interface1_active ) return; + + machine_load_rom_bank( if1_memory_map_romcs, 0, 0, + settings_current.rom_interface_i, + settings_default.rom_interface_i, + MEMORY_PAGE_SIZE ); + + if1_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; + + machine_current->ram.romcs = 0; + + if1_ula.cts = 2; /* force to emit first out if raw */ + if1_ula.comms_clk = 0; + if1_ula.comms_data = 0; + if1_ula.net = 0; + if1_ula.esc_in = 0; + + microdrives_reset(); + + update_menu( UMENU_ALL ); + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + + if1_mdr_status = 0; + + if1_available = 1; +} + +void +if1_page( void ) +{ + if1_active = 1; + machine_current->ram.romcs = 1; + machine_current->memory_map(); + + debugger_event( page_event ); +} + +void +if1_unpage( void ) +{ + if1_active = 0; + machine_current->ram.romcs = 0; + machine_current->memory_map(); + + debugger_event( unpage_event ); +} + +void +if1_memory_map( void ) +{ + if( !if1_active ) return; + + memory_map_read[0] = memory_map_write[0] = if1_memory_map_romcs[0]; +} + +static void +if1_enabled_snapshot( libspectrum_snap *snap ) +{ + if( libspectrum_snap_interface1_active( snap ) ) + settings_current.interface1 = 1; +} + +static void +if1_from_snapshot( libspectrum_snap *snap ) +{ + if( !libspectrum_snap_interface1_active( snap ) ) return; + + if( libspectrum_snap_interface1_custom_rom( snap ) && + libspectrum_snap_interface1_rom( snap, 0 ) && + machine_load_rom_bank_from_buffer( + if1_memory_map_romcs, 0, 0, + libspectrum_snap_interface1_rom( snap, 0 ), + libspectrum_snap_interface1_rom_length( snap, 0 ), + 1 ) ) + return; + + if( libspectrum_snap_interface1_paged( snap ) ) { + if1_page(); + } else { + if1_unpage(); + } +} + +static void +if1_to_snapshot( libspectrum_snap *snap ) +{ + libspectrum_byte *buffer; + + if( !periph_interface1_active ) return; + + libspectrum_snap_set_interface1_active( snap, 1 ); + libspectrum_snap_set_interface1_paged ( snap, if1_active ); + libspectrum_snap_set_interface1_drive_count( snap, 8 ); + + if( if1_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { + size_t rom_length = MEMORY_PAGE_SIZE; + + if( if1_memory_map_romcs[1].source == MEMORY_SOURCE_CUSTOMROM ) { + rom_length <<= 1; + } + + libspectrum_snap_set_interface1_custom_rom( snap, 1 ); + libspectrum_snap_set_interface1_rom_length( snap, 0, rom_length ); + + buffer = malloc( rom_length ); + if( !buffer ) { + ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); + return; + } + + memcpy( buffer, if1_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); + + if( rom_length == MEMORY_PAGE_SIZE*2 ) { + memcpy( buffer + MEMORY_PAGE_SIZE, if1_memory_map_romcs[1].page, + MEMORY_PAGE_SIZE ); + } + + libspectrum_snap_set_interface1_rom( snap, 0, buffer ); + } +} + +static void +microdrives_reset( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + microdrive[m].head_pos = 0; + microdrive[m].motor_on = 0; /* motor off */ + microdrive[m].gap = 15; + microdrive[m].sync = 15; + microdrive[m].transfered = 0; + } + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + if1_mdr_status = 0; +/* + if1_ula.comms_data = 0; + if1_ula.count_in = 0; + if1_ula.count_out = 0; + if1_ula.cts = 0; + if1_ula.dtr = 0; + if1_ula.wait = 0; + if1_ula.busy = 0; + if1_ula.net = 0; + if1_ula.net_state = 0; +*/ +} + +static enum if1_port +decode_port( libspectrum_word port ) +{ + switch( port & 0x0018 ) { + case 0x0000: return PORT_MDR; + case 0x0008: return PORT_CTR; + case 0x0010: return PORT_NET; + default: return PORT_UNKNOWN; + } +} + +static libspectrum_byte +port_mdr_in( void ) +{ + libspectrum_byte ret = 0xff; + int m; + + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { + + if( mdr->transfered < mdr->max_bytes ) { + mdr->last = libspectrum_microdrive_data( mdr->cartridge, + mdr->head_pos ); + increment_head( m ); + } + + mdr->transfered++; + ret &= mdr->last; /* I assume negative logic, but how know? */ + } + + } + + return ret; +} + +static libspectrum_byte +port_ctr_in( void ) +{ + libspectrum_byte ret = 0xff; + int m, block; + + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { + block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); + if( mdr->pream[block] == SYNC_OK ) { /* if formatted */ + if( mdr->gap ) { + /* ret &= 0xff; GAP and SYNC high ? */ + mdr->gap--; + } else { + ret &= 0xf9; /* GAP and SYNC low */ + if( mdr->sync ) { + mdr->sync--; + } else { + mdr->gap = 15; + mdr->sync = 15; + } + } + } + /* if write protected */ + if( libspectrum_microdrive_write_protect( mdr->cartridge) ) + ret &= 0xfe; /* active bit */ + } + } + /* Here we have to poll, the if1_ula DTR 'line' */ + if( if1_ula.rs232_buffer > 0xff ) { /* buffer empty */ + unsigned char byte; + int yes = 1; + + while( yes && read( if1_ula.fd_r, &byte, 1 ) == 1 ) { + if( if1_ula.esc_in == 1 ) { + if1_ula.esc_in = 0; + if( byte == '*' ) { + if1_ula.rs232_buffer = 0x00; + yes = 0; + } else if( byte == 0x00 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 0; + } else if( byte == 0x01 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 1; + } + } else if( byte == 0x00 ) { + if1_ula.esc_in = 1; + } else { + if1_ula.rs232_buffer = byte; + yes = 0; + break; + } + } + } + + if( if1_ula.dtr == 0 ) + ret &= 0xf7; /* %11110111 */ + + /* Here we have to poll, the 'SinclairNet' busy flag but never used by + software in Interface 1 */ + if( if1_ula.busy == 0 ) + ret &= 0xef; /* %11101111 */ + /* fprintf( stderr, "Read CTR ( %%%d%d%d%d%d%d%d%d ).\n", + !!(ret & 128), !!(ret & 64), !!(ret & 32), !!(ret & 16), + !!(ret & 8), !!(ret & 4), !!(ret & 2), !!(ret & 1)); */ + microdrives_restart(); + + return ret; +} + +/* + return 1 if read a byte + 0 if nothing interesting... +*/ + +static int +read_rs232() +{ + if( if1_ula.rs232_buffer <= 0xff ) { /* we read from the buffer */ + if1_ula.data_in = if1_ula.rs232_buffer; + if1_ula.rs232_buffer = 0x0100; + return 1; + } + while( read( if1_ula.fd_r, &if1_ula.data_in, 1 ) == 1 ) { + if( if1_ula.esc_in == 1 ) { + if1_ula.esc_in = 0; + if( if1_ula.data_in == '*' ) { + if1_ula.data_in = 0x00; + return 1; + } else if( if1_ula.data_in == 0x00 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 0; + } else if( if1_ula.data_in == 0x01 ) { + if( settings_current.rs232_handshake ) + if1_ula.dtr = 1; + } + } else if( if1_ula.data_in == 0x00 ) { + if1_ula.esc_in = 1; + } else { + return 1; + } + } + return 0; +} + +static libspectrum_byte +port_net_in( void ) +{ + libspectrum_byte ret = 0xff; + + if( if1_ula.fd_r == -1 ) + goto no_rs232_in; + + /* Here is the RS232 input routine */ + if( if1_ula.cts ) { /* If CTS == 1 */ + if( if1_ula.count_in == 0 ) { + if( if1_ula.fd_r >= 0 && read_rs232() == 1 ) { + if1_ula.count_in++; /* Ok, if read a byte, we begin */ + } + if1_ula.tx = 0; /* now send __ to if1 + later we raise :-) */ + } else if( if1_ula.count_in >= 1 && if1_ula.count_in < 5 ) { + if1_ula.tx = 1; /* send ~~ (start bit :-) */ + if1_ula.count_in++; + } else if( if1_ula.count_in >= 5 && if1_ula.count_in < 13 ) { + if1_ula.tx = ( if1_ula.data_in & 0x01 ) ? 0 : 1; + /* send .. (data bits :-) */ + if1_ula.data_in >>= 1; /* prepare next bit :-) */ + if1_ula.count_in++; + } else + if1_ula.count_in = 0; + } else { /* if( if1_ula.cts ) */ + if1_ula.count_in = 0; /* reset serial in */ + if1_ula.tx = 0; /* send __ stop bits or s.e. :-) */ + } + +no_rs232_in: + if( if1_ula.fd_net == -1 ) + goto no_snet_in; + + if( if1_ula.s_net_mode == 0 ) { /* if we do raw */ + /* Here is the input routine */ + read( if1_ula.fd_net, &if1_ula.net, 1 ); /* Ok, if no byte, we send last*/ + } else {/* if( if1_ula.s_net_mode == 1 ) if we do interpreted */ +/* Here is the input routine. There are several stage in input + and output. So first for output. if1 first do SEND-SC + (http://www.wearmouth.demon.co.uk/if1_2.htm#L101E) to send + a Sync-Out signal and SEND-SC do first a NET-STATE + (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FBC) to see + the line activity: + 11xxxxxx times (192-255) have to get a zero (bit for network) + plus 1 times more from SEND-SC. Next SEND-SC send a 0 which is + a 1 on the net wire (negated output, straight input!!!) + + OK. In input first if1 call WT-SC-E to check Network activity + (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FD3). Now check + 128 times the net wire (we do two round, because to differentiate + net out routines...) +*/ + + if( if1_ula.net_state < 0x0100 ) { /* if1 may in NET-STATE */ + if1_ula.net_state++; + if1_ula.net = 0; +#ifdef IF1_DEBUG_NET + fprintf( stderr, "NET-STAT(%03d)? We send 0!\n", if1_ula.net_state ); +#endif + } else if( if1_ula.net_state == 0x0100 ) { /* probably waiting for input */ + if( read( if1_ula.fd_net, &if1_ula.net_data, 1 ) == 1 ) { + if1_ula.net_state++; + if1_ula.net = 1; /* Start with __/~~ */ + } /* Ok, if have a byte, we send it! */ + } else if( if1_ula.net_state == 0x0101 ) { + if1_ula.net_state++; + if1_ula.net = 1; /* one more ~~ */ + } else if( if1_ula.net_state > 0x0101 && + if1_ula.net_state < 0x010a ) { /* we send the data bits... */ + if1_ula.net_state++; + if1_ula.net = if1_ula.net_data & 1; + if1_ula.net_data >>= 1; + } else if( if1_ula.net_state == 0x010a ) { + if1_ula.net = 0; + if1_ula.net_state = 0; /* OK, we starting a new byte... */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "NET-STAT(%03d)? Get a byte!\n", if1_ula.net_state ); +#endif + } + } +no_snet_in: + if( !if1_ula.tx ) + ret &= 0x7f; + if( !if1_ula.net ) + ret &= 0xfe; + microdrives_restart(); + + return ret; +} + +libspectrum_byte +if1_port_in( libspectrum_word port GCC_UNUSED, int *attached ) +{ + libspectrum_byte ret = 0xff; + + if( !if1_active ) return ret; + + *attached = 1; + + switch( decode_port( port ) ) + { + case PORT_MDR: ret &= port_mdr_in(); break; + case PORT_CTR: ret &= port_ctr_in(); break; + case PORT_NET: ret &= port_net_in(); break; + case PORT_UNKNOWN: break; + } + + return ret; +} + +static void +port_mdr_out( libspectrum_byte val ) +{ + int m, block; + + /* allow access to the port only if motor 1 is ON and there's a file open */ + for( m = 0; m < 8; m++ ) { + + microdrive_t *mdr = µdrive[ m ]; + + if( mdr->motor_on && mdr->inserted ) { +#ifdef IF1_DEBUG_MDR + fprintf(stderr, "#%05d %03d(%03d): 0x%02x\n", + mdr->head_pos, mdr->transfered, mdr->max_bytes, val ); +#endif + block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); + if( mdr->transfered == 0 && val == 0x00 ) { /* start pream */ + mdr->pream[block] = 1; + } else if( mdr->transfered > 0 && mdr->transfered < 10 && val == 0x00 ) { + mdr->pream[block]++; + } else if( mdr->transfered > 9 && mdr->transfered < 12 && val == 0xff ) { + mdr->pream[block]++; + } else if( mdr->transfered == 12 && mdr->pream[block] == 12 ) { + mdr->pream[block] = SYNC_OK; + } + if( mdr->transfered > 11 && + mdr->transfered < mdr->max_bytes + 12 ) { + + libspectrum_microdrive_set_data( mdr->cartridge, mdr->head_pos, + val ); + increment_head( m ); + mdr->modified = 1; + } + mdr->transfered++; + } + } +} + +static void +port_ctr_out( libspectrum_byte val ) +{ + int m; + + if( !( val & 0x02 ) && ( if1_ula.comms_clk ) ) { /* ~~\__ */ + + for( m = 7; m > 0; m-- ) { + /* Rotate one drive */ + microdrive[m].motor_on = microdrive[m - 1].motor_on; + } + microdrive[0].motor_on = (val & 0x01) ? 0 : 1; + + if( microdrive[0].motor_on || microdrive[1].motor_on || + microdrive[2].motor_on || microdrive[3].motor_on || + microdrive[4].motor_on || microdrive[5].motor_on || + microdrive[6].motor_on || microdrive[7].motor_on ) { + if( !if1_mdr_status ) { + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_ACTIVE ); + if1_mdr_status = 1; + } + } else if ( if1_mdr_status ) { + ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, + UI_STATUSBAR_STATE_INACTIVE ); + if1_mdr_status = 0; + } + } + if( val & 0x01 ) { /* comms_data == 1 */ + /* Interface 1 service manual p.:1.4 par.: 1.5.1 + The same pin on IC1 (if1 ULA), pin 33, is used for the network + transmit data and for the RS232 transmit data. In order to select + the required function IC1 uses its COMMS_OUT (pin 30) signal, + borrowed from the microdrive control when the microdrive is not + being used (I do not know what it is exactly meaning. It is a + hardware not being used, or a software should not use..?) This signal + is routed from pin 30 to the emitter of transistor Q3 (RX DATA) and + via resistor R4, to the base of transistor Q1 (NET). When COMMS_OUT + is high Q3 is enabled this selecting RS232, and when it is low + Q1 is enabled selecting the network. + + OK, the schematics offer a different interpretation, because if + COMMS_OUT pin level high (>+3V) then Q3 is off (the basis cannot + be more higher potential then emitter (NPN transistor), so whatever + is on the IC1 RX DATA (pin 33) the basis of Q4 is always on +12V, + so the collector of Q4 (PNP transistor) always on -12V. + If COMMS_OUT pin level goes low (~0V), then Q3 basis (connected + to IC1 RX DATA pin) can be higher level (>+3V) than emitter, so + the basis potential of Q4 depend on IC1 RX DATA. + + OK, Summa summarum I assume that, the COMMS OUT pin is a + negated output of the if1 ULA CTR register's COMMS DATA bit. + */ + /* C_DATA = 1 */ + if( if1_ula.comms_data == 0 ) { + if1_ula.count_out = 0; + if1_ula.data_out = 0; + if1_ula.count_in = 0; + if1_ula.data_in = 0; + } + } + if1_ula.wait = ( val & 0x20 ) ? 1 : 0; + if1_ula.comms_data = ( val & 0x01 ) ? 1 : 0; + if1_ula.comms_clk = ( val & 0x02 ) ? 1 : 0; + val = ( val & 0x10 ) ? 1 : 0; + if( settings_current.rs232_handshake && + if1_ula.fd_t != -1 && if1_ula.cts != val ) { + char data = val ? 0x03 : 0x02; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + do ; while( write( if1_ula.fd_t, &data, 1 ) != 1 ); + } + if1_ula.cts = val; + +#ifdef IF1_DEBUG_NET + fprintf( stderr, "Set CTS to %d, set WAIT to %d and COMMS_DATA to %d\n", + if1_ula.cts, if1_ula.wait, if1_ula.comms_data ); +#endif + + microdrives_restart(); +} + +static void +port_net_out( libspectrum_byte val ) +{ + if( if1_ula.fd_t == -1 ) + return; /* nothing to write */ + + if( if1_ula.comms_data == 1 ) { /* OK, RS232 */ + val &= 0x01; + if( if1_ula.count_out == 0 && !val ) { /* waiting for ~~\__ */ + if1_ula.count_out++; + } else if( if1_ula.count_out == 1 ) { + if( if1_ula.cts != 0 || !val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; /* else get the start bit __/~~ */ + } else if( if1_ula.count_out >= 2 && if1_ula.count_out <= 9 ) { + if1_ula.data_out >>= 1; + if1_ula.data_out |= val & 0x01 ? 0 : 128; + if1_ula.count_out++; /* waiting for next data bit */ + } else if( if1_ula.count_out >= 10 && if1_ula.count_out <= 11 ) { + if( val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; + } else if( if1_ula.count_out == 12 ) { + if( !val ) + if1_ula.count_out = -1; + else + if1_ula.count_out++; + } else if( if1_ula.count_out == 13 ) { + if( val ) + if1_ula.count_out = -1; + } + + if( if1_ula.count_out == -1 ) { + if1_ula.count_out = 13; + if1_ula.data_out = '?'; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + } + if( if1_ula.count_out == 13 ) { + /* Here is the output routine */ + if( if1_ula.data_out == 0x00 ) { + if1_ula.data_out = '*'; + do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); + } + do ; while( write( if1_ula.fd_t, &if1_ula.data_out, 1 ) != 1 ); + if1_ula.count_out = 0; + } + if1_ula.rx = val & 0x01; /* set rx */ + } else { /* if( if1_ula.comms_data == 1 ) SinclairNET :-)*/ + if( if1_ula.s_net_mode == 0 ) { /* if we out bit by bit, do it */ + /* Here is the output routine */ + +/* OK, examining the schematics of if1 and the disassembly of if1 ROM, I + see that the Q1 and Q2 transistors negate the RX DATA signal, and the + floating state of the net wire is the ~0V level, the forced is the ~3V. + The if1 software send complemented data and read straight data. +*/ + if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set rx */ + lseek( if1_ula.fd_net, 0, SEEK_SET ); /* we save only the state of the wire*/ + do ; while( write( if1_ula.fd_net, &if1_ula.net, 1 ) == -1 ); +#ifdef HAVE_FSYNC + fsync( if1_ula.fd_net ); +#endif /* #ifdef HAVE_FSYNC */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "Send SinclairNET: %d\n", if1_ula.net ); +#endif + } else { /* if( if1_ula.s_net_mode == 0 ) if we out byte by byte, do it */ + if( if1_ula.net_state >= 0x0200 && if1_ula.net_state < 0x0208 ) { + if1_ula.net_state++; + if1_ula.net_data <<= 1; + if1_ula.net_data |= ( val & 0x01 ) ? 0 : 1; + } else if( if1_ula.net_state == 0x0208 ) { + if1_ula.net_data &= 0xff; + if1_ula.net_state++; /* OK, now we get data bytes... */ + +/* lseek( if1_ula.fd_net, 0, SEEK_SET ); start a packet */ + /* first we send the station number */ + do ; while( write( if1_ula.fd_net, &if1_ula.net_data, 1 ) == -1 ); +#ifdef HAVE_FSYNC + fsync( if1_ula.fd_net ); +#endif /* #ifdef HAVE_FSYNC */ +#ifdef IF1_DEBUG_NET + fprintf( stderr, "SC-OUT send network number: %d\n", + if1_ula.net_data ^ 0xff ); +#endif + } else if( if1_ula.net_state > 192 && if1_ula.net_state < 0x0200 && + ( ( val & 0x01 ) == 0 ) ) { + /* NET-STATE ask as many times.... and now send a 0 */ +/* if1_ula.net = 1; */ + if1_ula.net_state = 0x0200; /* Send the station number */ + } + if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set net wire? */ + } + } + microdrives_restart(); +} + +void +if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val ) +{ + if( !if1_active ) return; + +#ifdef IF1_DEBUG_NET_1 + fprintf( stderr, "In if1_port_out( %%%d%d%d%d%d%d%d%d => 0x%04x ).\n", + !!(val & 128), !!(val & 64), !!(val & 32), !!(val & 16), + !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port); +#endif + + switch( decode_port( port ) ) { + case PORT_MDR: port_mdr_out( val ); break; + case PORT_CTR: port_ctr_out( val ); break; + case PORT_NET: port_net_out( val ); break; + case PORT_UNKNOWN: break; + } +} + +static void +increment_head( int m ) +{ + microdrive[m].head_pos++; + if( microdrive[m].head_pos >= + libspectrum_microdrive_cartridge_len( microdrive[m].cartridge ) * + LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) + microdrive[m].head_pos = 0; +} + +static void +microdrives_restart( void ) +{ + int m; + + for( m = 0; m < 8; m++ ) { + while( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != 0 && + ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != LIBSPECTRUM_MICRODRIVE_HEAD_LEN ) + increment_head( m ); /* put head in the start of a block */ + + microdrive[m].transfered = 0; /* reset current number of bytes written */ + + if( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) == 0 ) { + microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN; /* up to 15 bytes for header blocks */ + } else { + microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN + LIBSPECTRUM_MICRODRIVE_DATA_LEN + 1; /* up to 528 bytes for data blocks */ + } + } +} + +void +if1_mdr_writeprotect( int drive, int wrprot ) +{ + libspectrum_microdrive_set_write_protect( microdrive[drive].cartridge, + wrprot ? 1 : 0 ); + microdrive[drive].modified = 1; + + update_menu( UMENU_MDRV1 + drive ); +} + +static void +if1_mdr_new( microdrive_t *mdr ) +{ + libspectrum_byte len; + long int i; + + mdr->filename = NULL; + if( settings_current.mdr_random_len ) { /* Random length */ + len = 171 + ( ( rand() >> 2 ) + ( rand() >> 2 ) + + ( rand() >> 2 ) + ( rand() >> 2 ) ) + / rnd_factor; + } else + len = settings_current.mdr_len = settings_current.mdr_len < 10 ? 10 : + settings_current.mdr_len > LIBSPECTRUM_MICRODRIVE_BLOCK_MAX ? LIBSPECTRUM_MICRODRIVE_BLOCK_MAX : settings_current.mdr_len; + + /* Erase the entire cartridge */ + libspectrum_microdrive_set_cartridge_len( mdr->cartridge, len ); + + for( i = 0; i < len * LIBSPECTRUM_MICRODRIVE_BLOCK_LEN; i++ ) + libspectrum_microdrive_set_data( mdr->cartridge, i, 0xff ); + + for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); + i > 0; i-- ) + mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_NO; + + /* but don't write-protect */ + libspectrum_microdrive_set_write_protect( mdr->cartridge, 0 ); + + mdr->inserted = 1; + mdr->modified = 1; + +} + +int +if1_mdr_insert( int which, const char *filename ) +{ + microdrive_t *mdr; + int m, i; + + if( which == -1 ) { /* find an empty one */ + for( m = 0; m < 8; m++ ) { + if( !microdrive[m].inserted ) { + which = m; + break; + } + } + } + + if( which == -1 ) { + ui_error( UI_ERROR_ERROR, + "Cannot insert cartridge '%s', all Microdrives in use", + filename ); + return 1; + } + + if( which >= 8 ) { + ui_error( UI_ERROR_ERROR, "if1_mdr_insert: unknown drive %d", which ); + return 1; + } + + mdr = µdrive[ which ]; + + /* Eject any cartridge already in the drive */ + if( mdr->inserted ) { + /* Abort the insert if we want to keep the current cartridge */ + if( if1_mdr_eject( which, 0 ) ) return 0; + } + + if( filename == NULL ) { /* insert new unformatted cartridge */ + if1_mdr_new( mdr ); + update_menu( UMENU_MDRV1 + which ); + return 0; + } + + if( utils_read_file( filename, &mdr->file ) ) { + ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); + return 1; + } + + if( libspectrum_microdrive_mdr_read( mdr->cartridge, mdr->file.buffer, + mdr->file.length ) ) { + utils_close_file( &mdr->file ); + ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); + return 1; + } + + if( utils_close_file( &mdr->file ) ) return 1; + + mdr->inserted = 1; + mdr->modified = 0; + mdr->filename = strdup( filename ); + /* we assume formatted cartridges */ + for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); + i > 0; i-- ) + mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_OK; + + update_menu( UMENU_MDRV1 + which ); + + return 0; +} + +int +if1_mdr_eject( int which, int saveas ) +{ + microdrive_t *mdr; + + if( which >= 8 ) + return 1; + + mdr = µdrive[ which ]; + + if( !mdr->inserted ) + return 0; + + if( saveas ) { /* 1 -> save as.., 2 -> save */ + + if( mdr->filename == NULL ) saveas = 1; + if( ui_mdr_write( which, 2 - saveas ) ) return 1; + mdr->modified = 0; + return 0; + + } else { + + if( mdr->modified ) { + + ui_confirm_save_t confirm = ui_confirm_save( + "Cartridge in Microdrive %i has been modified.\n" + "Do you want to save it?", + which + 1 + ); + + switch( confirm ) { + + case UI_CONFIRM_SAVE_SAVE: + if( if1_mdr_eject( which, 2 ) ) return 1; /* first save */ + break; + + case UI_CONFIRM_SAVE_DONTSAVE: break; + case UI_CONFIRM_SAVE_CANCEL: return 1; + + } + } + } + + mdr->inserted = 0; + if( mdr->filename != NULL ) { + free( mdr->filename ); + mdr->filename = NULL; + } + + update_menu( UMENU_MDRV1 + which ); + return 0; +} + +int +if1_mdr_write( int which, const char *filename ) +{ + microdrive_t *mdr = µdrive[which]; + + libspectrum_microdrive_mdr_write( mdr->cartridge, &mdr->file.buffer, + &mdr->file.length ); + + if( filename == NULL ) filename = mdr->filename; /* Write over the original file */ + + if( utils_write_file( filename, mdr->file.buffer, mdr->file.length ) ) + return 1; + + if( mdr->filename && strcmp( filename, mdr->filename ) ) { + free( mdr->filename ); + mdr->filename = strdup( filename ); + } + return 0; +} + +#ifndef O_NONBLOCK +#define O_NONBLOCK FNDELAY +#endif + +void +if1_plug( const char *filename, int what ) +{ +#ifdef WIN32 + ui_error( UI_ERROR_ERROR, "Not yet implemented on Win32" ); + return; +#else + int fd = -1; + + switch( what ) { + case 1: + if( if1_ula.fd_r >= 0 ) + close( if1_ula.fd_r ); + fd = if1_ula.fd_r = open( filename, O_RDWR | O_NONBLOCK ); + if( fcntl( fd, F_SETFL, O_RDONLY | O_NONBLOCK ) ) + ui_error( UI_ERROR_ERROR, "Cannot set O_RDONLY on '%s': %s", + filename, strerror( errno ) ); + if1_ula.rs232_buffer = 0x100; /* buffer is empty */ + break; + case 2: + if( if1_ula.fd_t >= 0 ) + close( if1_ula.fd_t ); + fd = if1_ula.fd_t = open( filename, O_RDWR | O_NONBLOCK ); + if( fcntl( fd, F_SETFL, O_WRONLY | O_NONBLOCK ) ) + ui_error( UI_ERROR_ERROR, "Cannot set O_WRONLY on '%s': %s", + filename, strerror( errno ) ); + break; + case 3: + if( if1_ula.fd_net >= 0 ) + close( if1_ula.fd_net ); + fd = if1_ula.fd_net = open( filename, O_RDWR | O_NONBLOCK ); + break; + } + + /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ + if( !settings_current.rs232_handshake && + if1_ula.fd_t != -1 && if1_ula.fd_r != -1 ) + if1_ula.dtr = 1; + + if( fd < 0 ) { + ui_error( UI_ERROR_ERROR, "Error opening '%s': %s", + filename, strerror( errno ) ); + return; + } + + if1_ula.s_net_mode = settings_current.raw_s_net ? 0 : 1; + update_menu( UMENU_RS232 ); +#endif +} + +void +if1_unplug( int what ) +{ + switch( what ) { + case 1: + if( if1_ula.fd_r >= 0 ) + close( if1_ula.fd_r ); + if1_ula.fd_r = -1; + break; + case 2: + if( if1_ula.fd_t >= 0 ) + close( if1_ula.fd_t ); + if1_ula.fd_t = -1; + if1_ula.dtr = 0; + break; + case 3: + if( if1_ula.fd_net >= 0 ) + close( if1_ula.fd_net ); + if1_ula.fd_net = -1; + break; + } + /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ + if( !settings_current.rs232_handshake && + ( if1_ula.fd_t == -1 || if1_ula.fd_r == -1 ) ) + if1_ula.dtr = 0; + update_menu( UMENU_RS232 ); +} Copied: vendor/fuse-emulator/current/fuse/if1.h (from rev 681, vendor/fuse-emulator/current/fuse/if1.h) =================================================================== --- vendor/fuse-emulator/current/fuse/if1.h (rev 0) +++ vendor/fuse-emulator/current/fuse/if1.h 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,59 @@ +/* if1.h: Interface I handling routines + Copyright (c) 2004-2005 Gergely Szasz, Philip Kendall + + $Id: if1.h 3327 2007-11-22 23:06:47Z 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: + + Gergely: sz...@hu... + +*/ + +#ifndef FUSE_IF1_H +#define FUSE_IF1_H + +#include <libspectrum.h> + +#include "periph.h" + +/* IF1 */ +extern int if1_active; +extern int if1_available; + +extern const periph_t if1_peripherals[]; +extern const size_t if1_peripherals_count; + +int if1_init( void ); +libspectrum_error if1_end( void ); + +void if1_page( void ); +void if1_unpage( void ); +void if1_memory_map( void ); + +void if1_port_out( libspectrum_word port, libspectrum_byte val ); +libspectrum_byte if1_port_in( libspectrum_word port, int *attached ); + +int if1_mdr_insert( int drive, const char *filename ); +int if1_mdr_write( int drive, const char *filename ); +int if1_mdr_eject( int drive, int write ); +void if1_mdr_writeprotect( int drive, int wrprot ); +void if1_plug( const char *filename, int what ); +void if1_unplug( int what ); + +void if1_update_menu( void ); + +#endif /* #ifndef FUSE_IF1_H */ Copied: vendor/fuse-emulator/current/fuse/if2.c (from rev 681, vendor/fuse-emulator/current/fuse/if2.c) =================================================================== --- vendor/fuse-emulator/current/fuse/if2.c (rev 0) +++ vendor/fuse-emulator/current/fuse/if2.c 2012-01-14 13:01:10 UTC (rev 683) @@ -0,0 +1,204 @@ +/* if2.c: Interface II cartridge handling routines + Copyright (c) 2003 Darren Salt, Fredrick Meunier, Philip Kendall + Copyright (c) 2004 Fredrick Meunier + + $Id: if2.c 4099 2009-10-22 10:59:02Z fredm $ + + This program is free software; ... [truncated message content] |
From: <fr...@us...> - 2012-02-15 12:32:44
|
Revision: 684 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=684&view=rev Author: fredm Date: 2012-02-15 12:32:32 +0000 (Wed, 15 Feb 2012) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 24 renames. Added Paths: ----------- vendor/fuse-emulator/current/fuse/peripherals/ vendor/fuse-emulator/current/fuse/peripherals/ay.c vendor/fuse-emulator/current/fuse/peripherals/ay.h vendor/fuse-emulator/current/fuse/peripherals/dck.c vendor/fuse-emulator/current/fuse/peripherals/dck.h vendor/fuse-emulator/current/fuse/peripherals/disk/ vendor/fuse-emulator/current/fuse/peripherals/fuller.c vendor/fuse-emulator/current/fuse/peripherals/fuller.h vendor/fuse-emulator/current/fuse/peripherals/ide/ vendor/fuse-emulator/current/fuse/peripherals/if1.c vendor/fuse-emulator/current/fuse/peripherals/if1.h vendor/fuse-emulator/current/fuse/peripherals/if2.c vendor/fuse-emulator/current/fuse/peripherals/if2.h vendor/fuse-emulator/current/fuse/peripherals/joystick.c vendor/fuse-emulator/current/fuse/peripherals/joystick.h vendor/fuse-emulator/current/fuse/peripherals/kempmouse.c vendor/fuse-emulator/current/fuse/peripherals/kempmouse.h vendor/fuse-emulator/current/fuse/peripherals/melodik.c vendor/fuse-emulator/current/fuse/peripherals/melodik.h vendor/fuse-emulator/current/fuse/peripherals/printer.c vendor/fuse-emulator/current/fuse/peripherals/printer.h vendor/fuse-emulator/current/fuse/peripherals/scld.c vendor/fuse-emulator/current/fuse/peripherals/scld.h vendor/fuse-emulator/current/fuse/peripherals/ula.c vendor/fuse-emulator/current/fuse/peripherals/ula.h Removed Paths: ------------- vendor/fuse-emulator/current/fuse/ay.c vendor/fuse-emulator/current/fuse/ay.h vendor/fuse-emulator/current/fuse/dck.c vendor/fuse-emulator/current/fuse/dck.h vendor/fuse-emulator/current/fuse/disk/ vendor/fuse-emulator/current/fuse/fuller.c vendor/fuse-emulator/current/fuse/fuller.h vendor/fuse-emulator/current/fuse/ide/ vendor/fuse-emulator/current/fuse/if1.c vendor/fuse-emulator/current/fuse/if1.h vendor/fuse-emulator/current/fuse/if2.c vendor/fuse-emulator/current/fuse/if2.h vendor/fuse-emulator/current/fuse/joystick.c vendor/fuse-emulator/current/fuse/joystick.h vendor/fuse-emulator/current/fuse/kempmouse.c vendor/fuse-emulator/current/fuse/kempmouse.h vendor/fuse-emulator/current/fuse/melodik.c vendor/fuse-emulator/current/fuse/melodik.h vendor/fuse-emulator/current/fuse/printer.c vendor/fuse-emulator/current/fuse/printer.h vendor/fuse-emulator/current/fuse/scld.c vendor/fuse-emulator/current/fuse/scld.h vendor/fuse-emulator/current/fuse/ula.c vendor/fuse-emulator/current/fuse/ula.h Deleted: vendor/fuse-emulator/current/fuse/ay.c =================================================================== --- vendor/fuse-emulator/current/fuse/ay.c 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/ay.c 2012-02-15 12:32:32 UTC (rev 684) @@ -1,169 +0,0 @@ -/* ay.c: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.c 4030 2009-06-07 14:38:38Z 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 <string.h> - -#include "compat.h" -#include "machine.h" -#include "module.h" -#include "printer.h" -#include "psg.h" -#include "sound.h" - -/* Unused bits in the AY registers are silently zeroed out; these masks - accomplish this */ -static const libspectrum_byte mask[ AY_REGISTERS ] = { - - 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0xff, - 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x0f, 0xff, 0xff, - -}; - -static void ay_reset( int hard_reset ); -static void ay_from_snapshot( libspectrum_snap *snap ); -static void ay_to_snapshot( libspectrum_snap *snap ); - -static module_info_t ay_module_info = { - - ay_reset, - NULL, - NULL, - ay_from_snapshot, - ay_to_snapshot, - -}; - -int -ay_init( void ) -{ - module_register( &ay_module_info ); - - return 0; -} - -static void -ay_reset( int hard_reset GCC_UNUSED ) -{ - ayinfo *ay = &machine_current->ay; - - ay->current_register = 0; - memset( ay->registers, 0, sizeof( ay->registers ) ); -} - -/* What happens when the AY register port (traditionally 0xfffd on the 128K - machines) is read from */ -libspectrum_byte -ay_registerport_read( libspectrum_word port GCC_UNUSED, int *attached ) -{ - int current; - const libspectrum_byte port_input = 0xbf; /* always allow serial output */ - - *attached = 1; - - current = machine_current->ay.current_register; - - /* The AY I/O ports return input directly from the port when in - input mode; but in output mode, they return an AND between the - register value and the port input. So, allow for this when - reading R14... */ - - if( current == 14 ) { - if(machine_current->ay.registers[7] & 0x40) - return (port_input & machine_current->ay.registers[14]); - else - return port_input; - } - - /* R15 is simpler to do, as the 8912 lacks the second I/O port, and - the input-mode input is always 0xff */ - if( current == 15 && !( machine_current->ay.registers[7] & 0x80 ) ) - return 0xff; - - /* Otherwise return register value, appropriately masked */ - return machine_current->ay.registers[ current ] & mask[ current ]; -} - -/* And when it's written to */ -void -ay_registerport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - machine_current->ay.current_register = (b & 15); -} - -/* What happens when the AY data port (traditionally 0xbffd on the 128K - machines) is written to; no corresponding read function as this - always returns 0xff */ -void -ay_dataport_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b ) -{ - int current; - - current = machine_current->ay.current_register; - - machine_current->ay.registers[ current ] = b & mask[ current ]; - sound_ay_write( current, b, tstates ); - if( psg_recording ) psg_write_register( current, b ); - - if( current == 14 ) printer_serial_write( b ); -} - -void -ay_state_from_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - ay_registerport_write( 0xfffd, - libspectrum_snap_out_ay_registerport( snap ) ); - - for( i = 0; i < AY_REGISTERS; i++ ) { - machine_current->ay.registers[i] = - libspectrum_snap_ay_registers( snap, i ); - sound_ay_write( i, machine_current->ay.registers[i], 0 ); - } -} - -static void -ay_from_snapshot( libspectrum_snap *snap ) -{ - if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) { - ay_state_from_snapshot( snap ); - } -} - -static void -ay_to_snapshot( libspectrum_snap *snap ) -{ - size_t i; - - libspectrum_snap_set_out_ay_registerport( - snap, machine_current->ay.current_register - ); - - for( i = 0; i < AY_REGISTERS; i++ ) - libspectrum_snap_set_ay_registers( snap, i, - machine_current->ay.registers[i] ); -} Deleted: vendor/fuse-emulator/current/fuse/ay.h =================================================================== --- vendor/fuse-emulator/current/fuse/ay.h 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/ay.h 2012-02-15 12:32:32 UTC (rev 684) @@ -1,47 +0,0 @@ -/* ay.h: AY-8-3912 routines - Copyright (c) 1999-2009 Philip Kendall - - $Id: ay.h 4030 2009-06-07 14:38:38Z 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... - -*/ - -#ifndef FUSE_AY_H -#define FUSE_AY_H - -#include <libspectrum.h> - -#define AY_REGISTERS 16 - -typedef struct ayinfo { - int current_register; - libspectrum_byte registers[ AY_REGISTERS ]; -} ayinfo; - -int ay_init( void ); - -libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached ); -void ay_registerport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_dataport_write( libspectrum_word port, libspectrum_byte b ); - -void ay_state_from_snapshot( libspectrum_snap *snap ); - -#endif /* #ifndef FUSE_AY_H */ Deleted: vendor/fuse-emulator/current/fuse/dck.c =================================================================== --- vendor/fuse-emulator/current/fuse/dck.c 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/dck.c 2012-02-15 12:32:32 UTC (rev 684) @@ -1,184 +0,0 @@ -/* dck.c: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#include <config.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <libspectrum.h> - -#include "dck.h" -#include "machine.h" -#include "memory.h" -#include "settings.h" -#include "scld.h" -#include "ui/ui.h" -#include "utils.h" -#include "debugger/debugger.h" - -/* Dock cart inserted? */ -int dck_active = 0; - -int -dck_insert( const char *filename ) -{ - int error; - - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return 1; - } - - error = settings_set_string( &settings_current.dck_file, filename ); - if( error ) return error; - - machine_reset( 0 ); - - return 0; -} - -void -dck_eject( void ) -{ - if ( !( libspectrum_machine_capabilities( machine_current->machine ) & - LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { - ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); - return; - } - - if( settings_current.dck_file ) free( settings_current.dck_file ); - settings_current.dck_file = NULL; - - dck_active = 0; - - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - - machine_reset( 0 ); -} - -int -dck_reset( void ) -{ - utils_file file; - size_t num_block = 0; - libspectrum_dck *dck; - int error; - - dck_active = 0; - - if( !settings_current.dck_file ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); - return 0; - } - - dck = libspectrum_dck_alloc(); - - error = utils_read_file( settings_current.dck_file, &file ); - if( error ) { libspectrum_dck_free( dck, 0 ); return error; } - - error = libspectrum_dck_read2( dck, file.buffer, file.length, - settings_current.dck_file ); - if( error ) { - utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error; - } - - if( utils_close_file( &file ) ) { - libspectrum_dck_free( dck, 0 ); - return 1; - } - - while( dck->dck[num_block] != NULL ) { - memory_page **mem; - int i; - - switch( dck->dck[num_block]->bank ) { - case LIBSPECTRUM_DCK_BANK_HOME: - mem = memory_map_home; - break; - case LIBSPECTRUM_DCK_BANK_DOCK: - mem = memory_map_dock; - break; - case LIBSPECTRUM_DCK_BANK_EXROM: - mem = memory_map_exrom; - break; - default: - ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported", - dck->dck[num_block]->bank ); - libspectrum_dck_free( dck, 0 ); - return 1; - } - - for( i = 0; i < 8; i++ ) { - - switch( dck->dck[num_block]->access[i] ) { - - case LIBSPECTRUM_DCK_PAGE_NULL: - break; - - case LIBSPECTRUM_DCK_PAGE_ROM: - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - mem[i]->writable = 0; - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - break; - - case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY: - case LIBSPECTRUM_DCK_PAGE_RAM: - /* Because the scr and snapshot code depends on the standard - memory map being in the RAM[] array, we just copy RAM - blocks from the HOME bank into the appropriate page; in - other cases, we allocate ourselves a new page to store the - contents in */ - if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) { - mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE ); - if( !mem[i]->page ) return 1; - mem[i]->writable = 1; - } - - mem[i]->source = MEMORY_SOURCE_CARTRIDGE; - memcpy( mem[i]->page, dck->dck[num_block]->pages[i], - MEMORY_PAGE_SIZE ); - break; - - } - } - num_block++; - } - - dck_active = 1; - - /* Make the menu item to eject the cartridge active */ - ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 ); - - return libspectrum_dck_free( dck, 0 ); -} Deleted: vendor/fuse-emulator/current/fuse/dck.h =================================================================== --- vendor/fuse-emulator/current/fuse/dck.h 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/dck.h 2012-02-15 12:32:32 UTC (rev 684) @@ -1,39 +0,0 @@ -/* dck.h: dock snapshot (Warajevo .DCK) handling routines - Copyright (c) 2003 Darren Salt, Fredrick Meunier - - $Id: dck.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: - - Philip: phi...@sh... - - Darren: li...@yo... - Fred: fr...@sp... - -*/ - -#ifndef FUSE_DCK_H -#define FUSE_DCK_H - -/* Dock cart inserted? */ -extern int dck_active; - -int dck_insert( const char *filename ); -void dck_eject( void ); -int dck_reset( void ); - -#endif Deleted: vendor/fuse-emulator/current/fuse/fuller.c =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.c 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/fuller.c 2012-02-15 12:32:32 UTC (rev 684) @@ -1,90 +0,0 @@ -/* fuller.c: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.c 4032 2009-06-10 11:09:44Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#include <config.h> - -#include <libspectrum.h> - -#include "ay.h" -#include "compat.h" -#include "fuller.h" -#include "joystick.h" -#include "module.h" -#include "periph.h" -#include "settings.h" - -static void fuller_enabled_snapshot( libspectrum_snap *snap ); -static void fuller_from_snapshot( libspectrum_snap *snap ); -static void fuller_to_snapshot( libspectrum_snap *snap ); - -static module_info_t fuller_module_info = { - - NULL, - NULL, - fuller_enabled_snapshot, - fuller_from_snapshot, - fuller_to_snapshot, - -}; - -const periph_t fuller_peripherals[] = { - { 0x00ff, 0x003f, ay_registerport_read, ay_registerport_write }, - { 0x00ff, 0x005f, NULL, ay_dataport_write }, - { 0x00ff, 0x007f, joystick_fuller_read, NULL }, -}; - -const size_t fuller_peripherals_count = - sizeof( fuller_peripherals ) / sizeof( periph_t ); - -static void -fuller_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_fuller_box_active( snap ) ) - settings_current.fuller = 1; -} - -static void -fuller_from_snapshot( libspectrum_snap *snap ) -{ - if( periph_fuller_active ) { - ay_state_from_snapshot( snap ); - } -} - -static void -fuller_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_snap_set_fuller_box_active( snap, periph_fuller_active ); -} - -int -fuller_init( void ) -{ - module_register( &fuller_module_info ); - - return 0; -} Deleted: vendor/fuse-emulator/current/fuse/fuller.h =================================================================== --- vendor/fuse-emulator/current/fuse/fuller.h 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/fuller.h 2012-02-15 12:32:32 UTC (rev 684) @@ -1,40 +0,0 @@ -/* fuller.h: Routines for handling the Fuller Box - Copyright (c) 2007-2009 Stuart Brady, Fredrick Meunier - - $Id: fuller.h 4030 2009-06-07 14:38:38Z 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: - - Philip: phi...@sh... - - Stuart: sd...@nt... - -*/ - -#ifndef FUSE_FULLER_H -#define FUSE_FULLER_H - -#include <libspectrum.h> - -#include "periph.h" - -extern const periph_t fuller_peripherals[]; -extern const size_t fuller_peripherals_count; - -int fuller_init( void ); - -#endif /* #ifndef FUSE_FULLER_H */ Deleted: vendor/fuse-emulator/current/fuse/if1.c =================================================================== --- vendor/fuse-emulator/current/fuse/if1.c 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/if1.c 2012-02-15 12:32:32 UTC (rev 684) @@ -1,1304 +0,0 @@ -/* if1.c: Interface I handling routines - Copyright (c) 2004-2008 Gergely Szasz, Philip Kendall - - $Id: if1.c 4180 2010-10-09 12:59: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 - 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: - - Gergely: sz...@hu... - -*/ - -#include <config.h> - -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <unistd.h> - -#include "compat.h" -#include "debugger/debugger.h" -#include "if1.h" -#include "machine.h" -#include "memory.h" -#include "module.h" -#include "periph.h" -#include "settings.h" -#include "utils.h" -#include "ui/ui.h" - -#undef IF1_DEBUG_MDR -#undef IF1_DEBUG_NET -#undef IF1_DEBUG_NET_1 - -#define BUFF_EMPTY 0x100 - -enum { - SYNC_NO = 0, - SYNC_OK = 0xff -}; - -/* - Microdrive cartridge - GAP PREAMBLE 15 byte GAP PREAMBLE 15 byte 512 1 - [-----][00 00 ... ff ff][BLOCK HEAD][-----][00 00 ... ff ff][REC HEAD][ DATA ][CHK] - Preamble = 10 * 0x00 + 2 * 0xff (12 byte) -*/ - -typedef struct microdrive_t { - utils_file file; - char *filename; /* old filename */ - int inserted; - int modified; - int motor_on; - int head_pos; - int transfered; - int max_bytes; - libspectrum_byte pream[512]; /* preamble/sync area written */ - libspectrum_byte last; - libspectrum_byte gap; - libspectrum_byte sync; - - libspectrum_microdrive *cartridge; /* write protect, len, blocks */ - -} microdrive_t; - -typedef struct if1_ula_t { - int fd_r; /* file descriptor for reading bytes or bits RS232 */ - int fd_t; /* file descriptor for writing bytes or bits RS232 */ - int fd_net; /* file descriptor for rw bytes or bits SinclairNET */ - int rs232_buffer; /* read buffer */ - int s_net_mode; - int status; /* if1_ula/SinclairNET */ - int comms_data; /* the previous data comms state */ - int comms_clk; /* the previous data comms state */ - int cts; /* CTS of peripheral */ - int dtr; /* DTR of peripheral */ - int tx; /* TxD the name is very kind, because this is the read end of - the TxD wire of DATA machine (really RxD the view of - spectrum */ - int rx; /* RxD the name is very kind, because this is the write end of - the RxD wire of DATA machine (really TxD the view of - spectrum */ - int data_in; /* interpreted incoming data */ - int count_in; - int data_out; /* interpreted outgoing data */ - int count_out; - int esc_in; /* if we compose an escape seq */ - - int net; /* Network in/out (really 1 wire bus :-) */ - int net_data; /* Interpreted network data */ - int net_state; /* Interpreted network data */ - int wait; /* Wait state */ - int busy; /* Indicate busy; if1 software never poll it ... */ -} if1_ula_t; - -/* - 7 6 5 4 3 2 1 0 - STATUS RO $EF(239) --- --- --- BSY DTR GAP SYN WPR - - CONTRO WO $EF(239) --- --- WAT CTS ERA R/w CLK DTA - - MDR DT RW $E7(231) D7 D6 D5 D4 D3 D2 D1 D0 - - COMM I RO $F7(247) TX --- --- --- --- --- --- NET - - COMM O WO $F7(247) --- --- --- --- --- --- --- NET/RX - -RS232: - DTR -> Data Terminal Ready (DTE -> DCE) - CTS -> Clear To Send (DCE -> DTE) - TX -> Transmitted Data (DTE -> DCE) - RX -> Received Data (DCE -> DTE) - - The IF1 serial behaves not as a DTE (Data Terminal Equipment, e.g. - a computer) but as a DCE (Data Communications Equipment, e.g. a modem) - - If we were to consider the ZX Spectrum a DTE, we would rename the lines: - DTR := DSR (Data Set Ready) - CTS := RTS (Request To Send) - TX := RX - RX := TX - - On the communication channels: - Bytes interpreted as is, except: - 0x00 0x00 --> DTR ~~\__ - 0x00 0x01 --> DTR __/~~ - 0x00 0x02 --> CTS ~~\__ - 0x00 0x03 --> CTS __/~~ - 0x00 ? --> lost - 0x00 * --> 0x00 - Additionally: - if fuse read 0x00 0x00 => DTR = 0 ~~\__ - if fuse read 0x00 0x01 => DTR = 1 __/~~ - if CTS = ~~\__ fuse send 0x00 0x02 - if CTS = __/~~ fuse send 0x00 0x03 - if fuse lost send 0x00 + 0x3f (?) - every other 0x00 + 0x## are discarded -*/ - -/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */ -static memory_page if1_memory_map_romcs[2]; - -/* IF1 paged out ROM activated? */ -int if1_active = 0; -int if1_available = 0; -static int if1_mdr_status = 0; - -int rnd_factor = ( ( RAND_MAX >> 2 ) << 2 ) / 19 + 1; - -static microdrive_t microdrive[8]; /* We have 8 microdrive */ -static if1_ula_t if1_ula; - -static void microdrives_reset( void ); -static void microdrives_restart( void ); -static void increment_head( int m ); - -#define MDR_IN(m) microdrive[m - 1].inserted -#define MDR_WP(m) libspectrum_microdrive_write_protect( microdrive[m - 1].cartridge ) - -enum if1_menu_item { - - UMENU_ALL = 0, - UMENU_MDRV1, - UMENU_MDRV2, - UMENU_MDRV3, - UMENU_MDRV4, - UMENU_MDRV5, - UMENU_MDRV6, - UMENU_MDRV7, - UMENU_MDRV8, - UMENU_RS232, -}; - -enum if1_port { - PORT_MDR, - PORT_CTR, - PORT_NET, - PORT_UNKNOWN, -}; - -static void if1_reset( int hard_reset ); -static void if1_enabled_snapshot( libspectrum_snap *snap ); -static void if1_from_snapshot( libspectrum_snap *snap ); -static void if1_to_snapshot( libspectrum_snap *snap ); - -static module_info_t if1_module_info = { - - if1_reset, - if1_memory_map, - if1_enabled_snapshot, - if1_from_snapshot, - if1_to_snapshot, - -}; - -const periph_t if1_peripherals[] = { - { 0x0018, 0x0010, if1_port_in, if1_port_out }, - { 0x0018, 0x0008, if1_port_in, if1_port_out }, - { 0x0018, 0x0000, if1_port_in, if1_port_out }, -}; - -const size_t if1_peripherals_count = - sizeof( if1_peripherals ) / sizeof( periph_t ); - -/* Debugger events */ -static const char *event_type_string = "if1"; -static int page_event, unpage_event; - -static void -update_menu( enum if1_menu_item what ) -{ - if( what == UMENU_ALL || what == UMENU_MDRV1 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_EJECT, MDR_IN( 1 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M1_WP_SET, - !MDR_IN( 1 ) ? 0 : !MDR_WP( 1 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV2 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_EJECT, MDR_IN( 2 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M2_WP_SET, - !MDR_IN( 2 ) ? 0 : !MDR_WP( 2 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV3 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_EJECT, MDR_IN( 3 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M3_WP_SET, - !MDR_IN( 3 ) ? 0 : !MDR_WP( 3 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV4 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_EJECT, MDR_IN( 4 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M4_WP_SET, - !MDR_IN( 4 ) ? 0 : !MDR_WP( 4 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV5 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_EJECT, MDR_IN( 5 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M5_WP_SET, - !MDR_IN( 5 ) ? 0 : !MDR_WP( 5 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV6 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_EJECT, MDR_IN( 6 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M6_WP_SET, - !MDR_IN( 6 ) ? 0 : !MDR_WP( 6 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV7 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_EJECT, MDR_IN( 7 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M7_WP_SET, - !MDR_IN( 7 ) ? 0 : !MDR_WP( 7 ) ); - } - - if( what == UMENU_ALL || what == UMENU_MDRV8 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_EJECT, MDR_IN( 8 ) ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_M8_WP_SET, - !MDR_IN( 8 ) ? 0 : !MDR_WP( 8 ) ); - } - - if( what == UMENU_ALL || what == UMENU_RS232 ) { - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_R, - ( if1_ula.fd_r > -1 ) ? 1 : 0 ); - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_RS232_UNPLUG_T, - ( if1_ula.fd_t > -1 ) ? 1 : 0 ); -#ifdef BUILD_WITH_SNET - ui_menu_activate( UI_MENU_ITEM_MEDIA_IF1_SNET_UNPLUG, - ( if1_ula.fd_net > -1 ) ? 1 : 0 ); -#endif - } -} - -int -if1_init( void ) -{ - int m, i; - - if1_ula.fd_r = -1; - if1_ula.fd_t = -1; - if1_ula.dtr = 0; /* No data terminal yet */ - if1_ula.cts = 2; /* force to emit first cts status */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; /* really? */ - if1_ula.fd_net = -1; - if1_ula.s_net_mode = 1; - if1_ula.net = 0; - if1_ula.esc_in = 0; /* empty */ - - for( m = 0; m < 8; m++ ) { - microdrive[m].cartridge = libspectrum_microdrive_alloc(); - microdrive[m].inserted = 0; - microdrive[m].modified = 0; - } - - if( settings_current.rs232_rx ) { - if1_plug( settings_current.rs232_rx, 1 ); - free( settings_current.rs232_rx ); - settings_current.rs232_rx = NULL; - } - - if( settings_current.rs232_tx ) { - if1_plug( settings_current.rs232_tx, 2 ); - free( settings_current.rs232_tx ); - settings_current.rs232_tx = NULL; - } - - if( settings_current.snet ) { - if1_plug( settings_current.snet, 3 ); - free( settings_current.snet ); - settings_current.snet = NULL; - } - - module_register( &if1_module_info ); - for( i = 0; i < 2; i++ ) if1_memory_map_romcs[i].bank = MEMORY_BANK_ROMCS; - - if( periph_register_paging_events( event_type_string, &page_event, - &unpage_event ) ) - return 1; - - return 0; -} - -libspectrum_error -if1_end( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - libspectrum_error error = - libspectrum_microdrive_free( microdrive[m].cartridge ); - if( error ) return error; - } - - return LIBSPECTRUM_ERROR_NONE; -} - -void -if1_update_menu( void ) -{ - update_menu( UMENU_ALL ); -} - -static void -if1_reset( int hard_reset GCC_UNUSED ) -{ - if1_active = 0; - if1_available = 0; - - if( !periph_interface1_active ) return; - - machine_load_rom_bank( if1_memory_map_romcs, 0, 0, - settings_current.rom_interface_i, - settings_default.rom_interface_i, - MEMORY_PAGE_SIZE ); - - if1_memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL; - - machine_current->ram.romcs = 0; - - if1_ula.cts = 2; /* force to emit first out if raw */ - if1_ula.comms_clk = 0; - if1_ula.comms_data = 0; - if1_ula.net = 0; - if1_ula.esc_in = 0; - - microdrives_reset(); - - update_menu( UMENU_ALL ); - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - - if1_mdr_status = 0; - - if1_available = 1; -} - -void -if1_page( void ) -{ - if1_active = 1; - machine_current->ram.romcs = 1; - machine_current->memory_map(); - - debugger_event( page_event ); -} - -void -if1_unpage( void ) -{ - if1_active = 0; - machine_current->ram.romcs = 0; - machine_current->memory_map(); - - debugger_event( unpage_event ); -} - -void -if1_memory_map( void ) -{ - if( !if1_active ) return; - - memory_map_read[0] = memory_map_write[0] = if1_memory_map_romcs[0]; -} - -static void -if1_enabled_snapshot( libspectrum_snap *snap ) -{ - if( libspectrum_snap_interface1_active( snap ) ) - settings_current.interface1 = 1; -} - -static void -if1_from_snapshot( libspectrum_snap *snap ) -{ - if( !libspectrum_snap_interface1_active( snap ) ) return; - - if( libspectrum_snap_interface1_custom_rom( snap ) && - libspectrum_snap_interface1_rom( snap, 0 ) && - machine_load_rom_bank_from_buffer( - if1_memory_map_romcs, 0, 0, - libspectrum_snap_interface1_rom( snap, 0 ), - libspectrum_snap_interface1_rom_length( snap, 0 ), - 1 ) ) - return; - - if( libspectrum_snap_interface1_paged( snap ) ) { - if1_page(); - } else { - if1_unpage(); - } -} - -static void -if1_to_snapshot( libspectrum_snap *snap ) -{ - libspectrum_byte *buffer; - - if( !periph_interface1_active ) return; - - libspectrum_snap_set_interface1_active( snap, 1 ); - libspectrum_snap_set_interface1_paged ( snap, if1_active ); - libspectrum_snap_set_interface1_drive_count( snap, 8 ); - - if( if1_memory_map_romcs[0].source == MEMORY_SOURCE_CUSTOMROM ) { - size_t rom_length = MEMORY_PAGE_SIZE; - - if( if1_memory_map_romcs[1].source == MEMORY_SOURCE_CUSTOMROM ) { - rom_length <<= 1; - } - - libspectrum_snap_set_interface1_custom_rom( snap, 1 ); - libspectrum_snap_set_interface1_rom_length( snap, 0, rom_length ); - - buffer = malloc( rom_length ); - if( !buffer ) { - ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); - return; - } - - memcpy( buffer, if1_memory_map_romcs[0].page, MEMORY_PAGE_SIZE ); - - if( rom_length == MEMORY_PAGE_SIZE*2 ) { - memcpy( buffer + MEMORY_PAGE_SIZE, if1_memory_map_romcs[1].page, - MEMORY_PAGE_SIZE ); - } - - libspectrum_snap_set_interface1_rom( snap, 0, buffer ); - } -} - -static void -microdrives_reset( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - microdrive[m].head_pos = 0; - microdrive[m].motor_on = 0; /* motor off */ - microdrive[m].gap = 15; - microdrive[m].sync = 15; - microdrive[m].transfered = 0; - } - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; -/* - if1_ula.comms_data = 0; - if1_ula.count_in = 0; - if1_ula.count_out = 0; - if1_ula.cts = 0; - if1_ula.dtr = 0; - if1_ula.wait = 0; - if1_ula.busy = 0; - if1_ula.net = 0; - if1_ula.net_state = 0; -*/ -} - -static enum if1_port -decode_port( libspectrum_word port ) -{ - switch( port & 0x0018 ) { - case 0x0000: return PORT_MDR; - case 0x0008: return PORT_CTR; - case 0x0010: return PORT_NET; - default: return PORT_UNKNOWN; - } -} - -static libspectrum_byte -port_mdr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - - if( mdr->transfered < mdr->max_bytes ) { - mdr->last = libspectrum_microdrive_data( mdr->cartridge, - mdr->head_pos ); - increment_head( m ); - } - - mdr->transfered++; - ret &= mdr->last; /* I assume negative logic, but how know? */ - } - - } - - return ret; -} - -static libspectrum_byte -port_ctr_in( void ) -{ - libspectrum_byte ret = 0xff; - int m, block; - - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->pream[block] == SYNC_OK ) { /* if formatted */ - if( mdr->gap ) { - /* ret &= 0xff; GAP and SYNC high ? */ - mdr->gap--; - } else { - ret &= 0xf9; /* GAP and SYNC low */ - if( mdr->sync ) { - mdr->sync--; - } else { - mdr->gap = 15; - mdr->sync = 15; - } - } - } - /* if write protected */ - if( libspectrum_microdrive_write_protect( mdr->cartridge) ) - ret &= 0xfe; /* active bit */ - } - } - /* Here we have to poll, the if1_ula DTR 'line' */ - if( if1_ula.rs232_buffer > 0xff ) { /* buffer empty */ - unsigned char byte; - int yes = 1; - - while( yes && read( if1_ula.fd_r, &byte, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( byte == '*' ) { - if1_ula.rs232_buffer = 0x00; - yes = 0; - } else if( byte == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( byte == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( byte == 0x00 ) { - if1_ula.esc_in = 1; - } else { - if1_ula.rs232_buffer = byte; - yes = 0; - break; - } - } - } - - if( if1_ula.dtr == 0 ) - ret &= 0xf7; /* %11110111 */ - - /* Here we have to poll, the 'SinclairNet' busy flag but never used by - software in Interface 1 */ - if( if1_ula.busy == 0 ) - ret &= 0xef; /* %11101111 */ - /* fprintf( stderr, "Read CTR ( %%%d%d%d%d%d%d%d%d ).\n", - !!(ret & 128), !!(ret & 64), !!(ret & 32), !!(ret & 16), - !!(ret & 8), !!(ret & 4), !!(ret & 2), !!(ret & 1)); */ - microdrives_restart(); - - return ret; -} - -/* - return 1 if read a byte - 0 if nothing interesting... -*/ - -static int -read_rs232() -{ - if( if1_ula.rs232_buffer <= 0xff ) { /* we read from the buffer */ - if1_ula.data_in = if1_ula.rs232_buffer; - if1_ula.rs232_buffer = 0x0100; - return 1; - } - while( read( if1_ula.fd_r, &if1_ula.data_in, 1 ) == 1 ) { - if( if1_ula.esc_in == 1 ) { - if1_ula.esc_in = 0; - if( if1_ula.data_in == '*' ) { - if1_ula.data_in = 0x00; - return 1; - } else if( if1_ula.data_in == 0x00 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 0; - } else if( if1_ula.data_in == 0x01 ) { - if( settings_current.rs232_handshake ) - if1_ula.dtr = 1; - } - } else if( if1_ula.data_in == 0x00 ) { - if1_ula.esc_in = 1; - } else { - return 1; - } - } - return 0; -} - -static libspectrum_byte -port_net_in( void ) -{ - libspectrum_byte ret = 0xff; - - if( if1_ula.fd_r == -1 ) - goto no_rs232_in; - - /* Here is the RS232 input routine */ - if( if1_ula.cts ) { /* If CTS == 1 */ - if( if1_ula.count_in == 0 ) { - if( if1_ula.fd_r >= 0 && read_rs232() == 1 ) { - if1_ula.count_in++; /* Ok, if read a byte, we begin */ - } - if1_ula.tx = 0; /* now send __ to if1 - later we raise :-) */ - } else if( if1_ula.count_in >= 1 && if1_ula.count_in < 5 ) { - if1_ula.tx = 1; /* send ~~ (start bit :-) */ - if1_ula.count_in++; - } else if( if1_ula.count_in >= 5 && if1_ula.count_in < 13 ) { - if1_ula.tx = ( if1_ula.data_in & 0x01 ) ? 0 : 1; - /* send .. (data bits :-) */ - if1_ula.data_in >>= 1; /* prepare next bit :-) */ - if1_ula.count_in++; - } else - if1_ula.count_in = 0; - } else { /* if( if1_ula.cts ) */ - if1_ula.count_in = 0; /* reset serial in */ - if1_ula.tx = 0; /* send __ stop bits or s.e. :-) */ - } - -no_rs232_in: - if( if1_ula.fd_net == -1 ) - goto no_snet_in; - - if( if1_ula.s_net_mode == 0 ) { /* if we do raw */ - /* Here is the input routine */ - read( if1_ula.fd_net, &if1_ula.net, 1 ); /* Ok, if no byte, we send last*/ - } else {/* if( if1_ula.s_net_mode == 1 ) if we do interpreted */ -/* Here is the input routine. There are several stage in input - and output. So first for output. if1 first do SEND-SC - (http://www.wearmouth.demon.co.uk/if1_2.htm#L101E) to send - a Sync-Out signal and SEND-SC do first a NET-STATE - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FBC) to see - the line activity: - 11xxxxxx times (192-255) have to get a zero (bit for network) - plus 1 times more from SEND-SC. Next SEND-SC send a 0 which is - a 1 on the net wire (negated output, straight input!!!) - - OK. In input first if1 call WT-SC-E to check Network activity - (http://www.wearmouth.demon.co.uk/if1_2.htm#L0FD3). Now check - 128 times the net wire (we do two round, because to differentiate - net out routines...) -*/ - - if( if1_ula.net_state < 0x0100 ) { /* if1 may in NET-STATE */ - if1_ula.net_state++; - if1_ula.net = 0; -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? We send 0!\n", if1_ula.net_state ); -#endif - } else if( if1_ula.net_state == 0x0100 ) { /* probably waiting for input */ - if( read( if1_ula.fd_net, &if1_ula.net_data, 1 ) == 1 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* Start with __/~~ */ - } /* Ok, if have a byte, we send it! */ - } else if( if1_ula.net_state == 0x0101 ) { - if1_ula.net_state++; - if1_ula.net = 1; /* one more ~~ */ - } else if( if1_ula.net_state > 0x0101 && - if1_ula.net_state < 0x010a ) { /* we send the data bits... */ - if1_ula.net_state++; - if1_ula.net = if1_ula.net_data & 1; - if1_ula.net_data >>= 1; - } else if( if1_ula.net_state == 0x010a ) { - if1_ula.net = 0; - if1_ula.net_state = 0; /* OK, we starting a new byte... */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "NET-STAT(%03d)? Get a byte!\n", if1_ula.net_state ); -#endif - } - } -no_snet_in: - if( !if1_ula.tx ) - ret &= 0x7f; - if( !if1_ula.net ) - ret &= 0xfe; - microdrives_restart(); - - return ret; -} - -libspectrum_byte -if1_port_in( libspectrum_word port GCC_UNUSED, int *attached ) -{ - libspectrum_byte ret = 0xff; - - if( !if1_active ) return ret; - - *attached = 1; - - switch( decode_port( port ) ) - { - case PORT_MDR: ret &= port_mdr_in(); break; - case PORT_CTR: ret &= port_ctr_in(); break; - case PORT_NET: ret &= port_net_in(); break; - case PORT_UNKNOWN: break; - } - - return ret; -} - -static void -port_mdr_out( libspectrum_byte val ) -{ - int m, block; - - /* allow access to the port only if motor 1 is ON and there's a file open */ - for( m = 0; m < 8; m++ ) { - - microdrive_t *mdr = µdrive[ m ]; - - if( mdr->motor_on && mdr->inserted ) { -#ifdef IF1_DEBUG_MDR - fprintf(stderr, "#%05d %03d(%03d): 0x%02x\n", - mdr->head_pos, mdr->transfered, mdr->max_bytes, val ); -#endif - block = mdr->head_pos / 543 + ( mdr->max_bytes == 15 ? 0 : 256 ); - if( mdr->transfered == 0 && val == 0x00 ) { /* start pream */ - mdr->pream[block] = 1; - } else if( mdr->transfered > 0 && mdr->transfered < 10 && val == 0x00 ) { - mdr->pream[block]++; - } else if( mdr->transfered > 9 && mdr->transfered < 12 && val == 0xff ) { - mdr->pream[block]++; - } else if( mdr->transfered == 12 && mdr->pream[block] == 12 ) { - mdr->pream[block] = SYNC_OK; - } - if( mdr->transfered > 11 && - mdr->transfered < mdr->max_bytes + 12 ) { - - libspectrum_microdrive_set_data( mdr->cartridge, mdr->head_pos, - val ); - increment_head( m ); - mdr->modified = 1; - } - mdr->transfered++; - } - } -} - -static void -port_ctr_out( libspectrum_byte val ) -{ - int m; - - if( !( val & 0x02 ) && ( if1_ula.comms_clk ) ) { /* ~~\__ */ - - for( m = 7; m > 0; m-- ) { - /* Rotate one drive */ - microdrive[m].motor_on = microdrive[m - 1].motor_on; - } - microdrive[0].motor_on = (val & 0x01) ? 0 : 1; - - if( microdrive[0].motor_on || microdrive[1].motor_on || - microdrive[2].motor_on || microdrive[3].motor_on || - microdrive[4].motor_on || microdrive[5].motor_on || - microdrive[6].motor_on || microdrive[7].motor_on ) { - if( !if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_ACTIVE ); - if1_mdr_status = 1; - } - } else if ( if1_mdr_status ) { - ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE, - UI_STATUSBAR_STATE_INACTIVE ); - if1_mdr_status = 0; - } - } - if( val & 0x01 ) { /* comms_data == 1 */ - /* Interface 1 service manual p.:1.4 par.: 1.5.1 - The same pin on IC1 (if1 ULA), pin 33, is used for the network - transmit data and for the RS232 transmit data. In order to select - the required function IC1 uses its COMMS_OUT (pin 30) signal, - borrowed from the microdrive control when the microdrive is not - being used (I do not know what it is exactly meaning. It is a - hardware not being used, or a software should not use..?) This signal - is routed from pin 30 to the emitter of transistor Q3 (RX DATA) and - via resistor R4, to the base of transistor Q1 (NET). When COMMS_OUT - is high Q3 is enabled this selecting RS232, and when it is low - Q1 is enabled selecting the network. - - OK, the schematics offer a different interpretation, because if - COMMS_OUT pin level high (>+3V) then Q3 is off (the basis cannot - be more higher potential then emitter (NPN transistor), so whatever - is on the IC1 RX DATA (pin 33) the basis of Q4 is always on +12V, - so the collector of Q4 (PNP transistor) always on -12V. - If COMMS_OUT pin level goes low (~0V), then Q3 basis (connected - to IC1 RX DATA pin) can be higher level (>+3V) than emitter, so - the basis potential of Q4 depend on IC1 RX DATA. - - OK, Summa summarum I assume that, the COMMS OUT pin is a - negated output of the if1 ULA CTR register's COMMS DATA bit. - */ - /* C_DATA = 1 */ - if( if1_ula.comms_data == 0 ) { - if1_ula.count_out = 0; - if1_ula.data_out = 0; - if1_ula.count_in = 0; - if1_ula.data_in = 0; - } - } - if1_ula.wait = ( val & 0x20 ) ? 1 : 0; - if1_ula.comms_data = ( val & 0x01 ) ? 1 : 0; - if1_ula.comms_clk = ( val & 0x02 ) ? 1 : 0; - val = ( val & 0x10 ) ? 1 : 0; - if( settings_current.rs232_handshake && - if1_ula.fd_t != -1 && if1_ula.cts != val ) { - char data = val ? 0x03 : 0x02; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - do ; while( write( if1_ula.fd_t, &data, 1 ) != 1 ); - } - if1_ula.cts = val; - -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Set CTS to %d, set WAIT to %d and COMMS_DATA to %d\n", - if1_ula.cts, if1_ula.wait, if1_ula.comms_data ); -#endif - - microdrives_restart(); -} - -static void -port_net_out( libspectrum_byte val ) -{ - if( if1_ula.fd_t == -1 ) - return; /* nothing to write */ - - if( if1_ula.comms_data == 1 ) { /* OK, RS232 */ - val &= 0x01; - if( if1_ula.count_out == 0 && !val ) { /* waiting for ~~\__ */ - if1_ula.count_out++; - } else if( if1_ula.count_out == 1 ) { - if( if1_ula.cts != 0 || !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; /* else get the start bit __/~~ */ - } else if( if1_ula.count_out >= 2 && if1_ula.count_out <= 9 ) { - if1_ula.data_out >>= 1; - if1_ula.data_out |= val & 0x01 ? 0 : 128; - if1_ula.count_out++; /* waiting for next data bit */ - } else if( if1_ula.count_out >= 10 && if1_ula.count_out <= 11 ) { - if( val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 12 ) { - if( !val ) - if1_ula.count_out = -1; - else - if1_ula.count_out++; - } else if( if1_ula.count_out == 13 ) { - if( val ) - if1_ula.count_out = -1; - } - - if( if1_ula.count_out == -1 ) { - if1_ula.count_out = 13; - if1_ula.data_out = '?'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - if( if1_ula.count_out == 13 ) { - /* Here is the output routine */ - if( if1_ula.data_out == 0x00 ) { - if1_ula.data_out = '*'; - do ; while( write( if1_ula.fd_t, "", 1 ) != 1 ); - } - do ; while( write( if1_ula.fd_t, &if1_ula.data_out, 1 ) != 1 ); - if1_ula.count_out = 0; - } - if1_ula.rx = val & 0x01; /* set rx */ - } else { /* if( if1_ula.comms_data == 1 ) SinclairNET :-)*/ - if( if1_ula.s_net_mode == 0 ) { /* if we out bit by bit, do it */ - /* Here is the output routine */ - -/* OK, examining the schematics of if1 and the disassembly of if1 ROM, I - see that the Q1 and Q2 transistors negate the RX DATA signal, and the - floating state of the net wire is the ~0V level, the forced is the ~3V. - The if1 software send complemented data and read straight data. -*/ - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set rx */ - lseek( if1_ula.fd_net, 0, SEEK_SET ); /* we save only the state of the wire*/ - do ; while( write( if1_ula.fd_net, &if1_ula.net, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "Send SinclairNET: %d\n", if1_ula.net ); -#endif - } else { /* if( if1_ula.s_net_mode == 0 ) if we out byte by byte, do it */ - if( if1_ula.net_state >= 0x0200 && if1_ula.net_state < 0x0208 ) { - if1_ula.net_state++; - if1_ula.net_data <<= 1; - if1_ula.net_data |= ( val & 0x01 ) ? 0 : 1; - } else if( if1_ula.net_state == 0x0208 ) { - if1_ula.net_data &= 0xff; - if1_ula.net_state++; /* OK, now we get data bytes... */ - -/* lseek( if1_ula.fd_net, 0, SEEK_SET ); start a packet */ - /* first we send the station number */ - do ; while( write( if1_ula.fd_net, &if1_ula.net_data, 1 ) == -1 ); -#ifdef HAVE_FSYNC - fsync( if1_ula.fd_net ); -#endif /* #ifdef HAVE_FSYNC */ -#ifdef IF1_DEBUG_NET - fprintf( stderr, "SC-OUT send network number: %d\n", - if1_ula.net_data ^ 0xff ); -#endif - } else if( if1_ula.net_state > 192 && if1_ula.net_state < 0x0200 && - ( ( val & 0x01 ) == 0 ) ) { - /* NET-STATE ask as many times.... and now send a 0 */ -/* if1_ula.net = 1; */ - if1_ula.net_state = 0x0200; /* Send the station number */ - } - if1_ula.net = ( val & 0x01 ) ? 0 : 1; /* set net wire? */ - } - } - microdrives_restart(); -} - -void -if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val ) -{ - if( !if1_active ) return; - -#ifdef IF1_DEBUG_NET_1 - fprintf( stderr, "In if1_port_out( %%%d%d%d%d%d%d%d%d => 0x%04x ).\n", - !!(val & 128), !!(val & 64), !!(val & 32), !!(val & 16), - !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port); -#endif - - switch( decode_port( port ) ) { - case PORT_MDR: port_mdr_out( val ); break; - case PORT_CTR: port_ctr_out( val ); break; - case PORT_NET: port_net_out( val ); break; - case PORT_UNKNOWN: break; - } -} - -static void -increment_head( int m ) -{ - microdrive[m].head_pos++; - if( microdrive[m].head_pos >= - libspectrum_microdrive_cartridge_len( microdrive[m].cartridge ) * - LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) - microdrive[m].head_pos = 0; -} - -static void -microdrives_restart( void ) -{ - int m; - - for( m = 0; m < 8; m++ ) { - while( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != 0 && - ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) != LIBSPECTRUM_MICRODRIVE_HEAD_LEN ) - increment_head( m ); /* put head in the start of a block */ - - microdrive[m].transfered = 0; /* reset current number of bytes written */ - - if( ( microdrive[m].head_pos % LIBSPECTRUM_MICRODRIVE_BLOCK_LEN ) == 0 ) { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN; /* up to 15 bytes for header blocks */ - } else { - microdrive[m].max_bytes = LIBSPECTRUM_MICRODRIVE_HEAD_LEN + LIBSPECTRUM_MICRODRIVE_DATA_LEN + 1; /* up to 528 bytes for data blocks */ - } - } -} - -void -if1_mdr_writeprotect( int drive, int wrprot ) -{ - libspectrum_microdrive_set_write_protect( microdrive[drive].cartridge, - wrprot ? 1 : 0 ); - microdrive[drive].modified = 1; - - update_menu( UMENU_MDRV1 + drive ); -} - -static void -if1_mdr_new( microdrive_t *mdr ) -{ - libspectrum_byte len; - long int i; - - mdr->filename = NULL; - if( settings_current.mdr_random_len ) { /* Random length */ - len = 171 + ( ( rand() >> 2 ) + ( rand() >> 2 ) + - ( rand() >> 2 ) + ( rand() >> 2 ) ) - / rnd_factor; - } else - len = settings_current.mdr_len = settings_current.mdr_len < 10 ? 10 : - settings_current.mdr_len > LIBSPECTRUM_MICRODRIVE_BLOCK_MAX ? LIBSPECTRUM_MICRODRIVE_BLOCK_MAX : settings_current.mdr_len; - - /* Erase the entire cartridge */ - libspectrum_microdrive_set_cartridge_len( mdr->cartridge, len ); - - for( i = 0; i < len * LIBSPECTRUM_MICRODRIVE_BLOCK_LEN; i++ ) - libspectrum_microdrive_set_data( mdr->cartridge, i, 0xff ); - - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_NO; - - /* but don't write-protect */ - libspectrum_microdrive_set_write_protect( mdr->cartridge, 0 ); - - mdr->inserted = 1; - mdr->modified = 1; - -} - -int -if1_mdr_insert( int which, const char *filename ) -{ - microdrive_t *mdr; - int m, i; - - if( which == -1 ) { /* find an empty one */ - for( m = 0; m < 8; m++ ) { - if( !microdrive[m].inserted ) { - which = m; - break; - } - } - } - - if( which == -1 ) { - ui_error( UI_ERROR_ERROR, - "Cannot insert cartridge '%s', all Microdrives in use", - filename ); - return 1; - } - - if( which >= 8 ) { - ui_error( UI_ERROR_ERROR, "if1_mdr_insert: unknown drive %d", which ); - return 1; - } - - mdr = µdrive[ which ]; - - /* Eject any cartridge already in the drive */ - if( mdr->inserted ) { - /* Abort the insert if we want to keep the current cartridge */ - if( if1_mdr_eject( which, 0 ) ) return 0; - } - - if( filename == NULL ) { /* insert new unformatted cartridge */ - if1_mdr_new( mdr ); - update_menu( UMENU_MDRV1 + which ); - return 0; - } - - if( utils_read_file( filename, &mdr->file ) ) { - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( libspectrum_microdrive_mdr_read( mdr->cartridge, mdr->file.buffer, - mdr->file.length ) ) { - utils_close_file( &mdr->file ); - ui_error( UI_ERROR_ERROR, "Failed to open cartridge image" ); - return 1; - } - - if( utils_close_file( &mdr->file ) ) return 1; - - mdr->inserted = 1; - mdr->modified = 0; - mdr->filename = strdup( filename ); - /* we assume formatted cartridges */ - for( i = libspectrum_microdrive_cartridge_len( mdr->cartridge ); - i > 0; i-- ) - mdr->pream[255 + i] = mdr->pream[i-1] = SYNC_OK; - - update_menu( UMENU_MDRV1 + which ); - - return 0; -} - -int -if1_mdr_eject( int which, int saveas ) -{ - microdrive_t *mdr; - - if( which >= 8 ) - return 1; - - mdr = µdrive[ which ]; - - if( !mdr->inserted ) - return 0; - - if( saveas ) { /* 1 -> save as.., 2 -> save */ - - if( mdr->filename == NULL ) saveas = 1; - if( ui_mdr_write( which, 2 - saveas ) ) return 1; - mdr->modified = 0; - return 0; - - } else { - - if( mdr->modified ) { - - ui_confirm_save_t confirm = ui_confirm_save( - "Cartridge in Microdrive %i has been modified.\n" - "Do you want to save it?", - which + 1 - ); - - switch( confirm ) { - - case UI_CONFIRM_SAVE_SAVE: - if( if1_mdr_eject( which, 2 ) ) return 1; /* first save */ - break; - - case UI_CONFIRM_SAVE_DONTSAVE: break; - case UI_CONFIRM_SAVE_CANCEL: return 1; - - } - } - } - - mdr->inserted = 0; - if( mdr->filename != NULL ) { - free( mdr->filename ); - mdr->filename = NULL; - } - - update_menu( UMENU_MDRV1 + which ); - return 0; -} - -int -if1_mdr_write( int which, const char *filename ) -{ - microdrive_t *mdr = µdrive[which]; - - libspectrum_microdrive_mdr_write( mdr->cartridge, &mdr->file.buffer, - &mdr->file.length ); - - if( filename == NULL ) filename = mdr->filename; /* Write over the original file */ - - if( utils_write_file( filename, mdr->file.buffer, mdr->file.length ) ) - return 1; - - if( mdr->filename && strcmp( filename, mdr->filename ) ) { - free( mdr->filename ); - mdr->filename = strdup( filename ); - } - return 0; -} - -#ifndef O_NONBLOCK -#define O_NONBLOCK FNDELAY -#endif - -void -if1_plug( const char *filename, int what ) -{ -#ifdef WIN32 - ui_error( UI_ERROR_ERROR, "Not yet implemented on Win32" ); - return; -#else - int fd = -1; - - switch( what ) { - case 1: - if( if1_ula.fd_r >= 0 ) - close( if1_ula.fd_r ); - fd = if1_ula.fd_r = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_RDONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_RDONLY on '%s': %s", - filename, strerror( errno ) ); - if1_ula.rs232_buffer = 0x100; /* buffer is empty */ - break; - case 2: - if( if1_ula.fd_t >= 0 ) - close( if1_ula.fd_t ); - fd = if1_ula.fd_t = open( filename, O_RDWR | O_NONBLOCK ); - if( fcntl( fd, F_SETFL, O_WRONLY | O_NONBLOCK ) ) - ui_error( UI_ERROR_ERROR, "Cannot set O_WRONLY on '%s': %s", - filename, strerror( errno ) ); - break; - case 3: - if( if1_ula.fd_net >= 0 ) - close( if1_ula.fd_net ); - fd = if1_ula.fd_net = open( filename, O_RDWR | O_NONBLOCK ); - break; - } - - /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ - if( !settings_current.rs232_handshake && - if1_ula.fd_t != -1 && if1_ula.fd_r != -1 ) - if1_ula.dtr = 1; - - if( fd < 0 ) { - ui_error( UI_ERROR_ERROR, "Error opening '%s': %s", - filename, strerror( errno ) ); - return; - } - - if1_ula.s_net_mode = settings_current.raw_s_net ? 0 : 1; - update_menu( UMENU_RS232 ); -#endif -} - -void -if1_unplug( int what ) -{ - switch( what ) { - case 1: - if( if1_ula.fd_r >= 0 ) - close( if1_ula.fd_r ); - if1_ula.fd_r = -1; - break; - case 2: - if( if1_ula.fd_t >= 0 ) - close( if1_ula.fd_t ); - if1_ula.fd_t = -1; - if1_ula.dtr = 0; - break; - case 3: - if( if1_ula.fd_net >= 0 ) - close( if1_ula.fd_net ); - if1_ula.fd_net = -1; - break; - } - /* rs232_handshake == 0 -> we assume DTR(DSR) always 1 if tx and rx plugged */ - if( !settings_current.rs232_handshake && - ( if1_ula.fd_t == -1 || if1_ula.fd_r == -1 ) ) - if1_ula.dtr = 0; - update_menu( UMENU_RS232 ); -} Deleted: vendor/fuse-emulator/current/fuse/if1.h =================================================================== --- vendor/fuse-emulator/current/fuse/if1.h 2012-01-14 13:01:10 UTC (rev 683) +++ vendor/fuse-emulator/current/fuse/if1.h 2012-02-15 12:32:32 UTC (rev 684) @@ -1,59 +0,0 @@ -/* if1.h: Interface I handling routines - Copyright (c) 2004-2005 Gergely Szasz, Philip Kendall - - $Id: if1.h 3327 2007-11-22 23:06:47Z 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: - - Gergely: sz...@hu... - -*/ - -#ifndef FUSE_IF1_H -#define FUSE_IF1_H - -#include <libspectrum.h> - -#include "periph.h" - -/* IF1 */ -extern int if1_active; -extern int if1_available; - -extern const periph_t if1_peripherals[]; -extern const size_t if1_peripherals_count; - -int if1_init( void ); -libspectrum_error if1_end( void ); - -void if1_page( void ); -void if1_unpage( void ); -void if1_memory_map( void ); - -void if1_port_out( libspectrum_word port, libspectrum_byte val ); -libspectrum_byte if1_port_in( lib... [truncated message content] |
From: <fr...@us...> - 2013-06-01 03:20:50
|
Revision: 760 http://sourceforge.net/p/fuse-for-macosx/code/760 Author: fredm Date: 2013-06-01 03:20:47 +0000 (Sat, 01 Jun 2013) Log Message: ----------- Load . into vendor/fuse-emulator/current. Modified Paths: -------------- vendor/fuse-emulator/current/fuse/Makefile.am vendor/fuse-emulator/current/fuse/hacking/ChangeLog vendor/fuse-emulator/current/fuse/man/fuse.1 vendor/fuse-emulator/current/fuse/pokefinder/pokemem.c vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in Modified: vendor/fuse-emulator/current/fuse/Makefile.am =================================================================== --- vendor/fuse-emulator/current/fuse/Makefile.am 2013-05-26 12:20:07 UTC (rev 759) +++ vendor/fuse-emulator/current/fuse/Makefile.am 2013-06-01 03:20:47 UTC (rev 760) @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in ## Copyright (c) 1999-2009 Philip Kendall -## $Id: Makefile.am 4980 2013-05-21 12:37:51Z fredm $ +## $Id: Makefile.am 5003 2013-05-26 16:24:03Z sbaldovi $ ## 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 @@ -244,7 +244,7 @@ cp $(top_builddir)/.libs/fuse$(EXEEXT) $(DESTDIR) || \ cp $(top_builddir)/fuse$(EXEEXT) $(DESTDIR) # Get text files - for file in AUTHORS COPYING README; \ + for file in AUTHORS ChangeLog COPYING README; \ do cp "$(top_srcdir)/$$file" "$(DESTDIR)/$$file.txt"; \ done # Get manuals Modified: vendor/fuse-emulator/current/fuse/hacking/ChangeLog =================================================================== --- vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2013-05-26 12:20:07 UTC (rev 759) +++ vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2013-06-01 03:20:47 UTC (rev 760) @@ -4518,3 +4518,13 @@ 20130524 ChangeLog,README: updates for a "1.1.1" release (Fred). 20130524 ChangeLog,README,configure.ac,man/fuse.1: fill in date and bump version number (Stuart). +20130526 Makefile.am,ui/win32/installer/fuse.nsi.in: distribute ChangeLog and + build notes in Windows packages (Sergio). +20130527 pokefinder/pokemem.c: fix crash when opening a file without extension + (patch #312) (UB880D and Sergio). +20130531 man/fuse.1: correct Spectranet initialisation script (thanks, Guesser) + (Fred). +20130531 man/fuse.1: add missing documentation (fixes bug #282) (Stuart). +20130531 ui/win32/installer/fuse.nsi.in: adding Fuse to the OpenWith list for + file extensions could result in an true association under some + circumstances on Windows 7 (thanks, Alessandro Grussu) (Sergio). Modified: vendor/fuse-emulator/current/fuse/man/fuse.1 =================================================================== --- vendor/fuse-emulator/current/fuse/man/fuse.1 2013-05-26 12:20:07 UTC (rev 759) +++ vendor/fuse-emulator/current/fuse/man/fuse.1 2013-06-01 03:20:47 UTC (rev 760) @@ -1988,6 +1988,13 @@ you wish to stop the tape at a specific point. .RE .PP +.I "Accelerate loaders" +.RS +If this option is enabled, then Fuse will attempt to accelerate tape +loaders by \(lqshort circuiting\(rq the loading loop. This will in +general speed up loading, but may cause some loaders to fail. +.RE +.PP .I "Detect loaders" .RS If this option is enabled, Fuse will attempt to detect when a loading @@ -2046,6 +2053,14 @@ If the value smaller than 4 or greater than 254 Fuse assumes 4 or 254. .RE .PP +.I "Random length MDR cartridge" +.RS +If this option is enabled, Fuse will use a random Microdrive cartridge +length instead of the length specified in the +.I "MDR cartridge len" +option. +.RE +.PP .I "RS-232 handshake" .RS If you turn this option off, Fuse assumes the RS-232 line other end is @@ -2211,6 +2226,12 @@ connected mouse may be used. .RE .PP +.I "Swap mouse buttons" +.RS +If this option is enabled, the left and right mouse buttons will be swapped +when emulating a Kempston mouse. +.RE +.PP .I "Fuller Box" .RS If this option is selected, Fuse will emulate a Fuller Box AY sound and @@ -2365,14 +2386,6 @@ section for more details. .RE .PP -.I "Opus Discovery interface" -.RS -If this option is selected, Fuse will emulate the Opus Discovery interface. -See the -.B "OPUS DISCOVERY EMULATION" -section for more details. -.RE -.PP .I "+D interface" .RS If this option is selected, Fuse will emulate the +D interface. See the @@ -2395,8 +2408,22 @@ section for more details. Beta\ 128 emulation is enabled for the Pentagon and Scorpion machines regardless of this option. .RE +.PP +.I "Beta\ 128 auto-boot in 48K\ machines" +.RS +If this option is selected, then when a Beta\ 128 interface is used in 48K +or TC2048 emulation, the machine will boot directly into the TR-DOS system. .RE .PP +.I "Opus Discovery interface" +.RS +If this option is selected, Fuse will emulate the Opus Discovery interface. +See the +.B "OPUS DISCOVERY EMULATION" +section for more details. +.RE +.RE +.PP .I "Options, RZX..." .RS Display the RZX Options dialog, letting you configure how Fuse's deals @@ -3740,11 +3767,7 @@ starting with \(lqAlioth Spectranet\(rq and ending with the Spectranet's IP address (which will be 255.255.255.255 at this stage). .PP -If you see all that, type the following command: -.PP -%cfgnew -.PP -Which will show the standard 0 OK, 0:1 at the bottom of the screen. Now trigger an NMI (the Machine / NMI menu option) +Now trigger an NMI (the Machine / NMI menu option) and you should get a white on blue Spectranet NMI menu with five options. .PP @@ -3798,7 +3821,17 @@ .PP If everything looks correct, select [I] Save changes and exit (you'll see a brief \(lqSaving configuration...\(rq message) followed by [E] Exit, -at which point you'll be returned to BASIC. Reset the Spectrum again +at which point you'll be returned to BASIC. +.PP +Now type the following commands: +.PP +%cfgnew +.br +%cfgcommit +.PP +Which will show the standard 0 OK, 0:1 at the bottom of the screen. +.PP +Reset the Spectrum again and you'll see the same four line status display, but this time with your IP address on the last line. .PP Modified: vendor/fuse-emulator/current/fuse/pokefinder/pokemem.c =================================================================== --- vendor/fuse-emulator/current/fuse/pokefinder/pokemem.c 2013-05-26 12:20:07 UTC (rev 759) +++ vendor/fuse-emulator/current/fuse/pokefinder/pokemem.c 2013-06-01 03:20:47 UTC (rev 760) @@ -1,7 +1,7 @@ /* pokemem.c: help with handling pokes Copyright (c) 2011 Philip Kendall, Sergio Baldoví - $Id: pokemem.c 4785 2012-12-07 23:56:40Z sbaldovi $ + $Id: pokemem.c 5005 2013-05-29 21:17:26Z 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 @@ -487,8 +487,8 @@ int pokemem_find_pokfile( const char *path ) { - int n, has_extension; - size_t length, filename_size, last_dot, last_slash; + int n, has_extension, last_dot, last_slash; + size_t length, filename_size; char *test_file, *c; if( pokfile ) return 1; /* Previous .pok file already found */ @@ -507,7 +507,7 @@ c = strrchr( test_file, '.' ); last_dot = ( c )? c - test_file : -1; - has_extension = ( last_dot > last_slash ); + has_extension = ( last_dot > last_slash + 1 ); /* Try .pok extension */ if( has_extension ) { @@ -532,15 +532,16 @@ } /* Browse POKES/ directory */ - if( last_slash ) { + if( last_slash >= 0 ) { n = last_slash + 1; /* insert directory */ - filename_size = ( has_extension )? last_dot - last_slash - 1 : - strlen( &path[n] ); + filename_size = + ( has_extension )? (unsigned int) ( last_dot - last_slash - 1 ) : + strlen( &path[n] ); test_file[ n ] = '\0'; strncat( test_file, "POKES", 5 ); } else { n = 0; /* prepend directory */ - filename_size = ( has_extension )? last_dot : length; + filename_size = ( has_extension )? (unsigned int) last_dot : length; strncpy( test_file, "POKES", 5 ); test_file[ 5 ] = '\0'; } Modified: vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in =================================================================== --- vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in 2013-05-26 12:20:07 UTC (rev 759) +++ vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in 2013-06-01 03:20:47 UTC (rev 760) @@ -1,7 +1,7 @@ ## NSIS (nsis.sf.net) script to produce installer for win32 platform ## Copyright (c) 2009 Marek Januszewski -## $Id: fuse.nsi.in 4775 2012-11-26 23:03:36Z sbaldovi $ +## $Id: fuse.nsi.in 5010 2013-05-31 18:32:45Z sbaldovi $ ## 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 @@ -116,10 +116,6 @@ ${CallArtificialFunction} UnRegisterExtension_ !macroend -!macro AddOpenWithListCall _EXTENSION - WriteRegStr HKLM "Software\Classes\${_EXTENSION}\OpenWithProgids" "${PROG_ID}" "" -!macroend - !macro SelectUnregisteredExt_ Exch $R1 ;section Exch @@ -146,6 +142,9 @@ Exch $R0 ;extension Push $0 + ; Recommend Fuse in the Open With list + WriteRegStr HKLM "Software\Classes\$R0\OpenWithProgids" "${PROG_ID}" "" + ; Read global file association ReadRegStr $0 HKLM "Software\Classes\$R0" "" StrCmp "$0" "" NoBackup ; is it empty @@ -211,7 +210,6 @@ !define SelectUnregisteredExt `!insertmacro SelectUnregisteredExtCall` !define RegisterExtension `!insertmacro RegisterExtensionCall` !define UnRegisterExtension `!insertmacro UnRegisterExtensionCall` -!define AddOpenWithList `!insertmacro AddOpenWithListCall` ;-------------------------------- ; Uninstall previous version @@ -246,10 +244,12 @@ ; Installation files File "AUTHORS.txt" + File "ChangeLog.txt" File "COPYING.txt" File "fuse.exe" File "fuse.html" File "README.txt" + File /nonfatal "README-win32.txt" File "*.dll" SetOutPath $INSTDIR\lib File "lib\*" @@ -303,14 +303,6 @@ WriteRegStr HKLM "Software\Classes\${PROG_ID}\shell\open\command" "" '"$INSTDIR\fuse.exe" "%1"' WriteRegStr HKLM "Software\Classes\Applications\fuse.exe" "NoOpenWith" "" - ; Recommend Fuse for known extensions - ${AddOpenWithList} ".pzx" - ${AddOpenWithList} ".rzx" - ${AddOpenWithList} ".sna" - ${AddOpenWithList} ".szx" - ${AddOpenWithList} ".tap" - ${AddOpenWithList} ".tzx" - ${AddOpenWithList} ".z80" System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' SectionEnd @@ -362,10 +354,12 @@ Delete "$INSTDIR\roms\*" RMDir "$INSTDIR\roms" Delete "$INSTDIR\AUTHORS.txt" + Delete "$INSTDIR\ChangeLog.txt" Delete "$INSTDIR\COPYING.txt" Delete "$INSTDIR\fuse.exe" Delete "$INSTDIR\fuse.html" Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\README-win32.txt" Delete "$INSTDIR\*.dll" RMDir "$INSTDIR" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fr...@us...> - 2016-05-24 14:04:18
|
Revision: 795 http://sourceforge.net/p/fuse-for-macosx/code/795 Author: fredm Date: 2016-05-24 14:04:16 +0000 (Tue, 24 May 2016) Log Message: ----------- To prepare to load . into vendor/fuse-emulator/current, perform 3 renames. * vendor/fuse-emulator/current/fuse/data/win32/fuse.manifest.in: Renamed from vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in. * vendor/fuse-emulator/current/fuse/data/win32/installer.nsi.in: Renamed from vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in. * vendor/fuse-emulator/current/fuse/data/win32/winfuse.ico: Renamed from vendor/fuse-emulator/current/fuse/winfuse.ico. Added Paths: ----------- vendor/fuse-emulator/current/fuse/data/win32/ vendor/fuse-emulator/current/fuse/data/win32/fuse.manifest.in vendor/fuse-emulator/current/fuse/data/win32/installer.nsi.in vendor/fuse-emulator/current/fuse/data/win32/winfuse.ico Removed Paths: ------------- vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in vendor/fuse-emulator/current/fuse/winfuse.ico Copied: vendor/fuse-emulator/current/fuse/data/win32/fuse.manifest.in (from rev 794, vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in) =================================================================== --- vendor/fuse-emulator/current/fuse/data/win32/fuse.manifest.in (rev 0) +++ vendor/fuse-emulator/current/fuse/data/win32/fuse.manifest.in 2016-05-24 14:04:16 UTC (rev 795) @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="@FUSE_FULL_VERSION@" + processorArchitecture="*" + name="fuse.exe" + type="win32" +/> +<description>Fuse (Free Unix Spectrum Emulator)</description> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.Windows.Common-Controls" + version="6.0.0.0" + processorArchitecture="*" + publicKeyToken="6595b64144ccf1df" + language="*" + /> + </dependentAssembly> +</dependency> +</assembly> Copied: vendor/fuse-emulator/current/fuse/data/win32/installer.nsi.in (from rev 794, vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in) =================================================================== --- vendor/fuse-emulator/current/fuse/data/win32/installer.nsi.in (rev 0) +++ vendor/fuse-emulator/current/fuse/data/win32/installer.nsi.in 2016-05-24 14:04:16 UTC (rev 795) @@ -0,0 +1,384 @@ +## NSIS (nsis.sf.net) script to produce installer for win32 platform +## Copyright (c) 2009 Marek Januszewski + +## $Id: fuse.nsi.in 5010 2013-05-31 18:32:45Z sbaldovi $ + +## 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... + +!define FUSE_VERSION "@PACKAGE_VERSION@" ; could have letters like -RC1 +!define FUSE_FULL_VERSION "@FUSE_FULL_VERSION@" ; must have four numeric tokens +!define DISPLAY_NAME "Free Unix Spectrum Emulator (Fuse) ${FUSE_VERSION}" +!define SETUP_FILENAME "@PACKAGE@-${FUSE_VERSION}-win32-setup" +!define SETUP_FILE "${SETUP_FILENAME}.exe" +!define HKLM_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Fuse" +!define PROG_ID "Fuse.Files.1" + +;Include Modern UI +!include "MUI2.nsh" +!include "Sections.nsh" +!include "Util.nsh" + +;-------------------------------- +;General + +Name "${DISPLAY_NAME}" +outFile "${SETUP_FILE}" +Caption "${DISPLAY_NAME}" + +installDir "$PROGRAMFILES\Fuse" + +; [Additional Installer Settings ] +XPStyle on +SetCompress force +SetCompressor lzma + +;-------------------------------- +;Interface Settings + + !define MUI_ABORTWARNING + +;-------------------------------- +;Pages + + !insertmacro MUI_PAGE_LICENSE "COPYING.txt" + !define MUI_COMPONENTSPAGE_SMALLDESC + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + !insertmacro MUI_PAGE_INSTFILES + !define MUI_FINISHPAGE_RUN "$INSTDIR\fuse.exe" + !define MUI_FINISHPAGE_NOREBOOTSUPPORT + !insertmacro MUI_PAGE_FINISH + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + !define MUI_FINISHPAGE_SHOWREADME_CHECKED + !define MUI_FINISHPAGE_SHOWREADME "" + !define MUI_FINISHPAGE_SHOWREADME_TEXT "Delete configuration file" + !define MUI_FINISHPAGE_SHOWREADME_FUNCTION un.DeleteConfigFile + !insertmacro MUI_UNPAGE_FINISH + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Version Information + + VIProductVersion ${FUSE_FULL_VERSION} + VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "" + VIAddVersionKey /LANG=${LANG_ENGLISH} "InternalName" "${SETUP_FILENAME}" + VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "@FUSE_COPYRIGHT@" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Fuse" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${FUSE_VERSION}" + VIAddVersionKey /LANG=${LANG_ENGLISH} "OriginalFilename" "${SETUP_FILE}" + VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Fuse - the Free Unix Spectrum Emulator" + VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "${FUSE_VERSION}" + +;-------------------------------- +;File association functions + +!macro SelectUnregisteredExtCall _EXTENSION _SECTION + Push `${_EXTENSION}` + Push `${_SECTION}` + ${CallArtificialFunction} SelectUnregisteredExt_ +!macroend + +!macro NewSecExtensionCall _EXTENSION _DESCRIPTION + Section /o "${_DESCRIPTION} File" SEC_${_DESCRIPTION} + ${registerExtension} "${_EXTENSION}" + SectionEnd +!macroend + +!macro RegisterExtensionCall _EXTENSION + Push `${_EXTENSION}` + ${CallArtificialFunction} RegisterExtension_ +!macroend + +!macro UnRegisterExtensionCall _EXTENSION + Push "${_EXTENSION}" + ${CallArtificialFunction} UnRegisterExtension_ +!macroend + +!macro SelectUnregisteredExt_ + Exch $R1 ;section + Exch + Exch $R0 ;extension + Exch + Push $0 + + ReadRegStr $0 HKLM "Software\Classes\$R0" "" + ;Select if already associated with FUSE, i.e., reinstallation + StrCmp $0 "${PROG_ID}" Select 0 + ;Select if available + StrCmp $0 "" Select NoSelect + +Select: + !insertmacro SelectSection $R1 + +NoSelect: + Pop $0 + Pop $R1 + Pop $R0 +!macroend + +!macro RegisterExtension_ + Exch $R0 ;extension + Push $0 + + ; Recommend Fuse in the Open With list + WriteRegStr HKLM "Software\Classes\$R0\OpenWithProgids" "${PROG_ID}" "" + + ; Read global file association + ReadRegStr $0 HKLM "Software\Classes\$R0" "" + StrCmp "$0" "" NoBackup ; is it empty + StrCmp "$0" "${PROG_ID}" NoBackup ; is it our own + ; Backup current value + WriteRegStr HKLM "Software\Classes\$R0" "backup_val" "$0" + +NoBackup: + ; Set global file association + WriteRegStr HKLM "Software\Classes\$R0" "" "${PROG_ID}" + + ; Set current user (custom) file association + ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" + StrCmp "$0" "" NoLocalBackup ; is it empty + StrCmp "$0" "${PROG_ID}" NoLocalBackup ; is it our own + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" "$0" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" "${PROG_ID}" + +NoLocalBackup: + Pop $0 + Pop $R0 +!macroend + +!macro UnRegisterExtension_ + Exch $R0 ;extension + Push $0 + + ; Unregister OpenWith recommendation + DeleteRegValue HKLM "Software\Classes\$R0\OpenWithProgids" "${PROG_ID}" + + ; Try to delete current file association + ReadRegStr $0 HKLM "Software\Classes\$R0" "" + StrCmp $0 ${PROG_ID} 0 NoOwn ; only do this if we own it + ReadRegStr $0 HKLM "Software\Classes\$R0" "backup_val" + StrCmp $0 "" 0 Restore ; if backup="" then delete the whole key + DeleteRegKey HKLM "Software\Classes\$R0" + Goto NoOwn + +Restore: + WriteRegStr HKLM "Software\Classes\$R0" "" $0 + DeleteRegValue HKLM "Software\Classes\$R0" "backup_val" + +NoOwn: + ; Delete programmatic identifier + DeleteRegKey HKLM "Software\Classes\${PROG_ID}"; + + ; Delete current user (custom) file association + ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" + StrCmp "$0" "" NoLocalRestore ; is it empty + StrCmp "$0" "${PROG_ID}" 0 NoLocalRestore ; is it our own + ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" + StrCmp "$0" "" 0 +2 ; if no backup -> delete + DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" "$0" + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" + +NoLocalRestore: + Pop $0 + Pop $R0 +!macroend + +!define NewSecExtension `!insertmacro NewSecExtensionCall` +!define SelectUnregisteredExt `!insertmacro SelectUnregisteredExtCall` +!define RegisterExtension `!insertmacro RegisterExtensionCall` +!define UnRegisterExtension `!insertmacro UnRegisterExtensionCall` + +;-------------------------------- +; Uninstall previous version + + Section "" SecUninstallPrevious + + Push $R0 + ReadRegStr $R0 HKLM "${HKLM_REG_KEY}" "UninstallString" + + ; Check if we are upgrading a previous installation + ${If} $R0 == '"$INSTDIR\uninstall.exe"' + DetailPrint "Removing previous installation..." + + ; Run the uninstaller silently + ExecWait '"$INSTDIR\uninstall.exe" /S _?=$INSTDIR' + ${EndIf} + + Pop $R0 + +SectionEnd + +;-------------------------------- +; start default section + +section "!Fuse Core Files (required)" SecCore + + SectionIn RO + DetailPrint "Installing Fuse Core Files..." + + ; set the installation directory as the destination for the following actions + setOutPath "$INSTDIR" + + ; Installation files + File "AUTHORS.txt" + File "ChangeLog.txt" + File "COPYING.txt" + File "fuse.exe" + File "fuse.html" + File "README.txt" + File /nonfatal "README-win32.txt" + File "*.dll" + SetOutPath $INSTDIR\lib + File "lib\*" + SetOutPath "$INSTDIR\roms" + File "roms\*" + + ; create the uninstaller + writeUninstaller "$INSTDIR\uninstall.exe" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "${HKLM_REG_KEY}" "DisplayName" "${DISPLAY_NAME}" + WriteRegStr HKLM "${HKLM_REG_KEY}" "DisplayVersion" "${FUSE_VERSION}" + WriteRegStr HKLM "${HKLM_REG_KEY}" "HelpLink" "@PACKAGE_URL@" + WriteRegStr HKLM "${HKLM_REG_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "${HKLM_REG_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${HKLM_REG_KEY}" "NoRepair" 1 + +sectionEnd + +;-------------------------------- +; Create shortcuts + +section "Start Menu and Desktop links" SecShortcuts + + DetailPrint "Creating Shortcuts..." + CreateDirectory "$SMPROGRAMS\Fuse" + CreateShortCut "$SMPROGRAMS\Fuse\Fuse.lnk" "$INSTDIR\fuse.exe" + CreateShortCut "$SMPROGRAMS\Fuse\Manual.lnk" "$INSTDIR\fuse.html" + CreateShortCut "$SMPROGRAMS\Fuse\Readme.lnk" "$INSTDIR\README.txt" + CreateShortCut "$SMPROGRAMS\Fuse\Uninstall.lnk" "$INSTDIR\uninstall.exe" + CreateShortCut "$DESKTOP\Fuse.lnk" "$INSTDIR\fuse.exe" + +sectionEnd + +;-------------------------------- +; Register common file extensions + +SectionGroup /e "Register File Extensions" SecFileExt + ${NewSecExtension} ".pzx" "PZX" + ${NewSecExtension} ".rzx" "RZX" + ${NewSecExtension} ".sna" "SNA" + ${NewSecExtension} ".szx" "SZX" + ${NewSecExtension} ".tap" "TAP" + ${NewSecExtension} ".tzx" "TZX" + ${NewSecExtension} ".z80" "Z80" +SectionGroupEnd + +Section "-Register Application" + WriteRegStr HKLM "Software\Classes\${PROG_ID}\shell" "" "open" + WriteRegStr HKLM "Software\Classes\${PROG_ID}\DefaultIcon" "" "$INSTDIR\fuse.exe,0" + WriteRegStr HKLM "Software\Classes\${PROG_ID}\shell\open\command" "" '"$INSTDIR\fuse.exe" "%1"' + WriteRegStr HKLM "Software\Classes\Applications\fuse.exe" "NoOpenWith" "" + + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' +SectionEnd + +Function .onInit + ; Select extensions not associated with other applications + ${SelectUnregisteredExt} ".pzx" ${SEC_PZX} + ${SelectUnregisteredExt} ".rzx" ${SEC_RZX} + ${SelectUnregisteredExt} ".sna" ${SEC_SNA} + ${SelectUnregisteredExt} ".szx" ${SEC_SZX} + ${SelectUnregisteredExt} ".tap" ${SEC_TAP} + ${SelectUnregisteredExt} ".tzx" ${SEC_TZX} + ${SelectUnregisteredExt} ".z80" ${SEC_Z80} +FunctionEnd + +;-------------------------------- +; uninstaller section start + +section "uninstall" + + ; Unregister file extensions association (if owned) + DetailPrint "Deleting Registry Keys..." + ${unregisterExtension} ".pzx" + ${unregisterExtension} ".rzx" + ${unregisterExtension} ".sna" + ${unregisterExtension} ".szx" + ${unregisterExtension} ".tap" + ${unregisterExtension} ".tzx" + ${unregisterExtension} ".z80" + + ; Unregister Application + DeleteRegKey HKLM "Software\Classes\${PROG_ID}" + DeleteRegKey HKLM "Software\Classes\Applications\fuse.exe" + + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' + + ; Delete the links + DetailPrint "Deleting Shortcuts..." + Delete "$SMPROGRAMS\Fuse\Fuse.lnk" + Delete "$SMPROGRAMS\Fuse\Manual.lnk" + Delete "$SMPROGRAMS\Fuse\Readme.lnk" + Delete "$SMPROGRAMS\Fuse\Uninstall.lnk" + RMDir "$SMPROGRAMS\Fuse" + Delete "$DESKTOP\Fuse.lnk" + + ; Installation files + DetailPrint "Deleting Files..." + Delete "$INSTDIR\lib\*" + RMDir "$INSTDIR\lib" + Delete "$INSTDIR\roms\*" + RMDir "$INSTDIR\roms" + Delete "$INSTDIR\AUTHORS.txt" + Delete "$INSTDIR\ChangeLog.txt" + Delete "$INSTDIR\COPYING.txt" + Delete "$INSTDIR\fuse.exe" + Delete "$INSTDIR\fuse.html" + Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\README-win32.txt" + Delete "$INSTDIR\*.dll" + RMDir "$INSTDIR" + + ; Delete the uninstaller and remove the uninstall keys for Windows + DetailPrint "Deleting Uninstaller..." + Delete "$INSTDIR\uninstall.exe" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Fuse" + +sectionEnd + +Function un.DeleteConfigFile + Delete "$PROFILE\fuse.cfg" +FunctionEnd + +;-------------------------------- +;Descriptions + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "The core files required to use Fuse (program, libraries, ROMs, etc.)" + !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} "Adds icons to your start menu and your desktop for easy access" + !insertmacro MUI_DESCRIPTION_TEXT ${SecFileExt} "Register common file extensions with Fuse: pzx, rzx, sna, szx, tap, tzx and z80" +!insertmacro MUI_FUNCTION_DESCRIPTION_END Copied: vendor/fuse-emulator/current/fuse/data/win32/winfuse.ico (from rev 794, vendor/fuse-emulator/current/fuse/winfuse.ico) =================================================================== (Binary files differ) Deleted: vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in =================================================================== --- vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in 2016-05-24 11:04:28 UTC (rev 794) +++ vendor/fuse-emulator/current/fuse/ui/win32/fuse.manifest.in 2016-05-24 14:04:16 UTC (rev 795) @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> -<assemblyIdentity - version="@FUSE_FULL_VERSION@" - processorArchitecture="*" - name="fuse.exe" - type="win32" -/> -<description>Fuse (Free Unix Spectrum Emulator)</description> -<dependency> - <dependentAssembly> - <assemblyIdentity - type="win32" - name="Microsoft.Windows.Common-Controls" - version="6.0.0.0" - processorArchitecture="*" - publicKeyToken="6595b64144ccf1df" - language="*" - /> - </dependentAssembly> -</dependency> -</assembly> Deleted: vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in =================================================================== --- vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in 2016-05-24 11:04:28 UTC (rev 794) +++ vendor/fuse-emulator/current/fuse/ui/win32/installer/fuse.nsi.in 2016-05-24 14:04:16 UTC (rev 795) @@ -1,384 +0,0 @@ -## NSIS (nsis.sf.net) script to produce installer for win32 platform -## Copyright (c) 2009 Marek Januszewski - -## $Id: fuse.nsi.in 5010 2013-05-31 18:32:45Z sbaldovi $ - -## 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... - -!define FUSE_VERSION "@PACKAGE_VERSION@" ; could have letters like -RC1 -!define FUSE_FULL_VERSION "@FUSE_FULL_VERSION@" ; must have four numeric tokens -!define DISPLAY_NAME "Free Unix Spectrum Emulator (Fuse) ${FUSE_VERSION}" -!define SETUP_FILENAME "@PACKAGE@-${FUSE_VERSION}-win32-setup" -!define SETUP_FILE "${SETUP_FILENAME}.exe" -!define HKLM_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Fuse" -!define PROG_ID "Fuse.Files.1" - -;Include Modern UI -!include "MUI2.nsh" -!include "Sections.nsh" -!include "Util.nsh" - -;-------------------------------- -;General - -Name "${DISPLAY_NAME}" -outFile "${SETUP_FILE}" -Caption "${DISPLAY_NAME}" - -installDir "$PROGRAMFILES\Fuse" - -; [Additional Installer Settings ] -XPStyle on -SetCompress force -SetCompressor lzma - -;-------------------------------- -;Interface Settings - - !define MUI_ABORTWARNING - -;-------------------------------- -;Pages - - !insertmacro MUI_PAGE_LICENSE "COPYING.txt" - !define MUI_COMPONENTSPAGE_SMALLDESC - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - !define MUI_FINISHPAGE_RUN "$INSTDIR\fuse.exe" - !define MUI_FINISHPAGE_NOREBOOTSUPPORT - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !define MUI_FINISHPAGE_SHOWREADME_CHECKED - !define MUI_FINISHPAGE_SHOWREADME "" - !define MUI_FINISHPAGE_SHOWREADME_TEXT "Delete configuration file" - !define MUI_FINISHPAGE_SHOWREADME_FUNCTION un.DeleteConfigFile - !insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -;Version Information - - VIProductVersion ${FUSE_FULL_VERSION} - VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "" - VIAddVersionKey /LANG=${LANG_ENGLISH} "InternalName" "${SETUP_FILENAME}" - VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "@FUSE_COPYRIGHT@" - VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Fuse" - VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${FUSE_VERSION}" - VIAddVersionKey /LANG=${LANG_ENGLISH} "OriginalFilename" "${SETUP_FILE}" - VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Fuse - the Free Unix Spectrum Emulator" - VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "${FUSE_VERSION}" - -;-------------------------------- -;File association functions - -!macro SelectUnregisteredExtCall _EXTENSION _SECTION - Push `${_EXTENSION}` - Push `${_SECTION}` - ${CallArtificialFunction} SelectUnregisteredExt_ -!macroend - -!macro NewSecExtensionCall _EXTENSION _DESCRIPTION - Section /o "${_DESCRIPTION} File" SEC_${_DESCRIPTION} - ${registerExtension} "${_EXTENSION}" - SectionEnd -!macroend - -!macro RegisterExtensionCall _EXTENSION - Push `${_EXTENSION}` - ${CallArtificialFunction} RegisterExtension_ -!macroend - -!macro UnRegisterExtensionCall _EXTENSION - Push "${_EXTENSION}" - ${CallArtificialFunction} UnRegisterExtension_ -!macroend - -!macro SelectUnregisteredExt_ - Exch $R1 ;section - Exch - Exch $R0 ;extension - Exch - Push $0 - - ReadRegStr $0 HKLM "Software\Classes\$R0" "" - ;Select if already associated with FUSE, i.e., reinstallation - StrCmp $0 "${PROG_ID}" Select 0 - ;Select if available - StrCmp $0 "" Select NoSelect - -Select: - !insertmacro SelectSection $R1 - -NoSelect: - Pop $0 - Pop $R1 - Pop $R0 -!macroend - -!macro RegisterExtension_ - Exch $R0 ;extension - Push $0 - - ; Recommend Fuse in the Open With list - WriteRegStr HKLM "Software\Classes\$R0\OpenWithProgids" "${PROG_ID}" "" - - ; Read global file association - ReadRegStr $0 HKLM "Software\Classes\$R0" "" - StrCmp "$0" "" NoBackup ; is it empty - StrCmp "$0" "${PROG_ID}" NoBackup ; is it our own - ; Backup current value - WriteRegStr HKLM "Software\Classes\$R0" "backup_val" "$0" - -NoBackup: - ; Set global file association - WriteRegStr HKLM "Software\Classes\$R0" "" "${PROG_ID}" - - ; Set current user (custom) file association - ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" - StrCmp "$0" "" NoLocalBackup ; is it empty - StrCmp "$0" "${PROG_ID}" NoLocalBackup ; is it our own - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" "$0" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" "${PROG_ID}" - -NoLocalBackup: - Pop $0 - Pop $R0 -!macroend - -!macro UnRegisterExtension_ - Exch $R0 ;extension - Push $0 - - ; Unregister OpenWith recommendation - DeleteRegValue HKLM "Software\Classes\$R0\OpenWithProgids" "${PROG_ID}" - - ; Try to delete current file association - ReadRegStr $0 HKLM "Software\Classes\$R0" "" - StrCmp $0 ${PROG_ID} 0 NoOwn ; only do this if we own it - ReadRegStr $0 HKLM "Software\Classes\$R0" "backup_val" - StrCmp $0 "" 0 Restore ; if backup="" then delete the whole key - DeleteRegKey HKLM "Software\Classes\$R0" - Goto NoOwn - -Restore: - WriteRegStr HKLM "Software\Classes\$R0" "" $0 - DeleteRegValue HKLM "Software\Classes\$R0" "backup_val" - -NoOwn: - ; Delete programmatic identifier - DeleteRegKey HKLM "Software\Classes\${PROG_ID}"; - - ; Delete current user (custom) file association - ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" - StrCmp "$0" "" NoLocalRestore ; is it empty - StrCmp "$0" "${PROG_ID}" 0 NoLocalRestore ; is it our own - ReadRegStr $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" - StrCmp "$0" "" 0 +2 ; if no backup -> delete - DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" - WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "Progid" "$0" - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$R0" "backup_val" - -NoLocalRestore: - Pop $0 - Pop $R0 -!macroend - -!define NewSecExtension `!insertmacro NewSecExtensionCall` -!define SelectUnregisteredExt `!insertmacro SelectUnregisteredExtCall` -!define RegisterExtension `!insertmacro RegisterExtensionCall` -!define UnRegisterExtension `!insertmacro UnRegisterExtensionCall` - -;-------------------------------- -; Uninstall previous version - - Section "" SecUninstallPrevious - - Push $R0 - ReadRegStr $R0 HKLM "${HKLM_REG_KEY}" "UninstallString" - - ; Check if we are upgrading a previous installation - ${If} $R0 == '"$INSTDIR\uninstall.exe"' - DetailPrint "Removing previous installation..." - - ; Run the uninstaller silently - ExecWait '"$INSTDIR\uninstall.exe" /S _?=$INSTDIR' - ${EndIf} - - Pop $R0 - -SectionEnd - -;-------------------------------- -; start default section - -section "!Fuse Core Files (required)" SecCore - - SectionIn RO - DetailPrint "Installing Fuse Core Files..." - - ; set the installation directory as the destination for the following actions - setOutPath "$INSTDIR" - - ; Installation files - File "AUTHORS.txt" - File "ChangeLog.txt" - File "COPYING.txt" - File "fuse.exe" - File "fuse.html" - File "README.txt" - File /nonfatal "README-win32.txt" - File "*.dll" - SetOutPath $INSTDIR\lib - File "lib\*" - SetOutPath "$INSTDIR\roms" - File "roms\*" - - ; create the uninstaller - writeUninstaller "$INSTDIR\uninstall.exe" - - ; Write the uninstall keys for Windows - WriteRegStr HKLM "${HKLM_REG_KEY}" "DisplayName" "${DISPLAY_NAME}" - WriteRegStr HKLM "${HKLM_REG_KEY}" "DisplayVersion" "${FUSE_VERSION}" - WriteRegStr HKLM "${HKLM_REG_KEY}" "HelpLink" "@PACKAGE_URL@" - WriteRegStr HKLM "${HKLM_REG_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe"' - WriteRegDWORD HKLM "${HKLM_REG_KEY}" "NoModify" 1 - WriteRegDWORD HKLM "${HKLM_REG_KEY}" "NoRepair" 1 - -sectionEnd - -;-------------------------------- -; Create shortcuts - -section "Start Menu and Desktop links" SecShortcuts - - DetailPrint "Creating Shortcuts..." - CreateDirectory "$SMPROGRAMS\Fuse" - CreateShortCut "$SMPROGRAMS\Fuse\Fuse.lnk" "$INSTDIR\fuse.exe" - CreateShortCut "$SMPROGRAMS\Fuse\Manual.lnk" "$INSTDIR\fuse.html" - CreateShortCut "$SMPROGRAMS\Fuse\Readme.lnk" "$INSTDIR\README.txt" - CreateShortCut "$SMPROGRAMS\Fuse\Uninstall.lnk" "$INSTDIR\uninstall.exe" - CreateShortCut "$DESKTOP\Fuse.lnk" "$INSTDIR\fuse.exe" - -sectionEnd - -;-------------------------------- -; Register common file extensions - -SectionGroup /e "Register File Extensions" SecFileExt - ${NewSecExtension} ".pzx" "PZX" - ${NewSecExtension} ".rzx" "RZX" - ${NewSecExtension} ".sna" "SNA" - ${NewSecExtension} ".szx" "SZX" - ${NewSecExtension} ".tap" "TAP" - ${NewSecExtension} ".tzx" "TZX" - ${NewSecExtension} ".z80" "Z80" -SectionGroupEnd - -Section "-Register Application" - WriteRegStr HKLM "Software\Classes\${PROG_ID}\shell" "" "open" - WriteRegStr HKLM "Software\Classes\${PROG_ID}\DefaultIcon" "" "$INSTDIR\fuse.exe,0" - WriteRegStr HKLM "Software\Classes\${PROG_ID}\shell\open\command" "" '"$INSTDIR\fuse.exe" "%1"' - WriteRegStr HKLM "Software\Classes\Applications\fuse.exe" "NoOpenWith" "" - - System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' -SectionEnd - -Function .onInit - ; Select extensions not associated with other applications - ${SelectUnregisteredExt} ".pzx" ${SEC_PZX} - ${SelectUnregisteredExt} ".rzx" ${SEC_RZX} - ${SelectUnregisteredExt} ".sna" ${SEC_SNA} - ${SelectUnregisteredExt} ".szx" ${SEC_SZX} - ${SelectUnregisteredExt} ".tap" ${SEC_TAP} - ${SelectUnregisteredExt} ".tzx" ${SEC_TZX} - ${SelectUnregisteredExt} ".z80" ${SEC_Z80} -FunctionEnd - -;-------------------------------- -; uninstaller section start - -section "uninstall" - - ; Unregister file extensions association (if owned) - DetailPrint "Deleting Registry Keys..." - ${unregisterExtension} ".pzx" - ${unregisterExtension} ".rzx" - ${unregisterExtension} ".sna" - ${unregisterExtension} ".szx" - ${unregisterExtension} ".tap" - ${unregisterExtension} ".tzx" - ${unregisterExtension} ".z80" - - ; Unregister Application - DeleteRegKey HKLM "Software\Classes\${PROG_ID}" - DeleteRegKey HKLM "Software\Classes\Applications\fuse.exe" - - System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' - - ; Delete the links - DetailPrint "Deleting Shortcuts..." - Delete "$SMPROGRAMS\Fuse\Fuse.lnk" - Delete "$SMPROGRAMS\Fuse\Manual.lnk" - Delete "$SMPROGRAMS\Fuse\Readme.lnk" - Delete "$SMPROGRAMS\Fuse\Uninstall.lnk" - RMDir "$SMPROGRAMS\Fuse" - Delete "$DESKTOP\Fuse.lnk" - - ; Installation files - DetailPrint "Deleting Files..." - Delete "$INSTDIR\lib\*" - RMDir "$INSTDIR\lib" - Delete "$INSTDIR\roms\*" - RMDir "$INSTDIR\roms" - Delete "$INSTDIR\AUTHORS.txt" - Delete "$INSTDIR\ChangeLog.txt" - Delete "$INSTDIR\COPYING.txt" - Delete "$INSTDIR\fuse.exe" - Delete "$INSTDIR\fuse.html" - Delete "$INSTDIR\README.txt" - Delete "$INSTDIR\README-win32.txt" - Delete "$INSTDIR\*.dll" - RMDir "$INSTDIR" - - ; Delete the uninstaller and remove the uninstall keys for Windows - DetailPrint "Deleting Uninstaller..." - Delete "$INSTDIR\uninstall.exe" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Fuse" - -sectionEnd - -Function un.DeleteConfigFile - Delete "$PROFILE\fuse.cfg" -FunctionEnd - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "The core files required to use Fuse (program, libraries, ROMs, etc.)" - !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} "Adds icons to your start menu and your desktop for easy access" - !insertmacro MUI_DESCRIPTION_TEXT ${SecFileExt} "Register common file extensions with Fuse: pzx, rzx, sna, szx, tap, tzx and z80" -!insertmacro MUI_FUNCTION_DESCRIPTION_END Deleted: vendor/fuse-emulator/current/fuse/winfuse.ico =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fr...@us...> - 2016-07-17 12:27:13
|
Revision: 815 http://sourceforge.net/p/fuse-for-macosx/code/815 Author: fredm Date: 2016-07-17 12:27:10 +0000 (Sun, 17 Jul 2016) Log Message: ----------- Load . into vendor/fuse-emulator/current. Modified Paths: -------------- vendor/fuse-emulator/current/fuse/ChangeLog vendor/fuse-emulator/current/fuse/README vendor/fuse-emulator/current/fuse/configure.ac vendor/fuse-emulator/current/fuse/hacking/ChangeLog vendor/fuse-emulator/current/fuse/man/fuse.1 Modified: vendor/fuse-emulator/current/fuse/ChangeLog =================================================================== --- vendor/fuse-emulator/current/fuse/ChangeLog 2016-07-17 12:20:31 UTC (rev 814) +++ vendor/fuse-emulator/current/fuse/ChangeLog 2016-07-17 12:27:10 UTC (rev 815) @@ -1,4 +1,4 @@ -2016-07-?? Philip Kendall <phi...@sh...> +2016-07-17 Philip Kendall <phi...@sh...> * Fuse 1.2.1 released. @@ -1325,4 +1325,4 @@ * Version 0.1.0 released. -$Id: ChangeLog 5677 2016-07-09 13:58:02Z fredm $ +$Id: ChangeLog 5686 2016-07-17 10:37:50Z fredm $ Modified: vendor/fuse-emulator/current/fuse/README =================================================================== --- vendor/fuse-emulator/current/fuse/README 2016-07-17 12:20:31 UTC (rev 814) +++ vendor/fuse-emulator/current/fuse/README 2016-07-17 12:27:10 UTC (rev 815) @@ -108,6 +108,6 @@ <http://www.worldofspectrum.org/forums/>. Philip Kendall <phi...@sh...> -10th July, 2016 +17th July, 2016 -$Id: README 5681 2016-07-10 13:06:44Z fredm $ +$Id: README 5686 2016-07-17 10:37:50Z fredm $ Modified: vendor/fuse-emulator/current/fuse/configure.ac =================================================================== --- vendor/fuse-emulator/current/fuse/configure.ac 2016-07-17 12:20:31 UTC (rev 814) +++ vendor/fuse-emulator/current/fuse/configure.ac 2016-07-17 12:27:10 UTC (rev 815) @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Id: configure.ac 5681 2016-07-10 13:06:44Z fredm $ +dnl $Id: configure.ac 5686 2016-07-17 10:37:50Z 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 @@ -20,7 +20,7 @@ dnl E-mail: phi...@sh... dnl Package version -m4_define([fuse_version], [1.2.1-pre1]) +m4_define([fuse_version], [1.2.1]) dnl Product full version m4_define([fuse_major_version], [1]) Modified: vendor/fuse-emulator/current/fuse/hacking/ChangeLog =================================================================== --- vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2016-07-17 12:20:31 UTC (rev 814) +++ vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2016-07-17 12:27:10 UTC (rev 815) @@ -5366,3 +5366,5 @@ 20160709 ChangeLog: tweak +D/DISCiPLE ROM/RAM change description (Fred). 20160710 README,configure.ac,man/fuse.1: bump some dates and mark as 1.2.1-pre1 (Fred). +20160717 ChangeLog,README,configure.ac,man/fuse.1: update release dates and mark + this release as 1.2.1 (Fred). Modified: vendor/fuse-emulator/current/fuse/man/fuse.1 =================================================================== --- vendor/fuse-emulator/current/fuse/man/fuse.1 2016-07-17 12:20:31 UTC (rev 814) +++ vendor/fuse-emulator/current/fuse/man/fuse.1 2016-07-17 12:27:10 UTC (rev 815) @@ -23,7 +23,7 @@ .\" E-mail: phi...@sh... .\" .\" -.TH fuse 1 "10th July, 2016" "Version 1.2.1" "Emulators" +.TH fuse 1 "17th July, 2016" "Version 1.2.1" "Emulators" .\" .\"------------------------------------------------------------------ .\" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |