diff --git a/src/computer.c b/src/computer.c index d38f33f..22260c4 100644 --- a/src/computer.c +++ b/src/computer.c @@ -1713,7 +1713,7 @@ void ResetComputer () { ordenador.last_selected_poke_file[0]='\0'; - ordenador.tst_sample=(ordenador.cpufreq + ordenador.freq/2)/ordenador.freq; + ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES); microdrive_reset(); diff --git a/src/computer.h b/src/computer.h index 3edd481..223561f 100644 --- a/src/computer.h +++ b/src/computer.h @@ -28,6 +28,7 @@ #define KB_BUFFER_LENGHT 10 #define MAX_PATH_LENGTH 256 +#define N_SAMPLES 4 extern char salir; diff --git a/src/emulator.c b/src/emulator.c index 42e1210..5d39a91 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -584,7 +584,7 @@ int bucle, bucle2,ret2; } printf("Init sound 2\n"); - ordenador.tst_sample=(ordenador.cpufreq + ordenador.freq/2)/ordenador.freq; + ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES); } void end_system() { diff --git a/src/menu_sdl.c b/src/menu_sdl.c index 8c1effa..2cbc20d 100644 --- a/src/menu_sdl.c +++ b/src/menu_sdl.c @@ -344,7 +344,6 @@ static const char **get_file_list(const char *base_dir) int cur = 0; struct dirent *de; int cnt = 16; - int i; if (!d) return NULL; @@ -371,6 +370,7 @@ static const char **get_file_list(const char *base_dir) size_t len = strlen(de->d_name) + 4; p = (char*)malloc( len ); + if (p==NULL) break; //Terminate the list snprintf(p, len, "[%s]", de->d_name); file_list[cur++] = p; file_list[cur] = NULL; @@ -380,6 +380,7 @@ static const char **get_file_list(const char *base_dir) char *p; p = strdup(de->d_name); + if (p==NULL) break; //Terminate the list file_list[cur++] = p; file_list[cur] = NULL; } @@ -388,15 +389,8 @@ static const char **get_file_list(const char *base_dir) { cnt = cnt + 32; realloc_file_list = (const char**)realloc(file_list, cnt * sizeof(char*)); - if (realloc_file_list) file_list = realloc_file_list; else - { - /* Cleanup everything - file_list is NULL-terminated */ - for ( i = 0; file_list[i]; i++ ) - free((void*)file_list[i]); - free(file_list); - closedir(d); - return NULL; - } + if (realloc_file_list) file_list = realloc_file_list; else break; + } } closedir(d); diff --git a/src/menus.c b/src/menus.c index 9100bd0..6df076d 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1747,7 +1747,7 @@ char *select_file(char *path,enum LOAD_FILE_TYPES kind) { unsigned char fin,read,*salida; int bucle,ancho,numitems,selected,from,longitud; - salida=(unsigned char *)malloc(2049); + salida=(unsigned char *)malloc(MAX_PATH_LENGTH); salida[0]=0; ancho=screen->w; @@ -2018,6 +2018,6 @@ if (freq == 0) } else ordenador.cpufreq = freq; -ordenador.tst_sample=(ordenador.cpufreq + ordenador.freq/2)/ordenador.freq; +ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES); } \ No newline at end of file diff --git a/src/spk_ay.c b/src/spk_ay.c index 5eab8fc..32710a7 100644 --- a/src/spk_ay.c +++ b/src/spk_ay.c @@ -24,7 +24,8 @@ #include "sound.h" #include -unsigned int beeper = 0; +unsigned int beeper = 0, lvalue_sum=0, rvalue_sum=0 ; +unsigned char sample_count = 0; /* emulates the AY-3-8912 during TSTADOS tstates */ @@ -314,23 +315,12 @@ inline void play_ay (unsigned int tstados) { inline void play_sound (unsigned int tstados) { - int lvalue, rvalue; - ordenador.tstados_counter_sound += tstados; while (ordenador.tstados_counter_sound >= ordenador.tst_sample) { ordenador.tstados_counter_sound -= ordenador.tst_sample; - /* - //Low pass filter - if (ordenador.sound_bit) - { - if (beeper<480) beeper = beeper + ordenador.low_filter; //Sound bit volume max 480*vol - } - else if (beeper>0) beeper = beeper - ordenador.low_filter; - */ - if (ordenador.sound_bit) { if (ordenador.sound_bit_mic) beeper = 544; //480 + 64 - MIC is audible only if EAR is on @@ -340,46 +330,55 @@ inline void play_sound (unsigned int tstados) { //Each channel max 256*vol - if (ordenador.ay_emul) + if ((ordenador.ay_emul)&&(!ordenador.turbo_state)) { switch (ordenador.audio_mode) { case 0: //Mono - lvalue = (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; - rvalue = (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; + lvalue_sum = lvalue_sum + (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; + rvalue_sum = rvalue_sum + (beeper + ordenador.vol_a + ordenador.vol_b +ordenador.vol_c)*ordenador.volume; break; case 1: //ABC - lvalue = (beeper + ordenador.vol_a*2 + ordenador.vol_b)*ordenador.volume; - rvalue = (beeper + ordenador.vol_b + ordenador.vol_c*2)*ordenador.volume; + lvalue_sum = lvalue_sum + (beeper + ordenador.vol_a*2 + ordenador.vol_b)*ordenador.volume; + rvalue_sum = rvalue_sum + (beeper + ordenador.vol_b + ordenador.vol_c*2)*ordenador.volume; break; case 2: //ACB - lvalue = (beeper + ordenador.vol_a*2 + ordenador.vol_c)*ordenador.volume; - rvalue = (beeper + ordenador.vol_c + ordenador.vol_b*2)*ordenador.volume; + lvalue_sum = lvalue_sum + (beeper + ordenador.vol_a*2 + ordenador.vol_c)*ordenador.volume; + rvalue_sum = rvalue_sum + (beeper + ordenador.vol_c + ordenador.vol_b*2)*ordenador.volume; break; case 3: //BAC - lvalue = (beeper + ordenador.vol_b*2 + ordenador.vol_a)*ordenador.volume; - rvalue = (beeper + ordenador.vol_a + ordenador.vol_c*2)*ordenador.volume; + lvalue_sum = lvalue_sum + (beeper + ordenador.vol_b*2 + ordenador.vol_a)*ordenador.volume; + rvalue_sum = rvalue_sum + (beeper + ordenador.vol_a + ordenador.vol_c*2)*ordenador.volume; break; default: //No emulation - rvalue = beeper*ordenador.volume; - lvalue = beeper*ordenador.volume; + lvalue_sum = lvalue_sum + beeper*ordenador.volume; + rvalue_sum = rvalue_sum + beeper*ordenador.volume; break; } } else { - rvalue = beeper*ordenador.volume; - lvalue = beeper*ordenador.volume; + lvalue_sum = lvalue_sum + beeper*ordenador.volume; + rvalue_sum = rvalue_sum + beeper*ordenador.volume; } + - *ordenador.current_buffer = (rvalue<<16)|(lvalue); - ordenador.current_buffer++; + if (sample_count==(N_SAMPLES-1)) + { - ordenador.sound_cuantity++; + *ordenador.current_buffer = ((rvalue_sum/N_SAMPLES)<<16)|(lvalue_sum/N_SAMPLES); + ordenador.current_buffer++; + + ordenador.sound_cuantity++; - if (ordenador.sound_cuantity == ordenador.buffer_len) { // buffer filled - sound_play(); - ordenador.sound_cuantity = 0; + if (ordenador.sound_cuantity == ordenador.buffer_len) { // buffer filled + sound_play(); + ordenador.sound_cuantity = 0; + } + sample_count=0; + lvalue_sum=0; + rvalue_sum=0; } + else sample_count++; } } diff --git a/src/tape.c b/src/tape.c index 61e11ab..5cfe05c 100644 --- a/src/tape.c +++ b/src/tape.c @@ -57,8 +57,8 @@ inline void tape_read(FILE *fichero, int tstados) { //Auto ultra fast mode if ((ordenador.turbo_state != 1)&&(ordenador.turbo==1)) { - if (ordenador.tape_file_type==TAP_TAP) update_frequency(13000000); - else update_frequency(11000000); + if (ordenador.tape_file_type==TAP_TAP) update_frequency(12500000); + else update_frequency(10500000); jump_frames=7; ordenador.precision_old=ordenador.precision; ordenador.precision =0; @@ -207,6 +207,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) { static unsigned char value, value2,value3,value4,done; static unsigned int bucle,bucle2, byte_position; int retval; + char block_jump[2]; if (fichero == NULL) { @@ -423,6 +424,11 @@ inline void tape_read_tzx (FILE * fichero, int tstados) { case 0x22: // group end break; + + case 0x23: // jump to block + retval=fread(block_jump,1,2,fichero); + jump_to_block(fichero, (int) block_jump[0] + 256*((int) block_jump[1])); + break; case 0x24: // loop start retval=fread(&value2,1,1,fichero); @@ -938,6 +944,7 @@ void fastload_block_tzx (FILE * fichero) { unsigned int longitud, len, bucle, number_bytes, byte_position, byte_position2, retorno; unsigned char value[65536], empty, blockid, parity, pause[2],flag_byte; int retval; + char block_jump[2]; longitud =0; pause[0]=pause[1]=0; @@ -1039,11 +1046,19 @@ void fastload_block_tzx (FILE * fichero) { break; case 0x21: // group start - retorno=2; + retval=fread(value,1,1,fichero); + if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;} + len = (unsigned int) value[0]; + retval=fread(value,1,len,fichero); break; case 0x22: // group end - retorno=2; + break; + + case 0x23: // jump to block + retval=fread(block_jump,1,2,fichero); + if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;} + jump_to_block(fichero, (int) block_jump[0] + 256*((int) block_jump[1])); break; case 0x24: // loop start diff --git a/src/tape_browser.c b/src/tape_browser.c index a4fdf9f..48e00b3 100644 --- a/src/tape_browser.c +++ b/src/tape_browser.c @@ -40,7 +40,8 @@ struct tape_select *block_select_list[MAX_SELECT_ITEM+1]; void browser_tzx (FILE * fichero) { unsigned int longitud, len, bucle, byte_position, retorno, block_number; - unsigned char value[65536], empty, blockid, pause[2], flag_byte; + unsigned char value[65536], empty, blockid, pause[2], flag_byte; + char block_jump[2]; int retval, retval2; longitud =0; @@ -196,7 +197,7 @@ void browser_tzx (FILE * fichero) { if (longitud==0) strcpy(browser_list[block_number]->block_type,"Stop the Tape "); else { - strcpy(browser_list[block_number]->block_type,"Pause: "); + strcpy(browser_list[block_number]->block_type,"Pause "); sprintf(browser_list[block_number]->info,"%d ms", longitud); } break; @@ -216,6 +217,13 @@ void browser_tzx (FILE * fichero) { strcpy(browser_list[block_number]->block_type,"Group end "); break; + case 0x23: // jump to block + strcpy(browser_list[block_number]->block_type,"Jump to block "); + retval=fread(block_jump,1,2,fichero); + if (retval!=2) {retorno=1;break;} + sprintf(browser_list[block_number]->info,"Block: %d", ((int) block_jump[0]) + 256*((int) block_jump[1]) + ((int) block_number)); + break; + case 0x24: // loop start strcpy(browser_list[block_number]->block_type,"Loop start "); retval=fread(value,1,2, fichero); @@ -302,7 +310,7 @@ void browser_tzx (FILE * fichero) { default: // not supported strcpy(browser_list[block_number]->block_type,"Not supported"); - retorno=1; //Tape error + retorno=1; //Error break; } block_number++; @@ -421,7 +429,7 @@ browser_list[block_number]=NULL; int select_block(FILE * fichero) { - unsigned int longitud, bucle, byte_position, block_number,nblocks,offset, blk_sel_pos; + unsigned int longitud, bucle, block_number,nblocks,offset, blk_sel_pos; unsigned char value[64], len_text; int retval; @@ -434,14 +442,14 @@ int select_block(FILE * fichero) block_select_list[bucle]=NULL; } - byte_position=ftell(fichero)-1; - - //search for select block + //search for select block position for(blk_sel_pos=0; - ((browser_list[blk_sel_pos]!=NULL)&&(blk_sel_posposition!=byte_position)); + ((blk_sel_posposition!=ordenador.tape_position)); blk_sel_pos++); - if (browser_list[blk_sel_pos]->position!=byte_position) return -1; + if (browser_list[blk_sel_pos]==NULL) return -1; + + if (browser_list[blk_sel_pos]->position!=ordenador.tape_position) return -1; retval=fread(value,1,3,fichero); if (retval!=3) {return -1;} @@ -473,7 +481,7 @@ int select_block(FILE * fichero) block_select_list[block_number]=NULL; if (feof(fichero)) return -1; - unsigned int tape_position, block_n_int; + unsigned int block_n_int; const char *row_selected; char block_n[3]; @@ -488,23 +496,52 @@ int select_block(FILE * fichero) block_n_int=atoi(block_n); - if ((block_n_int<0)||(block_n_int >(MAX_SELECT_ITEM-1))) return -1; + if ((block_n_int<0)||(block_n_int >(MAX_SELECT_ITEM-1))||block_select_list[block_n_int]==NULL) return -1; if ((block_select_list[block_n_int]->offset+blk_sel_pos) > (MAX_BROWSER_ITEM-1)) return -1; - tape_position=browser_list[block_select_list[block_n_int]->offset+blk_sel_pos]->position; + if (browser_list[block_select_list[block_n_int]->offset+blk_sel_pos]==NULL) return -1; + + ordenador.tape_position=browser_list[block_select_list[block_n_int]->offset+blk_sel_pos]->position; ordenador.tape_current_bit=0; ordenador.tape_current_mode=TAP_TRASH; ordenador.next_block= NOBLOCK; - fseek(ordenador.tap_file, tape_position, SEEK_SET); - ordenador.tape_position = tape_position; + fseek(ordenador.tap_file, ordenador.tape_position, SEEK_SET); free((void*)row_selected); return 0; } +int jump_to_block(FILE * fichero, int blocks_to_jump) +{ + + int blk_sel_pos, dest_block; + + + //search for block position + for(blk_sel_pos=0; + ((blk_sel_posposition!=ordenador.tape_position)); + blk_sel_pos++); + + if (browser_list[blk_sel_pos]==NULL) return -1; + + if (browser_list[blk_sel_pos]->position!=ordenador.tape_position) return -1; + + dest_block=blk_sel_pos+blocks_to_jump; + + if ((dest_block<0)||(dest_block>MAX_BROWSER_ITEM)) return -1; + + if (browser_list[dest_block]==NULL) return -1; + + fseek(fichero, browser_list[dest_block]->position, SEEK_SET); + + ordenador.tape_position = browser_list[dest_block]->position; + + return 0; +} + void free_browser() { unsigned int bucle; diff --git a/src/tape_browser.h b/src/tape_browser.h index 06e2ca7..63123c7 100644 --- a/src/tape_browser.h +++ b/src/tape_browser.h @@ -40,6 +40,7 @@ extern struct browser *browser_list[MAX_BROWSER_ITEM+1]; void browser_tap (FILE *); void browser_tzx (FILE *); int select_block(FILE * fichero); +int jump_to_block(FILE * fichero, int blocks_to_jump); void free_browser(); #endif