added 64k NTSC, precision emulation, 320X240 resolution, frame rate setting, screen menu

This commit is contained in:
fabio.olimpieri 2012-07-29 08:39:21 +00:00
parent 52fa3dabd5
commit 539e3e81a8
16 changed files with 11736 additions and 10987 deletions

View File

@ -67,8 +67,8 @@ void draw()
int y,x; int y,x;
int screen_w = VirtualKeyboard.screen->w; int screen_w = VirtualKeyboard.screen->w;
int screen_h = VirtualKeyboard.screen->h; int screen_h = VirtualKeyboard.screen->h;
int key_w = 54; int key_w = 54/RATIO;
int key_h = 36; int key_h = 36/RATIO;
int border_x = (screen_w - (key_w * KEY_COLS)) / 2; int border_x = (screen_w - (key_w * KEY_COLS)) / 2;
int border_y = (screen_h - (key_h * KEY_ROWS)) / 2; int border_y = (screen_h - (key_h * KEY_ROWS)) / 2;
SDL_Rect bg_rect = {border_x, border_y, SDL_Rect bg_rect = {border_x, border_y,
@ -170,7 +170,7 @@ struct virtkey *get_key_internal()
struct virtkey* get_key() struct virtkey* get_key()
{ {
virtkey_t *key; virtkey_t *key;
SDL_Rect rect = {32, 120, FULL_DISPLAY_X-64, FULL_DISPLAY_Y-250}; SDL_Rect rect = {32/RATIO, 120/RATIO, FULL_DISPLAY_X-64/RATIO, FULL_DISPLAY_Y-250/RATIO};
keys[3 * KEY_COLS + 0 ].is_done = 0; //Caps Shit keys[3 * KEY_COLS + 0 ].is_done = 0; //Caps Shit
keys[3 * KEY_COLS + 8 ].is_done = 0; //Sym Shift keys[3 * KEY_COLS + 8 ].is_done = 0; //Sym Shift

View File

@ -591,9 +591,10 @@ void load_snap(struct z80snapshot *snap) {
printf("Mode 128K\n"); printf("Mode 128K\n");
ordenador.mode128k=1; // 128k mode ordenador.mode128k=1; // 128k mode
ordenador.issue=3; ordenador.issue=3;
ordenador.videosystem=0;
ResetComputer(); ResetComputer();
printf("Pager: %X\n",snap->pager); printf("Pager: %X\n",snap->pager);
Z80free_Out(0x7FFD,snap->pager); Z80free_Out_fake(0x7FFD,snap->pager);
break; break;
default: default:
break; break;
@ -642,7 +643,7 @@ void load_snap(struct z80snapshot *snap) {
printf("IFF1:%x IFF2:%x\n",snap->IFF1,snap->IFF1); printf("IFF1:%x IFF2:%x\n",snap->IFF1,snap->IFF1);
procesador.IM=snap->Imode; procesador.IM=snap->Imode;
printf("IM:%x\n",snap->Imode); printf("IM:%x\n",snap->Imode);
Z80free_Out(0xFFFE,((snap->border&0x07)|0x10)); Z80free_Out_fake(0xFFFE,((snap->border&0x07)|0x10));
switch(snap->type) { switch(snap->type) {
case 0: // 48K case 0: // 48K

View File

@ -33,6 +33,7 @@
#include "microdrive.h" #include "microdrive.h"
#include "Virtualkeyboard.h" #include "Virtualkeyboard.h"
#include "gui_sdl.h" #include "gui_sdl.h"
#include "menu_sdl.h"
#if defined(GEKKO) #if defined(GEKKO)
# include <ogc/system.h> # include <ogc/system.h>
# include <wiiuse/wpad.h> # include <wiiuse/wpad.h>
@ -47,6 +48,7 @@ extern FILE *fdebug;
#endif #endif
#endif #endif
/* Returns the bus value when reading a port without a periferial */ /* Returns the bus value when reading a port without a periferial */
inline byte bus_empty () { inline byte bus_empty () {
@ -60,13 +62,19 @@ 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 (int tstados) { inline void emulate_screen (int tstados) {
if((procesador.I>=0x40)&&(procesador.I<=0x7F)) { if((procesador.I & 0xC0) == 0x40) { // (procesador.I>=0x40)&&(procesador.I<=0x7F)
ordenador.screen_snow=1; ordenador.screen_snow=1;
} else } else
ordenador.screen_snow=0; ordenador.screen_snow=0;
show_screen (tstados);
if (ordenador.precision) show_screen_precision (tstados);
else show_screen(tstados);
}
inline void emulate (int tstados) {
play_ay (tstados); play_ay (tstados);
play_sound (tstados); play_sound (tstados);
tape_read (ordenador.tap_file, tstados); tape_read (ordenador.tap_file, tstados);
@ -87,10 +95,12 @@ void computer_init () {
ordenador.port254 = 0; ordenador.port254 = 0;
ordenador.issue = 3; ordenador.issue = 3;
ordenador.mode128k = 0; ordenador.mode128k = 0;
ordenador.videosystem = 0; //PAL
ordenador.joystick[0] = 1; //Kemposton ordenador.joystick[0] = 1; //Kemposton
ordenador.joystick[1] = 0; // Cursor ordenador.joystick[1] = 0; // Cursor
ordenador.rumble[0] = 0; ordenador.rumble[0] = 0;
ordenador.rumble[1] = 0; ordenador.rumble[1] = 0;
ordenador.precision = 0;
ordenador.tape_readed = 0; ordenador.tape_readed = 0;
ordenador.pause = 1; // tape stop ordenador.pause = 1; // tape stop
@ -124,6 +134,10 @@ void computer_init () {
ordenador.vol_c = 0; ordenador.vol_c = 0;
ordenador.tst_ay = 0; ordenador.tst_ay = 0;
ordenador.tst_ay2 = 0; ordenador.tst_ay2 = 0;
ordenador.wr = 0;
ordenador.r_fetch = 0;
ordenador.io = 0;
ordenador.contention = 0;
ordenador.ayval_a = 0; ordenador.ayval_a = 0;
ordenador.ayval_b = 0; ordenador.ayval_b = 0;
@ -144,6 +158,8 @@ void computer_init () {
strcpy (ordenador.SmbShare, "Share"); strcpy (ordenador.SmbShare, "Share");
strcpy (ordenador.SmbIp, "192.168.0.1"); strcpy (ordenador.SmbIp, "192.168.0.1");
ordenador.autoconf=0; ordenador.autoconf=0;
ordenador.cpufreq = 3500000; // values for 48K mode
} }
void computer_set_palete() { void computer_set_palete() {
@ -360,6 +376,7 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.screen = pantalla; ordenador.screen = pantalla;
ordenador.border = 0; ordenador.border = 0;
ordenador.border_p = 0;
ordenador.currline = 0; ordenador.currline = 0;
ordenador.currpix = 0; ordenador.currpix = 0;
ordenador.flash = 0; ordenador.flash = 0;
@ -372,8 +389,6 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.init_line = 0; ordenador.init_line = 0;
ordenador.next_line = 640; ordenador.next_line = 640;
ordenador.next_scanline = 640; ordenador.next_scanline = 640;
ordenador.first_line = 40;
ordenador.last_line = 280;
ordenador.first_pixel = 16; ordenador.first_pixel = 16;
ordenador.last_pixel = 336; ordenador.last_pixel = 336;
ordenador.next_pixel = 1; ordenador.next_pixel = 1;
@ -383,8 +398,6 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.init_line = 65; ordenador.init_line = 65;
ordenador.next_line = 160; ordenador.next_line = 160;
ordenador.next_scanline = 160; ordenador.next_scanline = 160;
ordenador.first_line = 40;
ordenador.last_line = 280;
ordenador.first_pixel = 0; ordenador.first_pixel = 0;
ordenador.last_pixel = 351; ordenador.last_pixel = 351;
ordenador.next_pixel = 1; ordenador.next_pixel = 1;
@ -394,8 +407,6 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.init_line = 479; ordenador.init_line = 479;
ordenador.next_line = -(307202); ordenador.next_line = -(307202);
ordenador.next_scanline = -1; ordenador.next_scanline = -1;
ordenador.first_line = 40;
ordenador.last_line = 280;
ordenador.first_pixel = 16; ordenador.first_pixel = 16;
ordenador.last_pixel = 336; ordenador.last_pixel = 336;
ordenador.next_pixel = 480; ordenador.next_pixel = 480;
@ -405,8 +416,6 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.init_line = 0; ordenador.init_line = 0;
ordenador.next_line = 0; ordenador.next_line = 0;
ordenador.next_scanline = 0; ordenador.next_scanline = 0;
ordenador.first_line = 40;
ordenador.last_line = 280;
ordenador.first_pixel = 0; ordenador.first_pixel = 0;
ordenador.last_pixel = 319; ordenador.last_pixel = 319;
ordenador.next_pixel = 1; ordenador.next_pixel = 1;
@ -424,6 +433,7 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.pixel = ((unsigned char *) (ordenador.screen->pixels)) + ordenador.init_line; ordenador.pixel = ((unsigned char *) (ordenador.screen->pixels)) + ordenador.init_line;
ordenador.interr = 0; ordenador.interr = 0;
ordenador.readkeyboard = 0;
ordenador.p_translt = ordenador.translate; ordenador.p_translt = ordenador.translate;
ordenador.p_translt2 = ordenador.translate2; ordenador.p_translt2 = ordenador.translate2;
@ -431,7 +441,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;
@ -439,8 +449,6 @@ void register_screen (SDL_Surface * pantalla) {
ordenador.num_buff = 0; // first buffer ordenador.num_buff = 0; // first buffer
ordenador.sound_cuantity = 0; ordenador.sound_cuantity = 0;
ordenador.sound_current_value = 0; ordenador.sound_current_value = 0;
ordenador.pixancho = 447;
ordenador.pixalto = 311; // values for 48K mode
} }
void set_memory_pointers () { void set_memory_pointers () {
@ -514,38 +522,48 @@ void set_memory_pointers () {
/* Paints the spectrum screen during the TSTADOS tstates that the Z80 used /* Paints the spectrum screen during the TSTADOS tstates that the Z80 used
to execute last instruction */ to execute last instruction */
inline void show_screen (int tstados) { inline void show_screen (int tstados) {
static unsigned char temporal, ink, paper, fflash, tmp2; static unsigned char temporal, temporal3, ink, paper, fflash, tmp2;
ordenador.tstados_counter += tstados; ordenador.tstados_counter += tstados;
ordenador.cicles_counter += tstados; ordenador.cicles_counter += tstados;
if (curr_frames<jump_frames) { //Jump the frame drawing if (curr_frames<jump_frames) { //Jump the frame drawing
if (ordenador.tstados_counter>=69888) { if (ordenador.tstados_counter>=ordenador.tstatodos_frame) {
ordenador.tstados_counter-=69888; ordenador.tstados_counter-=ordenador.tstatodos_frame;
ordenador.interr = 1; ordenador.interr = 1;
if ((ordenador.turbo == 0) || (curr_frames%7 == 0)) ordenador.readkeyboard = 1;
curr_frames++; curr_frames++;
} }
return; return;
} }
fflash = 0; // flash flag fflash = 0; // flash flag
while (ordenador.tstados_counter > 3) { while (ordenador.tstados_counter > 3) {
ordenador.tstados_counter -= 4; ordenador.tstados_counter -= 4;
//test if current pixel is outside visible area
if ((ordenador.currline >= ordenador.first_line) && (ordenador.currline < ordenador.last_line)&&
(ordenador.currpix > 15) && (ordenador.currpix < 336))
{
// test if current pixel is for border or for user area // test if current pixel is for border or for user area
if ((ordenador.currline < 64) || (ordenador.currline > 255) if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line)
|| (ordenador.currpix < 48) || (ordenador.currpix > 303)) { || (ordenador.currpix < 48) || (ordenador.currpix > 303)) {
// is border // is border
ordenador.contended_zone=0; // no contention here
if (ordenador.ulaplus) { if (ordenador.ulaplus) {
paint_pixels (255, ordenador.border+24, 0); // paint 8 pixels with BORDER color paint_pixels (255, ordenador.border+24, 0, 8); // paint 8 pixels with BORDER color
} else { } else {
paint_pixels (255, ordenador.border, 0); // paint 8 pixels with BORDER color paint_pixels (255, ordenador.border, 0, 8); // paint 8 pixels with BORDER color
} }
ordenador.bus_value = 255; ordenador.bus_value = 255;
@ -554,10 +572,9 @@ 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; // can have contention
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;
ink = temporal & 0x07; // ink colour ink = temporal & 0x07; // ink colour
paper = (temporal >> 3) & 0x07; // paper colour paper = (temporal >> 3) & 0x07; // paper colour
if (ordenador.ulaplus) { if (ordenador.ulaplus) {
@ -575,18 +592,23 @@ inline void show_screen (int tstados) {
// Snow Effect // Snow Effect
if(ordenador.screen_snow) { if(ordenador.screen_snow) {
temporal = ordenador.memoria[(((*ordenador.p_translt) + (ordenador.video_offset))&0xFFFFFF00)+(procesador.R)]; // data with snow temporal3 = ordenador.memoria[(((*ordenador.p_translt) + (ordenador.video_offset))&0xFFFFFF00)+(procesador.R)]; // data with snow
ordenador.screen_snow=0; // no more snow for now ordenador.screen_snow=0; // no more snow for now
} else } else
temporal = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // data temporal3 = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // bitmap // bitmap
ordenador.p_translt++; ordenador.p_translt++;
ordenador.p_translt2++; ordenador.p_translt2++;
if ((fflash) && (ordenador.flash)) if ((fflash) && (ordenador.flash))
paint_pixels (temporal, paper, ink); // if FLASH, invert PAPER and INK paint_pixels (temporal3, paper, ink, 8); // if FLASH, invert PAPER and INK
else else
paint_pixels (temporal, ink, paper); paint_pixels (temporal3, ink, paper, 8);
} }
}
//Update pixel position
ordenador.currpix += 8; ordenador.currpix += 8;
if (ordenador.currpix > ordenador.pixancho) { if (ordenador.currpix > ordenador.pixancho) {
ordenador.currpix = 0; ordenador.currpix = 0;
@ -596,7 +618,9 @@ inline void show_screen (int tstados) {
} }
} }
if ((ordenador.currline > ordenador.pixalto)&&(ordenador.currpix>=64)) {
//End of frame
if ((ordenador.currline > ordenador.pixalto)&&(ordenador.currpix>63)) {
ordenador.currpix=64; ordenador.currpix=64;
if (ordenador.osd_time) { if (ordenador.osd_time) {
ordenador.osd_time--; ordenador.osd_time--;
@ -626,6 +650,7 @@ inline void show_screen (int tstados) {
curr_frames=0; curr_frames=0;
ordenador.currline = 0; ordenador.currline = 0;
ordenador.interr = 1; ordenador.interr = 1;
ordenador.readkeyboard = 1;
ordenador.cicles_counter=0; ordenador.cicles_counter=0;
ordenador.pixel = ((unsigned char *) (ordenador.screen->pixels))+ordenador.init_line; // +ordenador.init_line; ordenador.pixel = ((unsigned char *) (ordenador.screen->pixels))+ordenador.init_line; // +ordenador.init_line;
ordenador.p_translt = ordenador.translate; ordenador.p_translt = ordenador.translate;
@ -639,21 +664,236 @@ inline void show_screen (int tstados) {
} }
} }
//Write the screen from 14339 state
/* PAINT_PIXELS paints one byte with INK color for 1 bits and PAPER color inline void show_screen_precision (int tstados) {
static unsigned char temporal, temporal2, temporal_1, temporal2_1,temporal3, ink, paper, fflash, tmp2;
ordenador.tstados_counter += tstados;
if (curr_frames<jump_frames) { //Jump the frame drawing
if (ordenador.tstados_counter>=ordenador.tstatodos_frame) {
ordenador.tstados_counter-=ordenador.tstatodos_frame;
ordenador.interr = 1;
ordenador.readkeyboard = 1;
curr_frames++;
}
if (ordenador.tstados_counter > 31) ordenador.interr = 0;
return;
}
while (ordenador.tstados_counter>0) {
ordenador.tstados_counter--;
//test if current pixel is outside visible area
if ((ordenador.currline >= ordenador.first_line) && (ordenador.currline < ordenador.last_line)&&
(ordenador.currpix > 15) && (ordenador.currpix < 336))
{
ordenador.pixels_word = ordenador.currpix%16;
ordenador.pixels_octect = ordenador.currpix%8;
// test if current pixel is for border or for user area
if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line)
|| (ordenador.currpix < 48) || (ordenador.currpix > 303)) {
// is border
if (ordenador.pixels_octect==0) ordenador.border_p = ordenador.border;
if (ordenador.ulaplus) {
paint_pixels (255, ordenador.border_p+24, 0, 2); // paint 2 pixels with BORDER color
} else {
paint_pixels (255, ordenador.border_p, 0, 2); // paint 2 pixels with BORDER color
}
ordenador.bus_value = 255;
if ((ordenador.currline == ordenador.upper_border_line) && (ordenador.currpix == 46))
{
temporal = ordenador.memoria[(*ordenador.p_translt2) + ordenador.video_offset]; // attributes
temporal2 = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // bitmap
temporal_1 = ordenador.memoria[(*(ordenador.p_translt2+1)) + ordenador.video_offset]; // attributes
temporal2_1 = ordenador.memoria[((*ordenador.p_translt+1)) + ordenador.video_offset]; // bitmap
ordenador.p_translt+=2;
ordenador.p_translt2+=2;
ordenador.bus_value = temporal2;
}
} else {
// is user area. We search for ink and paper colours
switch (ordenador.pixels_word)
{
case 0: //start of first byte
ink = temporal & 0x07; // ink colour
paper = (temporal >> 3) & 0x07; // paper colour
if (ordenador.ulaplus) {
tmp2=0x10+((temporal>>2)&0x30);
ink+=tmp2;
paper+=8+tmp2;
} else {
if (temporal & 0x40) { // bright flag?
ink += 8;
paper += 8;
}
fflash = temporal & 0x80; // flash flag
}
// Snow Effect
if(ordenador.screen_snow) {
temporal3 = ordenador.memoria[(((*ordenador.p_translt) + (ordenador.video_offset))&0xFFFFFF00)+(procesador.R)]; // data with snow
ordenador.screen_snow=0; // no more snow for now
} else
temporal3 = temporal2; // bitmap
break;
case 8: //start of second byte
ink = temporal_1 & 0x07; // ink colour
paper = (temporal_1 >> 3) & 0x07; // paper colour
if (ordenador.ulaplus) {
tmp2=0x10+((temporal_1>>2)&0x30);
ink+=tmp2;
paper+=8+tmp2;
} else {
if (temporal_1 & 0x40) { // bright flag?
ink += 8;
paper += 8;
}
fflash = temporal_1 & 0x80; // flash flag
}
temporal3 = temporal2_1; // bitmap
break;
case 14: //sample the memory
temporal = ordenador.memoria[(*ordenador.p_translt2) + ordenador.video_offset]; // attributes
temporal2 = ordenador.memoria[(*ordenador.p_translt) + ordenador.video_offset]; // bitmap
temporal_1 = ordenador.memoria[(*(ordenador.p_translt2+1)) + ordenador.video_offset]; // attributes
temporal2_1 = ordenador.memoria[((*ordenador.p_translt+1)) + ordenador.video_offset]; // bitmap
ordenador.p_translt+=2;
ordenador.p_translt2+=2;
break;
}
//Floating bus
if (ordenador.currpix < 295)
switch (ordenador.pixels_word)
{
case 14:
// bitmap
ordenador.bus_value = temporal2;
break;
case 0:
// attributes
ordenador.bus_value = temporal;
break;
case 2:
// bitmap
ordenador.bus_value = temporal2_1;
break;
case 4:
// attributes
ordenador.bus_value = temporal_1;
break;
default:
ordenador.bus_value = 255;
break;
}
if ((fflash) && (ordenador.flash))
paint_pixels (temporal3, paper, ink, 2); // if FLASH, invert PAPER and INK
else
paint_pixels (temporal3, ink, paper ,2);
}
}
//Update pixel position
ordenador.cicles_counter++;
ordenador.currpix += 2;
if (ordenador.currpix > ordenador.pixancho) {
ordenador.currpix = 0;
ordenador.currline++;
if (ordenador.currline > ordenador.first_line) { // ordenador.first_line)
ordenador.pixel += ordenador.next_line; // ordenador.next_line;
}
}
//End of frame
if ((ordenador.currline > ordenador.pixalto)&&(ordenador.currpix>ordenador.start_screen)){
if (ordenador.osd_time) {
ordenador.osd_time--;
if (ordenador.osd_time==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 {
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.mustlock) {
SDL_UnlockSurface (ordenador.screen);
SDL_Flip (ordenador.screen);
SDL_LockSurface (ordenador.screen);
} else {
SDL_Flip (ordenador.screen);
}
curr_frames=0;
ordenador.currline = 0;
ordenador.interr = 1;
ordenador.readkeyboard = 1;
ordenador.cicles_counter=0;
ordenador.pixel = ((unsigned char *) (ordenador.screen->pixels))+ordenador.init_line; // +ordenador.init_line;
ordenador.p_translt = ordenador.translate;
ordenador.p_translt2 = ordenador.translate2;
ordenador.contador_flash++;
if (ordenador.contador_flash == 16) {
ordenador.flash = 1 - ordenador.flash;
ordenador.contador_flash = 0;
}
}
//End of interrupt
if (ordenador.cicles_counter == 32) ordenador.interr = 0;
}
}
/* PAINT_PIXELS paints bits with INK color for 1 bits and PAPER color
for 0 bits, and increment acordingly the pointer PIXEL */ for 0 bits, and increment acordingly the pointer PIXEL */
inline void paint_pixels (unsigned char octet,unsigned char ink, unsigned char paper) { inline void paint_pixels (unsigned char octet,unsigned char ink, unsigned char paper, unsigned char bit) {
static int bucle,valor,*p; static int bucle,valor,*p;
static unsigned char mask; static unsigned char mask;
if ((ordenador.currpix < 16) || (ordenador.currpix >= 336) if (ordenador.pixels_octect==0 ||bit == 8) mask = 0x80;
|| (ordenador.currline < 40) || (ordenador.currline >= 280))
return;
mask = 0x80; for (bucle = 0; bucle < bit; bucle++) {
for (bucle = 0; bucle < 8; bucle++) {
valor = (octet & mask) ? (int) ink : (int) paper; valor = (octet & mask) ? (int) ink : (int) paper;
p=(colors+valor); p=(colors+valor);
@ -1133,6 +1373,11 @@ void ResetComputer () {
ordenador.updown=0; ordenador.updown=0;
ordenador.leftright=0; ordenador.leftright=0;
ordenador.wr=0;
ordenador.r_fetch = 0;
ordenador.io = 0;
ordenador.contention = 0;
ordenador.ulaplus=0; ordenador.ulaplus=0;
ordenador.mport1 = 0; ordenador.mport1 = 0;
@ -1141,8 +1386,31 @@ void ResetComputer () {
switch (ordenador.mode128k) { switch (ordenador.mode128k) {
case 0: // 48K case 0: // 48K
ordenador.pixancho = 447; ordenador.pixancho = 447;
ordenador.start_screen=41;
if (ordenador.videosystem==0)
{
ordenador.pixalto = 311; ordenador.pixalto = 311;
ordenador.upper_border_line = 64;
ordenador.lower_border_line = 64 + 192;
ordenador.cpufreq = 3500000;
ordenador.tstatodos_frame= 69888;
ordenador.start_contention = 14335;
ordenador.end_contention = 14335+224*192;
ordenador.first_line = 40;
ordenador.last_line = 280;
}
else
{
ordenador.pixalto = 263;
ordenador.upper_border_line = 40;
ordenador.lower_border_line = 40 + 192;
ordenador.cpufreq = 3527500;
ordenador.tstatodos_frame= 59136;
ordenador.start_contention = 8959;
ordenador.end_contention = 8959+224*192;
ordenador.first_line = 16;
ordenador.last_line = 256;
}
ordenador.block0 = ordenador.memoria; ordenador.block0 = ordenador.memoria;
ordenador.block1 = ordenador.memoria + 131072; // video mem. in page 9 (page 5 in 128K) ordenador.block1 = ordenador.memoria + 131072; // video mem. in page 9 (page 5 in 128K)
ordenador.block2 = ordenador.memoria + 65536; // 2nd block in page 6 (page 2 in 128K) ordenador.block2 = ordenador.memoria + 65536; // 2nd block in page 6 (page 2 in 128K)
@ -1151,13 +1419,22 @@ void ResetComputer () {
break; break;
case 3: // +2A/+3 case 3: // +2A/+3
Z80free_Out (0x1FFD, 0); Z80free_Out_fake (0x1FFD, 0);
case 1: // 128K case 1: // 128K
case 2: // +2 case 2: // +2
case 4: // spanish 128K case 4: // spanish 128K
Z80free_Out (0x7FFD, 0); Z80free_Out_fake (0x7FFD, 0);
ordenador.pixancho = 455; ordenador.pixancho = 455;
ordenador.pixalto = 310; ordenador.pixalto = 310;
ordenador.upper_border_line = 63;
ordenador.lower_border_line = 63 + 192;
ordenador.cpufreq = 3546900;
ordenador.tstatodos_frame= 70908;
ordenador.start_contention = 14361;
ordenador.end_contention = 14361+228*192;
ordenador.first_line = 40;
ordenador.last_line = 280;
ordenador.start_screen=45;
break; break;
} }
@ -1168,26 +1445,66 @@ void ResetComputer () {
void do_contention() { void do_contention() {
if (!ordenador.contended_zone) static int ccicles;
return;
if (ordenador.cicles_counter<14335) { if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line)
return; || (ordenador.currpix < 40) || (ordenador.currpix > 295)) return;
if (ordenador.mode128k==3) //+3
{
ccicles=((ordenador.currpix-28)/2)%8; //44-16
if (ccicles>6) return;
ordenador.contention+=7-ccicles;
emulate_screen(7-ccicles);
}
else //64k/128k/+2
{
ccicles=((ordenador.currpix-40)/2)%8;
if (ccicles>5) return;
ordenador.contention+=6-ccicles;
emulate_screen(6-ccicles);
} }
int ccicles=(ordenador.cicles_counter-14335)%8;
if (ccicles>5) {
return;
} }
emulate(6-ccicles);
}
void Z80free_Wr (register word Addr, register byte Value) { void Z80free_Wr (register word Addr, register byte Value) {
ordenador.wr+=3;
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000:
// 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.mode128k == 3) && (1 == (ordenador.mport2 & 0x01)))
*(ordenador.block0 + Addr) = (unsigned char) Value;
break;
case 0x4000:
do_contention();
if (ordenador.precision) emulate_screen(3);
*(ordenador.block1 + Addr) = (unsigned char) Value;
break;
case 0x8000:
if (ordenador.precision) emulate_screen(3);
*(ordenador.block2 + Addr) = (unsigned char) Value;
break;
case 0xC000:
if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention();
emulate_screen(3);
}
*(ordenador.block3 + Addr) = (unsigned char) Value;
break;
}
}
void Z80free_Wr_fake (register word Addr, register byte Value) {
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
@ -1196,7 +1513,6 @@ void Z80free_Wr (register word Addr, register byte Value) {
break; break;
case 0x4000: case 0x4000:
do_contention();
*(ordenador.block1 + Addr) = (unsigned char) Value; *(ordenador.block1 + Addr) = (unsigned char) Value;
break; break;
@ -1210,6 +1526,53 @@ void Z80free_Wr (register word Addr, register byte Value) {
} }
} }
byte Z80free_Rd_fetch (register word Addr) {
if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I
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;
switch (Addr & 0xC000) {
case 0x0000:
if (ordenador.precision) emulate_screen (4);
return ((byte) (*(ordenador.block0 + Addr)));
break;
case 0x4000:
do_contention();
if (ordenador.precision) emulate_screen (4);
return ((byte) (*(ordenador.block1 + Addr)));
break;
case 0x8000:
if (ordenador.precision) emulate_screen (4);
return ((byte) (*(ordenador.block2 + Addr)));
break;
case 0xC000:
if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention();
emulate_screen (4);
}
return ((byte) (*(ordenador.block3 + Addr)));
break;
default:
printf ("Memory error\n");
exit (1);
return 0;
}
break;
}
}
byte Z80free_Rd (register word Addr) { byte Z80free_Rd (register word Addr) {
@ -1223,21 +1586,29 @@ byte Z80free_Rd (register word Addr) {
break; break;
default: default:
ordenador.wr+=3;
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
if (ordenador.precision) emulate_screen (3);
return ((byte) (*(ordenador.block0 + Addr))); return ((byte) (*(ordenador.block0 + Addr)));
break; break;
case 0x4000: case 0x4000:
do_contention(); do_contention();
if (ordenador.precision) emulate_screen (3);
return ((byte) (*(ordenador.block1 + Addr))); return ((byte) (*(ordenador.block1 + Addr)));
break; break;
case 0x8000: case 0x8000:
if (ordenador.precision) emulate_screen (3);
return ((byte) (*(ordenador.block2 + Addr))); return ((byte) (*(ordenador.block2 + Addr)));
break; break;
case 0xC000: case 0xC000:
if (ordenador.precision) {
if (((ordenador.mode128k==1)||(ordenador.mode128k==2)||(ordenador.mode128k==4))&&(ordenador.mport1 & 0x01)) do_contention();
emulate_screen (3);
}
return ((byte) (*(ordenador.block3 + Addr))); return ((byte) (*(ordenador.block3 + Addr)));
break; break;
@ -1275,22 +1646,47 @@ void set_palete_entry(unsigned char entry, byte Value) {
void Z80free_Out (register word Port, register byte Value) { void Z80free_Out (register word Port, register byte Value) {
// Microdrive access
register word maskport; register word maskport;
if (((Port&0x0001)==0)||((Port>=0x4000)&&(Port<0x8000))) { //It should out after 3 states
do_contention();
if (ordenador.precision)
{
switch (ordenador.mode128k)
{
case 0:
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;}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();ordenador.io+=3;}
} }
else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();ordenador.io+=1;}
break;
case 1:
case 2:
case 4:
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;}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();ordenador.io+=3;}
}
else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();ordenador.io+=1;}
break;
case 3:
break; //no io contention in +3
default:
break;
}
}
else if ((Port&0x0001)==0) do_contention();
// ULAPlus // ULAPlus
if (Port == 0xBF3B) { if (Port == 0xBF3B) {
do_contention();
ordenador.ulaplus_reg = Value; ordenador.ulaplus_reg = Value;
return; return;
} }
if (Port == 0xFF3B) { if (Port == 0xFF3B) {
do_contention();
if (ordenador.ulaplus_reg==0x40) { // mode if (ordenador.ulaplus_reg==0x40) { // mode
ordenador.ulaplus=Value&0x01; ordenador.ulaplus=Value&0x01;
return; return;
@ -1301,6 +1697,8 @@ void Z80free_Out (register word Port, register byte Value) {
} }
} }
// Microdrive access
if(((Port &0x0018)!=0x0018)&&(ordenador.mdr_active)) if(((Port &0x0018)!=0x0018)&&(ordenador.mdr_active))
microdrive_out(Port,Value); microdrive_out(Port,Value);
@ -1321,9 +1719,9 @@ void Z80free_Out (register word Port, register byte Value) {
// Memory page (7FFD & 1FFD) // Memory page (7FFD & 1FFD)
if (ordenador.mode128k==3) { if (ordenador.mode128k==3) {
maskport=0x0FFD;
} else {
maskport=0x3FFD; maskport=0x3FFD;
} else {
maskport=0x7FFD;
} }
if (((Port|maskport) == 0x7FFD) && (0 == (ordenador.mport1 & 0x20))) { if (((Port|maskport) == 0x7FFD) && (0 == (ordenador.mport1 & 0x20))) {
@ -1331,37 +1729,104 @@ void Z80free_Out (register word Port, register byte Value) {
set_memory_pointers (); // set the pointers set_memory_pointers (); // set the pointers
} }
if (((Port|maskport) == 0x1FFD) && (0 == (ordenador.mport1 & 0x20))) { if (((Port|0x0FFD) == 0x1FFD) && (0 == (ordenador.mport1 & 0x20))) {
ordenador.mport2 = (unsigned char) Value; ordenador.mport2 = (unsigned char) Value;
set_memory_pointers (); // set the pointers set_memory_pointers (); // set the pointers
} }
// Sound chip (AY-3-8912) // Sound chip (AY-3-8912)
if (((Port|maskport) == 0xFFFD)&&(ordenador.ay_emul)) if (((Port|0x3FFD) == 0xFFFD)&&(ordenador.ay_emul)) // bit1, 14 ,15 according to the manual
ordenador.ay_latch = ((unsigned int) (Value & 0x0F)); ordenador.ay_latch = ((unsigned int) (Value & 0x0F));
if (((Port|maskport) == 0xBFFD)&&(ordenador.ay_emul)) { if (((Port|0x3FFD) == 0xBFFD)&&(ordenador.ay_emul)) { //bit1, 14 ,15 according to the manual
ordenador.ay_registers[ordenador.ay_latch] = (unsigned char) Value; ordenador.ay_registers[ordenador.ay_latch] = (unsigned char) Value;
if (ordenador.ay_latch == 13) //Envelope shape if (ordenador.ay_latch == 13) //Envelope shape
ordenador.ay_envel_way = 2; // start cycle ordenador.ay_envel_way = 2; // start cycle
} }
} }
void Z80free_Out_fake (register word Port, register byte Value) {
register word maskport;
// ULA port (A0 low)
if (!(Port & 0x0001)) {
ordenador.port254 = (unsigned char) Value;
ordenador.border = (((unsigned char) Value) & 0x07);
if (ordenador.pause) {
if (Value & 0x10)
ordenador.sound_bit = 1;
else
ordenador.sound_bit = 0; // assign to SOUND_BIT the value
}
}
// Memory page (7FFD & 1FFD)
if (ordenador.mode128k==3) {
maskport=0x3FFD;
} else {
maskport=0x7FFD;
}
if (((Port|maskport) == 0x7FFD) && (0 == (ordenador.mport1 & 0x20))) {
ordenador.mport1 = (unsigned char) Value;
set_memory_pointers (); // set the pointers
}
if (((Port|0x0FFD) == 0x1FFD) && (0 == (ordenador.mport1 & 0x20))) {
ordenador.mport2 = (unsigned char) Value;
set_memory_pointers (); // set the pointers
}
}
byte Z80free_In (register word Port) { byte Z80free_In (register word Port) {
static unsigned int temporal_io; static unsigned int temporal_io;
byte pines; static byte pines;
if (((Port&0x0001)==0)||((Port>=0x4000)&&(Port<0x8000))) {
do_contention(); if (ordenador.precision)
{
ordenador.io+=4;
switch (ordenador.mode128k)
{
case 0:
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);}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);}
} }
else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();emulate_screen(3);}
else emulate_screen(4);
break;
case 1:
case 2:
case 4:
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);}
else {do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);do_contention();emulate_screen(1);}
}
else
if ((Port&0x0001)==0 ||(Port == 0xBF3B)||(Port == 0xFF3B)) {emulate_screen(1);do_contention();emulate_screen(3);}
else emulate_screen(4);
break;
case 3:
emulate_screen(4);//no io contention in +3
break;
default:
emulate_screen(4);
break;
}
}
else if ((Port&0x0001)==0) do_contention();
temporal_io = (unsigned int) Port; temporal_io = (unsigned int) Port;
if (Port == 0xFF3B) { if (Port == 0xFF3B) {
do_contention();
if (ordenador.ulaplus_reg==0x40) { // mode if (ordenador.ulaplus_reg==0x40) { // mode
return(ordenador.ulaplus&0x01); return(ordenador.ulaplus&0x01);
} }
@ -1415,7 +1880,10 @@ byte Z80free_In (register word Port) {
} }
} }
if ((temporal_io == 0xFFFD)&&(ordenador.ay_emul)) if ((temporal_io == 0xFFFD)&&(ordenador.ay_emul)) //any mask to apply?
return (ordenador.ay_registers[ordenador.ay_latch]);
if ((temporal_io == 0xBFFD)&&(ordenador.ay_emul)&&(ordenador.mode128k==3)) //any mask to apply?
return (ordenador.ay_registers[ordenador.ay_latch]); return (ordenador.ay_registers[ordenador.ay_latch]);
// Microdrive access // Microdrive access
@ -1425,6 +1893,11 @@ byte Z80free_In (register word Port) {
pines=bus_empty(); pines=bus_empty();
if (ordenador.precision && (ordenador.mode128k==1||ordenador.mode128k==2||(ordenador.mode128k==4)))
{ if (temporal_io == 0x7FFD) Z80free_Out_fake (0x7FFD,pines); //writeback 0X7ffd
if (temporal_io == 0x3FFD) Z80free_Out_fake (0x3FFD,pines); //writeback 0X3ffd
}
return (pines); return (pines);
} }
@ -1475,3 +1948,46 @@ void set_volume (unsigned char volume) {
break; break;
} }
} }
void restart_video()
{
int dblbuffer=1,hwsurface=1;
char old_border;
clean_screen();
if (ordenador.mustlock) {
SDL_UnlockSurface (ordenador.screen);
SDL_Flip (ordenador.screen);
SDL_LockSurface (ordenador.screen);
} else {
SDL_Flip (ordenador.screen);
}
switch(ordenador.zaurus_mini) {
case 0:
init_screen(640,480,0,0,dblbuffer,hwsurface);
break;
case 1:
case 2:
init_screen(480,640,0,0,dblbuffer,hwsurface);
break;
case 3:
init_screen(320,240,0,0,dblbuffer,hwsurface);
break;
}
old_border = ordenador.border;
register_screen(screen);
ordenador.border = old_border;
ordenador.screenbuffer=ordenador.screen->pixels;
ordenador.screen_width=ordenador.screen->w;
//Init SDL Menu
menu_init(ordenador.screen);
clean_screen();
}

View File

@ -36,6 +36,7 @@ int countdown;
struct computer { struct computer {
unsigned char precision; //If set 1 emulate with more precision
unsigned int temporal_io; unsigned int temporal_io;
// screen private global variables // screen private global variables
@ -52,7 +53,7 @@ struct computer {
unsigned int *p_translt,*p_translt2; unsigned int *p_translt,*p_translt2;
unsigned char *pixel; // current address unsigned char *pixel; // current address
char border,flash; char border,flash, border_p;
int currline,currpix; int currline,currpix;
int tstados_counter; // counts tstates leaved to the next call int tstados_counter; // counts tstates leaved to the next call
@ -67,8 +68,18 @@ struct computer {
int next_pixel; // next pixel int next_pixel; // next pixel
int pixancho,pixalto; // maximum pixel value for width and height int pixancho,pixalto; // maximum pixel value for width and height
int jump_pixel; int jump_pixel;
int upper_border_line; //63 or 62 for 48k or 128k
int lower_border_line; //upper_border_line + 192
int start_screen; //Pixel at which the interrupt is generated
int cpufreq; //frequency CPU
int tstatodos_frame; //number of tstados per frame
int pixels_octect; //2 bits in the octect
int pixels_word; //2 bits in the word
int start_contention; //start 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 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
@ -121,13 +132,18 @@ struct computer {
signed char ay_envel_value; signed char ay_envel_value;
unsigned char ay_envel_way; unsigned char ay_envel_way;
unsigned char sound_current_value; unsigned char sound_current_value;
unsigned int wr;
unsigned int r_fetch;
unsigned int io;
unsigned int contention;
// bus global variables // bus global variables
unsigned char bus_counter; unsigned char bus_counter;
unsigned char bus_value; unsigned char bus_value;
unsigned char issue; // 2= 48K issue 2, 3= 48K issue 3 unsigned char issue; // 2= 48K issue 2, 3= 48K issue 3
unsigned char mode128k; // 0=48K, 1=128K, 2=+2, 3=+3 unsigned char mode128k; // 0=48K, 1=128K, 2=+2, 3=+3 4=sp
unsigned char videosystem; //0=PAL, 1=NTSC
unsigned char joystick[2]; // 0=cursor, 1=kempston, 2=sinclair1, 3=sinclair2 unsigned char joystick[2]; // 0=cursor, 1=kempston, 2=sinclair1, 3=sinclair2
unsigned char port254; unsigned char port254;
@ -193,6 +209,7 @@ struct computer {
unsigned char memoria[196608]; // memory (12 pages of 16K each one). 4 for ROM, and 8 for RAM unsigned char memoria[196608]; // memory (12 pages of 16K each one). 4 for ROM, and 8 for RAM
unsigned char shadowrom[8192]; // space for Interface I's ROMs unsigned char shadowrom[8192]; // space for Interface I's ROMs
unsigned char interr; unsigned char interr;
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)
@ -219,11 +236,13 @@ struct computer {
void computer_init(); void computer_init();
void register_screen(SDL_Surface *); void register_screen(SDL_Surface *);
inline void show_screen(int); inline void show_screen(int);
inline void paint_pixels(unsigned char, unsigned char, unsigned char); inline void show_screen_precision(int);
inline void paint_pixels(unsigned char, unsigned char, unsigned char, unsigned char);
inline void read_keyboard(); inline void read_keyboard();
void fill_audio(void *udata,Uint8 *,int); void fill_audio(void *udata,Uint8 *,int);
void set_volume(unsigned char); void set_volume(unsigned char);
inline void play_sound(unsigned int); inline void play_sound(unsigned int);
inline void emulate_screen(int);
inline void emulate(int); inline void emulate(int);
void ResetComputer(); void ResetComputer();
inline byte bus_empty(); inline byte bus_empty();
@ -232,5 +251,6 @@ inline void play_ay();
inline void paint_one_pixel(unsigned char *colour,unsigned char *address); inline void paint_one_pixel(unsigned char *colour,unsigned char *address);
void computer_set_palete(); void computer_set_palete();
void set_palete_entry(unsigned char entry, byte Value); void set_palete_entry(unsigned char entry, byte Value);
void restart_video();
#endif #endif

View File

@ -77,6 +77,10 @@ bool usbismount = false;
bool networkisinit = false; bool networkisinit = false;
bool smbismount = false; bool smbismount = false;
extern int FULL_DISPLAY_X; //640
extern int FULL_DISPLAY_Y; //480
extern int RATIO;
#if defined(GEKKO) #if defined(GEKKO)
/**************************************************************************** /****************************************************************************
@ -347,10 +351,9 @@ void load_rom(char type) {
size=fread(ordenador.shadowrom,8192,1,fichero); size=fread(ordenador.shadowrom,8192,1,fichero);
fclose(fichero); fclose(fichero);
} }
void init_sdl()
void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hwsurface) { {
int retorno, bucle;
int retorno,bucle,bucle2,valores,ret2;
//if (sound_type!=3) //if (sound_type!=3)
retorno=SDL_Init(SDL_INIT_VIDEO); retorno=SDL_Init(SDL_INIT_VIDEO);
@ -380,6 +383,11 @@ void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hw
} }
} }
} }
}
void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hwsurface) {
int valores;
// screen initialization // screen initialization
valores=SDL_HWPALETTE|SDL_ANYFORMAT; valores=SDL_HWPALETTE|SDL_ANYFORMAT;
@ -410,6 +418,17 @@ void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hw
printf("Locking screen: %d\n", ordenador.mustlock); printf("Locking screen: %d\n", ordenador.mustlock);
printf("Return screen init\n");
FULL_DISPLAY_X = resx;
FULL_DISPLAY_Y = resy;
RATIO = 640/FULL_DISPLAY_X;
}
void init_sound()
{
int bucle, bucle2,ret2;
// sound initialization // sound initialization
if (sound_type==SOUND_AUTOMATIC) { if (sound_type==SOUND_AUTOMATIC) {
@ -439,10 +458,9 @@ void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hw
} }
printf("Init sound 2\n"); printf("Init sound 2\n");
ordenador.tst_sample=3500000/ordenador.freq; ordenador.tst_sample=ordenador.cpufreq/ordenador.freq;
//printf("Set volume\n"); //printf("Set volume\n");
//set_volume(70); //set_volume(70);
printf("Return init\n");
} }
void end_system() { void end_system() {
@ -506,11 +524,16 @@ int save_config(struct computer *object, char *filename) {
fprintf(fconfig,"mode=%c%c",48+object->mode128k,10); fprintf(fconfig,"mode=%c%c",48+object->mode128k,10);
fprintf(fconfig,"issue=%c%c",48+object->issue,10); fprintf(fconfig,"issue=%c%c",48+object->issue,10);
fprintf(fconfig,"ntsc=%c%c",48+object->videosystem,10);
fprintf(fconfig,"joystick1=%c%c",48+object->joystick[0],10); fprintf(fconfig,"joystick1=%c%c",48+object->joystick[0],10);
fprintf(fconfig,"joystick2=%c%c",48+object->joystick[1],10); fprintf(fconfig,"joystick2=%c%c",48+object->joystick[1],10);
fprintf(fconfig,"ay_sound=%c%c",48+object->ay_emul,10); fprintf(fconfig,"ay_sound=%c%c",48+object->ay_emul,10);
fprintf(fconfig,"interface1=%c%c",48+object->mdr_active,10); fprintf(fconfig,"interface1=%c%c",48+object->mdr_active,10);
fprintf(fconfig,"doublescan=%c%c",48+object->dblscan,10); fprintf(fconfig,"doublescan=%c%c",48+object->dblscan,10);
fprintf(fconfig,"framerate=%c%c",48+jump_frames,10);
fprintf(fconfig,"screen=%c%c",48+object->zaurus_mini,10);
fprintf(fconfig,"text=%c%c",48+object->text_mini,10);
fprintf(fconfig,"precision=%c%c",48+object->precision,10);
fprintf(fconfig,"volume=%c%c",65+(object->volume),10); fprintf(fconfig,"volume=%c%c",65+(object->volume),10);
fprintf(fconfig,"bw=%c%c",48+object->bw,10); fprintf(fconfig,"bw=%c%c",48+object->bw,10);
fprintf(fconfig,"tap_fast=%c%c",48+object->tape_fast_load,10); fprintf(fconfig,"tap_fast=%c%c",48+object->tape_fast_load,10);
@ -639,8 +662,9 @@ int load_config(struct computer *object, char *filename) {
char line[1024],carac,done; char line[1024],carac,done;
int pos, key_sdl=0; int pos, key_sdl=0;
FILE *fconfig; FILE *fconfig;
unsigned char volume=255,mode128k=255,issue=255,joystick1=255,joystick2=255,ay_emul=255,mdr_active=255, unsigned char volume=255,mode128k=255,issue=255,ntsc=255, joystick1=255,joystick2=255,ay_emul=255,mdr_active=255,
dblscan=255,bw=255, tap_fast=255, joypad1=255, joypad2=255, rumble1=255, rumble2=255, joy_n=255, key_n=255, port=255, autoconf=255; dblscan=255,framerate =255, screen =255, text=255, precision=255, bw=255, tap_fast=255,
joypad1=255, joypad2=255, rumble1=255, rumble2=255, joy_n=255, key_n=255, port=255, autoconf=255;
if (filename) strcpy(config_path,filename); if (filename) strcpy(config_path,filename);
else return -2; else return -2;
@ -682,6 +706,10 @@ int load_config(struct computer *object, char *filename) {
issue=line[6]-'0'; issue=line[6]-'0';
continue; continue;
} }
if (!strncmp(line,"ntsc=",5)) {
ntsc=line[5]-'0';
continue;
}
if (!strncmp(line,"joystick1=",10)) { if (!strncmp(line,"joystick1=",10)) {
joystick1=line[10]-'0'; joystick1=line[10]-'0';
continue; continue;
@ -698,10 +726,26 @@ int load_config(struct computer *object, char *filename) {
mdr_active=line[11]-'0'; mdr_active=line[11]-'0';
continue; continue;
} }
if (!strncmp(line,"screen=",7)) {
screen=line[7]-'0';
continue;
}
if (!strncmp(line,"text=",5)) {
text=line[5]-'0';
continue;
}
if (!strncmp(line,"doublescan=",11)) { if (!strncmp(line,"doublescan=",11)) {
dblscan=line[11]-'0'; dblscan=line[11]-'0';
continue; continue;
} }
if (!strncmp(line,"framerate=",10)) {
framerate=line[10]-'0';
continue;
}
if (!strncmp(line,"precision=",10)) {
precision=line[10]-'0';
continue;
}
if (!strncmp(line,"volume=",7)) { if (!strncmp(line,"volume=",7)) {
volume=(line[7]-'A'); volume=(line[7]-'A');
continue; continue;
@ -752,6 +796,9 @@ int load_config(struct computer *object, char *filename) {
if (issue<4) { if (issue<4) {
object->issue=issue; object->issue=issue;
} }
if (issue<2) {
object->videosystem=ntsc;
}
if (joystick1<4) { if (joystick1<4) {
object->joystick[0]=joystick1; object->joystick[0]=joystick1;
} }
@ -767,6 +814,18 @@ int load_config(struct computer *object, char *filename) {
if (dblscan<2) { if (dblscan<2) {
object->dblscan=dblscan; object->dblscan=dblscan;
} }
if (framerate<6) {
jump_frames=framerate;
}
if (screen<4) {
object->zaurus_mini=screen;
}
if (text<2) {
object->text_mini=text;
}
if (precision<2) {
object->precision=precision;
}
if (bw<2) { if (bw<2) {
object->bw=bw; object->bw=bw;
} }
@ -802,7 +861,7 @@ int load_config(struct computer *object, char *filename) {
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
int bucle,tstados,argumento,fullscreen,dblbuffer,hwsurface,length; int bucle,tstados,tstados_screen, argumento,fullscreen,dblbuffer,hwsurface,length;
char gamefile[4096],config_path[1024] ; char gamefile[4096],config_path[1024] ;
word PC=0; word PC=0;
@ -965,6 +1024,9 @@ int main(int argc,char *argv[]) {
} }
atexit(end_system); atexit(end_system);
init_sdl();
switch(ordenador.zaurus_mini) { switch(ordenador.zaurus_mini) {
case 0: case 0:
init_screen(640,480,0,0,dblbuffer,hwsurface); init_screen(640,480,0,0,dblbuffer,hwsurface);
@ -977,6 +1039,9 @@ int main(int argc,char *argv[]) {
init_screen(320,240,0,0,dblbuffer,hwsurface); init_screen(320,240,0,0,dblbuffer,hwsurface);
break; break;
} }
init_sound();
printf("Modo: %d\n",ordenador.mode128k); printf("Modo: %d\n",ordenador.mode128k);
register_screen(screen); register_screen(screen);
printf("Screen registered\n"); printf("Screen registered\n");
@ -988,16 +1053,18 @@ int main(int argc,char *argv[]) {
SDL_WM_SetCaption("FBZX",""); SDL_WM_SetCaption("FBZX","");
#endif #endif
ordenador.interr=0; ordenador.interr=0;
ordenador.readkeyboard = 0;
ordenador.screenbuffer=ordenador.screen->pixels; ordenador.screenbuffer=ordenador.screen->pixels;
ordenador.screen_width=ordenador.screen->w; ordenador.screen_width=ordenador.screen->w;
//Init SDL Menu //Init SDL Menu
font_init();
menu_init(ordenador.screen); menu_init(ordenador.screen);
//Load the splash screen //Load the splash screen
if (load_zxspectrum_picture()) SDL_FreeSurface (image); if (ordenador.zaurus_mini==0) if (load_zxspectrum_picture()) SDL_FreeSurface (image);
#ifdef GEKKO #ifdef GEKKO
usbismount = InitUSB(); usbismount = InitUSB();
@ -1098,11 +1165,24 @@ int main(int argc,char *argv[]) {
do { do {
tstados=Z80free_ustep(&procesador); tstados=Z80free_ustep(&procesador);
if(tstados<0) {
printf("Error %X\n",procesador.PC); if (ordenador.precision)
exit(1); {
tstados_screen=tstados-ordenador.r_fetch -ordenador.wr -ordenador.io;
if(tstados_screen>0) emulate_screen(tstados_screen);
ordenador.wr=0;
ordenador.r_fetch=0;
ordenador.io=0;
emulate(tstados+ordenador.contention); // execute the whole hardware emulation for that number of TSTATES
ordenador.contention=0;
} }
emulate(tstados); // execute the whole hardware emulation for that number of TSTATES else
if (tstados>0) {
emulate_screen(tstados);
emulate(tstados+ordenador.contention);
ordenador.contention=0;
}
} while(procesador.Status!=Z80XX); } while(procesador.Status!=Z80XX);
PC=procesador.PC; PC=procesador.PC;
@ -1149,10 +1229,14 @@ int main(int argc,char *argv[]) {
if((PC==0x0700)&&(ordenador.mdr_active)) if((PC==0x0700)&&(ordenador.mdr_active))
ordenador.mdr_paged = 2; ordenador.mdr_paged = 2;
if(ordenador.interr==1) { if(ordenador.readkeyboard==1) {
read_keyboard (); // read the physical keyboard read_keyboard (); // read the physical keyboard
ordenador.readkeyboard = 0;
}
if(ordenador.interr==1) {
Z80free_INT(&procesador,bus_empty()); Z80free_INT(&procesador,bus_empty());
ordenador.interr=0; if (ordenador.precision==0) ordenador.interr=0;
} }
} }

View File

@ -47,5 +47,8 @@ int load_config(struct computer *object, char *filename);
int save_config(struct computer *object, char *filename); int save_config(struct computer *object, char *filename);
int save_config_game(struct computer *object, char *filename, int overwrite); int save_config_game(struct computer *object, char *filename, int overwrite);
FILE *myfopen(char *filename,char *mode); FILE *myfopen(char *filename,char *mode);
void init_sdl();
void init_sound();
void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hwsurface);
#endif #endif

View File

@ -31,7 +31,7 @@
#include "emulator.h" #include "emulator.h"
#include "VirtualKeyboard.h" #include "VirtualKeyboard.h"
#include "tape.h" #include "tape.h"
//#include "menus.h" #include "menus.h"
#include "emulator.h" #include "emulator.h"
#include "cargador.h" #include "cargador.h"
@ -62,33 +62,46 @@ static const char *main_menu_messages[] = {
/*05*/ "Wiimote configuration", /*05*/ "Wiimote configuration",
/*06*/ "^|Wiimote1|Wiimote2", /*06*/ "^|Wiimote1|Wiimote2",
/*07*/ "Emulation settings", /*07*/ "Emulation settings",
/*08*/ "Confs files", /*08*/ "Screen settings",
/*09*/ "Microdrive", /*09*/ "Confs files",
/*10*/ "Tools", /*10*/ "Microdrive",
/*11*/ "Reset", /*11*/ "Tools",
/*12*/ "Help", /*12*/ "Reset",
/*13*/ "Quit", /*13*/ "Help",
/*14*/ "Quit",
NULL NULL
}; };
static const char *emulation_messages[] = { static const char *emulation_messages[] = {
/*00*/ "Emulated machine", /*00*/ "Emulated machine",
/*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp", /*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp|NTSC",
/*02*/ "Volume", /*02*/ "Volume",
/*03*/ "^|0|1|2|3|4|5|6|7|max", /*03*/ "^|0|1|2|3|4|5|6|7|max",
/*04*/ "Tap fast speed", /*04*/ "Frame rate",
/*05*/ "^|on|off", /*05*/ "^|100%|50%|33%|25%|20%",
/*06*/ "Turbo mode", /*06*/ "Tap fast speed",
/*07*/ "^|off|speed|ultraspeed", /*07*/ "^|on|off",
/*08*/ "Double scan", /*08*/ "Turbo mode",
/*09*/ "^|on|off", /*09*/ "^|off|speed|ultraspeed",
/*10*/ "TV mode", /*10*/ "Precision",
/*11*/ "^|Color|B&W", /*11*/ "^|on|off",
/*12*/ "AY-3-8912 Emulation", /*12*/ "AY-3-8912 Emulation",
/*13*/ "^|on|off", /*13*/ "^|on|off",
NULL NULL
}; };
static const char *screen_messages[] = {
/*00*/ "Double scan",
/*01*/ "^|on|off",
/*02*/ " ",
/*03*/ "TV mode",
/*04*/ "^|Color|B&W",
/*05*/ " ",
/*06*/ "Resolution",
/*07*/ "^|640X480|320X240",
NULL
};
static const char *input_messages[] = { static const char *input_messages[] = {
/*00*/ "Joystick type", /*00*/ "Joystick type",
/*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2", /*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2",
@ -264,7 +277,7 @@ static void delete_tape()
if ((ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")| if ((ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
ext_matches(filename, ".TZX")) ext_matches(filename, ".TZX"))
&& (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))) unlink(filename); && (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO))) unlink(filename);
free((void *)filename); free((void *)filename);
} }
@ -323,7 +336,9 @@ static void manage_tape(int which)
static unsigned int get_machine_model(void) static unsigned int get_machine_model(void)
{ {
return ordenador.mode128k + (ordenador.issue==3); if (ordenador.videosystem == 0)
return (ordenador.mode128k + (ordenador.issue==3));
else return (6);
} }
static void set_machine_model(int which) static void set_machine_model(int which)
@ -334,34 +349,45 @@ static void set_machine_model(int which)
ordenador.issue=2; ordenador.issue=2;
ordenador.mode128k=0; ordenador.mode128k=0;
ordenador.ay_emul=0; ordenador.ay_emul=0;
ordenador.videosystem =0;
break; break;
case 1: //48k issue3 case 1: //48k issue3
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=0; ordenador.mode128k=0;
ordenador.ay_emul=0; ordenador.ay_emul=0;
ordenador.videosystem =0;
break; break;
case 2: //128k case 2: //128k
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=1; ordenador.mode128k=1;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem =0;
break; break;
case 3: //Amstrad +2 case 3: //Amstrad +2
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=2; ordenador.mode128k=2;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem =0;
break; break;
case 4: //Amstrad +2A/+3 case 4: //Amstrad +2A/+3
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=3; ordenador.mode128k=3;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.mdr_active=0; ordenador.mdr_active=0;
ordenador.videosystem =0;
break; break;
case 5: //128K Spanish case 5: //128K Spanish
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=4; ordenador.mode128k=4;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem =0;
break;
case 6: //48k ntsc
ordenador.issue=3;
ordenador.mode128k=0;
ordenador.ay_emul=0;
ordenador.videosystem =1;
break; break;
} }
} }
@ -369,20 +395,21 @@ static void emulation_settings(void)
{ {
unsigned int submenus[7],submenus_old[7]; unsigned int submenus[7],submenus_old[7];
int opt, i; int opt, i;
unsigned char old_mode; unsigned char old_mode, old_videosystem;
memset(submenus, 0, sizeof(submenus)); memset(submenus, 0, sizeof(submenus));
submenus[0] = get_machine_model(); submenus[0] = get_machine_model();
submenus[1] = ordenador.volume/2; submenus[1] = ordenador.volume/2;
submenus[2] = !ordenador.tape_fast_load; submenus[2] = jump_frames;
submenus[3] = ordenador.turbo; submenus[3] = !ordenador.tape_fast_load;
submenus[4] = !ordenador.dblscan; submenus[4] = ordenador.turbo;
submenus[5] = ordenador.bw; submenus[5] = !ordenador.precision;
submenus[6] = !ordenador.ay_emul; submenus[6] = !ordenador.ay_emul;
for (i=0; i<7; i++) submenus_old[i] = submenus[i]; for (i=0; i<7; i++) submenus_old[i] = submenus[i];
old_mode=ordenador.mode128k; old_mode=ordenador.mode128k;
old_videosystem = ordenador.videosystem;
opt = menu_select_title("Emulation settings menu", opt = menu_select_title("Emulation settings menu",
emulation_messages, submenus); emulation_messages, submenus);
@ -390,36 +417,72 @@ static void emulation_settings(void)
return; return;
set_machine_model(submenus[0]); set_machine_model(submenus[0]);
if (old_mode!=ordenador.mode128k) ResetComputer(); else if ((old_mode!=ordenador.mode128k)||(old_videosystem!=ordenador.videosystem)) ResetComputer(); else
ordenador.ay_emul = !submenus[6]; ordenador.ay_emul = !submenus[6];
ordenador.volume = submenus[1]*2; //I should use set_volume() ? ordenador.volume = submenus[1]*2; //I should use set_volume() ?
ordenador.tape_fast_load = !submenus[2]; jump_frames = submenus[2];
ordenador.turbo = submenus[3]; ordenador.tape_fast_load = !submenus[3];
ordenador.turbo = submenus[4];
curr_frames=0; curr_frames=0;
if (submenus[4] != submenus_old[4])
{
switch(ordenador.turbo) switch(ordenador.turbo)
{ {
case 0: //off case 0: //off
ordenador.tst_sample=3500000/ordenador.freq; update_frequency(0); //set machine frequency
jump_frames=0; jump_frames=0;
break; break;
case 1: //speed case 1: //speed
ordenador.tst_sample=12000000/ordenador.freq; //5,0 MHz max emulation speed for wii at full frames update_frequency(10000000);
jump_frames=3; jump_frames=4;
ordenador.precision =0;
break; break;
case 2: //very speed case 2: //ultra speed
ordenador.tst_sample=20000000/ordenador.freq; update_frequency(15000000);
jump_frames=24; jump_frames=24;
ordenador.precision =0;
break; break;
default: default:
break; break;
} }
}
ordenador.dblscan = !submenus[4]; if (ordenador.turbo==0) ordenador.precision = !submenus[5];
ordenador.bw = submenus[5]; }
if (submenus[5]!=submenus_old[5]) computer_set_palete();
static void save_load_general_configurations(int);
static void screen_settings(void)
{
unsigned int submenus[3],submenus_old[3];
int opt, i;
memset(submenus, 0, sizeof(submenus));
submenus[0] = !ordenador.dblscan;
submenus[1] = ordenador.bw;
submenus[2] = ordenador.zaurus_mini?1:0;
for (i=0; i<3; i++) submenus_old[i] = submenus[i];
opt = menu_select_title("Screen settings menu",
screen_messages, submenus);
if (opt < 0)
return;
ordenador.dblscan = !submenus[0];
ordenador.bw = submenus[1];
if (submenus[1]!=submenus_old[1]) computer_set_palete();
if (submenus[2] != submenus_old[2])
{
if (submenus[2]==0) {ordenador.zaurus_mini = 0; ordenador.text_mini=0;}
else {ordenador.zaurus_mini = 3; ordenador.text_mini=1;}
restart_video();
}
} }
static void setup_joystick(int joy, unsigned int sdl_key, int joy_key) static void setup_joystick(int joy, unsigned int sdl_key, int joy_key)
@ -544,7 +607,7 @@ static void delete_mdr()
return; return;
if ((ext_matches(filename, ".mdr")|ext_matches(filename, ".MDR")) if ((ext_matches(filename, ".mdr")|ext_matches(filename, ".MDR"))
&& (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))) unlink(filename); && (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO))) unlink(filename);
free((void *)filename); free((void *)filename);
} }
@ -707,7 +770,7 @@ static void save_scr()
if(fichero!=NULL) if(fichero!=NULL)
{ {
fclose(fichero); fclose(fichero);
if (!msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160, FULL_DISPLAY_Y /2-48)) if (!msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160/RATIO, FULL_DISPLAY_Y /2-48/RATIO))
return; // file already exists return; // file already exists
} }
@ -792,7 +855,7 @@ static void tools()
switch(opt) switch(opt)
{ {
case 0: // Show keyboard case 0: // Show keyboard
show_keyboard_layout(); if (ordenador.zaurus_mini == 0) show_keyboard_layout(); else msgInfo("No picture available in 320X240 resolution",3000,NULL);
break; break;
case 2: // Save SCR case 2: // Save SCR
save_scr(); save_scr();
@ -879,7 +942,7 @@ static void save_load_snapshot(int which)
} }
} }
else // Delete snashot file else // Delete snashot file
if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) unlink(filename); if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) unlink(filename);
} }
free((void*)filename); free((void*)filename);
} break; } break;
@ -892,7 +955,7 @@ static void save_load_snapshot(int which)
msgInfo("Snapshot saved",3000,NULL); msgInfo("Snapshot saved",3000,NULL);
break; break;
case -1: case -1:
if (msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160, FULL_DISPLAY_Y /2-48)) if (msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160/RATIO, FULL_DISPLAY_Y /2-48/RATIO))
{ {
save_z80(db,1); //force overwrite save_z80(db,1); //force overwrite
msgInfo("Snapshot saved",3000,NULL); msgInfo("Snapshot saved",3000,NULL);
@ -935,7 +998,7 @@ static void save_load_game_configurations(int which)
break; break;
} }
else // Delete config file else // Delete config file
if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) unlink(filename); if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) unlink(filename);
} }
free((void*)filename); free((void*)filename);
} break; } break;
@ -965,7 +1028,7 @@ static void save_load_game_configurations(int which)
msgInfo("Game confs saved",3000,NULL); msgInfo("Game confs saved",3000,NULL);
break; break;
case -1: case -1:
if (msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160, FULL_DISPLAY_Y /2-48)) if (msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160/RATIO, FULL_DISPLAY_Y /2-48/RATIO))
{ {
save_config_game(&ordenador,db,1); //force overwrite save_config_game(&ordenador,db,1); //force overwrite
msgInfo("Game confs saved",3000,NULL); msgInfo("Game confs saved",3000,NULL);
@ -1018,7 +1081,7 @@ static void save_load_general_configurations(int which)
break; break;
} }
else // Delete config file else // Delete config file
if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) unlink(config_path); if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) unlink(config_path);
} break; } break;
case 1: // Save configuration file case 1: // Save configuration file
@ -1102,15 +1165,18 @@ void main_menu()
emulation_settings(); emulation_settings();
break; break;
case 8: case 8:
manage_configurations(); screen_settings();
break; break;
case 9: case 9:
microdrive(); manage_configurations();
break; break;
case 10: case 10:
tools(); microdrive();
break; break;
case 11: case 11:
tools();
break;
case 12:
ResetComputer (); ResetComputer ();
ordenador.pause = 1; ordenador.pause = 1;
if (ordenador.tap_file != NULL) { if (ordenador.tap_file != NULL) {
@ -1118,17 +1184,17 @@ void main_menu()
rewind_tape (ordenador.tap_file,1); rewind_tape (ordenador.tap_file,1);
} }
break; break;
case 12: case 13:
help(); help();
break; break;
case 13: case 14:
if (msgYesNo("Are you sure to quit?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) if (msgYesNo("Are you sure to quit?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO))
{salir = 0;} {salir = 0;}
break; break;
default: default:
break; break;
} }
} while (opt == 5 || opt == 7 || opt == 9 || opt == 12); } while (opt == 5 || opt == 7 || opt == 10 || opt == 13);
clean_screen(); clean_screen();

View File

@ -72,7 +72,7 @@ static SDL_Surface *real_screen;
#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' ) #define IS_MARKER(p_msg) ( (p_msg)[0] == '@' )
static int is_inited = 0; static int is_inited = 0;
static TTF_Font *menu_font16, *menu_font20; static TTF_Font *menu_font16, *menu_font20, *menu_font8, *menu_font10;
#if defined(GEKKO) #if defined(GEKKO)
#define FONT_PATH "/fbzx-wii/fbzx/FreeMono.ttf" #define FONT_PATH "/fbzx-wii/fbzx/FreeMono.ttf"
#else #else
@ -89,21 +89,21 @@ int msgInfo(char *text, int duration, SDL_Rect *irc)
SDL_Rect rc; SDL_Rect rc;
SDL_Rect brc; SDL_Rect brc;
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12; X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12/RATIO;
Y = (FULL_DISPLAY_Y /2) - 24; Y = (FULL_DISPLAY_Y /2) - 24/RATIO;
brc.x = FULL_DISPLAY_X/2-2*12; brc.x = FULL_DISPLAY_X/2-2*12/RATIO;
brc.y=Y+42; brc.y=Y+42/RATIO;
brc.w=48; brc.w=48/RATIO;
brc.h=20; brc.h=20/RATIO;
rc.x = X; rc.x = X;
rc.y=Y; rc.y=Y;
rc.w=12*(len + 2); rc.w=12*(len + 2)/RATIO;
rc.h=duration > 0 ? 48 : 80; rc.h=duration > 0 ? 48/RATIO : 80/RATIO;
src.x=rc.x+4; src.x=rc.x+4/RATIO;
src.y=rc.y+4; src.y=rc.y+4/RATIO;
src.w=rc.w; src.w=rc.w;
src.h=rc.h; src.h=rc.h;
@ -117,7 +117,7 @@ int msgInfo(char *text, int duration, SDL_Rect *irc)
} }
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0));
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128));
menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20); menu_print_font(real_screen, 255,255,255, X+12/RATIO, Y+12/RATIO, text,20);
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
if (duration > 0) if (duration > 0)
@ -125,7 +125,7 @@ int msgInfo(char *text, int duration, SDL_Rect *irc)
else if (duration < 0) else if (duration < 0)
{ {
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00));
menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-12, Y+42, "OK",20); menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-12/RATIO, Y+42/RATIO, "OK",20);
SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h); SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h);
while (!(KEY_SELECT & menu_wait_key_press())) {} while (!(KEY_SELECT & menu_wait_key_press())) {}
@ -151,22 +151,22 @@ int msgYesNo(char *text, int default_opt, int x, int y)
uint32_t key; uint32_t key;
if (x < 0) if (x < 0)
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12; X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12/RATIO;
else else
X = x; X = x;
if (y < 0) if (y < 0)
Y = (FULL_DISPLAY_Y /2) - 48; Y = (FULL_DISPLAY_Y /2) - 48/RATIO;
else else
Y = y; Y = y;
rc.x=X; rc.x=X;
rc.y=Y; rc.y=Y;
rc.w=12*(len + 2); rc.w=12*(len + 2)/RATIO;
rc.h=80; rc.h=80/RATIO;
src.x=rc.x+4; src.x=rc.x+4/RATIO;
src.y=rc.y+4; src.y=rc.y+4/RATIO;
src.w=rc.w; src.w=rc.w;
src.h=rc.h; src.h=rc.h;
@ -174,27 +174,27 @@ int msgYesNo(char *text, int default_opt, int x, int y)
{ {
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0));
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128));
menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20); menu_print_font(real_screen, 255,255,255, X+12/RATIO, Y+12/RATIO, text,20);
if (default_opt) if (default_opt)
{ {
brc.x=rc.x + rc.w/2-5*12; brc.x=rc.x + rc.w/2-5*12/RATIO;
brc.y=rc.y+42; brc.y=rc.y+42/RATIO;
brc.w=12*3; brc.w=12*3/RATIO;
brc.h=20; brc.h=20/RATIO;
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00));
} }
else else
{ {
brc.x=rc.x + rc.w/2+5*12-2*12-6; brc.x=rc.x + rc.w/2+5*12/RATIO-2*12/RATIO-6/RATIO;
brc.y=rc.y+42; brc.y=rc.y+42/RATIO;
brc.w=12*3; brc.w=12*3/RATIO;
brc.h=20; brc.h=20/RATIO;
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00)); SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00));
} }
menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12, Y+42, "YES",20); menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO, Y+42/RATIO, "YES",20);
menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12+8*12, Y+42, "NO",20); menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO+8*12/RATIO, Y+42/RATIO, "NO",20);
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
@ -364,8 +364,17 @@ void menu_print_font(SDL_Surface *screen, int r, int g, int b,
buf[i] = ' '; buf[i] = ' ';
} }
if (FULL_DISPLAY_X == 640)
{
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font16, buf, color); if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font16, buf, color);
else font_surf = TTF_RenderUTF8_Blended(menu_font20, buf, color); else font_surf = TTF_RenderUTF8_Blended(menu_font20, buf, color);
}
else
{
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font8, buf, color);
else font_surf = TTF_RenderUTF8_Blended(menu_font10, buf, color);
}
if (!font_surf) if (!font_surf)
{ {
fprintf(stderr, "%s\n", TTF_GetError()); fprintf(stderr, "%s\n", TTF_GetError());
@ -843,8 +852,16 @@ int menu_select_sized(const char *title, const char **msgs, int *submenus, int s
menu_t menu; menu_t menu;
int out; int out;
if (FULL_DISPLAY_X == 640)
{
if (font_size == 16) menu_init_internal(&menu, title, menu_font16, msgs, x, y, x2, y2); if (font_size == 16) menu_init_internal(&menu, title, menu_font16, msgs, x, y, x2, y2);
else menu_init_internal(&menu, title, menu_font20, msgs, x, y, x2, y2); else menu_init_internal(&menu, title, menu_font20, msgs, x, y, x2, y2);
}
else
{
if (font_size == 16) menu_init_internal(&menu, title, menu_font8, msgs, x, y, x2, y2);
else menu_init_internal(&menu, title, menu_font10, msgs, x, y, x2, y2);
}
if (sel >= 0) if (sel >= 0)
select_one(&menu, sel); select_one(&menu, sel);
@ -860,7 +877,7 @@ int menu_select_title(const char *title, const char **msgs, int *submenus)
{ {
SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0)); SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0));
return menu_select_sized(title, msgs, submenus, 0, return menu_select_sized(title, msgs, submenus, 0,
32, 32, FULL_DISPLAY_X-32, FULL_DISPLAY_Y-32, 32/RATIO, 32/RATIO, FULL_DISPLAY_X-32/RATIO, FULL_DISPLAY_Y-32/RATIO,
NULL, NULL, 20); NULL, NULL, 20);
} }
@ -948,7 +965,7 @@ const char *menu_select_file(const char *dir_path,const char *selected_file, int
if (dir_path == NULL) if (dir_path == NULL)
dir_path = ""; dir_path = "";
return menu_select_file_internal(dir_path, return menu_select_file_internal(dir_path,
0, 32, FULL_DISPLAY_X, FULL_DISPLAY_Y - 32, selected_file, which); 0, 32/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 32/RATIO, selected_file, which);
} }
static TTF_Font *read_font(const char *path, int font_size) static TTF_Font *read_font(const char *path, int font_size)
@ -984,15 +1001,21 @@ static TTF_Font *read_font(const char *path, int font_size)
return out; return out;
} }
void menu_init(SDL_Surface *screen) void font_init()
{ {
TTF_Init(); TTF_Init();
menu_font16 = read_font(FONT_PATH, 16); menu_font16 = read_font(FONT_PATH, 16);
menu_font20 = read_font(FONT_PATH, 20); menu_font20 = read_font(FONT_PATH, 20);
menu_font8 = read_font(FONT_PATH, 8);
menu_font10 = read_font(FONT_PATH, 10);
}
void menu_init(SDL_Surface *screen)
{
real_screen = screen; real_screen = screen;
VirtualKeyboard_init(screen, menu_font16); //prima c'era il font 16 alt if (FULL_DISPLAY_X == 640) VirtualKeyboard_init(screen, menu_font16); //prima c'era il font 16 alt
else VirtualKeyboard_init(screen, menu_font8);
is_inited = 1; is_inited = 1;
} }

View File

@ -38,8 +38,10 @@
#define KEY_PAGEDOWN 64 #define KEY_PAGEDOWN 64
#define KEY_PAGEUP 128 #define KEY_PAGEUP 128
#define KEY_HELP 256 #define KEY_HELP 256
#define FULL_DISPLAY_X 640
#define FULL_DISPLAY_Y 480 int FULL_DISPLAY_X; //640
int FULL_DISPLAY_Y; //480
int RATIO;
void menu_print_font(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg, int font_size); void menu_print_font(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg, int font_size);
@ -58,6 +60,8 @@ extern int msgInfo(char *text, int duration, SDL_Rect *rc);
extern int msgYesNo(char *text, int def,int x, int y); extern int msgYesNo(char *text, int def,int x, int y);
void font_init();
void menu_init(SDL_Surface *screen); void menu_init(SDL_Surface *screen);
int menu_is_inited(void); int menu_is_inited(void);

View File

@ -232,18 +232,21 @@ void settings_menu() {
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=1; ordenador.mode128k=1;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem=0;
ResetComputer(); ResetComputer();
break; break;
case SDLK_4: case SDLK_4:
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=2; ordenador.mode128k=2;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem=0;
ResetComputer(); ResetComputer();
break; break;
case SDLK_5: case SDLK_5:
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=3; ordenador.mode128k=3;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem=0;
ordenador.mdr_active=0; ordenador.mdr_active=0;
ResetComputer(); ResetComputer();
break; break;
@ -251,6 +254,7 @@ void settings_menu() {
ordenador.issue=3; ordenador.issue=3;
ordenador.mode128k=4; ordenador.mode128k=4;
ordenador.ay_emul=1; ordenador.ay_emul=1;
ordenador.videosystem=0;
ResetComputer(); ResetComputer();
break; break;
case SDLK_7: case SDLK_7:
@ -284,13 +288,13 @@ void settings_menu() {
case SDLK_t: case SDLK_t:
curr_frames=0; curr_frames=0;
if(ordenador.turbo){ if(ordenador.turbo){
ordenador.tst_sample=3500000/ordenador.freq; update_frequency(0); //set machine frequency
ordenador.turbo = 0; ordenador.turbo = 0;
jump_frames=0; jump_frames=0;
} else { } else {
ordenador.tst_sample=12000000/ordenador.freq; //5,0 MHz max emulation speed for wii at full frames update_frequency(10000000); //5,0 MHz max emulation speed for wii at full frames
ordenador.turbo = 1; ordenador.turbo = 1;
jump_frames=3; jump_frames=4;
} }
break; break;
} }
@ -1988,3 +1992,27 @@ void print_files(struct fichero *filelist,int from,int mark) {
pos+=16; pos+=16;
} }
} }
void update_frequency (int freq)
{
if (freq == 0)
switch (ordenador.mode128k) {
case 0: // 48K
if (ordenador.videosystem==0) ordenador.cpufreq = 3500000;
else ordenador.cpufreq = 3527500;
break;
case 3: // +2A/+3
case 1: // 128K
case 2: // +2
case 4: // spanish 128K
ordenador.cpufreq = 3546900;
break;
default:
ordenador.cpufreq = 3500000;
break;
}
else ordenador.cpufreq = freq;
ordenador.tst_sample=ordenador.cpufreq/ordenador.freq;
}

View File

@ -52,3 +52,4 @@ void do_poke();
int ask_value(int *final_value,int y_coord,int max_value); int ask_value(int *final_value,int y_coord,int max_value);
void tools_menu(); void tools_menu();
int launch_menu(unsigned int key_pressed); int launch_menu(unsigned int key_pressed);
void update_frequency (int freq);

View File

@ -743,7 +743,7 @@ void fastload_block (FILE * fichero) {
salir = 2; salir = 2;
if (!salir) { if (!salir) {
retval=fread (value, 1, 1, fichero); // read byte retval=fread (value, 1, 1, fichero); // read byte
Z80free_Wr (procesador.Rm.wr.IX, (byte) value[0]); // store the byte Z80free_Wr_fake (procesador.Rm.wr.IX, (byte) value[0]); // store the byte
procesador.Rm.wr.IX++; procesador.Rm.wr.IX++;
procesador.Rm.wr.DE--; procesador.Rm.wr.DE--;
longitud--; longitud--;

View File

@ -93,10 +93,10 @@ int Z80free_ustep(Z80FREE *processor) {
Z80free_doPush(processor,processor->PC); Z80free_doPush(processor,processor->PC);
if (processor->IM!=2) { // we will forget IM0 mode for now; maybe in the future... if (processor->IM!=2) { // we will forget IM0 mode for now; maybe in the future...
processor->PC=0x0038; processor->PC=0x0038;
return (13); return (13); //IM1
} else { } else {
processor->PC=Z80free_read16(((((word)processor->I)<<8)&0xFF00) | ((word)processor->empty_bus)); processor->PC=Z80free_read16(((((word)processor->I)<<8)&0xFF00) | ((word)processor->empty_bus));
return (19); return (19); //IM2
} }
} }
} }
@ -105,7 +105,7 @@ int Z80free_ustep(Z80FREE *processor) {
if (processor->IFF1>1) // set the right status for interrupts if (processor->IFF1>1) // set the right status for interrupts
processor->IFF1--; processor->IFF1--;
opcode=Z80free_Rd(processor->PC); opcode=Z80free_Rd_fetch(processor->PC);
processor->PC++; processor->PC++;
switch(processor->Status) { switch(processor->Status) {
case Z80INT: case Z80INT:
@ -145,7 +145,7 @@ int Z80free_ustep(Z80FREE *processor) {
} }
processor->Status=Z80XX; processor->Status=Z80XX;
if (opcode==0xCB) { if (opcode==0xCB) {
d1=Z80free_Rd(processor->PC++); d1=Z80free_Rd_fetch(processor->PC++);
retval+=Z80free_codesDDCB(processor,d1); retval+=Z80free_codesDDCB(processor,d1);
} else { } else {
retval+=Z80free_codesDD(processor,opcode); retval+=Z80free_codesDD(processor,opcode);
@ -163,7 +163,7 @@ int Z80free_ustep(Z80FREE *processor) {
} }
processor->Status=Z80XX; processor->Status=Z80XX;
if (opcode==0xCB) { if (opcode==0xCB) {
d1=Z80free_Rd(processor->PC++); d1=Z80free_Rd_fetch(processor->PC++);
retval+=Z80free_codesFDCB(processor,d1); retval+=Z80free_codesFDCB(processor,d1);
} else { } else {
retval+=Z80free_codesFD(processor,opcode); retval+=Z80free_codesFD(processor,opcode);

View File

@ -139,9 +139,12 @@ int Z80free_ustep(Z80FREE *);
void Z80free_INT(Z80FREE *,byte); void Z80free_INT(Z80FREE *,byte);
byte Z80free_Rd (register word Addr); byte Z80free_Rd (register word Addr);
byte Z80free_Rd_fetch (register word Addr);
void Z80free_Wr (register word Addr, register byte Value); void Z80free_Wr (register word Addr, register byte Value);
void Z80free_Wr_fake (register word Addr, register byte Value);
byte Z80free_In (register word Port); byte Z80free_In (register word Port);
void Z80free_Out (register word Port, register byte Value); void Z80free_Out (register word Port, register byte Value);
void Z80free_Out_fake (register word Port, register byte Value);
/* Opcode functions */ /* Opcode functions */

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(processor->PC++); opcode=Z80free_Rd_fetch(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(processor->PC++); opcode=Z80free_Rd_fetch(processor->PC++);
switch(opcode) { switch(opcode) {
case 0: // LD_RLC B,(IY+d) case 0: // LD_RLC B,(IY+d)