Asmusr Posted October 21, 2015 Share Posted October 21, 2015 Awesome Quote Link to comment Share on other sites More sharing options...
palmheads Posted November 11, 2015 Share Posted November 11, 2015 Had an idea to help newbies like me. And this may already be possible... One thing that I get stuck with is figuring out how many bytes each instruction uses. ie ;rotate keys ci r3,90 ;z key - rotate jne $+4 b @rotl ci r3,67 ;c key - rotate jne $+4 b @rotr li r9,0 bl @collsp For the small keyscan routine above, to figure out that I needed to jump $+4, I actually loaded up the LBLA & entering each instruction (as the LBLA compiles each line as entered) it told me how many bytes each instruction took. If it was possibly for the xdt tools to take an .asm file, & from a starting AORG actually output how many bytes each instruction took in 2 columns ie 7D00 lwpi >70b8 7D04 li r0,>0384 7D08 etc etc That might be useful for useless people such as myself! cheers Daryn Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted November 11, 2015 Share Posted November 11, 2015 (edited) Had an idea to help newbies like me. And this may already be possible... One thing that I get stuck with is figuring out how many bytes each instruction uses. ie ... Use labels. They're a bit more cryptic with the LBLA than with the E/A module—2 characters as opposed to the 6 allowed with E/A. You then rarely need to know how many bytes instructions take. Your code above would be ;rotate keys ci r3,90 ;z key - rotate jne kc b @rotl kc ci r3,67 ;c key - rotate jne ex b @rotr ex li r9,0 bl @collsp ...lee Edited November 11, 2015 by Lee Stewart 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 12, 2015 Share Posted November 12, 2015 I'm working on some F18A GPU code and will soon be using the XORG directive. Is there any chance you could add support for the new F18A GPU instructions? CALL >0C80 0000 1100 10Ts SSSS RET >0C00 0000 1100 0000 0000 PUSH >0D00 0000 1101 00Ts SSSS POP >0F00 0000 1111 00Td DDDD SLC >0E00 0000 1110 SHFT SSSS Thanks, Rasmus 1 Quote Link to comment Share on other sites More sharing options...
palmheads Posted November 14, 2015 Share Posted November 14, 2015 Use labels. They're a bit more cryptic with the LBLA than with the E/A module—2 characters as opposed to the 6 allowed with E/A. You then rarely need to know how many bytes instructions take. Your code above would be ;rotate keys ci r3,90 ;z key - rotate jne kc b @rotl kc ci r3,67 ;c key - rotate jne ex b @rotr ex li r9,0 bl @collsp ...lee Funny, I use labels everywhere...but did not think of doing this! haha cheers Lee! Daryn Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted November 14, 2015 Share Posted November 14, 2015 Funny, I use labels everywhere...but did not think of doing this! haha cheers Lee! Daryn Just remember that jump instructions do not use ‘@’ as do branch instructions. I still, occasionally, trip on that one. ...lee Quote Link to comment Share on other sites More sharing options...
ralphb Posted November 15, 2015 Author Share Posted November 15, 2015 One thing that I get stuck with is figuring out how many bytes each instruction uses. Sorry for the late reply, Daryn, but I've just returned from my vacation (nice to be offline for a while!). There really isn't anything to add to Lee's reply, except for two minor points. As you know, labels must be unique within each program so that references, e.g., in jump and branch instructions, can be resolved unambiguously. If you have many code sequences that correspond to IF or WHILE blocks you'll have to introduce a lot of unique labels. . ;rotate keys ci r3,90 ;z key - rotate jne nextkey1 b @rotl nextkey1 ci r3,67 ;c key - rotate jne nextkey2 b @rotr nextkey2 li r9,0 bl @collsp . These labels are not meant to be called from outside your current subroutine, and coming up with unique names can get difficult as your program grows. Just imagine that you want to test another key before the C key -- then you'd have to add a "nextkey3" label, but before the "nextkey2" one, which looks ugly. Mostly for this reason xas99 supports so-called local labels that need not be unique. This sounds weird at first -- where should we jump to if the target is not unique? . ci r3,90 ;z key - rotate jne !next b @rotl !next ci r3,67 ;c key - rotate jne !next b @rotr !next li r9,0 bl @collsp . But the answer is actually quite simple: the assembler will pick the nearest label after the current position. In your example above, each "jne !next" will skip to the next "!next" label. You might even drop the name of the label and use . ci r3,90 ;z key - rotate jne ! b @rotl ! ci r3,67 ;c key - rotate jne ! b @rotr ! li r9,0 bl @collsp . for maximum brevity (and IMHO legibility). The "!..." will always search forward. If you want to jump backwards you simple prefix the local label reference with a unary minus, e.g., . li r0, >a000 li r1, 128 ! clr *r0+ dect r1 jne -! ; jump back rt . And you can use "!!..." (and "-!!...") to jump to the label after the next label (the label before the previous label), although I personally rarely use this. Keep in mind, though, that local labels are unique to xas99; the original TI assembler won't know about them. Finally, if you ever really need to find out the size (or timings) of instructions, you can have a look at the listing file, generated with the -L option: . XAS99 CROSS-ASSEMBLER VERSION 1.5.1 ... 0001 checkkeys 0002 0000 0283 22 ci r3,90 ;z key - rotate 0002 005A 0003 0004 1602 14 jne ! 0004 0006 0460 28 b @rotl 0008 001Cr 0005 0006 000A 0283 22 ! ci r3,67 ;c key - rotate 000C 0043 0007 000E 1602 14 jne ! 0008 0010 0460 28 b @rotr 0012 001Er 0009 0010 0014 0209 20 ! li r9,0 0016 0000 0011 0018 06A0 32 bl @collsp 001A 0020r ... . The second column contains the (relative or absolute) address of the instruction. 3 Quote Link to comment Share on other sites More sharing options...
palmheads Posted November 16, 2015 Share Posted November 16, 2015 Sorry for the late reply, Daryn, but I've just returned from my vacation (nice to be offline for a while!). There really isn't anything to add to Lee's reply, except for two minor points. As you know, labels must be unique within each program so that references, e.g., in jump and branch instructions, can be resolved unambiguously. If you have many code sequences that correspond to IF or WHILE blocks you'll have to introduce a lot of unique labels. . ;rotate keys ci r3,90 ;z key - rotate jne nextkey1 b @rotl nextkey1 ci r3,67 ;c key - rotate jne nextkey2 b @rotr nextkey2 li r9,0 bl @collsp . These labels are not meant to be called from outside your current subroutine, and coming up with unique names can get difficult as your program grows. Just imagine that you want to test another key before the C key -- then you'd have to add a "nextkey3" label, but before the "nextkey2" one, which looks ugly. Mostly for this reason xas99 supports so-called local labels that need not be unique. This sounds weird at first -- where should we jump to if the target is not unique? . ci r3,90 ;z key - rotate jne !next b @rotl !next ci r3,67 ;c key - rotate jne !next b @rotr !next li r9,0 bl @collsp . But the answer is actually quite simple: the assembler will pick the nearest label after the current position. In your example above, each "jne !next" will skip to the next "!next" label. You might even drop the name of the label and use . ci r3,90 ;z key - rotate jne ! b @rotl ! ci r3,67 ;c key - rotate jne ! b @rotr ! li r9,0 bl @collsp . for maximum brevity (and IMHO legibility). The "!..." will always search forward. If you want to jump backwards you simple prefix the local label reference with a unary minus, e.g., . li r0, >a000 li r1, 128 ! clr *r0+ dect r1 jne -! ; jump back rt . And you can use "!!..." (and "-!!...") to jump to the label after the next label (the label before the previous label), although I personally rarely use this. Keep in mind, though, that local labels are unique to xas99; the original TI assembler won't know about them. Finally, if you ever really need to find out the size (or timings) of instructions, you can have a look at the listing file, generated with the -L option: . XAS99 CROSS-ASSEMBLER VERSION 1.5.1 ... 0001 checkkeys 0002 0000 0283 22 ci r3,90 ;z key - rotate 0002 005A 0003 0004 1602 14 jne ! 0004 0006 0460 28 b @rotl 0008 001Cr 0005 0006 000A 0283 22 ! ci r3,67 ;c key - rotate 000C 0043 0007 000E 1602 14 jne ! 0008 0010 0460 28 b @rotr 0012 001Er 0009 0010 0014 0209 20 ! li r9,0 0016 0000 0011 0018 06A0 32 bl @collsp 001A 0020r ... . The second column contains the (relative or absolute) address of the instruction. Thanks so much for this info ralphb, will try the local labels out for sure! Fantastic set of tools! Quote Link to comment Share on other sites More sharing options...
ralphb Posted November 17, 2015 Author Share Posted November 17, 2015 I'm working on some F18A GPU code and will soon be using the XORG directive. Is there any chance you could add support for the new F18A GPU instructions? Sure! I've added all of the above, plus PIX as an alias for XOP. I guess the SPI instructions aren't needed for regular programming? Just grab the latest version directly from GitHub. The IDEA plugin still needs to be updated, though. I noticed that a new IDEA platform version has been released, so I need to figure out any changes first. Are you staying put on IDEA 13, or do you plan to switch to their new subscription model? 2 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 17, 2015 Share Posted November 17, 2015 Sure! I've added all of the above, plus PIX as an alias for XOP. I guess the SPI instructions aren't needed for regular programming? Just grab the latest version directly from GitHub. The IDEA plugin still needs to be updated, though. I noticed that a new IDEA platform version has been released, so I need to figure out any changes first. Are you staying put on IDEA 13, or do you plan to switch to their new subscription model? Thank you, that's great. I will probably get a licence for IDEA 15 from my workplace. I think I just found an issue. This program: WIDTH EQU >100 HEIGHT EQU >C0 LI R2,WIDTH*HEIGHT/4 produces this output: XAS99 CROSS-ASSEMBLER VERSION 1.5.2 **** **** **** > problem.a99 0001 0100 WIDTH EQU >100 0002 00C0 HEIGHT EQU >C0 0003 0000 0202 20 LI R2,WIDTH*HEIGHT/4 0002 F000 but the result of the calculation should be >3000 instead of >F000. problem.a99 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 17, 2015 Share Posted November 17, 2015 Here is another issue, this time with XORG. If I try to assemble the code below I get an error that the JMP instruction is far out of range: ***** Out of range: LOOP +/- -0x3803 AORG >A000 B @LOOP XCODE XORG >3000 LOOP JMP LOOP END (This is just an example that wouldn't work with without a loop to copy the XCODE to >3000). Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted November 18, 2015 Share Posted November 18, 2015 Thank you, that's great. I will probably get a licence for IDEA 15 from my workplace. I think I just found an issue. This program: WIDTH EQU >100 HEIGHT EQU >C0 LI R2,WIDTH*HEIGHT/4 produces this output: XAS99 CROSS-ASSEMBLER VERSION 1.5.2 **** **** **** > problem.a99 0001 0100 WIDTH EQU >100 0002 00C0 HEIGHT EQU >C0 0003 0000 0202 20 LI R2,WIDTH*HEIGHT/4 0002 F000 but the result of the calculation should be >3000 instead of >F000. >F000 is, in fact, correct. That is what the E/A cartridge Assembler will give you. According to the E/A Manual, the “well-defined” expression in the EQU directive uses signed, integer division as opposed to the unsigned, integer division of the TMS9900's DIV instruction, which would result in the >3000 you expected. Asm994a gives >3000 for that same expression, which is in error per the E/A Manual. The E/A Manual does have a handful of errors; but, I doubt this is one of them. ...lee Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 18, 2015 Share Posted November 18, 2015 >F000 is, in fact, correct. That is what the E/A cartridge Assembler will give you. According to the E/A Manual, the “well-defined” expression in the EQU directive uses signed, integer division as opposed to the unsigned, integer division of the TMS9900's DIV instruction, which would result in the >3000 you expected. Asm994a gives >3000 for that same expression, which is in error per the E/A Manual. The E/A Manual does have a handful of errors; but, I doubt this is one of them. ...lee OK, thanks, so it's another backwards compatibility issue. I think it would be more useful if any rounding was postponed until the end, or at least it should give a warning at the point where the result of the multiplication of two unsigned numbers is being treated as a signed number. Quote Link to comment Share on other sites More sharing options...
Willsy Posted November 18, 2015 Share Posted November 18, 2015 How about a / for signed division, and a \ for unsigned division? Why you would want signed division in an assembler is beyond me, but I suppose we should stay with the TI standard. \ as unsigned seems more useful to me, however. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted November 18, 2015 Share Posted November 18, 2015 Why you would want signed division in an assembler is beyond me I could imagine you might want to find the difference of two memory location, and as soon as you assume negative values, you have to do signed arithmetics. Quote Link to comment Share on other sites More sharing options...
ralphb Posted November 18, 2015 Author Share Posted November 18, 2015 Here is another issue, this time with XORG. If I try to assemble the code below I get an error that the JMP instruction is far out of range: ***** Out of range: LOOP +/- -0x3803 Doh! That was caused by a typo: In one case I accidentally wrote self.symbols.xorgLOffset instead of self.symbols.xorgOffset! Well, that's what you get when giving up statically typed languages in favor of Python ... It's fixed on GitHub now. (And note to self: Test the basic stuff as well. ) Quote Link to comment Share on other sites More sharing options...
ralphb Posted November 18, 2015 Author Share Posted November 18, 2015 I could imagine you might want to find the difference of two memory location, and as soon as you assume negative values, you have to do signed arithmetics. I concur. I guess what's missing here are shift operators. xas99 already supports &, |, and ^, but << and >> will require some fiddeling, as > is already used as hex indicator. And yes, backwards compatibility can be a pain ... I particularly dislike that 1 + 2 * 3 yields 9, and I have to find a "modern" solution to that yet. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 19, 2015 Share Posted November 19, 2015 I concur. I guess what's missing here are shift operators. xas99 already supports &, |, and ^, but << and >> will require some fiddeling, as > is already used as hex indicator. And yes, backwards compatibility can be a pain ... I particularly dislike that 1 + 2 * 3 yields 9, and I have to find a "modern" solution to that yet. Perhaps you could switch to 32-bit arithmetic when brackets are used, which means it does not have to be backwards compatible? Then (>100*>C0) would not be treated as a negative number and (>100*>C0)/4 would return the expected result of >3000. Edit: This would also prevent that (>100/4)*>C0 yields a different result than (>100*>C0)/4. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted November 19, 2015 Share Posted November 19, 2015 Perhaps you could switch to 32-bit arithmetic when brackets are used, which means it does not have to be backwards compatible? Then (>100*>C0) would not be treated as a negative number and (>100*>C0)/4 would return the expected result of >3000. I would think it best to avoid using () to bracket calculations because of their use in addressing—perhaps [] or {} would be better. ...lee Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 19, 2015 Share Posted November 19, 2015 Doh! That was caused by a typo: In one case I accidentally wrote self.symbols.xorgLOffset instead of self.symbols.xorgOffset! Well, that's what you get when giving up statically typed languages in favor of Python ... It's fixed on GitHub now. (And note to self: Test the basic stuff as well. ) Thanks. XORG, SLC, PIX all working fine. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 24, 2015 Share Posted November 24, 2015 Is there any way to cancel XORG and return to use the previous AORG? Quote Link to comment Share on other sites More sharing options...
ralphb Posted November 25, 2015 Author Share Posted November 25, 2015 Is there any way to cancel XORG and return to use the previous AORG? Sure, just use "AORG" without argument. IIRC this also works with the TI assembler when switching between RORG and AORG. 2 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 26, 2015 Share Posted November 26, 2015 Sorry, me again. I have switched to IDEA 15. but I'm still getting errors: null java.lang.NullPointerException at net.endlos.xdt99.xas99.Xas99Reference.findBeginningOfLine(Xas99Reference.java:78) at net.endlos.xdt99.xas99.Xas99Reference.<init>(Xas99Reference.java:27) at net.endlos.xdt99.xas99.psi.impl.Xas99PsiImplUtil.getReference(Xas99PsiImplUtil.java:79) at net.endlos.xdt99.xas99.psi.impl.Xas99OpLabelImpl.getReference(Xas99OpLabelImpl.java:40) at com.intellij.psi.impl.SharedPsiElementImplUtil.getReferences(SharedPsiElementImplUtil.java:83) at com.intellij.psi.impl.PsiElementBase.getReferences(PsiElementBase.java:82) at org.intellij.plugins.intelliLang.references.InjectedReferencesContributor.getInjectedReferences(InjectedReferencesContributor.java:56) at org.intellij.plugins.intelliLang.references.InjectedReferencesInspection$1.visitElement(InjectedReferencesInspection.java:38) at com.intellij.psi.impl.PsiElementBase.accept(PsiElementBase.java:274) at net.endlos.xdt99.xas99.psi.impl.Xas99OpLabelImpl.accept(Xas99OpLabelImpl.java:23) at com.intellij.codeInspection.InspectionEngine.acceptElements(InspectionEngine.java:81) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass$4.process(LocalInspectionsPass.java:320) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass$4.process(LocalInspectionsPass.java:315) at com.intellij.concurrency.ApplierCompleter.a(ApplierCompleter.java:122) at com.intellij.concurrency.ApplierCompleter.access$000(ApplierCompleter.java:44) at com.intellij.concurrency.ApplierCompleter$1.run(ApplierCompleter.java:85) at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1169) at com.intellij.concurrency.ApplierCompleter$2.run(ApplierCompleter.java:94) at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:446) at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:443) at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:392) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54) at com.intellij.concurrency.ApplierCompleter.a(ApplierCompleter.java:106) at com.intellij.concurrency.ApplierCompleter.compute(ApplierCompleter.java:82) at jsr166e.CountedCompleter.exec(CountedCompleter.java:684) at jsr166e.ForkJoinTask.doExec(ForkJoinTask.java:260) at jsr166e.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:858) at jsr166e.ForkJoinPool.scan(ForkJoinPool.java:1687) at jsr166e.ForkJoinPool.runWorker(ForkJoinPool.java:1642) at jsr166e.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:108) Source code attached. f18a-isometric-xas99.a99 Quote Link to comment Share on other sites More sharing options...
ralphb Posted December 20, 2015 Author Share Posted December 20, 2015 I've just released version 1.5.1, which contains an updated IDEA plugin that supports IDEA 15, adds a code formatter, and fixes some bugs, including the one above. Code Reformat will do exactly that, based on your preferences in Settings > Editor > Code Style. This is handy when you copy and paste code from other sources, or if you want to cover up your sloppiness. For technical reasons you may have to reformat twice in a row to get comments align properly -- don't ask. And I suspect a bug in the IntelliJ platform that results in incorrect indenting if the very first line of the file does not start in column 1; let's see where that bug report goes. 3 Quote Link to comment Share on other sites More sharing options...
Davvel Posted January 14, 2016 Share Posted January 14, 2016 Why does xga99 gpl compiler implement the SLL, SRC etc... (shift bit wise instructions) in reverse order to that specified in the gpl_programmers_guide.pdf ? It took me some time to realise why it was throwing an exception. According to PDF Shift Right Circular = SRC GD,GS but XGA99 needs this instruction as SRC GS,GD Thanks 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.