mirror of
https://github.com/Oibaf66/fbzx-wii.git
synced 2024-11-24 09:09:20 +01:00
added 64k NTSC, precision emulation, 320X240 resolution, frame rate setting, screen menu
This commit is contained in:
parent
52fa3dabd5
commit
539e3e81a8
@ -67,8 +67,8 @@ void draw()
|
||||
int y,x;
|
||||
int screen_w = VirtualKeyboard.screen->w;
|
||||
int screen_h = VirtualKeyboard.screen->h;
|
||||
int key_w = 54;
|
||||
int key_h = 36;
|
||||
int key_w = 54/RATIO;
|
||||
int key_h = 36/RATIO;
|
||||
int border_x = (screen_w - (key_w * KEY_COLS)) / 2;
|
||||
int border_y = (screen_h - (key_h * KEY_ROWS)) / 2;
|
||||
SDL_Rect bg_rect = {border_x, border_y,
|
||||
@ -170,7 +170,7 @@ struct virtkey *get_key_internal()
|
||||
struct virtkey* get_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 + 8 ].is_done = 0; //Sym Shift
|
||||
|
1357
src/cargador.c
1357
src/cargador.c
File diff suppressed because it is too large
Load Diff
680
src/computer.c
680
src/computer.c
@ -33,6 +33,7 @@
|
||||
#include "microdrive.h"
|
||||
#include "Virtualkeyboard.h"
|
||||
#include "gui_sdl.h"
|
||||
#include "menu_sdl.h"
|
||||
#if defined(GEKKO)
|
||||
# include <ogc/system.h>
|
||||
# include <wiiuse/wpad.h>
|
||||
@ -47,6 +48,7 @@ extern FILE *fdebug;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns the bus value when reading a port without a periferial */
|
||||
|
||||
inline byte bus_empty () {
|
||||
@ -60,13 +62,19 @@ inline byte bus_empty () {
|
||||
/* calls all the routines that emulates the computer, runing them for 'tstados'
|
||||
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;
|
||||
} else
|
||||
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_sound (tstados);
|
||||
tape_read (ordenador.tap_file, tstados);
|
||||
@ -87,10 +95,12 @@ void computer_init () {
|
||||
ordenador.port254 = 0;
|
||||
ordenador.issue = 3;
|
||||
ordenador.mode128k = 0;
|
||||
ordenador.videosystem = 0; //PAL
|
||||
ordenador.joystick[0] = 1; //Kemposton
|
||||
ordenador.joystick[1] = 0; // Cursor
|
||||
ordenador.rumble[0] = 0;
|
||||
ordenador.rumble[1] = 0;
|
||||
ordenador.precision = 0;
|
||||
|
||||
ordenador.tape_readed = 0;
|
||||
ordenador.pause = 1; // tape stop
|
||||
@ -124,6 +134,10 @@ void computer_init () {
|
||||
ordenador.vol_c = 0;
|
||||
ordenador.tst_ay = 0;
|
||||
ordenador.tst_ay2 = 0;
|
||||
ordenador.wr = 0;
|
||||
ordenador.r_fetch = 0;
|
||||
ordenador.io = 0;
|
||||
ordenador.contention = 0;
|
||||
|
||||
ordenador.ayval_a = 0;
|
||||
ordenador.ayval_b = 0;
|
||||
@ -144,6 +158,8 @@ void computer_init () {
|
||||
strcpy (ordenador.SmbShare, "Share");
|
||||
strcpy (ordenador.SmbIp, "192.168.0.1");
|
||||
ordenador.autoconf=0;
|
||||
|
||||
ordenador.cpufreq = 3500000; // values for 48K mode
|
||||
}
|
||||
|
||||
void computer_set_palete() {
|
||||
@ -360,6 +376,7 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.screen = pantalla;
|
||||
|
||||
ordenador.border = 0;
|
||||
ordenador.border_p = 0;
|
||||
ordenador.currline = 0;
|
||||
ordenador.currpix = 0;
|
||||
ordenador.flash = 0;
|
||||
@ -372,8 +389,6 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.init_line = 0;
|
||||
ordenador.next_line = 640;
|
||||
ordenador.next_scanline = 640;
|
||||
ordenador.first_line = 40;
|
||||
ordenador.last_line = 280;
|
||||
ordenador.first_pixel = 16;
|
||||
ordenador.last_pixel = 336;
|
||||
ordenador.next_pixel = 1;
|
||||
@ -383,8 +398,6 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.init_line = 65;
|
||||
ordenador.next_line = 160;
|
||||
ordenador.next_scanline = 160;
|
||||
ordenador.first_line = 40;
|
||||
ordenador.last_line = 280;
|
||||
ordenador.first_pixel = 0;
|
||||
ordenador.last_pixel = 351;
|
||||
ordenador.next_pixel = 1;
|
||||
@ -394,8 +407,6 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.init_line = 479;
|
||||
ordenador.next_line = -(307202);
|
||||
ordenador.next_scanline = -1;
|
||||
ordenador.first_line = 40;
|
||||
ordenador.last_line = 280;
|
||||
ordenador.first_pixel = 16;
|
||||
ordenador.last_pixel = 336;
|
||||
ordenador.next_pixel = 480;
|
||||
@ -405,8 +416,6 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.init_line = 0;
|
||||
ordenador.next_line = 0;
|
||||
ordenador.next_scanline = 0;
|
||||
ordenador.first_line = 40;
|
||||
ordenador.last_line = 280;
|
||||
ordenador.first_pixel = 0;
|
||||
ordenador.last_pixel = 319;
|
||||
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.interr = 0;
|
||||
|
||||
ordenador.readkeyboard = 0;
|
||||
|
||||
ordenador.p_translt = ordenador.translate;
|
||||
ordenador.p_translt2 = ordenador.translate2;
|
||||
|
||||
ordenador.contador_flash = 0;
|
||||
ordenador.readed = 0;
|
||||
|
||||
ordenador.contended_zone=0;
|
||||
//ordenador.contended_zone=0;
|
||||
ordenador.cicles_counter=0;
|
||||
|
||||
ordenador.tstados_counter_sound = 0;
|
||||
@ -439,8 +449,6 @@ void register_screen (SDL_Surface * pantalla) {
|
||||
ordenador.num_buff = 0; // first buffer
|
||||
ordenador.sound_cuantity = 0;
|
||||
ordenador.sound_current_value = 0;
|
||||
ordenador.pixancho = 447;
|
||||
ordenador.pixalto = 311; // values for 48K mode
|
||||
}
|
||||
|
||||
void set_memory_pointers () {
|
||||
@ -514,38 +522,48 @@ void set_memory_pointers () {
|
||||
/* Paints the spectrum screen during the TSTADOS tstates that the Z80 used
|
||||
to execute last instruction */
|
||||
|
||||
|
||||
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.cicles_counter += tstados;
|
||||
|
||||
if (curr_frames<jump_frames) { //Jump the frame drawing
|
||||
if (ordenador.tstados_counter>=69888) {
|
||||
ordenador.tstados_counter-=69888;
|
||||
if (ordenador.tstados_counter>=ordenador.tstatodos_frame) {
|
||||
ordenador.tstados_counter-=ordenador.tstatodos_frame;
|
||||
ordenador.interr = 1;
|
||||
if ((ordenador.turbo == 0) || (curr_frames%7 == 0)) ordenador.readkeyboard = 1;
|
||||
curr_frames++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fflash = 0; // flash flag
|
||||
|
||||
while (ordenador.tstados_counter > 3) {
|
||||
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
|
||||
|
||||
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)) {
|
||||
|
||||
// is border
|
||||
|
||||
ordenador.contended_zone=0; // no contention here
|
||||
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 {
|
||||
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;
|
||||
@ -553,11 +571,10 @@ inline void show_screen (int tstados) {
|
||||
} else {
|
||||
|
||||
// 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
|
||||
ordenador.bus_value = temporal;
|
||||
|
||||
ink = temporal & 0x07; // ink colour
|
||||
paper = (temporal >> 3) & 0x07; // paper colour
|
||||
if (ordenador.ulaplus) {
|
||||
@ -575,18 +592,23 @@ inline void show_screen (int tstados) {
|
||||
// Snow Effect
|
||||
|
||||
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
|
||||
} 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_translt2++;
|
||||
|
||||
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
|
||||
paint_pixels (temporal, ink, paper);
|
||||
paint_pixels (temporal3, ink, paper, 8);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Update pixel position
|
||||
ordenador.currpix += 8;
|
||||
if (ordenador.currpix > ordenador.pixancho) {
|
||||
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;
|
||||
if (ordenador.osd_time) {
|
||||
ordenador.osd_time--;
|
||||
@ -626,6 +650,7 @@ inline void show_screen (int tstados) {
|
||||
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;
|
||||
@ -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 */
|
||||
|
||||
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 unsigned char mask;
|
||||
|
||||
if ((ordenador.currpix < 16) || (ordenador.currpix >= 336)
|
||||
|| (ordenador.currline < 40) || (ordenador.currline >= 280))
|
||||
return;
|
||||
|
||||
mask = 0x80;
|
||||
for (bucle = 0; bucle < 8; bucle++) {
|
||||
|
||||
if (ordenador.pixels_octect==0 ||bit == 8) mask = 0x80;
|
||||
|
||||
for (bucle = 0; bucle < bit; bucle++) {
|
||||
valor = (octet & mask) ? (int) ink : (int) paper;
|
||||
p=(colors+valor);
|
||||
|
||||
@ -1132,17 +1372,45 @@ void ResetComputer () {
|
||||
|
||||
ordenador.updown=0;
|
||||
ordenador.leftright=0;
|
||||
|
||||
ordenador.wr=0;
|
||||
ordenador.r_fetch = 0;
|
||||
ordenador.io = 0;
|
||||
ordenador.contention = 0;
|
||||
|
||||
ordenador.ulaplus=0;
|
||||
|
||||
ordenador.mport1 = 0;
|
||||
ordenador.mport2 = 0;
|
||||
ordenador.video_offset = 0; // video in page 9 (page 5 in 128K)
|
||||
switch (ordenador.mode128k) {
|
||||
switch (ordenador.mode128k) {
|
||||
case 0: // 48K
|
||||
ordenador.pixancho = 447;
|
||||
ordenador.start_screen=41;
|
||||
if (ordenador.videosystem==0)
|
||||
{
|
||||
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.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)
|
||||
@ -1151,13 +1419,22 @@ void ResetComputer () {
|
||||
break;
|
||||
|
||||
case 3: // +2A/+3
|
||||
Z80free_Out (0x1FFD, 0);
|
||||
Z80free_Out_fake (0x1FFD, 0);
|
||||
case 1: // 128K
|
||||
case 2: // +2
|
||||
case 4: // spanish 128K
|
||||
Z80free_Out (0x7FFD, 0);
|
||||
Z80free_Out_fake (0x7FFD, 0);
|
||||
ordenador.pixancho = 455;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1167,36 +1444,75 @@ void ResetComputer () {
|
||||
// check if there's contention and waits the right number of tstates
|
||||
|
||||
void do_contention() {
|
||||
|
||||
if (!ordenador.contended_zone)
|
||||
return;
|
||||
|
||||
if (ordenador.cicles_counter<14335) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ccicles=(ordenador.cicles_counter-14335)%8;
|
||||
|
||||
if (ccicles>5) {
|
||||
return;
|
||||
}
|
||||
static int ccicles;
|
||||
|
||||
if ((ordenador.currline < ordenador.upper_border_line ) || (ordenador.currline >= ordenador.lower_border_line)
|
||||
|| (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) {
|
||||
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:
|
||||
// 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;
|
||||
break;
|
||||
|
||||
@ -1210,8 +1526,7 @@ void Z80free_Wr (register word Addr, register byte Value) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
byte Z80free_Rd (register word Addr) {
|
||||
byte Z80free_Rd_fetch (register word Addr) {
|
||||
|
||||
if((ordenador.mdr_active)&&(ordenador.mdr_paged)&&(Addr<8192)) // Interface I
|
||||
return((byte)ordenador.shadowrom[Addr]);
|
||||
@ -1223,21 +1538,77 @@ byte Z80free_Rd (register word Addr) {
|
||||
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) {
|
||||
|
||||
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)));
|
||||
break;
|
||||
|
||||
@ -1275,22 +1646,47 @@ void set_palete_entry(unsigned char entry, byte Value) {
|
||||
|
||||
void Z80free_Out (register word Port, register byte Value) {
|
||||
|
||||
// Microdrive access
|
||||
|
||||
register word maskport;
|
||||
|
||||
if (((Port&0x0001)==0)||((Port>=0x4000)&&(Port<0x8000))) {
|
||||
do_contention();
|
||||
//It should out after 3 states
|
||||
|
||||
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
|
||||
if (Port == 0xBF3B) {
|
||||
do_contention();
|
||||
ordenador.ulaplus_reg = Value;
|
||||
return;
|
||||
}
|
||||
if (Port == 0xFF3B) {
|
||||
do_contention();
|
||||
if (ordenador.ulaplus_reg==0x40) { // mode
|
||||
ordenador.ulaplus=Value&0x01;
|
||||
return;
|
||||
@ -1300,6 +1696,8 @@ void Z80free_Out (register word Port, register byte Value) {
|
||||
set_palete_entry(ordenador.ulaplus_reg,Value);
|
||||
}
|
||||
}
|
||||
|
||||
// Microdrive access
|
||||
|
||||
if(((Port &0x0018)!=0x0018)&&(ordenador.mdr_active))
|
||||
microdrive_out(Port,Value);
|
||||
@ -1321,9 +1719,9 @@ void Z80free_Out (register word Port, register byte Value) {
|
||||
// Memory page (7FFD & 1FFD)
|
||||
|
||||
if (ordenador.mode128k==3) {
|
||||
maskport=0x0FFD;
|
||||
} else {
|
||||
maskport=0x3FFD;
|
||||
} else {
|
||||
maskport=0x7FFD;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if (((Port|maskport) == 0x1FFD) && (0 == (ordenador.mport1 & 0x20))) {
|
||||
if (((Port|0x0FFD) == 0x1FFD) && (0 == (ordenador.mport1 & 0x20))) {
|
||||
ordenador.mport2 = (unsigned char) Value;
|
||||
set_memory_pointers (); // set the pointers
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
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;
|
||||
if (ordenador.ay_latch == 13) //Envelope shape
|
||||
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) {
|
||||
|
||||
static unsigned int temporal_io;
|
||||
byte pines;
|
||||
|
||||
if (((Port&0x0001)==0)||((Port>=0x4000)&&(Port<0x8000))) {
|
||||
do_contention();
|
||||
static byte pines;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
if (Port == 0xFF3B) {
|
||||
do_contention();
|
||||
if (ordenador.ulaplus_reg==0x40) { // mode
|
||||
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]);
|
||||
|
||||
// Microdrive access
|
||||
@ -1424,7 +1892,12 @@ byte Z80free_In (register word Port) {
|
||||
return(microdrive_in(Port));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1475,3 +1948,46 @@ void set_volume (unsigned char volume) {
|
||||
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();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ int countdown;
|
||||
|
||||
struct computer {
|
||||
|
||||
unsigned char precision; //If set 1 emulate with more precision
|
||||
unsigned int temporal_io;
|
||||
|
||||
// screen private global variables
|
||||
@ -52,7 +53,7 @@ struct computer {
|
||||
|
||||
unsigned int *p_translt,*p_translt2;
|
||||
unsigned char *pixel; // current address
|
||||
char border,flash;
|
||||
char border,flash, border_p;
|
||||
int currline,currpix;
|
||||
|
||||
int tstados_counter; // counts tstates leaved to the next call
|
||||
@ -67,8 +68,18 @@ struct computer {
|
||||
int next_pixel; // next pixel
|
||||
int pixancho,pixalto; // maximum pixel value for width and height
|
||||
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 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
|
||||
|
||||
char ulaplus; // 0 = inactive; 1 = active
|
||||
@ -121,13 +132,18 @@ struct computer {
|
||||
signed char ay_envel_value;
|
||||
unsigned char ay_envel_way;
|
||||
unsigned char sound_current_value;
|
||||
unsigned int wr;
|
||||
unsigned int r_fetch;
|
||||
unsigned int io;
|
||||
unsigned int contention;
|
||||
|
||||
// bus global variables
|
||||
|
||||
unsigned char bus_counter;
|
||||
unsigned char bus_value;
|
||||
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 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 shadowrom[8192]; // space for Interface I's ROMs
|
||||
unsigned char interr;
|
||||
unsigned char readkeyboard;
|
||||
unsigned char mustlock;
|
||||
unsigned char other_ret; // 0=no change; 1=memory returns RET (201)
|
||||
|
||||
@ -219,11 +236,13 @@ struct computer {
|
||||
void computer_init();
|
||||
void register_screen(SDL_Surface *);
|
||||
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();
|
||||
void fill_audio(void *udata,Uint8 *,int);
|
||||
void set_volume(unsigned char);
|
||||
inline void play_sound(unsigned int);
|
||||
inline void emulate_screen(int);
|
||||
inline void emulate(int);
|
||||
void ResetComputer();
|
||||
inline byte bus_empty();
|
||||
@ -232,5 +251,6 @@ inline void play_ay();
|
||||
inline void paint_one_pixel(unsigned char *colour,unsigned char *address);
|
||||
void computer_set_palete();
|
||||
void set_palete_entry(unsigned char entry, byte Value);
|
||||
void restart_video();
|
||||
|
||||
#endif
|
||||
|
2416
src/emulator.c
2416
src/emulator.c
File diff suppressed because it is too large
Load Diff
105
src/emulator.h
105
src/emulator.h
@ -1,51 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Fabio Olimpieri
|
||||
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "z80free/Z80free.h"
|
||||
#include "computer.h"
|
||||
|
||||
#ifndef emulator_h
|
||||
#define emulator_h
|
||||
|
||||
#define NUM_SNDBUF 2
|
||||
|
||||
extern char debug_var;
|
||||
|
||||
extern SDL_Surface *screen;
|
||||
extern Z80FREE procesador;
|
||||
extern struct computer ordenador;
|
||||
extern unsigned char *sound[NUM_SNDBUF];
|
||||
extern char path_snaps[2049];
|
||||
extern char path_taps[2049];
|
||||
extern char path_mdrs[2049];
|
||||
extern char path_scr[2049];
|
||||
extern char path_confs[2049];
|
||||
extern unsigned int colors[80];
|
||||
extern unsigned int jump_frames,curr_frames;
|
||||
|
||||
void SDL_Fullscreen_Switch(void);
|
||||
void load_rom(char);
|
||||
void load_main_game(char *nombre);
|
||||
int load_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);
|
||||
FILE *myfopen(char *filename,char *mode);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2012 Fabio Olimpieri
|
||||
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "z80free/Z80free.h"
|
||||
#include "computer.h"
|
||||
|
||||
#ifndef emulator_h
|
||||
#define emulator_h
|
||||
|
||||
#define NUM_SNDBUF 2
|
||||
|
||||
extern char debug_var;
|
||||
|
||||
extern SDL_Surface *screen;
|
||||
extern Z80FREE procesador;
|
||||
extern struct computer ordenador;
|
||||
extern unsigned char *sound[NUM_SNDBUF];
|
||||
extern char path_snaps[2049];
|
||||
extern char path_taps[2049];
|
||||
extern char path_mdrs[2049];
|
||||
extern char path_scr[2049];
|
||||
extern char path_confs[2049];
|
||||
extern unsigned int colors[80];
|
||||
extern unsigned int jump_frames,curr_frames;
|
||||
|
||||
void SDL_Fullscreen_Switch(void);
|
||||
void load_rom(char);
|
||||
void load_main_game(char *nombre);
|
||||
int load_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);
|
||||
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
|
||||
|
2336
src/gui_sdl.c
2336
src/gui_sdl.c
File diff suppressed because it is too large
Load Diff
2027
src/menu_sdl.c
2027
src/menu_sdl.c
File diff suppressed because it is too large
Load Diff
140
src/menu_sdl.h
140
src/menu_sdl.h
@ -1,68 +1,72 @@
|
||||
/*********************************************************************
|
||||
* Copyright (C) 2012, Fabio Olimpieri
|
||||
* Copyright (C) 2009, Simon Kagstrom
|
||||
*
|
||||
* Filename: menu_sdl.h
|
||||
*
|
||||
* Description: Code for menus (originally for Mophun)
|
||||
*
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
#ifndef __MENU_H__
|
||||
#define __MENU_H__
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_ttf.h>
|
||||
|
||||
#define KEY_UP 1
|
||||
#define KEY_DOWN 2
|
||||
#define KEY_LEFT 4
|
||||
#define KEY_RIGHT 8
|
||||
#define KEY_SELECT 16
|
||||
#define KEY_ESCAPE 32
|
||||
#define KEY_PAGEDOWN 64
|
||||
#define KEY_PAGEUP 128
|
||||
#define KEY_HELP 256
|
||||
#define FULL_DISPLAY_X 640
|
||||
#define FULL_DISPLAY_Y 480
|
||||
|
||||
|
||||
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);
|
||||
const char *menu_select_file(const char *dir_path,const char *selected_file, int which);
|
||||
const char *menu_select_file_start(const char *dir_path, const char **d64_name);
|
||||
|
||||
uint32_t menu_wait_key_press(void);
|
||||
|
||||
extern void msgKill(SDL_Rect *rc);
|
||||
extern int msgInfo(char *text, int duration, SDL_Rect *rc);
|
||||
|
||||
extern int msgYesNo(char *text, int def,int x, int y);
|
||||
|
||||
void menu_init(SDL_Surface *screen);
|
||||
|
||||
int menu_is_inited(void);
|
||||
|
||||
int ext_matches(const char *name, const char *ext);
|
||||
|
||||
|
||||
#endif /* !__MENU_H__ */
|
||||
/*********************************************************************
|
||||
* Copyright (C) 2012, Fabio Olimpieri
|
||||
* Copyright (C) 2009, Simon Kagstrom
|
||||
*
|
||||
* Filename: menu_sdl.h
|
||||
*
|
||||
* Description: Code for menus (originally for Mophun)
|
||||
*
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
#ifndef __MENU_H__
|
||||
#define __MENU_H__
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_ttf.h>
|
||||
|
||||
#define KEY_UP 1
|
||||
#define KEY_DOWN 2
|
||||
#define KEY_LEFT 4
|
||||
#define KEY_RIGHT 8
|
||||
#define KEY_SELECT 16
|
||||
#define KEY_ESCAPE 32
|
||||
#define KEY_PAGEDOWN 64
|
||||
#define KEY_PAGEUP 128
|
||||
#define KEY_HELP 256
|
||||
|
||||
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);
|
||||
|
||||
|
||||
/* 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);
|
||||
const char *menu_select_file(const char *dir_path,const char *selected_file, int which);
|
||||
const char *menu_select_file_start(const char *dir_path, const char **d64_name);
|
||||
|
||||
uint32_t menu_wait_key_press(void);
|
||||
|
||||
extern void msgKill(SDL_Rect *rc);
|
||||
extern int msgInfo(char *text, int duration, SDL_Rect *rc);
|
||||
|
||||
extern int msgYesNo(char *text, int def,int x, int y);
|
||||
|
||||
void font_init();
|
||||
|
||||
void menu_init(SDL_Surface *screen);
|
||||
|
||||
int menu_is_inited(void);
|
||||
|
||||
int ext_matches(const char *name, const char *ext);
|
||||
|
||||
|
||||
#endif /* !__MENU_H__ */
|
||||
|
4008
src/menus.c
4008
src/menus.c
File diff suppressed because it is too large
Load Diff
109
src/menus.h
109
src/menus.h
@ -1,54 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Fabio Olimpieri
|
||||
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
struct fichero {
|
||||
char nombre[256]; // filename (for files and directories)
|
||||
char nombrepath[2049]; // filename with path
|
||||
int tipo; // file type (0=file, 1=directory, 2=parent directory)
|
||||
struct fichero *next;
|
||||
};
|
||||
|
||||
enum LOAD_FILE_TYPES {FILETYPE_Z80, FILETYPE_TAP_TZX, FILETYPE_MDR, FILETYPE_SCR};
|
||||
|
||||
void clean_screen();
|
||||
void help_menu();
|
||||
void load_z80file();
|
||||
char *select_file(char *,enum LOAD_FILE_TYPES);
|
||||
struct fichero *read_directory(char *,enum LOAD_FILE_TYPES);
|
||||
unsigned int wait_key();
|
||||
void print_files(struct fichero *,int,int);
|
||||
void delete_filelist(struct fichero *);
|
||||
void select_tapfile();
|
||||
void save_z80file();
|
||||
void settings_menu();
|
||||
void snapshots_menu();
|
||||
void taps_menu();
|
||||
void create_tapfile();
|
||||
void select_mdrfile();
|
||||
void create_mdrfile();
|
||||
void microdrive_menu();
|
||||
void keyboard_menu();
|
||||
void load_scrfile();
|
||||
int ask_filename(char *nombre,int y_coord,char *extension, char *path, char *name);
|
||||
void create_scrfile();
|
||||
void do_poke();
|
||||
int ask_value(int *final_value,int y_coord,int max_value);
|
||||
void tools_menu();
|
||||
int launch_menu(unsigned int key_pressed);
|
||||
/*
|
||||
* Copyright (C) 2012 Fabio Olimpieri
|
||||
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of FBZX Wii
|
||||
*
|
||||
* FBZX Wii is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FBZX Wii is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
struct fichero {
|
||||
char nombre[256]; // filename (for files and directories)
|
||||
char nombrepath[2049]; // filename with path
|
||||
int tipo; // file type (0=file, 1=directory, 2=parent directory)
|
||||
struct fichero *next;
|
||||
};
|
||||
|
||||
enum LOAD_FILE_TYPES {FILETYPE_Z80, FILETYPE_TAP_TZX, FILETYPE_MDR, FILETYPE_SCR};
|
||||
|
||||
void clean_screen();
|
||||
void help_menu();
|
||||
void load_z80file();
|
||||
char *select_file(char *,enum LOAD_FILE_TYPES);
|
||||
struct fichero *read_directory(char *,enum LOAD_FILE_TYPES);
|
||||
unsigned int wait_key();
|
||||
void print_files(struct fichero *,int,int);
|
||||
void delete_filelist(struct fichero *);
|
||||
void select_tapfile();
|
||||
void save_z80file();
|
||||
void settings_menu();
|
||||
void snapshots_menu();
|
||||
void taps_menu();
|
||||
void create_tapfile();
|
||||
void select_mdrfile();
|
||||
void create_mdrfile();
|
||||
void microdrive_menu();
|
||||
void keyboard_menu();
|
||||
void load_scrfile();
|
||||
int ask_filename(char *nombre,int y_coord,char *extension, char *path, char *name);
|
||||
void create_scrfile();
|
||||
void do_poke();
|
||||
int ask_value(int *final_value,int y_coord,int max_value);
|
||||
void tools_menu();
|
||||
int launch_menu(unsigned int key_pressed);
|
||||
void update_frequency (int freq);
|
||||
|
1544
src/tape.c
1544
src/tape.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,156 +1,159 @@
|
||||
/*
|
||||
* Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of Z80Free, with some bits extracted
|
||||
* and fixed from libZ80 (from Gabriel Gambetta)
|
||||
*
|
||||
* Z80Free is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Z80Free is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef Z80FREE_H
|
||||
#define Z80FREE_H
|
||||
|
||||
#ifdef GEKKO
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#ifndef Z80_H
|
||||
typedef unsigned short int word;
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
#define F_S 0x80
|
||||
#define F_Z 0x40
|
||||
#define F_5 0x20
|
||||
#define F_H 0x10
|
||||
#define F_3 0x08
|
||||
#define F_PV 0x04
|
||||
#define F_N 0x02
|
||||
#define F_C 0x01
|
||||
|
||||
//enum Z80free_prefix {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD};
|
||||
|
||||
|
||||
typedef union {
|
||||
/** Word registers. */
|
||||
struct
|
||||
{
|
||||
word AF, BC, DE, HL, IX, IY, SP;
|
||||
} wr;
|
||||
|
||||
/** Byte registers. SP can be accessed partially to simplify the load/save code. */
|
||||
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
struct
|
||||
{
|
||||
byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S;
|
||||
} br;
|
||||
#else
|
||||
|
||||
struct
|
||||
{
|
||||
byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P;
|
||||
} br;
|
||||
|
||||
#endif
|
||||
|
||||
} Z80FRegs;
|
||||
|
||||
/** A Z80 execution context. */
|
||||
typedef struct
|
||||
{
|
||||
Z80FRegs Ra; /* Alternate register set (R) */
|
||||
Z80FRegs Rm; /* Main register set (R) */
|
||||
word PC; /* Program counter */
|
||||
byte R; /* Refresh */
|
||||
byte R2; /* Upper bit for Refresh */
|
||||
byte I;
|
||||
byte IFF1; /* Interrupt Flipflop 1. If it's 2, decrement it and don't allow INT */
|
||||
byte IFF2; /* Interrupt Flipflop 2 */
|
||||
byte IM; /* Interrupt mode */
|
||||
byte HALT; /* HALT status */
|
||||
byte INT_P; /* INT pending */
|
||||
byte NMI_P; /* NMI pending */
|
||||
byte empty_bus; /* value for empty bus when procesing a maskable int */
|
||||
word IAddr; /* address with offset for IX+d and IY+d */
|
||||
byte IAddr_done; /* if 1, IAddr contains a valid data */
|
||||
enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status;
|
||||
} Z80FREE;
|
||||
|
||||
/* internal Z80 methods */
|
||||
|
||||
void Z80free_setFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_resFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_valFlag(Z80FREE *processor, byte flag, int val);
|
||||
int Z80free_getFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_adjustFlags (Z80FREE *processor, byte val);
|
||||
void Z80free_adjustFlagSZP (Z80FREE *processor, byte val);
|
||||
void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH);
|
||||
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);
|
||||
void Z80free_doAND (Z80FREE *processor, byte value);
|
||||
void Z80free_doOR (Z80FREE *processor, byte value);
|
||||
void Z80free_doXOR (Z80FREE *processor, byte value);
|
||||
void Z80free_doBIT (Z80FREE *processor, int b, byte val);
|
||||
byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val);
|
||||
byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec);
|
||||
word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec);
|
||||
byte Z80free_doRLC (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_doRR (Z80FREE *processor, int adjFlags, byte val);
|
||||
byte Z80free_doSL (Z80FREE *processor, int isArith, byte val);
|
||||
byte Z80free_doSR (Z80FREE *processor, int isArith, byte val);
|
||||
void Z80free_doPush (Z80FREE *processor, word val);
|
||||
word Z80free_doPop (Z80FREE *processor);
|
||||
void Z80free_doDAA (Z80FREE *processor);
|
||||
byte Z80free_readR(Z80FREE *processor);
|
||||
void Z80free_setR(Z80FREE *processor,byte value);
|
||||
byte Z80free_readI(Z80FREE *processor);
|
||||
void Z80free_doRRD(Z80FREE *processor);
|
||||
void Z80free_doRLD(Z80FREE *processor);
|
||||
|
||||
void Z80free_jump_relative(Z80FREE *processor,byte relvar);
|
||||
word Z80free_addr_relative(Z80FREE *processor,word address);
|
||||
word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1);
|
||||
byte Z80free_read_param_8(Z80FREE *z80);
|
||||
word Z80free_read_param_16(Z80FREE *z80);
|
||||
word Z80free_read16 (register word addr);
|
||||
void Z80free_write16 (register word addr,register word val);
|
||||
|
||||
/* external Z80 methods */
|
||||
|
||||
void Z80free_reset(Z80FREE *);
|
||||
int Z80free_step(Z80FREE *);
|
||||
int Z80free_ustep(Z80FREE *);
|
||||
void Z80free_INT(Z80FREE *,byte);
|
||||
|
||||
byte Z80free_Rd (register word Addr);
|
||||
void Z80free_Wr (register word Addr, register byte Value);
|
||||
byte Z80free_In (register word Port);
|
||||
void Z80free_Out (register word Port, register byte Value);
|
||||
|
||||
/* Opcode functions */
|
||||
|
||||
int Z80free_codes (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesCB (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesDD (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesED (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesFD (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesDDCB (Z80FREE *processor,byte d1);
|
||||
int Z80free_codesFDCB (Z80FREE *processor,byte d1);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||
* This file is part of Z80Free, with some bits extracted
|
||||
* and fixed from libZ80 (from Gabriel Gambetta)
|
||||
*
|
||||
* Z80Free is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Z80Free is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef Z80FREE_H
|
||||
#define Z80FREE_H
|
||||
|
||||
#ifdef GEKKO
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#ifndef Z80_H
|
||||
typedef unsigned short int word;
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
#define F_S 0x80
|
||||
#define F_Z 0x40
|
||||
#define F_5 0x20
|
||||
#define F_H 0x10
|
||||
#define F_3 0x08
|
||||
#define F_PV 0x04
|
||||
#define F_N 0x02
|
||||
#define F_C 0x01
|
||||
|
||||
//enum Z80free_prefix {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD};
|
||||
|
||||
|
||||
typedef union {
|
||||
/** Word registers. */
|
||||
struct
|
||||
{
|
||||
word AF, BC, DE, HL, IX, IY, SP;
|
||||
} wr;
|
||||
|
||||
/** Byte registers. SP can be accessed partially to simplify the load/save code. */
|
||||
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
struct
|
||||
{
|
||||
byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S;
|
||||
} br;
|
||||
#else
|
||||
|
||||
struct
|
||||
{
|
||||
byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P;
|
||||
} br;
|
||||
|
||||
#endif
|
||||
|
||||
} Z80FRegs;
|
||||
|
||||
/** A Z80 execution context. */
|
||||
typedef struct
|
||||
{
|
||||
Z80FRegs Ra; /* Alternate register set (R) */
|
||||
Z80FRegs Rm; /* Main register set (R) */
|
||||
word PC; /* Program counter */
|
||||
byte R; /* Refresh */
|
||||
byte R2; /* Upper bit for Refresh */
|
||||
byte I;
|
||||
byte IFF1; /* Interrupt Flipflop 1. If it's 2, decrement it and don't allow INT */
|
||||
byte IFF2; /* Interrupt Flipflop 2 */
|
||||
byte IM; /* Interrupt mode */
|
||||
byte HALT; /* HALT status */
|
||||
byte INT_P; /* INT pending */
|
||||
byte NMI_P; /* NMI pending */
|
||||
byte empty_bus; /* value for empty bus when procesing a maskable int */
|
||||
word IAddr; /* address with offset for IX+d and IY+d */
|
||||
byte IAddr_done; /* if 1, IAddr contains a valid data */
|
||||
enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status;
|
||||
} Z80FREE;
|
||||
|
||||
/* internal Z80 methods */
|
||||
|
||||
void Z80free_setFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_resFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_valFlag(Z80FREE *processor, byte flag, int val);
|
||||
int Z80free_getFlag(Z80FREE *processor, byte flag);
|
||||
void Z80free_adjustFlags (Z80FREE *processor, byte val);
|
||||
void Z80free_adjustFlagSZP (Z80FREE *processor, byte val);
|
||||
void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH);
|
||||
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);
|
||||
void Z80free_doAND (Z80FREE *processor, byte value);
|
||||
void Z80free_doOR (Z80FREE *processor, byte value);
|
||||
void Z80free_doXOR (Z80FREE *processor, byte value);
|
||||
void Z80free_doBIT (Z80FREE *processor, int b, byte val);
|
||||
byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val);
|
||||
byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec);
|
||||
word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec);
|
||||
byte Z80free_doRLC (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_doRR (Z80FREE *processor, int adjFlags, byte val);
|
||||
byte Z80free_doSL (Z80FREE *processor, int isArith, byte val);
|
||||
byte Z80free_doSR (Z80FREE *processor, int isArith, byte val);
|
||||
void Z80free_doPush (Z80FREE *processor, word val);
|
||||
word Z80free_doPop (Z80FREE *processor);
|
||||
void Z80free_doDAA (Z80FREE *processor);
|
||||
byte Z80free_readR(Z80FREE *processor);
|
||||
void Z80free_setR(Z80FREE *processor,byte value);
|
||||
byte Z80free_readI(Z80FREE *processor);
|
||||
void Z80free_doRRD(Z80FREE *processor);
|
||||
void Z80free_doRLD(Z80FREE *processor);
|
||||
|
||||
void Z80free_jump_relative(Z80FREE *processor,byte relvar);
|
||||
word Z80free_addr_relative(Z80FREE *processor,word address);
|
||||
word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1);
|
||||
byte Z80free_read_param_8(Z80FREE *z80);
|
||||
word Z80free_read_param_16(Z80FREE *z80);
|
||||
word Z80free_read16 (register word addr);
|
||||
void Z80free_write16 (register word addr,register word val);
|
||||
|
||||
/* external Z80 methods */
|
||||
|
||||
void Z80free_reset(Z80FREE *);
|
||||
int Z80free_step(Z80FREE *);
|
||||
int Z80free_ustep(Z80FREE *);
|
||||
void Z80free_INT(Z80FREE *,byte);
|
||||
|
||||
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_fake (register word Addr, register byte Value);
|
||||
byte Z80free_In (register word Port);
|
||||
void Z80free_Out (register word Port, register byte Value);
|
||||
void Z80free_Out_fake (register word Port, register byte Value);
|
||||
|
||||
/* Opcode functions */
|
||||
|
||||
int Z80free_codes (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesCB (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesDD (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesED (Z80FREE *processor,byte opcode);
|
||||
int Z80free_codesFD (Z80FREE *processor,byte opcode);
|
||||
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
Loading…
Reference in New Issue
Block a user