sync 2.2.1

parent 716e8cfa
/*
* 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"
......
/*
* 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"
......
/*
* UAE - The Un*x Amiga Emulator
*
* Debugger
*
* (c) 1995 Bernd Schmidt
* (c) 2006 Toni Wilen
*
*/
* UAE - The Un*x Amiga Emulator
*
* Debugger
*
* (c) 1995 Bernd Schmidt
* (c) 2006 Toni Wilen
*
*/
#include "sysconfig.h"
#include "sysdeps.h"
......@@ -68,9 +68,9 @@ static FILE *logfile;
#define console_out printf
#define console_flush() fflush( stdout )
#define console_get( input, len ) fgets( input, len, stdin )
#define console_out_f printf
#endif
void deactivate_debugger (void)
{
debugger_active = 0;
......@@ -170,101 +170,252 @@ void debug_help (void)
static int debug_linecounter;
#define MAX_LINECOUNTER 1000
static void ignore_ws (const char **c)
static int debug_out (const TCHAR *format, ...)
{
va_list parms;
TCHAR buffer[4000];
va_start (parms, format);
_vsntprintf (buffer, 4000 - 1, format, parms);
va_end (parms);
console_out (buffer);
if (debug_linecounter < MAX_LINECOUNTER)
debug_linecounter++;
if (debug_linecounter >= MAX_LINECOUNTER)
return 0;
return 1;
}
static void ignore_ws (TCHAR **c)
{
while (**c && isspace (**c))
(*c)++;
while (**c && _istspace(**c))
(*c)++;
}
static uae_u32 readint (const char **c);
static uae_u32 readbin (const char **c);
static uae_u32 readhex (const char **c)
static uae_u32 readint (TCHAR **c);
static uae_u32 readbin (TCHAR **c);
static uae_u32 readhex (TCHAR **c);
static int readregx (TCHAR **c, uae_u32 *valp)
{
uae_u32 val = 0;
char nc;
int i;
uae_u32 addr;
TCHAR *p = *c;
TCHAR tmp[10];
int extra = 0;
ignore_ws (c);
if (**c == '!' || **c == '_') {
(*c)++;
return readint (c);
}
while (isxdigit (nc = **c)) {
(*c)++;
val *= 16;
nc = toupper (nc);
if (isdigit (nc)) {
val += nc - '0';
addr = 0;
i = 0;
while (p[i]) {
tmp[i] = _totupper (p[i]);
if (i >= sizeof (tmp) / sizeof (TCHAR) - 1)
break;
i++;
}
tmp[i] = 0;
if (_totupper (tmp[0]) == 'R') {
memmove (tmp, tmp + 1, sizeof (tmp) - sizeof (TCHAR));
extra = 1;
}
if (!_tcscmp (tmp, "USP")) {
addr = regs.usp;
(*c) += 3;
} else if (!_tcscmp (tmp, "VBR")) {
addr = regs.vbr;
(*c) += 3;
} else if (!_tcscmp (tmp, "MSP")) {
addr = regs.msp;
(*c) += 3;
} else if (!_tcscmp (tmp, "ISP")) {
addr = regs.isp;
(*c) += 3;
} else if (!_tcscmp (tmp, "PC")) {
addr = regs.pc;
(*c) += 2;
} else if (tmp[0] == 'A' || tmp[0] == 'D') {
int reg = 0;
if (tmp[0] == 'A')
reg += 8;
reg += tmp[1] - '0';
if (reg < 0 || reg > 15)
return 0;
addr = regs.regs[reg];
(*c) += 2;
} else {
val += nc - 'A' + 10;
return 0;
}
}
return val;
*valp = addr;
(*c) += extra;
return 1;
}
static uae_u32 readint (const char **c)
static uae_u32 readbinx (TCHAR **c)
{
uae_u32 val = 0;
char nc;
int sign = 1;
uae_u32 val = 0;
ignore_ws (c);
if (**c == '$') {
(*c)++;
return readhex (c);
}
if (**c == '0' && toupper ((*c)[1]) == 'X') {
(*c) += 2;
return readhex (c);
}
if (**c == '-') {
sign = 1;
(*c)++;
}
while (isdigit (nc = **c)) {
(*c)++;
val *= 10;
val += nc - '0';
}
return val * sign;
ignore_ws (c);
for (;;) {
TCHAR nc = **c;
if (nc != '1' && nc != '0')
break;
(*c)++;
val <<= 1;
if (nc == '1')
val |= 1;
}
return val;
}
static char next_char (const char **c)
static uae_u32 readhexx (TCHAR **c)
{
ignore_ws (c);
return *(*c)++;
uae_u32 val = 0;
TCHAR nc;
ignore_ws (c);
while (isxdigit (nc = **c)) {
(*c)++;
val *= 16;
nc = _totupper (nc);
if (isdigit (nc)) {
val += nc - '0';
} else {
val += nc - 'A' + 10;
}
}
return val;
}
static char peek_next_char (const char **c)
static uae_u32 readintx (TCHAR **c)
{
const char *pc = *c;
return pc[1];
uae_u32 val = 0;
TCHAR nc;
int negative = 0;
ignore_ws (c);
if (**c == '-')
negative = 1, (*c)++;
while (isdigit (nc = **c)) {
(*c)++;
val *= 10;
val += nc - '0';
}
return val * (negative ? -1 : 1);
}
static int more_params (const char **c)
static int checkvaltype (TCHAR **c, uae_u32 *val)
{
ignore_ws (c);
return (**c) != 0;
TCHAR nc;
ignore_ws (c);
nc = _totupper (**c);
if (nc == '!') {
(*c)++;
*val = readintx (c);
return 1;
}
if (nc == '$') {
(*c)++;
*val = readhexx (c);
return 1;
}
if (nc == '0' && _totupper ((*c)[1]) == 'X') {
(*c)+= 2;
*val = readhexx (c);
return 1;
}
if (nc == '%') {
(*c)++;
*val = readbinx (c);
return 1;
}
if (nc >= 'A' && nc <= 'Z' && nc != 'A' && nc != 'D') {
if (readregx (c, val))
return 1;
}
return 0;
}
static int next_string (const char **c, char *out, unsigned int max, int forceupper)
static uae_u32 readint (TCHAR **c)
{
uae_u32 val;
if (checkvaltype (c, &val))
return val;
return readintx (c);
}
static uae_u32 readhex (TCHAR **c)
{
uae_u32 val;
if (checkvaltype (c, &val))
return val;
return readhexx (c);
}
static uae_u32 readbin (TCHAR **c)
{
char *p = out;
uae_u32 val;
if (checkvaltype (c, &val))
return val;
return readbinx (c);
}
static TCHAR next_char (TCHAR **c)
{
ignore_ws (c);
return *(*c)++;
}
static TCHAR peek_next_char (TCHAR **c)
{
TCHAR *pc = *c;
return pc[1];
}
static int more_params (TCHAR **c)
{
ignore_ws (c);
return (**c) != 0;
}
static int next_string (TCHAR **c, TCHAR *out, int max, int forceupper)
{
TCHAR *p = out;
int startmarker = 0;
*p = 0;
while (**c != 0) {
if (**c == 32) {
ignore_ws (c);
return strlen (out);
if (**c == '\"') {
startmarker = 1;
(*c)++;
}
*p = next_char (c);
if (forceupper)
*p = toupper (*p);
*++p = 0;
max--;
if (max <= 1)
break;
}
return strlen (out);
*p = 0;
while (**c != 0) {
if (**c == '\"' && startmarker)
break;
if (**c == 32 && !startmarker) {
ignore_ws (c);
break;
}
*p = next_char (c);
if (forceupper)
*p = _totupper(*p);
*++p = 0;
max--;
if (max <= 1)
break;
}
return _tcslen (out);
}
static void converter (TCHAR **c)
{
uae_u32 v = readint (c);
TCHAR s[100];
TCHAR *p = s;
int i;
for (i = 0; i < 32; i++)
s[i] = (v & (1 << (31 - i))) ? '1' : '0';
s[i] = 0;
console_out_f ("0x%08X = %%%s = %u = %d\n", v, s, v, (uae_s32)v);
}
int notinrom (void)
......@@ -373,7 +524,7 @@ static uaecptr nextaddr (uaecptr addr, uaecptr *end)
uaecptr xa = addr;
if (xa == 1)
xa = 0;
console_out ("%08X -> %08X (%08X)...\n", xa, xa + next - 1, next);
console_out_f ("%08X -> %08X (%08X)...\n", xa, xa + next - 1, next);
}
#endif
return addr;
......@@ -433,17 +584,24 @@ static void dumpmem (uaecptr addr, uaecptr *nxmem, int lines)
TCHAR line[MAX_LINEWIDTH + 1];
for (;lines--;) {
addr = dumpmem2 (addr, line, sizeof(line));
write_log ("%s\n", line);
debug_out ("%s", line);
if (!debug_out ("\n"))
break;
}
*nxmem = addr;
}
static void dump_custom_regs (void)
static void dump_custom_regs (int aga)
{
unsigned int len;
unsigned int i, j, end;
uae_u8 *p1, *p2, *p3, *p4;
if (aga) {
dump_aga_custom();
return;
}
p1 = p2 = save_custom (&len, 0, 1);
p1 += 4; // skip chipset type
for (i = 0; i < 4; i++) {
......@@ -476,7 +634,7 @@ static void dump_custom_regs (void)
addr2 = custd[j].adr & 0x1ff;
v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1];
v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 1];
console_out ("%03X %s\t%04X\t%03X %s\t%04X\n",
console_out_f ("%03X %s\t%04X\t%03X %s\t%04X\n",
addr1, custd[i].name, v1,
addr2, custd[j].name, v2);
}
......@@ -492,12 +650,12 @@ static void dump_vectors (uaecptr addr)
while (int_labels[i].name || trap_labels[j].name) {
if (int_labels[i].name) {
console_out ("$%08X %02d: %12s $%08X ", int_labels[i].adr + addr, int_labels[i].adr / 4,
console_out_f ("$%08X %02d: %12s $%08X ", int_labels[i].adr + addr, int_labels[i].adr / 4,
int_labels[i].name, get_long (int_labels[i].adr + addr));
i++;
}
if (trap_labels[j].name) {
console_out ("$%08X %02d: %12s $%08X", trap_labels[j].adr + addr, trap_labels[j].adr / 4,
console_out_f ("$%08X %02d: %12s $%08X", trap_labels[j].adr + addr, trap_labels[j].adr / 4,
trap_labels[j].name, get_long (trap_labels[j].adr + addr));
j++;
}
......@@ -505,7 +663,7 @@ static void dump_vectors (uaecptr addr)
}
}
static void disassemble_wait (uae_u32 insn)
static void disassemble_wait (FILE *file, unsigned long insn)
{
unsigned int vp, hp, ve, he, bfd, v_mask, h_mask;
int doout = 0;
......@@ -523,9 +681,9 @@ static void disassemble_wait (uae_u32 insn)
doout = 1;
console_out ("vpos ");
if (ve != 0x7f) {
console_out ("& 0x%02x ", ve);
console_out_f ("& 0x%02x ", ve);
}
console_out (">= 0x%02x", v_mask);
console_out_f (">= 0x%02x", v_mask);
}
if (he > 0) {
if (v_mask > 0) {
......@@ -533,16 +691,16 @@ static void disassemble_wait (uae_u32 insn)
}
console_out (" hpos ");
if (he != 0xfe) {
console_out ("& 0x%02x ", he);
console_out_f ("& 0x%02x ", he);
}
console_out (">= 0x%02x", h_mask);
console_out_f (">= 0x%02x", h_mask);
} else {
if (doout)
console_out (", ");
console_out (", ignore horizontal");
}
console_out ("\n \t; VP %02x, VE %02x; HP %02x, HE %02x; BFD %d\n",
console_out_f ("\n \t; VP %02x, VE %02x; HP %02x, HE %02x; BFD %d\n",
vp, ve, hp, he, bfd);
}
......@@ -722,7 +880,7 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
if (!dma_record[0])
return;
dr = &dma_record[dma_record_toggle ^ toggle][vpos * NR_DMA_REC_HPOS];
write_log ("Line: %02X %3d HPOS %02X %3d:\n", vpos, vpos, hpos, hpos);
console_out_f ("Line: %02X %3d HPOS %02X %3d:\n", vpos, vpos, hpos, hpos);
h = hpos;
dr += hpos;
maxh = hpos + 80;
......@@ -731,14 +889,14 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
while (h < maxh) {
int col = 9;
int cols = 8;
char l1[81];
char l2[81];
char l3[81];
char l4[81];
TCHAR l1[81];
TCHAR l2[81];
TCHAR l3[81];
TCHAR l4[81];
for (i = 0; i < cols && h < maxh; i++, h++, dr++) {
int cl = i * col, cl2;
int r = dr->reg;
char *sr;
TCHAR *sr;
sr = " ";
if (dr->type == DMARECORD_COPPER)
......@@ -799,11 +957,11 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
l4[cl + col - 1] = 32;
}
}
console_out ("%s\n", l1);
console_out ("%s\n", l2);
console_out ("%s\n", l3);
console_out ("%s\n", l4);
console_out ("\n");
console_out_f ("%s\n", l1);
console_out_f ("%s\n", l2);
console_out_f ("%s\n", l3);
console_out_f ("%s\n", l4);
console_out_f ("\n");
}
}
......@@ -830,186 +988,425 @@ void record_copper (uaecptr addr, int hpos, int vpos)
}
}
static int find_copper_record (uaecptr addr, unsigned int *phpos, unsigned int *pvpos)
static struct cop_rec *find_copper_records (uaecptr addr)
{
unsigned int s = curr_cop_set ^ 1;
unsigned int t = nr_cop_records[s];
unsigned int i;
int s = curr_cop_set ^ 1;
int t = nr_cop_records[s];
int i;
for (i = 0; i < t; i++) {
if (cop_record[s][i].addr == addr) {
*phpos = cop_record[s][i].hpos;
*pvpos = cop_record[s][i].vpos;
return 1;
}
if (cop_record[s][i].addr == addr)
return &cop_record[s][i];
}
return 0;
}
/* simple decode copper by Mark Cox */
static void decode_copper_insn (uae_u32 insn, uaecptr addr)
static void decode_copper_insn (FILE* file, unsigned long insn, unsigned long addr)
{
uae_u32 insn_type = insn & 0x00010001;
unsigned int hpos, vpos;
char here = ' ';
char record[] = " ";
if (find_copper_record (addr, &hpos, &vpos)) {
sprintf (record, " [%03x %03x]", vpos, hpos);
}
struct cop_rec *cr = NULL;
uae_u32 insn_type = insn & 0x00010001;
TCHAR here = ' ';
TCHAR record[] = " ";
if (get_copper_address(-1) >= addr && get_copper_address(-1) <= addr + 3)
here = '*';
if ((cr = find_copper_records (addr))) {
_stprintf (record, " [%03x %03x]", cr->vpos, cr->hpos);
}
console_out ("%c%08x: %04x %04x%s\t; ", here, addr, insn >> 16, insn & 0xFFFF, record);
if (get_copper_address (-1) >= addr && get_copper_address(-1) <= addr + 3)
here = '*';
switch (insn_type) {
case 0x00010000: /* WAIT insn */
console_out ("Wait for ");
disassemble_wait (insn);
console_out_f ("%c%08lx: %04lx %04lx%s\t; ", here, addr, insn >> 16, insn & 0xFFFF, record);
if (insn == 0xfffffffe)
console_out (" \t; End of Copperlist\n");
switch (insn_type) {
case 0x00010000: /* WAIT insn */
console_out ("Wait for ");
disassemble_wait (file, insn);
break;
if (insn == 0xfffffffe)
console_out (" \t; End of Copperlist\n");
case 0x00010001: /* SKIP insn */
console_out ("Skip if ");
disassemble_wait (insn);
break;
break;
case 0x00000000:
case 0x00000001: /* MOVE insn */
{
uae_u32 addr = (insn >> 16) & 0x1fe;
int i = 0;
while (custd[i].name) {
if (custd[i].adr == addr + 0xdff000)
break;
i++;
}
if (custd[i].name)
console_out ("%s := 0x%04x\n", custd[i].name, insn & 0xffff);
else
console_out ("%04x := 0x%04x\n", addr, insn & 0xffff);
case 0x00010001: /* SKIP insn */
console_out ("Skip if ");
disassemble_wait (file, insn);
break;
case 0x00000000:
case 0x00000001: /* MOVE insn */
{
int addr = (insn >> 16) & 0x1fe;
int i = 0;
while (custd[i].name) {
if (custd[i].adr == addr + 0xdff000)
break;
i++;
}
if (custd[i].name)
console_out_f ("%s := 0x%04lx\n", custd[i].name, insn & 0xffff);
else
console_out_f ("%04x := 0x%04lx\n", addr, insn & 0xffff);
}
break;
default:
abort ();
}
break;
default:
abort ();
}
}
static uaecptr decode_copperlist (FILE* file, uaecptr address, int nolines)
{
uae_u32 insn;
while (nolines-- > 0) {
insn = (chipmem_wget_indirect (address) << 16) | chipmem_wget_indirect (address + 2);
decode_copper_insn (file, insn, address);
address += 4;
}
return address;
/* You may wonder why I don't stop this at the end of the copperlist?
* Well, often nice things are hidden at the end and it is debatable the actual
* values that mean the end of the copperlist */
}
static uaecptr decode_copperlist (uaecptr address, unsigned int nolines)
static int copper_debugger (TCHAR **c)
{
uae_u32 insn;
while (nolines-- > 0) {
insn = get_long (address);
decode_copper_insn (insn, address);
address += 4;
}
return address;
/* You may wonder why I don't stop this at the end of the copperlist?
* Well, often nice things are hidden at the end and it is debatable the actual
* values that mean the end of the copperlist */
static uaecptr nxcopper;
uae_u32 maddr;
int lines;
if (**c == 'd') {
next_char (c);
if (debug_copper)
debug_copper = 0;
else
debug_copper = 1;
console_out_f ("Copper debugger %s.\n", debug_copper ? "enabled" : "disabled");
} else if (**c == 't') {
debug_copper = 1|2;
return 1;
} else if (**c == 'b') {
(*c)++;
debug_copper = 1|4;
if (more_params (c)) {
debug_copper_pc = readhex (c);
console_out_f ("Copper breakpoint @0x%08x\n", debug_copper_pc);
} else {
debug_copper &= ~4;
}
} else {
if (more_params (c)) {
maddr = readhex (c);
if (maddr == 1 || maddr == 2)
maddr = get_copper_address (maddr);
else if (maddr == 0)
maddr = get_copper_address (-1);
} else
maddr = nxcopper;
if (more_params (c))
lines = readhex (c);
else
lines = 20;
nxcopper = decode_copperlist (stdout, maddr, lines);
}
return 0;
}
static int copper_debugger (const char **c)
#define MAX_CHEAT_VIEW 100
struct trainerstruct {
uaecptr addr;
int size;
};
static struct trainerstruct *trainerdata;
static int totaltrainers;
static void clearcheater(void)
{
if (!trainerdata)
trainerdata = xmalloc(struct trainerstruct, MAX_CHEAT_VIEW);
memset(trainerdata, 0, sizeof (struct trainerstruct) * MAX_CHEAT_VIEW);
totaltrainers = 0;
}
static int addcheater(uaecptr addr, int size)
{
if (totaltrainers >= MAX_CHEAT_VIEW)
return 0;
trainerdata[totaltrainers].addr = addr;
trainerdata[totaltrainers].size = size;
totaltrainers++;
return 1;
}
static void listcheater(int mode, int size)
{
static uaecptr nxcopper;
uae_u32 maddr;
unsigned int lines;
int i, skip;
if (**c == 'd') {
next_char (c);
if (debug_copper)
debug_copper = 0;
if (!trainerdata)
return;
if (mode)
skip = 6;
else
debug_copper = 1;
console_out ("Copper debugger %s.\n", debug_copper ? "enabled" : "disabled");
} else if (**c == 't') {
debug_copper = 1|2;
return 1;
} else if (**c == 'b') {
(*c)++;
debug_copper = 1|4;
if (more_params (c)) {
debug_copper_pc = readhex (c);
console_out ("Copper breakpoint @0x%8.8x\n", debug_copper_pc);
skip = 8;
for(i = 0; i < totaltrainers; i++) {
struct trainerstruct *ts = &trainerdata[i];
uae_u16 b;
if (size) {
b = get_byte (ts->addr);
} else {
b = get_word (ts->addr);
}
if (mode)
console_out_f ("%08X=%04X ", ts->addr, b);
else
console_out_f ("%08X ", ts->addr);
if ((i % skip) == skip)
console_out ("\n");
}
}
static void deepcheatsearch (TCHAR **c)
{
static int first = 1;
static uae_u8 *memtmp;
static int memsize, memsize2;
uae_u8 *p1, *p2;
uaecptr addr, end;
int i, wasmodified, nonmodified;
static int size;
static int inconly, deconly, maxdiff;
int addrcnt, cnt;
TCHAR v;
v = _totupper (**c);
if(!memtmp || v == 'S') {
maxdiff = 0x10000;
inconly = 0;
deconly = 0;
size = 1;
}
if (**c)
(*c)++;
ignore_ws (c);
if ((**c) == '1' || (**c) == '2') {
size = **c - '0';
(*c)++;
}
if (more_params (c))
maxdiff = readint(c);
if (!memtmp || v == 'S') {
first = 1;
xfree (memtmp);
memsize = 0;
addr = 0xffffffff;
while ((addr = nextaddr (addr, &end)) != 0xffffffff) {
memsize += end - addr;
addr = end - 1;
}
memsize2 = (memsize + 7) / 8;
memtmp = xmalloc (uae_u8, memsize + memsize2);
if (!memtmp)
return;
memset (memtmp + memsize, 0xff, memsize2);
p1 = memtmp;
addr = 0xffffffff;
while ((addr = nextaddr (addr, &end)) != 0xffffffff) {
for (i = addr; i < end; i++)
*p1++ = get_byte (i);
addr = end - 1;
}
console_out ("Deep trainer first pass complete.\n");
return;
}
inconly = deconly = 0;
wasmodified = v == 'X' ? 0 : 1;
nonmodified = v == 'Z' ? 1 : 0;
if (v == 'I')
inconly = 1;
if (v == 'D')
deconly = 1;
p1 = memtmp;
p2 = memtmp + memsize;
addrcnt = 0;
cnt = 0;
addr = 0xffffffff;
while ((addr = nextaddr (addr, NULL)) != 0xffffffff) {
uae_s32 b, b2;
int doremove = 0;
int addroff = addrcnt >> 3;
int addrmask ;
if (size == 1) {
b = (uae_s8)get_byte (addr);
b2 = (uae_s8)p1[addrcnt];
addrmask = 1 << (addrcnt & 7);
} else {
b = (uae_s16)get_word (addr);
b2 = (uae_s16)((p1[addrcnt] << 8) | p1[addrcnt + 1]);
addrmask = 3 << (addrcnt & 7);
}
if (p2[addroff] & addrmask) {
if (wasmodified && !nonmodified) {
int diff = b - b2;
if (b == b2)
doremove = 1;
if (abs(diff) > maxdiff)
doremove = 1;
if (inconly && diff < 0)
doremove = 1;
if (deconly && diff > 0)
doremove = 1;
} else if (nonmodified && b != b2) {
doremove = 1;
} else if (!wasmodified && b != b2) {
doremove = 1;
}
if (doremove)
p2[addroff] &= ~addrmask;
else
cnt++;
}
if (size == 1) {
p1[addrcnt] = b;
addrcnt++;
} else {
p1[addrcnt] = b >> 8;
p1[addrcnt + 1] = b >> 0;
addr = nextaddr (addr, NULL);
if (addr == 0xffffffff)
break;
addrcnt += 2;
}
}
console_out_f ("%d addresses found\n", cnt);
if (cnt <= MAX_CHEAT_VIEW) {
clearcheater ();
cnt = 0;
addrcnt = 0;
addr = 0xffffffff;
while ((addr = nextaddr(addr, NULL)) != 0xffffffff) {
int addroff = addrcnt >> 3;
int addrmask = (size == 1 ? 1 : 3) << (addrcnt & 7);
if (p2[addroff] & addrmask)
addcheater (addr, size);
addrcnt += size;
cnt++;
}
if (cnt > 0)
console_out ("\n");
listcheater (1, size);
} else {
debug_copper &= ~4;
console_out ("Now continue with 'g' and use 'D' again after you have lost another life\n");
}
} else {
if (more_params (c)) {
maddr = readhex (c);
if (maddr == 1 || maddr == 2)
maddr = get_copper_address (maddr);
else if (maddr == 0)
maddr = get_copper_address (-1);
} else
maddr = nxcopper;
}
/* cheat-search by Toni Wilen (originally by Holger Jakob) */
static void cheatsearch (TCHAR **c)
{
static uae_u8 *vlist;
static int listsize;
static int first = 1;
static int size = 1;
uae_u32 val, memcnt, prevmemcnt;
int i, count, vcnt, memsize;
uaecptr addr, end;
memsize = 0;
addr = 0xffffffff;
while ((addr = nextaddr (addr, &end)) != 0xffffffff) {
memsize += end - addr;
addr = end - 1;
}
if (_totupper (**c) == 'L') {
listcheater (1, size);
return;
}
ignore_ws (c);
if (!more_params (c)) {
first = 1;
console_out ("Search reset\n");
xfree (vlist);
listsize = memsize;
vlist = xcalloc (uae_u8, listsize >> 3);
return;
}
val = readint (c);
if (first) {
if (val > 255)
size = 2;
if (val > 65535)
size = 3;
if (val > 16777215)
size = 4;
}
ignore_ws (c);
if (more_params (c))
lines = readhex (c);
else
lines = 20;
nxcopper = decode_copperlist (maddr, lines);
}
return 0;
}
/* cheat-search by Holger Jakob */
static void cheatsearch (const char **c)
{
uae_u8 *p = get_real_address (0);
static uae_u32 *vlist = NULL;
uae_u32 ptr;
uae_u32 val = 0;
uae_u32 type = 0; /* not yet */
uae_u32 count = 0;
uae_u32 fcount = 0;
uae_u32 full = 0;
ignore_ws (c);
val = readhex (c);
if (vlist == NULL) {
vlist = malloc (256 * 4);
if (vlist != 0) {
for (count = 0; count < 255; count++)
vlist[count] = 0;
count = 0;
for (ptr = 0; ptr < allocated_chipmem - 40; ptr += 2, p += 2) {
if (ptr >= 0x438 && p[3] == (val & 0xff)
&& p[2] == (val >> 8 & 0xff)
&& p[1] == (val >> 16 & 0xff)
&& p[0] == (val >> 24 & 0xff))
{
if (count < 255) {
vlist[count++]=ptr;
console_out ("%08x: %x%x%x%x\n",ptr,p[0],p[1],p[2],p[3]);
} else
full = 1;
size = readint (c);
if (size > 4)
size = 4;
if (size < 1)
size = 1;
if (vlist == NULL) {
listsize = memsize;
vlist = xcalloc (uae_u8, listsize >> 3);
}
count = 0;
vcnt = 0;
clearcheater ();
addr = 0xffffffff;
prevmemcnt = memcnt = 0;
while ((addr = nextaddr (addr, &end)) != 0xffffffff) {
if (addr + size < end) {
for (i = 0; i < size; i++) {
int shift = (size - i - 1) * 8;
if (get_byte (addr + i) != ((val >> shift) & 0xff))
break;
}
if (i == size) {
int voffset = memcnt >> 3;
int vmask = 1 << (memcnt & 7);
if (!first) {
while (prevmemcnt < memcnt) {
vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
prevmemcnt++;
}
if (vlist[voffset] & vmask) {
count++;
addcheater(addr, size);
} else {
vlist[voffset] &= ~vmask;
}
prevmemcnt = memcnt + 1;
} else {
vlist[voffset] |= vmask;
count++;
}
}
}
}
console_out ("Found %d possible addresses with %d\n",count,val);
console_out ("Now continue with 'g' and use 'C' with a different value\n");
}
} else {
for (count = 0; count<255; count++) {
if (p[vlist[count]+3] == (val & 0xff)
&& p[vlist[count]+2] == (val>>8 & 0xff)
&& p[vlist[count]+1] == (val>>16 & 0xff)
&& p[vlist[count]] == (val>>24 & 0xff))
{
fcount++;
console_out ("%08x: %x%x%x%x\n", vlist[count], p[vlist[count]],
p[vlist[count]+1], p[vlist[count]+2], p[vlist[count]+3]);
}
}
console_out ("%d hits of %d found\n",fcount,val);
free (vlist);
vlist = NULL;
}
memcnt++;
}
if (!first) {
while (prevmemcnt < memcnt) {
vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
prevmemcnt++;
}
listcheater (0, size);
}
console_out_f ("Found %d possible addresses with 0x%X (%u) (%d bytes)\n", count, val, val, size);
if (count > 0)
console_out ("Now continue with 'g' and use 'C' with a different value\n");
first = 0;
}
struct breakpoint_node bpnodes[BREAKPOINT_TOTAL];
......@@ -1119,17 +1516,17 @@ static void illg_debug_do (uaecptr addr, int rwi, int size, uae_u32 val)
illg_debug_check (ad, rwi, size, val);
} else if ((mask & 3) == 0) {
if (rwi & 2)
console_out ("W: %08X=%02X PC=%08X\n", ad, v, pc);
console_out_f ("W: %08X=%02X PC=%08X\n", ad, v, pc);
else if (rwi & 1)
console_out ("R: %08X PC=%08X\n", ad, pc);
console_out_f ("R: %08X PC=%08X\n", ad, pc);
if (illgdebug_break)
activate_debugger ();
} else if (!(mask & 1) && (rwi & 1)) {
console_out ("RO: %08X=%02X PC=%08X\n", ad, v, pc);
console_out_f ("RO: %08X=%02X PC=%08X\n", ad, v, pc);
if (illgdebug_break)
activate_debugger ();
} else if (!(mask & 2) && (rwi & 2)) {
console_out ("WO: %08X PC=%08X\n", ad, pc);
console_out_f ("WO: %08X PC=%08X\n", ad, pc);
if (illgdebug_break)
activate_debugger ();
}
......@@ -1181,7 +1578,7 @@ static void smc_detect_init (TCHAR **c)
initialize_memwatch (0);
if (v)
smc_mode = 1;
console_out ("SMCD enabled. Break=%d\n", smc_mode);
console_out_f ("SMCD enabled. Break=%d\n", smc_mode);
}
#define SMC_MAXHITS 8
......@@ -1223,12 +1620,12 @@ static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp)
}
if (hitcnt < 100) {
smc_table[hitaddr].cnt++;
console_out ("SMC at %08X - %08X (%d) from %08X\n",
console_out_f ("SMC at %08X - %08X (%d) from %08X\n",
hitaddr, hitaddr + hitcnt, hitcnt, hitpc);
if (smc_mode)
activate_debugger ();
if (smc_table[hitaddr].cnt >= SMC_MAXHITS)
console_out ("* hit count >= %d, future hits ignored\n", SMC_MAXHITS);
console_out_f ("* hit count >= %d, future hits ignored\n", SMC_MAXHITS);
}
}
......@@ -1535,23 +1932,27 @@ struct membank_store
static struct membank_store *membank_stores;
static void deinitialize_memwatch (void)
static int deinitialize_memwatch (void)
{
unsigned int i;
int i, oldmode;
if (!memwatch_enabled)
return;
for (i = 0; i < 256; i++) {
addrbank *a1 = debug_mem_banks[i];
addrbank *a2 = mem_banks[i];
memcpy (a2, a1, sizeof (addrbank));
free (a1);
}
free (debug_mem_banks);
debug_mem_banks = 0;
memwatch_enabled = 0;
free (illgdebug);
illgdebug = 0;
if (!memwatch_enabled && !mmu_enabled)
return -1;
for (i = 0; membank_stores[i].addr; i++) {
memcpy (membank_stores[i].addr, &membank_stores[i].store, sizeof (addrbank));
}
oldmode = mmu_enabled ? 1 : 0;
xfree (debug_mem_banks);
debug_mem_banks = NULL;
xfree (debug_mem_area);
debug_mem_area = NULL;
xfree (membank_stores);
membank_stores = NULL;
memwatch_enabled = 0;
mmu_enabled = 0;
xfree (illgdebug);
illgdebug = 0;
return oldmode;
}
static void initialize_memwatch (int mode)
......@@ -1601,7 +2002,7 @@ static void initialize_memwatch (int mode)
}
int debug_bankchange (int mode)
{/*
{
if (mode == -1) {
int v = deinitialize_memwatch ();
if (v < 0)
......@@ -1611,87 +2012,110 @@ int debug_bankchange (int mode)
if (mode >= 0)
initialize_memwatch (mode);
return -1;
*/}
}
void memwatch_dump2 (TCHAR *buf, int bufsize, int num)
{
int i;
struct memwatch_node *mwn;
if (buf)
memset (buf, 0, bufsize);
for (i = 0; i < MEMWATCH_TOTAL; i++) {
if ((num >= 0 && num == i) || (num < 0)) {
mwn = &mwnodes[i];
if (mwn->size == 0)
continue;
buf = buf_out (buf, &bufsize, "%d: %08X - %08X (%d) %c%c%c",
i, mwn->addr, mwn->addr + (mwn->size - 1), mwn->size,
(mwn->rwi & 1) ? 'R' : ' ', (mwn->rwi & 2) ? 'W' : ' ', (mwn->rwi & 4) ? 'I' : ' ');
if (mwn->frozen)
buf = buf_out (buf, &bufsize, "F");
if (mwn->val_enabled)
buf = buf_out (buf, &bufsize, " =%X", mwn->val);
if (mwn->modval_written)
buf = buf_out (buf, &bufsize, " =M");
if (mwn->mustchange)
buf = buf_out (buf, &bufsize, " C");
buf = buf_out (buf, &bufsize, "\n");
}
}
}
static void memwatch_dump (int num)
{
unsigned int i;
const struct memwatch_node *mwn;
for (i = 0; i < MEMWATCH_TOTAL; i++) {
if ((num >= 0 && num == (int)i) || (num < 0)) {
mwn = &mwnodes[i];
if (mwn->size == 0)
continue;
console_out ("%d: %8.8X - %8.8X (%d) %s",
i, mwn->addr, mwn->addr + (mwn->size - 1), mwn->size,
mwn->rwi == 0 ? "R" : (mwn->rwi == 1 ? "W" : "RW"));
if (mwn->val_enabled)
console_out (" =%X", mwn->val);
if (mwn->modval_written)
console_out (" =M");
console_out ("\n");
}
}
}
static void memwatch (const char **c)
{
int num;
struct memwatch_node *mwn;
char nc;
if (!memwatch_enabled) {
TCHAR *buf;
int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
buf = xmalloc (TCHAR, 50 * multiplier);
if (!buf)
return;
memwatch_dump2 (buf, 50 * multiplier, num);
//f_out (stdout, "%s", buf);
xfree (buf);
}
static void memwatch (TCHAR **c)
{
int num;
struct memwatch_node *mwn;
TCHAR nc;
if (!memwatch_enabled) {
initialize_memwatch (0);
console_out ("Memwatch breakpoints enabled\n");
}
}
ignore_ws (c);
if (!more_params (c)) {
memwatch_dump (-1);
return;
}
nc = next_char (c);
if (nc == '-') {
deinitialize_memwatch ();
console_out ("Memwatch breakpoints disabled\n");
return;
}
if (nc == 'd') {
if (illgdebug) {
ignore_ws (c);
if (more_params (c)) {
uae_u32 addr = readhex (c);
uae_u32 len = 1;
if (more_params (c))
len = readhex (c);
write_log ("cleared logging addresses %8.8X - %8.8X\n", addr, addr + len);
while (len > 0) {
addr &= 0xffffff;
illgdebug[addr] = 0;
addr++;
len--;
ignore_ws (c);
if (!more_params (c)) {
memwatch_dump (-1);
return;
}
nc = next_char (c);
if (nc == '-') {
deinitialize_memwatch ();
console_out ("Memwatch breakpoints disabled\n");
return;
}
if (nc == 'd') {
if (illgdebug) {
ignore_ws (c);
if (more_params (c)) {
uae_u32 addr = readhex (c);
uae_u32 len = 1;
if (more_params (c))
len = readhex (c);
console_out_f ("Cleared logging addresses %08X - %08X\n", addr, addr + len);
while (len > 0) {
addr &= 0xffffff;
illgdebug[addr] = 7;
addr++;
len--;
}
} else {
illg_free();
console_out ("Illegal memory access logging disabled\n");
}
} else {
illg_init ();
ignore_ws (c);
illgdebug_break = 0;
if (more_params (c))
illgdebug_break = 1;
console_out_f ("Illegal memory access logging enabled. Break=%d\n", illgdebug_break);
}
}
} else {
illg_init ();
console_out ("Illegal memory access logging enabled\n");
ignore_ws (c);
illgdebug_break = 0;
if (more_params (c))
illgdebug_break = 1;
return;
}
num = nc - '0';
if (num < 0 || num >= MEMWATCH_TOTAL)
return;
mwn = &mwnodes[num];
mwn->size = 0;
ignore_ws (c);
if (!more_params (c)) {
console_out_f ("Memwatch %d removed\n", num);
return;
}
return;
}
num = nc - '0';
if (num < 0 || num >= MEMWATCH_TOTAL)
return;
mwn = &mwnodes[num];
mwn->size = 0;
ignore_ws (c);
if (!more_params (c)) {
console_out ("Memwatch %d removed\n", num);
return;
}
mwn->addr = readhex (c);
mwn->size = 1;
mwn->rwi = 7;
......@@ -1704,18 +2128,29 @@ static void memwatch (const char **c)
mwn->size = readhex (c);
ignore_ws (c);
if (more_params (c)) {
char nc = toupper (next_char (c));
if (nc == 'W')
mwn->rwi = 1;
else if (nc == 'R' && toupper (**c) != 'W')
mwn->rwi = 0;
else if (nc == 'R' && toupper (**c) == 'W')
next_char (c);
ignore_ws (c);
if (more_params (c)) {
if (toupper (**c) == 'M') {
mwn->modval_written = 1;
} else if (toupper (**c) == 'C') {
for (;;) {
TCHAR ncc = peek_next_char(c);
TCHAR nc = _totupper (next_char (c));
if (mwn->rwi == 7)
mwn->rwi = 0;
if (nc == 'F')
mwn->frozen = 1;
if (nc == 'W')
mwn->rwi |= 2;
if (nc == 'I')
mwn->rwi |= 4;
if (nc == 'R')
mwn->rwi |= 1;
if (ncc == ' ')
break;
if (!more_params(c))
break;
}
ignore_ws (c);
if (more_params (c)) {
if (_totupper (**c) == 'M') {
mwn->modval_written = 1;
} else if (_totupper (**c) == 'C') {
mwn->mustchange = 1;
} else {
mwn->val = readhex (c);
......@@ -1729,11 +2164,11 @@ static void memwatch (const char **c)
memwatch_dump (num);
}
static void writeintomem (const char **c)
static void writeintomem (TCHAR **c)
{
uae_u32 addr = 0;
uae_u32 val = 0;
char cc;
TCHAR cc;
int len = 1;
ignore_ws(c);
......@@ -1760,7 +2195,7 @@ static void writeintomem (const char **c)
put_byte (addr, val);
cc = 'B';
}
console_out ("Wrote %X (%u) at %08X.%c\n", val, val, addr, cc);
console_out_f ("Wrote %X (%u) at %08X.%c\n", val, val, addr, cc);
}
static uae_u8 *dump_xlate (uae_u32 addr)
......@@ -1775,7 +2210,7 @@ static void memory_map_dump_2 (int log)
bool imold;
int i, j, max;
addrbank *a1 = mem_banks[0];
char txt[256];
TCHAR txt[256];
imold = currprefs.illegal_mem;
currprefs.illegal_mem = false;
......@@ -1787,10 +2222,10 @@ static void memory_map_dump_2 (int log)
a2 = mem_banks[i];
if (a1 != a2) {
int k, mirrored, size, size_out;
char size_ext;
TCHAR size_ext;
uae_u8 *caddr;
char *name;
char tmp[MAX_DPATH];
TCHAR *name;
TCHAR tmp[MAX_DPATH];
name = a1->name;
if (name == NULL)
......@@ -1817,7 +2252,7 @@ static void memory_map_dump_2 (int log)
tmp[0] = 0;
if (a1->flags == ABFLAG_ROM && mirrored) {
char *p = txt + _tcslen (txt);
TCHAR *p = txt + _tcslen (txt);
uae_u32 crc = get_crc32 (a1->xlateaddr(j << 16), (size * 1024) / mirrored);
struct romdata *rd = getromdatabycrc (crc);
_stprintf (p, " (%08X)", crc);
......@@ -1853,21 +2288,36 @@ STATIC_INLINE uaecptr BPTR2APTR (uaecptr addr)
{
return addr << 2;
}
/*static TCHAR *BSTR2CSTR (uae_u8 *bstr)
{
TCHAR *s;
char *cstr = xmalloc (char, bstr[0] + 1);
if (cstr) {
memcpy (cstr, bstr + 1, bstr[0]);
cstr[bstr[0]] = 0;
}
s = au (cstr);
xfree (cstr);
return s;
}*/
static void print_task_info (uaecptr node)
{
char *s;
TCHAR *s;
int process = get_byte (node + 8) == 13 ? 1 : 0;
console_out ("%08X: ", node);
console_out (process ? " PROCESS '%s'" : " TASK '%s'\n", ((char*)get_real_address (get_long (node + 10))));
console_out_f ("%08X: ", node);
s = ((char*)get_real_address (get_long (node + 10)));
console_out_f (process ? " PROCESS '%s'" : " TASK '%s'\n", s);
xfree (s);
if (process) {
uaecptr cli = BPTR2APTR (get_long (node + 172));
int tasknum = get_long (node + 140);
if (cli && tasknum) {
uae_u8 *command_bstr = get_real_address (BPTR2APTR (get_long (cli + 16)));
console_out (" [%d, '%s']\n", tasknum, command_bstr);
xfree (command_bstr);
//TCHAR *command = BSTR2CSTR (command_bstr);
console_out_f (" [%d, '%s']\n", tasknum, command_bstr);
//xfree (command);
} else {
console_out ("\n");
}
......@@ -1880,11 +2330,11 @@ static void show_exec_tasks (void)
uaecptr taskready = get_long (execbase + 406);
uaecptr taskwait = get_long (execbase + 420);
uaecptr node, end;
console_out ("Execbase at 0x%08X\n", execbase);
console_out_f ("Execbase at 0x%08X\n", execbase);
console_out ("Current:\n");
node = get_long (execbase + 276);
print_task_info (node);
console_out ("Ready:\n");
console_out_f ("Ready:\n");
node = get_long (taskready);
end = get_long (taskready + 4);
while (node) {
......@@ -1900,12 +2350,12 @@ static void show_exec_tasks (void)
}
}
static void show_exec_lists (char t)
static void show_exec_lists (TCHAR t)
{
uaecptr execbase = get_long (4);
uaecptr list = 0, node;
switch (toupper (t))
switch (_totupper (t))
{
case 'R':
list = execbase + 336;
......@@ -1921,7 +2371,7 @@ static void show_exec_lists (char t)
return;
node = get_long (list);
while (get_long (node)) {
console_out ("%08x %s\n", node, ((char*)get_real_address (get_long (node + 10))));
console_out_f ("%08x %s\n", node, ((char*)get_real_address (get_long (node + 10))));
node = get_long (node);
}
}
......@@ -1933,13 +2383,13 @@ static struct regstruct trace_prev_regs;
#endif
static uaecptr nextpc;
int instruction_breakpoint (const char **c)
int instruction_breakpoint (TCHAR **c)
{
struct breakpoint_node *bpn;
int i;
if (more_params (c)) {
char nc = toupper ((*c)[0]);
TCHAR nc = _totupper ((*c)[0]);
if (nc == 'S') {
next_char (c);
sr_bpvalue = sr_bpmask = 0;
......@@ -1949,7 +2399,7 @@ int instruction_breakpoint (const char **c)
if (more_params (c))
sr_bpmask = readhex (c);
}
console_out ("SR breakpoint, value=%04X, mask=%04X\n", sr_bpvalue, sr_bpmask);
console_out_f ("SR breakpoint, value=%04X, mask=%04X\n", sr_bpvalue, sr_bpmask);
return 0;
} else if (nc == 'I') {
next_char (c);
......@@ -1971,7 +2421,7 @@ int instruction_breakpoint (const char **c)
bpn = &bpnodes[i];
if (!bpn->enabled)
continue;
console_out ("%8X ", bpn->addr);
console_out_f ("%8X ", bpn->addr);
got = 1;
}
if (!got)
......@@ -2022,11 +2472,31 @@ int instruction_breakpoint (const char **c)
return 1;
}
static void savemem (char **cc)
static int process_breakpoint(TCHAR **c)
{
processptr = 0;
xfree (processname);
processname = NULL;
if (!more_params (c))
return 0;
if (**c == '\"') {
TCHAR pn[200];
next_string (c, pn, 200, 0);
processname = ua (pn);
} else {
processptr = readhex (c);
}
do_skip = 1;
skipaddr_doskip = 1;
skipaddr_start = 0;
return 1;
}
static void savemem (TCHAR **cc)
{
uae_u8 b;
uae_u32 src, src2, len, len2;
char *name;
TCHAR *name;
FILE *fp;
if (!more_params (cc))
......@@ -2046,9 +2516,9 @@ static void savemem (char **cc)
if (!more_params (cc))
goto S_argh;
len2 = len = readhex (cc);
fp = fopen (name, "wb");
fp = _tfopen (name, "wb");
if (fp == NULL) {
console_out ("Couldn't open file '%s'\n", name);
console_out_f ("Couldn't open file '%s'\n", name);
return;
}
while (len > 0) {
......@@ -2062,19 +2532,19 @@ static void savemem (char **cc)
}
fclose (fp);
if (len == 0)
console_out ("Wrote %08X - %08X (%d bytes) to '%s'\n",
src2, src2 + len2 - 1, len2, name);
console_out_f ("Wrote %08X - %08X (%d bytes) to '%s'\n",
src2, src2 + len2, len2, name);
return;
S_argh:
console_out ("S-command needs more arguments!\n");
}
static void searchmem (const char **cc)
static void searchmem (TCHAR **cc)
{
int i, sslen, got, val, stringmode;
uae_u8 ss[256];
uae_u32 addr, endaddr;
char nc;
TCHAR nc;
got = 0;
sslen = 0;
......@@ -2093,7 +2563,7 @@ static void searchmem (const char **cc)
for (;;) {
if (**cc == 32 || **cc == 0)
break;
nc = toupper (next_char (cc));
nc = _totupper (next_char (cc));
if (isspace (nc))
break;
if (isdigit(nc))
......@@ -2105,7 +2575,7 @@ static void searchmem (const char **cc)
val *= 16;
if (**cc == 32 || **cc == 0)
break;
nc = toupper (next_char (cc));
nc = _totupper (next_char (cc));
if (isspace (nc))
break;
if (isdigit(nc))
......@@ -2127,7 +2597,7 @@ static void searchmem (const char **cc)
if (more_params (cc))
endaddr = readhex (cc);
}
console_out ("Searching from %08x to %08x..\n", addr, endaddr);
console_out_f ("Searching from %08X to %08X..\n", addr, endaddr);
while ((addr = nextaddr (addr, NULL)) != 0xffffffff) {
if (addr == endaddr)
break;
......@@ -2143,7 +2613,7 @@ static void searchmem (const char **cc)
}
if (i == sslen) {
got++;
console_out (" %08x", addr);
console_out_f (" %08X", addr);
if (got > 100) {
console_out ("\nMore than 100 results, aborting..");
break;
......@@ -2156,9 +2626,9 @@ static void searchmem (const char **cc)
}
#ifdef SAVESTATE
static int staterecorder (const char **cc)
static int staterecorder (TCHAR **cc)
{
char nc;
TCHAR nc;
if (!more_params (cc)) {
if (savestate_dorewind (1)) {
......@@ -2181,16 +2651,204 @@ static const TCHAR *debugtest_names[] = {
"Blitter", "Keyboard", "Floppy"
};
static void disk_debug (const char **inptr)
void debugtest (enum debugtest_item di, const TCHAR *format, ...)
{
va_list parms;
TCHAR buffer[1000];
if (!debugtest_modes[di])
return;
va_start (parms, format);
_vsntprintf (buffer, 1000 - 1, format, parms);
va_end (parms);
write_log ("%s PC=%08X: %s\n", debugtest_names[di], M68K_GETPC, buffer);
if (debugtest_modes[di] == 2)
activate_debugger ();
}
static void debugtest_set (TCHAR **inptr)
{
char parm[10];
int i, val, val2;
ignore_ws (inptr);
val2 = 1;
if (!more_params (inptr)) {
for (i = 0; i < DEBUGTEST_MAX; i++)
debugtest_modes[i] = 0;
console_out ("All debugtests disabled\n");
return;
}
val = readint (inptr);
if (more_params (inptr)) {
val2 = readint (inptr);
if (val2 > 0)
val2 = 2;
}
if (val < 0) {
for (i = 0; i < DEBUGTEST_MAX; i++)
debugtest_modes[i] = val2;
console_out ("All debugtests enabled\n");
return;
}
if (val >= 0 && val < DEBUGTEST_MAX) {
if (debugtest_modes[val])
debugtest_modes[val] = 0;
else
debugtest_modes[val] = val2;
console_out_f ("Debugtest '%s': %s. break = %s\n",
debugtest_names[val], debugtest_modes[val] ? "on" :L"off", val2 == 2 ? "on" : "off");
}
}
static void debug_sprite (TCHAR **inptr)
{
uaecptr saddr, addr, addr2;
int xpos, xpos_ecs;
int ypos, ypos_ecs;
int ypose, ypose_ecs;
int attach;
uae_u64 w1, w2, ww1, ww2;
int size = 1, width;
int ecs, sh10;
int y, i;
TCHAR tmp[80];
int max = 2;
addr2 = 0;
ignore_ws (inptr);
addr = readhex (inptr);
ignore_ws (inptr);
if (more_params (inptr))
size = readhex (inptr);
if (size != 1 && size != 2 && size != 4) {
addr2 = size;
ignore_ws (inptr);
if (more_params (inptr))
size = readint (inptr);
if (size != 1 && size != 2 && size != 4)
size = 1;
}
for (;;) {
ecs = 0;
sh10 = 0;
saddr = addr;
width = size * 16;
w1 = get_word (addr);
w2 = get_word (addr + size * 2);
console_out_f (" %06X ", addr);
for (i = 0; i < size * 2; i++)
console_out_f ("%04X ", get_word (addr + i * 2));
console_out_f ("\n");
ypos = w1 >> 8;
xpos = w1 & 255;
ypose = w2 >> 8;
attach = (w2 & 0x80) ? 1 : 0;
if (w2 & 4)
ypos |= 256;
if (w2 & 2)
ypose |= 256;
ypos_ecs = ypos;
ypose_ecs = ypose;
if (w2 & 0x40)
ypos_ecs |= 512;
if (w2 & 0x20)
ypose_ecs |= 512;
xpos <<= 1;
if (w2 & 0x01)
xpos |= 1;
xpos_ecs = xpos << 2;
if (w2 & 0x10)
xpos_ecs |= 2;
if (w2 & 0x08)
xpos_ecs |= 1;
if (w2 & (0x40 | 0x20 | 0x10 | 0x08))
ecs = 1;
if (w1 & 0x80)
sh10 = 1;
if (ypose < ypos)
ypose += 256;
for (y = ypos; y < ypose; y++) {
int x;
addr += size * 4;
if (addr2)
addr2 += size * 4;
if (size == 1) {
w1 = get_word (addr);
w2 = get_word (addr + 2);
if (addr2) {
ww1 = get_word (addr2);
ww2 = get_word (addr2 + 2);
}
} else if (size == 2) {
w1 = get_long (addr);
w2 = get_long (addr + 4);
if (addr2) {
ww1 = get_long (addr2);
ww2 = get_long (addr2 + 4);
}
} else if (size == 4) {
w1 = get_long (addr) << 16;
w2 = get_long (addr + 4) << 16;
w1 <<= 16;
w2 <<= 16;
w1 |= get_long (addr);
w2 |= get_long (addr2 + 4);
if (addr2) {
ww1 = get_long (addr2) << 16;
ww2 = get_long (addr2 + 4) << 16;
ww1 <<= 16;
ww2 <<= 16;
ww1 |= get_long (addr2);
ww2 |= get_long (addr2 + 4);
}
}
width = size * 16;
for (x = 0; x < width; x++) {
int v1 = (w1 >> (width - x)) & 1;
int v2 = (w2 >> (width - x)) & 1;
int v = v1 * 2 + v2;
if (addr2) {
int vv1 = (ww1 >> (width - x)) & 1;
int vv2 = (ww2 >> (width - x)) & 1;
int vv = vv1 * 2 + vv2;
v *= 4;
v += vv;
tmp[x] = v >= 10 ? 'A' + v - 10 : v + '0';
} else {
tmp[x] = v + '0';
}
}
tmp[width] = 0;
console_out_f ("%3d %06X %s\n", y, addr, tmp);
}
console_out_f ("Sprite address %08X, width = %d\n", saddr, size * 16);
console_out_f ("OCS: StartX=%d StartY=%d EndY=%d\n", xpos, ypos, ypose);
console_out_f ("ECS: StartX=%d (%d.%d) StartY=%d EndY=%d%s\n", xpos_ecs, xpos_ecs / 4, xpos_ecs & 3, ypos_ecs, ypose_ecs, ecs ? " (*)" : "");
console_out_f ("Attach: %d. AGA SSCAN/SH10 bit: %d\n", attach, sh10);
addr += size * 4;
if (get_word (addr) == 0 && get_word (addr + size * 4) == 0)
break;
max--;
if (max <= 0)
break;
}
}
static void disk_debug (TCHAR **inptr)
{
TCHAR parm[10];
unsigned int i;
if (**inptr == 'd') {
(*inptr)++;
ignore_ws (inptr);
disk_debug_logging = readint (inptr);
console_out ("Disk logging level %d\n", disk_debug_logging);
console_out_f ("Disk logging level %d\n", disk_debug_logging);
return;
}
disk_debug_mode = 0;
......@@ -2198,7 +2856,7 @@ static void disk_debug (const char **inptr)
ignore_ws (inptr);
if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
goto end;
for (i = 0; i < strlen (parm); i++) {
for (i = 0; i < _tcslen(parm); i++) {
if (parm[i] == 'R')
disk_debug_mode |= DISK_DEBUG_DMA_READ;
if (parm[i] == 'W')
......@@ -2213,14 +2871,14 @@ static void disk_debug (const char **inptr)
if (disk_debug_logging == 0)
disk_debug_logging = 1;
end:
console_out ("Disk breakpoint mode %c%c%c track %d\n",
console_out_f ("Disk breakpoint mode %c%c%c track %d\n",
disk_debug_mode & DISK_DEBUG_DMA_READ ? 'R' : '-',
disk_debug_mode & DISK_DEBUG_DMA_WRITE ? 'W' : '-',
disk_debug_mode & DISK_DEBUG_PIO ? 'P' : '-',
disk_debug_track);
}
static void find_ea (char **inptr)
static void find_ea (TCHAR **inptr)
{
uae_u32 ea, sea, dea;
uaecptr addr, end;
......@@ -2234,7 +2892,7 @@ static void find_ea (char **inptr)
if (more_params(inptr))
end = readhex (inptr);
}
console_out ("Searching from %08X to %08X\n", addr, end);
console_out_f ("Searching from %08X to %08X\n", addr, end);
while((addr = nextaddr(addr, &end)) != 0xffffffff) {
if ((addr & 1) == 0 && addr + 6 <= end) {
sea = 0xffffffff;
......@@ -2252,19 +2910,19 @@ static void find_ea (char **inptr)
}
}
static void m68k_modify (const char **inptr)
static void m68k_modify (TCHAR **inptr)
{
uae_u32 v;
char parm[10];
unsigned char c1, c2;
TCHAR parm[10];
TCHAR c1, c2;
int i;
if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
return;
c1 = toupper (parm[0]);
c1 = _totupper (parm[0]);
c2 = 99;
if (c1 == 'A' || c1 == 'D' || c1 == 'P') {
c2 = toupper (parm[1]);
c2 = _totupper (parm[1]);
if (isdigit (c2))
c2 -= '0';
else
......@@ -2302,7 +2960,7 @@ static void m68k_modify (const char **inptr)
static void debug_1 (void)
{
char input[MAX_LINEWIDTH];
TCHAR input[MAX_LINEWIDTH];
uaecptr nxdis, nxmem, addr;
m68k_dumpstate (stdout, &nextpc);
......@@ -2310,8 +2968,7 @@ static void debug_1 (void)
debugger_active = 1;
for (;;) {
char cmd;
const char *inptr;
TCHAR cmd, *inptr;
int v;
if (!debugger_active)
......@@ -2351,7 +3008,7 @@ static void debug_1 (void)
}
break;
}
case 'e': dump_custom_regs (); break;
case 'e': dump_custom_regs (tolower(*inptr) == 'a'); break;
case 'r':
{
if (more_params(&inptr))
......@@ -2360,7 +3017,7 @@ static void debug_1 (void)
m68k_dumpstate (stdout, &nextpc);
}
break;
//case 'D': deepcheatsearch (&inptr); break;
case 'D': deepcheatsearch (&inptr); break;
case 'C': cheatsearch (&inptr); break;
case 'W': writeintomem (&inptr); break;
case 'w': memwatch (&inptr); break;
......@@ -2368,157 +3025,293 @@ static void debug_1 (void)
case 's':
if (*inptr == 'c') {
;//screenshot (1, 1);
} else if (*inptr == 'p') {
inptr++;
debug_sprite (&inptr);
} else if (*inptr == 'm') {
next_char (&inptr);
if (more_params (&inptr))
debug_sprite_mask = readint (&inptr);
console_out ("sprite mask: %2.2X\n", debug_sprite_mask);
} else {
searchmem (&inptr);
}
break;
case 'd':
{
if (*inptr == 'i') {
next_char (&inptr);
disk_debug (&inptr);
} else {
uae_u32 daddr;
int count;
if (more_params (&inptr))
daddr = readhex (&inptr);
else
daddr = nxdis;
if (more_params (&inptr))
count = readhex (&inptr);
else
count = 10;
m68k_disasm (stdout, daddr, &nxdis, count);
}
}
break;
case 'T': show_exec_tasks (); break;
case 't':
if (more_params (&inptr))
skipaddr_doskip = readint (&inptr);
if (skipaddr_doskip <= 0 || skipaddr_doskip > 10000)
skipaddr_doskip = 1;
set_special (SPCFLAG_BRK);
exception_debugging = 1;
return;
case 'z':
skipaddr_start = nextpc;
skipaddr_doskip = 1;
do_skip = 1;
exception_debugging = 1;
return;
case 'f':
if (instruction_breakpoint (&inptr))
return;
break;
if (*(inptr + 1) == 'c') {
next_char (&inptr);
next_char (&inptr);
if (!smc_table)
smc_detect_init (&inptr);
else
smc_free ();
}
} else {
searchmem (&inptr);
}
break;
case 'd':
{
if (*inptr == 'i') {
next_char (&inptr);
disk_debug (&inptr);
} else if (*inptr == 'j') {
inptr++;
inputdevice_logging = 1 | 2;
if (more_params (&inptr))
inputdevice_logging = readint(&inptr);
console_out_f ("Input logging level %d\n", inputdevice_logging);
} else if (*inptr == 'm') {
memory_map_dump_2 (0);
} else if (*inptr == 't') {
next_char (&inptr);
debugtest_set (&inptr);
#ifdef _WIN32
} else if (*inptr == 'g') {
extern void update_disassembly (uae_u32);
next_char (&inptr);
if (more_params (&inptr))
update_disassembly (readhex (&inptr));
#endif
} else {
uae_u32 daddr;
int count;
if (more_params (&inptr))
daddr = readhex (&inptr);
else
daddr = nxdis;
if (more_params (&inptr))
count = readhex (&inptr);
else
count = 10;
m68k_disasm (stdout, daddr, &nxdis, count);
}
}
break;
case 'T':
if (inptr[0] == 't' || inptr[0] == 0)
show_exec_tasks ();
else
show_exec_lists (inptr[0]);
break;
case 't':
no_trace_exceptions = 0;
if (*inptr != 't') {
if (more_params (&inptr))
skipaddr_doskip = readint (&inptr);
if (skipaddr_doskip <= 0 || skipaddr_doskip > 10000)
skipaddr_doskip = 1;
} else {
no_trace_exceptions = 1;
}
set_special (SPCFLAG_BRK);
exception_debugging = 1;
return;
case 'z':
skipaddr_start = nextpc;
skipaddr_doskip = 1;
do_skip = 1;
exception_debugging = 1;
return;
case 'q': uae_quit();
debugger_active = 0;
debugging = 0;
return;
case 'f':
if (inptr[0] == 'a') {
next_char(&inptr);
find_ea (&inptr);
} else if (inptr[0] == 'p') {
inptr++;
if (process_breakpoint(&inptr))
return;
} else {
if (instruction_breakpoint (&inptr))
return;
}
break;
case 'g':
if (more_params (&inptr)) {
m68k_setpc (readhex (&inptr));
fill_prefetch_slow ();
}
debugger_active = 0;
debugging = 0;
exception_debugging = 0;
return;
case 'q':
uae_quit();
deactivate_debugger();
return;
case 'H':
{
unsigned int count, temp, badly;
uae_u32 oldpc = m68k_getpc ();
struct regstruct save_regs = regs;
badly = 0;
if (inptr[0] == 'H') {
badly = 1;
inptr++;
}
if (more_params (&inptr))
count = readhex (&inptr);
else
count = 10;
temp = lasthist;
while (count-- > 0 && temp != firsthist) {
if (temp == 0)
temp = MAX_HIST - 1;
else
temp--;
}
while (temp != lasthist) {
regs = history[temp];
m68k_setpc (history[temp].pc);
if (badly) {
m68k_dumpstate (stdout, NULL);
} else {
m68k_disasm (stdout, history[temp].pc, NULL, 1);
}
if (++temp == MAX_HIST)
temp = 0;
}
regs = save_regs;
m68k_setpc (oldpc);
}
break;
case 'm':
{
uae_u32 maddr; int lines;
if (more_params (&inptr))
maddr = readhex (&inptr);
else
maddr = nxmem;
if (more_params (&inptr))
lines = readhex (&inptr);
else
lines = 20;
dumpmem (maddr, &nxmem, lines);
}
break;
case 'o':
{
if (copper_debugger(&inptr)) {
debugger_active = 0;
debugging = 0;
return;
}
break;
}
case 'O':
break;
#ifdef SAVESTATE
case 'b':
if (staterecorder (&inptr))
return;
break;
case 'g':
if (more_params (&inptr)) {
m68k_setpc (readhex (&inptr));
fill_prefetch_slow ();
}
deactivate_debugger();
return;
case 'x':
if (_totupper(inptr[0]) == 'X') {
debugger_change(-1);
} else {
deactivate_debugger();
close_console();
return;
}
break;
case 'H':
{
int count, temp, badly, skip;
uae_u32 oldpc = m68k_getpc ();
struct regstruct save_regs = regs;
badly = 0;
if (inptr[0] == 'H') {
badly = 1;
inptr++;
}
if (more_params(&inptr))
count = readint (&inptr);
else
count = 10;
if (count < 0)
break;
skip = count;
if (more_params (&inptr))
skip = count - readint (&inptr);
temp = lasthist;
while (count-- > 0 && temp != firsthist) {
if (temp == 0)
temp = MAX_HIST - 1;
else
temp--;
}
while (temp != lasthist) {
regs = history[temp];
m68k_setpc (history[temp].pc);
if (badly)
m68k_dumpstate (stdout, NULL);
else
m68k_disasm (stdout, history[temp].pc, NULL, 1);
if (skip-- < 0)
break;
if (++temp == MAX_HIST)
temp = 0;
}
regs = save_regs;
m68k_setpc (oldpc);
}
break;
case 'M':
if (more_params (&inptr)) {
switch (next_char (&inptr))
{
case 'a':
if (more_params (&inptr))
audio_channel_mask = readhex (&inptr);
console_out_f ("Audio mask = %02X\n", audio_channel_mask);
break;
case 's':
if (more_params (&inptr))
debug_sprite_mask = readhex (&inptr);
console_out_f ("Sprite mask: %02X\n", debug_sprite_mask);
break;
case 'b':
if (more_params (&inptr)) {
debug_bpl_mask = readhex (&inptr) & 0xff;
if (more_params (&inptr))
debug_bpl_mask_one = readhex (&inptr) & 0xff;
notice_screen_contents_lost ();
}
console_out_f ("Bitplane mask: %02X (%02X)\n", debug_bpl_mask, debug_bpl_mask_one);
break;
}
}
break;
case 'm':
{
uae_u32 maddr;
int lines;
#ifdef _WIN32
if (*inptr == 'g') {
extern void update_memdump (uae_u32);
next_char (&inptr);
if (more_params (&inptr))
update_memdump (readhex (&inptr));
break;
}
#endif
case 'a':
if (more_params (&inptr)) {
char nc = next_char (&inptr);
if (nc == 'm')
audio_channel_mask = readint (&inptr);
}
break;
case 'h':
case '?':
debug_help ();
break;
if (more_params (&inptr)) {
maddr = readhex (&inptr);
} else {
maddr = nxmem;
}
if (more_params (&inptr))
lines = readhex (&inptr);
else
lines = 20;
dumpmem (maddr, &nxmem, lines);
}
break;
case 'v':
case 'V':
{
int v1 = vpos, v2 = 0;
if (more_params (&inptr))
v1 = readint (&inptr);
if (more_params (&inptr))
v2 = readint (&inptr);
if (debug_dma) {
decode_dma_record (v2, v1, cmd == 'v');
} else {
debug_dma = v1 < 0 ? -v1 : 1;
console_out_f ("DMA debugger enabled, mode=%d.\n", debug_dma);
}
}
break;
case 'o':
{
if (copper_debugger (&inptr)) {
debugger_active = 0;
debugging = 0;
return;
}
break;
}
case 'O':
break;
case 'b':
if (staterecorder (&inptr))
return;
break;
case 'U':
if (currprefs.cpu_model && more_params (&inptr)) {
int super, data, i;
uaecptr addrl = readhex (&inptr);
uaecptr addrp;
console_out_f ("%08X translates to:\n", addrl);
for (i = 0; i < 4; i++) {
super = (i & 2) ? 1 : 0;
data = (i & 1) ? 1 : 0;
console_out_f ("S%dD%d=", super, data);
TRY(prb) {
addrp = mmu_translate (addrl, super, data, 0);
console_out_f ("%08X", addrp);
TRY(prb2) {
addrp = mmu_translate (addrl, super, data, 1);
console_out_f (" RW");
} CATCH(prb2) {
console_out_f (" RO");
}
} CATCH(prb) {
console_out_f ("***********");
}
console_out_f (" ");
}
console_out_f ("\n");
}
break;
case 'h':
case '?':
if (more_params (&inptr))
converter (&inptr);
else
debug_help ();
break;
}
}
}
}
static void addhistory (void)
{
uae_u32 pc = m68k_getpc ();
// if (!notinrom())
// return;
history[lasthist] = regs;
history[lasthist].pc = m68k_getpc ();
if (++lasthist == MAX_HIST)
......@@ -2530,33 +3323,33 @@ static void addhistory (void)
void debug (void)
{
int i;
int i;
#ifdef SAVESTATE
if (savestate_state)
return;
if (savestate_state)
return;
#endif
bogusframe = 1;
addhistory ();
bogusframe = 1;
addhistory ();
#if 0
if (do_skip && skipaddr_start == 0xC0DEDBAD) {
if (trace_same_insn_count > 0) {
if (memcmp (trace_insn_copy, regs.pc_p, 10) == 0
&& memcmp (trace_prev_regs.regs, regs.regs, sizeof regs.regs) == 0)
{
trace_same_insn_count++;
return;
}
}
if (trace_same_insn_count > 1)
fprintf (logfile, "[ repeated %d times ]\n", trace_same_insn_count);
m68k_dumpstate (logfile, &nextpc);
trace_same_insn_count = 1;
memcpy (trace_insn_copy, regs.pc_p, 10);
memcpy (&trace_prev_regs, &regs, sizeof regs);
}
if (do_skip && skipaddr_start == 0xC0DEDBAD) {
if (trace_same_insn_count > 0) {
if (memcmp (trace_insn_copy, regs.pc_p, 10) == 0
&& memcmp (trace_prev_regs.regs, regs.regs, sizeof regs.regs) == 0)
{
trace_same_insn_count++;
return;
}
}
if (trace_same_insn_count > 1)
fprintf (logfile, "[ repeated %d times ]\n", trace_same_insn_count);
m68k_dumpstate (logfile, &nextpc);
trace_same_insn_count = 1;
memcpy (trace_insn_copy, regs.pc_p, 10);
memcpy (&trace_prev_regs, &regs, sizeof regs);
}
#endif
if (!memwatch_triggered) {
......@@ -2573,7 +3366,7 @@ void debug (void)
continue;
if (bpnodes[i].addr == pc) {
bp = 1;
console_out ("Breakpoint at %08X\n", pc);
console_out_f ("Breakpoint at %08X\n", pc);
break;
}
}
......@@ -2581,7 +3374,36 @@ void debug (void)
if (skipaddr_doskip) {
if (skipaddr_start == pc)
bp = 1;
if (skipins != 0xffffffff) {
if ((processptr || processname) && notinrom()) {
uaecptr execbase = get_long (4);
uaecptr activetask = get_long (execbase + 276);
int process = get_byte (activetask + 8) == 13 ? 1 : 0;
char *name = (char*)get_real_address (get_long (activetask + 10));
if (process) {
uaecptr cli = BPTR2APTR(get_long (activetask + 172));
uaecptr seglist = 0;
uae_char *command = NULL;
if (cli) {
if (processname)
command = (char*)get_real_address (BPTR2APTR(get_long (cli + 16)));
seglist = BPTR2APTR(get_long (cli + 60));
} else {
seglist = BPTR2APTR(get_long (activetask + 128));
seglist = BPTR2APTR(get_long (seglist + 12));
}
if (activetask == processptr || (processname && (!strcasecmp (name, processname) || (command && command[0] && !strncasecmp (command + 1, processname, command[0]) && processname[command[0]] == 0)))) {
while (seglist) {
uae_u32 size = get_long (seglist - 4) - 4;
if (pc >= (seglist + 4) && pc < (seglist + size)) {
bp = 1;
break;
}
seglist = BPTR2APTR(get_long (seglist));
}
}
}
} else if (skipins != 0xffffffff) {
if (skipins == 0x10000) {
if (opcode == 0x4e75 || opcode == 0x4e73 || opcode == 0x4e77)
bp = 1;
......@@ -2610,8 +3432,10 @@ void debug (void)
}
}
} else {
write_log ("Memwatch %d: break at %8.8X.%c %c %8.8X\n", memwatch_triggered - 1, mwhit.addr,
mwhit.size == 1 ? 'B' : (mwhit.size == 2 ? 'W' : 'L'), mwhit.rwi ? 'W' : 'R', mwhit.val);
console_out_f ("Memwatch %d: break at %08X.%c %c%c%c %08X PC=%08X\n", memwatch_triggered - 1, mwhit.addr,
mwhit.size == 1 ? 'B' : (mwhit.size == 2 ? 'W' : 'L'),
(mwhit.rwi & 1) ? 'R' : ' ', (mwhit.rwi & 2) ? 'W' : ' ', (mwhit.rwi & 4) ? 'I' : ' ',
mwhit.val, mwhit.pc);
memwatch_triggered = 0;
}
if (skipaddr_doskip > 0) {
......@@ -2777,7 +3601,7 @@ static void mmu_do_hit_pre (struct mmudata *md, uaecptr addr, int size, int rwi,
mmur = regs;
pc = m68k_getpc ();
if (mmu_logging)
console_out ("MMU: hit %08X SZ=%d RW=%d V=%08X PC=%08X\n", addr, size, rwi, v, pc);
console_out_f ("MMU: hit %08X SZ=%d RW=%d V=%08X PC=%08X\n", addr, size, rwi, v, pc);
p = mmu_regs;
put_long (p, 0); p += 4;
......@@ -2840,7 +3664,7 @@ static int mmu_hit (uaecptr addr, int size, int rwi, uae_u32 *v)
if (maddr == addr) /* infinite mmu hit loop? no thanks.. */
return 1;
if (mmu_logging)
console_out ("MMU: remap %08X -> %08X SZ=%d RW=%d\n", addr, maddr, size, rwi);
console_out_f ("MMU: remap %08X -> %08X SZ=%d RW=%d\n", addr, maddr, size, rwi);
if ((rwi & 2)) {
switch (size)
{
......@@ -2966,7 +3790,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
p = parm;
mmu_struct = p;
if (get_long (p) != 1) {
console_out ("MMU: version mismatch %d <> %d\n", get_long (p), 1);
console_out_f ("MMU: version mismatch %d <> %d\n", get_long (p), 1);
return 0;
}
p += 4;
......@@ -2988,7 +3812,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
if (mn->mmubank->p_addr == parm2) {
getmmubank(mn->mmubank, parm2);
if (mmu_logging)
console_out ("MMU: bank update %08X: %08X - %08X %08X\n",
console_out_f ("MMU: bank update %08X: %08X - %08X %08X\n",
mn->mmubank->flags, mn->mmubank->addr, mn->mmubank->len + mn->mmubank->addr,
mn->mmubank->remap);
}
......@@ -3026,7 +3850,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
}
initialize_memwatch (1);
console_out ("MMU: enabled, %d banks, CB=%08X S=%08X BNK=%08X SF=%08X, %d*%d\n",
console_out_f ("MMU: enabled, %d banks, CB=%08X S=%08X BNK=%08X SF=%08X, %d*%d\n",
size - 1, mmu_callback, parm, banks, mmu_regs, mmu_slots, 1 << MMU_PAGE_SHIFT);
set_special (SPCFLAG_BRK);
return 1;
......
......@@ -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 */
......@@ -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;
}
/*
* 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
......
/*
* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment