dis51-0.5.orig/0000700000175000017500000000000007757543077011437 5ustar uweuwedis51-0.5.orig/Makefile0000600000175000017500000000131007751605523013061 0ustar uweuweCC=gcc CFLAGS=-c -I. -Wall LDFLAGS= SHAREDLDFLAGS=-lhexfile OBJECTS=main.o pass1.o pass2.o global.o HFOBJ=hexfile.o default: dis51 dis51: $(OBJECTS) $(HFOBJ) $(CC) $(LDFLAGS) $(OBJECTS) $(HFOBJ) -o dis51 main.o: pass1.h main.c $(CC) $(CFLAGS) main.c -o main.o pass1.o: pass1.c distypes.h global.h $(CC) $(CFLAGS) pass1.c -o pass1.o pass2.o: pass2.c distypes.h global.h $(CC) $(CFLAGS) pass2.c -o pass2.o global.o: global.c distypes.h $(CC) $(CFLAGS) global.c -o global.o hexfile.o: hexfile.c $(CC) $(CFLAGS) hexfile.c -o hexfile.o # use "make shared" if you have libhexfile installed as a shared library shared: $(OBJECTS) $(CC) $(SHAREDLDFLAGS) $(OBJECTS) -o dis51 clean: rm -f *.o dis51 core dis51-0.5.orig/NOTES0000600000175000017500000000357407347673747012270 0ustar uweuwe9/4/01 My initial idea for the disassembler was to do everything in one pass, but I've decided to change to a two-pass approach. One pass would require lots of extra memory to store everything I want to output. Keep track of flags for every address. Possible values are EMPTY, CODE, DATA, and LABELLED. Everything starts out as EMPTY. Everything loaded from the hex file is DATA by default. Pass 1: Start at entry point 0000. Follow code through all branches. Note any change to interrupt vectors. Decode interrupt vector entry points as well if necessary. As I go, mark all decoded addresses as CODE. Mark all jump destinations as LABELLED. Give them a label number. Pass 2: Start at address 0000. Output "CSEG AT 0000h". Increment through "memory" to address 65535. Everything marked as LABELLED gets a label looked up from a label table. Everything marked as CODE gets decoded and output. Everything marked as DATA gets a DB command. If EMPTY is encountered, the next non-EMPTY code or data is preceded by at CSEG AT address. Output "END" at the end. 9/12/01 The pass1/pass2 thing worked well. The one "issue" the program has is with indirect jumps (JMP @A+DPTR). There is no way to "follow" the code with an indirect jump. It also seems that at least one 8051 C compiler (Keil uVision 1) generates a number of these indirect jumps. My program will take multiple entry points on the command line, so someone could examine the assembly output by hand, and make an educated guess about where the jump table begins, and then re-disassemble the program with the additional entry points. I decode SFR addresses, both in byte- and bit-addressed memory, into their symbolic names. This helps make the assembly output a bit more readable. I think the only feature to add is one that examines writes to the interrupt registers and makes a guess about which interrupt vectors are being used. dis51-0.5.orig/README0000600000175000017500000001176210015503427012300 0ustar uweuwe Dis51 8051 Hex-file Disassembler Description Dis51 is a simple 8051 disassembler for Unix-like systems. It may even compile under Microsoft Windows, but that has never been tested. It takes an object file in Intel Hex format as input, and outputs an assembly language file. This disassembler assumes by default that everything in memory is data, and nothing is code. It starts at any number of entry points you give it on the command line, then follows the code through all branches until no branches are left. It then outputs an assembly language file which should assemble under any standard 8051 assembler. All data memory is declared using "DB" directives. Dis51 uses symbolic names for SFRs it knows about. To be compatible with as many assemblers as possible, I only defined SFRs that I thought were common to "standard" 8051s. If you need to add other SFRs (or special function bits) then the source file to modify is global.c. It should be self-explanatory how to modify it, I hope. I wrote Dis51 mostly for fun. It was Labor Day weekend and I felt like taking a break from studies, so I started sketching out how I would design a disassembler. I probably spent no more than two weeks from preliminary design to completion of testing. I have been using the disassembler for a few months now with no problems. Another reason I created it was because I spent one afternoon downloading every free 8051 disassembler I could find on the web, and couldn't find a single one that compiled under Solaris and successfully disassembled a HEX file. I sincerely believe that such a program exists, I just couldn't find it. Thus, Dis51. How to get it Dis51 is free to download. Get it from http://home.earthlink.net/~davesullins/software/dis51-0.5.tar.gz. It's released under the GNU Public License (GPL), which means you can download the program for free, you get the source code with it, you can change the source code to suit your needs, and you can redistribute the program with or without modifications as long as the person you distribute the program to gets the same rights you were given. If you use some of the code in your own program, then your own program should also be released under the GPL. Compiling Dis51 Dis51 should compile without changes on any Unix-like machine. It probably even works under Microsoft Windows, but I don't have a compiler to try it out. Let me know what results you get if you try this. First you need to download the source code. If you have GNU tar, extract the file using one of the following commands, depending on what GNU tar is called on your system: gtar xvfz dis51-0.5.tar.gz tar xvfz dis51-0.5.tar.gz If you do not have GNU tar, you can use the following command to extract the source code: cat dis51-0.5.tar.gz | gunzip -c - | tar -xvf - Now change to the dis51-0.5 directory. Edit the Makefile if necessary. If you do not have gcc on your system, change the first line from "CC=gcc" to "CC=cc" or whatever your C compiler is called. Type "make" when you are done and dis51 will be created. Alternatively, you can use the libhexfile shared library. Just type "make shared" instead of "make" to link with libhexfile. If you don't know whether you have the libhexfile shared library installed then you probably don't. That's it! I apologize for the lack of a man page, but luckily it's a pretty simple program. Copy the executable (called dis51) to a bin directory and you're ready to go. How to use it Dis51 takes a Hex file as stdin and outputs an assembly file to stdout. In its simplest form, you can use the following command line: dis51 < file.hex > file.a51 Without any command line options, Dis51 uses the entry point 0. If you want to use other entry points, list them on the command line. For example, to disassemble a program starting at address 0 which also uses the serial port interrupt vector at address 35: dis51 0 35 < file.hex > file.a51 Optionally, you can give the first command line argument "-l" to output in list format. To repeat the previous example in list format: dis51 -l 0 35 < file.hex > file.a51 One problem with Dis51 is that it is unable to determine the target address of an indirect jump (JMP @A+DPTR). Thus if your program contains indirect jumps certain parts of code will not be disassembled. The solution is to search through the disassembled output of dis51 for the JMP @A+DPTR instruction. If you find this instruction, look for large chunks of DB directives elsewhere in the program. If you find some DB directives that you suspect are code and not data, then manually add the addresses of these directives to the command line of dis51 and run it again. Hint: 80h is the SJMP command. Lots of DB 80h directives alternated with other data bytes is likely to be a jump table. Bugs Please send me a message at davesullins@earthlink.net if you think you have found a bug. dis51-0.5.orig/global.c0000600000175000017500000002067610015502622013024 0ustar uweuwe/* global.c * * Data shared by all modules * * Copyright 2001 - 2003 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #include "distypes.h" int Lst; short lbl[65536]; const char mnemonic[256][20] = { /* 0 */ "NOP", "AJMP %s\n", "LJMP %s\n", "RR A", "INC A", "INC %s", "INC @R0", "INC @R1", "INC R0", "INC R1", "INC R2", "INC R3", "INC R4", "INC R5", "INC R6", "INC R7", /* 1 */ "JBC %s, %s", "ACALL %s", "LCALL %s", "RRC A", "DEC A", "DEC %s", "DEC @R0", "DEC @R1", "DEC R0", "DEC R1", "DEC R2", "DEC R3", "DEC R4", "DEC R5", "DEC R6", "DEC R7", /* 2 */ "JB %s, %s", "AJMP %s\n", "RET\n", "RL A", "ADD A, #%s", "ADD A, %s", "ADD A, @R0", "ADD A, @R1", "ADD A, R0", "ADD A, R1", "ADD A, R2", "ADD A, R3", "ADD A, R4", "ADD A, R5", "ADD A, R6", "ADD A, R7", /* 3 */ "JNB %s, %s", "ACALL %s", "RETI\n", "RLC A", "ADDC A, #%s", "ADDC A, %s", "ADDC A, @R0", "ADDC A, @R1", "ADDC A, R0", "ADDC A, R1", "ADDC A, R2", "ADDC A, R3", "ADDC A, R4", "ADDC A, R5", "ADDC A, R6", "ADDC A, R7", /* 4 */ "JC %s", "AJMP %s\n", "ORL %s, A", "ORL %s, #%s", "ORL A, #%s", "ORL A, %s", "ORL A, @R0", "ORL A, @R1", "ORL A, R0", "ORL A, R1", "ORL A, R2", "ORL A, R3", "ORL A, R4", "ORL A, R5", "ORL A, R6", "ORL A, R7", /* 5 */ "JNC %s", "ACALL %s", "ANL %s, A", "ANL %s, #%s", "ANL A, #%s", "ANL A, %s", "ANL A, @R0", "ANL A, @R1", "ANL A, R0", "ANL A, R1", "ANL A, R2", "ANL A, R3", "ANL A, R4", "ANL A, R5", "ANL A, R6", "ANL A, R7", /* 6 */ "JZ %s", "AJMP %s\n", "XRL %s, A", "XRL %s, #%s", "XRL A, #%s", "XRL A, %s", "XRL A, @R0", "XRL A, @R1", "XRL A, R0", "XRL A, R1", "XRL A, R2", "XRL A, R3", "XRL A, R4", "XRL A, R5", "XRL A, R6", "XRL A, R7", /* 7 */ "JNZ %s", "ACALL %s", "ORL C, %s", "JMP @A+DPTR\n", "MOV A, #%s", "MOV %s, #%s", "MOV @R0, #%s", "MOV @R1, #%s", "MOV R0, #%s", "MOV R1, #%s", "MOV R2, #%s", "MOV R3, #%s", "MOV R4, #%s", "MOV R5, #%s", "MOV R6, #%s", "MOV R7, #%s", /* 8 */ "SJMP %s\n", "AJMP %s\n", "ANL C, %s", "MOVC A, @A+PC", "DIV AB", "MOV %s, %s", "MOV %s, @R0", "MOV %s, @R1", "MOV %s, R0", "MOV %s, R1", "MOV %s, R2", "MOV %s, R3", "MOV %s, R4", "MOV %s, R5", "MOV %s, R6", "MOV %s, R7", /* 9 */ "MOV DPTR, #0%X%02Xh", "ACALL %s", "MOV %s, C", "MOVC A, @A+DPTR", "SUBB A, #%s", "SUBB A, %s", "SUBB A, @R0", "SUBB A, @R1", "SUBB A, R0", "SUBB A, R1", "SUBB A, R2", "SUBB A, R3", "SUBB A, R4", "SUBB A, R5", "SUBB A, R6", "SUBB A, R7", /* A */ "ORL C, /%s", "AJMP %s\n", "MOV C, %s", "INC DPTR", "MUL AB", "", /* undefined opcode */ "MOV @R0, %s", "MOV @R1, %s", "MOV R0, %s", "MOV R1, %s", "MOV R2, %s", "MOV R3, %s", "MOV R4, %s", "MOV R5, %s", "MOV R6, %s", "MOV R7, %s", /* B */ "ANL C, /%s", "ACALL %s", "CPL %s", "CPL C", "CJNE A, #%s, %s", "CJNE A, %s, %s", "CJNE @R0, #%s, %s", "CJNE @R1, #%s, %s", "CJNE R0, #%s, %s", "CJNE R1, #%s, %s", "CJNE R2, #%s, %s", "CJNE R3, #%s, %s", "CJNE R4, #%s, %s", "CJNE R5, #%s, %s", "CJNE R6, #%s, %s", "CJNE R7, #%s, %s", /* C */ "PUSH %s", "AJMP %s\n", "CLR %s", "CLR C", "SWAP A", "XCH A, %s", "XCH A, @R0", "XCH A, @R1", "XCH A, R0", "XCH A, R1", "XCH A, R2", "XCH A, R3", "XCH A, R4", "XCH A, R5", "XCH A, R6", "XCH A, R7", /* D */ "POP %s", "ACALL %s", "SETB %s", "SETB C", "DA A", "DJNZ %s, %s", "XCHD A, @R0", "XCHD A, @R1", "DJNZ R0, %s", "DJNZ R1, %s", "DJNZ R2, %s", "DJNZ R3, %s", "DJNZ R4, %s", "DJNZ R5, %s", "DJNZ R6, %s", "DJNZ R7, %s", /* E */ "MOVX A, @DPTR", "AJMP %s\n", "MOVX A, @R0", "MOVX A, @R1", "CLR A", "MOV A, %s", "MOV A, @R0", "MOV A, @R1", "MOV A, R0", "MOV A, R1", "MOV A, R2", "MOV A, R3", "MOV A, R4", "MOV A, R5", "MOV A, R6", "MOV A, R7", /* F */ "MOVX @DPTR, A", "ACALL %s", "MOVX @R0, A", "MOVX @R1, A", "CPL A", "MOV %s, A", "MOV @R0, A", "MOV @R1, A", "MOV R0, A", "MOV R1, A", "MOV R2, A", "MOV R3, A", "MOV R4, A", "MOV R5, A", "MOV R6, A", "MOV R7, A" }; /* op_format table * * 0 = illegal opcode * 1 = no operands * 2 = one immediate operand * 3 = one direct operand * 4 = one bit-addressed operand * 5 = one relative address operand * 6 = one absolute address operand * 7 = two-byte immediate operand * 8 = two operands: direct, immediate * 9 = two operands: direct, direct * 10 = two operands: immediate, relative address * 11 = two operands: direct, relative address * 12 = two operands: bit address, relative address * 13 = two-byte long address operand */ const char op_format[256] = { 1, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */ 12, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */ 12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ 12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 5, 6, 4, 1, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 7 */ 5, 6, 4, 1, 1, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 8 */ 7, 6, 4, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ 4, 6, 4, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* A */ 4, 6, 4, 1, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* B */ 3, 6, 4, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C */ 3, 6, 4, 1, 1, 11, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, /* D */ 1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E */ 1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* F */ }; const char sfbitname[128][6] = { /* 80 */ "P0.0", "P0.1", "P0.2", "P0.3", "P0.4", "P0.5", "P0.6", "P0.7", /* 88 */ "IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1", /* 90 */ "P1.0", "P1.1", "P1.2", "P1.3", "P1.4", "P1.5", "P1.6", "P1.7", /* 98 */ "RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0", /* A0 */ "P2.0", "P2.1", "P2.2", "P2.3", "P2.4", "P2.5", "P2.6", "P2.7", /* A8 */ "EX0", "ET0", "EX1", "ET1", "ES", "0ADh", "0AEh", "EA", /* B0 */ "P3.0", "P3.1", "P3.2", "P3.3", "P3.4", "P3.5", "P3.6", "P3.7", /* B8 */ "PX0", "PT0", "PX1", "PT1", "PS", "0BDh", "0BEh", "0BFh", /* C0 */ "0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h", /* C8 */ "0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh", /* D0 */ "P", "0D1h", "OV", "RS0", "RS1", "F0", "AC", "CY", /* D8 */ "0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh", /* E0 */ "ACC.0", "ACC.1", "ACC.2", "ACC.3", "ACC.4", "ACC.5", "ACC.6", "ACC.7", /* E8 */ "0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh", /* F0 */ "B.0", "B.1", "B.2", "B.3", "B.4", "B.5", "B.6", "B.7", /* F8 */ "0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh" }; const char sfrname[128][5] = { /* 80 */ "P0", "SP", "DPL", "DPH", "84h", "85h", "86h", "PCON", /* 88 */ "TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", "8Eh", "8Fh", /* 90 */ "P1", "91h", "92h", "93h", "94h", "95h", "96h", "97h", /* 98 */ "SCON", "SBUF", "9Ah", "9Bh", "9Ch", "9Dh", "9Eh", "9Fh", /* A0 */ "P2", "0A1h", "0A2h", "0A3h", "0A4h", "0A5h", "0A6h", "0A7h", /* A8 */ "IE", "0A9h", "0AAh", "0ABh", "0ACh", "0ADh", "0AEh", "0AFh", /* B0 */ "P3", "0B1h", "0B2h", "0B3h", "0B4h", "0B5h", "0B6h", "0B7h", /* B8 */ "IP", "0B9h", "0BAh", "0BBh", "0BCh", "0BDh", "0BEh", "0BFh", /* C0 */ "0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h", /* C8 */ "0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh", /* D0 */ "PSW", "0D1h", "0D2h", "0D3h", "0D4h", "0D5h", "0D6h", "0D7h", /* D8 */ "0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh", /* E0 */ "ACC", "0E1h", "0E2h", "0E3h", "0E4h", "0E5h", "0E6h", "0E7h", /* E8 */ "0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh", /* F0 */ "B", "0F1h", "0F2h", "0F3h", "0F4h", "0F5h", "0F6h", "0F7h", /* F8 */ "0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh" }; dis51-0.5.orig/global.h0000600000175000017500000000216110015502607013021 0ustar uweuwe/* global.h * * Data shared by all modules * * Copyright 2001, 2002 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #ifndef _GLOBAL_H_ #define _GLOBAL_H_ #include "distypes.h" /* global data */ extern int Lst; extern unsigned short lbl[65536]; extern const char mnemonic[256][20]; extern const char op_format[256]; extern const char sfrname[128][5]; extern const char sfbitname[128][6]; #endif /* _GLOBAL_H_ */ dis51-0.5.orig/hexfile.c0000600000175000017500000002025210015502621013175 0ustar uweuwe/* hexfile.c * * Library for reading files in Intel hex format. * * Copyright 2001 - 2003 by David Sullins * * This file is part of Libhexfile. * * Libhexfile 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, version 2 of the License. * * Libhexfile 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 Libhexfile; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #include #include #include #include "hexfile.h" /* init_hexfile * * Initializes a struct hexfile. * * memsize should be the size of the internal memory buffer. 65536 is a * good choice. * filename should be a readable hex file OR ifile should be a valid * input stream. To use filename, set ifile to NULL. * * Return 0 upon success, -1 otherwise. */ int init_hexfile(struct hexfile *hf, int memsize, FILE *ifile, const char *filename) { /* open file for reading */ if (ifile == NULL) { hf->ifile = fopen(filename, "r"); if (hf->ifile == NULL) return -1; } else hf->ifile = ifile; hf->memsize = memsize; hf->mem = malloc(memsize); hf->flag = malloc(memsize); hf->hl = malloc(sizeof(struct hexline)); memset(hf->flag, 0x80, memsize); return init_hexline(hf->hl); } /* destroy_hexfile * * Undoes what init_hexfile did. Closes input hexfile. */ void destroy_hexfile(struct hexfile *hf) { if (hf->ifile != NULL) { fclose(hf->ifile); hf->ifile = NULL; } if (hf->mem != NULL) { free(hf->mem); hf->mem = NULL; } if (hf->flag != NULL) { free(hf->flag); hf->flag = NULL; } if (hf->hl != NULL) { destroy_hexline(hf->hl); free(hf->hl); hf->hl = NULL; } } /* init_hexline * * Initializes a struct hexline. * filename should be a readable hex file. * * Return 0 upon success, -1 otherwise. */ int init_hexline(struct hexline *hl) { hl->addr = 0; hl->len = 0; hl->record = 0; hl->linaddr = 0; /* HFINPUTSIZE characters less the length, address, record type, * checksum, and colon is twice the number of bytes available on * a line. Add one just in case. */ hl->bufsize = (HFINPUTSIZE - 11) / 2 + 1; hl->membuf = malloc(hl->bufsize); return 0; } /* destroy_hexline * * Undoes what init_hexline did. */ void destroy_hexline(struct hexline *hl) { if (hl->membuf != NULL) { free(hl->membuf); hl->membuf = NULL; } } /* parse_line * * Parse one line of a hex file. Will not read a line larger than * HFINPUTSIZE characters. The author once read that 100 characters is the * maximum length of a hex-file line (source forgotten), so HFINPUTSIZE is * defined as 100. Redefine and recompile if that length is a problem for * you. * * Exits at first sign of trouble. Makes no attempt to parse a line * with errors. * EXCEPT: If the ONLY error is with a checksum, memory is updated * normally. * * Only understands record types 00 (code/data) and 01 (end of file). * * Returns: -1 on bad checksum * -2 on unknown record type * -3 on unexpected line length * -4 on unexpected character * -5 on buffer full * 0 on code/data record * 1 on EOF record * 4 on linear address record * * Note: The segment address record type (2) is not supported, so a hex file * containing this record type will return -2. */ int parse_line(struct hexfile *hf) { char inputbuf[HFINPUTSIZE]; char *bufPtr; unsigned char checksum; int i, t; struct hexline *hl = hf->hl; /* read one line, null-terminate just in case */ fgets(inputbuf, HFINPUTSIZE, hf->ifile); bufPtr = strchr(inputbuf, (int)'\n'); if (bufPtr != 0) *bufPtr = 0; bufPtr = strchr(inputbuf, (int)'\r'); if (bufPtr != 0) *bufPtr = 0; /* check for leading colon, point to length */ bufPtr = inputbuf; if (':' != *bufPtr++) return -4; /* no leading colon */ /* parse length */ sscanf(bufPtr, "%2x", &(hl->len)); if (strlen(bufPtr) != 10+hl->len*2) return -3; /* bad length */ checksum = hl->len; /* parse address */ sscanf(bufPtr+2, "%4x", &(hl->addr)); checksum += (hl->addr>>8); checksum += hl->addr; hl->addr |= ((hl->linaddr)<<16); /* parse record type */ sscanf(bufPtr+6, "%2x", &(hl->record)); if (hl->record == 1) { /* EOF line */ if (hl->len != 0) return -3; /* bad length */ if (strncasecmp(bufPtr+8, "ff", 2)) return -1; /* bad checksum */ } else if (hl->record == 4) hl->linaddr = 0; /* new linear address */ else if (hl->record != 0) return -2; /* bad record type */ checksum += hl->record; /* parse data */ bufPtr += 8; for (i = 0; i < hl->len; ++i, bufPtr += 2) { if (i >= hl->bufsize) return -5; /* buffer full */ sscanf(bufPtr, "%2x", &t); *(hl->membuf+i) = (unsigned char)t; checksum += t; if (hl->record == 4) { hl->linaddr <<= 8; hl->linaddr |= (unsigned char)t; } } /* parse checksum */ sscanf(bufPtr, "%2x", &t); checksum += t; if (checksum != 0) return -1; /* bad checksum */ return hl->record; } /* read_hex * * Parse a hex file from given input file. * * Fills mem buffer with appropriate memory contents. * Also sets flag buffer to 0 for each address read from file. * * mem and flag should both be 65536 byte buffers. You should initialize * the contents of flag to something non-zero before calling read_hex if you * want to be able to tell which memory addresses are valid. * * Returns: -1 on error in hex file, 0 otherwise */ int read_hex(struct hexfile *hf) { return read_hex_cb(hf, NULL, NULL); } /* read_hex_cb * * Parse a hex file from given input file, invoking a callback for addresses * over 65536. * * Fills mem buffer with appropriate memory contents less than 65536. * Also sets flag buffer to 0 for each address read from file. * * mem and flag should both be 65536 byte buffers. You should initialize * the contents of flag to something non-zero before calling read_hex if you * want to be able to tell which memory addresses are valid. * * cb() can use hl->len bytes of data from hl->membuf, which starts at * address hl->addr. * * Returns: -1 on error in hex file, 0 otherwise */ int read_hex_cb(struct hexfile *hf, void(*cb)(const struct hexline *, void *), void *arg) { unsigned char *cmem = hf->mem; unsigned char *cflag = hf->flag; struct hexline *hl; int record; int retval = 0; int line = 0; hl = hf->hl; while (!feof(hf->ifile)) { record = parse_line(hf); switch(record) { case 4: /* new linear address, do nothing */ break; case 1: /* EOF */ return retval; case 0: /* code/data */ if (hl->addr >= hf->memsize) { if (cb != NULL) cb(hl, arg); break; } memcpy(cmem+hl->addr, hl->membuf, hl->len); memset(cflag+hl->addr, 0, hl->len); break; case -1: /* checksum error */ fprintf(stderr, "Warning: Bad checksum in hex file "); fprintf(stderr, "Line %d\n", line); retval = -1; record = hl->record; continue; case -2: /* unknown record type */ fprintf(stderr, "Warning: Unknown record type in hex file "); fprintf(stderr, "Line %d\n", line); retval = -1; break; case -3: /* bad line length */ fprintf(stderr, "Warning: Bad length field in hex file "); fprintf(stderr, "Line %d\n", line); retval = -1; break; case -4: /* unexpected character */ fprintf(stderr, "Warning: Bad character in hex file "); fprintf(stderr, "Line %d\n", line); retval = -1; break; case -5: /* buffer full */ fprintf(stderr, "Warning: Buffer full in hex file "); fprintf(stderr, "Line %d\n", line); retval = -1; break; default: /* ??? unknown error ??? */ fprintf(stderr, "Unknown error in hex file Line %d\n", line); retval = -1; } ++line; } fprintf(stderr, "Warning: Unexpected end of hex file\n"); return -1; } dis51-0.5.orig/hexfile.h0000600000175000017500000001171210015502606013206 0ustar uweuwe/* hexfile.h * * Library for reading files in Intel hex format. * * Copyright 2001-2003 by David Sullins * * This file is part of Libhexfile. * * Libhexfile 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, version 2 of the License. * * Libhexfile 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 Libhexfile; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #ifndef _HEXLIB_H_ #define _HEXLIB_H_ #include /* The author once read that 100 characters is the maximum length of a * hex-file line (source forgotten), so HFINPUTSIZE is defined as 100 by * default. Redefine and recompile if that length is a problem. */ #ifndef HFINPUTSIZE #define HFINPUTSIZE 100 #endif struct hexline; /* struct hexfile * * - ifile is the file to take input from. * - memsize is the size of internal memory buffers. * - mem is a pointer to the contents of memory. * - flag is a pointer to a set of flags indicating which memory addresses * are valid. * - hl is a pointer to an internally-used structure. * * Call init_hexfile before using and destroy_hexfile when done. */ struct hexfile { FILE *ifile; int memsize; unsigned char *mem; unsigned char *flag; struct hexline *hl; }; /* init_hexfile * * Initializes a struct hexfile. * * memsize should be the size of the internal memory buffer. 65536 is a * good choice for most hex files. * filename should be a readable hex file OR ifile should be a valid * input stream. To use filename, set ifile to NULL. * * Return 0 upon success, -1 otherwise. */ int init_hexfile(struct hexfile *hf, int memsize, FILE *ifile, const char *filename); /* destroy_hexfile * * Undoes what init_hexfile did. Closes input hexfile. */ void destroy_hexfile(struct hexfile *hf); /* read_hex * * Parse a hex file from given input file, ignoring addresses >= memsize. * * Fills mem buffer with appropriate memory contents. * Also sets flag buffer to 0 for each address read from file (initially * 128). * * Returns: -1 on error in hex file, 0 otherwise */ int read_hex(struct hexfile *hf); /* read_hex_cb * * Parse a hex file from given input file, invoking a callback for addresses * >= memsize. * * Fills mem buffer with appropriate memory contents less than memsize. * Also sets flag buffer to 0 for each address read from file. * * cb() can use hl->len bytes of data from hl->membuf, which starts at * address hl->addr. arg is passed as the second argument to cb(). * * Returns: -1 on error in hex file, 0 otherwise */ int read_hex_cb(struct hexfile *hf, void(*cb)(const struct hexline *, void *), void *arg); /* * STOP! You probably don't need anything below this line. * These routines are available if you want to implement something * like read_hex yourself. */ /* struct hexline * * - membuf points to len bytes from the last read line. * - addr is the starting address of the data in membuf. * - len is the number of bytes read from the last line. * - record is the numeric record type of the last read line. * - bufsize is the length of membuf in bytes. * - linaddr is the current linear address. Initialize to 0 before calling * parse_line the first time. After that, parse_line takes care of the * rest. * * Call init_hexline before using and destroy_hexline when done. */ struct hexline { unsigned int addr; int len; unsigned char *membuf; int record; int bufsize; int linaddr; }; /* init_hexline * * Initializes a struct hexline. * filename should be a readable hex file. * * Return 0 upon success, -1 otherwise. */ int init_hexline(struct hexline *hl); /* destroy_hexline * * Undoes what init_hexline did. */ void destroy_hexline(struct hexline *hl); /* parse_line * * Parse one line of a hex file. Will not read a line larger than * HFINPUTSIZE characters. * * Exits at first sign of trouble. Makes no attempt to parse a line * with errors. * EXCEPT: If the ONLY error is with a checksum, memory is updated * normally. * * Only understands record types 00 (code/data) and 01 (end of file). * * Returns: -1 on bad checksum * -2 on unknown record type * -3 on unexpected line length * -4 on unexpected character * -5 on buffer full * 0 on code/data record * 1 on EOF record * 4 on linear address record * * Note: The segment address record type (2) is not supported, so a hex file * containing this record type will return -2. */ int parse_line(struct hexfile *hf); #endif /* _HEXLIB_H_ */ dis51-0.5.orig/HISTORY0000600000175000017500000000224710015502614012477 0ustar uweuweDis51-0.5, written and maintained by Dave Sullins (davesullins@earthlink.net). 21 Nov 2003: Version 0.5 Applied patch from Peter Peres (plp@actcom.co.il). Adds "-l" command-line argument to output in list format. Includes decoded ASCII characters from DB directives as comments. Nice feature, thanks Peter! 3 Nov 2003: Version 0.4 The same code as version 0.3, but things are packaged a little more neatly into the tarball and documentation has been updated to reflect the version change. Also, this time I remembered to add a link from my Dis51 page to the tarball. 15 Feb 2003: Version 0.3 Updated to work with new libhexfile. This version was "released" in that it was placed on a publically available website, but I failed to add a public link to it. So this version, if you have it, is a collector's item. 7 Dec 2002: Version 0.2 This is the first numbered version. Any unnumbered version is 0.1. I don't know if I released the program multiple times, so there may be different 0.1 versions out there. The only difference in 0.2 is the new libhexfile library, which really shouldn't affect the program since 32-bit addresses are not used in any 8051 variant I've heard of. dis51-0.5.orig/main.c0000600000175000017500000000444010015502620012475 0ustar uweuwe/* main.c * * Main function for Dis51. * * Copyright 2001 - 2003 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. * * HISTORY: * 0.4, 3 Nov 2003: Only documentation changes. * 0.3, 14 Feb 2003: Updated for newer libhexfile. * 0.2: first numbered version, updated for new libhexfile. */ #include #include #include #include #include "global.h" #include "pass1.h" #include "pass2.h" int main(int argc, char **argv) { struct hexfile hf; int i; int entry = 0; char *p, *q; unsigned long ul; Lst = 0; /* clear memory */ memset(lbl, 0, 65536*2); /* read hex file from stdin */ if (init_hexfile(&hf, 65536, stdin, NULL)) { fprintf(stderr, "Error opening hex file.\n"); exit(1); } if (read_hex(&hf)) { fprintf(stderr, "Error reading hex file.\n"); exit(1); } if (argc > 1) { i = 1; /* Set listing mode */ if(!strcmp(argv[i],"-l")) { Lst=1; ++i; /* use entry point 0 if none given on command line */ if (argc == i) pass1(&hf, 0); } /* use entry points from command line */ for (; i < argc; ++i) { if(!Lst) sscanf(argv[i], "%d", &entry); else { p = q = argv[i]; if(*p == '\0') { fprintf(stderr, "Warning: NULL argument on command line.\n"); continue; } ul = strtoul(p, &q, 0); if(*q != 0) { fprintf(stderr, "Error: Bad address '%s'. Abort\n", argv[i]); exit(1); } entry = (int)ul; } pass1(&hf, entry); } } else /* use entry point 0 if none given on command line */ pass1(&hf, 0); /* disassemble to stdout */ pass2(stdout, &hf); return 0; } dis51-0.5.orig/distypes.h0000600000175000017500000000176210015502611013426 0ustar uweuwe/* distypes.h * * Define types used in 8051 disassembler * * Copyright 2001, 2002 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #ifndef _DISTYPES_H_ #define _DISTYPES_H_ #ifndef uchar typedef unsigned char uchar; #endif #define CODE 1 #define EMPTY 0x80 #endif /* _DISTYPES_H_ */ dis51-0.5.orig/pass1.c0000600000175000017500000001077110015502633012610 0ustar uweuwe/* pass1.c * * Functions for pass 1 of the disassembler. * * Copyright 2001 - 2003 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #include #include #include "distypes.h" #include "global.h" #include "pass1.h" /* newlbl is used by longaddr, absaddr, and reladdr * Keep track of next available label */ static unsigned short newlbl = 0; /* nextbyte: read a byte from memory * */ #define nextbyte() (nextbyte_f(hf, memPtr++)) static uchar nextbyte_f(struct hexfile *hf, int memPtr) { hf->flag[memPtr] |= CODE; return hf->mem[memPtr]; } /* longaddr * */ static int longaddr(uchar op1, uchar op2) { int addr; /* calculate address */ addr = ((((int)op1)<<8) | op2); /* check if this address has already been labelled */ if (lbl[addr] == 0) lbl[addr] = ++newlbl; return addr; } /* absaddr * */ static int absaddr(uchar opcode, uchar operand, int memPtr) { int addr; /* calculate address */ addr = ((memPtr & 0xf800) | (((int)opcode & 0xe0)<<3) | operand); /* check if this address has already been labelled */ if (lbl[addr] == 0) lbl[addr] = ++newlbl; return addr; } /* reladdr * */ static int reladdr(uchar operand, int memPtr) { int addr; /* calculate address */ addr = memPtr + (signed char)operand; /* check if this address has already been labelled */ if (lbl[addr] == 0) lbl[addr] = ++newlbl; return addr; } /* dis_inst: Disassemble one instruction (pass 1) * * Also increments memPtr to point to the next instruction address. * * Return -1 on error. * Otherwise, return opcode byte. * * CAVEAT: Indirect jumps not handled (JMP @A+DPTR) */ static int dis_inst1(struct hexfile *hf, int memPtr) { uchar opcode; uchar op1, op2; int newaddr = -1; opcode = nextbyte(); switch(op_format[opcode]) { case 0: /* A5 is an illegal opcode */ fprintf(stderr, "Illegal opcode A5 at address %04X\n", memPtr-1); newaddr = -1; break; case 1: /* no operands */ newaddr = memPtr; /* if this is a return, stop disassembly */ if ((opcode & 0xef) == 0x22) newaddr = -1; /* we don't handle indirect jumps */ else if (opcode == 0x73) newaddr = -1; break; case 2: case 3: case 4: /* one operand */ nextbyte(); newaddr = memPtr; break; case 5: /* one operand, relative address */ op1 = nextbyte(); /* relative addr calculation */ newaddr = reladdr(op1, memPtr); /* if this is a branch, continue disassembly */ if (opcode != 0x80) pass1(hf, memPtr); break; case 6: /* one operand, absolute address */ op1 = nextbyte(); /* absolute addr calculation */ newaddr = absaddr(opcode, op1, memPtr); /* if this is a call, continue disassembly */ if (opcode & 0x10) pass1(hf, memPtr); break; case 7: case 8: case 9: /* two operands */ nextbyte(); nextbyte(); newaddr = memPtr; break; case 10: case 11: case 12: /* two operands, relative address */ nextbyte(); op2 = nextbyte(); /* relative addr calculation */ newaddr = reladdr(op2, memPtr); /* this is always a branch instruction */ pass1(hf, memPtr); break; case 13: /* long address */ op1 = nextbyte(); op2 = nextbyte(); /* long addr calculation */ newaddr = longaddr(op1, op2); /* if this is a call, continue disassembly */ if (opcode == 0x12) pass1(hf, memPtr); break; default: /* error in op_format table */ fprintf(stderr, "Invalid opcode format, error in format table\n"); newaddr = -1; break; } return newaddr; } /* pass1: Disassemble instructions starting at given entry point (pass 1) * */ void pass1(struct hexfile *hf, int addr) { while ((addr != -1) && (hf->flag[addr] == 0)) /* no error, we haven't been here before, and non-empty */ /* disassemble next instruction */ addr = dis_inst1(hf, addr); } dis51-0.5.orig/pass1.h0000600000175000017500000000203710015502617012613 0ustar uweuwe/* pass1.h * * Functions for pass 1 of the assembler * * Copyright 2001, 2002 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #ifndef _PASS1_H_ #define _PASS1_H_ #include /* pass1: Disassemble instructions starting at given entry point (pass 1) * */ void pass1(struct hexfile *hf, int addr); #endif /* _PASS1_H_ */ dis51-0.5.orig/pass2.c0000600000175000017500000001606510015502632012612 0ustar uweuwe/* pass2.c * * Functions for pass 2 of the disassembler. * * Copyright 2001 - 2003 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #include #include #include #include #include "distypes.h" #include "global.h" /* nextbyte: read a byte from memory * */ #define nextbyte() (hf->mem[addr++]) /* longaddr * */ static int longaddr(uchar op1, uchar op2, char *label) { int addr; /* calculate address */ addr = ((((int)op1)<<8) | op2); /* form label string */ sprintf(label, "L%04d", lbl[addr]); return lbl[addr]; } /* absaddr * */ static int absaddr(uchar opcode, uchar operand, int memPtr, char *label) { int addr; /* calculate address */ addr = ((memPtr & 0xf800) | (((int)opcode & 0xe0)<<3) | operand); /* form label string */ sprintf(label, "L%04d", lbl[addr]); return lbl[addr]; } /* reladdr * */ static int reladdr(uchar operand, int memPtr, char *label) { int addr; /* calculate address */ addr = memPtr + (signed char)operand; /* form label string */ sprintf(label, "L%04d", lbl[addr]); return lbl[addr]; } /* printhex * * Pretty format a hexadecimal number in a string. */ static void printhex(uchar num, char *name) { if ((num >= 0xa0) || ((num <= 0xf) && (num >= 0xa))) snprintf(name, 5, "0%Xh", num); else snprintf(name, 5, "%Xh", num); } /* sfrdecode * * Convert a direct memory value to a SFR name if appropriate. * Otherwise output the formatted number. */ static void sfrdecode(uchar sfr, char *name) { if (sfr & 0x80) strncpy(name, sfrname[sfr&0x7f], 5); else printhex(sfr, name); } /* sfbitdecode * * Convert a bit memory value to a SF bit name if appropriate. * Otherwise output the formatted number. */ static void sfbitdecode(uchar sfbit, char *name) { if (sfbit & 0x80) strncpy(name, sfbitname[sfbit&0x7f], 6); else printhex(sfbit, name); } /* _listhex, listhex * * Output list-format address and data for the -l command line switch. * * Contributed by Peter Peres. */ #define listhex(len,addr,ofile) { if(Lst) _listhex(ofile,hf,addr,len); } static void _listhex(FILE *file, const struct hexfile *hf, int addr, int len) { fprintf( file, " %04X %02X", addr-len, hf->mem[addr-len] ); switch(len) { case 3: fprintf( file, "%02X", hf->mem[addr-2] ); case 2: fprintf( file, "%02X", hf->mem[addr-1] ); if(len == 2) fprintf( file, " "); break; default: fprintf( file, " "); } fprintf( file, "\t\t" ); } /* dis_inst2: Disassemble one instruction to ofile * * Returns address immediately after instruction. */ static int dis_inst2(FILE *ofile, const struct hexfile *hf, int addr) { uchar opcode; uchar op1, op2; char label[6]; char name[6]; char name2[5]; int bytes = 1; /* Fetch opcode */ opcode = nextbyte(); /* Fetch second and third byte, if appropriate */ if (op_format[opcode] > 1) { op1 = nextbyte(); bytes = 2; } if (op_format[opcode] > 6) { op2 = nextbyte(); bytes = 3; } /* Output decoded instruction */ if(!Lst) fprintf(ofile, "\t"); else listhex(bytes, addr, ofile); switch(op_format[opcode]) { case 0: /* A5 is an illegal opcode */ fprintf(ofile, "DB 85h ; illegal opcode"); case 1: /* no operands */ fprintf(ofile, mnemonic[opcode]); break; case 2: /* one immediate operand */ printhex(op1, name); fprintf(ofile, mnemonic[opcode], name); break; case 3: /* one direct operand */ sfrdecode(op1, name); fprintf(ofile, mnemonic[opcode], name); break; case 4: /* one bit-addressed operand */ sfbitdecode(op1, name); fprintf(ofile, mnemonic[opcode], name); break; case 5: /* one operand, relative address */ /* relative addr calculation */ reladdr(op1, addr, label); fprintf(ofile, mnemonic[opcode], label); break; case 6: /* one operand, absolute address */ /* absolute addr calculation */ absaddr(opcode, op1, addr, label); fprintf(ofile, mnemonic[opcode], label); break; case 7: /* two-byte immediate operand */ /* MOV DPTR, #immediate16 */ fprintf(ofile, mnemonic[opcode], op1, op2); break; case 8: /* two operands: direct, immediate */ sfrdecode(op1, name); printhex(op2, name2); fprintf(ofile, mnemonic[opcode], name, name2); break; case 9: /* two operands: direct, direct */ /* (operands in reverse order) */ sfrdecode(op1, name); sfrdecode(op2, name2); fprintf(ofile, mnemonic[opcode], name2, name); break; case 10: /* two operands: immediate, relative */ printhex(op1, name); reladdr(op2, addr, label); fprintf(ofile, mnemonic[opcode], name, label); break; case 11: /* two operands: direct, relative */ sfrdecode(op1, name); reladdr(op2, addr, label); fprintf(ofile, mnemonic[opcode], name, label); break; case 12: /* two operands: bit, relative */ sfbitdecode(op1, name); reladdr(op2, addr, label); fprintf(ofile, mnemonic[opcode], name, label); break; case 13: /* long address */ /* long addr calculation */ longaddr(op1, op2, label); fprintf(ofile, mnemonic[opcode], label); break; default: /* error in op_format table */ fprintf(ofile, "DB 0%Xh ; error in op_format table", opcode); } fprintf(ofile, "\n"); return addr; } /* pass2: Disassemble memory to given output file (pass 2) * */ void pass2(FILE *ofile, const struct hexfile *hf) { int addr = 0; uchar empty = 1; /* 1 for no code/data, 0 for code or data */ while (addr < 65536) { /* Step 1: check if memory is empty */ if ((hf->flag[addr] != EMPTY) && (empty)) /* We've changed from empty to non-empty, * so start a new segment. */ fprintf(ofile, "CSEG AT %04Xh\n", addr); else if (hf->flag[addr] == EMPTY) { /* no code or data here */ ++addr; empty = 1; continue; } empty = 0; /* Step 2: Output a label if one exists */ if (lbl[addr]) fprintf(ofile, "L%04d:\n", lbl[addr]); /* Step 3: Output code or data as appropriate */ if (hf->flag[addr]&CODE) /* code here, so disassemble next instruction */ addr = dis_inst2(ofile, hf, addr); else { /* data here */ if(!Lst) fprintf(ofile, "\tDB 0%Xh\n", hf->mem[addr]); else { listhex(1, addr+1, ofile); if(isprint(hf->mem[addr])) fprintf(ofile, "DB 0%02Xh ; '%c'\n", hf->mem[addr], hf->mem[addr]); else fprintf(ofile, "DB 0%02Xh \n", hf->mem[addr]); } ++addr; } } fprintf(ofile, "END\n"); } dis51-0.5.orig/pass2.h0000600000175000017500000000205410015502616012612 0ustar uweuwe/* pass2.h * * Functions for pass 2 of the assembler * * Copyright 2001, 2002 by David Sullins * * This file is part of Dis51. * * Dis51 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, version 2 of the License. * * Dis51 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 * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author at davesullins@earthlink.net. */ #ifndef _PASS2_H_ #define _PASS2_H_ #include #include /* pass2: Disassemble memory to given output file (pass 2) * */ void pass2(FILE *ofile, const struct hexfile *hf); #endif /* _PASS2_H_ */ dis51-0.5.orig/COPYING0000600000175000017500000004313107347676162012473 0ustar uweuwe GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.