TGB1718 Posted March 12, 2021 Author Share Posted March 12, 2021 In cc65 if you want assembly modules, I create a new file <name>.s example to rotate colours in a VB routine in your "C" file:- extern void setvb(void); void main(void) { setvb(); more code . . . . } // in .s file .include "atari.inc" .export _setvb .proc _setvb: near .code _setvb: LDA #7 LDX # >MYVB LDY # <MYVB JSR SETVBV RTS MYVB: INC 704 JMP XITVBV .endproc you can also export variables to/from C/.s so no need to use the stack Quote Link to comment Share on other sites More sharing options...
CuloMajia Posted March 13, 2021 Share Posted March 13, 2021 Finally figured out the ML call routine. Need to .export the routine name and either need fastcall or cdecl in with the name in the C program source. Cannot use an ___underscores___ or else it throughs a duplicate definition error. Reason why I am hard pressed to figure C is that I want to also port to NES, Commodore 64, and other platforms. Let's say I already ported some stuff over to Fast Basic and they work very well. What is great a compiled Fast Basic program does not need a Run Time and can run from SpartaDOS. C and Fast Basic, you guys have something very valuable here. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 13, 2021 Share Posted March 13, 2021 Yep, sounds like you know what you're doing. Keep us posted, Quote Link to comment Share on other sites More sharing options...
CuloMajia Posted March 14, 2021 Share Posted March 14, 2021 (edited) This drove me crazy for awhile until someone in another forum pointed out. If you need to send arguments to a subroutine, they are stored in a custom stack upper ram, (The sp Pointer) not the 6502 stack. What you need to do is .... _my_custom_routine: .export _my_custom_routine ldy #0 lda (sp),y sta parameter01 ldy #2 lda (sp),y sta parameter02 ... processes .... lda sp adc #4 sta sp bcc no_sp_hi_inc_r0 inc sp+1 no_sp_hi_inc_r0: Edited March 14, 2021 by CuloMajia Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 14, 2021 Share Posted March 14, 2021 or just use inline asm in a C function perhaps, then you don't need to consider the byte sizes etc Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 14, 2021 Share Posted March 14, 2021 Yes, CC65 supports automatic access to passed in variables. Look at the ASM keyword. RTFM, in other words Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 15, 2021 Author Share Posted March 15, 2021 Also remember you can export variables to your C program from an assembler module in C use extern char PM[10]; and use it as a normal variable i.e. X=PM[2]; Variables have to be outside the .proc to be exported, variables inside the proc are local. in assembly module .include "atari.inc" .export _putsprite ; export function .export _PM ; <<<<<<<<<<export variable .proc _putsprite: near .code _putsprite: LDA _source STA $CB LDA _source+1 STA $CC . . MORE CODE HERE . AND TEMP ORA PM,X ; <<<<<<<used here STA PM,X RTS TEMP: .BYTE 0 COUNT: .BYTE 0 .endproc PM: _PM: .BYTE 0,0,0,0,0,0,0,0,0,0 Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 15, 2021 Share Posted March 15, 2021 (edited) You don't need the '_putsprite' after the '.code' as this is already defined by the proc line. Alternatively, you can drop the .proc and .endproc lines and use the label, there is no rule that code needs to be wrapped like that. LDA _source STA $CB Its unclear in the example if _source comes from this file or is an import/importzp? The use of hard-coded ZP locations is not good practice to be teaching as there's potential for conflicting with a ZP segment variable. As 'PM' is redundant just use '_PM' in the procedure? Plus the variables here are in the code segment, e.g. not good if you were targeting a cartridge. 1 hour ago, TGB1718 said: Variables have to be outside the .proc to be exported, variables inside the proc are local. That statement isn't true, where did you get that from? I think you are mixing C scope rules as in the asm generated from C where the local variable isn't visible? E.g. // C file 1 void initTemp(void); extern char TEMP; void main(void) { initTemp(); TEMP = 2; } // C file 2 void initTemp(void) { char TEMP; TEMP = 1; } which gives us: .import _initTemp .import _TEMP .export _main ; --------------------------------------------------------------- ; void __near__ main (void) ; --------------------------------------------------------------- .segment "CODE" .proc _main: near .segment "CODE" jsr _initTemp lda #$02 sta _TEMP rts .endproc and here (with the --static-locals flag used) .export _initTemp ; --------------------------------------------------------------- ; void __near__ initTemp (void) ; --------------------------------------------------------------- .segment "CODE" .proc _initTemp: near .segment "BSS" L0002: .res 1,$00 .segment "CODE" lda #$01 sta L0002 rts .endproc Which when linked gives the expected error: Unresolved external `_TEMP' referenced in: test_a.s(30) In your example, if you were to move _PM/PM before the .endproc then, yes, it would no longer be in the global scope and you see the error: Error: Exported symbol `_PM' was never defined But it, or in this example, TEMP can be made visible to C within the proc as follows: (To make an export visible in C it will need to have prefixing underscore) .data .export _TEMP _TEMP: .BYTE 0 Therefore now from C we can do: extern char TEMP; void initTemp(void) { TEMP = 1; } The rights and wrong of exposing a variable within a method is something else of course. However one legit use would be to export the label so that it is available for debugging within the emulator. Edited March 15, 2021 by Wrathchild added error from C file 1/2 example Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 15, 2021 Author Share Posted March 15, 2021 2 hours ago, Wrathchild said: That statement isn't true, where did you get that from? Was a while ago, maybe before I realised you need an underscore and not tried since then Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 15, 2021 Share Posted March 15, 2021 Yeah, the underscore gets slapped on automagically. Quote Link to comment Share on other sites More sharing options...
sanny Posted March 16, 2021 Share Posted March 16, 2021 If you ever programmed for MS-DOS in mixed C and Assembler, the underscore is a natural thing to you... Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 16, 2021 Author Share Posted March 16, 2021 25 minutes ago, sanny said: If you ever programmed for MS-DOS in mixed C and Assembler, the underscore is a natural thing to you... Only ever mixed C and Assembler on Atari ST so never used the underscore. Why is it used ? just seems to be a waste of time typing unnecessary characters, what relevance does it have ? other than code fails to compile if it's not there. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 16, 2021 Share Posted March 16, 2021 (edited) It's to prevent variable name collisions between 'namespaces'. Lots of systems use it still, but you only run into it when mixing direct calls into C libs or using mixed assembler, etc. I think it's actually a C convention. You should see what modern c++ does to internal names. Edited March 16, 2021 by danwinslow 1 Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 16, 2021 Share Posted March 16, 2021 (edited) Plenty of answers on StackOverflow but as Dan says, essentially this form of name-mangling helps stop clashes with asm names. But one of the valid reasons for me is that is also helps avoid register name conflicts (less so in 6502). Say in C you wrote: unsigned char a; ... a *= 2; this could translate to: asl a which is not what was wanted. So 'asl _a' avoids that. (Some assemblers, e.g. in MADS the 'a' is optional in 'asl a', CA65 does require it and other assemblers even use @ for the accumulator) Edited March 16, 2021 by Wrathchild Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 16, 2021 Author Share Posted March 16, 2021 Thank you for the explanations, makes total sense now Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 16, 2021 Author Share Posted March 16, 2021 I've noticed some things though with cc65 in assembler modules, I would expect some minor changes to adapt the code to fit with the C portion, however, I was having a small problem so loaded the code into BUG/65 to trace the code and had a bit of trouble finding the problem area, when I did figure it out this is what I found. this piece of code:- z2: lda #1 ;problem here ??? and _plotx bne l2 turned into this ??? 20B6 LDY #02 A0 02 20B8 LDA (82),Y B1 82 20BA AND #01 29 01 20BC STA 290D 8D 0D 29 Other code here . . . . Then here 20D6 LDA 290D AD 0D 29 20D9 BEQ 20E2 F0 07 20DB CMP #01 C9 01 20DD BEQ 20F3 F0 14 20DF JMP 2103 4C 03 21 even though it looks like it should work, it actually never got into one of the branches, really strange. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 16, 2021 Share Posted March 16, 2021 Woah, complete lack of context here, are you asking for help, do you still have a problem or sorted it? From what I can sense, you are building something with ca65 and including/linking this other things and running the binary. What are the build steps and parameters, e.g. is the optimzer involved? Best thing is to reduce it down to a small project that exhibits the same issue and share the source for that. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 17, 2021 Author Share Posted March 17, 2021 16 hours ago, Wrathchild said: Woah, complete lack of context here, are you asking for help, do you still have a problem or sorted it? Sorry, not asking for help, was just pointing out something that I spotted that I thought was rather unusual as I would expect the .asm code to remain reasonably unchanged. I did do it with and without Optimiser, no change. I also tried with smaller code and it produced what I expected (correct code). In the end I just gave up as it didn't seem worth the effort, I was just trying to speed up a "C" routine, but the increase in speed was minimal. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 17, 2021 Share Posted March 17, 2021 ok. Well, if you want meaningful commentary, you'll need to take the time to provide context. I have no idea what you are talking about at all from your post. Glad you got it sorted tho 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.