JamesD Posted August 29, 2016 Share Posted August 29, 2016 For those that don't know, these tools come with the CC65 compiler.I have had several problems with the assembler and linker so I've started this thread to see if the problems I'm having are bugs, if there are work arounds, if I'm doing something wrong, or whatever.I'll put each code sample in separate posts. Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 (edited) What we have here is a work around.I don't have a copy of the original code but I'll try to explain/recreate it enough it can be tested.The original code did not define scrval or coltable, the code was inline and I used < and > for extracting the LSB and MSB.Oddly enough, the same operators work in similar code elsewhere.As far as I can tell, the parser is barfing on the long sequences of math operations I use to build the data differently for individual platforms.The original code looked something like this with the data spread over 3 or 4 lines: scrtableLSB: <ScreenAdr+(BytesPerLine**0, <ScreenAdr+(BytesPerLine**1,... The error was that it was treating the resulting numbers as 16 bit rather than 8 bit, as if the < > operators were not there. This worked, but I had to define .scrval separately to get it to work. .if BytesPerLine = 40 ;************************************************** ; 80 column address lookup table ;************************************************** .define scrval ScreenAdr+BytesPerLine*8 .define coltable scrval*0, scrval*1, scrval*2, scrval*3, scrval*4, scrval*5, scrval*6, scrval*7, scrval*8, scrval*9, scrval*10, scrval*11, scrval*12, scrval*13, scrval*14, scrval*15, scrval*16, scrval*17, scrval*18, scrval*19, scrval*20, scrval*21, scrval*22, scrval*23, scrval*24 scrtableLSB: .lobytes coltable scrtableMSB: .hibytes coltable .endif Edited August 29, 2016 by JamesD Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 This is a macro for simplifying the 65816 memory move, the assembler has been told to support 65816 code. Other macros I'm using work fine. .macro MOVEMEMN StartAddress,DestAddress,BytesToMove,SourceBank,DestBank rep #$30 .A16 .I16 LDX #StartAddress LDY #DestAddress LDD #BytesToMove MVN SourceBank DestBank sep #$30 .A8 .I8 .endmacro Here is how the program is using it. The commented out version was the first attempt.Notice the number of math operations... just like other code I've had trouble with. .if Use65816 = 1 ; MOVEMEMN (ScreenAdr+BytesPerLine*FontHeight, ScreenAdr, BytesPerLine*ScreenHeight*FontHeight-BytesPerLine*FontHeight, 0, 0) MOVEMEMN (ScreenAdr+40*8, ScreenAdr, 40*23*8, 0, 0) ldx #0 ;@sloop: .else ; the non 65816 code goes here ... Here is the list of errors: Print80,CA65(511): Error: ')' expectedPrint80,CA65(79): Note: Macro was defined herePrint80,CA65(511): Error: ':' expectedPrint80,CA65(79): Note: Macro was defined herePrint80,CA65(511): Unexpected trailing garbage characters Print80,CA65(79): Note: Macro was defined here Print80,CA65(511): Error: ',' expected Print80,CA65(79): Note: Macro was defined here Print80,CA65(511): Note: Macro parameter came from here Print80,CA65(511): Unexpected trailing garbage characters Print80,CA65(79): Note: Macro was defined here Print80,CA65(511): Note: Macro parameter came from here Quote Link to comment Share on other sites More sharing options...
danwinslow Posted August 29, 2016 Share Posted August 29, 2016 I am not super-sure that .define is intended for what you are doing with it. I thought it just defines the presence or absence of a particular value for use in .ifdef statements...you seem to be using it to hold named values: .define scrval ScreenAdr+BytesPerLine*8 I always just use an equate for that kind of thing - scrval=ScreenAdr+BytesPerLine*8 Quote Link to comment Share on other sites More sharing options...
sanny Posted August 29, 2016 Share Posted August 29, 2016 Please provide self-contained examples. Ideally (a) source file(s) which can be fed into the assembler to show the problem. For example, I have no idea what ScreenAdr, BytesPerLine, FontHeight, etc. are defined to. In your first post, does it make a difference if you enclose the parameter to "<" in parentheses? So <(ScreenAdr+(BytesPerLine**0) instead of <ScreenAdr+(BytesPerLine**0 Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 I am not super-sure that .define is intended for what you are doing with it. I thought it just defines the presence or absence of a particular value for use in .ifdef statements...you seem to be using it to hold named values: .define scrval ScreenAdr+BytesPerLine*8 I always just use an equate for that kind of thing - scrval=ScreenAdr+BytesPerLine*8 There is an example under 11.44 .HIBYTEShttp://www.cc65.org/doc/ca65-11.html#ss11.44 And I should probably change as much as I can from defines to equates and some of my problems will go away. Quote Link to comment Share on other sites More sharing options...
Island2Live Posted August 29, 2016 Share Posted August 29, 2016 (edited) I am using ca65 from cc65 compiler myself on a project. As far as I can tell what sanny suggested is completely right: You need to put round brackets around the whole expression. So your provided code example <ScreenAdr+(BytesPerLine**0, <ScreenAdr+(BytesPerLine**1, ... will of course result in 16 Bit values. This is intentional and is described in the provided documentation (»ca65 Users Guide«) in chapter 4. »Expressions«. Especially sub-chapters 4.2 »Size of expression result« and 4.5 »Available operators« are of importance. Your code example will evaluate to something like this: 8 Bit + (16 Bit * * 0, 8 Bit + (16 Bit * 8 ) * 1, ... which results in 16 Bit, 16 Bit, ... So you must do what sanny already told: <(ScreenAdr + BytesPerLine * 8 * 0), <(ScreenAdr + BytesPerLine * 8 * 1), ... Edited August 29, 2016 by Island2Live Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 (edited) Please provide self-contained examples. Ideally (a) source file(s) which can be fed into the assembler to show the problem. For example, I have no idea what ScreenAdr, BytesPerLine, FontHeight, etc. are defined to. In your first post, does it make a difference if you enclose the parameter to "<" in parentheses? So <(ScreenAdr+(BytesPerLine**0) instead of <ScreenAdr+(BytesPerLine**0 Actually, I thought I tried that on the first line of values and it still barfed on it. I may experiment with it a bit and get back to you. It's working now so I'll leave that real code alone. *edit* BTW, ScreenAdr is defined as the Screen Address, BytesPerLine is 32 or 40 depending on how it's assembled, and FontHeight is 8. For whatever reason, most of those are .defines and not equ. So I'm hoping the problem goes away with that change. Edited August 29, 2016 by JamesD Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 Now I remember why I used defines. The code tests BytesPerLine to see whether to generate 64 or 80 character per line code, etc... Quote Link to comment Share on other sites More sharing options...
sanny Posted August 29, 2016 Share Posted August 29, 2016 You could use a different equate in the calculations. The equate is set differently depending on BytesPerLine. Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 29, 2016 Author Share Posted August 29, 2016 I think I have identified the problem. Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 30, 2016 Author Share Posted August 30, 2016 Current macro .P816 ;Memory Move Negative. Move from hi to lo address. ;Memory is moved at the rate of seven clock cycles per byte. .macro MOVEMEMN SourceAddress,DestAddress,BytesToMove,SourceBank,DestBank rep #$30 ; set A, X, and Y to 16 bit .A16 ; Tell assembler Accumulator is 16 bit .I16 ; Tell assembler Index registers are 16 bit LDX #SourceAddress ; The source address for the memory move LDY #DestAddress ; The destination address for the memory move LDA #BytesToMove+1 ; The number of bytes we want to move + 1 because MVN needs it MVN SourceBank,DestBank ; RAM banks, should be 00,00 on 64K system sep #$30 ; set A, X, and Y to 8 bits .A8 ; Tell assembler Accumulator is 8 bit .I8 ; Tell assembler Index registers are 8 bit .endmacro This does not work MOVEMEMN ($75C0,$74C0,5888,0,0) Quote Link to comment Share on other sites More sharing options...
Alfred Posted August 30, 2016 Share Posted August 30, 2016 Not a ca65 user, but you don't normally put macro parms in parens. What happens if you remove them ? 1 Quote Link to comment Share on other sites More sharing options...
JamesD Posted August 30, 2016 Author Share Posted August 30, 2016 (edited) Not a ca65 user, but you don't normally put macro parms in parens. What happens if you remove them ? Winner winner chicken dinner I was basing the code on an earlier macro I made .macro PRINT str lda #<str sta string lda #>str sta string+1 jsr print .endmacro And this works Endless: PRINT(String) ; print the string we just built clc bcc Endless But notice... only 1 parameter Edited August 30, 2016 by JamesD Quote Link to comment Share on other sites More sharing options...
JamesD Posted September 6, 2016 Author Share Posted September 6, 2016 I traced some of the errors I was having to using defined values within other defines.equated values can't be used in defines either. So some of my screen calculations I was performing based on other constants... are impossible. I had to create other defines. Quote Link to comment Share on other sites More sharing options...
JamesD Posted September 9, 2016 Author Share Posted September 9, 2016 (edited) This is a bit of a problem.I share a lot of code between the 65816 and 6502 versions for the unrolled scroll loop.I also have an alternate scroll for the 65816 using the MVN instruction.I have to test if I am generating 816 code and if I want to use the unrolled loop or not.If I'm not using the 65816 MVN, or I'm just using the 6502, I want to generate the unrolled loop.If it's for the 816 I have some optional code before and after the loop for changing A to 16 bit and back.But the assembler hates me.if unrollmore isn't defined (the define is nested in a test) it wants me to use .ifndef CRAP.if unrollmore is 1 it wants me to use .if CRAP < 1.ifndef should work even if CRAP is defined as 1 This gives me an Error: Identifier Expected in the .ifndef CRAP .define Use65816 1 .define unrollmore 0 .if Use65816 = 1 .if unrollmore = 0 MOVEMEMN (ScreenAdr+(BytesPerLine*FontHeight)),ScreenAdr,((BytesPerLine*ScreenHeight)-(BytesPerLine*FontHeight)),0,0 ; clear last line ldx #(BytesPerLine*4)-1 lda BGColor @sloop: sta ScreenAdr+LastRow*FontHeight*BytesPerLine,x sta ScreenAdr+LastRow*FontHeight*BytesPerLine+BytesPerLine*FontHeight/2,x dex bne @sloop .define CRAP 1 .endif .endif ; assembler workaround for .if unrollmore = 1 OR Use65816 = 0 .ifndef CRAP .if Use65816 = 1 ;... set A to 16 bit etc... .endif ;unrolled loop screen scroll goes here .if Use65816 = 1 ;... set A to 8 bit etc... .endif .endif Edited September 9, 2016 by JamesD Quote Link to comment Share on other sites More sharing options...
dmsc Posted September 10, 2016 Share Posted September 10, 2016 Hi!, This is a bit of a problem. I share a lot of code between the 65816 and 6502 versions for the unrolled scroll loop. I also have an alternate scroll for the 65816 using the MVN instruction. I have to test if I am generating 816 code and if I want to use the unrolled loop or not. If I'm not using the 65816 MVN, or I'm just using the 6502, I want to generate the unrolled loop. If it's for the 816 I have some optional code before and after the loop for changing A to 16 bit and back. But the assembler hates me. if unrollmore isn't defined (the define is nested in a test) it wants me to use .ifndef CRAP. if unrollmore is 1 it wants me to use .if CRAP < 1 .ifndef should work even if CRAP is defined as 1 This gives me an Error: Identifier Expected in the .ifndef CRAP I think you should read the CA65 manual (at http://cc65.github.io/doc/ca65.html) carefully. Your example works using the correct syntax, see: .define Use65816 1 .define unrollmore 0 .if Use65816 = 1 .and unrollmore = 0 .warning "inside block 1" .endif .if unrollmore = 1 .or Use65816 = 0 .warning "inside block 2" .endif See, use ".and" and ".or". Also, the ".warning" are useful to follow which code path is being assembled. Quote Link to comment Share on other sites More sharing options...
JamesD Posted September 11, 2016 Author Share Posted September 11, 2016 Thanks!FWIW, according to the documentation, my code should have worked. 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.