sync 2.2.1

parent 716e8cfa
/* /*
* UAE - The Un*x Amiga Emulator * UAE - The Un*x Amiga Emulator
* *
* ADIDE * ADIDE
* *
* (c) 2009 Toni Wilen * (c) 2009 Toni Wilen
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
......
/* /*
* cpummu.cpp - MMU emulation * cpummu.cpp - MMU emulation
* *
* Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
* *
* Inspired by UAE MMU patch * Inspired by UAE MMU patch
* *
* This file is part of the ARAnyM project which builds a new and powerful * This file is part of the ARAnyM project which builds a new and powerful
* TOS/FreeMiNT compatible virtual machine running on almost any hardware. * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
* *
* ARAnyM is free software; you can redistribute it and/or modify * ARAnyM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* ARAnyM is distributed in the hope that it will be useful, * ARAnyM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with ARAnyM; if not, write to the Free Software * along with ARAnyM; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#define DEBUG 0 #define DEBUG 0
#include "sysconfig.h" #include "sysconfig.h"
......
/* /*
* UAE - The Un*x Amiga Emulator * UAE - The Un*x Amiga Emulator
* *
* Debugger * Debugger
* *
* (c) 1995 Bernd Schmidt * (c) 1995 Bernd Schmidt
* (c) 2006 Toni Wilen * (c) 2006 Toni Wilen
* *
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
...@@ -68,9 +68,9 @@ static FILE *logfile; ...@@ -68,9 +68,9 @@ static FILE *logfile;
#define console_out printf #define console_out printf
#define console_flush() fflush( stdout ) #define console_flush() fflush( stdout )
#define console_get( input, len ) fgets( input, len, stdin ) #define console_get( input, len ) fgets( input, len, stdin )
#define console_out_f printf
#endif #endif
void deactivate_debugger (void) void deactivate_debugger (void)
{ {
debugger_active = 0; debugger_active = 0;
...@@ -170,101 +170,252 @@ void debug_help (void) ...@@ -170,101 +170,252 @@ void debug_help (void)
static int debug_linecounter; static int debug_linecounter;
#define MAX_LINECOUNTER 1000 #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)) while (**c && _istspace(**c))
(*c)++; (*c)++;
} }
static uae_u32 readint (const char **c); static uae_u32 readint (TCHAR **c);
static uae_u32 readbin (const char **c); static uae_u32 readbin (TCHAR **c);
static uae_u32 readhex (const char **c) static uae_u32 readhex (TCHAR **c);
static int readregx (TCHAR **c, uae_u32 *valp)
{ {
uae_u32 val = 0; int i;
char nc; uae_u32 addr;
TCHAR *p = *c;
TCHAR tmp[10];
int extra = 0;
ignore_ws (c); addr = 0;
if (**c == '!' || **c == '_') { i = 0;
(*c)++; while (p[i]) {
return readint (c); tmp[i] = _totupper (p[i]);
} if (i >= sizeof (tmp) / sizeof (TCHAR) - 1)
while (isxdigit (nc = **c)) { break;
(*c)++; i++;
val *= 16; }
nc = toupper (nc); tmp[i] = 0;
if (isdigit (nc)) { if (_totupper (tmp[0]) == 'R') {
val += nc - '0'; 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 { } else {
val += nc - 'A' + 10; return 0;
} }
} *valp = addr;
return val; (*c) += extra;
return 1;
} }
static uae_u32 readint (const char **c) static uae_u32 readbinx (TCHAR **c)
{ {
uae_u32 val = 0; uae_u32 val = 0;
char nc;
int sign = 1;
ignore_ws (c); ignore_ws (c);
if (**c == '$') { for (;;) {
(*c)++; TCHAR nc = **c;
return readhex (c); if (nc != '1' && nc != '0')
} break;
if (**c == '0' && toupper ((*c)[1]) == 'X') { (*c)++;
(*c) += 2; val <<= 1;
return readhex (c); if (nc == '1')
} val |= 1;
if (**c == '-') { }
sign = 1; return val;
(*c)++;
}
while (isdigit (nc = **c)) {
(*c)++;
val *= 10;
val += nc - '0';
}
return val * sign;
} }
static char next_char (const char **c) static uae_u32 readhexx (TCHAR **c)
{ {
ignore_ws (c); uae_u32 val = 0;
return *(*c)++; 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; uae_u32 val = 0;
return pc[1]; 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); TCHAR nc;
return (**c) != 0;
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; if (**c == '\"') {
while (**c != 0) { startmarker = 1;
if (**c == 32) { (*c)++;
ignore_ws (c);
return strlen (out);
} }
*p = next_char (c); *p = 0;
if (forceupper) while (**c != 0) {
*p = toupper (*p); if (**c == '\"' && startmarker)
*++p = 0; break;
max--; if (**c == 32 && !startmarker) {
if (max <= 1) ignore_ws (c);
break; break;
} }
return strlen (out); *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) int notinrom (void)
...@@ -373,7 +524,7 @@ static uaecptr nextaddr (uaecptr addr, uaecptr *end) ...@@ -373,7 +524,7 @@ static uaecptr nextaddr (uaecptr addr, uaecptr *end)
uaecptr xa = addr; uaecptr xa = addr;
if (xa == 1) if (xa == 1)
xa = 0; 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 #endif
return addr; return addr;
...@@ -433,17 +584,24 @@ static void dumpmem (uaecptr addr, uaecptr *nxmem, int lines) ...@@ -433,17 +584,24 @@ static void dumpmem (uaecptr addr, uaecptr *nxmem, int lines)
TCHAR line[MAX_LINEWIDTH + 1]; TCHAR line[MAX_LINEWIDTH + 1];
for (;lines--;) { for (;lines--;) {
addr = dumpmem2 (addr, line, sizeof(line)); addr = dumpmem2 (addr, line, sizeof(line));
write_log ("%s\n", line); debug_out ("%s", line);
if (!debug_out ("\n"))
break;
} }
*nxmem = addr; *nxmem = addr;
} }
static void dump_custom_regs (void) static void dump_custom_regs (int aga)
{ {
unsigned int len; unsigned int len;
unsigned int i, j, end; unsigned int i, j, end;
uae_u8 *p1, *p2, *p3, *p4; uae_u8 *p1, *p2, *p3, *p4;
if (aga) {
dump_aga_custom();
return;
}
p1 = p2 = save_custom (&len, 0, 1); p1 = p2 = save_custom (&len, 0, 1);
p1 += 4; // skip chipset type p1 += 4; // skip chipset type
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -476,7 +634,7 @@ static void dump_custom_regs (void) ...@@ -476,7 +634,7 @@ static void dump_custom_regs (void)
addr2 = custd[j].adr & 0x1ff; addr2 = custd[j].adr & 0x1ff;
v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1]; v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1];
v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 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, addr1, custd[i].name, v1,
addr2, custd[j].name, v2); addr2, custd[j].name, v2);
} }
...@@ -492,12 +650,12 @@ static void dump_vectors (uaecptr addr) ...@@ -492,12 +650,12 @@ static void dump_vectors (uaecptr addr)
while (int_labels[i].name || trap_labels[j].name) { while (int_labels[i].name || trap_labels[j].name) {
if (int_labels[i].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)); int_labels[i].name, get_long (int_labels[i].adr + addr));
i++; i++;
} }
if (trap_labels[j].name) { 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)); trap_labels[j].name, get_long (trap_labels[j].adr + addr));
j++; j++;
} }
...@@ -505,7 +663,7 @@ static void dump_vectors (uaecptr addr) ...@@ -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; unsigned int vp, hp, ve, he, bfd, v_mask, h_mask;
int doout = 0; int doout = 0;
...@@ -523,9 +681,9 @@ static void disassemble_wait (uae_u32 insn) ...@@ -523,9 +681,9 @@ static void disassemble_wait (uae_u32 insn)
doout = 1; doout = 1;
console_out ("vpos "); console_out ("vpos ");
if (ve != 0x7f) { 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 (he > 0) {
if (v_mask > 0) { if (v_mask > 0) {
...@@ -533,16 +691,16 @@ static void disassemble_wait (uae_u32 insn) ...@@ -533,16 +691,16 @@ static void disassemble_wait (uae_u32 insn)
} }
console_out (" hpos "); console_out (" hpos ");
if (he != 0xfe) { 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 { } else {
if (doout) if (doout)
console_out (", "); console_out (", ");
console_out (", ignore horizontal"); 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); vp, ve, hp, he, bfd);
} }
...@@ -722,7 +880,7 @@ static void decode_dma_record (int hpos, int vpos, int toggle) ...@@ -722,7 +880,7 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
if (!dma_record[0]) if (!dma_record[0])
return; return;
dr = &dma_record[dma_record_toggle ^ toggle][vpos * NR_DMA_REC_HPOS]; 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; h = hpos;
dr += hpos; dr += hpos;
maxh = hpos + 80; maxh = hpos + 80;
...@@ -731,14 +889,14 @@ static void decode_dma_record (int hpos, int vpos, int toggle) ...@@ -731,14 +889,14 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
while (h < maxh) { while (h < maxh) {
int col = 9; int col = 9;
int cols = 8; int cols = 8;
char l1[81]; TCHAR l1[81];
char l2[81]; TCHAR l2[81];
char l3[81]; TCHAR l3[81];
char l4[81]; TCHAR l4[81];
for (i = 0; i < cols && h < maxh; i++, h++, dr++) { for (i = 0; i < cols && h < maxh; i++, h++, dr++) {
int cl = i * col, cl2; int cl = i * col, cl2;
int r = dr->reg; int r = dr->reg;
char *sr; TCHAR *sr;
sr = " "; sr = " ";
if (dr->type == DMARECORD_COPPER) if (dr->type == DMARECORD_COPPER)
...@@ -799,11 +957,11 @@ static void decode_dma_record (int hpos, int vpos, int toggle) ...@@ -799,11 +957,11 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
l4[cl + col - 1] = 32; l4[cl + col - 1] = 32;
} }
} }
console_out ("%s\n", l1); console_out_f ("%s\n", l1);
console_out ("%s\n", l2); console_out_f ("%s\n", l2);
console_out ("%s\n", l3); console_out_f ("%s\n", l3);
console_out ("%s\n", l4); console_out_f ("%s\n", l4);
console_out ("\n"); console_out_f ("\n");
} }
} }
...@@ -830,186 +988,425 @@ void record_copper (uaecptr addr, int hpos, int vpos) ...@@ -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; int s = curr_cop_set ^ 1;
unsigned int t = nr_cop_records[s]; int t = nr_cop_records[s];
unsigned int i; int i;
for (i = 0; i < t; i++) { for (i = 0; i < t; i++) {
if (cop_record[s][i].addr == addr) { if (cop_record[s][i].addr == addr)
*phpos = cop_record[s][i].hpos; return &cop_record[s][i];
*pvpos = cop_record[s][i].vpos;
return 1;
}
} }
return 0; return 0;
} }
/* simple decode copper by Mark Cox */ /* 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; struct cop_rec *cr = NULL;
unsigned int hpos, vpos; uae_u32 insn_type = insn & 0x00010001;
char here = ' '; TCHAR here = ' ';
char record[] = " "; TCHAR record[] = " ";
if (find_copper_record (addr, &hpos, &vpos)) {
sprintf (record, " [%03x %03x]", vpos, hpos);
}
if (get_copper_address(-1) >= addr && get_copper_address(-1) <= addr + 3) if ((cr = find_copper_records (addr))) {
here = '*'; _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) { console_out_f ("%c%08lx: %04lx %04lx%s\t; ", here, addr, insn >> 16, insn & 0xFFFF, record);
case 0x00010000: /* WAIT insn */
console_out ("Wait for ");
disassemble_wait (insn);
if (insn == 0xfffffffe) switch (insn_type) {
console_out (" \t; End of Copperlist\n"); 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 */ break;
console_out ("Skip if ");
disassemble_wait (insn);
break;
case 0x00000000: case 0x00010001: /* SKIP insn */
case 0x00000001: /* MOVE insn */ console_out ("Skip if ");
{ disassemble_wait (file, insn);
uae_u32 addr = (insn >> 16) & 0x1fe; break;
int i = 0;
while (custd[i].name) { case 0x00000000:
if (custd[i].adr == addr + 0xdff000) case 0x00000001: /* MOVE insn */
break; {
i++; int addr = (insn >> 16) & 0x1fe;
} int i = 0;
if (custd[i].name) while (custd[i].name) {
console_out ("%s := 0x%04x\n", custd[i].name, insn & 0xffff); if (custd[i].adr == addr + 0xdff000)
else break;
console_out ("%04x := 0x%04x\n", addr, insn & 0xffff); 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; static uaecptr nxcopper;
while (nolines-- > 0) { uae_u32 maddr;
insn = get_long (address); int lines;
decode_copper_insn (insn, address);
address += 4; if (**c == 'd') {
} next_char (c);
return address; if (debug_copper)
/* You may wonder why I don't stop this at the end of the copperlist? debug_copper = 0;
* Well, often nice things are hidden at the end and it is debatable the actual else
* values that mean the end of the copperlist */ 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; int i, skip;
uae_u32 maddr;
unsigned int lines;
if (**c == 'd') { if (!trainerdata)
next_char (c); return;
if (debug_copper) if (mode)
debug_copper = 0; skip = 6;
else else
debug_copper = 1; skip = 8;
console_out ("Copper debugger %s.\n", debug_copper ? "enabled" : "disabled"); for(i = 0; i < totaltrainers; i++) {
} else if (**c == 't') { struct trainerstruct *ts = &trainerdata[i];
debug_copper = 1|2; uae_u16 b;
return 1;
} else if (**c == 'b') { if (size) {
(*c)++; b = get_byte (ts->addr);
debug_copper = 1|4; } else {
if (more_params (c)) { b = get_word (ts->addr);
debug_copper_pc = readhex (c); }
console_out ("Copper breakpoint @0x%8.8x\n", debug_copper_pc); 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 { } 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)) if (more_params (c))
lines = readhex (c); size = readint (c);
else if (size > 4)
lines = 20; size = 4;
if (size < 1)
nxcopper = decode_copperlist (maddr, lines); size = 1;
}
return 0; if (vlist == NULL) {
} listsize = memsize;
vlist = xcalloc (uae_u8, listsize >> 3);
/* cheat-search by Holger Jakob */ }
static void cheatsearch (const char **c)
{ count = 0;
uae_u8 *p = get_real_address (0); vcnt = 0;
static uae_u32 *vlist = NULL;
uae_u32 ptr; clearcheater ();
uae_u32 val = 0; addr = 0xffffffff;
uae_u32 type = 0; /* not yet */ prevmemcnt = memcnt = 0;
uae_u32 count = 0; while ((addr = nextaddr (addr, &end)) != 0xffffffff) {
uae_u32 fcount = 0; if (addr + size < end) {
uae_u32 full = 0; for (i = 0; i < size; i++) {
int shift = (size - i - 1) * 8;
ignore_ws (c); if (get_byte (addr + i) != ((val >> shift) & 0xff))
val = readhex (c); break;
if (vlist == NULL) { }
vlist = malloc (256 * 4); if (i == size) {
if (vlist != 0) { int voffset = memcnt >> 3;
for (count = 0; count < 255; count++) int vmask = 1 << (memcnt & 7);
vlist[count] = 0; if (!first) {
count = 0; while (prevmemcnt < memcnt) {
for (ptr = 0; ptr < allocated_chipmem - 40; ptr += 2, p += 2) { vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
if (ptr >= 0x438 && p[3] == (val & 0xff) prevmemcnt++;
&& p[2] == (val >> 8 & 0xff) }
&& p[1] == (val >> 16 & 0xff) if (vlist[voffset] & vmask) {
&& p[0] == (val >> 24 & 0xff)) count++;
{ addcheater(addr, size);
if (count < 255) { } else {
vlist[count++]=ptr; vlist[voffset] &= ~vmask;
console_out ("%08x: %x%x%x%x\n",ptr,p[0],p[1],p[2],p[3]); }
} else prevmemcnt = memcnt + 1;
full = 1; } else {
vlist[voffset] |= vmask;
count++;
}
}
} }
} memcnt++;
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"); if (!first) {
} while (prevmemcnt < memcnt) {
} else { vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
for (count = 0; count<255; count++) { prevmemcnt++;
if (p[vlist[count]+3] == (val & 0xff) }
&& p[vlist[count]+2] == (val>>8 & 0xff) listcheater (0, size);
&& p[vlist[count]+1] == (val>>16 & 0xff) }
&& p[vlist[count]] == (val>>24 & 0xff)) console_out_f ("Found %d possible addresses with 0x%X (%u) (%d bytes)\n", count, val, val, size);
{ if (count > 0)
fcount++; console_out ("Now continue with 'g' and use 'C' with a different value\n");
console_out ("%08x: %x%x%x%x\n", vlist[count], p[vlist[count]], first = 0;
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;
}
} }
struct breakpoint_node bpnodes[BREAKPOINT_TOTAL]; struct breakpoint_node bpnodes[BREAKPOINT_TOTAL];
...@@ -1119,17 +1516,17 @@ static void illg_debug_do (uaecptr addr, int rwi, int size, uae_u32 val) ...@@ -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); illg_debug_check (ad, rwi, size, val);
} else if ((mask & 3) == 0) { } else if ((mask & 3) == 0) {
if (rwi & 2) 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) 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) if (illgdebug_break)
activate_debugger (); activate_debugger ();
} else if (!(mask & 1) && (rwi & 1)) { } 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) if (illgdebug_break)
activate_debugger (); activate_debugger ();
} else if (!(mask & 2) && (rwi & 2)) { } 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) if (illgdebug_break)
activate_debugger (); activate_debugger ();
} }
...@@ -1181,7 +1578,7 @@ static void smc_detect_init (TCHAR **c) ...@@ -1181,7 +1578,7 @@ static void smc_detect_init (TCHAR **c)
initialize_memwatch (0); initialize_memwatch (0);
if (v) if (v)
smc_mode = 1; 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 #define SMC_MAXHITS 8
...@@ -1223,12 +1620,12 @@ static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp) ...@@ -1223,12 +1620,12 @@ static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp)
} }
if (hitcnt < 100) { if (hitcnt < 100) {
smc_table[hitaddr].cnt++; 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); hitaddr, hitaddr + hitcnt, hitcnt, hitpc);
if (smc_mode) if (smc_mode)
activate_debugger (); activate_debugger ();
if (smc_table[hitaddr].cnt >= SMC_MAXHITS) 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 ...@@ -1535,23 +1932,27 @@ struct membank_store
static struct membank_store *membank_stores; 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) if (!memwatch_enabled && !mmu_enabled)
return; return -1;
for (i = 0; i < 256; i++) { for (i = 0; membank_stores[i].addr; i++) {
addrbank *a1 = debug_mem_banks[i]; memcpy (membank_stores[i].addr, &membank_stores[i].store, sizeof (addrbank));
addrbank *a2 = mem_banks[i]; }
memcpy (a2, a1, sizeof (addrbank)); oldmode = mmu_enabled ? 1 : 0;
free (a1); xfree (debug_mem_banks);
} debug_mem_banks = NULL;
free (debug_mem_banks); xfree (debug_mem_area);
debug_mem_banks = 0; debug_mem_area = NULL;
memwatch_enabled = 0; xfree (membank_stores);
free (illgdebug); membank_stores = NULL;
illgdebug = 0; memwatch_enabled = 0;
mmu_enabled = 0;
xfree (illgdebug);
illgdebug = 0;
return oldmode;
} }
static void initialize_memwatch (int mode) static void initialize_memwatch (int mode)
...@@ -1601,7 +2002,7 @@ static void initialize_memwatch (int mode) ...@@ -1601,7 +2002,7 @@ static void initialize_memwatch (int mode)
} }
int debug_bankchange (int mode) int debug_bankchange (int mode)
{/* {
if (mode == -1) { if (mode == -1) {
int v = deinitialize_memwatch (); int v = deinitialize_memwatch ();
if (v < 0) if (v < 0)
...@@ -1611,87 +2012,110 @@ int debug_bankchange (int mode) ...@@ -1611,87 +2012,110 @@ int debug_bankchange (int mode)
if (mode >= 0) if (mode >= 0)
initialize_memwatch (mode); initialize_memwatch (mode);
return -1; 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) static void memwatch_dump (int num)
{ {
unsigned int i; TCHAR *buf;
const struct memwatch_node *mwn; int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
for (i = 0; i < MEMWATCH_TOTAL; i++) {
if ((num >= 0 && num == (int)i) || (num < 0)) { buf = xmalloc (TCHAR, 50 * multiplier);
mwn = &mwnodes[i]; if (!buf)
if (mwn->size == 0) return;
continue; memwatch_dump2 (buf, 50 * multiplier, num);
console_out ("%d: %8.8X - %8.8X (%d) %s", //f_out (stdout, "%s", buf);
i, mwn->addr, mwn->addr + (mwn->size - 1), mwn->size, xfree (buf);
mwn->rwi == 0 ? "R" : (mwn->rwi == 1 ? "W" : "RW")); }
if (mwn->val_enabled)
console_out (" =%X", mwn->val); static void memwatch (TCHAR **c)
if (mwn->modval_written) {
console_out (" =M"); int num;
console_out ("\n"); struct memwatch_node *mwn;
} TCHAR nc;
}
} if (!memwatch_enabled) {
static void memwatch (const char **c)
{
int num;
struct memwatch_node *mwn;
char nc;
if (!memwatch_enabled) {
initialize_memwatch (0); initialize_memwatch (0);
console_out ("Memwatch breakpoints enabled\n"); console_out ("Memwatch breakpoints enabled\n");
} }
ignore_ws (c); ignore_ws (c);
if (!more_params (c)) { if (!more_params (c)) {
memwatch_dump (-1); memwatch_dump (-1);
return; return;
} }
nc = next_char (c); nc = next_char (c);
if (nc == '-') { if (nc == '-') {
deinitialize_memwatch (); deinitialize_memwatch ();
console_out ("Memwatch breakpoints disabled\n"); console_out ("Memwatch breakpoints disabled\n");
return; return;
} }
if (nc == 'd') { if (nc == 'd') {
if (illgdebug) { if (illgdebug) {
ignore_ws (c); ignore_ws (c);
if (more_params (c)) { if (more_params (c)) {
uae_u32 addr = readhex (c); uae_u32 addr = readhex (c);
uae_u32 len = 1; uae_u32 len = 1;
if (more_params (c)) if (more_params (c))
len = readhex (c); len = readhex (c);
write_log ("cleared logging addresses %8.8X - %8.8X\n", addr, addr + len); console_out_f ("Cleared logging addresses %08X - %08X\n", addr, addr + len);
while (len > 0) { while (len > 0) {
addr &= 0xffffff; addr &= 0xffffff;
illgdebug[addr] = 0; illgdebug[addr] = 7;
addr++; addr++;
len--; 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);
} }
} return;
} else { }
illg_init (); num = nc - '0';
console_out ("Illegal memory access logging enabled\n"); if (num < 0 || num >= MEMWATCH_TOTAL)
ignore_ws (c); return;
illgdebug_break = 0; mwn = &mwnodes[num];
if (more_params (c)) mwn->size = 0;
illgdebug_break = 1; 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->addr = readhex (c);
mwn->size = 1; mwn->size = 1;
mwn->rwi = 7; mwn->rwi = 7;
...@@ -1704,18 +2128,29 @@ static void memwatch (const char **c) ...@@ -1704,18 +2128,29 @@ static void memwatch (const char **c)
mwn->size = readhex (c); mwn->size = readhex (c);
ignore_ws (c); ignore_ws (c);
if (more_params (c)) { if (more_params (c)) {
char nc = toupper (next_char (c)); for (;;) {
if (nc == 'W') TCHAR ncc = peek_next_char(c);
mwn->rwi = 1; TCHAR nc = _totupper (next_char (c));
else if (nc == 'R' && toupper (**c) != 'W') if (mwn->rwi == 7)
mwn->rwi = 0; mwn->rwi = 0;
else if (nc == 'R' && toupper (**c) == 'W') if (nc == 'F')
next_char (c); mwn->frozen = 1;
ignore_ws (c); if (nc == 'W')
if (more_params (c)) { mwn->rwi |= 2;
if (toupper (**c) == 'M') { if (nc == 'I')
mwn->modval_written = 1; mwn->rwi |= 4;
} else if (toupper (**c) == 'C') { 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; mwn->mustchange = 1;
} else { } else {
mwn->val = readhex (c); mwn->val = readhex (c);
...@@ -1729,11 +2164,11 @@ static void memwatch (const char **c) ...@@ -1729,11 +2164,11 @@ static void memwatch (const char **c)
memwatch_dump (num); memwatch_dump (num);
} }
static void writeintomem (const char **c) static void writeintomem (TCHAR **c)
{ {
uae_u32 addr = 0; uae_u32 addr = 0;
uae_u32 val = 0; uae_u32 val = 0;
char cc; TCHAR cc;
int len = 1; int len = 1;
ignore_ws(c); ignore_ws(c);
...@@ -1760,7 +2195,7 @@ static void writeintomem (const char **c) ...@@ -1760,7 +2195,7 @@ static void writeintomem (const char **c)
put_byte (addr, val); put_byte (addr, val);
cc = 'B'; 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) static uae_u8 *dump_xlate (uae_u32 addr)
...@@ -1775,7 +2210,7 @@ static void memory_map_dump_2 (int log) ...@@ -1775,7 +2210,7 @@ static void memory_map_dump_2 (int log)
bool imold; bool imold;
int i, j, max; int i, j, max;
addrbank *a1 = mem_banks[0]; addrbank *a1 = mem_banks[0];
char txt[256]; TCHAR txt[256];
imold = currprefs.illegal_mem; imold = currprefs.illegal_mem;
currprefs.illegal_mem = false; currprefs.illegal_mem = false;
...@@ -1787,10 +2222,10 @@ static void memory_map_dump_2 (int log) ...@@ -1787,10 +2222,10 @@ static void memory_map_dump_2 (int log)
a2 = mem_banks[i]; a2 = mem_banks[i];
if (a1 != a2) { if (a1 != a2) {
int k, mirrored, size, size_out; int k, mirrored, size, size_out;
char size_ext; TCHAR size_ext;
uae_u8 *caddr; uae_u8 *caddr;
char *name; TCHAR *name;
char tmp[MAX_DPATH]; TCHAR tmp[MAX_DPATH];
name = a1->name; name = a1->name;
if (name == NULL) if (name == NULL)
...@@ -1817,7 +2252,7 @@ static void memory_map_dump_2 (int log) ...@@ -1817,7 +2252,7 @@ static void memory_map_dump_2 (int log)
tmp[0] = 0; tmp[0] = 0;
if (a1->flags == ABFLAG_ROM && mirrored) { 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); uae_u32 crc = get_crc32 (a1->xlateaddr(j << 16), (size * 1024) / mirrored);
struct romdata *rd = getromdatabycrc (crc); struct romdata *rd = getromdatabycrc (crc);
_stprintf (p, " (%08X)", crc); _stprintf (p, " (%08X)", crc);
...@@ -1853,21 +2288,36 @@ STATIC_INLINE uaecptr BPTR2APTR (uaecptr addr) ...@@ -1853,21 +2288,36 @@ STATIC_INLINE uaecptr BPTR2APTR (uaecptr addr)
{ {
return addr << 2; 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) static void print_task_info (uaecptr node)
{ {
char *s; TCHAR *s;
int process = get_byte (node + 8) == 13 ? 1 : 0; int process = get_byte (node + 8) == 13 ? 1 : 0;
console_out ("%08X: ", node); console_out_f ("%08X: ", node);
console_out (process ? " PROCESS '%s'" : " TASK '%s'\n", ((char*)get_real_address (get_long (node + 10)))); s = ((char*)get_real_address (get_long (node + 10)));
console_out_f (process ? " PROCESS '%s'" : " TASK '%s'\n", s);
xfree (s);
if (process) { if (process) {
uaecptr cli = BPTR2APTR (get_long (node + 172)); uaecptr cli = BPTR2APTR (get_long (node + 172));
int tasknum = get_long (node + 140); int tasknum = get_long (node + 140);
if (cli && tasknum) { if (cli && tasknum) {
uae_u8 *command_bstr = get_real_address (BPTR2APTR (get_long (cli + 16))); uae_u8 *command_bstr = get_real_address (BPTR2APTR (get_long (cli + 16)));
console_out (" [%d, '%s']\n", tasknum, command_bstr); //TCHAR *command = BSTR2CSTR (command_bstr);
xfree (command_bstr); console_out_f (" [%d, '%s']\n", tasknum, command_bstr);
//xfree (command);
} else { } else {
console_out ("\n"); console_out ("\n");
} }
...@@ -1880,11 +2330,11 @@ static void show_exec_tasks (void) ...@@ -1880,11 +2330,11 @@ static void show_exec_tasks (void)
uaecptr taskready = get_long (execbase + 406); uaecptr taskready = get_long (execbase + 406);
uaecptr taskwait = get_long (execbase + 420); uaecptr taskwait = get_long (execbase + 420);
uaecptr node, end; uaecptr node, end;
console_out ("Execbase at 0x%08X\n", execbase); console_out_f ("Execbase at 0x%08X\n", execbase);
console_out ("Current:\n"); console_out ("Current:\n");
node = get_long (execbase + 276); node = get_long (execbase + 276);
print_task_info (node); print_task_info (node);
console_out ("Ready:\n"); console_out_f ("Ready:\n");
node = get_long (taskready); node = get_long (taskready);
end = get_long (taskready + 4); end = get_long (taskready + 4);
while (node) { while (node) {
...@@ -1900,12 +2350,12 @@ static void show_exec_tasks (void) ...@@ -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 execbase = get_long (4);
uaecptr list = 0, node; uaecptr list = 0, node;
switch (toupper (t)) switch (_totupper (t))
{ {
case 'R': case 'R':
list = execbase + 336; list = execbase + 336;
...@@ -1921,7 +2371,7 @@ static void show_exec_lists (char t) ...@@ -1921,7 +2371,7 @@ static void show_exec_lists (char t)
return; return;
node = get_long (list); node = get_long (list);
while (get_long (node)) { 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); node = get_long (node);
} }
} }
...@@ -1933,13 +2383,13 @@ static struct regstruct trace_prev_regs; ...@@ -1933,13 +2383,13 @@ static struct regstruct trace_prev_regs;
#endif #endif
static uaecptr nextpc; static uaecptr nextpc;
int instruction_breakpoint (const char **c) int instruction_breakpoint (TCHAR **c)
{ {
struct breakpoint_node *bpn; struct breakpoint_node *bpn;
int i; int i;
if (more_params (c)) { if (more_params (c)) {
char nc = toupper ((*c)[0]); TCHAR nc = _totupper ((*c)[0]);
if (nc == 'S') { if (nc == 'S') {
next_char (c); next_char (c);
sr_bpvalue = sr_bpmask = 0; sr_bpvalue = sr_bpmask = 0;
...@@ -1949,7 +2399,7 @@ int instruction_breakpoint (const char **c) ...@@ -1949,7 +2399,7 @@ int instruction_breakpoint (const char **c)
if (more_params (c)) if (more_params (c))
sr_bpmask = readhex (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; return 0;
} else if (nc == 'I') { } else if (nc == 'I') {
next_char (c); next_char (c);
...@@ -1971,7 +2421,7 @@ int instruction_breakpoint (const char **c) ...@@ -1971,7 +2421,7 @@ int instruction_breakpoint (const char **c)
bpn = &bpnodes[i]; bpn = &bpnodes[i];
if (!bpn->enabled) if (!bpn->enabled)
continue; continue;
console_out ("%8X ", bpn->addr); console_out_f ("%8X ", bpn->addr);
got = 1; got = 1;
} }
if (!got) if (!got)
...@@ -2022,11 +2472,31 @@ int instruction_breakpoint (const char **c) ...@@ -2022,11 +2472,31 @@ int instruction_breakpoint (const char **c)
return 1; 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_u8 b;
uae_u32 src, src2, len, len2; uae_u32 src, src2, len, len2;
char *name; TCHAR *name;
FILE *fp; FILE *fp;
if (!more_params (cc)) if (!more_params (cc))
...@@ -2046,9 +2516,9 @@ static void savemem (char **cc) ...@@ -2046,9 +2516,9 @@ static void savemem (char **cc)
if (!more_params (cc)) if (!more_params (cc))
goto S_argh; goto S_argh;
len2 = len = readhex (cc); len2 = len = readhex (cc);
fp = fopen (name, "wb"); fp = _tfopen (name, "wb");
if (fp == NULL) { if (fp == NULL) {
console_out ("Couldn't open file '%s'\n", name); console_out_f ("Couldn't open file '%s'\n", name);
return; return;
} }
while (len > 0) { while (len > 0) {
...@@ -2062,19 +2532,19 @@ static void savemem (char **cc) ...@@ -2062,19 +2532,19 @@ static void savemem (char **cc)
} }
fclose (fp); fclose (fp);
if (len == 0) if (len == 0)
console_out ("Wrote %08X - %08X (%d bytes) to '%s'\n", console_out_f ("Wrote %08X - %08X (%d bytes) to '%s'\n",
src2, src2 + len2 - 1, len2, name); src2, src2 + len2, len2, name);
return; return;
S_argh: S_argh:
console_out ("S-command needs more arguments!\n"); 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; int i, sslen, got, val, stringmode;
uae_u8 ss[256]; uae_u8 ss[256];
uae_u32 addr, endaddr; uae_u32 addr, endaddr;
char nc; TCHAR nc;
got = 0; got = 0;
sslen = 0; sslen = 0;
...@@ -2093,7 +2563,7 @@ static void searchmem (const char **cc) ...@@ -2093,7 +2563,7 @@ static void searchmem (const char **cc)
for (;;) { for (;;) {
if (**cc == 32 || **cc == 0) if (**cc == 32 || **cc == 0)
break; break;
nc = toupper (next_char (cc)); nc = _totupper (next_char (cc));
if (isspace (nc)) if (isspace (nc))
break; break;
if (isdigit(nc)) if (isdigit(nc))
...@@ -2105,7 +2575,7 @@ static void searchmem (const char **cc) ...@@ -2105,7 +2575,7 @@ static void searchmem (const char **cc)
val *= 16; val *= 16;
if (**cc == 32 || **cc == 0) if (**cc == 32 || **cc == 0)
break; break;
nc = toupper (next_char (cc)); nc = _totupper (next_char (cc));
if (isspace (nc)) if (isspace (nc))
break; break;
if (isdigit(nc)) if (isdigit(nc))
...@@ -2127,7 +2597,7 @@ static void searchmem (const char **cc) ...@@ -2127,7 +2597,7 @@ static void searchmem (const char **cc)
if (more_params (cc)) if (more_params (cc))
endaddr = readhex (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) { while ((addr = nextaddr (addr, NULL)) != 0xffffffff) {
if (addr == endaddr) if (addr == endaddr)
break; break;
...@@ -2143,7 +2613,7 @@ static void searchmem (const char **cc) ...@@ -2143,7 +2613,7 @@ static void searchmem (const char **cc)
} }
if (i == sslen) { if (i == sslen) {
got++; got++;
console_out (" %08x", addr); console_out_f (" %08X", addr);
if (got > 100) { if (got > 100) {
console_out ("\nMore than 100 results, aborting.."); console_out ("\nMore than 100 results, aborting..");
break; break;
...@@ -2156,9 +2626,9 @@ static void searchmem (const char **cc) ...@@ -2156,9 +2626,9 @@ static void searchmem (const char **cc)
} }
#ifdef SAVESTATE #ifdef SAVESTATE
static int staterecorder (const char **cc) static int staterecorder (TCHAR **cc)
{ {
char nc; TCHAR nc;
if (!more_params (cc)) { if (!more_params (cc)) {
if (savestate_dorewind (1)) { if (savestate_dorewind (1)) {
...@@ -2181,16 +2651,204 @@ static const TCHAR *debugtest_names[] = { ...@@ -2181,16 +2651,204 @@ static const TCHAR *debugtest_names[] = {
"Blitter", "Keyboard", "Floppy" "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; unsigned int i;
if (**inptr == 'd') { if (**inptr == 'd') {
(*inptr)++; (*inptr)++;
ignore_ws (inptr); ignore_ws (inptr);
disk_debug_logging = readint (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; return;
} }
disk_debug_mode = 0; disk_debug_mode = 0;
...@@ -2198,7 +2856,7 @@ static void disk_debug (const char **inptr) ...@@ -2198,7 +2856,7 @@ static void disk_debug (const char **inptr)
ignore_ws (inptr); ignore_ws (inptr);
if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1)) if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
goto end; goto end;
for (i = 0; i < strlen (parm); i++) { for (i = 0; i < _tcslen(parm); i++) {
if (parm[i] == 'R') if (parm[i] == 'R')
disk_debug_mode |= DISK_DEBUG_DMA_READ; disk_debug_mode |= DISK_DEBUG_DMA_READ;
if (parm[i] == 'W') if (parm[i] == 'W')
...@@ -2213,14 +2871,14 @@ static void disk_debug (const char **inptr) ...@@ -2213,14 +2871,14 @@ static void disk_debug (const char **inptr)
if (disk_debug_logging == 0) if (disk_debug_logging == 0)
disk_debug_logging = 1; disk_debug_logging = 1;
end: 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_READ ? 'R' : '-',
disk_debug_mode & DISK_DEBUG_DMA_WRITE ? 'W' : '-', disk_debug_mode & DISK_DEBUG_DMA_WRITE ? 'W' : '-',
disk_debug_mode & DISK_DEBUG_PIO ? 'P' : '-', disk_debug_mode & DISK_DEBUG_PIO ? 'P' : '-',
disk_debug_track); disk_debug_track);
} }
static void find_ea (char **inptr) static void find_ea (TCHAR **inptr)
{ {
uae_u32 ea, sea, dea; uae_u32 ea, sea, dea;
uaecptr addr, end; uaecptr addr, end;
...@@ -2234,7 +2892,7 @@ static void find_ea (char **inptr) ...@@ -2234,7 +2892,7 @@ static void find_ea (char **inptr)
if (more_params(inptr)) if (more_params(inptr))
end = readhex (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) { while((addr = nextaddr(addr, &end)) != 0xffffffff) {
if ((addr & 1) == 0 && addr + 6 <= end) { if ((addr & 1) == 0 && addr + 6 <= end) {
sea = 0xffffffff; sea = 0xffffffff;
...@@ -2252,19 +2910,19 @@ static void find_ea (char **inptr) ...@@ -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; uae_u32 v;
char parm[10]; TCHAR parm[10];
unsigned char c1, c2; TCHAR c1, c2;
int i; int i;
if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1)) if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
return; return;
c1 = toupper (parm[0]); c1 = _totupper (parm[0]);
c2 = 99; c2 = 99;
if (c1 == 'A' || c1 == 'D' || c1 == 'P') { if (c1 == 'A' || c1 == 'D' || c1 == 'P') {
c2 = toupper (parm[1]); c2 = _totupper (parm[1]);
if (isdigit (c2)) if (isdigit (c2))
c2 -= '0'; c2 -= '0';
else else
...@@ -2302,7 +2960,7 @@ static void m68k_modify (const char **inptr) ...@@ -2302,7 +2960,7 @@ static void m68k_modify (const char **inptr)
static void debug_1 (void) static void debug_1 (void)
{ {
char input[MAX_LINEWIDTH]; TCHAR input[MAX_LINEWIDTH];
uaecptr nxdis, nxmem, addr; uaecptr nxdis, nxmem, addr;
m68k_dumpstate (stdout, &nextpc); m68k_dumpstate (stdout, &nextpc);
...@@ -2310,8 +2968,7 @@ static void debug_1 (void) ...@@ -2310,8 +2968,7 @@ static void debug_1 (void)
debugger_active = 1; debugger_active = 1;
for (;;) { for (;;) {
char cmd; TCHAR cmd, *inptr;
const char *inptr;
int v; int v;
if (!debugger_active) if (!debugger_active)
...@@ -2351,7 +3008,7 @@ static void debug_1 (void) ...@@ -2351,7 +3008,7 @@ static void debug_1 (void)
} }
break; break;
} }
case 'e': dump_custom_regs (); break; case 'e': dump_custom_regs (tolower(*inptr) == 'a'); break;
case 'r': case 'r':
{ {
if (more_params(&inptr)) if (more_params(&inptr))
...@@ -2360,7 +3017,7 @@ static void debug_1 (void) ...@@ -2360,7 +3017,7 @@ static void debug_1 (void)
m68k_dumpstate (stdout, &nextpc); m68k_dumpstate (stdout, &nextpc);
} }
break; break;
//case 'D': deepcheatsearch (&inptr); break; case 'D': deepcheatsearch (&inptr); break;
case 'C': cheatsearch (&inptr); break; case 'C': cheatsearch (&inptr); break;
case 'W': writeintomem (&inptr); break; case 'W': writeintomem (&inptr); break;
case 'w': memwatch (&inptr); break; case 'w': memwatch (&inptr); break;
...@@ -2368,157 +3025,293 @@ static void debug_1 (void) ...@@ -2368,157 +3025,293 @@ static void debug_1 (void)
case 's': case 's':
if (*inptr == 'c') { if (*inptr == 'c') {
;//screenshot (1, 1); ;//screenshot (1, 1);
} else if (*inptr == 'p') {
inptr++;
debug_sprite (&inptr);
} else if (*inptr == 'm') { } else if (*inptr == 'm') {
next_char (&inptr); if (*(inptr + 1) == 'c') {
if (more_params (&inptr)) next_char (&inptr);
debug_sprite_mask = readint (&inptr); next_char (&inptr);
console_out ("sprite mask: %2.2X\n", debug_sprite_mask); if (!smc_table)
} else { smc_detect_init (&inptr);
searchmem (&inptr); else
} smc_free ();
break; }
case 'd': } else {
{ searchmem (&inptr);
if (*inptr == 'i') { }
next_char (&inptr); break;
disk_debug (&inptr); case 'd':
} else { {
uae_u32 daddr; if (*inptr == 'i') {
int count; next_char (&inptr);
if (more_params (&inptr)) disk_debug (&inptr);
daddr = readhex (&inptr); } else if (*inptr == 'j') {
else inptr++;
daddr = nxdis; inputdevice_logging = 1 | 2;
if (more_params (&inptr)) if (more_params (&inptr))
count = readhex (&inptr); inputdevice_logging = readint(&inptr);
else console_out_f ("Input logging level %d\n", inputdevice_logging);
count = 10; } else if (*inptr == 'm') {
m68k_disasm (stdout, daddr, &nxdis, count); memory_map_dump_2 (0);
} } else if (*inptr == 't') {
} next_char (&inptr);
break; debugtest_set (&inptr);
case 'T': show_exec_tasks (); break; #ifdef _WIN32
case 't': } else if (*inptr == 'g') {
if (more_params (&inptr)) extern void update_disassembly (uae_u32);
skipaddr_doskip = readint (&inptr); next_char (&inptr);
if (skipaddr_doskip <= 0 || skipaddr_doskip > 10000) if (more_params (&inptr))
skipaddr_doskip = 1; update_disassembly (readhex (&inptr));
set_special (SPCFLAG_BRK); #endif
exception_debugging = 1; } else {
return; uae_u32 daddr;
case 'z': int count;
skipaddr_start = nextpc; if (more_params (&inptr))
skipaddr_doskip = 1; daddr = readhex (&inptr);
do_skip = 1; else
exception_debugging = 1; daddr = nxdis;
return; if (more_params (&inptr))
count = readhex (&inptr);
case 'f': else
if (instruction_breakpoint (&inptr)) count = 10;
return; m68k_disasm (stdout, daddr, &nxdis, count);
break; }
}
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(); case 'f':
debugger_active = 0; if (inptr[0] == 'a') {
debugging = 0; next_char(&inptr);
return; find_ea (&inptr);
} else if (inptr[0] == 'p') {
inptr++;
if (process_breakpoint(&inptr))
return;
} else {
if (instruction_breakpoint (&inptr))
return;
}
break;
case 'g': case 'q':
if (more_params (&inptr)) { uae_quit();
m68k_setpc (readhex (&inptr)); deactivate_debugger();
fill_prefetch_slow (); return;
}
debugger_active = 0;
debugging = 0;
exception_debugging = 0;
return;
case 'H': case 'g':
{ if (more_params (&inptr)) {
unsigned int count, temp, badly; m68k_setpc (readhex (&inptr));
uae_u32 oldpc = m68k_getpc (); fill_prefetch_slow ();
struct regstruct save_regs = regs; }
deactivate_debugger();
badly = 0; return;
if (inptr[0] == 'H') {
badly = 1; case 'x':
inptr++; if (_totupper(inptr[0]) == 'X') {
} debugger_change(-1);
} else {
if (more_params (&inptr)) deactivate_debugger();
count = readhex (&inptr); close_console();
else return;
count = 10; }
temp = lasthist; break;
while (count-- > 0 && temp != firsthist) {
if (temp == 0) case 'H':
temp = MAX_HIST - 1; {
else int count, temp, badly, skip;
temp--; uae_u32 oldpc = m68k_getpc ();
} struct regstruct save_regs = regs;
while (temp != lasthist) {
regs = history[temp]; badly = 0;
m68k_setpc (history[temp].pc); if (inptr[0] == 'H') {
if (badly) { badly = 1;
m68k_dumpstate (stdout, NULL); inptr++;
} else { }
m68k_disasm (stdout, history[temp].pc, NULL, 1);
} if (more_params(&inptr))
if (++temp == MAX_HIST) count = readint (&inptr);
temp = 0; else
} count = 10;
regs = save_regs; if (count < 0)
m68k_setpc (oldpc); break;
} skip = count;
break; if (more_params (&inptr))
case 'm': skip = count - readint (&inptr);
{
uae_u32 maddr; int lines; temp = lasthist;
if (more_params (&inptr)) while (count-- > 0 && temp != firsthist) {
maddr = readhex (&inptr); if (temp == 0)
else temp = MAX_HIST - 1;
maddr = nxmem; else
if (more_params (&inptr)) temp--;
lines = readhex (&inptr); }
else while (temp != lasthist) {
lines = 20; regs = history[temp];
dumpmem (maddr, &nxmem, lines); m68k_setpc (history[temp].pc);
} if (badly)
break; m68k_dumpstate (stdout, NULL);
case 'o': else
{ m68k_disasm (stdout, history[temp].pc, NULL, 1);
if (copper_debugger(&inptr)) { if (skip-- < 0)
debugger_active = 0; break;
debugging = 0; if (++temp == MAX_HIST)
return; temp = 0;
} }
break; regs = save_regs;
} m68k_setpc (oldpc);
case 'O': }
break; break;
#ifdef SAVESTATE case 'M':
case 'b': if (more_params (&inptr)) {
if (staterecorder (&inptr)) switch (next_char (&inptr))
return; {
break; 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 #endif
case 'a': if (more_params (&inptr)) {
if (more_params (&inptr)) { maddr = readhex (&inptr);
char nc = next_char (&inptr); } else {
if (nc == 'm') maddr = nxmem;
audio_channel_mask = readint (&inptr); }
} if (more_params (&inptr))
break; lines = readhex (&inptr);
case 'h': else
case '?': lines = 20;
debug_help (); dumpmem (maddr, &nxmem, lines);
break; }
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) static void addhistory (void)
{ {
uae_u32 pc = m68k_getpc ();
// if (!notinrom())
// return;
history[lasthist] = regs; history[lasthist] = regs;
history[lasthist].pc = m68k_getpc (); history[lasthist].pc = m68k_getpc ();
if (++lasthist == MAX_HIST) if (++lasthist == MAX_HIST)
...@@ -2530,33 +3323,33 @@ static void addhistory (void) ...@@ -2530,33 +3323,33 @@ static void addhistory (void)
void debug (void) void debug (void)
{ {
int i; int i;
#ifdef SAVESTATE #ifdef SAVESTATE
if (savestate_state) if (savestate_state)
return; return;
#endif #endif
bogusframe = 1; bogusframe = 1;
addhistory (); addhistory ();
#if 0 #if 0
if (do_skip && skipaddr_start == 0xC0DEDBAD) { if (do_skip && skipaddr_start == 0xC0DEDBAD) {
if (trace_same_insn_count > 0) { if (trace_same_insn_count > 0) {
if (memcmp (trace_insn_copy, regs.pc_p, 10) == 0 if (memcmp (trace_insn_copy, regs.pc_p, 10) == 0
&& memcmp (trace_prev_regs.regs, regs.regs, sizeof regs.regs) == 0) && memcmp (trace_prev_regs.regs, regs.regs, sizeof regs.regs) == 0)
{ {
trace_same_insn_count++; trace_same_insn_count++;
return; return;
} }
} }
if (trace_same_insn_count > 1) if (trace_same_insn_count > 1)
fprintf (logfile, "[ repeated %d times ]\n", trace_same_insn_count); fprintf (logfile, "[ repeated %d times ]\n", trace_same_insn_count);
m68k_dumpstate (logfile, &nextpc); m68k_dumpstate (logfile, &nextpc);
trace_same_insn_count = 1; trace_same_insn_count = 1;
memcpy (trace_insn_copy, regs.pc_p, 10); memcpy (trace_insn_copy, regs.pc_p, 10);
memcpy (&trace_prev_regs, &regs, sizeof regs); memcpy (&trace_prev_regs, &regs, sizeof regs);
} }
#endif #endif
if (!memwatch_triggered) { if (!memwatch_triggered) {
...@@ -2573,7 +3366,7 @@ void debug (void) ...@@ -2573,7 +3366,7 @@ void debug (void)
continue; continue;
if (bpnodes[i].addr == pc) { if (bpnodes[i].addr == pc) {
bp = 1; bp = 1;
console_out ("Breakpoint at %08X\n", pc); console_out_f ("Breakpoint at %08X\n", pc);
break; break;
} }
} }
...@@ -2581,7 +3374,36 @@ void debug (void) ...@@ -2581,7 +3374,36 @@ void debug (void)
if (skipaddr_doskip) { if (skipaddr_doskip) {
if (skipaddr_start == pc) if (skipaddr_start == pc)
bp = 1; 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 (skipins == 0x10000) {
if (opcode == 0x4e75 || opcode == 0x4e73 || opcode == 0x4e77) if (opcode == 0x4e75 || opcode == 0x4e73 || opcode == 0x4e77)
bp = 1; bp = 1;
...@@ -2610,8 +3432,10 @@ void debug (void) ...@@ -2610,8 +3432,10 @@ void debug (void)
} }
} }
} else { } else {
write_log ("Memwatch %d: break at %8.8X.%c %c %8.8X\n", memwatch_triggered - 1, mwhit.addr, 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 ? 'W' : 'R', mwhit.val); 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; memwatch_triggered = 0;
} }
if (skipaddr_doskip > 0) { if (skipaddr_doskip > 0) {
...@@ -2777,7 +3601,7 @@ static void mmu_do_hit_pre (struct mmudata *md, uaecptr addr, int size, int rwi, ...@@ -2777,7 +3601,7 @@ static void mmu_do_hit_pre (struct mmudata *md, uaecptr addr, int size, int rwi,
mmur = regs; mmur = regs;
pc = m68k_getpc (); pc = m68k_getpc ();
if (mmu_logging) 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; p = mmu_regs;
put_long (p, 0); p += 4; put_long (p, 0); p += 4;
...@@ -2840,7 +3664,7 @@ static int mmu_hit (uaecptr addr, int size, int rwi, uae_u32 *v) ...@@ -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.. */ if (maddr == addr) /* infinite mmu hit loop? no thanks.. */
return 1; return 1;
if (mmu_logging) 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)) { if ((rwi & 2)) {
switch (size) switch (size)
{ {
...@@ -2966,7 +3790,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) ...@@ -2966,7 +3790,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
p = parm; p = parm;
mmu_struct = p; mmu_struct = p;
if (get_long (p) != 1) { 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; return 0;
} }
p += 4; p += 4;
...@@ -2988,7 +3812,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) ...@@ -2988,7 +3812,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
if (mn->mmubank->p_addr == parm2) { if (mn->mmubank->p_addr == parm2) {
getmmubank(mn->mmubank, parm2); getmmubank(mn->mmubank, parm2);
if (mmu_logging) 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->flags, mn->mmubank->addr, mn->mmubank->len + mn->mmubank->addr,
mn->mmubank->remap); mn->mmubank->remap);
} }
...@@ -3026,7 +3850,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2) ...@@ -3026,7 +3850,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
} }
initialize_memwatch (1); 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); size - 1, mmu_callback, parm, banks, mmu_regs, mmu_slots, 1 << MMU_PAGE_SHIFT);
set_special (SPCFLAG_BRK); set_special (SPCFLAG_BRK);
return 1; return 1;
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
//FIXME: ---end //FIXME: ---end
#define TRACING_ENABLED 0 #define TRACING_ENABLED 0
#define TRACE2(x) do { write_log x; } while(0)
#if TRACING_ENABLED #if TRACING_ENABLED
#define TRACE(x) do { write_log x; } while(0) #define TRACE(x) do { write_log x; } while(0)
#define DUMPLOCK(u,x) dumplock(u,x) #define DUMPLOCK(u,x) dumplock(u,x)
......
...@@ -207,11 +207,11 @@ int gui_display(int shortcut){ ...@@ -207,11 +207,11 @@ int gui_display(int shortcut){
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y,icon_floppy, menu_sel_floppy); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y,icon_floppy, menu_sel_floppy);
blit_image (icon_floppy, iconpos_x, iconpos_y); blit_image (icon_floppy, iconpos_x, iconpos_y);
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_preferences, menu_sel_prefs); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_preferences, menu_sel_prefs);
blit_image (icon_preferences, iconpos_x, iconpos_y); blit_image (icon_preferences, iconpos_x, iconpos_y);
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_tweaks, menu_sel_tweaks); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_tweaks, menu_sel_tweaks);
blit_image (icon_tweaks, iconpos_x, iconpos_y); blit_image (icon_tweaks, iconpos_x, iconpos_y);
...@@ -219,7 +219,7 @@ int gui_display(int shortcut){ ...@@ -219,7 +219,7 @@ int gui_display(int shortcut){
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_keymaps, menu_sel_keymaps); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_keymaps, menu_sel_keymaps);
blit_image (icon_keymaps, iconpos_x, iconpos_y); blit_image (icon_keymaps, iconpos_x, iconpos_y);
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_expansion, menu_sel_expansion); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_expansion, menu_sel_expansion);
blit_image (icon_expansion, iconpos_x, iconpos_y); blit_image (icon_expansion, iconpos_x, iconpos_y);
...@@ -237,7 +237,7 @@ int gui_display(int shortcut){ ...@@ -237,7 +237,7 @@ int gui_display(int shortcut){
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_run, menu_sel_run); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_run, menu_sel_run);
blit_image (icon_run, iconpos_x, iconpos_y); blit_image (icon_run, iconpos_x, iconpos_y);
iconpos_x += iconsizex + bosluk; iconpos_x += iconsizex + bosluk;
secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_exit, menu_sel_exit); secilimi (iconpos_x,iconpos_y,mouse_x,mouse_y, icon_exit, menu_sel_exit);
blit_image (icon_exit, iconpos_x, iconpos_y); blit_image (icon_exit, iconpos_x, iconpos_y);
...@@ -279,8 +279,8 @@ int gui_display(int shortcut){ ...@@ -279,8 +279,8 @@ int gui_display(int shortcut){
return menu_exitcode; 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); SDL_Surface* pText_Surface = TTF_RenderText_Solid(amiga_font, txt, text_color);
rect.x = x; rect.x = x;
...@@ -291,7 +291,8 @@ void write_text(int x, int y, char* txt) { ...@@ -291,7 +291,8 @@ void write_text(int x, int y, char* txt) {
SDL_BlitSurface (pText_Surface,NULL,tmpSDLScreen,&rect); SDL_BlitSurface (pText_Surface,NULL,tmpSDLScreen,&rect);
SDL_FreeSurface(pText_Surface); 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; SDL_Rect dest;
dest.x = x; dest.x = x;
dest.y = y; dest.y = y;
...@@ -313,28 +314,3 @@ void secilimi (int ix, int iy, int mx, int my, SDL_Surface* img, int hangi) { ...@@ -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); ...@@ -37,7 +37,7 @@ extern void memory_map_dump (void);
extern void debug_help (void); extern void debug_help (void);
extern uaecptr dumpmem2 (uaecptr addr, char *out, int osize); extern uaecptr dumpmem2 (uaecptr addr, char *out, int osize);
extern void update_debug_info (void); extern void update_debug_info (void);
extern int instruction_breakpoint (const char **c); extern int instruction_breakpoint (TCHAR **c);
extern int debug_bankchange (int); extern int debug_bankchange (int);
#define BREAKPOINT_TOTAL 8 #define BREAKPOINT_TOTAL 8
......
...@@ -424,4 +424,5 @@ extern void xfree (const void*); ...@@ -424,4 +424,5 @@ extern void xfree (const void*);
#define bool _Bool #define bool _Bool
#define true 1 #define true 1
#define false 0 #define false 0
#define _vsntprintf vsnprintf
#endif #endif
...@@ -147,6 +147,233 @@ static int bouncy; ...@@ -147,6 +147,233 @@ static int bouncy;
static signed long bouncy_cycles; static signed long bouncy_cycles;
#define BOUNCY_CYCLES 30 #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) static int isdevice (const struct uae_input_device *id)
{ {
int i, j; int i, j;
...@@ -1571,7 +1798,35 @@ STATIC_INLINE int adjust (int val) ...@@ -1571,7 +1798,35 @@ STATIC_INLINE int adjust (int val)
int getbuttonstate (int joy, int button) 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; return (joybutton[joy] & (1 << button)) ? 1 : 0;
#endif
} }
static int getvelocity (int num, int subnum, int pct) static int getvelocity (int num, int subnum, int pct)
...@@ -1731,6 +1986,21 @@ int getjoystate (int joy) ...@@ -1731,6 +1986,21 @@ int getjoystate (int joy)
#ifdef DONGLE_DEBUG #ifdef DONGLE_DEBUG
if (notinrom ()) if (notinrom ())
write_log ("JOY%dDAT %04X %s\n", joy, v, debuginfo (0)); 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 #endif
return v; return v;
} }
......
...@@ -24,7 +24,7 @@ extern struct flag_struct regflags; ...@@ -24,7 +24,7 @@ extern struct flag_struct regflags;
* with a setto %AL instr and the other flags copied to AH with an * with a setto %AL instr and the other flags copied to AH with an
* lahf instr). * lahf instr).
* *
* The 68k CZNV flags are thus assinged in cznv as: * The 68k CZNV flags are thus assigned in cznv as:
* *
* <--AL--> <--AH--> * <--AL--> <--AH-->
* 76543210 FEDCBA98 --------- --------- * 76543210 FEDCBA98 --------- ---------
......
...@@ -56,31 +56,32 @@ extern struct flag_struct regflags; ...@@ -56,31 +56,32 @@ extern struct flag_struct regflags;
#define FLAGVAL_V (1 << FLAGBIT_V) #define FLAGVAL_V (1 << FLAGBIT_V)
#define FLAGVAL_X (1 << FLAGBIT_X) #define FLAGVAL_X (1 << FLAGBIT_X)
#define SET_ZFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_Z) | ((y) << FLAGBIT_Z)) #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z))
#define SET_CFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_C) | ((y) << FLAGBIT_C)) #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C))
#define SET_VFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_V) | ((y) << FLAGBIT_V)) #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V))
#define SET_NFLG(flags, y) ((flags)->cznv = ((flags)->cznv & ~FLAGVAL_N) | ((y) << FLAGBIT_N)) #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N))
#define SET_XFLG(flags, y) ((flags)->x = ((y) << FLAGBIT_X)) #define SET_XFLG(y) (regflags.x = ((y) ? 1 : 0) << FLAGBIT_X)
#define GET_ZFLG(flags) (((flags)->cznv >> FLAGBIT_Z) & 1) #define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1)
#define GET_CFLG(flags) (((flags)->cznv >> FLAGBIT_C) & 1) #define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1)
#define GET_VFLG(flags) (((flags)->cznv >> FLAGBIT_V) & 1) #define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1)
#define GET_NFLG(flags) (((flags)->cznv >> FLAGBIT_N) & 1) #define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1)
#define GET_XFLG(flags) (((flags)->x >> FLAGBIT_X) & 1) #define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1)
#define CLEAR_CZNV(flags) ((flags)->cznv = 0) #define CLEAR_CZNV() (regflags.cznv = 0)
#define GET_CZNV(flags) ((flags)->cznv) #define GET_CZNV (regflags.cznv)
#define IOR_CZNV(flags, X) ((flags)->cznv |= (X)) #define IOR_CZNV(X) (regflags.cznv |= (X))
#define SET_CZNV(flags, X) ((flags)->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 * 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) { switch (cc) {
case 0: return 1; /* T */ case 0: return 1; /* T */
......
...@@ -31,89 +31,82 @@ ...@@ -31,89 +31,82 @@
* *
* Evaluate operand and set Z and N flags. Always clear C and V. * Evaluate operand and set Z and N flags. Always clear C and V.
*/ */
#define optflag_testl(regs, v) \ #define optflag_testl (v) \
do { \ do { \
uae_u32 tmp; \ asm ( \
asm ( \ "cmpi cr0, %2, 0 \n\t" \
"cmpi cr0, %2, 0 \n\t" \ "mfcr %1 \n\t" \
"mfcr %1 \n\t" \ "rlwinm %0, %1, 0, 0, 3 \n\t" \
"rlwinm %0, %1, 0, 0, 3 \n\t" \ \
\ :: "r" (v) \
: "=r" ((regs)->ccrflags.cznv), \ : "cr0" \
"=r" (tmp) \ ); \
: "r" (v) \
: "cr0" \
); \
} while (0) } while (0)
#define optflag_testw(regs, v) optflag_testl(regs, (uae_s32)(v)) #define optflag_testw(v) optflag_testl((uae_s32)(v))
#define optflag_testb(regs, v) optflag_testl(regs, (uae_s32)(v)) #define optflag_testb(v) optflag_testl((uae_s32)(v))
/* /*
* Add operations * Add operations
* *
* Perform v = s + d and set ZNCV accordingly * Perform v = s + d and set ZNCV accordingly
*/ */
#define optflag_addl(regs, v, s, d) \ #define optflag_addl(v, s, d) \
do { \ do { \
asm ( \ asm ( \
"addco. %1, %2, %3 \n\t" \ "addco. %1, %2, %3 \n\t" \
"mcrxr cr2 \n\t" \ "mcrxr cr2 \n\t" \
"mfcr %0 \n\t" \ "mfcr %0 \n\t" \
\ \
: "=r" ((regs)->ccrflags.cznv), "=r" (v) \ : "=r" (v) \
: "r" (s), "r" (d) \ : "r" (s), "r" (d) \
: "cr0", "cr2" DEP_XER \ : "cr0", "cr2" DEP_XER \
); \ ); \
COPY_CARRY(&(regs)->ccrflags); \ regflags.x = regflags.cznv; \
} while (0) } 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_addw(v, s, d) do { optflag_addl((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_addb(v, s, d) do { optflag_addl((v), (s) << 24, (d) << 24); v = v >> 24; } while (0)
/* /*
* Subtraction operations * Subtraction operations
* *
* Perform v = d - s and set ZNCV accordingly * Perform v = d - s and set ZNCV accordingly
*/ */
#define optflag_subl(regs, v, s, d) \ #define optflag_subl(v, s, d) \
do { \ do { \
asm ( \ asm ( \
"subfco. %1, %2, %3 \n\t" \ "subfco. %1, %2, %3 \n\t" \
"mcrxr cr2 \n\t" \ "mcrxr cr2 \n\t" \
"mfcr %0 \n\t" \ "mfcr %0 \n\t" \
"xoris %0,%0,32 \n\t" \ "xoris %0,%0,32 \n\t" \
\ \
: "=r" ((regs)->ccrflags.cznv), \ : "=r" (v) \
"=r" (v) \ : "r" (s), \
: "r" (s), \ "r" (d) \
"r" (d) \ : "cr0", "cr2" DEP_XER \
: "cr0", "cr2" DEP_XER \ ); \
); \ regflags.x = regflags.cznv; \
COPY_CARRY(&(regs)->ccrflags); \
} while (0) } 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_subw(v, s, d) do { optflag_subl(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_subb(v, s, d) do { optflag_subl(v, (s) << 24, (d) << 24); v = v >> 24; } while (0)
#define optflag_cmpl(regs, s, d) \ #define optflag_cmpl(s, d) \
do { \ do { \
uae_s32 tmp; \ asm ( \
asm ( \ "subfco. %1, %2, %3 \n\t" \
"subfco. %1, %2, %3 \n\t" \ "mcrxr cr2 \n\t" \
"mcrxr cr2 \n\t" \ "mfcr %0 \n\t" \
"mfcr %0 \n\t" \ "xoris %0,%0,32 \n\t" \
"xoris %0,%0,32 \n\t" \ \
\ :: "r" (s), \
: "=r" ((regs)->ccrflags.cznv), \ "r" (d) \
"=r" (tmp) \ : "cr0", "cr2" DEP_XER \
: "r" (s), \ ); \
"r" (d) \
: "cr0", "cr2" DEP_XER \
); \
} while (0) } while (0)
#define optflag_cmpw(regs, s, d) optflag_cmpl(regs, (s) << 16, (d) << 16) #define optflag_cmpw(s, d) optflag_cmpl((s) << 16, (d) << 16)
#define optflag_cmpb(regs, s, d) optflag_cmpl(regs, (s) << 24, (d) << 24) #define optflag_cmpb(s, d) optflag_cmpl((s) << 24, (d) << 24)
#endif /* EUAE_MACHDEP_M68KOPS_H */ #endif /* EUAE_MACHDEP_M68KOPS_H */
...@@ -925,3 +925,45 @@ TCHAR *au_copy (TCHAR *dst, int maxlen, const char *src) ...@@ -925,3 +925,45 @@ TCHAR *au_copy (TCHAR *dst, int maxlen, const char *src)
memcpy (dst, src, maxlen); memcpy (dst, src, maxlen);
return dst; 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 * UAE - The Un*x Amiga Emulator
* *
* A4000T NCR 53C710 SCSI (nothing done yet) * A4000T NCR 53C710 SCSI (nothing done yet)
* *
* (c) 2007 Toni Wilen * (c) 2007 Toni Wilen
*/ */
#ifdef NCR #ifdef NCR
#define NCR_LOG 1 #define NCR_LOG 1
...@@ -47,24 +47,24 @@ static struct ncrscsi regsinfo[] = ...@@ -47,24 +47,24 @@ static struct ncrscsi regsinfo[] =
{ {
"SCNTL0", 0, 3, "SCNTL0", 0, 3,
"SCNTL1", 1, 2, "SCNTL1", 1, 2,
"SDID", 2, 1, "SDID", 2, 1,
"SIEN", 3, 0, "SIEN", 3, 0,
"SCID", 4, 7, "SCID", 4, 7,
"SXFER", 5, 6, "SXFER", 5, 6,
"SODL", 6, 5, "SODL", 6, 5,
"SOCL", 7, 4, "SOCL", 7, 4,
"SFBR", 8, 11, "SFBR", 8, 11,
"SIDL", 9, 10, "SIDL", 9, 10,
"SBDL", 10, -1, "SBDL", 10, -1,
"SBCL", 11, 8, "SBCL", 11, 8,
"DSTAT", 12, 15, "DSTAT", 12, 15,
"SSTAT0", 13, 14, "SSTAT0", 13, 14,
"SSTAT1", 14, 13, "SSTAT1", 14, 13,
"SSTAT2", 15, 12, "SSTAT2", 15, 12,
"DSA0", 16, 19, "DSA0", 16, 19,
"DSA1", 17, 18, "DSA1", 17, 18,
"DSA2", 18, 17, "DSA2", 18, 17,
"DSA3", 19, 16, "DSA3", 19, 16,
"CTEST0", 20, 23, "CTEST0", 20, 23,
"CTEST1", 21, 22, "CTEST1", 21, 22,
"CTEST2", 22, 21, "CTEST2", 22, 21,
...@@ -80,19 +80,19 @@ static struct ncrscsi regsinfo[] = ...@@ -80,19 +80,19 @@ static struct ncrscsi regsinfo[] =
"DFIFO", 32, 35, "DFIFO", 32, 35,
"ISTAT", 33, 34, "ISTAT", 33, 34,
"CTEST8", 34, 33, "CTEST8", 34, 33,
"LCRC", 35, 32, "LCRC", 35, 32,
"DBC0", 36, 39, "DBC0", 36, 39,
"DBC1", 37, 38, "DBC1", 37, 38,
"DBC2", 38, 37, "DBC2", 38, 37,
"DCMD", 39, 36, "DCMD", 39, 36,
"DNAD0", 40, 43, "DNAD0", 40, 43,
"DNAD1", 41, 42, "DNAD1", 41, 42,
"DNAD2", 42, 41, "DNAD2", 42, 41,
"DNAD3", 43, 40, "DNAD3", 43, 40,
"DSP0", 44, 47, "DSP0", 44, 47,
"DSP1", 45, 46, "DSP1", 45, 46,
"DSP2", 46, 45, "DSP2", 46, 45,
"DSP3", 47, 44, "DSP3", 47, 44,
"DSPS0", 48, 51, "DSPS0", 48, 51,
"DSPS1", 49, 50, "DSPS1", 49, 50,
"DSPS2", 50, 49, "DSPS2", 50, 49,
...@@ -102,8 +102,8 @@ static struct ncrscsi regsinfo[] = ...@@ -102,8 +102,8 @@ static struct ncrscsi regsinfo[] =
"SCRATCH2", 54, 53, "SCRATCH2", 54, 53,
"SCRATCH3", 55, 52, "SCRATCH3", 55, 52,
"DMODE", 56, 59, "DMODE", 56, 59,
"DIEN", 57, 58, "DIEN", 57, 58,
"DWT", 58, 57, "DWT", 58, 57,
"DCNTL", 59, 56, "DCNTL", 59, 56,
"ADDER0", 60, 63, "ADDER0", 60, 63,
"ADDER1", 61, 62, "ADDER1", 61, 62,
......
...@@ -797,7 +797,7 @@ void read_table68k (void) ...@@ -797,7 +797,7 @@ void read_table68k (void)
} }
} }
static int mismatch; static int imismatch;
static void handle_merges (long int opcode) static void handle_merges (long int opcode)
{ {
...@@ -852,20 +852,20 @@ 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].suse != table68k[opcode].suse
|| table68k[code].duse != table68k[opcode].duse) || table68k[code].duse != table68k[opcode].duse)
{ {
mismatch++; continue; imismatch++; continue;
} }
if (table68k[opcode].suse if (table68k[opcode].suse
&& (table68k[opcode].spos != table68k[code].spos && (table68k[opcode].spos != table68k[code].spos
|| table68k[opcode].smode != table68k[code].smode || table68k[opcode].smode != table68k[code].smode
|| table68k[opcode].stype != table68k[code].stype)) || table68k[opcode].stype != table68k[code].stype))
{ {
mismatch++; continue; imismatch++; continue;
} }
if (table68k[opcode].duse if (table68k[opcode].duse
&& (table68k[opcode].dpos != table68k[code].dpos && (table68k[opcode].dpos != table68k[code].dpos
|| table68k[opcode].dmode != table68k[code].dmode)) || table68k[opcode].dmode != table68k[code].dmode))
{ {
mismatch++; continue; imismatch++; continue;
} }
if (code != opcode) if (code != opcode)
...@@ -878,7 +878,7 @@ void do_merges (void) ...@@ -878,7 +878,7 @@ void do_merges (void)
{ {
long int opcode; long int opcode;
int nr = 0; int nr = 0;
mismatch = 0; imismatch = 0;
for (opcode = 0; opcode < 65536; opcode++) { for (opcode = 0; opcode < 65536; opcode++) {
if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
continue; continue;
...@@ -890,5 +890,5 @@ void do_merges (void) ...@@ -890,5 +890,5 @@ void do_merges (void)
int get_no_mismatches (void) int get_no_mismatches (void)
{ {
return mismatch; return imismatch;
} }
...@@ -42,11 +42,11 @@ ...@@ -42,11 +42,11 @@
#define O_NONBLOCK O_NDELAY #define O_NONBLOCK O_NDELAY
#endif #endif
#define SERIALDEBUG 1 /* 0, 1, 2 3 */ #define SERIALDEBUG 1 /* 0, 1, 2 3 */
#define MODEMTEST 0 /* 0 or 1 */ #define MODEMTEST 0 /* 0 or 1 */
void serial_open(void); void serial_open (void);
void serial_close(void); void serial_close (void);
void serial_init (void); void serial_init (void);
void serial_exit (void); void serial_exit (void);
......
...@@ -445,7 +445,7 @@ configure:4344: $? = 0 ...@@ -445,7 +445,7 @@ configure:4344: $? = 0
configure:4344: result: yes configure:4344: result: yes
configure:4350: checking for _doprnt configure:4350: checking for _doprnt
configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 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' /home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4350: $? = 1 configure:4350: $? = 1
...@@ -533,7 +533,7 @@ configure:4364: $? = 0 ...@@ -533,7 +533,7 @@ configure:4364: $? = 0
configure:4364: result: yes configure:4364: result: yes
configure:4364: checking for strcmpi configure:4364: checking for strcmpi
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 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' /home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4364: $? = 1 configure:4364: $? = 1
...@@ -613,7 +613,7 @@ configure: failed program was: ...@@ -613,7 +613,7 @@ configure: failed program was:
configure:4364: result: no configure:4364: result: no
configure:4364: checking for stricmp configure:4364: checking for stricmp
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5 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' /home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
configure:4364: $? = 1 configure:4364: $? = 1
......
/* /*
* E-UAE - The portable Amiga Emulator * E-UAE - The portable Amiga Emulator
* *
* Support for traps * Support for traps
* *
* Copyright Richard Drummond 2005 * Copyright Richard Drummond 2005
* *
* Inspired by code from UAE: * Inspired by code from UAE:
* Copyright 1995, 1996 Bernd Schmidt * Copyright 1995, 1996 Bernd Schmidt
* Copyright 1996 Ed Hanway * Copyright 1996 Ed Hanway
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
...@@ -63,10 +63,10 @@ ...@@ -63,10 +63,10 @@
*/ */
struct Trap struct Trap
{ {
TrapHandler handler; /* Handler function to be invoked for this trap. */ TrapHandler handler; /* Handler function to be invoked for this trap. */
int flags; /* Trap attributes. */ int flags; /* Trap attributes. */
const TCHAR *name; /* For debugging purposes. */ const TCHAR *name; /* For debugging purposes. */
uaecptr addr; uaecptr addr;
}; };
#define MAX_TRAPS 4096 #define MAX_TRAPS 4096
...@@ -82,14 +82,14 @@ static void trap_HandleExtendedTrap (TrapHandler, int has_retval); ...@@ -82,14 +82,14 @@ static void trap_HandleExtendedTrap (TrapHandler, int has_retval);
uaecptr find_trap (const TCHAR *name) 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]; struct Trap *trap = &traps[i];
if ((trap->flags & TRAPFLAG_UAERES) && trap->name && !_tcscmp (trap->name, name)) if ((trap->flags & TRAPFLAG_UAERES) && trap->name && !_tcscmp (trap->name, name))
return trap->addr; return trap->addr;
} }
return 0; return 0;
} }
...@@ -104,18 +104,18 @@ uaecptr find_trap (const TCHAR *name) ...@@ -104,18 +104,18 @@ uaecptr find_trap (const TCHAR *name)
*/ */
unsigned int define_trap (TrapHandler handler_func, int flags, 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"); write_log ("Ran out of emulator traps\n");
abort (); abort ();
return -1; return -1;
} else { } else {
int i; int i;
unsigned int trap_num; unsigned int trap_num;
struct Trap *trap; struct Trap *trap;
uaecptr addr = here (); uaecptr addr = here ();
for (i = 0; i < trap_count; i++) { for (i = 0; i < trap_count; i++) {
if (addr == traps[i].addr) if (addr == traps[i].addr)
return i; return i;
} }
...@@ -128,7 +128,7 @@ unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name ...@@ -128,7 +128,7 @@ unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name
trap->addr = addr; trap->addr = addr;
return trap_num; return trap_num;
} }
} }
...@@ -140,35 +140,35 @@ unsigned int define_trap (TrapHandler handler_func, int flags, const TCHAR *name ...@@ -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) void REGPARAM2 m68k_handle_trap (unsigned int trap_num)
{ {
struct Trap *trap = &traps[trap_num]; struct Trap *trap = &traps[trap_num];
uae_u32 retval = 0; uae_u32 retval = 0;
int has_retval = (trap->flags & TRAPFLAG_NO_RETVAL) == 0; int has_retval = (trap->flags & TRAPFLAG_NO_RETVAL) == 0;
int implicit_rts = (trap->flags & TRAPFLAG_DORET) != 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); write_log ("TRAP: %s\n", trap->name);
if (trap_num < trap_count) { if (trap_num < trap_count) {
if (trap->flags & TRAPFLAG_EXTRA_STACK) { if (trap->flags & TRAPFLAG_EXTRA_STACK) {
/* Handle an extended trap. /* Handle an extended trap.
* Note: the return value of this trap is passed back to 68k * Note: the return value of this trap is passed back to 68k
* space via a separate, dedicated simple trap which the trap * space via a separate, dedicated simple trap which the trap
* handler causes to be invoked when it is done. * handler causes to be invoked when it is done.
*/ */
trap_HandleExtendedTrap (trap->handler, has_retval); trap_HandleExtendedTrap (trap->handler, has_retval);
} else { } else {
/* Handle simple trap */ /* Handle simple trap */
retval = (trap->handler) (NULL); retval = (trap->handler) (NULL);
if (has_retval) if (has_retval)
m68k_dreg (regs, 0) = retval; m68k_dreg (regs, 0) = retval;
if (implicit_rts) { if (implicit_rts) {
m68k_do_rts (); m68k_do_rts ();
fill_prefetch_slow (); fill_prefetch_slow ();
} }
} }
} else } else
write_log ("Illegal emulator trap %d\n", trap_num); write_log ("Illegal emulator trap %d\n", trap_num);
} }
...@@ -227,41 +227,41 @@ static void *trap_thread (void *arg) ...@@ -227,41 +227,41 @@ static void *trap_thread (void *arg)
{ {
TrapContext *context = (TrapContext *) arg; TrapContext *context = (TrapContext *) arg;
/* Wait until main thread is ready to switch to the /* Wait until main thread is ready to switch to the
* this trap context. */ * this trap context. */
uae_sem_wait (&context->switch_to_trap_sem); uae_sem_wait (&context->switch_to_trap_sem);
/* Execute trap handler function. */ /* Execute trap handler function. */
context->trap_retval = context->trap_handler (context); context->trap_retval = context->trap_handler (context);
/* Trap handler is done - we still need to tidy up /* Trap handler is done - we still need to tidy up
* and make sure the handler's return value is propagated * and make sure the handler's return value is propagated
* to the calling 68k thread. * to the calling 68k thread.
* *
* We do this by causing our exit handler to be executed on the 68k context. * 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! */ /* Enter critical section - only one trap at a time, please! */
uae_sem_wait (&trap_mutex); uae_sem_wait (&trap_mutex);
regs = context->saved_regs; regs = context->saved_regs;
/* Don't allow an interrupt and thus potentially another /* Don't allow an interrupt and thus potentially another
* trap to be invoked while we hold the above mutex. * trap to be invoked while we hold the above mutex.
* This is probably just being paranoid. */ * This is probably just being paranoid. */
regs.intmask = 7; regs.intmask = 7;
/* Set PC to address of the exit handler, so that it will be called /* Set PC to address of the exit handler, so that it will be called
* when the 68k context resumes. */ * when the 68k context resumes. */
m68k_setpc (exit_trap_trapaddr); m68k_setpc (exit_trap_trapaddr);
current_context = context; current_context = context;
/* Switch back to 68k context */ /* Switch back to 68k context */
uae_sem_post (&context->switch_to_emu_sem); uae_sem_post (&context->switch_to_emu_sem);
/* Good bye, cruel world... */ /* Good bye, cruel world... */
/* dummy return value */ /* dummy return value */
return 0; return 0;
} }
/* /*
...@@ -271,11 +271,11 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval) ...@@ -271,11 +271,11 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
{ {
struct TrapContext *context = xcalloc (TrapContext, 1); 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_trap_sem, 0, 0);
uae_sem_init (&context->switch_to_emu_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->trap_has_retval = has_retval;
context->saved_regs = regs; /* Copy of regs to be restored when trap is done */ 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) ...@@ -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 * It'll do this when the trap handler is done - or when
* the handler wants to call 68k code. */ * the handler wants to call 68k code. */
uae_sem_wait (&context->switch_to_emu_sem); uae_sem_wait (&context->switch_to_emu_sem);
} }
} }
/* /*
...@@ -303,34 +303,34 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval) ...@@ -303,34 +303,34 @@ static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
*/ */
static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr) static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr)
{ {
/* Enter critical section - only one trap at a time, please! */ /* Enter critical section - only one trap at a time, please! */
uae_sem_wait (&trap_mutex); uae_sem_wait (&trap_mutex);
current_context = context; current_context = context;
/* Don't allow an interrupt and thus potentially another /* Don't allow an interrupt and thus potentially another
* trap to be invoked while we hold the above mutex. * trap to be invoked while we hold the above mutex.
* This is probably just being paranoid. */ * This is probably just being paranoid. */
regs.intmask = 7; regs.intmask = 7;
/* Set up function call address. */ /* Set up function call address. */
context->call68k_func_addr = func_addr; context->call68k_func_addr = func_addr;
/* Set PC to address of 68k call trap, so that it will be /* Set PC to address of 68k call trap, so that it will be
* executed when emulator context resumes. */ * executed when emulator context resumes. */
m68k_setpc (m68k_call_trapaddr); m68k_setpc (m68k_call_trapaddr);
fill_prefetch_slow (); fill_prefetch_slow ();
/* Switch to emulator context. */ /* Switch to emulator context. */
uae_sem_post (&context->switch_to_emu_sem); uae_sem_post (&context->switch_to_emu_sem);
/* Wait for 68k call return handler to switch back to us. */ /* Wait for 68k call return handler to switch back to us. */
uae_sem_wait (&context->switch_to_trap_sem); uae_sem_wait (&context->switch_to_trap_sem);
/* End critical section. */ /* End critical section. */
uae_sem_post (&trap_mutex); uae_sem_post (&trap_mutex);
/* Get return value from 68k function called. */ /* Get return value from 68k function called. */
return context->call68k_retval; return context->call68k_retval;
} }
/* /*
...@@ -344,31 +344,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx) ...@@ -344,31 +344,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx)
sp = m68k_areg (regs, 7); sp = m68k_areg (regs, 7);
/* Push address of trap context on 68k stack. This is /* Push address of trap context on 68k stack. This is
* so the return trap can find this context. */ * so the return trap can find this context. */
sp -= sizeof (void *); sp -= sizeof (void *);
put_pointer (sp, context); put_pointer (sp, context);
/* Push addr to return handler trap on 68k stack. /* Push addr to return handler trap on 68k stack.
* When the called m68k function does an RTS, the CPU will pull this * When the called m68k function does an RTS, the CPU will pull this
* address off the stack and so call the return handler. */ * address off the stack and so call the return handler. */
sp -= 4; sp -= 4;
put_long (sp, m68k_return_trapaddr); 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. */ /* Set PC to address of 68k function to call. */
m68k_setpc (context->call68k_func_addr); m68k_setpc (context->call68k_func_addr);
fill_prefetch_slow (); fill_prefetch_slow ();
/* End critical section: allow other traps run. */ /* End critical section: allow other traps run. */
uae_sem_post (&trap_mutex); uae_sem_post (&trap_mutex);
/* Restore interrupts. */ /* Restore interrupts. */
regs.intmask = context->saved_regs.intmask; regs.intmask = context->saved_regs.intmask;
/* Dummy return value. */ /* Dummy return value. */
return 0; return 0;
} }
/* /*
...@@ -377,31 +377,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx) ...@@ -377,31 +377,31 @@ static uae_u32 REGPARAM2 m68k_call_handler (TrapContext *dummy_ctx)
static uae_u32 REGPARAM2 m68k_return_handler (TrapContext *dummy_ctx) static uae_u32 REGPARAM2 m68k_return_handler (TrapContext *dummy_ctx)
{ {
TrapContext *context; TrapContext *context;
uae_u32 sp; uae_u32 sp;
/* One trap returning at a time, please! */ /* One trap returning at a time, please! */
uae_sem_wait (&trap_mutex); uae_sem_wait (&trap_mutex);
/* Get trap context from 68k stack. */ /* Get trap context from 68k stack. */
sp = m68k_areg (regs, 7); sp = m68k_areg (regs, 7);
context = (TrapContext *)get_pointer (sp); context = (TrapContext *)get_pointer (sp);
sp += sizeof (void *); sp += sizeof (void *);
m68k_areg (regs, 7) = sp; m68k_areg (regs, 7) = sp;
/* Get return value from the 68k call. */ /* Get return value from the 68k call. */
context->call68k_retval = m68k_dreg (regs, 0); context->call68k_retval = m68k_dreg (regs, 0);
/* Switch back to trap context. */ /* Switch back to trap context. */
uae_sem_post (&context->switch_to_trap_sem); uae_sem_post (&context->switch_to_trap_sem);
/* Wait for trap context to switch back to us. /* Wait for trap context to switch back to us.
* *
* It'll do this when the trap handler is done - or when * It'll do this when the trap handler is done - or when
* the handler wants to call another 68k function. */ * the handler wants to call another 68k function. */
uae_sem_wait (&context->switch_to_emu_sem); uae_sem_wait (&context->switch_to_emu_sem);
/* Dummy return value. */ /* Dummy return value. */
return 0; return 0;
} }
/* /*
...@@ -412,27 +412,27 @@ static uae_u32 REGPARAM2 exit_trap_handler (TrapContext *dummy_ctx) ...@@ -412,27 +412,27 @@ static uae_u32 REGPARAM2 exit_trap_handler (TrapContext *dummy_ctx)
{ {
TrapContext *context = current_context; TrapContext *context = current_context;
/* Wait for trap context thread to exit. */ /* Wait for trap context thread to exit. */
uae_wait_thread (context->thread); uae_wait_thread (context->thread);
/* Restore 68k state saved at trap entry. */ /* Restore 68k state saved at trap entry. */
regs = context->saved_regs; regs = context->saved_regs;
/* If trap is supposed to return a value, then store /* If trap is supposed to return a value, then store
* return value in D0. */ * return value in D0. */
if (context->trap_has_retval) if (context->trap_has_retval)
m68k_dreg (regs, 0) = context->trap_retval; m68k_dreg (regs, 0) = context->trap_retval;
uae_sem_destroy (&context->switch_to_trap_sem); uae_sem_destroy (&context->switch_to_trap_sem);
uae_sem_destroy (&context->switch_to_emu_sem); uae_sem_destroy (&context->switch_to_emu_sem);
xfree (context); xfree (context);
/* End critical section */ /* End critical section */
uae_sem_post (&trap_mutex); uae_sem_post (&trap_mutex);
/* Dummy return value. */ /* Dummy return value. */
return 0; return 0;
} }
...@@ -442,14 +442,14 @@ static uae_u32 REGPARAM2 exit_trap_handler (TrapContext *dummy_ctx) ...@@ -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 CallLib (TrapContext *context, uaecptr base, uae_s16 offset)
{ {
uae_u32 retval; uae_u32 retval;
uaecptr olda6 = m68k_areg (regs, 6); uaecptr olda6 = m68k_areg (regs, 6);
m68k_areg (regs, 6) = base; m68k_areg (regs, 6) = base;
retval = trap_Call68k (context, base + offset); retval = trap_Call68k (context, base + offset);
m68k_areg (regs, 6) = olda6; m68k_areg (regs, 6) = olda6;
return retval; return retval;
} }
/* /*
...@@ -466,7 +466,7 @@ uae_u32 CallFunc (TrapContext *context, uaecptr func) ...@@ -466,7 +466,7 @@ uae_u32 CallFunc (TrapContext *context, uaecptr func)
*/ */
void init_traps (void) void init_traps (void)
{ {
trap_count = 0; trap_count = 0;
} }
/* /*
...@@ -474,14 +474,14 @@ void init_traps (void) ...@@ -474,14 +474,14 @@ void init_traps (void)
*/ */
void init_extended_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")); 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")); 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")); 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