#include "vasm.h" #if defined(OUTHANS) && defined(VASM_CPU_HANS) static char *copyright = "vasm Hans output module 1.0 (c) 2024 by Yannik Stamm"; static char int_to_ascii(int number) { switch (number) { case 0: return '0'; case 1: return '1'; case 2: return '2'; case 3: return '3'; case 4: return '4'; case 5: return '5'; case 6: return '6'; case 7: return '7'; case 8: return '8'; case 9: return '9'; case 10: return 'A'; case 11: return 'B'; case 12: return 'C'; case 13: return 'D'; case 14: return 'E'; case 15: return 'F'; default: return '@'; } } /* /// /// Converts the given 32-Bit Byte into Hexadecimal ascii and writes it to the buffer /// /// This buffer needs enough space for 9 chars /// */ static void write_byte_in_ascii(char* buffer, taddr byte) { int index; for (index = 0; index < 8; index++) { taddr mask = 15; taddr shiftedByte = byte >> (index * 4); taddr number = shiftedByte & mask;/*number is now in [0, 15]*/ buffer[7 - index] = int_to_ascii(number); } buffer[8] = '\0'; } static void write_32bit_byte_to_file(FILE* file, taddr data) { char buffer[9]; write_byte_in_ascii(buffer, data); fprintf(file, buffer); } static void write_32bit_byte_to_file_from_pointer(FILE* file, unsigned char* first8Bit_Byte) { taddr data = (*(first8Bit_Byte + 0)) << 24; data |= (*(first8Bit_Byte + 1)) << 16; data |= (*(first8Bit_Byte + 2)) << 8; data |= (*(first8Bit_Byte + 3)) << 0; write_32bit_byte_to_file(file, data); } static int is_HA_Reloc(nreloc* rel1, nreloc* rel2) { return rel1->mask == 0xFFFF0000 && rel2->mask == 0x8000 && rel1->bitoffset == rel2->bitoffset && rel1->addend == rel2->addend && rel1->byteoffset == rel2->byteoffset && rel1->size == rel2->size && rel1->sym == rel2->sym; } static void write_output(FILE* file, section* firstSection, symbol* firstSymbol) { unsigned char* firstData; const char* pcRelativeValue, *highLow; int i, j; unsigned int byteOffset; atom* atom; rlist* listEntry; section* section; symbol* activeSymbol; fprintf(file, "Symbole:\n"); /* Print list of all symbols and their value*/ for (activeSymbol = firstSymbol; activeSymbol != NULL; activeSymbol = activeSymbol->next) { if (activeSymbol->type == IMPORT) { fprintf(file, ".%s:?\n", activeSymbol->name); } else if (activeSymbol->type == EXPRESSION) { simplify_expr(activeSymbol->expr); if (activeSymbol->expr->type != NUM) output_error(21, activeSymbol->name); fprintf(file, ".%s:%i\n", activeSymbol->name, activeSymbol->expr->c.val); } } fprintf(file, "\nAbschnitte:\n"); for (section = firstSection; section != NULL; section = section->next) { fprintf(file, "%s:\n", section->name); fprintf(file, "\tSymbole:\n"); for (activeSymbol = firstSymbol; activeSymbol != NULL; activeSymbol = activeSymbol->next) { /*if is label and is in this section and is not an assembler internal symbol*/ if (activeSymbol->type == LABSYM && activeSymbol->sec == section && activeSymbol->name[0] != ' ') { fprintf(file, "\t.%s:%i\n", activeSymbol->name, activeSymbol->pc); } } fprintf(file, "\n\tRelokationen:\n"); byteOffset = 0; for (atom = section->first; atom != NULL; atom = atom->next) { if (atom->type == DATA) { if (atom->content.db->relocs != NULL) { listEntry = atom->content.db->relocs; for (; listEntry != NULL; listEntry = listEntry->next) { nreloc* reloc = listEntry->reloc; if (listEntry->type == REL_PC) pcRelativeValue = "true"; else if (listEntry->type == REL_ABS) pcRelativeValue = "false"; else pcRelativeValue = "?"; if (reloc->mask == 0xFFFF0000) { if (listEntry->next != NULL && is_HA_Reloc(reloc, listEntry->next->reloc)) { highLow = "@ha"; listEntry = listEntry->next; } else highLow = "@h"; } else if (reloc->mask == 0xFFFF) { highLow = "@l"; } else { highLow = "none"; } fprintf(file, "\t<%u,%u,%u,%i,%i,%s,%s,%s>\n", (unsigned)(reloc->byteoffset + byteOffset), (unsigned)reloc->bitoffset, (unsigned)reloc->size, reloc->mask, reloc->addend, reloc->sym->name, pcRelativeValue, highLow); } } byteOffset++; } else if (atom->type == SPACE) { for (i = 0; i < atom->content.sb->space; i++) { for (j = 0; j < atom->content.sb->size; j++) { firstData = atom->content.sb->fill + j * 4; write_32bit_byte_to_file_from_pointer(file, firstData); } byteOffset++; } } } fprintf(file, "\n\tDaten:\n\t"); for (atom = section->first; atom != NULL; atom = atom->next) { if (atom->type == DATA) { for (i = 0; i < atom->content.db->size; i++) { firstData = atom->content.db->data + i * 4; write_32bit_byte_to_file_from_pointer(file, firstData); } } else if (atom->type == SPACE) { for (i = 0; i < atom->content.sb->space; i++) { for (j = 0; j < atom->content.sb->size; j++) { firstData = atom->content.sb->fill + j * 4; write_32bit_byte_to_file_from_pointer(file, firstData); } } } } fprintf(file, "\n"); } } /*This function is called for every command line argument that has */ /*not been handled yet. Because we do not have any command line arguments, */ /*this just returns 0 (== given argument is ignored by parse_args)*/ static int parse_args(char* arg) { return 0; } int init_output_hans (char** cp, void (**wo)(FILE*, section*, symbol*), int (**oa)(char*)) { *cp = copyright; *wo = write_output; *oa = parse_args; asciiout = 1; output_bitsperbyte = 1; /* we do support BITSPERBYTE != 8 */ defsecttype = emptystr; /* default section is "org 0" */ return 1; } #else int init_output_hans (char** cp, void (**wo)(FILE*, section*, symbol*), int (**oa)(char*)) { return 0; } #endif