mirror of
https://github.com/Oibaf66/fbzx-wii.git
synced 2025-01-12 16:49:08 +01:00
improved instant load, tzx instant load, tzx text on screen, shorten 128k load command, increased tape speed
This commit is contained in:
parent
1d83a75fe5
commit
a654a30323
@ -62,7 +62,7 @@ void printchar(unsigned char *memo, unsigned char carac, int x, int y, unsigned
|
||||
|
||||
void print_string(unsigned char *memo, char *cadena, int x, int y, unsigned char color, unsigned char back, int width) {
|
||||
|
||||
int length, ncarac, bucle, xx;
|
||||
int length, ncarac, bucle, xx,yy, nr;
|
||||
int xxx, yyy;
|
||||
int w,h;
|
||||
unsigned char *str2;
|
||||
@ -79,12 +79,12 @@ void print_string(unsigned char *memo, char *cadena, int x, int y, unsigned char
|
||||
}
|
||||
|
||||
for (ncarac=0,str2=cadena;*str2;str2++) {
|
||||
if ((*str2)>=' ') {
|
||||
if (((*str2)>=' ')||(*str2==13)) {
|
||||
ncarac++;
|
||||
}
|
||||
}
|
||||
length=w * ncarac;
|
||||
|
||||
|
||||
if (length > width) {
|
||||
if (x>=0)
|
||||
xx=x;
|
||||
@ -96,9 +96,14 @@ void print_string(unsigned char *memo, char *cadena, int x, int y, unsigned char
|
||||
else
|
||||
xx=x;
|
||||
}
|
||||
|
||||
|
||||
nr=length/width;
|
||||
yy=y-h*nr;
|
||||
|
||||
if (yy<0) yy=0;
|
||||
|
||||
xxx=xx;
|
||||
yyy=y;
|
||||
yyy=yy;
|
||||
str2=cadena;
|
||||
for (bucle=0;bucle<ncarac;bucle++) {
|
||||
while ((*str2)<' ') {
|
||||
@ -112,7 +117,12 @@ void print_string(unsigned char *memo, char *cadena, int x, int y, unsigned char
|
||||
str2+=2;
|
||||
continue;
|
||||
}
|
||||
printf("Error de cadena %d %s\n",*str2,cadena);
|
||||
if (*str2==13) {
|
||||
*(str2)=' ';
|
||||
str2++;
|
||||
continue;
|
||||
}
|
||||
//printf("Error de cadena %d %s\n",*str2,cadena);
|
||||
str2++;
|
||||
}
|
||||
if ((*str2)<=127) {
|
||||
|
@ -130,7 +130,7 @@ void computer_init () { //Called only on start-up
|
||||
ordenador.s8 = ordenador.s9 = ordenador.s10 = ordenador.s11 =
|
||||
ordenador.s12 = ordenador.s13 = ordenador.s14 =
|
||||
ordenador.s15 = 0xFF;
|
||||
ordenador.tab_extended=0;
|
||||
//ordenador.tab_extended=0;
|
||||
ordenador.esc_again=0;
|
||||
|
||||
ordenador.js = 0x00;
|
||||
@ -647,19 +647,23 @@ inline void show_screen (int tstados) {
|
||||
if (ordenador.osd_time) {
|
||||
ordenador.osd_time--;
|
||||
if (ordenador.osd_time==0) {
|
||||
ordenador.tab_extended=0;
|
||||
//ordenador.tab_extended=0;
|
||||
ordenador.esc_again=0;
|
||||
}
|
||||
|
||||
if (ordenador.osd_time)
|
||||
print_string (ordenador.screenbuffer,ordenador.osd_text, -1,450, 12, 0,ordenador.screen_width);
|
||||
else {
|
||||
/*else {
|
||||
if (ordenador.zaurus_mini==0)
|
||||
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
|
||||
else
|
||||
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay
|
||||
|
||||
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
|
||||
|
||||
if (ordenador.mustlock) {
|
||||
SDL_UnlockSurface (ordenador.screen);
|
||||
@ -886,19 +890,23 @@ inline void show_screen_precision (int tstados) {
|
||||
if (ordenador.osd_time) {
|
||||
ordenador.osd_time--;
|
||||
if (ordenador.osd_time==0) {
|
||||
ordenador.tab_extended=0;
|
||||
//ordenador.tab_extended=0;
|
||||
ordenador.esc_again=0;
|
||||
}
|
||||
|
||||
if (ordenador.osd_time)
|
||||
print_string (ordenador.screenbuffer,ordenador.osd_text, -1,450, 12, 0,ordenador.screen_width);
|
||||
else {
|
||||
/*else {
|
||||
if (ordenador.zaurus_mini==0)
|
||||
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
|
||||
else
|
||||
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (ordenador.tape_start_countdwn==1) ordenador.pause=0; //Autoplay
|
||||
|
||||
if (ordenador.tape_start_countdwn>0) ordenador.tape_start_countdwn--;
|
||||
|
||||
if (ordenador.mustlock) {
|
||||
SDL_UnlockSurface (ordenador.screen);
|
||||
@ -1224,12 +1232,12 @@ inline void read_keyboard () {
|
||||
break;
|
||||
|
||||
case SDLK_F5: // STOP tape
|
||||
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
|
||||
//if ((ordenador.tape_fast_load == 0))
|
||||
ordenador.pause = 1;
|
||||
break;
|
||||
|
||||
case SDLK_F6: // PLAY tape
|
||||
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
|
||||
//if (ordenador.tape_fast_load == 0)
|
||||
ordenador.pause = 0;
|
||||
break;
|
||||
|
||||
@ -1501,7 +1509,7 @@ inline void read_keyboard () {
|
||||
ordenador.s15 = (ordenador.s15 & 0xE0)| (ordenador.k15 ^ 0x1F);
|
||||
ordenador.js = ordenador.jk;
|
||||
|
||||
if (joybutton_matrix[0][SDLK_F6] && ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX)))
|
||||
if (joybutton_matrix[0][SDLK_F6] && (ordenador.tape_fast_load == 0))
|
||||
ordenador.pause = 0; //Play the tape
|
||||
|
||||
//Virtual Keyboard
|
||||
@ -1664,6 +1672,7 @@ void ResetComputer () {
|
||||
}
|
||||
}
|
||||
ordenador.precision=ordenador.precision_old; //in case the machine is reset during loading
|
||||
ordenador.tape_start_countdwn=0;
|
||||
}
|
||||
|
||||
// check if there's contention and waits the right number of tstates
|
||||
|
@ -100,7 +100,7 @@ struct computer {
|
||||
unsigned char s8,s9,s10,s11,s12,s13,s14,s15;
|
||||
unsigned char k8,k9,k10,k11,k12,k13,k14,k15;
|
||||
unsigned char readed;
|
||||
unsigned char tab_extended;
|
||||
//unsigned char tab_extended;
|
||||
unsigned char esc_again;
|
||||
|
||||
// kempston joystick private global variables
|
||||
@ -187,6 +187,7 @@ struct computer {
|
||||
unsigned int tape_bit1_level;
|
||||
unsigned char tape_bits_at_end;
|
||||
unsigned int tape_loop_counter;
|
||||
unsigned int tape_start_countdwn;
|
||||
long tape_loop_pos;
|
||||
|
||||
unsigned char tape_write; // 0 can't write; 1 can write
|
||||
|
@ -1530,9 +1530,12 @@ int main(int argc,char *argv[]) {
|
||||
/* if PC is 0x0556, a call to LD_BYTES has been made, so if
|
||||
FAST_LOAD is 1, we must load the block in memory and return */
|
||||
|
||||
if((!ordenador.mdr_paged)&&(PC==0x0556) && (ordenador.tape_fast_load==1)&&(ordenador.tape_file_type==TAP_TAP)) {
|
||||
if((!ordenador.mdr_paged)&&(PC==0x056c) && (ordenador.tape_fast_load==1)) {
|
||||
if(ordenador.tap_file!=NULL)
|
||||
fastload_block(ordenador.tap_file);
|
||||
{
|
||||
if (ordenador.tape_file_type==TAP_TAP) fastload_block_tap(ordenador.tap_file);
|
||||
else fastload_block_tzx(ordenador.tap_file);
|
||||
}
|
||||
else {
|
||||
sprintf(ordenador.osd_text,"No TAP file selected");
|
||||
ordenador.osd_time=50;
|
||||
|
@ -80,7 +80,7 @@ static const char *emulation_messages[] = {
|
||||
/*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp|NTSC",
|
||||
/*02*/ "Frame rate",
|
||||
/*03*/ "^|100%|50%|33%|25%|20%",
|
||||
/*04*/ "Tap instant load",
|
||||
/*04*/ "Tape instant load",
|
||||
/*05*/ "^|on|off",
|
||||
/*06*/ "Turbo mode",
|
||||
/*07*/ "^|off|auto|fast|ultrafast",
|
||||
@ -369,8 +369,9 @@ static int manage_tape(int which)
|
||||
break;
|
||||
case 1: //Emulate load ""
|
||||
countdown_buffer=8;
|
||||
if (ordenador.mode128k==4) //Spanish 128k
|
||||
{
|
||||
switch (ordenador.mode128k)
|
||||
{
|
||||
case 4://Spanish 128k
|
||||
ordenador.keyboard_buffer[0][8]= SDLK_l;
|
||||
ordenador.keyboard_buffer[1][8]= 0;
|
||||
ordenador.keyboard_buffer[0][7]= SDLK_o;
|
||||
@ -388,9 +389,18 @@ static int manage_tape(int which)
|
||||
ordenador.keyboard_buffer[0][1]= SDLK_F6; //F6 - play
|
||||
ordenador.keyboard_buffer[1][1]= 0;
|
||||
ordenador.kbd_buffer_pointer=8;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case 3: //+3
|
||||
case 2: //+2
|
||||
case 1: //128k
|
||||
ordenador.keyboard_buffer[0][2]= SDLK_RETURN; // Return
|
||||
ordenador.keyboard_buffer[1][2]= 0;
|
||||
ordenador.keyboard_buffer[0][1]= SDLK_F6; //F6 - play
|
||||
ordenador.keyboard_buffer[1][1]= 0;
|
||||
ordenador.kbd_buffer_pointer=2;
|
||||
break;
|
||||
case 0: //48k
|
||||
default:
|
||||
ordenador.keyboard_buffer[0][5]= SDLK_j; //Load
|
||||
ordenador.keyboard_buffer[1][5]= 0;
|
||||
ordenador.keyboard_buffer[0][4]= SDLK_p; //"
|
||||
@ -402,16 +412,17 @@ static int manage_tape(int which)
|
||||
ordenador.keyboard_buffer[0][1]= SDLK_F6; //F6
|
||||
ordenador.keyboard_buffer[1][1]= 0;
|
||||
ordenador.kbd_buffer_pointer=5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
retorno=-1;
|
||||
break;
|
||||
break;
|
||||
case 2: //Play
|
||||
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
|
||||
//if (ordenador.tape_fast_load == 0)
|
||||
ordenador.pause = 0;
|
||||
retorno=-1;
|
||||
break;
|
||||
case 3: //Stop
|
||||
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
|
||||
//if (ordenador.tape_fast_load == 0)
|
||||
ordenador.pause = 1;
|
||||
retorno=-1;
|
||||
break;
|
||||
@ -1088,7 +1099,7 @@ static int save_scr(int i)
|
||||
|
||||
switch(retorno) {
|
||||
case 0:
|
||||
if (i==1) msgInfo("SCR1 saved",3000,NULL); else msgInfo("SCR2 saved",3000,NULL);
|
||||
if (i==1) msgInfo("Screen 1 saved",3000,NULL); else msgInfo("Screen 2 saved",3000,NULL);
|
||||
retorno2=-2; //come back to emulator
|
||||
break;
|
||||
case -1:
|
||||
|
488
src/tape.c
488
src/tape.c
@ -24,6 +24,15 @@
|
||||
#include "menus.h"
|
||||
#include "tape.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
extern FILE *fdebug;
|
||||
#define printf(...) fprintf(fdebug,__VA_ARGS__)
|
||||
#else
|
||||
#ifdef GEKKO
|
||||
#define printf(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int elcontador=0;
|
||||
int eltstado=0;
|
||||
char elbit=0;
|
||||
@ -47,7 +56,8 @@ inline void tape_read(FILE *fichero, int tstados) {
|
||||
//Auto ultra fast mode
|
||||
if ((ordenador.turbo_state != 4)&&(ordenador.turbo==1))
|
||||
{
|
||||
update_frequency(11000000);
|
||||
if (ordenador.tape_file_type==TAP_TAP) update_frequency(13000000);
|
||||
else update_frequency(11000000);
|
||||
jump_frames=7;
|
||||
ordenador.precision_old=ordenador.precision;
|
||||
ordenador.precision =0;
|
||||
@ -82,6 +92,7 @@ inline void tape_read_tap (FILE * fichero, int tstados) {
|
||||
}
|
||||
ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2);
|
||||
retval=fread (&(ordenador.tape_byte), 1, 1, fichero);
|
||||
printf("TAP: Flag_byte_norm: %X en %ld\n",ordenador.tape_byte,ftell(fichero));
|
||||
ordenador.tape_bit = 0x80;
|
||||
ordenador.tape_current_mode = TAP_GUIDE;
|
||||
ordenador.tape_counter0 = 2168;
|
||||
@ -139,8 +150,8 @@ inline void tape_read_tap (FILE * fichero, int tstados) {
|
||||
ordenador.tape_counter0 = 1710 - tstados;
|
||||
ordenador.tape_counter1 = 1710;
|
||||
} else {
|
||||
ordenador.tape_counter0 = 851 - tstados;
|
||||
ordenador.tape_counter1 = 852;
|
||||
ordenador.tape_counter0 = 855 - tstados;
|
||||
ordenador.tape_counter1 = 855;
|
||||
}
|
||||
ordenador.tape_bit = ((ordenador.tape_bit >> 1) & 0x7F); // from bit0 to bit7
|
||||
if (!ordenador.tape_bit) {
|
||||
@ -195,7 +206,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
|
||||
done = 0;
|
||||
do {
|
||||
retval=fread(&value,1,1,fichero); // read block ID
|
||||
//printf("ID: %X en %d\n",value,ftell(fichero));
|
||||
printf("TZX:ID_normal: %X en %ld\n",value,ftell(fichero));
|
||||
if(feof(fichero))
|
||||
done = 1;
|
||||
else
|
||||
@ -204,7 +215,7 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
|
||||
done = 1;
|
||||
bucle = 0;
|
||||
ordenador.tape_current_bit = 0;
|
||||
ordenador.tape_bit0_level = 852;
|
||||
ordenador.tape_bit0_level = 855;
|
||||
ordenador.tape_bit1_level = 1710;
|
||||
ordenador.tape_bits_at_end = 8;
|
||||
ordenador.tape_block_level = 2168;
|
||||
@ -431,9 +442,14 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
|
||||
|
||||
case 0x31: // show text
|
||||
retval=fread(&value2,1,1,fichero);
|
||||
if (value2 < 11) ordenador.osd_time=value2*50; else ordenador.osd_time=500; //max 10 sec
|
||||
retval=fread(&value2,1,1,fichero); // length
|
||||
for(bucle=0;bucle<((unsigned int)value2);bucle++)
|
||||
retval=fread(&value3,1,1,fichero);
|
||||
{
|
||||
retval=fread(&value3,1,1,fichero);
|
||||
if (bucle<199) ordenador.osd_text[bucle] = value3;
|
||||
}
|
||||
if (bucle>199) ordenador.osd_text[199]=0; else ordenador.osd_text[bucle]=0;
|
||||
break;
|
||||
|
||||
case 0x32: // archive info
|
||||
@ -704,21 +720,40 @@ void save_file(FILE *fichero) {
|
||||
return;
|
||||
}
|
||||
|
||||
void fastload_block (FILE * fichero) {
|
||||
void fastload_block_tap (FILE * fichero) {
|
||||
|
||||
unsigned int longitud;
|
||||
unsigned char value[65536], salir,empty,flag_found;
|
||||
unsigned int veces;
|
||||
/*Frome Fuse On exit:
|
||||
* A = calculated parity byte if parity checked, else 0 (CHECKME)
|
||||
* F : if parity checked, all flags are modified
|
||||
* else carry only is modified (FIXME)
|
||||
* B = 0xB0 (success) or 0x00 (failure)
|
||||
* C = 0x01 (confirmed), 0x21, 0xFE or 0xDE (CHECKME)
|
||||
* DE : decremented by number of bytes loaded or verified
|
||||
* H = calculated parity byte or undefined
|
||||
* L = last byte read, or 1 if none
|
||||
* IX : incremented by number of bytes loaded or verified
|
||||
* A' = unchanged on error + no flag byte, else 0x01
|
||||
* F' = 0x01 on error + no flag byte, else 0x45
|
||||
* R = no point in altering it :-)
|
||||
* Other registers unchanged.
|
||||
*/
|
||||
|
||||
unsigned int longitud, bucle, number_bytes;
|
||||
unsigned char value[65536], empty, parity;
|
||||
int retval;
|
||||
|
||||
ordenador.other_ret = 1; // next instruction must be RET
|
||||
//ordenador.other_ret = 1; // next instruction must be RET
|
||||
procesador.PC=0x5e2;
|
||||
|
||||
if (!(procesador.Rm.br.F & F_C)) { // if Carry=0, is VERIFY, so return OK
|
||||
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);
|
||||
|
||||
@ -735,65 +770,394 @@ void fastload_block (FILE * fichero) {
|
||||
return;
|
||||
}
|
||||
|
||||
veces=0;
|
||||
|
||||
flag_found=0;
|
||||
do {
|
||||
retval=fread (value, 2, 1, fichero); // read length of current block
|
||||
retval=fread (value, 1, 2, fichero); // read length of current block
|
||||
if (feof (fichero)) { // end of file?
|
||||
veces++; // one more time rewinded
|
||||
sprintf (ordenador.osd_text, "Tape rewind");
|
||||
sprintf (ordenador.osd_text, "Rewind tape");
|
||||
ordenador.osd_time = 100;
|
||||
rewind (fichero); // again
|
||||
retval=fread (value, 2, 1, fichero); // read length of current block
|
||||
}
|
||||
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
|
||||
retval=fread (value, 1, 1, fichero); // read flag byte
|
||||
longitud--;
|
||||
if (value[0] != procesador.Rm.br.A) { // different flag
|
||||
retval=fread (value, longitud, 1, fichero); // jump to the next block
|
||||
if (veces==3) { // tape rewinded three times? Block with that flag not found.
|
||||
sprintf(ordenador.osd_text,"Block with right flag not found");
|
||||
ordenador.osd_time = 100;
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
return;
|
||||
rewind_tape(fichero, 1);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
flag_found = 1;
|
||||
} while(flag_found == 0);
|
||||
|
||||
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
|
||||
|
||||
retval=fread (value, 1,1, fichero); //Flag Byte
|
||||
if (retval!=1)
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
printf("TAP: Read file error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
salir = 0;
|
||||
do {
|
||||
if (longitud == 0)
|
||||
salir = 1;
|
||||
if (procesador.Rm.wr.DE == 0)
|
||||
salir = 2;
|
||||
if (!salir) {
|
||||
retval=fread (value, 1, 1, fichero); // read byte
|
||||
Z80free_Wr_fake (procesador.Rm.wr.IX, (byte) value[0]); // store the byte
|
||||
longitud--;
|
||||
printf("TAP: Flag_byte_fast: %X en %ld\n",value[0],ftell(fichero));
|
||||
|
||||
if (value[0] != procesador.Ra.br.A) // different flag
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
retval=fread (value, 1,longitud, fichero); //read the remaining bytes
|
||||
printf("TAP: Flag byte error, expected %X\n", procesador.Ra.br.A);
|
||||
return;
|
||||
}
|
||||
|
||||
parity=(byte) value[0];
|
||||
|
||||
if ((longitud-1)!=procesador.Rm.wr.DE)
|
||||
{
|
||||
printf("TAP: length block error\n");
|
||||
printf("TAP: expected by system %d\n", procesador.Rm.wr.DE);
|
||||
printf("TAP: expected by file %d\n", longitud-1);
|
||||
}
|
||||
|
||||
if (procesador.Rm.wr.DE>(longitud-1))
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
retval=fread (value, 1,longitud, fichero); //read the remaining bytes
|
||||
return;
|
||||
}
|
||||
|
||||
retval=fread (value, 1,longitud, fichero);
|
||||
if (retval!=longitud)
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
printf("TAP: Read file error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
number_bytes=procesador.Rm.wr.DE;
|
||||
|
||||
for(bucle=0;bucle<number_bytes; bucle++)
|
||||
{
|
||||
Z80free_Wr_fake (procesador.Rm.wr.IX, (byte) value[bucle]); // store the byte
|
||||
procesador.Rm.wr.IX++;
|
||||
procesador.Rm.wr.DE--;
|
||||
longitud--;
|
||||
parity^=(byte) value[bucle];
|
||||
}
|
||||
}
|
||||
while (!salir);
|
||||
|
||||
clean_screen ();
|
||||
//clean_screen ();
|
||||
|
||||
if (salir == 1) { // system wants to load more bytes that the existent
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
return;
|
||||
}
|
||||
|
||||
if ((salir == 2) && (longitud != 1)) { // there are more bytes to load
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
if (longitud > 1)
|
||||
retval=fread (value, longitud, 1, fichero); // jump to the next block
|
||||
return;
|
||||
}
|
||||
|
||||
retval=fread (value, 1, 1, fichero); // jump over the checksum
|
||||
parity^=value[number_bytes]; // checksum
|
||||
|
||||
if (parity) printf("TAP: Parity error\n");
|
||||
|
||||
procesador.Rm.br.A=parity;
|
||||
//CP 01
|
||||
Z80free_doArithmetic(&procesador,procesador.Rm.br.A,0x01,0,1);
|
||||
Z80free_adjustFlags(&procesador,0x01);
|
||||
|
||||
procesador.Rm.br.B=0xB0;
|
||||
procesador.Rm.br.C=0x01;
|
||||
procesador.Rm.br.H=parity;
|
||||
procesador.Rm.br.L=value[longitud-1];
|
||||
procesador.Ra.br.A=0x01;
|
||||
procesador.Ra.br.F=0x45;
|
||||
procesador.Rm.br.F |= F_C; // Load OK
|
||||
|
||||
//if (longitud==6913) sleep(2); //Screen
|
||||
return;
|
||||
}
|
||||
|
||||
void fastload_block_tzx (FILE * fichero) {
|
||||
|
||||
/* From Fuse - On exit:
|
||||
* A = calculated parity byte if parity checked, else 0 (CHECKME)
|
||||
* F : if parity checked, all flags are modified
|
||||
* else carry only is modified (FIXME)
|
||||
* B = 0xB0 (success) or 0x00 (failure)
|
||||
* C = 0x01 (confirmed), 0x21, 0xFE or 0xDE (CHECKME)
|
||||
* DE : decremented by number of bytes loaded or verified
|
||||
* H = calculated parity byte or undefined
|
||||
* L = last byte read, or 1 if none
|
||||
* IX : incremented by number of bytes loaded or verified
|
||||
* A' = unchanged on error + no flag byte, else 0x01
|
||||
* F' = 0x01 on error + no flag byte, else 0x45
|
||||
* R = no point in altering it :-)
|
||||
* Other registers unchanged.
|
||||
*/
|
||||
|
||||
unsigned int longitud, len, bucle, number_bytes, byte_position;
|
||||
unsigned char value[65536], empty, blockid, parity;
|
||||
int retval;
|
||||
fpos_t *file_pos;
|
||||
|
||||
|
||||
//ordenador.other_ret = 1; // next instruction must be RET
|
||||
procesador.PC=0x5e2;
|
||||
longitud =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);
|
||||
|
||||
|
||||
if ((fichero == NULL)||(empty)) {
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
if(empty)
|
||||
sprintf (ordenador.osd_text, "Tape file empty");
|
||||
else
|
||||
sprintf (ordenador.osd_text, "No tape selected");
|
||||
ordenador.osd_time = 100;
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
retval=fread (&blockid, 1, 1, fichero); //Read id block
|
||||
if (feof (fichero)) // end of file?
|
||||
{
|
||||
sprintf (ordenador.osd_text, "Rewind tape");
|
||||
ordenador.osd_time = 100;
|
||||
rewind_tape(fichero, 1);
|
||||
return;
|
||||
}
|
||||
printf("TZX: ID_fast: %X en %ld\n",blockid,ftell(fichero));
|
||||
switch(blockid) {
|
||||
case 0x10: // classic tape block
|
||||
retval=fread (value, 1, 2, fichero); //pause lenght
|
||||
retval=fread (value, 1, 2, fichero); // read length of current block
|
||||
if (retval!=2)
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
printf("TZX: Read file error\n");
|
||||
return;
|
||||
}
|
||||
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
|
||||
break;
|
||||
|
||||
case 0x11: // turbo
|
||||
retval=fread(value,1,0x0F, fichero);
|
||||
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;
|
||||
|
||||
case 0x12: // pure tone
|
||||
retval=fread(value,1,4,fichero);
|
||||
break;
|
||||
|
||||
case 0x13: // multiple pulses
|
||||
retval=fread(value,1,1,fichero); // number of pulses
|
||||
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;
|
||||
|
||||
case 0x14: // turbo tape block
|
||||
retval=fread(value,1,0x07, fichero);
|
||||
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;
|
||||
|
||||
case 0x20: // pause
|
||||
retval=fread(value,1,2,fichero);
|
||||
if (retval!=2) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
if (!value[0]&&!value[1]) {procesador.Rm.br.F &= (~F_C);return;} //stop the tape
|
||||
break;
|
||||
|
||||
case 0x21: // group start
|
||||
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
|
||||
break;
|
||||
|
||||
case 0x24: // loop start
|
||||
retval=fread(value,1,2, fichero);
|
||||
break;
|
||||
|
||||
case 0x25: // loop end
|
||||
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);
|
||||
break;
|
||||
|
||||
case 0x2A: // pause if 48K
|
||||
retval=fread(value,1,4,fichero);
|
||||
break;
|
||||
|
||||
case 0x30: // text description
|
||||
retval=fread(value,1,1,fichero); // length
|
||||
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
len = (unsigned int) value[0] ;
|
||||
retval=fread(value,1,len,fichero);
|
||||
break;
|
||||
|
||||
case 0x31: // show text
|
||||
retval=fread(value,1,1,fichero);
|
||||
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
if (value[0] < 11) ordenador.osd_time=value[0]*50; else ordenador.osd_time=500;//max 10 sec
|
||||
retval=fread(value,1,1,fichero); // length
|
||||
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
len = (unsigned int) value[0];
|
||||
for(bucle=0;bucle<len;bucle++)
|
||||
{
|
||||
retval=fread(value,1,1,fichero);
|
||||
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
if (bucle<199) ordenador.osd_text[bucle] = value[0];
|
||||
}
|
||||
if (bucle>199) ordenador.osd_text[199]=0; else ordenador.osd_text[bucle]=0;
|
||||
break;
|
||||
|
||||
case 0x32: // archive info
|
||||
retval=fread(value,1,2,fichero); // length
|
||||
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 0x33: // hardware info
|
||||
retval=fread(value,1,1,fichero);
|
||||
if (retval!=1) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
len = (unsigned int) value[0] *3;
|
||||
retval=fread(value,1,len,fichero);
|
||||
break;
|
||||
|
||||
case 0x34: // emulation info
|
||||
retval=fread(value,1,8,fichero);
|
||||
break;
|
||||
|
||||
case 0x35: // custom info
|
||||
retval=fread(value,1,16,fichero);
|
||||
retval=fread(value,1,4,fichero);
|
||||
if (retval!=4) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
len = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]) + 65536*((unsigned int) value[2]);// + 16777216*((unsigned int) value[3]);
|
||||
retval=fread(value,1,len,fichero);
|
||||
break;
|
||||
|
||||
default: // not supported
|
||||
procesador.Rm.br.F &= (~F_C);return; //Tape error
|
||||
break;
|
||||
}
|
||||
} while ((blockid!=0x10)&&(!feof(fichero)));
|
||||
|
||||
if (feof(fichero)) {procesador.Rm.br.F &= (~F_C);return;}
|
||||
|
||||
//Fast load routine
|
||||
|
||||
retval=fread (value, 1,1, fichero); //Flag Byte
|
||||
if (retval!=1)
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
printf("TZX: Read file error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
longitud--;
|
||||
printf("TZX: Flag_byte_fast: %X en %ld\n",value[0],ftell(fichero));
|
||||
|
||||
if (value[0] != procesador.Ra.br.A) // different flag
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
retval=fread (value, 1,longitud, fichero); //read the remaining bytes
|
||||
printf("TZX Flag byte error, expected %X\n", procesador.Ra.br.A);
|
||||
return;
|
||||
}
|
||||
|
||||
parity=(byte) value[0];
|
||||
|
||||
if ((longitud-1)!=procesador.Rm.wr.DE)
|
||||
{
|
||||
printf("TZX: length block error\n");
|
||||
printf("TZX: expected by system %d\n", procesador.Rm.wr.DE);
|
||||
printf("TZX: expected by file %d\n", longitud-1);
|
||||
}
|
||||
|
||||
if (procesador.Rm.wr.DE>(longitud-1))
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
retval=fread (value, 1,longitud, fichero); //read the remaining bytes
|
||||
return;
|
||||
}
|
||||
|
||||
retval=fread (value, 1,longitud, fichero);
|
||||
if (retval!=longitud)
|
||||
{
|
||||
procesador.Rm.br.F &= (~F_C); // Load error
|
||||
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||
procesador.Rm.wr.DE = 0;
|
||||
printf("TZX: Read file error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
number_bytes=procesador.Rm.wr.DE;
|
||||
|
||||
for(bucle=0;bucle<number_bytes; bucle++)
|
||||
{
|
||||
Z80free_Wr_fake (procesador.Rm.wr.IX, (byte) value[bucle]); // store the byte
|
||||
procesador.Rm.wr.IX++;
|
||||
procesador.Rm.wr.DE--;
|
||||
parity^=(byte) value[bucle];
|
||||
}
|
||||
|
||||
//clean_screen ();
|
||||
|
||||
parity^=value[number_bytes]; // checksum
|
||||
|
||||
if (parity) printf("TZX: Parity error\n");
|
||||
|
||||
procesador.Rm.br.A=parity;
|
||||
//CP 01
|
||||
Z80free_doArithmetic(&procesador,procesador.Rm.br.A,0x01,0,1);
|
||||
Z80free_adjustFlags(&procesador,0x01);
|
||||
|
||||
procesador.Rm.br.B=0xB0;
|
||||
procesador.Rm.br.C=0x01;
|
||||
procesador.Rm.br.H=parity;
|
||||
procesador.Rm.br.L=value[longitud-1];
|
||||
procesador.Ra.br.A=0x01;
|
||||
procesador.Ra.br.F=0x45;
|
||||
procesador.Rm.br.F |= F_C; // Load OK
|
||||
|
||||
//if (longitud==6913) sleep(2); //Screen
|
||||
|
||||
byte_position=ftell(fichero);
|
||||
|
||||
retval=fread (&blockid, 1, 1, fichero); //Read next id block
|
||||
|
||||
if (!feof(fichero))
|
||||
{
|
||||
if ((blockid==0x11)||(blockid==0x12)||(blockid==0x13)||(blockid==0x14)||(blockid==0x21)||(blockid==0x24)) ordenador.tape_start_countdwn=80; //autoplay countdown
|
||||
fseek(fichero, byte_position, SEEK_SET);
|
||||
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
@ -26,7 +26,8 @@ inline void tape_read_tap(FILE *, int);
|
||||
inline void tape_read_tzx(FILE *, int);
|
||||
void rewind_tape(FILE *,unsigned char);
|
||||
unsigned char file_empty(FILE *);
|
||||
void fastload_block (FILE *);
|
||||
void fastload_block_tap (FILE *);
|
||||
void fastload_block_tzx (FILE *);
|
||||
void save_file(FILE *);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user