From: <sba...@us...> - 2023-07-19 17:46:25
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/8fd745102caa85f49b9f2bcb7135bf4d3d751b97/ commit 8fd745102caa85f49b9f2bcb7135bf4d3d751b97 Author: Vic Chwe <ch...@us...> AuthorDate: Wed Jul 19 18:47:01 2023 +0200 Add UI elements to manage SP0256 ROM file location SP0256 ROM initialisation moved to the uspeech.c and produces meaningful error messages if something goes wrong. --- menu.c | 9 ++-- menu_data.dat | 9 ++-- peripherals/sound/sp0256.c | 105 ++++++++++++++++---------------------------- peripherals/sound/sp0256.h | 5 ++- peripherals/sound/uspeech.c | 76 ++++++++++++++++++++++++++++++-- settings.dat | 1 + settings.pl | 9 ++-- ui/options.dat | 1 + 8 files changed, 129 insertions(+), 86 deletions(-) diff --git a/menu.c b/menu.c index 77608c16..99835be7 100644 --- a/menu.c +++ b/menu.c @@ -291,10 +291,11 @@ MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_peripheral_select ) case 7: menu_select_peripheral_roms( "Multiface 128", 6, 1 ); return; case 8: menu_select_peripheral_roms( "Multiface 3", 7, 1 ); return; case 9: menu_select_peripheral_roms( "Opus Discovery", 8, 1 ); return; - case 10: menu_select_peripheral_roms( "SpeccyBoot", 9, 1 ); return; - case 11: menu_select_peripheral_roms( "TTX2000S", 10, 1 ); return; - case 12: menu_select_peripheral_roms( "uSource", 11, 1 ); return; - case 13: menu_select_peripheral_roms( "uSpeech", 12, 1 ); return; + case 14: menu_select_peripheral_roms( "SP0256", 9, 1 ); return; + case 10: menu_select_peripheral_roms( "SpeccyBoot", 10, 1 ); return; + case 11: menu_select_peripheral_roms( "TTX2000S", 11, 1 ); return; + case 12: menu_select_peripheral_roms( "uSource", 12, 1 ); return; + case 13: menu_select_peripheral_roms( "uSpeech", 13, 1 ); return; } diff --git a/menu_data.dat b/menu_data.dat index 55f2f02c..dc126bd6 100644 --- a/menu_data.dat +++ b/menu_data.dat @@ -123,10 +123,11 @@ Options/Select ROMs/Peripheral ROMs/Mu_ltiface One..., Item,, menu_options_selec Options/Select ROMs/Peripheral ROMs/Multiface _128..., Item,, menu_options_selectroms_peripheral_select,, 7 Options/Select ROMs/Peripheral ROMs/Multiface _3..., Item,, menu_options_selectroms_peripheral_select,, 8 Options/Select ROMs/Peripheral ROMs/_Opus Discovery..., Item,, menu_options_selectroms_peripheral_select,, 9 -Options/Select ROMs/Peripheral ROMs/Specc_yBoot..., Item,, menu_options_selectroms_peripheral_select,, 10 -Options/Select ROMs/Peripheral ROMs/TT_X2000S..., Item,, menu_options_selectroms_peripheral_select,, 11 -Options/Select ROMs/Peripheral ROMs/_uSource..., Item,, menu_options_selectroms_peripheral_select,, 12 -Options/Select ROMs/Peripheral ROMs/_uSpeech..., Item,, menu_options_selectroms_peripheral_select,, 13 +Options/Select ROMs/Peripheral ROMs/_SP0256..., Item,,menu_options_selectroms_peripheral_select,, 10 +Options/Select ROMs/Peripheral ROMs/Specc_yBoot..., Item,, menu_options_selectroms_peripheral_select,, 11 +Options/Select ROMs/Peripheral ROMs/TT_X2000S..., Item,, menu_options_selectroms_peripheral_select,, 12 +Options/Select ROMs/Peripheral ROMs/_uSource..., Item,, menu_options_selectroms_peripheral_select,, 13 +Options/Select ROMs/Peripheral ROMs/uS_peech..., Item,, menu_options_selectroms_peripheral_select,, 14 Options/_Filter..., Item,,, menu_filter_detail diff --git a/peripherals/sound/sp0256.c b/peripherals/sound/sp0256.c index 8ad75edd..6094eb9b 100644 --- a/peripherals/sound/sp0256.c +++ b/peripherals/sound/sp0256.c @@ -70,6 +70,7 @@ #define debug_printf(x) #define jzp_printf(x, ...) +#define DEBUG_USPEECH_ALLOPHONE #define HIGH_QUALITY #define SCBUF_SIZE (4096) /* Must be power of 2 */ #define SCBUF_MASK (SCBUF_SIZE - 1) @@ -142,7 +143,7 @@ static void sp0256_write_ald(sp0256_t *s, uint32_t data); /* ======================================================================== */ /* sp0256_do_init -- Makes a new SP0256. */ /* ======================================================================== */ -static int sp0256_do_init( sp0256_t *s ); +static int sp0256_do_init( sp0256_t *s, uint8_t *sp0256rom ); static int factor = 358; @@ -1115,60 +1116,6 @@ sp0256_micro(sp0256_t *s) } } -/* ======================================================================== */ -/* sp0256_rdrom -- Tries to read a ROM file in the current directory. */ -/* ======================================================================== */ -static int -sp0256_rdrom(sp0256_t *s, int page) -{ - uint8_t *rom; - char buf[32]; - FILE *f; - - /* -------------------------------------------------------------------- */ - /* Generate a file name, and then see if it exists. */ - /* -------------------------------------------------------------------- */ - sprintf(buf, "sp0256_%.1X.bin", page); - - f = fopen(buf, "rb"); - if (!f) return 0; - - printf("SDB: sp0256_rdrom() %.1X\n", page); - - /* -------------------------------------------------------------------- */ - /* Allocate 4K worth of space to the ROM image. */ - /* -------------------------------------------------------------------- */ - rom = calloc(4096, 1); - if (!rom) { - fprintf(stderr, "SP0256: Out of memory in rdrom\n"); - return -1; - } - - /* -------------------------------------------------------------------- */ - /* Read in the ROM image and then bit-reverse it. */ - /* -------------------------------------------------------------------- */ - int l=fread(rom, 1, 4096, f); // FIXME: check length - fclose(f); - - if( l == 2048 ) { - memcpy( rom + 2048, rom, 2048); - } else { - free(rom); - fprintf(stderr, "SP0256 %.1X ROM has %d bytes, expected 2048\n", page, l); - return -1; - } - - /* -------------------------------------------------------------------- */ - /* Set this as our ROM page, and we're all set. */ - /* -------------------------------------------------------------------- */ - s->rom[page] = rom; - - jzp_printf("SP0256: added %s at SP0256 address $%.4X.0\n", buf, page << 12); - - return 0; -} - - /* ======================================================================== */ /* sp0256_run -- Where the magic happens. Generate voice data for */ /* our good friend, the SP0256. */ @@ -1326,10 +1273,8 @@ sp0256_do_reset(sp0256_t *s) /* sp0256_do_init -- Makes a new SP0256. */ /* ======================================================================== */ static int -sp0256_do_init( sp0256_t *s ) +sp0256_do_init( sp0256_t *s, uint8_t *sp0256rom ) { - int i; - /* -------------------------------------------------------------------- */ /* First, lets zero out the structure to be safe. */ /* -------------------------------------------------------------------- */ @@ -1363,15 +1308,17 @@ sp0256_do_init( sp0256_t *s ) /* you're going to have multiple SP0256's in a system, or use ROMs */ /* from various places, but it'll do for the moment. */ /* -------------------------------------------------------------------- */ - for (i = 0; i < 16; i++) - if (sp0256_rdrom(s, i)) - return -1; + + /* Original code was iterating over 16 "pages", but we always provided + ROM for "page" 1 only */ + s->rom[1] = sp0256rom; return 0; } static int current_intonation = 0; +#ifdef DEBUG_USPEECH_ALLOPHONE struct allophone_t { const char *name; int length; @@ -1448,20 +1395,38 @@ static const struct allophone_t al2_allophones[ 64 ] = { { "/BB2/", 50 }, /* (bb) */ }; +#endif /* #ifdef DEBUG_USPEECH_ALLOPHONE */ static sp0256_t sp0256; -void -sp0256_init( void ) +int +sp0256_init( uint8_t *sp0256rom ) { - sp0256_do_init(&sp0256); + return sp0256_do_init(&sp0256, sp0256rom); +} + +int +sp0256_reset( uint8_t *sp0256rom ) +{ + debug_printf("sp0256_reset\n"); + /* Lazy init, if necessary */ + if( !sp0256.scratch ) { + if( sp0256_do_init( &sp0256, sp0256rom ) ) { + return -1; + } + } else { + sp0256_do_reset( &sp0256 ); + } + return 0; } void -sp0256_reset( void ) +sp0256_end() { - printf("sp0256_reset\n"); - sp0256_do_reset(&sp0256); + if( sp0256.scratch ) { + free( sp0256.scratch ); + } + memset( &sp0256, 0, sizeof(sp0256) ); } static void @@ -1485,6 +1450,8 @@ sp0256_run_to(sp0256_t *s, uint64_t t ) void sp0256_do_frame( void ) { + /* No op if it wasn't initialised yet */ + if( !sp0256.scratch ) return; sp0256_run_to( &sp0256, machine_current->timings.tstates_per_frame ); sp0256_tstates -= machine_current->timings.tstates_per_frame; } @@ -1492,6 +1459,7 @@ sp0256_do_frame( void ) void sp0256_play( int a ) { +#ifdef DEBUG_USPEECH_ALLOPHONE if( a >= 5 && a < 64 ) { if( al2_allophones[ a ].name ) { printf( "sp0256: allophone written: 0x%02x, %s\n", a, al2_allophones[ a ].name ); @@ -1500,6 +1468,7 @@ sp0256_play( int a ) } fflush( stdout ); } +#endif /* #ifdef DEBUG_USPEECH_ALLOPHONE */ sp0256_run_to(&sp0256, tstates); sp0256_write_ald(&sp0256, a); @@ -1510,7 +1479,7 @@ sp0256_set_intonation( int intonation ) { if( intonation != current_intonation ) { sp0256_run_to(&sp0256, tstates); - printf("sp0256: intonation %s\n", intonation ? "high" : "normal" ); + debug_printf( ("sp0256: intonation %s\n", intonation ? "high" : "normal") ); current_intonation = intonation; /* 358 - 1/8th = 314 */ factor = intonation ? 314 : 358; diff --git a/peripherals/sound/sp0256.h b/peripherals/sound/sp0256.h index 5564d9c0..4fcac101 100644 --- a/peripherals/sound/sp0256.h +++ b/peripherals/sound/sp0256.h @@ -29,8 +29,9 @@ #ifndef FUSE_SP0256_H #define FUSE_SP0256_H -void sp0256_init( void ); -void sp0256_reset( void ); +int sp0256_init( uint8_t *sp0256rom ); +int sp0256_reset( uint8_t *sp0256rom ); +void sp0256_end( void ); void sp0256_play( int allophone ); void sp0256_set_intonation( int intonation ); diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index b9e90948..f10b26f1 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -37,14 +37,20 @@ #include "periph.h" #include "settings.h" #include "sp0256.h" +#include "ui/ui.h" #include "unittests/unittests.h" #include "uspeech.h" +#include "utils.h" + +#define SP0256_ROM_SIZE 2048 /* A 2 KiB memory chunk accessible by the Z80 when /ROMCS is low * (mirrored when active) */ static memory_page uspeech_memory_map_romcs[ MEMORY_PAGES_IN_2K ]; static int uspeech_memory_source; +static uint8_t *sp0256rom = NULL; + int uspeech_active = 0; int uspeech_available = 0; @@ -87,8 +93,6 @@ uspeech_init( void *context ) int uspeech_source; int i; - sp0256_init(); - module_register( &uspeech_module_info ); uspeech_source = memory_source_register( "uSpeech" ); @@ -104,6 +108,10 @@ static void uspeech_end( void ) { uspeech_available = 0; + sp0256_end(); + if( sp0256rom ) { + libspectrum_free( sp0256rom ); + } } void @@ -118,6 +126,62 @@ uspeech_register_startup( void ) uspeech_end ); } +static int +uspeech_load_sp0256_rom() +{ + int error; + char *filename; + utils_file rom; + + filename = settings_current.rom_sp0256; + error = utils_read_auxiliary_file( filename, &rom, UTILS_AUXILIARY_ROM ); + if( error ) { + filename = settings_default.rom_sp0256; + error = utils_read_auxiliary_file( filename, &rom, UTILS_AUXILIARY_ROM ); + if( error ) { + ui_error( UI_ERROR_ERROR, "couldn't find ROM '%s'", filename ); + return -1; + } + } + + if( rom.length != SP0256_ROM_SIZE ) { + ui_error( UI_ERROR_ERROR, + "ROM '%s' is %ld bytes long; expected %ld bytes", + filename, (unsigned long)rom.length, + (unsigned long)SP0256_ROM_SIZE ); + utils_close_file( &rom ); + return -1; + } + + sp0256rom = libspectrum_new( uint8_t, SP0256_ROM_SIZE * 2 ); + + if( !sp0256rom ) { + utils_close_file( &rom ); + ui_error( UI_ERROR_ERROR, "SP0256: Out of memory in rdrom" ); + return -1; + } + + memcpy( sp0256rom, rom.buffer, SP0256_ROM_SIZE ); + memcpy( sp0256rom + SP0256_ROM_SIZE, rom.buffer, SP0256_ROM_SIZE ); + + utils_close_file( &rom ); + + return 0; +} + +static int +uspeech_sp0256_reset() +{ + if( !sp0256rom && uspeech_load_sp0256_rom() ) { + return -1; + } + + if( sp0256_reset( sp0256rom ) ) { + return -1; + } + + return 0; +} static void uspeech_reset( int hard_reset GCC_UNUSED ) @@ -125,8 +189,6 @@ uspeech_reset( int hard_reset GCC_UNUSED ) uspeech_active = 0; uspeech_available = 0; - sp0256_reset(); - if( !periph_is_active( PERIPH_TYPE_USPEECH ) ) return; @@ -138,6 +200,12 @@ uspeech_reset( int hard_reset GCC_UNUSED ) return; } + if( uspeech_sp0256_reset()) { + settings_current.uspeech = 0; + periph_activate_type( PERIPH_TYPE_USPEECH, 0 ); + return; + } + machine_current->ram.romcs = 0; uspeech_available = 1; diff --git a/settings.dat b/settings.dat index fcfa0416..d0007066 100644 --- a/settings.dat +++ b/settings.dat @@ -260,6 +260,7 @@ rom_multiface1, string, "mf1.rom", rom_multiface128, string, "mf128.rom", rom_multiface3, string, "mf3.rom", rom_opus, string, "opus.rom", +rom_sp0256, string, "sp0256-al2.rom", rom_speccyboot, string, "speccyboot-1.4.rom", rom_ttx2000s, string, "ttx2000s.rom", rom_usource, string, "usource.rom", diff --git a/settings.pl b/settings.pl index 651b2da4..bac46f00 100644 --- a/settings.pl +++ b/settings.pl @@ -768,10 +768,11 @@ settings_get_rom_setting( settings_info *settings, size_t which, case 6: return &( settings->rom_multiface128 ); case 7: return &( settings->rom_multiface3 ); case 8: return &( settings->rom_opus ); - case 9: return &( settings->rom_speccyboot ); - case 10: return &( settings->rom_ttx2000s ); - case 11: return &( settings->rom_usource ); - case 12: return &( settings->rom_uspeech ); + case 9: return &( settings->rom_sp0256 ); + case 10: return &( settings->rom_speccyboot ); + case 11: return &( settings->rom_ttx2000s ); + case 12: return &( settings->rom_usource ); + case 13: return &( settings->rom_uspeech ); default: return NULL; } } diff --git a/ui/options.dat b/ui/options.dat index 20d807b2..41940414 100644 --- a/ui/options.dat +++ b/ui/options.dat @@ -161,6 +161,7 @@ Entry, A(Y) volume, volume_ay, INPUT_KEY_y, 3, % Entry, B(e)eper volume, volume_beeper, INPUT_KEY_e, 3, % Entry, Spec(D)rum volume, volume_specdrum, INPUT_KEY_d, 3, % Entry, (C)ovox volume, volume_covox, INPUT_KEY_c, 3, % +Entry, (u)Speech volume, volume_uspeech, INPUT_KEY_u, 3, % diskoptions Drives Setup |