⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d52pass2.c

📁 這是一個8051的模擬器 以java寫成
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
 * D52 8052 Disassembler
 * Copyright (C) 1995-2004 by Jeffery L. Post
 * theposts <AT> pacbell <DOT> net
 *
 * d52pass2.C - Disassembly pass 2
 *
 * Version 3.3.6 - 11/28/04
 *
 *	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
 *
 */

#include	<stdio.h>
#include	<stdlib.h>
#include	<ctype.h>
#include	<string.h>
#include	<time.h>

#include	"d52.h"
#include	"common.h"
#include	"d52pass1.h"
#include	"d52pass2.h"
#include	"d52table.h"

//
//		Defined Constants
//
/* none */

//
//		Global variables
//
/* none */

//
// Pass two of disassembly. Rescan data array and generate output file.
// Generate label if location flagged as referenced by some other opcode.
// If un-initialized data is encountered, ignore it but set skip flag so
// that an ORG statement can be generated when the next initialized data
// is found.
//

void pass2(void)
{
	char		*cptr;
	int		skip, year;
	int		i, l, q, temp, oldpc;
	byte		j, k;
	int		pflag;
	time_t	tp;

	if (upperflag)			// convert SFR, register, etc text to upper case
	{
		for (i=0; i<128; i++)
			makeupper(sfr[i].dent);
		for (i=0; i<128; i++)
			makeupper(keilsfr[i].dent);
		for (i=0; i<128; i++)
			makeupper(sfrbits[i].dent);
		for (i=0; i<128; i++)
			makeupper(keilsfrbits[i].dent);
		for (i=0; i<128; i++)
			makeupper(membits[i].dent);
		for (i=0; i<128; i++)
			makeupper(keilmembits[i].dent);
		for (i=0; i<128; i++)
			makeupper(rbname[i].dent);
	}

	k = 0;
	j = 0xff;
	skip = TRUE;
	dump = FALSE;
	byte_cnt = 0;
	asc_cnt = 0;
	newline = FALSE;

	printf("\nPass 2 0000");

	fp = fopen(dst, "w");							// open output source file

	if (!fp)
	{
		printf("\n* Can't open output file %s *\n", dst);
		exit(FILE_ERROR);
	}
															// output header
	fprintf(fp, ";\n;  D52 V%d.%d.%d 8052 Disassembly of %s", VERSION, MAJORREV, MINORREV, src);

	time(&tp);									// get current time
	date_time = localtime(&tp);			// convert to hr/min/day etc
	year = date_time->tm_year;

	while (year > 100)
		year -= 100;

	fprintf(fp, "\n;  %02d/%02d/%02d %02d:%02d", date_time->tm_mon + 1,
		date_time->tm_mday, year,
		date_time->tm_hour, date_time->tm_min);

	if (incflag)
		fprintf(fp, "\n;\n\tinclude\t\"sfr52.inc\"");

	if (ascii_flag)					// if user specified A on command line...
	{
		fprintf(fp, "\n;\nascii\tmacro\tx");		// generate macro for text
		fprintf(fp, "\n\t%s\t'#x#'", defbstr);
		fprintf(fp, "\n\tendm");
		strcpy(ascistr, "ascii");
	}

//
//  Generate output file
//
	for (i=offset; i<=himark; )
	{
		if (pgmflags[i] & PF_CMT)
		{
			if (byte_cnt)							// dump any pending binary
				dump_bytes(i);

			if (asc_cnt)							// dump any accumulated ascii
				dump_ascii(i);

			output_comment(i);
		}

		if (pgmflags[i] & PF_PATCH)
		{
			if (byte_cnt)					// dump any pending binary
				dump_bytes(i);

			if (asc_cnt)					// dump any accumulated ascii
				dump_ascii(i);

			output_patch(i);
		}

		oldpc = i;
		l = i & 0xff;
		pflag = pgmflags[i];

		if (pflag == PF_INIT)					// ignore un-initialized data
		{
			if (byte_cnt)				// if binary or ascii data in buffers...
				dump_bytes(i);			// output them now

			if (asc_cnt)
				dump_ascii(i);

			if (dump)					// if we had to flush buffers...
			{								// do a newline, since we will
				dump = FALSE;			// be doing an org (or end)
				fprintf(fp, "\n;");
				newline = TRUE;
			}
			i++;							// next program location
			skip = TRUE;				// flag skip for ORG statement
			j = -1;
		}
		else if (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII))
		{												// if not executable code
			if (!(j & 0x80) && !skip)
			{
				j = -1;
				fprintf(fp, "\n;");
				newline = TRUE;
			}

			switch (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII))	// ignore irrelevant bits
			{
				case PF_ASCII:						// if ascii text...
					if (byte_cnt)					// dump any pending binary
						dump_bytes(i);

					if (skip)						// insert ORG statement
					{
						if (!newline)
							fprintf(fp, "\n;");

						fprintf(fp, "\n\t%s\t", orgstr);
						puthex(i);
						fprintf(fp, "\n;");
						newline = TRUE;
						skip = FALSE;				// reset skip flag
					}

					if (is_ascii(pgmmem[i]))	// if it really is ascii...
					{
						string[asc_cnt] = pgmmem[i];
						asc_cnt++;

						if (asc_cnt >= ASCLIMIT)
							dump_ascii(i + 1);
					}
					else								// else treat it as binary data
					{
						pgmflags[i] |= PF_BYTE;

						if (asc_cnt)				// dump any accumulated ascii

							dump_ascii(i);
						byte_data[byte_cnt] = pgmmem[i];	// add data to buffer
						byte_cnt++;
					}
					break;

				case PF_WORD:					// if word data...
					if (byte_cnt)			// dump any binary or ascii in buffers
						dump_bytes(i);

					if (asc_cnt)
						dump_ascii(i);

					if (skip)					// insert ORG statement
					{
						if (!newline)
							fprintf(fp, "\n;");

						fprintf(fp, "\n\t%s\t", orgstr);
						puthex(i);
						fprintf(fp, "\n;");
						newline = TRUE;
						skip = FALSE;			// reset skip flag
					}

					chk_label(i);							// add label if referenced
					q = ((int) pgmmem[i] & 0xff) << 8;	// get word value
					temp = pgmmem[i + 1] & 0xff;
					q |= temp;
					fprintf(fp, "%s\t", defwstr);
					cptr = find_entry(q, symbol_count, sym_val_index);	// see if symbol exists

					if (cptr == NULL)						// if not, do hex value
						puthex(q);
					else
						fprintf(fp, "%s", cptr);		// else output symbol

					if (hexflag)							// add comment field
					{
						fprintf(fp, "\t\t; %04x   %02x %02x      %c%c",
							i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]),
							ascii(pgmmem[i + 1]));
					}

					if (pgmflags[i] & PF_ICMT)
						output_icomment(i);

					i++;

					if (pgmflags[i + 2] != PF_ADRS && pgmflags[i + 2] != PF_WORD)
					{
						fprintf(fp, "\n;");
						newline = TRUE;
					}
					break;

				case PF_ADRS:					// if address data...
					if (byte_cnt)				// output any pending binary or
						dump_bytes(i);			// ascii data from buffers

					if (asc_cnt)
						dump_ascii(i);

					if (skip)					// insert ORG statement
					{
						if (!newline)
							fprintf(fp, "\n;");

						fprintf(fp, "\n\t%s\t", orgstr);
						puthex(i);
						fprintf(fp, "\n;");
						newline = TRUE;
						skip = FALSE;			// reset skip flag
					}

					chk_label(i);							// add label if referenced
					q = ((int) pgmmem[i]) << 8;	// get address value
					temp = pgmmem[i + 1] & 0xff;
					q |= temp;
					fprintf(fp, "%s\t", defwstr);
					cptr = find_entry(q, label_count, lab_val_index);
																// see if label exists
					if (cptr == NULL)						// if not, output hex
					{
						if (!pgmflags[i] & PF_LABEL)	// search symbol table only if not defined as label
							cptr = find_entry(q, symbol_count, sym_val_index);

						if (cptr == NULL)
						{
							if (!upperflag)
								fprintf(fp, "X%04x", q);
							else
								fprintf(fp, "X%04X", q);
						}
						else
							fprintf(fp, "%s", cptr);
					}
					else
						fprintf(fp, "%s", cptr);		// else output label text

					if (hexflag)							// do comment field
					{
						fprintf(fp, "\t\t; %04x   %02x %02x      %c%c",
							i, pgmmem[i], pgmmem[i + 1],
							ascii(pgmmem[i]), ascii(pgmmem[i + 1]));
					}

					if (pgmflags[i] & PF_ICMT)
						output_icomment(i);

					i++;

					if (pgmflags[i + 2] != PF_ADRS)
					{
						fprintf(fp, "\n;");
						newline = TRUE;
					}
					break;

				default:							// default = binary data...
					if (asc_cnt)				// output any pending ascii data
						dump_ascii(i);

					if (skip)					// insert ORG statement
					{
						if (byte_cnt)
							dump_bytes(i);

						if (!newline)
							fprintf(fp, "\n;");

						fprintf(fp, "\n\t%s\t", orgstr);
						puthex(i);
						fprintf(fp, "\n;");
						newline = TRUE;
						skip = FALSE;			// reset skip flag
					}

					byte_data[byte_cnt] = pgmmem[i];	// add data to buffer
					byte_cnt++;

					if (byte_cnt >= BYTELIMIT)			// if end of buffer...
						dump_bytes(i + 1);				// dump accumulated data
			}

			i++;									// next program location

			if (pgmflags[i] != PF_INIT && pgmflags[i] & PF_ASCII)
			{											// if next byte is flagged as
				if (!is_ascii(pgmmem[i]))		// ascii, but is not...
					pgmflags[i] |= PF_BYTE;		// then flag it as binary
			}
		}

