dmsc Posted May 5, 2023 Author Share Posted May 5, 2023 Hi! 2 hours ago, Jess Ragan said: I guess the big question is this... will this work with the Atari 5200 as well? There was a 5200 compiler, Calamari or something, but it was early and difficult to figure out. From the README at https://github.com/dmsc/fastbasic#fastbasic---fast-basic-interpreter-for-the-atari-8-bit-computers : The FastBasic cross-compiler supports the Atari 5200, producing cartridge images. The cross-compiler runs on Linux, Windows or OSX. Have Fun! 1 Quote Link to comment Share on other sites More sharing options...
fenrock Posted June 20, 2023 Share Posted June 20, 2023 Hello, I'm back using fastbasic and have some questions about linking separate asm files. I have 2 asm files, e.g. gen.asm and gen2.asm. In gen2.asm is a .proc I want to call from gen.asm. How do I do that? I've tried following in gen.asm: .import GEN2 .export GEN .proc GEN jsr GEN2::start ; the scoped start label inside GEN2 ;; do stuff with returned values ;; ... rts .endproc With gen2.asm: .export GEN2 .proc GEN2 start: pla ;; ... more stuff rts .endproc The fastbasic file is simple, just doing USR to gen (test.bas): dim d1(31) byte x = USR(@gen, &d1, 1, 2) ? "x:" ? x I've tried various ways to compile, but I'm getting $ fb test.bas -X:-U gen2.asm gen.asm BAS compile 'test.bas' to 'test.asm' ASM assemble 'test.asm' to 'test.o' ASM assemble 'gen2.asm' to 'gen2.o' ASM assemble 'gen.asm' to 'gen.o' gen.asm(10): Error: No such scope: 'GEN2' gen.asm(10): Error: Unexpected trailing garbage characters fastbasic: can't assemble file I've tried it with and without the `-X:-U` parameter, and with a `-X:-DGEN2` (which errors with duplicate symbol). What's the correct way to link the two together so procs in one asm are callable from another? Thanks! Quote Link to comment Share on other sites More sharing options...
danwinslow Posted June 20, 2023 Share Posted June 20, 2023 11 minutes ago, fenrock said: Hello, I'm back using fastbasic and have some questions about linking separate asm files. I have 2 asm files, e.g. gen.asm and gen2.asm. In gen2.asm is a .proc I want to call from gen.asm. How do I do that? I've tried following in gen.asm: .import GEN2 .export GEN .proc GEN jsr GEN2::start ; the scoped start label inside GEN2 ;; do stuff with returned values ;; ... rts .endproc With gen2.asm: .export GEN2 .proc GEN2 start: pla ;; ... more stuff rts .endproc The fastbasic file is simple, just doing USR to gen (test.bas): dim d1(31) byte x = USR(@gen, &d1, 1, 2) ? "x:" ? x I've tried various ways to compile, but I'm getting $ fb test.bas -X:-U gen2.asm gen.asm BAS compile 'test.bas' to 'test.asm' ASM assemble 'test.asm' to 'test.o' ASM assemble 'gen2.asm' to 'gen2.o' ASM assemble 'gen.asm' to 'gen.o' gen.asm(10): Error: No such scope: 'GEN2' gen.asm(10): Error: Unexpected trailing garbage characters fastbasic: can't assemble file I've tried it with and without the `-X:-U` parameter, and with a `-X:-DGEN2` (which errors with duplicate symbol). What's the correct way to link the two together so procs in one asm are callable from another? Thanks! Just guessing, but the circularity of both of them needing the other might be a problem. Have you tried putting them in the same file? Quote Link to comment Share on other sites More sharing options...
fenrock Posted June 20, 2023 Share Posted June 20, 2023 (edited) 28 minutes ago, danwinslow said: Just guessing, but the circularity of both of them needing the other might be a problem. Have you tried putting them in the same file? They don't need each other, gen calls gen2, but not the other way around. I've tried them together, finding that the issue is using `jsr GEN2::start`, but in a single file just `jsr GEN2` works. I was reading the scoping rules of ca65, and thought the ::start should work. Got it mostly working in 1 file, but I really want to have multiple files. Edited June 20, 2023 by fenrock Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted June 20, 2023 Share Posted June 20, 2023 It says it's using ld65 to link it all together, so maybe you need something like ld65 -o test test.o gen.o gen2.o So maybe run ld65 after the compile, although fb should be doing that anyway, don't know enough about FB Quote Link to comment Share on other sites More sharing options...
fenrock Posted June 20, 2023 Share Posted June 20, 2023 (edited) ok, after a lot of experimenting, I've got it working. The main issue was using GEN2::start as previously noted. The second issue I had was forgetting that JSR pushed values onto the stack, which I had to deal with. Here's a minimal functioning program using multiple asm files test.bas x = USR(@gen, 1, 2) ? "x:" ? x ? PEEK(x) ? PEEK(x + 1) ? PEEK(x + 2) ? PEEK(x + 3) gen.asm .export GEN .import GEN2 .proc GEN ; call one proc from another ; it will take our current params, add 1 to each, and then return them on ; stack, which we then push into _p1/2, and return memory location of p1 jsr GEN2 ; results were pushed to the stack in GEN2 pla sta _p2+1 pla sta _p2 pla sta _p1+1 pla sta _p1 ; return the location of the stored data in A,X for FB to use as return value lda #<_p1 ldx #>_p1 rts _p1: .res 2 _p2: .res 2 .endproc gen2.asm .export GEN2 .proc GEN2 start: ; save return address pla sta _ret pla sta _ret+1 ; pull out the original parameters from the GEN call pla sta _p2+1 pla sta _p2 pla sta _p1+1 pla sta _p1 ; add one to both vars inc _p1 bne no1 inc _p1+1 no1: inc _p2 bne no2 inc _p2+1 no2: ; now save values to stack for the caller to get out (i.e. GEN) lda _p1 pha lda _p1+1 pha lda _p2 pha lda _p2+1 pha ; push the return address back into stack as we did JSR to here lda _ret+1 pha lda _ret pha rts ; temporary data _p1: .res 2 _p2: .res 2 _ret: .res 2 .endproc Compile: fb test.bas gen2.asm gen.asm Output: x: 8594 2 0 3 0 We can see the original args of "1, 2" have been incremented to 2, 3 Some useful other stuff while debugging in ALTIRRA: $ grep GEN test.lbl al 0022E2 .GEN al 00228F .GEN2 # Now add breakpoints in Altirra before running test.xex in SDX: bp 22e2 bp 228f Edited June 20, 2023 by fenrock fixed asm comments Quote Link to comment Share on other sites More sharing options...
dmsc Posted June 21, 2023 Author Share Posted June 21, 2023 Hi! 8 hours ago, fenrock said: ok, after a lot of experimenting, I've got it working. The main issue was using GEN2::start as previously noted. The second issue I had was forgetting that JSR pushed values onto the stack, which I had to deal with. This is not about FastBasic, more about 6502 assembly 🙂 ... yes, accessing results from depth in the stack is not that easy. But, there is an alternative to pop and push, use TSX to transfer the stack pointer to the X register and access from there: .export GEN2 .proc GEN2 start: ; Get stack pointer int X: tsx ; Read original parameter 2: lda $103,x sta _p2+1 lda $104,x sta _p2 ; Increment inc _p2 bne no1 inc _p2+1 no1: ; Store parameter 2: lda _p2+1 sta $103,x lda _p2 sta $104,x ; Or do the same in place for parameter 1 inc $105,x bne no2 inc $106,x no2: ; Return rts ; temporary data _p2: .res 2 .endproc About the ".export" and ".proc", those are specific to CA65 assembler. In your first example, you were trying to access "GEN2::start" from outside, but that does not work because ".export" only exports the given symbol, all other local symbols are hidden from the file. Have Fun! Quote Link to comment Share on other sites More sharing options...
fenrock Posted June 21, 2023 Share Posted June 21, 2023 (edited) Thanks @dmsc My own noob-ishness at not thinking of tsx etc. I haven't done any real 6502 assembly in years. I've got a further question for you. I've just pushed a repo that adds command line args reading for FastBasic applications here: https://github.com/markjfisher/fb-args So you can call your applications and pass args to it on the command line in spartados for example. There's examples in the repo. It's all working as I expected except for one thing. In my example program here: https://github.com/markjfisher/fb-args/blob/master/example/main.bas On line 23, I have to initialise any variable name, otherwise the loop below that code fails to run correctly. I think it's probably something to do with the asm file I include doing something funny, but can't track it down. Building and running the main.bas file, I get the following output example: Which looks great. Command line parsing from FastBasic 🎉 However, if I remove the line: foo$ = "" which has nothing to do with the rest of the application, then when I run it I get this instead: Can you help me work out what's wrong with the application? There's only 2 files involved: https://github.com/markjfisher/fb-args/blob/master/example/getargs-sdx.asm https://github.com/markjfisher/fb-args/blob/master/example/main.bas so not difficult to test and reproduce I hope, assuming you have a SDX environment. Thanks! Edited June 21, 2023 by fenrock Quote Link to comment Share on other sites More sharing options...
dmsc Posted June 21, 2023 Author Share Posted June 21, 2023 Hi! Thanks for your FastBasic examples! 9 hours ago, fenrock said: Thanks @dmsc My own noob-ishness at not thinking of tsx etc. I haven't done any real 6502 assembly in years. I've got a further question for you. I've just pushed a repo that adds command line args reading for FastBasic applications here: https://github.com/markjfisher/fb-args So you can call your applications and pass args to it on the command line in spartados for example. There's examples in the repo. It's all working as I expected except for one thing. In my example program here: https://github.com/markjfisher/fb-args/blob/master/example/main.bas On line 23, I have to initialise any variable name, otherwise the loop below that code fails to run correctly. I think it's probably something to do with the asm file I include doing something funny, but can't track it down. The problem is in your assembly, at line 18: https://github.com/markjfisher/fb-args/blob/master/example/getargs-sdx.asm#L18 .zeropage ptr1: .res 1 Here, you reserved 1 byte of zeropage to store your "ptr1" variable.... but then, at line 46: sparta: lda DOSVEC clc adc #<LBUF sta ptr1 lda DOSVEC+1 adc #>LBUF sta ptr1+1 You are writing to "ptr1+1", so you used two bytes. This overwrites one FastBasic pointer, messing up the code later. The fix is simply to reserve 2 bytes for ptr1. Have Fun! 2 Quote Link to comment Share on other sites More sharing options...
fenrock Posted June 22, 2023 Share Posted June 22, 2023 Goodness, I should have spotted that. Thanks. Quote Link to comment Share on other sites More sharing options...
rickcollette Posted December 6, 2023 Share Posted December 6, 2023 On 6/21/2023 at 7:44 AM, fenrock said: I've just pushed a repo that adds command line args reading for FastBasic applications here: https://github.com/markjfisher/fb-args This is brilliant - thank you for doing this. It solves a lot of issues I was going to have with creating and reading "drop files" to manage this exact thing. I starred your repo. 1 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.