Changed TZX fast load parser

This commit is contained in:
fabio.olimpieri 2013-03-06 22:37:42 +00:00
parent 5176c41c71
commit 329b8e37ef
6 changed files with 97 additions and 90 deletions

View File

@ -87,7 +87,7 @@ inline void emulate (int tstados) {
play_sound (tstados); play_sound (tstados);
tape_read (ordenador.tap_file, tstados); tape_read (ordenador.tap_file, tstados);
microdrive_emulate(tstados); microdrive_emulate(tstados);
if (!ordenador.pause) { if (!ordenador.tape_stop) {
if (ordenador.tape_readed) if (ordenador.tape_readed)
ordenador.sound_bit = 1; ordenador.sound_bit = 1;
else else
@ -116,7 +116,7 @@ void computer_init () { //Called only on start-up
ordenador.precision_old = 1; ordenador.precision_old = 1;
ordenador.tape_readed = 0; ordenador.tape_readed = 0;
ordenador.pause = 1; // tape stop ordenador.tape_stop = 1; // tape stop
ordenador.tape_fast_load = 1; // fast load by default ordenador.tape_fast_load = 1; // fast load by default
ordenador.rewind_on_reset = 1; //Rewound on reset by default ordenador.rewind_on_reset = 1; //Rewound on reset by default
ordenador.pause_instant_load = 0; ordenador.pause_instant_load = 0;
@ -561,7 +561,7 @@ inline void show_screen (int tstados) {
ordenador.interr = 1; ordenador.interr = 1;
if ((ordenador.turbo_state == 0) || (curr_frames%7 == 0)) ordenador.readkeyboard = 1; if ((ordenador.turbo_state == 0) || (curr_frames%7 == 0)) ordenador.readkeyboard = 1;
curr_frames++; curr_frames++;
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--; if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--; if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--;
} }
@ -666,7 +666,7 @@ inline void show_screen (int tstados) {
}*/ }*/
} }
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--; if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--; if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--;
@ -710,7 +710,7 @@ inline void show_screen_precision (int tstados) {
ordenador.interr = 1; ordenador.interr = 1;
ordenador.readkeyboard = 1; ordenador.readkeyboard = 1;
curr_frames++; curr_frames++;
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--; if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--; if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--;
} }
@ -913,7 +913,7 @@ inline void show_screen_precision (int tstados) {
}*/ }*/
} }
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--; if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--; if (ordenador.pause_fastload_countdwn>0) ordenador.pause_fastload_countdwn--;
@ -1243,13 +1243,13 @@ inline void read_keyboard () {
case SDLK_F5: // STOP tape case SDLK_F5: // STOP tape
//if ((ordenador.tape_fast_load == 0)) //if ((ordenador.tape_fast_load == 0))
ordenador.pause = 1; ordenador.tape_stop = 1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
break; break;
case SDLK_F6: // PLAY tape case SDLK_F6: // PLAY tape
//if (ordenador.tape_fast_load == 0) //if (ordenador.tape_fast_load == 0)
ordenador.pause = 0; ordenador.tape_stop = 0;
break; break;
case SDLK_F9: case SDLK_F9:
@ -1553,7 +1553,7 @@ inline void read_keyboard () {
ordenador.js = ordenador.jk; ordenador.js = ordenador.jk;
if (joybutton_matrix[0][SDLK_F6] && (ordenador.tape_fast_load == 0)) if (joybutton_matrix[0][SDLK_F6] && (ordenador.tape_fast_load == 0))
ordenador.pause = 0; //Play the tape ordenador.tape_stop = 0; //Play the tape
//Virtual Keyboard //Virtual Keyboard
@ -1706,7 +1706,7 @@ void ResetComputer () {
microdrive_reset(); microdrive_reset();
ordenador.pause = 1; ordenador.tape_stop = 1;
if (ordenador.rewind_on_reset) if (ordenador.rewind_on_reset)
{ {
@ -2046,7 +2046,7 @@ void Z80free_Out (register word Port, register byte Value) {
ordenador.port254 = (unsigned char) Value; ordenador.port254 = (unsigned char) Value;
ordenador.border = (((unsigned char) Value) & 0x07); ordenador.border = (((unsigned char) Value) & 0x07);
if (ordenador.pause) { if (ordenador.tape_stop) {
if (Value & 0x10) if (Value & 0x10)
ordenador.sound_bit = 1; ordenador.sound_bit = 1;
else else
@ -2098,7 +2098,7 @@ void Z80free_Out_fake (register word Port, register byte Value) {
ordenador.port254 = (unsigned char) Value; ordenador.port254 = (unsigned char) Value;
ordenador.border = (((unsigned char) Value) & 0x07); ordenador.border = (((unsigned char) Value) & 0x07);
if (ordenador.pause) { if (ordenador.tape_stop) {
if (Value & 0x10) if (Value & 0x10)
ordenador.sound_bit = 1; ordenador.sound_bit = 1;
else else
@ -2196,7 +2196,7 @@ byte Z80free_In (register word Port) {
if (!(temporal_io & 0x8000)) if (!(temporal_io & 0x8000))
pines &= ordenador.s15; pines &= ordenador.s15;
if (ordenador.pause) { if (ordenador.tape_stop) {
if (ordenador.issue == 2) { if (ordenador.issue == 2) {
if (ordenador.port254 & 0x18) if (ordenador.port254 & 0x18)
pines |= 0x40; pines |= 0x40;

View File

@ -167,7 +167,7 @@ struct computer {
enum tapmodes tape_current_mode; enum tapmodes tape_current_mode;
enum block_type next_block; enum block_type next_block;
unsigned char pause; // 1=tape stop unsigned char tape_stop; // 1=tape stop
enum taptypes tape_file_type; enum taptypes tape_file_type;
unsigned int tape_counter0; unsigned int tape_counter0;
unsigned int tape_counter1; unsigned int tape_counter1;

View File

@ -1555,7 +1555,7 @@ int main(int argc,char *argv[]) {
else else
{ {
ordenador.tape_start_countdwn=0; //Stop tape play countdown ordenador.tape_start_countdwn=0; //Stop tape play countdown
if (ordenador.pause ==1) fastload_block_tzx(ordenador.tap_file); if (ordenador.tape_stop ==1) fastload_block_tzx(ordenador.tap_file);
} }
} }
} }

View File

@ -243,6 +243,11 @@ static void insert_tape()
{ {
ordenador.current_tap[0] = '\0'; ordenador.current_tap[0] = '\0';
free((void *)filename); free((void *)filename);
if(ordenador.tap_file!=NULL) {
fclose(ordenador.tap_file);
}
ordenador.tap_file=NULL;
ordenador.tape_file_type = TAP_TAP;
return; return;
} }
@ -435,17 +440,17 @@ static int manage_tape(int which)
break; break;
case 2: //Play case 2: //Play
//if (ordenador.tape_fast_load == 0) //if (ordenador.tape_fast_load == 0)
ordenador.pause = 0; ordenador.tape_stop = 0;
retorno=-1; retorno=-1;
break; break;
case 3: //Stop case 3: //Stop
//if (ordenador.tape_fast_load == 0) //if (ordenador.tape_fast_load == 0)
ordenador.pause = 1; ordenador.tape_stop = 1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
retorno=-1; retorno=-1;
break; break;
case 4: //Rewind case 4: //Rewind
ordenador.pause=1; ordenador.tape_stop=1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
if(ordenador.tap_file!=NULL) { if(ordenador.tap_file!=NULL) {
ordenador.tape_current_mode=TAP_TRASH; ordenador.tape_current_mode=TAP_TRASH;

View File

@ -632,12 +632,12 @@ void taps_menu() {
fin=0; fin=0;
break; break;
case SDLK_1: case SDLK_1:
//ordenador.pause=1; //ordenador.tape_stop=1;
select_tapfile(); select_tapfile();
break; break;
case SDLK_2: case SDLK_2:
fin=0; fin=0;
ordenador.pause=1; ordenador.tape_stop=1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
if(ordenador.tap_file!=NULL) { if(ordenador.tap_file!=NULL) {
ordenador.tape_current_mode=TAP_TRASH; ordenador.tape_current_mode=TAP_TRASH;
@ -647,7 +647,7 @@ void taps_menu() {
ordenador.osd_time=50; ordenador.osd_time=50;
break; break;
case SDLK_3: case SDLK_3:
ordenador.pause=1; ordenador.tape_stop=1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
ordenador.tape_fast_load=1-ordenador.tape_fast_load; ordenador.tape_fast_load=1-ordenador.tape_fast_load;
if(ordenador.tap_file!=NULL) { if(ordenador.tap_file!=NULL) {

View File

@ -41,7 +41,7 @@ char elbit=0;
inline void tape_read(FILE *fichero, int tstados) { inline void tape_read(FILE *fichero, int tstados) {
if(ordenador.pause) if(ordenador.tape_stop)
{ {
if ((ordenador.turbo_state != 0)&&(ordenador.turbo==1)) if ((ordenador.turbo_state != 0)&&(ordenador.turbo==1))
{ {
@ -79,9 +79,14 @@ inline void tape_read_tap (FILE * fichero, int tstados) {
int retval; int retval;
if (fichero == NULL) if (fichero == NULL)
{
sprintf (ordenador.osd_text, "No tape selected");
ordenador.osd_time = 100;
ordenador.tape_stop=1; //Stop the tape
return; return;
}
if (!ordenador.pause) { if (!ordenador.tape_stop) {
if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block
retval=fread (&value, 1, 1, fichero); retval=fread (&value, 1, 1, fichero);
retval=fread (&value2, 1, 1, fichero); // read block longitude retval=fread (&value2, 1, 1, fichero); // read block longitude
@ -183,7 +188,7 @@ inline void tape_read_tap (FILE * fichero, int tstados) {
break; break;
case TAP_STOP: case TAP_STOP:
ordenador.tape_current_mode = TAP_TRASH; // initialize ordenador.tape_current_mode = TAP_TRASH; // initialize
ordenador.pause = 1; // pause it ordenador.tape_stop = 1; // pause it
break; break;
default: default:
break; break;
@ -199,7 +204,15 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
static unsigned int bucle,bucle2; static unsigned int bucle,bucle2;
int retval; int retval;
if ((fichero == NULL)||(ordenador.pause)) if (fichero == NULL)
{
sprintf (ordenador.osd_text, "No tape selected");
ordenador.osd_time = 100;
ordenador.tape_stop=1; //Stop the tape
return;
}
if (ordenador.tape_stop)
return; return;
if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block
@ -431,7 +444,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
for(bucle=0;bucle<4;bucle++) for(bucle=0;bucle<4;bucle++)
retval=fread(&value,1,1,fichero); retval=fread(&value,1,1,fichero);
if(ordenador.mode128k==0) { if(ordenador.mode128k==0) {
ordenador.pause = 1; ordenador.tape_stop = 1;
ordenador.tape_start_countdwn=0; ordenador.tape_start_countdwn=0;
return; return;
} }
@ -619,7 +632,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
ordenador.tape_counter_rep = 0; ordenador.tape_counter_rep = 0;
ordenador.tape_current_mode = TAP_TRASH; // read new block ordenador.tape_current_mode = TAP_TRASH; // read new block
ordenador.next_block= NOBLOCK; ordenador.next_block= NOBLOCK;
ordenador.pause = 1; ordenador.tape_stop = 1;
} }
break; break;
case TZX_PURE_TONE: case TZX_PURE_TONE:
@ -649,7 +662,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
ordenador.tape_current_bit = 0; ordenador.tape_current_bit = 0;
ordenador.tape_current_mode = TAP_TRASH; // initialize ordenador.tape_current_mode = TAP_TRASH; // initialize
ordenador.next_block= NOBLOCK; ordenador.next_block= NOBLOCK;
ordenador.pause = 1; // pause it ordenador.tape_stop = 1; // pause it
break; break;
default: default:
break; break;
@ -667,7 +680,7 @@ void rewind_tape(FILE *fichero,unsigned char pause) {
for(thebucle=0;thebucle<10;thebucle++) for(thebucle=0;thebucle<10;thebucle++)
retval=fread(&value,1,1,ordenador.tap_file); // jump over the header retval=fread(&value,1,1,ordenador.tap_file); // jump over the header
ordenador.next_block= NOBLOCK; ordenador.next_block= NOBLOCK;
ordenador.pause=pause; ordenador.tape_stop=pause;
if (pause) ordenador.tape_start_countdwn=0; //Stop tape play countdown if (pause) ordenador.tape_start_countdwn=0; //Stop tape play countdown
} }
@ -905,29 +918,17 @@ void fastload_block_tzx (FILE * fichero) {
* Other registers unchanged. * Other registers unchanged.
*/ */
unsigned int longitud, len, bucle, number_bytes, byte_position; unsigned int longitud, len, bucle, number_bytes, byte_position, byte_position2, retorno;
unsigned char value[65536], empty, blockid, parity, pause[2],flag_byte; unsigned char value[65536], empty, blockid, parity, pause[2],flag_byte;
int retval, retval2; int retval;
//ordenador.other_ret = 1; // next instruction must be RET
procesador.PC=0x5e2;
longitud =0; longitud =0;
pause[0]=pause[1]=0; pause[0]=pause[1]=0;
if (!(procesador.Ra.br.F & F_C)) { // if Carry=0, is VERIFY, so return OK
procesador.Rm.br.F |= F_C; // verify OK
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0;
return;
}
procesador.Rm.br.B=0;
procesador.Rm.br.L=0x01;
empty=file_empty(fichero); empty=file_empty(fichero);
if ((fichero == NULL)||(empty)) { if ((fichero == NULL)||(empty)) {
procesador.PC=0x5e2;
procesador.Rm.br.F &= (~F_C); // Load error procesador.Rm.br.F &= (~F_C); // Load error
procesador.Rm.wr.IX += procesador.Rm.wr.DE; procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0; procesador.Rm.wr.DE = 0;
@ -940,6 +941,8 @@ void fastload_block_tzx (FILE * fichero) {
} }
do { do {
retorno=0;
byte_position=ftell(fichero);
retval=fread (&blockid, 1, 1, fichero); //Read id block retval=fread (&blockid, 1, 1, fichero); //Read id block
if (feof (fichero)) // end of file? if (feof (fichero)) // end of file?
{ {
@ -952,8 +955,10 @@ void fastload_block_tzx (FILE * fichero) {
switch(blockid) { switch(blockid) {
case 0x10: // classic tape block case 0x10: // classic tape block
retval=fread (pause, 1, 2, fichero); //pause lenght retval=fread (pause, 1, 2, fichero); //pause lenght
retval2=fread (value, 1, 2, fichero); // read length of current block retval=fread (value, 1, 2, fichero); // read length of current block
if ((retval!=2)||(retval2!=2)) byte_position2=ftell(fichero);
retval=fread (&flag_byte, 1, 1, fichero);
if ((retval!=1))
{ {
procesador.Rm.br.F &= (~F_C); // Load error procesador.Rm.br.F &= (~F_C); // Load error
procesador.Rm.wr.IX += procesador.Rm.wr.DE; procesador.Rm.wr.IX += procesador.Rm.wr.DE;
@ -962,9 +967,7 @@ void fastload_block_tzx (FILE * fichero) {
return; return;
} }
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]); longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
byte_position=ftell(fichero);
retval=fread (&flag_byte, 1, 1, fichero);
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
switch(flag_byte) switch(flag_byte)
{ {
case 0x00: //header case 0x00: //header
@ -992,60 +995,45 @@ void fastload_block_tzx (FILE * fichero) {
ordenador.next_block=NOBLOCK; ordenador.next_block=NOBLOCK;
break; break;
} }
fseek(fichero, byte_position, SEEK_SET); retorno=1;
fseek(fichero, byte_position2, SEEK_SET);
break; break;
case 0x11: // turbo case 0x11: // turbo
retval=fread(value,1,0x0F, fichero); retorno=2;
retval=fread (value, 1,3 ,fichero); // read length of current block
if (retval!=3) {procesador.Rm.br.F &= (~F_C);return;}
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1])+ 65536 * ((unsigned int) value[2]);
for(bucle=0;bucle<longitud;bucle++)
retval=fread(value,1,1, fichero);
break; break;
case 0x12: // pure tone case 0x12: // pure tone
retval=fread(value,1,4,fichero); retorno=2;
break; break;
case 0x13: // multiple pulses case 0x13: // multiple pulses
retval=fread(value,1,1,fichero); // number of pulses retorno=2;
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
if(value[0] != 0)
{
retval=fread(&value,1,2,fichero); // length of pulse in T-states
}
break; break;
case 0x14: // turbo tape block case 0x14: // turbo tape block
retval=fread(value,1,0x07, fichero); retorno=2;
retval=fread (value, 1, 3, fichero); // read length of current block
if (retval!=3) {procesador.Rm.br.F &= (~F_C);return;}
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1])+ 65536 * ((unsigned int) value[2]);
for(bucle=0;bucle<longitud;bucle++)
retval=fread(value,1,1, fichero);
break; break;
case 0x20: // pause case 0x20: // pause
retval=fread(value,1,2,fichero); retval=fread(value,1,2,fichero);
if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;} if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;}
if (!value[0]&&!value[1]) {return;} //stop the tape if (!value[0]&&!value[1]) {retorno=2;} //stop the tape
break; break;
case 0x21: // group start case 0x21: // group start
retval=fread(value,1,1,fichero); retorno=2;
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
len = (unsigned int) value[0];
retval=fread(value,1,len,fichero);
break; break;
case 0x22: // group end case 0x22: // group end
retorno=2;
break; break;
case 0x24: // loop start case 0x24: // loop start
retval=fread(value,1,2, fichero); retorno=2;
break; break;
case 0x25: // loop end case 0x25: // loop end
retorno=2;
break; break;
case 0x28: // select block case 0x28: // select block
@ -1056,12 +1044,7 @@ void fastload_block_tzx (FILE * fichero) {
break; break;
case 0x2A: // pause if 48K case 0x2A: // pause if 48K
retval=fread(value,1,4,fichero); retorno=2;
if(ordenador.mode128k==0) {
ordenador.pause = 1;
ordenador.tape_start_countdwn=0;
return;
}
break; break;
case 0x30: // text description case 0x30: // text description
@ -1114,16 +1097,35 @@ void fastload_block_tzx (FILE * fichero) {
break; break;
default: // not supported default: // not supported
procesador.Rm.br.F &= (~F_C);return; //Tape error retorno=2;
break; break;
} }
} while ((blockid!=0x10)&&(!feof(fichero))); } while ((retorno==0)&&(!feof(fichero)));
if (feof(fichero)) {procesador.Rm.br.F &= (~F_C);return;} if (feof(fichero)) {retorno=2;}
if (retorno==2)
{
fseek(fichero, byte_position, SEEK_SET);
ordenador.tape_stop=1; //Start the tape
return;
}
//Fast load routine //Fast load routine
retval=fread (value, 1,1, fichero); //Flag Byte procesador.PC=0x5e2;
if (!(procesador.Ra.br.F & F_C)) { // if Carry=0, is VERIFY, so return OK
procesador.Rm.br.F |= F_C; // verify OK
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0;
return;
}
procesador.Rm.br.B=0;
procesador.Rm.br.L=0x01;
retval=fread (&flag_byte, 1,1, fichero); //Flag Byte
if (retval!=1) if (retval!=1)
{ {
procesador.Rm.br.F &= (~F_C); // Load error procesador.Rm.br.F &= (~F_C); // Load error
@ -1134,9 +1136,9 @@ void fastload_block_tzx (FILE * fichero) {
} }
longitud--; longitud--;
printf("TZX: Flag_byte_fast: %X en %ld\n",value[0],ftell(fichero)); printf("TZX: Flag_byte_fast: %X en %ld\n",flag_byte,ftell(fichero));
if (value[0] != procesador.Ra.br.A) // different flag if (flag_byte != procesador.Ra.br.A) // different flag
{ {
procesador.Rm.br.F &= (~F_C); // Load error procesador.Rm.br.F &= (~F_C); // Load error
procesador.Rm.wr.IX += procesador.Rm.wr.DE; procesador.Rm.wr.IX += procesador.Rm.wr.DE;
@ -1146,7 +1148,7 @@ void fastload_block_tzx (FILE * fichero) {
return; return;
} }
parity=(byte) value[0]; parity=(byte) flag_byte;
if ((longitud-1)!=procesador.Rm.wr.DE) if ((longitud-1)!=procesador.Rm.wr.DE)
{ {