//
// If previous data was an unconditional transfer, AND
// current location is not referenced by some other opcode, AND
// current byte is 0 or 0FFH, THEN
// treat this byte as un-initialized data.
//
		else if ((j & 0x80) && (!(pflag & PF_REF)) &&
			((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) &&
			(!(pflag & PF_FORCE)))
		{
			if (byte_cnt)				// since we're going to skip some
				dump_bytes(i);			// data, output any pending ascii

			if (asc_cnt)				// or binary data remaining in buffers
				dump_ascii(i);

			if (dump)					// if ascii or binary output was done,
			{								// stick in a newline
				fprintf(fp, "\n;");
				dump = FALSE;
				newline = TRUE;
			}

			pgmflags[i] = PF_INIT;	// flag as uninitialized data
			i++;
			skip = TRUE;
			byte_cnt = 0;
		}

//
// If previous opcode was 0 or 0ffH, AND current location is not
// referenced but is initialized, AND current opcode is 0 or 0ffH,
// un-initialize it.
//
		else if ((k == 0 || k == 0xff) &&
			(!(pflag & PF_REF)) && (pgmmem[i] == 0 || pgmmem[i] == NO_DATA) &&
			(!(pflag & PF_CLREF)) && !(pflag & PF_NOINIT) &&
			(!(pflag & PF_FORCE)))
		{
			pgmflags[i] = PF_INIT;
			i++;
			skip = TRUE;
			j = -1;
		}

		else								// IT'S EXECUTABLE CODE!
		{
			pgmflags[i] &= ~PF_NOINIT;	// clear for label search in pass 3

			if (byte_cnt)				// if any ascii or binary data remains
				dump_bytes(i);			// in the buffers, output them now

			if (asc_cnt)
				dump_ascii(i);

			if (dump)
			{
				fprintf(fp, "\n;");
				dump = FALSE;
				newline = TRUE;
			}

			byte_cnt = 0;

			if (skip)						// insert ORG statement
			{
				if (!newline)
					fprintf(fp, "\n;");

				fprintf(fp, "\n\t%s\t", orgstr);
				puthex(i);
				fprintf(fp, "\n;");
				newline = TRUE;
				skip = FALSE;				// reset skip flag
			}

			k = pgmmem[i];						// get opcode

			if (k == 0xa5 && !newline)		// if invalid opcode
			{
				fprintf(fp, "\n;");
				newline = TRUE;
			}

			chk_ref(i);							// add label if referenced
			kcnt = 8;
			j = opttbl[k];						// get options
			doopcode(mnemtbl[k].mnem);		// output mnemonic

//
// Generate operands
//
			switch (j & OPT_MASK)
			{
				case OPT_NONE:					// single byte - no options
					break;

				case OPT_IMM2:					// 2 byte immediate data
					q = (int) pgmmem[i + 1] & 0xff;

					if (pgmflags[i + 1] & PF_NAME)
						cptr = find_entry(i + 1, name_count, name_val_index);
					else
						cptr = find_entry(q, symbol_count, sym_val_index);

					if (cptr == NULL)
						puthex(q);
					else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -