This is misc.c in view mode; [Download] [Up]
/*
* misc.c - Miscellaneous functions for debugging.
*
* Written by
* Vesa-Matti Puro (vmp@lut.fi)
* Jarkko Sonninen (sonninen@lut.fi)
* Jouko Valta (jopi@stekt.oulu.fi)
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
/*
* This file contains misc funtions to help debugging.
* Included are:
* o Show numeric conversions
* o Show CPU registers
* o Show Stack contents
* o Print binary number
* o Print instruction hexas from memory
* o Print instruction from memory
* o Decode instruction
* o Find effective address for operand
* o Create a copy of string
* o Move memory
*
* sprint_opcode returns mnemonic code of machine instruction.
* sprint_binary returns binary form of given code (8bit)
*
*/
#include "vice.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "maincpu.h"
#include "misc.h"
#include "mshell.h"
#include "asm.h"
#include "resources.h"
#include "mon.h"
#define HEX 1
/*
* show prints PSW and contents of registers.
*/
#if 0
void show(void)
{
printf(app_resources.hexFlag ? "%lx %4X %s\n" : "%ld %4d %s\n",
clk, maincpu_regs.pc,
sprint_opcode(maincpu_regs.pc, app_resources.hexFlag));
}
#endif
void print_stack(BYTE sp)
{
int i;
printf("Stack: ");
for (i = 0x101 + sp; i < 0x200; i += 2)
printf("%02X%02X ", ram[i + 1], ram[i]);
printf("\n");
}
char *sprint_binary(BYTE code)
{
static char bin[9];
int i;
bin[8] = 0; /* Terminator. */
for (i = 0; i < 8; i++) {
bin[i] = (code & 128) ? '1' : '0';
code <<= 1;
}
return bin;
}
/* ------------------------------------------------------------------------- */
char *sprint_ophex (ADDRESS p)
{
static char hexbuf [20];
char *bp;
int j, len;
len = clength[lookup[mem_read(p)].addr_mode];
*hexbuf = '\0';
for (j = 0, bp = hexbuf; j < 3 ; j++, bp += 3) {
if (j < len) {
sprintf (bp, "%02X ", mem_read(p+j));
} else {
strcat (bp, " ");
}
}
return hexbuf;
}
char *sprint_opcode(ADDRESS counter, int base)
{
BYTE x = mem_read(counter);
BYTE p1 = mem_read(counter + 1);
BYTE p2 = mem_read(counter + 2);
return sprint_disassembled(counter, x, p1, p2, base);
}
char *sprint_disassembled(ADDRESS counter,
BYTE x, BYTE p1, BYTE p2, int base)
{
static char buff[20];
const char *string;
char *buffp, *addr_name;
int addr_mode;
int ival;
ival = p1 & 0xFF;
buffp = buff;
string = lookup[x].mnemonic;
addr_mode = lookup[x].addr_mode;
sprintf(buff, "$%02X %s", x, string); /* Print opcode and mnemonic. */
while (*++buffp);
switch (addr_mode) {
/*
* Bits 0 and 1 are usual marks for X and Y indexed addresses, i.e.
* if bit #0 is set addressing mode is X indexed something and if
* bit #1 is set addressing mode is Y indexed something. This is not
* from MOS6502, but convention used in this program. See
* "vmachine.h" for details.
*/
/* Print arguments of the machine instruction. */
case IMPLIED:
break;
case ACCUMULATOR:
sprintf(buffp, " A");
break;
case IMMEDIATE:
sprintf(buffp, ((base & HEX) ? " #$%02X" : " %3d"), ival);
break;
case ZERO_PAGE:
sprintf(buffp, ((base & HEX) ? " $%02X" : " %3d"), ival);
break;
case ZERO_PAGE_X:
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%02X,X" : " %3d,X"), ival);
else
sprintf(buffp, " %s,X", addr_name);
break;
case ZERO_PAGE_Y:
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%02X,Y" : " %3d,Y"), ival);
else
sprintf(buffp, " %s,Y", addr_name);
break;
case ABSOLUTE:
ival |= ((p2 & 0xFF) << 8);
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%04X" : " %5d"), ival);
else
sprintf(buffp, " %s", addr_name);
break;
case ABSOLUTE_X:
ival |= ((p2 & 0xFF) << 8);
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%04X,X" : " %5d,X"), ival);
else
sprintf(buffp, " %s,X", addr_name);
break;
case ABSOLUTE_Y:
ival |= ((p2 & 0xFF) << 8);
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%04X,Y" : " %5d,Y"), ival);
else
sprintf(buffp, " %s,Y", addr_name);
break;
case INDIRECT_X:
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " ($%02X,X)" : " (%3d,X)"), ival);
else
sprintf(buffp, " (%s,X)", addr_name);
break;
case INDIRECT_Y:
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " ($%02X),Y" : " (%3d),Y"), ival);
else
sprintf(buffp, " (%s),Y", addr_name);
break;
case ABS_INDIRECT:
ival |= ((p2 & 0xFF) << 8);
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " ($%04X)" : " (%5d)"), ival);
else
sprintf(buffp, " (%s)", addr_name);
break;
case RELATIVE:
if (0x80 & ival)
ival -= 256;
ival += counter;
ival += 2;
if ( !(addr_name = mon_symbol_table_lookup_name(e_comp_space, ival)) )
sprintf(buffp, ((base & HEX) ? " $%04X" : " %5d"), ival);
else
sprintf(buffp, " %s", addr_name);
break;
}
return buff;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.