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

File diff suppressed because it is too large Load Diff

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,14 +433,15 @@ 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;
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;
@ -553,11 +571,10 @@ inline void show_screen (int tstados) {
} else { } else {
// 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; for (bucle = 0; bucle < bit; bucle++) {
mask = 0x80;
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);
@ -1132,17 +1372,45 @@ 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;
ordenador.mport2 = 0; ordenador.mport2 = 0;
ordenador.video_offset = 0; // video in page 9 (page 5 in 128K) ordenador.video_offset = 0; // video in page 9 (page 5 in 128K)
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;
} }
@ -1167,36 +1444,75 @@ void ResetComputer () {
// check if there's contention and waits the right number of tstates // check if there's contention and waits the right number of tstates
void do_contention() { void do_contention() {
if (!ordenador.contended_zone)
return;
if (ordenador.cicles_counter<14335) {
return;
}
int ccicles=(ordenador.cicles_counter-14335)%8; static int ccicles;
if (ccicles>5) { 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);
}
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: 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.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(); 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:
// only writes in the first 16K if we are in +3 mode and bit0 of mport2 is 1
if ((ordenador.mode128k == 3) && (1 == (ordenador.mport2 & 0x01)))
*(ordenador.block0 + Addr) = (unsigned char) Value;
break;
case 0x4000:
*(ordenador.block1 + Addr) = (unsigned char) Value; *(ordenador.block1 + Addr) = (unsigned char) Value;
break; break;
@ -1210,8 +1526,7 @@ void Z80free_Wr (register word Addr, register byte Value) {
} }
} }
byte Z80free_Rd_fetch (register word Addr) {
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]);
@ -1223,21 +1538,77 @@ byte Z80free_Rd (register word Addr) {
break; break;
default: default:
ordenador.r_fetch+=4;
switch (Addr & 0xC000) { switch (Addr & 0xC000) {
case 0x0000: case 0x0000:
if (ordenador.precision) emulate_screen (4);
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 (4);
return ((byte) (*(ordenador.block1 + Addr))); return ((byte) (*(ordenador.block1 + Addr)));
break; break;
case 0x8000: case 0x8000:
if (ordenador.precision) emulate_screen (4);
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 (4);
}
return ((byte) (*(ordenador.block3 + Addr)));
break;
default:
printf ("Memory error\n");
exit (1);
return 0;
}
break;
}
}
byte Z80free_Rd (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.wr+=3;
switch (Addr & 0xC000) {
case 0x0000:
if (ordenador.precision) emulate_screen (3);
return ((byte) (*(ordenador.block0 + Addr)));
break;
case 0x4000:
do_contention();
if (ordenador.precision) emulate_screen (3);
return ((byte) (*(ordenador.block1 + Addr)));
break;
case 0x8000:
if (ordenador.precision) emulate_screen (3);
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 (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;
@ -1300,6 +1696,8 @@ void Z80free_Out (register word Port, register byte Value) {
set_palete_entry(ordenador.ulaplus_reg,Value); set_palete_entry(ordenador.ulaplus_reg,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
@ -1424,7 +1892,12 @@ byte Z80free_In (register word Port) {
return(microdrive_in(Port)); return(microdrive_in(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

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,54 @@
/* /*
* Copyright (C) 2012 Fabio Olimpieri * Copyright (C) 2012 Fabio Olimpieri
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas) * Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
* This file is part of FBZX Wii * This file is part of FBZX Wii
* *
* FBZX Wii is free software; you can redistribute it and/or modify * FBZX Wii is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* FBZX Wii is distributed in the hope that it will be useful, * FBZX Wii is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "z80free/Z80free.h" #include "z80free/Z80free.h"
#include "computer.h" #include "computer.h"
#ifndef emulator_h #ifndef emulator_h
#define emulator_h #define emulator_h
#define NUM_SNDBUF 2 #define NUM_SNDBUF 2
extern char debug_var; extern char debug_var;
extern SDL_Surface *screen; extern SDL_Surface *screen;
extern Z80FREE procesador; extern Z80FREE procesador;
extern struct computer ordenador; extern struct computer ordenador;
extern unsigned char *sound[NUM_SNDBUF]; extern unsigned char *sound[NUM_SNDBUF];
extern char path_snaps[2049]; extern char path_snaps[2049];
extern char path_taps[2049]; extern char path_taps[2049];
extern char path_mdrs[2049]; extern char path_mdrs[2049];
extern char path_scr[2049]; extern char path_scr[2049];
extern char path_confs[2049]; extern char path_confs[2049];
extern unsigned int colors[80]; extern unsigned int colors[80];
extern unsigned int jump_frames,curr_frames; extern unsigned int jump_frames,curr_frames;
void SDL_Fullscreen_Switch(void); void SDL_Fullscreen_Switch(void);
void load_rom(char); void load_rom(char);
void load_main_game(char *nombre); void load_main_game(char *nombre);
int load_config(struct computer *object, char *filename); 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();
#endif void init_sound();
void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hwsurface);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +1,72 @@
/********************************************************************* /*********************************************************************
* Copyright (C) 2012, Fabio Olimpieri * Copyright (C) 2012, Fabio Olimpieri
* Copyright (C) 2009, Simon Kagstrom * Copyright (C) 2009, Simon Kagstrom
* *
* Filename: menu_sdl.h * Filename: menu_sdl.h
* *
* Description: Code for menus (originally for Mophun) * Description: Code for menus (originally for Mophun)
* *
* This file is part of FBZX Wii * This file is part of FBZX Wii
* *
* FBZX Wii is free software; you can redistribute it and/or modify * FBZX Wii is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* FBZX Wii is distributed in the hope that it will be useful, * FBZX Wii is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
********************************************************************/ ********************************************************************/
#ifndef __MENU_H__ #ifndef __MENU_H__
#define __MENU_H__ #define __MENU_H__
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <SDL/SDL_ttf.h> #include <SDL/SDL_ttf.h>
#define KEY_UP 1 #define KEY_UP 1
#define KEY_DOWN 2 #define KEY_DOWN 2
#define KEY_LEFT 4 #define KEY_LEFT 4
#define KEY_RIGHT 8 #define KEY_RIGHT 8
#define KEY_SELECT 16 #define KEY_SELECT 16
#define KEY_ESCAPE 32 #define KEY_ESCAPE 32
#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);
/* Various option selects */
int menu_select_title(const char *title, const char **pp_msgs, int *p_submenus);
int menu_select(const char **pp_msgs, int *p_submenus); /* Various option selects */
const char *menu_select_file(const char *dir_path,const char *selected_file, int which); int menu_select_title(const char *title, const char **pp_msgs, int *p_submenus);
const char *menu_select_file_start(const char *dir_path, const char **d64_name); int menu_select(const char **pp_msgs, int *p_submenus);
const char *menu_select_file(const char *dir_path,const char *selected_file, int which);
uint32_t menu_wait_key_press(void); const char *menu_select_file_start(const char *dir_path, const char **d64_name);
extern void msgKill(SDL_Rect *rc); uint32_t menu_wait_key_press(void);
extern int msgInfo(char *text, int duration, SDL_Rect *rc);
extern void msgKill(SDL_Rect *rc);
extern int msgYesNo(char *text, int def,int x, int y); extern int msgInfo(char *text, int duration, SDL_Rect *rc);
void menu_init(SDL_Surface *screen); extern int msgYesNo(char *text, int def,int x, int y);
int menu_is_inited(void); void font_init();
int ext_matches(const char *name, const char *ext); void menu_init(SDL_Surface *screen);
int menu_is_inited(void);
#endif /* !__MENU_H__ */
int ext_matches(const char *name, const char *ext);
#endif /* !__MENU_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,55 @@
/* /*
* Copyright (C) 2012 Fabio Olimpieri * Copyright (C) 2012 Fabio Olimpieri
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas) * Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
* This file is part of FBZX Wii * This file is part of FBZX Wii
* *
* FBZX Wii is free software; you can redistribute it and/or modify * FBZX Wii is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* FBZX Wii is distributed in the hope that it will be useful, * FBZX Wii is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
struct fichero { struct fichero {
char nombre[256]; // filename (for files and directories) char nombre[256]; // filename (for files and directories)
char nombrepath[2049]; // filename with path char nombrepath[2049]; // filename with path
int tipo; // file type (0=file, 1=directory, 2=parent directory) int tipo; // file type (0=file, 1=directory, 2=parent directory)
struct fichero *next; struct fichero *next;
}; };
enum LOAD_FILE_TYPES {FILETYPE_Z80, FILETYPE_TAP_TZX, FILETYPE_MDR, FILETYPE_SCR}; enum LOAD_FILE_TYPES {FILETYPE_Z80, FILETYPE_TAP_TZX, FILETYPE_MDR, FILETYPE_SCR};
void clean_screen(); void clean_screen();
void help_menu(); void help_menu();
void load_z80file(); void load_z80file();
char *select_file(char *,enum LOAD_FILE_TYPES); char *select_file(char *,enum LOAD_FILE_TYPES);
struct fichero *read_directory(char *,enum LOAD_FILE_TYPES); struct fichero *read_directory(char *,enum LOAD_FILE_TYPES);
unsigned int wait_key(); unsigned int wait_key();
void print_files(struct fichero *,int,int); void print_files(struct fichero *,int,int);
void delete_filelist(struct fichero *); void delete_filelist(struct fichero *);
void select_tapfile(); void select_tapfile();
void save_z80file(); void save_z80file();
void settings_menu(); void settings_menu();
void snapshots_menu(); void snapshots_menu();
void taps_menu(); void taps_menu();
void create_tapfile(); void create_tapfile();
void select_mdrfile(); void select_mdrfile();
void create_mdrfile(); void create_mdrfile();
void microdrive_menu(); void microdrive_menu();
void keyboard_menu(); void keyboard_menu();
void load_scrfile(); void load_scrfile();
int ask_filename(char *nombre,int y_coord,char *extension, char *path, char *name); int ask_filename(char *nombre,int y_coord,char *extension, char *path, char *name);
void create_scrfile(); void create_scrfile();
void do_poke(); 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);

1544
src/tape.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +1,159 @@
/* /*
* Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas) * Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
* This file is part of Z80Free, with some bits extracted * This file is part of Z80Free, with some bits extracted
* and fixed from libZ80 (from Gabriel Gambetta) * and fixed from libZ80 (from Gabriel Gambetta)
* *
* Z80Free is free software; you can redistribute it and/or modify * Z80Free is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Z80Free is distributed in the hope that it will be useful, * Z80Free is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#ifndef Z80FREE_H #ifndef Z80FREE_H
#define Z80FREE_H #define Z80FREE_H
#ifdef GEKKO #ifdef GEKKO
#include <machine/endian.h> #include <machine/endian.h>
#endif #endif
#ifndef Z80_H #ifndef Z80_H
typedef unsigned short int word; typedef unsigned short int word;
typedef unsigned char byte; typedef unsigned char byte;
#endif #endif
#define F_S 0x80 #define F_S 0x80
#define F_Z 0x40 #define F_Z 0x40
#define F_5 0x20 #define F_5 0x20
#define F_H 0x10 #define F_H 0x10
#define F_3 0x08 #define F_3 0x08
#define F_PV 0x04 #define F_PV 0x04
#define F_N 0x02 #define F_N 0x02
#define F_C 0x01 #define F_C 0x01
//enum Z80free_prefix {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD}; //enum Z80free_prefix {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD};
typedef union { typedef union {
/** Word registers. */ /** Word registers. */
struct struct
{ {
word AF, BC, DE, HL, IX, IY, SP; word AF, BC, DE, HL, IX, IY, SP;
} wr; } wr;
/** Byte registers. SP can be accessed partially to simplify the load/save code. */ /** Byte registers. SP can be accessed partially to simplify the load/save code. */
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
struct struct
{ {
byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S; byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S;
} br; } br;
#else #else
struct struct
{ {
byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P; byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P;
} br; } br;
#endif #endif
} Z80FRegs; } Z80FRegs;
/** A Z80 execution context. */ /** A Z80 execution context. */
typedef struct typedef struct
{ {
Z80FRegs Ra; /* Alternate register set (R) */ Z80FRegs Ra; /* Alternate register set (R) */
Z80FRegs Rm; /* Main register set (R) */ Z80FRegs Rm; /* Main register set (R) */
word PC; /* Program counter */ word PC; /* Program counter */
byte R; /* Refresh */ byte R; /* Refresh */
byte R2; /* Upper bit for Refresh */ byte R2; /* Upper bit for Refresh */
byte I; byte I;
byte IFF1; /* Interrupt Flipflop 1. If it's 2, decrement it and don't allow INT */ byte IFF1; /* Interrupt Flipflop 1. If it's 2, decrement it and don't allow INT */
byte IFF2; /* Interrupt Flipflop 2 */ byte IFF2; /* Interrupt Flipflop 2 */
byte IM; /* Interrupt mode */ byte IM; /* Interrupt mode */
byte HALT; /* HALT status */ byte HALT; /* HALT status */
byte INT_P; /* INT pending */ byte INT_P; /* INT pending */
byte NMI_P; /* NMI pending */ byte NMI_P; /* NMI pending */
byte empty_bus; /* value for empty bus when procesing a maskable int */ byte empty_bus; /* value for empty bus when procesing a maskable int */
word IAddr; /* address with offset for IX+d and IY+d */ word IAddr; /* address with offset for IX+d and IY+d */
byte IAddr_done; /* if 1, IAddr contains a valid data */ byte IAddr_done; /* if 1, IAddr contains a valid data */
enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status; enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status;
} Z80FREE; } Z80FREE;
/* internal Z80 methods */ /* internal Z80 methods */
void Z80free_setFlag(Z80FREE *processor, byte flag); void Z80free_setFlag(Z80FREE *processor, byte flag);
void Z80free_resFlag(Z80FREE *processor, byte flag); void Z80free_resFlag(Z80FREE *processor, byte flag);
void Z80free_valFlag(Z80FREE *processor, byte flag, int val); void Z80free_valFlag(Z80FREE *processor, byte flag, int val);
int Z80free_getFlag(Z80FREE *processor, byte flag); int Z80free_getFlag(Z80FREE *processor, byte flag);
void Z80free_adjustFlags (Z80FREE *processor, byte val); void Z80free_adjustFlags (Z80FREE *processor, byte val);
void Z80free_adjustFlagSZP (Z80FREE *processor, byte val); void Z80free_adjustFlagSZP (Z80FREE *processor, byte val);
void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH); void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH);
byte Z80free_doArithmetic (Z80FREE *processor, byte value1,byte value2, int withCarry, int isSub); byte Z80free_doArithmetic (Z80FREE *processor, byte value1,byte value2, int withCarry, int isSub);
word Z80free_doArithmetic16 (Z80FREE *processor, word value1,word value2, int withCarry, int isSub); word Z80free_doArithmetic16 (Z80FREE *processor, word value1,word value2, int withCarry, int isSub);
void Z80free_doAND (Z80FREE *processor, byte value); void Z80free_doAND (Z80FREE *processor, byte value);
void Z80free_doOR (Z80FREE *processor, byte value); void Z80free_doOR (Z80FREE *processor, byte value);
void Z80free_doXOR (Z80FREE *processor, byte value); void Z80free_doXOR (Z80FREE *processor, byte value);
void Z80free_doBIT (Z80FREE *processor, int b, byte val); void Z80free_doBIT (Z80FREE *processor, int b, byte val);
byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val); byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val);
byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec); byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec);
word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec); word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec);
byte Z80free_doRLC (Z80FREE *processor, int adjFlags, byte val); byte Z80free_doRLC (Z80FREE *processor, int adjFlags, byte val);
byte Z80free_doRL (Z80FREE *processor, int adjFlags, byte val); byte Z80free_doRL (Z80FREE *processor, int adjFlags, byte val);
byte Z80free_doRRC (Z80FREE *processor, int adjFlags, byte val); byte Z80free_doRRC (Z80FREE *processor, int adjFlags, byte val);
byte Z80free_doRR (Z80FREE *processor, int adjFlags, byte val); byte Z80free_doRR (Z80FREE *processor, int adjFlags, byte val);
byte Z80free_doSL (Z80FREE *processor, int isArith, byte val); byte Z80free_doSL (Z80FREE *processor, int isArith, byte val);
byte Z80free_doSR (Z80FREE *processor, int isArith, byte val); byte Z80free_doSR (Z80FREE *processor, int isArith, byte val);
void Z80free_doPush (Z80FREE *processor, word val); void Z80free_doPush (Z80FREE *processor, word val);
word Z80free_doPop (Z80FREE *processor); word Z80free_doPop (Z80FREE *processor);
void Z80free_doDAA (Z80FREE *processor); void Z80free_doDAA (Z80FREE *processor);
byte Z80free_readR(Z80FREE *processor); byte Z80free_readR(Z80FREE *processor);
void Z80free_setR(Z80FREE *processor,byte value); void Z80free_setR(Z80FREE *processor,byte value);
byte Z80free_readI(Z80FREE *processor); byte Z80free_readI(Z80FREE *processor);
void Z80free_doRRD(Z80FREE *processor); void Z80free_doRRD(Z80FREE *processor);
void Z80free_doRLD(Z80FREE *processor); void Z80free_doRLD(Z80FREE *processor);
void Z80free_jump_relative(Z80FREE *processor,byte relvar); void Z80free_jump_relative(Z80FREE *processor,byte relvar);
word Z80free_addr_relative(Z80FREE *processor,word address); word Z80free_addr_relative(Z80FREE *processor,word address);
word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1); word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1);
byte Z80free_read_param_8(Z80FREE *z80); byte Z80free_read_param_8(Z80FREE *z80);
word Z80free_read_param_16(Z80FREE *z80); word Z80free_read_param_16(Z80FREE *z80);
word Z80free_read16 (register word addr); word Z80free_read16 (register word addr);
void Z80free_write16 (register word addr,register word val); void Z80free_write16 (register word addr,register word val);
/* external Z80 methods */ /* external Z80 methods */
void Z80free_reset(Z80FREE *); 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);
byte Z80free_Rd (register word Addr); byte Z80free_Rd (register word Addr);
void Z80free_Wr (register word Addr, register byte Value); byte Z80free_Rd_fetch (register word Addr);
byte Z80free_In (register word Port); void Z80free_Wr (register word Addr, register byte Value);
void Z80free_Out (register word Port, register byte Value); void Z80free_Wr_fake (register word Addr, register byte Value);
byte Z80free_In (register word Port);
/* Opcode functions */ void Z80free_Out (register word Port, register byte Value);
void Z80free_Out_fake (register word Port, register byte Value);
int Z80free_codes (Z80FREE *processor,byte opcode);
int Z80free_codesCB (Z80FREE *processor,byte opcode); /* Opcode functions */
int Z80free_codesDD (Z80FREE *processor,byte opcode);
int Z80free_codesED (Z80FREE *processor,byte opcode); int Z80free_codes (Z80FREE *processor,byte opcode);
int Z80free_codesFD (Z80FREE *processor,byte opcode); int Z80free_codesCB (Z80FREE *processor,byte opcode);
int Z80free_codesDDCB (Z80FREE *processor,byte d1); int Z80free_codesDD (Z80FREE *processor,byte opcode);
int Z80free_codesFDCB (Z80FREE *processor,byte d1); int Z80free_codesED (Z80FREE *processor,byte opcode);
int Z80free_codesFD (Z80FREE *processor,byte opcode);
#endif int Z80free_codesDDCB (Z80FREE *processor,byte d1);
int Z80free_codesFDCB (Z80FREE *processor,byte d1);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff