// Copyright (C) 2000-2003 Core Technologies. // // This file is part of tpasm. // // tpasm is free software; you can redistribute it and/or modify // it under the terms of the tpasm LICENSE AGREEMENT. // // tpasm 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 // tpasm LICENSE AGREEMENT for more details. // // You should have received a copy of the tpasm LICENSE AGREEMENT // along with tpasm; see the file "LICENSE.TXT". // Dump segments out in Motorola S-Record format #include "include.h" static int dataRecordType, endRecordType; static void DumpGenericLine(FILE *theFile,unsigned int address,unsigned char recordType,unsigned char *theBytes,int numBytes) // Create a line of motorola hex output to theFile { int checkSum; int i; checkSum=0; switch(recordType) { case 0: // all these types have 2 byte addresses case 1: case 4: case 5: case 6: case 9: fprintf(theFile,"S%d%02X%04X",recordType,numBytes+3,address&0xFFFF); checkSum+=numBytes+3; checkSum+=address&0xFF; checkSum+=(address>>8)&0xFF; break; case 2: // these have 3 byte addresses case 8: fprintf(theFile,"S%d%02X%06X",recordType,numBytes+4,address&0xFFFFFF); checkSum+=numBytes+4; checkSum+=address&0xFF; checkSum+=(address>>8)&0xFF; checkSum+=(address>>16)&0xFF; break; case 3: // these have 4 byte addresses case 7: fprintf(theFile,"S%d%02X%08X",recordType,numBytes+5,address); checkSum+=numBytes+5; checkSum+=address&0xFF; checkSum+=(address>>8)&0xFF; checkSum+=(address>>16)&0xFF; checkSum+=(address>>24)&0xFF; break; } for(i=0;igenerateOutput) { thePage=theSegment->firstPage; while(thePage) { for(i=0;i<256;i+=16) { j=0; while(j<16) { while(j<16&&!(thePage->usageMap[(i+j)>>3]&(1<<(j&7)))) // skip over empty space { j++; } if(j<16) { k=j; while(k<16&&(thePage->usageMap[(i+k)>>3]&(1<<(k&7)))) // count up used space { k++; } DumpLine(theFile,thePage->address+i+j,&thePage->pageData[i+j],k-j); // dump out used bytes j=k; // move forward } } } thePage=thePage->next; } } } static bool OutputSegments(FILE *theFile) // create a hex dump of all segments to theFile // NOTE: this is careful to dump only the bytes which are marked as used // within each segment // Segments marked as not generating output will not be dumped // NOTE: Segments will be dumped in reverse order of creation // this should probably be changed to dump in the order of creation { SEGMENT_RECORD *theSegment; theSegment=segmentsHead; while(theSegment) { DumpSegment(theFile,theSegment); theSegment=theSegment->next; } DumpEOF(theFile); return(true); } static bool OutputSegments16(FILE *theFile) // output segments with S1 records (16 bit addresses) { dataRecordType=1; endRecordType=9; return(OutputSegments(theFile)); } static bool OutputSegments32(FILE *theFile) // output segments with S3 records (32 bit addresses) { dataRecordType=3; endRecordType=7; return(OutputSegments(theFile)); } // output file types handled here (the constuctors for these variables link them to the global // list of output file types that the assembler knows how to handle) static OUTPUTFILE_TYPE outputFileType32("srec32","Motorola S-Record format segment dump (32 bit)",false,OutputSegments32), outputFileType16("srec","Motorola S-Record format segment dump (16 bit)",false,OutputSegments16);