SDL sound, compile against MINGW (VK, fopen binary files, menu key calls FBZX Wii menu, return key active on KEYUP), 2 bugs in 128k snap format, turbo N in line command, separated code for normal and precise emulation, toggle full screen in FBZX menu, removed snow effect in normal emulation, changed save tape routine, fixed 2 bugs in z80, changed SP call in z80

This commit is contained in:
fabio.olimpieri 2013-04-06 14:45:45 +00:00
parent bd14dbb56b
commit 24c37cf1ac
27 changed files with 582 additions and 251 deletions

188
Makefile.win Normal file
View File

@ -0,0 +1,188 @@
#
# Make file for windows version of FBZX Wii
#
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
export PATH := /c/devkitPro/MinGW/bin:$(PATH)
export CC := gcc
export SHELL=/bin/bash
#---------------------------------------------------------------------------------
%.o: %.c
@echo $(notdir $<)
@$(CC) $(CFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
%.exe:
@echo linking ... $(notdir $@)
@$(LD) $^ $(LDFLAGS) $(LIBPATHS) $(LIBS) -o $@
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := fbzx-wii
BUILD := build
SOURCES := src src/z80free src/minizip
DATA :=
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(INCLUDE) -Wno-pointer-sign -DBYTE_ORDER=LITTLE_ENDIAN -DMINGW
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lmingw32 -lSDLmain -lSDL -lSDL_image -lSDL_ttf -lz
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CFILES := $(filter-out z80free_tester.c, $(CFILES))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).exe dist
#---------------------------------------------------------------------------------
dist: $(BUILD)
rm -fr $@
mkdir -p $@/fbzx-wii/fbzx
mkdir -p $@/fbzx-wii/spectrum-roms
mkdir -p $@/fbzx-wii/tapes
mkdir -p $@/fbzx-wii/snapshots
mkdir -p $@/fbzx-wii/microdrives
mkdir -p $@/fbzx-wii/scr
mkdir -p $@/fbzx-wii/scr2
mkdir -p $@/fbzx-wii/configurations
mkdir -p $@/fbzx-wii/poke
mkdir -p $@/fbzx-wii/doc
cp fbzx.exe $@/fbzx-wii/fbzx.exe
cp meta.xml $@/fbzx-wii/meta.xml
cp spectrum-roms/* $@/fbzx-wii/spectrum-roms
cp dll/* $@/fbzx-wii
cp images/keymap.bmp $@/fbzx-wii/fbzx
cp images/Spectrum_keyboard.png $@/fbzx-wii/fbzx
cp images/symbol_shift.png $@/fbzx-wii/fbzx
cp images/caps_shift.png $@/fbzx-wii/fbzx
cp images/Spectrum_keyboard_small.png $@/fbzx-wii/fbzx
cp images/symbol_shift_small.png $@/fbzx-wii/fbzx
cp images/caps_shift_small.png $@/fbzx-wii/fbzx
cp images/ZXSpectrum48k.png $@/fbzx-wii/fbzx
cp images/FreeMono.ttf $@/fbzx-wii/fbzx
cp fbzx.net $@/fbzx-wii
cp AMSTRAD CAPABILITIES COPYING FAQ README README.TZX VERSIONS VERSIONS.wii $@/fbzx-wii/doc
touch $@/fbzx-wii/tapes/dummy
touch $@/fbzx-wii/snapshots/dummy
touch $@/fbzx-wii/microdrives/dummy
touch $@/fbzx-wii/scr/dummy
touch $@/fbzx-wii/scr2/dummy
touch $@/fbzx-wii/configurations/dummy
touch $@/fbzx-wii/poke/dummy
cd $@ && tar -czf ../fbzx-wii-windows-v-bin.tar.gz *
distsource:
cd .. && cp -r fbzx-wii fbzx-wii-v
cd ../fbzx-wii-v && find . -name ".svn" | xargs rm -rf
cd .. && tar -czf fbzx-wii-v.tar.gz fbzx-wii-v
cd .. && rm -fr fbzx-wii-v
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).exe: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

BIN
dll/SDL.dll Normal file

Binary file not shown.

BIN
dll/SDL_image.dll Normal file

Binary file not shown.

BIN
dll/SDL_ttf.dll Normal file

Binary file not shown.

BIN
dll/libgcc_s_dw2-1.dll Normal file

Binary file not shown.

BIN
dll/libpng15-15.dll Normal file

Binary file not shown.

BIN
dll/libz-1.dll Normal file

Binary file not shown.

BIN
dll/zlib1.dll Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

After

Width:  |  Height:  |  Size: 308 KiB

View File

@ -30,8 +30,10 @@
#include "VirtualKeyboard.h" #include "VirtualKeyboard.h"
#include "menu_sdl.h" #include "menu_sdl.h"
#include<SDL/SDL_image.h> #include<SDL/SDL_image.h>
#include <wiiuse/wpad.h>
#ifdef GEKKO
#include <wiiuse/wpad.h>
#endif
#define K(name, sdl_code) \ #define K(name, sdl_code) \
{ name, sdl_code, 0 ,0, 0} { name, sdl_code, 0 ,0, 0}
@ -210,7 +212,7 @@ void virtkey_ir_run(void)
int border_y = VirtualKeyboard.sel_y/RATIO; int border_y = VirtualKeyboard.sel_y/RATIO;
int key_sel = 0; int key_sel = 0;
SDL_Joystick *joy; SDL_Joystick *joy;
static int joy_bottons_last[4]; static int joy_bottons_last[5];
static char countdown_rumble=0; static char countdown_rumble=0;
#ifdef GEKKO #ifdef GEKKO
@ -222,21 +224,31 @@ void virtkey_ir_run(void)
if ((SDL_JoystickGetButton(joy, 0) && !joy_bottons_last[0]) || /* A */ if ((SDL_JoystickGetButton(joy, 0) && !joy_bottons_last[0]) || /* A */
(SDL_JoystickGetButton(joy, 3) && !joy_bottons_last[1]) || /* 2 */ (SDL_JoystickGetButton(joy, 3) && !joy_bottons_last[1]) || /* 2 */
(SDL_JoystickGetButton(joy, 9) && !joy_bottons_last[2]) || /* CA */ (SDL_JoystickGetButton(joy, 9) && !joy_bottons_last[2]) || /* CA */
(SDL_JoystickGetButton(joy, 10) && !joy_bottons_last[3])) /* CB */ (SDL_JoystickGetButton(joy, 10) && !joy_bottons_last[3]) /* CB */
key_sel = KEY_SELECT; #ifndef GEKKO
||((SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))&& !joy_bottons_last[4])//mouse left button
#endif
) key_sel = KEY_SELECT;
if ((!SDL_JoystickGetButton(joy, 0) && joy_bottons_last[0]) || /* A */ if ((!SDL_JoystickGetButton(joy, 0) && joy_bottons_last[0]) || /* A */
(!SDL_JoystickGetButton(joy, 3) && joy_bottons_last[1]) || /* 2 */ (!SDL_JoystickGetButton(joy, 3) && joy_bottons_last[1]) || /* 2 */
(!SDL_JoystickGetButton(joy, 9) && joy_bottons_last[2]) || /* CA */ (!SDL_JoystickGetButton(joy, 9) && joy_bottons_last[2]) || /* CA */
(!SDL_JoystickGetButton(joy, 10) && joy_bottons_last[3])) /* CB */ (!SDL_JoystickGetButton(joy, 10) && joy_bottons_last[3]) /* CB */
key_sel = KEY_DESELECT; #ifndef GEKKO
||(!(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1)) && joy_bottons_last[4]) //mouse left button
#endif
) key_sel = KEY_DESELECT;
joy_bottons_last[0]=SDL_JoystickGetButton(joy, 0) ; /* A */ joy_bottons_last[0]=SDL_JoystickGetButton(joy, 0) ; /* A */
joy_bottons_last[1] =SDL_JoystickGetButton(joy, 3) ; /* 2 */ joy_bottons_last[1] =SDL_JoystickGetButton(joy, 3) ; /* 2 */
joy_bottons_last[2] =SDL_JoystickGetButton(joy, 9) ; /* CA */ joy_bottons_last[2] =SDL_JoystickGetButton(joy, 9) ; /* CA */
joy_bottons_last[3] =SDL_JoystickGetButton(joy, 10) ; /* CB */ joy_bottons_last[3] =SDL_JoystickGetButton(joy, 10) ; /* CB */
#ifndef GEKKO
joy_bottons_last[4] =SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1); //mouse left button
#endif
if (key_sel==KEY_SELECT) if (key_sel==KEY_SELECT)
{ {

View File

@ -83,13 +83,13 @@ int save_z80(char *filename, int overwrite) {
unsigned char value,bucle; unsigned char value,bucle;
int retval; int retval;
fichero=fopen(filename,"r"); fichero=fopen(filename,"rb");
if((fichero!=NULL)&&(!overwrite)) { if((fichero!=NULL)&&(!overwrite)) {
fclose(fichero); fclose(fichero);
return -1; // file already exists return -1; // file already exists
} }
fichero=fopen(filename,"w"); fichero=fopen(filename,"wb");
if(fichero==NULL) if(fichero==NULL)
return -2; // can't create file return -2; // can't create file
@ -182,7 +182,7 @@ int load_z80(char *filename) {
for(bucle=0;bucle<16;bucle++) for(bucle=0;bucle<16;bucle++)
snap->ay_regs[bucle]=0; snap->ay_regs[bucle]=0;
fichero=fopen(filename,"r"); fichero=fopen(filename,"rb");
if(fichero==NULL) { if(fichero==NULL) {
free(memo); free(memo);
free(snap); free(snap);
@ -461,7 +461,7 @@ int load_sna(char *filename) {
printf("Loading SNA file\n"); printf("Loading SNA file\n");
fichero=fopen(filename,"r"); fichero=fopen(filename,"rb");
if(fichero==NULL) { if(fichero==NULL) {
free(tempo); free(tempo);
free(tempo2); free(tempo2);
@ -547,12 +547,12 @@ int load_sna(char *filename) {
snap->PC=((word)tempo2[0])+256*((word)tempo2[1]); snap->PC=((word)tempo2[0])+256*((word)tempo2[1]);
memcpy(snap->page[5],tempo+27,16384); memcpy(snap->page[5],tempo+27,16384);
memcpy(snap->page[2],tempo+16411,16384); memcpy(snap->page[2],tempo+16411,16384);
v1=tempo[2]; v1=tempo2[2];
snap->pager=v1; snap->pager=v1;
v1&=0x07; v1&=0x07;
memcpy(snap->page[v1],tempo+32795,16384); memcpy(snap->page[v1],tempo+32795,16384);
addr=4; addr=4;
for (loop=0;loop<7;loop++) { for (loop=0;loop<8;loop++) {
if ((loop==2)||(loop==5)||(loop==((int)v1))) { if ((loop==2)||(loop==5)||(loop==((int)v1))) {
continue; continue;
} }

View File

@ -28,7 +28,7 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
#include <sys/wait.h> //#include <sys/wait.h>
#include "tape.h" #include "tape.h"
#include "microdrive.h" #include "microdrive.h"
#include "Virtualkeyboard.h" #include "Virtualkeyboard.h"
@ -73,16 +73,6 @@ inline byte bus_empty () {
/* calls all the routines that emulates the computer, runing them for 'tstados' /* calls all the routines that emulates the computer, runing them for 'tstados'
tstates */ tstates */
inline void emulate_screen (int tstados) {
if(((procesador.I & 0xC0) == 0x40)&&(ordenador.mode128k!=3)) { // (procesador.I>=0x40)&&(procesador.I<=0x7F)
ordenador.screen_snow=1;
} else
ordenador.screen_snow=0;
if (ordenador.precision) show_screen_precision (tstados);
else show_screen(tstados);
}
inline void emulate (int tstados) { inline void emulate (int tstados) {
@ -132,8 +122,6 @@ void computer_init () { //Called only on start-up
ordenador.osd_text[0] = 0; ordenador.osd_text[0] = 0;
ordenador.osd_time = 0; ordenador.osd_time = 0;
ordenador.other_ret = 0;
ordenador.s8 = ordenador.s9 = ordenador.s10 = ordenador.s11 = ordenador.s8 = ordenador.s9 = ordenador.s10 = ordenador.s11 =
ordenador.s12 = ordenador.s13 = ordenador.s14 = ordenador.s12 = ordenador.s13 = ordenador.s14 =
ordenador.s15 = 0xFF; ordenador.s15 = 0xFF;
@ -468,7 +456,7 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.contador_flash = 0; ordenador.contador_flash = 0;
ordenador.readed = 0; ordenador.readed = 0;
//ordenador.contended_zone=0; ordenador.contended_zone=0;
ordenador.cicles_counter=0; ordenador.cicles_counter=0;
ordenador.tstados_counter_sound = 0; ordenador.tstados_counter_sound = 0;
@ -592,6 +580,8 @@ inline void show_screen (int tstados) {
// is border // is border
ordenador.contended_zone=0;
if (ordenador.ulaplus) { if (ordenador.ulaplus) {
paint_pixels (255, ordenador.border+24, 0,1); // paint 8 pixels with BORDER color paint_pixels (255, ordenador.border+24, 0,1); // paint 8 pixels with BORDER color
} else { } else {
@ -604,6 +594,8 @@ inline void show_screen (int tstados) {
// is user area. We search for ink and paper colours // is user area. We search for ink and paper colours
ordenador.contended_zone=1;
temporal = ordenador.memoria[(*ordenador.p_translt2) + ordenador.video_offset]; // attributes temporal = ordenador.memoria[(*ordenador.p_translt2) + ordenador.video_offset]; // attributes
ordenador.bus_value = temporal; ordenador.bus_value = temporal;
@ -621,12 +613,6 @@ inline void show_screen (int tstados) {
fflash = temporal & 0x80; // flash flag fflash = temporal & 0x80; // flash flag
} }
// Snow Effect
if(ordenador.screen_snow) {
temporal3 = ordenador.memoria[(((*ordenador.p_translt) + (ordenador.video_offset))&0xFFFFFF80)+(procesador.R&0x7F)]; // data with snow
ordenador.screen_snow=0; // no more snow for now
} else
temporal3 = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // bitmap temporal3 = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // bitmap
ordenador.p_translt++; ordenador.p_translt++;
@ -1127,6 +1113,7 @@ inline void read_keyboard () {
SDL_PollEvent (&evento); SDL_PollEvent (&evento);
if (pevento->type==SDL_QUIT) { if (pevento->type==SDL_QUIT) {
printf("SDL_QUIT event\n");
salir = 0; salir = 0;
return; return;
} }
@ -1334,6 +1321,14 @@ inline void read_keyboard () {
sprintf (ordenador.osd_text, " Volume: %d ",ordenador.volume); sprintf (ordenador.osd_text, " Volume: %d ",ordenador.volume);
ordenador.osd_time = 50; ordenador.osd_time = 50;
break; break;
case SDLK_MENU: //Call FBZX wii menu
if (ordenador.vk_is_active) virtkey_ir_deactivate();
main_menu();
break;
case SDLK_RCTRL: //Activate virtual keyboard
if (!ordenador.vk_auto)
{if (!ordenador.vk_is_active) virtkey_ir_activate(); else virtkey_ir_deactivate();}
break;
} }
// reorder joystick if screen is rotated // reorder joystick if screen is rotated
@ -1489,7 +1484,7 @@ inline void read_keyboard () {
#endif #endif
if (ordenador.key[SDLK_SPACE]|| joybutton_matrix[0][SDLK_SPACE] || joybutton_matrix[1][SDLK_SPACE]) ordenador.k15|=1; if (ordenador.key[SDLK_SPACE]|| joybutton_matrix[0][SDLK_SPACE] || joybutton_matrix[1][SDLK_SPACE]) ordenador.k15|=1;
if (ordenador.key[SDLK_RCTRL]||ordenador.key[SDLK_LCTRL]|| joybutton_matrix[0][SDLK_LCTRL] || joybutton_matrix[1][SDLK_LCTRL]) ordenador.k15|=2; //Symbol shift if (ordenador.key[SDLK_LCTRL]|| joybutton_matrix[0][SDLK_LCTRL] || joybutton_matrix[1][SDLK_LCTRL]) ordenador.k15|=2; //Symbol shift
if (ordenador.key[SDLK_m] || joybutton_matrix[0][SDLK_m] || joybutton_matrix[1][SDLK_m]) ordenador.k15|=4; if (ordenador.key[SDLK_m] || joybutton_matrix[0][SDLK_m] || joybutton_matrix[1][SDLK_m]) ordenador.k15|=4;
if (ordenador.key[SDLK_n] || joybutton_matrix[0][SDLK_n] || joybutton_matrix[1][SDLK_n]) ordenador.k15|=8; if (ordenador.key[SDLK_n] || joybutton_matrix[0][SDLK_n] || joybutton_matrix[1][SDLK_n]) ordenador.k15|=8;
if (ordenador.key[SDLK_b] || joybutton_matrix[0][SDLK_b] || joybutton_matrix[1][SDLK_b]) ordenador.k15|=16; if (ordenador.key[SDLK_b] || joybutton_matrix[0][SDLK_b] || joybutton_matrix[1][SDLK_b]) ordenador.k15|=16;
@ -1756,27 +1751,50 @@ void do_contention() {
static int ccicles; static int ccicles;
if (ordenador.contended_zone==0) return;
if (ordenador.mode128k==3) //+3
{
ccicles=(ordenador.cicles_counter-ordenador.start_contention)%8;
if (ccicles>6) return;
ordenador.contention+=7-ccicles;
show_screen(7-ccicles);
}
else //64k/128k/+2
{
ccicles=(ordenador.cicles_counter-ordenador.start_contention)%8;
if (ccicles>5) return;
ordenador.contention+=6-ccicles;
show_screen(6-ccicles);
}
}
void do_contention_precision() {
static int ccicles;
if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line) if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line)
|| (ordenador.currpix < 40) || (ordenador.currpix > 295)) return; || (ordenador.currpix < 40) || (ordenador.currpix > 295)) return;
if (ordenador.mode128k==3) //+3 if (ordenador.mode128k==3) //+3
{ {
if (ordenador.precision) ccicles=((ordenador.currpix-28)/2)%8; //44-16 ccicles=((ordenador.currpix-28)/2)%8; //44-16
else ccicles=(ordenador.cicles_counter-ordenador.start_contention)%8;
if (ccicles>6) return; if (ccicles>6) return;
ordenador.contention+=7-ccicles; ordenador.contention+=7-ccicles;
emulate_screen(7-ccicles); show_screen_precision(7-ccicles);
} }
else //64k/128k/+2 else //64k/128k/+2
{ {
if (ordenador.precision) ccicles=((ordenador.currpix-40)/2)%8; ccicles=((ordenador.currpix-40)/2)%8;
else ccicles=(ordenador.cicles_counter-ordenador.start_contention)%8;
if (ccicles>5) return; if (ccicles>5) return;
ordenador.contention+=6-ccicles; ordenador.contention+=6-ccicles;
emulate_screen(6-ccicles); show_screen_precision(6-ccicles);
} }
} }
@ -1788,26 +1806,26 @@ void Z80free_Wr (register word Addr, register byte Value) {
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
// only writes in the first 16K if we are in +3 mode and bit0 of mport2 is 1 // only writes in the first 16K if we are in +3 mode and bit0 of mport2 is 1
if (ordenador.precision) emulate_screen(3); if (ordenador.precision) show_screen_precision(3);
if ((ordenador.mode128k == 3) && (1 == (ordenador.mport2 & 0x01))) if ((ordenador.mode128k == 3) && (1 == (ordenador.mport2 & 0x01)))
*(ordenador.block0 + Addr) = (unsigned char) Value; *(ordenador.block0 + Addr) = (unsigned char) Value;
break; break;
case 0x4000: case 0x4000:
do_contention(); if (ordenador.precision) {do_contention_precision();show_screen_precision(3); }
if (ordenador.precision) emulate_screen(3); else do_contention();
*(ordenador.block1 + Addr) = (unsigned char) Value; *(ordenador.block1 + Addr) = (unsigned char) Value;
break; break;
case 0x8000: case 0x8000:
if (ordenador.precision) emulate_screen(3); if (ordenador.precision) show_screen_precision(3);
*(ordenador.block2 + Addr) = (unsigned char) Value; *(ordenador.block2 + Addr) = (unsigned char) Value;
break; break;
case 0xC000: case 0xC000:
if (ordenador.precision) { if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention(); if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention_precision();
emulate_screen(3); show_screen_precision(3);
} }
*(ordenador.block3 + Addr) = (unsigned char) Value; *(ordenador.block3 + Addr) = (unsigned char) Value;
break; break;
@ -1845,36 +1863,29 @@ byte Z80free_Rd_fetch (register word Addr) {
if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I
return((byte)ordenador.shadowrom[Addr]); return((byte)ordenador.shadowrom[Addr]);
switch (ordenador.other_ret) {
case 1:
ordenador.other_ret = 0;
return (201); // RET instruction
break;
default:
ordenador.r_fetch+=4; ordenador.r_fetch+=4;
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
if (ordenador.precision) {ordenador.fetch_state=4;emulate_screen (4);} if (ordenador.precision) {ordenador.fetch_state=4;show_screen_precision (4);}
return ((byte) (*(ordenador.block0 + Addr))); return ((byte) (*(ordenador.block0 + Addr)));
break; break;
case 0x4000: case 0x4000:
do_contention(); if (ordenador.precision) {do_contention_precision();ordenador.fetch_state=4;show_screen_precision (4);}
if (ordenador.precision) {ordenador.fetch_state=4;emulate_screen (4);} else do_contention();
return ((byte) (*(ordenador.block1 + Addr))); return ((byte) (*(ordenador.block1 + Addr)));
break; break;
case 0x8000: case 0x8000:
if (ordenador.precision) {ordenador.fetch_state=4;emulate_screen (4);} if (ordenador.precision) {ordenador.fetch_state=4;show_screen_precision (4);}
return ((byte) (*(ordenador.block2 + Addr))); return ((byte) (*(ordenador.block2 + Addr)));
break; break;
case 0xC000: case 0xC000:
if (ordenador.precision) { if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention(); if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention_precision();
ordenador.fetch_state=4; ordenador.fetch_state=4;
emulate_screen (4); show_screen_precision (4);
} }
return ((byte) (*(ordenador.block3 + Addr))); return ((byte) (*(ordenador.block3 + Addr)));
break; break;
@ -1884,9 +1895,6 @@ byte Z80free_Rd_fetch (register word Addr) {
exit (1); exit (1);
return 0; return 0;
} }
break;
}
} }
byte Z80free_Rd (register word Addr) { byte Z80free_Rd (register word Addr) {
@ -1894,35 +1902,28 @@ byte Z80free_Rd (register word Addr) {
if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I
return((byte)ordenador.shadowrom[Addr]); return((byte)ordenador.shadowrom[Addr]);
switch (ordenador.other_ret) {
case 1:
ordenador.other_ret = 0;
return (201); // RET instruction
break;
default:
ordenador.wr+=3; ordenador.wr+=3;
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
if (ordenador.precision) emulate_screen (3); if (ordenador.precision) show_screen_precision (3);
return ((byte) (*(ordenador.block0 + Addr))); return ((byte) (*(ordenador.block0 + Addr)));
break; break;
case 0x4000: case 0x4000:
do_contention(); if (ordenador.precision) {do_contention_precision();show_screen_precision (3);}
if (ordenador.precision) emulate_screen (3); else do_contention();
return ((byte) (*(ordenador.block1 + Addr))); return ((byte) (*(ordenador.block1 + Addr)));
break; break;
case 0x8000: case 0x8000:
if (ordenador.precision) emulate_screen (3); if (ordenador.precision) show_screen_precision (3);
return ((byte) (*(ordenador.block2 + Addr))); return ((byte) (*(ordenador.block2 + Addr)));
break; break;
case 0xC000: case 0xC000:
if (ordenador.precision) { if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention(); if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention_precision();
emulate_screen (3); show_screen_precision (3);
} }
return ((byte) (*(ordenador.block3 + Addr))); return ((byte) (*(ordenador.block3 + Addr)));
break; break;
@ -1932,19 +1933,11 @@ byte Z80free_Rd (register word Addr) {
exit (1); exit (1);
return 0; return 0;
} }
break;
}
} }
byte Z80free_Rd_fake (register word Addr) { byte Z80free_Rd_fake (register word Addr) {
switch (ordenador.other_ret) {
case 1:
ordenador.other_ret = 0;
return (201); // RET instruction
break;
default:
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
return ((byte) (*(ordenador.block0 + Addr))); return ((byte) (*(ordenador.block0 + Addr)));
@ -1967,9 +1960,6 @@ switch (ordenador.other_ret) {
exit (1); exit (1);
return 0; return 0;
} }
break;
}
} }
void set_palete_entry(unsigned char entry, byte Value) { void set_palete_entry(unsigned char entry, byte Value) {
@ -2007,21 +1997,21 @@ void Z80free_Out (register word Port, register byte Value) {
{ {
case 0: case 0:
if ((Port & 0xC000) == 0x4000) // (Port>=0x4000)&&(Port<0x8000) if ((Port & 0xC000) == 0x4000) // (Port>=0x4000)&&(Port<0x8000)
{if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention();emulate_screen(1);do_contention();ordenador.io+=1;} {if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention_precision();show_screen_precision(1);do_contention_precision();ordenador.io+=1;}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();ordenador.io+=3;} else {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();ordenador.io+=3;}
} }
else else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();ordenador.io+=1;} if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {show_screen_precision(1);do_contention_precision();ordenador.io+=1;}
break; break;
case 1: case 1:
case 2: case 2:
case 4: case 4:
if (((Port & 0xC000) == 0x4000)||((ordenador.mport1 & 0x01)&&((Port & 0xC000) == 0xC000))) // (Port>=0xc000)&&(Port<=0xffff) if (((Port & 0xC000) == 0x4000)||((ordenador.mport1 & 0x01)&&((Port & 0xC000) == 0xC000))) // (Port>=0xc000)&&(Port<=0xffff)
{if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention();emulate_screen(1);do_contention();ordenador.io+=1;} {if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention_precision();show_screen_precision(1);do_contention_precision();ordenador.io+=1;}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();ordenador.io+=3;} else {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();ordenador.io+=3;}
} }
else else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();ordenador.io+=1;} if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {show_screen_precision(1);do_contention_precision();ordenador.io+=1;}
break; break;
case 3: case 3:
break; //no io contention in +3 break; //no io contention in +3
@ -2151,29 +2141,29 @@ byte Z80free_In (register word Port) {
{ {
case 0: case 0:
if ((Port & 0xC000) == 0x4000) // (Port>=0x4000)&&(Port<0x8000) if ((Port & 0xC000) == 0x4000) // (Port>=0x4000)&&(Port<0x8000)
{if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention();emulate_screen(1);do_contention();emulate_screen(3);} {if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(3);}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);} else {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);}
} }
else else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();emulate_screen(3);} if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {show_screen_precision(1);do_contention_precision();show_screen_precision(3);}
else emulate_screen(4); else show_screen_precision(4);
break; break;
case 1: case 1:
case 2: case 2:
case 4: case 4:
if (((Port & 0xC000) == 0x4000)||((ordenador.mport1 & 0x01)&&((Port & 0xC000) == 0xC000))) // (Port>=0xc000)&&(Port<=0xffff) if (((Port & 0xC000) == 0x4000)||((ordenador.mport1 & 0x01)&&((Port & 0xC000) == 0xC000))) // (Port>=0xc000)&&(Port<=0xffff)
{if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention();emulate_screen(1);do_contention();emulate_screen(3);} {if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(3);}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);} else {do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);do_contention_precision();show_screen_precision(1);}
} }
else else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();emulate_screen(3);} if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {show_screen_precision(1);do_contention_precision();show_screen_precision(3);}
else emulate_screen(4); else show_screen_precision(4);
break; break;
case 3: case 3:
emulate_screen(4);//no io contention in +3 show_screen_precision(4);//no io contention in +3
break; break;
default: default:
emulate_screen(4); show_screen_precision(4);
break; break;
} }
} }

