ftp.nice.ch/pub/next/tools/emulators/vice.0.15.0.NeXT.sd.tgz#/vice-0.15.0/src/misc.c

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.