Added RZX support

This commit is contained in:
fabio.olimpieri 2015-02-25 09:46:20 +00:00
parent 393db594ba
commit 6b1eab6ac5
10 changed files with 364 additions and 21 deletions

View File

@ -17,7 +17,7 @@ include $(DEVKITPPC)/gamecube_rules
#---------------------------------------------------------------------------------
TARGET := fbzx_gc
BUILD := build
SOURCES := src src/z80free src/minizip
SOURCES := src src/z80free src/minizip src/rzx_lib
DATA :=
INCLUDES :=

View File

@ -17,7 +17,7 @@ include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
TARGET := fbzx
BUILD := build
SOURCES := src src/z80free src/minizip src/tinyFTP
SOURCES := src src/z80free src/minizip src/tinyFTP src/rzx_lib
DATA :=
INCLUDES :=

View File

@ -31,7 +31,7 @@ export SHELL=/bin/bash
#---------------------------------------------------------------------------------
TARGET := fbzx-wii
BUILD := build
SOURCES := src src/z80free src/minizip
SOURCES := src src/z80free src/minizip src/rzx_lib
DATA :=
INCLUDES :=

View File

@ -35,6 +35,7 @@
#include "Virtualkeyboard.h"
#include "gui_sdl.h"
#include "menu_sdl.h"
#include "rzx_lib/rzx.h"
#if defined(HW_RVL)
# include <wiiuse/wpad.h>
#endif
@ -770,6 +771,8 @@ inline void show_screen (int tstados) {
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
}
}
else if (ordenador.recording_rzx) print_string (ordenador.screenbuffer,"RZX Recording",-1, 450, 12, 0,ordenador.screen_width);
else if (ordenador.playing_rzx) print_string (ordenador.screenbuffer,"RZX Playing",-1, 450, 12, 0,ordenador.screen_width);
if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
@ -1017,6 +1020,8 @@ inline void show_screen_precision (int tstados) {
print_string (ordenador.screenbuffer," ",-1, 450, 12, 0,ordenador.screen_width);
}
}
else if (ordenador.recording_rzx) print_string (ordenador.screenbuffer,"RZX Recording",-1, 450, 12, 0,ordenador.screen_width);
else if (ordenador.playing_rzx) print_string (ordenador.screenbuffer,"RZX Playing",-1, 450, 12, 0,ordenador.screen_width);
if (ordenador.tape_start_countdwn==1) ordenador.tape_stop=0; //Autoplay
@ -1917,6 +1922,10 @@ void ResetComputer () {
ordenador.currpix=0;
ordenador.interr = 0;
ordenador.recording_rzx=0;
ordenador.playing_rzx=0;
ordenador.icount=0;
currah_microspeech_reset();
}
@ -2060,6 +2069,8 @@ void Z80free_Wr_fake (register word Addr, register byte Value) {
byte Z80free_Rd_fetch (register word Addr) {
ordenador.icount++;
if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I
return((byte)ordenador.shadowrom[Addr]);
@ -2370,11 +2381,23 @@ void Z80free_Out_fake (register word Port, register byte Value) {
}
}
byte Z80free_In (register word Port) {
inline byte Z80free_In_internal (register word Port) {
static unsigned int temporal_io;
static byte pines;
static byte pines, pines_rzx;
if (ordenador.playing_rzx)
{
pines_rzx = rzx_get_input();
if (pines_rzx == RZX_SYNCLOST)
{
msgInfo("RZX sync lost", 4000, NULL);
pines_rzx =0;
ordenador.playing_rzx=0;
rzx_close();
}
}
if (ordenador.precision)
{
@ -2423,6 +2446,7 @@ byte Z80free_In (register word Port) {
}
if (!(temporal_io & 0x0001)) {
if (ordenador.playing_rzx) return (pines_rzx);
pines = 0xBF; // by default, sound bit is 0
if (!(temporal_io & 0x0100))
pines &= ordenador.s8;
@ -2460,6 +2484,7 @@ byte Z80free_In (register word Port) {
// Joystick - Kempston
if (!(temporal_io & 0x0020)) {
if (ordenador.playing_rzx) return (pines_rzx);
if ((ordenador.joystick[0] == 1)||(ordenador.joystick[1] == 1)) {
return (ordenador.js);
} else {
@ -2469,6 +2494,7 @@ byte Z80free_In (register word Port) {
// Joystick - Fuller
if ((temporal_io & 0x00FF)==0x7F) {
if (ordenador.playing_rzx) return (pines_rzx);
if ((ordenador.joystick[0] == 4)||(ordenador.joystick[1] == 4)) {
return (~ordenador.js);
} else {
@ -2492,7 +2518,7 @@ byte Z80free_In (register word Port) {
if ((ordenador.currah_active)&&(temporal_io ==0x0038)) ordenador.currah_paged = !ordenador.currah_paged;
pines=bus_empty();
if (ordenador.playing_rzx) pines = pines_rzx; else pines=bus_empty(); //RZX floating bus emulation
if (ordenador.precision && (ordenador.mode128k==1||ordenador.mode128k==2||(ordenador.mode128k==4)))
{ if (temporal_io == 0x7FFD) Z80free_Out_fake (0x7FFD,pines); //writeback 0X7ffd
@ -2502,6 +2528,14 @@ byte Z80free_In (register word Port) {
return (pines);
}
byte Z80free_In (register word Port) {
byte input;
input = Z80free_In_internal (Port);
if (ordenador.recording_rzx) rzx_store_input(input);
return input;
}
void set_volume (unsigned char volume) {
unsigned char vol2;

View File

@ -207,6 +207,12 @@ struct computer {
unsigned char tape_write; // 0 can't write; 1 can write
//Recording Variable
unsigned char recording_rzx;
unsigned char playing_rzx;
unsigned short int maxicount;
unsigned short int icount;
// Microdrive global variables
FILE *mdr_file; // Current microdrive file
unsigned char mdr_current_mdr[MAX_PATH_LENGTH]; // current path and name for microdrive file

View File

@ -41,6 +41,7 @@
#include "menu_sdl.h"
#include "tape_browser.h"
#include "VirtualKeyboard.h"
#include "rzx_lib/rzx.h"
#include <dirent.h>
@ -84,10 +85,12 @@ char path_paste[MAX_PATH_LENGTH];
char path_copy[MAX_PATH_LENGTH];
char path_delete[MAX_PATH_LENGTH];
char path_tmp[MAX_PATH_LENGTH];
char path_rzx[MAX_PATH_LENGTH];
char load_path_snaps[MAX_PATH_LENGTH];
char load_path_taps[MAX_PATH_LENGTH];
char load_path_scr1[MAX_PATH_LENGTH];
char load_path_poke[MAX_PATH_LENGTH];
char load_path_rzx[MAX_PATH_LENGTH];
char rom_cartridge[MAX_PATH_LENGTH];
char pasted_file[MAX_PATH_LENGTH];
@ -108,6 +111,8 @@ extern int FULL_DISPLAY_X; //640
extern int FULL_DISPLAY_Y; //480
extern int RATIO;
void init_rzx(void);
#ifdef MINGW
#define mkdir(name, mode) mkdir(name)
#endif
@ -660,6 +665,7 @@ void end_system() {
menu_deinit();
font_fini();
SDL_Quit();
rzx_close();
if (!chdir(path_tmp)) {chdir("/"); remove_dir(path_tmp);} //remove the tmp directory if it exists
@ -1543,6 +1549,7 @@ int main(int argc,char *argv[])
strcpy(path_delete,path_snaps);
strcpy(path_copy,path_snaps);
strcpy(path_tmp,path_snaps);
strcpy(path_rzx,path_snaps);
strcat(path_snaps,"snapshots");
strcat(path_taps,"tapes");
strcat(path_mdrs,"microdrives");
@ -1551,9 +1558,11 @@ int main(int argc,char *argv[])
strcat(path_confs,"configurations");
strcat(load_path_poke,"poke");
strcat(path_tmp,"tmp");
strcat(path_rzx,"rzx_files");
strcpy(load_path_snaps,path_snaps);
strcpy(load_path_taps,path_taps);
strcpy(load_path_scr1,path_scr1);
strcpy(load_path_rzx,path_rzx);
pasted_file[0]=0;
@ -1591,6 +1600,7 @@ int main(int argc,char *argv[])
strcpy(load_path_taps,"sd:/");
strcpy(load_path_scr1,"sd:/");
strcpy(load_path_poke,"sd:/");
strcpy(load_path_rzx,"sd:/");
strcpy(path_paste,"sd:/");
}
else ordenador.port =0;
@ -1602,6 +1612,7 @@ int main(int argc,char *argv[])
strcpy(load_path_taps,"usb:/");
strcpy(load_path_scr1,"usb:/");
strcpy(load_path_poke,"usb:/");
strcpy(load_path_rzx,"usb:/");
strcpy(path_paste,"usb:/");
}
else ordenador.port =0;
@ -1613,6 +1624,7 @@ int main(int argc,char *argv[])
strcpy(load_path_taps,"smb:/");
strcpy(load_path_scr1,"smb:/");
strcpy(load_path_poke,"smb:/");
strcpy(load_path_rzx,"smb:/");
strcpy(path_paste,"smb:/");
}
else ordenador.port =0;
@ -1624,6 +1636,7 @@ int main(int argc,char *argv[])
strcpy(load_path_taps,"ftp:/");
strcpy(load_path_scr1,"ftp:/");
strcpy(load_path_poke,"ftp:/");
strcpy(load_path_rzx,"ftp:/");
strcpy(path_paste,"ftp:/");
}
else ordenador.port =0;
@ -1631,6 +1644,8 @@ int main(int argc,char *argv[])
}
#endif
init_rzx();
ordenador.current_tap[0]=0;
// assign random values to the memory before start execution
@ -1778,11 +1793,44 @@ int main(int argc,char *argv[])
read_keyboard (); // read the physical keyboard
ordenador.readkeyboard = 0;
}
if (ordenador.playing_rzx)
{
if (ordenador.icount>=ordenador.maxicount)
{
int error;
if (ordenador.icount!=ordenador.maxicount)
{
printf("Icount in excess= %d\n",ordenador.icount-ordenador.maxicount);
msgInfo("RZX sync lost" , 4000, NULL);
ordenador.playing_rzx=0;
rzx_close();
}
ordenador.icount = 0;
error = rzx_update(&ordenador.maxicount);
if (error == RZX_FINISHED)
{
printf("RZX playing finished\n");
msgInfo("RZX playing finished",4000,NULL);
ordenador.playing_rzx = 0;
}
if (error == RZX_SYNCLOST)
{
msgInfo("RZX sync lost", 4000, NULL);
ordenador.playing_rzx=0;
rzx_close();
}
Z80free_INT(&procesador,255); //Bus always 255
}
}
else
if(ordenador.interr==1) {
Z80free_INT(&procesador,bus_empty());
if ((ordenador.precision==0)||(jump_frames>0)) ordenador.interr=0;
} //else if (ordenador.precision==1) Z80free_INT_reset(&procesador);
if (ordenador.recording_rzx) {rzx_update(&ordenador.icount);ordenador.icount=0;}
}
}
return 0;

View File

@ -43,10 +43,12 @@ extern char path_paste[MAX_PATH_LENGTH];
extern char path_copy[MAX_PATH_LENGTH];
extern char path_delete[MAX_PATH_LENGTH];
extern char path_tmp[MAX_PATH_LENGTH];
extern char path_rzx[MAX_PATH_LENGTH];
extern char load_path_snaps[MAX_PATH_LENGTH];
extern char load_path_taps[MAX_PATH_LENGTH];
extern char load_path_scr1[MAX_PATH_LENGTH];
extern char load_path_poke[MAX_PATH_LENGTH];
extern char load_path_rzx[MAX_PATH_LENGTH];
extern char rom_cartridge[MAX_PATH_LENGTH];
extern char pasted_file[MAX_PATH_LENGTH];

View File

@ -37,6 +37,7 @@
#include "characters.h"
#include "spk_ay.h"
#include "sound.h"
#include "rzx_lib/rzx.h"
#define ID_BUTTON_OFFSET 0
@ -210,12 +211,11 @@ static const char *tools_messages[] = {
#endif
/*08*/ "Keyboard rumble",
/*09*/ "^|on|off",
/*10*/ " ",
/*11*/ "Load poke file",
/*12*/ " ",
/*10*/ "Recording (RZX)",
/*11*/ "^|Record|Play|Stop",
/*12*/ "Load poke file",
/*13*/ "Insert poke",
/*14*/ " ",
/*15*/ "Help",
/*14*/ "Help",
NULL
};
@ -1380,11 +1380,13 @@ static void set_port(int which)
strcpy(load_path_taps,load_path_snaps);
strcpy(load_path_scr1,load_path_snaps);
strcpy(load_path_poke,load_path_snaps);
strcpy(load_path_rzx,load_path_snaps);
strcpy(path_paste,load_path_snaps);
strcat(load_path_snaps,"snapshots");
strcat(load_path_taps,"tapes");
strcat(load_path_scr1,"scr");
strcat(load_path_poke,"poke");
strcat(load_path_rzx,"rzx_files");
ordenador.port = which;
break;
#ifdef HW_RVL
@ -1394,6 +1396,7 @@ static void set_port(int which)
strcpy(load_path_taps,"sd:/");
strcpy(load_path_scr1,"sd:/");
strcpy(load_path_poke,"sd:/");
strcpy(load_path_rzx,"sd:/");
strcpy(path_paste,"sd:/");
ordenador.port = which;}
else
@ -1405,6 +1408,7 @@ static void set_port(int which)
strcpy(load_path_taps,"usb:/");
strcpy(load_path_scr1,"usb:/");
strcpy(load_path_poke,"usb:/");
strcpy(load_path_rzx,"usb:/");
strcpy(path_paste,"usb:/");
ordenador.port = which;}
else
@ -1423,6 +1427,7 @@ static void set_port(int which)
strcpy(load_path_taps,"smb:/");
strcpy(load_path_scr1,"smb:/");
strcpy(load_path_poke,"smb:/");
strcpy(load_path_rzx,"smb:/");
strcpy(path_paste,"smb:/");
ordenador.port = which;}
else
@ -1442,6 +1447,7 @@ static void set_port(int which)
strcpy(load_path_taps,"ftp:/");
strcpy(load_path_scr1,"ftp:/");
strcpy(load_path_poke,"ftp:/");
strcpy(load_path_rzx,"ftp:/");
strcpy(path_paste,"ftp:/");
ordenador.port = which;}
else
@ -1870,10 +1876,103 @@ static int manage_file(int which)
return retorno;
}
static int load_rzx()
{
int retorno;
const char *filename = menu_select_file(load_path_rzx, NULL, 1); // Load from rzx_files
if (filename==NULL) // Aborted
return -1;
if (!(ext_matches(filename, ".rzx")|ext_matches(filename, ".RZX"))) {free((void *)filename); return -1;}
retorno=rzx_playback(filename);
if (retorno!=RZX_OK) //RZX_OK = 0
{
printf("Error starting playback %d\n", retorno);
msgInfo("Error starting playback",3000,NULL);
free((void *)filename);
return -1;
}
free((void *)filename);
return 0; //OK
}
static int save_rzx()
{
int retorno;
unsigned char filename[MAX_PATH_LENGTH], fb[81];
clean_screen();
if (ordenador.last_selected_file && strrchr(ordenador.last_selected_file, '/'))
strncpy(fb, strrchr(ordenador.last_selected_file, '/') + 1, 80);
else
strcpy(fb, "");
retorno=ask_filename_sdl(filename,82,"rzx",path_rzx,fb);
if(retorno==2) // abort
return -1;
if(rzx_record(filename)!=RZX_OK) {printf("RZX: Impossible to create snapshot\n"); return -1;}
return 0;
}
static int do_rzx(int which)
{
int retorno = 0; //Stay in the menu as default
int retorno2;
switch (which)
{
case 0: // Record
ordenador.playing_rzx=0;
ordenador.icount = 0;
retorno2=save_rzx();
if (retorno2) break; //Error
save_z80("temp.z80",1);
if (rzx_add_snapshot("temp.z80", RZX_COMPRESSED)==RZX_OK) printf("RZX: Added snapshot\n");
else {printf("RZX: Impossible to create snapshot\n"); break;}
unlink("temp.z80");
ordenador.recording_rzx=1;
retorno = -2;
break;
case 1: // Play
ordenador.recording_rzx=0;
ordenador.icount = 0;
retorno2 = load_rzx();
if (retorno2) break; //Error or no file
retorno2 = rzx_update(&ordenador.maxicount);
if (retorno2 == RZX_FINISHED) {printf("RZX: Playing finished at fisrt frame\n"); break;}
ordenador.playing_rzx = 1;
retorno = -2; //Come back to the menu
break;
case 2: // stop
ordenador.recording_rzx=0;
ordenador.playing_rzx=0;
rzx_close();
printf("RZX: Stop\n");
retorno = -2;
break;
default:
break;
}
return retorno;
}
static int tools()
{
int opt , retorno;
int submenus[5], old_port;
int submenus[6], old_port;
memset(submenus, 0, sizeof(submenus));
@ -1905,13 +2004,16 @@ static int tools()
case 4:
retorno = manage_file(submenus[2]);
break;
case 11: // Load poke file
case 10:
retorno = do_rzx(submenus[5]);
break;
case 12: // Load poke file
retorno = load_poke_file();
break;
case 13: // Insert poke
retorno = do_poke_sdl();
break;
case 15:
case 14:
help();
retorno = -1;
break;

View File

@ -322,7 +322,7 @@ static const char **get_file_list_zip(const char *path)
break;
}
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA", "rzx", "RZX",
".mdr", ".MDR", ".scr", ".SCR", ".conf", ".CONF",".pok", ".POK" ,".rom", ".ROM", NULL};
if (ext_matches_list(filename_inzip, exts))
@ -374,7 +374,7 @@ static const char **get_file_list(const char *base_dir)
de = readdir(d))
{
char buf[255];
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA", "rzx", "RZX",
".mdr", ".MDR", ".scr", ".SCR", ".conf", ".CONF",".pok", ".POK", ".zip", ".ZIP",".rom", ".ROM",NULL};
struct stat st;

151
src/rzx_init.c Normal file
View File

@ -0,0 +1,151 @@
/*
* Copyright (C) 2015 Fabio Olimpieri
* This file is part of FBZX Wii
*
* FBZX Wii is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* FBZX Wii is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "rzx_lib/rzx.h"
#include "cargador.h"
#include "menu_sdl.h"
#include "computer.h"
#ifdef DEBUG
extern FILE *fdebug;
#define printf(...) fprintf(fdebug,__VA_ARGS__)
#else
#ifdef GEKKO
#define printf(...)
#endif
#endif
#define FBZXVMAJ 14
#define FBZXVMIN 0
RZX_EMULINFO emul_info;
rzx_u32 tstates;
void find_name (char *name, char *filename)
{
const char *ptr;
const char *dir = path_snaps;
char fb[81];
ptr = strrchr(filename, '\\');
if (ptr==NULL) ptr = strrchr(filename, '/');
if (ptr==NULL) strncpy(fb, filename, 80); else
strncpy(fb, ptr+1, 80);
snprintf(name, MAX_PATH_LENGTH-1, "%s/%s", dir, fb);
}
rzx_u32 rzx_callback(int msg, void *par)
{
int retorno;
char name[MAX_PATH_LENGTH];
switch(msg)
{
case RZXMSG_LOADSNAP:
retorno=0;
printf("> LOADSNAP: '%s' (%i bytes), %s, %s\n",
((RZX_SNAPINFO*)par)->filename,
(int)((RZX_SNAPINFO*)par)->length,
(((RZX_SNAPINFO*)par)->options&RZX_EXTERNAL)?"external":"embedded",
(((RZX_SNAPINFO*)par)->options&RZX_COMPRESSED)?"compressed":"uncompressed");
if (((RZX_SNAPINFO*)par)->options&RZX_EXTERNAL) find_name(name,((RZX_SNAPINFO*)par)->filename);
else strncpy (name, ((RZX_SNAPINFO*)par)->filename,80);
if (ext_matches(name, ".z80")|ext_matches(name, ".Z80"))
retorno = load_z80(name);
else if (ext_matches(name, ".sna")|ext_matches(name, ".SNA"))
retorno = load_sna(name);
else
{printf("> Not supported snap format\n");retorno=-1;}
if (retorno)
{
printf("> Load snapshot error %d\n", retorno);
return RZX_INVALID;
}
break;
case RZXMSG_CREATOR:
printf("> CREATOR: '%s %d.%d'\n",
((RZX_EMULINFO*)par)->name,
(int)((RZX_EMULINFO*)par)->ver_major,
(int)((RZX_EMULINFO*)par)->ver_minor);
if ((int)((RZX_EMULINFO*)par)->length>0)
printf("%s \n", (const char *)((RZX_EMULINFO*)par)->data);
break;
case RZXMSG_IRBNOTIFY:
if(rzx.mode==RZX_PLAYBACK)
{
/* fetch the IRB info if needed */
tstates=((RZX_IRBINFO*)par)->tstates;
printf("> IRB notify: tstates=%i, %s, %s\n",(int)tstates,
((RZX_IRBINFO*)par)->options&RZX_COMPRESSED?"compressed":"uncompressed",
((RZX_IRBINFO*)par)->options&RZX_PROTECTED?"protected":"not protected");
}
else if(rzx.mode==RZX_RECORD)
{
/* fill in the relevant info, i.e. tstates, options */
((RZX_IRBINFO*)par)->tstates=ordenador.cicles_counter;
((RZX_IRBINFO*)par)->options=0;
#ifdef RZX_USE_COMPRESSION
((RZX_IRBINFO*)par)->options|=RZX_COMPRESSED;
#endif
printf("> IRB notify: tstates=%i, %s\n",(int)ordenador.cicles_counter,
((RZX_IRBINFO*)par)->options&RZX_COMPRESSED?"compressed":"uncompressed");
}
break;
case RZXMSG_SECURITY:
printf("> Security Information Block\n");
break;
case RZXMSG_SEC_SIG:
printf("> Security Signature Block\n");
break;
case RZXMSG_UNKNOWN:
printf("> Unknown block\n");
break;
default:
printf("> MSG #%02X\n",msg);
return RZX_INVALID;
break;
}
return RZX_OK;
}
///////////////////////////////////////////////////////////////////////////
void init_rzx()
{
printf("Init RZX library\n");
printf("Using RZX Library v%i.%02i build %i\n",(RZX_LIBRARY_VERSION&0xFF00)>>8,RZX_LIBRARY_VERSION&0xFF,RZX_LIBRARY_BUILD);
strcpy(emul_info.name,"RZX FBZX Wii");
emul_info.ver_major=FBZXVMAJ;
emul_info.ver_minor=FBZXVMIN;
emul_info.data=0; emul_info.length=0;
emul_info.options=0;
rzx_init(&emul_info,rzx_callback);
}