+Lee Stewart Posted January 19, 2020 Share Posted January 19, 2020 2 hours ago, ralphb said: And alas, so far no one could name a use for RORG <addr>, so we don't know if the offset really is waste. Actually, I thought that I did (see post #4). Even though it was a workaround, it was, indeed, “RORG <addr>”. ...lee Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 19, 2020 Share Posted January 19, 2020 Ah, I finally understood the point. The first program is this RORG >0010 DATA 1 DATA 2 DATA 3 END and the loader loads the data at addresses A010, A012, A014. When I now load RORG >0020 DATA 4 DATA 5 DATA 6 RORG >0030 DATA 7 DATA 8 END the data are put at A036, A038, A03A, A046, A048; just saw it in the MAME debugger. That is the way it should be. The relocatable location counter points to the first free word in the relocatable space, and this is RORG 0. Anything else would not make sense. If you concatenate the sources for a single file, then of course, the location counter is a single one for the concatenated file. If I inserted the second file before the end of the first one, the locations of 4, 5, 6, 7, 8 would be A020 etc. 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 21, 2020 Author Share Posted January 21, 2020 On 1/19/2020 at 5:02 PM, mizapf said: That is the way it should be. The relocatable location counter points to the first free word in the relocatable space, and this is RORG 0. Anything else would not make sense. If you concatenate the sources for a single file, then of course, the location counter is a single one for the concatenated file. So linking two files yields something different than COPYing them? I mean, I'm fine with that, I was just looking for a motivation. Also, about resolving conflicts between AORG and RORG: If this happens within one program unit, sure, blame the developer. But I think it's a valid conflict scenario for linking two files, potentially by two different authors. Why would I need to disassemble the object file to spot any potential conflicts? But anyway, my question was how to resolve something like this: AORG >10 DATA 1,1 linked with RORG >E DATA 2,2 Would the resulting program with conflicts resolved be equivalent to AORG >10 DATA 1,1 RORG >14 * MOVE AS LITTLE AS REQUIRED DATA 2,2 or rather AORG >10 DATA 1,1 RORG >22 * KEEP THE RORG "DISTANCE" TO OTHER SEGMENTS The answer depends on what that offset would be used for. Finally, note that such conflicts only manifest when linking into binary formats such as cartridge or E/A 5 image. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted January 21, 2020 Share Posted January 21, 2020 8 hours ago, ralphb said: So linking two files yields something different than COPYing them? I mean, I'm fine with that, I was just looking for a motivation. Also, about resolving conflicts between AORG and RORG: If this happens within one program unit, sure, blame the developer. But I think it's a valid conflict scenario for linking two files, potentially by two different authors. Why would I need to disassemble the object file to spot any potential conflicts? But anyway, my question was how to resolve something like this: AORG >10 DATA 1,1 linked with RORG >E DATA 2,2 Would the resulting program with conflicts resolved be equivalent to AORG >10 DATA 1,1 RORG >14 * MOVE AS LITTLE AS REQUIRED DATA 2,2 or rather AORG >10 DATA 1,1 RORG >22 * KEEP THE RORG "DISTANCE" TO OTHER SEGMENTS The answer depends on what that offset would be used for. Finally, note that such conflicts only manifest when linking into binary formats such as cartridge or E/A 5 image. mizapf's finding makes sense to me (in the previous post.) RORG with an offset N is just like RORG followed by BSS N. AORG shouldn't affect the relocation counter at all. If two object files have conflicting AORG sections, or overlap absolute addresses on the free area for relocatable code, that is a bug. So your first two files linked together should result in: 0010 0001 0012 0001 R000E 0002 -> A00E 0002 R0010 0002 -> A010 0002 As I understand it, the second file would be equivalent to RORG * redundant BSS >E DATA 2,2 A question I have is, how would you link multiple relocatable files into a base like >6000? with the TI linker, one kludge is to AORG into the first free address counter, and put >6000 there, then do RORG (does that work?). You'd have to have RAM at >6000. Same question for linking a DSR to >4000 from relocatable files? Is there a directive for that? I think I made cartridge binaries in the past with GENLINK and RORG. Good tool. 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 21, 2020 Share Posted January 21, 2020 9 hours ago, ralphb said: So linking two files yields something different than COPYing them? I mean, I'm fine with that, I was just looking for a motivation. Sure. COPY means source code inclusion. This also means your symbols are available in the file with all inclusions. You can create a file with some constants and COPY it into your code for direct use. Using COPY means you get a single object code. Linking via the linking loader requires you to declare symbols with DEF, and you have to explicitly REF them in another file that is to be linked with the first one. All other symbols are only valid in the respective object file. AORG or RORG are only interesting for the assembler, not the linker. The linker does not see any of them; it only sees the 9 or A tags (9 for absolute position, A for relocatable position), and it does not know how they were created (e.g. by BSS, BES, or RORG). 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 21, 2020 Share Posted January 21, 2020 9 hours ago, ralphb said: So linking two files yields something different than COPYing them? I mean, I'm fine with that, I was just looking for a motivation. Yeah, it would be a bad idea to COPY multiple files that each contain RORG operands when they are intended to be offsets from the beginning load address of each file. Regarding your examples, it might be clearer what happens if the AORGed address were >A010 instead of >10. As @FarmerPotato mentioned, AORG does not affect the relocation counter. In fact, the E/A loader does not update the program load address when it loads a program with no relocatable code. If you load the following File #1 and File #2 separately or as part of the same file (File #3), they will have precisely the same result with the E/A loader, which is to overwrite the first >0001 of the AORGed code with the second >0002 of the RORGed code: * File #1 AORG >A010 DATA 1,1 * File #2 RORG >E DATA 2,2 * File #3 AORG >A010 DATA 1,1 RORG >E DATA 2,2 The above presumes that the first available high memory address is >A000. ...lee 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 22, 2020 Author Share Posted January 22, 2020 15 hours ago, FarmerPotato said: mizapf's finding makes sense to me (in the previous post.) RORG with an offset N is just like RORG followed by BSS N. AORG shouldn't affect the relocation counter at all. If two object files have conflicting AORG sections, or overlap absolute addresses on the free area for relocatable code, that is a bug. ... unless it's a second RORG in a program unit. The point of relocatable code is that it can be moved around. The E/A loader treats initial RORGs like offsets, but this is a choice. And regarding conflicts, it's certainly not a likely scenario. But imagine you're linking someone else's sort routine, and for some reason that uses some RORG that conflicts with some AORG area you defined -- why wouldn't you want to move the conflicting relocatable code out of the way instead of having a broken program? 15 hours ago, FarmerPotato said: A question I have is, how would you link multiple relocatable files into a base like >6000? with the TI linker, one kludge is to AORG into the first free address counter, and put >6000 there, then do RORG (does that work?). You'd have to have RAM at >6000. Same question for linking a DSR to >4000 from relocatable files? Is there a directive for that? No, it doesn't. For E/A, there is no way I know of. For xas99, you can rebase relocatable code using the -a <base addr> option. Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 22, 2020 Author Share Posted January 22, 2020 14 hours ago, Lee Stewart said: Regarding your examples, it might be clearer what happens if the AORGed address were >A010 instead of >10. As was talking generally about linking, not loading using E/A. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 22, 2020 Share Posted January 22, 2020 1 hour ago, ralphb said: ... unless it's a second RORG in a program unit. The point of relocatable code is that it can be moved around. The E/A loader treats initial RORGs like offsets, but this is a choice. In assembly code, RORG typically appears when you used an AORG before. If you have a second RORG, then you may have had such an absolute block in between, but you would not expect that the loader treats this RORG block as if it were a completely independent file. As for your AORG/RORG overwrite concerns, it certainly sounds interesting that your linker intelligently avoids a clash of absolute code and relocatable code, but you should at least allow for a "compatibility" option with the same behaviour as our existing linkers. Otherwise, you may write some program that links correctly with your linker, but fails with the E/A or LDR linker. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 22, 2020 Share Posted January 22, 2020 4 hours ago, ralphb said: As was talking generally about linking, not loading using E/A. I understand. I just wanted to make clear that, with the E/A utilities, any AORGed addresses in ALC are irrelevant to any RORGed addressing offsets (which affect the E/A loader’s load pointers) and that AORGed addresses do not affect the load pointers. And, I think that anything you do with your linker should, at least, not break what happens with the E/A Assembler and Loader. I certainly welcome any additional, clearer capabilities of your linker. ...lee 2 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 22, 2020 Share Posted January 22, 2020 (edited) Here is a test. The original source code is RORG >0020 DATA 1,2,3 AORG >A024 DATA 4,5,6 RORG DATA 7 END This is the tagged object code as produced by the E/A assembler: 01 0028 " " A 0020 B 0001 B 0002 B 0003 9 A024 B 0004 B 0005 B 0006 A 0026 B 0007 F See the result in the memory view of the MAME debugger. Edited January 22, 2020 by mizapf 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 23, 2020 Author Share Posted January 23, 2020 I think this discussion makes no sense any more. I absolutely know what happens in the loader. That's not the point. And Lee, by "breaking" the loader you probably mean that linking must not yield a different result as the loader. Rest assured that I implemented that. But there is also a "safe" (a/k/a wrong, broken, unholy) mode that resolves conflicts. And I made my mind up how that should work. 2 1 Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted January 23, 2020 Share Posted January 23, 2020 Ralph, not sure if this has been asked before or if this is already possible; Would it be possible to set address boundaries? If during assembly the PC crosses the boundary a warning/error is generated. Simple case, assembling for an 8K cartridge (>6000 - >7fff) and program is too big, so PC goes beyond >7fff which ofcourse yields unpredictable results. To make this not too specific for this case, it would be cool if "protected" or "allowed" memory areas could be defined via pragma, hint or parameter. Quote Link to comment Share on other sites More sharing options...
+9640News Posted January 23, 2020 Share Posted January 23, 2020 28 minutes ago, retroclouds said: Ralph, not sure if this has been asked before or if this is already possible; Would it be possible to set address boundaries? If during assembly the PC crosses the boundary a warning/error is generated. Simple case, assembling for an 8K cartridge (>6000 - >7fff) and program is too big, so PC goes beyond >7fff which ofcourse yields unpredictable results. To make this not too specific for this case, it would be cool if "protected" or "allowed" memory areas could be defined via pragma, hint or parameter. Paul Charlton's GenASM/Linker had these capabilities. In the LINK control file for a project, you could set blocks: BLOCK >6000,>7FFF BLOCK >A000,>FFD8 This would allow one object file that may be AORG'd into 6000 to load into the >6000 area. Then, if other code was AORG'd to >A000, it would load there. Of course, if everything was going to run from cartridge space, you do not need to define other blocks. There is some control file manipulation to reorganize the blocks for the filesave process, but you could essentially with DEF statements for the >6000 code and >8000 code have different SLAST statements defined such as: SAVEALL UTIL1,>A000,SLAST2,4 SAVEALL UTIL4,>6000,SLAST1,3 I may have the "codes, i.e, 4 and 3" not used properly. What it does is established the first file that is loaded (UTIL1) to load initially at >A000, so it will be the first piece of code executed when the EA5 loader transfers from loading to program execution. The details for the linker is in the GenLINK manual for the precise details. Pulling from memory at the moment. Quote Link to comment Share on other sites More sharing options...
PeteE Posted January 23, 2020 Share Posted January 23, 2020 1 hour ago, retroclouds said: Ralph, not sure if this has been asked before or if this is already possible; Would it be possible to set address boundaries? If during assembly the PC crosses the boundary a warning/error is generated. Simple case, assembling for an 8K cartridge (>6000 - >7fff) and program is too big, so PC goes beyond >7fff which ofcourse yields unpredictable results. To make this not too specific for this case, it would be cool if "protected" or "allowed" memory areas could be defined via pragma, hint or parameter. This is already possible using the ".ifgt" and ".error" preprocessor commands. Ralph even shows this very thing as an example in the XDT99 documentation: Quote The .error command prints a message and aborts the assembly. aorg >6000 ... .ifgt $, >7fff .error 'Catridge program too large' .endif 2 Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 25, 2020 Author Share Posted January 25, 2020 And for what it's worth, xas99 also has a SAVE directive (for E/A 5 images and binaries) that will create one file each, containing the specified address range (missing addresses are set to 0). For example, file sample.a99 save >2000, >4000 ; saves >2000->3fff save >8300, >8400 ; saves >8300->83ff aorg >8300 bytes 1, 2, 3, 4 ... aorg >2000 limi 0 ... will create two files sample_2000.bin and sample_8300.bin with 8192 and 256 bytes, resp. (NOTE: This is the behavior of the upcoming version, the current xas99 also has SAVE, but might yield a different number of files.) 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.