Program tape select, fixed 3 bugs in tape browser, free tape browser allocs, set 2500 max browser blocks, custom header block

This commit is contained in:
fabio.olimpieri 2013-03-19 07:26:39 +00:00
parent ff739e4e01
commit b17bd01131
7 changed files with 243 additions and 54 deletions

View File

@ -38,6 +38,7 @@
#include "tape.h"
#include "microdrive.h"
#include "menu_sdl.h"
#include "tape_browser.h"
#include <dirent.h>
@ -1615,5 +1616,7 @@ int main(int argc,char *argv[]) {
fatUnmount(0);
#endif
free_browser();
return 0;
}

View File

@ -234,17 +234,19 @@ static void tape_browser()
{
unsigned int tape_position, block_n_int;
const char *row_selected;
char block_n[4];
char block_n[5];
if (browser_list[0]==NULL) {msgInfo("No tape inserted",3000,NULL);return;}
row_selected = menu_select_browser(ordenador.tape_position);
if (row_selected==NULL) // Aborted
return;
if (row_selected[0]==']') strncpy(block_n, row_selected+1,3);
else strncpy(block_n, row_selected,3);
if (row_selected[0]==']') strncpy(block_n, row_selected+1,4);
else strncpy(block_n, row_selected,4);
block_n[3]=0;
block_n[4]=0;
block_n_int=atoi(block_n);

View File

@ -1294,24 +1294,43 @@ const char **get_file_list_browser(unsigned int tape_pos, unsigned int *block_po
unsigned int loop;
char **browser_list_menu;
*block_pos=0;
browser_list_menu = (char**)malloc((MAX_BROWSER_ITEM+1) * sizeof(char*));
browser_list_menu[0] = NULL;
for(loop=0;browser_list[loop]!=NULL;loop++)
{
browser_list_menu[loop]=malloc(24+32+8);
browser_list_menu[loop]=malloc(24+36+9);
if (browser_list[loop]->position==tape_pos)
{
sprintf(browser_list_menu[loop],"]%03d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
sprintf(browser_list_menu[loop],"]%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
*block_pos=loop;
}
else
sprintf(browser_list_menu[loop],"%03d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
sprintf(browser_list_menu[loop],"%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
}
browser_list_menu[loop]=NULL;
return (const char **) browser_list_menu;
}
const char **get_file_list_select_block()
{
unsigned int loop;
char **block_list_menu;
block_list_menu = (char**)malloc((MAX_SELECT_ITEM+1) * sizeof(char*));
block_list_menu[0] = NULL;
for(loop=0;block_select_list[loop]!=NULL;loop++)
{
block_list_menu[loop]=malloc(32);
sprintf(block_list_menu[loop],"%02d %s",loop, block_select_list[loop]->info);
}
block_list_menu[loop]=NULL;
return (const char **) block_list_menu;
}
static const char *menu_select_file_internal(char *dir_path,
int x, int y, int x2, int y2, const char *selected_file, int draw_scr, unsigned int tape_pos)
{
@ -1326,12 +1345,15 @@ static const char *menu_select_file_internal(char *dir_path,
char buf[64];
unsigned int block_pos;
if (strcmp(dir_path,"browser")) file_list = get_file_list(dir_path); else file_list = get_file_list_browser(tape_pos, &block_pos);
if (!strcmp(dir_path,"browser")) file_list = get_file_list_browser(tape_pos, &block_pos);
else if (!strcmp(dir_path,"select_block")) file_list = get_file_list_select_block();
else file_list = get_file_list(dir_path);
if (file_list == NULL)
return NULL;
if (!strcmp(dir_path,"browser")) opt = menu_select_sized("Select block", file_list, NULL, block_pos, x, y, x2, y2, NULL, NULL ,16, draw_scr);
if (!strcmp(dir_path,"browser")) opt = menu_select_sized("Select block", file_list, NULL, block_pos, x, y, x2, y2, NULL, NULL ,16, 0);
else if (!strcmp(dir_path,"select_block")) opt = menu_select_sized("Select program", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16, 0);
else if (selected_file)
{
ptr_selected_file= strrchr(selected_file,'/');
@ -1354,7 +1376,7 @@ static const char *menu_select_file_internal(char *dir_path,
if (!sel)
return NULL;
if (!strcmp(dir_path,"browser")) return sel;
if (!strcmp(dir_path,"browser")||!strcmp(dir_path,"select_block")) return sel;
if (!strcmp(sel,"[..]")) //selected "[..]"
{
@ -1427,6 +1449,13 @@ const char *menu_select_browser(unsigned int tape_pos)
0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, NULL, 0, tape_pos);
}
const char *menu_select_tape_block()
{
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
return menu_select_file_internal("select_block",
0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, NULL, 0, 0);
}
static TTF_Font *read_font(const char *path, int font_size)
{

View File

@ -74,4 +74,6 @@ int ask_value_sdl(int *final_value,int y_coord,int max_value);
int ask_filename_sdl(char *nombre_final,int y_coord,char *extension, char *path, char *name);
const char *menu_select_tape_block();
#endif /* !__MENU_H__ */

View File

@ -23,6 +23,7 @@
#include "emulator.h"
#include "menus.h"
#include "tape.h"
#include "tape_browser.h"
#ifdef DEBUG
extern FILE *fdebug;
@ -204,7 +205,7 @@ inline void tape_read_tap (FILE * fichero, int tstados) {
inline void tape_read_tzx (FILE * fichero, int tstados) {
static unsigned char value, value2,value3,value4,done;
static unsigned int bucle,bucle2;
static unsigned int bucle,bucle2, byte_position;
int retval;
if (fichero == NULL)
@ -221,8 +222,8 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block
done = 0;
ordenador.tape_position=ftell(fichero);
do {
ordenador.tape_position=ftell(fichero);
retval=fread(&value,1,1,fichero); // read block ID
printf("TZX:ID_normal: %X en %ld\n",value,ftell(fichero));
if(feof(fichero))
@ -438,11 +439,17 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
break;
case 0x28: // select block
retval=fread(&value2,1,1,fichero);
retval=fread(&value3,1,1,fichero);
bucle2 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
for(bucle=0;bucle<bucle2;bucle++)
retval=fread(&value3,1,1,fichero);
byte_position=ftell(fichero);
retval=select_block(fichero);
if (retval)
{
fseek(fichero, byte_position, SEEK_SET);
retval=fread(&value2,1,1,fichero);
retval=fread(&value3,1,1,fichero);
bucle2 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
for(bucle=0;bucle<bucle2;bucle++)
retval=fread(&value3,1,1,fichero);
}
break;
case 0x2A: // pause if 48K
@ -994,7 +1001,7 @@ void fastload_block_tzx (FILE * fichero) {
case 0X03:
ordenador.next_block=DATA;
break;
default: //??
default: //Custom header
ordenador.next_block=NOBLOCK;
break;
}
@ -1048,10 +1055,16 @@ void fastload_block_tzx (FILE * fichero) {
break;
case 0x28: // select block
retval=fread(value,1,2,fichero);
if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;}
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
retval=fread(value,1,len,fichero);
byte_position2=ftell(fichero);
retval=select_block(fichero);
if (retval)
{
fseek(fichero, byte_position2, SEEK_SET);
retval=fread(value,1,2,fichero);
if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;}
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
retval=fread(value,1,len,fichero);
}
break;
case 0x2A: // pause if 48K

View File

@ -23,6 +23,7 @@
#include "emulator.h"
#include "tape_browser.h"
#include "tape.h"
#include "menu_sdl.h"
#ifdef DEBUG
extern FILE *fdebug;
@ -34,6 +35,7 @@ extern FILE *fdebug;
#endif
struct browser *browser_list[MAX_BROWSER_ITEM+1];
struct tape_select *block_select_list[MAX_SELECT_ITEM+1];
void browser_tzx (FILE * fichero) {
@ -75,15 +77,14 @@ void browser_tzx (FILE * fichero) {
retval=fread (&blockid, 1, 1, fichero); //Read id block
if (retval!=1) {retorno=1;break;}
browser_list[block_number]=(struct browser *)malloc(sizeof(struct browser));
//if (browser_list[block_number]==NULL) retorno=1;
browser_list[block_number]->position=byte_position;
strcpy(browser_list[block_number]->info, " ");
strcpy(browser_list[block_number]->info, " ");
printf("TZX: browser: %X en %d\n",blockid, byte_position);
printf("TZX browser: %X en %d\n",blockid, byte_position);
switch(blockid) {
case 0x10: // classic tape block
strcpy(browser_list[block_number]->block_type,"Standard speed data");
strcpy(browser_list[block_number]->block_type,"Standard Speed Data");
retval=fread (pause, 1, 2, fichero); //pause lenght
retval2=fread (value, 1, 2, fichero); // read length of current block
if ((retval!=2)||(retval2!=2)) {retorno=1;break;}
@ -93,6 +94,17 @@ void browser_tzx (FILE * fichero) {
switch(flag_byte)
{
case 0x00: //header
if (longitud!=19)
{
sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud);
if (longitud>1)
{
retval=fread (value, 1, longitud-1, fichero);
if (retval!=(longitud-1)) {retorno=1;break;}
}
}
else
{
retval=fread (value, 1, 18, fichero);
if (retval!=18) {retorno=1;break;}
value[11]=0;
@ -111,10 +123,11 @@ void browser_tzx (FILE * fichero) {
case 0X03:
sprintf(browser_list[block_number]->info,"Code: %s", value+1);
break;
default: //??
strcpy(browser_list[block_number]->info,"???");
default: //Custom header
sprintf(browser_list[block_number]->info,"Custom header: %s", value+1);
break;
}
}
break;
case 0xFF: //data
sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud);
@ -135,7 +148,7 @@ void browser_tzx (FILE * fichero) {
}
break;
case 0x11: // turbo
strcpy(browser_list[block_number]->block_type,"Turbo speed data ");
strcpy(browser_list[block_number]->block_type,"Turbo Speed Data ");
retval=fread(value,1,0x0F, fichero);
retval=fread (value, 1,3 ,fichero); // read length of current block
if (retval!=3) {retorno=1;break;}
@ -146,11 +159,12 @@ void browser_tzx (FILE * fichero) {
break;
case 0x12: // pure tone
strcpy(browser_list[block_number]->block_type,"Pure tone ");
strcpy(browser_list[block_number]->block_type,"Pure Tone ");
retval=fread(value,1,4,fichero);
if (retval!=4) {retorno=1;break;}
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
longitud = ((unsigned int) value[2]) + 256 * ((unsigned int) value[3]);
sprintf(browser_list[block_number]->info,"%d pulses", longitud);
sprintf(browser_list[block_number]->info,"%d pulses of %d Ts", longitud, len);
break;
case 0x13: // multiple pulses
@ -165,7 +179,7 @@ void browser_tzx (FILE * fichero) {
break;
case 0x14: // Pure data
strcpy(browser_list[block_number]->block_type,"Pure data ");
strcpy(browser_list[block_number]->block_type,"Pure Data ");
retval=fread(value,1,0x07, fichero);
retval=fread (value, 1, 3, fichero); // read length of current block
if (retval!=3) {retorno=1;break;}
@ -179,7 +193,7 @@ void browser_tzx (FILE * fichero) {
retval=fread(value,1,2,fichero);
if (retval!=2) {retorno=1;break;}
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
if (longitud==0) strcpy(browser_list[block_number]->block_type,"Stop tape ");
if (longitud==0) strcpy(browser_list[block_number]->block_type,"Stop the Tape ");
else
{
strcpy(browser_list[block_number]->block_type,"Pause: ");
@ -193,7 +207,7 @@ void browser_tzx (FILE * fichero) {
if (retval!=1) {retorno=1;break;}
len = (unsigned int) value[0];
retval=fread(value,1,len,fichero);
if (len>31) len=31;
if (len>35) len=35;
value[len]=0;
strcpy(browser_list[block_number]->info,value);
break;
@ -212,7 +226,7 @@ void browser_tzx (FILE * fichero) {
break;
case 0x28: // select block
strcpy(browser_list[block_number]->block_type,"Select block ");
strcpy(browser_list[block_number]->block_type,"Select ");
retval=fread(value,1,2,fichero);
if (retval!=2) {retorno=1;break;}
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
@ -226,13 +240,13 @@ void browser_tzx (FILE * fichero) {
break;
case 0x30: // text description
strcpy(browser_list[block_number]->block_type,"Text: ");
strcpy(browser_list[block_number]->block_type,"Text description: ");
retval=fread(value,1,1,fichero); // length
if (retval!=1) {retorno=1;break;}
len = (unsigned int) value[0] ;
retval=fread(value,1,len,fichero);
if (retval!=len) {retorno=1;break;}
if (len>31) len=31;
if (len>35) len=35;
value[len]=0;
for(bucle=0;bucle<len;bucle++)
if (value[bucle]<' ') value[bucle]=' '; //not printable character
@ -240,7 +254,7 @@ void browser_tzx (FILE * fichero) {
break;
case 0x31: // show text
strcpy(browser_list[block_number]->block_type,"Show text: ");
strcpy(browser_list[block_number]->block_type,"Show message: ");
retval=fread(value,1,1,fichero); //Time lengt
if (retval!=1) {retorno=1;break;}
retval=fread(value,1,1,fichero); // length
@ -248,7 +262,7 @@ void browser_tzx (FILE * fichero) {
len = (unsigned int) value[0];
retval=fread(value,1,len,fichero);
if (retval!=len) {retorno=1;break;}
if (len>31) len=31;
if (len>35) len=35;
value[len]=0;
for(bucle=0;bucle<len;bucle++)
if (value[bucle]<' ') value[bucle]=' '; //not printable character
@ -256,7 +270,7 @@ void browser_tzx (FILE * fichero) {
break;
case 0x32: // archive info
strcpy(browser_list[block_number]->block_type,"Archive info: ");
strcpy(browser_list[block_number]->block_type,"Archive info ");
retval=fread(value,1,2,fichero); // length
if (retval!=2) {retorno=1;break;}
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
@ -264,7 +278,7 @@ void browser_tzx (FILE * fichero) {
break;
case 0x33: // hardware info
strcpy(browser_list[block_number]->block_type,"Hardware info: ");
strcpy(browser_list[block_number]->block_type,"Hardware info ");
retval=fread(value,1,1,fichero);
if (retval!=1) {retorno=1;break;}
len = (unsigned int) value[0] *3;
@ -272,12 +286,12 @@ void browser_tzx (FILE * fichero) {
break;
case 0x34: // emulation info
strcpy(browser_list[block_number]->block_type,"Emulation info: ");
strcpy(browser_list[block_number]->block_type,"Emulation info ");
retval=fread(value,1,8,fichero);
break;
case 0x35: // custom info
strcpy(browser_list[block_number]->block_type,"Custom info: ");
strcpy(browser_list[block_number]->block_type,"Custom info ");
retval=fread(value,1,16,fichero);
retval=fread(value,1,4,fichero);
if (retval!=4) {retorno=1;break;}
@ -334,20 +348,31 @@ void browser_tap (FILE * fichero) {
do {
byte_position=ftell(fichero);
browser_list[block_number]=(struct browser *)malloc(sizeof(struct browser));
//if (browser_list[block_number]==NULL) retorno=1;
browser_list[block_number]->position=byte_position;
printf("TAP: browser: %X en %d\n",10, byte_position);
strcpy(browser_list[block_number]->block_type,"Standard speed data");
strcpy(browser_list[block_number]->info, " ");
strcpy(browser_list[block_number]->block_type,"Standard Speed Data");
retval=fread (value, 1, 2, fichero); // read length of current block
if (retval!=2) {retorno=1;break;}
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
retval=fread (&flag_byte, 1, 1, fichero);
if (retval!=1) {retorno=1;break;}
printf("TAP browser: flag byte %X en %ld\n",flag_byte, ftell(fichero));
switch(flag_byte)
{
case 0x00: //header
retval=fread (value, 1, 18, fichero);
if (retval!=18) {retorno=1;break;}
if (longitud!=19)
{
sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud);
if (longitud>1)
{
retval=fread (value, 1, longitud-1, fichero);
if (retval!=(longitud-1)) {retorno=1;break;}
}
}
else
{
retval=fread (value, 1, 18, fichero);
if (retval!=18) {retorno=1;break;}
value[11]=0;
for(bucle=1;bucle<11;bucle++)
if (value[bucle]<' ') value[bucle]='?'; //not printable character
@ -364,13 +389,14 @@ void browser_tap (FILE * fichero) {
case 0X03:
sprintf(browser_list[block_number]->info,"Code: %s", value+1);
break;
default: //??
strcpy(browser_list[block_number]->info,"???");
default: //Custom header
sprintf(browser_list[block_number]->info,"Custom header: %s", value+1);
break;
}
}
break;
case 0xFF: //data
sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud-2);
sprintf(browser_list[block_number]->info,"Standard Data: %d bytes", longitud);
if (longitud>1)
{
retval=fread (value, 1, longitud-1, fichero);
@ -378,7 +404,7 @@ void browser_tap (FILE * fichero) {
}
break;
default: //Custom data
sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud-2);
sprintf(browser_list[block_number]->info,"Custom Data: %d bytes", longitud);
if (longitud>1)
{
retval=fread (value, 1, longitud-1, fichero);
@ -392,3 +418,109 @@ void browser_tap (FILE * fichero) {
rewind_tape (fichero,1);
browser_list[block_number]=NULL;
}
int select_block(FILE * fichero)
{
unsigned int longitud, bucle, byte_position, block_number,nblocks,offset, blk_sel_pos;
unsigned char value[64], len_text;
int retval;
block_number=0;
//Free the block list
for(bucle=0; ((block_select_list[bucle]!=NULL)&&(bucle<MAX_SELECT_ITEM)); bucle++)
{
free (block_select_list[bucle]);
block_select_list[bucle]=NULL;
}
byte_position=ftell(fichero)-1;
//search for select block
for(blk_sel_pos=0;
((browser_list[blk_sel_pos]!=NULL)&&(blk_sel_pos<MAX_BROWSER_ITEM)&&(browser_list[blk_sel_pos]->position!=byte_position));
blk_sel_pos++);
if (browser_list[blk_sel_pos]->position!=byte_position) return -1;
retval=fread(value,1,3,fichero);
if (retval!=3) {return -1;}
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
nblocks=value[2];
if (nblocks>MAX_SELECT_ITEM) {return -1;}
for(block_number=0;block_number<nblocks;block_number++)
{
retval=fread (value, 1, 2, fichero); //Read offset
if (retval!=2) return -1;
offset = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
retval=fread (&len_text, 1, 1, fichero); //Read len text
if (retval!=1) return -1;
if (len_text>64) return -1;
retval=fread (value, 1, len_text, fichero); //Read text
if (retval!=len_text) return -1;
if (len_text>31) len_text=31;
value[len_text]=0;
block_select_list[block_number]=(struct tape_select *)malloc(sizeof(struct tape_select));
block_select_list[block_number]->offset = offset;
strcpy(block_select_list[block_number]->info, value);
}
block_select_list[block_number]=NULL;
if (feof(fichero)) return -1;
unsigned int tape_position, block_n_int;
const char *row_selected;
char block_n[3];
row_selected = menu_select_tape_block();
if (row_selected==NULL) // Aborted
return -1;
strncpy(block_n, row_selected,2);
block_n[2]=0;
block_n_int=atoi(block_n);
if ((block_n_int<0)||(block_n_int >(MAX_SELECT_ITEM-1))) 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;
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;
free((void*)row_selected);
return 0;
}
void free_browser()
{
unsigned int bucle;
//Free the browser list
for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle<MAX_BROWSER_ITEM)); bucle++)
{
free (browser_list[bucle]);
browser_list[bucle]=NULL;
}
//Free the block list
for(bucle=0; ((block_select_list[bucle]!=NULL)&&(bucle<MAX_SELECT_ITEM)); bucle++)
{
free (block_select_list[bucle]);
block_select_list[bucle]=NULL;
}
}

View File

@ -20,18 +20,26 @@
#ifndef H_TAPE_BROWSER
#define H_TAPE_BROWSER
#define MAX_BROWSER_ITEM 1000
#define MAX_BROWSER_ITEM 2500
#define MAX_SELECT_ITEM 63
struct browser {
unsigned int position;
char block_type[24];
char info[36];
};
struct tape_select {
unsigned int offset;
char info[32];
};
extern struct tape_select *block_select_list[MAX_SELECT_ITEM+1];
extern struct browser *browser_list[MAX_BROWSER_ITEM+1];
void browser_tap (FILE *);
void browser_tzx (FILE *);
int select_block(FILE * fichero);
void free_browser();
#endif