mirror of
https://github.com/libretro/PUAE.git
synced 2024-11-24 00:09:54 +00:00
sync 2.2.1
This commit is contained in:
parent
716e8cfae1
commit
332ed3d1fd
14
src/adide.c
14
src/adide.c
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* UAE - The Un*x Amiga Emulator
|
||||
*
|
||||
* ADIDE
|
||||
*
|
||||
* (c) 2009 Toni Wilen
|
||||
*/
|
||||
/*
|
||||
* UAE - The Un*x Amiga Emulator
|
||||
*
|
||||
* ADIDE
|
||||
*
|
||||
* (c) 2009 Toni Wilen
|
||||
*/
|
||||
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
|
46
src/cpummu.c
46
src/cpummu.c
@ -1,27 +1,27 @@
|
||||
/*
|
||||
* cpummu.cpp - MMU emulation
|
||||
*
|
||||
* Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
|
||||
*
|
||||
* Inspired by UAE MMU patch
|
||||
*
|
||||
* This file is part of the ARAnyM project which builds a new and powerful
|
||||
* TOS/FreeMiNT compatible virtual machine running on almost any hardware.
|
||||
*
|
||||
* ARAnyM 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ARAnyM 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 ARAnyM; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
* cpummu.cpp - MMU emulation
|
||||
*
|
||||
* Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
|
||||
*
|
||||
* Inspired by UAE MMU patch
|
||||
*
|
||||
* This file is part of the ARAnyM project which builds a new and powerful
|
||||
* TOS/FreeMiNT compatible virtual machine running on almost any hardware.
|
||||
*
|
||||
* ARAnyM 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ARAnyM 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 ARAnyM; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
#include "sysconfig.h"
|
||||
|
2036
src/debug.c
2036
src/debug.c
File diff suppressed because it is too large
Load Diff
@ -68,6 +68,7 @@
|
||||
//FIXME: ---end
|
||||
|
||||
#define TRACING_ENABLED 0
|
||||
#define TRACE2(x) do { write_log x; } while(0)
|
||||
#if TRACING_ENABLED
|
||||
#define TRACE(x) do { write_log x; } while(0)
|
||||
#define DUMPLOCK(u,x) dumplock(u,x)
|
||||
|
@ -207,11 +207,11 @@ int gui_display(int shortcut){
|
||||
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y,icon_floppy, menu_sel_floppy);
|
||||
blit_image (icon_floppy, iconpos_x, iconpos_y);
|
||||
|
||||
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_preferences, menu_sel_prefs);
|
||||
blit_image (icon_preferences, iconpos_x, iconpos_y);
|
||||
|
||||
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_tweaks, menu_sel_tweaks);
|
||||
blit_image (icon_tweaks, iconpos_x, iconpos_y);
|
||||
@ -219,7 +219,7 @@ int gui_display(int shortcut){
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_keymaps, menu_sel_keymaps);
|
||||
blit_image (icon_keymaps, iconpos_x, iconpos_y);
|
||||
|
||||
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_expansion, menu_sel_expansion);
|
||||
blit_image (icon_expansion, iconpos_x, iconpos_y);
|
||||
@ -237,7 +237,7 @@ int gui_display(int shortcut){
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_run, menu_sel_run);
|
||||
blit_image (icon_run, iconpos_x, iconpos_y);
|
||||
|
||||
|
||||
iconpos_x += iconsizex + bosluk;
|
||||
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_exit, menu_sel_exit);
|
||||
blit_image (icon_exit, iconpos_x, iconpos_y);
|
||||
@ -279,8 +279,8 @@ int gui_display(int shortcut){
|
||||
|
||||
return menu_exitcode;
|
||||
}
|
||||
|
||||
void write_text(int x, int y, char* txt) {
|
||||
|
||||
void write_text (int x, int y, char* txt) {
|
||||
SDL_Surface* pText_Surface = TTF_RenderText_Solid(amiga_font, txt, text_color);
|
||||
|
||||
rect.x = x;
|
||||
@ -291,7 +291,8 @@ void write_text(int x, int y, char* txt) {
|
||||
SDL_BlitSurface (pText_Surface,NULL,tmpSDLScreen,&rect);
|
||||
SDL_FreeSurface(pText_Surface);
|
||||
}
|
||||
void blit_image(SDL_Surface* img, int x, int y) {
|
||||
|
||||
void blit_image (SDL_Surface* img, int x, int y) {
|
||||
SDL_Rect dest;
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
@ -313,28 +314,3 @@ void secilimi (int ix, int iy, int mx, int my, SDL_Surface* img, int hangi) {
|
||||
}
|
||||
}
|
||||
//
|
||||
static void sigchldhandler(int foo) {}
|
||||
int gui_update (void){ return 0; }
|
||||
void gui_fps (int fps, int idle){
|
||||
gui_data.fps = fps;
|
||||
gui_data.idle = idle;
|
||||
}
|
||||
void gui_flicker_led (int led, int unitnum, int status){}
|
||||
void gui_led (int led, int on){}
|
||||
|
||||
void gui_filename (int num, const char *name){}
|
||||
void gui_handle_events (void){}
|
||||
void gui_changesettings (void){}
|
||||
void gui_update_gfx (void){}
|
||||
void gui_lock (void){}
|
||||
void gui_unlock (void){}
|
||||
void gui_message (const char *format,...){
|
||||
char msg[2048];
|
||||
va_list parms;
|
||||
|
||||
va_start (parms,format);
|
||||
vsprintf ( msg, format, parms);
|
||||
va_end (parms);
|
||||
|
||||
write_log (msg);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ extern void memory_map_dump (void);
|
||||
extern void debug_help (void);
|
||||
extern uaecptr dumpmem2 (uaecptr addr, char *out, int osize);
|
||||
extern void update_debug_info (void);
|
||||
extern int instruction_breakpoint (const char **c);
|
||||
extern int instruction_breakpoint (TCHAR **c);
|
||||
extern int debug_bankchange (int);
|
||||
|
||||
#define BREAKPOINT_TOTAL 8
|
||||
|
@ -424,4 +424,5 @@ extern void xfree (const void*);
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define _vsntprintf vsnprintf
|
||||
#endif
|
||||
|
@ -147,6 +147,233 @@ static int bouncy;
|
||||
static signed long bouncy_cycles;
|
||||
#define BOUNCY_CYCLES 30
|
||||
|
||||
#ifdef INPREC
|
||||
int inprec_open (TCHAR *fname, int record)
|
||||
{
|
||||
uae_u32 t = (uae_u32)time(0);
|
||||
int i;
|
||||
|
||||
inprec_close();
|
||||
inprec_zf = zfile_fopen (fname, record > 0 ? "wb" : "rb", ZFD_NORMAL);
|
||||
if (inprec_zf == NULL)
|
||||
return 0;
|
||||
inprec_size = 10000;
|
||||
inprec_div = 1;
|
||||
if (record < 0) {
|
||||
uae_u32 id;
|
||||
zfile_fseek (inprec_zf, 0, SEEK_END);
|
||||
inprec_size = zfile_ftell (inprec_zf);
|
||||
zfile_fseek (inprec_zf, 0, SEEK_SET);
|
||||
inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
|
||||
zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
|
||||
inprec_plastptr = inprec_buffer;
|
||||
id = inprec_pu32();
|
||||
if (id != 'UAE\0') {
|
||||
inprec_close ();
|
||||
return 0;
|
||||
}
|
||||
inprec_pu32();
|
||||
t = inprec_pu32 ();
|
||||
i = inprec_pu32 ();
|
||||
while (i-- > 0)
|
||||
inprec_pu8 ();
|
||||
inprec_p = inprec_plastptr;
|
||||
oldbuttons[0] = oldbuttons[1] = oldbuttons[2] = oldbuttons[3] = 0;
|
||||
oldjoy[0] = oldjoy[1] = 0;
|
||||
if (record < -1)
|
||||
inprec_div = maxvpos;
|
||||
} else if (record > 0) {
|
||||
inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
|
||||
inprec_ru32 ('UAE\0');
|
||||
inprec_ru8 (1);
|
||||
inprec_ru8 (UAEMAJOR);
|
||||
inprec_ru8 (UAEMINOR);
|
||||
inprec_ru8 (UAESUBREV);
|
||||
inprec_ru32 (t);
|
||||
inprec_ru32 (0); // extra header size
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
input_recording = record;
|
||||
srand (t);
|
||||
CIA_inprec_prepare ();
|
||||
write_log ("inprec initialized '%s', mode=%d\n", fname, input_recording);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void inprec_close(void)
|
||||
{
|
||||
if (!inprec_zf)
|
||||
return;
|
||||
if (inprec_buffer && input_recording > 0) {
|
||||
hsync_counter++;
|
||||
inprec_rstart(INPREC_END);
|
||||
inprec_rend();
|
||||
hsync_counter--;
|
||||
zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
|
||||
inprec_p = inprec_buffer;
|
||||
}
|
||||
zfile_fclose (inprec_zf);
|
||||
inprec_zf = NULL;
|
||||
xfree (inprec_buffer);
|
||||
inprec_buffer = NULL;
|
||||
input_recording = 0;
|
||||
write_log ("inprec finished\n");
|
||||
}
|
||||
|
||||
void inprec_ru8(uae_u8 v)
|
||||
{
|
||||
*inprec_p++= v;
|
||||
}
|
||||
void inprec_ru16 (uae_u16 v)
|
||||
{
|
||||
inprec_ru8 ((uae_u8)(v >> 8));
|
||||
inprec_ru8 ((uae_u8)v);
|
||||
}
|
||||
void inprec_ru32 (uae_u32 v)
|
||||
{
|
||||
inprec_ru16 ((uae_u16)(v >> 16));
|
||||
inprec_ru16 ((uae_u16)v);
|
||||
}
|
||||
void inprec_rstr (const TCHAR *src)
|
||||
{
|
||||
char *s = ua (src);
|
||||
while(*s) {
|
||||
inprec_ru8 (*s);
|
||||
s++;
|
||||
}
|
||||
inprec_ru8 (0);
|
||||
xfree (s);
|
||||
}
|
||||
void inprec_rstart (uae_u8 type)
|
||||
{
|
||||
write_log ("INPREC: %08X: %d\n", hsync_counter, type);
|
||||
inprec_ru32 (hsync_counter);
|
||||
inprec_ru8 (0);
|
||||
inprec_plast = inprec_p;
|
||||
inprec_ru8 (0xff);
|
||||
inprec_ru8 (type);
|
||||
}
|
||||
void inprec_rend (void)
|
||||
{
|
||||
*inprec_plast = inprec_p - (inprec_plast + 2);
|
||||
if (inprec_p >= inprec_buffer + inprec_size - 256) {
|
||||
zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
|
||||
inprec_p = inprec_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
int inprec_pstart (uae_u8 type)
|
||||
{
|
||||
uae_u8 *p = inprec_p;
|
||||
uae_u32 hc = hsync_counter;
|
||||
static uae_u8 *lastp;
|
||||
uae_u32 hc_orig, hc2_orig;
|
||||
|
||||
if (savestate_state)
|
||||
return 0;
|
||||
if (p[5 + 1] == INPREC_END) {
|
||||
inprec_close ();
|
||||
return 0;
|
||||
} else if (p[5 + 1] == INPREC_QUIT) {
|
||||
inprec_close ();
|
||||
uae_quit ();
|
||||
return 0;
|
||||
}
|
||||
hc_orig = hc;
|
||||
hc /= inprec_div;
|
||||
hc *= inprec_div;
|
||||
for (;;) {
|
||||
uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
if (p > lastp) {
|
||||
write_log ("INPREC: Next %08x (%08x=%d): %d (%d)\n", hc2, hc, hc2 - hc, p[5 + 1], p[5]);
|
||||
lastp = p;
|
||||
}
|
||||
hc2_orig = hc2;
|
||||
hc2 /= inprec_div;
|
||||
hc2 *= inprec_div;
|
||||
if (hc > hc2) {
|
||||
write_log ("INPREC: %08x > %08x: %d (%d) missed!\n", hc, hc2, p[5 + 1], p[5]);
|
||||
inprec_close ();
|
||||
return 0;
|
||||
}
|
||||
if (hc2 != hc) {
|
||||
lastp = p;
|
||||
break;
|
||||
}
|
||||
if (p[5 + 1] == type) {
|
||||
write_log ("INPREC: %08x: %d (%d) (%+d)\n", hc, type, p[5], hc_orig - hc2_orig);
|
||||
inprec_plast = p;
|
||||
inprec_plastptr = p + 5 + 2;
|
||||
return 1;
|
||||
}
|
||||
p += 5 + 2 + p[5];
|
||||
}
|
||||
inprec_plast = NULL;
|
||||
return 0;
|
||||
}
|
||||
void inprec_pend (void)
|
||||
{
|
||||
uae_u8 *p = inprec_p;
|
||||
uae_u32 hc = hsync_counter;
|
||||
|
||||
if (!inprec_plast)
|
||||
return;
|
||||
inprec_plast[5 + 1] = 0;
|
||||
inprec_plast = NULL;
|
||||
inprec_plastptr = NULL;
|
||||
hc /= inprec_div;
|
||||
hc *= inprec_div;
|
||||
for (;;) {
|
||||
uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
hc2 /= inprec_div;
|
||||
hc2 *= inprec_div;
|
||||
if (hc2 != hc)
|
||||
break;
|
||||
if (p[5 + 1] != 0)
|
||||
return;
|
||||
p += 5 + 2 + p[5];
|
||||
}
|
||||
inprec_p = p;
|
||||
if (p[5 + 1] == INPREC_END)
|
||||
inprec_close ();
|
||||
}
|
||||
|
||||
uae_u8 inprec_pu8 (void)
|
||||
{
|
||||
return *inprec_plastptr++;
|
||||
}
|
||||
uae_u16 inprec_pu16 (void)
|
||||
{
|
||||
uae_u16 v = inprec_pu8 () << 8;
|
||||
v |= inprec_pu8 ();
|
||||
return v;
|
||||
}
|
||||
uae_u32 inprec_pu32 (void)
|
||||
{
|
||||
uae_u32 v = inprec_pu16 () << 16;
|
||||
v |= inprec_pu16 ();
|
||||
return v;
|
||||
}
|
||||
int inprec_pstr (TCHAR *dst)
|
||||
{
|
||||
char tmp[MAX_DPATH];
|
||||
char *s;
|
||||
int len = 0;
|
||||
|
||||
s = tmp;
|
||||
for(;;) {
|
||||
uae_u8 v = inprec_pu8 ();
|
||||
*s++ = v;
|
||||
if (!v)
|
||||
break;
|
||||
len++;
|
||||
}
|
||||
au_copy (dst, MAX_DPATH, tmp);
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int isdevice (const struct uae_input_device *id)
|
||||
{
|
||||
int i, j;
|
||||
@ -1571,7 +1798,35 @@ STATIC_INLINE int adjust (int val)
|
||||
|
||||
int getbuttonstate (int joy, int button)
|
||||
{
|
||||
#ifdef INPREC
|
||||
int v;
|
||||
|
||||
v = (joybutton[joy] & (1 << button)) ? 1 : 0;
|
||||
if (input_recording > 0 && ((joybutton[joy] ^ oldbuttons[joy]) & (1 << button))) {
|
||||
oldbuttons[joy] &= ~(1 << button);
|
||||
if (v)
|
||||
oldbuttons[joy] |= 1 << button;
|
||||
inprec_rstart (INPREC_JOYBUTTON);
|
||||
inprec_ru8 (joy);
|
||||
inprec_ru8 (button);
|
||||
inprec_ru8 (v);
|
||||
inprec_rend ();
|
||||
} else if (input_recording < 0) {
|
||||
while(inprec_pstart (INPREC_JOYBUTTON)) {
|
||||
uae_u8 j = inprec_pu8 ();
|
||||
uae_u8 but = inprec_pu8 ();
|
||||
uae_u8 vv = inprec_pu8 ();
|
||||
inprec_pend ();
|
||||
oldbuttons[j] &= ~(1 << but);
|
||||
if (vv)
|
||||
oldbuttons[j] |= 1 << but;
|
||||
}
|
||||
v = (oldbuttons[joy] & (1 << button)) ? 1 : 0;
|
||||
}
|
||||
return v;
|
||||
#else
|
||||
return (joybutton[joy] & (1 << button)) ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int getvelocity (int num, int subnum, int pct)
|
||||
@ -1731,6 +1986,21 @@ int getjoystate (int joy)
|
||||
#ifdef DONGLE_DEBUG
|
||||
if (notinrom ())
|
||||
write_log ("JOY%dDAT %04X %s\n", joy, v, debuginfo (0));
|
||||
#endif
|
||||
#ifdef INPREC
|
||||
if (input_recording > 0 && oldjoy[joy] != v) {
|
||||
oldjoy[joy] = v;
|
||||
inprec_rstart (INPREC_JOYPORT);
|
||||
inprec_ru16 (v);
|
||||
inprec_rend ();
|
||||
} else if (input_recording < 0) {
|
||||
v = oldjoy[joy];
|
||||
if (inprec_pstart (INPREC_JOYPORT)) {
|
||||
v = inprec_pu16 ();
|
||||
inprec_pend ();
|
||||
}
|
||||
oldjoy[joy] = v;
|
||||
}
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ extern struct flag_struct regflags;
|
||||
* with a setto %AL instr and the other flags copied to AH with an
|
||||
* lahf instr).
|
||||
*
|
||||
* The 68k CZNV flags are thus assinged in cznv as:
|
||||
* The 68k CZNV flags are thus assigned in cznv as:
|
||||
*
|
||||
* <--AL--> <--AH-->
|
||||
* 76543210 FEDCBA98 --------- ---------
|
||||
|
@ -56,31 +56,32 @@ extern struct flag_struct regflags;
|
||||
#define FLAGVAL_V (1 << FLAGBIT_V)
|
||||
#define FLAGVAL_X (1 << FLAGBIT_X)
|
||||
|
||||
#define SET_ZFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_Z) | ((y) << FLAGBIT_Z))
|
||||
#define SET_CFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_C) | ((y) << FLAGBIT_C))
|
||||
#define SET_VFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_V) | ((y) << FLAGBIT_V))
|
||||
#define SET_NFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_N) | ((y) << FLAGBIT_N))
|
||||
#define SET_XFLG(flags, y) ((flags)->x = ((y) << FLAGBIT_X))
|
||||
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z))
|
||||
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C))
|
||||
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V))
|
||||
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N))
|
||||
#define SET_XFLG(y) (regflags.x = ((y) ? 1 : 0) << FLAGBIT_X)
|
||||
|
||||
#define GET_ZFLG(flags) (((flags)->cznv >> FLAGBIT_Z) & 1)
|
||||
#define GET_CFLG(flags) (((flags)->cznv >> FLAGBIT_C) & 1)
|
||||
#define GET_VFLG(flags) (((flags)->cznv >> FLAGBIT_V) & 1)
|
||||
#define GET_NFLG(flags) (((flags)->cznv >> FLAGBIT_N) & 1)
|
||||
#define GET_XFLG(flags) (((flags)->x >> FLAGBIT_X) & 1)
|
||||
#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1)
|
||||
#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1)
|
||||
#define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1)
|
||||
#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1)
|
||||
#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1)
|
||||
|
||||
#define CLEAR_CZNV(flags) ((flags)->cznv = 0)
|
||||
#define GET_CZNV(flags) ((flags)->cznv)
|
||||
#define IOR_CZNV(flags, X) ((flags)->cznv |= (X))
|
||||
#define SET_CZNV(flags, X) ((flags)->cznv = (X))
|
||||
#define CLEAR_CZNV() (regflags.cznv = 0)
|
||||
#define GET_CZNV (regflags.cznv)
|
||||
#define IOR_CZNV(X) (regflags.cznv |= (X))
|
||||
#define SET_CZNV(X) (regflags.cznv = (X))
|
||||
|
||||
#define COPY_CARRY (regflags.x = regflags.cznv)
|
||||
|
||||
#define COPY_CARRY(flags) ((flags)->x = (flags)->cznv)
|
||||
|
||||
/*
|
||||
* Test CCR condition
|
||||
*/
|
||||
STATIC_INLINE int cctrue (const struct flag_struct *flags, int cc)
|
||||
STATIC_INLINE int cctrue(int cc)
|
||||
{
|
||||
uae_u32 cznv = flags->cznv;
|
||||
uae_u32 cznv = regflags.cznv;
|
||||
|
||||
switch (cc) {
|
||||
case 0: return 1; /* T */
|
||||
|
@ -31,89 +31,82 @@
|
||||
*
|
||||
* Evaluate operand and set Z and N flags. Always clear C and V.
|
||||
*/
|
||||
#define optflag_testl(regs, v) \
|
||||
do { \
|
||||
uae_u32 tmp; \
|
||||
asm ( \
|
||||
"cmpi cr0, %2, 0 \n\t" \
|
||||
"mfcr %1 \n\t" \
|
||||
"rlwinm %0, %1, 0, 0, 3 \n\t" \
|
||||
\
|
||||
: "=r" ((regs)->ccrflags.cznv), \
|
||||
"=r" (tmp) \
|
||||
: "r" (v) \
|
||||
: "cr0" \
|
||||
); \
|
||||
#define optflag_testl (v) \
|
||||
do { \
|
||||
asm ( \
|
||||
"cmpi cr0, %2, 0 \n\t" \
|
||||
"mfcr %1 \n\t" \
|
||||
"rlwinm %0, %1, 0, 0, 3 \n\t" \
|
||||
\
|
||||
:: "r" (v) \
|
||||
: "cr0" \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
#define optflag_testw(regs, v) optflag_testl(regs, (uae_s32)(v))
|
||||
#define optflag_testb(regs, v) optflag_testl(regs, (uae_s32)(v))
|
||||
#define optflag_testw(v) optflag_testl((uae_s32)(v))
|
||||
#define optflag_testb(v) optflag_testl((uae_s32)(v))
|
||||
|
||||
/*
|
||||
* Add operations
|
||||
*
|
||||
* Perform v = s + d and set ZNCV accordingly
|
||||
*/
|
||||
#define optflag_addl(regs, v, s, d) \
|
||||
do { \
|
||||
asm ( \
|
||||
"addco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
\
|
||||
: "=r" ((regs)->ccrflags.cznv), "=r" (v) \
|
||||
: "r" (s), "r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
COPY_CARRY(&(regs)->ccrflags); \
|
||||
#define optflag_addl(v, s, d) \
|
||||
do { \
|
||||
asm ( \
|
||||
"addco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
\
|
||||
: "=r" (v) \
|
||||
: "r" (s), "r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
regflags.x = regflags.cznv; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_addw(regs, v, s, d) do { optflag_addl(regs, (v), (s) << 16, (d) << 16); v = v >> 16; } while (0)
|
||||
#define optflag_addb(regs, v, s, d) do { optflag_addl(regs, (v), (s) << 24, (d) << 24); v = v >> 24; } while (0)
|
||||
#define optflag_addw(v, s, d) do { optflag_addl((v), (s) << 16, (d) << 16); v = v >> 16; } while (0)
|
||||
#define optflag_addb(v, s, d) do { optflag_addl((v), (s) << 24, (d) << 24); v = v >> 24; } while (0)
|
||||
|
||||
/*
|
||||
* Subtraction operations
|
||||
*
|
||||
* Perform v = d - s and set ZNCV accordingly
|
||||
*/
|
||||
#define optflag_subl(regs, v, s, d) \
|
||||
do { \
|
||||
asm ( \
|
||||
"subfco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
"xoris %0,%0,32 \n\t" \
|
||||
\
|
||||
: "=r" ((regs)->ccrflags.cznv), \
|
||||
"=r" (v) \
|
||||
: "r" (s), \
|
||||
"r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
COPY_CARRY(&(regs)->ccrflags); \
|
||||
#define optflag_subl(v, s, d) \
|
||||
do { \
|
||||
asm ( \
|
||||
"subfco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
"xoris %0,%0,32 \n\t" \
|
||||
\
|
||||
: "=r" (v) \
|
||||
: "r" (s), \
|
||||
"r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
regflags.x = regflags.cznv; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_subw(regs, v, s, d) do { optflag_subl(regs, v, (s) << 16, (d) << 16); v = v >> 16; } while (0)
|
||||
#define optflag_subb(regs, v, s, d) do { optflag_subl(regs, v, (s) << 24, (d) << 24); v = v >> 24; } while (0)
|
||||
#define optflag_subw(v, s, d) do { optflag_subl(v, (s) << 16, (d) << 16); v = v >> 16; } while (0)
|
||||
#define optflag_subb(v, s, d) do { optflag_subl(v, (s) << 24, (d) << 24); v = v >> 24; } while (0)
|
||||
|
||||
#define optflag_cmpl(regs, s, d) \
|
||||
do { \
|
||||
uae_s32 tmp; \
|
||||
asm ( \
|
||||
"subfco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
"xoris %0,%0,32 \n\t" \
|
||||
\
|
||||
: "=r" ((regs)->ccrflags.cznv), \
|
||||
"=r" (tmp) \
|
||||
: "r" (s), \
|
||||
"r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
#define optflag_cmpl(s, d) \
|
||||
do { \
|
||||
asm ( \
|
||||
"subfco. %1, %2, %3 \n\t" \
|
||||
"mcrxr cr2 \n\t" \
|
||||
"mfcr %0 \n\t" \
|
||||
"xoris %0,%0,32 \n\t" \
|
||||
\
|
||||
:: "r" (s), \
|
||||
"r" (d) \
|
||||
: "cr0", "cr2" DEP_XER \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
#define optflag_cmpw(regs, s, d) optflag_cmpl(regs, (s) << 16, (d) << 16)
|
||||
#define optflag_cmpb(regs, s, d) optflag_cmpl(regs, (s) << 24, (d) << 24)
|
||||
#define optflag_cmpw(s, d) optflag_cmpl((s) << 16, (d) << 16)
|
||||
#define optflag_cmpb(s, d) optflag_cmpl((s) << 24, (d) << 24)
|
||||
|
||||
#endif /* EUAE_MACHDEP_M68KOPS_H */
|
||||
|
42
src/misc.c
42
src/misc.c
@ -925,3 +925,45 @@ TCHAR *au_copy (TCHAR *dst, int maxlen, const char *src)
|
||||
memcpy (dst, src, maxlen);
|
||||
return dst;
|
||||
}
|
||||
//writelog.cpp
|
||||
int consoleopen = 0;
|
||||
static int realconsole = 1;
|
||||
|
||||
static int debugger_type = -1;
|
||||
|
||||
static void openconsole (void)
|
||||
{
|
||||
if (realconsole) {
|
||||
if (debugger_type == 2) {
|
||||
//open_debug_window ();
|
||||
consoleopen = 1;
|
||||
} else {
|
||||
//close_debug_window ();
|
||||
consoleopen = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void close_console (void)
|
||||
{
|
||||
if (realconsole)
|
||||
return;
|
||||
}
|
||||
|
||||
void debugger_change (int mode)
|
||||
{
|
||||
if (mode < 0)
|
||||
debugger_type = debugger_type == 2 ? 1 : 2;
|
||||
else
|
||||
debugger_type = mode;
|
||||
if (debugger_type != 1 && debugger_type != 2)
|
||||
debugger_type = 2;
|
||||
// regsetint (NULL, "DebuggerType", debugger_type);
|
||||
openconsole ();
|
||||
}
|
||||
//unicode.c
|
||||
char *ua (const TCHAR *s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* UAE - The Un*x Amiga Emulator
|
||||
*
|
||||
* A4000T NCR 53C710 SCSI (nothing done yet)
|
||||
*
|
||||
* (c) 2007 Toni Wilen
|
||||
*/
|
||||
* UAE - The Un*x Amiga Emulator
|
||||
*
|
||||
* A4000T NCR 53C710 SCSI (nothing done yet)
|
||||
*
|
||||
* (c) 2007 Toni Wilen
|
||||
*/
|
||||
|
||||
#ifdef NCR
|
||||
#define NCR_LOG 1
|
||||
@ -47,24 +47,24 @@ static struct ncrscsi regsinfo[] =
|
||||
{
|
||||
"SCNTL0", 0, 3,
|
||||
"SCNTL1", 1, 2,
|
||||
"SDID", 2, 1,
|
||||
"SIEN", 3, 0,
|
||||
"SCID", 4, 7,
|
||||
"SDID", 2, 1,
|
||||
"SIEN", 3, 0,
|
||||
"SCID", 4, 7,
|
||||
"SXFER", 5, 6,
|
||||
"SODL", 6, 5,
|
||||
"SOCL", 7, 4,
|
||||
"SFBR", 8, 11,
|
||||
"SIDL", 9, 10,
|
||||
"SBDL", 10, -1,
|
||||
"SBCL", 11, 8,
|
||||
"SODL", 6, 5,
|
||||
"SOCL", 7, 4,
|
||||
"SFBR", 8, 11,
|
||||
"SIDL", 9, 10,
|
||||
"SBDL", 10, -1,
|
||||
"SBCL", 11, 8,
|
||||
"DSTAT", 12, 15,
|
||||
"SSTAT0", 13, 14,
|
||||
"SSTAT1", 14, 13,
|
||||
"SSTAT2", 15, 12,
|
||||
"DSA0", 16, 19,
|
||||
"DSA1", 17, 18,
|
||||
"DSA2", 18, 17,
|
||||
"DSA3", 19, 16,
|
||||
"DSA0", 16, 19,
|
||||
"DSA1", 17, 18,
|
||||
"DSA2", 18, 17,
|
||||
"DSA3", 19, 16,
|
||||
"CTEST0", 20, 23,
|
||||
"CTEST1", 21, 22,
|
||||
"CTEST2", 22, 21,
|
||||
@ -80,19 +80,19 @@ static struct ncrscsi regsinfo[] =
|
||||
"DFIFO", 32, 35,
|
||||
"ISTAT", 33, 34,
|
||||
"CTEST8", 34, 33,
|
||||
"LCRC", 35, 32,
|
||||
"DBC0", 36, 39,
|
||||
"DBC1", 37, 38,
|
||||
"DBC2", 38, 37,
|
||||
"DCMD", 39, 36,
|
||||
"LCRC", 35, 32,
|
||||
"DBC0", 36, 39,
|
||||
"DBC1", 37, 38,
|
||||
"DBC2", 38, 37,
|
||||
"DCMD", 39, 36,
|
||||
"DNAD0", 40, 43,
|
||||
"DNAD1", 41, 42,
|
||||
"DNAD2", 42, 41,
|
||||
"DNAD3", 43, 40,
|
||||
"DSP0", 44, 47,
|
||||
"DSP1", 45, 46,
|
||||
"DSP2", 46, 45,
|
||||
"DSP3", 47, 44,
|
||||
"DSP0", 44, 47,
|
||||
"DSP1", 45, 46,
|
||||
"DSP2", 46, 45,
|
||||
"DSP3", 47, 44,
|
||||
"DSPS0", 48, 51,
|
||||
"DSPS1", 49, 50,
|
||||
"DSPS2", 50, 49,
|
||||
@ -102,8 +102,8 @@ static struct ncrscsi regsinfo[] =
|
||||
"SCRATCH2", 54, 53,
|
||||
"SCRATCH3", 55, 52,
|
||||
"DMODE", 56, 59,
|
||||
"DIEN", 57, 58,
|
||||
"DWT", 58, 57,
|
||||
"DIEN", 57, 58,
|
||||
"DWT", 58, 57,
|
||||
"DCNTL", 59, 56,
|
||||
"ADDER0", 60, 63,
|
||||
"ADDER1", 61, 62,
|
||||
|
@ -797,7 +797,7 @@ void read_table68k (void)
|
||||
}
|
||||
}
|
||||
|
||||
static int mismatch;
|
||||
static int imismatch;
|
||||
|
||||
static void handle_merges (long int opcode)
|
||||
{
|
||||
@ -852,20 +852,20 @@ static void handle_merges (long int opcode)
|
||||
|| table68k[code].suse != table68k[opcode].suse
|
||||
|| table68k[code].duse != table68k[opcode].duse)
|
||||
{
|
||||
mismatch++; continue;
|
||||
imismatch++; continue;
|
||||
}
|
||||
if (table68k[opcode].suse
|
||||
&& (table68k[opcode].spos != table68k[code].spos
|
||||
|| table68k[opcode].smode != table68k[code].smode
|
||||
|| table68k[opcode].stype != table68k[code].stype))
|
||||
{
|
||||
mismatch++; continue;
|
||||
imismatch++; continue;
|
||||
}
|
||||
if (table68k[opcode].duse
|
||||
&& (table68k[opcode].dpos != table68k[code].dpos
|
||||
|| table68k[opcode].dmode != table68k[code].dmode))
|
||||
{
|
||||
mismatch++; continue;
|
||||
imismatch++; continue;
|
||||
}
|
||||
|
||||
if (code != opcode)
|
||||
@ -878,7 +878,7 @@ void do_merges (void)
|
||||
{
|
||||
long int opcode;
|
||||
int nr = 0;
|
||||
mismatch = 0;
|
||||
imismatch = 0;
|
||||
for (opcode = 0; opcode < 65536; opcode++) {
|
||||
if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
|
||||
continue;
|
||||
@ -890,5 +890,5 @@ void do_merges (void)
|
||||
|
||||
int get_no_mismatches (void)
|
||||
{
|
||||
return mismatch;
|
||||
return imismatch;
|
||||
}
|
||||
|
@ -42,11 +42,11 @@
|
||||
#define O_NONBLOCK O_NDELAY
|
||||
#endif
|
||||
|
||||
#define SERIALDEBUG 1 /* 0, 1, 2 3 */
|
||||
#define MODEMTEST 0 /* 0 or 1 */
|
||||
#define SERIALDEBUG 1 /* 0, 1, 2 3 */
|
||||
#define MODEMTEST 0 /* 0 or 1 */
|
||||
|
||||
void serial_open(void);
|
||||
void serial_close(void);
|
||||
void serial_open (void);
|
||||
void serial_close (void);
|
||||
void serial_init (void);
|
||||
void serial_exit (void);
|
||||
|
||||
|
@ -445,7 +445,7 @@ configure:4344: $? = 0
|
||||
configure:4344: result: yes
|
||||
configure:4350: checking for _doprnt
|
||||
configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
|
||||
/tmp/ccJt8Zal.o: In function `main':
|
||||
/tmp/ccNsQ6E6.o: In function `main':
|
||||
/home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt'
|
||||
collect2: ld returned 1 exit status
|
||||
configure:4350: $? = 1
|
||||
@ -533,7 +533,7 @@ configure:4364: $? = 0
|
||||
configure:4364: result: yes
|
||||
configure:4364: checking for strcmpi
|
||||
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
|
||||
/tmp/ccmv4giy.o: In function `main':
|
||||
/tmp/ccttoGGl.o: In function `main':
|
||||
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi'
|
||||
collect2: ld returned 1 exit status
|
||||
configure:4364: $? = 1
|
||||
@ -613,7 +613,7 @@ configure: failed program was:
|
||||
configure:4364: result: no
|
||||
configure:4364: checking for stricmp
|
||||
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
|
||||
/tmp/cczfg0cD.o: In function `main':
|
||||
/tmp/ccls9BAq.o: In function `main':
|
||||
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp'
|
||||
collect2: ld returned 1 exit status
|
||||
configure:4364: $? = 1
|
||||
|
286
src/traps.c
286
src/traps.c
@ -1,14 +1,14 @@
|
||||
/*
|
||||
* E-UAE - The portable Amiga Emulator
|
||||
*
|
||||
* Support for traps
|
||||
*
|
||||
* Copyright Richard Drummond 2005
|
||||
*
|
||||
* Inspired by code from UAE:
|
||||
* Copyright 1995, 1996 Bernd Schmidt
|
||||
* Copyright 1996 Ed Hanway
|
||||
*/
|
||||
/*
|
||||
* E-UAE - The portable Amiga Emulator
|
||||
*
|
||||
* Support for traps
|
||||
*
|
||||
* Copyright Richard Drummond 2005
|
||||
*
|
||||
* Inspired by code from UAE:
|
||||
* Copyright 1995, 1996 Bernd Schmidt
|
||||
* Copyright 1996 Ed Hanway
|
||||
*/
|
||||
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
@ -63,10 +63,10 @@
|
||||
*/
|
||||
struct Trap
|
||||
{
|
||||
TrapHandler handler; /* Handler function to be invoked for this trap. */
|
||||
int flags; /* Trap attributes. */
|
||||
TrapHandler handler; /* Handler function to be invoked for this trap. */
|
||||
int flags; /* Trap attributes. */
|
||||
const TCHAR *name; /* For debugging purposes. */
|
||||
uaecptr addr;
|
||||
uaecptr addr;
|
||||
};
|
||||
|
||||
#define MAX_TRAPS 4096
|
||||
@ -82,14 +82,14 @@ static void trap_HandleExtendedTrap (TrapHandler, int has_retval);
|
||||
|
||||
uaecptr find_trap (const TCHAR *name)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < trap_count; i++) {
|
||||
for (i = 0; i < trap_count; i++) {
|
||||
struct Trap *trap = &traps[i];
|
||||
if ((trap->flags & TRAPFLAG_UAERES) && trap->name && !_tcscmp (trap->name, name))
|
||||
return trap->addr;
|
||||
}
|
||||
return 0;
|
||||
return trap->addr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -104,18 +104,18 @@ uaecptr find_trap (const TCHAR *name)
|
||||
*/
|
||||
unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name)
|
||||
{
|
||||
if (trap_count == MAX_TRAPS) {
|
||||
if (trap_count == MAX_TRAPS) {
|
||||
write_log ("Ran out of emulator traps\n");
|
||||
abort ();
|
||||
return -1;
|
||||
} else {
|
||||
} else {
|
||||
int i;
|
||||
unsigned int trap_num;
|
||||
struct Trap *trap;
|
||||
uaecptr addr = here ();
|
||||
|
||||
for (i = 0; i < trap_count; i++) {
|
||||
if (addr == traps[i].addr)
|
||||
if (addr == traps[i].addr)
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name
|
||||
trap->addr = addr;
|
||||
|
||||
return trap_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,35 +140,35 @@ unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name
|
||||
*/
|
||||
void REGPARAM2 m68k_handle_trap (unsigned int trap_num)
|
||||
{
|
||||
struct Trap *trap = &traps[trap_num];
|
||||
uae_u32 retval = 0;
|
||||
struct Trap *trap = &traps[trap_num];
|
||||
uae_u32 retval = 0;
|
||||
|
||||
int has_retval = (trap->flags & TRAPFLAG_NO_RETVAL) == 0;
|
||||
int implicit_rts = (trap->flags & TRAPFLAG_DORET) != 0;
|
||||
int has_retval = (trap->flags & TRAPFLAG_NO_RETVAL) == 0;
|
||||
int implicit_rts = (trap->flags & TRAPFLAG_DORET) != 0;
|
||||
|
||||
if (trap->name && trap->name[0] != 0 && trace_traps)
|
||||
if (trap->name && trap->name[0] != 0 && trace_traps)
|
||||
write_log ("TRAP: %s\n", trap->name);
|
||||
|
||||
if (trap_num < trap_count) {
|
||||
if (trap_num < trap_count) {
|
||||
if (trap->flags & TRAPFLAG_EXTRA_STACK) {
|
||||
/* Handle an extended trap.
|
||||
* Note: the return value of this trap is passed back to 68k
|
||||
* space via a separate, dedicated simple trap which the trap
|
||||
* handler causes to be invoked when it is done.
|
||||
*/
|
||||
trap_HandleExtendedTrap (trap->handler, has_retval);
|
||||
/* Handle an extended trap.
|
||||
* Note: the return value of this trap is passed back to 68k
|
||||
* space via a separate, dedicated simple trap which the trap
|
||||
* handler causes to be invoked when it is done.
|
||||
*/
|
||||
trap_HandleExtendedTrap (trap->handler, has_retval);
|
||||
} else {
|
||||
/* Handle simple trap */
|
||||
/* Handle simple trap */
|
||||
retval = (trap->handler) (NULL);
|
||||
|
||||
if (has_retval)
|
||||
if (has_retval)
|
||||
m68k_dreg (regs, 0) = retval;
|
||||
|
||||
if (implicit_rts) {
|
||||
if (implicit_rts) {
|
||||
m68k_do_rts ();
|
||||
fill_prefetch_slow ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
write_log ("Illegal emulator trap %d\n", trap_num);
|
||||
}
|
||||
@ -227,41 +227,41 @@ static void *trap_thread (void *arg)
|
||||
{
|
||||
TrapContext *context = (TrapContext *) arg;
|
||||
|
||||
/* Wait until main thread is ready to switch to the
|
||||
* this trap context. */
|
||||
uae_sem_wait (&context->switch_to_trap_sem);
|
||||
/* Wait until main thread is ready to switch to the
|
||||
* this trap context. */
|
||||
uae_sem_wait (&context->switch_to_trap_sem);
|
||||
|
||||
/* Execute trap handler function. */
|
||||
/* Execute trap handler function. */
|
||||
context->trap_retval = context->trap_handler (context);
|
||||
|
||||
/* Trap handler is done - we still need to tidy up
|
||||
* and make sure the handler's return value is propagated
|
||||
* to the calling 68k thread.
|
||||
*
|
||||
* We do this by causing our exit handler to be executed on the 68k context.
|
||||
*/
|
||||
/* Trap handler is done - we still need to tidy up
|
||||
* and make sure the handler's return value is propagated
|
||||
* to the calling 68k thread.
|
||||
*
|
||||
* We do this by causing our exit handler to be executed on the 68k context.
|
||||
*/
|
||||
|
||||
/* Enter critical section - only one trap at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
/* Enter critical section - only one trap at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
|
||||
regs = context->saved_regs;
|
||||
/* Don't allow an interrupt and thus potentially another
|
||||
* trap to be invoked while we hold the above mutex.
|
||||
* This is probably just being paranoid. */
|
||||
/* Don't allow an interrupt and thus potentially another
|
||||
* trap to be invoked while we hold the above mutex.
|
||||
* This is probably just being paranoid. */
|
||||
regs.intmask = 7;
|
||||
|
||||
/* Set PC to address of the exit handler, so that it will be called
|
||||
* when the 68k context resumes. */
|
||||
m68k_setpc (exit_trap_trapaddr);
|
||||
current_context = context;
|
||||
/* Set PC to address of the exit handler, so that it will be called
|
||||
* when the 68k context resumes. */
|
||||
m68k_setpc (exit_trap_trapaddr);
|
||||
current_context = context;
|
||||
|
||||
/* Switch back to 68k context */
|
||||
uae_sem_post (&context->switch_to_emu_sem);
|
||||
/* Switch back to 68k context */
|
||||
uae_sem_post (&context->switch_to_emu_sem);
|
||||
|
||||
/* Good bye, cruel world... */
|
||||
/* Good bye, cruel world... */
|
||||
|
||||
/* dummy return value */
|
||||
return 0;
|
||||
/* dummy return value */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -271,11 +271,11 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
|
||||
{
|
||||
struct TrapContext *context = xcalloc (TrapContext, 1);
|
||||
|
||||
if (context) {
|
||||
if (context) {
|
||||
uae_sem_init (&context->switch_to_trap_sem, 0, 0);
|
||||
uae_sem_init (&context->switch_to_emu_sem, 0, 0);
|
||||
|
||||
context->trap_handler = handler_func;
|
||||
context->trap_handler = handler_func;
|
||||
context->trap_has_retval = has_retval;
|
||||
|
||||
context->saved_regs = regs; /* Copy of regs to be restored when trap is done */
|
||||
@ -293,7 +293,7 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
|
||||
* It'll do this when the trap handler is done - or when
|
||||
* the handler wants to call 68k code. */
|
||||
uae_sem_wait (&context->switch_to_emu_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -303,34 +303,34 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
|
||||
*/
|
||||
static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr)
|
||||
{
|
||||
/* Enter critical section - only one trap at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
current_context = context;
|
||||
/* Enter critical section - only one trap at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
current_context = context;
|
||||
|
||||
/* Don't allow an interrupt and thus potentially another
|
||||
* trap to be invoked while we hold the above mutex.
|
||||
* This is probably just being paranoid. */
|
||||
/* Don't allow an interrupt and thus potentially another
|
||||
* trap to be invoked while we hold the above mutex.
|
||||
* This is probably just being paranoid. */
|
||||
regs.intmask = 7;
|
||||
|
||||
/* Set up function call address. */
|
||||
context->call68k_func_addr = func_addr;
|
||||
/* Set up function call address. */
|
||||
context->call68k_func_addr = func_addr;
|
||||
|
||||
/* Set PC to address of 68k call trap, so that it will be
|
||||
* executed when emulator context resumes. */
|
||||
m68k_setpc (m68k_call_trapaddr);
|
||||
fill_prefetch_slow ();
|
||||
/* Set PC to address of 68k call trap, so that it will be
|
||||
* executed when emulator context resumes. */
|
||||
m68k_setpc (m68k_call_trapaddr);
|
||||
fill_prefetch_slow ();
|
||||
|
||||
/* Switch to emulator context. */
|
||||
uae_sem_post (&context->switch_to_emu_sem);
|
||||
/* Switch to emulator context. */
|
||||
uae_sem_post (&context->switch_to_emu_sem);
|
||||
|
||||
/* Wait for 68k call return handler to switch back to us. */
|
||||
uae_sem_wait (&context->switch_to_trap_sem);
|
||||
/* Wait for 68k call return handler to switch back to us. */
|
||||
uae_sem_wait (&context->switch_to_trap_sem);
|
||||
|
||||
/* End critical section. */
|
||||
uae_sem_post (&trap_mutex);
|
||||
/* End critical section. */
|
||||
uae_sem_post (&trap_mutex);
|
||||
|
||||
/* Get return value from 68k function called. */
|
||||
return context->call68k_retval;
|
||||
/* Get return value from 68k function called. */
|
||||
return context->call68k_retval;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -344,31 +344,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx)
|
||||
|
||||
sp = m68k_areg (regs, 7);
|
||||
|
||||
/* Push address of trap context on 68k stack. This is
|
||||
* so the return trap can find this context. */
|
||||
sp -= sizeof (void *);
|
||||
put_pointer (sp, context);
|
||||
/* Push address of trap context on 68k stack. This is
|
||||
* so the return trap can find this context. */
|
||||
sp -= sizeof (void *);
|
||||
put_pointer (sp, context);
|
||||
|
||||
/* Push addr to return handler trap on 68k stack.
|
||||
* When the called m68k function does an RTS, the CPU will pull this
|
||||
* address off the stack and so call the return handler. */
|
||||
sp -= 4;
|
||||
put_long (sp, m68k_return_trapaddr);
|
||||
/* Push addr to return handler trap on 68k stack.
|
||||
* When the called m68k function does an RTS, the CPU will pull this
|
||||
* address off the stack and so call the return handler. */
|
||||
sp -= 4;
|
||||
put_long (sp, m68k_return_trapaddr);
|
||||
|
||||
m68k_areg (regs, 7) = sp;
|
||||
m68k_areg (regs, 7) = sp;
|
||||
|
||||
/* Set PC to address of 68k function to call. */
|
||||
m68k_setpc (context->call68k_func_addr);
|
||||
fill_prefetch_slow ();
|
||||
/* Set PC to address of 68k function to call. */
|
||||
m68k_setpc (context->call68k_func_addr);
|
||||
fill_prefetch_slow ();
|
||||
|
||||
/* End critical section: allow other traps run. */
|
||||
uae_sem_post (&trap_mutex);
|
||||
/* End critical section: allow other traps run. */
|
||||
uae_sem_post (&trap_mutex);
|
||||
|
||||
/* Restore interrupts. */
|
||||
/* Restore interrupts. */
|
||||
regs.intmask = context->saved_regs.intmask;
|
||||
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -377,31 +377,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx)
|
||||
static uae_u32 REGPARAM2 m68k_return_handler (TrapContext *dummy_ctx)
|
||||
{
|
||||
TrapContext *context;
|
||||
uae_u32 sp;
|
||||
uae_u32 sp;
|
||||
|
||||
/* One trap returning at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
/* One trap returning at a time, please! */
|
||||
uae_sem_wait (&trap_mutex);
|
||||
|
||||
/* Get trap context from 68k stack. */
|
||||
sp = m68k_areg (regs, 7);
|
||||
/* Get trap context from 68k stack. */
|
||||
sp = m68k_areg (regs, 7);
|
||||
context = (TrapContext *)get_pointer (sp);
|
||||
sp += sizeof (void *);
|
||||
m68k_areg (regs, 7) = sp;
|
||||
sp += sizeof (void *);
|
||||
m68k_areg (regs, 7) = sp;
|
||||
|
||||
/* Get return value from the 68k call. */
|
||||
context->call68k_retval = m68k_dreg (regs, 0);
|
||||
/* Get return value from the 68k call. */
|
||||
context->call68k_retval = m68k_dreg (regs, 0);
|
||||
|
||||
/* Switch back to trap context. */
|
||||
uae_sem_post (&context->switch_to_trap_sem);
|
||||
/* Switch back to trap context. */
|
||||
uae_sem_post (&context->switch_to_trap_sem);
|
||||
|
||||
/* Wait for trap context to switch back to us.
|
||||
*
|
||||
* It'll do this when the trap handler is done - or when
|
||||
* the handler wants to call another 68k function. */
|
||||
uae_sem_wait (&context->switch_to_emu_sem);
|
||||
/* Wait for trap context to switch back to us.
|
||||
*
|
||||
* It'll do this when the trap handler is done - or when
|
||||
* the handler wants to call another 68k function. */
|
||||
uae_sem_wait (&context->switch_to_emu_sem);
|
||||
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -412,27 +412,27 @@ static uae_u32 REGPARAM2 exit_trap_handler (TrapContext *dummy_ctx)
|
||||
{
|
||||
TrapContext *context = current_context;
|
||||
|
||||
/* Wait for trap context thread to exit. */
|
||||
uae_wait_thread (context->thread);
|
||||
/* Wait for trap context thread to exit. */
|
||||
uae_wait_thread (context->thread);
|
||||
|
||||
/* Restore 68k state saved at trap entry. */
|
||||
/* Restore 68k state saved at trap entry. */
|
||||
regs = context->saved_regs;
|
||||
|
||||
/* If trap is supposed to return a value, then store
|
||||
* return value in D0. */
|
||||
if (context->trap_has_retval)
|
||||
m68k_dreg (regs, 0) = context->trap_retval;
|
||||
/* If trap is supposed to return a value, then store
|
||||
* return value in D0. */
|
||||
if (context->trap_has_retval)
|
||||
m68k_dreg (regs, 0) = context->trap_retval;
|
||||
|
||||
uae_sem_destroy (&context->switch_to_trap_sem);
|
||||
uae_sem_destroy (&context->switch_to_emu_sem);
|
||||
uae_sem_destroy (&context->switch_to_trap_sem);
|
||||
uae_sem_destroy (&context->switch_to_emu_sem);
|
||||
|
||||
xfree (context);
|
||||
|
||||
/* End critical section */
|
||||
uae_sem_post (&trap_mutex);
|
||||
/* End critical section */
|
||||
uae_sem_post (&trap_mutex);
|
||||
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
/* Dummy return value. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -442,14 +442,14 @@ static uae_u32 REGPARAM2 exit_trap_handler (TrapContext *dummy_ctx)
|
||||
*/
|
||||
uae_u32 CallLib (TrapContext *context, uaecptr base, uae_s16 offset)
|
||||
{
|
||||
uae_u32 retval;
|
||||
uae_u32 retval;
|
||||
uaecptr olda6 = m68k_areg (regs, 6);
|
||||
|
||||
m68k_areg (regs, 6) = base;
|
||||
retval = trap_Call68k (context, base + offset);
|
||||
m68k_areg (regs, 6) = olda6;
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -466,7 +466,7 @@ uae_u32 CallFunc (TrapContext *context, uaecptr func)
|
||||
*/
|
||||
void init_traps (void)
|
||||
{
|
||||
trap_count = 0;
|
||||
trap_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -474,14 +474,14 @@ void init_traps (void)
|
||||
*/
|
||||
void init_extended_traps (void)
|
||||
{
|
||||
m68k_call_trapaddr = here ();
|
||||
m68k_call_trapaddr = here ();
|
||||
calltrap (deftrap2 (m68k_call_handler, TRAPFLAG_NO_RETVAL, "m68k_call"));
|
||||
|
||||
m68k_return_trapaddr = here();
|
||||
m68k_return_trapaddr = here();
|
||||
calltrap (deftrap2 (m68k_return_handler, TRAPFLAG_NO_RETVAL, "m68k_return"));
|
||||
|
||||
exit_trap_trapaddr = here();
|
||||
exit_trap_trapaddr = here();
|
||||
calltrap (deftrap2 (exit_trap_handler, TRAPFLAG_NO_RETVAL, "exit_trap"));
|
||||
|
||||
uae_sem_init (&trap_mutex, 0, 1);
|
||||
uae_sem_init (&trap_mutex, 0, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user