Jump to content
IGNORED

Object file format details?


TheBF
 Share

Recommended Posts

So I created a little set of markup tags that let me create the output format.

Which makes the final program to generate an object file look like this.

HEX
: .EA3  ( -- )
        <NEW.EA3>
        LOADADDRESS <AORG>
        <HEADER>
        THERE ORGADR @
        DO
           <9> I <####>  I  B/REC <WORDS>  <CRC> <EOR> <LINE#> <BR>
        B/REC +LOOP
        <EOF> <FOOTER>  <LINE#> ;

Which I thought was pretty clever. :)

 

But I have something wrong with the checksum.

 

I thought it would be simple to create a little ASM program and compare the object file from the TI assembler,

but I cannot get Classic99 to generate one.

 

My program assembles with no errors.

What incantations do I need to create an object file in Classic99 E/A?

 

B

 

*EDIT* OK I got a file but it is binary. (compressed) But I did not use the C option. ??

 

EDIT2: OK it's not compressed its in a CLASSIC99 format. So I will have to create that around my ea3 file.

 

The fog is slowly lifting...

Edited by TheBF
Link to comment
Share on other sites

Classic99 does not have its own formats. So there is no "Classic99 format". This is very intentional.

 

If you used a disk image, then it's a V9T9 disk image (also called 'sector format'). The file would be inside that.

 

If you are using FIAD instead, then it's either a V9T9 file or a TIFILES file, depending on what you have configured. Both of these have a 128 byte header (which differs slightly) followed by the actual data, laid out as it would be on a diskette (that is to say, blocked into 256 byte 'sectors'.)

 

You can usually ask Classic99 to write a text file as a Windows text file by inserting a "?W" string after the device name (ie: DSK1.?W.OUTPUT.TXT). However, in testing here this trick does not work with the output filename from the assembler because it tries to work as DF80 (instead of DV80) and also tries to open the output file in UPDATE mode instead of OUTPUT mode. These two steps trigger an error message that stops the assembler.

 

There are two ways to work around it. The first, and the simplest way, is to assemble normally. Then use the PRINT option to write it out to a Windows file (thus Classic99 does the conversion for you). Just print to "DSK1.?W.OUTPUT.TXT". I've tried this and it works fine. (You can also print to "CLIP" to put it on the clipboard instead for pasting).

 

post-12959-0-65152000-1494348602_thumb.png

 

The second way if you will do this a lot is to change the option on the disk configuration and enable "Write DF80 as Windows Text". Just be aware that this can in some instances make it difficult to reload the file into the TI emulator again, since all the format information is thrown away. I'd recommend the print approach for now.

Edited by Tursi
  • Like 1
Link to comment
Share on other sites

Classic99 does not have its own formats. So there is no "Classic99 format". This is very intentional.

 

If you used a disk image, then it's a V9T9 disk image (also called 'sector format'). The file would be inside that.

 

If you are using FIAD instead, then it's either a V9T9 file or a TIFILES file, depending on what you have configured. Both of these have a 128 byte header (which differs slightly) followed by the actual data, laid out as it would be on a diskette (that is to say, blocked into 256 byte 'sectors'.)

 

You can usually ask Classic99 to write a text file as a Windows text file by inserting a "?W" string after the device name (ie: DSK1.?W.OUTPUT.TXT). However, in testing here this trick does not work with the output filename from the assembler because it tries to work as DF80 (instead of DV80) and also tries to open the output file in UPDATE mode instead of OUTPUT mode. These two steps trigger an error message that stops the assembler.

 

There are two ways to work around it. The first, and the simplest way, is to assemble normally. Then use the PRINT option to write it out to a Windows file (thus Classic99 does the conversion for you). Just print to I've tried this and it works fine. (You can also print to "CLIP" to put it on the clipboard instead for pasting).

 

attachicon.gifpic.png

 

The second way if you will do this a lot is to change the option on the disk configuration and enable "Write DF80 as Windows Text". Just be aware that this can in some instances make it difficult to reload the file into the TI emulator again, since all the format information is thrown away. I'd recommend the print approach for now.

I have found frustration with Assembler cutting off text files an 80 columns yet my RICH/NOTEPAD text files are much longer lines.

 

The GPL Assembler and Editor Assembler both do this. Does this still happen with "DSK1.?W.OUTPUT.TXT". as I assume they work without change?

Link to comment
Share on other sites

Classic99 does not have its own formats. So there is no "Classic99 format". This is very intentional.

 

If you used a disk image, then it's a V9T9 disk image (also called 'sector format'). The file would be inside that.

 

If you are using FIAD instead, then it's either a V9T9 file or a TIFILES file, depending on what you have configured. Both of these have a 128 byte header (which differs slightly) followed by the actual data, laid out as it would be on a diskette (that is to say, blocked into 256 byte 'sectors'.)

 

You can usually ask Classic99 to write a text file as a Windows text file by inserting a "?W" string after the device name (ie: DSK1.?W.OUTPUT.TXT). However, in testing here this trick does not work with the output filename from the assembler because it tries to work as DF80 (instead of DV80) and also tries to open the output file in UPDATE mode instead of OUTPUT mode. These two steps trigger an error message that stops the assembler.

 