View File

@ -90,9 +90,9 @@ struct computer {
int start_contention; //start tstados for contention int start_contention; //start tstados for contention
//int end_contention; //end tstados for contention //int end_contention; //end tstados for contention
unsigned char screen_snow; // 0-> no emulate snow; 1-> emulate snow //unsigned char screen_snow; // 0-> no emulate snow; 1-> emulate snow
unsigned char fetch_state; unsigned char fetch_state;
//unsigned char contended_zone; // 0-> no contention; 1-> contention possible unsigned char contended_zone; // 0-> no contention; 1-> contention possible
int cicles_counter; // counts how many pixel clock cicles passed since las interrupt int cicles_counter; // counts how many pixel clock cicles passed since las interrupt
char ulaplus; // 0 = inactive; 1 = active char ulaplus; // 0 = inactive; 1 = active
@ -237,7 +237,7 @@ struct computer {
unsigned char interr; unsigned char interr;
unsigned char readkeyboard; unsigned char readkeyboard;
unsigned char mustlock; unsigned char mustlock;
unsigned char other_ret; // 0=no change; 1=memory returns RET (201) //unsigned char other_ret; // 0=no change; 1=memory returns RET (201)
unsigned char turbo; unsigned char turbo;
unsigned char turbo_state; unsigned char turbo_state;

View File

@ -48,8 +48,6 @@
#include <ogc/usbstorage.h> #include <ogc/usbstorage.h>
#include <network.h> #include <network.h>
#include <smb.h> #include <smb.h>
#include <stdio.h>
#include <stdlib.h>
#include "tinyFTP/ftp_devoptab.h" #include "tinyFTP/ftp_devoptab.h"
#endif #endif
@ -82,7 +80,7 @@ char load_path_scr1[MAX_PATH_LENGTH];
char load_path_poke[MAX_PATH_LENGTH]; char load_path_poke[MAX_PATH_LENGTH];
unsigned int colors[80]; unsigned int colors[80];
unsigned int jump_frames,curr_frames; unsigned int jump_frames,curr_frames, turbo_n;
static SDL_Surface *image; static SDL_Surface *image;
@ -97,6 +95,10 @@ extern int FULL_DISPLAY_X; //640
extern int FULL_DISPLAY_Y; //480 extern int FULL_DISPLAY_Y; //480
extern int RATIO; extern int RATIO;
#ifdef MINGW
#define mkdir(name, mode) mkdir(name)
#endif
#if defined(GEKKO) #if defined(GEKKO)
@ -322,13 +324,11 @@ FILE *myfopen(char *filename,char *mode) {
if (fichero!=NULL) { if (fichero!=NULL) {
return (fichero); return (fichero);
} }
#ifdef GEKKO
sprintf(tmp,"/fbzx-wii/%s",filename); sprintf(tmp,"/fbzx-wii/%s",filename);
fichero=fopen(tmp,mode); fichero=fopen(tmp,mode);
if (fichero!=NULL) { if (fichero!=NULL) {
return (fichero); return (fichero);
} }
#endif
return (NULL); return (NULL);
} }
@ -341,7 +341,7 @@ char *load_a_rom(char **filenames) {
int size; int size;
for(pointer=filenames;*pointer!=NULL;pointer++) { for(pointer=filenames;*pointer!=NULL;pointer++) {
fichero=myfopen(*pointer,"r"); fichero=myfopen(*pointer,"rb");
if(fichero==NULL) { if(fichero==NULL) {
return (*pointer); return (*pointer);
} }
@ -433,10 +433,10 @@ void load_rom(char type) {
break; break;
} }
fichero=myfopen("spectrum-roms/if1-2.rom","r"); // load Interface1 ROM fichero=myfopen("spectrum-roms/if1-2.rom","rb"); // load Interface1 ROM
if(fichero==NULL) { if(fichero==NULL) {
// try legacy name // try legacy name
fichero=myfopen("spectrum-roms/if1-v2.rom","r"); fichero=myfopen("spectrum-roms/if1-v2.rom","rb");
if(fichero==NULL) { if(fichero==NULL) {
printf("Can't open Interface1 ROM file\n"); printf("Can't open Interface1 ROM file\n");
exit(1); exit(1);
@ -471,21 +471,18 @@ int set_video_mode()
VIDEO_Configure(rmode); VIDEO_Configure(rmode);
VIDEO_Flush(); VIDEO_Flush();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
return 0;
#endif #endif
return 0;
} }
void init_sdl() void init_sdl()
{ {
int retorno, bucle; int retorno, bucle;
//if (sound_type!=3) if (sound_type==SOUND_SDL)
retorno=SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
else
retorno=SDL_Init(SDL_INIT_VIDEO); retorno=SDL_Init(SDL_INIT_VIDEO);
/*else
retorno=SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);*/
if(retorno!=0) { if(retorno!=0) {
printf("Can't initialize SDL library. Exiting\n"); printf("Can't initialize SDL library. Exiting\n");
exit(1); exit(1);
@ -558,16 +555,13 @@ void init_sound()
int bucle, bucle2,ret2; int bucle, bucle2,ret2;
// sound initialization // sound initialization
if (sound_type==SOUND_AUTOMATIC) { ret2=sound_init(); // check all sound systems or the selected sound
ret2=sound_init(1); // check all sound systems
} else {
ret2=sound_init(0); // try with the one specified in command line
}
if(ret2==0) { if(ret2==0) {
sound_aborted=0; sound_aborted=0;
} else { // if fails, run without sound } else { // if fails, run without sound
sound_type=SOUND_NO; sound_type=SOUND_NO;
sound_init(0); sound_init();
sound_aborted=1; sound_aborted=1;
} }
printf("Init sound\n"); printf("Init sound\n");
@ -578,17 +572,24 @@ int bucle, bucle2,ret2;
for(bucle2=0;bucle2<NUM_SNDBUF;bucle2++) { for(bucle2=0;bucle2<NUM_SNDBUF;bucle2++) {
//ASND Required alligned memory with padding //ASND Required alligned memory with padding
#ifdef GEKKO
sound[bucle2]=(unsigned int *)memalign(32,ordenador.buffer_len*ordenador.increment+32); sound[bucle2]=(unsigned int *)memalign(32,ordenador.buffer_len*ordenador.increment+32);
for(bucle=0;bucle<ordenador.buffer_len+8;bucle++) for(bucle=0;bucle<ordenador.buffer_len+8;bucle++)
sound[bucle2][bucle]=0; sound[bucle2][bucle]=0;
#else
sound[bucle2]=(unsigned int *) calloc(ordenador.buffer_len+1,ordenador.increment);
for(bucle=0;bucle<ordenador.buffer_len;bucle++)
sound[bucle2][bucle]=0;
#endif
} }
printf("Init sound 2\n"); printf("Init sound 2\n");
ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES); ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES);
} }
void end_system() { void end_system() {
printf("Quitting...\n");
sound_close(); sound_close();
if(ordenador.mustlock) if(ordenador.mustlock)
@ -598,6 +599,17 @@ void end_system() {
fclose(ordenador.tap_file); fclose(ordenador.tap_file);
SDL_Quit(); SDL_Quit();
if (!chdir(path_tmp)) {chdir("/"); remove_dir(path_tmp);} //remove the tmp directory if it exists
#ifdef GEKKO
if (smbismount) CloseShare();
if (ftpismount) CloseFTP();
DeInitUSB();
fatUnmount(0);
#endif
free_browser();
} }
void load_main_game(char *nombre) { void load_main_game(char *nombre) {
@ -618,7 +630,7 @@ void load_main_game(char *nombre) {
if ((0==strcasecmp(".tap",puntero))||(0==strcasecmp(".tzx",puntero))) { if ((0==strcasecmp(".tap",puntero))||(0==strcasecmp(".tzx",puntero))) {
char char_id[10]; char char_id[10];
ordenador.tape_write = 0; // by default, can't record ordenador.tape_write = 0; // by default, can't record
ordenador.tap_file=fopen(nombre,"r+"); // read and write ordenador.tap_file=fopen(nombre,"r+b"); // read and write
if(ordenador.tap_file==NULL) if(ordenador.tap_file==NULL)
return; return;
@ -738,7 +750,7 @@ int save_config_game(struct computer *object, char *filename, int overwrite) {
unsigned char key, joy_n; unsigned char key, joy_n;
FILE *fconfig; FILE *fconfig;
fconfig=fopen(filename,"r"); fconfig=fopen(filename,"rb");
if((fconfig!=NULL)&&(!overwrite)) { if((fconfig!=NULL)&&(!overwrite)) {
fclose(fconfig); fclose(fconfig);
return -1; // file already exists return -1; // file already exists
@ -774,7 +786,7 @@ void load_config_network(struct computer *object) {
unsigned char smb_enable=0, ftp_enable=0, FTPPassive=0; unsigned char smb_enable=0, ftp_enable=0, FTPPassive=0;
unsigned int FTPPort=21; unsigned int FTPPort=21;
fconfig = fopen("/fbzx-wii/fbzx.net","r"); fconfig = fopen("/fbzx-wii/fbzx.net","rb");
if (fconfig==NULL) { if (fconfig==NULL) {
return; return;
} }
@ -1135,7 +1147,16 @@ int load_config(struct computer *object, char *filename) {
return 0; return 0;
} }
int main(int argc,char *argv[]) { #ifdef MINGW
int WinMain()
{
int argc=__argc;
char **argv=__argv;
#else
int main(int argc,char *argv[])
{
#endif
int bucle,tstados,tstados_screen, argumento,fullscreen,dblbuffer,hwsurface,length; int bucle,tstados,tstados_screen, argumento,fullscreen,dblbuffer,hwsurface,length;
char gamefile[MAX_PATH_LENGTH],config_path[MAX_PATH_LENGTH] ; char gamefile[MAX_PATH_LENGTH],config_path[MAX_PATH_LENGTH] ;
@ -1159,15 +1180,23 @@ int main(int argc,char *argv[]) {
curr_frames=0; curr_frames=0;
ordenador.dblscan=1; ordenador.dblscan=1;
ordenador.bw=0; ordenador.bw=0;
turbo_n=1;
#ifdef DEBUG #ifdef DEBUG
#ifdef GEKKO
fatInitDefault(); fatInitDefault();
#endif
fdebug = fopen("/fbzx-wii/logfile.txt","w"); fdebug = fopen("/fbzx-wii/logfile.txt","w");
#endif #endif
#ifdef MINGW
if(!getenv("HOME")) putenv("HOME=/fbzx-wii");
#endif
#ifdef GEKKO #ifdef GEKKO
dblbuffer=1; dblbuffer=1;
hwsurface=1; hwsurface=1;
sound_type=SOUND_ASND;
setenv("HOME", "/fbzx-wii", 1); setenv("HOME", "/fbzx-wii", 1);
//initialize libfat library //initialize libfat library
@ -1249,6 +1278,7 @@ int main(int argc,char *argv[]) {
printf(" -bw: emulate black&white TV set\n"); printf(" -bw: emulate black&white TV set\n");
printf(" -color: emulate a color TV set\n"); printf(" -color: emulate a color TV set\n");
printf(" -jumpN: show one TV refresh and jump over N refreshes (for slow systems)\n"); printf(" -jumpN: show one TV refresh and jump over N refreshes (for slow systems)\n");
printf(" -turboN: accelerate the tape loading by N (2-9)\n");
printf(" gamefile: an optional .Z80 snapshot or .TAP/.TZX tape file\n\n"); printf(" gamefile: an optional .Z80 snapshot or .TAP/.TZX tape file\n\n");
exit(0); exit(0);
} else if(0==strcmp(argv[argumento],"-nosound")) { } else if(0==strcmp(argv[argumento],"-nosound")) {
@ -1302,9 +1332,16 @@ int main(int argc,char *argv[]) {
argumento++; argumento++;
} else if(0==strncmp(argv[argumento],"-jump",5)) { } else if(0==strncmp(argv[argumento],"-jump",5)) {
jump_frames=(int)(argv[argumento][5]); jump_frames=(int)(argv[argumento][5]);
jump_frames-=48;//??? jump_frames-=48;
if ((jump_frames<0)||(jump_frames>9)) jump_frames = 0;
argumento++; argumento++;
printf ("Jump %d\n",jump_frames); printf ("Jump %d\n",jump_frames);
} else if(0==strncmp(argv[argumento],"-turbo",6)) {
turbo_n=(int)(argv[argumento][6]);
turbo_n-=48;
if ((turbo_n<1)||(turbo_n>9)) turbo_n = 1;
argumento++;
printf ("turbo %d\n",turbo_n);
} else { } else {
strcpy(gamefile,argv[argumento]); strcpy(gamefile,argv[argumento]);
argumento++; argumento++;
@ -1338,7 +1375,7 @@ int main(int argc,char *argv[]) {
if(fullscreen) { if(fullscreen) {
SDL_Fullscreen_Switch(); SDL_Fullscreen_Switch();
} }
SDL_WM_SetCaption("FBZX",""); SDL_WM_SetCaption("FBZX Wii","");
#endif #endif
ordenador.interr=0; ordenador.interr=0;
ordenador.readkeyboard = 0; ordenador.readkeyboard = 0;
@ -1393,7 +1430,7 @@ int main(int argc,char *argv[]) {
//Remove and make tmp dir //Remove and make tmp dir
if (!chdir(path_tmp)) remove_dir(path_tmp); //remove the tmp directory if it exists if (!chdir(path_tmp)) {chdir("/"); remove_dir(path_tmp);} //remove the tmp directory if it exists
int write_protection=0; int write_protection=0;
@ -1489,6 +1526,9 @@ int main(int argc,char *argv[]) {
SDL_EventState(SDL_SYSWMEVENT,SDL_IGNORE); SDL_EventState(SDL_SYSWMEVENT,SDL_IGNORE);
SDL_EventState(SDL_VIDEORESIZE,SDL_IGNORE); SDL_EventState(SDL_VIDEORESIZE,SDL_IGNORE);
SDL_EventState(SDL_USEREVENT,SDL_IGNORE); SDL_EventState(SDL_USEREVENT,SDL_IGNORE);
#ifndef GEKKO
SDL_EventState(SDL_MOUSEBUTTONDOWN,SDL_ENABLE);
#endif
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
salir=1; salir=1;
@ -1499,7 +1539,7 @@ int main(int argc,char *argv[]) {
printf("Reset computer\n"); printf("Reset computer\n");
ResetComputer(); ResetComputer();
sleep(1); SDL_Delay(1000);
printf("Reset screen\n"); printf("Reset screen\n");
clean_screen(); clean_screen();
@ -1526,7 +1566,7 @@ int main(int argc,char *argv[]) {
if (ordenador.precision) if (ordenador.precision)
{ {
tstados_screen=tstados-ordenador.r_fetch -ordenador.wr -ordenador.io; tstados_screen=tstados-ordenador.r_fetch -ordenador.wr -ordenador.io;
if(tstados_screen>0) emulate_screen(tstados_screen); if(tstados_screen>0) show_screen_precision(tstados_screen);
ordenador.wr=0; ordenador.wr=0;
ordenador.r_fetch=0; ordenador.r_fetch=0;
ordenador.io=0; ordenador.io=0;
@ -1535,7 +1575,7 @@ int main(int argc,char *argv[]) {
} }
else else
if (tstados>0) { if (tstados>0) {
emulate_screen(tstados); show_screen(tstados);
emulate(tstados+ordenador.contention); emulate(tstados+ordenador.contention);
ordenador.contention=0; ordenador.contention=0;
} }
@ -1604,19 +1644,8 @@ int main(int argc,char *argv[]) {
if(ordenador.interr==1) { if(ordenador.interr==1) {
Z80free_INT(&procesador,bus_empty()); Z80free_INT(&procesador,bus_empty());
if ((ordenador.precision==0)||(jump_frames>0)) ordenador.interr=0; if ((ordenador.precision==0)||(jump_frames>0)) ordenador.interr=0;
} //else if (ordenador.precision==1) Z80free_INT_reset(&procesador);
} }
}
if (!chdir(path_tmp)) remove_dir(path_tmp); //remove the tmp directory if it exists
#ifdef GEKKO
if (smbismount) CloseShare();
if (ftpismount) CloseFTP();
DeInitUSB();
fatUnmount(0);
#endif
free_browser();
return 0; return 0;
} }

View File

@ -46,7 +46,7 @@ extern char load_path_scr1[MAX_PATH_LENGTH];
extern char load_path_poke[MAX_PATH_LENGTH]; extern char load_path_poke[MAX_PATH_LENGTH];
extern unsigned int colors[80]; extern unsigned int colors[80];
extern unsigned int jump_frames,curr_frames; extern unsigned int jump_frames,curr_frames, turbo_n;
extern unsigned char sdismount, usbismount, smbismount, tmpismade, ftpismount,networkisinit; extern unsigned char sdismount, usbismount, smbismount, tmpismade, ftpismount,networkisinit;
void SDL_Fullscreen_Switch(void); void SDL_Fullscreen_Switch(void);

View File

@ -236,7 +236,7 @@ static void tape_browser()
const char *row_selected; const char *row_selected;
char block_n[5]; char block_n[5];
if (browser_list[0]==NULL) {msgInfo("No tape inserted",3000,NULL);return;} if (browser_list[0]==NULL) {msgInfo("No tape inserted or empty",3000,NULL);return;}
row_selected = menu_select_browser(ordenador.tape_position); row_selected = menu_select_browser(ordenador.tape_position);
@ -297,7 +297,7 @@ static void insert_tape()
} }
if (!strncmp(filename,"smb:",4)) ordenador.tap_file=fopen(filename,"r"); //tinysmb does not work with r+ if (!strncmp(filename,"smb:",4)) ordenador.tap_file=fopen(filename,"r"); //tinysmb does not work with r+
else ordenador.tap_file=fopen(filename,"r+"); // read and write else ordenador.tap_file=fopen(filename,"r+b"); // read and write
ordenador.tape_write = 1; // by default, can record ordenador.tape_write = 1; // by default, can record
@ -325,12 +325,10 @@ static void insert_tape()
retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header
if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) { if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) {
ordenador.tape_file_type = TAP_TZX; ordenador.tape_file_type = TAP_TZX;
rewind_tape(ordenador.tap_file,1); create_browser_tzx(ordenador.tap_file);
browser_tzx(ordenador.tap_file);
} else { } else {
ordenador.tape_file_type = TAP_TAP; ordenador.tape_file_type = TAP_TAP;
rewind_tape(ordenador.tap_file,1); create_browser_tap(ordenador.tap_file);
browser_tap(ordenador.tap_file);
} }
} }
@ -376,14 +374,14 @@ void create_tapfile_sdl() {
if(ordenador.tap_file!=NULL) if(ordenador.tap_file!=NULL)
fclose(ordenador.tap_file); fclose(ordenador.tap_file);
ordenador.tap_file=fopen(nombre2,"r"); // test if it exists ordenador.tap_file=fopen(nombre2,"rb"); // test if it exists
if(ordenador.tap_file==NULL) if(ordenador.tap_file==NULL)
retorno=0; retorno=0;
else else
retorno=-1; retorno=-1;
if(!retorno) { if(!retorno) {
ordenador.tap_file=fopen(nombre2,"a+"); // create for read and write ordenador.tap_file=fopen(nombre2,"a+b"); // create for read and write
if(ordenador.tap_file==NULL) if(ordenador.tap_file==NULL)
retorno=-2; retorno=-2;
else else
@ -395,6 +393,7 @@ void create_tapfile_sdl() {
switch(retorno) { switch(retorno) {
case 0: case 0:
strcpy(ordenador.last_selected_file,nombre2); strcpy(ordenador.last_selected_file,nombre2);
create_browser_tap(ordenador.tap_file);
break; break;
case -1: case -1:
msgInfo("File already exists",3000,NULL); msgInfo("File already exists",3000,NULL);
@ -942,7 +941,7 @@ void create_mdrfile_sdl() {
if(retorno==2) // abort if(retorno==2) // abort
return; return;
ordenador.mdr_file=fopen(nombre2,"r"); // test if it exists ordenador.mdr_file=fopen(nombre2,"rb"); // test if it exists
if(ordenador.mdr_file==NULL) if(ordenador.mdr_file==NULL)
retorno=0; retorno=0;
else else
@ -1139,7 +1138,7 @@ static int save_scr(int i)
snprintf(db, MAX_PATH_LENGTH-1, "%s/%s.scr", dir, fb); snprintf(db, MAX_PATH_LENGTH-1, "%s/%s.scr", dir, fb);
fichero=fopen(db,"r"); fichero=fopen(db,"rb");
if(fichero!=NULL) if(fichero!=NULL)
{ {
@ -1195,6 +1194,7 @@ static void set_port(int which)
strcat(load_path_poke,"poke"); strcat(load_path_poke,"poke");
ordenador.port = which; ordenador.port = which;
break; break;
#ifdef GEKKO
case 1: //PORT_SD case 1: //PORT_SD
if (sdismount) { if (sdismount) {
strcpy(load_path_snaps,"sd:/"); strcpy(load_path_snaps,"sd:/");
@ -1250,6 +1250,7 @@ static void set_port(int which)
else else
msgInfo("FTP is not mounted",3000,NULL); msgInfo("FTP is not mounted",3000,NULL);
break; break;
#endif
default: default:
break; break;
} }
@ -1371,7 +1372,7 @@ int parse_poke (const char *filename)
trainer=0; trainer=0;
fpoke = fopen(filename,"r"); fpoke = fopen(filename,"rb");
if (fpoke==NULL) if (fpoke==NULL)
{ {
@ -1809,7 +1810,7 @@ static void save_load_general_configurations(int which)
case 2: case 2:
case 0: // Load or delete file case 0: // Load or delete file
{ {
fconfig = fopen(config_path,"r"); fconfig = fopen(config_path,"rb");
if (fconfig==NULL) if (fconfig==NULL)
{ {
msgInfo("Can not access the file",3000,NULL); msgInfo("Can not access the file",3000,NULL);

View File

@ -86,14 +86,10 @@ static SDL_Surface *real_screen;
#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' ) #define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' )
#define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' ) #define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' )
#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' ) #define IS_MARKER(p_msg) ( (p_msg)[0] == '@' )
#define FONT_PATH "/fbzx-wii/fbzx/FreeMono.ttf"
static int is_inited = 0; static int is_inited = 0;
static TTF_Font *menu_font16, *menu_font20, *menu_font8, *menu_font10; static TTF_Font *menu_font16, *menu_font20, *menu_font8, *menu_font10;
#if defined(GEKKO)
#define FONT_PATH "/fbzx-wii/fbzx/FreeMono.ttf"
#else
#define FONT_PATH "FreeMono.ttf"
#endif
int fh, fw; int fh, fw;
@ -1035,10 +1031,6 @@ uint32_t menu_wait_key_press()
case SDLK_PAGEUP: case SDLK_PAGEUP:
keys |= KEY_PAGEUP; keys |= KEY_PAGEUP;
break; break;
case SDLK_RETURN:
case SDLK_SPACE:
keys |= KEY_SELECT;
break;
case SDLK_HOME: case SDLK_HOME:
case SDLK_ESCAPE: case SDLK_ESCAPE:
keys |= KEY_ESCAPE; keys |= KEY_ESCAPE;
@ -1047,14 +1039,28 @@ uint32_t menu_wait_key_press()
break; break;
} }
break; break;
case SDL_QUIT: case SDL_KEYUP:
exit(0); switch (ev.key.keysym.sym)
{
case SDLK_RETURN:
case SDLK_SPACE:
keys |= KEY_SELECT;
break; break;
default: default:
break; break;
} }
break; break;
case SDL_QUIT:
exit(0);
break;
#ifndef GEKKO
case SDL_MOUSEBUTTONDOWN:
if (ev.button.button==SDL_BUTTON_LEFT) keys |= KEY_SELECT;
break;
#endif
default:
break;
}
} }
if (keys != 0) if (keys != 0)
@ -1456,7 +1462,7 @@ static TTF_Font *read_font(const char *path, int font_size)
TTF_Font *out; TTF_Font *out;
SDL_RWops *rw; SDL_RWops *rw;
Uint8 *data = (Uint8*)malloc(1 * 1024*1024); Uint8 *data = (Uint8*)malloc(1 * 1024*1024);
FILE *fp = fopen(path, "r"); FILE *fp = fopen(path, "rb");
if (!data) { if (!data) {
fprintf(stderr, "Malloc failed\n"); fprintf(stderr, "Malloc failed\n");

View File

@ -209,6 +209,11 @@ void settings_menu() {
print_string(fbuffer,"V:",30,400,12,0,ancho); print_string(fbuffer,"V:",30,400,12,0,ancho);
print_string(fbuffer,"TV Set mode",78,400,15,0,ancho); print_string(fbuffer,"TV Set mode",78,400,15,0,ancho);
#ifndef GEKKO
print_string(fbuffer,"F:",350,400,12,0,ancho);
print_string(fbuffer,"Full screen",398,400,15,0,ancho);
#endif
print_string(fbuffer,"ESC:",168,450,12,0,ancho); print_string(fbuffer,"ESC:",168,450,12,0,ancho);
print_string(fbuffer,"return emulator",232,450,15,0,ancho); print_string(fbuffer,"return emulator",232,450,15,0,ancho);
@ -298,6 +303,11 @@ void settings_menu() {
ordenador.turbo = 1; //Auto mode ordenador.turbo = 1; //Auto mode
} }
break; break;
#ifndef GEKKO
case SDLK_f:
SDL_Fullscreen_Switch();
break;
#endif
} }
} while(fin); } while(fin);
@ -706,7 +716,7 @@ void select_tapfile() {
} }
if (!strncmp(filename,"smb:",4)) ordenador.tap_file=fopen(filename,"r"); //tinysmb does not work with r+ if (!strncmp(filename,"smb:",4)) ordenador.tap_file=fopen(filename,"r"); //tinysmb does not work with r+
else ordenador.tap_file=fopen(filename,"r+"); // read and write else ordenador.tap_file=fopen(filename,"r+b"); // read and write
ordenador.tape_write = 0; // by default, can't record ordenador.tape_write = 0; // by default, can't record
if(ordenador.tap_file==NULL) if(ordenador.tap_file==NULL)
@ -734,12 +744,10 @@ void select_tapfile() {
retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header
if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) { if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) {
ordenador.tape_file_type = TAP_TZX; ordenador.tape_file_type = TAP_TZX;
rewind_tape(ordenador.tap_file,1); create_browser_tzx(ordenador.tap_file);
browser_tzx(ordenador.tap_file);
} else { } else {
ordenador.tape_file_type = TAP_TAP; ordenador.tape_file_type = TAP_TAP;
rewind_tape(ordenador.tap_file,1); create_browser_tap(ordenador.tap_file);
browser_tap(ordenador.tap_file);
} }
clean_screen(); clean_screen();
@ -780,7 +788,7 @@ void create_tapfile() {
retorno=-1; retorno=-1;
if(!retorno) { if(!retorno) {
ordenador.tap_file=fopen(nombre2,"a+"); // create for read and write ordenador.tap_file=fopen(nombre2,"a+b"); // create for read and write
if(ordenador.tap_file==NULL) if(ordenador.tap_file==NULL)
retorno=-2; retorno=-2;
else else
@ -791,6 +799,8 @@ void create_tapfile() {
ordenador.tape_file_type = TAP_TAP; ordenador.tape_file_type = TAP_TAP;
switch(retorno) { switch(retorno) {
case 0: case 0:
strcpy(ordenador.last_selected_file,nombre2);
create_browser_tap(ordenador.tap_file);
break; break;
case -1: case -1:
print_string(videomem,"File already exists",-1,80,10,0,ancho); print_string(videomem,"File already exists",-1,80,10,0,ancho);
@ -1872,7 +1882,7 @@ void keyboard_menu() {
buffer=screen->pixels; buffer=screen->pixels;
clean_screen(); clean_screen();
fichero=myfopen("fbzx/keymap.bmp","r"); fichero=myfopen("fbzx/keymap.bmp","rb");
if (fichero==NULL) { if (fichero==NULL) {
strcpy(ordenador.osd_text,"Keymap picture not found"); strcpy(ordenador.osd_text,"Keymap picture not found");
ordenador.osd_time=100; ordenador.osd_time=100;
@ -2019,7 +2029,7 @@ if (freq == 0)
ordenador.cpufreq = 3500000; ordenador.cpufreq = 3500000;
break; break;
} }
else ordenador.cpufreq = freq; else ordenador.cpufreq = freq*turbo_n;
ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES); ordenador.tst_sample=(ordenador.cpufreq + (ordenador.freq*N_SAMPLES/2))/(ordenador.freq*N_SAMPLES);

View File

@ -24,12 +24,14 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <SDL/SDL_audio.h>
//char tabla[1024]; //char tabla[1024];
#include <fcntl.h> #include <fcntl.h>
#ifndef GEKKO #ifndef GEKKO
#include <sys/ioctl.h> //#include <sys/ioctl.h>
#endif #endif
#ifdef DEBUG #ifdef DEBUG
@ -70,6 +72,11 @@ pa_simple *pulse_s;
int started_sound_asnd; int started_sound_asnd;
#endif #endif
unsigned char started_sound_sdl;
unsigned char buffer0_occupied;
unsigned char buffer1_occupied;
unsigned char buffer_reading;
enum e_soundtype sound_type; enum e_soundtype sound_type;
int sound_init() { int sound_init() {
@ -79,12 +86,22 @@ int sound_init() {
case SOUND_NO: // No sound; simulate 8bits mono case SOUND_NO: // No sound; simulate 8bits mono
printf("No Sound\n"); printf("No Sound\n");
ordenador.sign=0; ordenador.sign=0;
ordenador.format=0; ordenador.format=1;
ordenador.channels=1; ordenador.channels=2;
ordenador.freq=48000; ordenador.freq=48000;
ordenador.buffer_len=4800; // will wait 1/10 second ordenador.buffer_len=4800; // will wait 1/10 second
return (0); return (0);
break; break;
case SOUND_SDL:
printf("Trying SDL sound\n");
if(0==sound_init_sdl()) {
sound_type=SOUND_SDL;
return 0;
} else {
printf("Failed\n");
return -1;
}
break;
#ifdef D_SOUND_PULSE #ifdef D_SOUND_PULSE
case SOUND_PULSEAUDIO: case SOUND_PULSEAUDIO:
printf("Trying PulseAudio\n"); printf("Trying PulseAudio\n");
@ -138,6 +155,13 @@ int sound_init() {
break; break;
} }
} }
printf("Trying SDL sound\n");
if(0==sound_init_sdl()) {
sound_type=SOUND_SDL;
return 0;
}
#ifdef D_SOUND_PULSE #ifdef D_SOUND_PULSE
printf("Trying PulseAudio\n"); printf("Trying PulseAudio\n");
if(0==sound_init_pulse()) { if(0==sound_init_pulse()) {
@ -172,6 +196,58 @@ int sound_init() {
return -1; return -1;
} }
void sdlcallback(void *unused, Uint8 *stream, int len)
{
int i;
len=len/4;
for(i=0;i<len;i++) //len = ordenador.buffer_len
{
if (buffer_reading==0)
{
*((unsigned int *)stream) =sound[0][i];
sound[0][i]=0;
}
else
{
*((unsigned int *)stream) =sound[1][i];
sound[1][i]=0;
}
stream=stream+4;
}
//change reading buffer
if (buffer_reading==0) {buffer0_occupied=0;if (buffer1_occupied) buffer_reading=1;}
else {buffer1_occupied=0;if (buffer0_occupied) buffer_reading=0;}
}
int sound_init_sdl() {
SDL_AudioSpec fmt;
ordenador.sign=0;
ordenador.format=1; //16 bit
ordenador.channels=2; //stereo
ordenador.freq=48000;
ordenador.buffer_len=4096;
/* Set 16-bit stereo audio at 48Khz */
fmt.freq = ordenador.freq;
fmt.format = AUDIO_U16LSB; //unsigned Little endian
fmt.channels = ordenador.channels;
fmt.samples = ordenador.buffer_len; //number of samples
fmt.callback = sdlcallback;
fmt.userdata = NULL;
started_sound_sdl=0;
/* Open the audio device and start playing sound! */
if (SDL_OpenAudio(&fmt, NULL) < 0 ) return -1;
return 0;
}
#ifdef GEKKO #ifdef GEKKO
int voice; int voice;
void callback(voice) void callback(voice)
@ -465,6 +541,24 @@ void sound_play() {
usleep(75000); // wait 1/20 second usleep(75000); // wait 1/20 second
return; return;
break; break;
case SOUND_SDL: // SDL
if (!started_sound_sdl) {
SDL_PauseAudio(0);
ordenador.current_buffer = sound[0];
buffer0_occupied=1;
started_sound_sdl = 1;
buffer_reading=0;
}
//Double buffer
while ((buffer0_occupied)&&(buffer1_occupied)){usleep(1000);}; //Wait for one buffer to be free
if (!buffer0_occupied) //Buffer 0 is now free
{buffer0_occupied=1;
ordenador.current_buffer = sound[0]; }
else //Buffer 1 is now free
{buffer1_occupied=1;
ordenador.current_buffer = sound[1]; }
return;
break;
#ifdef D_SOUND_OSS #ifdef D_SOUND_OSS
case SOUND_OSS: // OSS case SOUND_OSS: // OSS
retval=write(audio_fd,ordenador.current_buffer,ordenador.buffer_len*ordenador.increment); retval=write(audio_fd,ordenador.current_buffer,ordenador.buffer_len*ordenador.increment);
@ -523,6 +617,9 @@ void sound_close() {
switch(sound_type) { switch(sound_type) {
case SOUND_NO: case SOUND_NO:
break; break;
case SOUND_SDL:
SDL_CloseAudio();
break;
#ifdef D_SOUND_OSS #ifdef D_SOUND_OSS
case SOUND_OSS: case SOUND_OSS:
close(audio_fd); close(audio_fd);

View File

@ -21,7 +21,7 @@
#ifndef SOUND_H #ifndef SOUND_H
#define SOUND_H #define SOUND_H
enum e_soundtype {SOUND_NO, SOUND_OSS, SOUND_ALSA, SOUND_PULSEAUDIO, SOUND_AUTOMATIC, SOUND_ASND}; enum e_soundtype {SOUND_NO, SOUND_OSS, SOUND_ALSA, SOUND_PULSEAUDIO, SOUND_AUTOMATIC, SOUND_ASND,SOUND_SDL};
extern enum e_soundtype sound_type; extern enum e_soundtype sound_type;
@ -35,6 +35,7 @@ int sound_init_oss();
int sound_init_alsa(); int sound_init_alsa();
int sound_init_pulse(); int sound_init_pulse();
int sound_init_asnd(); int sound_init_asnd();
int sound_init_sdl();
//void sdlcallback(void *userdata, Uint8 *stream, int len); //void sdlcallback(void *userdata, Uint8 *stream, int len);

View File

@ -76,8 +76,9 @@ inline void tape_read(FILE *fichero, int tstados) {
inline void tape_read_tap (FILE * fichero, int tstados) { inline void tape_read_tap (FILE * fichero, int tstados) {
static unsigned char value, value2; static unsigned char value;
int retval; static unsigned char value2;
static int retval;
if (fichero == NULL) if (fichero == NULL)
{ {
@ -206,8 +207,8 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
static unsigned char value, value2,value3,value4,done; static unsigned char value, value2,value3,value4,done;
static unsigned int bucle,bucle2, byte_position; static unsigned int bucle,bucle2, byte_position;
int retval; static int retval;
char block_jump[2]; static char block_jump[2];
if (fichero == NULL) if (fichero == NULL)
{ {
@ -249,7 +250,6 @@ inline void tape_read_tzx (FILE * fichero, int tstados) {
ordenador.tape_pause_at_end=10; // to avoid problems ordenador.tape_pause_at_end=10; // to avoid problems
ordenador.tape_pause_at_end *= 3500; ordenador.tape_pause_at_end *= 3500;
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
if (feof (fichero)) { if (feof (fichero)) {
rewind_tape(fichero,1); rewind_tape(fichero,1);
@ -722,12 +722,10 @@ unsigned char file_empty(FILE *fichero) {
void save_file(FILE *fichero) { void save_file(FILE *fichero) {
long position;
unsigned char xor,salir_s; unsigned char xor,salir_s;
byte dato; byte dato;
int longitud; int longitud;
position=ftell(fichero); // store current position
fseek(fichero,0,SEEK_END); // put position at end fseek(fichero,0,SEEK_END); // put position at end
xor=0; xor=0;
@ -758,12 +756,11 @@ void save_file(FILE *fichero) {
fprintf(fichero,"%c",xor); fprintf(fichero,"%c",xor);
procesador.Rm.wr.IX++; procesador.Rm.wr.IX++;
procesador.Rm.wr.IX++; procesador.Rm.wr.IX++;
fseek(fichero,position,SEEK_SET); // put position at end
ordenador.tape_position = position; create_browser_tap(ordenador.tap_file);
if(ordenador.tape_fast_load==1) //if we want fast load, we assume we want fast save too if(ordenador.tape_fast_load==1) //if we want fast load, we assume we want fast save too
ordenador.other_ret = 1; // next instruction must be RET procesador.PC=0x555; // next instruction must be RET
return; return;
} }
@ -794,7 +791,6 @@ void fastload_block_tap (FILE * fichero) {
unsigned char value[65536], empty, parity; unsigned char value[65536], empty, parity;
int retval; int retval;
//ordenador.other_ret = 1; // next instruction must be RET
procesador.PC=0x5e2; procesador.PC=0x5e2;
if (!(procesador.Ra.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

View File

@ -37,7 +37,7 @@ extern FILE *fdebug;
struct browser *browser_list[MAX_BROWSER_ITEM+1]; struct browser *browser_list[MAX_BROWSER_ITEM+1];
struct tape_select *block_select_list[MAX_SELECT_ITEM+1]; struct tape_select *block_select_list[MAX_SELECT_ITEM+1];
void browser_tzx (FILE * fichero) { void create_browser_tzx (FILE * fichero) {
unsigned int longitud, len, bucle, byte_position, retorno, block_number; 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;
@ -49,20 +49,6 @@ void browser_tzx (FILE * fichero) {
blockid=0; blockid=0;
flag_byte=0; flag_byte=0;
empty=file_empty(fichero);
if (fichero == NULL)
{
sprintf (ordenador.osd_text, "No tape selected");
ordenador.osd_time = 100;
return;
}
if(empty)
{
sprintf (ordenador.osd_text, "Tape file empty");
return;
}
//Free the browser list //Free the browser list
for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle<MAX_BROWSER_ITEM)); bucle++) for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle<MAX_BROWSER_ITEM)); bucle++)
@ -71,6 +57,14 @@ void browser_tzx (FILE * fichero) {
browser_list[bucle]=NULL; browser_list[bucle]=NULL;
} }
if (fichero == NULL) return;
empty=file_empty(fichero);
if (empty) return;
rewind_tape(fichero,1);
retorno=0; retorno=0;
block_number=0; block_number=0;
do { do {
@ -321,28 +315,12 @@ browser_list[block_number]=NULL;
} }
void browser_tap (FILE * fichero) { void create_browser_tap (FILE * fichero) {
unsigned int longitud, bucle, block_number, byte_position ; unsigned int longitud, bucle, block_number, byte_position ;
unsigned char value[65536], empty, flag_byte; unsigned char value[65536], empty, flag_byte;
int retval, retorno; int retval, retorno;
empty=file_empty(fichero);
if (fichero == NULL)
{
sprintf (ordenador.osd_text, "No tape selected");
ordenador.osd_time = 100;
return;
}
if(empty)
{
sprintf (ordenador.osd_text, "Tape file empty");
return;
}
//Free the browser list //Free the browser list
for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle<MAX_BROWSER_ITEM)); bucle++) for(bucle=0; ((browser_list[bucle]!=NULL)&&(bucle<MAX_BROWSER_ITEM)); bucle++)
{ {
@ -350,6 +328,14 @@ void browser_tap (FILE * fichero) {
browser_list[bucle]=NULL; browser_list[bucle]=NULL;
} }
if (fichero == NULL) return;
empty=file_empty(fichero);
if (empty) return;
rewind_tape(fichero,1);
flag_byte=0; flag_byte=0;
retorno=0; retorno=0;
block_number=0; block_number=0;

View File

@ -37,8 +37,8 @@ struct tape_select {
extern struct tape_select *block_select_list[MAX_SELECT_ITEM+1]; extern struct tape_select *block_select_list[MAX_SELECT_ITEM+1];
extern struct browser *browser_list[MAX_BROWSER_ITEM+1]; extern struct browser *browser_list[MAX_BROWSER_ITEM+1];
void browser_tap (FILE *); void create_browser_tap (FILE *);
void browser_tzx (FILE *); void create_browser_tzx (FILE *);
int select_block(FILE * fichero); int select_block(FILE * fichero);
int jump_to_block(FILE * fichero, int blocks_to_jump); int jump_to_block(FILE * fichero, int blocks_to_jump);
void free_browser(); void free_browser();

View File

@ -52,6 +52,12 @@ void Z80free_INT(Z80FREE *processor,byte value) {
} }
void Z80free_INT_reset(Z80FREE *processor) {
processor->INT_P=0;
}
int Z80free_step(Z80FREE *processor) { int Z80free_step(Z80FREE *processor) {
int retval=0; int retval=0;
@ -77,7 +83,6 @@ int Z80free_ustep(Z80FREE *processor) {
Z80free_doPush(processor,processor->PC); Z80free_doPush(processor,processor->PC);
processor->PC=0x0066; processor->PC=0x0066;
processor->IFF1=0; // disable INTs processor->IFF1=0; // disable INTs
processor->Status=Z80INT;
return(11); // we use 11 tstates for attending a NMI return(11); // we use 11 tstates for attending a NMI
} }
if (processor->INT_P) { if (processor->INT_P) {
@ -87,7 +92,6 @@ int Z80free_ustep(Z80FREE *processor) {
processor->HALT=0; processor->HALT=0;
processor->PC++; processor->PC++;
} }
processor->Status=Z80INT;
processor->IFF1=0; processor->IFF1=0;
processor->IFF2=0; processor->IFF2=0;
Z80free_doPush(processor,processor->PC); Z80free_doPush(processor,processor->PC);
@ -143,9 +147,13 @@ int Z80free_ustep(Z80FREE *processor) {
processor->Status=Z80FD; processor->Status=Z80FD;
return 4; return 4;
} }
if (opcode==0xED) {
processor->Status=Z80ED;
return 4;
}
processor->Status=Z80XX; processor->Status=Z80XX;
if (opcode==0xCB) { if (opcode==0xCB) {
d1=Z80free_Rd_fetch(processor->PC++); d1=Z80free_Rd(processor->PC++);
retval+=Z80free_codesDDCB(processor,d1); retval+=Z80free_codesDDCB(processor,d1);
} else { } else {
retval+=Z80free_codesDD(processor,opcode); retval+=Z80free_codesDD(processor,opcode);
@ -161,9 +169,13 @@ int Z80free_ustep(Z80FREE *processor) {
if (opcode==0xFD) { if (opcode==0xFD) {
return 4; return 4;
} }
if (opcode==0xED) {
processor->Status=Z80ED;
return 4;
}
processor->Status=Z80XX; processor->Status=Z80XX;
if (opcode==0xCB) { if (opcode==0xCB) {
d1=Z80free_Rd_fetch(processor->PC++); d1=Z80free_Rd(processor->PC++);
retval+=Z80free_codesFDCB(processor,d1); retval+=Z80free_codesFDCB(processor,d1);
} else { } else {
retval+=Z80free_codesFD(processor,opcode); retval+=Z80free_codesFD(processor,opcode);
@ -582,8 +594,10 @@ void Z80free_doRRD(Z80FREE *processor) {
void Z80free_doPush (Z80FREE *processor, word val) { void Z80free_doPush (Z80FREE *processor, word val) {
processor->Rm.wr.SP-=2; processor->Rm.wr.SP-=1;
Z80free_write16(processor->Rm.wr.SP, val); Z80free_Wr(processor->Rm.wr.SP, (byte)((val >> 8) & 0xFF));
processor->Rm.wr.SP-=1;
Z80free_Wr(processor->Rm.wr.SP, (byte)(val & 0xFF));
} }

View File

@ -137,6 +137,7 @@ void Z80free_reset(Z80FREE *);
int Z80free_step(Z80FREE *); int Z80free_step(Z80FREE *);
int Z80free_ustep(Z80FREE *); int Z80free_ustep(Z80FREE *);
void Z80free_INT(Z80FREE *,byte); void Z80free_INT(Z80FREE *,byte);
void Z80free_INT_reset(Z80FREE *);
byte Z80free_Rd (register word Addr); byte Z80free_Rd (register word Addr);
byte Z80free_Rd_fake (register word Addr); byte Z80free_Rd_fake (register word Addr);

View File

@ -23,7 +23,7 @@ int Z80free_codesDDCB (Z80FREE *processor,byte d1) {
static byte tmp1; static byte tmp1;
static word tmp2; static word tmp2;
static byte opcode; static byte opcode;
opcode=Z80free_Rd_fetch(processor->PC++); opcode=Z80free_Rd(processor->PC++);
switch(opcode) { switch(opcode) {
case 0: // LD_RLC B,(IX+d) case 0: // LD_RLC B,(IX+d)

View File

@ -23,7 +23,7 @@ int Z80free_codesFDCB (Z80FREE *processor,byte d1) {
static byte tmp1; static byte tmp1;
static word tmp2; static word tmp2;
static byte opcode; static byte opcode;
opcode=Z80free_Rd_fetch(processor->PC++); opcode=Z80free_Rd(processor->PC++);
switch(opcode) { switch(opcode) {
case 0: // LD_RLC B,(IY+d) case 0: // LD_RLC B,(IY+d)