tsom Posted February 6, 2020 Share Posted February 6, 2020 I, for my own amusement, was trying to build the source to ANALOG Magazine's RaceInSpace (https://ksquiggle.neocities.org/asmgames/raceinsp.htm / https://github.com/jtsom/AnalogSourceCode/blob/master/RaceInSpace.asm ) and using ATASM it was generating an Immediate Overflow warning on this snippet of code: ORIGIN = $1000 ; ; DRAM = ORIGIN+$1000 *= $0090 GRP20P *= *+2 ;scrn pntr -20 *= $600 LDA # <DRAM-20 ;w/offset lo -- Warning here STA GRP20P ;offset pntr lo LDA # >DRAM-20 ;w/offset hi STA GRP20P+1 ;offset pntr hi (this is snipped from around line 1745). Looking at the generated code from ATASM I see: In test.s, line 11-- Warning: Immediate overflow 00:06 A9 EC LDA # <DRAM-20 ;w/offset lo 02:06 85 90 STA GRP20P ;offset pntr lo 04:06 A9 0C LDA # >DRAM-20 ;w/offset hi 06:06 85 91 STA GRP20P+1 ;offset pntr hi Using MADS I get the same assembled bytes. (without any warnings) Using the original Mac/65 assembler the assembled bytes are: 00:06 A9 EC LDA # <DRAM-20 ;w/offset lo 02:06 85 90 STA GRP20P ;offset pntr lo 04:06 A9 1F LDA # >DRAM-20 ;w/offset hi 06:06 85 91 STA GRP20P+1 ;offset pntr hi Notice the high and low bytes of the LDA instructions. Aside from I'm not sure why Atasm is giving the warning, it looks like both assemblers are taking the high and low bytes of the address BEFORE subtracting 20. Mac/65 (correctly?) subtracts first THEN gets the high/low bytes. Now I can make it assemble correctly(?) if I add parenthesis - LDA #<(DRAM-20), which is fine, but if attempting to build old code that doesn't take that into account, lots of errors and crashes will happen. I can try to post issues (somewhere) for this on the respective assemblers, but it doesn't look like ATASM is even maintained anymore. Thoughts? Thanks! Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 6, 2020 Share Posted February 6, 2020 Probably a difference in evaluation priority as you mention. It would probably be preferable that the low/high byte operators only act on the immediate following part of the expression since that gives both options - bracketting the rest as you show gives the other option. I guess if it did it the other way then you might need to use LDA # (<DRAM) - 20 which would likely confuse the assembler and give an error. I think you're right about AtAsm not being actively supported. I used an older build for a time that had some annoying nasty bugs so sought out the current one of the time. I think someone resurrected it for a little while to add a couple of features/fixes but AFAIK it's an inactive project for some time now. The advantage of AtAsm is you can feed it Mac-65 source with minimal modification. MADs though, does have a bit of a learning curve but is well supported and somewhat more powerful than AtAsm. Best bet is to endure a bit of initial pain and use the better product. Quote Link to comment Share on other sites More sharing options...
tsom Posted February 6, 2020 Author Share Posted February 6, 2020 I suppose my main question is, is the way Mac/65 assembling the correct output? I would think it would be - which would mean both Atasm and MADS, without any changes, are incorrect. The down side to MADS is you have to build it from source. And being on MacOS, it took a little doing. Luckily the Free Pascal compiler comes as a Homebrew package, so all it took was 'brew install fpc' to have it, then just build the MADS source. And also the page/site isn't fully in English, (and the source isn't in something like Github), so have to keep checking to see if there's a new version. Thanks for the help, either way! Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 6, 2020 Share Posted February 6, 2020 It comes down to does it follow normal precedence of operators rules? The thing with Atari's AsmEd and followons, and assemblers in general - they generally have relaxed rules vs high level languages, ie are more likely to do simple left to right processing. Quote Link to comment Share on other sites More sharing options...
tsom Posted February 6, 2020 Author Share Posted February 6, 2020 Except, it looks like Mac/65 (I haven't tested the Atari EdAsm) is doing the "right" thing, as far as I would think (do the subtraction then get the high/low byte). Quote Link to comment Share on other sites More sharing options...
NRV Posted February 7, 2020 Share Posted February 7, 2020 Well mads has the precedence in the documentation: Operators Binary operators: + Addition - Subtraction * Multiplication / Division % Remainder & Bitwise and | Bitwise or ^ Bitwise xor << Arithmetic shift left >> Arithmetic shift right = Equal == Equal (same as =) <> Not equal != Not equal (same as <>) < Less than > Greater than <= Less or equal >= Greater or equal && Logical and || Logical or Unary operators: + Plus (does nothing) - Minus (changes sign) ~ Bitwise not (complements all bits) ! Logical not (changes true to false and vice versa) < Low (extracts low byte) > High (extracts high byte) ^ High 24bit (extracts high byte) = Extracts memory bank : Extracts global variable value Operator precedence: first [] (brackets) + - ~ < > (unary) * / % & << >> (binary) + - | ^ (binary) = == <> != < > <= >= (binary) ! (unary) && (binary) last || (binary) I tried to see it your way, but I couldn't.. I feel that mads is doing the right thing, but maybe is out of habit But I think I would find it strange if: "<LABEL + 1" is different than "1 + <LABEL" .. Quote Link to comment Share on other sites More sharing options...
drac030 Posted February 26, 2020 Share Posted February 26, 2020 MAC/65 is right, the unary operators < and > should extract the low and high byte, respectively, from the value of the operand. Which means that the assembler should first evaluate the entire expression and then apply the unary operator. It has always been natural for me, and not only for me, as it seems - see a snippet from the WDC's 65C816 manual, chapter six: Quote 6.3.3.4 The assembler shall use the <, >, and ^ characters after the # character in immediate address to specify which byte or bytes will be selected from the value of the operand. Any calculations in the operand must be performed before the byte selection takes place. 1 Quote Link to comment Share on other sites More sharing options...
tsom Posted February 26, 2020 Author Share Posted February 26, 2020 @drac030 Thanks - that's what I figured it should be doing, and that ATASM and MADS are not quite doing it the same. Quote Link to comment Share on other sites More sharing options...
StefanD Posted February 26, 2020 Share Posted February 26, 2020 ATASM has the precedence also in its docs. Same as MADS regarding unary < > and binary + -. For me, this is also strange, but it has the advantage, that it has same precedence as unary -, e.g. -5+7 is 2 and not -(5+7) = -12. And you can use expressions like x+<y+z, where you probably don't expect x+<[y+z]. So put the expr in brackets [] and it works as it should without warnings, e.g. lda #<[adr-1]. Quote Link to comment Share on other sites More sharing options...
tsom Posted February 26, 2020 Author Share Posted February 26, 2020 Yes, they both say the have the same precedence. But I'd say that the < and > are not quite the same as math functions (+, -). The < and > should act on the result of any calculations of the operand - returning the high / low bytes of the calculated address. Going forward (if I choose to use ATASM or MADS) I can remember to use ( ) to get the precedence right - but if I want to compile old code with these newer compilers, I'd have to make sure to watch for that code, so it compiles correctly (like the RaceInSpace code where I originally found the issue). 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.