There are two ways to work around it. The first, and the simplest way, is to assemble normally. Then use the PRINT option to write it out to a Windows file (thus Classic99 does the conversion for you). Just print to "DSK1.?W.OUTPUT.TXT". I've tried this and it works fine. (You can also print to "CLIP" to put it on the clipboard instead for pasting).

 

attachicon.gifpic.png

 

The second way if you will do this a lot is to change the option on the disk configuration and enable "Write DF80 as Windows Text". Just be aware that this can in some instances make it difficult to reload the file into the TI emulator again, since all the format information is thrown away. I'd recommend the print approach for now.

 

Thanks Tursi!

  • Like 1
Link to comment
Share on other sites

I have found frustration with Assembler cutting off text files an 80 columns yet my RICH/NOTEPAD text files are much longer lines.

 

The GPL Assembler and Editor Assembler both do this. Does this still happen with "DSK1.?W.OUTPUT.TXT". as I assume they work without change?

 

I expect it will still cut off. The Editor/Assembler package opens everything with 80 character record lengths, so no line can be longer than 80 chars.

  • Like 1
Link to comment
Share on other sites

  • 2 years later...

This is a little convoluted but I think you could do it with Classic99 if you know the start address and the end address of the program's image in memory.

 

  1. Load the object file program into Classic99
  2. Press F1 to stop the program
  3. Press Select the "Make" Menu in Classic99 and click the "Save memory as a program option"
  4. Typically you would click the high RAM box and enter the start and end addresses.  (make end address 1 byte more if end is an even number)
  5. Enter the start address which is the address the program enters to run itself.
  6. Click Include E/A utilities and character set if your program depends on those things (I have never used this)
  7. Press the build button

Its one way to "skin the cat"

  • Like 1
Link to comment
Share on other sites

  • 2 years later...


Anyone have ideas on extending the TI tagged object file format?

 

