ralphb Posted January 17, 2020 Share Posted January 17, 2020 I have a question for all assembly developers, irrespective of particular assembler used: In your programs, have you ever used the RORG directive with an address, like RORG >1000? If so, what was your motivation for doing so, e.g., did you want to reserve memory at the beginning of the program, or did you want the listing to show a particular address range, or did you want to use the address the program will be placed at later, or ...? I'm asking this question because I'm unsure about one detail regarding the new xas99 linker. The E/A loader, on the other hand, is quite primitive. It will load any relocatable program (i.e., one using RORG) relative to memory address >A000, which means that any RORG address >6000 or higher cannot be loaded by E/A. When loading two relocatable programs, the second program will be loaded relative to the end of the first program. Thus, if you load multiple programs with RORG >1000, you'll get a lot of unused space. For compatibility, the xas99 linker uses the same logic. But there is one special case, where a RORG programs conflicts with an AORG program, which the loader ignores. For xas99, I'm thinking of two possible solutions to resolve conflicts, and for deciding on one solution I would need to know some opinions on why one would use RORG with address -- I never have used this construct. (Programs can have both RORG and AORG parts, but I dont't want to complicate things too much here.) 1 Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted January 17, 2020 Share Posted January 17, 2020 No. Quote Link to comment Share on other sites More sharing options...
+9640News Posted January 17, 2020 Share Posted January 17, 2020 Never used it. Not sure if you have the capability, but I would also test with how GenLINK handles RORG on the Geneve. I know several of us use Paul Charlton's GenProg package. If you do not have a Geneve, you should be able to use a MAME system if you need to see/test something. The linker (LINK aka GenLINK) is very versatile as you can set memory boundaries as blocks (pages or 8K memory boundaries) for putting code and modules together. You can find the documentation for GenLINK by going to http://9640news.ddns.net:8080 as it is on the home page there if you are not familiar with it. There is also Clint Pulley's linker, however it has been 25 years since I used that software. I think people that use it are any programmers for "c" for MDOS which I have not heard or seen anyone developing things in a number of years. Beery Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2020 Share Posted January 17, 2020 Yes, I have used it. I used it as a workaround for a specific problem I was having with Cory Burr’s Asm994a.exe Assembler. RORG was not working as expected when a dummy block was inserted into relocatable code, which may have been due to a misunderstanding on my part. Nevertheless, I saved the address before DORG and restored it as follows: _RORG1 EQU $ DORG 0 ... RORG _RORG1 ... ...lee 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 17, 2020 Share Posted January 17, 2020 I have never used RORG - with or without an address. Quote Link to comment Share on other sites More sharing options...
GDMike Posted January 17, 2020 Share Posted January 17, 2020 Never used it. Im just Happy with AORG Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted January 17, 2020 Share Posted January 17, 2020 2 hours ago, Lee Stewart said: Yes, I have used it. I used it as a workaround for a specific problem I was having with Cory Burr’s Asm994a.exe Assembler. RORG was not working as expected when a dummy block was inserted into relocatable code, which may have been due to a misunderstanding on my part. Nevertheless, I saved the address before DORG and restored it as follows: _RORG1 EQU $ DORG 0 ... RORG _RORG1 ... ...lee So does RORG _RORG1 restore the address count to what it was at _RORG1? It sounds like Ralph is saying that the E/A loader interprets it to add _RORG1 to the first free address and continue there. The listing file should sort that out.. or its a bug in the loader. Quote Link to comment Share on other sites More sharing options...
F.G. Kaal Posted January 17, 2020 Share Posted January 17, 2020 I have just used it to create a listing with the correct addresses for debugging with SBUG. After printing the listing I assembled the program agian with just RORG. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 17, 2020 Share Posted January 17, 2020 Paul Charlton's GenASM does some pretty weird things with RORG in the object code, which I find rather ugly, but it seems to work, obviously. This is what TIImageTool produces from one of my program (and I surely did not use RORG). IDT '21:06:04' DEF START START B @>0000 R0004 TEXT 'ABS(' R0008 TEXT ' ? status=' R0016 TEXT ' ' BYTE >0D BYTE >0A DATA >0009 R001E DATA >FFFE DATA >FFFF DATA >0000 DATA >0001 DATA >0002 DATA >7FFE DATA >7FFF DATA >8000 DATA >8001 DATA >0006 R0032 LWPI >F000 RORG $-52 R0002 DATA R0032+2 R0004 BSS 52 R0038 LIMI >0000 LI R8,R001E MOV *R8+,R9 R0042 MOV *R8,R6 LI R1,>FC00 LST R1 ABS R6 STST R7 MOV *R8+,R0 LI R1,R0008 BL @>0000 MOV R7,R0 LI R1,R0016 BL @>0000 LI R0,>0027 LI R1,R0004 CLR R2 XOP @R0032,0 DEC R9 JNE R0042 BLWP @>0000 R0078 TEXT '0123456789ABCDEF' R0088 MOV R0,R3 RORG $-42 R0060 DATA R0088 RORG $-12 R0056 DATA R0088 R0058 BSS 50 R008A LI R2,>0004 R008E SRC R3,12 MOV R3,R4 ANDI R4,>000F MOVB @R0078(R4),*R1+ DEC R2 JNE R008E RT END (If only these silly emojis could be deactivated, at least in a code block ...) 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2020 Share Posted January 17, 2020 5 hours ago, FarmerPotato said: So does RORG _RORG1 restore the address count to what it was at _RORG1? It sounds like Ralph is saying that the E/A loader interprets it to add _RORG1 to the first free address and continue there. The listing file should sort that out.. or its a bug in the loader. It does, indeed, restore the address count to what it was at _RORG1. My listing file from Asm994a showed that to be the case. As I read the E/A Manual, if there is an RORG operand, the Assembler sets the relocation program counter to that value. If there is no RORG operand, the Assembler does the following: Following absolute (AORG) or dummy (DORG) code, picks up where relocatable code before AORG/DORG left off. If it is the first occurrence of relocatable data/code, it will be >0000. Following relocatable code, it has no effect. It was in (1) above where I believe Asm994a failed me. ...lee Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted January 18, 2020 Share Posted January 18, 2020 1 hour ago, Lee Stewart said: It does, indeed, restore the address count to what it was at _RORG1. My listing file from Asm994a showed that to be the case. As I read the E/A Manual, if there is an RORG operand, the Assembler sets the relocation program counter to that value. If there is no RORG operand, the Assembler does the following: Following absolute (AORG) or dummy (DORG) code, picks up where relocatable code before AORG/DORG left off. If it is the first occurrence of relocatable data/code, it will be >0000. Following relocatable code, it has no effect. It was in (1) above where I believe Asm994a failed me. ...lee I don't think I ever mixed them. I found uses for DORG 0 at the top of a file, like building struct offsets, then RORG for the code. I wrote whole programs with AORG (for XB environment or cart images). Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 18, 2020 Share Posted January 18, 2020 34 minutes ago, FarmerPotato said: I don't think I ever mixed them. I found uses for DORG 0 at the top of a file, like building struct offsets, then RORG for the code. I wrote whole programs with AORG (for XB environment or cart images). I used RORG because the original TI Forth programmers used it. They, however, did not use it with an operand. It followed an embedded dummy block. When I tried to assemble that code with Asm994a, it did not work as expected. That is when I used the workaround with the operand—mainly because I did not want to use the E/A Assembler (or learn another) at the time. I also used RORG with fbForth 1.0 because it was a clone of TI Forth, with the major change from sector-based Forth blocks to file-based Forth blocks. Obviously, for the cartridge-based development of fbForth 2.0, I had to use AORG, which requires an operand, so how to handle embedded dummy blocks was a little more obvious. ...lee Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 18, 2020 Author Share Posted January 18, 2020 Oh wow, that's interesting! Thanks to all who responded. The Geneve is a good point I'll have to check. But other than that, no one is really using RORG with address -- I'll change the xas99 linker accordingly. And please keep in mind that what I stated above only applies to loading multiple object codes (with E/A #3). Using multiple RORGs with address within one program unit (i.e., everything you assemble in one go) will not be additive. For example, RORG >1000 DATA 1 RORG >2000 DATA 2 places data at >B000 and >C000, but splitting this into two programs RORG >1000 DATA 1 and RORG >2000 DATA 2 will place it >B000 and >D002. Go figure. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 18, 2020 Share Posted January 18, 2020 (edited) Note that the RORG magic in the code is just done by GenASM, not by TASM that is also used on the Geneve. So it is not a requirement for the platform, and I did not use it in the source code. And actually, RORG does not appear in the object code; it is my TIImageTool that inserts these RORGs because the location counter was changed at that point in the tagged object code. Here is the tagged object code for reference. 000000: 01 00 a0 32 31 3a 30 36 3a 30 34 41 00 00 42 04 ...21:06:04A..B. 000010: 60 42 00 00 42 41 42 42 53 28 42 20 20 42 20 20 `B..BABBS(B B 000020: 42 29 3a 42 20 73 42 74 61 42 74 75 42 73 3d 42 B):B sBtaBtuBs=B 000030: 20 20 42 20 20 42 0d 0a 44 00 41 00 1e 42 00 09 B B..D.A..B.. 000040: 42 ff fe 42 ff ff 42 00 00 42 00 01 46 20 20 20 B..B..B..B..F 000050: 42 00 02 42 7f fe 42 7f ff 42 80 00 42 80 01 42 B..B..B..B..B..B 000060: 00 06 42 02 e0 42 f0 00 41 00 02 43 00 34 41 00 ..B..B..A..C.4A. 000070: 38 42 03 00 42 00 00 42 02 08 43 00 1e 42 c2 78 8B..B..B..C..B.x 000080: 42 c1 98 42 02 01 42 fc 00 42 00 81 42 07 46 42 B..B..B..B..B.FB 000090: 02 c7 42 c0 38 42 02 01 43 00 08 42 06 a0 46 20 ..B.8B..C..B..F 0000a0: 42 00 00 42 c0 07 42 02 01 43 00 16 42 06 a0 42 B..B..B..C..B..B 0000b0: 00 00 42 02 00 42 00 27 42 02 01 43 00 04 42 04 ..B..B.'B..C..B. 0000c0: c2 42 2c 20 43 00 32 42 06 09 42 16 e7 42 04 20 .B, C.2B..B..B. 0000d0: 42 00 00 42 30 31 42 32 33 42 34 35 42 36 37 42 B..B01B23B45B67B 0000e0: 38 39 42 41 42 42 43 44 42 45 46 42 c0 c0 46 20 89BABBCDBEFB..F 0000f0: 41 00 60 43 00 88 41 00 56 43 00 88 41 00 8a 42 A.`C..A.VC..A..B 000100: 02 02 42 00 04 42 0b c3 42 c1 03 42 02 44 42 00 ..B..B..B..B.DB. 000110: 0f 42 dc 64 43 00 78 42 06 02 42 16 f8 42 04 5b .B.dC.xB..B..B.[ 000120: 35 00 00 53 54 41 52 54 20 46 20 20 20 20 20 20 5..START F 000130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 000140: 3a 20 47 65 6e 41 53 4d 20 76 31 2e 30 33 2c 20 : GenASM v1.03, 000150: 28 43 29 20 31 39 38 38 2c 31 39 38 39 20 62 79 (C) 1988,1989 by 000160: 20 4a 2e 20 50 61 75 6c 20 43 68 61 72 6c 74 6f J. Paul Charlto 000170: 6e 2e 20 41 73 73 65 6d 62 6c 65 64 3a 20 30 36 n. Assembled: 06 000180: 2d 32 32 2d 31 39 20 32 31 3a 30 36 3a 30 34 20 -22-19 21:06:04 Edited January 18, 2020 by mizapf Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 18, 2020 Share Posted January 18, 2020 Reading the manual of GenASM, I now know why it creates such a strange code: It is a one-pass assembler. For that reason, it writes object code with forward references using a 0000, then rewinds the location counter when the symbol appears, inserts the values, then forwards again. What a nonsense. Why should one do a one-pass assembler? Just to save some time? I'd rather get a reasonable object code, I'm not so short of time. I think I'll return to TASM again. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 18, 2020 Share Posted January 18, 2020 Sorry, but what does RORG do? Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 18, 2020 Share Posted January 18, 2020 (edited) Switch the location pointer to relocatable mode and optionally set its value ("Relocatable origin"). The location pointer is the address pointer used by the assembler and the loader. In contrast, AORG ("Absolute origin") switches to absolute (non-relocatable) mode and places the argument into the location pointer. The code after this directive will be loaded starting from the provided address. To switch back to relocatable mode, you have to use RORG. Edited January 18, 2020 by mizapf Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 18, 2020 Share Posted January 18, 2020 (edited) So it's only for when you load (multiple) object files using E/A#3? Edited January 18, 2020 by Asmusr Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 18, 2020 Share Posted January 18, 2020 These assembler directives are directed at the linking loader (E/A option 3, Extended Basic loader, Geneve LDR). As I once said, what we - in the TI world - disparagingly call "just E/A 3" actually corresponds to Windows EXE files or Linux ELF files. The "E/A option 5" files correspond to the COM files in MSDOS. I know, it is a matter of loading speed for us. Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted January 18, 2020 Share Posted January 18, 2020 1 hour ago, mizapf said: Reading the manual of GenASM, I now know why it creates such a strange code: It is a one-pass assembler. For that reason, it writes object code with forward references using a 0000, then rewinds the location counter when the symbol appears, inserts the values, then forwards again. What a nonsense. Why should one do a one-pass assembler? Just to save some time? I'd rather get a reasonable object code, I'm not so short of time. I think I'll return to TASM again. Assemble MDOS or another large set of source files and you may appreciate the one-pass assembler's speed. I would abandon using my real hardware for development without the use of Paul's Genprog package. (To me, the object code is just an interim step to linking the resulting program image; I rarely find a need to inspect the object code with an image handy) My only recollection of using RORG with a directive is for some self-modifying relocatable code. I have seen its use sporadically in other source, less frequently than DORG and AORG. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 19, 2020 Share Posted January 19, 2020 I did not yet assemble GeneveOS/MDOS, but I do have some projects (TIC or assembly language) that have several source files (XModem e.g. has 14 source files, Fractals' executable files use 29K together). If one assembler takes 5 minutes and the other 8 minutes, I don't care, but this is just my personal view, of course. (I admit, at some time I stripped down the set of systems in MAME to the TI family when I built MAME, as I started to get annoyed from waiting 15 minutes every time that I started a build during debugging; now I am down to five minutes.) Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 19, 2020 Share Posted January 19, 2020 I guess this is quite unlikely, but do we have the source code of TASM? There is at least one bug that requires a fix: COC is not recognized as a valid mnemonic. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 19, 2020 Share Posted January 19, 2020 On 1/18/2020 at 12:09 PM, ralphb said: RORG >1000 DATA 1 RORG >2000 DATA 2 places data at >B000 and >C000, but splitting this into two programs RORG >1000 DATA 1 and RORG >2000 DATA 2 will place it >B000 and >D002. Go figure. The first example is as expected; the RORG value is absolute with respect to its location counter (i.e. the value is not an offset, but the relocatable address). I don't see the second result with TASM - or did you mean separately loaded object code (e.g. multiple calls of E/A option 3)? This is RORG1_S: RORG >1000 DATA 1 COPY "RORG2_S" END This is RORG2_S: RORG >2000 DATA 2 RORG >2800 DATA 3 The resulting object code: 01 28 02 20 20 20 20 20 20 20 20 41 10 00 42 00 .(. A..B. 01 41 20 00 42 00 02 41 28 00 42 00 03 46 20 20 .A .B..A(.B..F 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3a 20 20 20 39 39 2f 34 41 20 61 6e 64 20 39 36 : 99/4A and 96 34 30 20 43 72 6f 73 73 2d 41 73 73 65 6d 62 6c 40 Cross-Assembl 65 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 er with tags as text: A 1000 B 0001 A 2000 B 0002 A 2800 B 0003 F : 99/4A and 9640 Cross-Assembler I think for compatibility's sake you should allow for RORG <address>. Quote Link to comment Share on other sites More sharing options...
ralphb Posted January 19, 2020 Author Share Posted January 19, 2020 8 minutes ago, mizapf said: I don't see the second result with TASM - or did you mean separately loaded object code (e.g. multiple calls of E/A option 3)? [...] I think for compatibility's sake you should allow for RORG <address>. Yes, I'm talking about the loader of E/A 3, which basically does the linking. I'm not preventing the use of RORG with address in sources, but I wonder (a) if I should follow the approach of E/A and waste(?) a lot of space and (b) if and how I should resolve conflicts. Another example: RORG >1000 DATA 1 and AORG >1000 DATA -1 When loading both programs in E/A 3, one program will overwrite the other, as the loader doesn't check for address conflicts between absolute and relocatable segments. And alas, so far no one could name a use for RORG <addr>, so we don't know if the offset really is waste. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted January 19, 2020 Share Posted January 19, 2020 (edited) You mean AORG >B000? (Assuming that the relocatable location counter starts at A000.) Overwriting would be - I'd say - intentional. (Or: The program author just deserves it. ) One more suggestion from the section "1% of the people actually thought about this, but much less actually need it": You could think about including PSEG / CSEG / DSEG for your linker - just in case we discover that we could need that. (I actually included it in TIMT's disassembler. Just in case.) Edited January 19, 2020 by mizapf 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.