1  /**************************************************************************\
2  *						Microchip PIC16C5x Emulator							*
3  *																			*
4  *					  Copyright (C) 2003+ Tony La Porta						*
5  *				   Originally written for the MAME project.					*
6  *																			*
7  *																			*
8  *		Notes : Data is expected to be read from source file as LSB first.	*
9  *																			*
10  \**************************************************************************/
11 
12 #include <stdio.h>
13 #include <string.h>
14 
15 #include "16c5xdsm.c"
16 
17 
18 unsigned char *Buffer;
19 
20 
main(int argc,char * argv[])21 int main(int argc,char *argv[])
22 {
23 	int  length=0, length_to_dump=0, offset=0, disasm_words=0;
24 	int  filelength=0, bytes_read;
25 	int  Counter=0;
26 
27 	FILE *F;
28 	char *String_Output;
29 
30 	if(argc<2)
31 	{
32 		log_cb(RETRO_LOG_INFO, LOGPRE "\n");
33 		log_cb(RETRO_LOG_INFO, LOGPRE "PIC16C5x Disassembler 1.0 by Tony La Porta (C)2003+\n\n");
34 		log_cb(RETRO_LOG_INFO, LOGPRE "Usage: dis16c5x <input-file> [ <start-addr> [ <num-of-addr> ] ]\n");
35 		log_cb(RETRO_LOG_INFO, LOGPRE "                <input-file>  source file data must be MSB first\n");
36 		log_cb(RETRO_LOG_INFO, LOGPRE "                <start-addr>  starting address to disassemble from (decimal)\n");
37 		log_cb(RETRO_LOG_INFO, LOGPRE "                <num-of-addr> number of addresses to disassemble (decimal)\n");
38 		log_cb(RETRO_LOG_INFO, LOGPRE "                              Preceed values with 0x if HEX values preffered\n");
39 		exit(1);
40 	}
41 
42 	if(!(F=fopen(argv[1],"rb")))
43 	{
44 		log_cb(RETRO_LOG_DEBUG, LOGPRE "\n%s: Can't open file %s\n",argv[0],argv[1]);
45 		exit(2);
46 	}
47 	argv++; argc--;
48 	if (argv[1])
49 	{
50 		offset = strtol(argv[1],NULL,0);
51 		argv++; argc--;
52 	}
53 	if (argv[1])
54 	{
55 		length = strtol(argv[1],NULL,0);
56 		argv++; argc--;
57 	}
58 
59 	fseek(F,0, SEEK_END);
60 	filelength = ftell(F);
61 
62 	length *= 2;
63 
64 	if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2);
65 	log_cb(RETRO_LOG_INFO, LOGPRE "Length=%04Xh(words)  Offset=$%04Xh  filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength);
66 	length_to_dump = length;
67 	log_cb(RETRO_LOG_INFO, LOGPRE "Starting from %d, dumping %d opcodes (word size)\n",offset,length/2);
68 	Buffer = calloc((filelength+1),sizeof(char));
69 	if (Buffer==NULL)
70 	{
71 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Out of Memory !!!");
72 		fclose(F);
73 		exit(3);
74 	}
75 	String_Output = calloc(80,sizeof(char));
76 	if (String_Output==NULL)
77 	{
78 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Out of Memory !!!");
79 		free(Buffer);
80 		fclose(F);
81 		exit(4);
82 	}
83 
84 	if (fseek(F,0,SEEK_SET) != 0)
85 	{
86 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Error seeking to beginning of file\n");
87 		free(String_Output);
88 		free(Buffer);
89 		fclose(F);
90 		exit(5);
91 	}
92 
93 	Counter = offset;
94 	bytes_read = fread(Buffer,sizeof(char),filelength,F);
95 	if (bytes_read >= length)
96 	{
97 		for (; length > 0; length -= (disasm_words*2))
98 		{
99 			int ii;
100 			disasm_words = Dasm16C5x(String_Output,Counter);
101 			log_cb(RETRO_LOG_INFO, LOGPRE "$%03X: ",Counter);
102 			for (ii = 0; ii < disasm_words; ii++)
103 			{
104 				if (((Counter*2) + ii) > filelength)	/* Past end of length to dump ? */
105 				{
106 					sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)+1],Buffer[((Counter-1)*2)]);
107 				}
108 				else
109 				{
110 					log_cb(RETRO_LOG_DEBUG, LOGPRE "%02.2x%02.2x ",Buffer[(Counter*2)+1],Buffer[(Counter*2)]);
111 				}
112 				Counter++ ;
113 			}
114 			for (; ii < 4; ii++)
115 			{
116 				log_cb(RETRO_LOG_DEBUG, LOGPRE " ");
117 			}
118 			log_cb(RETRO_LOG_DEBUG, LOGPRE "\t%s\n",String_Output);
119 		}
120 	}
121 	else
122 	{
123 		log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR length to dump was %d ", length_to_dump/2);
124 		log_cb(RETRO_LOG_DEBUG, LOGPRE ", but bytes read from file were %d\n", bytes_read/2);
125 		free(String_Output);
126 		free(Buffer);
127 		fclose(F);
128 		exit(7);
129 	}
130 	free(String_Output);
131 	free(Buffer);
132 	fclose(F);
133 	return(0);
134 }
135