From 627de5a2bda3909dec55c5a23e17afa576410fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Henrik=20Sk=C3=A5rstedt?= Date: Tue, 3 Sep 2019 17:10:48 -0700 Subject: [PATCH] Adding 64TASS list/labels output files for no reason. --- x65.cpp | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 3 deletions(-) diff --git a/x65.cpp b/x65.cpp index 2f27752..0c43d91 100644 --- a/x65.cpp +++ b/x65.cpp @@ -1518,6 +1518,9 @@ public: // Generate assembler listing if requested bool List(strref filename); + // Mimic TASS listing + bool ListTassStyle( strref filename ); + // Generate source for all valid instructions and addressing modes for current CPU bool AllOpcodes(strref filename); @@ -5837,6 +5840,113 @@ struct cycleCnt { } }; +bool Asm::ListTassStyle( strref filename ) { + // NOTE: This file needs more information to be useful for things + FILE *f = stdout; + bool opened = false; + if( filename ) { + f = fopen( strown<512>( filename ).c_str(), "w" ); + if( !f ) { return false; } + opened = true; + } + + // ensure that the greatest instruction set referenced is used for listing + if (list_cpu!=cpu) { SetCPU(list_cpu); } + + // Build a disassembly lookup table + uint8_t mnemonic[256]; + uint8_t addrmode[256]; + memset(mnemonic, 255, sizeof(mnemonic)); + memset(addrmode, 255, sizeof(addrmode)); + for (int i = 0; i < opcode_count; i++) { + for (int j = AMB_COUNT-1; j >= 0; j--) { + if (opcode_table[i].modes & (1 << j)) { + uint8_t op = opcode_table[i].aCodes[j]; + if (addrmode[op]==255) { + mnemonic[op] = (uint8_t)i; + addrmode[op] = (uint8_t)j; + } + } + } + } + + strref first_src; + for( std::vector
::iterator si = allSections.begin(); si != allSections.end() && !first_src; ++si ) { + if( !si->pListing ) + continue; + for(auto & li : *si->pListing) { + if( li.source_name ) { first_src = li.source_name; break; } + } + } + fprintf( f, ";6502/65C02/65816/CPU64/DTV Turbo Assembler V1.4x listing file of \"" STRREF_FMT "\"\n;done on WkDay Month Date Time\n\n", STRREF_ARG( first_src ) ); + + fprintf( f, ";Offset\t;Hex\t\t;Monitor\t;Source\n\n" ); + + for(auto &si : allSections) { + if( !si.pListing || si.type == ST_REMOVED || !si.pListing ) { continue; } + for(const struct ListLine &lst : *si.pListing) { + /*if( lst.size && lst.wasMnemonic() )*/ { + strown<256> out; + /*if( lst.size )*/ { out.sprintf_append( ".%04x\t", lst.address + si.start_address ); } + int s = lst.wasMnemonic() ? ( lst.size < 4 ? lst.size : 4 ) : ( lst.size < 8 ? lst.size : 8 ); + if( si.output && si.output_capacity >= size_t( lst.address + s ) ) { + for( int b = 0; b < s; ++b ) { + out.sprintf_append( "%02x ", si.output[ lst.address + b ] ); + } + } + out.append( "\t\t" ); + if (lst.size && lst.wasMnemonic()) { + //out.pad_to(' ', 21); + uint8_t *buf = si.output + lst.address; + uint8_t op = mnemonic[*buf]; + uint8_t am = addrmode[*buf]; + if (op != 255 && am != 255 && am<(sizeof(aAddrModeFmt)/sizeof(aAddrModeFmt[0]))) { + const char *fmt = aAddrModeFmt[am]; + if (opcode_table[op].modes & AMM_FLIPXY) { + if (am == AMB_ZP_X) fmt = "%s $%02x,y"; + else if (am == AMB_ABS_X) fmt = "%s $%04x,y"; + } + if (opcode_table[op].modes & AMM_ZP_ABS) { + out.sprintf_append(fmt, opcode_table[op].instr, buf[1], (char)buf[2]+lst.address+si.start_address+3); + } else if (opcode_table[op].modes & AMM_BRANCH) { + out.sprintf_append(fmt, opcode_table[op].instr, (char)buf[1]+lst.address+si.start_address+2); + } else if (opcode_table[op].modes & AMM_BRANCH_L) { + out.sprintf_append(fmt, opcode_table[op].instr, (int16_t)(buf[1]|(buf[2]<<8))+lst.address+si.start_address+3); + } else if (am==AMB_NON||am==AMB_ACC) { + out.sprintf_append(fmt, opcode_table[op].instr); + } else if (am==AMB_ABS||am==AMB_ABS_X||am==AMB_ABS_Y||am==AMB_REL||am==AMB_REL_X||am==AMB_REL_L) { + out.sprintf_append(fmt, opcode_table[op].instr, buf[1]|(buf[2]<<8)); + } else if (am==AMB_ABS_L||am==AMB_ABS_L_X) { + out.sprintf_append(fmt, opcode_table[op].instr, buf[1]|(buf[2]<<8)|(buf[3]<<16)); + } else if (am==AMB_BLK_MOV) { + out.sprintf_append(fmt, opcode_table[op].instr, buf[1], buf[2]); + } else if (am==AMB_IMM && lst.size==3) { + out.sprintf_append("%s #$%04x", opcode_table[op].instr, buf[1]|(buf[2]<<8)); + } else { + out.sprintf_append(fmt, opcode_table[op].instr, buf[1]); + } + } + } else { out.append('\t');} +// out.pad_to( ' ', 36 ); + out.append( '\t' ); + strref line = lst.code.get_skipped( lst.line_offs ).get_line(); + line.clip_trailing_whitespace(); + strown<128> line_fix( line ); + for( strl_t pos = 0; pos < line_fix.len(); ++pos ) { + if( line_fix[ pos ] == '\t' ) + line_fix.exchange( pos, 1, pos & 1 ? strref( " " ) : strref( " " ) ); + } + out.append( line_fix.get_strref() ); + + fprintf( f, STRREF_FMT "\n", STRREF_ARG( out ) ); + } + } + } + fprintf( f, "\n;****** end of code\n" ); + if( opened ) { fclose( f ); } + return true; +} + bool Asm::List(strref filename) { FILE *f = stdout; bool opened = false; @@ -6871,6 +6981,8 @@ StatusCode Asm::WriteA2GS_OMF(strref filename, bool full_collapse) { int main(int argc, char **argv) { const strref listing("lst"); + const strref tass_listing( "tsl" ); + const strref tass_labels( "tl" ); const strref allinstr("opcodes"); const strref endmacro("endm"); const strref cpu("cpu"); @@ -6884,12 +6996,16 @@ int main(int argc, char **argv) { bool gen_allinstr = false; bool gs_os_reloc = false; bool force_merge_sections = false; + bool list_output = false; + bool tass_list_output = false; + Asm assembler; const char *source_filename = nullptr, *obj_out_file = nullptr; const char *binary_out_name = nullptr; - const char *sym_file = nullptr, *vs_file = nullptr; + const char *sym_file = nullptr, *vs_file = nullptr, *tass_labels_file = nullptr; strref list_file, allinstr_file; + strref tass_list_file; for (int a = 1; avalue; + if( size_t( i->section ) < assembler.allSections.size() ) { value += assembler.allSections[ i->section ].start_address; } + if( i->name.same_str( "debugbreak" ) ) {} + else { + strown<256> line; + line.append( i->name ); + line.sprintf_append( "\t= $%04x\n", value); + fprintf(f, line.c_str()); + } + } + fclose( f ); + } + } + + + } // free some memory assembler.Cleanup();