(I'll call it TOFF)

 

I'm interested in ways to add long symbol names, up to 31 characters.

 

For symbol names, the existing tags are 3 and 4 for REFs, 5 and 6 for DEFs.

 

They are followed by a 16-bit word and 6 characters of symbol name. Just 6 significant characters, which I read was the standard for C in 80 and Fortran before that.

 

Example:

300E6VMBW  50020START 
00E6 Relocatable address of first reference to VMBW (chained)
0020 Relocatable entry point of DEF START

 

C language standard 5.2.4.1 defines these limits:
* 63 significant characters in an internal identifier
* 31 significant initial characters in an external identifier

 

To get 31 characters into the REF/DEF, I thought of starting the field with a character 1-31 for the string length.
Compressed object format uses non-printable characters already. But that would be mixing modes.


Collecting the above references: 


Tagged Object File Format

http://www.unige.ch/medecine/nouspikel/ti99/ea_mod.htm#tagged-object
http://www.ninerpedia.org/index.php?title=Tagged_Object_Code
http://turboforth.net/resources/ea3loader.html

 

C Draft Standard

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf


Example from Mark Wills' TurboForth page

00000        92000920029200492006B2008B04C0B04C6B020CB0024B30C07F366F       0001
92012B020CB0006B3606B04C1B0200B0100B0202B0008B020CB0024B30C07F333F          0002
...
921B4B0E08B191CB1B07B1402B1B1CB1016B1701B111A7F5FFF                         0021
62006KSCAN 62000VBLANK62002KSTAT 7F7E4F                                     0022
:Asm994a TMS99000 Assembler - v3.010                                        0023

 

Link to comment
Share on other sites

24 minutes ago, FarmerPotato said:


Anyone have ideas on extending the TI tagged object file format?

 

(I'll call it TOFF)

 

I'm interested in ways to add long symbol names, up to 31 characters.

 

If you had a new object file wouldn't you need a new loader in a cartridge too?

 

It would be up to the all the assemblers and compilers to generate it so they all need changing too.

What do the new tool chains generate?  They allow long label names.

 

It would not be hard to modify my linker to read them by changing the 6 to 31 below. :) 

: GETLABEL  ( addr len -- addr' len' label len)
        /TAG  6 CHOP  -TRAILING ;

But something has to generate the new format. 

Or are you proposing creating a "standard" for tools chains to comply with?

Link to comment
Share on other sites

3 hours ago, TheBF said:

But something has to generate the new format. 

Or are you proposing creating a "standard" for tools chains to comply with?

Yeah, that's the idea: propose a new standard where you can have longer symbol names.

It doesn't have to be backwards compatible (though I guess 6-character names might be output exactly as before.)

 

Then:

  • Suppose a C compiler output the 9900 assembly source with long names. 
  • An assembler is adapted to allow long names and output them in object code. 
  • A linker/loader is modified to accept that.

TI's format was geared for Fortran.  Here's what I found for Fortran 77:

  • Symbolic names can any number of characters long. The standard is 6. @
    
    Symbolic names consist of letters, digits, the dollar sign ($), and the underscore character (_). $ and _ are not standard. @
    
    Symbolic names generally start with a letter--never with a digit or dollar sign ($). Names that start with an underscore (_) are allowed, but may conflict with names in the Fortran and system libraries.

 

Sound familiar?

 

  • Like 2
Link to comment
Share on other sites

30 minutes ago, Tursi said:

If you need to do all that work anyway, I'd be inclined to do none of it and just declare the ELF format output by GCC to be sufficient. It meets your design goals. At worst, you need to write a loader to do whatever you wanted long labels for. :)

 

I hadn't considered jumping to a different format. Hmm. 

 

 

Link to comment
Share on other sites

Actually, Paul Charlton (@techguru) implemented long names in GenPROG ie GenASM/GenLINK. Names from 6-31 chars are preceded by the length byte. While GENASM /O turns off extensions and makes E/A compatible output. Debug symbols are another extension in GenPROG.

 

Also, it should be easy to modify @ralphb 's xas99 to output REF/DEF as GenASM does. Then they can be fed to GenLINK.

 

So, that covers what I wanted.

 

 

GenLINK v1.00 page 18


"3" 	{2 byte relocatable REF chain header} <symbol> 
"4"		{2 byte absolute REF chain header} <symbol>

These tags are used to define symbols which are to be resolved from other object
modules. Each REF symbol in a file must be placed into the object file as a
linked-list of addresses, the data at each address in the object file must
contain a pointer to the next location which needs to be patched when the REF is
resolved. The last location to be patched must have a value of >0000 in the
object file.

The following algorithm is used to resolve REFerenced symbols: 
  
location = header
while (location != 0)
do {
	temp = *location;
	*location = DEF symbol value; location = temp
}

The "symbol" used in the REF may have one of two forms, depending on the number
of characters in the symbol name.

If the symbol name has six or fewer characters, it must be entered into the
object file in a field six characters wide, padded on the right with spaces if
it is shorter than six characters to start with.

If the symbol name has seven to thirty-one characters, it must be entered into
the object file as <length><characters>, where <length> is a single character
with a value of >07 to >1f.

"5"		{2 byte relocatable address} <symbol>
"6"		{2 byte absolute address} <symbol>

These tags are used to define symbols for use in other object modules. The 2
byte address specified is used as the value of the symbol.

The symbol's name must be constructed as described under tag "3" and "4".

 

Edited by FarmerPotato
  • Like 1
Link to comment
Share on other sites

43 minutes ago, Tursi said:

If you need to do all that work anyway, I'd be inclined to do none of it and just declare the ELF format output by GCC to be sufficient. It meets your design goals. At worst, you need to write a loader to do whatever you wanted long labels for. :)

 

 

 

What intermediate formats does gcc9900 (with your libti99) use?  

 

Link to comment
Share on other sites

6 hours ago, FarmerPotato said:

What intermediate formats does gcc9900 (with your libti99) use?  

I didn't build gcc9900, and the library doesn't have any impact on that. So, I'm not the right one to ask. All I know is it outputs ELF format files, which are well documented, and includes a tool to convert ELF to EA#5 ;)

 

More than likely, it outputs the same intermediate formats as most other ports of GCC, though... but I don't expect any of them to be more useful than the linked ELF.

 

  • Like 1
Link to comment
Share on other sites

On 1/27/2022 at 1:29 AM, Tursi said:

I didn't build gcc9900, and the library doesn't have any impact on that. So, I'm not the right one to ask. All I know is it outputs ELF format files, which are well documented, and includes a tool to convert ELF to EA#5 ;)

 

More than likely, it outputs the same intermediate formats as most other ports of GCC, though... but I don't expect any of them to be more useful than the linked ELF.

 

Thanks, that's what I wanted to know.  

 

I went and spent some time considering ELF. 

 

Then I checked how COFF was doing these days.  TI used it in their own C compilers (TMS320Cxxxx, TMS340, MSP430, Code Composer etc), but added ELF in the 2000s. 

 

Looks like GenPROG is all I need right now.

 

 

 

Edited by FarmerPotato
  • Like 2
Link to comment
Share on other sites

On 7/2/2019 at 9:11 AM, g0blinish said:

how to convert object file to executable binary? lost in mans (

With xas99, you could do

xas99.py -l yourobjectfile.obj -b -o theexecutable.bin

which basically "links" your object code into a binary.  You'll need to supply a start address with "-a <addr>", though, if the object code is relocatable.

  • Like 1
Link to comment
Share on other sites

6 minutes ago, ralphb said:

With xas99, you could do


xas99.py -l yourobjectfile.obj -b -o theexecutable.bin

which basically "links" your object code into a binary.  You'll need to supply a start address with "-a <addr>", though, if the object code is relocatable.

 

I didn't know xas99 was a linker!  I just read the current docs.

 

XDT99 is a really great tool. If it were shareware, I would have paid for it already!  The extensions and flexibility are tremendously helpful, and I appreciate the -105 option.

 

I'm currently using it to output Geneve2020 ROMs. So far I just configure output to binary, and I've got an AORG 0. Externally, I break it into high/low bytes for 16-bit data bus.  

 

 

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...