Pokeypy Posted March 5, 2021 Share Posted March 5, 2021 (edited) Hi, I'm trying to compile a few lines of Atari 800XL assembly code from a tutorial; with "ca65", the assembly-compiler of cc65 on Linux. (The tutorial used Eclipse with WUDSN on Windows, so I'm trying to use a different compiler/assembler). This is the code: org $2000 start: lda #0 sta $022F loop: lda $D40B sta $240A sta $201A jmp loop run start The program renders the typical Atari colors. If I leave out the first and the last line, the code compiles (with "export CC65_HOME="/usr/local/share/cc65" && cl65 -t atari colours.s[/code]". But it refuses to link. I get the following error message: Unresolved external '_main' referenced in: runtime/callmain.s(27) ld65: Error: 1 unresolved external(s) found - cannot create output file What do I have to do to make it work with cl65? Edited March 5, 2021 by Pokeypy Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 5, 2021 Share Posted March 5, 2021 Try renaming 'start' to '_main' but also put a '.export _main' before it (indented). The 'template' you could use could be found by taking a C example with a main function in it and compile it to asm using cc65. Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 5, 2021 Share Posted March 5, 2021 Please note also, that your "org" statement does have an other meaning in ca65, normally not the intended one. Memory positioning is up to the linker. Your "run start" also seems to be meaningless under the ca65 context. Furthermore I don't see, how your code would produce the rainbow effect. $240A/$201A is just RAM and no hardware register is mapped there. If you like to see a working example, please inspect: Quote Link to comment Share on other sites More sharing options...
Pokeypy Posted March 5, 2021 Author Share Posted March 5, 2021 (edited) 5 hours ago, Wrathchild said: Try renaming 'start' to '_main' but also put a '.export _main' before it (indented). Thank you very much! That made it compile and link. Nice! I tried in that direction before, but it seems, I missed that combination. I was just guessing. "Irgendwer" wrote: Quote Furthermore I don't see, how your code would produce the rainbow effect. $240A/$201A is just RAM and no hardware register is mapped there. Interesting. Well, it's not my code, I took it from a lecture on Youtube (in German). The part with the addresses is at minute 53:05: But you're right, I can't get the rainbow effect (Edit: see below, was my own fault). I tried to translate it to C. It compiled with cc65 (cl65), but same result: No rainbow. I was quite confused. #include <peekpoke.h> typedef unsigned char byte; void blankScreen() { POKE(0x022F, 0); } byte getScanlinePosition() { return PEEK(0xD40B); } void interruptCPUUntilScanlineFinished() { POKE(0x240A, 0x19); } void setNextScanlineColor(byte color) { POKE(0x201A, color); } int main(void) { byte a; blankScreen(); while (1) { a = getScanlinePosition(); interruptCPUUntilScanlineFinished(); setNextScanlineColor(a); } return 0; } Edited March 5, 2021 by Pokeypy Quote Link to comment Share on other sites More sharing options...
Pokeypy Posted March 5, 2021 Author Share Posted March 5, 2021 (edited) I'm sorry. It was my fault. I wrote the wrong addresses down. It's $D40A/$D01A, not something with "2". Well, the program is for a very old computer, and I'm myself are getting old too. Sorry. So now it works. With a bit of judder in C though. Actually not usable, lol. Has to be assembler. But it works. Thanks to all! Edited March 5, 2021 by Pokeypy Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 5, 2021 Share Posted March 5, 2021 (edited) 26 minutes ago, Pokeypy said: With a bit of judder in C though. Actually not usable, lol. Has to be assembler. Go back to to the first structure, by introducing function calls of course you are now taking too long [Edit] Also pass the -O on the compiler command line to let the optimizer help Edited March 5, 2021 by Wrathchild Quote Link to comment Share on other sites More sharing options...
Pokeypy Posted March 5, 2021 Author Share Posted March 5, 2021 Ok, this is faster: int main(void) { unsigned char a; unsigned char *p; p = (unsigned char *) 0x022F; *p = 0; while (1) { p = (unsigned char *) 0xD40B; a = *p; p = (unsigned char *) 0xD40A; *p = 0x19; p = (unsigned char *) 0xD01A; *p = a; } return 0; } But not very beautiful. No judder, but one "step" in the horizontal middle of the lines. Also used "-O". Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 5, 2021 Share Posted March 5, 2021 (edited) OK, but again... using cc65 to generate the asm file gives: .proc _main: near .segment "CODE" jsr decsp3 ldx #$02 lda #$2F jsr stax0sp sta ptr1 stx ptr1+1 lda #$00 L0018: ldy #$00 sta (ptr1),y ldx #$D4 lda #$0B jsr stax0sp sta ptr1 stx ptr1+1 ldy #$00 lda (ptr1),y ldy #$02 sta (sp),y lda #$0A jsr stax0sp sta ptr1 lda #$19 ldy #$00 sta (ptr1),y ldx #$D0 lda #$1A jsr stax0sp sta ptr1 stx ptr1+1 ldy #$02 lda (sp),y jmp L0018 .endproc But I change it to: #include <atari.h> int main(void) { static unsigned char a; OS.sdmctl = 0; while (1) { a = ANTIC.vcount; ANTIC.wsync = 0x19; GTIA_WRITE.colbk = a; } return 0; } It becomes: .proc _main: near .segment "BSS" L0021: .res 1,$00 .segment "CODE" lda #$00 sta $022F L0033: lda $D40B sta L0021 lda #$19 sta $D40A lda L0021 sta $D01A jmp L0033 .endproc But you can also do away with the variable, e.g. #include <atari.h> int main(void) { OS.sdmctl = 0; while (1) { asm("sta %w", 0xD40A); // ANTIC.wsync GTIA_WRITE.colbk = ANTIC.vcount; } return 0; } Which brings it down to just: .proc _main: near .segment "CODE" lda #$00 sta $022F L0024: sta $D40A lda $D40B sta $D01A jmp L0024 .endproc So lesson is to examine the asm produced from the C and whether its how you thought it would be. Edited March 5, 2021 by Wrathchild 1 Quote Link to comment Share on other sites More sharing options...
Pokeypy Posted March 5, 2021 Author Share Posted March 5, 2021 @Wrathchild: Wow! Very good! These are just the steps, I'd have to take now (and that's the kind of information I need for that). Thanks a lot! Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 5, 2021 Share Posted March 5, 2021 You're welcome Would also recommend anyone to read @ilmenit's thread and the associated guide on github Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted March 5, 2021 Share Posted March 5, 2021 Would also NOT recommend anyone uses <peekpoke.h> 2 Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 5, 2021 Share Posted March 5, 2021 If sheer speed is necessary, best to consider CC65 C as a very advanced macro assembler 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.